selection sort (c) · selection sort, now in python 1def selection sort (s ): 2 ””” 3input :...
TRANSCRIPT
Using Python to Implement Algorithms
Tyler Moore
CSE 3353, SMU, Dallas, TX
Lecture 2
Some slides created by or adapted from Dr. Kevin Wayne. For more information see
http://www.cs.princeton.edu/~wayne/kleinberg-tardos
We already know Java and C++. Why learn Python?
Python has far less overhead than Java/C++ for the programmer.
Python is closer to psuedo-code on the English-pseudocode-codespectrum than Java or C/C++, but it actually executes!
Python is handy for data manipulation and transformation, andanything ”quick and dirty.”
Python is very powerful, thanks to all those extension modules.
2 / 33
Python Resources
Download from python.org for all major platforms
I’ve written an online tutorial:http://lyle.smu.edu/~tylerm/courses/cse3353/python.html
Think Python by Allen Downey:http://www.greenteapress.com/thinkpython/
Videos from Khan academy: https://www.khanacademy.org/science/computer-science-subject/computer-science
3 / 33
Selection Sort (C)
1 s e l e c t i o n s o r t ( i n t s [ ] , i n t n )2 {3 i n t i , j ;4 i n t min ;5 f o r ( i =0; i<n ; i++) {6 min=i ;7 f o r ( j=i +1; j<n ; j++)8 i f ( s [ j ] < s [ min ] ) min=j ;9 swap(&s [ i ] ,& s [ min ] ) ;
10 }
4 / 33
Selection Sort, now in Python
1 def s e l e c t i o n s o r t ( s ) :2 ”””3 I npu t : l i s t s to be s o r t e d4 Output : s o r t e d l i s t5 ”””6 f o r i i n range ( l e n ( s ) ) :7 #don ’ t name min s i n c e r e s e r v e d word8 min idx=i9 f o r j i n range ( i +1, l e n ( s ) ) :
10 i f s [ j ]< s [ min idx ] :11 min idx=j12 s [ i ] , s [ m in idx ]= s [ min idx ] , s [ i ]13 return s
Whitespacematters!
Dynamic, implicittyping
Iterators makelooping easy
Has built-in lists,dictionaries
Multiple variableassignment perline
5 / 33
Insertion Sort (C)
1 i n s e r t i o n s o r t ( i n t s [ ] , i n t n )2 {3 i n t i , j ;4 i n t min ;5 f o r ( i =1; i<n ; i++) {6 j = i ;7 whi le ( ( j >0) &&8 ( s [ j ] < s [ j −1])) {9 swap(&s [ j ] ,& s [ j −1 ] ) ;
10 j = j −1;11 }12 }13 }
6 / 33
Insertion Sort (Python)
1 def i n s e r t i o n s o r t ( s ) :2 ”””3 I npu t : l i s t s to be s o r t e d4 Output : s o r t e d l i s t5 ”””6 f o r i i n range ( l e n ( s ) ) :7 j=i #don ’ t c a l l v a r i a b l e min s i n c e i t ’ s r e s e r v e d word8 whi le j>0 and s [ j ]< s [ j −1] :9 s [ j ] , s [ j −1]=s [ j −1] , s [ j ]
10 j=j−111 return s
7 / 33
Python Built-in Data Types
Python uses implicit, dynamic typing
You can use casting functions float(), int() and str() to explicitlyconvert.
In addition to numbers and strings, Python offers built-in support forlists, tuples, sets and dictionaries.
8 / 33
Working with lists
1 >>> s p o r t s =[ ’ f o o t b a l l ’ , ’ t e n n i s ’ , ’ i c e hockey ’ , ’ l a c r o s s e ’ ,’ f i e l d hockey ’ , ’ b a s k e t b a l l ’ , ’ b a s e b a l l ’ , ’ swimming ’ ]2 >>> i n o r o u t =[ ’ out ’ , ’ both ’ , ’ i n ’ , ’ out ’ , ’ out ’ , ’ i n ’ , ’ out ’ , ’ i n ’ ]3 >>> l e n ( s p o r t s ) #bu i l t −i n f u n c t i o n computes the l e n g t h o f l i s t s4 85 >>> s p o r t s l o c=z i p ( s po r t s , i n o r o u t ) #bu i l t −i n f u n c t i o n combines l i s t e lement−wi s e6 >>> s p o r t s l o c7 [ ( ’ f o o t b a l l ’ , ’ out ’ ) , ( ’ t e n n i s ’ , ’ both ’ ) , ( ’ i c e hockey ’ , ’ i n ’ ) ,( ’ l a c r o s s e ’ , ’ out ’ ) , ( ’ f i e l d hockey ’ , ’ out ’ ) , ( ’ b a s k e t b a l l ’ , ’ i n ’ ) ,( ’ b a s e b a l l ’ , ’ out ’ ) , ( ’ swimming ’ , ’ i n ’ ) ]8 >>> r a n d om l i s t =[ ’ f o o t b a l l ’ , 3 , 6 . 7 , ’ham ’ ] #l i s t e l ement s don ’ t have to be the same type
9 / 33
List indexing
Python offers several ways to extract elements and sublists from alist. Syntactically you use square braces at the end of the list variablename, with the indices you want to access.
Indices start at 0. You can get a range of values by including twonumbers separated by a colon. If you use one number and a colon, itwill give you the rest of the list.
You can access the end of the list by using negative numbers
1 >>> s p o r t s [ 2 ]2 ’ i c e hockey ’3 >>> s p o r t s [ 1 : 3 ]4 [ ’ t e n n i s ’ , ’ i c e hockey ’ ]5 >>> s p o r t s [ 2 : ]6 [ ’ i c e hockey ’ , ’ l a c r o s s e ’ , ’ f i e l d hockey ’ , ’ b a s k e t b a l l ’ , ’ b a s e b a l l ’ , ’ swimming ’ ]7 >>> s p o r t s [ : 2 ]8 [ ’ f o o t b a l l ’ , ’ t e n n i s ’ ]9 >>> s p o r t s [−2]
10 ’ b a s e b a l l ’11 >>> s p o r t s [−2: ]12 [ ’ b a s e b a l l ’ , ’ swimming ’ ]
10 / 33
Modifying a list
>>> bar = [ ’ b ’ , ’ a ’ , ’ j ’ , ’ h ’ , ’ l ’ ]>>> bar . append ( ’ o ’ )>>> bar[ ’ b ’ , ’ a ’ , ’ j ’ , ’ h ’ , ’ l ’ , ’ o ’ ]>>> bar . pop ( )’ o ’>>> bar[ ’ b ’ , ’ a ’ , ’ j ’ , ’ h ’ , ’ l ’ ]>>> bar . ex tend ( [ ’ y ’ , ’ x ’ ] )>>> bar[ ’ b ’ , ’ a ’ , ’ j ’ , ’ h ’ , ’ l ’ , ’ y ’ , ’ x ’ ]>>> bar . i n s e r t ( ’w ’ , 3 )Traceback (most r e c e n t c a l l l a s t ) :
F i l e ”<s t d i n>” , l i n e 1 , i n <module>TypeError : an i n t e g e r i s r e q u i r e d>>> bar . i n s e r t (3 , ’w ’ )>>> bar[ ’ b ’ , ’ a ’ , ’ j ’ , ’w ’ , ’ h ’ , ’ l ’ , ’ y ’ , ’ x ’ ]>>> bar . s o r t ( )>>> bar[ ’ a ’ , ’ b ’ , ’ h ’ , ’ j ’ , ’ l ’ , ’w ’ , ’ x ’ , ’ y ’ ]>>> bar [ : : −1 ][ ’ y ’ , ’ x ’ , ’w ’ , ’ l ’ , ’ j ’ , ’ h ’ , ’ b ’ , ’ a ’ ]
11 / 33
Tuples and sets
Tuples are immutable lists
Sets are unordered lists
>>> t = (4 , 6 , 2 , 3 )>>> t [0 ]=5Traceback (most r e c e n t c a l l l a s t ) :
F i l e ”<s t d i n>” , l i n e 1 , i n <module>TypeError : ’ t u p l e ’ o b j e c t does not suppo r t i tem ass i gnment>>> s ={3 ,9 ,6 ,2}>>> s [ 2 ]Traceback (most r e c e n t c a l l l a s t ) :
F i l e ”<s t d i n>” , l i n e 1 , i n <module>TypeError : ’ s e t ’ o b j e c t does not suppo r t i n d e x i n g>>> 6 i n sTrue>>> 7 i n sF a l s e
12 / 33
Dictionaries
Dictionaries map keys to values. Both the keys and values can be of anytype, from strings to numbers, to other dictionaries.
1 >>> from sampledata import ∗2 >>> un i3 { ’ Jones ’ : ’ Oxford ’ , ’ G i l l i am ’ : ’ Oc c i d e n t a l ’ , ’ C l e e s e ’ : ’ Cambridge ’ ,’Chapman ’ : ’ Cambridge ’ , ’ I d l e ’ : ’ Cambridge ’ , ’ P a l i n ’ : ’ Oxford ’ }4 >>> un i [ ’ P a l i n ’ ]5 ’ Oxford ’6 >>> un i [ ’ P a l i n ’ ] = ’ Oxford U n i v e r s i t y ’7 >>> un i [ ’ P a l i n ’ ]8 ’ Oxford U n i v e r s i t y ’9 >>> un i . key s ( )
10 [ ’ Jones ’ , ’ G i l l i am ’ , ’ C l e e s e ’ , ’Chapman ’ , ’ I d l e ’ , ’ P a l i n ’ ]
13 / 33
Dictionaries
You can also start from an empty dictionary and then add values:
s p o r t 2 t y p e={}s p o r t 2 t y p e [ ’ f o o t b a l l ’ ]= ’ out ’s p o r t 2 t y p e [ ’ i c e hockey ’ ]= ’ i n ’>>> s p o r t 2 t y p e{ ’ i c e hockey ’ : ’ i n ’ , ’ f o o t b a l l ’ : ’ out ’ }
14 / 33
Python Tips
To see the methods available for a variable s, type dir(s) at theinterpreter
Python documentation (and Google) will help explain what eachmethod does: http://docs.python.org/2/index.html
You can also check the docstring for what methods do
15 / 33
Python Tips
>>> f oo = [ ’ ca t ’ , ’ dog ’ , ’ hamster ’ , ’ b u f f a l o ’ , ’ chee tah ’ ]>>> d i r ( foo ) #f i n d l i s t a t t r i b u t e s and methods[ ’ a d d ’ , ’ c l a s s ’ , ’ c o n t a i n s ’ , ’ d e l a t t r ’ ,’ d e l i t e m ’ , ’ d e l s l i c e ’ , ’ d o c ’ , ’ e q ’ ,
’ f o rm a t ’ , ’ g e ’ , ’ g e t a t t r i b u t e ’ , ’ g e t i t em ’ ,’ g e t s l i c e ’ , ’ g t ’ , ’ h a s h ’ , ’ i a d d ’ , ’ i m u l ’ ,
’ i n i t ’ , ’ i t e r ’ , ’ l e ’ , ’ l e n ’ , ’ l t ’ ,’ mu l ’ , ’ n e ’ , ’ n ew ’ , ’ r e d u c e ’ , ’ r e d u c e e x ’ ,’ r e p r ’ , ’ r e v e r s e d ’ , ’ rm u l ’ , ’ s e t a t t r ’ ,’ s e t i t e m ’ , ’ s e t s l i c e ’ , ’ s i z e o f ’ , ’ s t r ’ ,
’ s u b c l a s s h o o k ’ , ’ append ’ , ’ count ’ , ’ ex tend ’ , ’ i n d e x ’ ,’ i n s e r t ’ , ’ pop ’ , ’ remove ’ , ’ r e v e r s e ’ , ’ s o r t ’ ]>>> p r i n t f oo . pop . d o c #check the d o c s t r i n gL . pop ( [ i nd e x ] ) −> i t em −− remove and r e tu rn i t em at i nd ex ( d e f a u l t l a s t ) .R a i s e s I n d e xE r r o r i f l i s t i s empty or i n d e x i s out o f range .>>> f oo . pop ( )’ chee tah ’>>> f oo[ ’ ca t ’ , ’ dog ’ , ’ hamster ’ , ’ b u f f a l o ’ ]
16 / 33
Iteration in python
The python for loop is very powerful, due to its natural integration withiterators.
You can iterate lists:1 >>> from sampledata import ∗2 >>> f o r chee s e i n ch e e s e s :3 . . . p r i n t ’%s i s t a s t y ’ % ( chee s e )4 . . .5 sw i s s i s t a s t y6 g r u y e r e i s t a s t y7 cheddar i s t a s t y8 s t i l t o n i s t a s t y9 r o q u e f o r t i s t a s t y
10 b r i e i s t a s t y
You can iterate dictionaries:1 >>> f o r name i n un i :2 . . . p r i n t name , ”went to ” , un i [ name ]3 . . .4 Jones went to Oxford5 G i l l i am went to Occ i d en t a l6 C l e e s e went to Cambridge7 Chapman went to Cambridge8 I d l e went to Cambridge9 Pa l i n went to Oxford U n i v e r s i t y
17 / 33
List comprehensions
Recall set-builder notation from Discrete Math:
S = {3x |x ∈ N, x > 5}
We can approximate that in Python
>>> range (1 , 11 )[ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ]>>> {3∗ x f o r x i n range (1 , 11 ) i f x>5}s e t ( [ 2 4 , 18 , 27 , 21 , 3 0 ] )>>> [ 3∗ x f o r x i n range (1 , 11 ) i f x>5][ 1 8 , 21 , 24 , 27 , 30 ]
Comprehensions arise in very common coding scenarios
18 / 33
List comprehensions
Here’s a common coding task: iterate over some list, perform some actionon each element of that list, and store the results in a new list. Here’s anexample:
>>> ch e e s e s = [ ’ sw i s s ’ , ’ g r u y e r e ’ , ’ cheddar ’ , ’ s t i l t o n ’ ,’ r o q u e f o r t ’ , ’ b r i e ’ ]
>>> c h e e s e l e n =[]>>> f o r c i n ch e e s e s :. . . c h e e s e l e n . append ( l e n ( c ) ). . .>>> c h e e s e l e n[ 5 , 7 , 7 , 7 , 9 , 4 ]
We can do this on a single line:
c h e e s e l e n =[ l e n ( c ) f o r c i n ch e e s e s ]>>> c h e e s e l e n[ 5 , 7 , 7 , 7 , 9 , 4 ]
19 / 33
List comprehensions
But wait, there’s more! Suppose you only want to add items to the list ifthey meet a certain condition, say if the item begins with the letter s. Wellhere’s the long way:
>>> s c h e e s e l e n =[]>>> f o r c i n ch e e s e s :. . . i f c [0]== ’ s ’ :. . . s c h e e s e l e n . append ( l e n ( c ) ). . .>>> s c h e e s e l e n[ 5 , 7 ]
You can add a condition at the end of the list comprehension:
c h e e s e l e n =[ l e n ( c ) f o r c i n ch e e s e s i f c [0]==” s ” ]>>> s c h e e s e l e n[ 5 , 7 ]
20 / 33
More list comprehension examples
1 >>> s p o r t s2 [ ’ f o o t b a l l ’ , ’ t e n n i s ’ , ’ i c e hockey ’ , ’ l a c r o s s e ’ ,’ f i e l d hockey ’ , ’ b a s k e t b a l l ’ , ’ b a s e b a l l ’ , ’ swimming ’ ]3 >>> [ s f o r s i n s p o r t s i f l e n ( s )>8]4 [ ’ i c e hockey ’ , ’ f i e l d hockey ’ , ’ b a s k e t b a l l ’ ]5 >>> [ s f o r s i n s p o r t s i f ’ b a l l ’ i n s ]6 [ ’ f o o t b a l l ’ , ’ b a s k e t b a l l ’ , ’ b a s e b a l l ’ ]78 >>> s p o r t s l o c9 [ ( ’ f o o t b a l l ’ , ’ out ’ ) , ( ’ t e n n i s ’ , ’ both ’ ) , ( ’ i c e hockey ’ , ’ i n ’ ) ,
( ’ l a c r o s s e ’ , ’ out ’ ) , ( ’ f i e l d hockey ’ , ’ out ’ ) , ( ’ b a s k e t b a l l ’ , ’ i n ’ ) ,( ’ b a s e b a l l ’ , ’ out ’ ) , ( ’ swimming ’ , ’ i n ’ ) ]10 >>> [ s [ 0 ] f o r s i n s p o r t s l o c ]11 [ ’ f o o t b a l l ’ , ’ t e n n i s ’ , ’ i c e hockey ’ , ’ l a c r o s s e ’ , ’ f i e l d hockey ’ ,’ b a s k e t b a l l ’ , ’ b a s e b a l l ’ , ’ swimming ’ ]
12 >>> ou t d o o r s p o r t s =[ s [ 0 ] f o r s i n s p o r t s l o c i f s [1]== ’ out ’ ]13 >>> ou t d o o r s p o r t s14 [ ’ f o o t b a l l ’ , ’ l a c r o s s e ’ , ’ f i e l d hockey ’ , ’ b a s e b a l l ’ ]
21 / 33
List comprehension exercise
Write a function that squares each element of a list so long as theelements are positive using a list comprehension. Complete this code:
def s q u a r e L i s t ( l ) :r e t u r n #f i l l i n l i s t comprehens ion
22 / 33
Stacks and Queues
Sometimes, the order in which we retrieve data is independent of itscontent, being only a function of when it arrived.
A stack supports last-in, first-out operations: push and pop.
A queue supports first-in, first-out operations: enqueue and dequeue.
Lines in banks are based on queues, while food in my refrigerator istreated as a stack.
23 / 33
Python lists can be treated like stacks
Push: l.append()
Pop: l.pop()
What’s missing from list’s built-in methods to make queues possible?
List’s methods are ‘append’, ‘count’, ‘extend’, ‘index’, ‘insert’, ‘pop’,‘remove’, ‘reverse’, ’sort’enqueue():dequeue():
24 / 33
Queues in Python: deque
>>> from c o l l e c t i o n s import deque>>> q = deque ( [ 2 , 5 , 1 , 7 ] )>>> q . append (6 )>>> qdeque ( [ 2 , 5 , 1 , 7 , 6 ] )>>> q . p o p l e f t ( )2>>>
Enqueue: q.append()
Dequeue: q.popleft()
25 / 33
An intuitive method that guarantees to find a stable matching.
9
������������������������������������������
�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
��������������������������������
�������������������������������������������������������������������
�������←�������������������������������������������������������
������������������������
���������������������������
������������������������������������������������
���������������������������������
���������������������������
����
������������
�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
Python data structures to represent preferences
1 men = [ ’ x a v i e r ’ , ’ yancey ’ , ’ z eus ’ ]2 women = [ ’amy ’ , ’ b e r t ha ’ , ’ c l a r e ’ ]3
4 p r e f = { ’ x a v i e r ’ : [ ’ amy ’ , ’ b e r t ha ’ , ’ c l a r e ’ ] ,5 ’ yancey ’ : [ ’ b e r t ha ’ , ’ amy ’ , ’ c l a r e ’ ] ,6 ’ z eus ’ : [ ’ amy ’ , ’ b e r t ha ’ , ’ c l a r e ’ ] ,7 ’ amy ’ : [ ’ yancey ’ , ’ x a v i e r ’ , ’ z eus ’ ] ,8 ’ b e r t ha ’ : [ ’ x a v i e r ’ , ’ yancey ’ , ’ z eus ’ ] ,9 ’ c l a r e ’ : [ ’ x a v i e r ’ , ’ yancey ’ , ’ z eus ’ ]
10 }11 #turn the p r e f e r e n c e s i n t o a u s ab l e s t a c k by r e v e r s i n g o r d e r12 f o r n i n p r e f :13 p r e f [ n ] . r e v e r s e ( )
26 / 33
Python data structures to represent preferences
1 rank = { ’ amy ’ :{ ’ x a v i e r ’ : 2 , ’ yancey ’ : 1 , ’ z eus ’ : 3} ,2 ’ b e r t ha ’ :{ ’ x a v i e r ’ : 1 , ’ yancey ’ : 2 , ’ z eus ’ : 3} ,3 ’ c l a r e ’ :{ ’ x a v i e r ’ : 1 , ’ yancey ’ : 2 , ’ z eus ’ : 3}4 }5
6 f reemen = l i s t (men) #i n i t i a l l y a l l men and women a r e f r e e7 numpartners = l e n (men)8 #c r e a t e l i s t o f matches9 S = {}
27 / 33
Gale-Shapley algorithm in Python
1 whi le f reemen :2 m = freemen . pop ( )3 i f l e n ( p r e f [m])==0: continue4 #get the h i g h e s t ranked woman tha t has not y e t been proposed to5 w = p r e f [m] . pop ( )6 i f w not in S : S [w] = m7 e l s e :8 mprime = S [w]9 i f rank [w ] [m] < rank [w ] [ mprime ] :
10 S [w] = m11 f reemen . append (mprime )12 e l s e :13 f reemen . append (m)14
15 p r i n t S16 #{ ’ amy ’ : ’ x a v i e r ’ , ’ c l a r e ’ : ’ z eus ’ , ’ b e r t ha ’ : ’ yancey ’}
28 / 33
Alternative implementation: “pointers” instead of a stack
1 p r e f p t r = {}2 f o r m i n men :3 p r e f p t r [m] = 04
5 whi le f reemen :6 m = freemen . pop ( )7 i f p r e f p t r [m]>numpartners : continue8 #get the h i g h e s t ranked woman tha t has not y e t been proposed to9 w = p r e f [m] [ p r e f p t r [m] ]
10 p r e f p t r [m]+=111 i f w not in S : S [w] = m12 e l s e :13 mprime = S [w]14 i f rank [w ] [m] < rank [w ] [ mprime ] :15 S [w] = m16 f reemen . append (mprime )17 e l s e :18 f reemen . append (m)
29 / 33
Improving the code
An advantage of Python is quick development: you can get instantfeedback from code by running it in the interpreter (demo)
Once the code is working, though, we must make it modular
30 / 33
Step 1 to modularity: Create a function
1 def Ga l eShap l ey (men , women , p r e f ) :2 # p r e p r o c e s s i n g3 ## bu i l d the rank d i c t i o n a r y4 rank={}5 f o r w i n women :6 rank [w] = {}7 i = 18 f o r m i n p r e f [w ] :9 rank [w ] [m]= i
10 i+=111 ## c r e a t e a ” p o i n t e r ” to the nex t woman to propose12 p r e f p t r = {}13 f o r m i n men :14 p r e f p t r [m] = 015
16 f reemen = l i s t (men) #i n i t i a l l y a l l men and women a r e f r e e17 numpartners = l e n (men)18 S = {} #bu i l d d i c t i o n a r y to s t o r e engagements
31 / 33
Step 1 to modularity: Create a function
1 #run the a l g o r i t hm2 whi le f reemen :3 m = freemen . pop ( )4 i f p r e f p t r [m]>numpartners : continue5 #get the h i g h e s t ranked woman tha t has not y e t been proposed to6 w = p r e f [m] [ p r e f p t r [m] ]7 p r e f p t r [m]+=18 i f w not in S : S [w] = m9 e l s e :
10 mprime = S [w]11 i f rank [w ] [m] < rank [w ] [ mprime ] :12 S [w] = m13 f reemen . append (mprime )14 e l s e :15 f reemen . append (m)16 return S
32 / 33
Invoking the function
1 i f name ==” ma i n ” :2 #inpu t data3 themen = [ ’ x a v i e r ’ , ’ yancey ’ , ’ z eus ’ ]4 thewomen = [ ’amy ’ , ’ b e r t ha ’ , ’ c l a r e ’ ]5
6 t h e p r e f = { ’ x a v i e r ’ : [ ’ amy ’ , ’ b e r t ha ’ , ’ c l a r e ’ ] ,7 ’ yancey ’ : [ ’ b e r t ha ’ , ’ amy ’ , ’ c l a r e ’ ] ,8 ’ z eus ’ : [ ’ amy ’ , ’ b e r t ha ’ , ’ c l a r e ’ ] ,9 ’ amy ’ : [ ’ yancey ’ , ’ x a v i e r ’ , ’ z eus ’ ] ,
10 ’ b e r t ha ’ : [ ’ x a v i e r ’ , ’ yancey ’ , ’ z eus ’ ] ,11 ’ c l a r e ’ : [ ’ x a v i e r ’ , ’ yancey ’ , ’ z eus ’ ]12 }13
14 eng = Ga l eShap l ey ( themen , thewomen , t h e p r e f )15 p r i n t eng
33 / 33