"""
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