Exercise 0: Python warmup (not assessed)

Using the autograder

Run the following two lines, for example at the top of your notebook, to set up the grader. The questions are grouped by which section of the notes they're in, and here we're working on section ex0.

import ucamcl
GRADER = ucamcl.autograder('https://markmy.solutions', course='scicomp').subsection('ex0')

It will ask you to log in via Raven, and show you your progress so far.

Note. If you get the error message
----> 1 import ucamcl
ModuleNotFoundError: No module named 'ucamcl'
it means you need to install ucamcl. Install it from within Jupyter by running
!pip install ucamcl
It has been preinstalled on hub.cl.cam.ac.uk, but on other platforms you'll need to install it yourself. If you're running on your own machine, you only need to do this once. If you're running on Google Colab, for example, you need to do it every time you get a new server.

Here's how questions are answered. The notebook tells you the code to run, to fetch the question and submit your answers. Give it a go!

Question (q0).

q = GRADER.fetch_question('q0')
ans = ... # create a list with q.n copies of q.x
GRADER.submit_answer(q, ans)

The reason you're asked to call fetch_question is so that different students work with different parameters. You also get different parameters each time you make a fresh attempt.

Warmup questions

These are optional warmup exercises, to get you used to Python coding. For these questions there is no answer for you to submit. Insead, the autograder shows you model code. View it like this:
q = GRADER.fetch_question('q1')
print(q)
    

Question (q1) from notes 1 section 2.1. In Python, how do you ...

Question (q2) from notes 1 section 3.1. What is the difference between the two commented lines? Do they give the same result?

a = [1, 2, 'buckle my shoe']
b = (a, 3, 4, 'knock at the door')
# b[0].append('then')
# b[0] = a + ['then']
print(a, b)

Question (q3) from notes 1 section 3.5. If you go overboard with list comprehensions, your code becomes unreadable. What does the following code do? Here rooms is from the code in notes 1 section 3.4.

'\n'.join(['Room {r} has {', '.join(occs)}}' 
          for r,occs in rooms.items() if r is not None])

Question (q4) from notes 1 section 3.5. Write a single line of code to sort the names in this list

names = ['adrian', 'chloe', 'guarav', 'shay', 'alexis', 'rebecca', 'zubin']

by length, breaking ties alphabetically, using list comprehension.

_Hint: make a list of (len(name), name) then sort it, where len(s) gives the length of a string. When Python sorts a list of tuples, it uses lexicographic ordering._

Question (q5) from notes 1 section 3.5. Let $x$ be a list of numbers. Give a one-line expression to find the number of unique elements in $x$. Hint: use a dictionary comprehension to create a dictionary whose keys are elements of $x$.

Question (q6) from notes 1 section 4.1. A simple queue can be simulated by the following equations. Let $q_t$ be the queue size just before timestep $t$, let the service rate be $C$, and let $a_t$ be the amount of work arriving at timestep $t$. Then $$ q_{t+1} = \max(q_t + a_t - C, 0). $$ This is called Lindley's Recursion. Write a function sim(q0,C,a) to compute the queue sizes. It should accept an initial queue size q0 and a list a consisting of $[a_0,a_1,\dots,a_{t-1}]$, and it should return a list $[q_1,\dots,q_t]$. For example,

sim(1, 3, [4, 1, 2, 8, 2, 3, 1])

should produce the answer

[2, 0, 0, 5, 4, 4, 2]

Question (q7) from notes 1 sections 4.4. We can represent a tree as a nested list, for example

x = [1,[[2,4,3],9],[5,[6,7],8]]

Define a function maptree(f, x) which applies a function f to every leaf of the tree.