Skip to content
wannacode

Doing math

Problem

The bill at the table

You ordered three coffees at €2.50 and two croissants at €1.50. You pay with a €20 bill. How much is the bill, and how much change should you get?

You can do it in your head. But the register at the café does this math hundreds of times a day, with different prices and quantities. The program has to do the math by itself.

The idea

The arithmetic operators

You do math the way you would on paper: + adds, - subtracts, * multiplies, / divides. These signs are called operators.

coffee = 2.5
croissant = 1.5
total = 3 * coffee + 2 * croissant
change = 20 - total
print(f"Total: €{total}")
print(f"Change: €{change}")
Output
Total: €10.5
Change: €9.5

The order is the same as in math: first * and /, then + and -. That is why 3 * coffee + 2 * croissant is 7.5 + 3. If you want a different order, you add parentheses: (2 + 3) * 4 is 20.

There is a fifth operator too, %. The next idea is about it.

More precisely, if you are curious
  • Operators with the same precedence are evaluated left to right: 20 - 5 - 3 is 12, not 18.
  • - in front of a number makes it negative: -total.
  • With text, + does not add, it glues, but only text to text. Text + a number stops the program. That is the trap in the next card.

Try it

Concert tickets

Three tickets at €8 and a €5 order fee.

What will the program print?

tickets = 3
fee = 5
print("Total: " + tickets * 8 + fee)
Answer

Problem

2.25 hours instead of 2 h 15 min

The movie is 135 minutes long. You want to show it as hours and minutes: 2 h 15 min. The first try:

minutes = 135
hours = minutes / 60
print(f"{hours} h")
Output
2.25 h

In Python, / always gives a decimal result, even when both numbers are whole: 6 / 3 is 2.0, and 17 / 3 is 5.666666666666667. But here you need two whole hours and the minutes that are left. How do you get only the whole part?

The idea

Integer division: // and %

// divides and keeps only the whole part: 135 // 60 is 2, and 17 // 3 is 5. The decimal part is cut off. This is called integer division.

Here it is step by step, with the sum of three grades:

math = 5
physics = 6
english = 6
whole = (math + physics + english) // 3
print(f"Whole part: {whole}")
Step by step, in words
  1. Three grades, each in an int: 5, 6, 6.
  2. First the parentheses: 5 + 6 + 6 = 17. The sum is an int too.
  3. 17 // 3: how many whole groups of 3 are in 17? 5.
  4. The remainder 2 (that is 17 % 3) is cut off. The result is the whole number 5.
  5. 5 is stored in whole. The result of // on whole numbers is an int, with no .0.
  6. It prints "Whole part: 5". The decimal part (5.67) is not in the result: that is what / is for.

What is cut off is not completely lost. The % operator gives the remainder of the division: 17 % 3 is 2, because 17 = 5 · 3 + 2.

Together the two split an amount into whole parts and a remainder. The movie is 135 minutes:

minutes = 135
hours = minutes // 60
rest = minutes % 60
print(f"{hours} h {rest} min")
Output
2 h 15 min

You will need % often. A number is even if n % 2 is 0. The last digit of a number is n % 10.

More precisely, if you are curious
  • With negative numbers // rounds down, toward the smaller number: -7 // 2 is -4, not -3 as in Java and C#. The remainder has the sign of the divisor. % also works with decimal numbers:
print(-7 // 2)
print(-7 % 2)
print(7.5 % 2)
Output
-4
1
1.5
  • Division by 0 stops the program: ZeroDivisionError: division by zero. In Python this is true for decimal numbers too: 5.0 / 0 also stops.

Try it

Bottles in cases

A case holds 6 bottles. You have 17.

What will the program print?

bottles = 17
per_case = 6
print(f"{bottles // per_case} cases")
print(f"{bottles % per_case} left over")
Answer

The idea

Converting between types

In Python / already gives a decimal result, and the average grade comes out right away. You need a conversion the other way: from decimal to whole.

total = 5 + 6 + 6
average = total / 3
print(average)
print(f"{average:.2f}")
whole = int(9.99)
print(whole)
Output
5.666666666666667
5.67
9

You convert a type by writing the name of the type: int(9.99) makes an int, and float(17) makes 17.0. This is called a cast. int(...) cuts off the decimal part: int(9.99) is 9, not 10.

From int to float nothing is lost, and the conversion happens by itself: 10 + 0.5 is a float, 10.5. If one side is a float, // also gives a float: 17 // 3.0 is 5.0.

More precisely, if you are curious
  • int("25") from the lesson on input is the same function: it turns both text and a decimal number into a whole number.
  • Every character has a code, a number in the character table. ord gives the code, and chr makes a character from a code:
print(ord("A"))
print(chr(66))
max_int = 2147483647
print(max_int + 1)
Output
65
B
2147483648
  • In Java and C#, int goes up to 2,147,483,647, and one more "wraps around" to a negative number. In Python int has no limit, so the third line simply gives 2147483648.

Try it

Find the bug

The electricity bill is €125, split between three roommates. The program says each person pays €41.00, but it should be €41.67. Which line is the bug on?

Pick the line with the bug.

The idea

Shorthand: += and -=

You often change a value based on itself: the card balance goes down with every purchase, a counter goes up by one. There is a short way to write this:

balance = 20
purchases = 0
balance -= 4.5
purchases += 1
balance -= 3.5
purchases += 1
print(f"{purchases} purchases, €{balance} left")
Output
2 purchases, €12.0 left
You write It means
balance -= 4.5 balance = balance - 4.5
total += price total = total + price
x *= 2, x /= 2, x //= 2, x %= 2 the same with *, /, // and %
purchases += 1 purchases = purchases + 1
seats -= 1 seats = seats - 1

Python has no ++ and --. A counter goes up with += 1.

+= works with text too: message += "!" glues an exclamation mark onto the end.

More precisely, if you are curious

a++ in Python is SyntaxError: invalid syntax. ++a is sneakier: it is not an error, but two plus signs in front of the number, +(+a). The value does not change:

a = 5
++a
print(a)
Output
5

If you come from another language, be careful: the counter stays the same, and Python says nothing.

The idea

math: roots, powers, rounding

A pizza place sells a 30 cm pizza for the same price as two 20 cm pizzas. Which is more? The area of a circle is π · r². For powers Python has an operator: **. 15 ** 2 is 225. For π and for the square root there is something ready in the math module: the line import math at the top loads it, and then you write math., the name and the numbers in parentheses. These are functions, ready-made pieces of code. You will write your own in the "Functions" module.

import math
big = math.pi * 15 ** 2
small = 2 * math.pi * 10 ** 2
print(f"One 30 cm pizza: {big:.1f} sq cm")
print(f"Two 20 cm pizzas: {small:.1f} sq cm")
print(math.sqrt(144))
print(abs(-7.5))
Output
One 30 cm pizza: 706.9 sq cm
Two 20 cm pizzas: 628.3 sq cm
12.0
7.5

One big pizza is more than two small ones.

You write What it gives
math.sqrt(x) the square root
x ** n or math.pow(x, n) x to the power n
abs(x) the absolute value (without the sign), no math.
round(x) rounding to a whole number, no math.
math.pi the number π, 3.14159…

math.sqrt and math.pow return a float, even when the result is a whole number (that is why you see 12.0). ** with whole numbers gives an int: 15 ** 2 is 225. If you need an int, convert it: int(math.sqrt(144)).

More precisely, if you are curious
  • Rounding 2.5: the languages give different results.
print(round(2.5))
print(round(3.5))
print(round(5.678, 2))
Output
2
4
5.68
  • round rounds "the half" to the even number: 2.5 becomes 2, and 3.5 becomes 4. Banks do it this way (hence the name "banker's rounding"), and so does C#. With a second argument you round to that many digits after the decimal point: round(5.678, 2) is 5.68.
  • f-strings do not follow the computer's language settings: a point stays a point everywhere.

Exercise

Let the program do the math

Solve the tasks in your editor. Each number in the input is on a separate line.

1. Average of three numbers. Read three whole numbers and print their average with two digits after the decimal point. Here you need decimal division.

Input
5
6
6
Output
Average: 5.67

2. Seconds into hours. Read a number of seconds and split it into hours, minutes and seconds. Hint: an hour has 3600 seconds, and % gives what is left.

Input
3725
Output
1 h 2 min 5 s

3. Volume of a sphere. Read the radius and print the volume: V = 4/3 · π · r³. Here 4 / 3 is 1.333…, as it should be. But what would 4 // 3 be?

Input
10
Output
Volume: 4188.79 cubic cm

4. Celsius to Fahrenheit. F = C · 9 / 5 + 32. Read the temperature in degrees Celsius.

Input
37
Output
37.0 °C = 98.6 °F

More tasks

  • Inches to centimeters. One inch is 2.54 cm. For 12 inches: 30.48 cm.
  • Area of a rectangle. Read the length and the width, and print the area (length · width).
  • Area of a square. Read the side and print the area. Do it once with * and once with **.
  • Radians to degrees. Degrees = radians · 180 / π. For 3.14159: 180.00°.
  • Hours to seconds. Read a number of hours and print how many seconds that is. For 2 hours: 7200.
  • A character's code. Read a character and print its code. For A: 65. You get the first character of the text you read with input()[0]. You will see what this means in the lesson on text.

Test

Check yourself

1. What is 17 // 5?
2. What is 17 % 5?
3. What is 17 / 5 in Python?
4. What does int(9.99) give?
5. What does print("Sum: " + 2 + 3) do?

Made by Ivo Gergov as part of Evo Tech's campaign for accessible programming education ·