1
1
# Submitted by Marius Becker
2
+ # Updated by Amaras
2
3
3
4
import sys
4
5
from random import shuffle
5
6
from copy import copy
6
- from string import ascii_uppercase
7
+ from string import ascii_uppercase , ascii_lowercase
8
+
7
9
8
10
def main ():
9
11
# Set this to however many men and women you want
10
- if len ( sys . argv ) > 1 :
12
+ try :
11
13
num_pairs = int (sys .argv [1 ])
12
- else :
14
+ except (IndexError , ValueError ):
15
+ # If you either did not set how many pairs you wanted or you
16
+ # did not set it as a number, use default value of 5
13
17
num_pairs = 5
14
18
15
- # There are only 26 possible names
16
- if num_pairs > 13 :
17
- print ('You can\' have more than 13 pairs.' )
19
+
20
+ # There are only 26 possible names for each sex
21
+ if num_pairs > 26 :
22
+ print ("You can't have more than 26 pairs." )
18
23
return
19
24
20
25
# Create all Person objects
21
- men = [ Person (name ) for name in ascii_uppercase [0 :num_pairs ] ]
22
- women = [ Person (name ) for name in ascii_uppercase [ num_pairs :num_pairs * 2 ] ]
26
+ men = [Person (name ) for name in ascii_uppercase [:num_pairs ]]
27
+ women = [Person (name ) for name in ascii_lowercase [ :num_pairs ] ]
23
28
24
29
# Set everyone's preferences
25
30
for man in men :
@@ -35,49 +40,46 @@ def main():
35
40
36
41
# Print preferences and the result
37
42
for man in men :
38
- print ('{}: {}' .format (man .name , ', ' .join ([ p .name for p in man .preference ])))
43
+ print (f"{ man .name } : { ', ' .join ((p .name for p in man .preference ))} " )
44
+
45
+ print ('' )
39
46
40
47
for woman in women :
41
- print ('{ }: {}' . format ( woman . name , ', ' .join ([ p .name for p in woman .preference ])) )
48
+ print (f" { woman . name } : { ' , ' .join (( p .name for p in woman .preference )) } " )
42
49
43
- print ('' )
50
+ print ('\n ' )
44
51
45
52
for man in men :
46
- print ('{ } + {}' . format ( man .name , man . partner .name ) )
53
+ print (f' { man . name } + { man .partner .name } ' )
47
54
48
55
def resolve (men , women ):
49
56
"""Finds pairs with stable marriages"""
50
- cont = True
51
- while cont :
57
+
58
+ while True :
52
59
# Let every man without a partner propose to a woman
53
60
for man in men :
54
- if not man .has_partner () :
61
+ if not man .has_partner :
55
62
man .propose_to_next ()
56
63
57
64
# Let the women pick their favorites
58
65
for woman in women :
59
66
woman .pick_preferred ()
60
67
61
68
# Continue only when someone is still left without a partner
62
- cont = False
63
- for man in men :
64
- if not man .has_partner ():
65
- cont = True
66
- break
69
+ if all ((man .has_partner for man in men )):
70
+ return
71
+
67
72
68
73
class Person :
69
- name = None
70
- preference = None
71
- pref_index = 0
72
- candidates = None
73
- partner = None
74
74
75
75
def __init__ (self , name ):
76
76
self .name = name
77
77
self .preference = []
78
78
self .candidates = []
79
+ self .pref_index = 0
80
+ self ._partner = None
79
81
80
- def get_next_choice (self ):
82
+ def next_choice (self ):
81
83
"""Return the next person in the own preference list"""
82
84
if self .pref_index >= len (self .preference ):
83
85
return None
@@ -86,7 +88,7 @@ def get_next_choice(self):
86
88
87
89
def propose_to_next (self ):
88
90
"""Propose to the next person in the own preference list"""
89
- person = self .get_next_choice ()
91
+ person = self .next_choice ()
90
92
person .candidates .append (self )
91
93
self .pref_index += 1
92
94
@@ -99,33 +101,39 @@ def pick_preferred(self):
99
101
if person == self .partner :
100
102
break
101
103
elif person in self .candidates :
102
- self .set_partner ( person )
104
+ self .partner = person
103
105
break
104
106
105
107
# Rejected candidates don't get a second chance. :(
106
108
self .candidates .clear ()
107
109
108
- def get_partner (self ):
109
- """Return the current partner"""
110
- return self .partner
110
+ @property
111
+ def partner (self ):
112
+ return self ._partner
113
+
114
+ # This allows one to change both self.partner and person.partner
115
+ # with the simple call: "self.partner = person"
116
+ @partner .setter
117
+ def partner (self , person ):
118
+ """Set a person as the new partner and sets the partner of that
119
+ person as well"""
111
120
112
- def set_partner (self , person ):
113
- """Set a person as the new partner and run set_partner() on that person
114
- as well"""
115
121
# Do nothing if nothing would change
116
122
if person != self .partner :
117
123
# Remove self from current partner
118
124
if self .partner is not None :
119
- self .partner . partner = None
125
+ self ._partner . _partner = None
120
126
121
127
# Set own and the other person's partner
122
- self .partner = person
128
+ self ._partner = person
123
129
if self .partner is not None :
124
- self .partner . partner = self
130
+ self ._partner . _partner = self
125
131
132
+ # This allows use of self.has_parnter instead of self.has_partner()
133
+ @property
126
134
def has_partner (self ):
127
- """Determine whether this person currently has a partner or not"""
128
- return self .partner != None
135
+ """Determine whether this person currently has a partner or not. """
136
+ return self .partner is not None
129
137
130
138
if __name__ == '__main__' :
131
139
main ()
0 commit comments