I’ve started something new this week: a role at a new department. I’m spending the first week poking my nose into things, meeting people, and getting my hardware/software/note-taking approach sorted.
I’m currently getting stuck into Obsidian, which I use to take notes in Markdown. It’s got a lovely feature whereby it links together ideas, so I can tag notes about #Architecture and then see at a glance who else I’ve spoken to about it. I’m hopeful that this will help me make sense of the whole thing, as well as keeping a good record of what I’m actually doing.
So far I’ve met a lot of people and generated multiple pages of notes. The constellation of my connected thoughts is currently a little haphazard, but I’m looking forward to seeing how that’ll grow over the next couple of weeks.
My new department is very keen on apprenticeships and so, inspired by Terence, I’m going to sign myself up to something. Before long I’ll have as many letters after my name as are in my name.
Also this week: I wrote a tiny little bit of code and then used Twilio to set up my familial secret Santa. For any rational human being, this is a task achieved through the use of small slips of paper and a hat/bag/inside-out umbrella. My family – my extended family – is closer to a clan, and with the addition of rules such as “No one in your immediate family”, I wondered if perhaps we could get a robot to do it.
Of course we could. Much geekery ahead:
Let’s start with some data:
id | name | family_name | parent_names |
0 | Sansa | Stark | NedCatelyn |
1 | Jon | Snow | Lyanna |
2 | Rickard | Stark | – |
3 | Arya | Stark | NedCatelyn |
The parent_names
property is useful, because we can use it to identify siblings, children, and parents – so that nobody ends up with someone in their immediate family. This can’t be done purely on family_name
, because although Rickard and Arya share the same family_name
they’re not in the same immediate family.
Here’s some code to match people together:
def score(person_one: dict, person_two: dict):
"""Good scores are low, bad scores are high"""
if person_one.get("parent_names") == person_two.get("parent_names")
# these would be siblings or partners - for the purposes of this
# code partners were modelled as siblings
# hence my use of Game of Thrones as an example...
or person_one.name in person_two.parent_names or person_two.name in person_one.parent_names:
# these are parent-child or child-parent relationships
return 1
else:
return 0
and here’s some code to calculate how every person matches with every other person:
import csv
import munkres
import itertools
import math
with open(family_data.csv) as the_clan:
everyone = [score(*pairing) for pairing in itertools.product(csv.DictReader(the_clan), repeat=2)]
square_size = math.sqrt(len(everyone))
matrix = [lst[i:i + square_size] for i in range(0, len(everyone), square_size)]
matches = munkres.Matrix(matrix).solve()
# this returns pairings that match the ids in the table above
return matches
I used this basic guide from Twilio to help write my function to send the messages.
# Download the helper library from https://www.twilio.com/docs/python/install
import os
from twilio.rest import Client
def send(recipient_number: str, gifter_name: str, giftee_name: str):
account_sid = os.environ['TWILIO_ACCOUNT_SID']
auth_token = os.environ['TWILIO_AUTH_TOKEN']
client = Client(account_sid, auth_token)
message_body = f"Dear {gifter_name}, you're going to be buying a present for {giftee_name} this year. " \
f"Don't forget to put some ideas in the WhatsApp group for your secret Santa! Lots of love, Santa"
message = client.messages \
.create(
body=message_body,
from_='Santa',
to=recipient_number
)
print(message.sid)
One cool feature of Twilio is that, if you chuck them £20 for an “upgraded” account, you can send texts where the “from” field can be a string, rather than a number. The upshot of this is that I could send messages that seemed to come from Santa!