1

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

4
  • "When the function calls, it returns just what ever is under else. despite the if statement is fulfilled." That is not true. What is almost certainly true is that you are mistaken about what your if statement is doing. Commented Dec 5, 2018 at 20:56
  • 1
    Your if statement and elif statements are returning the same values, what is the point of them having there if I may ask? how do you know for sure that your if statement is not being called even when full filled, could you please share such input and output when that happens. Commented Dec 5, 2018 at 20:59
  • I think I got the problem here. I ran your code and found the issue with the else statement. I posted a answer, should help you fix the issue now. Cheers! Commented Dec 5, 2018 at 21:16
  • @FamousJameous You are wrong. Notice the python-3.x tag. Commented Dec 9, 2018 at 11:44

2 Answers 2

2
+50

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot. your solution is a great help for me.
1

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)

4 Comments

Thanks for clarifying the problem and explaining debug of for-loop and if statement. But unfortunately it does not help fixing my problem. There should be a way to run for-loop without jumping at first time and return even values when Error message shows up something like R = xxx and i = 99.
That's impossible to use return like that, Then I would solve your problem like this. How about adding the for loop inside your main body, and call fun inside it. Should solve your problem that way? You can return after each run. i think this is the only option you have now. Let me know if you got the idea
I edited and added the demo answer, do you like it now ? i commented the Qt codes, i don't have them.
I have got the point by rewritning the above code, as you proposed, smart. returns every single run. but that is not how I want it, I am afraid, it does not fit to my exercise. Thanks any way.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.