Marks File That Crashes the Average Script
A teacher writes a Python script to process marks from marks.txt. Each line should contain one integer from 0 to 100, but the file contains blank lines, the word Absent, and one value 105 entered after a bonus. The draft is: total = 0; count = 0; for line in open('marks.txt'): total += int(line); count += 1; average = total / count. It crashes on the first blank line. The teacher also wants to scale every mark so that the highest becomes 100, while ensuring no mark exceeds 100, and to report how many students were absent. The class has 38 students on roll, but only 35 valid numeric marks are present. The principal wants the average to reflect only students who appeared, while the teacher initially included absentees as zero. The script must not silently ignore malformed data such as '10O' (letter O).
1. Identify each failure in the draft and rewrite the parsing loop to handle blanks, Absent, 105, and malformed input.
Read the worked answer
Each failure is different: int('') raises ValueError on a blank line; int('Absent') also raises ValueError; 105 parses but violates the 0–100 range; '10O' with a letter O is malformed and must be reported, not silently dropped.
valid, invalid = [], []
absent = 0
with open('marks.txt') as f:
for raw in f:
s = raw.strip()
if not s:
continue
if s.lower() == 'absent':
absent += 1
continue
try:
m = int(s)
except ValueError:
invalid.append(s)
continue
if 0 <= m <= 100:
valid.append(m)
else:
invalid.append(s)
This keeps malformed and out-of-range data visible for correction instead of hiding it.
2. The principal wants the average of students who appeared. Explain the denominator choice with 35 valid marks and 38 on roll.
Read the worked answer
With 35 valid numeric marks and 38 on roll, sum(valid)/35 is the average of students who appeared; sum(valid)/38 treats the three absentees as zero and lowers the average. The principal explicitly wants the appeared-student average, so use 35 as the denominator - but report absent = 3 and invalid = ... separately.
If the board’s result rule requires absentees to be counted as zero, then use 38 and label the figure as ‘average over roll’, not ‘class average’. The important judgement is to state the denominator in the output; otherwise the same number can be misread. Do not use the total number of lines as the denominator, because blanks and the ‘Absent’ lines are not students.
3. The highest raw mark is 105. Explain how you would scale to a maximum of 100, and why you might not scale at all.
Read the worked answer
First decide what 105 means. If it is a genuine bonus, linear scaling is scaled = min(100, round(m * 100/105, 2)). Then 0 stays 0, 105 becomes 100, and a real 100 becomes about 95.24, which changes every student’s mark. If 105 is a data-entry error, correct it to 100 and do not scale the others; otherwise the correction penalises the whole class.
The exam-style judgement is: verify the source before transforming. A safe interim report can show raw marks plus a flag for 105, rather than silently capping or scaling. If scaling is approved, apply it after validation and state the formula on the report so the change is auditable.