cs 61a structure and interpretation of computer programs ...shidi/cs61a/61a-fa13-midterm2... · cs...
TRANSCRIPT
CS 61A Structure and Interpretation of Computer Programs
Fall 2013 Midterm 2
INSTRUCTIONS
• You have 2 hours to complete the exam.
• The exam is closed book, closed notes, closed computer, closed calculator, except one hand-written 8.5” ⇥ 11”crib sheet of your own creation and the two o�cial 61A midterm study guides attached to the back of thisexam.
• Mark your answers ON THE EXAM ITSELF. If you are not sure of your answer you may wish to provide abrief explanation.
Last name
First name
SID
Login
TA & section time
Name of the person toyour left
Name of the person toyour right
All the work on this exam
is my own. (please sign)
For sta↵ use only
Q. 1 Q. 2 Q. 3 Q. 4 Total
/14 /14 /12 /10 /50
,YERK
%RHVI[
GW��E�X^
.SLR�*VMHE]��TQ
%RHVI[�,YERK
*SVIZIV
%PSRI���
��������
;%0/8,639+,
2
1. (14 points) Classy Costumes
For each of the following expressions, write the value to which it evaluates. The first two rows have been providedas examples. If evaluation causes an error, write Error. If evaluation never completes, write Forever.
Assume that you have started Python 3 and executed the following statements:
class Monster:
vampire = {2: ’scary’}
def werewolf(self):
return self.vampire [2]
class Blob(Monster ):
vampire = {2: ’night’}
def __init__(self , ghoul):
vampire = {2: ’frankenstein ’}
self.witch = ghoul.vampire
self.witch [3] = self
spooky = Blob(Monster)
spooky.werewolf = lambda self: Monster.vampire [2]
Expression Evaluates to
square(5)
25
1/0
Error
[k+2 for k in range(4)]
Monster.vampire[2][3]
repr(len(spooky.witch))
spooky.witch[3] is not spooky
spooky.witch[2][0:4]
spooky.werewolf()
Monster.werewolf(spooky)
7XIT����6IEH�ERH�YRHIVWXERH�XLI�UYIWXMSR
7XIT����KPERGI�EX�XLI�TVSZMHIH�GSHI���8LMRKW�XS�RSXI�EX�¾VWX�KPERGI�������XLIVI�EVI�X[S�GPEWWIW��1SRWXIV�ERH�&PSF�������&PSF�MRLIVMXW�JVSQ�1SRWXIV������8LIVI�MW�XLMW�GSQTPMGEXMIH�QIWW�[MXL�ZEQTMVIW��
?����������A ����0MWX�GSQTVILIRWMSR��TVIXX]����WXVEMKLXJSV[EVH�MJ�]SY�ORS[�XLIQ
7XIT����8EGOPI�XLI�TVSFPIQW�
2SXMGI�1SRWXIV�MW�XLI�GPEWW
8LEX�QIERW�XLMW��ZEQTMVI��MW�_����WGEV]������WTSSO]a
7XIT����*MKYVI�SYX�[LEX�W�KSMRK�SR�[MXL�XLI�QIWW]�FMXW��WTSSO]�MW�E�MRWXERGI�SJ�XLI�&PSF�GPEWW��*SV�[LEXIZIV�VIEWSR���[I�VI�TEWWMRK�MR�XLI�1SRWXIV�GPEWW�EW�EVKYQIRX��WS�KLSYP�MW�1SRWXIV���3YV�RI[�SFNIGX�LEW�ER�MRWXERGI�ZEVMEFPI�[MXGL�WIX�IUYEP�XS��KLSYP�ZEQTMVI�!"�XLI�HMGXMSREV]�_����WGEV]�a
8LMW�MW�E�PSGEP�ZEVMEFPI������"ERH�HSIWR�X�E½IGX�ER]XLMRKMR�XLIWI�TEVXMGYPEV�TVSFPIQW
_����WGEV]������WTSSO]a
8LIWI�PMRIW�GEYWIW�XLI�GLERKIW�MR�VIH�EFSZI�
QSVI�EGGYVEXIP]��XLI�SFNIGX�XLEX�WTSO]�TSMRXW�XS
�V�1SRWXIV�ZEQTMVI?�A�KMZIW�YW��WGEV]�-RHI\MRK�MRXS�WPSX���SJ�XLI�WXVMRK�KMZIW�YW��V�
8LMW�VERKI�QIERW�����������
8LMW�MW�XLI�HMGXSREV]�_����WGEV]������WTSSO]a��� 2SXMGI�XLMW�MW�E�WXVMRK��WMRGI�VITV�EP[E]W
VIXYVRW�E�WXVMRK
*EPWI%KEMR��XLMW�MW�XLI�HMGXMSREV]�_����WGEV]������WTSSO]a
[LMGL�QEOIW�XLMW�WTSSO]
�WGEV]��WGEV�
6IQIQFIV�XLI�WPMGMRK�STIVEXMSR?WXEVX�IRHA�KSIW�WXEVX�MRGPYWMZI�XSIRH�I\GPYWMZI
8LMW�¿EX�SYX�IVVSVW�FIGEYWI�XLMW�[IVI[SPJ�MWR�XE�FSYRH�QIXLSH��7IEVGL��FSYRH�QIXLSH��SR4ME^^E�JSV�HIXEMPW
�RMKLX�;I�YWI�XLI�[IVI[SPJ�QIXLSH�MR�1SRWXIV�ERHTEWW�MR�WTSSO]��8LYW�WIPJ�MW�WTSSO]��ERMRWXERGI�SJ�XLI�&PSF�GPEWW ��1SRWXIV�[IVI[SPJVIXYVRW�WIPJ�ZEQTMVI?�A��[LMGL�IZEPYEXIW�XSXLI�ZEQTMVI�WXEXMG�ZEVMEFPI�EFSZI�MR�KVIIR�
5YIWXMSR�WE]W��[LEX�[MPP�4]XLSR�SYXTYX#�
Login: 3
2. (14 points) Wreaking Ball
(a) (8 pt) Fill in the environment diagram that results from executing the code below until the entire programis finished, an error occurs, or all frames are filled. You may not need to use all of the spaces or frames.
A complete answer will:
• Add all missing names, labels, and parent annotations to all local frames.
• Add all missing values created during execution.
• Show the return value for each local frame.
Global frame
miley func miley(ray)
Return Value
Return Value
Return Value
Return Value
def miley(ray): def cy(): def rus(billy): nonlocal cy cy = lambda: billy + ray return (1, billy) if len(rus(2)) == 1: return (3, 4) else: return (cy(), 5) return cy()[1]billy = 6miley(7)
billy 6
7XIT����KMZIR�QMPI]�� �IZEPYEXI�XLI�STIVEXSV�ERH�STIVERHW���QMPI]�XYVRW�SYX�XS�FI�XLI�QMPI]�JYRGXMSR�����MW�WIPJ�IZEPYEXMRK8LMW�WXIT�MW�WS�YXXIVP]�MQTSVXERX�(SR�X�IZIV�JSVKIX�XS�I\TPMGXP]�GEVV]�SYX�XLMW�WXIT�IZIR�MJ��EW�MR�XLMW�GEWI��MX�W�WMQTPI�
7XIT����'VIEXI�J���XLI�JVEQI�GVIEXIH�JSV�QMPI]�� ��8LI�TEVIRX�SJ�J��MW�KPSFEP��XLI�TEVIRX�SJ�QMPI]
J� QMPI] TEVIRX�!�+PSFEP
VE] �
7XIT����FMRH�XLI�JSVQEP�TEVEQIXIV��VE] �XS��XLI�EGXYEP�EVKYQIRX�ZEPYI���
T�!�+PSFEP
G]JYRG�G]�FMPP] �TEVIRX�!�J�
7XIT����GVIEXI�XLMW�RI[�JYRGXMSR�G]��[LSWI�TEVIRX�MW�XLI�GYVVIRXJVEQI��J�
78%68�,)6)���
7XIT����IZEPYEXI�G]� ?�AF]�¾VWX�IZEPYEXMRK�G]� �G]�MW�XLI�G]�JYRGXMSR�MR�J��;I�GVIEXI�E�RI[�JVEQIJ��[LSWI�TEVIRX�MW�XLITEVIRX�SJ�G]��J���8LMW�MWXLI�RI[�GYVVIRX�JVEQI�
J� G] TEVIRX�!�J�
JYRG�VYW�FMPP] ���TEVIRX�!�J�
VYW
7XIT����'VIEXI�XLI�JYRGXMSR�VYW�[LSWI�TEVIRX�MW�XLI�GYVVIRX�JVEQI��J��
J� VYW
FMPP] �TEVIRX�!�J�
7XIT����HS�XLI�MJ�WXEXIQIRX�MR�G]�[LMGL�GEYWIW�YW�XS�IZEPYEXI�VYW�� VYW�MW�XLI�JYRGXMSR�MR�J�����MW���'VIEXI�E�RI[�JVEQI�J��[LSWITEVIRX�MW�XLI�TEVIRX�SJ�VYW��J���8LMW�MWXLI�RI[�GYVVIRX�JVEQI�
7XIT����XLI�RSRPSGEP�G]�GEYWIWG]�XS�FI�VIFSYRH�XS�E�PEQFHE�JYRGXMSR�'VIEXI�XLI�PEQFHE�JYRGXMSRXLEX�XEOIW�MR�RS�EVKYQIRXW��[LSWITEVIRX�MW�XLI�GYVVIRX�JVEQI��J��
7XIT����FMRH�FMPP]�XS���7XIT����VIXYVR�����FMPP] ��FMPP]�IZEPYEXIW�XS����WSHVE[�X[S�FS\IW�XS�VITVIWIRX�XLI�XYTPI��7MRGI�VYWVIXYVRIH��XLI�GYVVIRX�JVEQI�KSIW�FEGO�XSFIMRK�J���XLI�JVEQI�XLEX�GEPPIH�VYW�
JYRGXMSR�PEQFHE� �TEVIRX�!�J�
7XIT�����2S[�¾REPP]�KIX�FEGO�XS�XLEX�MJ�WXEXIQIRX�MR�G]��7MRGI�VYW�� VIXYVRW�E�XYTPI��ERH�XLI�PIR�SJ�XLEX�XYTPI�MW����[LMGL�MW�RSX�IUYEP�XS���VIXYVR��G]� ��� �-R�SVHIV�XS�VIXYVR�XLI�XYTPI��G]� ��� ��¾VWX�IZEPYEXI�G]� �
7XIT�����-R�SVHIV�XS�IZEPYEXI�G]� ��¾VWX�IZEPYEXI�XLI�STIVEXSV��+9)77�;,%8#�G]�MW�RS[�XLI�PEQFHE�JYRGXMSR�JVSQ�WXIT���830(�=39�):%09%8-2+�8,)�34)6%836�%2(�34)6%2(7�-7�-1436%28��%R][E]W��GVIEXI�E�RI[�JVEQI�J��JSV�G]��[LSWITEVIRX�MW�J���XLI�TEVIRX�SJ�XLI�PEQFHE��8LMW�MW�XLI�RI[�GYVVIRX�JVEQI
J� PEQFHE TEVIRX�!�J�
7XIT�����IZEPYEXI�XLI�FSH]�SJ�XLI�PEQFHE�MR�XLI�GSRXI\X�SJ�XLMW�GYVVIRX�JVEQI��0SSO�YT�FMPP]�ERH�MX�IZEPYEXI�XS���0SSO�YT�VE]�ERH�IZEPYEXI�MX�XS����6IXYVR����8LI�GYVVIRX�JVEQI�KSIW�FEGO�XS�FIMRK�J���XLI�JVEQI�XLEX�GEPPIH�XLI�PEQFHE�
�
7XIT�����31+�;-00�8,-7�2):)6�)2(#�PSP��2S[�XLEX�G]� �LEW�FIIR�IZEPYEXIH��¾REPP]�VIXYVR�XLI�XYTPI�SJ���ERH���2S[�XLI�GYVVIRX�JVEQI�KSIW�FEGO�XS�FIMRK�J���XLI�JVEQI�XLEX�GEPPIH�G]�
7XIT�����FEGO�MR�J���VIXYVR������ ?�A�!"����%RH�XLIR�KMZI�]SYVWIPJ�E�TEX�SR�XLI�FEGO��]SY�GLEQT�
�
5YIWXMSR�WE]W��(VE[�ER�IRZMVSRQIRX�HMEKVEQ��
4
(b) (6 pt) Write the letter of the environment diagram that would result from executing each code snippetbelow, just after starting Python. The first blank is filled for you. Two di↵erent snippets may result in thesame environment diagram. If none of the environment diagrams are correct, write N.
A
A
B
C
D
F
N: None of the above
Global frame
s
t
list10
1list
10
2
1 2
Global frame
s
t
Global frame
s
t
list0
list10
1
list0
list0
list10
1
list0
list0
Global frame
s
t
list0
list10
1
list0
Global frame
s
t
list0
list10
1 2list0
list0
EGlobal frame
s
t
list0
list10
1 2list0
8LI�SRP]�EHZMGI�-�LEZI�JSV�]SY�LIVI�MW�XS�HVE[�SYX�IEGL�SJ�XLI�WXVYGXYVIW��ERH�XLIR�QEXGL�XLIQ�
* ' (
*SV�IEGL�SJ�XLIWI��W�TSMRXW�XS�E�PMWX�SJ�SRI�IPIQIRX��E�PMWX�[MXL�X[S�IPIQIRXW����ERH��
X�TSMRXW�XS�XLEX�MRRIV�PMWX
XLI�¾VWX�IPIQIRX�SJ�X�MW�RS[E�RI[�PMWX�[MXL�SRI�IPIQIRX��W
X�TSMRXW�XS�XLI�WEQI�PMWX�XLEX�W�HSIW
XLI�WIGSRH�IPIQIRX�SJ�XLI�MRRIV�PMWXMW�RS[�E�RI[�PMWX�[MXL�SRI�IPIQIRX��W
X�TSMRXW�XS�E�RI[�PMWX�SJ�SRI����������������IPIQIRX��W
2S[�XLI�¾VWX�IPIQIRX�SJ�XMW�E�RI[�PMWX�SJ�SRI�IPIQIRX��W
5YIWXMSR�WE]W��(VE[�FS\�ERH�TSMRXIVW�
Login: 5
3. (12 points) Mutants
(a) (4 pt) Given two Rlist arguments a and b, the function merge(a, b) changes a so that it also includesall elements of b at the end, but does not change b. After merging, changes to b should not a↵ect a.Assume that a is not empty, but b may be empty. Complete the implementation by filling the blanks withexpressions. The Rlist class is defined in your study guide.
def merge(a, b):
""" Add the elements of b to the end of a, mutating a but not b.
>>> a = Rlist(1, Rlist(2, Rlist (3)))
>>> b = Rlist(4, Rlist(5, Rlist (6)))
>>> merge(a, b)
>>> a # a should be modified
Rlist(1, Rlist(2, Rlist(3, Rlist(4, Rlist(5, Rlist (6))))))
>>> b # b should not be modified
Rlist(4, Rlist(5, Rlist (6)))
>>> b.first = 7 # modify the elements of b
>>> b # b should be modified
Rlist(7, Rlist(5, Rlist (6)))
>>> a # a should not be modified
Rlist(1, Rlist(2, Rlist(3, Rlist(4, Rlist(5, Rlist (6))))))
"""
assert a is not Rlist.empty
if b is Rlist.empty:
return # No entries to add to a.
elif _________________________________________________________:
__________________________________________________________
__________________________________________________________
else:
__________________________________________________________
(b) (2 pt) Define a mathematical function f(m,n) such that evaluating a correct and e�cient implementationof merge(a, b) on Rlist a of length m and Rlist b of length n requires ⇥(f(m,n)) function calls.
f(m,n) =
5YIWXMSR�WE]W��[VMXI�QIVKI���[MXL�GEZIEXW
8LMW�QIERW�[I�LEZI�XS�GSRWXVYGXE�RI[�PMWX�XS�LSSO�SRXS�E�
7XIT����%WWIWW�XLII\EQTPIW
7XIT����6IEH�ERH�YRHIVWXERH�XLI�UYIWXMSR
8LI�HSGXIWXW�SR�I\EQW�XIPP�]SY�I\EGXP][LEX�XLI�UYIWXMSR�MW�EWOMRK
7XIT����%WWIWW�XLIGSHI�KMZIR
Q�R -X�XEOIW�Q�VIGYVWMZI�GEPPW�XS�KIX�XS�XLI�IRH�SJ�XLI�¾VWX�PMWXERH�R�VIGYVWMZI�GEPPW�XS�GSRWXVYGX�E�GST]�SJ�XLI�WIGSRH�PMWX�
,IVI�W�E�FEWI�GEWI��7MRGI�E�MW�RSRIQTX]��[I�SRP]�[SVV]�EFSYX�F
8LMW�QYWX�FI�XLI�GEWI�[LIVI�F�MWR�X�IQTX]��;LEX�KSIW�MR�XLMW�IPMJ#�,Q���7XIT����8LMRO�EFSYX�XLITVSFPIQ�MR�)RKPMWL8LI�FMK�MHIE�MW�XLEX�[I�WSQILS[LEZI�XS�KIX�XS�XLI�IRHSJ�E�ERH�XLIR�QSHMJ]�XLI�IRH�SJE�WS�XLEX�[I�GVIEXI�ERH�EXXEGLE�RI[�PMWX�XLEX�LEWXLI�IPIQIRXW�SJ�F�MR�MX�
7XIT����8VERWPEXI�MRXS�4]XLSR3OE]��LS[�HS�[I�XVEZIVWI�E#�;LIR�HS�[I�ORS[�[LIR�[I�VI�EX�XLI�IRH�SJ�E#�3L��;LIR�E�VIWX�MW�IQTX]�;I�GER�EWWYQI�E�[SR�X�IZIV�IQTX]��JVSQ�XLI�TVSFPIQ�WXEXIQIRX ��WS�MX�PP�LEZI�E�VIWX�
E�VIWX�MW�6PMWX�IQTX]-J�XLI�VIWX�MW�IQTX]��XLIR�[I�WLSYPH�WXEVX�XLI�QIVKMRK��7MRGI[I�LEZI�XS�QEOI�E�GST]�SJ�F��[I�[MPP�QEOI�E�RI[�6PMWX��;IGER�SRP]�VIEPP]�QEOI�SRI�IPIQIRX�EX�E�XMQI��0IX�W�WXEVX�[MXL�XLI¾VWX�IPIQIRX�
E�VIWX�!�6PMWX�F�¾VWX
,S[�HS�[I�LERHPI�IZIV]XLMRK�IPWI#�6IGYVWMSR�QIVKI�E�VIWX��F�VIWX
-J�XLI�IPMJ�GLIGOIH�XLEX�E�VIWX�MW�IQTX]��XLIR�XLMW�MW�XLI�GEWI�[LIVI�MX�MWR�X��;I�LEZIR�X�KSXXIRXS�XLI�IRH�SJ�E�]IX�
QIVKI�E�VIWX��F 7XIT����8IWX�XIWX�XIWX�0IX�W�NYWX�GLIGO�SYX�XLI�HSGXIWX��-J�[I�HS�QIVKI�E��F ��XLI�VIGYVWMZI�GEPPW�[MPP�OIIT�LMXXMRK�XLI�IPWI�GEWI
YRXMP�[I�VI�EX�XLI�6PMWX�GSRXEMRMRK����8LIR�[I�WIX�MXW�VIWX�XS�6PMWX�� ��ERH�XLIR�HS�XLEX�EKEMR�JSV���ERH���
6(c) (6 pt) The function fold_tree takes in a three-argument function, a zero value, and a Tree. It returns
the value of replacing Tree with the function and empty branches with the zero value. For each of size,reverse, and repeated, complete the inner function f. Each f cannot be recursive.
def fold_tree(fn , zero , tree):
""" Replaces the tree constructor with a 3-argument function.
>>> t = Tree(3, Tree(5, None , Tree (3)), Tree (2))
>>> f = lambda a, b, c: a + b + c
>>> fold_tree(f, 0, t) # is equivalent to the expression ...
13
>>> f(3, f(5, 0, f(3, 0, 0)), f(2, 0, 0))
13
"""
if tree is None:
return zero
return fn(tree.entry , fold_tree(fn , zero , tree.left),
fold_tree(fn , zero , tree.right ))
def size(tree):
""" Return the number of trees contained in tree.
>>> size(Tree(3, Tree(5, None , Tree (3)), Tree (2)))
4
"""
def f(entry , left , right):
return fold_tree(f, 0, tree)
def reverse(tree):
""" Return a new tree swapping all left and right branches of tree.
>>> reverse(Tree(3, Tree(5, None , Tree (3)), Tree (2)))
Tree(3, Tree(2), Tree(5, Tree(3), None))
"""
def f(entry , left , right):
return fold_tree(f, None , tree)
def repeated(tree):
""" Return how many times the root entry of tree appears in tree.
>>> repeated(Tree(3, Tree(5, None , Tree (3)), Tree (2))) # 3 appears twice
2
"""
def f(entry , left , right):
return fold_tree(f, 0, tree)
7XIT����6IEH�ERH�YRHIVWXERH�XLI�UYIWXMSR
�;I�LEZI�XLMW�JYRGXMSR�JSPH�XVII�XLEX�HSIW�WSQIXLMRK�GVE^]�[MXL�XVIIW��;I�VI�WYTTSWI�XS�YWI�MX��
7XIT����9RHIVWXERHXLI�I\EQTPIW�ERHTVSZMHIH�GSHI�
JSPHCXVII�XEOIW�MR�E�JYRGXMSR��WSQI�RYPP�ZEPYI��ERH�E�XVII
-X�PSSOW�PMOI�JSPHCXVII�VIXYVRW�E�ZEPYI�[MXL�XLI�WEQI�X]TI�EW�^IVS
8LEX�QIERW�JR�QYWXXEOI�MR�XLVII�XLMRKW��EPP�SJ�XLI�WEQI�X]TI�EW�^IVS
8VII�6IGYVWMSR�;I�QEOI�VIGYVWMZI�GEPPWSR�XLI�PIJX�ERH�VMKLX�8LMW�QIERW�[I�PP�KS�XLVSYKLXLI�IRXMVI�XVII�
&EWIH�SR�XLI�I\EQTPI�X�!������������������@��������������������@���������
J�MW�E�JYRGXMSR�XLEX�XEOIW�XLVII�XLMRKW�ERH�EHHW�XLIQ�YT
;LIR�[I�GEPP�JSPHCXVII��[I�TEWW�MR�J��E�PMXIVEP����ERH�XLI�I\EQTPI�XVII
3OE]��WS�-�ORS[�XLEXJSPHCXVII�HSIW�WSQIWSVX�SJ�XVII�VIGYVWMSRJSV�QI�ERH�GSQFMRIWXLMRKW�XSKIXLIV�
7XIT����9WI�XLI�I\EQTPIW�ERH�XLI�HSGWXVMRK�XS�YRHIVWXERH�LS[�XS�YWI�JSPHCXVII
-�ORS[�-�LEZI�XS�YWI�JSPH�XVII�ERH�XLEX�MX�[MPP�XVEZIVWI�XLI�XVIIERH�GEPP�J�EX�IEGL�IRXV]�
0SSO��XLI]�IZIR�KEZI�YW�XLI�^IVS�
VIXYVR�����PIJX���VMKLX*VSQ�EFSZI��-�ORS[�XLEX�PIJX�ERH�VMKLX�[MPP�FI�XLI�WEQI�X]TI�EW�XLI�^IVS��WS�E�RYQFIV�
7XIT����8IWX�XIWX�XIWX�
;I�[ERX�E�RYQFIV�EX�XLI�IRH�
8LI�I\EQTPI�XVII�MWXLI�WEQI�EW�XLI�SRI�EFSZI�-J�[I�GEPP�WM^I�SR�MX��[IXVEZIVWI�XLI�IRXMVI�XVIIERH�JSV�IEGL�IRXV]�EHH���
7XIT����6ITIEX�
VIXYVR�8VII�IRXV]��VMKLX��PIJX
-X�PSSOW�PMOI�[I�[ERX�XS�VIXYVR�E�8VII�EX�XLI�IRH�2SRI�MW�LS[�[I�VI�VITVIWIRXMRK�XLI�IQTX]�XVII�LIVI���WSXLEX�QEOIW�WIRWI��-R�SVHIV�XS�W[MXGL�XLI�PIJX�ERH�VMKLX�[I�NYWX�W[MXGL�XLI�EVKYQIRXW�
��8LMW�MW�EGXYEPP]�E�WPMKLX�HEXE�EFWXVEGXSMR�ZMSPEXMSR����&EH���%�WXE½�
MJ�XVII�IRXV]�!!�IRXV]�����VIXYVR�����PIJX���VMKLXIPWI�����VIXYVR�PIJX���VMKLX
,IVI�[I�[ERX�E�GSYRX��WS�[I�WLSYPH�SYXTYX�E�RYQFIV�;I�EP[E]W�LEZI�EGGIWW�XS�XLI�IRXV]�EX�XLI�VSSX��XVII�IRXV] �IRXV]�MW�ER�EVKYQIRX�XS�J�ERH�MX�[MPP�FI�IEGL�IRXV]�MR�XLIIRXMVI�XVII��;I�GER�GSQTEVI�XLI�GYVVIRX�IRXV]�[MXL�XVII�IRXV]XS�¾KYVI�SYX�[LIXLIV�SV�RSX�[I�[ERX�XS�GSYRX�XLI�GYVVIRXIRXV]��F]�EHHMRK�� �
Login: 7
4. (10 points) Expansion Mansion
For a fraction n/d with n < d, its decimal expansion is written as a series of digits following a decimal point.
For example, 5/8 expands to 0.625. We can compute this result recursively. The numerator 5 times 10 is 50. 50divided by 8 is 6 with remainder 2. 20 divided by 8 is 2 with remainder 4. 40 divided by 8 is 5 with remainder0. The quotients in bold are the digits of the expansion. Each subsequent digit is the quotient of dividing 10times the remainder of the previous digit by the denominator of the fraction.
(a) (4 pt) Assume that the decimal expansion of n/d is finite, n is positive, and n < d. The functionexpand_finite returns the digits of the decimal expasion as an Rlist. Complete it by filling in eachblank with an expression. The Rlist class is defined in your study guide.
def expand_finite(n, d):
""" Return the finite decimal expansion of n/d as an Rlist. Assume n<d.
>>> expand_finite (1, 2) # 1/2 = 0.5
Rlist (5)
>>> expand_finite (5, 8) # 5/8 = 0.625
Rlist(6, Rlist(2, Rlist (5)))
>>> expand_finite (3, 40) # 3/40 = 0.075
Rlist(0, Rlist(7, Rlist (5)))
"""
dividend = n * 10
quotient , remainder = dividend // d, dividend % d
if _________________________________________________________________:
return _________________________________________________________
else:
return _________________________________________________________
(b) (2 pt) The function coerce_to_float returns the float equal to an input Rlist representing the seriesof digits following the decimal point in a finite decimal expansion. Complete its implementation below.
def coerce_to_float(s):
""" Return a float equal to an Rlist encoding a series of digits.
>>> coerce_to_float(expand_finite (1, 2))
0.5
>>> coerce_to_float(expand_finite (3, 40))
0.075
"""
if s is Rlist.empty:
return 0
else:
return ________________________________________________________
7XIT����6IEH�ERH�YRHIVWXERH�XLI�UYIWXMSR
5YIWXMSR�WE]W��;VMXI�E�VIGYVWMZI�JYRGXMSR�XLEX�HSIW�HMZMWMSR��
7XIT����%WWIWW�XLI)\EQTPIW
8LMW�I\EQTPI�MR�TEVXMGYPEV�MW�I\TPEMRIH�MR�XLITVSFPIQ�WXEXIQIRX��8LI�TVSFPIQ�KSIW�WXITF]�WXIT�ERH�I\TPEMRW�LS[�XLI�HMZMWMSR�[SVOW�
6)1)1&)6�(31%-2�%2(�6%2+)�
(SQEMR�LIVI�MWRYQFIVW
6ERKI�ETTIEVW�XS�FI�VPMWXW7XIT����%WWIWW�XLI�KMZIR�GSHI
.YWX�PMOI�MR�XLI�I\EQTPI�MR�XLI�TVSFPIQ�WXEXIQIRX��[I�XEOI�XLI�RYQIVEXSVERH�QYPXMTP]�MX�[MXL����¾VWX��*SV�I\EQTPI��MJ�R�!���ERH�H�!����XLIR�HMZMHIRH�!����
7XIT����8LMRO�EFSYXWSPZMRK�XLI�TVSFPIQFEWIH�SR�XLI�I\EQTPIW�VIEH�XLI�TYVTPI�XI\X
-J�R�!���ERH�H�!����XLIR�XLI�UYSXMIRX�!���ERH�VIQEMRHIV�!��MJ�R�!���ERH�H�!����XLIR�XLI�UYSXMIRX�!���������!���ERH�VIQEMRHIV�!��MJ�R�!���ERH�H�!����XLIR�XLI�UYSXMIRX�!���������!���ERH�VIQEMRHIV�!��8LVS[�EPP�XLI�UYSXMIRXW�MR�ER�6PMWX�WSQI[LS[�ERH�XLIR�[I�VI�HSRI�
2SXMGI�XLEX�XLI�VIQEMRHIVSJ�XLI�TVIZMSYW�GEPGYPEXMSR�FIGSQIWXLI�RI[�R��[LMPI�H�VIQEMRWXLI�WEQI
VIQEMRHIV�!!��
VIXYVR�6PMWX�UYSXMIRX
I\TERHC:RMXI�VIQEMRHIV��H 6PMWX�UYSXMIRX�
7S�RS[�[I�ORS[�XLI�VIGYVWMZI�GEPP��XLI�KVIIR ��FYX�MX�WXMPP�HSIWR�X�WIIQ�VMKLX���HSQEMR�ERH�VERKI�XS�XLI�VIWGYI��;I�ORS[�XLEX�I\TERHC¾RMXI�WLSYPH�VIXYVR�ER�6PMWX��VIH �
7XIT����8LMRO�EFSYX�XLI�XLMRKW�RIIHIH�JSVVIGYVWMSR��FEWI�GEWIW��VIGYVWMZI�GEPPW�ERH�[E]W�XS�QEOI�XLI�TVSFPIQ�WQEPPIV��-R�XLMW�GEWI�XLI�TVSFPIQ�LEW�FIIR�FVSOIR�HS[R�MRXS�XLIVIQEMRHIV�ERH�XLI�HMZMHIRH�
�
&EWI�GEWI��[LEX�W�XLI�WMQTPMIWX�GEWI�JSVI\TERHC¾RMXI#�;LIR�EVI�[I�HSRI#
,IVI�XLI�FEWI�GEWI�MW�KMZIR�XS�YW�;I�NYWX�RIIH�XS�:KYVI�SYX�XLI�VIGYVWMZIGEWI�ERH�LS[�XLI�TVSFPIQ�VIHYGIW�XS�MX�
GSIVGICXSC¿SEX�W�VIWX
0IX�W�NYWX�XV]�XLI�HYQF�XLMRK�
7XIT����8IWX8IWX�8IWX�I\TERH����� !"�6PMWX��
I\TERH������ !"�6PMWX����I\TERH������� ��!"�6PMWX����I\TERH������� ���!"�6PMWX�� !"�6����6����6��
(MHR�X�[SVO��(SGXIWXW�VIXYVRIH����;I�VI�QMWWMRK�WSQIXLMRK��0IX�W�XV]�EHHMRK�W�¾VWX�
��W�¾VWX
7XMPP�RSX�UYMXI��8LI�¾VWX�HSGXIWX�VIXYVRW����,S[�HS�[I�KIX�E�HIGMQEP#�0IX�W�XV]�WSQIXLMRK�HYQF���3L�LI]��XLI�XIWXW�TEWW�
� �����
8
Repeating Decimal Expansions. The decimal expansion of a rational number may be infinite, butcan always be described by a finite (and possibly repeating) series of digits. We can represent a series ofdigits as a recursive list, which may contain itself.
(c) (4 pt) Assume that n is positive and n < d. The expand function returns representations of both finiteand infinite decimal expansions. Complete it by filling in each blank with an expression or assignmentstatement.
def expand(n, d):
""" Return the decimal expansion of n/d as an Rlist. Assume n < d.
>>> expand(1, 2) # 1/2 = 0.5
Rlist (5)
>>> expand(5, 8) # 5/8 = 0.625
Rlist(6, Rlist(2, Rlist (5)))
>>> third = expand(1, 3) # 1/3 = 0.333333...
>>> [third[i] for i in range (10)]
[3, 3, 3, 3, 3, 3, 3, 3, 3, 3]
>>> third.rest is third # There is only one unique digit in 1/3
True
>>> fourteenth = expand(1, 14) # 1/14 = 0.0714285714285...
>>> [fourteenth[i] for i in range (10)]
[0, 7, 1, 4, 2, 8, 5, 7, 1, 4]
"""
return expand_using(n, d, {})
def expand_using(n, d, known):
""" Return the decimal expansion of n/d as an Rlist.
known -- a dictionary from integer k to the decimal expansion of k/d.
"""
if n in known:
return known[n]
else:
dividend = n * 10
quotient , remainder = dividend // d, dividend % d
digits = ________________________________________________________
_________________________________________________________________
if ______________________________________________________________:
_____________________________________________________________
return digits
7XIT����6IEH�ERH�YRHIVWXERH�XLI�UYIWXMSR
;EMX����HMHR�X�[I�NYWX�HS�XLMW#�;LEX�W�HM½IVIRX�LIVI#�;VMXI�E�VIGYVWMZI�JYRGXMSR�XLEX�HSIW�HMZMWMSR��
;EEEEEX#
7XIT����%WWIWW�XLII\EQTPIW��-R�XLMWGEWI��XLMW�LIPTW�YWHS�7XIT���QYGLFIXXIV��7II�KVIIR�
7S�XLIWI�¾VWX�X[S�I\EQTPIW�EVI�XLI�WEQI�EW�FIJSVI
,IVI�W�[LIVI�XLMRKW�KIX�XVMGO]��;LEX�HSIW�XLMW�QIER#
0IX�W�XV]�HVE[MRKSYX�[LEX�XLMVH�MW�
XLMVH
7XIT����%WWIWW�XLIKMZIR�GSHI��VIH �
7S�IZIRXYEPP]��[I�PP�GEPP�I\TERHCYWMRK�[MXLR��H�ERH�ER�IQTX]�HMGXMSREV]
8LIVI�W�E�LIPTIVJYGXMSR��I\TERHCYWMRK�;I�VI�WYTTSWI�XS�[VMXIMX#�SC3
;LEX�MW�I\TERHCYWMRKXV]MRK�XS�HS#�#
-X�PSSOW�PMOI�I\TERHCYWMRK�MW�HSMRK�EPP�XLI�[SVO��;L]�HS�[I�RIIH�XLMWHMGXMSREV]#�0IX�W�PSSO�EX�XLI�GSHI���
-J�SYV�R�MW�MR�XLMW�HMGXMSREV]�VIXYVR�XLI�ZEPYI#�%XPIEWX�[I�ORS[�SYVOI]W�EVI�KSMRK�XS�FIR�W
� �
8LMW�PSSOW�JEQMPMEV����MX�W�XLI�WEQI�GSHI�JVSQ��E�
7XIT����'SRWMHIV�HSQEMRERH�VERKI�ERH�EPWS�XLIXLMRKW�RIGIWWEV]�JSVVIGYVWMSR���KVIIR
;I�ORS[�XLEX�[I�VIXYVR�HMKMXW�EX�XLI�IRH�ERH�I\TERHCYWMRK�1978�VIXYVR�ER�6PMWX��WS�HMKMXW�QYWX�FI�ER�6PMWX�
6PMWX�UYSXMIRX�I\TERHCYWMRK�VIQEMRHIV��H��ORS[R
7XIT����8V]�XLMRKW�XIWX�XLIQ�SYX��RSXMGI�XLEXXLI]�VI�FVSOIR��ERH�:\XLIQ�6ITIEX�MJ�RIGIWWEV]��G]ER��SVERKI��ERH�TYVTPI 0IX�W�NYWX�XV]�XLI�SFZMSYW
XLMRK��;I�HMH�XLMW�MRI\TERHC¾RMXI�
;EMX��XLIR�[L]�EVI�XLIVIEPP�XLIWI�PMRIW�PIJX#;I�LEZIR�X�HSRI�ER]XLMRK[MXL�ORS[R�]IX�IMXLIV�-J�[I�OITX�XLI�G]ER�MR�[I�[SYPH�VIGYVWI�JSVIZIV��XIWX�[MXLI\TERHCYWMRK�������_a
8LI�HSGWXVMRK�WE]WXLEX�ORS[R�MW�E�HMGXMSREV][LSWI�OI]W�EVI�RYQFIVWERH�[LSWI�ZEPYIW�EVIHIGMQEP�I\TERWMSRW��6PMWXW� 0IX�W�XV]�XLI�WXYTMH�XLMRKXS�:PP�SYX�ORS[R�
ORS[R?RA�!�HMKMXW
&EWIH�SR�XLI�GSHI�VMKLXRS[��F]�XV]MRK�XLMRKW�SYX�[I�GER�SRP]�GSZIV�XLI�FEWI�GEWI�I\EQTPI�I\TERHCYWMRK�������_a �;LMGL�QIERW�XLEX�XLI�MJ�QYWX�FI�[LIVI�XLI�VIGYVWMZI�GEWI�MW�-J�XLI�FEWI�GEWI�MW�[LIVI�VIQEMRHIV�!!����XLIR�XLI�VIGYVWMZI�GEWI�MW�XLI�STTSWMXI�
VIQEMRHIV��!��
I\TERHCYWMRK�VIQEMRHIV��H��ORS[R
7XIT����8IWX�XIWX�XIWX���VIH 8IWXMRK�SYX�I\TERHCYWMRK�������_a �[SYPH�KMZI�YW�6PMWX�� ��8LEX�W�RSX�[LEX�[I�[ERX�;I�RIIH�XS�TSMRX�XLI�VIWX�SJ�XLI�VPMWX�XS�MXWIPJ��NYWX�PMOI�MR�XLI�FS\�ERH�TSMRXIV�HMEKVEQEFSZI��8LI�SRP]�[E]�XS�HS�XLEX�MW�XS�WE]�WSQI[LIVI�HMKMXW�VIWX����MX�W�RSX�MR�XLI�:VWX�PMRI�ERH�XLI�WIGSRH�PMRI�WIIQW�XS�FI�HSMRK�WSQIXLMRK�XLEX�[I�HSR�X�[ERX�XS�QIWW�[MXL�0IX�W�TYX�XLMW�SR�XLI�PEWX�PMRI�ERH�XIWX�EKEMR����3OE]��8LMW�XMQI�MX�[SVOW�
HMKMXW�VIWX�!
CS 61A Midterm 1 Study Guide – Page 1
208mul(add(2, mul(4, 6)), add(3, 5))
add(2, mul(4, 6))26mul
add 2mul(4, 6)
mul 4 6
24
add(3, 5)
add 3 5
8
-22
-2None
abs(number):
print(...):
display “-2”
2, 101024
pow(x, y):
Pure Functions
Non-Pure Functions
A name evaluates to the value bound to that name in the earliest frame of the current environment in which that name is found.
Defining:
Call expression:
square( x ):
return mul(x, x)
>>> def
square(2+2)
Calling/Applying: square( x ):
return mul(x, x)
Def statement
Formal parameter
Body
Return expression
(return statement)
operand: 2+2argument: 4
operator: squarefunction: func square(x)
Intrinsic name
4
16Argument
Return value
<header>: <statement> <statement> ... <separating header>: <statement> <statement> ... ...
Compound statement
Suite
Clause
Each clause is considered in order.1.Evaluate the header's expression.2.If it is a true value, execute the suite, then skip the remaining clauses in the statement.
1. Evaluate the header’s expression.2. If it is a true value, execute the (whole) suite, then return to step 1.
Execution rule for while statements:
Execution rule for def statements:
Execution rule for assignment statements:
Evaluation rule for call expressions:
Execution rule for conditional statements: hof.py Page 2
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
def pi_term(k): return 8 / (k * 4 − 3) / (k * 4 − 1)
# 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
def compose1(f, g): """Return a function that composes f and g.
f, g −− functions of a single argument """ def h(x): return f(g(x)) return h
@maindef run(): interact()
Function of a single argument (not called term)
A formal parameter that will be bound to a function
The function bound to term gets called here
The cube function is passed as an argument value
0 + 13 + 23 + 33 + 43 + 55
Higher-order function: A function that takes a function as an argument value or returns a function as a return value
Nested def statements: Functions defined within other function bodies are bound to names in the local frame
Evaluation rule for or expressions:
Evaluation rule for and expressions:
Evaluation rule for not expressions:
Applying user-defined functions:
1.Evaluate the operator and operand subexpressions.2.Apply the function that is the value of the operator subexpression to the arguments that are the values of the operand subexpressions.
1.Create a new local frame with the same parent as the function that was applied.
2.Bind the arguments to the function's formal parameter names in that frame.
3.Execute the body of the function in the environment beginning at that frame.
1.Create a new function value with the specified name, formal parameters, and function body.
2.Its parent is the first frame of the current environment.3.Bind the name of the function to the function value in the first frame of the current environment.
1.Evaluate the expression(s) on the right of the equal sign.2.Simultaneously bind the names on the left to those values, in the first frame of the current environment.
1.Evaluate the subexpression <left>.2.If the result is a false value v, then the expression evaluates to v.
3.Otherwise, the expression evaluates to the value of the subexpression <right>.
1.Evaluate the subexpression <left>.2.If the result is a true value v, then the expression evaluates to v.
3.Otherwise, the expression evaluates to the value of the subexpression <right>.
1.Evaluate <exp>; The value is True if the result is a false value, and False otherwise.
A name is bound to a value
In a frame, there is at most one binding per name
Statements and expressionsRed arrow points to next line.Gray arrow points to the line just executed
Frames (right):Code (left):
Import statement
Assignment statement
Name Value
Binding
Local frame
Intrinsic name of function called
Formal parameter bound to argument Return value is
not a binding!
Built-in function
User-defined function
2
1
“mul” is not found
2
1
3
1
2 1
Always extends
When a frame or function has no label
[parent=___]
then its parent is always the global
frame
Always extends
A three-frame environment
A two-frame environment
The global environment: the environment with only the global frame
A frame extends the environment that begins with its parent
2
1
“y” is not found
“y” is not found
Error
def abs_value(x):
if x > 0: return x elif x == 0: return 0 else: return -x
1 statement,3 clauses,3 headers,3 suites,2 boolean contexts
•An environment is a sequence of frames
•An environment for a non-nested function (no def within def) consists of one local frame, followed by the global frame
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
CS 61A Midterm 1 Study Guide – Page 2
A function that returns a function
A local def statement
The name add_three is bound to a function
Can refer to names in the enclosing function
square = lambda x,y: x * y
that returns the value of "x * x"with formal parameters x and y
A function
Must be a single expression
square = lambda x: x * x def square(x): return x * xVS
• Both create a function with the same domain, range, and behavior.
• Both functions have as their parent the environment in which they were defined.
• Both bind that function to the name square.
• Only the def statement gives the function an intrinsic name.
Begin with a function f and an initial guess x
(x, f(x))
-f(x)/f'(x)
-f(x)
�� ���)�����
>>> f = lambda x: x*x - 2>>> df = lambda x: 2*x>>> find_zero(f, df)1.4142135623730951
How to find the square root of 2?
1. Compute the value of f at the guess: f(x)2. Compute the derivative of f at the guess: f'(x)3. Update guess to be:
from operator import floordiv, moddef divide_exact(n, d): """Return the quotient and remainder of dividing N by D.
>>> q, r = divide_exact(2012, 10) >>> q 201 """ return floordiv(n, d), mod(n, d)
Multiple return values, separated by commas
Multiple assignmentto two names
def improve(update, close, guess=1): """Iteratively improve guess with update until close(guess) is true.""" while not close(guess): guess = update(guess) return guess
def approx_eq(x, y, tolerance=1e-15): return abs(x - y) < tolerance
def find_zero(f, df): """Return a zero of the function f with derivative df.""" def near_zero(x): return approx_eq(f(x), 0) return improve(newton_update(f, df), near_zero)
def newton_update(f, df): """Return an update function for f with derivative df, using Newton's method.""" def update(x): return x - f(x) / df(x) return update
def power(x, n): """Return x * x * x * ... * x for x repeated n times.""" product, k = 1, 0 while k < n: product, k = product * x, k + 1 return product
def nth_root_of_a(n, a): """Return the nth root of a.""" def f(x): return power(x, n) - a def df(x): return n * power(x, n-1) return find_zero(f, df)
2
1
3
1
2
3
•Every user-defined function has a parent frame (often global)
•The parent of a function is the frame in which it was defined
•Every local frame has a parent frame (often global)
•The parent of a frame is the parent of the function called
A function’s signature has all the information to create a local frame
Evaluates to a function.No "return" keyword!
def curry2(f): """Returns a function g such that g(x)(y) returns f(x, y).""" def g(x): def h(y): return f(x, y) return h return g
• The def statement header is similar to other functions• Conditional statements check for base cases• Base cases are evaluated without recursive calls• Recursive cases are evaluated with recursive callsdef sum_digits(n):
"""Return the sum of the digits of positive integer n.""" if n < 10: return n else: all_but_last, last = n // 10, n % 10 return sum_digits(all_but_last) + last
Currying: Transforming a multi-argument function into a single-argument, higher-order function.
Is fact implemented correctly?1. Verify the base case.2. Treat fact as a functional abstraction! 3. Assume that fact(n-1) is correct.4. Verify that fact(n) is correct,
assuming that fact(n-1) correct.
def fact(n): if n == 0: return 1 else: return n * fact(n-1)
• Each cascade frame is from a different call to cascade.
• Until the Return value appears, that call has not completed.
• Any statement can appear before or after the recursive call.
def count_partitions(n, m): if n == 0: return 1 elif n < 0: return 0 elif m == 0: return 0 else: with_m = count_partitions(n-m, m) without_m = count_partitions(n, m-1) return with_m + without_m
• Recursive decomposition: finding simpler instances of the problem: partition(6, 4)• Explore two possibilities:• Use at least one 4• Don't use any 4• Solve two simpler problems:• partition(2, 4)• partition(6, 3)• Tree recursion often involves exploring different choices.
When a function is defined:1. Create a function value: func <name>(<formal parameters>)2. If the parent frame of that function is not the global frame,
add matching labels to the parent frame and the function value (such as f1, f2, or f3).
3. Bind <name> to the function value in the first frame of the current environment.
When a function is called:1. Add a local frame, titled with the <name> of the function being
called.2. If the function has a parent label, copy it to the local frame:
[parent=<label>]3. Bind the <formal parameters> to the arguments in the local frame.4. Execute the body of the function in the environment that starts
with the local frame.
CS 61A Midterm 2 Study Guide – Page 1
Numeric types in Python:
>>> type(2)<class 'int'>
>>> type(1.5)<class 'float'>
>>> type(1+1j)<class 'complex'>
Represents integers exactly
Represents real numbers approximately
•Exact representation of fractions•A pair of integers•As soon as division occurs, the exact representation may be lost!•Assume we can compose and decompose rational numbers:
numeratordenominator
•rational(n, d) returns a rational number x
•numer(x) returns the numerator of x
•denom(x) returns the denominator of x
Constructor
Selectors
Rational number:
These functions implement an abstract data typefor rational numbers
There isn't just one sequence class or abstract data type (in Python or in general).The sequence abstraction is a collection of behaviors:
Length. A sequence has a finite length.Element selection. A sequence has an element corresponding to any non-negative integer index less than its length, starting at 0 for the first element.
We can implement recursive lists as pairs. We'll use two-element tuples to encode pairs.
A recursive list is a pair
The first element of the pair is the first element
of the list
The second element of the pair is the rest of
the list
None represents the empty
list
1 , 2 , 3 , 4
for <name> in <expression>: <suite>
1.Evaluate the header <expression>, which must yield an iterable value.2.For each element in that sequence, in order:A. Bind <name> to that element in the first frame of the current
environment.B. Execute the <suite>.
Executing a for statement:
..., -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, ...
>>> tuple(range(-2, 2))(-2, -1, 0, 1)
>>> tuple(range(4))(0, 1, 2, 3)
A range is a sequence of consecutive integers.
range(-2, 2)Length: ending value - starting valueElement selection: starting value + index
Tuple constructor
With a 0 starting value
[<map exp> for <name> in <iter exp> if <filter exp>]Short version: [<map exp> for <name> in <iter exp>]
A combined expression that evaluates to a list by this procedure:1. Add a new frame extending the current frame.2. Create an empty result list that is the value of the expression.3. For each element in the iterable value of <iter exp>:
A. Bind <name> to that element in the new frame from step 1.B. If <filter exp> evaluates to a true value, then add the value of
<map exp> to the result list.
List comprehensions:
•Lists are mutable sequences•Tuples are immutable sequences•Dictionaries are unordered collections of key-value pairs.
•Sets are unordered collections of values.
•Two dictionary keys or set elements cannot be equal.
•A dictionary key or set element cannot be an instance of a mutable built-in type.
The "in" and "not in" operators match substrings
>>> 'here' in "Where's Waldo?"True>>> 234 in (1, 2, 3, 4, 5)False
>>> city = 'Berkeley'>>> len(city)8>>> city[3]'k'
An element of a string is itself a string, but with only one character!
Strings are sequences too:
A function with a non-global parent frame
The parent contains local state
Every call changes the balance
All calls to the same function have the same
parent
def make_withdraw(balance): """Return a withdraw function with a starting balance.""" def withdraw(amount): nonlocal balance if amount > balance: return 'Insufficient funds' balance = balance - amount return balance return withdraw
Declare the name "balance" nonlocal at the top of the body of the function in which it
is re-assigned
Re-bind balance in the first non-local frame in which it was bound
previously
>>> withdraw(25)75
>>> withdraw(25)50
x = 2Status Effect
•No nonlocal statement•"x" is not bound locally
•No nonlocal statement•"x" is bound locally
•nonlocal x•"x" is bound in a non-local frame•"x" also bound locally
•nonlocal x•"x" is not bound in a non-local frame
•nonlocal x•"x" is bound in a non-local frame
Create a new binding from name "x" to object 2 in the first frame of the current environment.
Re-bind name "x" to object 2 in the first frame of the current env.
SyntaxError: name 'x' is parameter and nonlocal
SyntaxError: no binding for nonlocal 'x' found
Re-bind "x" to 2 in the first non-local frame of the current environment in which it is bound.
class ComplexRI: def __init__(self, real, imag): self.real = real self.imag = imag @property def magnitude(self): return (self.real ** 2 + self.imag ** 2) ** 0.5 @property def angle(self): return atan2(self.imag, self.real) def __repr__(self): return 'ComplexRI({0}, {1})'.format(self.real, self.imag)
math.atan2(y,x): Angle between x-axis and the point (x,y)
Property decorator: "Call this function on attribute look-up"
Type dispatching: Look up a cross-type implementation of an operation based on the types of its argumentsData-directed programming: Look up a cross-type implementation based on both the operator and types of its argumentsType coercion: Look up a function for converting one type to another, then apply a type-specific implementation.
>>> z = ComplexRI(-1, 0)>>> (z.real, z.imag)(-1, 0)>>> z.magnitude1>>> z.angle3.141592653589793
User-defined complex type:
CS 61A Midterm 2 Study Guide – Page 2
A class statement creates a new class and binds that class to <name> in the first frame of the current environment.Statements in the <suite> create attributes of the class.As soon as an instance is created, it is passed to __init__, which is a class attribute called the constructor method.
class <name>: <suite>
The suite is executed when a class statement is evaluated.
When a class is called:
1.A new instance of that class is created:
2.The constructor __init__ of the class is called with the new object as its first argument (named self), along with any additional arguments provided in the call expression.
>>> a = Account('Jim')
class Account: def __init__(self, account_holder): self.balance = 0 self.holder = account_holder
>>> a = Account('Jim')>>> b = Account('Jack')
>>> a is aTrue>>> a is not bTrue
Every object that is an instance of a user-defined class has a unique identity:
Binding an object to a new name using assignment does not create a new object:
Identity testing is performed by "is" and "is not" operators:
>>> c = a>>> c is aTrue
Every call to Account creates a new Account instance. There is only one Account class.
All invoked methods have access to the object via the self parameter, and so they can all access and manipulate the object's state.
class Account: ...
def deposit(self, amount): self.balance = self.balance + amount return self.balance
>>> tom_account = Account('Tom')>>> tom_account.deposit(100)100
Dot notation automatically supplies the first argument to a method.
Invoked with one argument
Defined with two arguments
Assignment statements with a dot expression on their left-hand side affect attributes for the object of that dot expression• For an instance, then assignment sets an instance attribute• For a class, then assignment sets a class attribute
>>> jim_account = Account('Jim')>>> tom_account = Account('Tom')>>> tom_account.interest0.02>>> jim_account.interest0.02>>> Account.interest = 0.04>>> tom_account.interest0.04
>>> jim_account.interest = 0.08>>> jim_account.interest0.08>>> tom_account.interest0.04>>> Account.interest = 0.05>>> tom_account.interest0.05>>> jim_account.interest0.08
Objects receive messages via dot notation.Dot notation accesses attributes of the instance or its class.
<expression> . <name>The <expression> can be any valid Python expression.The <name> must be a simple name.Evaluates to the value of the attribute looked up by <name> in the object that is the value of the <expression>.
tom_account.deposit(10)
Dot expressionCall expression
To evaluate a dot expression:1.Evaluate the <expression> to the left of the dot, which
yields the object of the dot expression.2.<name> is matched against the instance attributes of that
object; if an attribute with that name exists, its value is returned.
3.If not, <name> is looked up in the class, which yields a class attribute value (see inheritance below).
4.That value is returned unless it is a function, in which case a bound method is returned instead.
0.05Account class attributes
interest: 0.02(withdraw, deposit, __init__)
0.04
balance: 0holder: 'Jim'
Instance attributes of jim_account
balance: 0holder: 'Tom'
Instance attributes of tom_account
interest: 0.08
class CheckingAccount(Account): """A bank account that charges for withdrawals.""" withdraw_fee = 1 interest = 0.01 def withdraw(self, amount): return Account.withdraw(self, amount + self.withdraw_fee)
Inheritance: To look up a name in a class.1. If it names an attribute in the class, return its value.2. Otherwise, look up the name in the base class, if it exists.
>>> ch = CheckingAccount('Tom') # Calls Account.__init__>>> ch.interest # Found in CheckingAccount0.01>>> ch.deposit(20) # Found in Account20>>> ch.withdraw(5) # Found in CheckingAccount14
class Account: def __init__(self, account_holder): self.balance = 0 self.holder = account_holder def deposit(self, amount): self.balance = self.balance + amount return self.balance def withdraw(self, amount): if amount > self.balance: return 'Insufficient funds' self.balance = self.balance - amount return self.balance
class SavingsAccount(Account): deposit_fee = 2 def deposit(self, amount): return Account.deposit(self, amount - self.deposit_fee)
class AsSeenOnTVAccount(CheckingAccount, SavingsAccount): def __init__(self, account_holder): self.holder = account_holder self.balance = 1 # A free dollar!
class Rlist: class EmptyList: def __len__(self): return 0 empty = EmptyList() def __init__(self, first, rest=empty): assert type(rest) is Rlist or rest is Rlist.empty self.first = first self.rest = rest def __getitem__(self, index): if index == 0: return self.first else: return self.rest[index-1] def __len__(self): return 1 + len(self.rest) def __repr__(self): rest = '' if self.rest is not Rlist.empty: rest = ', ' + repr(self.rest) return 'Rlist({0}{1})'.format(self.first, rest)
Yes, this call is recursive
There's the base case!
def extend_rlist(s1, s2): if s1 is Rlist.empty: return s2 return Rlist(s1.first, extend_rlist(s1.rest, s2))
class Tree: def __init__(self, entry, left=None, right=None): self.entry = entry self.left = left self.right = right
def memo(f): cache = {} def memoized(n): if n not in cache: cache[n] = f(n) return cache[n] return memoized
def sum_entries(t): if t is None: return 0 else: return t.entry + sum_entries(t.left) + sum_entries(t.right)
12
3
Rlist(1, Rlist(2, Rlist(3)))
2
1 1
0 1
Tree(2, Tree(1), Tree(1, Tree(0), Tree(1)))left and right are
Trees or None
R(n) = �(f(n))
k1 · f(n) � R(n) � k2 · f(n)
n: size of the problemR(n): Measurement of some resource
means that there are positive constants k1 and k2 such that
for sufficiently large values of n.
�(bn)
�(n)
�(log n)
�(1)
⇥(n2)
Exponential growth! Incrementing the problem scales R(n) by a factor.
Linear growth.
Logarithmic growth.Doubling the problem only increments R(n).
Constant.
Quadratic growth. Incrementing n increases R(n) by the problem size n.
Resources scale with the problem size.
Independent of problem size.
5
3
1 7
9
11
8
7
9
11
8 7 8
Right! Left! Right!
None None
8None
Stop!
Tree set: A set is a Tree. Each entry is:• Larger than all entries in its left branch, and• Smaller than all entries in its right branch