Skip to content

← Final exam model papers

Final Exam Model Paper 1

Theory paper: 50 marksTime: 2 hours

Practical exam: 25 marksTime: 1 hour 30 minutes

All questions are compulsory.

A full practice run of the Grade 10 final exam: the theory paper (50 marks, 2 hours) and, below it, the practical exam (25 marks, 1 hour 30 minutes, at a computer, marked by the school). In the theory paper, work out on paper what each program does, as in the exam hall: its programs have no Run button. In the practical exam, the programs run on this page.

A practice paper by Science Playground, made to its own course’s grid; not an official exam paper.

Write your answers on paper first. Then open each answer and its marking scheme, and give yourself one mark for each point you got. In multiple choice, your first choice counts.

Section A

10 × 1 = 10

1. Choose the correct option for each of the following questions.

a.

What is a module in Python?

Pick an answer to see why.

b.

A simplified map of the trails around Ghandruk, as a dictionary of neighbors:

trails = {    "Nayapul": ["Birethanti"],    "Birethanti": ["Nayapul", "Tikhedhunga", "Ghandruk"],    "Tikhedhunga": ["Birethanti", "Ulleri"],    "Ulleri": ["Tikhedhunga", "Ghorepani"],    "Ghorepani": ["Ulleri", "Tadapani"],    "Tadapani": ["Ghorepani", "Ghandruk"],    "Ghandruk": ["Birethanti", "Tadapani", "Landruk"],    "Landruk": ["Ghandruk"],}

What is the fewest number of trails a trekker must walk from Landruk to Ghorepani?

Pick an answer to see why.

c.

What is a foreign key?

Pick an answer to see why.

d.

A survey of 600 students in Lalitpur finds that students who visit the school library more often get higher marks. The head teacher says: “So if we make every student visit the library twice a week, everyone’s marks will go up.” Which judgment is right?

Pick an answer to see why.

e.

A river station measures the water’s height from 0 to 10 m. Its analog-to-digital converter gives whole numbers from 0 to 1023. What is the smallest rise in the water it can show?

Pick an answer to see why.

f.

A program’s website gives a checksum beside its download. What is it for?

Pick an answer to see why.

g.

Nearly every large language model is built on the transformer. What does its attention do?

Pick an answer to see why.

h.

Rohan asks a chatbot for a function: “bus_fare(km) returns the fare: Rs 25 for a trip of up to 5 km, and Rs 3 more for each km after the first 5.” It gives:

def bus_fare(km):    return 25 + (km - 5) * 3

Which test, chosen from the requirement, shows that the function is wrong?

Pick an answer to see why.

i.

A cooperative’s old program stores the year a member joined in two digits, and works out how many years someone has been a member as this year minus the year they joined. Kanchha joined in 1998. What does the program work out for him in 2026?

Pick an answer to see why.

j.

A ward chair reads that quantum computers “try every answer at once”. He says: “In a few years the ward should buy a quantum computer for its office, because it will do all our work instantly.” Which judgment is right?

Pick an answer to see why.

Section B

10 × 2 = 20

Write short answers to the following questions.

2.
[2]

A momo shop in Butwal sells a plate for Rs 160. Its owner’s nephew writes:

def plate_price(plates):    print(plates * 160) total = plate_price(2) + plate_price(3)print("Total:", total)
  • i.What does the program show before it stops with an error on line 4, and why does line 4 fail?
  • ii.Rewrite the function so that the program prints the total.
Answer

i. Each call runs the function, which prints its price, so the screen shows 320, then 480. But the function has no return, so each call gives back None, and line 4 tries to work out None + None, which Python can’t add:

Output

320480

and then TypeError: unsupported operand type(s) for +: 'NoneType' and 'NoneType'. Printing a value shows it to a person; only return gives it back to the program.
ii. Return the price instead of printing it:

def plate_price(plates):    """The price in rupees of this many plates."""    return plates * 160 total = plate_price(2) + plate_price(3)print("Total:", total)

Output

Total: 800
Marking scheme
  • i. 320 and 480 are printed, then a TypeError: the function returns None (it prints but doesn’t return), and None + None can’t be added.
  • ii. return plates * 160 in place of the print, so the program prints Total: 800.
3.
[2]

Eight schools play a knockout football cup in Dhangadhi: four first-round matches, then two semi-finals, then the final. Draw it as a graph with a node for each match, and an edge from each match to the match its winner plays next.

  • i.Why is this graph a tree? Name its root and its leaves.
  • ii.Why is there exactly one route from a first-round match up to the final, and what does that route tell a team?
Answer
  • i.It is joined up and has no loops: each match except the final sends its winner to exactly one next match, its parent, and no winner ever goes back to an earlier match. The root is the final, which has no parent; the leaves are the four first-round matches, which have no matches below them. (7 matches, 6 edges: a tree with n nodes has n − 1 edges.)
  • ii.Every match has only one parent, so going up from a first-round match there is only one way: that match, its semi-final, the final. It is the list of matches a team starting there must win to lift the cup: three wins, in that order.
Marking scheme
  • i. No loops, each match sending its winner to exactly one next match; the final is the root and the four first-round matches are the leaves.
  • ii. One parent each, so one route up; it is the matches the team must win (three).
4.
[2]

Lalitpur Metropolitan City keeps the trees planted in its green campaign in a table, trees:

tree_id species ward planted alive
1 Chanp 9 2025-06-14 yes
2 Lapsi 9 2025-06-14 no
3 Rudraksha 4 2025-07-02 yes
… … … … …

Write an SQL query that lists the species and the planting date of the trees in ward 9 that have died, the most recently planted first.

Answer
SELECT species, plantedFROM treesWHERE ward = 9 AND alive = 'no'ORDER BY planted DESC;

Dates written as year-month-day sort in the right order, so DESC puts the most recent first.

Marking scheme
  • SELECT species, planted FROM trees with WHERE ward = 9 AND alive = 'no'.
  • ORDER BY planted DESC.
5.
[2]

Seven houses in a tole paid these electricity bills, in rupees, for Poush. The last house runs a small flour mill.

820, 1,150, 640, 990, 1,300, 760, 9,400

  • i.Work out the mean and the median.
  • ii.Which better describes the bill of a typical house in the tole? Give a reason.
Answer
  • i.Mean = (820 + 1,150 + 640 + 990 + 1,300 + 760 + 9,400) ÷ 7 = 15,060 ÷ 7 ≈ Rs 2,151. In order: 640, 760, 820, 990, 1,150, 1,300, 9,400, so the median is the middle one, Rs 990.
  • ii.The median. The mill’s bill is an outlier, far above the rest, and it pulls the mean up to more than any other house pays. The median isn’t moved by how far out the outlier is.
Marking scheme
  • i. Mean about Rs 2,151 and median Rs 990.
  • ii. The median, because the mill’s bill is an outlier that pulls the mean up.
6.
[2]

Kiran’s quiz program, quiz.py, is in his class10 folder, and the file of questions it reads is in a folder called data inside it. He runs it:

Output

kiran@lab-pc:~/school/class10$ lsdata  quiz.pykiran@lab-pc:~/school/class10$ python3 quiz.pyTraceback (most recent call last):  File "/home/kiran/school/class10/quiz.py", line 1, in <module>    with open("questions.txt") as f:         ~~~~^^^^^^^^^^^^^^^^^FileNotFoundError: [Errno 2] No such file or directory: 'questions.txt'
  • i.Why can’t the program find questions.txt, though the file exists?
  • ii.Give one way to fix it.
Answer
  • i.Python found and started quiz.py; it is the program that can’t find its file. open("questions.txt") names no folder, so it looks in the working directory, the folder Kiran ran it from, ~/school/class10. questions.txt is in data, one folder further in.
  • ii.Any one: change line 1 to open("data/questions.txt"); or move questions.txt into class10; or run the program from the data folder: cd data, then python3 ../quiz.py.
Marking scheme
  • i. The program looks for the file in the working directory (class10), but the file is in data.
  • ii. One working fix: open "data/questions.txt", move the file, or run it from the data folder.
7.
[2]

Pema’s prompt is pema@lab-pc:~$. Her home folder holds a folder school, with folders class9 and class10 inside it. For the science club she types, one after another:

cd schoolmkdir clubcd clubcd ../class10pwd
  • i.What does pwd print? In which folder is the new folder club?
  • ii.Write one command that takes her from there into club, and the prompt she will then see.
Answer

i. cd school takes her into school, so mkdir club makes club inside school, beside class9 and class10. cd club goes into it; .. is the folder one level up, school, so cd ../class10 goes to class10, and pwd prints:

Output

/home/pema/school/class10

ii. Up one level and into club:

cd ../club

The prompt then shows pema@lab-pc:~/school/club$. (cd ~/school/club or cd /home/pema/school/club works as well.)

Marking scheme
  • i. /home/pema/school/class10, and club is inside school (/home/pema/school/club).
  • ii. cd ../club (or a full path to club), with the prompt pema@lab-pc:~/school/club$.
8.
[2]

At a class debate in Biratnagar, Suman says: “A bigger model always gives better answers.” Rekha replies that in OpenAI’s tests in 2022, people preferred the answers of InstructGPT, with 1.3 billion parameters, to those of GPT-3, the base model with 175 billion that it was made from.

  • i.What had been done to InstructGPT that hadn’t been done to GPT-3?
  • ii.Why could that make a model more than 100 times smaller give better answers?
Answer
  • i.After pretraining, it was fine-tuned on example conversations written by people (a request and a good answer), and then trained on people’s comparisons of its answers, choosing the better one (feedback from people, RLHF).
  • ii.Size and pretraining give a model its knowledge, but a base model only carries on text: given a question, it may write more questions. Fine-tuning and feedback teach it to answer a request helpfully, in the way people prefer. People judge the answers they get, so a smaller model that answers well beats a bigger one that doesn’t answer at all.
Marking scheme
  • i. Fine-tuning on example conversations, and training on people’s choices between its answers (feedback, RLHF).
  • ii. The base model only carries on text; fine-tuning and feedback taught the smaller one to answer helpfully, as people prefer (size gives knowledge, not helpfulness).
9.
[2]

Two students test whether a chatbot answers questions about Nepal’s districts well. Bina asks it five questions she thinks of while she is testing, and finds four right. Kiran writes 60 questions first, half about Karnali Province’s districts and half about Bagmati’s, checks each answer in official sources, then asks them all, and counts right answers in each half. Whose test should the school trust more? Give two reasons.

Answer

Kiran’s. His questions were chosen before he saw any answers, so he couldn’t pick them, even without meaning to, to make the chatbot look good or bad; every answer was checked in a reliable source; 60 questions are far more than 5, so one lucky or unlucky answer matters less; and counting by group can show whether it is worse about Karnali than about Bagmati, which an overall score would hide.

Marking scheme
  • Kiran’s, with one reason: questions chosen in advance, or answers checked in sources, or many more questions.
  • A second reason: counted by group, which shows if it is worse for one province (or another reason from the first point).
10.
[2]

After her SEE, Sujata in Dang wants to work in computing itself, not only use computers in another job. Name two jobs about computing, and say in one line what someone in each does.

Answer

Any two, for example:

  • Software developer: writes, tests and fixes programs and apps.
  • Data analyst: cleans data, finds patterns and makes honest charts for decisions.
  • Network engineer: designs and runs the networks of internet companies, banks and offices.
  • Security analyst: finds weaknesses before attackers do, and responds to attacks.
  • UI/UX designer: designs screens and how people use them, and tests them with users.
  • IT support or system administrator: keeps a school’s, hospital’s or company’s computers and accounts running.
  • GIS and mapping specialist: makes and analyzes maps from satellite and GPS data.
  • Machine learning engineer: builds and tests AI models.
  • Computing teacher: teaches computing to the next people.
Marking scheme
  • One job about computing, with what its people do.
  • A second, different one, with what its people do.
11.
[2]

From next year a municipality will take its property tax only through a mobile app, in English. Judge this plan: who could be left out, and what one change would let them in?

Answer

It leaves out people without a smartphone or a connection (many older people, poorer households, villages with a weak signal) and people who don’t read English well: an inequity in access, made by design choices. Changes that let them in: keep a counter at the ward office, or let people pay at a bank; make the app work in Nepali; or let a family member or a ward helper pay for them.

Marking scheme
  • Who is left out, with the reason: people without a smartphone, data or signal, or who don’t read English.
  • A change that would let them in: a counter or bank payment kept, a Nepali version, or help at the ward.

Section C

5 × 4 = 20

Write long answers to the following questions.

12.
[4]

A homestay in Bandipur charges Rs 1,500 per guest per night, and Rs 350 for each meal. Guests who stay 3 nights or more get 10% off the nights (not the meals).

  • i.Write a module, homestay.py, with a function bill(guests, nights, meals) that returns the bill in rupees, and a docstring. (2)
  • ii.Add tests at the end of the module that run only when homestay.py itself is run, choosing values that check the rule for the discount. (1)
  • iii.Write a separate program that imports the module and prints the bill for a family of 4 staying 3 nights with 24 meals. (1)
Answer

i. and ii.

homestay.py

"""The homestay's charges.""" PER_NIGHT = 1500     # rupees, for each guestPER_MEAL = 350       # rupees  def bill(guests, nights, meals):    """The bill in rupees: the nights, 10% off for 3 nights or more, plus the meals."""    stay = guests * nights * PER_NIGHT    if nights >= 3:        stay = stay * 0.9    return round(stay + meals * PER_MEAL)  if __name__ == "__main__":    # tests: 2 nights get no discount, 3 nights do    print(bill(1, 2, 0), "should be 3000")    print(bill(1, 3, 0), "should be 4050")    print(bill(2, 1, 2), "should be 3700")

iii.

import homestay print("Bill: Rs", homestay.bill(4, 3, 24))

Output

Bill: Rs 24600

4 guests × 3 nights × Rs 1,500 = Rs 18,000, less 10% = Rs 16,200; 24 meals × Rs 350 = Rs 8,400; together Rs 24,600. Any clear names and messages are fine.

Marking scheme
  • i. A function bill with the three parameters that returns (not prints) guests × nights × 1,500 plus meals × 350, with a docstring.
  • i. The 10% off the nights only, for 3 nights or more (nights >= 3).
  • ii. Tests under if __name__ == "__main__": that include 2 and 3 nights (the edge of the discount), with what each should give.
  • iii. A program that imports homestay and prints homestay.bill(4, 3, 24) (Rs 24,600).
13.
[4]

The eco club is cleaning the banks of the Bagmati on Saturday, and the news is passed on from friend to friend. This dictionary shows who is friends with whom:

friends = {    "Aarati": ["Bikram", "Chandani", "Dipa"],    "Bikram": ["Aarati", "Esha", "Dipa"],    "Chandani": ["Aarati", "Furba"],    "Dipa": ["Aarati", "Bikram", "Gopal"],    "Esha": ["Bikram", "Hemant"],    "Furba": ["Chandani", "Gopal"],    "Gopal": ["Dipa", "Furba", "Hemant"],    "Hemant": ["Esha", "Gopal"],}
  • i.Do a breadth-first search from Aarati by hand. Write a row for each visit: the person visited, their steps, the new people added (with their steps), and the list still to visit. (2)
  • ii.In how few steps can the news reach Hemant? Write the route, from the notes of whom each person was first reached from. (1)
  • iii.Bikram and Esha stop being friends. In how few steps can the news now reach Esha, and by which route? (1)
Answer

i.

Visit Steps New people (steps) List still to visit, front first
(start) Aarati (0) Aarati
Aarati 0 Bikram, Chandani, Dipa (1) Bikram, Chandani, Dipa
Bikram 1 Esha (2); Aarati and Dipa already seen Chandani, Dipa, Esha
Chandani 1 Furba (2) Dipa, Esha, Furba
Dipa 1 Gopal (2) Esha, Furba, Gopal
Esha 2 Hemant (3) Furba, Gopal, Hemant
Furba 2 none Gopal, Hemant
Gopal 2 none (Hemant already seen) Hemant
Hemant 3 none (empty)
  • ii.3 steps. Hemant was first reached from Esha, Esha from Bikram, Bikram from Aarati: Aarati → Bikram → Esha → Hemant.
  • iii.Esha can now be reached only through Hemant, who is 3 steps away by Dipa and Gopal: 4 steps, Aarati → Dipa → Gopal → Hemant → Esha.
Marking scheme
  • i. The visits in the right order: Aarati; Bikram, Chandani, Dipa; then Esha, Furba, Gopal; then Hemant.
  • i. Correct steps (Bikram, Chandani, Dipa 1; Esha, Furba, Gopal 2; Hemant 3) and the list kept as a queue (new people at the back).
  • ii. 3 steps, Aarati → Bikram → Esha → Hemant.
  • iii. 4 steps, Aarati → Dipa → Gopal → Hemant → Esha.
14.
[4]

A school keeps its inter-house football tournament in two tables.

players

player_id name house
1 Aayush Rai Everest
2 Binita Magar Kanchenjunga
3 Chirag Shah Everest
4 Dawa Sherpa Makalu
5 Elina Gurung Kanchenjunga
6 Firoj Ansari Makalu

goals

match player_id minute
1 3 12
1 1 30
1 3 41
2 2 5
2 4 27
2 5 33
3 3 18
3 6 22
3 2 39

Write what each query gives.

  • i.SELECT name FROM players WHERE house = 'Makalu'; (1)
  • ii.SELECT player_id, COUNT(*) FROM goals GROUP BY player_id ORDER BY COUNT(*) DESC LIMIT 2; (1)
  • iii.(1)
SELECT players.name, goals.minuteFROM goalsJOIN players ON goals.player_id = players.player_idWHERE goals.match = 2ORDER BY goals.minute;

iv. Why does the goals table store each scorer’s player_id, and not the player’s name and house? (1)

Answer
  • i.The two players of Makalu: Dawa Sherpa and Firoj Ansari.
  • ii.One row per player, with the number of goals, most first, and only the first two kept: 3, 3 (Chirag Shah scored 3) and 2, 2 (Binita Magar scored 2). Everyone else scored 1.
player_id COUNT(*)
3 3
2 2

iii. Each goal of match 2 joined to its scorer’s row, earliest first:

name minute
Binita Magar 5
Dawa Sherpa 27
Elina Gurung 33

iv. So that each fact is kept once. A player’s name and house are written once, in players, and each goal points to that row with a foreign key. Writing the name and house in every goal would repeat them (Chirag Shah three times), and if one copy were changed or misspelled, the copies would disagree; the ID also tells apart two players with the same name.

Marking scheme
  • i. Dawa Sherpa and Firoj Ansari.
  • ii. The rows (3, 3) and (2, 2).
  • iii. Binita Magar 5, Dawa Sherpa 27, Elina Gurung 33, in that order.
  • iv. Each fact is kept once (no repeated copies that can disagree), linked by the foreign key.
15.
[4]

A dairy cooperative in Panauti records the milk each farmer brings one morning in milk.csv:

milk.csv

farmer,village,litersSarita,Panauti,12Ram,Panauti,9Kamala,Dhulikhel,15Bishnu,Dhulikhel,11Gita,Panauti,-Hari,Dhulikhel,14 L

A program reads it:

import pandas as pd milk = pd.read_csv("milk.csv")print(milk.dtypes)print(milk["liters"].sum())
  • i.What type does dtypes give for the liters column, and why? (1)
  • ii.What does line 5 print, and why is it not a total? (1)
  • iii.Gita brought no milk that morning that was recorded: the clerk wrote “-”. When the column is cleaned, should her value become 0 or be left missing? Give a reason. (1)
  • iv.After cleaning (Hari’s 14 L becomes 14, and Gita’s value is left missing), what does milk.groupby("village")["liters"].median() give? (1)
Answer
  • i.str (text). pandas makes a column numbers only if every value reads as a number, and - and 14 L don’t.
  • ii.It joins the strings end to end, as + does for text:

Output

1291511-14 L

That is not a sum: adding text sticks it together. Nothing warns you, which is why you look at dtypes before working with a column.

  • iii.Left missing. “-” means nobody knows the amount, not that she brought none; writing 0 would pull Panauti’s average and median down with a number nobody measured. (If the clerk is asked and she really brought none, then 0 is right.)
  • iv.Each village’s middle value, the missing one left out:

Output

villageDhulikhel    14.0Panauti      10.5Name: liters, dtype: float64

Dhulikhel: 11, 14, 15, so 14. Panauti: 9 and 12 (Gita’s gap is skipped), so the middle is (9 + 12) ÷ 2 = 10.5.

Marking scheme
  • i. str (text), because - and 14 L aren’t numbers.
  • ii. The values joined as one string, 1291511-14 L, because adding text joins it.
  • iii. Left missing, because “-” is unknown, not zero, and a 0 would pull the village’s figures down.
  • iv. Dhulikhel 14 and Panauti 10.5.
16.
[4]

Read the given passage and answer the questions that follow.

Tsering is trekking up the Langtang valley with no mobile signal, yet the map on her phone still shows a blue dot on the trail. Her phone works out where she is from signals sent by satellites about 20,000 km above the Earth, each carrying atomic clocks; before launch, those clocks were set to tick slightly slow. Back in Syabrubesi, with mobile data again, her phone finds its place in a second or two.

  • i.What two things does each satellite’s signal tell her phone? (1)
  • ii.Her phone sends nothing to the satellites. How can it still find where it is, with no mobile signal? (1)
  • iii.Why are the satellites’ clocks set to tick slightly slow before launch? (1)
  • iv.Why does the phone find its place faster once it has mobile data? (1)
Answer
  • i.Where the satellite is at that moment, and the exact time the signal left it.
  • ii.GPS only needs the phone to listen. It notes when each signal arrives, works out how long it took, and turns the time into a distance (speed of light × travel time). From its distances to several satellites (four, one for its own clock’s error) it works out where it is: trilateration. No mobile network is used.
  • iii.Because of Einstein’s relativity: up there gravity is weaker, which makes the satellites’ clocks run fast, and their speed makes them run a little slow; together they would gain about 38 microseconds a day on clocks on the ground. Left alone, that would move every position by about 10 km a day; ticking slightly slow cancels it.
  • iv.With mobile data the phone downloads where the satellites are (assisted GPS), so it doesn’t have to wait to hear that from the satellites’ own slow signals.
Marking scheme
  • i. Its position and the exact time the signal was sent.
  • ii. It only listens: travel time × speed of light gives each distance, and the distances give its place (trilateration).
  • iii. Relativity makes the satellites’ clocks gain on clocks on the ground (about 38 µs a day), which would spoil positions by kilometers.
  • iv. It downloads where the satellites are over mobile data (assisted GPS) instead of waiting for the satellites’ signals.

Practical exam

25 marks

Marked by the school. Work alone at a computer, with no internet and no AI, in front of the teacher, for 1 hour 30 minutes. Write and run each program, show it working, and answer the teacher’s questions. On this page, press Edit on a program to type in it, and Run to run it.

P1.
[7]

Late books. The ward library charges for late books: Rs 5 a day for each of the first 7 days late, then Rs 10 a day, but never more than Rs 200 for one book.

At the computer, make two files in one folder:

  • library.py, a module with a function late_fee(days) that returns the fee for a book returned that many days late, with tests at the end that run only when library.py itself is run;
  • main.py, which imports it, asks how many days late each of a member’s 3 books is, and prints the total to pay.

Run library.py, then main.py with 4, 9 and 45 days. (On this page, try your function in the box below first.)

# Try your late_fee function heredef late_fee(days):    return 0
Answer

library.py

"""The ward library's late fees.""" MAX_FEE = 200    # rupees, for one book  def late_fee(days):    """The fee in rupees for a book returned this many days late."""    if days <= 7:        fee = days * 5    else:        fee = 7 * 5 + (days - 7) * 10    return min(fee, MAX_FEE)  if __name__ == "__main__":    # tests at the edges: on time, the 7th and 8th days, and the cap    print(late_fee(0), "should be 0")    print(late_fee(7), "should be 35")    print(late_fee(8), "should be 45")    print(late_fee(30), "should be 200")

Run by itself, library.py prints its tests:

Output

0 should be 035 should be 3545 should be 45200 should be 200

main.py

import library total = 0for book in range(1, 4):    days = int(input(f"Book {book}: how many days late? "))    total = total + library.late_fee(days)print("Total to pay: Rs", total)

Output

Book 1: how many days late? 4Book 2: how many days late? 9Book 3: how many days late? 45Total to pay: Rs 275

4 days: Rs 20. 9 days: Rs 35 + 2 × 10 = Rs 55. 45 days: Rs 35 + 38 × 10 = Rs 415, capped at Rs 200. Together Rs 275.

Marking scheme
  • library.py has a function late_fee(days) that returns the fee (it doesn’t print it).
  • Rs 5 a day up to 7 days.
  • Rs 35 for the first week plus Rs 10 for each day after it.
  • Never more than Rs 200.
  • Tests under if __name__ == "__main__": at the edges (such as 7, 8 and a long delay), which don’t run when it is imported.
  • main.py imports library and uses the returned values to add up the 3 books, asking with int(input(…)).
  • Runs both in front of the teacher, and 4, 9, 45 give Rs 275.
P2.
[6]

The winter bird count. The eco club counted birds at three places around the valley. This program makes their database and gives you ask(), which prints what a query gives. Run it, then add one ask() for each question:

  • i.Every sighting at Shivapuri: the bird_id and how many were seen, the most first. (2)
  • ii.How many birds were counted at each place, in all: one row per place. (2)
  • iii.The names of the birds seen at Taudaha, with how many of each, the most first. (2)
import sqlite3 db = sqlite3.connect(":memory:")db.execute("CREATE TABLE birds (bird_id INTEGER PRIMARY KEY, name TEXT, kind TEXT)")db.execute("""CREATE TABLE sightings (sighting_id INTEGER PRIMARY KEY,              bird_id INTEGER REFERENCES birds(bird_id),              place TEXT, day TEXT, how_many INTEGER)""")db.executemany("INSERT INTO birds VALUES (?, ?, ?)", [    (1, "Spiny Babbler", "resident"),    (2, "Red-vented Bulbul", "resident"),    (3, "Common Myna", "resident"),    (4, "Ruddy Shelduck", "winter visitor"),    (5, "Great Barbet", "resident"),    (6, "Oriental Magpie-Robin", "resident"),])db.executemany("INSERT INTO sightings VALUES (?, ?, ?, ?, ?)", [    (1, 2, "Phulchowki", "2026-01-10", 4),    (2, 5, "Phulchowki", "2026-01-10", 2),    (3, 1, "Phulchowki", "2026-01-10", 1),    (4, 4, "Taudaha", "2026-01-11", 23),    (5, 3, "Taudaha", "2026-01-11", 6),    (6, 2, "Taudaha", "2026-01-11", 3),    (7, 6, "Shivapuri", "2026-01-12", 2),    (8, 5, "Shivapuri", "2026-01-12", 3),    (9, 2, "Shivapuri", "2026-01-12", 5),    (10, 1, "Shivapuri", "2026-01-12", 1),])  def ask(sql):    """Print each row the query gives, then a blank line."""    for row in db.execute(sql):        print(row)    print()  ask("SELECT * FROM birds")
Answer

The same program, with these three lines in place of the last one:

import sqlite3 db = sqlite3.connect(":memory:")db.execute("CREATE TABLE birds (bird_id INTEGER PRIMARY KEY, name TEXT, kind TEXT)")db.execute("""CREATE TABLE sightings (sighting_id INTEGER PRIMARY KEY,              bird_id INTEGER REFERENCES birds(bird_id),              place TEXT, day TEXT, how_many INTEGER)""")db.executemany("INSERT INTO birds VALUES (?, ?, ?)", [    (1, "Spiny Babbler", "resident"),    (2, "Red-vented Bulbul", "resident"),    (3, "Common Myna", "resident"),    (4, "Ruddy Shelduck", "winter visitor"),    (5, "Great Barbet", "resident"),    (6, "Oriental Magpie-Robin", "resident"),])db.executemany("INSERT INTO sightings VALUES (?, ?, ?, ?, ?)", [    (1, 2, "Phulchowki", "2026-01-10", 4),    (2, 5, "Phulchowki", "2026-01-10", 2),    (3, 1, "Phulchowki", "2026-01-10", 1),    (4, 4, "Taudaha", "2026-01-11", 23),    (5, 3, "Taudaha", "2026-01-11", 6),    (6, 2, "Taudaha", "2026-01-11", 3),    (7, 6, "Shivapuri", "2026-01-12", 2),    (8, 5, "Shivapuri", "2026-01-12", 3),    (9, 2, "Shivapuri", "2026-01-12", 5),    (10, 1, "Shivapuri", "2026-01-12", 1),])  def ask(sql):    """Print each row the query gives, then a blank line."""    for row in db.execute(sql):        print(row)    print()  ask("SELECT bird_id, how_many FROM sightings WHERE place = 'Shivapuri' ORDER BY how_many DESC")ask("SELECT place, SUM(how_many) FROM sightings GROUP BY place")ask("""SELECT birds.name, sightings.how_many FROM sightings       JOIN birds ON sightings.bird_id = birds.bird_id       WHERE sightings.place = 'Taudaha' ORDER BY sightings.how_many DESC""")

Output

(2, 5)(5, 3)(6, 2)(1, 1) ('Phulchowki', 7)('Shivapuri', 11)('Taudaha', 32) ('Ruddy Shelduck', 23)('Common Myna', 6)('Red-vented Bulbul', 3)

(The counts are made up for this paper.)

Marking scheme
  • i. WHERE place = 'Shivapuri', selecting bird_id and how_many.
  • i. ORDER BY how_many DESC, giving 5, 3, 2, 1.
  • ii. GROUP BY place.
  • ii. SUM(how_many) for each place: Phulchowki 7, Shivapuri 11, Taudaha 32.
  • iii. A JOIN of sightings and birds ON sightings.bird_id = birds.bird_id.
  • iii. Only Taudaha, the most first: Ruddy Shelduck 23, Common Myna 6, Red-vented Bulbul 3.
P3.
[6]

The fire drill. In a fire drill, every class must leave the school by the fewest doorways. The dictionary below shows which places of the school have a doorway between them (the store room is kept locked). Write a function fewest_steps(graph, start, goal) that returns the route with the fewest doorways as a list of places, or None if there is no way. Then print the route and the number of doorways:

  • from the Science lab to the Gate;
  • from the Canteen to the Computer lab;
  • from the Store room to the Gate (print “No way out” if there is none).
school = {    "Gate": ["Playground", "Office"],    "Playground": ["Gate", "Hall", "Canteen", "Garden"],    "Office": ["Gate", "Hall"],    "Hall": ["Office", "Playground", "Library", "Computer lab"],    "Library": ["Hall", "Science lab"],    "Computer lab": ["Hall", "Science lab"],    "Science lab": ["Library", "Computer lab"],    "Canteen": ["Playground", "Garden"],    "Garden": ["Playground", "Canteen"],    "Store room": [],} # Write fewest_steps here
Answer
school = {    "Gate": ["Playground", "Office"],    "Playground": ["Gate", "Hall", "Canteen", "Garden"],    "Office": ["Gate", "Hall"],    "Hall": ["Office", "Playground", "Library", "Computer lab"],    "Library": ["Hall", "Science lab"],    "Computer lab": ["Hall", "Science lab"],    "Science lab": ["Library", "Computer lab"],    "Canteen": ["Playground", "Garden"],    "Garden": ["Playground", "Canteen"],    "Store room": [],}  def fewest_steps(graph, start, goal):    """The route from start to goal with the fewest steps, or None."""    came_from = {start: None}    to_visit = [start]    while len(to_visit) > 0:        place = to_visit.pop(0)        if place == goal:            route = []            while place is not None:                route.append(place)                place = came_from[place]            route.reverse()            return route        for nxt in graph[place]:            if nxt not in came_from:                came_from[nxt] = place                to_visit.append(nxt)    return None  for start, goal in [("Science lab", "Gate"), ("Canteen", "Computer lab"), ("Store room", "Gate")]:    route = fewest_steps(school, start, goal)    if route is None:        print(start, "to", goal + ": No way out")    else:        print(start, "to", goal + ":", " → ".join(route), "(" + str(len(route) - 1), "doorways)")

Output

Science lab to Gate: Science lab → Library → Hall → Office → Gate (4 doorways)Canteen to Computer lab: Canteen → Playground → Hall → Computer lab (3 doorways)Store room to Gate: No way out

Through the Computer lab, or through the Playground instead of the Office, is also 4 doorways: any route of 4 is right.

Marking scheme
  • A function with the graph, start and goal, that starts its list (and its notes) with the start.
  • A queue: takes from the front with pop(0) and adds to the back with append().
  • Marks a place as seen (in came_from) when it is added, so none is added twice.
  • Stops at the goal and follows the notes back to the start, then reverses them.
  • Prints each route and the number of doorways (one less than the places): 4 and 3.
  • Returns None when the list runs out, and the program prints “No way out” for the store room.
P4.
[6]

Viva. The teacher asks each student about their own work, for example:

  • i.In library.py, why did you test 7 and 8 days? What would happen to main.py if your tests were not under if __name__ == "__main__":? (2)
  • ii.In your bird count, why does the third query need a JOIN, and what does its ON part do? (2)
  • iii.In fewest_steps, what would change if you wrote to_visit.pop() instead of to_visit.pop(0)? (2)
Answer
  • i.The rule changes between the 7th and the 8th day, and mistakes hide at the edges (< instead of <=, an off-by-one in the days after the first week), so testing both sides of the edge catches them. Without the if, the tests would run every time main.py imports library, printing their lines in the middle of the member’s bill.
  • ii.The bird’s name is in the birds table, but the place is in sightings: the JOIN puts each sighting beside its bird. ON says which rows go together: a sighting’s bird_id (the foreign key) must equal the bird’s bird_id (its primary key).
  • iii.pop() takes the newest place from the back: the list becomes a stack, and the search dives down one path first (depth-first). It still finds a way out if there is one, but not always the one with the fewest doorways, because it no longer searches in rings.
Marking scheme
  • i. The fee rule changes between 7 and 8 days, and mistakes hide at the edges.
  • i. Without the if, the tests would run whenever main.py imports the module.
  • ii. The names are in another table, so the JOIN brings each sighting’s bird’s name to it.
  • ii. ON matches the foreign key (sightings.bird_id) to the primary key (birds.bird_id).
  • iii. pop() takes the newest place (a stack), so it searches depth-first.
  • iii. Then the route found may not have the fewest doorways.

Your score

0 / 50 theory

0 / 25 practical

29 questions not marked yet

Section A–Full marks 10
Section B–Full marks 20
Section C–Full marks 20
Practical exam–Full marks 25

Marks lost, by unit

Mark a question to see your score here.

Score 0 of 0 0 of 29 marked Time left: 2:00:00