2 Numeric types
This chapter introduces Python’s core numeric types and shows how they underpin everyday programming tasks. While Python supports integers, floating-point numbers, and complex numbers, the practical focus is on ints and floats—how they’re stored, compared, converted, and displayed. Through discussion of assignment, function arguments, loops, user input, and string formatting, the chapter emphasizes the habits you need when mixing numbers with other common types (like strings) and working with iteration and comparisons. It also highlights f-strings for readable output and illustrates where numeric handling conventions in Python can differ from expectations (for example, how ranges and inclusivity work).
The first set of exercises builds fluency with control flow, input handling, and type conversion. A number-guessing game reinforces generating random integers, converting user input from string to int, comparing values, and looping until a condition is met, with a nod to the walrus operator as an alternative looping pattern. A reimplementation of sum demonstrates function design with variable-length argument lists using the splat operator, iterating over tuples of inputs, and the practical differences between receiving an iterable versus expanding it into arguments. The guidance stresses clear, Pythonic usage of parameters and iteration when accumulating numeric results.
The later exercises deepen numeric reasoning with floats and bases. A run-timing task collects repeated floating-point inputs, exits cleanly on empty input, computes an average, and discusses numeric robustness: using try/except for validation, the limits of floating-point precision, formatting with f-strings, and when integers or Decimal are safer choices. A hexadecimal conversion task then ties iteration concepts together—reversing a string, enumerating positions, applying powers, and converting digits with base-aware int—to produce a decimal result. Together, these exercises reinforce practical numeric workflows in Python: iterate cleanly, convert explicitly, format thoughtfully, and choose numeric representations that match the problem’s precision needs.
Summary
It’s hard to imagine a Python program that doesn’t use numbers. Whether as numeric indexes (into a string, list, or tuple), counting the number of times an IP address appears in a log file, or calculating interest rates on bank loans, you’ll be using numbers all of the time.
Remember that Python is strongly typed, meaning that integers and strings (for example) are different types. You can turn strings into integers with int, and integers into strings with str. And you can turn either of these types into a floating-point number with float.
In this chapter, we saw a few ways we can work with numbers of different types. You’re unlikely to write programs that only use numbers in this way, but feeling confident about how they work and fit into the larger Python ecosystem is important.
FAQ
What numeric types does Python provide, and which will I use most often?
Python has three numeric types: int (whole numbers), float (numbers with fractional parts), and complex (numbers with real and imaginary parts). In everyday code you’ll mostly use int and float.How does input() work with numbers, and why do I get errors comparing input to integers?
input(prompt) always returns a string. If you need a number, convert it first: use int(s) for whole numbers or float(s) for decimals. Comparing a string to an int (for example, "5" < 10) raises a TypeError, so convert before comparing.Example:
s = input('Enter a number: ')
n = int(s) # or float(s)
How do I generate a random integer, and is the upper bound inclusive?
Use random.randint(a, b) to get a random int between a and b inclusive. This inclusivity is unusual compared to many Python ranges (like range), which are upper-exclusive.Example:
import random
n = random.randint(0, 100) # 0 ≤ n ≤ 100
What are f-strings and why should I use them?
f-strings let you embed expressions directly in string literals using { }. They’re concise, readable, and powerful, including formatting options for numbers (such as digits after the decimal).Examples:
name = 'World'
msg = f'Hello, {name}!'
x = 0.1 + 0.7
print(f'{x:.2f}') # prints 0.80
How can I build a “guess the number” loop correctly?
Pick a number with random.randint, then loop until the user guesses it. Convert the user’s guess with int(), and compare.Sketch:
import random
answer = random.randint(0, 100)
while True:
guess = int(input('Your guess: '))
if guess == answer:
print('Just right')
break
elif guess < answer:
print('Too low')
else:
print('Too high')
What is the “splat” operator (*) and how do I use it in functions like mysum?
The splat operator collects a variable number of positional arguments into a tuple when defining a function, and it can also expand an iterable into separate arguments when calling a function.Examples:
def mysum(*numbers):
total = 0
for n in numbers:
total += n
return total
mysum(1, 2, 3) # 6
nums = [10, 20, 30]
mysum(*nums) # 60 (list expanded into args)
How do I read multiple run times and compute the average until the user presses Enter?
Keep a running total and count. Read input in a loop; an empty string (user just presses Enter) is falsey, so you can break on if not s:. Convert to float for averaging.Sketch:
count = 0
total = 0.0
while True:
s = input('Enter 10 km run time: ')
if not s:
break
total += float(s)
count += 1
avg = total / count if count else 0.0
print(f'Average of {avg}, over {count} runs')
Why does 0.1 + 0.2 not equal 0.3 in Python, and what can I do about it?
Binary floating-point can’t represent many decimals exactly, so small rounding errors appear. Mitigations:- Format output (e.g., f'{x:.2f}') to control displayed precision.
- For exact decimal math (e.g., money), use the Decimal class or store smallest units as integers (cents instead of dollars).
Example with Decimal:
from decimal import Decimal
print(Decimal('0.1') + Decimal('0.2')) # 0.3
How can I convert a hexadecimal string to decimal without converting the whole string at once?
Iterate over the hex string in reverse, convert each digit with int(digit, 16), and accumulate digit * 16**position.Example:
hexnum = '50'
dec = 0
for power, digit in enumerate(reversed(hexnum)):
dec += int(digit, 16) * (16 ** power)
print(dec) # 80
What do enumerate and reversed do, and why are they useful in loops?
reversed(seq) lets you iterate from the last element to the first without copying data. enumerate(iterable) yields (index, item) pairs starting at 0, giving you both the position and value during iteration. They’re handy when you need index-aware or reverse-order processing without manual index math.Example:
for idx, ch in enumerate('abcd'):
print(idx, ch) # 0 a, 1 b, ...
for ch in reversed('abcd'):
print(ch) # d c b a
Python Workout, Second Edition ebook for free