Last active
December 5, 2015 20:01
-
-
Save s5b/4138054 to your computer and use it in GitHub Desktop.
KrisKringulator for creating your Kris Kringle so that even you don't know who got whom. (2015 version)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
""" | |
This is the KrisKringulator 2015. | |
It is a script that uses python (2.7+) to create a set of files containing the | |
name of the person for whom a participant in the Kris Kringle needs to buy a | |
gift. That is, it creates a file named after the buyer, with the name of the | |
buyer's recipient inside the file. | |
Based on an algorithm mentioned by Ryan Sattler. | |
This is designed to preserve the anonimity of all receivers. Simply send the | |
resulting files to the names of the file. | |
To use the application, by example: | |
>>> python kk.py outcome peter fred joanne gary jane | |
This will generate the following files: | |
./outcome/fred.txt | |
./outcome/gary.txt | |
./outcome/jane.txt | |
./outcome/joanne.txt | |
./outcome/peter.txt | |
""" | |
import sys | |
import random | |
import os | |
def create_gifting(result_dir, participant_from, participant_to): | |
with open(os.path.join(result_dir, participant_from + '.txt'), 'wt') as f: | |
f.write("%s buys for %s.\n" % (participant_from, participant_to)) | |
f.close() | |
def initialize_result_directory(result_dir): | |
if os.path.exists(result_dir): | |
print "The result directory must not already exist:", result_dir | |
exit() | |
os.mkdir(result_dir) | |
if len(sys.argv) < 3 : | |
print "Usage:", sys.argv[0], "result_directory participant1 participant2 ..." | |
result_dir = sys.argv[1] | |
initialize_result_directory(result_dir) | |
participants = sys.argv[2:] | |
random.shuffle(participants) | |
for index in range(0, len(participants) - 1): | |
create_gifting(result_dir, participants[index], participants[index + 1]) | |
create_gifting(result_dir, participants[len(participants) - 1], participants[0]) |
Updated the KrisKringulator to be implemented in python, instead of ruby. (Python is usually already installed on your *nix distribution, unlike ruby.) And the algorithm uses a different approach, as mentioned by Ryan Sattler. See the comments at the top of the gist to understand how to use it.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Gosh... There was a bug in the KrisKringulator! Thanks to Brett Herlihy for pointing out the symptom.
You see, the original code ran into a problem when the last remaining unmatched participant was the same as the last participant in the list. That is, all other participants had been matched with each other except the last participant. And since the same participant can't be matched to itself, then the last match would be blank - because a participant can't buy for themselves.
To fix the code I have added a test that checks if the last participant is contained in the final two remaining participants. If so, then the final two remaining participants are matched with each other. This solves the problem of not matching the last participant with themselves, but causes a slightly higher probability of the last two participants being matched together.
To mitigate the match probability problem, the participants are shuffled before being matched. This prevents the order in which the participants are entered on the command line from affecting the outcome.