pdb
and %debug
# by default, only the result of the last expression in a cell is displayed after evaluation.
# the following forces display of *all* self-standing expressions in a cell.
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
Recursive functions, directly or indirectly, call themselves.
Recursive solutions are applicable when a problem can be broken down into more easily solved sub-problems that resemble the original, and whose solutions can then be combined.
E.g., computing the combined price of a bunch of nested shopping bags of items:
class Bag:
def __init__(self, price, *contents): # * means variable number of arguments
self.price = price # of the items loose in the "self" bag
self.contents = contents # contents could be empty, but it is an iterable
bag1 = Bag(10)
<__main__.Bag at 0x17f67b8f160>
bag2 = Bag(5, Bag(3))
bag3 = Bag(5, Bag(4, Bag(3)), Bag(2))
bag4 = Bag(0, Bag(5), Bag(10), Bag(3, Bag(2), Bag(100)), Bag(9, Bag(2, Bag(25))))
def price(bag):
priceSoFar=bag.price
#base case a bag with no other bags in it
if not bag.contents:
return priceSoFar
else:
for b in bag.contents:
priceSoFar=priceSoFar+price(b) #before recursive call
# program counter is also pushed
# line number to come back to
return priceSoFar
price(bag1)
price(bag2)
price(bag3)
price(bag4)
10
8
14
156
import sys
sys.setrecursionlimit(200)
def silly_rec(n):
print(n)
silly_rec(n-1)
silly_rec(1)
1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155
--------------------------------------------------------------------------- RecursionError Traceback (most recent call last) <ipython-input-15-af015c898eaa> in <module> ----> 1 silly_rec(1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): 2 print(n) ----> 3 silly_rec(n-1) <ipython-input-14-d3f98e10e6a7> in silly_rec(n) 1 def silly_rec(n): ----> 2 print(n) 3 silly_rec(n-1) ~\anaconda3\lib\site-packages\ipykernel\iostream.py in write(self, string) 402 is_child = (not self._is_master_process()) 403 # only touch the buffer in the IO thread to avoid races --> 404 self.pub_thread.schedule(lambda : self._buffer.write(string)) 405 if is_child: 406 # mp.Pool cannot be trusted to flush promptly (or ever), ~\anaconda3\lib\site-packages\ipykernel\iostream.py in schedule(self, f) 200 If the thread is not running, call immediately. 201 """ --> 202 if self.thread.is_alive(): 203 self._events.append(f) 204 # wake event thread (message content is ignored) ~\anaconda3\lib\threading.py in is_alive(self) 1080 if self._is_stopped or not self._started.is_set(): 1081 return False -> 1082 self._wait_for_tstate_lock(False) 1083 return not self._is_stopped 1084 ~\anaconda3\lib\threading.py in _wait_for_tstate_lock(self, block, timeout) 1025 if lock is None: # already determined that the C code is done 1026 assert self._is_stopped -> 1027 elif lock.acquire(block, timeout): 1028 lock.release() 1029 self._stop() RecursionError: maximum recursion depth exceeded while calling a Python object
def silly_rec(n):
print(n)
if n>0:
silly_rec(n-1)
silly_rec(5)
5 4 3 2 1 0
$n! = \begin{cases} 1 & \text{if}\ n=0 \\ n \cdot (n-1)! & \text{if}\ n>0 \end{cases}$
i.e., $n! = n \cdot (n-1) \cdot (n-2) \cdots 3 \cdot 2 \cdot 1$
def rec_factorial(n):
print('n = ', n)
if n==0:
return 1
else:
partial_product= n*rec_factorial(n-1)
print ('partialprod=', partial_product)
return partial_product
rec_factorial(10)
n = 10 n = 9 n = 8 n = 7 n = 6 n = 5 n = 4 n = 3 n = 2 n = 1 n = 0 partialprod= 1 partialprod= 2 partialprod= 6 partialprod= 24 partialprod= 120 partialprod= 720 partialprod= 5040 partialprod= 40320 partialprod= 362880 partialprod= 3628800
3628800
$m + n = \begin{cases} m & \text{if}\ n=0 \\ (m + 1) + (n - 1) & \text{if}\ n > 0 \end{cases}$
def add(m, n):
print('m, n = ', (m, n))
if n==0:
return m
else:
return add(m+1, n-1)
add(5, 0)
m, n = (5, 0)
5
add(5, 1)
m, n = (5, 1) m, n = (6, 0)
6
add(5, 5)
m, n = (5, 5) m, n = (6, 4) m, n = (7, 3) m, n = (8, 2) m, n = (9, 1) m, n = (10, 0)
10
def bin_search(x, lst):
def rec_bin_search(x, lst, start=0,end=len(lst)-1):
print("start=",start, "end=", end)
if start <= end: # I still have items to look at
mid = (start+end)//2
if lst[mid]==x:
return mid
elif lst[mid]>x: # recurse on lower half
end=mid-1
return rec_bin_search(x, lst, start, end)
else: # recurse on upper half
start=mid+1
return rec_bin_search(x, lst, start, end)
else: #base case
return -1 # not found
return rec_bin_search(x, lst, 0,len(lst)-1)
bin_search(20, list(range(100)))
start= 0 end= 99 start= 0 end= 48 start= 0 end= 23 start= 12 end= 23 start= 18 end= 23
20
bin_search(-1, list(range(100)))
start= 0 end= 99 start= 0 end= 48 start= 0 end= 23 start= 0 end= 10 start= 0 end= 4 start= 0 end= 1 start= 0 end= -1
-1
bin_search(50.5, list(range(100)))
start= 0 end= 99 start= 50 end= 99 start= 50 end= 73 start= 50 end= 60 start= 50 end= 54 start= 50 end= 51 start= 51 end= 51 start= 51 end= 50
-1
$fib(n) = \begin{cases} 0 & \text{if}\ n=0 \\ 1 & \text{if}\ n=1 \\ fib(n-1) + fib(n-2) & \text{otherwise} \end{cases}$
i.e., 0, 1, 1, 2, 3, 5, 8, 13, 21, ...
def rec_fib(n):
print('n = ', n)
if n==0:
return 0
elif n==1:
return 1
else:
return rec_fib(n-1)+rec_fib(n-2)
rec_fib(5)
n = 5 n = 4 n = 3 n = 2 n = 1 n = 0 n = 1 n = 2 n = 1 n = 0 n = 3 n = 2 n = 1 n = 0 n = 1
5
Setup: three rods, with one or more discs of different sizes all stacked on one rod, smallest (top) to largest (bottom). E.g.,
|| || ||
== || ||
==== || ||
====== || ||
------------------------------------
Goal: move all the discs, one by one, to another rod, with the rules being that (1) only smaller discs can be stacked on larger ones and (2) only the top disc in a stack can be moved to another rod.
For three discs, as shown above, we would carry out the following sequence to move the stack to the rightmost rod. The rods are abbreviated L (left), M (middle), R (right):
Can you come up with the sequence needed to move a stack of 4 discs from one rod to another? 5 discs? An arbitrary number of discs?
height = 3
towers = [[] for _ in range(3)]
towers[0] = list(range(height, 0, -1))
def move(frm, to): #frm is a rod number, to is a rod number
# currently no error checking on moves
towers[to].append(towers[frm].pop(-1))
display()
def hanoi(frm, to, using, levels):
#levels is how many disks are on the from rod
# base case if levels == 1, move the disk from to to
# subproblem is levels-1 hanoi
if levels == 1:
move(frm, to) # this will always be onto an empty to
else:
hanoi(frm, using, to, levels-1) #largest subproblem
move(frm, to) #move the disk not in the subproblem
hanoi(using, to, frm, levels-1)
towers
[[3, 2, 1], [], []]
from time import sleep
from IPython.display import clear_output
def display():
clear_output(True)
print('{:^12}'.format('||') * 3)
for level in range(height, 0, -1):
for t in towers:
try:
print('{:^12}'.format('==' * t[level-1]), end='')
except IndexError:
print('{:^12}'.format('||'), end='')
print()
print('-' * 36)
sleep(1)
display()
|| || || == || || ==== || || ====== || || ------------------------------------
height = 3
towers = [[] for _ in range(3)]
towers[0] = list(range(height, 0, -1))
hanoi(0, 2, 1, 3)
|| || || || || == || || ==== || || ====== ------------------------------------
def merge(l1, l2): # O(N), where N is the number of elements in the two lists
merged = []
i1 = i2 = 0 #index pointers to walk l1 and l2
while i1 < len(l1) or i2 < len(l2):
if i2 == len(l2) or (i1 < len(l1)
and l1[i1] < l2[i2]):
# no items in l2 OR items in both and l1[i1] < l2[i2]
merged.append(l1[i1]) #assumed O(1)
i1 += 1
else:
merged.append(l2[i2])
i2 += 1
return merged
l1 = [1, 5, 9]
l2 = [2, 6, 8, 11]
merge(l1, l2)
[1, 2, 5, 6, 8, 9, 11]
def merge1(lst, f, m, t):
merged = []
i1 = f
i2 = m+1
while i1 < m+1 or i2 < t+1:
if i2 == t+1 or (i1 < m+1 and lst[i1] < lst[i2]):
merged.append(lst[i1])
i1 += 1
else:
merged.append(lst[i2])
i2 += 1
#return merged
# copy elements from merged into lst (f, t)
i=f
j=0
while i<=t:
lst[i]=merged[j]
i+=1
j+=1
l= [1, 5, 9, 2, 6, 8, 11]
merge1(l,0,2,6)
l
[1, 2, 5, 6, 8, 9, 11]
def mergesort(lst):
def rec_mergesort(lst, frm, to):
if frm < to:
mid = (frm+to)//2
rec_mergesort(lst, frm, mid)
rec_mergesort(lst, mid+1, to)
merge1(lst, frm, mid, to)
#else base case do nothing
rec_mergesort(lst, 0, len(lst)-1)
import random
lst = list(range(10))
random.shuffle(lst)
lst
[0, 4, 3, 8, 2, 6, 9, 5, 1, 7]
mergesort(lst)
lst
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
def insertion_sort(lst):
for i in range(1, len(lst)):
for j in range(i, 0, -1):
if lst[j-1] > lst[j]:
lst[j-1], lst[j] = lst[j], lst[j-1] # swap
else:
break
class Heap:
def __init__(self):
self.data = []
@staticmethod
def _parent(idx):
return (idx-1)//2
@staticmethod
def _left(idx):
return idx*2+1
@staticmethod
def _right(idx):
return idx*2+2
def _heapify(self, idx=0):
while True:
l = Heap._left(idx)
r = Heap._right(idx)
maxidx = idx
if l < len(self) and self.data[l] > self.data[idx]:
maxidx = l
if r < len(self) and self.data[r] > self.data[maxidx]:
maxidx = r
if maxidx != idx:
self.data[idx], self.data[maxidx] = self.data[maxidx], self.data[idx]
idx = maxidx
else:
break
def add(self, x):
self.data.append(x)
i = len(self.data) - 1
p = Heap._parent(i)
while i > 0 and self.data[p] < self.data[i]:
self.data[p], self.data[i] = self.data[i], self.data[p]
i = p
p = Heap._parent(i)
def max(self):
return self.data[0]
def pop_max(self):
ret = self.data[0]
self.data[0] = self.data[len(self.data)-1]
del self.data[len(self.data)-1]
self._heapify()
return ret
def __bool__(self):
return len(self.data) > 0
def __len__(self):
return len(self.data)
def heapsort(iterable):
heap = Heap()
for x in iterable:
heap.add(x)
sorted_lst = []
while heap:
sorted_lst.append(heap.pop_max())
sorted_lst.reverse()
return sorted_lst
import timeit
import random
insertionsort_times = []
heapsort_times = []
mergesort_times = []
for size in range(100, 3000, 100):
insertionsort_times.append(timeit.timeit(stmt='insertion_sort(lst)',
setup='import random ; from __main__ import insertion_sort ; '
'lst = [random.random() for _ in range({})]'.format(size),
number=1))
heapsort_times.append(timeit.timeit(stmt='heapsort(lst)',
setup='import random ; from __main__ import heapsort ; '
'lst = [random.random() for _ in range({})]'.format(size),
number=1))
mergesort_times.append(timeit.timeit(stmt='mergesort(lst)'.format(size),
setup='import random ; from __main__ import mergesort ; '
'lst = [random.random() for _ in range({})]'.format(size),
number=1))
%matplotlib inline
import matplotlib.pyplot as plt
plt.plot(insertionsort_times, 'ro')
plt.plot(heapsort_times, 'b^')
plt.plot(mergesort_times, 'gs')
plt.show()
[<matplotlib.lines.Line2D at 0x16aff879160>]
[<matplotlib.lines.Line2D at 0x16aff879610>]
[<matplotlib.lines.Line2D at 0x16aff8794c0>]
%matplotlib inline
import matplotlib.pyplot as plt
plt.plot(heapsort_times, 'b^')
plt.plot(mergesort_times, 'gs')
plt.show()
[<matplotlib.lines.Line2D at 0x16aff95b640>]
[<matplotlib.lines.Line2D at 0x16aff95ba60>]
Question: how many different ways are there of making up a specified amount of money, given a list of available denominations?
E.g., how many ways of making 10 cents, given 1c, 5c, 10c, 25c coins?
# other examples - palindrome, powerset, combinations
# palindrome string same forwards and backwards
# base case string length 0 or length 1 ARE palindromes
# largest subproblem racecar aceca length n problem, subproblem length n-2
# from to f t
def palindrome(s): # s can be any sequence type
def rec_palindrome(s, f, t): # f is from index, t is to index of subproblem
# base case, current subproblem length 0 or 1
if f==t or t<f:
return True
else:
if s[f]==s[t]:
return rec_palindrome(s, f+1, t-1)
else:
return False
return rec_palindrome(s, 0, len(s)-1)
palindrome('racecar')
palindrome('racecaR')
palindrome('I')
palindrome('')
palindrome([1,2,3,2,1])
True
False
True
True
True
#powerset set of all subsets of a sequence type
# base case - sequence type length 0, return empty set
# largest subproblem recursive case -
#find all the subsets of one smaller of the sequence type, then for the item
# removed, either add it or don;t add it to every subset of the subproblem
# allow slicing, print the powerset
def powerset(s, ans=[]): # s is a sequence type that I am generating the powerset
if len(s)>0:
powerset(s[:-1], ans) # don't use the current element, slice s
ans.append(s[-1])
powerset(s[:-1],ans ) # do use the current element, slice s
del ans[-1]
else:
print(ans)
powerset(['a','b','c'])
[] ['a'] ['b'] ['b', 'a'] ['c'] ['c', 'a'] ['c', 'b'] ['c', 'b', 'a']
def change(amount, denoms): # count how many ways
if amount==0:
return 1
elif amount<0:
return 0
elif len(denoms)==0:
return 0
else:
x=change(amount, denoms[:-1]) # don't use the last coin in denoms ANYMORE
y=change(amount-denoms[-1], denoms) # use the last coin in denoms
return x+y
change(5, (1, 5, 10, 25))
2
change(10, (1, 5, 10, 25))
4
change(1000, (1, 5, 10, 25))
142511
def change(amount, denoms, ans=[]): # count how many ways
if amount==0:
print(ans)
return 1
elif amount<0:
return 0
elif len(denoms)==0:
return 0
else:
x=change(amount, denoms[:-1]) # don't use the last coin in denoms ANYMORE
ans.append(denoms[-1])
y=change(amount-denoms[-1], denoms,ans ) # use the last coin in denoms
del ans[-1]
return x+y
change(10, (1, 5, 10, 25))
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1] [5, 1, 1, 1, 1, 1] [5, 5] [10]
4
def change(amount, denoms, ans=[], smallest=[]): # count how many ways
if amount==0:
# print(ans)
if len(ans)<len(smallest) or smallest==[]:
smallest=ans
print(smallest)
return 1
elif amount<0:
return 0
elif len(denoms)==0:
return 0
else:
x=change(amount, denoms[:-1], ans , smallest) # don't use the last coin in denoms ANYMORE
ans.append(denoms[-1])
y=change(amount-denoms[-1], denoms,ans, smallest ) # use the last coin in denoms
del ans[-1]
return x+y
change(10, (25, 5, 1, 10))
[5, 5] [1, 1, 1, 1, 1, 5] [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] [10]
4
factorial
¶class Stack(list):
push = list.append
pop = lambda self: list.pop(self, -1)
peek = lambda self: self[-1]
empty = lambda self: len(self) == 0
call_stack = Stack()
def call(arg):
call_stack.push('<frame begin>')
call_stack.push(('arg', arg))
def get_arg():
return call_stack.peek()[-1]
def save_local(name, val):
call_stack.push(('local', name, val))
def restore_local():
return call_stack.pop()[2]
def return_with(val):
while call_stack.pop() != '<frame begin>':
pass
call_stack.push(('ret', val))
def last_return_val():
return call_stack.pop()[-1]
call(10) # initial call
while True: # recursive calls
n = get_arg()
if n == 1:
return_with(1)
break
else:
save_local('n', n)
call(n-1)
call_stack
ret = last_return_val()
n = restore_local()
return_with(n * ret)
call_stack
pdb
¶def bin_search(x, lst):
if len(lst) == 0:
return False
else:
#print('lo, hi = ', (lst[0], lst[-1]))
# breakpoint()
mid = len(lst) // 2
import pdb ; pdb.set_trace() # breakpoint()
if x == lst[mid]:
return True
elif x < lst[mid]:
return bin_search(x, lst[:mid])
else:
return bin_search(x, lst[mid+1:])
bin_search(20, list(range(100)))
> <ipython-input-40-3cc760063b0c>(9)bin_search() 7 mid = len(lst) // 2 8 import pdb ; pdb.set_trace() # breakpoint() ----> 9 if x == lst[mid]: 10 return True 11 elif x < lst[mid]: ipdb> lst [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99] ipdb> x 20 ipdb> mid 50 ipdb> continue > <ipython-input-40-3cc760063b0c>(9)bin_search() 7 mid = len(lst) // 2 8 import pdb ; pdb.set_trace() # breakpoint() ----> 9 if x == lst[mid]: 10 return True 11 elif x < lst[mid]: ipdb> lst [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49] ipdb> mid 25 ipdb> args x = 20 lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49] ipdb> exit
--------------------------------------------------------------------------- BdbQuit Traceback (most recent call last) <ipython-input-41-b5349e06e942> in <module> ----> 1 bin_search(20, list(range(100))) <ipython-input-40-3cc760063b0c> in bin_search(x, lst) 7 mid = len(lst) // 2 8 import pdb ; pdb.set_trace() # breakpoint() ----> 9 if x == lst[mid]: 10 return True 11 elif x < lst[mid]: <ipython-input-40-3cc760063b0c> in bin_search(x, lst) 7 mid = len(lst) // 2 8 import pdb ; pdb.set_trace() # breakpoint() ----> 9 if x == lst[mid]: 10 return True 11 elif x < lst[mid]: <ipython-input-40-3cc760063b0c> in bin_search(x, lst) 7 mid = len(lst) // 2 8 import pdb ; pdb.set_trace() # breakpoint() ----> 9 if x == lst[mid]: 10 return True 11 elif x < lst[mid]: ~\anaconda3\lib\bdb.py in trace_dispatch(self, frame, event, arg) 86 return # None 87 if event == 'line': ---> 88 return self.dispatch_line(frame) 89 if event == 'call': 90 return self.dispatch_call(frame, arg) ~\anaconda3\lib\bdb.py in dispatch_line(self, frame) 111 if self.stop_here(frame) or self.break_here(frame): 112 self.user_line(frame) --> 113 if self.quitting: raise BdbQuit 114 return self.trace_dispatch 115 BdbQuit:
# list shows statements around breakpoint
# next execute next statement
# continue to next breakpoint
# variable or exp