""" Functions from second recursion lecture. These functions show the why the choice of division matters. Author: Walker M. White (wmw2) Date: October 10, 2017 (Python 3 Version) """ import sys # Allow us to go really deep sys.setrecursionlimit(999999999) # COMMAFY FUNCTIONS def commafy_str(s): """ Returns a copy of s, with commas every 3 digits. Example: commafy('5341267') = '5,341,267' Parameter s: string representing an integer Precondition: s a string with only digits, not starting with 0 """ # You can't always check everything with an assert # However, check what you can assert type(s) == str, repr(s) + ' is not a string' # Work on small data (BASE CASE) if len(s) <= 3: return s # Break up into halves (RECURSIVE CASE) left = commafy_str(s[0:-3]) right = s[-3:] # Combine the answer return left + ',' + right def commafy(n): """ Returns n as a string, with commas every 3 digits. Example: commafy('5341267') = '5,341,267' Parameter n: number to convert Precondition: n is an int with n >= 0 """ assert type(n) == int, repr(n)+' is not an int' # get in the habit assert n >= 0, repr(n)+' is negative' # get in the habit # Use helpers return commafy_str(str(n)) # Work on small data (BASE CASE) #if n < 1000: # return str(n) # Break up into halves (RECURSIVE CASE) #left = commafy(n/1000) #right = to3(n % 3) # Combine the answer #return left + ',' + right def to3(p): """ Returns a string representation of p with at least 3 chars Adds leading 0's if necessary Parameter n: number to pad Precondition: p is an int """ assert type(p) == int, repr(p)+' is not an int' # get in the habit if p < 10: return '00' + str(p) elif p < 100: return '0' + str(p) return str(p) # EXPONENTIAL FUNCTIONS # Number of frames used in exp recursive calls count_frames = 0 def exp_slow(b, c): """ Returns the value b^c. Property: b^c = b * b^(c-1) Parameter b: the number to raise to a power Precondition: b is a number Parameter c: the exponent Precondition: c is an int >= 0 """ # get in the habit of checking what you can assert type(b) in [float, int], repr(b)+' is not a number' assert type(c) == int, repr(c)+' is not an int' assert c >= 0, repr(c)+' is negative' # Allows us to write to global variable. EVIL! Do not use! global count_frames # Work on small data (BASE CASE) if c == 0: return 1 # Break up into halves (RECURSIVE CASE) left = b right = exp_slow(b, c-1) # Used to count the number of frames count_frames = count_frames+1; # Combine the answer return left * right def exp_alt(b, c): """ Returns the value b^c. Property: b^c = b^(c/2) * b^(c-c/2) Parameter b: the number to raise to a power Precondition: b is a number Parameter c: the exponent Precondition: c is an int >= 0 """ assert type(b) in [float, int], repr(b)+' is not a number' assert type(c) == int, repr(c)+' is not an int' assert c >= 0, repr(c)+' is negative' # Allows us to write to global variable. EVIL! Do not use! global count_frames # Work on small data (BASE CASE) if c == 0: return 1 elif c == 1: return b # Break up into halves (RECURSIVE CASE) left = exp_alt(b, c//2) right = exp_alt(b,c-c//2) # Used to count the number of frames count_frames = count_frames+1; # Combine the answer return left * right def exp_fast(b, c): """ Returns the value b^c. Property. b^c = b * b^(c-1) Property. b^c = (b*b)^(c/2) for even c Parameter b: the number to raise to a power Precondition: b is a number Parameter c: the exponent Precondition: c is an int >= 0 """ assert type(b) in [float, int], repr(b)+' is not a number' assert type(c) == int, repr(c)+' is not an int' assert c >= 0, repr(c)+' is negative' # Allows us to write to global variable. EVIL! Do not use! global count_frames # Work on small data (BASE CASE) if c == 0: return 1 # Used to count the number of frames count_frames = count_frames+1; # Break up into halves (RECURSIVE CASE) if c % 2 == 0: left = b right = b return exp_fast(left*right, c//2) # If not even left = b right = exp_fast(b, c-1) return left * right