Blog

November 16, 2018 19:39 +0000  |  2

This is going to be one of those ranty posts. If you don't fancy that sort of thing, you may wanna skip this one.

As a man, I honestly never gave much thought to childbirth. It wasn't something I'd have to deal with, so much like how to survive in a malaria-infested jungle, I mostly dismissed the idea as something others might have to contend with, but not something I needed to think about.

Then I married a girl who wanted a baby and so we started talking about and researching childbirth. What I've learnt in the past 6 months has been horrifying. If you have a uterus and are planning on using it to make a baby, you may want to buckle up. Here's a shortlist of the stuff that happens to you that we don't generally talk about:

Tearing

53-79% of women tear their vagainas during childbirth. For the lucky ones, this is only a 1st or 2nd degree tear which rip up your mucosal tissues (no stitches), labia minora (stitches... if the midwife notices), the perineum, or the area between the vagina and the anus.

For the unlucky ones, 3rd and 4th degree tears can extend all the way to the anus and even the anal sphincter. This is the sort of thing that you never truly heal from.

Breaking your tailbone

This is what we call it colloquially, but you're really breaking the joints in your tailbone which, if you're lucky (again) will heal after a few weeks of pain. If you're unlucky your tailbone will never heal correctly, you're forever in pain, and not even surgery can help you. [Source]

Incontinence

Ignoring the possibility of fistula from the aforementioned tearing, incontinence (the inability for you to control when you pee) is extremely disproportionately common in women vs men, in large part resulting from pregnancy and childbirth.

Painful Sex (dyspareunia)

Loss of pleasure or even painful sex, is another one. A recent study here in the UK showed that 7.5% of women suffer from this, with that number fluctuating between 5.3% and 10.4% depending on the age of the woman. In another study, 49% of all women experienced pain up to 6 months after birth, and 3.5% continued to suffer after that.


The reason we don't talk about this is multidimensional, but much of it can be attributed to a combination of taboos around sex, and a general lack-of-interest in women's health as a society. Most men don't know what a perineum is, or even that childbirth typically involves tearing, not to mention all of those other risks.

That's not the whole story though. If it were, I'd end the post here. Instead, I want to talk about our experience with the UK's midwife system, how backward, irrational, and dangerous it is, and how I sincerely believe it represents a system of women oppressing women.

Some Context

In the UK, we have the National Health Service (NHS), which is a form of single-payer health care much like Canada's Medicare system. Like Medicare, the NHS is struggling to keep up with demand, but unlike Medicare, the NHS is cripplingly poor. They're so broke that people aren't replacing the lights in the hospitals, there's regular shortages of staff, and a surplus of beds, as there's not enough people to staff them. Doctor strikes (to varying degrees) are a real concern.

It's in this climate that the NHS has adopted midwifery to handle the childbirth process. Over the years they've brought in less-rigorously trained midwives to do jobs the more experienced (and better paid) doctors were doing, freeing the doctors up for other work and thereby reducing the overall cost of baby-making on a national scale. These days, childbirth typically doesn't even involve a doctor and roughly 2.1% of births are done at home.

A midwife might be a trained & experienced registered nurse who chose to specialise in midwifery, or they could just be someone fresh out of high school with a C-average who liked the idea of being a midwife and showed up for a whole 3 years of training. There are no national minimum academic entry requirements for entry into pre-registration midwifery degrees.

Once trained, the midwives are posted to general practises around the country, where would-be parents are sent directly to them. From the moment you pee on that stick, the midwife is the gatekeeper between you and the NHS. She decides if you can see a doctor, if your needs are sufficient that you might go over her head to someone with an actual medical degree.

Feelings, not Evidence

None of this would be a problem really if the midwives were actually thoughtful, rational people, but everything we've seen to date tells us that the opposite is true.

Our midwife has flat-out lied to us on multiple occasions about Christina's health risks and personal welfare. Whether those lies were out of ignorance or ideology, there's no way to know, but the result is an immediate distrust of the only person you're permitted to talk to within the National Health Service.

When your midwife tells you that "vaccination causes whooping cough", there's no recourse for you to find a health care professional that isn't a dangerous idiot. In fact you're encouraged to come to them with everyday questions about your health, your risks, and those of your baby, and you're expected to take their advice at face-value. She is the "professional" after all.

When in Doubt, Make it Up

One of my favourite logical fallacies, the "appeal to nature", is the blind assumption that whatever is "natural" must be the best option. When it comes to baby-making, this means ignoring the fact that childbirth is fucking dangerous and has killed and maimed hundreds of millions of women over the centuries. Prioritising "natural" over man-made practises by virtue of their "naturalness" is not a rational choice but an emotional, and therefore irrational one.

In the context of the NHS midwife system, this takes the form of your only available "professional" giving you advice like the following:

Note: these are actual examples of advice given by midwives to us directly:

  • "Hypnobirthing works!" It doesn't.
  • "Aromatherapy works!" I'm not even going to dignify this the a refuting link.
  • "Avoid 'unnatural' sugars like chocolate or candy, and instead opt for 'natural' ones like honey because 'the sugars are different' and 'natural sugars won't make you crash'." The truth is that honey and sugar are both carbohydrates composed primarily of glucose and fructose, and that if anything, the opposite is true.
  • "Water births reduce tearing". While it's true that water births tend to involve less pain, fewer drugs, and a faster process overall, they don't reduce tearing. In fact, a UK study showed that water births had a 12% higher rate of perineal tears, and a 23% lower rate of episiotomy (when they cut you to avoid tearing). The reality is that it's a terrible method to use if you expect anyone to help monitor the process, because no one can see what's happening and work to prevent damage.
  • "Every woman can breast feed". This is also false and was the subject of a particularly galling incident during a prenatal class we attended last weekend:

    One of the attendees asked "what if you can't breast feed?" and the woman responded: "Why would you think that?" and went on to lecture him about how ignorant he was about women's bodies, that every woman can indeed breastfeed (false) and suggested that his wife was just lazy and wanted to sleep. She then went on to insist that we shouldn't bring formula to the hospital and that if they felt it was appropriate they would provide some.

    Finally, she claimed formula is so hard for a baby to digest that it can cause constipation for up to 4 days. In fact, it's normal for breast fed babies not to poop for as much as 5 days, and formula too has unpredictable results in "regularity". I could find no study citing a correlation (let alone a causation) between constipation and the method with which babies were being fed.

  • "Forceps don't increase tearing". Well of course the forceps don't cause the tear, but inserting them into you, widening you to fit a baby's head & forceps certainly does. Risks to mother and baby with completely dodged or glazed over despite multiple requests for more information.
  • "Midwives don't perform episiotomies". Except that when you press her for details as to who is cutting into you with a scalpel, she confesses that midwives, with all their years of medical training do in fact perform them.

On top of all of this, our experience with their examinations would be laughable if it weren't terrifying. Different midwives have "examined" Christina and found:

  • The baby hadn't grown in 2 weeks.
    • An ultrasound, performed by an actual doctor, showed that the baby was fine. The midwife just wasn't measuring properly.
  • The baby had turned. The midwife pointed to the location of the head, feet, etc.
    • An ultrasound, performed by an actual doctor, showed that the midwife had a completely backward notion of where the baby actually was.

These are the "professionals" you expect to protect you and your baby from injury and death. These women cut into you and make critical life-and-death decisions. The women who lie when the facts don't suit their worldview, and demonstrably don't have the skills (or perhaps just the interest? It's unclear which is worse) to gather the evidence needed to perform the work for which they're responsible.

Women as Baby-Making Machines

The above is disturbing for anyone headed into a life-threatening medical procedure, but unfortunately it's just the start. Imagine a situation where your appendectomy surgeon says to you: "What's really important here is that we save that appendix". You would be understandably alarmed. Surely the doctor's job is to make sure you survive the procedure... right?

If there's anything that's made abundantly clear though our dealings with NHS midwives it's that they don't care about women. Concerns about pain or long-term disability are either shrugged off or met with the same response:

Don't worry, worst case scenario, you won't be able to have another baby for a couple years.

That's right, you had a question about whether your sexual organs would ever be able to work properly again, and the "professional" let you know that the real question is whether or not you'll be able to give birth again soon.

To the midwife, every woman is just a baby-making machine.

The midwives have told us that they operate under what they call "assumed consent" during the birthing process. In other words, you're given the opportunity to outline what your needs are during childbirth, what your red-lines are around things like forceps and C-sections, and then those requirements are promptly thrown out in favour of what the midwife feels is best in the moment. The same professional that couldn't tell you where the baby was a few weeks ago.

If the aromatherapy and hypnobirthing hasn't done the trick and labour goes bad, the midwife makes the call as to whether she'll try to cut your perineum, or if she'll call the doctor to come with the forceps. C-section is typically off the table unless the baby is in real danger. Even more exciting is that these choices are time-sensitive: once the baby is far enough down the birth canal, a C-section becomes very dangerous -- but they might do it anyway.

You don't get a say in any of this. Your consent is assumed, and for the parts where legally your consent is still required, try standing up for your rights when you're hemorrhaging in a bathtub.

The Realities of Geography

So that's the state of things in this backward country. Christina had her final scan at 28 weeks and now we get to depend on the expert opinions of the midwives as their magic fingers somehow figure out if the baby has turned and if it's likely to be small enough not to irreparably harm her.

If somehow the complete lack of knowledge of the situation fails to produce a smooth & uneventful birth, it's unlikely that we will be able to refuse the use of forceps. We just get to hope that the overworked, underpaid doctor using medieval tools to operate on a woman he's never met and knows nothing about won't accidentally maim Christina, kill the baby, or just cause her brain damage.

Hope. In twenty fucking eighteen, people in the UK don't have pre-natal scans to determine child position and size, or properly educated medical help, but they have hope, because hope doesn't cost money.

Statistically speaking, the UK is a disaster on this file compared to other European countries. In countries with high rates of C-sections (either elective or as a first go-to for emergencies) forceps births are much, much lower:

Vaginal spontaneousVaginal instrumentalElective CaesareanEmergency Caesarean
Germany62.26.415.415.9
Italy58.63.424.913.1
Romania62.50.53.833.1
England62.812.69.914.7

Source: Royal College of Obstetricians and Gynaecologists

What's Next

We've been told that the hospital here flatly denies maternal requests for C-sections, despite the fulfillment of such requests being officially part of the NHS guidelines. We've talked about it, and Christina is comfortable with the "natural" method so long as she can trust that in the event that things go wrong, that forceps will not be used, but rather she would go straight to C-section.

But that's the problem: trust. There just isn't any between us and these budget midwives. They've lied to us, pushed an agenda, demonstrably ignored evidence and best practise in favour of ideology. They're grossly unqualified to cut into another human being, and have directly stated that they have no intention of adhering to Christina's wishes. I don't know what we're going to do, what we can do in this situation.

This is a Feminist Issue

Critically, and as a feminist, I find much of how we treat childbirth outrageous. From where I'm standing I see a bunch of crazy people, crazy women, imposing their whacked-out religion on other women under the guise of "taking back" pregnancy & childbirth from the evil doctors.

It's framed as a battle between "women know better because women" and "doctors want to medicalise everything for profit", but this is a preposterous comparison. The UK is suffering from shortages of nurses and doctors. There's no drive -- especially in a nationalised health care service -- to medicalise anything for profit. The motivation is quite the opposite, so this a blatant myth, a myth fact-phobic hippies are using to beat women into submission.

If this were a prostate cancer treatment, you can bet there'd be outrage. Men aren't socialsed to shut up and put up with whatever society foists upon us, but women are a different story. Women are being fed this lie that childbirth is safe & magical, that massage, hypnosis, and essential oils are just as good as ultrasounds because they're "natural".

Most importantly, women are told that to deny this myth is a betrayal of the feminine, that good mothers sacrifice for their children and so they shouldn't be concerned about what happens to them. This is bullying and oppression, by women, of women.

If this was an organisation of unqualified men insisting that bullshit snake oils were all women needed, that the risks weren't real, and that any concern for the mother's health made her a bad mother, we'd all know what to call it. But it's women pushing this fantasy, and so we play along. We set public policy to fund treatments that don't work, to employ people that lie to their patients.

I'm seething. I'm angry that the state would do this to my wife, but I'm even more angry that society has bought into this fantasy so much that getting professional help for a dangerous procedure is near impossible.

We can hope everything will be alright, but I think any rational person would take knowledgeable professionals over hope any day.

July 29, 2018 22:57 +0000  |  1

Even as a kid, I'd always known what I wanted to do for my own wedding. "Potluck in the park" I'd say, and everyone would look at me like I'm crazy or joking. I would then go on about how I was totally serious, that everyone would bring doughnuts and KFC, and that it would be cheapest, lowest-hassle wedding of all time. It would also be a lot of other things, but I would rarely talk about that.

Weddings #1 & #2 we're lovely, but most of the people I love, like deep-down-from-my-toes-up-love, the ones I've known forever, couldn't be there. People like my brother and his new family, or Michelle, Jeanie, Ruth, Shawna, Quinn, Chris & Trish, and Noreen -- I've known these people for more than twenty years -- and none of them were able to cross the Atlantic last year. Then there's the people I met later in life, with whom I've bonded terribly strongly: Poesy, Robin, Stephanie -- they couldn't be there in Cambridge or Athens either, so this one, this day was really important to me.

It was a day full of love, and hugs, and the all-important KFC & doughnuts. Some old friends brought their kids, Ruth brought her family's newest addition, Nelix the dog, and Noreen managed to rope Merry in with her too. People brought their partners, and chocolate, and a shared support for Christina & me. Michelle and I got to sing together, and we looped in Quinn & Merry for an SATB reunion that's 21 years old now. I got to meet Chris' new twins, and teach Violet how to tell time, and we had the simplest, most intimate ceremony I could have asked for.

Poesy led a simple ceremony wherein Violet tossed flowers about while she gave us all a crash course in indigenous culture, and Michael worked his photography magic with everyone over the course of the whole day.

I have never felt more loved, and more blessed than I did yesterday. Thank you to everyone who came out to make it wonderful. I don't think I'm capable of shaping my gratitude into the words I need to tell you how much I appreciate it.

July 01, 2018 15:04 +0000  |  4

So, yeah, this is happening.

Christina is officially carrying around a parasite that will one day rip its way out of her to be adorable for a few years before getting snotty and rebellious until she finally emerges to be the next Something Awesome.

In case you missed the pronoun selection there, yes, the doctors say they're pretty sure it's going to be a girl.

Predictably, I'm both excited and terrified by the whole ordeal. A kid changes everything, not the least of which is the simple cost of existing. Never mind the price of baby clothes, toys, diapers, and child-care, or the costs of food, toys, and clothing for a teenager. A dependent means adding 30% onto nearly every travel arrangement I'm going to make for the next twenty years.

There's also of course the near complete lack of support system we have here in the UK. We have a few friends, and zero family. While my brother lives a stone's throw from both sets of grandparents, we're 73623km from Kelowna and 2991km from Athens. Sure, family will visit, but we're on our own for most of this.

And then there's the risk that the child will be born with a severe disability of some kind that would relegate us to babysitters for life. We've done all the tests one can do for this sort of thing, but the risk is never 100% eliminated. This is the sort of thing you don't really consider when you think about bringing a new life into this world: that that life would mean that you are forever responsible for feeding them, cleaning up after them, that any semblance of a private life you may have fantasised about is gone. I'm willing to bet that every parent is absolutely terrified of this.

Finally, there's that wonderful conversation between two characters on one of the greatest TV shows ever made:

The world is dark and full of terrors: global warming is going to be the primary antagonist of her life, just as Nazism is making a comeback. The ocean is choking on plastic while every ecosystem is in decline and we're facing a mass privatisation of all fields of human endeavour -- and yet, terrors or not, she's coming. The world had best get ready.

I feel like I haven't done enough to fix the world in advance of her arrival, but she's coming anyway, before any of us are prepared. I already know what sort of person I want to raise her to be though, and I hope that that, combined with the wisdom our families have granted us will be enough to get her there.

I'm worried, but I feel like I'm ready -- at least mentally if not financially or globally. This is going to be an adventure.

May 18, 2018 09:11 +0000  |  0

Objects vs. Functions

I volunteer with a few groups of new software developers and a question that keeps coming up is: "why should I use objects?". Typically this is couched in something like: "I just have a lot of functions organised into files, and I'm not sure what reorganising all of my code to be OOP would really do for me".

So I thought I'd write out a detailed explanation with examples & such for those who might find it useful. Here goes:

It's ok not to OOP

I love me some objects. In fact, I'll often use objects for no other reason than to have my code neatly tucked into classes, even when a function will do, but I'm crazy like that. The truth is, a lot of smaller projects & scripts don't need OOP to do what you want, but once you really get a handle on what they can do for you, you might find that you're Classifying All The Things.

Regardless, please don't read this as some sort of "Classes are the One True Path" rant, 'cause it's not.

Foodz

I like me some food, so the examples I'm going to use are food-based. For our exercise we're going to be writing code for an imaginary kitchen run by robots, an idea that in 2018 really isn't all that crazy.

We've got 50 people to feed at 20 tables. Our code needs to keep track of who ordered what from what table, as well as prepare the food in the kitchen and deliver it to our hungry patrons. That's a lot of code, so we won't be writing it all out here. Instead, I'll break down a rough idea of how this might be done using procedural code (functions in files) vs. object-oriented code.

The Procedural Way (functions)

When you're working with functions, you're effectively pushing data around and modifying it when necessary. For our kitchen example, you might start with a complex array of data for our patrons:

patrons = [
    {
        "name": "Amber", 
        "table": 1, 
        "order": [
            {"name": "House Salad", "price": 350, "dressing": "Ranch"},
            {"name": "Death by Chocolate", "price": 250, "flavour": "Chocolate"}
        ]
    },
    {"name": "Brianne", "table": 1, "order": ["steak", "cake"]},
    {"name": "Charlie", "table": 2, "order": ["chicken burger", "pudding"]},
    {"name": "Dianna", "table": 2, "order": ["salad", "pudding"]},
    ...
]

That takes care of who is sitting where and what they ordered. Next we also need instructions for making the food, which uses a branching system of rules:

def make_food(food: str) -> str:
    if food == "salad":
        return make_salad()
    if food == "burger":
        return make_burger()
    if food == "steak":
        return make_steak()

Each of those functions in turn might call other functions to do the "making", for example, the steak might include something like marinade() or salad.py could have another function inside it called make_dressing() which is called from inside make_salad(). The key thing to note here is that each of these functions are either very specific, or contain branching code to decide which thing to call next. It can get very messy, very fast as you add more and more types of food.

Finally, we need to serve the stuff. The kitchen will announce to the waitbots that the food is ready (that's an exercise in queues & pub/sub for another day) and the waitbots will bring the food to everyone.

To do this, the food plates will have a type, like salad or burger, but we also need to include who the food is for. To do this procedurally, this usually involves bundling bits of information together and passing that around, so your business logic might do something like:

def process_order(patron: dict) -> None:
    for food in patron["order"]:
        deliver_to_table(patron["table"], make_food(food))

for patron in patrons:
    process_order(order)

As make_food() returns prepared food, then we can just pass the result of the food making to deliver_to_table along with the table number and we're good, right?

The thing is, this is really complicated, and we've got a lot of raw data floating around that's created a rather rigid system. What if a patron changes their mind and wants to order a side of fries? What about all the different types of burgers out there, are we going to create a separate method for make_chicken_burger(), make_veggie_burger(), and make_cow_burger(), or just one larger method with a bunch of if pattie == "chicken": code in it?

At first glance, this looks like something that will work, but in the long run, managing and extending this code is going to be painful.

The Object-oriented Way

Objects have two primary strengths:

  • Encapsulation
  • Extendability

I'm going to explain both before we get to how to run this kitchen the OOP way.

Encapsulation

It's just a fancy way of saying that objects know how to do stuff. Rather than taking raw data and acting upon it, you just create an object and tell it to do a high-level thing -- it will figure out the rest.

For example, assume that cooking a steak requires using a grill and (hopefully) includes a long series of instructions on how to use that grill. Assume also that it involves a marinade or rub and maybe a selection of sauces to apply.

In a procedural system, you'd have a function called make_steak() which would likely have internal calls to maridade_steak() and to grill_steak(). These functions would likely be different from the instructions for cooking cow burgers or chicken burgers, so each food type would require its own special function with its own rules. Sure, you can probably have some functions cross-call each other, but the more you do that, the messier your code becomes.

In an OOP system, the interface is as simple a calling steak.prepare() -- the steak object will figure out the rest for you.

Extendability

The "figure out the rest" part is only different from the procedural method because you can do stuff like subclassing in OOP. A rib-eye steak is a lot like a sirloin steak, but there may be slight differences in the preparation. Subclassing means that you can take the standard rules for steak preparation and extend them for your specific case. Suddenly your code is a lot simpler.

Have a look at the examples to see what I mean.

Our OOP Kitchen

We need to keep track of our patrons: where they're sitting, what they've ordered, so we could create a Patron class, but as the patrons aren't really doing anything in our exercise, this would kinda be overkill. I mean you could create a class called Patron, but it wouldn't do much more than hold data, which a dictionary or list will do just fine already:

class Patron:
    def __init__(self, name: str, table: int, orders=None) -> None:
        self.name = name
        self.table = table
        self.orders = orders or []

Well it's neat & clean, so let's keep it for now. I suppose we could later extend Patron to include a .pay() method that would tally the costs for their meal table and pay from their bank account, but for now, let's just use this as an example of a really simply class.

Now, as each person comes through the door and they're seated, we create new Patron objects and attach them to our list of patrons:

patrons = [
    Patron(name="Amber", table=1, order=["salad", "cake"]),
    Patron(name="Brianne", table=1, order=["steak", "cake"]),
    Patron(name="Charlie", table=2, order=["burger", "pudding"]),
    Patron(name="Dianna", table=2, order=["salad", "pudding"]),
    ...
]

So far, not very useful. It's basically the same as our procedural system. However now let's make our code smarter and do away with these strings for the food, replacing them with objects.

We'll start with a Food class:

class Food:

    def __init__(self, name, price) -> None:
        self.name = name
        self.price = price
        self.calories = 0
        self.is_prepared = False
        self.is_served = False

    def prepare(self) -> None:
        self.is_prepared = True

    def serve(self) -> None:
        self.is_served = True

    def get_price(self) -> int:
        return self.price

We now have a thing (food) that knows how to prepare itself. We can create an instance of food, and it will know what it means to prepare itself. Of course right now, all it does is set .is_prepared = True, but should that ever need to change to say, notify a central server that a particular food was just prepared, you only need to modify the Food class and your business logic won't know the difference.

So that's encapsulation, but let's do the extension part. Let's define a series of different foods:

class Salad(Food):

    def __init__(self, name, price, dressing) -> None:
        super().__init__(name, price)
        self.dressing = dressing
        self.calories = 50

    def prepare(self) -> None:
        self._add_dressing()
        super().prepare()

    def _add_dressing(self):
        self.calories += 200


class Burger(Food):

    def __init__(self, name, price) -> None:
        super().__init__(name, price)
        self.temperature = 22
        self.calories = 300
        self.pattie = None  # Defined in the subclasses

    def prepare(self) -> None:
        self._grill()
        self._add_bun()
        super().prepare()

    def _grill(self):
        self.temperature = 100
        self.calories += 20

    def _add_bun(self):
        pass  # Obviously important, but I'm not sure how to code this.


class ChickenBurger(Burger):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.pattie = "chicken"


class CowBurger(Burger):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.pattie = "cow"
        self.calories += 30

This is the magic of extending your classes: you get to be lazy.

We defined Food once and since everything else is a kind of food, we extend that class to further define the food we're talking about:

  • Salads are low on calories, but need dressing
  • Cow burgers are calorific
  • Chicken burgers have more calories than salads, but fewer than cow burgers
  • Both cow & chicken burgers are prepared the same way, so we have the intermediary Burger class that knows how to ._grill() and ._add_bun().
  • Salads need to have an _add_dressing() step in their preparation.

Note that everywhere, we're calling super() to make sure that we get the benefits of the parent class. Not only that, but doing this ensures that if we change the parent class (say we start notifying someone that food has been prepared), then all the child classes automatically get that happening.

Now, let's go back to our patron definition and spice that up a bit:

patrons = [
    Patron(
        name="Amber", 
        table=1, 
        order=[
            Salad(name="House", price=350, dressing="Ranch"), 
            Cake(name="Death by Chocolate", price=250, flavour="Chocolate")
        ]
    ),
    Patron(
        name="Brianne", 
        table=1, 
        order=[
            Steak(name="Rib Eye", price=1399)
            Cake(name="Lemontastic", price=200, flavour="lemon")
        ]
    ),
    ...
]

Now your business logic looks like this:

for patron in patrons:
    for food in patron.orders:
        food.prepare()
        food.serve(patron.table)

At this stage, your code is ready to be extended like crazy just by editing the objects themselves:

  • If you've introduced a new buffalo burger that has special preparation instructions like combining with coriander, you can just create a subclass of Burger with special instructions to do just that.
  • If you run a promotion on burgers, you can override .get_price() in your Burger class and put your discounting logic in there to affect all burgers.
  • If you want to trigger a notification of some kind when the food is served, you just update the code in Food.serve()

As a bonus, your code is a lot cleaner because your function calls aren't riddled with all of these suffixes like prepare_steak(), grill_steak(), etc. Instead, you have one concise interface: .prepare() and .serve(). Let the object figure out what that means to it.

Finally, your objects know more about themselves, say for example, we now want to tally a per-patron bill for the end of the night. OOP makes this easy, we just update our Patron class with a .get_bill() method:

class Patron:
    def __init__(self, name: str, table: int, orders=None) -> None:
        self.name = name
        self.table = table
        self.orders = orders or []

    def get_bill(self) -> None:
        for order in self.orders:
            print(f"{order.name}: {order.price}")

After that, you need only call .get_bill() on each patron to get what they owe. No looping over complex data sets, or calling special functions for calculations. You could even modify Patron to allow for coupon discounts -- your interface is the same: .get_bill() while the Patron knows what that means.

May 01, 2018 18:44 +0000  |  2

My earliest memory of my grandmother is of her giving my brother and me some Arrowroot cookies to dip in milk. They had a magical softness to them when you suspended them in the half-full glass for just the right amount of time. Grandma taught me that.

For the most part though, my childhood memories of her are sparse. Visiting Grandma & Grandad wasn't fun, it was just something you did, and often it would involve the adults doing boring stuff like talking, so Matt & I would hide out in our grandparent's bedroom watching one of those old tube-based TVs that took 5 minutes to warm up before you could see anything.

I wasn't a very engaged kid. Looking back on all that time I could have had with her now, I feel cheated by my 8 year-old self who chose Mary Poppins over time with my grandmother.

To be honest though, I don't think 8 year-old me could have appreciated Grandma Nana the way I came to as an adult. Young Daniel didn't know much about what was going on in the world, and honestly, I don't think he cared very much either. To him, Grandma's house meant cookies & movies and that was good enough.

It wasn't until decades later that I really came to appreciate and understand my grandmother better. The woman was unyielding in a way that can only be described as inspirational. At a time in my life when I was beginning to take an interest in politics and Canadian history in general, my grandmother was there, answering all of my questions and sending me scanned copies of newspaper articles covering topics we'd discussed earlier that week.

I was raised on rather right-wing ideals, but Grandma worked against that full-time, sending me links and petitions from the Canadian Centre for Policy Alternatives, and articles from Rabble. These weren't one-way discussions either: we disagreed often, sometimes spiralling into long email threads, referencing article after article. The goal was never to "win", but to better understand each other. Grandma didn't mould who I was, rather she challenged my preconceptions to help me build the person I wanted to be.

As I got older and more involved in politics & activism, our relationship developed into a pattern of advice. I would call or write to ask what she thought about a new campaign I was working on, or sometimes just for some encouragement. One time in particular, I wrote to her, tired & upset about a lot of the criticism I'd run up against in my political work in Toronto. I was lost and felt as if fighting wasn't worthwhile if all I was going to hear were people complaining and shouting me down. She had the Best Advice Ever, and I carry it with me to this day:

"The only people that don't get criticism are those that don't do anything."

In any avenue she could access, she was an activist her whole life. As a young woman, she volunteered with the NDP in its early years to help give Tommy Douglas a stronger voice in the House of Commons, and even in her 80s and 90s, she was circulating online petitions and tweeting about environmental and social issues.

Just last year, she was committed to the hospital for a litany of health issues, but the morning she checked out, she insisted that rather than going home, her daughter had to take her straight to an advance polling booth for the BC election. My grandmother, her lungs crippled with pulmonary fibrosis and breathing from a machine, made sure that she got her vote counted.

And this, this is how she went out. Literally lying on her death bed, her lungs ravaged after thirteen years of that slow-drowning disease, she contacted a local paper because she wanted to share with them that she would be taking advantage of Canada's new Medical Assistance in Dying law. As the first person in the Okanagan to make use of this law, she wanted to share her reasoning, and her strong belief that the Right to Die should be enshrined in the Canadian Charter of Rights and Freedoms.

At 91 and choking to death on her own lungs, my grandmother remained as fierce as ever. Using even her own death to further her desire for a better world. Not for her of course, her time was up, but for you and me.

I'm going to miss our talks, but her life has been an inspiration to me. I will endeavour to make sure that she isn't the last Quinn to be so uncompromising in both action and principles.

April 08, 2018 12:52 +0000  |  0

Here we are, four months into 2018 and I'm finally getting around to wrapping up 2017. I think I've been putting off for two reasons really: I've been swamping myself with side projects, which consume most of my time, and to be honest, with the exception of one Big Event, I don't really look back on 2017 as something really worth remembering. It's depressing frankly.

Personal

...but first, the good news.

We Got Married

I may have proposed back in 2015, but we finally made it happen in August of 2017. We decided that as this was our wedding, we didn't need to follow anyone else's conventions or demands. It was going to be that we wanted, and what we wanted was: cheap, low-stress, and as easy as possible.

We got married!

The real problem was all of you people. You insist on living all over the world 😛. This meant that if we were going to have a wedding and have it be cheap & low-stress, we'd have to break it up over 3 countries. This way, the events could be small & simple, and we could still see as many of you as possible.

Wedding #1 was the legal ceremony. Having it in the UK means that our license is less likely to be a problem in other countries than it would have been coming from Greece. It also meant that organising something would be easier & cheaper, since we could do it ourselves and keep things simple.

Christina got all prettied up with nice hair & make up, I got a linen suit (who the hell wants to sweat like crazy in your wedding photos), we booked a slot in the Cambridge registry office, and reserved a hotel banquet room for the evening. That was it. Those who could make the trip saw the "I dos" and then we took pictures, ate a lot of food, and called it a day.

Wedding #2 took place about a week later just outside Athens at a beautiful restaurant overlooking Lake Marathon. Christina's family covered the cost of this event and did all of the organising. All we had to do was show up. Best Gift Ev-ar. Friends that couldn't make the Cambridge event, hopped a flight to Athens for this one, and that led to some nice siteseeing around town with people we love but don't get to see very often. Honestly, that whole week was wonderufl.

Wedding #3 is still coming and will be in Vancouver this Summer. I'll try to post about it later and include some pictures too.

Travel

My travel history for 2017 was really quote disappointing. Where in the past, I've managed to travel to more than 10 different places in a single year, 2017 consisted of only 6 -- all but one were places I'm already familiar with.

Brussels

As is tradition, I made the trip out to Brussels for FOSDEM in February. The conference is getting crazy-popular, like, impossibly busy, and the resources available remain finite. Most of the rooms are full of people who showed up to hold a seat for the next talk, and the lines for food are just brutal. On the one hand, it's wonderful that Free software has garnered such interest and that a Free conference like this can draw so many people, but surely, there must be a way to raise money to expand the conference facilities without tainting the ideals that started it all.

Florence

The enormous(-ly overpriced) ice cream I got during a break in the conference

In April, I made the trip out to Florence for DjangoCon. I have a special blog post devoted to the event in detail if you're interested. Florence is still beautiful, but a lot of the wonder seemed to fall away for me on this trip, and not just because all of the food I had was disappointing.

I guess that when you travel for work, you really do get a different feel for a place. I didn't feel like I was exploring so much as going somewhere new to then ignore that somewhere new in favour of doing what I do at home. Maybe I would have felt different if I'd never visited Florence, but I think the lesson here is that if I'm going to travel for work, I really should bookend the trip with some personal time.

Prague

@travellingjack checking out the Prague skyline

The only new place I visited in 2017 was Prague in April. Christina was attending a conference in Brno, and did the smart thing: she added some personal days to the trip and met me in Prague so we could do a long weekend. It was only a short trip, but still well worth the time & money. Prague is as beautiful as they say, and the food wasn't bad either. It was nice to be somewhere actually foreign again, where English translations weren't immediately available everywhere, and wandering through the old city is an excellent way to spend a Saturday.

Vancouver & Kelowna

In May, I got news that my grandmother was fading fast and that she didn't have much time left. I decided to fly home to say a proper goodbye and to try and help out where I could. As it turns out, her body refused to give up, and she recovered, though her mobility was greatly affected. Still, it was nice that the trip didn't end up being as somber as I thought it would be when I boarded that flight.

This was also the week that Kelowna flooded though. The snow on the mountains melted faster than anyone was prepared for, and the water system that drains everything into the sea was not capable of handling the changes. As a result, all of the lakes in the Okanagan began to back up, and my parent's home (and those around them) was flooded. No amount of sandbagging would do, the water was literally coming up from under them as the water table rose.

On my last day in town, I were awoken at 1am by a police officer that had come to the door to evacuate us.

Athens from the Acropolis A pretty tree on the beach Ios at sunset A healthy reminder A group shot at wedding #3

In the end, the damage for some was substantial, while others -- like my parents -- managed to avoid the worst. The water went under their home, but didn't create any structural damage. The worst of it was that their entire yard was lost and had to be rebuilt.

Other families weren't so lucky.

Athens & Ios

A few months later, my parents made the trip from Kelowna to Cambridge for Weddings 1 & 2. They were here for the ceremony (my dad was the Best Man) and then they came with us to Athens where we did some sightseeing for a week together. After that, Christina & I disappeared for a week to the island of Ios (Ιος) for our honeymoon, and my parents went on a mini-cruise through the Agean.

It was all very pretty. Pictures can be seen here.

Amsterdam

I had a couple holidays left over as the year came to an end, so decided to take a long weekend in Amsterdam to see some friends. Mihnea was kind enough to put me up in his place for a couple nights, and when I stopped by the RIPE NCC office, they invited us both out to their annual Christmas party at Nemo!

I spent much of the night just catching up with everyone, chatting with Robert about Atlas architecture, and just plain enjoying my time there. That company really is a great place to work.

Mihnea dancing it up at the RIPE NCC party

Oh, and the food. I did miss Hotel V & Albert Heijn. Burger Bar was a terrible disappointment though.

Corporate

In terms of my day job, I'm afraid things haven't been too exciting, but at least the people I work with are great.

Migration

When I started at Money Mover, everything was running on an old version of Django and Python 2.7. I made it a priority from my first day there to bring everything up to date and it was about as difficult as you'd expect.

  • The entire project had 200 unit tests, 50% of which were failing.
  • It was running Django 1.6 and Python 2.7

In my year there, I increased those tests from 100 (working) to 1100, and leveraged that coverage to migrate us first to Django 1.8 (for a while), then to Python 3, then to Django 1.11. I also added a async subsystem (RabbitMQ + Celery) for bulk jobs and other heavy tasks.

If ever I wasn't sold on tests, I sure as hell am now. Migrations like these would have been so much more painful without adequate testing.

Side Projects

The truth about my job though is that the work isn't interesting. For business, this is good: you don't want interesting code, you want predictable, stable code. Experimental codebases make for bad banking platforms. However, as an engineer, I can get bored pretty fast with stuff like that, so 2017 saw a boom in my side projects.

Paperless

It's still going strong. I started it way back in 2015 and at this stage, the community does more work on it than I do. Mostly I step in once or twice a week to answer questions in the issue tracker, or accept pull requests. I've done a little original work, but for the most part, I try to stay out of it as my interests are elsewhere.

There's also been a few cases of people inventing drama around the project, claiming that I somehow "stole" the project idea (or maybe the actual code, I'm not sure) from the much-more-polished Mayan EDMS, but I've done my best to stay out of that too. I mean, the code is Free and Open. Anyone who wants to know the truth can just look at it to know that the projects are clearly an example of simultaneous invention.

There've also been a few cases of companies & individuals contacting me about the project specifically. In most cases, they want to know if they can find a way around the GPL, but some just want pointers about technology used, or want to know if I want to co-found a company with them.

Albatross

My Twitter-aggregator, Albatross was the code behind my Tweetpile project years ago. Unfortunately, when Twitter changed their API rules, I realised that it wasn't a feasible business model so I shelved the project. The domain lapsed and I forgot about it.

However when I moved to Cambridge, I met a woman doing a PhD that involved analysis of social media data and so I decided to try and repackage the project as a self-hosted thing. It let me expand my understanding of async and event-driven code as well as improve on my Docker-foo, and after a month or three of tinkering, it's now in a finished state. The latest release, codenamed Cersei Baratheon, can be installed and run with just a few clicks.

Aletheia

It started as a frustrated blog post, but one night I got it into my head that if no one was doing it yet, that I would start. Aletheia is an idea and technical spec, while pyletheia is the implementation. The gist is that this is a way for people to guarantee the source for a media file (image, audio, or video) and guarantee that that file hasn't been altered since it was released by that author.

At the moment, only JPEG images are supported, but I'm almost done hacking MP3 support into it as well (which opens the door for all sorts of audio & video). I also have a presentation that I'm just putting the finishing touches on. I hope to give this talk at the local Python meetup.

Sudo: Immerse

It's not a side project so much as a weekend-long event, but 2017 was also host to the Sudo:immerse hackathon here in Cambridge -- an event which my team won and that didn't suck.

Codebar

2017 is also the year I joined Codebar. Think of it as a monthly meetup tutorial session where people who can code teach people who want to learn -- with one exception: straight, white, males aren't allowed. The thinking is that there's enough people like me in this field, Codebar is an attempt to balance the scales a bit.

To be honest, I'm typically not a fan of exclusionary tactics, especially when your goal is inclusivity, but the reality is that all my life, programming has been straight-white-male dominated and nothing else we've done has fixed that. I'm happy to give this a shot. Besides, it's fun!. I've already helped one woman with her potato science PhD, another with basics of server access and typical dev-ops, and my current pupil is learning basic Python skills so she can do that social networking PhD I mentioned earlier.

I did have a rather ugly disagreement with the mods in their Slack channel though, so my participation is limited to the in-person meetups. I don't have enough patience to deal with people obsessed with thoughtcrime (long story).

PyStudyGroup

Along with the various bits of software I've written over the year, I also joined an online community of people aspiring to be better Python developers. Most of the members are very green, but a few are like me: happy to help and wanting to share what we know. I spend most of my time in the Slack group, but there's also a Github account with monthly challenges that the membership hacks on. For the most part, it's just nerds getting together to help each other out, and it's fun to be involved.

Conclusion

2017 has been very tech-heavy. Sure, we got married this year, but outside of that, my life has been largely tech-focused. I'm starting to feel like I've forgotten how to be anything else and it's freaking me out a bit. I may be a bit far into 2018, but my resolution for this year is to do something else with my life as well. That is to say, I'm not going to give up my various side projects or anything, but I need to get a handle on balancing this stuff out with having a life that doesn't involve code.

January 30, 2018 17:42 +0000  |  0

My Paperless project has been running for years now, and every once in a while someone discovers it and posts a link to Reddit or Hacker News and there's a sudden uptick in people trying out the software. When interest spikes like this, every once in a while I get a lovely email like this one and it makes my day.

I'm posting it here as a reminder to myself and others that while our labours on Free software projects may sometimes feel thankless, sometimes they help.

Hey Daniel,

I'd like to reach out and thank you for writing paperless.

While I like having things stored nicely and in a way that makes it easy for me to find them again, I have to admit that I'm not really a talent in doing so. Especially when it comes to paper.

Now I'm running paperless on an Odroid XU4Q and I actually manage to archive documents within the same month I receive them instead of moving them from pile to pile for a year or two and then spend whole weekends on filing them in folders.

In case you happen to visit Zurich one day and need information or help of any kind, please let me know. I'll be more than happy to help :)

Thanks again Cheers

p.s. I have donated CHF 100.- to UNHCR as a "Thank you".

It was the last line that really did it for me. I added a call for donations to the UNHCR to the bottom of the project's README.md file back in 2016 and pretty much forgot about it afterward. Now, more than a year later, someone helped refugees thanks in part to code I wrote.

That's fucking awesome.

November 20, 2017 23:17 +0000  |  1

Months ago, I signed up for a local hackathon and then promptly forgot about it. Then, the night before I was due to attend, I realised that it was actually a VR hack, and considered not going. I'm a web guy after all, and didn't fancy the idea of using Windows to play with Unity for two days.

Christina convinced me to to go, and I'm so glad she did.

It was a great event. We took over the RealVNC offices for 48hours to first learn about the capabilities of emerging VR hardware, and then to attempt to build something useful with it. I played with an HTC Vive and Microsoft Hololens and was introduced to a woman from Give Vision who inspired some of us to develop a project for the visually impaired.

I fell into a team of brilliant, committed people and early in the process we realised that we all more-or-less shared the same idea for the hack:

We were going to build a tool to first help diagnose people with macular degeneration, then build another tool to help those suffering from it cope with the disease.

Our team was comprised of six people, all of whom just showed up for the event looking for something to do. In fact, nearly every other person at the evnet arrived with a pre-defined team and product in mind. We were effectively the leftovers.

We broke into 3 sub-teams, with two people each:

  • Luke & George worked together to build the test front-end and coping tool respectively
  • Peter & Clare researched the industry, developed use-cases, and prepared a presentation
  • Ullash and I wrote the mapping system for the test as well as the algorithm to zero-in on a user's blind spot at higher and higher resolutions.

By 11pm Saturday night, each team had more-or-less completed their side, and by Sunday at 3pm we were ready to present.

...and we won.

The finished product is effectively two separate products focused on helping people with macular degeneration:

  • The test is a simple web app (written in Javascript) that runs on any phone. It's designed so that you can take your phone, plug it into any Google Cardboard device, and like magic you have an eye test that maps your blind spot(s) and will even email that map to your optometrist.
  • The visual aid works the same way, via Google Cardboard, but takes your blind spot map as input. It taps into your phone's camera to give you a real-time view of the world, literally bending the image around your blind spots to help you see.

The finished product(s) has all manner of benefits:

  • Reduce the costs of medical care by reducing routine visits for testing
  • Improving the mobility and independence of those suffering from the disease.
  • Increase the amount of data collected on this disease through the historical charting of the disease's progression.
  • Increase understanding, by allowing others to see what their relatives see using our app.

I'm really proud of the team. We built a product that's not only useful, but accessible. The total cost of this thing is that of a smart phone + $5 for Google Cardboard. This could be deployed around the world to help detect signs of macular degeneration literally years early allowing treatment before it progresses too far. It'll help parents stricken with the disease keep tabs on potential signs in their children (this is a genetic disorder) and all this done with a phone and the price of a Starbucks coffee.

Our prize was a Google Home, one for each of us. Honestly though, I don't think any of us much cared about the prize at the end of the day. We were exhausted and thrilled at what we were able to build in such a short amount of time.

The finished product is in a state one might expect from a hackathon: patched & working, but in no way ready for public use. The code is on Github and there's a few live samples if you wanna give it a try:

  • Moving car: Tap the screen to see what the world is like for someone with MD. The panel on the left is what they normally see. The one on the right is with our video distortion.
  • Live stream: You have to enable your camera permissions for this one, but this will demonstrate how the app works in real time. Tap the screen to switch though the few modes we setup.
  • The test: The actual test. Dots appear at random locations and at random times. Tap the screen to record the fact that you saw it. Hits & misses are logged in the app and mapped internally. PDF generation works, but it's flaky.

What happens next is still unclear. The product as-is isn't ready for the public, but no one person on the team is really capable of picking up the whole thing and running with it. Give Vision might take it over, or maybe we'll all get together in a few weeks and polish it up a bit. I don't know.

The organisers said they'd be doing another event like this in March next year though. I hope to attend that one as well.

Update: Peter Fuller, one of my team mates for the hack has written his own post

November 12, 2017 15:35 +0000  |  1

I probably should have said something back in August when it happened, but we had that was a chaotic month or so, and then we were waiting on the photographer to send us her stuff, so now, over 2months after the fact, here's the official post.

On August 25th of this year Christina & I were finally married. The ceremony was a simple civil one, and we had about 25 guests representing no fewer than 19 different nationalities. We had friends there new & old, and our immediate families both made the trip from their respective homes of Athens & Kelowna.

The Big Day was lovely, with excellent weather and zero problems from any of the various moving parts required for such an event. Christina's stylist did a wonderful job, the people running the actual ceremony had everyone in & out of there like a well-oiled machine, and our photographer was a pro through the whole thing, setting us up for shot after shot, getting lots of candid photos and just generally being awesome.

In terms of cost, everything was surprisingly reasonable with everything: the photographer, stylist, bouquet, ceremony, rings, dinner & venue coming in under £4000. For a wedding, I understand that that's pretty amazing.

I feel like this post should be a bigger deal, but it just doesn't feel like that. In retrospect, our wedding -- our marriage, feels like an inevitability, and the whole ceremony more of an excuse to have a party than anything monumental. Of course rationally, this is most definitely a Big Deal -- there's a reason LGBT activists continue to fight for marriage equality around the world, but for me the legal stuff has never really felt consequential. What matters is that I was committing to her, and I'd already done that years ago, you know?

After the Big Day, we all relaxed for a few days and then hopped on an abysmal Ryan Air flight to Athens where we were met at the airport by Christina's extended family. The swept us off to her aunt & uncle's home where we were treated to a fantastic traditional Greek feast. My parents, heads still spinning from landing in a foreign country fell in love with the food immediately. Christina's aunt is fricking genius in the kitchen and she had pulled out all the stops.

We then had a week of sightseeing in Athens, followed by Wedding #2 in an outdoor restaurant alongside Lake Marathon. Most of the guests were from Christina's side of the family, but a few of our friends from Amsterdam also made the trip down to celebrate with us. The next day, Christina & I toured Athens with the Amsterdammers before they all had to go home.

At that point, we all split up: my parents went on a cruise to a number of Greek islands, Christina and I went on our honeymoon to Ios, and Christina's parents took a week off from the craziness to relax a bit.

Ios is beautiful and much less hectic than other, more touristy islands. The food is wonderful, and the sightseeing was lovely. For my part though, all I wanted to do was relax by the pool and I managed to do lots of that :-)

After a week of that, we all returned to Athens for another week of sightseeing, and then finally returned to Cambridge where my parents celebrated their own wedding anniversary with their son & new daughter in-law.

It was just wonderful that so many of you were able to make it out to celebrate with us. Honestly, that's going to be the most memorable part of all of this for me. As an expat, you rarely have the opportunity to reconnect with all the people you love, because you're all scattered around the globe. It's one of the things that make weddings awesome.

There will be a Wedding #3 though: this one in Vancouver next year, likely in July (we're still working on exact timing). If you couldn't make it to #1 or #2, come on down to YVR for #3! We'll be doing what I'd always said I wanted for my wedding: a potlach in the park. There will (hopefully) be sunshine, and KFC, and my dear old friend Michelle has promised to sing with me for the occasion. It should be a good time. I'll post more when I know more.

For now though, check out the photos! These are the ones the pro took on the Big Day and these are the ones the rest of us took throughout the multi-week event.

July 30, 2017 19:23 +0000  |  1

I'm just writing down my thoughts here in the hopes that Someone Smarter Than Me might be able to shed some light on the idea, or perhaps even work with me to make it happen.

I'm reading more and more about how fake news stories are circulating, and how technology has developed to the point where we can literally create images, audio, and video of events that never happened but appear as though they did. The effort so far seems to be in the area of somehow detecting a fake by searching for evidence of tampering, but this to me feels wrong-headed: it's expensive, slow, and will always be a step behind the fakes.

Why instead do we not simply sign each file on a sub-channel so it can be easily proven to be legit from the source?

For example, the BBC does a story about a politician and includes with it a picture of her doing something interesting. This picture is then circulated around the web with two bits of information hidden inside the EXIF data:

  • The original source organisation (BBC)
  • The signature of the image based on the BBC's private key
  • The original URL of the image (maybe?)

The image is then re-shared onto Facebook, where they've got simple software that:

  • Reads the original file and authenticates its origin against the BBC's public key
  • Resizes the image for its own purposes
  • Appends a second signature using Facebook's private key
  • Posts the video into the user's timeline with a "Verified BBC image, resized original from Facebook" caption

If the image is re-shared onto Twitter, or Google+, or Diaspora, these services will only be able to know that the image came from Facebook, but theoretically this still means more than not knowing the origin at all.

The goal is to create a means of authenticating the original source -- or at least a source more credible than "Jim's computer", and perhaps even the chain of modifications to said source There's also no reason this couldn't be applied to all kinds of media.

Maybe this technology already exists, though a cursory search didn't turn up anything for me. Anyone have any bright ideas?