Go to file
2023-12-01 16:01:16 +00:00
templates Created script. 2023-12-01 15:36:40 +00:00
.gitignore Created script. 2023-12-01 15:36:40 +00:00
app.py Created script. 2023-12-01 15:36:40 +00:00
config.py Removed placeholder from testing 2023-12-01 16:01:16 +00:00
LICENSE Initial commit 2023-12-01 15:19:27 +00:00
README.md Created script. 2023-12-01 15:36:40 +00:00
secret.py.bak Corrected filename 2023-12-01 15:42:22 +00:00

README

This is a Python script for running a secret Santa draw.

This script:

  • Ingests participant data in JSON format,
  • Automates the randomised pairing of people to buy gifts for,
  • Includes information about preferences or restrictions for gifts that participants may have,
  • Automatically emails participants via GMail SMTP (requires external set-up), and
  • Creates an output file of gift pairings for troubleshooting later.

The script only uses standard libraries that come bundled with Python distributions, and does not require installing any dependencies.

Set Up

GMail SMTP

This app uses GMail as an SMTP provider.

  • This is because GMail accounts are free and easy to create,
  • The server is trusted by spam filters and is unlikely to be flagged as junk, and
  • The app can authenticate without using any external libraries.

This means that there will be a few steps of external set up.

  • Create secret.py from a copy of secret.py.bak.
  • Log in to (or create) a GMail account (a standard, free account should suffice).
  • Enable two-factor authentication on the account.
  • Under the two-factor authentication section, generate an App Password.
  • Enter your GMail username and the generated app password in secret.py.

secret.py

USERNAME = '<username>@gmail.com'
PASSWORD = '<app password>'

You can get more information on how to do this in the GMail documentation.

Using a Different SMTP Server

You can set up a different SMTP provider by editing the server information in config.py and providing the appropriate username and password in secret.py.

Data

The script ingests data as a JSON file. Create a file data.json (matching the file path in config.py) in the following format:

data.json

{
    "name0": {
        "email": "string",
        "preference": "string"
    },
    "name1": {
        "email": "string",
        "preference": "string"
    }
}

Note

Punctuation: Comma after every entry, except the last entry.

JSON syntax is very fragile and can break if not entered correctly.

Tip

Email Addresses: If you have provided an EMAIL_DOMAIN value in config.py, then you do not need to add the full email address, and can just provide the username before the @. If you do provide a full email address for a participant in the data file, it will override the domain name given.

Configuration

You can configure the app to send the draw for the secret Santa, including the greeting and the sign-off used, via the values in config.py. You can also edit the files in the ./templates directory to customise the email message to include any additional instructions or text as needed.

The most important configurations, however, are the credentials in secret.py and the data in data.json

Running the script

Because this script should work using standard libraries in Python 3, you should be able to execute the script using whatever Python 3 interpreter you have.

PowerShell

> python app.py

Bash

$ python3 app.py

The Algorithm

The algorithm I used for the secret santa draw is a very elegant one, as illustrated by Prof Hannah Fry.

  • Randomise the order of participants.
  • Generate a derangement from the randomised order by shifting the top name to the bottom of the list.
  • Match participants between the randomised list and derangement to pair who is buying for whom.

This ensures that:

  • People know whom they are buying for, but do not know who else is buying for whom, and
  • Everybody has an equal chance of buying for everybody else.
  • The person running the draw also does not know who is buying for them (unless they peek behind the curtain, as it were).

Troubleshooting

If you do need to see who is buying for whom, you can check the output.json file, or check the sent emails from the SMTP server.

Isn't This an Over-Engineered Solution for a Trivial Problem?

Of course it is.

Why Not Use an Existing Site for This?

Because where is the fun in that?