Reputation: 581
I have a simple function, which I do like to call and return some values. Inside that function there is a if, elif and else statement, purpose is when if condition is met, return some values, it is when if and elif are not fulfilled, run and display what ever is under else statement. I have used a widget alert to flag and state the problem.
The problem is:
1- When the function calls, it returns just what ever is under else. despite the if statement is fulfilled.
2- Remove all codelines under else, just run if and elif, return some value if the conditions are met, otherwise returns TypeError: 'NoneType' object is not iterable
.
The code:
from PyQt5 import QtCore, QtWidgets, QtGui
def fun( x, y, z):
X = x
Y = y
Z = z
for i in range(0,Z):
R = i * X/Y
if R == 10:
return R, i
elif 10 < R <= 45:
return R, i
else:
print('Error')
app = QtWidgets.QApplication([])
error_dialog = QtWidgets.QErrorMessage()
error_dialog.showMessage('Error!! change values')
app.exec_()
return R, i
Using these values to fulfill conditions.
result, prod = fun(10, 60, 100)
result, prod = fun(105, 60, 100)
result, prod = fun(10, 600, 100)
Input with else statement:
result, prod = fun(10, 60, 100)
print( result, prod)
Output with else statement:
Error window shows up
Error
0.0 0
Input without else statement:
result, prod = fun(10, 60, 100)
print( result, prod)
Output without else statement:
10.0 60
I want to keep the statements and return values as it is desired. Thanks for your help
Upvotes: 1
Views: 6351
Reputation: 13636
Try
def fun( x, y, z):
X = x
Y = y
Z = z
R, i = 0, 0 # <- if Z<1 you will not enter the loop at all, and your original function will not return anything.
for i in range(0,Z):
R = i * X/Y
if R == 10:
return R, i
elif 10 < R <= 45:
return R, i
print('Error')
app = QtWidgets.QApplication([])
error_dialog = QtWidgets.QErrorMessage()
error_dialog.showMessage('Error!! change values')
app.exec_()
return R, i
Your else
statement should be applied to for
, and not to if
. You intention is to run over all possible values in the loop, and if the condition is not met on all possible values in the loop, only then raise an error.
By the way, it is not a good style to place all returns
inside ifs
. This way you can overlook some rare cases and get an undesired behavior. This is exactly why you get TypeError: 'NoneType' object is not iterable
. You expect to get a tuple from the function, but receive nothing, as the program exits the function without returning a value at all.
Upvotes: 2
Reputation: 1316
I see the problem here, thanks to Tim B, Though he did not add how to fix it. So your if
statements are working fine. Just what is happening here is that you are having a return
statement at the end of all the if elif else
. So for the very first run with i = 0, R = 0
and it will go to else and return a value. WHEN that happens the for loop stops executing. So basically all your code is just running one time with R = 0 values.
What you probably want to do is remove the return
statement from else
clause. Or instead of returning the result save the results in two list or arrays. I hope this help you solve the issue.
def fun( x, y, z):
X = x
Y = y
Z = z
results = []
related_indexes = []
R = i * X/Y
print(R)
if R == 10:
return R, i
elif 10 < R <= 45:
return R, i
else:
print('Error')
#app = QtWidgets.QApplication([])
#error_dialog = QtWidgets.QErrorMessage()
#error_dialog.showMessage('Error!! change values')
#app.exec_()
return R, i
x,y,z = (10, 60, 100)
for i in range(0,z):
result,prod = fun(x,y,z)
print(result, prod)
Upvotes: 1