Lab: a receipt printer
Put the whole section together and build a program that prints a neat shop receipt, with line totals, tax, a discount and a grand total, then take the section quiz.

In this lesson you will
- Plan a small program before writing it
- Store prices and quantities in well-named variables
- Calculate subtotal, tax and total with correct rounding
- Print an aligned receipt with f-strings
- Test a program by changing its inputs and checking the output
Time to build something real. In this lab you’ll write a program that prints a receipt for a small café order, the kind of slip you get after buying a coffee. It uses everything from this section: values and types, variables, arithmetic, strings, f-strings and comments. Work through the steps in order; each cell builds on the one before, so run them top to bottom.
Step 0: plan first
Programmers rarely start by typing. They start by describing what they want. Here’s the receipt we’re aiming for:
==== THE BYTE CAFE ====
Latte 2 x 3.80
Muffin 1 x 2.95
Juice 3 x 2.10
-----------------------
Subtotal 16.85
Tax (8%) 1.35
TOTAL 18.20
=======================
Thank you, come again!
Look at it and list the values the program needs (item names, prices, quantities, the tax rate) and the calculations (each line’s cost, the subtotal, the tax, the total). That list is your plan. Writing it down first saves lots of confused typing later.
Step 1: the order, as variables
A real till would get the order from a touch screen. We don’t have one, so the order lives in variables at the top of the program, where it’s easy to change. Notice the names: you can tell what each one means without a comment.
# The order
item1_name = "Latte"
item1_price = 3.80
item1_qty = 2
item2_name = "Muffin"
item2_price = 2.95
item2_qty = 1
item3_name = "Juice"
item3_price = 2.10
item3_qty = 3
tax_rate = 0.08 # 8 percent
print("Order loaded:", item1_name, item2_name, item3_name)In the section on collections you’ll learn to keep a whole list of items in one variable. For now, numbered names do the job.
Step 2: the arithmetic
Each line costs price times quantity. The subtotal is the sum of the lines. The tax is the subtotal times the rate. Predict the subtotal before you run: 2 lattes, 1 muffin, 3 juices.
line1 = item1_price * item1_qty
line2 = item2_price * item2_qty
line3 = item3_price * item3_qty
subtotal = line1 + line2 + line3
tax = round(subtotal * tax_rate, 2)
total = round(subtotal + tax, 2)
print(subtotal, tax, total)Did you get 16.85? Depending on the numbers you might see something like 16.849999999999998
instead. That’s the floating-point wobble from the arithmetic lesson, and it’s why we round the
tax and total. We’ll also format everything to two decimal places when we print.
Step 3: lining things up
A receipt looks tidy because its columns line up. f-strings can pad a value to a fixed
width. After the colon, < means “line up on the left”, > means “line up on the right”, and the
number is the width in characters:
print(f"[{'Tea':<10}]")
print(f"[{'Tea':>10}]")
print(f"[{3.5:>8.2f}]")The square brackets are just there so you can see the padding. :>8.2f combines both ideas: a
number with two decimals, right-aligned in 8 characters. That’s exactly what a price column needs.
Step 4: print the receipt
Now put it together. Each item line pads the name to 12 characters, then shows quantity and price. The totals pad their labels to 15 characters and right-align the amount in 8.
width = 23
print(" THE BYTE CAFE ".center(width, "="))
print(f"{item1_name:<12}{item1_qty:>3} x {item1_price:.2f}")
print(f"{item2_name:<12}{item2_qty:>3} x {item2_price:.2f}")
print(f"{item3_name:<12}{item3_qty:>3} x {item3_price:.2f}")
print("-" * width)
print(f"{'Subtotal':<15}{subtotal:>8.2f}")
print(f"{'Tax (8%)':<15}{tax:>8.2f}")
print(f"{'TOTAL':<15}{total:>8.2f}")
print("=" * width)
print("Thank you, come again!").center(width, "=") is a string method that pads a string on both sides to centre it, using
= as the padding. Compare the output with the plan in step 0.
Step 5: test it by changing the inputs
A program you’ve only run once isn’t tested. Go back to step 1 and change the order: make it 5 lattes, or change the muffin’s price to 3.25. Then run steps 1, 2 and 4 again. Check the total with a calculator. Do the columns still line up when a quantity has two digits?
Try one edge case on purpose: set a quantity to 0. Does the receipt still make sense?
Step 6: add a discount
Shops love loyalty discounts. Add a 10% discount that comes off the subtotal before tax. Here’s one way. Read it first, predict the new total, then run it:
discount_rate = 0.10
discount = round(subtotal * discount_rate, 2)
after_discount = subtotal - discount
tax = round(after_discount * tax_rate, 2)
total = round(after_discount + tax, 2)
print(f"{'Subtotal':<15}{subtotal:>8.2f}")
print(f"{'Discount':<15}{-discount:>8.2f}")
print(f"{'Tax (8%)':<15}{tax:>8.2f}")
print(f"{'TOTAL':<15}{total:>8.2f}")Would the total be different if the discount came off after tax? Work it out on paper, then change the code to check. (For a percentage discount and a percentage tax the answer might surprise you, apart from tiny rounding differences.)
Your turn: the checked version
Now write the calculation part yourself, for a different order. The checker looks at your variables, so name them exactly as the exercise asks.
Exercise · Python
Receipt calculator
Solved ✓A customer buys 3 bagels at 2.25 each and 2 coffees at 3.40 each. Sales tax is 8%. Using the variables provided, create:
subtotal: the cost before tax,tax: 8% of the subtotal, rounded to 2 decimal places,total: subtotal plus tax, rounded to 2 decimal places.
Use the variables in your calculations instead of typing the numbers again, so the receipt would
still be right if the order changed. Finish by printing the total formatted with two decimals,
like Total: 11.98.
bagel_price = 2.25
bagel_qty = 3
coffee_price = 3.40
coffee_qty = 2
tax_rate = 0.08
subtotal = 0
tax = 0
total = 0
Section quiz
Ten questions covering the whole section. Take your time; each answer explains itself.
Self-check · 10 questions