-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsecret_santa.py
136 lines (122 loc) · 6.42 KB
/
secret_santa.py
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
import random
santas = {}
class Person(object):
def __init__(self,name,email,blacklist):
self.name = name
self.email = email
# blacklist may contain multiple names seperated by spaces,
# and should always include the santa's own name.
if name not in blacklist:
self.blacklist = ' '.join([name,blacklist])
else:
self.blacklist = blacklist
self.giftee = None
def display(self, name):
return self.name, self.email, self.blacklist, self.giftee
def shuffle(santas):
def draw(name, list, swap = False):
avail_santas = list[:]
for canidate in avail_santas[:]:
if canidate in santas[name].blacklist:
# canidate on blacklist, ineligible
avail_santas.remove(canidate)
elif swap != False and name in santas[canidate].blacklist:
# name on canidate's blacklist, ineligible
avail_santas.remove(canidate)
# all santas have been checked, now pick one.
if len(avail_santas) > 0:
# choose a random name from the avail_santas
choice = random.choice(avail_santas)
if swap == False: # this is the first draw
santas[name].giftee = choice
giftees.remove(choice)
else: # this is a redraw, choice redraws from remaining giftees
santas[name].giftee = santas[choice].giftee
santas[choice].giftee = name
giftees.remove(name)
elif swap is False: # no good choices left, name must redraw.
redraw.append(name)
choice = None
else:
print 'Failed while drawing for',name
print "No possible combination exists."
quit()
#return giftees
# Set up variables for shuffling
giftees = [x for x in santas]
random.shuffle(giftees)
redraw = [] # santas that could not draw
# sort santas by the length of their blacklist
# make a dictionary of name:length of blacklist
picky = {n:len(santas[n].blacklist.split()) for n in santas}
# easy_santas are sorted lowest blacklist length to highest
easy_santas = sorted(picky.keys(), key=picky.get)
# picky_santas are sorted highest blacklist length to lowest
picky_santas = sorted(picky.keys(), key=picky.get, reverse=True)
# starting with the most picky santas, match santas to giftees
for name in picky_santas:
draw(name, giftees)
# fix santas who need to redraw
for name in redraw:
# start with santas most likely to be able to trade
draw(name, easy_santas, True)
# debugging - display results
print '*** Final Results ***'
for s in santas:
print santas[s].display(s)
def menu():
print 'Welcome to the Secret Santa python app.'
while True: # loop until they shuffle
input = ''
while len(input) < 2: # make sure they entered something
print 'Available commands are: ADD, DEL, DISPLAY, SHUFFLE, and HELP.'
print 'Example: >add ted [email protected] jane nancy sue'
# break input apart into a list
input = raw_input('> ').lower()
if input.startswith('add'): # add
# Split input into name, email, blacklist
input = input.split(None,3)[1:]
# assign variables even if input is < 3 pieces
# 3 vars = (~3-6 vars)[:3]
name, email, blacklist = (input + [None]*3)[:3]
# todo - This still needs work, potentially lets users have empty names
while not name and not "":
name = raw_input("Please enter the Santa's name: ").capitalize()
if not email:
email = raw_input("Please enter {}'s email: ".format(name))
if not blacklist:
print "Besides themselves, is there anyone {} should not draw?".format(name)
blacklist = raw_input("Seperate names by spaces, or leave blank: ").title()
# add to santas dict as name:object
santas[name] = Person(name,email,blacklist)
elif input.startswith('del'): # delete
# todo - deleting needs work
print 'Deleting not yet functional.'
elif input.startswith('dis'): # display
# todo - Should be expanded
for s in santas:
print santas[s].display(s)
elif input.startswith('shu'): # shuffle
print 'Shuffling..'
shuffle(santas)
break
elif input.startswith('sam'): # sample data
data = [
('Jo','j@','Jo'),
('Ted','t@','Ted Bob'),
('Amy','a@','Amy Jo'),
('Bob','b@','Bob Jo Ted')
]
for name, email, blacklist in data:
santas[name] = Person(name,email,blacklist)
else: # help
print 'Here are some tips on using this program:'
print ' 1 - To add names use the following syntax:'
print ' > add name email blacklist'
print ' > add ted [email protected] jane nancy sue'
print ' 2 - You can delete a santa using:'
print ' > delete ted'
print ' 3 - Or, shuffle the Santa list and assign everyone a giftee:'
print ' > shuffle'
if __name__ == '__main__':
menu()