Infinite loop error by using while statement - vector

I want to know that why this is an infinite loop.
The script is as follows:
x=1;
while x<5;
x=2;
x=x+2;
if x==4;
x=x-1;
end
end

Step through this to see why x will always be less than 5:
x=1;
while x<5;
x=2; // You set x to 2 at the beginning of every single iteration
x=x+2; // At this point, x == 4
if x==4; // The "if" is unnecessary - of COURSE x == 4 - how could it possibly be anything else?
x=x-1; // x now contains 3
end
end
At the beginning of every iteration, then, x == 2. At the end of the iteration, x == 3.

Related

sum function in Julia is giving error if the array is empty

I am trying to create a code which identifies if the elements in an array are monotonic or not.
I wrote the below code and got the error -
function isMonotonic(array)
if length(array) <= 2
return true
end
check_up = []
check_down = []
for i in range(2, length(array))
if array[i] <= array[i-1]
append!(check_up, 1)
end
if array[i] >= array[i - 1]
append!(check_down, 1)
end
end
if sum(check_up) == length(array) - 1 || sum(check_down) == length(array) - 1
return true
else
return false
end
end
isMonotonic([1, 2, 3, 4, 5, 6 , 7])
I am getting the below error
Error: Methoderror: no method matching zero(::Type{Any})
I think it is because I am trying to sum up the empth array, I want to understand how to overcome this problem in general, I have a solution for the above code, but in genral I want to know the reason and how to use it. I do not want to first check if the array is empty or not and then do the sum.
If you wanted to save yourself lots of effort, the simplest solution would just be:
my_ismonotonic(x) = issorted(x) || issorted(x ; rev=true)
This will return true if x is sorted either forwards, or in reverse, and false otherwise.
We could maybe make it a little more efficient using a check so we only need a single call to issorted.
function my_ismonotonic(x)
length(x) <= 2 && return true
for n = 2:length(x)
if x[n] > x[1]
return issorted(x)
elseif x[n] < x[1]
return issorted(x ; rev=true)
end
end
return true
end
# Alternatively, a neater version using findfirst
function my_ismonotonic(x)
length(x) <= 2 && return true
ii = findfirst(a -> a != x[1], x)
isnothing(ii) && return true # All elements in x are equal
if x[ii] > x[1]
return issorted(x)
else
return issorted(x ; rev=true)
end
end
The loop detects the first occurrence of an element greater than or less than the first element and then calls the appropriate issorted as soon as this occurs. If all elements in the array are equal then the loop runs over the whole array and returns true.
There are a few problems of efficiency in your approach, but the reason you are getting an actual error message is because given the input, either this expression sum(check_up) or this expression sum(check_down) will effectively result in the following call:
sum(Any[])
There is no obvious return value for this since the array could have any type, so instead you get an error. If you had used the following earlier in your function:
check_up = Int[]
check_down = Int[]
then you shouldn't have the same problem, because:
julia> sum(Int[])
0
Note also that append! is usually for appending a vector to a vector. If you just want to add a single element to a vector use push!.

looping over an array and checking its elements

I have an array 'A'. I want to do a loop over all the elements of A, checking to see if any are greater than or equal to 1. If they are, I would like to assign a '1' to a new array 'B' in the same element index of A.
How would I go about implementing this?
I have the cumbersome idea of:
for i in 1:end
for j in 1:end
if A[i,j] >= 1
B[i,j] = 1
else
B[i,j] = 0
end
end
end
but I would prefer something more succinct.
Just use broadcast:
B = A .≥ 1
You can certainly use broadcasting as Oscar suggested (e.g. B = A .>= 1), but there's also nothing wrong with loops, since loops are fast and avoid excess allocations. You really only need one loop though, and the if statement is slightly superfluous, so:
B = similar(A, Int64) # If B doesn't already exist, otherwise omit this line
#inbounds for i in eachindex(A)
B[i] = A[i] >= 1
end
The #inbounds is optional, but improves speed.

How to break out of nested for loops in Julia

I have tried to break out of nested loops in a quite ineffective way:
BreakingPoint = false
a=["R1","R2","R3"]
b=["R2","R3","R4"]
for i in a
for j in b
if i == j
BreakingPoint = true
println("i = $i, j = $j.")
end
if BreakingPoint == true; break; end
end
if BreakingPoint == true; break; end
end
Is there an easier way to do that? In my actual problem, I have no idea about what are in arrays a and b, apart from they are ASCIIStrings. The array names (a and b in sample code) are also auto-generated through meta-programming methods.
You can do one of two things
have the loop statement (if thats what its called) in a multi outer loop
for i in a, j in b
if i == j
break
end
end
which is clean, but not always possible
I will be crucified for suggesting this, but you can use #goto and #label
for i in a
for j in b
if i == j
#goto escape_label
end
end
end
#label escape_label
If you go with the #goto/#label way, for the sake of the people maintaining/reviewing the code, document your use properly, as navigating code with labels is breathtakingly annoying
For the discussion on the multi-loop break, see this
Put the 2D loop into a function, and do an early return when you want to break.

Is there a way to always start at 0 using math.sin() Lua

Edit: This question is about Roblox Lua.
I'm using math.sin(tick()) to get a variable number and would like for it to always start at 0. Is this possible using math.sin? Is there something else I can use other than tick() to make this work?
Example:
for i = 1, 10 do
local a = math.sin(tick())+1
print(a)
wait()
end
wait(1)
for i = 1, 10 do
local a = math.sin(tick())+1
print(a)
wait()
end
My goal is to have this number start at 0 every time and then increase from there. So, it would start at 0 then increase to 2 and then decrease back to zero and continue modulating between 0 and 2 for as long as I continue calling it. Using the example above the number starts at any arbitrary number between 0 and 2.
I took a different approach and came up with this. It does exactly what I wanted to do with math.sin(tick()). If anyone knows other ways to accomplish this I would like to know.
local n = 0
local m = 0
local Debounce = true
local function SmoothStep(num)
return num * num * (3 - 2 * num)
end
while Debounce do
for i = 1, 100 do
wait()
m = m+.01
n = SmoothStep(m)
print(n)
if not Debounce then break end
end
for i = 1, 100 do
wait()
m = m+.01
n = SmoothStep(m)
print(n)
if not Debounce then break end
end
end
To non-Roblox users: tick() returns the local UNIX time. wait(t) yields the current thread for t seconds, the smallest possible interval being roughly 1/30th of a second.
Given that math.sin(0) equals 0, what you have to do is subtract the tick() inside the loop with the time the loop began at. This should make the expression inside math.sin start at roughly 0 at the beginning of the loop.
local loopstart = tick()
for i = 1, 10 do
local a = math.sin(tick() - loopstart)+1
print(a)
wait()
end

Why doesn't this "binding" code work as expected in JavaFX?

I am new to JavaFX. I am not able to understand why the code below doesn't work.
import javafx.util.Sequences;
def nums = [1..10];
var curr = 0;
var evenOrOdd = bind if (nums[curr] mod 2 == 0) "{nums[curr]} is an even number" else "{nums[curr]} is an odd number";
for (curr in [0..(sizeof nums -1)])
{
println("{evenOrOdd}");
}
I am getting
1 is an odd number
1 is an odd number
1 is an odd number
1 is an odd number
1 is an odd number
1 is an odd number
1 is an odd number
1 is an odd number
1 is an odd number
1 is an odd number
If I change the code to
import javafx.util.Sequences;
def nums = [1..10];
var curr = 0;
var evenOrOdd = bind if (nums[curr] mod 2 == 0) "{nums[curr]} is an even number" else "{nums[curr]} is an odd number";
for (i in [0..(sizeof nums -1)])
{
curr = i;
println("{evenOrOdd}");
}
I get the correct output:
1 is an odd number
2 is an even number
3 is an odd number
4 is an even number
5 is an odd number
6 is an even number
7 is an odd number
8 is an even number
9 is an odd number
10 is an even number
Clearly, the counter increment in the loop is not treated as a value change and the bound expression is not re evaluated.
Can anyone please explain the concept behind this behavior?
The for expression implicitly defines its iteration variable (that's why you didn't need to declare i in your second example). Even if there is already a variable with the same name, for will still create a new one for its scope. Your bind expression is bound to the curr variable outside of your for loop, not to the one inside your for loop. And the one outside of your loop doesn't change, so the bound expression will not change.
Example to demonstrate this behaviour of for:
var curr = 0;
var ousideCurrRef = bind curr;
println("Before 'for' loop: curr={curr}");
for (curr in [0..3])
{
println("In 'for' loop: curr={curr} ousideCurrRef={ousideCurrRef}");
}
println("After 'for' loop: curr={curr}");
This will print:
Before 'for' loop: curr=0
In 'for' loop: curr=0 ousideCurrRef=0
In 'for' loop: curr=1 ousideCurrRef=0
In 'for' loop: curr=2 ousideCurrRef=0
In 'for' loop: curr=3 ousideCurrRef=0
After 'for' loop: curr=0
Thus the curr outside the for loop won't change if you modify a variable of the same name inside the for loop.

Resources