Python and me, or when in Rome...

I've written in the past somewhat opaquely about certain programming languages and my complaints about them. One that I'm not afraid to complain about by name is Python. You can look in enough of my old posts to see this pattern keeps coming up. It never fails to make my life more interesting than it has to be.

So, with that said, one of the things I decided we needed at $COMPANY was something that would let us handle SEVs (you know, outages, site events, whatever?) well. What they had already when I arrived was, to put it mildly, cute. It was basically a wrapper around the Jira category they already had to track these things, plus it would blast out mails to extra places when someone commented in the tool. Unfortunately, those mails also tended to start full-on reply-to-all spam fests due to their scattershot nature. *Every person* was getting *every update* to *every SEV*.

This was getting people at the company to see the fact that something new had in fact broken, but only for about half a second before they spam-canned the whole thread, and then never saw the follow-ups as a result. It was annoying lots of people, and it was failing as a tool for actually getting a handle on what's broken now, what's broken lately, and what is going to happen about these things overall.

People agreed that it needed a per-user subscription model, and had already talked about moving it to a Postgres type backend where it would know about individual people at the company as user accounts, and they could subscribe or unsubscribe to updates for a SEV, and all of this good stuff. Some of the foundation work had even been laid in there, but there was a catch: the main person who had been doing this work had been doing it as a side amusement, it was not his nominally assigned project, and (worse still) his work on this thing was annoying his boss.

There was no way this would ever get a chance to blossom.

In talking with this person, he graciously agreed to step back and let me give it a shot. It was a case of truly egoless programming and supporting the case of the greater good, and I just wish I got to see it more in the world.

That left me with a bunch of Python running gunicorn, gevent, and Flask, running in VMs on some cloud vendor. It was basically everything I would never do for myself.

Did I turn it off? No.

Did I rewrite it in C++? Nope.

Did I go get HHVM and try to jam FB's infra into this company so I could use Hack and stuff like that because I had seen that before? Nuh uh.

So then, what did I do? I jumped in there and wrote more Python. That's right, I built the database schema, got a test db running locally, then started coding to it. There were SEVs, and SEVs had comments. Comments had authors and bodies and times and source IP addresses and all of this stuff. SEVs themselves had creation times and creators and owners and more. Then were tags, and tags were M:N with SEVs. Then we had to have users as the authors and creators and owners, and so on and so forth.

At some point during this work, the nascent "prod tools" team hired its first two software engineers and they joined in, and that stopped it from being just a wacky project driven by a single crazy person with a dream (me). Now it was really starting to shape up, and it was clear we were on to something.

All of this came together, and we "shipped" - we turned on the new Postgres-backed code for all to use, and left the old Jira-backed stuff in place just to make sure it'd hold up. Then we let it just run for a couple of days. When it was clear that nobody wanted to go back to the old way, we changed it to just use a HTTP redirect to fling you over to Jira itself when you tried to load one of the pre-Postgres SEVs.

Being one of those sticklers about the web and who believes "cool URLs don't change", I insisted that we not break any old URLs in case anyone had bookmarked the_service/whatever/FOO-1234. We would honor that forever, redirecting to Jira so they could see their FOO-1234 ticket and not lose access to it just because we decided we wanted a better backend.

With that done, we deleted every other part of the Jira-related code (connecting, fetching, rendering to a page, etc.) in our side of things and that was that.

The fact that this service might see at most 2000 distinct users over the next two years meant that it didn't really matter what it had been written in. If it could have been done safely with bash scripts and sed expressions to render templates, that probably would have been enough to handle the complete lack of load. The request rate would never be that high, and the things it did were not complicated.

Would I have liked to not write it that way? Well, sure. But people in hell also want ice water, and they aren't gonna get that, either.

I should mention that both of these folks showed up at the company and were dropped directly into this project with no warning, and both delivered. I'm really happy about how that project went, and it was really good to work with them. I hope they are doing well with whatever they are up to now.

Also, I had the pleasure of hosting an intern that summer who created a whole set of things in that tool which made it possible to manage the entire lot of SEVs, book the weekly review meeting, and generally removed a ton of manual labor from my plate. I loved showing off his creation and comparing it to the pile of gunk I had to do to track, choose, schedule, book, invite, and then review everything. It was also an honor working with him, and I know he's also going to go on to do some really amazing things some day.


Random bit of trivia: the biggest initial challenge to the project wasn't the fact that I was going to stop using Jira, or switch to Postgres, or write a bunch more code, or this, or that, or whatever else. Oh no.

The biggest fuss that happened early on was that I *dared* change it from "INCIDENT" (as in the Jira ticket/project prefix, INCIDENT-1234) to "SEV". It was amazing. People came out of the woodwork and used all of their best rationalization techniques to try to explain what was a completely senseless reaction on their part.

I got crap from all kinds of people about this, but the best one was from someone who said "new people to the company won't know what it means". This was said by someone who had been there long enough (4+ years) that they were newer than something like 90+% of the company according to the internal profile tool.

Meanwhile, my own tenure at the company at the time was... about three weeks. I told them that I'd be the judge of what a new person at the company had to figure out, given that I was already up to my neck in people who used terms without explaining them for the audience at that company.

I'm talking about the same place where I had to stop the presenter and say "I'm sorry, what are bookings?" after they had used it two or three times with absolutely no explanation given, and not enough context to derive it from adjacent words.

This might be okay in a meeting with a bunch of senior folks who had been there for years, but this bad use of jargon happened in on-boarding class. So yeah, I think I had a much better idea of what people needed to find out rather than someone who had been around since before most of us had even thought about working there.

The most amazing thing to me is that apparently none of these people had heard of the term "bikeshed" before. They were unintentionally really good at it, which is to say... incredibly irritating!

The Honest Troubleshooting Code of Conduct

Yesterday, I wrote a little about what happens when companies have a pervasive culture of shutting down attempts to talk about things that aren't seen as completely positive. I mentioned there was more to the story, and this is part two.

I found myself in yet another tech gig in an attempt to provide reliability to a company that (as it turned out) was about to have its IPO. Since people like me weren't allowed to know the actual date and time of these things, we could only read the same tea leaves as the rest of the world. We could watch the news cycle and the IPO road show and guess at the rest.

It would be *really bad* for this kind of stuff to go down, particularly when the execs are out doing their dog and pony thing in front of the press. Then of course, exactly that happened one afternoon. What's kind of amazing is that this event isn't captured anywhere in the press cycle, but internally, everyone knew about it.

This place hadn't quite ascended to the level of giving outages notable names ("Call the Cops", "Silent Night", "A Tree Did It" being just a few from elsewhere), so it remained just "1152" after an associated ticket in a bug tracking system.

It was clear: we had to do better than this. We needed to talk about broken stuff, and soon, but every time we did this, some annoying person would show up and start "well actuallying" the conversation to death - usually several hours later after everyone else had moved on! I gave an example of this yesterday about someone showing up, completely mis-parsing "Ubuntu is doomed" due to a lack of context and jumping on someone.

The problem is, it didn't end there. There was all kinds of shit being reported up the line through managers, up to directors and/or HR, and then *back down* onto the speakers of these lines. This happened to anyone who brought up difficult topics about broken things that threatened reliability, security, or really anything else you can imagine.

It even came down on me a few times. I remember being given crap for talking about something in a supposed "leads" channel which was private and had perhaps eight people total in it. Worse yet, the person in question didn't have the character to talk to me directly about their issue (which at least the "Ubuntu" person did...), and so I had to hear about it from their manager.

It didn't take me very long to do the set logic to find the place where person A was present but person A's manager wasn't, and the topic was being discussed and all of this.

Given this, you'd think I was talking about politics or religion or some stupid crap like that. Hell no. I was talking about infrastructure, and specifically the wobbly mess of shitty "we're gonna run Flask everywhere and call it microservices" that somehow let people accomplish things over the Internet. Absolutely amazing.

They wanted me to dial it back and not talk about these things... in a private channel... with other "leads" (whatever that even meant at a company that barely builds anything). What, you want me to not do my job? Why in the hell did you hire me? Are you serious?

At some point, I decided to come up with something truly ridiculous. It's something that should have never needed to be written, and indeed, in the 24 years of being paid for doing this work up to that point, had never come up. No company had needed it before. They were mostly adults. This one wasn't, and so I had to spell it out longform.

I called it the "Honest Troubleshooting Code of Conduct", and it goes a little something like this:

These are the terms of engagement for participating in any Slack channel which has decided to gate membership on this code. You don't have to accept the code, but you also don't have to be a member of that channel, either.

Assume the best intent.

We're all here to make things better at $COMPANY. So, if you think that someone is doing something not-great or it feels like they've violated the code, try to come up with the best possible motivations on their end, and honestly believe that's where they're coming from.

We're here to improve the reliability of $COMPANY.

We do this to improve the lives of our <customers>. Keep that in mind when considering any statement in a HTCoC-governed channel.

This work can be tough and personally draining at times. We need it to be at least a little fun at the same time. Make the environment one where you still want to come back and do this job again tomorrow even though it's hard, confusing and complicated. Make it so the other folks around you are having fun, too.

Most importantly, don't make it hard for other people to enjoy their jobs.

We never attack people.

We're not here to tear anyone down, whether living, dead, or undead. Sometimes it might feel like a HTCoC-governed channel is a little unvarnished, but you should not mistake jokes, shorthand, references, or swearing for something that's intended to harm specific people or groups. Or zombies. (See, that's a joke.) Yes, there is naughty language here. People tend to swear when dealing with broken things. (Ever hit your thumb with a hammer? You get the idea.)

In other words, save your venom for problems, not people: broken computers, networks, tech stuff, etc.

Honesty is productive.

No feigning surprise. Someone who hasn't heard of something is a learning opportunity, not a flaw. Think "you gotta see this!" instead of "what?! how can you not know about X?".

Anyone in a HTCoC-governed channel is encouraged to say "WTF" when they don't "get" something that's being discussed. Literally "what the fuck" is fine too. (See, naughty language!)


If you think someone has violated one or more of these rules, consider the possibility that you're missing context, have incomplete information, or have otherwise misinterpreted their words. Give them the benefit of the doubt and assume best intent. If you're still concerned, address problems directly either via Slack DM, VC call, or (preferably!) in person.

Commentary on why this exists

Why have this? So we can talk about problems openly, and not have people think we are attacking them or their projects personally.

For example: "Ubuntu is doomed" out of context seems like someone is hating on all Ubuntu, everywhere, and Canonical too. "Ubuntu is doomed" at $COMPANY (note context) is a statement that we're switching to a new base OS which is built around Fedora, and so, yes, we will be moving away from it. Some day it will be gone. So, if someone says that, and you don't know the context, you have no place jumping on them for "hating on Canonical", because they aren't, and you're wrong.


[ Side note: I've squished down the actual company name to $COMPANY and a few identifying marks, but if you've been reading me for a while, you can probably guess who this is. This is squarely about wages and working conditions. Inter-worker communications for improving work conditions? Protected concerted activity? You better believe it. ]


Anyway, once I had that written, I decided the way forward would be to create a Slack channel that would be invitation-only. Anyone could be invited to it, and anyone could join it, but they had to agree to the code of conduct shown above. That was the only condition, and then it was on them, as it should be.

This started with a handful of seed people who did the same sort of work I did, unsurprisingly, and grew. It started getting legs. We started having actual conversations with people we hadn't met in person before. There were third- and fourth-generation members who I had no idea about who had signed up to talk about reliability without being second-guessed to death and hounded by people who just wanted to talk about "our tone" or "a lot of work went into that".

Did it work? Kinda. I heard from a couple of people that they thought they were losing their minds because they seemed to be surrounded by people in the company who kept crapping on them for trying to fix things. They thought they were all alone in this, and then some person reached out with the invitation to the channel, and they realized that no, they were not alone.

At least one of these folks told me over coffee and tea one day at the Philz down the street that "it probably kept them at the company longer" since it gave them faith that it could be brought around to doing good, solid and real work. They believed in the actual stated mission of the company and just wanted to deliver on that as much as possible without being treated like a child by other children.


I'll leave this one here for now, but I may have more to say on the topic at some point in the future. Let's just see if opening up about what happened is actually worth it.

The chilling effect versus attempts to fix things

One of the weird patterns I keep seeing in management is that some of the folks with those jobs care more about what people say than what they do. They want everything to look happy and shiny and nice, even when things are broken and need help. They don't want you complaining about something, *especially* not in some venue where other managers might see it.

One particularly stupid example: I worked at a company with a fairly famous founder/chief executive. He would do these quarterly talks out in the courtyard. Said courtyard had a handful of "bridges" connecting the buildings that had been added to fix some of the bugs in the campus left by the original owner.

At some point, they started blocking off those bridges prior to one of the talks. You could not hang out to watch the show from there. You also could not *cross them* just to go to the other side. The first time they did this, they didn't tell anyone and people were understandably confused and annoyed.

Later, though, they figured that if they put up a little warning sign at the various points to be closed a day or so beforehand, people would not be surprised and would route around it. This worked for the most part. It was still dumb, and their reasons given seemed stupid to me, but whatever, it was what it was.

But, someone complained. Unsurprisingly, people who do reliability work like me tend to not stand for things like that as a default, and particularly if they haven't encountered it before, tend to go "WTF"? One of these reliability people, and then maybe two or three others joined in on a post in some fairly broad group - maybe some "social" type thing for that campus. (I forget the exact one - this is something like four years ago now.)

A week or two later, the internal organizational group which I was part of, some 400-500 people strong, had one of its semi-annual "summit" events where everyone doing that job tried to come to HQ to meet up and hang out and hear and give talks and all of that stuff. With everyone there, the head honcho of the group held one of their usual "Q&A" sessions, but opened it with something of a rant.

This (eventual) VP went off on the crowd, saying that they should knock it off and stop being "social justice warriors" about things like that. This guy actually used that term which turned it from a simple "I am a manager type who's offended that my people aren't pretending everything is hunky-dory" to a politically-charged statement that was dripping with problems, no matter which side of the aisle you're on.

I swear this totally happened, and it's even recorded. I don't happen to have a copy of that recording, but anyone who's there can build up a video-viewing URL for id 1427477117275466 and watch it for yourself. Or, find the Q&A from April 17, 2017, and if it has that same ID, that's the one. It's about 4 minutes and 15 seconds in, and if someone wanted to "leak" it to the world, that's cool too.

Anyway, this post is not primarily about that. It's about what happens when instead of having one petty despot, you have a whole company culture of not talking about the things that need to be fixed. I lived that life too, and it happened *after* the above experience. Yep, that was my 2019.

What would happen is this: a couple of people would get to talking (on Slack, for that is what they used) about something technical. There might be a topic at hand, like "Ubuntu is doomed", and they'd be hashing it out, figuring out what that meant. Then, invariably, someone would pop in two or three hours later, hit the hated "start thread" button on one of the comments, and would start shitting all over them.

"OMG why are you hating on Canonical" "Ubuntu is NOT DOOMED"

And then the people involved would have to walk this person back and say, look friend, Ubuntu *at this company* is doomed, because the company has decided that everything is moving from flavor X to flavor Y, and all of the flavor Y images are built from Fedora (yeah, I know, ignore that for this story) instead of X's Ubuntu. So once we're done with the migration, Ubuntu *at this company* is a goner!

Now imagine having to do that for anything that even had the TINIEST BIT of a "hook" for someone to grab onto and show up hours later to "well actually" you to death.

This happened constantly, in all venues, from almost all angles. There were people who didn't do this, but as these things go, they tended to not be heard from because they used to speak up, had been bitten a time too many, and then had shied away from it.

I had a way to deal with this, but I'll cover that another time, including what worked, what didn't, and what ended up happening anyway.

May 1, 2021: This post has an update.

Teaching our network some MANRS

By tim

We’ve recently rolled out software upgrades to our networks that enable improved routing security and we have joined the MANRS (Mutually Agreed Norms for Routing Security) initiative. Our MANRS certification for our EU and US networks confirms that we block spoofed traffic, drop incorrect routing information and work with others to maintain routing security. This […]

Weekly Update 241

By Troy Hunt

Presently sponsored by: CrowdSec - The open-source massively multiplayer firewall: respond to attacks & share signals across the community. Download it for free.

What. A. Week. Heaps of data breaches, heaps of law enforcement and gov stuff and somehow, I still found time to put even more IP addresses into the house courtesy of even more IoT. I'm not sure if the latter gives me a break from the more professional tech stuff

After the Pandemic

I'm looking forward to having to worry a lot less about covid, but wouldn't mind if we worried a little more about giving each other colds. Colds are bad!

Almost a real RF engineer!

By [email protected] (RevK)

As you will have read, I decided to trying and tackle making an NFC reader. It is my first project in any sort of RF, so a massive learning project, but also a first in terms of trying to fit small components (e.g. QFN-40) on a PCB. The QFN-16 for the FT230X was just about doable with a soldering iron, but now I am in to solder paste and re-flow oven territory (more on a later blog).

I decided to give it a go, and made an NFC board, and to my (quite frankly) shock, it worked! It worked well, in fact - seemingly at least as well as the Elechouse board. I have made some tweaks with smaller components, and that also worked. Designing a PCB can be like a never ending piece of art - always one more small tweak or improvement. I am now working on a 3rd version, with even smaller components, but this time I am starting to do it properly from am RF point of view. Instead of just drawing an antenna track and hoping (which worked, to be fair), I now have an "network vector analyser" to tell me how the antenna and tuning circuit works.

The trick is to test the antenna and make component changes, or even adjust the antenna design. Apparently all sorts of things impact the tuning including any components near it, or just bits of copper track, and so on, even the case (even if plastic). But using one of these gadgets it is possible to work out if you have the tuning right, or close, and make adjustments. I am still learning, but getting there. In that image, you can see I changed the loop length a bit, and as expected the centre frequency moved.

My plan is to have a good quality, tuned, working, NFC reader design (open sourced), that I can sell. Something that is better than the standard Elechouse boards everyone uses. Apart from better RF (well, better than all the cheap copies of the Elechouse) it has red/amber/green LED and tamper switch. This makes it perfect for any sort of access control entry reader. I'm not really expecting to make much money, but would be nice to cover the costs of getting this far and learning this stuff.

I expect to make up a few of a final design, maybe next week, and offer some (free) to people like hackspaces to have a play and give me feedback. Obviously, if they are hit, I could have hundreds properly made and sell them. But this whole project was more aimed at a learning exercise in the first place, so covering my costs would be a huge win.

It almost makes me a proper RF engineer, LOL!

Welcoming the Romanian Government to Have I Been Pwned

By Troy Hunt

Presently sponsored by: CrowdSec - The open-source massively multiplayer firewall: respond to attacks & share signals across the community. Download it for free.

Today I'm very happy to announce the arrival of the 15th government to Have I Been Pwned, Romania. As of now, CERT-RO has access to query all Romanian government domains across HIBP and subscribe them for future notifications when subsequent data breaches affect aliases on those domains.

Romania joins a

calming traffic and lowering speeds is not enough

By danny

Lower speed limits and speed limit enforcement keep cropping up as an alternative to low traffic neighbourhoods (or to city-wide action to take back space from motor trafic). Traffic calming and lower traffic speeds are an important complement to reducing motor traffic volumes, but not an alternative to doing that. Speeding is certainly a problem […]

Welcoming the Luxemburg Government CERT to Have I Been Pwned

By Troy Hunt

Presently sponsored by: CrowdSec - The open-source massively multiplayer firewall: respond to attacks & share signals across the community. Download it for free.

Continuing my efforts to make more breach data available to governments after data breaches impact their domains, I'm very happy to welcome Luxemburg aboard Have I Been Pwned. More specifically, the CERT of the Grand Duchy of Luxemburg ( now has free API level access to query their national

Types of Scientific Paper

Others include "We've incrementally improved the estimate of this coefficient," "Maybe all these categories are wrong," and "We found a way to make student volunteers worse at tasks."

Data From The Emotet Malware is Now Searchable in Have I Been Pwned, Courtesy of the FBI and NHTCU

By Troy Hunt

Presently sponsored by: CrowdSec - The open-source massively multiplayer firewall: respond to attacks & share signals across the community. Download it for free.

Earlier this year, the FBI in partnership with the Dutch National High Technical Crimes Unit (NHTCU), German Federal Criminal Police Office (BKA) and other international law enforcement agencies brought down what Europol rereferred to as the world's most dangerous malware: Emotet. This strain of malware dates back as far as

Well, I made one

By [email protected] (RevK)

As per my earlier blog post, I wondered if I could make a NFC card reader... Well, I have!


I am in a lucky position in many ways - whilst I have a "full time job", a lot of the day to day running of A&A is handled by my management team, so I can "tinker".

This means I can try things out, do R&D pretty much as much as I like, and try and make something like this NFC reader just for the hell of it. Of course there are practical applications - I have several of the Elechouse PN532 NFC readers here because we made access control and alarm systems for the office (and even sold one) which use them. I suspect we could make, and sell, these cards. But a lot of the R&D I do is speculative (and educational) - it might sell, or might lead to something that does, maybe. Indeed, my work on NFC and DESFire cards does look like it had led to a contract that is very worthwhile, but I could not have known that at the start. The more expertise we get as a company, the more we can sell.

So, to answer the questions people have asked, mainly "why?", it is mostly because I can!

Back to the NFC reader itself

I said it may be a nice idea to try and make my own reader, much like the Elechouse reader. Well, I went ahead, a proof of concept, and it works. Yes, I am shocked too.

As a version 1 board it was not perfect. For a start, it seems the data sheet for the crystal shows the underside of the chip pin out, so if you use that as the solder pads you end up back to front. Some messy soldering and wires allowed me to work around that.

I also found soldering a QFN-20 chip hard, even with my heat gun (hence the charring), so I have ordered an oven. I'll blog on that later. I may eventually progress to solder paste masks and the like. We'll see how it goes. Even so, this is all well within the grasp of the amateur / hobbiest.

I also found the LEDs would not work - apart from ordering the wrong LEDs (diode drop was more than the supply voltage, idiot), it seems GPIO P34 does not play and I can't work out why. I have read the data sheet over and over, tried loads of config changes, and it should work, but I cannot make it work (and cannot on the Elechouse boards either), so re-done using other GPIO pins.

Version 1 board - actually works!

Version 2 board

I also decided to move to smaller 0805 components instead of 1206 - simply because of the challenge of fitting all the components on such a small board. I have made a number of value changes to more closely match the PN532 reference circuit. So that is next. I also think the Elechouse boards can overload the receiver, and it meant my Amex card would not read on my board, but a component change and it does now!

But first I need to actually test the two LEDs that should work do in fact work well enough, and test the oven when it arrives. If all goes well I'll order some version 2 boards and test.

What is wrong with other boards?

If you search for NFC readers you find two main types of things you can buy: (a) a nice plastic card reader with rubber feet to sit on your desk and connect via a USB lead to your PC, or (b) a "development board" with lots of 0.1" spaced pins to allow you to tinker, usually quite large. What you don't find is a board designed to actually be used as a component in an access control system.

To be fair, the Elechouse is pretty close - it has lots of extra pads for general tinkering but is not bad. What is lacked was LEDs for feedback and a tamper switch. That is what I have added. Just to be clear, my board is not a copy of the Elechouse, and is based on the reference circuit in the PN532 datasheet.

My board is HSU (High Speed UART) only (as that is better on a length of wire than I2C), only four wires (GND/VCC/TX/RX), and a choice of connectors on either side of the board for easy use in an access system or in a nice simple case as a device on your desk connected to a PC, if that is what you want. I'll do a 3D case design as well for both.

So I actually think my board design will be a good, usable, and even sellable board. If there is any demand I may get a few hundred properly made. But it is also nice that I am making this all open source, not just the s/w drivers, but the actual PCB layouts so you can easily order and make yourself if you want.

This is the version 2 board so far... May be real boards next week.

[P.S. I have ordered these now...]

Update: The V2 board work, and I have sent to an RF engineer to check if I need to make any tweaks before making the next version.

Virus Consulting

All our teams make an effort to stay optimistic, but I will say that once our virus division saw the vaccine efficacy data, they started asking for payment up front.

Solder paste, and reflow oven

By [email protected] (RevK)

I got a cheap reflow oven off Amazon. Seems to work, but I am no expert, and there is some advice on the internet about some tweaks and improvements to that model too. However, baby steps.

I also got some solder paste. I do not (yet) have a stencil. So advice on how one uses a solder paste stencil, and what paste you get, and so on, may be useful.

This does, however, pose a problem. Whilst it is very easy to put a spot of paste on the pads for the passives, there is no way in hell I could possibly put paste on each pad on the FT231XQ or USB-C connector. The pins are too fine.

So how to do it. Well, I did wonder if just putting paste over the whole row of pads and relying on surface tension may work. But the other snag is these short turnaround boards from PCB Train have no solder resist. Still, it is worth a try...

Well, not quite. That is the USB-C connector, and you can maybe just see that the end power pads have bridged. As it happens a touch with soldering iron sorted that and all the fine pads were OK. But it is clearly not reliable. Attempts to do this on a simple QFN-16 were less good. I suspect if I got exactly the right amount of paste it might work, but generally, no. And I doubt any chance with a QFN-40.

So what now?

Well, what I was doing with the hot air gun was tinning the pads manually (easy), and putting liquid flux on the chip, and then blasting it. It worked pretty reliably, but the heat was not very controlled and you end up charing the PCB.

So will that work in the over? Well, the short answer is yes! (well sort of)

I tin the find pads, flux the chip and place on tinned pads, solder paste the passives and put them on board, and then reflow. It seems to work most of the time, but occasionally I have to heat gun and push the chip down on to the board to ensure all pins connected.

Just as well, as I have just got the new NFC boards to play with. Fingers crossed.

What Nobody Says about Startup Moms


Rainforest (YC S12) Is Hiring Senior Engineers, Globally and Remote


HashiCorp Nomad 1.1 Beta


Study: 40.2% of Consumers Would Consider Switching to Municipal Broadband


Why Use a Novichok?


A Lock Picking Game Changer [video]


Ask HN: Who is hiring? (May 2021)


Ask HN: Who wants to be hired? (May 2021)


Ask HN: Freelancer? Seeking freelancer? (May 2021)


Practical SQL for Data Analysis


Go Modules Cheat Sheet


Rural purge


Programming in Z3 by learning to think like a compiler


The Programming Language Zoo


Microsoft bids $44.6B to buy Yahoo (2008)


Manchester United protest: Arrest made over 'hostility' towards police

Six officers were injured in the "violent disorder" at Old Trafford on Sunday, police say.

Hillary Clinton warns of 'huge consequences' in Afghan US troop withdrawal

The end of the US deployment could play into the Taliban's hands, warns the former secretary of state.

Covid: 1m plus rule could end from 21 June, says Johnson

Any easing of England's social distancing rules will depend on Covid data, the prime minister says.

Man Utd supporters group urges Glazers to engage with fans

The Manchester United Supporters' Trust urges co-chairman Joel Glazer to engage with fans to avoid a repeat of Sunday's protests.

It’s the year of the Virtual Desktop again … but this time really is different

By David Gordon

Join us and Nutanix online this week and find out why

Webcast  A year of pandemic has forced momentous changes on how we work and the technology we use to support this.…

Félix Verdejo: Pro boxer charged with killing pregnant lover

Félix Verdejo, who fought in the 2012 Olympics, turned himself in to Puerto Rican officials.

India Covid pandemic: Delhi calls for army help amid crisis

Hospitals in India's capitals are full and facing shortages of oxygen as Covid cases surge.

Selby maintains lead over Murphy heading into final session

Mark Selby holds off a determined Shaun Murphy to maintain his three-frame lead in the World Championship final.

'We spent 40 days in a cave without sunlight or watches'

The Deep Time study aims to see how humans can adapt to isolation and losing their sense of time.

European Super League: Premier League brings in new owners' rule to stop repeat

The Premier League is to bring in a new owners' charter to stop future attempts to form a breakaway Super League.

Covid: Germany's Oktoberfest cancelled for the second time

Around six million revellers would normally attend the annual beer festival in Munich.

Child sexual abuse: Four held in German-led raid on huge network

German police say a dark web club for sharing images of child sex abuse had more than 400,000 users.

British and Irish Lions 2021: Who could be the bolters to tour South Africa?

Left-field selections are something of a British and Irish Lions tradition - who could be a surprise pick for the 2021 tour of South Africa?

World Snooker Championship: Crucible final first capacity crowd for over a year

Fans celebrate as the World Snooker Championship hosts the first capacity crowd at a UK sporting event in over a year.

Fan makes amazing one-handed catch while holding snack at Philadelphia Phillies v New York Mets

Watch a Philadelphia Phillies fan makes a one-handed catch without a glove from a 97mph strike - without dropping his food.

Even better.

By /u/esberat

Even better. submitted by /u/esberat to r/Unexpected
[link] [comments]

Dragon’s Eye , Norway 🇳🇴

By /u/mohRift

Dragon’s Eye , Norway 🇳🇴 submitted by /u/mohRift to r/interestingasfuck
[link] [comments]

Green Arrow in real life

By /u/Pierzakve

Green Arrow in real life submitted by /u/Pierzakve to r/nextfuckinglevel
[link] [comments]

Capturing that perfect frame

By /u/pg_sbucks

Capturing that perfect frame submitted by /u/pg_sbucks to r/instant_regret
[link] [comments]

Arcane Animated Series Trailer (Coming to Netflix this Fall)

By /u/dorkmax_executives

Arcane Animated Series Trailer (Coming to Netflix this Fall) submitted by /u/dorkmax_executives to r/leagueoflegends
[link] [comments]

The happiness in his eyes

By /u/Dull_Tonight

The happiness in his eyes submitted by /u/Dull_Tonight to r/MadeMeSmile
[link] [comments]

“Hi guys! Thanks for tuning in to another episode of Forgotten Weapons!”

By /u/ColumbianGeneral

“Hi guys! Thanks for tuning in to another episode of Forgotten Weapons!” submitted by /u/ColumbianGeneral to r/rareinsults
[link] [comments]

CB hates Mother Nature (giving away free dresser prior to move)

By /u/TheBreakUp2013

CB hates Mother Nature (giving away free dresser prior to move) submitted by /u/TheBreakUp2013 to r/ChoosingBeggars
[link] [comments]

Good luck scratching my car with this on it!

By /u/alimehdi242

Good luck scratching my car with this on it! submitted by /u/alimehdi242 to r/Damnthatsinteresting
[link] [comments]

Black Panther: Wakanda Forever - Official Title Treatment

By /u/chanma50

Black Panther: Wakanda Forever - Official Title Treatment submitted by /u/chanma50 to r/marvelstudios
[link] [comments]

We don't micromanage here

By /u/GraphsWordsDogs

We don't micromanage here submitted by /u/GraphsWordsDogs to r/funny
[link] [comments]

Florida Republicans rushed to curb mail voting after Trump’s attacks on the practice. Now some fear it could lower GOP turnout.

By /u/FriesWithThat

Florida Republicans rushed to curb mail voting after Trump’s attacks on the practice. Now some fear it could lower GOP turnout. submitted by /u/FriesWithThat to r/politics
[link] [comments]

Designer life before AutoCAD

By /u/gamingducks

Designer life before AutoCAD submitted by /u/gamingducks to r/pics
[link] [comments]

TIL in 1911, physicist George de Hevesy suspected his landlady was bulking up his meals with leftovers; he proved it by sprinkling radioactive material over his dinner and detecting it in the next day’s portion

By /u/johnlen1n

submitted by /u/johnlen1n to r/todayilearned
[link] [comments]

Elephant uses "stealth mode" to foil anti-elephant fence


Elephant uses "stealth mode" to foil anti-elephant fence submitted by /u/WlTCHFINDER-GENERAL to r/nextfuckinglevel
[link] [comments]

Adding GeoDjango to an existing Django project

Work on VIAL for Vaccinate The States continues.

I talked about matching last week. I've been building more features to support figuring out if a newly detected location is already listed or not, with one of the most significant being the ability to search for locations within a radius of a specific point.

I've experimented with a PostgreSQL/Django version of the classic cos/sin/radians query for this but if you're going to do this over a larger dataset it's worth using a proper spatial index for it - and GeoDjango has provided tools for this since Django 1.0 in 2008!

I have to admit that outside of a few prototypes I've never used GeoDjango extensively myself - partly I've not had the right project for it, and in the past I've also been put off by the difficulty involved in installing all of the components.

That's a lot easier in 2021 than it was in 2008. But VIAL is a project in-flight, so here are some notes on what it took to get GeoDjango added to an existing Django project.

Alex Vandiver has been working with me on VIAL and helped figure out quite a few of these steps.

Activating PostgreSQL

The first step was to install the PostGIS PostgreSQL extension. This can be achieved using a Django migration:

from django.contrib.postgres.operations import CreateExtension
from django.db import migrations

class Migration(migrations.Migration):

    dependencies = [
        ("my_app", "0108_previous-migration"),

    operations = [

Most good PostgreSQL hosting already makes this extension available - in our case we are using Google Cloud SQL which supports various extensions, including PostGIS. I use for my personal development environment which bundles PostGIS too.

So far, so painless!

System packages needed by GeoDjango

GeoDjango needs the GEOS, GDAL and PROJ system libraries. Alex added these to our Dockerfile (used for our production deployments) like so:

RUN apt-get update && apt-get install -y \
    binutils \
    gdal-bin \
    libproj-dev \
    && rm -rf /var/lib/apt/lists/*

Adding a point field to a Django model

I already had a Location model, which looked something like this:

class Location(models.Model):
    name = models.CharField()
    # ...
    latitude = models.DecimalField(
        max_digits=9, decimal_places=5
    longitude = models.DecimalField(
        max_digits=9, decimal_places=5

I made three changes to this class: I changed the base class to this:

from django.contrib.gis.db import models as gis_models

class Location(gis_models.Model):
    # ...

I added a point column:

    point = gis_models.PointField(

And I set up a custom save() method to populate that point field with a point representing the latitude and longitude every time the object was saved:

from django.contrib.gis.geos import Point

# ...

    def save(self, *args, **kwargs):
        # Point is derived from latitude/longitude
        if self.longitude and self.latitude:
            self.point = Point(
            self.point = None
        super().save(*args, **kwargs)

srid=4326 ensures the point is stored using WGS84 - the most common coordinate system for latitude and longitude values across our planet.

Running ./ makemigrations identified the new point Point column and created the corresponding migration for me.

Backfilling the point column with a migration

The .save() method would populate point for changes going forward, but I had 40,000 records that already existed which I needed to backfill. I used this migration to do that:

from django.db import migrations

class Migration(migrations.Migration):

    dependencies = [
        ("core", "0110_location_point"),

    operations = [
            update location
            set point = ST_SetSRID(
                    longitude, latitude

latitude/longitude/radius queries

With the new point column created and populated, here's the code I wrote to support simple latitude/longitude/radius queries:

from django.contrib.gis.geos import Point
from django.contrib.gis.measure import Distance

def search_locations(request):
    qs = Location.objects.filter(soft_deleted=False)
    latitude = request.GET.get("latitude")
    longitude = request.GET.get("longitude")
    radius = request.GET.get("radius")
    if latitude and longitude and radius:
        # Validate latitude/longitude/radius
        for value in (latitude, longitude, radius):
            except ValueError:
                return JsonResponse(
                    {"error": "latitude/longitude/radius should be numbers"}, status=400
        qs = qs.filter(
    # ... return JSON for locations

In writing up these notes I realize that this isn't actually the best way to do this, because it fails to take advantage of the spatial index on that column! I've filed myself an issue to switch to the spatial-index-friendly dwithin instead.

Getting CI to work

The hardest part of all of this turned out to be getting our CI suites to pass.

We run CI in two places at the moment: GitHub Actions and Google Cloud Build (as part of our continuous deployment setup).

The first error I hit was this one:

psycopg2.errors.UndefinedFile: could not open extension control file "/usr/share/postgresql/13/extension/postgis.control": No such file or directory

It turns out that's what happens when your PostgreSQL server doesn't have the PostGIS extension available.

Our GitHub Actions configuration started like this:

name: Run tests

on: [push]

    runs-on: ubuntu-latest
        image: postgres:13
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
          POSTGRES_DB: vaccinate
          --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
        - 5432:5432

The postgres:13 image doesn't have PostGIS. Swapping that out for postgis/postgis:13-3.1 fixed that (using this image).

Our Cloud Build configuration included this:

  # Start up a postgres for tests
  - id: "start postgres"
    name: ""
      - "run"
      - "-d"
      - "--network=cloudbuild"
      - "-e"
      - "--name"
      - "vaccinate-db"
      - "postgres"

  - id: "test image"
    name: ""
      - "run"
      - "-t"
      - "--network=cloudbuild"
      - "-e"
      - "DATABASE_URL=postgres://[email protected]:5432/vaccinate"
      - "${_IMAGE_NAME}:latest"
      - "pytest"
      - "-v"

I tried swapping out that last postgres argument for postgis/postgis:13-3.1, like I had with the GitHub Actions one... and it failed with this error instead:

django.db.utils.OperationalError: could not connect to server: Connection refused Is the server running on host "vaccinate-db" ( and accepting TCP/IP connections on port 5432?

This one stumped me. Eventually Alex figured out the problem: the extra extension meant the PostgreSQL was taking slightly longer to start - something that was covered in our GitHub Actions configuration by the pg_isready line. He added this step to our Cloud Build configuration:

  - id: "wait for postgres"
    name: "jwilder/dockerize"
    args: ["dockerize", "-timeout=60s", "-wait=tcp://vaccinate-db:5432"]

It uses jwilder/dockerize to wait until the database container starts accepting connections on port 5432.

Next steps

Now that we have GeoDjango I'm excited to start exploring new capabilities for our software. One thing in particular that interests me is teaching VIAL to backfill the county for a location based on its latitude and longitude - the US Census provide a shapefile of county polygons which I use with Datasette and SpatiaLite in my simonw/us-counties-datasette project, so I'm confident it would work well using PostGIS instead.

Releases this week

TIL this week

Hosting SQLite databases on Github Pages

Hosting SQLite databases on Github Pages

I've seen the trick of running SQLite compiled to WASM in the browser before, but this comes with an incredibly clever bonus trick: it uses SQLite's page structure to fetch subsets of the database file via HTTP range requests, which means you can run indexed SQL queries against a 600MB database file while only fetching a few MBs of data over the wire. Absolutely brilliant. Tucked away at the end of the post is another neat trick: making the browser DOM available to SQLite as a virtual table, so you can query and update the DOM of the current page using SQL!

Via Hacker News

One year of TILs

Just over a year ago I started tracking TILs, inspired by Josh Branchaud's collection. I've since published 148 TILs across 43 different topics. It's a great format!

TIL stands for Today I Learned. The thing I like most about TILs is that they drop the barrier to publishing something online to almost nothing.

If I'm writing a blog entry, I feel like it needs to say something new. This pressure for originality leads to vast numbers of incomplete, draft posts and a sporadic publishing schedule that trends towards not publishing anything at all.

(Establishing a weeknotes habit has helped enormously here too.)

The bar for a TIL is literally "did I just learn something?" - they effectively act as a public notebook.

They also reflect my values as a software engineer. The thing I love most about this career is that the opportunities to learn new things never reduce - there will always be new sub-disciplines to explore, and I aspire to learn something new every single working day.

My hope is that by publishing a constant stream of TILs I can reinforce the idea that even if you've been working in this industry for twenty years there will always be new things to learn, and learning any new trick - even the most basic thing - should be celebrated.

Query Engines: Push vs. Pull

Query Engines: Push vs. Pull

Justin Jaffray (who has worked on Materialize) explains the difference between push and pull query execution engines using some really clear examples built around JavaScript generators.

Via Hacker News

Free software activities in April 2021

Here is my monthly update covering what I have been doing in the free software world during April 2021 (previous month):


Reproducible Builds

One of the original promises of open source software is that distributed peer review and transparency of process results in enhanced end-user security. However, whilst anyone may inspect the source code of free and open source software for malicious flaws, almost all software today is distributed as pre-compiled binaries. This allows nefarious third-parties to compromise systems by injecting malicious code into ostensibly secure software during the various compilation and distribution processes.

The motivation behind the Reproducible Builds effort is to ensure no flaws have been introduced during this compilation process by promising identical results are always generated from a given source, thus allowing multiple third-parties to come to a consensus on whether a build was compromised.

The project is proud to be a member project of the Software Freedom Conservancy. Conservancy acts as a corporate umbrella allowing projects to operate as non-profit initiatives without managing their own corporate structure. If you like the work of the Conservancy or the Reproducible Builds project, please consider becoming an official supporter.

This month, I:



Debian Long Term Support (LTS)

This month I have worked 18 hours on Debian Long Term Support (LTS) and 12 hours on its sister Extended LTS project:

You can find out more about the project via the following video:

Quoting Drew DeVault, SourceHut

Over the past several months, everyone in the industry who provides any kind of free CPU resources has been dealing with a massive outbreak of abuse for cryptocurrency mining. The industry has been setting up informal working groups to pool knowledge of mitigations, communicate when our platforms are being leveraged against one another, and cumulatively wasting thousands of hours of engineering time implementing measures to deal with this abuse, and responding as attackers find new ways to circumvent them.

Drew DeVault, SourceHut

Weeknotes: Vaccinate The States, and how I learned that returning dozens of MB of JSON works just fine these days

On Friday VaccinateCA grew in scope, a lot: we launched a new website called Vaccinate The States. Patrick McKenzie wrote more about the project here - the short version is that we're building the most comprehensive possible dataset of vaccine availability in the USA, using a combination of data collation, online research and continuing to make a huge number of phone calls.

Screenshot of Vaccinate The States, showing a map with a LOT of markers on it

VIAL, the Django application I've been working on since late February, had to go through some extensive upgrades to help support this effort!

VIAL has a number of responsibilities. It acts as our central point of truth for the vaccination locations that we are tracking, powers the app used by our callers to serve up locations to call and record the results, and as-of this week it's also a central point for our efforts to combine data from multiple other providers and scrapers.

The data ingestion work is happening in a public repository, CAVaccineInventory/vaccine-feed-ingest. I have yet to write a single line of code there (and I thoroughly enjoy working on that kind of code) because I've been heads down working on VIAL itself to ensure it can support the ingestion efforts.

Matching and concordances

If you're combining data about vaccination locations from a range of different sources, one of the biggest challenges is de-duplicating the data: it's important the same location doesn't show up multiple times (potentially with slightly differing details) due to appearing in multiple sources.

Our first step towards handling this involved the addition of "concordance identifiers" to VIAL.

I first encountered the term "concordance" being used for this in the Who's On First project, which is building a gazetteer of every city/state/country/county/etc on earth.

A concordance is an identifier in another system. Our location ID for RITE AID PHARMACY 05976 in Santa Clara is receu5biMhfN8wH7P - which is e3dfcda1-093f-479a-8bbb-14b80000184c in VaccineFinder and 7537904 in Vaccine Spotter and ChIJZaiURRPKj4ARz5nAXcWosUs in Google Places.

We're storing them in a Django table called ConcordanceIdentifier: each record has an authority (e.g. vaccinespotter_org) and an identifier (7537904) and a many-to-many relationship to our Location model.

Why many-to-many? Surely we only want a single location for any one of these identifiers?

Exactly! That's why it's many-to-many: because if we import the same location twice, then assign concordance identifiers to it, we can instantly spot that it's a duplicate and needs to be merged.

Raw data from scrapers

ConcordanceIdentifier also has a many-to-many relationship with a new table, called SourceLocation. This table is essentially a PostgreSQL JSON column with a few other columns (including latitude and longitude) into which our scrapers and ingesters can dump raw data. This means we can use PostgreSQL queries to perform all kinds of analysis on the unprocessed data before it gets cleaned up, de-duplicated and loaded into our point-of-truth Location table.

How to dedupe and match locations?

Initially I thought we would do the deduping and matching inside of VIAL itself, using the raw data that had been ingested into the SourceLocation table.

Since we were on a tight internal deadline it proved more practical for people to start experimenting with matching code outside of VIAL. But that meant they needed the raw data - 40,000+ location records (and growing rapidly).

A few weeks ago I built a CSV export feature for the VIAL admin screens, using Django's StreamingHttpResponse class combined with keyset pagination for bulk export without sucking the entire table into web server memory - details in this TIL.

Our data ingestion team wanted a GeoJSON export - specifically newline-delimited GeoJSON - which they could then load into GeoPandas to help run matching operations.

So I built a simple "search API" which defaults to returning 20 results at a time, but also has an option to "give me everything" - using the same technique I used for the CSV export: keyset pagination combined with a StreamingHttpResponse.

And it worked! It turns out that if you're running on modern infrastructure (Cloud Run and Cloud SQL in our case) in 2021 getting Django to return 50+MB of JSON in a streaming response works just fine.

Some of these exports are taking 20+ seconds, but for a small audience of trusted clients that's completely fine.

While working on this I realized that my idea of what size of data is appropriate for a dynamic web application to return more or less formed back in 2005. I still think it's rude to serve multiple MBs of JavaScript up to an inexpensive mobile phone on an expensive connection, but for server-to-server or server-to-automation-script situations serving up 50+ MB of JSON in one go turns out to be a perfectly cromulent way of doing things.

Export full results from django-sql-dashboard

django-sql-dashboard is my Datasette-inspired library for adding read-only arbitrary SQL queries to any Django+PostgreSQL application.

I built the first version last month to help compensate for switching VaccinateCA away from Airtable - one of the many benefits of Airtable is that it allows all kinds of arbitrary reporting, and Datasette has shown me that bookmarkable SQL queries can provide a huge amount of that value with very little written code, especially within organizations where SQL is already widely understood.

While it allows people to run any SQL they like (against a read-only PostgreSQL connection with a time limit) it restricts viewing to the first 1,000 records to be returned - because building robust, performante pagination against arbitrary SQL queries is a hard problem to solve.

Today I released django-sql-dashboard 0.10a0 with the ability to export all results for a query as a downloadable CSV or TSV file, using the same StreamingHttpResponse technique as my Django admin CSV export and all-results-at-once search endpoint.

I expect it to be pretty useful! It means I can run any SQL query I like against a Django project and get back the full results - often dozens of MBs - in a form I can import into other tools (including Datasette).

Screenshot of the SQL Dashboard interface, showing the new 'Export as CSV/TSV' buttons which trigger a file download dialog

TIL this week

Releases this week

Weeknotes: The Aftermath

Some tweets that effectively illustrate my week:

Last week we went live with VIAL, the replacement backend I've been building for VaccinateCA. This meant we went from having no users to having a whole lot of users, and all of the edge-cases and missing details quickly started to emerge.

So this week I've been almost exclusively working my way through those. Not much to report otherwise!

TIL this week

Releases this week



Given a latitude and longitude, how can you tell what country that point sits within? One way is to do a point-in-polygon lookup against a set of country polygons, but this can be tricky: some countries such as New Zealand have extremely complex outlines, even though for this use-case you don't need the exact shape of the coastline. country-coder solves this with a custom designed 595KB GeoJSON file with detailed land borders but loosely defined ocean borders. It also comes with a wrapper JavaScript library that provides an API for resolving points, plus useful properties on each country with details like telepohen calling codes and emoji flags.

Via @bhousel

Tour d'Orwell: Wallington

Previously in George Orwell travel posts: Sutton Courtenay, Marrakesh, Hampstead, Paris, Southwold & The River Orwell.


Wallington is a small village in Hertfordshire, approximately fifty miles north of London and twenty-five miles from the outskirts of Cambridge. George Orwell lived at No. 2 Kits Lane, better known as 'The Stores', on a mostly-permanent basis from 1936 to 1940, but he would continue to journey up from London on occasional weekends until 1947.

His first reference to The Stores can be found in early 1936, where Orwell wrote from Lancashire during research for The Road to Wigan Pier to lament that he would very much like "to do some work again — impossible, of course, in the [current] surroundings":

I am arranging to take a cottage at Wallington near Baldock in Herts, rather a pig in a poke because I have never seen it, but I am trusting the friends who have chosen it for me, and it is very cheap, only 7s. 6d. a week [£20 in 2021].

For those not steeped in English colloquialisms, "a pig in a poke" is an item bought without seeing it in advance. In fact, one general insight that may be drawn from reading Orwell's extant correspondence is just how much he relied on a close network of friends, belying the lazy and hagiographical picture of an independent and solitary figure. (Still, even Orwell cultivated this image at times, such as in a patently autobiographical essay he wrote in 1946. But note the off-hand reference to varicose veins here, for they would shortly re-appear as a symbol of Winston's repressed humanity in Nineteen Eighty-Four.)

Nevertheless, the porcine reference in Orwell's idiom is particularly apt, given that he wrote the bulk of Animal Farm at The Stores — his 1945 novella, of course, portraying a revolution betrayed by allegorical pigs. Orwell even drew inspiration for his 'fairy story' from Wallington itself, principally by naming the novel's farm 'Manor Farm', just as it is in the village. But the allusion to the purchase of goods is just as appropriate, as Orwell returned The Stores to its former status as the village shop, even going so far as to drill peepholes in a door to keep an Orwellian eye on the jars of sweets. (Unfortunately, we cannot complete a tidy circle of references, as whilst it is certainly Napoleon — Animal Farm's substitute for Stalin — who is quoted as describing Britain as "a nation of shopkeepers", it was actually the maraisard Bertrand Barère who first used the phrase).


"It isn't what you might call luxurious", he wrote in typical British understatement, but Orwell did warmly emote on his animals. He kept hens in Wallington (perhaps even inspiring the opening line of Animal Farm: "Mr Jones, of the Manor Farm, had locked the hen-houses for the night, but was too drunk to remember to shut the pop-holes.") and a photograph even survives of Orwell feeding his pet goat, Muriel. Orwell's goat was the eponymous inspiration for the white goat in Animal Farm, a decidedly under-analysed character who, to me, serves to represent an intelligentsia that is highly perceptive of the declining political climate but, seemingly content with merely observing it, does not offer any meaningful opposition. Muriel's aesthetic of resistance, particularly in her reporting on the changes made to the Seven Commandments of the farm, thus rehearses the well-meaning (yet functionally ineffective) affinity for 'fact checking' which proliferates today. But I digress.

There is a tendency to "read Orwell backwards", so I must point out that Orwell wrote several other works whilst at The Stores as well. This includes his Homage to Catalonia, his aforementioned The Road to Wigan Pier, not to mention countless indispensable reviews and essays as well. Indeed, another result of focusing exclusively on Orwell's last works is that we only encounter his ideas in their highly-refined forms, whilst in reality, it often took many years for concepts to fully mature — we first see, for instance, the now-infamous idea of "2 + 2 = 5" in an essay written in 1939.

This is important to understand for two reasons. Although the ostentatiously austere Barnhill might have housed the physical labour of its writing, it is refreshing to reflect that the philosophical heavy-lifting of Nineteen Eighty-Four may have been performed in a relatively undistinguished North Hertfordshire village. But perhaps more importantly, it emphasises that Orwell was just a man, and that any of us is fully capable of equally significant insight, with — to quote Christopher Hitchens — "little except a battered typewriter and a certain resilience."


The red commemorative plaque not only limits Orwell's tenure to the time he was permanently in the village, it omits all reference to his first wife, Eileen O'Shaughnessy, whom he married in the village church in 1936.
Wallington's Manor Farm, the inspiration for the farm in Animal Farm. The lower sign enjoins the public to inform the police "if you see anyone on the [church] roof acting suspiciously". Non-UK-residents may be surprised to learn about the systematic theft of lead.

Why you shouldn't use ENV variables for secret data

Why you shouldn't use ENV variables for secret data

I do this all the time, but this article provides a good set of reasons that secrets in environment variables are a bad pattern - even when you know there's no multi-user access to the host you are deploying to. The biggest problem is that they often get captured by error handling scripts, which may not have the right code in place to redact them. This article suggests using Docker secrets instead, but I'd love to see a comprehensive write-up of other recommended patterns for this that go beyond applications running in Docker.

Via The environ-config tutorial

Porting VaccinateCA to Django

As I mentioned back in February, I've been working with the VaccinateCA project to try to bring the pandemic to an end a little earlier by helping gather as accurate a model as possible of where the Covid vaccine is available in California and how people can get it.

The key activity at VaccinateCA is calling places to check on their availability and eligibility criteria. Up until last night this was powered by a heavily customized Airtable instance, accompanied by a custom JavaScript app for the callers that communicated with the Airtable API via some Netlify functions.

Today, the flow is powered by a new custom Django backend, running on top of PostgreSQL.

The thing you should never do

Replacing an existing system with a from-scratch rewrite is risky. Replacing a system that is built on something as flexible as Airtable that is evolving on a daily basis is positively terrifying!

Airtable served us extremely well, but unfortunately there are hard limits to the number of rows Airtable can handle and we've already bounced up against them and had to archive some of our data. To keep scaling the organization we needed to migrate away.

We needed to build a matching relational database with a comprehensive, permission-controlled interface for editing it, plus APIs to drive our website and application. And we needed to do it using the most boring technology possible, so we could focus on solving problems directly rather than researching anything new.

It will never cease to surprise me that Django has attained boring technology status! VaccineCA sits firmly in Django's sweet-spot. So we used that to build our replacement.

The new Django-based system is called VIAL, for "Vaccine Information Archive and Library" - a neat Jesse Vincent bacronym.

We switched things over to VIAL last night, but we still have activity in Airtable as well. I expect we'll keep using Airtable for the lifetime of the organization - there are plenty of ad-hoc data projects for which it's a perfect fit.

The most important thing here is to have a trusted single point of truth for any piece of information. I'm not quite ready to declare victory on that point just yet, but hopefully once things settle down over the next few days.

Screenshot of the Django admin VIAL index page

Data synchronization patterns

The first challenge, before even writing any code, was how to get stuff out of Airtable. I built a tool for this a while ago called airtable-export, and it turned out the VaccinateCA team were using it already before I joined!

airtable-export was already running several times an hour, backing up the data in JSON format to a GitHub repository (a form of Git scraping). This gave us a detailed history of changes to the Airtable data, which occasionally proved extremely useful for answering questions about when a specific record was changed or deleted.

Having the data in a GitHub repository was also useful because it gave us somewhere to pull data from that wasn't governed by Airtable's rate limits.

I iterated through a number of different approaches for writing importers for the data.

Each Airtable table ended up as a single JSON file in our GitHub repository, containing an array of objects - those files got pretty big, topping out at about 80MB.

I started out with Django management commands, which could be passed a file or a URL. A neat thing about using GitHub for this is that you can use the "raw data" link to obtain a URL with a short-lived token, which grants access to that file. So I could create a short-term URL and paste it directly to my import tool.

I don't have a good pattern for running Django management commands on Google Cloud Run, so I started moving to API-based import scripts instead.

The pattern that ended up working best was to provide a /api/importRecords API endpoint which accepts a JSON array of items.

The API expects the input to have a unique primary key in each record - airtable_id in our case. It then uses Django's update_or_create() ORM method to create new records if they were missing, and update existing records otherwise.

One remaining challenge: posting 80MB of JSON to an API in one go would likely run into resource limits. I needed a way to break that input up into smaller batches.

I ended up building a new tool for this called json-post. It has an extremely specific use-case: it's for when you want to POST a big JSON array to an API endpoint but you want to first break it up into batches!

Here's how to break up the JSON in Reports.json into 50 item arrays and send them to that API as separate POSTs:

json-post Reports.json \                              
   "" \
   --batch-size 50

Here are some more complex options. Here we need to pass an Authorization: Beraer XXXtokenXXX API key header, run the array in reverse, record our progress (the JSON responses from the API as newline-delimited JSON) to a log file, set a longer HTTP read timeout and filter for just specific items:

% json-post Reports.json \                              
   "" \
  -h Authorization 'Bearer XXXtokenXXX' \
  --batch-size 50 \
  --reverse \
  --log /tmp/progress.txt \
  --http-read-timeout 20 \
  --filter 'item.get("is_soft_deleted")'

The --filter option proved particularly useful. As we kicked the tires on VIAL we would spot new bugs - things like the import script failing to correctly record the is_soft_deleted field we were using in Airtable. Being able to filter that input file with a command-line flag meant we could easily re-run the import just for a subset of reports that were affected by a particular bug.

--filter takes a Python expression that gets compiled into a function and passed item as the current item in the list. I borrowed the pattern from my sqlite-transform tool.

The value of API logs

VaccineCA's JavaScript caller application used to send data to Airtable via a Netlify function, which allowed additional authentication to be added built using Auth0.

Back in February, the team had the bright idea to log the API traffic to that function to a separate base in Airtable - including full request and response bodies.

This proved invaluable for debugging. It also meant that when I started building VIAL's alternative implementation of the "submit a call report" API I could replay historic API traffic that had been recorded in that table, giving me a powerful way to exercise the new API with real-world traffic.

This meant that when we turned on VIAL we could switch our existing JavaScript SPA over to talking to it using a fully tested clone of the existing Airtable-backed API.

VIAL implements this logging pattern again, this time using Django and PostgreSQL.

Given that the writable APIs will recieve in the low thousands of requests a day, keeping them in a database table works great. The table has grown to 90MB so far. I'm hoping that the pandemic will be over before we have to worry about logging capacity!

We're using PostgreSQL jsonb columns to store the incoming and returned JSON, via Django's JSONField. This means we can do in-depth API analysis using PostgreSQL's JSON SQL functions! Being able to examine returned JSON error messages or aggregate across incoming request bodies helped enormously when debugging problems with the API import scripts.

Storing the original JSON

Today, almost all of the data stored in VIAL originated in Airtable. One trick that has really helped build the system is that each of the tables that might contain imported data has both an airtable_id nullable column and an import_json JSON field.

Any time we import a record from airtable, we record both the ID and the full, original Airtable JSON that we used for the import.

This is another powerful tool for debugging: we can view the original Airtable JSON directly in the Django admin interface for a record, and confirm that it matches the ORM fields that we set from that.

I came up with a simple pattern for Pretty-printing all read-only JSON in the Django admin that helps with this too.

Staying as flexible as possible

The thing that worried me most about replacing Airtable with Django was Airtable's incredible flexibility. In the organization's short life it has already solved so many problems by adding new columns in Airtable, or building new views.

Is it possible to switch to custom software without losing that huge cultural advantage?

This is the same reason it's so hard for custom software to compete with spreadsheets.

We've only just made the switch, so we won't know for a while how well we've done at handling this. I have a few mechanisms in place that I'm hoping will help.

The first is django-sql-dashboard. I wrote about this project in previous weeknotes here and here - the goal is to bring some of the ideas from Datasette into the Django/PostgreSQL world, by providing a read-only mechanism for constructing SQL queries, bookmarking and saving the results and outputting simple SQL-driven visualizations.

We have a lot of SQL knowledge at VaccinateCA, so my hope is that people with SQL will be able to solve their own problems, and people who don't know SQL yet will have no trouble finding someone who can help them.

In the boring technology model of things, django-sql-dashboard counts as the main innovation token I'm spending for this project. I'm optimistic that it will pay off.

I'm also leaning heavily on Django's migration system, with the aim of making database migrations common and boring, rather than their usual default of being rare and exciting. We're up to 77 migrations already, in a codebase that is just over two months old!

I think a culture that evolves the database schema quickly and with as little drama as possible is crucial to maintaining the agility that this kind of organization needs.

Aside from the Django Admin providing the editing interface, everything that comes into and goes out of VIAL happens through APIs. These are fully documented: I want people to be able to build against the APIs independently, especially for things like data import.

After seeing significant success with PostgreSQL JSON already, I'm considering using it to add even more API-driven flexbility to VIAL in the future. Allowing our client developers to start collecting a new piece of data from our volunteers in an existing JSON field, then migrating that into a separate column once it has proven its value, is very tempting indeed.

Open source tools we are using

An incomplete list of open source packages we are using for VIAL so far:

Want to help out?

VaccinateCA is hiring! It's an interesting gig, because the ultimate goal is to end the pandemic and put this non-profit permanently out of business. So if you want to help end things faster, get in touch.

TIL this week

Releases this week

Quoting Jacques Chester

In general, relying only on natural keys is a nightmare. Double nightmare if it's PII. Natural keys only work if you are flawlessly omniscient about the domain. And you aren't.

Jacques Chester

Behind GitHub’s new authentication token formats

Behind GitHub’s new authentication token formats

This is a really smart design. GitHub's new tokens use a type prefix of "ghp_" or "gho_" or a few others depending on the type of token, to help support mechanisms that scan for accidental token publication. A further twist is that the last six characters of the tokens are a checksum, which means token scanners can reliably distinguish a real token from a coincidental string without needing to check back with the GitHub database. "One other neat thing about _ is it will reliably select the whole token when you double click on it" - what a useful detail!

Via Hacker News

Render single selected county on a map

Render single selected county on a map

Another experiment at the intersection of Datasette and Observable notebooks. This one imports a full Datasette table (3,200 US counties) using streaming CSV and loads that into Observable's new Search and Table filter widgets. Once you select a single county a second Datasette SQL query (this time retuning JSON) fetches a GeoJSON representation of that county which is then rendered as SVG using D3.

Via @simonw

Mini Hovercraft

I challenged myself to build a mini hovercraft in only a few days as part of a new video series!

Aviation Weather Map

Sure, you could look outside for the current weather, but isn't it a lot more fun to build a live-updating map instead?

E-Paper Weather Display

What happens when you combine two-colour e-paper with bad Python? Weather! Well, weather displays.

The RFID Checklist

What do you do when you want to massively over-engineer a solution to forgetting your phone charger?

The Long Drive

Over a thousand miles over some of the loneliest areas of the USA. What's not to love?

Travel Equipment: 2019 Edition

Taking a look at some of the key travelling equipment I've grown to like in the last year of travel.

ASGI 3.0

Upgrading the ASGI spec to simplify it, while keeping backwards compatibility.

A Django Async Roadmap

Taking a look at what it would take to make Django async-native, what it enables, and if we should even do it at all.

Python & Async Simplified

Event loops, coroutines and awaits, oh my!

Channels 2.0

Finally, the promised land is here and Channels 2.0 is released. But how much has changed? And why?

CodeSOD: A Real Switcheroo

By Remy Porter

Much of the stories and code we see here are objectively bad. Many of them are bad when placed into the proper context. Sometimes we're just opinionated. And sometimes, there's just something weird that treads the line between being an abuse of code, and almost being smart. Almost.

Nic was debugging some Curses-based code, and found this "solution" to handling arrow key inputs:

switch (val) { case ERR: // [snip] default: switch (val) { case 65: // [snip] case 66: // [snip] case 67: // [snip] case 68: // [snip] } }

The obvious badness here is the nested switch. Clearly, this isn't necessary. Putting the ERR check at the top makes sense. But burying a second switch under the default clause is pointless and weird. Given that this is C, and switches have weird power, I'm sure there's probably some bad side effect of doing this. Even if there isn't, it isn't needed.

But. It's almost smart. There's one thing that leaps out to me in this code: that there are two distinct paths, one for error-handling, and one for processing input. It's a weird way to accomplish that goal, mind you, but it does accomplish that goal. I'd still never do it, because almost smart is way worse than actually smart (and also way worse than really stupid). But I guess I can sympathize with the developer.

[Advertisement] ProGet’s got you covered with security and access controls on your NuGet feeds. Learn more.

Error'd: An Untimely Revival

By Lyle Seaman

We are all hopeful that there might be some cause for tentative optimism regarding the eventual end of coronavirus pandemic. But horror fan Adam B. has dug up a new side effect that may upend everything.



Valts S. "While adding an API user to an IP camera I whipped out my trusty random password generator, copied, pasted, and got this message." These are depressingly common, aren't they? I need a catchy label for developers who solve their bobby-tables-troubles by content-filtering passwords. Suggestions, anyone?



UI expert Chris N. has diagnosed this little chucklemaker as "Firefox and Windows mixed DPI."



Vestaboard tire-kicker Daniel D. shares a definite WTF (it's obvious, right?) and possibly a 2WTF. "Is that a failsafe, if your country is not include in the dropdown? We will never know," he muses. Or maybe it's a double-secret nation hidden in the Apennines.

belgium, man.


It might not be as restorative as Adam's unearthed effect, earlier, but Peter G. has identified an unorthodox date ordering that might provide at least the illusion of eternal youth. This one probably "worked fine on my machine".



[Advertisement] ProGet’s got you covered with security and access controls on your NuGet feeds. Learn more.

CodeSOD: Secure By Design

By Remy Porter

Many years ago, I worked for a company that mandated that information like user credentials should never be stored "as plain text". It had to be "encoded". One of the internally-developed HR applications interpreted this as "base64 is a kind of encoding", and stored usernames and passwords in base64 encoding.

Steven recently encountered a… similar situation. Specifically, his company upgraded their ERP system, and reports that used to output taxpayer ID numbers now outputs ~201~201~210~203~… or similar values. He checked the data dictionary for the application, and saw that the taxpayer_id field stored "encrypted" values. Clearly, this data isn't really encrypted.

Steven didn't have access to the front-end code that "decrypted" this data. The reports were written in SSRS, which allows Visual Basic to script extensions. So, with an understanding of what taxpayer IDs should look like, Steven was able to "fix" the reports by adding this function:

public function ConvertTaxID(tax_id as string) as string dim splitchar as char = "~" dim splits() as string splits = tax_id.split(splitchar) dim i as integer for i = splits.length-1 to 0 step -1 if isnumeric(splits(i)) then ConvertTaxID = ConvertTaxID & CHR(splits(i) - 125) end if next i end function

We can now understand the "encryption" algorithm by understanding the decryption.

~ acts as a character separator, and each character is stored as its numeric ASCII representation, with a value added to it, which Steven undoes by subtracting the same value. To make this basic shift cypher more "secure", it's also reversed.

Steven adds:

Normally, this software is pretty solid, but this was one case where I was left wondering who got encryption advice from their 6 year old…

Sure, this is certainly an elementary school level encryption algorithm, but could a six year old have reverse engineered it? Of course not! So this is very secure, if your attacker is a six year old.

[Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!

CodeSOD: An Exceptional Warning

By Remy Porter

Pierre inherited a PHP application. The code is pretty standard stuff, for a long-living PHP application which has been touched by many developers with constantly shifting requirements. Which is to say, it's a bit of a mess.

But there's one interesting quirk that shows up in the codebase. At some point, someone working on the project added a kinda stock way they chose to handle exceptions. Future developers saw that, didn't understand it, and copied it to just follow what appeared to be the "standard".

And that's why so many catch blocks look like this:

catch(ZendException $e) { $e = $e // no warning }

Pierre and a few peers spent more time than they should have puzzling over the comment, before they realized that an empty catch block would give you a warning about an "unused variable" in their linter. By setting the variable equal to itself, it got "used".

This is in lieu of, y'know, disabling that warning, or even better- addressing the issue by making sure you don't just blindly swallow exceptions and hope it's not a problem.

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!

CodeSOD: Absolute Mockery

By Remy Porter

At a certain point, it becomes difficult to write a unit test without also being able to provide mocked implementations of some of the code. But mocking well is its own art- it's easy to fall into the trap of writing overly complex mocks, or mocking the wrong piece of functionality, and ending up in situations where your tests end up spending more time testing their mocks than your actual code.

Was Rhonda's predecessor thinking of any of those things when writing code? Were they aware of the challenges of writing useful mocks, of managing dependency injection? Or was this Java solution the best they could come up with:

public class Person { private int age; private String name; public int getAge() { if (Testing.isTest) return 27; else return age; } public String getName() { if (Testing.isTest) return "John Smith"; else return name; } // and so on .. }

Every method was written like this. Every method. Each method contained its own mockery, and in turn, made a mockery of test-driven-development.

[Advertisement] ProGet’s got you covered with security and access controls on your NuGet feeds. Learn more.

CodeSOD: Documentation on Your Contract

By Remy Porter

Josh's company hired a contracting firm to develop an application. This project was initially specced for just a few months of effort, but requirements changed, scope changed, members of the development team changed jobs, new ones needed to be on-boarded. It stretched on for years.

Even through all those changes, though, each new developer on the project followed the same coding standards and architectural principles as the original developers. Unfortunately, those standards were "meh, whatever, it compiled, right?"

So, no, there weren't any tests. No, the code was not particularly readable or maintainable. No, there definitely weren't any comments, at least if you ignore the lines of code that were commented out in big blocks because someone didn't trust source control.

But once the project was finished, the code was given back to Josh's team. "There you are," management said. "You support this now."

Josh and the rest of his team had objections to this. Nothing about the code met their own internal standards for quality, and certainly it wasn't up to the standards specified in the contract.

"Well, yes," management replied, "but we've exhausted the budget."

"Right, but they didn't deliver what the contract was for," the IT team replied.

"Well, yes, but it's a little late to bring that up."

"That's literally your job. We'd fire a developer who handed us this code."

Eventually, management caved on documentation. Things like "code quality" and "robust testing" weren't clearly specified in the contract, and there was too much wiggle room to say, "We robustly tested it, you didn't say automated tests." But documentation was listed in the deliverables, and was quite clearly absent. So management pushed back: "We need documentation." The contractor pushed back in turn: "We need money."

Eventually, Josh's company had to spend more money to get the documentation added to the final product. It was not a trivial sum, as it was a large piece of software, and would take a large number of billable hours to fully document.

This was the result:

/** * Program represents a Program and its attributes. */


/** * Customer represents a Customer and its attributes. */
[Advertisement] ProGet’s got you covered with security and access controls on your NuGet feeds. Learn more.

Error'd: When Words Collide

By Lyle Seaman

Waiting for his wave to collapse, surfer Mike I. harmonizes "Nice try Power BI, but you're not doing quantum computing quite right." Or, does he?



Finn Antti, caught in a hella Catch-22, explains " Apparently I need to install Feedback Hub from Microsoft Store to tell Microsoft that I can't install Feedback Hub from Microsoft Store."



Our old friend Pascal shares "Coupon codes don't work very well when they are URL encoded."



Uninamed pydsigner has a strong meme game. "It's bad enough when your fairly popular meme creation site runs out of storage, but to be unable to serve your pictures as a result? The completely un-obfuscated stacktrace is just insult to the injury. "



But the submission from Brad W. wins this week's prize . Says he: "The vehicle emissions site (linked directly from the state site) isn't handling the increased traffic well, but their error handling is superb. An online code browser allowing for complete examination of the entire stack and surroundings."



[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!

CodeSOD: Saved Changes

By Remy Porter

When you look at bad code, there's a part of your body that reacts to it. You can just feel it, in your spleen. This is code you don't want to maintain. This is code you don't want to see in your code base.

Sometimes, you get that reaction to code, and then you think about the code, and say: "Well, it's not that bad," but your spleen still throbs, because you know if you had to maintain this code, it'd be constant, low-level pain. Maybe you ignore your spleen, because hey, a quick glance, it doesn't seem that bad.

But your spleen knows. A line that seems bad, but mostly harmless, can suddenly unfurl into something far, far nastier.

This example, from Rikki, demonstrates:

private async void AttemptContextChange(bool saveChanges = true) { if (m_Context != null) { if (saveChanges && !SaveChanges()) { // error was already displayed to the user, just stop } else { dataGrid.ItemSource = null; m_Context.Dispose(); } } }

if (saveChanges && !SaveChanges()) is one of those lines that crawls into your spleen and just sits there. My brain tried to say, "oh, this is fine, SaveChanges() probably is just a validation method, and that's why the UI is already up to date, it's just a bad name, it should be CanSaveChanges()" . But if that's true, where does it perform the actual save? Nowhere here. My brain didn't want to see it, but my spleen knew.

If you ignore your spleen and spend a second thinking, it more or less makes sense: saveChanges (the parameter) is a piece of information about this operation- the user would like to save their changes. SaveChanges() the method probably attempts to save the changes, and returns a boolean value if it succeeded.

But wait, returning boolean values isn't how we communicate errors in a language like C#. We can throw exceptions! SaveChanges() should throw an exception if it can't proceed.

Which, speaking of exceptions, we need to think a little bit about the comment: // error was already displayed to the user, just stop.

This comment contains a lot of information about the structure of this program. SaveChanges() attempts to do the save, it catches any exceptions, and then does the UI updates, completely within its own flow. That simple method call conceals a huge amount of spaghetti code.

Sometimes, code doesn't look terrible to your brain, but when you feel its badness in your spleen, listen to it. Spleen-oriented Programming is where you make sure none of the code you have to touch makes your spleen hurt.

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!

News Roundup: Single Point of Fun

By Amit Kooner

Let’s quickly recap the past three news roundups:

  1. Flash’s effect on web user experience
  2. Adding every requirement as a feature in a computer*
  3. A terrible UI that cost $900 million

At first glance it appears that poorly thought-through user experience is my sole fascination. But when the Suez Canal blockage story from March kept my full attention for nearly 10 days, I realized that my real fascination is the unintended consequences of poorly thought-through user experiences. Sometimes the poor user experience is relatively minor enough that a new protocol can be developed (in the case of Flash) or an anxiety-inducing technology gets made (in the case of the Expanscape).

But when all risks of the current user experience aren’t considered, then there are real financial consequences - just like in the case of the Suez Canal where one ship, the Ever Given, blocked 10% of global trade. The fact so much traffic comes through the canal makes it a very important single point of failure. (In case anyone wasn’t paying attention to global shipping news a few weeks ago, a large container ship piloted itself into the side of the canal. The ship is so famous to now have its own Wikipedia page, where it’s been reported that the now-unstuck ship has been fined $916 million - $300 of which is for “loss of reputation”.) So maybe my thesis needs to be amended to: the unintended consequences of poorly thought-through user experiences due to single points of failure. (It’s a mouthful, but it feels right.)

There’s the story of Mizuho Bank, whose ATMs started eating customer cards after some routine data migration work caused country-wide system malfunctions. Single point of failure: The IT team’s risk management process.

There’s the story of Ubiquiti, whose data breach in January was a lot more...relatable after a whistleblower complaint. Single point of failure: Password managers. (They’re not as secure when you leave the front door open.)

The anonymous whistleblower alleges that the statement was written in such a way to imply that the vulnerability was on the third party and that Ubiquiti was impacted by that. Among other things, the whistleblower alleges that the hacker(s) were able to target the system by acquiring privileged credentials from a Ubiquiti employee’s LastPass account.

And then there’s the story of Netflix, who is trying to sever the only remaining way I leech off of my parents. Single point of failure: family.

Citi equity analyst Jason Bazinet said that password sharing costs U.S. streaming companies $25 billion annually in lost revenue, and Netflix owns about 25% of that loss.

Perhaps the final example doesn't seem as critical as the first two, but it's not your Netflix access at stake.

Single points of failure are fascinating to me because, as it gets easy to be complacent about dealing with these vulnerabilities as their value increases and no catastrophes arise. I hope to use this space to keep reacting to, and perhaps even being proactive about, technical and operational single point of failure stories that I found.

Quick hits:

*As an addendum to my story, Nature Magazine published a study that shows that “people are more likely to consider solutions that add features than solutions that remove them, even when removing features is more efficient”.

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!

CodeSOD: Universal Problems

By Remy Porter

Universally Unique Identifiers are a very practical solution to unique IDs. With 10^30 possible values, the odds of having a collision are, well, astronomical. They're fast enough to generate, random enough to be unique, and there are so many of them that- well, they may not be universally unique through all time, but they're certainly unique enough.


Krysk's predecessor isn't so confident.

key = uuid4() if(key in self.unloadQueue): # it probably couldn't possibly collide twice right? # right guys? :D key = uuid4() self.unloadQueue[key] = unloaded

The comments explain the code, but leave me with so many more questions. Did they actually have a collision in the past? Exactly how many entries are they putting in this unloadQueue? The plausible explanation is that the developer responsible was being overly cautious. But… were they?

Krysk writes: "Some code in our production server software. Comments like these are the stuff of nightmares for maintenance programmers."

I don't know about nightmares, but I might lose some sleep puzzling over this.

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!

CodeSOD: Maximum Max

By Remy Porter

Imagine you were browsing a C++ codebase and found a signature in a header file like this:

int max (int a, int b, int c, int d);

Now, what do you think this function does? Would your theories change if I told you that this was just dropped in the header for an otherwise unrelated class file that doesn't actually use the max function?

Let's look at the implementation, supplied by Mariette.

int max (int a, int b, int c, int d) { if (c == d) { // Do nothing.. } if (a >= b) { return a; } else { return b; } }

Now, I have a bit of a reputation of being a ternary hater, but I hate bad ternaries. Every time I write a max function, I write it with a ternary. In that case, it's way more readable, and so while I shouldn't fault the closing if statement in this function, it annoys me. But it's not the WTF anyway.

This max function takes four parameters, but only actually uses two of them. The //Do nothing.. comment is in the code, and that first if statement is there specifically because if it weren't, the compiler would throw warnings about unused parameters.

Those warnings are there for a reason. I suspect someone saw the warning, and contemplated fixing the function, but after seeing the wall of compiler errors generated by changing the function signature, chose this instead. Or maybe they even went so far as to change the behavior, to make it find the max of all four, only to discover that tests failed because there were methods which depended on it only checking the first two parameters.

I'm joking. I assume there weren't any tests. But it did probably crash when someone changed the behavior. Fortunately, no one had used the method expecting it to use all four parameters. Yet.

Mariette confirmed that attempts to fix the function broke many things in the application, so she did the only thing she could do: moved the function into the appropriate implementation files and surrounded it with comments describing its unusual behavior.

[Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!

Error'd: Days of Future Passed

By Lyle Seaman

After reading through so many of your submissions these last few weeks, I'm beginning to notice certain patterns emerging. One of these patterns is that despite the fact that dates are literally as old as time, people seem pathologically prone to bungling them. Surely our readers are already familiar with the notable "Falsehoods Programmers Believe" series of blog posts, but if you happen somehow to have been living under an Internet rock (or a cabbage leaf) for the last few decades, you might start your time travails at Infinite Undo. The examples here are not the most egregious ever (there are better coming later or sooner) but they are today's:

Famished Dug S. peckishly pronounces "It's about time!"


Far luckier Zachary Palmer appears to have found the perfect solution to poor Dug's delayed dinner: "It took the shipping company a little bit to start moving my package, but they made up for it by shipping it faster than the speed of light," says he.


Patient Philip awaits his {ship,prince,processor}: " B&H hitting us with hard truth on when the new line of AMD CPUs will really be available."


While an apparent contemporary of the latest royal Eric R. creakily complains " This website for tracking my continuing education hours should be smart enough not to let me enter a date in the year 21 AD"


But as for His Lateness Himself, royal servant Steve A. has uncovered a scoop fit for Q:


[Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!

CodeSOD: Constantly Counting

By Remy Porter

Steven was working on a temp contract for a government contractor, developing extensions to an ERP system. That ERP system was developed by whatever warm bodies happened to be handy, which meant the last "tech lead" was a junior developer who had no supervision, and before that it was a temp who was only budgeted to spend 2 hours a week on that project.

This meant that it was a great deal of spaghetti code, mashed together with a lot of special-case logic, and attempts to have some sort of organization even if that organization made no sense. Which is why, for example, all of the global constants for the application were required to be in a class Constants.

Of course, when you put a big pile of otherwise unrelated things in one place, you get some surprising results. Like this:

foreach (PurchaseOrder po in poList) { if (String.IsNullOrEmpty(po.PoNumber)) { Constants.NEW_COUNT++; CreatePoInOtherSystem(po); } }

Yes, every time this system passes a purchase order off to another system for processing, the "constant" NEW_COUNT gets incremented. And no, this wasn't the only variable "constant", because before long, the Constants class became the "pile of static variables" class.

[Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!

CodeSOD: The Truth and the Truth

By Remy Porter

When Andy inherited some C# code from a contracting firm, he gave it a quick skim. He saw a bunch of methods with names like IsAvailable or CanPerform…, but he also saw that it was essentially random as to whether or not these methods returned bool or string.

That didn't seem like a good thing, so he started to take a deeper look, and that's when he found this.

public ActionResult EditGroup(Group group) { string fleetSuccess = string.Empty; bool success = false; if(action != null) { fleetSuccess = updateGroup(group); } else { fleetSuccess = Boolean.TrueString; } success = updateExternalGroup(group); fleetSuccess += "&&&" + success; if (fleetSuccess.ToLower().Equals("true&&&true")) { GetActivityDataFromService(group, false); } return Json(fleetSuccess, JsonRequestBehavior.AllowGet); }

So, updateGroup returns a string containing a boolean (at least, we hope it contains a boolean). updateExternalGroup returns an actual boolean. If both of these things are true, than we want to invoke GetActivityDataFromService.

Clearly, the only way to do this comparison is to force everything into being a string, with a &&& jammed in the middle as a spacer. Uh, for readability, I guess? Maybe? I almost suspect someone thought they were inventing their own "and" operator and didn't want it to conflict with & or &&.

Or maybe, maybe their code was read aloud by Jeff Goldblum. "True, and-and-and true!" It's very clear they didn't think about whether or not they should do this.

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!

CodeSOD: A Form of Reuse

By Remy Porter

Writing code that is reusable is an important part of software development. In a way, we're not simply solving the problem at hand, but we're building tools we can use to solve similar problems in the future. Now, that's also a risk: premature abstraction is its own source of WTFs.

Daniel's peer wrote some JavaScript which is used for manipulating form inputs on customer contact forms. You know the sorts of forms: give us your full name, phone number, company name, email, and someone from our team will be in touch. This developer wrote the script, and offered it to clients to enhance their forms. Well, there was one problem: this script would get embedded in customer contact forms, but not all customer contact forms use the same conventions for how they name their fields.

There's an easy solution for that, involving parameterizing the code or adding a configuration step. There's a hard solution, where you build a heuristic that works for most forms. Then there's this solution, which… well…. Let me present the logic for handling just one field type, unredacted or elided.

for(llelementlooper=0; llelementlooper<document.forms[llformlooper2].elements.length; llelementlooper++) { var llelementphone = (document.forms[llformlooper2].elements[llelementlooper].name) if ( llformphone == '' && ((llelementphone=='phone') || (llelementphone=='Phone') || (llelementphone=='phone') || (llelementphone=='mobilephone') || (llelementphone=='PHONE') || (llelementphone=='sPhone') || (llelementphone=='strPhone') || (llelementphone=='Telephone') || (llelementphone=='telephone') || (llelementphone=='tel') || (llelementphone=='si_contact_ex_field6') || (llelementphone=='phonenumber') || (llelementphone=='phone_number') || (llelementphone=='phoneTextBox') || (llelementphone=='PhoneNumber_num_25_1') || (llelementphone=='Telefone') || (llelementphone=='Contact Phone') || (llelementphone=='submitted[row_3][phone]') || (llelementphone=='edit-profile-phone') || (llelementphone=='contactTelephone') || (llelementphone=='f4') || (llelementphone=='Contact-Phone') || (llelementphone=='formItem_239') || (llelementphone=='phone_r') || (llelementphone=='PhoneNo') || (llelementphone=='LeadGen_ContactForm_98494_m0:Phone') || (llelementphone=='telefono') || (llelementphone=='ntelephone') || (llelementphone=='wtelephone') || (llelementphone=='watelephone') || (llelementphone=='form[telefoon]') || (llelementphone=='phone_work') || (llelementphone=='telephone-number') || (llelementphone=='ctl00$HeaderText$ctl00$PhoneText') || (llelementphone=='ctl00$ctl00$cphMain$cphInsideMain$widget1$ctl00$viewBiz$ctl00$phone$textbox') || (llelementphone=='ctl00$ctl00$ContentPlaceHolderBase$ContentPlaceHolderSideMenu$TextBoxPhone') || (llelementphone=='ctl00$SPWebPartManager1$g_c8bd31c3_e338_41df_bdbe_021242ca01c8$ctl01$ctl06$txtTextbox') || (llelementphone=='ctl00$ctl00$ctl00$ContentPlaceHolderDefault$MasterContentPlaceHolder$txtPhone') || (llelementphone=='curftelephone') || (llelementphone=='form[Telephone]') || (llelementphone=='tx_pilmailform_pi1[text][phone]') || (llelementphone=='ctl00$ctl00$templateMainContent$homeBanners$HomeBannerList$ctrLeads$txt_5_1') || (llelementphone=='ac_daytimeNumber') || (llelementphone=='daytime_phone') || (llelementphone=='r4') || (llelementphone=='ctl00$ContentPlaceHolderBody$Phone') || (llelementphone=='Fld10_label') || (llelementphone=='field333') || (llelementphone=='txtMobile') || (llelementphone=='form_nominator_phonenumber') || (llelementphone=='submitted[phone_no]') || (llelementphone=='submitted[phone]') || (llelementphone=='submitted[5]') || (llelementphone=='submitted[telephone_no]') || (llelementphone=='fields[Contact Phone]') || (llelementphone=='cf2_field_5') || (llelementphone=='a23786') || (llelementphone=='rpr_phone') || (llelementphone=='phone-number') || (llelementphone=='txt_homePhone') || (llelementphone=='your-number') || (llelementphone=='Contact_Phone') || (llelementphone=='ctl00$CPH_body$txtContactnumber') || (llelementphone=='profile_telephone') || (llelementphone=='item_meta[90]' && llfrmid==11823) || (llelementphone=='item_meta[181]' && llfrmid==26416) || (llelementphone=='input_4' && llfrmid==21452) || (llelementphone=='EditableTextField100' && llfrmid==13948) || (llelementphone=='EditableTextField205' && llfrmid==13948) || (llelementphone=='EditableTextField100' && llfrmid==13948) || (llelementphone=='EditableTextField166' && llfrmid==13948) || (llelementphone=='EditableTextField104' && llfrmid==13948) || (llelementphone=='cf2_field_4' && llfrmid==23878) || (llelementphone=='input_4' && llfrmid==24017) || (llelementphone=='cf_field_4' && llfrmid==15876) || (llelementphone=='cf5_field_5' && llfrmid==15876) || (llelementphone=='input_9' && llfrmid==17254) || (llelementphone=='input_2' && llfrmid==22954) || (llelementphone=='input_8' && llfrmid==23756) || (llelementphone=='input_3' && llfrmid==18793) || (llelementphone=='input_6' && llfrmid==24811) || (llelementphone=='input_3' && llfrmid==19880) || (llelementphone=='input_6' && llfrmid==19230) || (llelementphone=='input_3' && llfrmid==24747) || (llelementphone=='input_4' && llfrmid==25897) || (llelementphone=='text-481' && llfrmid==14451) || (llelementphone=='Form7111$formField_7576') || (llelementphone=='Form7168$formField_7673') || (llelementphone=='Form7116$formField_7592') || (llelementphone=='Form7150$formField_7645') || (llelementphone=='Form7153$formField_7655') || (llelementphone=='Form7119$formField_7600') || (llelementphone=='Form7123$formField_7608') || (llelementphone=='Form7161$formField_7665') || (llelementphone=='Form7176$formField_7690') || (llelementphone=='Form7172$formField_7681') || (llelementphone=='Form7113$formField_7584') || (llelementphone=='Form7106$formField_7568') || (llelementphone=='Form7111$formField_7576') || (llelementphone=='Form7136$formField_7628') || (llelementphone=='Form6482$formField_7621') || (llelementphone=='Form6548$formField_6988') || (llelementphone=='submitted[business_phone]') || (llelementphone=='tfa_3' && llfrmid==23388) || (llelementphone=='ContentObjectAttribute_ezsurvey_answer_4455_3633') || (llelementphone=='838ae21c-1f95-488f-a511-135a588a50fb_Phone') || (llelementphone=='plc$lt$zoneContent$pageplaceholder$pageplaceholder$lt$zoneRightContent$contentText$BizFormControl1$Bizform1$ctl00$Telephone$txt1st') || (llelementphone=='plc$lt$zoneContent$pageplaceholder$pageplaceholder$lt$zoneRightContent$contentText$BizFormControl1$Bizform1$ctl00$Telephone') || (llelementphone=='ctl00$ctl00$ctl00$ContentPlaceHolderDefault$ContentAreaPlaceholderMain$ctl02$ContactForm_3$TextBoxTelephone') || (llelementphone=='plc$lt$Content2$pageplaceholder1$pageplaceholder1$lt$Content$BizForm$viewBiz$ctl00$Phone_Number') || (llelementphone=='ctl00$ctl00$ContentPlaceHolder1$cphMainContent$C002$tbTelephone') || (llelementphone=='contact$tbPhoneNumber') || (llelementphone=='crMain$ctl00$txtPhone') || (llelementphone=='ctl00$PrimaryContent$tbPhone') || (llelementphone=='ff_nm_phone[]') || (llelementphone=='q5_phoneNumber5[phone]') || (llelementphone=='TechContactPhone') || (llelementphone=='referral_phone_number') || (llelementphone=='field8418998') || (llelementphone=='ctl00$Content$ctl00$txtPhone') || (llelementphone=='ctl00$PlaceHolderMain$ucContactUs$txtPhone') || (llelementphone=='m_field_id_4' && llfrmid==15091) || (llelementphone=='Field7' && llfrmid==23387) || (llelementphone=='input_4' && llfrmid==22578) || (llelementphone=='input_2' && llfrmid==11241) || (llelementphone=='input_7' && llfrmid==23633) || (llelementphone=='input_7' && llfrmid==22114) || (llelementphone=='input_4' && (llformalyzerURL.indexOf('demo') != -1) && llfrmid==17544) || (llelementphone=='input_4' && (llformalyzerURL.indexOf('contact') != -1) && llfrmid==17544) || (llelementphone=='field_4' && llfrmid==24654) || (llelementphone=='input_6' && llfrmid==24782) || (llelementphone=='input_4' && (llformalyzerURL.indexOf('contact-us') != -1) && llfrmid==16794) || (llelementphone=='input_3' && (llformalyzerURL.indexOf('try-and-buy') != -1) && llfrmid==16794) || (llelementphone=='input_4' && (llformalyzerURL.indexOf('contact-us') != -1) && llfrmid==23842) || (llelementphone=='input_4' && llfrmid==25451) || (llelementphone=='input_5' && llfrmid==24911) || (llelementphone=='input_3' && llfrmid==13417) || (llelementphone=='input_4' && llfrmid==23813) || (llelementphone=='input_4' && llfrmid==21483) || (llelementphone=='input_3' && llfrmid==25396) || (llelementphone=='input_3' && llfrmid==16175) || (llelementphone=='input_7' && llfrmid==25797) || (llelementphone=='input_4' && llfrmid==15650) || (llelementphone=='input_3' && llfrmid==22025) || (llelementphone=='input_3' && llfrmid==14534) || (llelementphone=='input_4' && llfrmid==25216) || (llelementphone=='input_5' && llfrmid==22884) || (llelementphone=='input_6' && llfrmid==25783) || (llelementphone=='text-747' && llfrmid==16324) || (llelementphone=='vfb-42' && llfrmid==24468) || (llelementphone=='vfb-33' && llfrmid==24468) || (llelementphone=='item_meta[57]' && llfrmid==25268) || (llelementphone=='item_meta[78]' && llfrmid==25268) || (llelementphone=='item_meta[85]' && llfrmid==25268) || (llelementphone=='item_meta[154]' && llfrmid==25268) || (llelementphone=='item_meta[220]' && llfrmid==25268) || (llelementphone=='item_meta[240]' && llfrmid==25268) || (llelementphone=='item_meta[286]' && llfrmid==25268) || (llelementphone=='fieldname5' && llfrmid==12535) || (llelementphone=='Question12' && llfrmid==24639) || (llelementphone=='ninja_forms_field_4' && llfrmid==19321) || (llelementphone=='EditableTextField' && llfrmid==15064) || (llelementphone=='form_fields[27]' && llfrmid==22688) || (llelementphone=='ctl00$body$phone') || (llelementphone=='ctl00$MainContent$txtPhone') || (llelementphone=='FreeTrialForm$Phone') || (llelementphone=='text-521ada035aa46') || (llelementphone=='C_BusPhone') || (llelementphone=='ctl00$ctl00$templateMainContent$pageContent$ctrLeads$txt_5_1') || (llelementphone=='ctl00$Modules$ctl00$rptFields$ctl06$1204') || (llelementphone=='ctl00$Modules$ctl00$rptFields$ctl06$1320') || (llelementphone=='ctl00$Modules$ctl00$rptFields$ctl07$1242') || (llelementphone=='ctl00$Modules$ctl00$rptFields$ctl07$1202') || (llelementphone=='ctl00$Modules$ctl00$rptFields$ctl08$1242') || (llelementphone=='ctl00$MainColumnPlaceHolder$uxPhone') || (llelementphone=='ctl00$MainContent$DropZoneTop$columnDisplay$ctl04$controlcolumn$ctl00$WidgetHost$WidgetHost_widget$IDPhone') || (llelementphone=='ctl00$ctl05$txtPhone') || (llelementphone=='ctl00$Modules$ctl00$rptFields$ctl07$1219') || (llelementphone=='LeadGen_ContactForm_33872_m419365:Phone') || (llelementphone=='F02220803') || (llelementphone=='h2c0f') || (llelementphone=='your_phone_number') || (llelementphone=='Question7') || (llelementphone=='Question51') || (llelementphone=='Question59') || (llelementphone=='Question35') || (llelementphone=='Question67') || (llelementphone=='field9740823') || (llelementphone=='message[phone]') || (llelementphone=='dnn$ctr1266$ViewKamakuraRegister$Phone') || (llelementphone=='phone1') || (llelementphone=='inf_field_Phone1') || (llelementphone=='hscontact_phone') || (llelementphone=='data[Contact][phone]') || (llelementphone=='fields[Phone]') || (llelementphone=='contact[PhoneNumber]') || (llelementphone=='phonename3') || (llelementphone=='UserPhone') || (llelementphone=='ctl00$MainBody$txtPhoneTech') || (llelementphone=='Telephone1') || (llelementphone=='PhoneNumber') || (llelementphone=='work_phone') || (llelementphone=='jform[contact_telephone]') || (llelementphone=='form[phone]') || (llelementphone=='RequestAQuote1$txtPhone') || (llelementphone=='06_Phone') || (llelementphone=='txtPhone') || (llelementphone=='field_location[und][0][phone]') || (llelementphone=='your-phone') || (llelementphone=='cmsForms_phone') || (llelementphone=='Txt_phonenumber') || (llelementphone=='businessPhone') || (llelementphone=='boxHomePhone') || (llelementphone=='HomePhone') || (llelementphone=='request-phone') || (llelementphone=='user[phone]') || (llelementphone=='DATA[PHONE]') || (llelementphone=='ctl00$ctl00$ctl00$cphContent$cphContent$cphContent$Phone') || (llelementphone=='ctl00$MainBody$Form1$obj11') || (llelementphone=='LeadGen_ContactForm_90888_m1467651:Phone') || (llelementphone=='Users[work]') || (llelementphone=='Question43') || (llelementphone=='aics_phone') || (llelementphone=='form[workphone]') || (llelementphone=='ctl00$ctl00$ContentPlaceHolder1$cphMainContent$C006$tbTelephone') || (llelementphone=='cntnt01fbrp__47') || (llelementphone=='submitted[phone_number]') || (llelementphone=='flipform_phone') || (llelementphone=='txtPhone') || (llelementphone=='ctl00$ContentPlaceHolder2$txtPhnno') || (llelementphone=='ctl00$ctl00$ContentPlaceHolder1$ContentPlaceHolder1$mainContentRegion$BizFormControl1$Bizform1$ctl00$Phone') || (llelementphone=='inpPhone') || (llelementphone=='j_phone') || (llelementphone=='m6e81afbrp__53') || (llelementphone=='item_meta[119]') || (llelementphone=='ctl00$ContentPlaceHolder_Content$dataPhone') || (llelementphone=='ctl00$generalContentPlaceHolder$ctrlContactUs$tbPhone') || (llelementphone=='ctl00$ctl00$ctl00$ContentPlaceHolderDefault$ContentPlaceHolder1$Contact_6$txtPhone') || (llelementphone=='ctl00$MainContent$tel') || (llelementphone=='dynform_element_3') || (llelementphone=='telephone_1') || (llelementphone=='cf_phone') || (llelementphone=='Lead_PrimaryPhone') || (llelementphone=='p_lt_zoneContent_wP_wP_lt_zonePageWidgets_RevolabsMicrosoftDynamicsCRMContactForm_1_txtBusinessPhone') || (llelementphone=='si_contact_ex_field2') || (llelementphone=='dnn$ctr458$XModPro$ctl00$ctl00$ctl00$Telephone') || (llelementphone=='ctl00$ctl06$txtTelephone') || (llelementphone=='dnn$ctr458$XModPro$ctl00$ctl00$ctl00$Telephone') || (llelementphone=='ctl00$ctl00$mainCopy$CPHCenter$ctl00$QuickRegControl_2$TBPhone') || (llelementphone=='LeadGen_ContactForm_38163_m457931:Phone') || (llelementphone=='LeadGen_ContactForm_29909_m371524:Phone') || (llelementphone=='LeadGen_ContactForm_32343_m395611:Phone') || (llelementphone=='LeadGen_ContactForm_31530_m388101:Phone') || (llelementphone=='LeadGen_ContactForm_27072_m349818:Phone') || (llelementphone=='LeadGen_ContactForm_28362_m354522:Phone') || (llelementphone=='LeadGen_ContactForm_28759_m358745:Phone') || (llelementphone=='LeadGen_ContactForm_32343_m395611:Phone') || (llelementphone=='LeadGen_ContactForm_33631_m415978:Phone') || (llelementphone=='LeadGen_ContactForm_30695_m380436:Phone') || (llelementphone=='LeadGen_ContactForm_29958_m372138:Phone') || (llelementphone=='LeadGen_ContactForm_31471_m387422:Phone') || (llelementphone=='LeadGen_ContactForm_32514_m397613:Phone') || (llelementphone=='LeadGen_ContactForm_29152_m362772:Phone') || (llelementphone=='LeadGen_ContactForm_32540_m397908:Phone') || (llelementphone=='pNumber') || (llelementphone=='organizer_phone') || (llelementphone=='ctl00$PlaceHolderMain$TrialDownloadForm$Phone') || (llelementphone=='ContactSubmission.Phone.Value') || (llelementphone=='ctl00$body$txtPhone') || (llelementphone=='p$lt$ctl03$pageplaceholder$p$lt$zoneCentre$editabletext$ucEditableText$widget1$ctl00$viewBiz$ctl00$Telephone$textbox') || (llelementphone=='ctl01_ctl00_pbForm1_ctl_phone_61f3') || (llelementphone=='ctl01$ctl00$ContentPlaceHolder1$ctl15$Phone') || (llelementphone=='p$lt$zoneContent$pageplaceholder$p$lt$zoneRightContent$contentText$ucEditableText$BizFormControl1$Bizform1$ctl00$Telephone$textbox') || (llelementphone=='ctl00$ctl00$ContentPlaceHolder$ContentPlaceHolder$ctl00$fPhone') || (llelementphone=='pagecolumns_0$form_B502CC1EC1644B38B722523526D45F36$field_6BCFC01A782747DF8E785B5533850EEB') || (llelementphone=='cf3_field_10') || (llelementphone=='r_phone') || (llelementphone=='c_phone') || (llelementphone=='cf-1[]') || (llelementphone=='frm_phone') || (llelementphone=='Patient_Phone_Number') || (llelementphone=='ctl00$PageContent$ctl00$txtPhone') || (llelementphone=='dnn$ctr398$FormMaster$ctl_6e49bedd138a4684a66b62dcb1a34658') || (llelementphone=='id_tel') || (llelementphone=='field_contact_tel[und][0][value]') || (llelementphone=='Phone:') || (llelementphone=='ContactPhone') || (llelementphone=='submitted[telephone]') || (llelementphone=='ctl00$ContentPlaceHolder1$ctl04$txtPhone') || (llelementphone=='ctl00$ContentPlaceHolder_pageContent$contact_phone') || (llelementphone=='264') || (llelementphone=='form_phone_number') || (llelementphone=='field8418998') || (llelementphone=='phoneTBox') || (llelementphone=='pagecontent_1$content_0$contentbottom_0$txtPhone') || (llelementphone=='application_0$PhoneTextBox') || (llelementphone=='submitted[phone_work]') || (llelementphone=='data[Lead][phone]') || (llelementphone=='a4475-telephone') || (llelementphone=='ctl00$Form$txtPhoneNumber') || (llelementphone=='signup_form_data[Phone]') || (llelementphone=='WorkPhone') || (llelementphone=='lldPhone') || (llelementphone=='web_form_1[field_102]value') || (llelementphone=='LeadGen_ContactForm_114694_m1832700:Phone') || (llelementphone=='phoneSalesForm') || (llelementphone=='fund_phone') || (llelementphone=='Phonepi_Phone') || (llelementphone=='field343') || (llelementphone=='cntnt01fbrp__48') || (llelementphone=='contact[phone]') || (llelementphone=='ctl00_ContentPlaceHolder1_ctl01_contactTelephoneBox_text') || (llelementphone=='ctl01$ctl00$ContentPlaceHolder1$ctl29$Phone') || (llelementphone=='plc$lt$content$pageplaceholder$pageplaceholder$lt$bodyColumnZone$LogilityContactUs$txtWorkPhone') || (llelementphone=='ctl00$ctl00$ctl00$cphBody$cphMain$cphMain$FormBuilder1$FormBuilderListView$ctrl4$FieldControl_Telephone') || (llelementphone=='ctl00$ctl00$ctl00$ContentPlaceHolderDefault$cp_content$ctl02$RenderForm_1$rpFieldsets$ctl00$rpFields$ctl04$126d33a3_9f7f_4583_8c94_5820d58fc030') || (llelementphone=='tx_powermail_pi1[uid1266]') || (llelementphone=='si_contact_ex_field3') || (llelementphone=='inc_contact1$txtPhone') || (llelementphone=='item2_tel_1') || (llelementphone=='LeadGen_ContactForm_15766_m0:Phone') || (llelementphone=='ctl00$ContentPlaceHolder1$txtPhone') || (llelementphone=='Default$Content$FormViewer$FieldsRepeater$ctl04$ctl00$ViewTextBox') || (llelementphone=='Default$Content$FormViewer$FieldsRepeater$ctl04$ctl00$ViewTextBox') || (llelementphone=='ctl00$SecondaryPageContent$C005$ctl00$ctl00$C002$ctl00$ctl00$textBox_write') || (llelementphone=='_u216318653597056311') || (llelementphone=='_u630018292785751084') || (llelementphone=='data[Contact][office_phone]') || (llelementphone=='ctl00$ctl00$cphMainContent$Content$txtPhone') || (llelementphone=='ctl00$ContentPlaceHolder1$txtTel') || (llelementphone=='item_5') || (llelementphone=='ques_21432') || (llelementphone=='phoneNum') || (llelementphone=='CONTACT_PHONE') || (llelementphone=='ff_nm_cf_phonetext[]') || (llelementphone=='WorkPhone') ) ) { llformphone = (document.forms[llformlooper2].elements[llelementlooper].value); if (llfrmid == debugid ) {alert('llformphone:'+llformphone+' llemailfound:'+llemailfound);} }

If the name property of the form element is equal to any one of the many many many items in this list, we can then extract the value and stuff it into a variable. And, since this will almost certainly break all the time, it's got a convenient "set the debugid and I'll spam alerts as I search the form".

Repeat this for every other field. It ends up being almost 2,000 lines of code, just to select the correct fields out of the forms.

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!

Animals, an Amelanchier and the wider world

By [email protected] (Jon North)

This weekend the French Covid restrictions will start, cautiously, to be eased - from Monday the 10 km radius for our journeys within France will be lifted though the evening curfew will only be lifted bit by bit.  That affects me taking the dogs for their late evening walk (for which I must carry an attestation until mid May - our shopping lists are written on old attestations for the moment!)  

Our lives have not varied much, but this week we bought a new garden tree/shrub/bush from a newly-discovered nursery not far from here.  We wondered if Amelanchiers, which we had in English gardens, would survive our hotter, drier climate, but were reassured by the man in charge of our excellent local arboretum and by the nurseryman., so our new little bush is proudly in the middle of the lawn near the tortoise enclosure and, lo, just as Mary was planting it the tortoise emerged muddily from her hibernation!  A week or so later than last year, but it is really good to have her back in view.

article about children reading more in lockdown in the Guardian offered me a moment to take notice of the everyday, and to be thankful that my mum encouraged me to read and use the public library. Reading is invaluable, and makes little noise in a time when many media are incredibly noisy. But laughing out loud was, I recall, still risky in my childhood: reading and enjoying Just William books under the bedclothes caused me occasional parental censure, especially when I disturbed the Quaker study groups downstairs! I try to ignore extraneous noise, but it drives me bonkers when someone's Facebook post unexpectedly bursts into speech or music - better to invite sounds in rather than have them blast out without warning (occasionally even waking a sleeping partner at night).

As we continue to mourn the lost opportunity to travel to Armenia again (it would have been a year ago) we take an interest in the terrible difficulties of the people in that tiny country for the sake of our friends there, and one of many good things coming out of the new USA last week was the announcement that President Biden formally recognises the  Armenian genocide.  It is incredible that (kowtowing to Turkey) they have been so slow to acknowledge such a blatant historic human rights abuse.

And among the fairly petty concerns people in the UK and Europe worry about, the appalling situation in countries further away, hooked into hard-line political agendas and too poor to afford the vaccines and treatments, even adequate health services, to cope with a flood of infections.  The people of India are in a profound crisis, somehow in scale with the terrible disasters and episodes of violence in the country’s history. European countries, and the US, have dithered and made false steps - I think we have to remember how fortunate we are. But political dogma and rigidity will always cap ineptitude.

Not my photo, but a beautiful shot of a vine near Pic Saint Loup which survived the recent frosts
Back to plants.  My normal shots of plants are pretty, but these have a whole different focus, and great importance for the future if you’re a wine lover. Looks rather more demanding than your average day in the garden!

At the St Christol Domaine de Coste Moynier

I have good memories of Glendurgan in Cornwall so am delighted to see it at the head of this article, as I am to celebrate spring flowers and blossom everywhere. But this campaign seems to have created a new kind of tree, a ‘blossom tree’. Not sure what that is - most blossom is a transient pleasure on the way to some fruit or other, or in cases like our beautiful grenadier, not due to flower for a month or more yet, categorised as flowering or ornamental trees or shrubs. Ah well, living language...

Podcasts are now a frequent source of information and entertainment for us, and one from the Guardian caught my attention last week - a real-life clown.  Have a listen.  Police spies seem to have been on the radar for ever. I read the book Undercover at least 10 years ago, and it seems to be trickling throughthe judicial process just now.

It turns out a lot of my preoccupations are UK-related - somehow they are more spicy than the French ones I can disentangle!  May day, the fête du travail, is tomorrow, and it has just been announced that the traditional lilies of the valley will be able to be sold, though there are Covid restrictions on roadside sales and it turns out that some of the flowers on sale beside the road are stolen in the first place!

More on words and language

By [email protected] (Jon North)

Our house with its tall conifer - a landmark for those lost around the neighbourhood!

I love maps, but not always on the internet - atlases and other printed maps often seem more satisfactory although less searchable.   You can see from these two maps from the Petit Larousse (too heavy to hold for long, so useful transferred to a screen) that Lunel is right at the eastern edge of the Hérault département.  So many places in the Hérault are actually a long way from us, and many of our contacts and meeting places when we can travel are in the Gard which wraps itself round the right hand side of the Hérault.  Most départements in France are named for rivers - the Gard is unusual in modifying the river name (Gardon), but in any case many rivers spend a lot of their lengths in other départements.  The river closest to us is the Vidourle which is notorious for its floods, every 25 years or so, which forms the eastern border of the Hérault with the Gard.

A scene in our garden some years ago for a lunch after our Tuesday French conversation group. The garden has not changed much but even before the pandemic the personnel has, several of these people have departed from our group in various ways, and there's little chance of gatherings like this again in the near future.

Our life here revolves round the non-stop process of learning French.  After nearly 15 years we've made a lot of progress, but it is still a minefield and equally a source of constant fascination.  There are two dimensions - one, the many-faceted business of written French (easier because you can usually go away and look it up) and spoken French which can vary both in speed (you discover that English people too seem to rattle away too fast) and regional accent, to say nothing of the difference between slang, jargon, technical vocabulary and formal statements.  We have found the Government press conferences models of clarity (even when the news is unwelcome) as are magazine tv shows like the excellent travel magazine programme  Des racines et des ailes, but catching chatter among friends is often difficult, as if speaking and hearing on the phone, especially when you don't know in advance the topic of the call.  Sadly we have all too little friendly chatter at the moment.

The first poppies a week or two ago

The issue of sexist language is very topical here now.  France is some way behind the English-speaking world in this, partly because of the additional complexity that all nouns have gender, and historically because of the Académie française which has for centuries laid down the law about what is correct and incorrect.  Now inclusive names of the 'man includes woman' kind are much less common - names of professions (professeuse as well as professeur, for instance) have increasingly been feminised since the 1980s and mor recently there have been official circulars defining how inclusive pronouns like 'he or she' should be written - I have always tended to use / , but one hotly debated method here is the use of the point médian, a kind of decimal point when for instance masculine and feminine endings are indicated, for example professeu·r·se.  As with much to do with language in French, this gets rather complicated (just typing the thing is complicated enough!)

Such cultural debates are often long and heated - a supplement in Midi Libre was headed to "cette écriture qui divise tant" and referred to a veritable (ardente) battle of Hernani - what on earth is that?  Well, it's a reference to a play Hernani by Victor Hugo (the name is from a Spanish town).  It became notorious for the demonstrations at its first performance between the romantics (Hugo had Berlioz and Théophile Gautier, poet of Les nuits d'été' among his champions) and classicists who saw the play as a direct attack on their values.  Verdi also wrote an opera, Ernani, apparently.  So passions were roused then, and people today recognise the reference nowadays well enough for it to be used in a local newspaper.

Clearly understanding culture, popular or not, is a complicated process.  Meanwhile, we listen to frequen official press conferences on Covid as much to hear the very clear language ministers and officials use as to keep up with the latest information.  Restrictions in movement are to be eased, and in any case we have now both been vaccinated, but our lives are quiet and the chance of travelling to England is very small just now, so sadly our family and friends there remain at the end of phones and video calls.  This week the physiotherapist, Emma, who has helped me through over 3 months' healing of broken arm is leaving for her next placement, working with children in the hills somewhere.  I'll miss her, but of course the team practice she works in will provide me with a replacement.  And April continues to bring mostly beautiful weather.

Roses starting to show in the front yard

Solemn news, and, What's in a name?

By [email protected] (Jon North)

National figureheads aged all but 100 do not die often, so the passing of Prince Philip deserves more than a mention.  ‘Figurehead’ is an apt description for this naval man whose function was mainly ornamental. 

These days my day starts early, since Elvire the dog needs letting out.  This Saturday the usual selection on Radio 3 (and I’m guessing all over the BBC) was replaced with nearly continuous music which is not disagreeable.  It leaves space for reflection - I’m not a royalist but I think the mood was right at a time of national mourning following the death of Prince Philip at a venerable age.  For my friends who already think there is too much fuss about posh people in the media, I find the response of wall-to-wall music ideal.  And despite the increasing rarity of chimney sweeps, I recall Shakespeare’s verse

Thou thy worldly task hast done,
Home art gone, and ta’en thy wages:
Golden lads and girls all must,
As chimney-sweepers, come to dust.



Here are the 20 top names (boys and girls, 40 in all) registered in Montpellier over the last 20 years.

Local expats (people like me, but I don't share their views!)) commented that the names were ‘not very French’.  But two things strike me – the people commenting are probably much older than the people (many being parents of the new babies) who chose the names, even if not as old as me.  One comment expressed surprise  that Catholic names do not figure more prominently – but France is a secular state and prides itself on its republican values, even though saints’ days still figure on all published diaries and calendars, and many public holidays are still church hangovers. 

 So yes, we live in a very contradictory country!  Second, saying things are not very French is a bit odd, since they are by definition French choices. I find the absence of more north African names a little surprising given the significant proportion of families of north African  origin in the area.

Among the podcasts we’ve listened to recently is Tim Harford's Cautionary Tales.  These are really good at adding a dose of reality and realism to the mad hype of modern life.  As well as reality checks on the pandemic, his subjects range from the Charge of the Light Brigade to Harold Shipman, and art forgery, and much, much more.

Our weekend has also been enlivened by watching two Rugby League Challenge Cup matches - the only French representatives, Catalan Dragons, gave a very spirited performance to win their tie against Wakefield Trinity.  Rugby here is almost all Union rather than the rugby à treize we were watching, but the Catalan team is more or less local to us, and we've always enjoyed watching this form of the game.

Meanwhile the news here has also been full of  grim news of frozen vines and fruit trees - lots of growers have lost their crop this year thanks to at least one night of temperatures as low as -8°C.  Not uncommon further north but pretty unusual here, and thus less likely to be insured.

Vines bursting into leaf near Luc's garden in Aigues Mortes, befiore the very cold weather  

More hopeful signs of spring with our latest dwarf irises

Spanish winter

By Jon North ([email protected])


My encounters with Spanish wines go back to my teens, when my father returned from holiday in Spain (with my mum of course, but I’m not sure if Pam and/or Tom went too) lugging on the train 12 bottles of Rioja.  We have carried many bottles in our car over the years, but on the train with all the suitcases too…  Only my Dad!

More recently it all started in the autumn when Mary sighed that she missed Fino sherry, and we both recalled our love of PX (short for Pedro Ximenes, a grape variety used for sweet fortified wines in southern Spain, and so used in blends with drier wines to make the ubiquitous 'cream sherries' well-known in the UK).  We first encountered 100% PX 20 years ago at Rick Stein’s Padstow restaurant when the dessert was simply vanilla ice cream with a schooner of PX poured over.  

So I hunted idly to try and satisfy Mary’s craving and came across the Barcelona wine merchant Decántalo.  They specialise in Spanish wines but a quick scan shows they have plenty from other countries too – it seems to me to be as reliable and well-organised as the UK Wine Society with the advantage for us that it is just down the road, not in what we have now sadly to think of as a foreign country!

On top of this, this wine merchant packs things in super-safe cartons – we've had one or two disasters with breakages in the past, but bottles really have a hard time getting broken in these deliveries.  We began before Christmas with Tio Pepe Palomino Fino and Gonzalez Byass Nectar PX, plus a couple of  unfortified wines.  One of the first of these we tried was Protos Clarete, a light red or dark pink from Ribera de Duero, an area now quite well-known, top centre/north Spain a bit SW of Rioja.  This reminds me of the light red clairet which is produced in Bordeaux and whose name of course links to the red clarets from there we all know and love.  But the dark pink, or light red, style is distinct there as it turns out to be in Spain.

We also tried 3 Muga Riojas (red, white and rosé), all of them very good – a friend who knows this whole field well says white Rioja is hard to find, and remembering Dad’s samples I was really interested in this – Oz Clarke says white Rioja is a bit of an afterthought, but we have really liked this Muga, so still have some bottles to enjoy!   We then spotted a Christmas offer of 18 different wines, all red,

·         6 from Ribera del Duero (see above – we have already enjoyed these, wines and makers included Juegabolos, Malleolus, Corimbo I, Pago de los Capellanes Reserva, Pícaro del Águila and Astrales);

·         6  from Priorat(wines and makers include Ferrer Bobet Vinyes Velles, Salanques, Laurel, Mas d'en Compte Negre, Planetes de Nin, and Coma Vella) – we are halfway through these and have been so impressed by the  Ferrer Bobet that we have spent a small fortune on some of these bottles to lay down for the next few years;

·         and 6 other reds, 3 from Montsant: (Fredi Torres Lectores Vini Montsant; Sindicat La Figuera; and Orto - we shared the  Figuera wine with friends yesterday and were very impressed), another Rioja: (Diez-Caballero Crianza 2018) and two from further south (Jumilla - SE Spain N of Murcia: Casa Castillo; and from Valencia: Parotet Vermell)

In the huge country of Spain and its many contrasting wine areas, I was surprised to find that two of these 3 appellations are tucked into a tiny hilly area SW of Barcelona: 

Priorat,  which according to Hugh Johnson's pocket guide produces some of Spains finest wines. It's named after a former monastery tucked under craggy cliffs. The key is the slate soil – known as llicorella. 

Montsant, tucked in around Priorat 

The thing to look forward to is a trip to these areas of Spain, relatively close to us although the travel complexities of travel with Covid, national restrictions and of course Brexit remain to be discovered! 


Springing forward

By [email protected] (Jon North)

This week's blog is mostly about health.  The good news this week is that my doctor has fixed Covid vaccinations for both of us today, which is a relief.  Of course, the rapidity with which vaccines has been developed and made safely available is pretty extraordinary.  It's interesting how many of the fears about vaccine denial have faded, though there is still negative babble at the fringes - I think most people see it as the only possible route back to 'normality', though there are hundreds of questions about what that should be or how things may change.

But the unholy tangle of new strains being discovered, problems about bulk manufacture and distribution of vaccines, political mud-slinging and bureaucratic delays, justifiable or unjustifiable caution about safety and side-effects, all of these created an unsettled atmosphere in ordinary people who worry about jobs as well as getting ill, with more time than usual to ponder things.  So other quite trivial things - for example the jamming of the automatic ignition on our gas hob, issuing a stream of crackling sparks for 24 hours - add yet more tension, and it took longer than it should have done to discover the off switch!

Hopeful buds on a drought-hit lemon tree, recovering this spring

I've written before about my physiotherapy, mostly a very positive experience this time (previous sessions of treatment for knee and sciatica were far less useful).  But I keep on realising how much better things will be as and when I can take responsibility for my own exercise and recovery.  When I was in a clinic after my knee operation I spent one hour out of 24 actually being treated; now I have a good half hour's intensive massage, and 20 minutes a session wrapped in a kind of cold blanket where icy water is pumped through.  And above all I have exercise machines at home which I can use when it suits me.  I've kept up the static bike throughout, and now I'm about to experiment gently with the cross-trainer whose arm movements seem to fit into what is allowed, applied gently!

Dogs meanwhile provide a structure and timetable to our days.  I've been able to resume early morning and late evening short walks, which takes pressure off Mary.  They have some digestive and bladder problems which need vet checkups.  But although these vet sessions are expensive, they are also reassuring, and the dogs are OK, and continue to provide us with enjoyment.

Marching on, and on

By [email protected] (Jon North)


Tom with me and sister Pam

13 March would have been my brother Tom's 70th birthday. He and his family are very much in our minds - departed far too soon. 

Meanwhile 12 March was another milestone in progressing our established status as French residents. That morning Mary and I surrendered our temporary EU cartes de séjour at the préfecture; our new cards as permanent foreign residents should arrive by post in a few weeks. Despite gripes elsewhere I have always respected French bureaucracy - if you follow the instructions you get the right results. The woman who dealt with our dossiers was very friendly and the whole rendez-vous more or less on time. We even had time, in a strangely quiet Montpellier, to buy some excellent kitchen gear before heading home to the dogs by midday. A good morning’s work.

There was some other welcome news for we Britons living abroad this week, or at least a promising development.  Buried in the details of the UK budget was news that the government plans to scrap the rule that bars those who have lived abroad for more than 15 years (as we shall soon have done) from voting in UK elections "the government is providing an additional £2.5m to remove the limit preventing British citizens who live overseas from voting after 15 years.”  So we shall be able to continue to vote in the West Derbyshire constituency where we lived before leaving the country.  

One story in the local paper caught my eye - of the revival of a traditional industry making fabric in Nîmes.  The blue denim, named ‘de Nîmes’ by the Americans who popularised it for jeans, is now going to be manufactured by a family firm in this area.  Among other local news, another story this month of wartime good deeds - A Jewish man has bequeathed a sizeable chunk of his fortune to the French village whose residents hid him and his family during the Second World War, despite the risk to their own lives. Eric Schwam, who died aged 90 on Christmas Day, is believed to have left s2m to the remote mountain village of Le Chambon-sur-Lignon, which gave shelter to 3,500 Jews during the war. Schwam and his family arrived in 1943 and stayed until 1950. In his will, he said the gift was an expression of his gratitude, and suggested it be spent on youth services.  We have friends whose family shared in the efforts to rescue Jewish people in this part of France during the war -  this strikes many chords with me.

This cartoon is for our daughter-in-law and many other friends involved in theatre and music. The Paris Odéon-Théâtre de l'Europe has been occupied by protestors, with Union support demanding reopening of theatres and extension of government support to the so-called intermittents who would normally be working there. The Minister Roselyne Bachelot has intervened but has not apparently been able to reassure all protestors. 

Sport has been a frequent interest for us as always.  I'm still reeling a little from the turbulent reversal of fortunes in the final stage of the Paris-Nice cycle race. Having led for most of the week, Primoz Roglič ended up 16th overall with ripped clothing and having dislocated a shoulder, and the winner in the end was Max Schachmann who also won last year. Riveting watching all the same.  Meanwhile the 6-nations rugby has caught fire despite the absence of spectators with a fizzing match between France and England and an absorbing on between Scotland and Ireland.  Meanwhile the woes of 'my' football team Liverpool continue, but it is after all only sport.  Another picture to end with.

Spring into March

By [email protected] (Jon North)

our house (on the right beyond the car park) and street a couple of weeks ago

2 months after I broke my arm, it is well on the way to healing.  If you happened to read this blog some years ago when I had a knee replacement you’ll recall that I had a poor view of physiotherapy – some essential exercises to get me back on track but too much time left hitched to electrodes.  This time, it has been much better – an enthusiastic team of young therapists who know how to help reduce swelling and prevent inappropriate movements.  But in any case I have a tongue in my head, and I am working out (even in French) what questions to ask and how to time them!  The physiotherapy team has two cramped rooms and too many people – therapists, students and patients – so we cannot expect miracles.  Even though everyone wears masks and washes hands regularly, social distancing is downright impossible – the therapists have to change to and from working clothes in corners, and the small collection of rubber balls, poles and cool jackets in constant use cannot possibly be sterilised well enough.  Anyway, on the whole I count my blessings and enjoy yet more sunshine as spring arrives.

So to other things that have caught my attention lately.  Vegetarianism has gained ground here in France since we started to come regularly in the 90s, and like many cases in the past, ‘veggie’ apparently includes fish in this report. But it seems always to raise heat and fury. 50 years ago a friend came for a meal and exclaimed she had ‘never eaten vegetarian’, and I thought then as I do still that this was odd - in any case, we love our vegetables in this southern French horticultural paradise, and while I like meat and fish, I am very happy to eat vegetables   Our favourite local greengrocers' reopened this week and I was able to go on my first solo shopping walk to find things like lovely fresh salads.

A fascinating chalky article here linking three things important to me - the chalk landscape of the Chilterns where I grew up, sparkling wine from Sussex closely linked to Champagne, and the continuity between southern England and northern France.

From Apollo Magazine : “Dolly Parton, the one public figure almost everyone would agree deserves a statue, has urged lawmakers in her home state of Tennessee to withdraw a bill to erect a statue of her in the grounds of the State Capitol building in Nashville. ‘Given all that is going on in the world,’ Parton tweeted, ‘I don’t think putting me on a pedestal is appropriate at this time.’ Which only makes her more deserving, of course.”

One of the constant struggles we have to improve our French is knowing about singular and plural. We have long known that trousers are singular (un pantalon), and we as a family also (les North rather than the Norths), but I realised today that the opposite can apply - ‘off the beaten track’ is ‘hors des sentiers battus’ 

Our minds, M’s especially, are often on Fair Isle knitting this year, so we were fascinated to find fashionable in yet another catalogue. The slimmer model’s ‘tank’ retails at nearly £150, but lacks the loving care that went into mine! Thanks again M xx

There are voies vertes, foot-and cycle paths made from old railways all around us, and the upgrade of the canal path from here to the coast at La Grande Motte is due to be completed shortly - I'm looking forward to riding it when I get back on my bike soon.   Of course we had the High Peak Trail near our old home in Wirksworth, where I'd sometimes cycle with dog Ruff running alongside.   There are also plenty of urban cycleways too - in Paris we have walked more than once on the Promenade Plantée SE of the city centre - so I was fascinated to see this article about another in an area of London . Old railways deserve a second life.

after lunch




By [email protected] (Jon North)

The first sign of spring, our neighbours' almond tree in bloom

I read last week that Amazon was running out of cardboard.  Not really a surprise to us, since the last delivery we had from them was a smallish item in a huge box padded with screwed-up paper.  I don't really make much apology for using them - we are in a vulnerable group better avoiding busy shopping centres even were they open.  Besides, lots of our Amazon purchases come from small suppliers only via Amazon, and often we have made links with the original merchant and bought direct from them the next time.  But Mr Bezos and his like are certainly getting rich on the bonanza of online purchases - I saw today that he is saving his pennies to fund a space project!

Macron is doing his best to seem green - not the first politician to jump on this bandwaggon - and this cartoon suggests a citizen's panel he set up has talked a lot to come up with very little.  But as new hope appears following the transition from Trump to Biden, I guess we are all hoping there will be some positive movement on climate change.

more signs of spring this week - cyclamen, daffodils and bay flowers in the garden

Meanwhile back in Lunel, like most French communes we have had various recycling options since the beginning of the millennium or before, but for the past year or two we get a small amount of local tax relief if we throw away less general rubbish (measured per collection by a microchip in the bin) and we have just heard that from next month all our plastic waste will be collected in the yellow bins we've always used for card, tins and plastic bottles.  This is a big change for us - hitherto we have always avoided adding it to the general rubbish by taking it to one of the local supermarkets which took its share of responsibility by collecting back its packaging.  But now, no more storing separately and carting round bags of used packaging - all simply added to the yellow recycling bin.  Cynics with more energy than I have might try and check what happens to it back at the depot, but I am just pleased some efforts are being made.  Glass and paper are also collected, separately and in different ways.

Over 40 years ago I was in charge of Friends House in London, and one of our perennial worries was whether the waste paper man would turn up to collect the paper we  generated in quantity.  It depended then as I expect it still does on the market for scrap paper, but I think things are a little more secure now - in the 70s, when the paper price dropped we had problems, sometimes for months on end.

Two 'new' expressions - obvious but suddenly part of everyday conversation.  First unboxing, simply the act of taking a new purchase out of its packaging, but now acquiring a kind of mystique as people start making unboxing videos.  Over the years I've suddenly found it really useful to look at videos about 'how to install' this or that, most recently a new counterbalance system for the dishwasher door when it broke, but apparently now it gives people a kind of kick to watch the process.  The most amusing things recently have been receiving large parcels which turn out to have tiny things inside - perhaps indicating that Amazon had run out of smaller boxes!

Then there is the whole concept of the podcast.  I was puzzled by this - you see a random title and lo you have a whole series of things to listen to.  Not always polished - you have to put up with noises off, and sometimes ums and ers.  And I thought they might be hard to find, but as soon as you look you trip over them everywhere.  So far this month I have tried two wine podcasts, another one called The Prime Ministers by Iain Dale which is serious stuff.  There's one following the publication The Week which we enjoy (it turns out the journalists are less good at talking about their chosen subjects than writing about them),  and two by the New Scientist which are excellent if slightly prone to publicise their own other stuff.  

The one Mary and I are beginning to enjoy together is the History of English podcast by a very well-organised American, Kevin Stroud, who is apparently a lawyer by trade but who knows is subject inside out and is exploring the history of the language thoroughly at least once a week for over 10 years after the first podcast.  I started looking for something to listen to while I do my 40 minutes' pedalling on the static bike each morning, but the range of things I can listen to now would keep me going day and night for ever!

As cycling is ever more popular in France there are now machines to
count the traffic, which may be confused by tandems!!

Happy Valentine's day

By [email protected] (Jon North)

This comes just before Valentine's day, le Saint Valentin in France, and a  bittersweet day for many, including those in our family, who have lost people dear to them over the past year or so, or even longer ago.  Remembering people dear to us is important though no substitute for their presence, but of course  the current pandemic crisis brings it closer to reality for many, not just from death but from forced separation because of travel restrictions or quarantine.  So this is in memory of many like my brother Tom who are no longer with us, and also thinking of those friends separated by travel restrictions, or living alone and isolated by circumstances, or bereaved and still missing a dear companion.  Even if we find the current restrictions trying, or dull, we (Mary and I) are much more fortunate than many in having at least one another's company.  

On top of that I personally am lucky and grateful to be being well looked after by M as well as by health services as my recovery from a broken arm continues slowly but surely.  I am now back in the land of regular physiotherapy, 3 times a week at the local hospital where I had my operation.  It takes place in two rather cramped rooms (not at all good for social distancing) with a team of bright young therapists who manipulate, massage and apply ice jackets in a slightly chaotic atmosphere.  I think I'll be back and forth there for several weeks.  

We have both been reading a lot in the past few weeks, and while Mary has returned to French books around the 19th century Goncourt brothers, mine has lately been about epidemics.  One book, Pale Rider: The Spanish Flu of 1918 and How it Changed the World by Laura Spinney, is especially apt as we've just passed the centenary of that pandemic, which killed an uncertain but certainly huge number of people.  There are strong and obvious parallels with today's situation and despite advances in scientific knowledge superstition, fear and gut reactions all too often rule the roost.  In fact, 100 years on, you could say that the influence of education and rational choices on people's behaviour is still limited.  Spinney wrote, just before Covid, "What the Spanish flu taught us, in essence, is that another flu pandemic is inevitable, but whether it kills 10 million or 100 million will be determined by the world into which it emerges."  In our case it was a world of Trump and Johnson so many chances to minimise damage have been missed.  

The rest of this post is in pictures and captions. 

Sand appeared in our weather forecast this week, though not as much as feared - I think the heavy rain washed a lot of it away!


People who run or work in restaurants are in a dire way with long and repeated closures - there are some govt bail-outs but many people lose their jobs all the same, and rats have a field day apparently in closed premises.

Ben Jennings summarised well all the misfires in UK govt policy over the past year - French and European problems are mostly about getting enough vaccine soon enough

and back home, we have just had a cosy weekend in front of the rugby as the 6 Nations tournament begins.  France are looking pretty good while the perennial doubts about whether Italy are good enough to take part resurface 

Into February

By [email protected] (Jon North)

This blog is  mostly about inequality and prejudice.  Holocaust Day has just passed.  My life has been studded with important relationships, family and friends, with extraordinary Jewish people, so (and especially at a time when denial is in the air) it is a powerful moment.  I was also privileged to do some work recognising the forgotten gay victims of the Holocaust with the National Holocaust Centre in Notts before I retired, so there are many links here for me.  Then, this weekend Marcus Rashford has been inexcusably racially abused (by so-called football fans)  And now LGBTQ+ month is starting.

So it was a telling coincidence that I had just finished reading House of Glass: the story and secrets of a 20th century Jewish family, by Hadley Freeman.  Reading is slow going just now when other tasks take twice as long one-handed, but this was a gripping book.   It had many personal resonances to people who have been important and still are to me, with links to Europe and the USA.  Hadley Freeman is a talented journalist who makes frequent connections between the biographies and story she is telling and the social, political and cultural settings her family inhabited across mid-century Poland and linking to our current life in France, with some moments typical of the worst of the Holocaust, descriptions of the deep ambivalence in France to Jews, with entrenched antisemitism on the one hand and courageous kindness on the other.  25 years ago Mary and I paid a memorable and moving visit to Sachsenhausen, one of the first German concentration camps just outside Berlin.

Friends here in France have close links to the precarious lives of Jewish people in Vichy France, also central to episodes in the book.  Freeman writes of her search for traces of her ancestors, travelling to places like Pithiviers  south of Paris, where there had been an internment camp for Jews in transit to Auschwitz.  But when she visited "it turned out we were making a pilgrimage to nowhere: if it weren’t for a stone memorial, its former location would look like just another French suburban street. All signs of the French concentration camp had vanished, hastily erased after the war when France tried to pretend that what had happened had not."  Later things changed - "the long-abandoned Pithiviers train station, where the Jews arrived before being taken to the camp, would be turned into a museum about the French deportations. France’s attitude towards its past is, at last, starting to evolve."  And one of her relatives escaped the Nazis during the war and had better luck, being housed and concealed in the sparsely populated countryside of the Massif Central we have often visited.  Here's the Financial Times review .

Before this I'd just finished another family saga, Kiss myself goodbye by Ferdinand Mount.  An outrageous tale, told like that of the Glass family with an investigator's relish, always another surprise round the corner.  But while the Jewish Glass and Freeman families probably had good reason to conceal their identities, the stories Mount tells of deception and concealment are scarcely credible.

Things are quiet here chez nous in Lunel to match the current grey, still weather, with these seemingly interminable restrictions compounded by the uncertainties of an epidemic we don't yet fully understand on the one hand and the logistics of vaccine delays and so on on the other.  Patience is vital with this as it is for the slow but steady healing of my broken arm, so of course there are some tense moments but on the whole things seem positive - physiotherapy on the arm seems to be helping.  On another pain front, sciatica, I was signed off with a new TENS machine from the pain clinic yesterday, and the combination of that and painkillers seems to be working well.  At times over the past month I've felt as if the two conditions were fighting like squabbling children for attention!

To end today, a couple of topical or lighthearted things found in newspapers

(talking of better manners in football)

The state of mind of French people [maybe in other countries too]:

 “I first met your grandpa in a place with tables, glasses and plates…”

“A restaurant?”

“oh, you know about them?”

Left-handed episode

By [email protected] (Jon North)

It's just over a fortnight since my accident when I broke my arm.  Superficially the wounds are healing. There are some bizarre sensations and I've been back to see the surgeon who is helpful and shows me x-rays to prove that the repair, a rod through the centrecof the bone fixed by screws at each end, is as solid as a rock, and all the weird things I feel are due to massive haematomas.

So healing will take a while, and meanwhile I am finding out what can, and can’t, be done with one (left) hand. Several wine related things not - opening bottles and dispensing from wine boxes for instance, but pouring and drinking are still possible. I can restock the wood store one-handed and do a bit of cooking, but my knife skills are restricted to bananas which is... well, limiting. 

Mary is brilliant and has developed good supplementary dog skills now she takes them out al the time - too much excited barking from Elvire was met with a quick spray from a water bottle so now just picking up the bottle silences her!  in fact the dogs are just fine and their occasional excavation of a waste bin easily solved by emptying the bins!. 

Nurses come and go and are friendly and efficient. Pain from the wounds mixes with the old sciatica but neither is unsupportable. Above all I am glad to have a warm comfortable place to be in and wonderful if cold, bright Languedoc weather - so much snow not too far away but none yet here. And I am so glad to have the best companions, human and canine, in my bubble. 

Apart from a most enjoyable watch of the Detectorists box set there has been plenty of football to watch recently, and amid the giant-killing upsets of the FA Cup we really enjoyed the unequal match between  Spurs and Marine (Marine and Mourinho!) OK, no giant-killing there, but an entertaining match between 2 teams more widely spaced in the leagues than ever. Oh, and Marine had in their squad James Joyce, Neil Young, Robbie Williams, David Lynch... but no T S Eliot nor even E M Forster. A good cultural afternoon all the same!

Mary would be at a loss without a good knitting project.  Her latest completed one has been a Fair Isle cardigan for my niece Katherine, which is the final photo in this gallery.  it's a year since her dad, my younger brother Tom, died, so she in much in my thoughts just now.  Among others in our family often in our thoughts is Sam's wife Saskia who as a primary teacher is struggling to keep up with confusing govt guidance.  The current government’s default is to blame people. It has long been a scandal (I think back into Blair/Blunkett days) that teachers and schools who so often are the real experts and heroes are seen as falling short rather than being brought into creative solutions. Now more than ever we need a partnership approach rather than a belittling process. So seeing yet more of this from the current Secretary of State, I ask myself why cannot the govt trumpet the positive messages about how well schools are doing?

I am an enthusiastic new subscriber to theLondon Review of Books. Not nearly as narrow in scope or genre as its title might suggest, the article here called ‘Get the jab’ by a clinical expert is well worth reading. 

Hunting and wild animals are often in the news here and elsewhere, with lockdowns and reduced activity have led to burgeoning growth among plants, and unchecked breeding of many animals.  The hunters here are under pressure to control wild boars but the market for their meat has plummeted, as has that for venison in the UK where flourishing herds threaten to change whole landscapes.  Some people want to encourage predators like wolves which are already a problem here on the continent of Europe.  Deer can just about stand up to them, but sheep certainly not.  What would Little Red Riding Hood say?

The photos this time are from our wonderfully sunny January, but to end here is a cartoon by Simone Lia - in this strangest of times, all sorts of things are coming out of the closet, but having broken our last vacuum flask we had to buy a new one to take soup to the homeless people in the town.  however cold, it is, it's at least dry for them at the moment.


Happy new year!

By [email protected] (Jon North)

 An unexpected lurch in the blog this time, and slowly written because with only one left hand.  On Monday evening, coming back from friends nearby, I fell by the road and broke my right humerus.  I was operated on at the local hospital.  Back in the evening strapped up, the usual rigmarole learning to sleep on my back

Despite all precautions, though, things turned weird in the morning.  It seemed to me that overnight the fixing had come loose so it was back to casualty for an x-ray.  All carried out in under 3 hours, including after talking to various surgeon’s sidekicks, by mid-morning and checking back with the surgeon, and it seems that the fixing wires and screws are as they should be and that strange sensations are probably due to a haematoma.  Back with relief for lunch and to write this – no photos this time because medical ones are not cheerful and in any case left handed photography is as difficult as LH typing.

I am in good spirits especially now I know what is what, and M is being A BRICK.   But not easy for either of us, and with the best will in the world waiting is the name of the game.

So a couple of thoughts to end this strange old year.  The first is that, aside from sometimes interminable waits, the treatment I have had has been good and courteous – results we’ll see, but so far so good.  A nurse said to his colleague ‘help, this one’s English’ and since I overheard I could reassure him – phew, he thought .  Lots of people ask how long we’ve lived here -  if anything there’s more interest now people know we are not here as EU citizens, and you can see, France scores highly for health services for us.

Earlier this year I quoted Alan Bennett on Victoria Wood (two of my favourite actor/writers of whom sadly only on still survives (and by far the older – we must pay him good attention) She was a great woman, her performance of ‘Let’s Do It’ at the Albert Hall the stuff of legend. I just hope Noël Coward was still around to see it. I first met her, almost epically, in Sainsbury’s in Lancaster at the avocado counter. Her Dinnerladies was often sentimental, but she caught in the part of the handyman, played by Duncan Preston, the idiom of an old-fashioned working-class man, elaborate, literate and language-loving, which is, or was, more typical of the North than the more clichéd dialect-rich versions.  

So I finish with the final passage from his dairy this year There were those in 1914 who believed that war was just what was needed – as a cleanser and a salutary shock. England would be the better for it. As we wait for the result of the final Brexit talks, the heirs of these fools are still with us.  You can read the whole of his 2019 diary here


Season's greetings

By [email protected] (Jon North)

Our crêche of santons this year - the traditional provençal clay figures were given to us some 25 years ago by the twinning association in Die, a connection which led to our being in France

We have written a lot of cards, some real ones though more than usual this year have been electronic (thank you Jacquie Lawson!)  But otherwise we have begin an enjoyable round of tv watching with the box set of the 3rd series of The Crown pronounced, as our dear friend Francis often reminded us, 'the Cra-een', and so rhyming with Queen as it should!  we (Mary especially) had low expectations but we have been absorbed, I think it is fair to say, by the storylines and by very good acting.  Olivia Colman did a really great job as Her Maj, and many other actors were equally impressive.

There are some really interesting themes, including the story of Princess Alice mother of the Duke of Edinburgh, about whom we learnt only a couple of weeks ago through a Channel 5 documentary.  Coming at the end of a long period for us of reading about the history of the monarchy over the centuries we are very well aware that films like this are just stories.  Who knows how much of this or any story is 'true', but as Pilate asks 'what is truth'?  The versions of events here are plausible, and if we reflect on the current political scene we realise how difficult it is to rely on 'news'.  So parts of The Crown may distort actual events, and we shall never know, but some surprising parts have an unexpected interest - for instance, the sympathetic relationship between the Queen and Harold Wilson.

Incidentally, the documentary on 'the making' of the series was also revealing - the huge amount of research needed, the vast array of costumes and props and the mind-blowing attention to detail are all really impressive.  And this theme of detail is a link to my next subject, football.  Because a writer's  encyclopaedic knowledge of games, players and the internal workings of teams and leagues was as impressive and unimaginable to me as the detail of royal events and the stories that describe them.

As the Festive season approaches the regularity of top-flight football matches in England goes up too.  As a Liverpool fan I have just read Anthony Quinn's Klopp: my Liverpool romance - not really a biography, but an appreciative review, of Jürgen Klopp's path into the role of Manager of the club.  Like expectations of the royal story, mine of this book were not very high, but I've been impressed and interested to read the kind of sports book I'd never have expected to enjoy.  It is nicely written, an absorbing insight into the way football managers' lives work, and coming as it does at a moment when the team is stamping its authority on the premiership again, it gives me a bit of a warm glow.

Local papers often surprise me.  In England, we often read endless reports of flower shows and French papers are not altogether different, plenty of detail of local clubs and societies, and of local villains!  But tucked into most editions of Midi Libre are serious bits like this reminder of the dangerous lives of journalists, defended (as here) against arbitrary restrictions for doing their job and uncovering their version of truth.  What is truth, again?  Here in France the President has made his own headlines by apparently trying to restrict reporting of police brutality, legal restrictions on what may be filmed an so on.  The fine line is evidently a movable one too, so for us watching events and finding truth in, say, Armenia where a gruesome war in the enclave of Nagorno Karabakh has led to atrocities, suffering and abuses, is almost impossible.  As I've said before, we'd planned to go there and think of our friends and their families caught in a bleak midwinter there. All that on top of an awful pandemic situation in an area with very poor health services.  This article talks of the gulf - the fossé or ditch - between speech and action in the defence of liberty, and has a bleak link in imagery with the real muddy trenches and traps still being dug on real battlefields in a forlorn attempt to obstruct modern weapons like drones...

A change of tone with a cartoon, a star or two, and two of our own stars, the dogs

Tomorrow if the weather allows Jupiter and Saturn will appear in more or less the same place near the southwestern horizon - a 'Christmas Star' effect which we may miss because of cloud!  but they will seem close enough together in the early evening for the next week or so.  Maybe for the 'wise men' of old, this was their truth...

Gardens and other living things

By [email protected] (Jon North)

This week I want to start with gardens and allotments.  Some of our good friends and family in England have or had allotments, and many more are keen gardeners.  Our own garden in France is large and surrounded by trees and hedges, but it is an open green space (brown during hot summers), not a place where we grow things.  Some fruit works well (citrus, kakis or persimmons) while other trees - cherry and apricot - had to be cut down because they were diseased.  We do at least have some herbs, rosemary and bay (the latter a magnificent hedge), and we even kept some mint alive this summer by parking it under the lemon tree which we often remember to water, but for the most part we rely on and help support the wonderful local growers who supply our greengrocer.  He knows personally where a lot of his produce grows and when it was picked.

Our friend Luc (pictured here with Mary and the dogs) on the other hand has a garden on old family land near the canal at Aigues Mortes, a place that became accessible when our lockdown radius was extended from 1 to 20 km.  We went to see him on Monday (as if by chance, since our legitimate purpose had to be to walk the dogs), and admired his marvellous vegetable beds on the sandy soil with a good water supply laid on.  Not a bad place to go on a bright December morning, meeting a good friend whose company at wine tastings and elsewhere we've missed!

As I write, two women who shared (as I expect they would agree) certain attributes (!) are in our thoughts.  One, Dame Barbara Windsor has just died at the age of 83, a funny lady always onn a cinema or tv screen near me when I was young.  The other, Dolly Parton, is almost exactly my age and (we can hope) seemingly everlasting, and has hit the headlines for a million dollar donation to vaccine research.  She is in my mind an extraordinary musician.  Washington Post article here.

Otherwise it has been a serious and sober time.  Brexit seems again to be heading for the buffers, a tragedy with no redeeming features unless you like queues of lorries in Kent.  The Covid pandemic rumbles on, giving regular kicks in the teeth to optimistic politicians everywhere who hope hope is round the corner.  The terrible triangle of a resistant infection, awful economic consequences of repeated lockdowns and the obstinate mild stupidity of people who prefer not to be tied down make for a long slow period of recovery, despite excellent news on vaccines.  But solutions take time, and neither politicians nor Joe Public are really prepared to wait long enough, so the virus will have more chance to spread.  Here is a useful link to a set of charts which is published through a European site for expats.  This is complex stuff.

So the upshot for us is a very quiet Christmas and new year.  We are safer than most because we don't have to go out a lot, and we see few people except occasional and welcome contacts with friends like Luc, our Aigues Mortes gardener, or Christiane (one of our longest-standing choral friends) who came to pick most of our persimmons/kakis last week - we don't eat them, but several friends love them and so do the birds.


In my quiet moments I muse about transport - cars are the safest bubbles just now but not only do fossil fuels have obvious faults, but the lithium needed to make the batteries for the electric vehicles supposed to replace them is itself itself in short supply and causes immense damage as it is mined.  Air travel is both very uncertain and obviously environmentally damaging, but how shall we see family and friends in other countries?  and the public transport always seen as responsible is built on economic models involving lots of people crammed together, so risky in spreading disease at busy times and hopelessly uneconomic at quieter ones - trains and planes lose money hand over fist at present and normally reliable companies look fragile, bookings not at all certain to be honoured.

I still love my photography, and always find beautiful subjects whatever the weather, so I'll end with a couple more recent photos and get back to writing Christmas cards!

Shopping days??

By [email protected] (Jon North)

This week I have to start with our first post-lockdown return to the beach, only the second visit ever for the dogs who had a fine time in the sunshine.   The Couchant beach just west of La Grande Motte was not at all crowded, lovely sunshine - altogether a tonic for humans and other animals alike!

I've just read in the local paper that Montpellier seems almost as busy as it used to be (though bars and restaurants are still shut.  The editorial regrets that people are so careless (and maskless) of others' health and wellbeing, crowding into streets and markets.  I know we all have to be careful not to criticise - the pressures on people with, little time and money, to make the best of moments of  'freedom' are huge.  Yet, even with vaccines on the horizon, the risks are also huge.  As the editorial says, businesses are forced to keep their shutters down while others risk prolonging the pandemic through carelessness.  Better safe than sorry, as innumerable people have said to us in the past... 

Reading - we keep resurrecting things we've already read, often because one of us has but not the other.  Following Henry VII Mary tried A L Rowse's Bosworth Field & the Wars of the Roses which she found a bit pedantic, but she has romped through a number of the Clive Sansom Shardlake series and is now venturing back further towards the middle ages with Azincourt  by Bernard Cornwell, one of his few but well-written non-fiction books, while I contemplate revisiting Sharpe and his adventures in the Spanish Peninsula war once I have caught up with Alexander McCall Smith and Mma Ramotswe with her wise sayings, with Mma Makutsi's talking shoes!

Our watching has included a lot of sport, and the close of the cycling season brought not only spectacular scenery across the Spanish uplands, but a lot of echos of  the Sharpe books with Wellington's battle sites as the Vuelta headed along the Portuguese border.  Now we are back to regular rendez-vous with Monday quizzes on BBC tv (Only Connect and University Challenge) and Wednesday's wonderful French tv series Des Racines et des Ailes.  We have a number of these on DVD as part of our Christmas viewing choices - a later blog will reveal all!  Meanwhile we have not been disappointed by the return of Masterchef the Professionals also on the BBC.  In the past we've really enjoyed this bi-annual series, and have occasionally sought out winners in their restaurants.  Now, with numbers of competitors reduced by distancing and so on in the pandemic, the focus seems even sharper and the standard higher, and so far we have continued to agree with the judging!

 Our day often begins with music on BBC Radio 3, and I am really looking forward to the Christmas season, especially since our live music has been badly reduced by lockdowns and curfews.  After a trying Zoom B.a.Bach choir committee for me (not the fault of the  participants, but the technology is uncertain, someone almost inaudible, someone else only seen as a muffled silhouette, and the time lags make it difficult to speak and be heard) yesterday everyone is trying hard to get singing going again in the new year, but I'm not convinced it will happen.  We have had to call off our little Christmas carol concert for the first time since we came to France - some of our singers rightly reserving contacts for their new grandchildren, other English friends who usually sing with us could not get over in any case.

However, Mary is looking forward to a couple of pre-Christmas cello dates at the Vauvert music school, including her first lesson for months.  Happily her hand has almost healed from the damage caused by a fall in the road when she was walking the dogs (a car came round the corner and she overbalanced trying to make sure the dogs were out of the way), and it has not really impeded her practising.

I've been delighted to see my old friend Martin Weatherhead (we met at school over 60 years ago!) about to display one of his wonderful wool tapestries.  He has become something of an icon for his art and his adopted Wales - more details in this article.  It will be a strange Christmas cut off from friends and family  but perhaps things will gradually open up if there is not too much over-enthusiasm!

r/McMansionHell - Hello r/McMansionHell, I'm Kate Wagner, creator of McMansion Hell and architecture critic at The New Republic. AMA!

r/McMansionHell - Hello r/McMansionHell, I'm Kate Wagner, creator of McMansion Hell and architecture critic at The New Republic. AMA!:

Howdy, Folks! If you’re not busy right now, I’m doing an AMA on the McMansion Hell Subreddit! Stop by and ask me some questions!

The McMansion Hell Yearbook: 1979

Howdy, folks! I hope all of my fellow Midwesterners are enjoying this year’s false spring. Seventy-degree days notwithstanding, the snow will indeed be back, and, as such, I have prepared for you a house to enjoy (?) alongside a miserably late-in-the-year hot cocoa. 

Now, this house isn’t as oppressively horrible as the last one, however, the point of the Yearbook is to show off how houses evolved overtime, and also to celebrate some of the kookier time capsules left out there. Our current house falls into the latter category, and to be honest, I find it weirdly endearing. 

Located just outside of Detroit, this 5 bed, 4.5 bath house tops out at over 10,000 square feet. Yes, you read that right. 10,000. You’ll see why later. Anyways, if you want to purchase said house, it can be all yours for just under $1,000,000. A steal!

??? Foyer

In America we don’t have barons, only robber barons, so I’m going to assume whoever built this house did so on the backs of thousands of exploited 19th century child laborers or whatever. Bad stuff. 

??? Room

Unsure of the purpose of this room, genuinely, because all other rooms are accounted for. This one’s just empty. It’s just existing. Vibing, as one might say.

TV (???) Room

Don’t mind me, I’m just getting out my birding binoculars in order to watch Seinfeld reruns.


Considering the history of the Midwest and the fact that Sears and co. cut down all our old growth forests in order to do cheap furniture and balloon framing, this whole wood paneling bit is really part of a much larger historical milieu.  

Dining Room

The American Bicentennial lurks in the background of all of these houses, its legacy permanently ingrained in too-dark rooms across the nation. 

Main Bedroom

Shivering at the thought of my feet touching cold tile floor every morning. That’ll wake you up. 

Other Bedroom

You know, the grandness of the chandelier has diminishing returns if you put one in every single room. Then it becomes just another light fixture. 

Random Bathroom

BROWN TUB BROWN TUB BROWN TUB (the rarest of all mid-century tubs)

Pleasure Grotto

Ok now this is why I chose this house. It also explains why this house is 10,000 square feet - at least half of that is just this pool alone. The funniest bit is, I can’t for the life of me tell WHERE this pool is by looking at the exterior of the house. In fact, I’m not sure how they managed to fit so much house in that small of an envelope, but at this point, it’s so weird I’m inclined not to ask further questions. Some things in the universe are not meant to be known to us. 

Rear Exterior


Anyways, I’ll let that haunt you for a little while. 

In the mean time, I’d like to take this space at the end of the post to announce that I’ve started a little side project devoted to my other love in life, professional cycling. It’s a newsletter called derailleur that aims to tell the stories of contemporary professional cycling in an unconventional, narrative-driven way. If you’re into such things, feel free to check it out: 


If you like this post, and want to see more like it, consider supporting me on Patreon!

There is a whole new slate of Patreon rewards, including: good house of the month, an exclusive Discord server, monthly livestreams, free merch at certain tiers and more!

Not into recurring donations but still want to show support? Consider the tip jar!

Or, Check out the McMansion Hell Store! Proceeds from the store help protect great buildings from the wrecking ball.

i draw cyclists

i draw cyclists:

hey so in my spare time, when i am not an architecture critic, i like to draw. this has merged with my other love in life (professional cycling) and as such i have dedicated the last six months of my evening hours to drawing cyclists. 

tl;dr i made a tumblr where i’m posting my art if you’re into that kind of thing. this isn’t monetized in any way and i don’t take commissions - it’s just a nice (if strange) hobby i enjoy.

see you all monday with a new house post <3

The McMansion Hell Yearbook: 1978

Howdy Folks! Today’s house comes to us from Iredell County, North Carolina, and trust me, it is quite a doozy - just in time for Valentines Day, too! If you don’t fall in love with it, I don’t know what to tell you. 

This 5300 square foot, 4 bedroom, 4.5 bath house, comes in at $625,000, making it more of a bargain than most McMansions usually are, and while the Tudors never came to America, a place that had not yet been “discovered” by the time the Tudors were in power in England, fear not - for all the repression and stuffiness of 15th century Britain can still be found within these darkened doors. 

Lawyer Foyer

If your house doesn’t constantly give off I AM MARRIED vibes, your spouse might start having indecent thoughts. One must stay vigilant at all times. 

Dining Room

Look, hutches are good storage, okay. Sturdy. We as a generation (millennials) need to get back into knickknacks. Minimalism is dead. Long live kitsch. 

Living Room

Honestly, this house is so dark and repressed it makes high school me look like a libertine. 


“What do you mean ‘dopeness’ isn’t a qualifier for granting a property historical landmark status?” 

Main Bedroom

Love is in the air. Also the air is really, really stale in here right now. 


If your bathroom doesn’t emulate a luxuriant grotto, wyd???

Bedroom 2

please, my floor ducks, they are so cold,,,,


I have got to stop using epic ironically. I already lived through 2008 once. 

That’s it for the interior! Let’s just step outside for a quick breather…

Rear Exterior

Well, I hope you had a good time traipsing through what can only be described as a treasure trove of different matching fabrics. Be sure to stick around for the next part of “Underground” which is coming your way shortly!

If you like this post, and want to see more like it, consider supporting me on Patreon!

There is a whole new slate of Patreon rewards, including: good house of the month, an exclusive Discord server, weekly drawings, monthly livestreams, a reading group, free merch at certain tiers and more!

Not into recurring donations but still want to show support? Consider the tip jar! 

Or, Check out the McMansion Hell Store! Proceeds from the store help protect great buildings from the wrecking ball.

Underground, Part 1

[Author’s Note: A year ago, when waiting for the DC Metro, I came up with an idea for a short story involving two realtors and the infamous Las Vegas Underground House, typed up an outline, and shoved it away in my documents where it sat neglected until this month. The house recently resurfaced on Twitter, and combined with almost a year of quarantine, the story quickly materialized. Though I rarely write fiction, I decided I’d give it a shot as a kind of novelty McMansion Hell post. I’ve peppered the story with photos from the house to break up the walls of text. Hopefully you find it entertaining. I look forward to returning next month with the second installment of this as well as our regularly scheduled McMansion content. Happy New Year!

Warning: there’s lots of swearing in this.]



Back in 1997, Mathieu Rino, the son of two Finnish mechanical engineers who may or may not have worked intimately with the US State Department, changed his name to Jay Renault in order to sell more houses. It worked wonders.

He gets out of the car, shuts the door harder than he should. Renault wrinkles his nose. It’s a miserable Las Vegas afternoon - a sizzling, dry heat pools in ripples above the asphalt. The desert is a place that is full of interesting and diverse forms of life, but Jay’s the kind of American who sees it all as empty square-footage. He frowns at the dirt dusting up his alligator-skin loafers but then remembers that every lot, after all, has potential. Renault wipes the sweat from his leathery face, slicks back his stringy blond hair and adjusts the aviators on the bridge of his nose. The Breitling diving watch crowding his wrist looks especially big in the afternoon glare. He glances at it.

“Shit,” he says. The door on the other side of the car closes, as though in response. 

If Jay Renault is the consummate rich, out-of-touch Gen-Xer trying to sell houses to other rich, out-of-touch Gen-Xers, then Robert Little is his millennial counterpart. Both are very good at their jobs. Robert adjusts his tie in the reflection of the Porsche window, purses his lips. He’s Vegas-showman attractive, with dark hair, a decent tan, and a too-bright smile - the kind of attractive that ruins marriages but makes for an excellent divorcee. Mildly sleazy.

“Help me with these platters, will you?” Renault gestures, popping the trunk. Robert does not want to sweat too much before an open house, but he obliges anyway. They’re both wearing suits. The heat is unbearable. A spread of charcuterie in one hand, Jay double-checks his pockets for the house keys, presses the button that locks his car. 

Both men sigh, and their eyes slowly trail up to the little stucco house sitting smack dab in the center of an enormous lot, a sea of gravel punctuated by a few sickly palms. The house has the distinct appearance of being made of cardboard, ticky-tacky, a show prop. Burnt orange awnings don its narrow windows, which somehow makes it look even more fake. 

“Here we go again,” Jay mutters, fishing the keys out of his pocket. He jiggles them until the splintered plywood door opens with a croak, revealing a dark and drab interior – dusty, even though the cleaners were here yesterday. Robert kicks the door shut with his foot behind him.

 “Christ,” he swears, eyes trailing over the terrible ecru sponge paint adorning the walls. “This shit is so bleak.”

The surface-level house is mostly empty. There’s nothing for them to see or attend to there, and so the men step through a narrow hallway at the end of which is an elevator. They could take the stairs, but don’t want to risk it with the platters. After all, they were quite expensive. Renault elbows the button and the doors part. 

“Let’s just get this over with,” he says as they step inside. The fluorescent lights above them buzz something awful. A cheery metal sign welcomes them to “Tex’s Hideaway.” Beneath it is an eldritch image of a cave, foreboding. Robert’s stomach’s in knots. Ever since the company assigned him to this property, he’s been terrified of it. He tells himself that the house is, in fact, creepy, that it is completely normal for him to be ill at ease. The elevator’s ding is harsh and mechanical. They step out. Jay flips a switch and the basement is flooded with eerie light. 

It’s famous, this house - The Las Vegas Underground House. The two realtors refer to it simply as “the bunker.” Built by an eccentric millionaire at the height of Cold War hysteria, it’s six-thousand square feet of paranoid, aspirational fantasy. The first thing anyone notices is the carpet – too-green, meant to resemble grass, sprawling out lawn-like, bookmarked by fake trees, each a front for a steel beam. Nothing can grow here. It imitates life, unable to sustain it. The leaves of the ficuses seem particularly plastic.

Bistro sets scatter the ‘yard’ (if one can call it that), and there’s plenty of outdoor activities – a parquet dance floor complete with pole and disco ball, a putt putt course, an outdoor grill made to look like it’s nestled in a rock, but in reality better resembles a baked potato. The pool and hot tub, both sculpted in concrete and fiberglass mimicking a natural rock formation, are less Playboy grotto and more Fred Flintstone. It’s a very seventies idea of fun.

Then, of course, there’s the house. That fucking house. 

A house built underground in 1978 was always meant to be a mansard – the mansard roof was a historical inevitability. The only other option was International Style modernism, but the millionaire and his wife were red-blooded anti-Communists. Hence, the mansard. Robert thinks the house looks like a fast-food restaurant. Jay thinks it looks like a lawn and tennis club he once attended as a child where he took badminton lessons from a swarthy Czech man named Jan. It’s drab and squat, made more open by big floor-to-ceiling windows nestled under fresh-looking cedar shingles. There’s no weather down here to shrivel them up.


“Shall we?” Jay drawls. The two make their way into the kitchen and set the platters down on the white tile countertop. Robert leans up against the island, careful of the oversized hood looming over the electric stovetop. He eyes the white cabinets, accented with Barbie pink trim. The matching linoleum floor squeaks under his Italian loafers. 

“I don’t understand why we bother doing this,” Robert complains. “Nobody’s seriously going to buy this shit, and the company’s out a hundred bucks for party platters.”

“It’s the same every time,” Renault agrees. “The only people who show up are Instagram kids and the crazies - you know, the same kind of freaks who’d pay money to see Chernobyl.” 

“Dark tourism, they call it.”

Jay checks his watch again. Being in here makes him nervous.

“Still an hour until open house,” he mutters. “I wish we could get drunk.”

Robert exhales deeply. He also wishes he could get drunk, but still, a job’s a job.

“I guess we should check to see if everything’s good to go.”

The men head into the living room. The beamed, slanted ceiling gives it a mid-century vibe, but the staging muddles the aura. Jay remembers making the call to the staging company. “Give us your spares,” he told them, “Whatever it is you’re not gonna miss. Nobody’ll ever buy this house anyway.” 

The result is eclectic – a mix of office furniture, neo-Tuscan McMansion garb, and stuffy waiting-room lamps, all scattered atop popcorn-butter shag carpeting. Hideous, Robert thinks. Then there’s the ‘entertaining’ room, which is a particular pain in the ass to them, because the carpet was so disgusting, they had to replace it with that fake wood floor just to be able to stand being in there for more than five minutes. There’s a heady stone fireplace on one wall, the kind they don’t make anymore, a hearth. Next to it, equally hedonistic, a full bar. Through some doors, a red-painted room with a pool table and paintings of girls in fedoras on the wall. It’s all so cheap, really. Jay pulls out a folded piece of paper out of his jacket pocket along with a pen. He ticks some boxes and moves on.

The dining room’s the worst to Robert. Somehow the ugly floral pattern on the curtains stretches up in bloomer-like into a frilly cornice, carried through to the wallpaper and the ceiling, inescapable, suffocating. It smells like mothballs and old fabric. The whole house smells like that. 

The master bedroom’s the most normal – if anything in this house could be called normal. Mismatched art and staging furniture crowd blank walls. When someone comes into a house, Jay told Robert all those years ago, they should be able to picture themselves living in it. That’s the goal of staging. 

There’s two more bedrooms. The men go through them quickly. The first isn’t so bad – claustrophobic, but acceptable – but the saccharine pink tuille wallpaper of the second gives Renault a sympathetic toothache. The pair return to the kitchen to wait.


Both men are itching to check their phones, but there’s no point – there’s no signal in here, none whatsoever. Renault, cynical to the core, thinks about marketing the house to the anti-5G people. It’s unsettlingly quiet. The two men have no choice but to entertain themselves the old-fashioned way, through small talk.

“It’s really fucked up, when you think about it,” Renault muses.

“What is?”

“The house, Bob.”

Robert hates being called Bob. He’s told Jay that hundreds of times, and yet…

“Yeah,” Robert mutters, annoyed.

“No, really. Like, imagine. You’re rich, you founded a major multinational company marketing hairbrushes to stay-at-home moms, and what do you decide to do with your money? Move to Vegas and build a fucking bunker. Like, imagine thinking the end of the world is just around the corner, forcing your poor wife to live there for ten, fifteen years, and then dying, a paranoid old man.” Renault finds the whole thing rather poetic. 

“The Russkies really got to poor ol’ Henderson, didn’t they?” Robert snickers.

“The wife’s more tragic if you ask me,” Renault drawls. “The second that batshit old coot died, she called a guy to build a front house on top of this one, since she already owned the lot. Poor woman probably hadn’t seen sunlight in God knows how long.”

“Surely they had to get groceries.”

Jay frowns. Robert has no sense of drama, he thinks. Bad trait for a realtor.

“Still,” he murmurs. “It’s sad.”

“I would have gotten a divorce, if I were her,” the younger man says, as though it were obvious. It’s Jay’s turn to laugh.

“I’ve had three of those, and trust me, it’s not as easy as you think.”

“You’re seeing some new girl now, aren’t you?” Robert doesn’t really care, he just knows Jay likes to talk about himself, and talking fills the time.  

“Yeah. Casino girl. Twenty-six.”

“And how old are you again?”

“None of your business.”

“Did you see the renderings I emailed to you?” Robert asks briskly, not wanting to discuss Jay’s sex life any further.

“What renderings?”

“Of this house, what it could look like.”

“Oh. Yeah.” Jay has not seen the renderings.

“If it were rezoned,” Robert continues, feeling very smart, “It could be a tourist attraction - put a nice visitor’s center on the lot, make it sleek and modern. Sell trinkets. It’s a nice parcel, close to the Strip - some clever investor could make it into a Museum of Ice Cream-type thing, you know?”

“Museum of Ice Cream?”

“In New York. It’s, not, like, educational or anything. Really, it’s just a bunch of colorful rooms where kids come to take pictures of themselves.”

“Instagram,” Jay mutters. “You know, I just sold a penthouse the other week to an Instagram influencer. Takes pictures of herself on the beach to sell face cream or some shit. Eight-point-two million dollars.”

“Jesus,” Robert whistles. “Fat commission.”

“You’re telling me. My oldest daughter turns sixteen this year. She’s getting a Mazda for Christmas.”

“You ever see that show, My Super Sweet Sixteen? On MTV? Where rich kids got, like, rappers to perform at their birthday parties? Every time at the end, some guy would pull up in, like, an Escalade with a big pink bow on it and all the kids would scream.”

“Sounds stupid,” Jay says.

“It was stupid.”

It’s Robert’s turn to check his watch, a dainty gold Rolex.

“Fuck, still thirty minutes.”

“Time really does stand still in here, doesn’t it?” Jay remarks.

“We should have left the office a little later,” Robert complains. “The charcuterie is going to get –“

A deafening sound roars through the house and a violent, explosive tremor throws both men on the ground, shakes the walls and everything between them. The power’s out for a few seconds before there’s a flicker, and light fills the room again. Two backup generators, reads Jay’s description in the listing - an appeal to the prepper demographic, which trends higher in income than non-preppers. For a moment, the only things either are conscious of are the harsh flourescent lighting and the ringing in their ears. Time slows, everything seems muted and too bright. Robert rubs the side of his face, pulls back his hand and sees blood.

“Christ,” he chokes out. “What the hell was that?”

“I don’t know,” Jay breathes, looking at his hands, trying to determine if he’s got a concussion. The results are inconclusive – everything’s slow and fuzzy, but after a moment, he thinks it might just be shock.

“It sounded like a fucking 747 just nosedived on top of us.” 

“Yeah, Jesus.” Jay’s still staring at his fingers in a daze. “You okay?”

“I think so,” Robert grumbles. Jay gives him a cursory examination.

“Nothing that needs stitches,” he reports bluntly. Robert’s relieved. His face sells a lot of houses to a lot of lonely women and a few lonely men. There’s a muffled whine, which the two men soon recognize as a throng of sirens. Both of them try to calm the panic rising in their chests, to no avail.

“Whatever the fuck happened,” Jay says, trying to make light of the situation, “At least we’re in here. The bunker.”

Fear forms in the whites of Robert’s eyes.

“What if we’re stuck in here,” he whispers, afraid to speak such a thing into the world. The fear spreads to his companion.

“Try the elevator,” Jay urges, and Robert gets up, wobbles a little as his head sorts itself out, and leaves. A moment later, Jay hears him swear a blue streak, and from the kitchen window, sees him standing before the closed metal doors, staring at his feet. His pulse racing, Renault jogs out to see for himself.

“It’s dead,” Robert murmurs. 

“Whatever happened,” Jay says cautiously, rubbing the back of his still-sore neck, “It must have been pretty bad. Like, I don’t think we should go up yet. Besides, surely the office knows we’re still down here.”

“Right, right,” the younger man breathes, trying to reassure himself.

“Let’s just wait it out. I’m sure everything’s fine.” The way Jay says it does not make Robert feel any better. 

“Okay,” the younger man grumbles. “I’m getting a fucking drink, though.”

“Yeah, Jesus. That’s the best idea you’ve had all day.” Renault shoves his hands in his suit pocket to keep them from trembling.  


If you like this post, and want to see more like it, consider supporting me on Patreon!

There is a whole new slate of Patreon rewards, including: good house of the month, an exclusive Discord server, weekly drawings, monthly livestreams, a reading group, free merch at certain tiers and more!

Not into recurring donations but still want to show support? Consider the tip jar! 

Or, Check out the McMansion Hell Store! Proceeds from the store help protect great buildings from the wrecking ball.

We Interrupt This Broadcast to Bring You an Especially Cursed House

Hello everyone. Originally, this post was supposed to be devoted to the year 1978, however something came up, and by something, I mean this 2.2 million-dollar, 5,420 sq ft 4 bed/4.5 bath house in Colt’s Neck, NJ. 

You see, usually, when a listing goes viral, I’m content to simply retweet it with a pithy comment, but this house genuinely shook something in me, genuinely made me say “what the (expletive)” out loud. It is only fair to inflict this same suffering onto all of you, hence, without further ado: 

Looks normal, right? Looks like the same low-brow New Jersey McMansion we’re all expecting, right? Oh, oh dear, you couldn’t be more wrong

Guess who’s making a list and checking it twice? 

Guess who’s gonna find out who’s naughty or nice?

Guess who’s coming to town? 

Guess who’s coming to town to drag your ass into hell?

A gentle reminder that it is not yet Thanksgiving. 

But oh. Oh. It continues:

If you’re wondering what’s happening here, you’re not alone, and sadly there is no convenient way to find out via a kind of haunted house hotline or something. 

I can’t even label these rooms because frankly I’m not even sure what they are. All I am sure of is that I want out of them as soon as humanly possible. 

r̸̘̆e̴̝̻̽m̵̡̼̚ȩ̵͑̎ͅm̷͍̮̉b̸̥̈e̶̯̺̽͗r̸̝͊͠ ̸̡͎̅̀t̴̯̲̓ȯ̷̮̫ ̷̜̅̀ŵ̶̟̱ā̴̭̘s̸̥͋h̴͉̿ ̵̡̑y̸̩͈͑o̷̹̭͛͝ů̷̩̮̔r̶̜̃ ̴̠̗͋ẖ̴̈́͛a̸̢̟̐͒n̶̩̟̆ḍ̵̍̀s̴̨̈́

How is it that a room can simultaneously threaten, frighten, and haunt me? Me, of all people!

My eyes do not know where to go here. They go to the window, they go to the fireplace, they go to the massive mound of fake plant and statuary currently gorging on the leftmost corner of the room, they go to my hands, which are shaking. 

“Hello, I would like to get in touch with the Ministry of Vibes? Yes, I’ll hold.” 

I haven’t been this afraid of a shower since I went to Girl Scout camp in the fifth grade and there was a brown recluse spider in the camp shower and I screamed until the counselor came in and told me it was only a wolf spider but it turns out those still bite you and it hurts

I love watching Still Images on my Television Set :)

Nobody make a sound. He’s watching you. 

i spy with my evil eye:


Their souls are trapped in these photographs forever :)

Okay, phew, we made it out alive. Here’s the back of the house I guess. 

Well, I hope you’re as thoroughly disturbed as I am. Seriously, I’m going to have trouble sleeping. I mean, I already have trouble sleeping, but this is just making that existing problem so much worse. 

If you like this post, and want to see more like it, consider supporting me on Patreon!

There is a whole new slate of Patreon rewards, including: good house of the month, an exclusive Discord server, weekly drawings, monthly livestreams, a reading group, free merch at certain tiers and more!

Not into recurring donations but still want to show support? Consider the tip jar! (Tips are much appreciated since I am making a cross country move in two weeks!!!)

Or, Check out the McMansion Hell Store! Proceeds from the store help protect great buildings from the wrecking ball.

The McMansion Hell Yearbook: 1977

Howdy, folks, and happy October! (It’s snowing here in Chicago lol) 

Before I get down to business on today’s post, I want to let you know of two big events coming up this week: 

First, I’ll be in conversation with Susan Chin and Vinson Cunningham tomorrow evening (10/28) to talk about urbanism during the pandemic (virtually) at the Museum of the City of New York. More info and tickets here

 I am giving this year’s Brendan Gill Lecture in Architectural Criticism at Yale via Zoom on Thursday the 29th of October at 6:30 Eastern Time. Admission is free. Here’s a link to the talk which includes info on how to register. 

Alright, now back to the main event. We’re back in Cook County, Illinois because of course we are, and this house falls into the rare McMansion Hell category of “this house is terrible but also kind of cute somehow????” 

It’s a shame you can’t really see the turret because it adds so much. Anyways, this house is peak 70s McMansion: longer than it is tall, involves a mansard, big picture windows, not too adventurous roof-wise. Still, it’s 6900 square feet boasting 5 bedrooms and 6.5 baths all at a whopping $1.5 million dollars. Just some pocket change, you know…

Let’s see inside, shall we?

Lawyer Foyer

All I want is some Looney Tunes action where some’s coming up from the basement and someone’s coming in the front door and WHAM!!!! 

Sitting Room

I kind of stan the dog pots though… 

Dining Room

I think the wallpaper might be crabs???? (????)


Pros of tile countertops: v twee and cute
Cons of tile countertops: grout 

Also we NEED to bring back the kitschy farmhouse aesthetic from 40 years ago. No more quartz countertops. It’s time for tiles with chickens on them!!!


Is this room supposed to be like weirdly tropical?? or Parisian??? or Martha Stewart??? or???

Vibe check: [please calibrate vibe checker and try again]


After all, inside every middle manager is a languishing Hemingway…

Main Bedroom

“Struggled hard for these views (six arm flexing emojis)”

Also, disclosure: McMansion Hell will no longer use the term “master bedroom” because it’s antiquated and never made much sense after the (American) Civil War if you really think about it for more than three seconds. 

Main Bathroom

where to purchase malachite wallpaper asking for a friend (the friend is my office)

Spare Bedroom

Nothing says “I am a fun-loving carefree and slightly cRaZy girl” like this font:

Alright, that’s it for the inside. Instead of the rear exterior though, I’m going to end this post with a fun aerial shot instead just to show that my suspicions about this house have been confirmed. 

Secret Aerial Footage (helicopter sounds)

See, this house is actually very weird!!!! It is not as cute when all of its wily tricks have been revealed!!!!

Okay, that’s it for 1977. Stay tuned for 1978! 

If you like this post, and want to see more like it, consider supporting me on Patreon!

There is a whole new slate of Patreon rewards, including: good house of the month, an exclusive Discord server, weekly drawings, monthly livestreams, a reading group, free merch at certain tiers and more!

Not into recurring donations but still want to show support? Consider the tip jar! (Tips are much appreciated since I am making a cross country move in two weeks!!!)

Or, Check out the McMansion Hell Store! Proceeds from the store help protect great buildings from the wrecking ball.

Public opinion has softened its views on Brutalism. That isn’t enough to stay the wrecking ball.

Public opinion has softened its views on Brutalism. That isn’t enough to stay the wrecking ball.:

I’m back in The Architect’s Newspaper, where I’m talking about my favorite subject (Brutalism) and my least favorite subject (capitalism).

The McMansion Hell Yearbook: 1976

Howdy, folks! Today’s house comes to us from my newly adopted county of Cook County, Illinois, and boy can this baby fit so many 70s house stereotypes in it. 

It’s got everything: weird spanish colonial revivalism, an external layout that can only be described as post-split-level, a 3 car garage, and it’s brown! This lovely 5 bedroom, 5 bath 5200 square foot estate is relatively affordable by McMansion Hell standards, coming in at around $600,000. There’s a lot of house to cover, so let’s get the ball rolling! 

Lawyer Foyer

This foyer has all the elements of a contemporary lawyer foyer (large chandelier, grand staircase, two stories) except for the oversized transom window over the front door. The fact that the house looks like a split-level on the outside is interesting because it’s a regular two-story house on the inside, furthering the hypothesis that the Lawyer Foyer itself is an offshoot of the 1.5 and two-story entrances present in split levels. In many ways this house is a transitional example nestled between two eras: the split-level/ranch of the 70s and the two-story neo-eclectic houses that would become popular in the 1980s. 

Sitting Room

Fun fact: a look at recent IKEA catalogs demonstrates that the grandma couch is slowly wedging its way back into America’s living rooms. 

Dining Room

I am weeping with envy at those chairs. (Instagram story vagueposting voice) Some people just don’t know what they have. 

Living Room

The overstuffed leather sofas might not be pretty but they are authentic.


Why I hate the kitchen island/peninsula stovetop recapped:
- can’t use the island for seating bc cooking stuff is hot and steamy
- one casual lean and you’re burned
- no backsplash to catch like overboiling pasta sauce
- wastes valuable counter space

I can go on.

Master Bedroom

Personally if I had all that extra space in my bedroom I’d put something cool like a pool table or a hot tub in there bc why not???

Speaking of tubs…

Master Bath

One must wonder why brown bathroom fixtures exist in the first place because frankly it’s not a very flattering color considering the functions. Let’s just say it was a different time. 

Bedroom 2

As someone who grew up in the era of Toyota Corolla hegemony, 70s cars are extremely funny to me - like they take up half a block and get 4 miles to the gallon??? No wonder there was an oil crisis!!! 

Bedroom 3

The virgin midcentury modern collector vs the chad grandma using a 1967 teak Dunbar sideboard as a display case for their doily collection 


This whole post is a ploy to get the zoomers to watch Cheers

Alright folks, our little house tour has come to a close - it’s time for our favorite part:

Rear Exterior

(looking enviously at other countries with functioning governments beginning to open back up): yeah ok you do you, i’m just gonna watch the tour de france in a bathrobe and rank the teams based on how cancelled their sponsors are.

Well that does it for 1976! Join us soon for another installment of the Brutalism Post and keep your eyes peeled for whatever wretched house the year 1977 has bestowed upon this cursed land. 

I know that these are economically uncertain times, but many creators including myself depend on Patreon for most of their income, so if you have a minimum of $12/year to spare and are into bonus content, then do I have some good news for you:

If you like this post, and want to see more like it, consider supporting me on Patreon!

There is a whole new slate of Patreon rewards, including: good house of the month, an exclusive Discord server, weekly drawings, monthly livestreams, a reading group, free merch at certain tiers and more!

Not into recurring donations but still want to show support? Consider the tip jar! (Tips are much appreciated since I am making a cross country move in two weeks!!!)

Or, Check out the McMansion Hell Store! Proceeds from the store help protect great buildings from the wrecking ball.

The McMansion Hell Yearbook: 1975

Howdy, folks! We’re halfway through the 70s, and I thought I’d celebrate with a time capsule house stuck weirdly enough, in the 80s. Our house this time comes to us from Fairfield County, Connecticut, and while it may not be an obvious contender on the exterior, I promise you won’t be disappointed once we head through that door. 

This house, despite its modest exterior, boasts 4 bedrooms, 4.5 bathrooms, and just over 5300 square feet. It can be yours for just over $2.2 million USD.  I know you’re dying to see what’s inside, so I won’t keep you any longer.

Lawyer Foyer

As you can see, painting the walls white did not take the 70s out of this house. The disappointing part is that this is the room with the most vestiges of its 70s past - that wrought iron railing, pink linoleum, and pseudo-gothic chandelier definitely affirm that originally this house was much, much groovier before its 80s redux. 

Great Room

The realtor described this house as “transitional” which in some cases is a polite way of saying “trapped between stylistic movements and terrified to death of choosing one.” 

Sitting Room

Alright, alright, here’s one for the 80s aesthetic blogs. You’re welcome. 

Dining Room

As a form of economic stimulus, I am willing to accept giant cabinets and twee bird knickknacks. Speaking of giant cabinets, that one is, like, hearse-sized. How many candelabras and cloth napkins could one family possibly possess? 

Also, for some reason, the listing did not include any pictures of the kitchen, so we’ll have to go right into the master bedroom. 

Master Bedroom

Even in the 80s, was there ever a time where this aesthetic didn’t look, well, grandmotherly?

Bedroom 2

I’m moving in a few weeks and my back hurts just thinking about trying to lift that furniture!!!!

Bonus Room

I have to give credit where credit is due: this room is cool, and I would absolutely chill in it. Which goes to prove how deeply uncool these rich people are for not using it for chilling or any other activities. 

Rec Room

The drop-ceiling/can light combo is somewhat rare in terms of McMansion bonus rooms, as is that diagonal wood paneling which I unironically stan. Forget shiplap!!!

Alright, that’s it for our interior. Now to check out the rear exterior which proves once and for all that this house is, in fact, a McMansion. 

Rear Exterior

Honestly, I don’t know what kind of house this is - my guess is that it’s, like, a post-split-level, whatever that means. Either way, it’s super tacky and I’m glad I found it so I could share it with all of you. Check back here soon for another 70s house, as well as a much-needed update to the Brutalism Post. 

I know that these are economically uncertain times, but many creators including myself depend on Patreon for most of their income, so if you have a minimum of $12/year to spare and are into bonus content, then do I have some good news for you:

If you like this post, and want to see more like it, consider supporting me on Patreon!

There is a whole new slate of Patreon rewards, including: good house of the month, an exclusive Discord server, weekly drawings, monthly livestreams, a reading group, free merch at certain tiers and more!

Not into recurring donations but still want to show support? Consider the tip jar! (Tips are much appreciated since I am making a cross country move in two weeks!!!)

Or, Check out the McMansion Hell Store! Proceeds from the store help protect great buildings from the wrecking ball.

#HousingLIVE Join The New Republic’s Kate Wagner for a special after-hours live action version of her satirical McMansion Hell blog. July 14, 2020 at 5.30pm EDT.

#HousingLIVE Join The New Republic’s Kate Wagner for a special after-hours live action version of her satirical McMansion Hell blog. July 14, 2020 at 5.30pm EDT.:

Howdy! Join me at the NewCities New Housing Solutions conference (along with much more important people like Ilhan Omar) where I’ll be roasting buildings and raising money for Moms4Housing! Link to submission and registration above. 

Design in Dialogue - Exhibitions - Friedman Benda

Design in Dialogue - Exhibitions - Friedman Benda:

Howdy folks! Join me on Design in Dialogue tomorrow (Monday, June 15th) at 11AM EDT for a (Zoom) talk on the best and worst impulses in contemporary architecture. More info and RSVP in link. 

How Normie Minimalism and Farmhouse Chic Took Over Contemporary Design

How Normie Minimalism and Farmhouse Chic Took Over Contemporary Design:

Hello! I wrote for Hyperallergic about how minimalism went from high design to normie chic. 

Coronagrifting: A Design Phenomenon

We now interrupt our regularly scheduled content to bring you a critical essay on the design world. I promise you that this will also be funny. 

This morning, the design website Dezeen tweeted a link to one of its articles, depicting a plexiglass coronavirus shield that could be suspended above dining areas, with the caption “Reader comment: ‘Dezeen, please stop promoting this stupidity.’”


This, of course, filled many design people, including myself, with a kind of malicious glee. The tweet seemed to show that the website’s editorial (or at least social media) staff retained within themselves a scintilla of self-awareness regarding the spread a new kind of virus in its own right: cheap mockups of COVID-related design “solutions” filling the endlessly scrollable feeds of PR-beholden design websites such as Dezeen, ArchDaily, and designboom. I call this phenomenon: Coronagrifting. 

I’ll go into detail about what I mean by this, but first, I would like to presenet some (highly condensed) history. 

From Paper Architecture to PR-chitecture

Back in the headier days of architecture in the 1960s and 70s, a number of architectural avant gardes (such as Superstudio and Archizoom in Italy and Archigram in the UK) ceased producing, well, buildings, in favor of what critics came to regard as “paper architecture. This “paper architecture” included everything from sprawling diagrams of megastructures, including cities that “walked” or “never stopped” - to playfully erotic collages involving Chicago’s Marina City. Occasionally, these theoretical and aesthetic explorations were accompanied by real-world productions of “anti-design” furniture that may or may not have involved foam fingers


Archigram’s Walking City (1964). Source.

Paper architecture, of course, still exists, but its original radical, critical, playful, (and, yes, even erotic) elements were shed when the last of the ultra-modernists were swallowed up by the emerging aesthetic hegemony of Postmodernism (which was much less invested in theoretical and aesthetic futurism) in the early 1980s. What remained were merely images, the production and consumption of which has only increased as the design world shifted away from print and towards the rapidly produced, easily digestible content of the internet and social media. 


Architect Bjarke Ingels’s “Oceanix” - a mockup of an ecomodernist, luxury city designed in response to rising sea levels from climate change. The city will never be built, and its critical interrogation amounts only to “city with solar panels that floats bc climate change is Serious”  - but it did get Ingels and his firm, BIG, a TED talk and circulation on all of the hottest blogs and websites. Meanwhile, Ingels has been in business talks with the right-wing climate change denialist president of Brazil, Jair Bolsonaro. (Image via designboom

Design websites are increasingly dominated by text and mockups from the desks of a firm’s public relations departments, facilitating a transition from the paper-architecture-imaginary to what I have begun calling “PR-chitecture.” In short, PR-chitecture is architecture and design content that has been dreamed up from scratch to look good on instagram feeds or, more simply, for clicks.  It is only within this substance-less, critically lapsed media landscape that Coronagrifting can prosper.

Coronagrifting: An Evolution

As of this writing, the two greatest offenders of Coronagrifting are Dezeen, which has devoted an entire section of its website to the virus (itself offering twelve pages of content since February alone) and designboom, whose coronavirus tag contains no fewer than 159 articles. 

Certainly, a small handful of these stories demonstrate useful solutions to COVID-related problems (such as this one from designboom about a student who created a mask prototype that would allow D/deaf and hard of hearing people to read lips) most of the prototypes and the articles about them are, for a lack of a better word, insipid. 

But where, you may ask, did it all start?

One of the easiest (and, therefore, one of the earliest) Coronagrifts involves “new innovative, health-centric designs tackling problems at the intersection of wearables and personal mobility,” which is PR-chitecture speak for “body shields and masks.” 

Wearables and Post-ables

The first example came from Chinese architect Sun Dayong, back at the end of February 2020, when the virus was still isolated in China. Dayong submitted to Dezeen a prototype of a full mask and body-shield that “would protect a wearer during a coronavirus outbreak by using UV light to sterilise itself.” The project was titled “Be a Bat Man.” No, I am not making this up. 


Screenshot of Dayong’s “Be a Batman” as seen on the Dezeen website. 

Soon after, every artist, architect, designer, and sharp-eyed PR rep at firms and companies only tangentially related to design realized that, with the small investment of a Photoshop mockup and some B-minus marketing text, they too could end up on the front page of these websites boasting a large social media following and an air of legitimacy in the field

By April, companies like Apple and Nike were promising the use of existing facilities for producing or supplying an arms race’s worth of slick-tech face coverings. Starchitecture’s perennial PR-churners like Foster + Partners and Bjarke Ingels were repping “3D-printed face shields”, while other, lesser firms promised wearable vaporware like “grapheme filters,” branded “skincare LED masks for encouraging self-development” and “solar powered bubble shields.” 

While the mask Coronagrift continues to this day, the Coronagrifting phenomenon had, by early March, moved to other domains of design. 

Consider the barrage of asinine PR fluff that is the “Public Service Announcement” and by Public Service Announcement, I mean “A Designer Has Done Something Cute to Capitalize on Information Meant to Save Lives.” 

Some of the earliest offenders include cutesy posters featuring flags in the shape of houses, ostensibly encouraging people to “stay home;” a designer building a pyramid out of pillows ostensibly encouraging people to “stay home”; and Banksy making “lockdown artwork” that involved covering his bathroom in images of rats ostensibly encouraging people to “stay home.” 


Lol. Screenshot from Dezeen. 

You may be asking, “What’s the harm in all this, really, if it projects a good message?” And the answer is that people are plenty well encouraged to stay home due to the rampant spread of a deadly virus at the urging of the world’s health authorities, and that these tone-deaf art world creeps are using such a crisis for shameless self promotion and the generation of clicks and income, while providing little to no material benefit to those at risk and on the frontlines.

Of course, like the mask coronagrift, the Public Service Announcement coronagrift continues to this very day

The final iteration of Post-able and Wearable Coronagrifting genres are what I call “Passive Aggressive Social Distancing Initiatives” or PASDIs. Many of the first PASDIs were themselves PSAs and art grifts, my favorite of which being the designboom post titled “social distancing applied to iconic album covers like the beatle’s abbey road.” As you can see, we’re dealing with extremely deep stuff here. 

However, an even earlier and, in many ways more prescient and lucrative grift involves “social distancing wearables.” This can easily be summarized by the first example of this phenomenon, published March 19th, 2020 on designboom


Never wasting a single moment to capitalize on collective despair, all manner of brands have seized on the social distancing wearable trend, which, again, can best be seen in the last example of the phenomenon, published May 22nd, 2020 on designboom:


We truly, truly live in Hell. 

Which brings us, of course, to living. 

“Architectural Interventions” for a “Post-COVID World”

As soon as it became clear around late March and early April that the coronavirus (and its implications) would be sticking around longer than a few months, the architectural solutions to the problem came pouring in. These, like the virus itself, started at the scale of the individual and have since grown to the scale of the city. (Whether or not they will soon encompass the entire world remains to be seen.) 

The architectural Coronagrift began with accessories (like the designboom article about 3D-printed door-openers that enable one to open a door with one’s elbow, and the Dezeen article about a different 3D-printed door-opener that enables one to open a door with one’s elbow) which, in turn, evolved into “work from home” furniture (”Stykka designs cardboard #StayTheF***Home Desk for people working from home during self-isolation”) which, in turn, evolved into pop-up vaporware architecture for first responders (”opposite office proposes to turn berlin’s brandenburg airport into COVID-19 ‘superhospital'”), which, in turn evolved into proposals for entire buildings (”studio prototype designs prefabricated 'vital house’ to combat COVID-19″); which, finally, in turn evolved into “urban solutions” aimed at changing the city itself (a great article summarizing and criticizing said urban solutions was recently written by Curbed’s Alissa Walker).


There is something truly chilling about an architecture firm, in order to profit from attention seized by a global pandemic, logging on to their computers, opening photoshop, and drafting up some lazy, ineffectual, unsanitary mockup featuring figures in hazmat suits carrying a dying patient (macabrely set in an unfinished airport construction site) as a real, tangible solution to the problem of overcrowded hospitals; submitting it to their PR desk for copy, and sending it out to blogs and websites for clicks, knowing full well that the sole purpose of doing so consists of the hope that maybe someone with lots of money looking to commission health-related interiors will remember that one time there was a glossy airport hospital rendering on designboom and hire them. 

Enough, already. 

Frankly, after an endless barrage of cyberpunk mask designs, social distancing burger king crowns, foot-triggered crosswalk beg buttons that completely ignore accessibility concerns such as those of wheelchair users, cutesy “stay home uwu” projects from well-to-do art celebrities (who are certainly not suffering too greatly from the economic ramifications of this pandemic), I, like the reader featured in the Dezeen Tweet at the beginning of this post, have simply had enough of this bullshit

What’s most astounding to me about all of this (but especially about #brand crap like the burger king crowns) is that it is taken completely seriously by design establishments that, despite being under the purview of PR firms, should frankly know better. I’m sure that Bjarke Ingels and Burger King aren’t nearly as affected by the pandemic as those who have lost money, jobs, stability, homes, and even their lives at the hands of COVID-19 and the criminally inept national and international response to it. On the other hand, I’m sure that architects and designers are hard up for cash at a time when nobody is building and buying anything, and, as a result, many see resulting to PR-chitecture as one of the only solutions to financial problems. 

However, I’m also extremely sure that there are interventions that can be made at the social, political, and organizational level, such as campaigning for paid sick leave, organizing against layoffs and for decent severance or an expansion of public assistance, or generally fighting the rapidly accelerating encroachment of work into all aspects of everyday life – that would bring much more good and, dare I say, progress into the world than a cardboard desk captioned with the hashtag #StaytheF***Home. 

Hence, I’ve spent most of my Saturday penning this article on my blog, McMansion Hell. I’ve chosen to run this here because I myself have lost work as a freelance writer, and the gutting of publications down to a handful of editors means that, were I to publish this story on another platform, it would have resulted in at least a few more weeks worth of inflatable, wearable, plexiglass-laden Coronagrifting, something my sanity simply can no longer withstand. 

So please, Dezeen, designboom, others – I love that you keep daily tabs on what architects and designers are up to, a resource myself and other critics and design writers find invaluable – however, I am begging, begging you to start having some discretion with regards to the proposals submitted to you as “news” or “solutions” by brands and firms, and the cynical, ulterior motives behind them. If you’re looking for a guide on how to screen such content, please scroll up to the beginning of this page. 


If you enjoyed this article, please consider subscribing to my Patreon, as I didn’t get paid to write it.  

i drew another thing!

i drew another thing!