Exam practice
Every question from the end of every unit, with hints and answers to open. After you check an answer, mark how you did, and come back to the ones you didn’t get.
10 questions
Unit 9 · Automate Your Work
What is a dry run, and why should a script that renames or moves files have one? How do the photo programs in this unit do it?
Answer
A dry run is running a program so that it shows what it would do, without doing it. A script that changes files can damage hundreds of them in a second if its rule is wrong; a dry run lets you read the plan and catch the mistake (a rule that skips everything, two files getting one name) before anything changes. In this unit, the first photo program has a constant DRY_RUN = True, and only renames when it is changed to False; tidy_photos.py only moves files when it is given the option --move, so the safe dry run is what happens by default.
Explain why each of these is a good habit when a script changes files: (i) testing on a copy, (ii) checking exists() before renaming, (iii) moving instead of deleting, (iv) keeping a list of what was done.
Answer
(i) If the script has a bug, only the copy is damaged; the original is still there.
(ii) Renaming onto a name that is taken silently replaces the other file on Linux and macOS (and stops with an error on Windows): checking first means no file is ever lost.
(iii) A moved file can be moved back; a file deleted by a program is gone, with no bin to recover it from.
(iv) With a list of old and new names, a short script can undo everything if the result turns out wrong.
A shop’s sheet has amounts written as 1500, "1,500", Rs 1500 and १५००. Write a function clean_amount(text) that turns any of them into the number 1500, and explain why it works for the last one.
Answer
def clean_amount(text): return int(text.replace("Rs", "").replace(",", "").strip())It takes out “Rs”, every comma and the spaces at the ends, then turns what is left into a whole number. It works for १५०० because Python’s int() reads any Unicode decimal digit, so the Nepali digits १, ५, ० read as 1, 5, 0. (A value it can’t read, such as “paid”, raises a ValueError, which is better than a wrong number.)
A program reads students.csv, saved from Excel as CSV UTF-8, with open("students.csv", encoding="utf-8"). row["name"] raises KeyError: 'name', though the first line of the file is name,class,phone. Explain what has happened and how to fix it.
Answer
Excel’s CSV UTF-8 starts the file with a byte order mark (BOM), three bytes that say the file is UTF-8. Read with plain UTF-8, the BOM becomes an invisible character, , at the start of the first line, so the first column is called "name", not "name", and row["name"] finds no such key. Opening the file with encoding="utf-8-sig" reads and drops the BOM (and reads a file without one just the same).
Write a regular expression for each, and give one text that should match and one that shouldn’t:
- i.a Nepali mobile number, ten digits starting with 96, 97 or 98;
- ii.a date written as year-month-day with dashes, such as 2083-07-08;
- iii.an amount in rupees written as Rs followed by a space and digits, such as Rs 450.
Answer
- i.
9[678]\d{8}(with re.fullmatch, or\bat both ends with search). Matches 9841000011; not 9541000011 (wrong start) or 984100001 (nine digits). - ii.
\d{4}-\d{2}-\d{2}. Matches 2083-07-08; not 2083/07/08 (slashes) or 83-07-08 (a two-digit year). - iii.
Rs \d+. Matches Rs 450; not Rs450 (no space) or NPR 450.
(Any correct pattern with sensible examples gets full marks; the point is to test both kinds of text.)
What does each print?
import reprint(re.findall(r"\d{2}", "Grade 11, Room 204"))print(re.sub(r"\s+", "-", "Science Exhibition 2083"))print(re.fullmatch(r"[A-Z]\d+", "A12") is not None)Answer
['11', '20']: two digits at a time, left to right; after 20, only the 4 is left, which isn’t two digits.Science-Exhibition-2083: every run of spaces (the double space too) becomes one dash.True: one capital letter followed by one or more digits is the whole of “A12”.
Why is string.Template used for the certificates instead of str.format()? Why must each value be passed through html.escape() first?
Answer
The certificate is an HTML page with CSS, which is full of { and }: str.format() would take every brace for a gap to fill, and fail or fill the wrong things. string.Template’s gaps are written $name, which doesn’t clash with CSS. In HTML, &, < and > have special meanings; a name like “Bibek & Kiran” or one containing < could show wrongly or break the page, or even be used to attack it. html.escape() turns them into &, < and >, which the browser shows as the characters themselves.
A Grade 11 student wants the daily prices of vegetables from a market website for a project. List four things her program must do to collect them responsibly.
Answer
Any four, such as:
- Look for an official API or a downloadable file first, and use it if there is one.
- Read the site’s terms of use, and its robots.txt, and stay out of whatever they forbid.
- Ask for one page at a time, with a pause of a few seconds (or the Crawl-delay) between requests, and only once a day: prices don’t change every minute.
- Save every page it fetches (a cache) and never fetch the same one twice.
- Send a User-Agent that names the program and how to contact her.
- Credit the source in her project, and not republish the data if the terms forbid it.
- Check its results each day, because a change in the page’s layout can make it collect nothing without an error.
A teacher spends 40 minutes every Friday copying the week’s attendance from five sections’ sheets into one report. A script to do it would take 4 hours to write and test, and 5 minutes each Friday to run and check. (i) How many Fridays until the script has paid for itself? (ii) How much time does it save in a school year of 36 weeks? (iii) Give one benefit and one risk that aren’t about time.
Answer
- i.Each Friday saves 40 − 5 = 35 minutes. 4 hours = 240 minutes; 240 ÷ 35 ≈ 6.9, so by the 7th Friday it has paid for itself.
- ii.By hand: 36 × 40 = 1,440 minutes (24 hours). With the script: 240 + 36 × 5 = 420 minutes (7 hours). It saves 1,020 minutes, 17 hours.
- iii.A benefit: no copying mistakes, and the report is the same every week. A risk: if a section changes its sheet (a new column, another way of writing names), the script may stop, or worse, quietly give a wrong report; so its results must be checked, and someone must be able to fix it.
What will python3 tidy_photos.py Camera print for a folder holding only these three files, and what will be in the folder afterwards? IMG_20261201_080000.jpg, IMG-20261201-WA0001.jpg, holiday.jpg
Answer
The files are taken in sorted order (a hyphen sorts before an underscore, capitals before small letters):
Output
IMG-20261201-WA0001.jpg -> 2026-12/2026-12-01 chat 0001.jpgIMG_20261201_080000.jpg -> 2026-12/2026-12-01 08.00.00.jpgskip: holiday.jpg (not a name it knows)Would move 2 files, skip 1 - add --move to do itWithout --move it is a dry run, so afterwards the folder is exactly as it was: nothing has moved.
