|Ned Batchelder : Blog | Code | Text | Site|
54 can be written as the sum of three squares in three different ways:
It is the smallest number with this property.
Also, a Rubik's cube has 54 colored squares.
I just got back from PyCon 2016, and it was a giant summer camp love-fest as usual. But I've been thinking about a subtle and unfortunate dynamic that I saw a few times there.
In three different cases, I was with a group of people, and one person in particular had a disproportionate amount of air-time. They were different guys each time, but they just had a way of being the one doing more talking than listening, and more talking than others. In some cases, they were physically loud, but I don't always mean literally the loudest.
These weren't bad people. Sometimes, they were explicitly discussing the need to include others, or improve diversity, or other good impulses. They weren't trying to dominate the space, and they might even be surprised to hear that they were.
But I found myself cringing watching their interactions with others. Even when they thought they were being encouraging, I felt like they were subtly pushing others aside to do it. Keep in mind, this was at PyCon, one of the most explicitly inclusive places I frequent.
I'm a successful white guy, so I know it can be very easy to slip into the alpha male stance. Sometimes people expect it of me. It can be hard to tamp down the impulse to hold forth, letting others have the spotlight. But it's important, and a good exercise for yourself. It's fine to be able to be at the front of the room, but you should be able to turn it off when needed, which is more often than you would think.
Sometimes, this was in a men-only setting. It's great to be aware of the gender gap, but there are other kinds of gaps to consider also: non-native speakers, introverts, beginners, outsiders of various sorts. There are lots of reasons people might be quiet, and need a little room.
Ask questions instead of making statements. Stay quiet, and see what happens. Listen rather than speak. Even when it seems no one is going to say anything, wait longer than you are comfortable. See what happens. Leave space.
Next time you are in a group of people, look around and try to figure out who is the loudest guy in the room. If you aren't sure, then maybe it's you.
I gave a talk today at PyCon 2016: Machete-Mode Debugging. I went over time, but people really liked it. Amazingly, the video was available within six hours!
Gratifyingly, a talk later in the day referenced the phrase "machete-mode debugging," so maybe it will catch on.
Coverage.py 4.1 is out!
I'm not sure what else to say about it that I haven't said a few times in the last six months: branch coverage is completely rewritten, so it should be more accurate and more understandable.
The beta wasn't getting much response, so I shielded my eyes and released the final version a few days ago. No explosions, so it's seems to be OK!
Often, when I am headed to bed, I stop in at my son Ben's room, to see what he's up to. He'll be working on some piece of art, and we'll chat for a moment about it.
The other night, he was working on a self-portrait. It was a realistic depiction, but in a style reminiscent of a Renaissance prince. We talked about the style, what parts looked just like him, and what parts might need tweaking.
I went to bed, and then in the morning this was on his Facebook:
I didn't get a story about why the realistic face was gone, and why the self-homunculus is in its place instead. This picture looks much less like him, but says much more about him. He changed it from a picture of him to a picture about him. Ben has always impressed me with his art, not just as a technical skill, but as an expression of deeper ideas.
As always, I am proud of him, and thrilled to see what he creates.
Python has a compact syntax for constructing a list with a loop and a condition, called a list comprehension:
You can also build dictionaries with dictionary comprehensions, and sets with set comprehensions:
(The syntax allows more complexity than these examples, let's not get distracted!)
Finally, you can make a generator with similar syntax:
Unfortunately, this is called a generator expression, not a generator comprehension. Why not? If the first three are all comprehensions, why isn't this a comprehension?
PEP 289, Generator Expressions has detailed notes at the end which point out that Raymond Hettinger originally proposed "generator comprehensions," that they were then resurrected by Peter Norvig as "accumulation displays," and that Tim Peters suggested the name "generator expressions." It does not explain why the names changed along the way.
I made a query on Twitter:
Guido's reply gets at the heart of the matter:
Matt Boehm found the email where Tim Peters proposed "generator expression" that also has some details.
After reading that, I understand more. First, what's with the word "comprehension"? As Tim pointed out, the word comes from set theory's Axiom of Comprehension, which talks about sets formed by applying a predicate (condition) to elements of another set. This is very similar to lists formed by applying a condition to elements of another sequence.
As Guido's tweet points out, and the subject line of the email thread makes clear ("accumulator display syntax"), the designers at the time were thinking much more about displays than they were about conditions. The word "display" here means that the syntax for the code looks like the data structure it will create. A list display (list comprehension) looks like a list. Same for set and dictionary displays. But there is no generator literal syntax, so there's nothing for a generator display to look like, so there are no generator displays.
In that original email thread designing the feature, the word "comprehension" became synonymous with "display", and since generators couldn't have displays, they also couldn't have comprehensions.
But as Tim points out in his email, the interesting part of a comprehension is the condition. The heart of the Axiom of Comprehension is the predicate. Perhaps because the condition is optional in a Python comprehension, the focus shifted to the display aspect.
I think we should call them "generator comprehensions" again. We don't use the term "display" for these things. There's no reason to link "comprehension" to "display," and literal syntax.
The four different expressions (list comprehension, dict comprehension, set comprehension, and generator expressions) have an awful lot in common with each other. It would be a great shorthand to be able to discuss their similarities by talking about "comprehensions" and having it cover all four. Their similarities are more than their differences, so let's use the same word for all four.
Proposal: call them "generator comprehensions."
Work on Coverage.py 4.1 is continuing: beta 3 is available.
If you haven't used any of the 4.1 betas, the big change is that branch coverage has been completely rewritten. The new code produces much more reliable results, and has allowed me to implement things like better support for lambdas. Eleven bugs with branch coverage have been fixed.
The HTML report has a cool new feature, contributed by Dmitry Shishov, a map in the scrollbar of where the highlighted lines are, so you can quickly drag to where you need to look. (By the way, there are also keyboard shortcuts to do that, have been for a long time!)
One small backward-incompatibility: if you've been using the API, and calling the Coverage.report function, the default for the show_missing parameter has changed.
Try Coverage.py 4.1b3 and let me know what you think.
Now, the truth about Coverage.py: I think it could be much better. There are lots of things about the internals that I don't like. I think the classes could be refactored better. Too many of the tests are integration tests rather than unit tests. Too many real-world scenarios aren't covered by tests. I'm not good at staying on top of the pull requests and issues. If you think you could help with any of this, get in touch.
I have two great juggling videos to share: two jugglers, each great in his own way.
First: Alexander Koblikov. He is a great professional juggler, currently with the Big Apple Circus. He has a smooth evocative style with a small number of balls, starting with simple contact moves, but growing to flawless five-ball work. Then he can show off raw power with nine-ball multiplexes. A very impressive combination of both ends of the professional spectrum:
Kota Hayashi is very different. He's an amateur juggler, performing at the International Juggler's Association convention. He isn't wearing any particular costume, his act has no story. He's not a poker-faced artiste, and he only juggles three balls. He's a good juggler, but more importantly, he just obviously loves juggling. His enthusiasm is infectious. As you watch his act, it gets a bit ridiculous. You start to think, this is silly. But really, isn't juggling silly to begin with? Why do we throw objects around in fancy patterns? There's no point to it, other than our own amusement. Kota's act is a visible embodiment of the pure pleasure of mastering an absurd skill for its own sake.
Skip ahead to 1:05 where Kota starts:
And because I can't stop watching juggling videos, here are two bonus jugglers showing two more completely different styles:
A little over a week ago, a nephew-of-sorts of mine died in a fall. He was almost 19, a freshman at Tufts. It was tragic, and senseless, and horrifying. The funeral was Sunday, and he's been on my mind a lot.
To be honest, I didn't know Alex that much. We saw each other at most once a year, and usually less frequently. I learned more about Alex at his funeral than I had over the years of rote greetings at family gatherings. He was a smart, generous, energetic guy (boy? man?)
When I think about Alex's death, of course I think about him, and his too-short life, and his final hours. I think about his parents, and what they must be going through, and I wonder if I could handle such a loss.
I think about my own children and I think about parenthood: the enormous commitment, energy, love, and work that goes into shaping and guiding these new people. The pain and fear of sending them off into the world, away from your protective watch. It's difficult in the best of times.
Alex's death was painful not only because we lost Alex, but because it was a brutal reminder that we can lose anyone, at any time, with no notice. It's easy to imagine a nearby parallel universe where it was one of my sons instead of him.
At the funeral, Alex's dad recounted an uncle's similar loss. The uncle's wisdom was that we will not find a reason for Alex's death, but that we will find meaning in life.
I come back again to Kurt Vonnegut's son Mark, answering, and neatly side-stepping, the question of meaning: "We're here to get each other through this thing, whatever it is."
Take care of each other.
If you use Slack, or read docs on Read The Docs, you've seen Lato. It's a free high-quality font. I like it a lot, but it has a feature that bugs me a lot: the f-i ligature:
If you've never looked into this before, a ligature is a combination of letters that are designed as a new distinct glyph. In this case, there's an "fi" shape that is used when you have an "f" and an "i" next to each other.
Ligatures have a long tradition in Latin fonts, for a reason: some pairings of letters can have a jarring look. The bulb of the f and the dot of the i can clash, and it looks better to design a combined shape that shares the space better.
But Lato doesn't suffer from this problem. Ligatures are a solution to a problem, and here they are being used when there is no problem to solve. The Lato fi ligature is more jarring than the f and the i, because it looks like there's no dot for the i.
Here's a comparison of the fi ligature in some fonts. The first column is a plain f and i presented naturally, but forced to be individual, naively. Then the fi combination as the browser text renderer draws them, and then the Unicode fi ligature, U+FB01 (LATIN SMALL LIGATURE FI):
The naive Lato f and i look fine together without any intervention. The ligature looks silly without the dot. The f is trying to reach over to join the dot, but it's too far to reach, so it doesn't get there, and the f has no bulb in the first place. It doesn't make any sense.
Constantia and Georgia demonstrate a good use of ligatures: the naive pairing shows how the bulb and the dot crowd into each other, and the ligatures shift things a little to resolve the clash.
(Somehow, Lato doesn't map its fi ligature to the U+FB01 code point, so we get the default font there instead.) If you want to experiment, here's the HTML file I used to make the image.
By the way, it was an interesting challenge to get the browsers to display the unligatured f-i pairs. In Firefox, I used a zero-width space (U+200B) between the characters. But Chrome substituted the ligature anyway, so I tried putting the f and the i in adjacent spans. This worked in Chrome, but Firefox used the ligature. So I combined both methods:
I got an email from a mom last week:
I told her I couldn't meet one-on-one, but suggested they attend the upcoming Boston Python project night. I didn't know what would come of it. Project night is completely unstructured, an opportunity to hang out with other Python people. It's a complete jumble of all kinds of people. There's no guarantee you'll find what you need there, but there's a good chance you will.
Last night was the project night, and there they were! They sat down at one of our beginning learner tables, and others joined them. I didn't have a chance to sit and talk with them at length, but I could see they had the attention of helpers, including John, one of the regulars. Each time I looked over, John was in deep discussion with the kid.
While talking to someone else last night who was interested in game programming, I looked up the game that originally got the mom's attention: I posted Nat's World to this site 13 years ago today!
The mom and the kid said goodbye to me when they had to go. She seemed pleased, and he did too, in his quiet but eager way. I told him, "That makes me happy."
As the night was winding down, I caught up with John, who was talking to a few others. "That kid was amazing!" he said. "I know, that was so cool," said someone else.
This is what makes local user groups so great. I don't know what John was expecting to do with his evening. I don't know what the mom and the kid were expecting when they decided to come. But they made a connection, got some help, and made an impression on each other. People across the room who didn't even talk to the mom or the kid came away with an unexpected picture of what the Python community can be like: broader and more diverse, more welcoming than the stereotype of a tech user group filled with brogrammers.
And this is also what is cool about making things and putting them online. Nat's World was a fun project when I made it. I haven't run it in years, but my family still remembers it fondly. When I first posted it, I had a few nibbles of interest from people, but it was only a little side project, I could have just as easily not put it on my site.
In the way of the internet, Nat's World had receded into the past, an old post unlikely to get any further attention. The code doesn't even run any more. But someone found it, and because of it they got in touch, and they got to a project night, and connected with other people, and who knows where it will all lead?
I was in the library yesterday, and wandered into the Brookline room, where books particular to Brookline are kept. They have annual town directories going back more than a century. I pulled one down and looked up my street address.
Of course, when we bought the house, the realtor had little stories about previous occupants. We were told it was built by a Cabot, and that he was a bachelor.
The town records gave me two names: John H. Cabot, and F. Ernest Cabot, living in the house in 1905. Googling around a little bit, I found a notice about John H's death:
Is it safe to say that today he would be out of the closet? It goes on:
I love that line: a distaste for retrospect!
"His chamber!" That's a room in our house! Of course living in an old house, you know that people have lived there before, had entire lives there, and felt as proprietary and private about the house as you do. But this sentence somehow made it much more real. This weekend as I have moved through my house, I've been more aware that others have preceded me.
A little more digging shows that John H. is buried in Mt. Auburn cemetery, along with some close family, so in the spring I may look them up...