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.
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.
calc_amount (short for "calculate") is preferred. Let's pick the former and start the definition:
The amount is based on three things: price of the item, quantity and flat delivery fee. Therefore, three numbers should "come into" your function:
These are going to be parameters, and we need names for them. Parameters are labels for values, so use nouns. Let's call them
fee and continue building the definition:
def get_amount(price, quantity, fee):
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
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
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
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.
There are a few cases when you may define functions without
- To print something onto the screen: put
- 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
- By mistake (you forgot to add
returnto function's body; remember — a function without
None is required to be returned, you may omit
return completely, but we recommend explicitly writing