[英]Secret Santa Program
We are required to create a program that can be used for the game "Secret Santa": 我们需要创建一个可用于游戏“ Secret Santa”的程序:
from random import *
people=[]
while True:
person=input("Enter a person participating.(end to exit):\n")
if person=="end": break
people.append(person)
shuffle(people)
for i in range(len(people)//2):
print(people[0],"buys for",people[1])
Here is the program I developed. 这是我开发的程序。 As of right now, if I input 3 people (Ex. Bob, Ben, Bill) it will return "Ben buys for Bill" with no one buying for Ben or Bob.
截至目前,如果我输入3个人(例如Bob,Ben,Bill),它将返回“ Ben为Bill买货”,而没人为Ben或Bob买东西。 I am currently trying to get it to output "Bob buys for Ben, Ben Buys for Bill, Bill buys for Bob" but have had no success thus far.
我目前正在尝试输出“ Bob买Ben,Ben买Bill,Bill买Bob”的输出,但是到目前为止还没有成功。 If someone could give me a hint/basis for setting this up it would be greatly appreciated.
如果有人可以给我提示/依据来进行设置,将不胜感激。 Also, if there are any errors in my code that are not allowing me to accomplish this, can you let me know?
另外,如果我的代码中有任何错误不允许我完成此操作,您可以让我知道吗? Thanks.
谢谢。
First hint, it makes no sense to use constants like 0 and 1 instead of i
inside your for
loop. 第一个提示,在
for
循环中使用0和1之类的常量代替i
是没有意义的。
for i in range(len(people)):
print(people[i],"buys for",people[(i+1)%(len(people))])
However, this implementation will not give you all the possibilities offered by a Secret Santa. 但是,此实现无法为您提供Secret Santa提供的所有可能性。
Let's suppose you enter "Alice", "Bob", "Claire", "David", you'll never get to the situation where: 假设您输入“ Alice”,“ Bob”,“ Claire”,“ David”,您将永远不会遇到以下情况:
You will only get circular permutations , ie: 您只会得到循环排列 ,即:
and alike. 都一样
You need some extra work to make a perfect Secret Santa :) 您需要做一些额外的工作才能制作出完美的Secret Santa :)
You are indexing 0 and 1, so it's always the first and second person being printed. 您正在索引0和1,因此它始终是要打印的第一个人和第二个人。 What you really want is:
您真正想要的是:
shuffle(people)
offset = [people[-1]] + people[:-1]
for santa, receiver in zip(people, offset):
print(santa, "buys for", receiver)
Say you have three people: ['Bob', 'Ben', 'Bill']
. 假设您有三个人:
['Bob', 'Ben', 'Bill']
。
In [1]: people = ['Bob', 'Ben', 'Bill']
Right now, when you get the length of this list, you're doing floor-division by 2. This results in: 现在,当您获得此列表的长度时,您正在按2进行地板分割。结果是:
In [2]: len(people) // 2
Out[2]: 1
That's why you only get a single line of output. 这就是为什么只获得一行输出的原因。
How might you get the Secret Santa result you want? 您将如何获得想要的Secret Santa结果? Here are some hints for an easy way to implement this:
以下是一些实现此目标的简单方法的提示:
from random import *
prompt = "Enter a person participating.(end to exit):\n"
people = list(iter(lambda:input(prompt), "end"))
shuffle(people)
people.append(people[0])
for i in range(len(people) - 1):
print(people[i],"buys for", people[i + 1])
Sample Run 样品运行
Enter a person participating.(end to exit):
A
Enter a person participating.(end to exit):
B
Enter a person participating.(end to exit):
C
Enter a person participating.(end to exit):
end
A buys for B
B buys for C
C buys for A
You can replace 您可以更换
people=[]
while True:
person=input("Enter a person participating.(end to exit):\n")
if person=="end": break
people.append(person)
with 与
prompt = "Enter a person participating.(end to exit):\n"
people = list(iter(lambda:input(prompt), "end"))
They both are doing the same thing. 他们俩都在做同一件事。
iter
function will keep executing the function we pass as the first parameter, till the second value is matched. iter
函数将继续执行作为第一个参数传递的函数,直到第二个值匹配为止。
And then, you do this 然后,您执行此操作
people.append(people[0])
Its a circular thing and the last person has to buy for the first person. 这是一个循环的事情,最后一个人必须为第一个人购买。
append
will insert at the last. append
将在最后插入。
for i in range(len(people) - 1):
We do len(people) - 1
, because if there are n
people, there will be n
buyings. 我们做
len(people) - 1
,因为如果有n
个人,就会有n
购买。 In this case, we have added the first person at the last, so we subtract one. 在这种情况下,我们在最后一个添加了第一个人,所以我们减去了一个。 Finally
最后
print(people[i],"buys for", people[i + 1])
every person has to buy for the next person in the list. 每个人都必须购买列表中的下一个人。 So,
people[i]
buys for the people[i + 1]
. 因此,
people[i]
为people[i + 1]
购买people[i + 1]
。
I realize my answer is a bit late, here is my own secret santa project I have been using the past few years and my answer might help. 我意识到我的回答有点晚了,这是我过去几年来一直在使用的自己的秘密圣诞老人项目 ,我的回答可能会有所帮助。 I snipped out the important pieces from my script.
我从脚本中摘录了重要的部分。
def pick_recipient(group,recipients,single_flag):
for person in group:
gift = random.choice(recipients)
if single_flag == 0:
while gift in group:
gift = random.choice(recipients)
else:
while gift in person:
gift = random.choice(recipients)
mail_list.append( '%s=%s' %(person,gift))
recipients.remove(gift)
return recipients
if __name__ == "__main__":
global mail_list
mail_list = []
#create lists of people, group couples at beginning or end of list and the singles opposite
all_recipients = ['name_1-CoupleA: name_1-CoupleA@gmail.com','name_2-CoupleA: name_2-CoupleA@gmail.com',
'name_3-CoupleB: name_3-CoupleB@hotmail.com','name_4: name_4CoupleB@hotmail.com',
'name_5-Single: name_5-Single@gmail.com','name_6-Single: name_6-Single@gmail.com']
#create couples and lists of singles to make sure couples don't get their other half
#modify the groups to match the list of people from above
coupleA = all_recipients [0:2]
coupleB = all_recipients [2:4]
single = all_recipients [4:]
#keep initial list in tact
possible_recipients = all_recipients
#modify the groups to match what the input list is
possible_recipients = pick_recipient(coupleA,possible_recipients,single_flag=0)
possible_recipients = pick_recipient(coupleB,possible_recipients,single_flag=0)
possible_recipients = pick_recipient(single,possible_recipients,single_flag=1)
print mail_list
https://github.com/savitojs/secret-santa-finder-script https://github.com/savitojs/secret-santa-finder-script
To use this script, you need to add name of the candidates you're playing with in secret_santa.py
file. 要使用此脚本,您需要在
secret_santa.py
文件中添加正在使用的候选名称。 _from and _to lists should be same for better results. _from和_to列表应该相同,以获得更好的结果。
Change _from
and _to
list(s) 更改
_from
和_to
列表
$ ./secret_santa.py Hi.. What is your nick name? [ENTER] savsingh Hey savsingh!, Hold on!! Searching... Any guess... ? Your secret santa is: bar Clear the screen [ENTER]:
So on... 等等...
Script here: 脚本在这里:
#!/usr/bin/python #=============================================================================== # # FILE: secret_santa.py # # USAGE: ./secret_santa.py # # DESCRIPTION: It can help you to find your secret santa, add participants name in _from and _to list # # REQUIREMENTS: python 2.6+, _from list and _to list should be same to work perfectly. # AUTHOR: Savitoj Singh (savitojs@gmail.com) # VERSION: 1.1 # CREATED: 12/21/2016 05:13:38 AM IST # REVISION: * Initial release # * Fixed minor bugs #=============================================================================== import random import os import time import sys '''Add participants to list''' _from = ['bob','foo','bar','savsingh','tom','jack','mac','hex'] '''Add participants to list''' _to = ['bob','foo','bar','savsingh','tom','jack','mac','hex'] class bcolors: HEADER = '\\033[95m' OKBLUE = '\\033[94m' OKGREEN = '\\033[92m' WARNING = '\\033[93m' FAIL = '\\033[91m' ENDC = '\\033[0m' BOLD = '\\033[1m' UNDERLINE = '\\033[4m' for i in range(len(_from)): try: user_name = raw_input('Hi.. What is your nick name? [ENTER] ') if user_name not in _from and user_name not in _to: try: print("") print(bcolors.FAIL + bcolors.BOLD + "Nick name doesn't seem to be in `_from` or `_to` list" + bcolors.ENDC) print(bcolors.HEADER + "\\nDo you expect me to look in galaxy ? It may take many x'mas to retrive results :P" + bcolors.ENDC) break except: pass else: print('Hey ' + bcolors.OKBLUE + bcolors.BOLD + str(user_name) + bcolors.ENDC + '!, Hold on!! Searching...') random.shuffle(_from) _from.remove(user_name) print(bcolors.WARNING + 'Any guess... ?' + bcolors.ENDC) print('') time.sleep(1) a = random.choice(_to) while str(a) == str(user_name): a = random.choice(_to) _to.remove(a) print(bcolors.BOLD + 'Your secret santa is: ' + bcolors.ENDC + bcolors.OKGREEN + bcolors.BOLD + str(a) + bcolors.ENDC) raw_input('Clear the screen [ENTER]: ') os.system('reset') except: print(bcolors.FAIL + bcolors.BOLD + "\\n\\nOops!!, Something went wrong..." + bcolors.ENDC) sys.exit(1)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.