Level 2 — RecallPython Intermediate

Python Intermediate

30 minutes40 marksprintable — key stays hidden on paper

Topic: Modules, Standard Library, File I/O, Exceptions, Decorators, Generators, Iterators, Regex, venv Level: 2 — Recall & Standard Problems Time Limit: 30 minutes Total Marks: 40


Instructions: Answer all questions. Write code exactly as required. Marks are shown against each question.


Q1. Modules & aliasing (4 marks)

(a) Write a single line that imports the sqrt and pi names directly from the math module. (2) (b) Write a single line that imports numpy under the alias np. (2)


Q2. Standard library (4 marks)

State which standard-library module provides each of the following, and give the fully-qualified call: (a) A function returning the current date and time. (2) (b) A container that counts hashable objects (frequency counting). (2)


Q3. File I/O — open modes (5 marks)

State the effect of each open mode when passed to open(): (a) 'r' (b) 'w' (c) 'a' (d) 'rb' (e) 'x'(1 each)


Q4. File I/O — reading (4 marks)

Given a text file, explain the difference between the return values of read(), readline(), and readlines(). (3) Then write the type returned by readlines(). (1)


Q5. Context managers (4 marks)

(a) Write a with statement that opens data.txt for writing as file object f. (2) (b) Name the two special methods a class must implement to be usable as a context manager. (2)


Q6. Exception handling (6 marks)

(a) Write a try/except/else/finally block that converts input string s to an int n, catches ValueError printing "bad", prints "ok" in the else, and prints "done" in finally. (4) (b) State when the else block of a try statement runs. (2)


Q7. Raising & custom exceptions (4 marks)

(a) Write one line that raises a ValueError with message "negative". (2) (b) Define a custom exception class MyError that inherits from Exception. (2)


Q8. Decorators (4 marks)

Complete the decorator so it prints "call" before invoking the wrapped function and preserves the function's metadata using functools.wraps:

import functools
def log(fn):
    @________________
    def wrapper(*args, **kwargs):
        ________________
        return fn(*args, **kwargs)
    return wrapper

Fill in the two blanks. (4)


Q9. Generators & iterators (3 marks)

(a) Write a generator function count_up(n) that yields 0,1,...,n-1. (2) (b) Which exception does next() raise when an iterator is exhausted? (1)


Q10. Regular expressions (2 marks)

Write a re.findall call that returns all sequences of one-or-more digits found in string text. (2)

Answer keyMark scheme & solutions

Q1 (4 marks)

(a) from math import sqrt, pi — correct syntax (2); from…import pulls specific names into namespace. (b) import numpy as np(2); as creates an alias.

Q2 (4 marks)

(a) datetime module → datetime.datetime.now() (2) (accept datetime.now() after from datetime import datetime). (b) collections module → collections.Counter(iterable) (2).

Q3 (5 marks)

(a) 'r' — read (default); file must exist, error if not. (1) (b) 'w' — write; truncates existing file to empty, creates if absent. (1) (c) 'a' — append; writes to end, creates if absent, keeps existing content. (1) (d) 'rb' — read in binary mode; returns bytes. (1) (e) 'x' — exclusive creation; fails with FileExistsError if file exists. (1)

Q4 (4 marks)

  • read() → returns the entire file as one string. (1)
  • readline() → returns the next single line (including \n). (1)
  • readlines() → returns all lines as a list of strings. (1)
  • Type returned by readlines(): list. (1)

Q5 (4 marks)

(a)

with open('data.txt', 'w') as f:
    ...

(2) — correct with/as form. (b) __enter__ and __exit__. (2) (1 each)

Q6 (6 marks)

(a)

try:
    n = int(s)
except ValueError:
    print("bad")
else:
    print("ok")
finally:
    print("done")

Marks: try+int (1), except ValueError+print (1), else (1), finally (1). (b) The else block runs only if the try block completed without raising any exception. (2)

Q7 (4 marks)

(a) raise ValueError("negative") (2). (b)

class MyError(Exception):
    pass

(2) — inherits from Exception.

Q8 (4 marks)

Blank 1: functools.wraps(fn) (2) — preserves __name__, __doc__. Blank 2: print("call") (2).

Q9 (3 marks)

(a)

def count_up(n):
    for i in range(n):
        yield i

(2). (b) StopIteration. (1)

Q10 (2 marks)

re.findall(r'\d+', text) (2)\d+ matches one-or-more digits; returns list of matches.

[
  {"claim":"re.findall matches all digit runs", "code":"import re; result = (re.findall(r'\\d+','a12b3c456')==['12','3','456'])"},
  {"claim":"Counter counts frequencies", "code":"from collections import Counter; result = (Counter('aabbbc')['b']==3)"},
  {"claim":"count_up generator yields 0..n-1", "code":"\ndef count_up(n):\n    for i in range(n):\n        yield i\nresult = (list(count_up(4))==[0,1,2,3])"},
  {"claim":"readlines-style split returns list", "code":"result = (type('a\\nb\\n'.splitlines())==list and 'a\\nb\\nc'.count(chr(10))==2)"}
]