I am writing a simple piece of code. Its a function that allowed the user to withdraw some money. There are some restrictions to this though.
- The user can’t withdraw more than the given withdraw limit.
- The user cannot withdraw more money they that have.
The script will terminate if this happens, and let the users know. Otherwise they user can withdraw the money and the balance updates, they also get a confirmation message.
Now my question is should I return False
if they hit either case 1 or 2? And should I return True
if the transactions completes successfully?
I do not have any current plans where I will need the booleans from the function call. But I wonder is it good coding practice to return something in a case like where the function could take different paths.
Some example code (Python):
limit = 500
balance = 5000
def withdraw_money(amount):
if amount > limit: # above the limt
print('You cannot withdraw more than ${}'.format(balance))
return False
elif amount > balance: # not enough money
print('Insuffecient funds')
return False
else: # actually worked
balance -= amount
print('Your new balance is ${}'.format(balance))
return True
There is no standard convention as far as returning booleans from functions. If the function returns true or false, it is up to you, the author of that function, to determine what the meaning of each value is and how the caller should react to each one.
However, one thing I would strongly recommend is that your function should ONLY return a boolean if you expect the caller to look at the result and act accordingly as part of normal workflow (in other words, False is no more a failure than True is).
On the other hand if your intention is to return a boolean as a way of indicating whether or not the function call succeeded, there’s a convention for that. Do not return anything in that case. Instead, if the caller calls your function and your function returns, that would be considered a success. If anything within your function fails, just raise an exception.
The benefits of doing it this way is that you don’t have to write code that looks like this:
if not withdraw_money():
.... handle error ....
return
if not do_something():
... handle error ...
return
if not do_something_else():
... handle error
return
Instead, you’d be able to write:
try:
withdraw_money()
do_something()
do_something_else()
except:
... handle all errors in one place ...
So now your actual logic isn’t intermingled with error handling. And if you use exception handling throughout your application, a lot of times you’ll be able to define try-except block at a higher level and all function calls from that point down can just focus on implementation of the actual feature, not checking for success/failure at every single step.
The other benefit is that your failure conditions are much more expressive. If the caller gets back “False” he knows something failed, but it could be just about anything. If a caller gets back InsufficientFundsError() as the exception type, he knows much more about what error condition caused the problem.
Update:
As Robert Harvey pointed out, the use of exceptions is somewhat of a controversial in the developer community and in different programming languages the use of exceptions will vary. I am gearing this answer towards python because that’s is what OP is learning.
Even in python, you will get arguments that exceptions should only be for truly exceptional situations but then you get a very subjective territory as to what is considered truly exceptional. Clearly if a RAM chip flips a bit due to hardware error, that’s an exceptional condition. What about missing config file?
So a lot of this will come down to your personal programming style and this answer definitely reflects mine, so read it with a grain of salt. Just like Robert’s example with python dictionary “that is required to return a valid object (as in a dictionary lookup)” I tend to write most of my code such that if a function returns a value, I require it to return a value. I don’t have to, but that’s my choice in how I define the signature of that function and how I intend for it to be used.
If you are new to programming, I’d definitely recommend for you to try different things and alter how you structure code just so you can see for yourself which constructs/conventions work better and make the most sense for you.
8