Full path: think, build, test, rebuild
Let's create a new function from scratch to see the whole process in one go.
Writing a function is never the goal. You write a function because you need to solve a problem repeatedly. So, it all starts with the problem, the task. Often, it comes from your client, a colleague or the manager. Let's say, you work for a retail company, and one day the boss says:
We need an app to calculate the billable amount for our invoices. The amount is based on three things: price of the item, quantity and a flat delivery fee. The formula is: amount = price × quantity + fee
Alright! It's a good fit for a Python function. To create a function, you have to make three decisions:
- How to name it.
- What comes in.
- What comes out.
1. How to name it
We've talked about technical aspects of naming a function previously. You know what symbols and words are and aren't allowed. But the semantic aspect of naming a function is far more important. For the interpreter it doesn't matter, it couldn't care less. But code is for people first, so you should give functions meaningful names. Names should reflect the purpose, the goal.
In our case the goal is to determine the billable amount. So, maybe, amount
seems like a good option, but, alas, it's not great. It's a motionless noun. Functions perform actions, so it's better to give them verb names. get_amount
or calc_amount
(short for "calculate") is preferred. Let's pick the former and start the definition:
def get_amount(
2. What comes in
The amount is based on three things: price of the item, quantity and flat delivery fee. Therefore, three numbers should "come into" your function:
- Price
- Quantity
- Fee
These are going to be parameters, and we need names for them. Parameters are labels for values, so use nouns. Let's call them price
, quantity
and fee
and continue building the definition:
def get_amount(price, quantity, fee):
3. What comes out
The goal of the function is to produce the answer: billable amount. While we haven't done anything to actually calculate it yet, we can just pretend that we did and write the final line of the function. It's like writing the ending of a story before writing the story.
The purpose of the function is to produce — return
— the amount:
def get_amount(price, quantity, fee):
return amount
Now we have a complete skeleton of the function. It's got a name, parameters and the final return
statement. All what's left is to actually calculate the value of amount
according to the formula given by the boss:
def get_amount(price, quantity, fee):
amount = price * quantity + fee
return amount
Calling it
Great! It's time to test if it works:
print(get_amount(100, 5, 21)) # →◼ 521
print(get_amount(121, 3, 19)) # →◼ 382
print(get_amount(227, 6, 4)) # →◼ 1366
Alternative implementations
You've seen that return
can process any value or any expression, and we don't have to create a variable in order to return a value. Here's an alternative implementation of get_amount
:
def get_amount(price, quantity, fee):
return price * quantity + fee
Or we could go the other way and expand the implementation:
def get_amount(price, quantity, fee):
cost = price * quantity
amount = cost + fee
return amount
Either way, the function behaves the same way, and for the caller it doesn't make a difference. There are always multiple ways to implement a function. The primary parts are always the same: the def
keyword, the parentheses, indentation. But the actual code in the body is decided by the programmer. The amount of arguments depends on the task, though. Sometimes the task is vague, so the programmer has to decide on the amount of arguments. Sometimes the task is strict and the amount of arguments is a part of the task.
Without return?
There are a few cases when you may define functions without return
:
- To print something onto the screen: put
print
inside the function and make the call. - To use some magic stuff for adding new values to or removing values from a group of objects (we'll discuss this in the next course).
- The task at hand requires the function to return
None
. - By mistake (you forgot to add
return
to function's body; remember — a function withoutreturn
will returnNone
)
If None
is required to be returned, you may omit return
completely, but we recommend explicitly writing return None
.