for i in 1:2
if i == 2
print(x)
end
if i == 1
x = 0
end
end
UndefVarError : x not defined
Why does the code gives that error instead of printing 0 in julia?
While in python the following code print 0?
for i in range(2):
if i==1:
print(x)
if i==0:
x=0
The reason is because in the loop a variable gets a new binding each time a loop is executed, see https://docs.julialang.org/en/latest/manual/variables-and-scoping/#For-Loops-and-Comprehensions-1.
In fact while loop changed this behavior between Julia 0.6.3 and Julia 0.7 (in Julia 0.6.3 a new binding was not created). Therefore the following code:
function f()
i=0
while i < 2
i+=1
if i == 2
print(x)
end
if i == 1
x = 0
end
end
end
Gives the following output.
Julia 0.6.3
julia> function f()
i=0
while i < 2
i+=1
if i == 2
print(x)
end
if i == 1
x = 0
end
end
end
f (generic function with 1 method)
julia> f()
0
Julia 0.7.0
julia> function f()
i=0
while i < 2
i+=1
if i == 2
print(x)
end
if i == 1
x = 0
end
end
end
f (generic function with 1 method)
julia> f()
ERROR: UndefVarError: x not defined
Stacktrace:
[1] f() at .\REPL[2]:6
[2] top-level scope
For-loop created a new binding already in Julia 0.6.3 at each iteration so it fails both under Julia 0.6.3 and Julia 0.7.0.
EDIT: I have wrapped the examples in a function, but you would get the same result if you executed the while loop in global scope.
Ignore my comment andgo with Bogumil's answer as that's is the real rwason why your x variable disapears in thesecond iteration.
If you want your code to work like in Python, you can add the global keyword to your assignment of x:
for i in 1:2
if i == 2
print(x)
end
if i == 1
global x = 0
end
end
Note that this is not recommended in most cases as it'll make your code performance suffer. Julia likes local variables that the compiler can optimise away easily.
Related
I'm doing a quiz on sololearn and I'm confused, it says I have to loop from 5 to 1 when I use hint I get this code and when I run the code it becomes infinite loop instead of looping from 5 to 1
is it an infinite looping?
x = 5
while x > 0:
print(x)
x -= 1
Python is sensitive to the indenting of code. In order for your decrement statement to fall within the loop it must be indented to fall under the print statement.
Any possibilities to access local and global scopes and manipulate these. Maybe something similar to this python example:
def foo():
x = 10
globals().update(locals()) # update global parameters
print(x) # continue using x
I would like to do this without using global for variables individually.
This seems like quite bad programming but here is a way to do this, with the #eval and Base.#locals macros (#eval evaluates in global scope)
julia> function f(a,b)
c = a*b
for (k,v) in Base.#locals
#eval $k = $v
end
end
f (generic function with 2 methods)
julia> f(2,3)
julia> a
2
julia> b
3
julia> c
6
julia> f("a", "b")
julia> a
"a"
julia> b
"b"
julia> c
"ab"
Here's #MarcMush's answer as a macro:
julia> macro horribile_dictu()
return quote
for (name, value) in Base.#locals()
eval(:(global $name = $value))
end
end
end
#horribile_dictu (macro with 1 method)
julia> #macroexpand let x = 1
#horribile_dictu()
end
:(let x = 1
#= REPL[29]:2 =#
begin
#= REPL[28]:3 =#
for (var"#3#name", var"#4#value") = $(Expr(:locals))
#= REPL[28]:4 =#
Main.eval(Core._expr(:global, Core._expr(:(=), var"#3#name", var"#4#value")))
end
end
end)
julia> let x = 1
#horribile_dictu()
end
julia> x
1
julia> function foo()
x = 10
#horribile_dictu()
end
foo (generic function with 1 method)
julia> foo()
julia> print(x)
10
julia>
To repeat: avoid this.
If I execute,
a = iter([1,2,3])
for x in a:
print(x)
if x==1:
z=next(a)
I get
1
3
which I expect, since the call to next advances the iterator and skips the 2.
However in interactive mode (command line), if I remove the z= assignment, and only call next, it behaves very differently.
>>> a = iter([1,2,3])
>>> for x in a:
... print(x)
... if x==1:
... next(a)
gives me
1
2
3
I'm using Python 3.8.8 in Windows 64 bits. Is this expected? It only happens in interactive mode.
Interpreter echoing back the return value of next() in addition to x being printed each iteration.
>>> a = iter([1,2,3])
>>> for x in a:
... print(x)
... if x==1:
... next(a)
So 1 and 3 is the output of print(x), 2 the return value from next(). If you assign the output of z=next() things work as expected 1,3 because your z isn't returning or printing. Assigning the result of "next(a)" to a variable inhibits the printing of its' result so that just the alternate values that the "x" loop variable are printed
I'm learning Julia as part of my PhD in economics but I've come across an issue that doesn't make sense to me. I'm trying to write a function that performs some preliminary calculations then conducts a while loop and returns some value. I want to do this without using global variables. For some reason I can't get it to work. See the minimal working example below which returns a undefined variable error for z.
function test_me(n)
x = 2 + 1
y = x - 1
i = y
while i <= n
println(i)
i += 1
z = 3*i
end
return z
end
I can solve the problem easily by making z a global variable.
function test_me2(n)
x = 2 + 1
y = x - 1
i = y
while i <= n
println(i)
i += 1
global z = 3*i
end
return z
end
I'm confused as I was under the impression that by wrapping the while loop in a function implies that z is in the local scope and the global declaration is unnecessary. For example the code below works as expected.
function test_me3(n)
i = 1
while i <= n
println(i)
i += 1
z = 3*i
end
return z
end
I apologise if this issue is trivial. Any help is really appreciated. Thanks.
Just put a local z or alternatively a z = 0 before your while loop such that z is defined in the loop.
For more on this check out the scoping page of the Julia documentation and the local keyword docstring.
See also this question/answer: In Julia, is there a way to pass a variable from a local scope to the enclosing local scope?
I am a novice trying to learn python from Automate The Boring Stuff with Python by Al Sweigart and I came across his block of code to answer a math problem: "What is the sum of all the numbers from 0 to 100?" Apparently, this was a question Gauss got when his teacher wanted to keep him busy.
Sweigart used a for loop and range() function to get the answer:
total = 0
for num in range(101):
total=total+num
print(total)
A page later he states that "you can actually use a while loop to do the same thing as a for loop; for loops are more concise."
How would this statement be rendered in a while loop?
I tried replacing the for with while but got an error: "name 'num' is not defined." I also tried to set up a summation math equation using another block of code from another forum, but completely got lost.
print('Gauss was presented with a math problem: add up all the numbers from 0 to 100. What was the total?')
a=[1,2,3,4,5,...,100]
i=0
while i< len(a)-1:
result=(a[i]+a[i+1])/2
print(result)
i +=1
Then, I tried to setup i in an equation that would loop until each number was added, but got stuck.
print('Gauss was presented with a math problem: add up all the numbers from 0 to 100. What was the total?')
i=0
while i<101:
i=i+1
a=i
Would the while statement be too complex to warrant the effort?
Your last example comes close.
A for loop of this form:
for x in range(N):
# ...
can be replaced by a while loop like this:
x = 0
while x < N:
# ...
x += 1 # equivalent to x = x + 1
Just make sure you leave the rest of the code unchanged!
The for loop is more concise. Notice how we need a "counter" variable , in this case i with the while loop. That's not to say we don't need them in a for loop, however they're integrated nicely into the syntax to make for cleaner code.
i = 0
total = 0
while i < 101:
total += i
i += 1
print(total)
Python's for loop syntax is also a foreach equivalent:
for eachItem in list:
# Do something