def multiplication_table(rows, cols): """A ROWS x COLS multiplication table wwhere row x column y (element [x][y]) contains xy. Example: >>> multiplication_table(4, 3) [[0, 0, 0], [0, 1, 2], [0, 2, 4], [0, 3, 6]] """ return [ [ row * col for col in range(cols) ] for row in range(rows) ] def triangle(rows): """A ROWSxROWS lower-triangular array containing "*"s.""" return [ [ "*" for c in range(k+1) ] for k in range(rows) ] def numbered_triangle(rows): """A ROWSxROWS lower-triangular array whose elements are integers, starting at 0 going left-to-right, up-to-down. >>> numbered_triangle(3) [[0], [1, 2], [3, 4, 5]]""" def first(row): return (row * row + row) // 2 return [ [ x for x in range(first(row), first(row) + row + 1) ] for row in range(rows) ] def make_tree(label, kids = []): """A (sub)tree with given LABEL at its root, whose children are KIDS.""" return [ label ] + kids def label(tree): """The label on TREE.""" return tree[0] def branches(tree): """The immediate descendants of TREE (each a tree).""" return tree[1:] def isleaf(tree): """True if TREE is a leaf node.""" return len(tree) == 1 def count_leaves(tree): """The number of leaf nodes in TREE.""" if isleaf(tree): return 1 else: return sum(map(count_leaves, branches(tree))) # A more elaborate version than in lecture. def value(expr): """Return the value of the expression represented by the expression tree expr. Assumes all leaves are numbers and all inner-node labels are operators. >>> value(make_tree("*", [ make_tree("+", [make_tree(3), make_tree(4)]), ... make_tree("-", [make_tree(9), make_tree(6)])])) 21 """ if isleaf(expr): return label(expr) operands = [ value(branch) for branch in branches(expr) ] if len(operands) != 2: raise ValueError("incorrect number of operands") if label(expr) == '+': return operands[0] + operands[1] elif label(expr) == '*': return operands[0] * operands[1] elif label(expr) == '-': return operands[0] - operands[1] elif label(expr) == '/': return operands[0] / operands[1] else: raise ValueError("invalid operator")