Final Exam Model Paper 5
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 = 101. Choose the correct option for each of the following questions.
After import statistics, what does dir(statistics) show?
Pick an answer to see why.
Heavy snow closes a school in Baitadi for a day, and the news goes out by a phone tree: the class teacher calls some parents, who each call others. Who calls whom:
calls = { "Teacher": ["Arun", "Binu", "Chandra"], "Arun": ["Dipesh", "Elina"], "Binu": ["Furba"], "Chandra": [], "Dipesh": ["Gopal"], "Elina": [], "Furba": ["Hira", "Ishan"], "Gopal": [], "Hira": [], "Ishan": [],}In each round, everyone who already knows makes all their calls. After how many rounds does everyone know?
Pick an answer to see why.
Which of these is a one-to-many relationship?
Pick an answer to see why.
A shop in Bajhang records its sales each day of Mangsir. Most days are between Rs 8,000 and Rs 15,000, but one day shows Rs 95,000. Kiran wants to delete that day as an outlier before working out the month’s average. Which judgment is right?
Pick an answer to see why.
A shop’s weighing scale weighs from 0 to 30 kg in steps of 5 g. A bag of rice weighs 12.3456 kg. What does the scale show?
Pick an answer to see why.
On a Linux computer, Sita has a file Notes.txt. She types cat notes.txt. What happens?
Pick an answer to see why.
What are a large language model’s parameters?
Pick an answer to see why.
A chatbot that can search the web tells Prakash that his ward office opens at 9 a.m. It opens at 10 a.m.: the chatbot used an old page from the office’s former website. Why could this happen?
Pick an answer to see why.
Someone could copy encrypted messages today, store them, and read them in twenty years with a quantum computer. Which of these most needs post-quantum encryption now?
Pick an answer to see why.
Anisha, in Jajarkot, is looking for online design work. Which of these offers is the most likely to be real?
Pick an answer to see why.
Section B
10 × 2 = 20Write short answers to the following questions.
Pasang, in Bajura, is training for the 1,600 m race: four laps of a 400 m track. His coach wrote a function for his lap times, in seconds:
def first_slow(laps, target): for i in range(len(laps)): if laps[i] > target: return i + 1 return 0 print(first_slow([88, 91, 95, 99], 94))print(first_slow([88, 90, 92, 93], 94))- i.Write the output.
- ii.Say in one sentence what the function does. Why does it
return 0at the end?
Answer
i. In the first race the third lap, 95 seconds, is the first one over 94, and return ends the function at once, so the fourth lap is never looked at. In the second race no lap is over 94:
Output
30ii. It returns the number of the first lap slower than the target (counting from 1), and 0 if every lap was on time. The last line runs only if the loop finished without finding a slow lap, so 0 means “none”, a number no real lap can have.
Marking scheme
- i.
3and0. - ii. It returns the number of the first lap over the target; 0 when no lap is, reached only after the loop finds none.
Gita asks a map app for the shortest way from her home in Kalanki to a shop in Koteshwor, across Kathmandu.
- i.A search that visits places nearest first spreads out equally in every direction. Why does that waste work here?
- ii.How does a search that aims at the goal (A*) save work?
Answer
- i.Nearest first visits every place closer to Kalanki than Koteshwor is, in all directions: it would work through roads toward Thankot and Kirtipur, away from the shop, as carefully as those toward it, before it reached Koteshwor.
- ii.It prefers places that are closer in a straight line to the goal, so it searches mostly in the direction of Koteshwor and visits far fewer places in the wrong direction. It still finds the shortest way, with much less work.
Marking scheme
- i. It visits every place nearer than the goal in all directions, including those away from the goal.
- ii. A* prefers places closer to the goal (in a straight line), so it searches mainly toward it.
A school in Jajarkot keeps its clubs in three tables. A student can join many clubs and a club has many students, so a linking table, memberships, joins them:
- students (student_id, name, grade)
- clubs (club_id, name, teacher)
- memberships (student_id, club_id, joined)
Write an SQL query that lists the names of the clubs that student 7 has joined, in alphabetical order.
Answer
SELECT clubs.nameFROM membershipsJOIN clubs ON memberships.club_id = clubs.club_idWHERE memberships.student_id = 7ORDER BY clubs.name;Each row of memberships is one student in one club; the JOIN brings each of student 7’s rows the club’s name. (Joining students as well, to pick her by name, also works.)
Marking scheme
- A JOIN of memberships and clubs
ON memberships.club_id = clubs.club_id. WHERE memberships.student_id = 7andORDER BY clubs.name, selecting the club’s name.
After Dashain, a class was asked: “What did you spend your Dashain money on?” A program sorts the typed answers into groups:
import pandas as pd def kind(text): text = text.lower() if "book" in text: return "books" if "cloth" in text or "shoe" in text: return "clothes" if "game" in text or "phone" in text: return "games" return "other" answers = pd.Series(["New clothes", "story books", "Shoes and a book", "mobile game", "saved it", "Football shoes"])print(answers.apply(kind).value_counts())- i.Write the output.
- ii.Which answer may be in the wrong group, and why?
Answer
i. Each answer is made small-letter and checked against the rules in order:
Output
clothes 2books 2games 1other 1Name: count, dtype: int64New clothes and Football shoes are clothes; story books and Shoes and a book are books; mobile game is games; saved it is other.
ii. “Shoes and a book”: it bought both, but the books rule comes first, so it is counted as books only. Every rule, and its order, is a choice, so it should be written down beside the results (or such answers counted in both groups).
Marking scheme
- i. clothes 2, books 2, games 1, other 1.
- ii. “Shoes and a book”, put in books only because that rule is checked first.
Dawa wants to install VLC, a free media player, on the lab computers of his school in Dhankuta. His search shows, above VLC’s own website, an advert: “VLC Free Download, fast! No virus!” on a site he doesn’t know.
- i.Where should he download VLC from, and why not from the advert?
- ii.Give two things he should check or do while installing it.
Answer
- i.From its source: VLC’s own website (or the computer’s app store or package manager). “Free download” sites and adverts can give a file that someone has changed, with malware or extra programs added, and the installer would then get administrator permission to put it on every lab computer.
- ii.Any two: check that the permission box names the right publisher (the program’s maker), not “Unknown”; give administrator permission only because he trusts the source; choose the custom install and untick any extras (toolbars, “recommended” programs); compare the file’s checksum with the one on the website, if one is given.
Marking scheme
- i. From the maker’s own website (or a store or package manager), because other sites can give a changed file with malware.
- ii. Two of: the publisher’s name, administrator permission only if trusted, custom install with extras unticked, the checksum.
Anil’s home folder is /home/anil, and it holds a folder school with folders class9 and class10 inside. He types these commands, starting in his home folder:
cd school/class10cd ../class9pwdcd ../..pwd- i.What does the first
pwdprint? - ii.What does the second
pwdprint?
Answer
i. cd school/class10 goes to /home/anil/school/class10; .. goes up to school, then into class9:
Output
/home/anil/school/class9ii. ../.. goes up two levels, from class9 to school and then to anil:
Output
/home/anilMarking scheme
- i.
/home/anil/school/class9. - ii.
/home/anil.
Why is a chatbot unreliable at counting the letters in a Nepali word, or at checking whether a Nepali word is spelled correctly?
Answer
A language model never sees letters: the tokenizer cuts the text into tokens, each turned into a number, and the model works only with those numbers. A tokenizer that learned mostly from English cuts Nepali into pieces that don’t match letters, sometimes even pieces of a letter’s bytes. So the model has no direct way to see how many letters a word has, or whether a vowel sign is the right one; it predicts a likely answer, which can be wrong. A dictionary (for Nepali, the Brihat Shabdakosh) is the place to check.
Marking scheme
- The model sees tokens (numbers), not letters.
- Nepali is cut into pieces that don’t match letters, so it predicts a likely answer instead of counting or checking.
Before her exams, Anju chats every night with a chatbot. It remembers what she said earlier in the chat, says it is proud of her, and tells her it understands how she feels. She says: “It really cares about me, more than my friends do.” Judge her claim, and give her advice.
Answer
What she sees is the ELIZA effect: people tend to feel that a program that answers in a human way understands and cares, even a very simple one. The chatbot writes the likely next words after hers, and kind, caring words are likely there; it “remembers” only because her earlier messages are in its context window. Whether such a model understands anything is still argued about, but nothing here shows that it cares, and it has no life of its own in which she matters. Advice: it can help her plan revision, but she shouldn’t rely on it for her feelings or tell it private things; when she is stressed, she should talk to people, a friend, a family member or a teacher, who really can care.
Marking scheme
- A judgment with a reason: the ELIZA effect, or it predicts likely (kind) words, or its memory is only the context window.
- Sensible advice: use it for study, not as a friend; don’t share private things; talk to real people.
Write any two parts of a good proposal to change a law about technology.
Answer
Any two of the seven: the problem, with evidence; the law (and the part) it changes; the change itself, in exact words; who gains and who pays; risks and safeguards; how it encourages good innovation (technology-neutral, proportionate); how we will know it worked (what is measured, and when it is reviewed).
Marking scheme
- One part: the problem with evidence, the law, the exact change, who gains and pays, risks and safeguards, good innovation, or how we will know.
- A second, different part.
A school decides to keep, forever, every student’s phone number, home address and photo in the database behind its website, “in case they are useful one day”. Judge this choice, and suggest a better one.
Answer
It is a poor choice. Data kept is data that can leak, be stolen, or be used for something nobody agreed to, and the risk grows with time: a list kept for twenty years has twenty years in which to leak, long after the students have left. “In case they are useful” is no purpose. Keeping it on the website’s database also puts it on the computer that the whole internet can reach.
Better: keep only what the school needs, for as long as it needs it; say why each item is kept; delete it at a set time (for example, a year after a student leaves); and keep it on a protected system that only the people who need it can open.
Marking scheme
- A judgment with a reason: the longer data is kept, the longer it can leak or be misused, and there is no purpose.
- A better choice: keep only what is needed, delete it at a set time, protect who can see it.
Section C
5 × 4 = 20Write long answers to the following questions.
A shop in Darchula sells mobile data packs. Its current packs, which change every few months (the shop counts 1 GB as 1,000 MB):
PACKS = { "Day 300 MB": (300, 30), # (MB, rupees) "Week 1 GB": (1000, 99), "Week 3 GB": (3000, 249), "Month 10 GB": (10000, 599),}- i.Write a module, datapacks.py, with a function
cheapest_pack(mb, packs)that returns the name of the cheapest pack with at leastmbMB, orNoneif no pack is big enough, with a docstring. The packs are passed in, so that the module needn’t change when the prices do. (2) - ii.Add tests at the end of the module that run only when datapacks.py itself is run, including a pack exactly the size needed and a need too big for any pack. (1)
- iii.Write a separate program with the PACKS above that imports the module and prints the best pack, and its price, for customers who need 800 MB, 5,000 MB and 20,000 MB. (1)
Answer
i. and ii.
datapacks.py
"""Choosing a data pack.""" def cheapest_pack(mb, packs): """The name of the cheapest pack in packs ({name: (MB, rupees)}) with at least mb MB, or None if no pack is big enough.""" best = None for name in packs: size, price = packs[name] if size >= mb: if best is None or price < packs[best][1]: best = name return best if __name__ == "__main__": test_packs = {"Small": (500, 50), "Big": (2000, 150)} print(cheapest_pack(300, test_packs), "should be Small") print(cheapest_pack(500, test_packs), "should be Small") print(cheapest_pack(501, test_packs), "should be Big") print(cheapest_pack(5000, test_packs), "should be None")iii.
import datapacks PACKS = { "Day 300 MB": (300, 30), # (MB, rupees) "Week 1 GB": (1000, 99), "Week 3 GB": (3000, 249), "Month 10 GB": (10000, 599),} for need in [800, 5000, 20000]: name = datapacks.cheapest_pack(need, PACKS) if name is None: print(need, "MB: no pack is big enough") else: print(need, "MB:", name, "for Rs", PACKS[name][1])Output
800 MB: Week 1 GB for Rs 995000 MB: Month 10 GB for Rs 59920000 MB: no pack is big enoughThe function keeps the cheapest pack found so far among those big enough. Because the packs are a parameter, the shop changes only the dictionary in its program when prices change: the module’s interface stays the same. Any clear names are fine. (The packs are made up for this paper.)
Marking scheme
- i. A function
cheapest_pack(mb, packs)with a docstring that looks only at packs with at leastmbMB. - i. Returns (doesn’t print) the name of the cheapest of those, or None if there is none.
- ii. Tests under
if __name__ == "__main__":including a pack exactly the size needed and a need too big, with what each should give. - iii. A program that imports the module, passes PACKS, and prints Week 1 GB (Rs 99), Month 10 GB (Rs 599) and “no pack” for 20,000 MB.
For sports day in Jajarkot, an obstacle maze is marked out in squares on the ground. A runner starts at S, must reach E, and can step to the square above, below, left or right, but never onto a wall (#).
| col 0 | col 1 | col 2 | col 3 | col 4 | |
|---|---|---|---|---|---|
| row 0 | S | # | |||
| row 1 | # | # | # | ||
| row 2 | |||||
| row 3 | # | # | # | ||
| row 4 | # | E |
- i.Search in rings from S, as a paint bucket fills a picture. Copy the grid and write in each open square the fewest steps from S. (2)
- ii.In how few steps can the runner reach E? Write one route, as the squares (row, col) in order. (1)
- iii.Explain why no route from S to E on this grid could ever be shorter than that, even if every wall were taken away. (1)
Answer
i. Each square is a node, joined to its open neighbors; breadth-first search from S numbers them ring by ring:
| col 0 | col 1 | col 2 | col 3 | col 4 | |
|---|---|---|---|---|---|
| row 0 | 0 | 1 | 2 | # | 8 |
| row 1 | # | # | 3 | # | 7 |
| row 2 | 6 | 5 | 4 | 5 | 6 |
| row 3 | 7 | # | # | # | 7 |
| row 4 | 8 | 9 | 10 | # | 8 |
- ii.8 steps. For example (0,0) → (0,1) → (0,2) → (1,2) → (2,2) → (2,3) → (2,4) → (3,4) → (4,4).
- iii.E is 4 rows down and 4 columns across from S, and each step moves only one row or one column. So every route needs at least 4 + 4 = 8 steps; the walls can make a route longer, never shorter. This route has no wasted step.
Marking scheme
- i. The numbers along the way to E correct (0, 1, 2, 3, 4, 5, 6, 7, 8 down the right side).
- i. The rest correct: row 2’s left side 5, 6; then 7, 8, 9, 10 round the bottom left, and 8 at the top right.
- ii. 8 steps, with a correct route.
- iii. E is 4 rows and 4 columns away, and each step moves one, so at least 8.
A school office in Arghakhanchi keeps its lost-and-found register in a table, lost_found. claimed_by is empty (NULL) until the owner collects the item.
| item_id | item | color | found_on | claimed_by |
|---|---|---|---|---|
| 1 | Water bottle | blue | 2026-07-03 | NULL |
| 2 | Sweater | red | 2026-07-03 | Anish |
| 3 | Water bottle | blue | 2026-07-10 | Priya |
| 4 | Umbrella | black | 2026-07-15 | NULL |
| 5 | Pencil box | blue | 2026-07-21 | NULL |
| 6 | Sweater | black | 2026-08-02 | NULL |
Write what each query gives.
- i.
SELECT item, found_on FROM lost_found WHERE color = 'blue' AND claimed_by IS NULL;(1) - ii.
SELECT color, COUNT(*) FROM lost_found GROUP BY color HAVING COUNT(*) > 1;(1) - iii.
SELECT item FROM lost_found WHERE found_on < '2026-07-15' ORDER BY found_on DESC LIMIT 1;(1) - iv.A new clerk records a blue cap with the color typed as “Blue”. Will query i find it? What rule in the table would stop this happening? (1)
Answer
i. The blue items nobody has collected:
| item | found_on |
|---|---|
| Water bottle | 2026-07-03 |
| Pencil box | 2026-07-21 |
ii. One row per color, kept only if it has more than one item; red has only one:
| color | COUNT(*) |
|---|---|
| black | 2 |
| blue | 3 |
- iii.Items found before 15 July are rows 1, 2 and 3; the latest of them, alone, is the Water bottle found on 2026-07-10. Dates written year-month-day sort and compare correctly as text.
- iv.No. Text must match exactly, and “Blue” with a capital B is not equal to
'blue', so the cap is left out of every search for blue things. A list check in the table, such asCHECK (color IN ('black', 'blue', 'red', …)), would refuse “Blue” (the form could also offer the colors to choose from, instead of typing).
Marking scheme
- i. Water bottle (2026-07-03) and Pencil box (2026-07-21).
- ii. black 2 and blue 3 (red left out by HAVING).
- iii. Water bottle (the one found on 2026-07-10).
- iv. No, text must match exactly (“Blue” is not
'blue'); a list check,CHECK (color IN (…)), would refuse it.
Dipika keeps the runs she scored in each innings for her school’s girls’ cricket team in innings.csv. Her coach looks at them with pandas:
innings.csv
match,runs1,122,493,44,315,206,77,178,1109,2410,1511,912,3813,28import pandas as pd innings = pd.read_csv("innings.csv")print(innings["runs"].describe().round(1))Output
count 13.0mean 28.0std 27.8min 4.025% 12.050% 20.075% 31.0max 110.0Name: runs, dtype: float64- i.What do
countand50%tell the coach? (1) - ii.Why is the mean (28) so much higher than the median (20)? Which better describes a usual innings? (1)
- iii.What do the 25% and 75% values tell the coach? (1)
- iv.Another girl in the team also has a mean of 28, but a standard deviation of 6. What is different about her scoring? (1)
Answer
- i.count: Dipika batted in 13 innings (13 values). 50% is the median: in half her innings she scored 20 or fewer, and in half 20 or more.
- ii.One innings of 110, far above the rest (an outlier), pulls the mean up; the median, the middle value, isn’t moved by how big it was. So the median, 20, describes a usual innings better.
- iii.A quarter of her innings were 12 runs or fewer, and three quarters 31 or fewer: the middle half of her innings were between 12 and 31 runs.
- iv.Her scores are much closer to her mean: most of her innings are near 28, so she is a steadier scorer. Dipika’s large standard deviation (27.8) shows her scores spread widely, from 4 to 110.
Marking scheme
- i. 13 innings; the median, 20: half her innings were below it.
- ii. The 110 (an outlier) pulls the mean up; the median describes a usual innings better.
- iii. The quartiles: the middle half of her innings were between 12 and 31.
- iv. A smaller standard deviation: her scores stay closer to 28 (steadier).
Read the given passage and answer the questions that follow.
For sports day, the computer club of a school in Bajura built a timer for the 100 m race. At the finish line, a light sensor faces a small lamp across the track; when a runner breaks the beam, the light on the sensor drops. A small computer reads the sensor 1,000 times a second through its analog-to-digital converter, and notes the time when the reading drops. The results go to the teacher’s laptop over Wi-Fi. In the results, one runner’s time is 0.4 seconds.
- i.What does a sensor do, and what does the analog-to-digital converter do? (1)
- ii.What is the timer’s sampling rate, and why must it be high for a race? (1)
- iii.What is the difference between the timer’s resolution and its accuracy? (1)
- iv.What should be done with the time of 0.4 seconds? (1)
Answer
- i.A sensor turns something in the world (here, light) into an electrical signal; the analog-to-digital converter turns that signal into numbers the computer can work with.
- ii.1,000 readings a second. Runners finish fractions of a second apart and move several meters each second, so a slow sampling rate would miss the moment the beam is broken and couldn’t tell close runners apart; at 1,000 a second the moment is known to a thousandth of a second.
- iii.Resolution is the smallest change it can show: here a thousandth of a second. Accuracy is how close its time is to the true time: if the start signal reaches the timer late, every time can be wrong by far more than a thousandth, however fine the resolution.
- iv.It is an impossible value: nobody runs 100 m in 0.4 seconds, so something else broke the beam (a hand, a bird, a falling leaf). It must not be used as the runner’s time: mark it as missing (keeping the original log), and take the time from another record, such as a teacher’s stopwatch.
Marking scheme
- i. A sensor turns light (the world) into a signal; the ADC turns the signal into numbers.
- ii. 1,000 a second; runners finish fractions of a second apart.
- iii. Resolution: the smallest change it shows; accuracy: how close to the true value.
- iv. Impossible, so an error: don’t use it, mark it missing and time the runner another way.
Practical exam
25 marksMarked 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.
Under 16. An under-16 football tournament in Darchula begins on 15 January 2027. A player may play only if they are under 16 on that day: a player whose 16th birthday is on that day, or before it, may not.
At the computer, make two files in one folder:
- players.py, a module with two functions, each of which returns its answer:
age_on(born, day), a person’s age in whole years on a day (both aredates fromdatetime), andeligible(born),Trueif a player born on that date may play; with tests at the end that run only when players.py itself is run; - main.py, which imports it, asks 3 players’ dates of birth, typed as year-month-day (such as 2011-03-25), and prints each player’s age on the first day and whether they may play.
Run players.py, then main.py with 2011-01-15, 2011-01-16 and 2013-06-30. (On this page, try your functions in the box below first.)
# Try your functions herefrom datetime import date def age_on(born, day): return 0Answer
players.py
"""Who may play in the under-16 tournament.""" from datetime import date FIRST_DAY = date(2027, 1, 15)AGE_LIMIT = 16 def age_on(born, day): """Age in whole years, on day, of someone born on born.""" age = day.year - born.year if (day.month, day.day) < (born.month, born.day): age = age - 1 # this year's birthday hasn't come yet return age def eligible(born): """True if a player born on born is under 16 on the first day.""" return age_on(born, FIRST_DAY) < AGE_LIMIT if __name__ == "__main__": # tests at the edge: 16 on the day, a day younger, a day older print(age_on(date(2011, 1, 15), FIRST_DAY), eligible(date(2011, 1, 15)), "should be 16 False") print(age_on(date(2011, 1, 16), FIRST_DAY), eligible(date(2011, 1, 16)), "should be 15 True") print(age_on(date(2011, 1, 14), FIRST_DAY), eligible(date(2011, 1, 14)), "should be 16 False") print(age_on(date(2010, 12, 31), FIRST_DAY), "should be 16")Run by itself, players.py prints its tests:
Output
16 False should be 16 False15 True should be 15 True16 False should be 16 False16 should be 16main.py
from datetime import dateimport players for p in range(1, 4): text = input(f"Player {p}: date of birth (year-month-day)? ") year, month, day = text.split("-") born = date(int(year), int(month), int(day)) age = players.age_on(born, players.FIRST_DAY) if players.eligible(born): print("Age", age, "on the first day: may play") else: print("Age", age, "on the first day: may not play")Output
Player 1: date of birth (year-month-day)? 2011-01-15Age 16 on the first day: may not playPlayer 2: date of birth (year-month-day)? 2011-01-16Age 15 on the first day: may playPlayer 3: date of birth (year-month-day)? 2013-06-30Age 13 on the first day: may playComparing (month, day) pairs works because Python compares them item by item, as it compares words letter by letter; born.month > day.month or (born.month == day.month and born.day > day.day) does the same.
Marking scheme
- players.py has
age_on(born, day)that returns the age (it doesn’t print it). - One year less when the birthday hasn’t yet come that year (2011-01-16 gives 15, 2011-01-15 gives 16).
eligible(born)returns True only if the age on the first day is under 16, usingage_on.- The first day and the limit as constants (or clear numbers), with docstrings.
- Tests under
if __name__ == "__main__":at the edge (16 on the day, a day younger), which don’t run when it is imported. - main.py imports players, turns the typed text into a
date(split on-andint), and prints the age and the answer. - Runs both in front of the teacher: 16 (may not play), 15 (may play), 13 (may play).
The science fair. At a school’s science fair in Baitadi, visiting students vote for the projects they like. This program makes the database and gives you ask(), which prints what a query gives. Run it, then add one ask() for each question:
- i.The title and grade of the robotics projects of Grades 9 and 10, in alphabetical order of title. (2)
- ii.The project_id and number of votes of each project with at least 2 votes. (2)
- iii.The titles of the three projects with the most votes, with their votes, the most first. (2)
import sqlite3 db = sqlite3.connect(":memory:")db.execute("CREATE TABLE projects (project_id INTEGER PRIMARY KEY, title TEXT, grade INTEGER, category TEXT)")db.execute("""CREATE TABLE votes (vote_id INTEGER PRIMARY KEY, project_id INTEGER REFERENCES projects(project_id), voter_grade INTEGER)""")db.executemany("INSERT INTO projects VALUES (?, ?, ?, ?)", [ (1, "Solar water heater", 9, "energy"), (2, "Line-following robot", 10, "robotics"), (3, "Rain gauge from bottles", 8, "weather"), (4, "Robot arm from cardboard", 9, "robotics"), (5, "Biogas from kitchen waste", 10, "energy"), (6, "Talking plant pot", 8, "robotics"),])db.executemany("INSERT INTO votes VALUES (?, ?, ?)", [ (1, 2, 6), (2, 2, 7), (3, 4, 6), (4, 2, 9), (5, 5, 10), (6, 1, 8), (7, 4, 7), (8, 2, 10), (9, 5, 8), (10, 6, 6), (11, 4, 9),]) 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 projects")Answer
The same program, with these three lines in place of the last one:
import sqlite3 db = sqlite3.connect(":memory:")db.execute("CREATE TABLE projects (project_id INTEGER PRIMARY KEY, title TEXT, grade INTEGER, category TEXT)")db.execute("""CREATE TABLE votes (vote_id INTEGER PRIMARY KEY, project_id INTEGER REFERENCES projects(project_id), voter_grade INTEGER)""")db.executemany("INSERT INTO projects VALUES (?, ?, ?, ?)", [ (1, "Solar water heater", 9, "energy"), (2, "Line-following robot", 10, "robotics"), (3, "Rain gauge from bottles", 8, "weather"), (4, "Robot arm from cardboard", 9, "robotics"), (5, "Biogas from kitchen waste", 10, "energy"), (6, "Talking plant pot", 8, "robotics"),])db.executemany("INSERT INTO votes VALUES (?, ?, ?)", [ (1, 2, 6), (2, 2, 7), (3, 4, 6), (4, 2, 9), (5, 5, 10), (6, 1, 8), (7, 4, 7), (8, 2, 10), (9, 5, 8), (10, 6, 6), (11, 4, 9),]) def ask(sql): """Print each row the query gives, then a blank line.""" for row in db.execute(sql): print(row) print() ask("""SELECT title, grade FROM projects WHERE category = 'robotics' AND grade IN (9, 10) ORDER BY title""")ask("SELECT project_id, COUNT(*) FROM votes GROUP BY project_id HAVING COUNT(*) >= 2")ask("""SELECT projects.title, COUNT(*) FROM votes JOIN projects ON votes.project_id = projects.project_id GROUP BY projects.project_id ORDER BY COUNT(*) DESC LIMIT 3""")Output
('Line-following robot', 10)('Robot arm from cardboard', 9) (2, 4)(4, 3)(5, 2) ('Line-following robot', 4)('Robot arm from cardboard', 3)('Biogas from kitchen waste', 2)AND (grade = 9 OR grade = 10) works as well as IN, but only with its brackets: without them, AND is done first, and every Grade 10 project would come in, robotics or not. (The votes are made up for this paper.)
Marking scheme
- i.
WHERE category = 'robotics'and Grades 9 and 10 (IN (9, 10), or OR in brackets). - i.
ORDER BY title: Line-following robot, Robot arm from cardboard. - ii.
GROUP BY project_idwithCOUNT(*). - ii.
HAVING COUNT(*) >= 2: projects 2 (4), 4 (3), 5 (2). - iii. A JOIN of votes and projects
ON votes.project_id = projects.project_id, grouped by project. - iii.
ORDER BY COUNT(*) DESC LIMIT 3: Line-following robot 4, Robot arm from cardboard 3, Biogas from kitchen waste 2.
Family links. For a family-history project in Jajarkot, Sita draws her family as a graph: two people are joined if they are parent and child, husband and wife, or brother and sister. (Hajurba and Hajurama are her grandfather and grandmother, Kaka her father’s younger brother, Mama her mother’s brother; the neighbor has no link to the family.) Write a function fewest_steps(graph, start, goal) that returns the route with the fewest links as a list of people, or None if there is none. Then print the route and the number of links:
- from Sita to Bikash, her cousin;
- from Bikash to Mama;
- from the Neighbor to Sita (print “Not related” if there is no route).
family = { "Sita": ["Buwa", "Aama", "Ram"], "Ram": ["Buwa", "Aama", "Sita"], "Buwa": ["Sita", "Ram", "Aama", "Hajurba", "Hajurama", "Kaka"], "Aama": ["Sita", "Ram", "Buwa", "Mama"], "Hajurba": ["Buwa", "Kaka", "Hajurama"], "Hajurama": ["Buwa", "Kaka", "Hajurba"], "Kaka": ["Hajurba", "Hajurama", "Buwa", "Bikash"], "Bikash": ["Kaka"], "Mama": ["Aama"], "Neighbor": [],} # Write fewest_steps hereAnswer
family = { "Sita": ["Buwa", "Aama", "Ram"], "Ram": ["Buwa", "Aama", "Sita"], "Buwa": ["Sita", "Ram", "Aama", "Hajurba", "Hajurama", "Kaka"], "Aama": ["Sita", "Ram", "Buwa", "Mama"], "Hajurba": ["Buwa", "Kaka", "Hajurama"], "Hajurama": ["Buwa", "Kaka", "Hajurba"], "Kaka": ["Hajurba", "Hajurama", "Buwa", "Bikash"], "Bikash": ["Kaka"], "Mama": ["Aama"], "Neighbor": [],} 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: person = to_visit.pop(0) if person == goal: route = [] while person is not None: route.append(person) person = came_from[person] route.reverse() return route for nxt in graph[person]: if nxt not in came_from: came_from[nxt] = person to_visit.append(nxt) return None for start, goal in [("Sita", "Bikash"), ("Bikash", "Mama"), ("Neighbor", "Sita")]: route = fewest_steps(family, start, goal) if route is None: print(start, "to", goal + ": Not related") else: print(start, "to", goal + ":", " → ".join(route), "(" + str(len(route) - 1), "links)")Output
Sita to Bikash: Sita → Buwa → Kaka → Bikash (3 links)Bikash to Mama: Bikash → Kaka → Buwa → Aama → Mama (4 links)Neighbor to Sita: Not relatedMarking 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 withappend(). - Marks a person as seen (in
came_from) when they are 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 links (one less than the people): 3 and 4.
- Returns
Nonewhen the list runs out, and the program prints “Not related” for the neighbor.
Viva. The teacher asks each student about their own work, for example:
- i.Why did you test a player born on 2011-01-15 and one born on 2011-01-16? Why does
eligiblecallage_oninstead of working out the age again? (2) - ii.In your first query, why does
grade = 9 OR grade = 10need brackets around it? In the second, why HAVING and not WHERE? (2) - iii.What happens if you ask
fewest_steps(family, "Didi", "Sita"), when Didi isn’t in the dictionary? How could you make the function safe? (2)
Answer
- i.They are on the two sides of the edge: the first turns 16 exactly on the first day and may not play, the second is a day younger and may. A mistake such as
<=for<, or forgetting the birthday check, shows up only there. Callingage_onmeans the age is worked out in one place: if it needs fixing, it is fixed once, and both functions stay right. - ii.AND is done before OR, so without brackets the query means “(robotics and Grade 9) or any Grade 10 project”, and Grade 10’s energy project would come in. HAVING is needed because the condition is on each project’s count of votes, a value of the group, which exists only after GROUP BY; WHERE works on single rows before grouping.
- iii.The function starts with Didi, takes her from the list, and looks up
graph["Didi"], which isn’t there: the program stops with a KeyError. To make it safe, check first,if start not in graph: return None, or look up neighbors withgraph.get(person, []), which gives an empty list for a missing name.
Marking scheme
- i. 2011-01-15 and 2011-01-16 are either side of the edge (16 on the day, or not), where mistakes hide.
- i. The age is worked out in one place, so a fix is made once.
- ii. AND is done before OR, so the brackets keep the OR together (otherwise all Grade 10 projects come in).
- ii. HAVING checks a group’s count, which WHERE (on single rows, before grouping) can’t.
- iii. A KeyError when it looks up Didi’s neighbors.
- iii. Check that the start is in the graph (return None), or use
graph.get(person, []).
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.
