Its that time of year where Secret Santa rolls around faster than you know it, and this year was no exception. For those unfamiliar, Secret Santa is a Christmas Gift exhange in which a person is randomly assigned a friend to gift to within a friend group. Nobody know whom is gifting to whom, and on the designed day, the Secret Santa is revealed and gifts are given out. This year, I took it upon myself to organize the event, with one exception, I did it all with code rather than pulling names out of a hat.
The Constraints were simple:
- Every individual must be assigned one individual
- Two people can not be assigned the same person
- You can not be assigned yourself
- You can not be assigned your significant other
The beauty of these constrants and this problem, is that it’s the perfect application of a Class in Python. For those unfamiliar: a class is a code template for creating objects, so you can assign parameters to each object.
class friend:
def __init__(self, name, partner = "None", email = "detroitsecretsanta2022@gmail.com"):
self.name = name
self.partner = partner
self.secretsanta = ""
self.email = email
In the case of this project, I assigned everyone four parameters, their name, their partner, their secret santa (undefined), and their email (defaulted to my sender). Now all we had to do was define our friends, and give everyone a Secret Santa. The friend definiton created objects for all of my friends as defined by the friend class. The name, partner, and email was assigned. If a friend was single, we could just omit the field because we initialized it to None!
#Friend Definition
Jon = friend("Jon", "Phoebe", "jonbarkersworld@gmail.com")
Phoebe= friend("Phoebe", "Jon", "phoebesemail@email.com")
friend1 = ...
...
...
all the friends!!!
After all friend objects were made, the friends were put in both a giver list and a reciever list, as every individual needed to give a gift to another individual.
giver_list = [Jon,Phoebe,friend1, ...]
reciever_list = [Jon,Phoebe,friend2, ...]
Now comes the fun part, the logic! Its a simple randon number generator that will randomly picks a name. the logic is as follows:
- Pick the first name in the giver list
- Generate a random number, and pick that name in the reciever list. Ex: If three, pick the third index in the list.
- Check if the name is the same as the giver or their partner.
- If it is, generate a new number and repeat
- If it is not, assign the reciever as the secret santa to the giver, and remove the name from the reciever list
- Move to the next name in the giver list
The Python code for the above logic is shown below.
index = 0
while len(giver_list) > 0:
random.seed = 2
random_int = random.randrange(-1,len(giver_list))
giver = giver_list[index]
reciever = reciever_list[random_int]
if giver.partner == reciever.name or giver.name == reciever.name:
random_int = random.randrange(-1,len(giver_list))
else:
giver.secretsanta = reciever
giver_list.remove(giver)
reciever_list.remove(reciever)
After checking that all of the names were properly assigned, the next part was to send an email! Now I could’ve copied and pasted everything into emails, but thats boring and I would know who has who. Python has this incredible library known as smtplib that allows you to send emails. After generating a two factor password for an application via email, you can enter the credentials and send an email via this library. For every giver in the list, I sent an email with their Santa. The code looked something like this:
import smtplib, ssl
from email.message import EmailMessage
import ssl
import smtplib
port = 465 # For SSL
email_sender = "detroitsecretsanta2022@gmail.com"
password = TWOFACTORGENERATEDPASS
subject = "Your Detroit Secret Santa for 2022!"
em = EmailMessage()
em['From'] = email_sender
#em['To'] = email_reciever
em['Subject'] = subject
em.set_content(body)
context = ssl.create_default_context()
with smtplib.SMTP_SSL('smtp.gmail.com', port, context = context) as smtp:
smtp.login(email_sender,twostep_password)
for giver in giver_list:
email_reciever = giver.email
em['To'] = email_reciever
body = f"""
Without further ado:
{giver.name} - Your Secret Santa for this year is: {giver.secretsanta.name}
Thanks for a great year, and can't wait for the next.
With love,
Jon
"""
em.set_content(body)
smtp.sendmail(email_sender,email_reciever, em.as_string())
del em['To']
It was that simple. the project was a little silly, but ultimately really fun to work through. Kinda neat how even times of remoteness, we can make a Secret Santa work.
Get Creative, y’all.
Why not?
-Jon

Leave a reply to Nireaux Cancel reply