Five dimensions of software project health
08.02.2025 PermalinkA software project is usually a complex endeavor spanning several months or years, requiring expensive expenditure of human labour. Many aspects are unique: the customer, the product, the composition of specialists, the challenges, chances and risks and so forth.
So it's no wonder that each project follows its own path, makes its own rules, distributes responsibilities in different ways. Many projects may officially adhere to a documented process framework like Scrum or whatever a company has decided to use. But at the operational level, they have to work in their own style.
So how can one judge if a project team is on its way to success or headed into trouble, if adherence to a process framwork (or lack thereof) is no useful indicator?
In order to examine for when a project team needs to review the way it works, I found much benefit in the following five dimensions:
Product Quality
If the product released by the team is in poor shape then something needs to change. Poor quality can manifest itself in frequent occurrence of bugs, change requests that point to fundamental traits, users complaining that their work is hampered, low performance on reasonably sized inputs or high effort to implement seemingly simple changes. The cause of poor quality may be time pressure, a low level of expertise or morale, a lack of understanding about user needs or simply skipping standard quality assurance steps like reviews or tests.
Stakeholder Satisfaction
The outcome of a software project usually affects different groups of people. For example there is the paying sponsor, subject matter experts, one or more user groups, possibly a work council, IT operations and last but not least the development team. Each group sees the project from its own angle, each individual has its own perception. The likelihood that something is actually broken is high when one or more stakeholder representatives express their concern.
Transparency
The management overseeing the project will have a hard time trusting the project team when its work is kind of opaque. Good project management will bring light to actual progress, budget consumption, spotted risks and problems, next milestones, task assignments and so forth. If the management feels a lack of transparency then the project team should change its habits.
Predictability
The more uncertainty there is the harder predictions are, especially those concerning the future. Uncertainty in the very early days of a project is usually high, therefore one important first task is some exploration to reduce choices and risks. However, at some point in time the project team will have to provide estimates about effort and attainable milestones. Going forward, if the team repeatedly misses milestones that were set based on its own estimates something needs to change. The project may have dependencies which it can't control, ever changing requirements, or the methods for the collection of numbers about the past and creating estimates for the future might need improvement. In any case the project management must adapt its modus operandi to regain their stakeholders trust.
Efficiency
Finally, even if all people affected by the product feel satisfied, the project team is able to live up to its promises, the management feels like it has enough insight and control and the product meets its requirements, there's a chance that time and budget are wasted for no good reason. Consequently, questioning habits, tools and technologies should be part of a well-formed closer look at how the product is developed from requirements to release.
In conclusion
A regular retrospective, as it is recommended in Scrum projects, is a good occasion to think about how the team is doing in light of the five dimensions explained above.
If it ain't broken then don't fix it. If the team is successful according to the five dimensions, then congratulate them and let them do their work, because it simply doesn't matter if the way they work complies to a given process framework.
My quest for the ideal keyboard switch
01.06.2021 PermalinkLast year I built my first ergonomic mechanical keyboard with brown (tactile) switches. After an initial phase of training I am very happy with the layout and keymap. Typing has become much more relaxed, there's no need to ever look at the keyboard to find a key, and my hands always remain in the same position.
There is actually a wide variety of keyboard switches out there so as I was striving for the perfect personal keyboard experience I was curious about how other switches felt like.
So, I used the last 12 months to build 4 more boards with the exact same design but different colors of acrylic plates, a pair made of poplar plywood and different switches. Here's how they turned out:
Dark anthracite acrylic plates, Cherry MX Red switches
(linear 45g, lubed). Never thought that I appreciate linear switches
that much.
Translucent acrylic plates, covered by a stickerbomb,
again Cherry MX Red switches
(linear 45g, lubed). Initially, I didn't plan to cover the
board with stickers. But unfortunately, the glue created an ugly
look on the translucent plates so I used the stickers as a rescue.
Poplar plywood clear coated, Cherry MX Black switches
(linear 60g, lubed). This very light wood makes the keyboard
weigh only 280g. It is very quiet and I use it while sitting
on the couch.
Poplar plywood yellow painted,
Kailh Speed Copper switches
(tactile, 50g, shorter travel distance, lubed, dampening
O-rings). Actually much more tactile than any MX Brown or
clone. The typing sound is considerable though. This is now my
daily driver in the office.
And here's my first build again with white acrylic plates. I replaced the
brown switches with Kailh BOX White switches
(click-bar, 55g, shorter travel distance, dampening O-rings)
to see if I like the sound and feeling. To me, in terms of
clickyness it is by far superior to any click-jacket based
switch like MX Blue or clones.
While it is fun and relaxing to build these boards it also served a serious purpose: find the ideal switch for me. Impressions from typical switch testers are limited because you can't do actual work with one of the switches.
What did I learn about switches and what type do I like best?
- MX Browns or clones are very popular and I used them myself for many years, but they are not really tactile. It is worthwhile to compare them to linears or more 'modern' switches like Kailh Speed Copper.
- MX Blues, known to be the clicky switches, are actually mushy compared to click-bar based MX style switches of the Kailh BOX series. If you're into clicky switches then I strongly recommend to give them a try.
- My fingers tend to bottom out on linears, so I always get the 'clack' and a physical feedback, plus I like the smoothness. Thus, I prefer a lighter linear switch over a clicky one for fast writing. For a more relaxed and quieter operation in the evening I find MX Blacks with their higher resistance more pleasant.
- I am fastest on Kailh Copper Speed, and their tactility often prevents me from bottoming out, so the actual travel distance is by far shorter compared to all other switches I used so far. However, they're by no means quiet switches.
- I don't play any computer games. Therefore I can't tell which type of switch might be the best for me in such a setup. The general opinion is that light linears are the typical choice for gamers.
My very personal summary for the time being: MX Blacks are my leisure time switches, but for serious writing I use Copper Speed or MX Red. But who knows? There are still many more switches to try, so maybe I'll do some more builds just to find out.
Six years of professional Clojure development
10.05.2021 PermalinkOver the last couple of years me and my colleagues here at doctronic have been busy creating and maintaining more than a dozen of individual software systems for our clients.
We have the privilege to almost exclusively use Clojure and ClojureScript, as this is still the valid strategic technology decision made by doctronic shortly before I joined them in 2015. In this post I'd like to list some of the strengths and weaknesses in everyday real-life use of the language and its ecosystem.
Stability of the language and libraries: Anyone who ever created software of practical value for paying customers knows that reliability of core language constructs and libraries is important. It supports predictability, and eventually saves you from insanity whenever you want to benefit from performance improvements or bug fixes. Upgrading to a new version of a library or even Clojure itself is risk-free. The authors and maintainers really do care about stability. If you listened to talks of Rich Hickey or Stuart Halloway you know that this is no coincidence. "Don't break things!" is part of the culture.
Code size: If you compare some of the idiomatic code snippets in Clojure with the equivalents in more popular languages you might conject that whole Clojure code bases might in general be smaller compared to what you can achieve in other languages. Now, after having worked more than 20 years with imperative OO languages and more than 5 years with Clojure I can firmly state that you'll achieve the same functionality with a fraction of the amount of code. This impacts costs: My feeling is that we now build systems with only half of the staff that I used to have on projects with a comparable scope.
Finding staff: Clojure's popularity is still far, far behind imperative general purpose languages like Java or Python, so fewer people feel encouraged to invest the time to learn the concepts and gain practice. It seems that this makes hiring harder. doctronic addressed this challenge by positioning itself as a supporter of the language in Germany through organizing and sponsoring the annual :clojureD conference. This helps greatly with staffing. But even if a company has a lower visibility, the fact that it uses Clojure will attract aficionados of advanced programming languages. If these developers do enjoy their workplace they will usually stay around longer with their employer. So I'd argue that you gain quality in skills and a lower turnover rate, but it might take more patience to build up a team of Clojure developers.
Teaching the language to apprentices: doctronic constantly employs apprentices so I was able to accompany some of them and help them learn Clojure. Young minds with very few programming experience are remarkably fast in picking up the language and become productive, it seems. I assume there are two main reasons for this: There's actually a whole lot of things they don't need to master compared to OO land. And they don't need to unlearn anything, in other words, they don't need to overcome old habits of doing things.
Some discipline required: Clojure is a language that gives us a wide range of options to implement solutions. And it imposes very little ceremony. For example, there is no static type system that checks your code upon compilation, but you can get some of the benefits for your data at runtime by using Clojure spec. This also serves as documentation and possibly a generator for test data. It is up to the team to decide when and where more checks, restrictions and tests have to be added. If the team misses out on this the code base might be harder to understand and maintain than necessary. In essence: with great freedom comes great responsibility.
Navigating the code: When maintaining or extending an existing code base you often need to find specific places where a function or a piece of data is referenced. To support this kind of search for specific identifiers it is important that naming is self-explaining and consistent, even more so because there are no links established via a type system. To mitigate this weakness in Clojure, you should use qualified keywords whereever possible.
Documentation becomes more important: When you're trying to understand a function that invokes other, non-core functions you'll need a clear idea what kind of data these functions expect and return. Without any data type declarations the code itself often doesn't reveal how the data that flows through you functions looks like. You'll need either Clojure spec or more thorough documentation to mitigate this problem. It is not so rare that you need to test functions of interest isolated in the REPL to get a clear idea how the data looks like.
The promise of purity: Any practical software application must cause some side-effects. So even if Clojure strongly encourages developers to create pure functions your systems will contain substantial parts that either depend on some environment or cause side-effects. The trick is to separate these pieces sharply and keep the unpure parts small. Without any discipline you could easily spread side-effects everywhere and end up with the typical imperative mess. Clojure makes it easy to create a mostly pure implementation but it does not enforce this. To ensure this and other qualities the teams at doctronic conduct code reviews for almost every commit before it is promoted into the master branch.
Reusability: Here's where Clojure really shines. Because most functions are pure and operate on few common data structures (mostly maps, vectors and sets) it is very easy to write reusable code. We created many internal libraries just by separating the candidate functions into their own namespaces within the regular project source tree. To finally establish the library we move the code from the project repo into a new Git repo and include the resulting library Jar in the project.clj as dependency. Thus, we have a very lean process that results in production-quality reusable assets.
Startup time: Starting a fresh JVM with a Clojure Uber-Jar to bring up an application takes noticable time. I assume that JVM class loading causes this delay. So if you consider to create a command line tool that has a short net execution time you wouldn't want this runtime overhead.
Runtime stability: Clojure applications are in general very stable. I remember that in bigger Java projects from my past we always had to do some load testing in order to detect programming flaws like memory leaks or race conditions. With Clojure, we do load testing only to find real performance issues.
Ok, time to come to an end before this post becomes too long. The list is perhaps not complete, but I guess I included the most important aspects that recently popped into my mind. When I decided to fully jump on this train in 2015 I expected more unpleasant surprises. Now, six years later I have proven to myself that Clojure and ClojureScript are a practical and sound choice for real world software development, and I still enjoy using them.
A handwired ergonomic keyboard
21.06.2020 PermalinkIn a recent post I explained how QMKs Mod-Tap feature helps me to keep my fingers on the home row, which finally enabled me to use touch typing for software development where I often have to use keyboard shortcuts involving one or more modifiers.
QMK with its multi layer support is a game changer insofar as your keyboard becomes like a stack of blank sheets upon which you can draw your keys just the way they fit your needs. However, there is an obvious limit. The physical placement of keys can not be changed like software. Just look at how the fingers of your left hand are supposed to travel across the keys:
While the fingers of your right hand can move in an almost natural way, you have to twist your left hand and its fingers in order to reach the keys as intended. In other words, the classical arrangement of keys isn't ideal for human hands.
Split keyboards are a consequential answer to this problem, and since I was in the middle of rethinking how I like one of my most important tools to be, I decided to search for a different layout.
The Atreus 42 is an open-source split keyboard in one piece with two panels, one for each hand, designed by Phil Hagelberg who is also the original author of Leiningen, Clojure's build tool. It is ultra compact and can even be used on your lap while sitting on the couch. It is sold by Keyboardio and FalbaTech. There is also a 62 key version, with a row dedicated to all the modifiers plus a dedicated number row, but since I'm fine with the Mod-Tap way of QMK, I wanted something in between.
There's a nice online tool for drawing realistic keyboard layouts, so I created some drafts. I printed my drafts on sheets of paper to get an impression of how the layout would fit my hands. And this is the layout I finally came up with:
Ok, a nice vision, but how can I realize the necessary piece of hardware?
When building a custom mechanical keyboard you typically need to have theses parts in place:
- A case, including the plate where the switches are mounted
- Switches
- PCB (printed circuit board, carrying the micro processor)
- Diodes, one for each switch
- Keycaps
- Stabilizers (not for my design because all keys are 1U size)
- USB cable
It took some time and patience until I had everything in place that I needed to create an Atreus like keyboard on my own.
The case
The Atreus was initially developed as a DIY kit, so it has a DIY friendly sandwich design, that is, the keyboard is assembled by mounting a number of laser-cut plates. With this idea in mind I started to draw sketches using Inkscape. Here are the 5 plates of the final version:
Note that the drawings have to be really clean since they repesent the path for the laser, i.e. they should not contain razor sharp corners or duplicated lines. Please find my design files, my QMK keymap and other source files on GitHub.
After some search for a laser cutting service in Germany I found cutcraft, which provide an excellent and friendly service. I ordered all plates to be cut from a 3mm acryl glass. And here's what I received:
I used acryl glue and 8 pairs of screws and nuts to assemble the case:
The switches
I used 52 stock Greetech Brown switches which are comparable to Cherry MX Brown switches. They feel a bit more tactile and unfortunately also more scratchy despite lubing them.
I had to use hot glue to properly fix the switches to the plate.
Handwiring instead of a PCB
The electronic heart of a keyboard is usually a PCB (printed circuit board, hosting the controller) but I wanted to avoid learning on how to design a PCB on my own, since I had no plans to sell any number of the keyboards I might eventually build for myself. So the overhead would perhaps not pay off. The alternative is handwiring. The prerequisite is to understand how the controller uses a matrix to scan many more switches than there are inputs on the controller. For the practical part of creating the matrix on your own with only wires and diodes, I found help in existing guides like this one that explain how to approach the work. It is obvious that handwiring takes more time, I estimate about 4 hours compared to 1 hour for soldering the required switches onto a PCB. But after all it is a hobby to build a personal piece of hardware, not a competitive race, so I enjoyed to spend more time on it.
Soldering the rows and columns, including diodes, is very straight forward, and the result looked quite clean:
The controller I used is a tiny board called Pro Micro, including the ATmega32U4, which is available for just a few Euros. Connecting the rows and columns with the Pro Micro also requires considerable work, and the result didn't look as clean:
Although a handwired board might look a bit fragile compared to a PCB based board the soldered connections are quite solid, so I have no doubt about the longevity of the product.
The finish
After soldering I used a multimeter to check every single connection. I connected my PC with the controller using a USB cable. Then I had to flash the firmware to the controller using the QMK tooling and a jumper-like cable to short circuit the controllers RST with the GND pin twice. The final step was to close the case with the screws and put on colorful keycaps and a unicorn sticker that my daughter gave me:
I am quite pleased with the outcome. The keyboard with all parts weighs about 500 grams, its size is 29cm x 14cm. The sound is muted, and the acrylic plate that holds the switches is flexible but not bouncy.
The hard part
Then came the strenuous phase of training my fingers to find the right keys with an acceptable speed. The first three days required a large amount of energy and frustration tolerance but I made enough progress to keep me motivated. This became much better after about a week. Working on such a keyboard feels totally different compared to a classical layout because my hands always stay in the same position. I can reach every key just by bending or stretching my fingers. It took some practise to master the additional layers (for nav functions, numbers, symbols, umlaut composition, mouse pointer, mouse wheel) but this is getting better every day.
The project was quite satisfying, and perhaps I will try another build with a different type of switch and other case material like wood.
QMK and touch typing
20.05.2020 PermalinkBack in 2012 I bought my first keyboard with mechanical Cherry MX Brown switches, the yellow edition of a Ducky Shine 3 TKL. By that time I had virtually no clue about the world of keyboards, but the product felt nice to me and it looked extraordinary:
In my opinion a good mechanical keyboard makes a difference so last year I tried to find a nice one for my daughter, as she was beginning to spend more time on her PC. I was lucky enough to buy a Ducky x Varmilo Miya Pro which has a very fine build quality and typing sound.
During the search I was a bit surprised that it is actually a matter of luck and/or patience to acquire a high quality mechanical keyboard. There are so many nice keyboards out there, as r/MechanicalKeyboards demonstrates on a daily basis. The nice pictures and stories got me hooked, so I started to explore the world of mechanical keyboards more in depth. Eventually I decided that I wanted to tackle one of my long lasting weaknesses: the lack of consistent typing speed. Isn't this the perfect excuse to spend some money on a new keyboard?
I was never a good typist, I hardly used touch typing, although I tried more than once to properly learn it. I suspect my failures of using touch typing in everyday work were caused by the position of the modifiers (Ctrl, Shift, Alt, Super) and especially the nav cluster (arrow keys, page up, page down), constantly drawing my right hand away from the home row (the row with the keys for A, S, D, F and so on).
My exploration led me to the idea that a programmable keyboard with a 60% form factor (a keyboard without numpad, nav cluster or function key row) might bring me closer to my goal. After some more research I bought a KB Paradise V60 Type R because it featured an ATmega32U4 micro processor which is known to support the open source firmware QMK. This firmware allows you to freely program your keyboard with up to 32 layers using the programming language C. In essence, this allows you to make it truly your very own keyboard.
The 60% form factor eliminated the nav cluster, so I assigned the arrow keys to I, J, K and L, but the modifier position was still disturbing.
QMK provides a feature called Mod-Tap which allows you to assign a modifier to any key. If you just tap the key, you'll get the character, but if you hold it and press it in conjunction with another key you'll get the modified behaviour. I assigned the modifiers to my home row like this:
A | S | D | F | G | H | J | K | L | ; |
Ctrl | Super | Alt | Fn | Fn | Alt | Super | Ctrl |
It took a bit of tweaking of QMK parameters and a few hours to really get used to it. But after all, my fingers stayed on the home row and my latest effort to properly learn touch typing succeeded!
But with this change the modifier keys on the bottom row of a classical keyboard became useless to me, so this leads me to think about keyboard layouts in a more general way. I am quite aware of Atreus and other split keyboards as a potentially more ergonomic arrangement of keys.
So this story might continue in the very near future...