简体   繁体   English

秘密圣诞老人计划

[英]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”,您将永远不会遇到以下情况:

  • Alice buys for Bob 爱丽丝买鲍勃
  • Bob buys for Alice 鲍勃买了爱丽丝
  • Claire buys for David 克莱尔为大卫买单
  • David buys for Claire 大卫买克莱尔

You will only get circular permutations , ie: 您只会得到循环排列 ,即:

  • Alice buys for Bob 爱丽丝买鲍勃
  • Bob buys for Claire 鲍勃为克莱尔买单
  • Claire buys for David 克莱尔为大卫买单
  • David buys for Alice 大卫买了爱丽丝

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: 以下是一些实现此目标的简单方法的提示:

  • You'll need some way of making sure two people don't get assigned to the same person and that a person doesn't get assigned to him- or herself. 您需要某种方法来确保两个人不会被分配给同一个人,并且一个人也不会被分配给他或她自己。
  • That probably means a list of possible buyers and a list of possible recipients -- pull them off one by one and find matches for them, checking that people aren't being assigned to themselves. 这可能意味着可能的买家列表和可能的收件人列表-逐一拉开他们,找到与他们匹配的商品,检查是否没有将他们分配给自己。
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

secret-santa-finder 秘密圣诞老人发现者

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列表

To run 跑步
 $ ./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.

相关问题 Python Secret Santa Program-如何获得更高的成功率 - Python Secret Santa Program - How To Achieve Higher Success Rate 秘密圣诞老人排序帽子 - Secret Santa Sorting Hat 有没有一种方法可以配对以后可以自行删除的数组的内容? (秘密圣诞老人计划) - Is there a way I could pair up the contents of an array that can delete itself later? (Secret Santa Program) 为什么我的 while 循环有时会卡住,但有时不会在我的“秘密圣诞老人”程序中? - Why does my while loop gets stuck sometimes,but sometimes not in my "secret santa" program? Python 秘密圣诞老人画画 - Python secret santa-ish draw 无法获得秘密圣诞老人代码来记住分配的名称 - Can't get Secret Santa code to memorize assigned names 防止在秘密圣诞老人算法中留下单个名字? - Prevent single name being left over in Secret Santa algorithm? 我正在尝试制作一个 discord 机器人,它会发送一条消息,提醒人们我们的秘密圣诞老人在 1 周内,但它不起作用 - Im trying to make a discord bot that sends a message reminding people that our secret santa is in 1 week but its isnt working python秘密词程序 - python secret word program 将秘密信息翻译成真正字母表的python程序 - python program that translates a secret message into real alphabet
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM