def fib(n): """Compute the nth Fibonacci number, for N >= 1. >>> fib(8) 21 """ pred, curr = 0, 1 # 0th and 1st Fibonacci numbers k = 1 # Tracks which Fib number is curr while k < n: pred, curr = curr, pred + curr k = k + 1 return curr def maybe_fib(n): """Compute the nth Fibonacci number, for N >= 0. >>> maybe_fib(8) 21 >>> maybe_fib(0) 0 >>> maybe_fib(1) 1 """ pred, curr = 1, 0 k = 0 while k < n: pred, curr = curr, pred + curr k = k + 1 return curr # DRY def same_order(a, b): """Return whether positive integers a and b have the same number of digits. >>> same_order(50, 70) True >>> same_order(50, 100) False >>> same_order(1000, 100000) False """ return digits(a) == digits(b) # a_digits = 0 # while a > 0: # last, a = a % 10, a // 10 # a_digits = a_digits + 1 # b_digits = 0 # while b > 0: # last, b = b % 10, b // 10 # b_digits = b_digits + 1 # return a_digits == b_digits def digits(a): a_digits = 0 while a > 0: a, last = a // 10, a % 10 a_digits = a_digits + 1 return a_digits # Generalizing patterns using arguments from math import pi, sqrt def area_square(r): """Return the area of a square with side length R.""" return r * r def area_circle(r): """Return the area of a circle with radius R.""" return r * r * pi def area_hexagon(r): """Return the area of a regular hexagon with side length R.""" return r * r * 3 * sqrt(3) / 2 def area(r, shape_constant): """Return the area of a shape from length measurement R.""" assert r > 0, 'A length must be positive' return r * r * shape_constant def area_square(r): return area(r, 1) def area_circle(r): return area(r, pi) def area_hexagon(r): return area(r, 3 * sqrt(3) / 2) # Functions as arguments def sum_naturals(n): """Sum the first N natural numbers. >>> sum_naturals(5) 15 """ total, k = 0, 1 while k <= n: total, k = total + k, k + 1 return total def sum_cubes(n): """Sum the first N cubes of natural numbers. >>> sum_cubes(5) 225 """ total, k = 0, 1 while k <= n: total, k = total + pow(k, 3), k + 1 return total def identity(k): return k def cube(k): return pow(k, 3) def summation(n, term): """Sum the first N terms of a sequence. >>> summation(5, cube) 225 """ total, k = 0, 1 while k <= n: total, k = total + term(k), k + 1 return total from operator import mul def pi_term(k): return 8 / mul(k * 4 - 3, k * 4 - 1) summation(10000, pi_term) # Local function definitions; returning functions def make_adder(n): """Return a function that takes one argument K and returns K + N. >>> add_three = make_adder(3) >>> add_three(4) 7 """ def adder(k): return k + n return adder make_adder(2000)(16)