Why am I getting a "Referenced before assignment" error? [duplicate] - python

This question already has answers here:
How can a name be "unbound" in Python? What code can cause an `UnboundLocalError`?
(3 answers)
Closed last year.
This Python program will determine whether the input array is a mountain array or not. I've found answers on stackoverflow for this same error in other programs I've made, but not this one. It seems to work without issue when a valid mountain array is the input, but I'm having issues when I change the first half of the test array to make it an invalid. Rather than it returning False, which is the goal, I'm getting this error: UnboundLocalError: local variable 'y' referenced before assignment. Also, I was getting the same error for the z variable, so I added the else statements and it fixed it. Can't figure out why it didn't fix the y variable as well. Here's my code:
def validMountainArray(arr):
maxElem = max(arr)
maxIndex = arr.index(maxElem)
if len(arr) < 3:
return False
else:
beginning = arr[:maxIndex]
end = arr[maxIndex + 1:]
for i in range(1, len(beginning) - 1):
if beginning[i + 1] > beginning[i]:
y = True
else:
y = False
for i in range(1, len(end) - 1):
if end[i + 1] < end[i]:
z = True
else:
z = False
if y == True and z == True:
return True
else:
return False

Those for-loops aren't guaranteed to be executed. It's possible that the range could end up with 0 numbers in it, and thus no loop will occur and y and/or z will never be assigned. To fix this, define those variables as False at the start of the function.
def validMountainArray(arr):
y = False
z = False
maxElem = max(arr)
maxIndex = arr.index(maxElem)
# etc

Related

How to check if exactly one of two condition is met [duplicate]

This question already has answers here:
How do you get the logical xor of two variables in Python?
(28 answers)
Closed 2 years ago.
I am checking wether one of two conditions applies and only one.
My question is if there is a way to have a single if statement to do this:
if x == True:
if y == False:
do_something()
elif x == False:
if y == True:
do_something()
Ideally similar to how and and or work so that it would something like:
enter code here
if x == True ° y == True:
do_something()
whereas ° is the wanted operator
do nothing if: x,y = True or x,y = False
do something if: x = True and y = False or x = False and y = True
I would appreciate any advice if this is not possible.
Thank you in advance!!
You need to use the logical operator XOR, but in this scenario, it's the equivalent of just saying
if x != y:
do_something()
As it will only be true if one of the conditions is met.
-- update --
There's also an actual XOR operator
if x ^ y:
do_something()
They will be identical in this example.

My code is working but with no outputs, what is the problem?

What is the problem?
i even tried this at the starting soas to get a output
print("enter list elements")
arr = input()
def AlternateRearr(arr, n):
arr.sort()
v1 = list()
v2 = list()
for i in range(n):
if (arr[i] % 2 == 0):
v1.append(arr[i])
else:
v2.append(arr[i])
index = 0
i = 0
j = 0
Flag = False
#set value to true is first element is even
if (arr[0] % 2 == 0):
Flag = True
#rearranging
while(index < n):
#if 1st elemnt is eevn
if (Flag == True):
arr[index] = v1[i]
index += 1
i+=1
Flag = ~Flag
else:
arr[index] = v2[j]
index +=1
j += 1
Flag = ~Flag
for i in range(n):
print(arr[i], end = "" )
arr = [9, 8, 13, 2, 19, 14]
n = len(arr)
AlternateRearr(arr, n)
print(AlternateRearr(arr))
There's no error.
Just the driver code dosen't work i guess, there's no output.
no outputs
The only place where it could output anything is print(AlternateRearr(arr)). But let's take a look at AlternateRearr itself - what does it return?
There's no return statement anywhere in AlternateRearr, so the print would show None. Well, it's something, not completely nothing...
But the code doesn't reach this part anyway - if it did, it would throw an error because print(AlternateRearr(arr)) passes only one argument to the function AlternateRearr that takes 2 arguments. You don't have default value set for n, so it wouldn't work.
Okay, so we came to conclusion that we don't reach the print anyway. But why? Because you never call it. You only define it and it's a different thing from calling it.
You might encounter a problem if you just try calling it near your normal code - Python is an interpreted language, so your main-level code (not enclosed in functions) should be at the bottom of the file because it doesn't know anything that is below it.
Is that your complete code?
Because you do have a function called AlternateRearr but you never call it
Call the function and also pass the integer for iteration.
Add after the function:
AlternateRearr(arr, 5)

How to avoid using a global variable in this recursion function and improve my code?

I made the next function to solve the problem of rat maze, where the rat only can move to forward and down, and i needed to find the number of ways possibles. I did it but i want to avoid the global variable "possible_ways". What are the way to improve my code ?
possible_ways = 0
def solve(n,x,y):
if x == n-1 and y == n-1:
global possible_ways
possible_ways = possible_ways+1
return True
if x<=n-1 and y<=n-1:
solve(n,x+1,y)
solve(n,x,y+1)
solve(4,0,0)
print(possible_ways)
In this case you can make the function return a value (for all possible code paths in it — your code returned None whenever the first if condition was untrue):
def solve(n,x,y):
if x == n-1 and y == n-1:
return 1
if x <= n-1 and y <= n-1:
return solve(n,x+1,y) + solve(n,x,y+1)
return 0
possible_ways = solve(4,0,0)
print(possible_ways)

How to count repetitions of a recursive function?

So I have this function (example):
def monty(x):
if abs(int(x)) == 1:
print("Cool!")
print("Took %s attempts.") % (z)
elif abs(int(x)) == 0:
print("Nope.")
else:
z = z + 1
y = x - 1
monty(y)
Now, of course, 'z' has not yet been defined, so when this function is run so that the 'else' statement is called, the program returns a NameError exception.
Well, ok. Let's try making the statement this:
else:
try: z
except NameError: z = 0
else: z = z + 1
y = x - 1
monty(y)
Also assume we added the same NameError catch to the 'if' statement.
The statement always returns 'z' as 0, as the variable is utterly forgotten when 'monty' is ran again. Ok, what if we try defining z outside of 'monty' first, and drop the NameError catch?
Well, it returns a NameError again, and if we instead keep the NameError catch, it still only ever outputs 0.
So, how do I make the function increase z every time it's called validly? In other words, how can I have the program silently count how many times a function was run, to be recalled later? Let's try to avoid adding another argument to the function, for the sake of user-friendliness.
Just add z as a keyword argument:
def monty(x, _z=0):
# ...
else:
_z = _z + 1
y = x - 1
monty(y, _z)
I renamed z to _z to indicate that it is an implementation detail the end-user doesn't need to worry about. Because keyword arguments have a default, the caller of monty() doesn't have to worry about it.

New to python and programming in general, need help editing a variable in terms of itself [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
When I put this in it brings up an error and I'd like some help finding out what I did wrong.
x = 0
def func(var):
if var = True:
x = x - 1
else:
pass
The error comes from x = x - 1, and I can't figure out what I'm doing wrong.
In order to use x inside the scope of the function you have to tell the compiler where to find x
so change your code to:
x = 0
def func(var):
if var == True:
global x # look for x outside the scope of the function
x = x - 1
else:
pass
Also it's nice to have a return into functions so I propose:
x = 0
def func(var):
if var == True:
global x # look for x outside the scope of the function
x = x - 1
return None # or -> return x (to return the value of x)
The error is actually from the line before. You are confusing = (assignment operator) with the == (comparison operator). The correct code is as follows:
def func(var):
global x
if var == True:
x -= 1 #also you can simply do it as x -= 1 instead of x = x - 1
else:
pass
Finally, there is really no point in having else: pass since you're not doing anything in there. Just shorten your code to:
def func(var):
global x
if var == True:
x -= 1
First you put an assignment operator = instead of the equals operator ==
x = 0
def func(var):
if var == True:
x = x - 1
else:
pass
Second never check if expressions/values are equal(==) to True /False especially in python. Just give a statement/variable that is True or truthy/False or falsey. In python None(null) empty collections such as [], 0, 0.0, timedelta of zero, and False are falsey and just about everything else is truthy. To test this for yourself just try passing the value or expression to the bool function to see if it returns True or False. See https://docs.python.org/2/library/stdtypes.html#truth-value-testing for more info.
x = 0
def func(var):
if var:
x = x - 1
else:
pass
Third you can lookup but not reassign a variable declared in the same module
outside the function. unless you declare it global. so you can print without global
x = 0
def func(var):
if var:
print x
but not reassign it. Also you don't need a else branch or return statement(python defaults to returning None), so it's just
x = 0
def func(var):
if var:
global x
x = x - 1

Categories