Smallest, Largest & Mean
Three of the programs the syllabus names outright, and they are one program each. Python has max(), min() and sum() and will do all three in a line — but the exam asks for the loop, and the loop is the version that survives when the question gets fussier, as it does at the end of this page.
1Program 1 — the largest, without max()
Find the highest mark in a tuple, without using max().
# the highest mark, by keeping a champion
marks = (56, 91, 43, 78, 65)
largest = marks[0]
for m in marks:
if m > largest:
largest = m
print('Largest:', largest)Largest: 91
largest = marks[0]The best seen so far, and it starts as a real member of the tuple. Made before the loop, so it survives every round.
if m > largest:One question per item: is this one better than the best so far? Most rounds the answer is no and nothing happens, which is fine.
largest = mThe new champion. Note it stores the mark, not the position — reporting where it was is a different program, further down.
marks[0], never at 0. Zero looks harmless because marks cannot be negative — and then the same code is used on temperatures:# the same program with largest = 0, on winter temperatures
temps = (-4, -11, -7, -2)
largest = 0
for t in temps:
if t > largest:
largest = t
print('Largest (wrong):', largest)Largest (wrong): 0
It reports 0, which is not in the tuple at all. Nothing crashed and nothing looked odd. marks[0] can never do this, because it really is one of the candidates.
2Program 2 — the largest and the smallest together
Find the highest and the lowest mark in one pass.
# both champions, one loop
marks = (56, 91, 43, 78, 65)
largest = marks[0]
smallest = marks[0]
for m in marks:
if m > largest:
largest = m
if m < smallest:
smallest = m
print('Largest: ', largest)
print('Smallest:', smallest)Largest: 91 Smallest: 43
ifs — not if…elif. Both questions have to be asked of every mark. With an elif, a mark that beat the largest would never be tested against the smallest. On this tuple it happens not to matter; on a tuple whose first item is the smallest it does.3Program 3 — the mean, without sum()
Work out the average of a tuple of marks, without sum().
# the total, then the mean
marks = (56, 91, 43, 78, 65)
total = 0
for m in marks:
total = total + m
print('Total:', total)
print('Mean: ', total / len(marks))Total: 333 Mean: 66.6
Divided by len(marks) and not by 5, so adding a sixth mark needs no other change. And the division is /, not //: a mean of 66.6 is the answer, and // would report 66.
# a mean is usually printed to two decimals
marks = (72, 65, 88, 91, 54, 77)
total = 0
for m in marks:
total = total + m
print('Mean:', round(total / len(marks), 2))Mean: 74.5
4The same three, in one line each
# what you would actually write outside an exam
marks = (56, 91, 43, 78, 65)
print('Largest: ', max(marks))
print('Smallest:', min(marks))
print('Total: ', sum(marks))
print('Mean: ', sum(marks) / len(marks))Largest: 91 Smallest: 43 Total: 333 Mean: 66.6
max()” — and it is the only one of the two that can be bent into a new shape, which the next two programs need.max() of an empty tuple is an error, not 0. ValueError: max() iterable argument is empty. The loop version fails earlier and more obviously — marks[0] on an empty tuple raises IndexError — but either way, a program that might be handed nothing has to check len() first.5Program 4 — where the largest is
Report the highest mark and the position it is at.
This is the first question max() cannot answer, and it is why the index form of the loop exists:
# the largest, and which student it belongs to
marks = (56, 91, 43, 78, 65)
largest = marks[0]
where = 0
for i in range(len(marks)):
if marks[i] > largest:
largest = marks[i]
where = i
print('Largest:', largest, 'at position', where)
print('That is student number', where + 1)Largest: 91 at position 1 That is student number 2
Two variables move together inside the same if, exactly as the name and the mark did in the topper program. Update one without the other and the program reports a real mark at the wrong position.
6Program 5 — the second largest
Find the second highest mark in a tuple.
The tempting answer — keep two champions and shuffle them along — is fiddly to get right. Two passes is easier to read and easier to trust: find the largest, then find the largest of everything that is not it.
# the second largest, in two passes
marks = (56, 91, 43, 78, 65)
largest = max(marks)
second = min(marks)
for m in marks:
if m > second and m != largest:
second = m
print('Largest: ', largest)
print('Second largest:', second)Largest: 91 Second largest: 78
second = min(marks)The second champion starts at the smallest mark — a real member again, and one that every other candidate beats or ties.
if m > second and m != largest:Two conditions: better than the best runner-up so far, and not the winner itself. Drop the second half and the answer comes back equal to largest.
(5, 5, 5) this program prints 5 twice, because every item equals largest and nothing ever replaces second. That is not a bug to patch quietly — it is a question the data cannot answer, and a real program would say so.7Recap
marks[0] is always safe. 0 or 100 can win, and then the answer is a number that was never in the data.
total = 0 and largest = marks[0] are both made before the loop. Inside it they only ever change.
When two questions must both be asked of every item, an elif silently skips one of them.
The moment the position is part of the answer, you are back to for i in range(len(marks)).
- 1
Find the longest name in a tuple of names, without
max().Hint · The champion program with
len(n) > len(longest), starting atnames[0]. - 2
Print how far the highest mark is above the mean.
Hint · Two passes: work out the mean, then
max(marks) - mean. Round it before printing. - 3
Count how many marks are above the mean.
Hint · Also two passes — the mean does not exist until the first one has finished, so nothing can be compared with it during that pass.
- 4
Report the smallest number and the position it sits at, in one loop.
Hint · Program 4 with
<. Bothsmallestandwhereupdate inside the sameif.
Why must largest start at marks[0] rather than at 0?
Which of these can max() not do?
In the second-largest program, why is `and m != largest` needed?