Calling and Storing
Concepts covered: Functions
An Uber Eats order passes through 3 pricing steps: the items are multiplied out, tax is added to that subtotal, and a delivery fee is added to the taxed amount. Each step is a function, and the result of one is the argument of the next. The program runs the chain twice, once storing every intermediate value and once nesting the calls:
def subtotal_cents(qty, unit_cents):
return qty * unit_cents
def with_tax(cents):
return cents + cents * 8 // 100
def with_delivery(cents):
return cents + 499
order = subtotal_cents(3, 1299)
print(order)
taxed = with_tax(order)
print(taxed)
print(with_delivery(taxed))
print(with_delivery(with_tax(subtotal_cents(3, 1299))))Output:
3897 4208 4707 4707
Both routes reach 4707. In the nested call, Python evaluates the innermost call first, because the outer calls need its result as their argument:
| Step | Expression being evaluated | Value |
|---|---|---|
| 1 | subtotal_cents(3, 1299) | 3897 |
| 2 | with_tax(3897) | 4208 |
| 3 | with_delivery(4208) | 4707 |
| 4 | print(4707) | prints 4707 |
Reading a nested call means reading from the inside out, the opposite of left to right. Watch the 2 versions run one after the other and note that the chained line produces the same 4707 without ever naming order or taxed:
def subtotal_cents(qty, unit_cents):
return qty * unit_cents
def with_tax(cents):
return cents + cents * 8 // 100
def with_delivery(cents):
return cents + 499
order = subtotal_cents(3, 1299)
taxed = with_tax(order)
total = with_delivery(taxed)
print("Step by step:", total)
chained = with_delivery(with_tax(subtotal_cents(3, 1299)))
print("Chained:", chained)Step by step: 4707 Chained: 4707
A function can call another function
A call can sit inside another function's body as well as at the top level of the program. A body can call any function that has been defined by the time the body runs, which lets one function wrap the whole chain:
def with_tax(cents):
return cents + cents * 8 // 100
def order_total(qty, unit_cents):
taxed = with_tax(qty * unit_cents)
return taxed + 499
print(order_total(3, 1299))
print(order_total(1, 899))Output:
4707 1469
order_total calls with_tax in its own body, waits for the answer, then adds the delivery fee. The second order, 1 item at 899 cents, pays 71 cents of tax (8 percent of 899, rounded down by //) and 499 for delivery.
Calls inside loops and conditions
A returned value is at home anywhere an expression is: added to a running total inside a loop, or compared against a limit in an if. The loop below prices 3 trips of growing length, each lasting 4 minutes per mile, and keeps the sum:
def fare_cents(miles, minutes):
return 250 + miles * 175 + minutes * 35
total = 0
for miles in range(1, 4):
total = total + fare_cents(miles, miles * 4)
print("After", miles, "miles:", total)
print("All trips:", total)Output:
After 1 miles: 565 After 2 miles: 1445 After 3 miles: 2640 All trips: 2640
On each pass the call receives the loop's miles and 4 times that for minutes; the 3 fares are 565, 880 and 1195. A call in a condition works the same way: if fare_cents(8, 25) > 2000: computes 2525 first, and only then does the comparison choose the branch.
In what order do the 3 functions run, and what is printed?
def double(n):
return n * 2
def add_one(n):
return n + 1
def square(n):
return n * n
print(double(add_one(square(3))))- double, add_one, square, printing 20
- double, add_one, square, printing 49
- square, add_one, double, printing 20
- square, add_one, double, printing 19
To write a nested call yourself, list the steps in the order they must happen, then build the line from the inside out: the first step is the innermost call, and each later step wraps the one before it. In the question above, squaring came first, so square(3) sat at the center and double wrapped everything else.
About this lesson
This section is part of the Functions: Beginner lesson on DataDriven, the home of data engineering. Lessons cover SQL, Python, Spark, data modeling and pipeline architecture, and each section pairs its explanation with worked examples and practice you run as you go.