My Heights Observer letter: The Elected Mayor Issue is really about discontent with status quo

The Heights Observer was nice enough to print my letter in the September 2019 issue.

Here’s the text:

First off, I want to say there are bright and conscientious people making some good arguments for why the city-manager system is right for our city.

Second, I’m not a political science expert, but I’ve researched this topic, and it is clear that successful and unsuccessful cities exist with a variety of structures.

Third, I want to say that the people arguing for preserving the system are utterly missing the bigger picture.

If people were largely content, there is no way a handful of part-time volunteers would have been able to get this far.

Ask your activist friends just how much work it is to gather 4,000 signatures. Consider how many years you have lived in the Heights, and consider all the petitions you’ve been asked to sign in the past. How many of those went anywhere? The vast majority of the time, these projects never go anywhere.

But this Citizens for an Elected Mayor (CEM) issue tapped into a deeper sense of pessimism and dissatisfaction with our city leadership. If people were generally content, the adage “If it ain’t broke, don’t fix it” would make this effort impossible.

The popularity of CEM’s issue shows many believe that “it is broke,” so they’re eager for change.

My suggestion to the folks who want to keep things as-is: quit saying it could always be worse. That’s like Candide claiming that this is the best of all possible worlds*. Instead, acknowledge the grumbling! Acknowledge that the status quo is not satisfying enough people, and then describe a new inspiring plan. Offer something new to inspire hope.

* Normally I wouldn’t use a pretentious literary reference, but since this is the Heights, I figure y’all would get it. That’s why I love it here.

I don’t like the new Cleveland Heights slogan “we choose this”

My town, the city of Cleveland Heights, wants to brand itself. Not with a hot poker, but with a new logo and slogan.

You can read about the proposed logos here.

They came up with the slogan “We choose this” and a few different logos.

Most of the public reaction that I have seen to the slogan “we choose this” has been negative.

I think that the folks that proposed “we choose this” are trying to express the notion that the people that call Cleveland Heights home have other options but are proud to live here, by choice.

Here’s the thing: that’s just not that factual. Net population in Cleveland Heights is falling. People are choosing to leave.

There are neighborhoods in our region where people are choosing to move. Look at downtown for example, or the Detroit Shoreway area. People are moving in and buying up old properties.

I’m in Cleveland Heights and I’m not a bitter curmudgeon. I think there are some wonderful things going on here. But we need to step our game.

I’d rather that the slogan references how we welcome a wide range of people here, and we want to improve ourselves without abandoning our history.

But “we choose this” comes off more like “love it or leave it”.

Notes from Fight To Win 32 in Cleveland

I noticed a few themes at last night’s Fight To Win 32:

  1. Takedowns are hard unless you’re Darren Branch. I am pretty sure he landed more takedowns in his match (which was like the 20th match) than in all previous fights summed up.
  2. A few fighters hopped back up to their feet once the fight went to the ground, and it usually led to good things. BJJ exposes how other martial arts don’t train what to do when the fight hits the floor. Last night exposes how few fighters can keep the fight on the floor, except when both sides agree to play along.
  3. A good part of the crowd (the casual fans) stop watching when the match begins with one fighter pulling half guard. If the goal is selling tickets, I can understand discouraging this stuff.
  4. Fundamental whitebelt stuff like guard recovery / retention, mount escapes, and surviving in bad positions define the game at all skill levels. This sport really is a lot like chess. You learn the basics quickly and then spend a lifetime mastering them.
  5. Classic submisssions like triangles, cross chokes, and kimura attacks were just as effective and popular as heel hooks at finishing fights.
  6. The crowd was great! I brought my 12-year-old kid there and he had a wonderful time. I never saw any drunk meathead behavior. In fact, the crowd was absolutely quiet during a lot of matches.

Gassing the glitterati

I wrote this like five years ago. Never posted because the missus didn’t like it.

Went to a fancy benefit dinner last night. A gala to raise money for some hospital. Somebody else bought a table and we went. Frank Jackson and some banker dorks were there, talking about a bunch of nonsense, but they were at table 1 and we were at table 890541 or so.

I’m allergic to places like this. Nobody wants to talk about UFOs and everybody wants to know where I went to college.

My wife knows me well enough and on the way in says “can you just turn down the matthew a little tonight?” I think this was after I told her I would pretend to be “square deal” Sam Beauregarde*.

But I can’t be turned down. The matthew comes out in a different way.

Dreading this all week. So I decided to have some fun. In the late afternoon I gorged on a quart of old brown guacamole and a cold can of refried beans. Then at the event, during the otherwise tedious cocktail hour, I ate as many appetizers as I could. Especially anything with soft cheese or bacon or horseradish. Unfortunately no brassica vegetables were available.

During dinner we sat through some boring speeches by Cleveland’s wealthiest, congratulating themselves on drinking champagne (literally) to help those less fortunate.

But no matter. My GI tract was hard at work. Like that Magician in the Disney film Fantasia. I had set my belt extra loose initially but now I felt like Violet Beauregarde after she chewed that forbidden gum and started swelling up into a blueberry**.

By now I had enough renewable wind energy going to crop dust who’s who in Cleveland last night once the band started playing really loud. Over and over and over.

Check the society pages for photos of rich old folks trying to smile while holding their nose. Now you know the real story.

My greatest regret was failing to meet / fumigate the mayor. He was encircled by too many sycophants. But the good news is that there’s still plenty of poor people that need help and we’re now on all sorts of mailing lists.

So if you ever see me at one of these events, and I’m double-fisting stuffed cabbage canapes, just wink and make sure to sit by a window.

[*] Violet Beauregarde’s dad in Charlie and the Chocolate Factory

[**] that makes two wonka references in the same post! James Joyce*** has nothing on me.

[***] fun James Joyce fact — he got turned on by farts. So that’s why I picked him for that literature dis.

Notes from Cleveland code retreat

I attended the day-long Code Retreat at Lean Dog’s floating office on Sunday.

We worked in pairs for 45-minute blocks of time, building Conway’s Game of Life. In each session, we started from the beginning. We didn’t build on previous code.

After each session, teams talked about what stuff they discovered. Then we reorganized into new pairs and started working from the beginning again.

First pairing

At first I paired with a C# developer. While other teams went right into writing test programs, we spent a fair amount of time talking and sketching out ideas about how to model the game.

Then we made a grid that knew how to generate the next state just by copying itself into a new grid.

We planned to add in code to support each of the four rules of the game of life one by one.

So, we wrote a test that created a grid with just a single living cell. Then we told that grid to make a grid for the next generation, and our test verified that the single cell survived the copy.

Then we started working on the first rule: if a cell is alive and has less than two neighbors, it dies.

We burned through the reminder of time sketching out ideas on my clipboard. By the end of our time, it was clear that we only needed to pay attention to living cells and neighbors of living cells.

It was also clear that the time spent writing the first test and then writing the code to satisfy the first test did nothing to move us toward a real solution.

Second pairing

Next I worked with a Java guy. This time, we did something a little closer to TDD.

We decided to start from the point of view of an end-user firing up the game. The user would want to make a grid, add a few living cells, and then tell the grid to generate its next state.

The first code we wrote was a test and we started writing tests almost immediately. In the test, we instantiated a Grid class. That test blew up with an error, since no Grid class existed. So then we wrote a grid class. It had no methods or attributes, but that was all we needed to write in order to satisfy our test.

Next we wrote a new test that instantiated a grid and then added a single cell by calling an (undefined) addCell(…) method.

After seeing that test crash with an error, we wrote an addCell(…) method that was a no-op, because that’s all our tests required us to do.

Then we wrote a test for rule one, where a living cell with less than two neighbors dies.

In this test, we made a grid, added a single cell, and then told the grid to create a new grid that represented itself in the future. Then we used an assert to verify the new grid had no cells.

First we added a “cells” instance-level ListArray attribute to our grid class. Then we wrote a generate_next_grid method on our grid class, and all that did was instantiate and return a new grid with an empty cells.

And bingo, we had enough code again to pass our test.

At this point, I became convinced that the kind of testing we were doing was harming our productivity. We had fallen into some kind of xeno’s paradox* where we would never actually get anything done, because we could always think of some new test that applied to a trivial subset of the project, and then work on writing code to satisfy that test.

*A dude shoots an arrow at a target. Before the arrow gets to the target, it has to cross half the distance to the target. Then it can cross the other half of the distance. But now it has to cross half of the remaining distance, so it does that.

Then it has to cross half of that remaining distance, and then half of the remaining distance after that, and so on for infinity.

Since the arrow has an infinite number of partial distances to cross, the arrow will never reach the target.

Read more about it here.

I was itching to solve a real problem, rather than just watch lights blink from red to green, so I cajoled my partner into writing a test for the blinker pattern, which is when a 3×1 rectangle of cells converts to a 1×3 rectangle of cells on the second turn, and then on the third turn, converts back to a 3×1 rectangle.

So, we started talking about how to implement the rules. We decided we needed to figure out for every cell that was near a living cell, how many living neighbors it had. So we wrote a method to generate the coordinates for the eight neighboring cell to a particular cell, and wrote a test for that.

Then we were going to make a neighbor_count hashmap attribute on our grid and we were going to use that to link cells to how many neighbors each had, and then the time ran out.

At this point, I had a good feeling about the algorithms involved in solving this project.

Third pairing

Right before the third pairing, a much older fellow raised his hand and asked if anyone wanted to work together on a solution that only tracked the living cells. That’s the approach I was using, so I paired with this guy. He said he didn’t care what language we used, but he was a lousy typist. So I said I could do the typing and we could use python.

At first we excitedly talked over each other and drew pictures until we confirmed we had the same solution in mind. It turned out my partner was an old common lisp hacker, and once he realized that I understood what he meant when he talked about stuff like &rest and cadr, we got along really well.

The first bit of code I wrote was a cell class with an x and a y attribute, and a method to generate a list of eight nearby cells.

I wrote a quick test in the same file as my code for that to make sure the execution was correct.

Of course, that test failed. I had lots of syntax errors because I was writing so fast and defending against good-natured jabs about how vim was so vastly inferior to emacs.

After a few cycles of fixing typos and rerunning the tests, we got the syntax errors out of the code. Then we attacked the project of generating the next state of the grid.

I had already seen how easy it was to write a test for the blinker pattern, so I wrote a quick test for that. The test made a grid with three cells in a vertical rectangle, then told the grid to generate the next state, then it tested that in the next state, the three cells were in a horizontal rectangle.

We wrote a grid class with a dictionary attribute of living cells in the current generation and a dictionary attribute of cells that would live in the next generation.

Then we wrote the function in our grid class to generate another grid. The function did an outer loop on all the living cells, then for each living cell, it looped through all the neighbors of that living cell, and then did an inner loop of all neighbors of that neighbor, and then counted up how many were alive.

Then we implemented the four rules of the game with two if-clauses.

We ran the test again, and of course, the code was again littered with indentation errors and mismatched parentheses because of how fast I had been typing and moving stuff around.

Then the timer went off. I stayed put while everybody was gathering in the middle to talk about how everything went. Within about 30 seconds I got the last few silly typing glitches fixed, and BAM. The test passed.

I walked over to my partner and told him we solved it.

Then we listened to other teams talk. The conversation centered around naming conventions that people were coming up with, like “sustainable neighborhood” and “four horsemen”.

I raised my hand and asked if anybody had written tests for any of the patterns in game of life beyond the blinker pattern, like tests for the glider pattern, or any of the other patterns shown on the wikipedia page.

Nobody replied to that. Instead the conversation shifted to a discussion of whether or not booleans hidden behind getters and setters were a sign of a bad design.

I think it was while somebody was talking about writing tests for their (nonexistent) display code that my partner leaned over and said “This is a drunkard’s search.” Of course, I didn’t know what meant, so he explained it. Here’s the wikipedia entry:

Conducting a drunkard’s search is to look in the place that’s easiest, rather than in the place most likely to yield results. Taken from an old joke about a drunkard who loses his car keys while unlocking his car and is found looking under a streetlamp down the road because the light is better, it has been an object of consideration in the social sciences since at least 1964.

Fourth pairing

I asked if anybody wanted to see a python solution, and four of us worked together, with me doing the typing.

First I described how we would need to find the eight neighboring cells of a particular cell. So I wrote a test for that, and then wrote the code to satisfy that test.

Then once that was finished, I described what the blinker looked like, and I wrote a test for that.

Then I reused the approach that we came up with in the third pairing, and then got it working fairly quickly.

At one point I showed the code we had written to one of the people running the event, and he pointed out two things (this is roughly paraphrased, and I hope I am getting these ideas correct):

  1. I had four if-clauses in a single function, and each if-clause tested two independent variables. So that means there were dozens of paths through the function that would have to be tested.
  2. My blinker test could be satisfied by code that just hardcoded the expected results, rather than built an actual game-of-life system. My test didn’t force a complete solution.

Both points illustrate the biggest difference in the TDD mindset versus whatever it is called that I do. (design by intuition?)

The fact that I didn’t have a test for every path that I created didn’t really concern me, because I was focused on getting the blinker pattern to work. If that blinker pattern test failed, then I might go in to my code and make sure that what I wrote was really what I meant, or maybe I’d even throw it all out and start from scratch. But I wouldn’t worry about covering all corners of this version until I was confident I was on the right track.

As for the second point, I use tests to catch errors, not to tell me what to write. I wouldn’t write code that returns a hard-coded list of values just to pass a test, unless I actually thought I could solve the real problem by doing that.

Anyhow, we got everything working pretty quickly this second time. You can see the output from my fourth pairing here.

After you download that code, you can run the tests like this:

$ python life.py
..
--------------------------------------------------------------------
Ran 2 tests in 0.001s

OK

Those two dots mean that my two tests passed. I spent the remainder of the time showing how to use the interactive interpreter and how to write doctests. I’ve tested a few of the patterns from the wikipedia page, and my code seems to do the right thing, but I’m not absolutely convinced that this implementation is correct.

Fifth pairing

I worked with two guys and we used ruby and rspec. I described the algorithm that I had used in the last two times, and we decided to work on building that.

We went with the approach of not writing any more code than was required to satisfy the tests.

So, first, we wrote some tests to instantiate a cell class, then we wrote some tests to call a neighbors method on the cell class and verify that it return a list of eight things, and then we verified that the first and last and elements in the neighbors list were at the position that we expected them to be at.

Then we started work on the grid class. We wanted to make sure that two different objects with the same values for their x and y attributes would be considered equal. But none of us knew how to redefine the == operator in ruby, and while we were researching this, the time ran out.

Again, I felt like we had fallen into the trap of slicing off trivial subsets of the real problem, and solving them, rather than attacking the real problem.

Commentary

Writing tests to check for errors (which is what I do) is not test-driven development. I daydream about solutions until I find one that I like, and then I build it, and I see if it works by writing tests to cover all the use cases I can think of.

My design comes from idle thoughts and doodles on my notepad, not from the testing.

Final note: I’ve tried my best to keep any generalizations and extrapolations out of this post. I don’t mean for this to be seen as an attack on anyone’s style of work. I’m very, very grateful for everything I’ve learned about how to write tests for software from the TDD community.

Looking for a few CLE pythoners for a quick project

I can build it myself, but it’s going to take a lot longer. I’m looking for a few people to help me build a geographical search app.

If you’re smart, live near me, and have at least eight hours a week to work, let me know.

This will be for some combination of money up front and equity.

I expect to launch in anywhere from six weeks to three months after the start.

I have no patience for ideologues, jackanapes, or freeloaders.