Standard 3

Sum of digits

Write digit_sum(n) that returns the sum of the digits of a non-negative whole number.

digit_sum(1234)  ->  10
digit_sum(0)     ->  0
def digit_sum(n):
    ...

What is in stock

stock maps items to quantities. Write available(stock) that returns the names of items with quantity above zero, alphabetically.

available({"milk": 0, "apple": 3, "bread": 1})  ->  ["apple", "bread"]
def available(stock):
    ...

Names by priority

orders is a list of (priority, name) tuples with distinct priorities. Write names_by_priority(orders) that returns the names ordered from lowest priority number to highest, using sorted.

names_by_priority([(3, "bread"), (1, "cake"), (2, "rolls")])  ->  ["cake", "rolls", "bread"]
def names_by_priority(orders):
    ...

Balanced brackets, two kinds

Write balanced(text) that returns True if every ( and [ is closed by the matching ) or ] in the right order, and no closer appears without an opener before it. Other characters are ignored.

balanced("([])")   ->  True
balanced("([)]")   ->  False
balanced("((")     ->  False
balanced("())")    ->  False
def balanced(text):
    ...

Boxes and crates

Write labels(n) that returns a list of strings for the numbers 1 to n: "Box" if the number is divisible by 3, "Crate" if divisible by 5, "BoxCrate" if divisible by both, otherwise the number as text.

labels(6)  ->  ["1", "2", "Box", "4", "Crate", "Box"]
def labels(n):
    ...

Merge two stock counts

Two shops report stock as dictionaries from item to quantity. Write merged(a, b) that returns one dictionary with the quantities added together for items in either.

merged({"apple": 3, "bread": 2}, {"bread": 1, "milk": 5})  ->  {"apple": 3, "bread": 3, "milk": 5}
def merged(a, b):
    ...

Average per item

history maps each item to a non-empty list of prices it has been sold at. Write averages(history) that returns a dictionary of each item's average price, rounded to two decimal places.

averages({"apple": [40, 42], "milk": [2.5]})  ->  {"apple": 41.0, "milk": 2.5}
def averages(history):
    ...

Rotate the line

Write rotate(line, k) that moves the front person of a deque to the back, k times over, and returns the same deque, changed in place. k may be larger than the line, or zero.

rotate(deque(["a", "b", "c"]), 1)  ->  deque(["b", "c", "a"])
rotate(deque(["a", "b", "c"]), 3)  ->  deque(["a", "b", "c"])
rotate(deque(["a", "b", "c"]), 4)  ->  deque(["b", "c", "a"])
from collections import deque

def rotate(line, k):
    ...

Clean up names

Staff typed item names with stray spaces and capitals, and some lines are blank. Write clean(names) that returns the names stripped and lowercased, with blank entries removed.

clean(["  Bread ", "", "MILK", "   "])  ->  ["bread", "milk"]
def clean(names):
    ...

All positions of a value

Write positions(items, value) that returns a list of every index where value appears in items.

positions(["a", "b", "a", "c", "a"], "a")  ->  [0, 2, 4]
positions(["a"], "z")                      ->  []
def positions(items, value):
    ...

Next: Standard 4.