Programs with Modules
Seven programs that put the three modules to work alongside everything else this course has built — tuples, dictionaries, loops and f-strings. This is also the last page of the Class 11 course, so each one deliberately uses more than the module it is showing off.
1Program 1 — the full marks report
Print a complete summary of a tuple of marks: count, highest, lowest, and the three averages.
import statistics
marks = (72, 65, 88, 91, 54, 65, 77)
print('How many :', len(marks))
print('Highest :', max(marks))
print('Lowest :', min(marks))
print('Mean :', round(statistics.mean(marks), 2))
print('Median :', statistics.median(marks))
print('Mode :', statistics.mode(marks))How many : 7 Highest : 91 Lowest : 54 Mean : 73.14 Median : 72 Mode : 65
Six lines that would have taken sixty a chapter ago — the champion loops, the total-and-divide, and the frequency dictionary are all in there, written by somebody else.
2Program 2 — who is above the class mean?
A dictionary of names and marks, and the two-pass shape: work the summary out, then walk the data again with it.
import statistics
scores = {'Riya': 78, 'Amit': 85, 'Sara': 62, 'John': 91, 'Zoya': 85}
values = tuple(scores.values())
print('Mean :', round(statistics.mean(values), 2))
print('Median:', statistics.median(values))
print('Mode :', statistics.mode(values))
for name, s in scores.items():
if s > statistics.mean(values):
print(name, 'is above the class mean')Mean : 80.2 Median: 85 Mode : 85 Amit is above the class mean John is above the class mean Zoya is above the class mean
values = tuple(scores.values())statistics.mean() is happy with .values() as it is; the tuple() is here so the same values can be handed to all three calls and read back if needed.
for name, s in scores.items():The names are part of the answer, so it has to be .items() — .values() would leave you with a number and nobody to attach it to.
statistics.mean() inside the loop is wasteful. It works out the same answer five times over. Store it once above the loop — avg = statistics.mean(values) — and compare against avg. On five students it makes no measurable difference; the habit is what matters, and it is the same habit as not calling rolls.count(r) once per item.3Program 3 — a table of circle areas
import math
radii = (1, 2.5, 7, 10)
for r in radii:
area = math.pi * r * r
print('r =', r, '-> area', round(area, 2))r = 1 -> area 3.14 r = 2.5 -> area 19.63 r = 7 -> area 153.94 r = 10 -> area 314.16
A tuple of radii, one loop, one formula. The tuple can hold whole numbers and decimals side by side, because a tuple never cared what type its items were.
4Program 4 — rolling a die sixty times
Roll a die 60 times, tally the faces, and draw the result as a bar chart.
Everything on this page so far has come from the modules. This one is the dictionary tally, the sorted walk and string replication all at once — with random supplying the data.
import random
freq = {}
for i in range(60):
face = random.randint(1, 6)
freq[face] = freq.get(face, 0) + 1
for face in sorted(freq):
print('Face', face, ':', freq[face], '*' * freq[face])Face 1 : 11 *********** Face 2 : 10 ********** Face 3 : 11 *********** Face 4 : 11 *********** Face 5 : 10 ********** Face 6 : 7 *******
freq[face] = freq.get(face, 0) + 1The frequency tally, unchanged from the dictionary chapter. It does not care that the numbers are arriving from random rather than from a tuple.
for face in sorted(freq):Without sorted() the faces come out in the order they were first rolled, which is different on every run and reads as noise.
'*' * freq[face]String replication makes the bar. Eleven stars for eleven rolls — the chart is the count, drawn.
5Program 5 — cartons for an order list
# every part-full carton still costs a whole carton
import math
orders = (('pens', 47), ('books', 12), ('bags', 100))
per_carton = 6
for item, qty in orders:
print(item, ':', qty, 'units ->', math.ceil(qty / per_carton), 'cartons')pens : 47 units -> 8 cartons books : 12 units -> 2 cartons bags : 100 units -> 17 cartons
A tuple of records unpacked in the loop header, and math.ceil() doing the one thing it is for. Note books: 12 ÷ 6 is exactly 2, and ceil() leaves an exact answer alone — it only ever rounds up something that is not already whole.
6Program 6 — the distance between two points
import math
x1, y1 = 2, 3
x2, y2 = 7, 15
d = math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2))
print('Distance:', d)Distance: 13.0
x1, y1 = 2, 3 is packing and unpacking in one line — the right-hand side builds the tuple (2, 3) and the left-hand side takes it apart. Two lines of setup instead of four, and the pairing of x with y is visible.
7Program 7 — compound interest
₹25,000 invested at 7.5% for 5 years, compounded yearly. What is it worth?
# A = P (1 + r/100) ** n
import math
p = 25000
r = 7.5
n = 5
amount = p * math.pow(1 + r / 100, n)
print('Amount after', n, 'years:', round(amount, 2))
print('Interest earned :', round(amount - p, 2))Amount after 5 years: 35890.73 Interest earned : 10890.73
math.pow(1 + r / 100, n) could equally be (1 + r / 100) ** n — same answer, and the operator is the one to prefer. The rounding is on the way out only: rounding 1.075 first would throw the answer off by rupees.
8Program 8 — the guessing game, with a limit
The game from the random page, with a cap on the tries — so the loop has two ways out and needs the loop's else to tell them apart:
# seven guesses is always enough if you halve the range each time
import random
secret = random.randint(1, 100)
for turn in range(1, 8):
guess = int(input('Guess ' + str(turn) + ': '))
if guess == secret:
print('Correct! You took', turn, 'tries.')
break
elif guess < secret:
print('Too low')
else:
print('Too high')
else:
print('Out of guesses. It was', secret)Guess 1: 50 Too high Guess 2: 25 Too low Guess 3: 37 Too low Guess 4: 43 Too high Guess 5: 40 Too low Guess 6: 41 Too low Guess 7: 42 Correct! You took 7 tries.
else belongs to the for. It runs only when the loop ran out of turns without a break — which is exactly “the player never got it”. The same shape as the “not found” branch of a linear search, doing a different job.Seven turns is not arbitrary. Halving the range each time — 50, 25, 37, 43, 40, 41, 42 — narrows 100 possibilities to one in at most seven guesses, which is math.ceil(math.log2(100)) if you want to prove it.
9Recap
They replace the arithmetic inside them. Every program here still needs a tuple, a dictionary or a for loop of your own.
statistics.mean() inside a loop recomputes the same number every round. Store it above the loop.
Rounding an intermediate value — 1.075 in the interest program — moves the final answer. Round only what you print.
Sixty rolls look lumpy however fair the die is. Six thousand is what tells you whether the code is right.
- 1
Roll two dice 1000 times and tally the totals. Which total wins, and why?
Hint · 7 — there are six ways to make it and only one to make 2. Draw it with
'*' * (count // 5)so the bars fit. - 2
Print a report for a dictionary of city temperatures: mean, median, hottest and coldest city by name.
Hint ·
statisticson.values(), and the champion loop on.items()for the two names. - 3
Generate 20 random marks between 0 and 100, then report how many passed and the class mean.
Hint · Build the tuple in a loop with
marks = marks + (random.randint(0, 100),), then summarise it. - 4
Write a simple quiz: five random addition questions, one mark each, with a score at the end.
Hint · Two
randintcalls per question, compare withint(input()), and a counter for the score. - 5
Print how many buses a school trip needs, for a tuple of
(class, strength)rows, at 40 to a bus.Hint · Program 5 with the numbers changed — and a total at the end, which is not the same as one
ceil()of the grand total.
Why is calling statistics.mean(values) inside the loop wasteful?
In the cartons program, why does 12 units give exactly 2 cartons?
What does the else attached to the for loop do in the guessing game?