Thursday, February 15, 2024
Friday, September 1, 2023
Sometime after 2008 or so, I started telling software crafters that I was coaching that I have a guideline for code quality: “Don’t make me think.” Often I used the phrase to reference one of the many well-known code smells. Recently, I wondered where I first learned that expression. Unfortunately, online searches are dominated by Steve Krug's 2000 UI/UX book (with editions in 2005 and 2013) by the same name.The earliest use that I could find of “Don’t make me think” as applied to code quality is a blog post from 2011, If you know of an earlier use, please get in touch.
As I thought more about "Don't make me think", I've come up with many examples. Here's my list so far. What's your favorite?
- Have a readme that tells me how to run tests and install and run your application
- Use a test naming convention that gives the action, initial state, and expected state.
- Name things well
- When possible, use the names that are the same as in the business domain
- No commented-out code
- No comments, except to explain something that you have to do in an unexpected way (Debunk “good” comments)
- Unless you squash, have meaningful commit messages. If you squash, have meaningful merge messages.
- Write short methods
- Write with idiomatic use of your language
- Don’t write “clever” code
- Don’t over architect or over generalize
- Have sufficient types and amounts of automated tests
- Maintain your tests as you maintain the rest of your code
- Methods should have few arguments, and probably no boolean arguments.
- The interface of a class should “hang together” without methods that “don’t belong”
- Avoid “primitive obsession”
- Find solutions besides switch statements
- Don’t go crazy with inheritance. Prefer composition.
- Use a rich domain model, not an anemic one.
- Avoid conditional nesting
- Avoid subclassing unless you need all (or most) of the parent class (avoid Refused Bequest)
- Declare things where they are used.
- Arrange Act Assert
- One assert/concept per test
- Avoid double negation
- Use a Formatting Convention
- Short feedback cycles
- Don’t mix levels of abstraction
Tuesday, September 29, 2020
This post is probably a little rough, but I wanted to get it out, so here it is:
Fowler’s article on pair programming lists four "styles" of pair programming:
Driver and Navigator
and then goes on to throw out Pair Development as not being a style. Ping-Pong to me is totally a different style from anything else. There are also "Evil Pair Partner" and “Silent Ping Pong”, which are variants of PingPong, so I'd say there are three styles related to Ping Pong.
Fowler doesn't list "Just Pairing” as a style. Likewise, I can’t see the difference between “Just Pairing” and D/N - I consider them different names for the same one style.
The rule of Strong Style from Llewellyn Falco and Clare Macrae is: "For an idea to go from your head into the computer it must go through someone else's hands". I'll restate this as "Driver may not type their own ideas; driver must only type the navigator's ideas." That sounds like D/N with a restriction, so maybe a separate style.
All that said, I’m seeing five distinct styles:
Driver and Navigator aka “Just Pairing”
Evil Pair Partner (more for practice, not writing prod code)
Silent Ping Pong (more for practice, not writing prod code)
Saturday, June 22, 2019
Saturday, June 15, 2019
Initial ConceptMy wife likes big, chunky jewelry, so I thought I would try and 3D print something for her. I started with this as a basic idea:
ToolsPrinter: I have access to a Prusa i3 MK3, the predecessor to the MK3S.
Modeling: OpenSCAD - open source, "The Programmers Solid 3D CAD Modeller". Unlike traditional CAD apps that rely on drawing and/or moving around shapes, in OpenSCAD, you build designs by writing lines of OpenSCAD language code (some examples) Once you have a design in OpenScad, you have the software render it and export it in STL format.
Slicing / exporting gcode: Prusa has their own version of the popular open source app, Slic3r. Slicing is the process of taking a 3D model (usually an STL file) and converting it to a stack of slices that a printer can print, one on top of the other, to create the object. Gcode is the low-level instruction language used by printers to control the motions of the bed, the extruder, the arms and so on. Exporting gcode is the process of taking slices and converting them into those low-level instructions
Iteration 1:Design a basic ring-ish shape. The easiest way I found was to design a disk and subtract from it a disk of same thickness but smaller diameter, centering the disks on each other. It looked like this:
Iteration 2:I wanted to improve the ring design from a harsh geometric shape into the first inkling of a bracelet design. This involved learning to rotate a 2-D circle in 3-space around an axis, using the rotate_extrude() function. The result looked like this:
Iteration 3:To create the first printed prototype, I reduced the thickness of the bracelet design, keeping the diameter. Thinness causes a quicker print and uses less plastic. Took about 40 minutes to print. (No pic)
Iteration 4:Discover that diameter of first physical prototype is about 1/3 of useful bracelet diameter. Scale design to 300% and print again. When my wife put it on, it was a little too big, I decided to measure a favorite bracelet of hers and use its inner diameter (ID), 65 mm, for my design. Going back to the Iteration 1 design, I quick-printed something with the 65 mm ID. Holding it up against the favorite bangle, the ID matched. My wife put it on and called the fit perfect. So, I had confirmed the final ID. (No pics)
Iteration 5:Learn to go from circular cross-section to something more complex.
First, I set out to relearn parabolas:
I created a curve that I liked. It turned out to be Y = 0.3*(x-6.1)^2 + c.
In OpenSCAD, I duplicated the "volcano", fliped it 180 degrees, and lined the duplicate up with the base of the original:
I showed the double-volcano model to my wife for her blessing, which I received. A first real physical prototype is in sight.
I decided I needed to find some way to smooth the sharp edges and reduce/eliminate the faceting artifacts shown above. I had already figured out how to reduce the faceting down the face of the "volcano" by using more points to express the curve that became the polygon that was rotated through space. The faceting around the perimeter turned out to be easy - I had to add an extra argument, $fn=360, (number of fragments) to the rotate_exclude() call. Of course, the extra computation changed the rendering and slicing time from seconds to several minutes. I smoothed the lips edges of the volcano by smoothing the polygon itself using the offset() function before the rotate_extrude() call. The resulting model looked like this:
But the print had some issues:
and shifting one of the volcanos along the x-axis make the asymmetry more obvious: