Reputation: 85
I would expect this to be a duplicate question, yet I couldn't find an answer. I'm sorry.
I have written a simple function that's supposed to return either an empty string or a string of one character. Sometimes, however, it returns None. Even though it should match one of the operands and, in case it doesn't, still output a string.
baseconvert = digits+ascii_lowercase+"0"
def checker(operand, factorlist): # hardcoded interpreter of the calculus converted in base 10. i is equal to the base.
if (operand == '+'):
if (factorlist[0] + factorlist[1] == factorlist[2]):
return baseconvert[i]
elif (operand == '-'):
if (factorlist[0] - factorlist[1] == factorlist[2]):
return baseconvert[i]
elif (operand == '*'):
if (factorlist[0] * factorlist[1] == factorlist[2]):
return baseconvert[i]
elif (operand == '/'):
if (factorlist[0] / factorlist[1] == factorlist[2]):
return baseconvert[i]
else:
return ""
So while typing this post I figured out I could just remove the else statement:
# else: is not necessary
return ""
works fine. I still wonder, however, why this else statement is never triggered.
P.S.: Is there a cleaner way to just interpret the string, for example "10 - 7 = 3" to get a boolean result? I'm relatively new to python and couldn't come up with anything.
The following code, with parameters taken out of context, prints None:
from string import digits, ascii_lowercase
baseconvert = digits+ascii_lowercase+"0"
def checker(operand, factorlist): # hardcoded interpreter of the calculus converted in base 10. i is equal to the base.
if (operand == '+'):
if (factorlist[0] + factorlist[1] == factorlist[2]):
return baseconvert[i]
elif (operand == '-'):
if (factorlist[0] - factorlist[1] == factorlist[2]):
return baseconvert[i]
elif (operand == '*'):
if (factorlist[0] * factorlist[1] == factorlist[2]):
return baseconvert[i]
elif (operand == '/'):
if (factorlist[0] / factorlist[1] == factorlist[2]):
return baseconvert[i]
else:
return ""
i=17
print(checker('+', [1987,222,2227]))
What was expected:
if (operand == "+")
is True.if (factorlist[0] + factorlist[1] == factorlist[2])
is False.else:
on line 15 is called.I still wonder why this behavior I expected isn't shown, but no matter. Using just one return statement as well as leaving the else:
away are great solutions.
I also found the following works, which is closest to what I was trying to accomplish:
def checker(operand, factorlist): # hardcoded interpreter of the calculus converted in base 10. i is equal to the base.
if ((operand == '+') & (factorlist[0] + factorlist[1] == factorlist[2])):
return baseconvert[i]
elif ((operand == '-') & (factorlist[0] - factorlist[1] == factorlist[2])):
return baseconvert[i]
elif ((operand == '*') & (factorlist[0] * factorlist[1] == factorlist[2])):
return baseconvert[i]
elif ((operand == '/') & (factorlist[0] / factorlist[1] == factorlist[2])):
return baseconvert[i]
else:
return ""
I've timed all solutions multiple times, and this final solution seems to be about 15% faster than having split if statements and using a variable with one return.
Upvotes: 0
Views: 378
Reputation: 44344
It is subjective, but many will say only have one return
in a function. In this case that can help. The problem is that you only return from each elif
if another condition is True. It can be refactored by something like this:
baseconvert = digits+ascii_lowercase+"0"
def checker(operand, factorlist):
# hardcoded interpreter of the calculus converted in base 10. i is equal to the base.
final_value = ""
if operand == '+':
if factorlist[0] + factorlist[1] == factorlist[2]:
final_value = baseconvert[i]
elif operand == '-':
if factorlist[0] - factorlist[1] == factorlist[2]:
final_value = baseconvert[i]
elif operand == '*':
if factorlist[0] * factorlist[1] == factorlist[2]:
final_value = baseconvert[i]
elif operand == '/':
if factorlist[0] / factorlist[1] == factorlist[2]:
final_value = baseconvert[i]
return final_value
Note that you only need parentheses around a condition in python for precedence, most of the time they are not required.
Upvotes: 0
Reputation: 78536
You have if
clauses nested in your parent if...elif
, when control does not flow out of those, it does not return to the parent else
(i.e. if the function is not exited via any of the nested ifs, execution completes at the end of the function). You should add a return at the end of your function to properly handle this and avoid returning the default None
:
def checker(operand, factorlist):
if operand == '+':
if (factorlist[0] + factorlist[1] == factorlist[2]):
...
elif operand == '-':
if (factorlist[0] - factorlist[1] == factorlist[2]):
...
elif operand == '*':
if (factorlist[0] * factorlist[1] == factorlist[2]):
...
elif operand == '/':
if (factorlist[0] / factorlist[1] == factorlist[2]):
...
return ""
You can also safely remove the final else
since the final return acts as a global return default in your function.
Upvotes: 2