def calculate_net_price(gross_price: float, vat_rate: float = 8.1) -> float:
"""
Calculates the net price from a given gross price.
Args:
gross_price (float): The total price including VAT.
vat_rate (float): The VAT percentage to be removed.
Defaults to 8.1 (Swiss standard rate).
Returns:
float: The calculated net price, rounded to two decimal places.
"""
# gross = net * (1 + VAT/100) -> net = gross / (1 + VAT/100)
gross_factor = 1 + (vat_rate / 100)
net_price = gross_price / gross_factor
return round(net_price, 2)
# --- Using the "Black Box" ---
# Case A: Standard rate (8.1% is used automatically)
standard_total = calculate_net_price(100.0)
print(f"Standard Net Price: {standard_total} CHF")
# Case B: Reduced rate for everyday goods (2.6%)
reduced_total = calculate_net_price(100.0, 2.6)
print(f"Reduced Net Price: {reduced_total} CHF")20 Functions: Revision and Consolidation
20.1 Function: A Definition
A function is a self-contained block of code that encapsulates specific logic. By using parameters and return values, it acts as a ‘black box’ that processes inputs into outputs.
Let’s break this definition down into its core components to understand how a function actually works:
“Self-contained block”
A function is like a “mini-program” within the main program. It has its own name and its own scope. This means that variables defined inside a function usually don’t interfere with the rest of the code. It promotes modular design, making the code organised and easier to read and to debug.
“Encapsulates specific logic”
Encapsulation means “wrapping things up.” There is no need to know how the function actually works to use it. It is sufficient to know what parameters it takes and what values it returns. This is the first step toward abstraction.
“Parameters” (The Inputs)
Parameters are the “knobs” or “settings” of a function. They allow for passing information into the function. Without parameters, a function would do exactly the same thing every time. With parameters, it becomes flexible and can handle different inputs each time it is called.
“Return Values” (The Outputs)
A function doesn’t just “do” something; it often “gives” something back. The
returnstatement is the exit point of the function, handing a result back to the part of the program that called it.The “Black Box” Concept
This is a key concept in computer science. The user provides an input, the “black box” (the function) performs its processing logic, and it produces an output. The user of a function only cares about the interface (Inputs/Outputs), not the implementation.
20.2 Practical Example: The VAT Calculator
In this example, we calculate the net price from a given gross price. In Swiss retail, prices are usually quoted as gross — i.e., including VAT. The net price is what remains after the VAT portion is removed. Since the standard VAT rate in Switzerland is 8.1 %, we use this as a default parameter. This makes the function easier to use for standard cases while remaining flexible for others.
Type Hints (
: floatand-> float): These document for the programmer (and the IDE) that the function expects decimal numbers and will return a decimal number. They are like labels on the “knobs” of our black box. Note: Python does not enforce Type Hints at runtime — they serve documentation and tooling, not validation.The Docstring (
""" ... """): This is the manual for the black box. It explains what the function does, what the arguments (Args) represent, and what the function Returns. In professional IDEs, this text pops up when you hover over the function name. The format used here is the Google style for docstrings.Default Parameter (
vat_rate: float = 8.1): By assigning a value in the signature, we make this input optional. If the user doesn’t provide a rate, Python automatically uses 8.1.
How this illustrates our five points:
Modularity & Scope: The variables gross_factor and net_price only exist inside the function. Your main program stays “clean” and doesn’t get cluttered with temporary calculation variables.
Encapsulation: The mathematical formula (dividing by the factor rather than just subtracting a percentage) is hidden. The user doesn’t need to be a maths expert; they just need to call the function.
Default Parameters: By setting vat_rate=8.1, we’ve made the function smarter. It assumes the most common case but allows the user to override it for special cases like hotels or groceries.
The Interface: The “interface” here is simply calculate_net_price(gross_price, vat_rate). As long as you know this signature, you can use the tool without ever looking at the code inside the function again.
20.3 Coding Exercise: The BMI Calculator
20.3.1 Objective
Apply your knowledge of functions, encapsulation, and documentation by creating a tool to calculate the Body Mass Index (BMI).
20.3.2 The Task
Write a Python function named calculate_bmi that takes a person’s weight and height as inputs and returns their BMI. Remember the “Black Box” principle: the user should only need to provide the numbers; your function handles the maths.
20.3.3 The Formula
The BMI is calculated by dividing a person’s weight in kilograms by the square of their height in metres:
\[ BMI = \frac{\text{weight (kg)}}{\text{height (m)}^2} \]
20.3.4 Requirements
- Function Signature: Use Type Hints to specify that both inputs and the return value are floats.
- Docstring: Include a complete Docstring at the beginning of the function. Use the Google style (with the sections
Args:andReturns:) as shown in the previous example. Write the prose in British English spelling (e.g., “metres”, “organised”). - Encapsulation: The internal calculation should be performed within the function, and the result should be returned rounded to two decimal places.
- Testing: Call your function at the end of your script to calculate the BMI for a person who weighs 80 kg and is 1.85 m tall.
20.3.5 Exercise Template:
# Define the signature: which parameters with which Type Hints?
# What is the return type?
def calculate_bmi(...) -> ...:
"""
[Write a brief description of the function here]
Args:
[List the arguments here]
Returns:
[Describe the return value here]
"""
# 1. Implementation: Calculate the BMI using the formula
# 2. Return Value: Return the result rounded to 2 decimal places
pass
# --- Test your "Black Box" ---
# 1. Call the function with 80.0 and 1.85
# 2. Print the result with an appropriate messageModel Implementation calculate_bmi()
def calculate_bmi(weight: float, height: float) -> float:
"""
Calculates the body mass index of a person from the person's weight
and height.
Args:
weight (float): The person's weight in kilogram.
height (float): The person's height in metres.
Returns:
float: The person's BMI, rounded to two decimal places.
"""
# 1. logic -> implementing the bmi formula
bmi = weight / (height ** 2)
# 2. formatting -> round the return value to 2 decimals
return round(bmi, 2)
print(calculate_bmi(80.0, 1.85))20.3.6 Success Criteria
- The function returns
23.37for a weight of 80 kg and a height of 1.85 m. - The Docstring clearly explains what the parameters represent.
- The calculation logic is entirely contained within the function (Encapsulation).
- The function uses the
returnstatement correctly rather than just printing the result inside the function.
20.3.7 Optional Extension: A Classifier Function
The BMI is a rough indicator and has well-known limitations (it ignores muscle mass and body composition). As a follow-up exercise, write a second function classify_bmi(bmi: float) -> str that returns a category according to the WHO scale (e.g. underweight, normal, overweight, obese).
This is the natural bridge to the next topic — conditional statements (if / elif / else) — and it also lets you practice function composition:
20.4 Coding Exercise: The Cuboid Space Diagonal
20.4.1 Objective
Create a geometry tool that calculates the space diagonal (the longest internal line) of a cuboid. This exercise will help you practice handling multiple parameters and using Python’s mathematical libraries.
20.4.2 The Task
Write a Python function named calculate_space_diagonal that accepts the three edge lengths of a cuboid and returns the length of the space diagonal.
20.4.3 The Formula
To find the space diagonal (\(d\)) of a cuboid with edge lengths \(a\), \(b\), and \(c\), we use the 3D version of Pythagoras’ Theorem:
\[ d = \sqrt{a^2 + b^2 + c^2} \]
20.4.4 Requirements
- Module Import: You will need the
sqrtfunction from Python’smathmodule. Afterimport math, the callmath.sqrt(x)calculates the square root of afloat. - Function Signature: Use Type Hints to ensure all three inputs and the return value are floats.
- Docstring: Write a professional Docstring in the Google style (sections
Args:andReturns:), using British English spelling (e.g., “metres”, “calculated”). - Encapsulation: The user should not have to worry about the square root or the squaring of numbers; the “Black Box” handles the maths internally.
- Testing: Test your function with a cuboid that has the dimensions \(a = 5.0\), \(b = 10.0\), and \(c = 2.0\).
Tip: You can square a number with x ** 2 (or x * x). The square root requires math.sqrt(x) after import math.
Model Implementation calculate_space_diagonal()
import math
def calculate_space_diagonal(a: float, b: float, c: float) -> float:
"""
Calculates the space diagonal of a cuboid from the edge lengths.
Args:
a (float): Length of the first edge.
b (float): Length of the second edge.
c (float): Length of the third edge.
The function works independently of the actual units as long as
all edges are provided in the same unit.
Returns:
float: The calculated space diagonal of a cuboid in the same
unit as the input.
"""
d = math.sqrt(a**2 + b**2 + c**2)
return d
calculate_space_diagonal(5.0, 10.0, 2.0)