&. |

A software developer’s musings on software development

Introducing Mini Calendar

Every December, for the last decade or so, I open up Excel and meticulously create a specific type of calendar for the coming year. I have a few goals for this calendar:

  1. I need to be able to tape it to the side of my monitor, for quick reference. So it needs to be pretty narrow (about an inch wide).
  2. I don’t want an imaginary gap between months. If Tuesday is the 31st, and Wednesday is the 1st, there’s no reason to show them on different rows of the calendar.
  3. I don’t want to waste space on weekends—this calendar is for work and I don’t work on weekends.
  4. I want to be able to mark my company holidays and PTO days.

Last year, I decided to create an application to generate this. Now you can use it here!

Fair warning: I didn’t really intend for anyone but myself to use this, so it may not be super intuitive. If you have any feedback I’d love to hear it!

Here is a photo of how I use this calendar:

Photo of MiniCalendar example

Stack Overflow reputation

Stack Overflow changed leadership recently and seems to be doing that thing where a company knows it has plateaued but doesn’t have any idea what to do about it. It’s not that they’re bad, it’s just that they don’t have much more improvement to make. I’ve noticed that when I google programming questions, I increasingly find the answer on a project’s GitHub page rather than Stack Overflow, which might be the impetus for all these changes. Granted, I don’t follow them very closely any more, so maybe my impression is off.

They brought back the podcast, but it’s pretty boring without Joel Spolsky and they don’t really spend any time talking about Stack Overflow itself. Even when they talk about programming, I just don’t care and I think it’s because everyone agrees with everyone about everything and their opinions are all too safe. They’ve also started blogging like it’s 2009 again—lots of words without saying much.1

But the thing that moved me to write the words you’re currently reading: they’re changing the point value of upvotes on questions, and they are retroactively recalculating everyone’s reputation.

Some background: You may not remember this, or you may be too young to have known, but before Stack Overflow, googling programming questions mostly turned up answers on an awful site called Experts Exchange, which hid the answers behind a paywall. Stack Overflow promised that all answers provided to the site would be under a creative commons license—meaning Stack Overflow did not own them and could not charge for access to them, even if they changed management in the future.

As an early adopter, and a believer in whatever Joel touched, I became pretty active on the site. This meant not just answering questions, but also asking them. I would ask questions even if I figured out the answer, as long I couldn’t find that it was already asked on Stack Overflow, because what the site needed to run Experts Exchange out of business was a lot of questions that Google would think are relevant to people’s searches.

When the site launched, upvotes on questions and answers were both worth 10 points. After a few years, they decided “questions will always come, but good answers are hard to come by”—I’m with you so far—”so we’re going to make upvotes on questions worth only 5 points instead of 10, but leave upvotes on answers at 10 points”—okay that makes sense—”and we’re going to retroactively recalculate everyone’s reputation based on those rules”—wait, what? retroactively??2

At the time, someone did an analysis and posted the users who would lose the most rep due to the recalc, and I’m pretty sure I was the third-most-affected user.3 Sure enough, I lost a ton of my fake internet points. I think it’s one of the main reasons I went from being a heavy user of the site to someone who only goes there when Google sends me there.

So I find it kind of hilarious that they’re now undoing that change—making question upvotes worth 10 points again—and that they are making the change retroactive again. My rep went up by about 30% today, from ~69k to ~91k. I finally get back all my stolen points!!

PS: This is the other reason I stopped being active on Stack Overflow.

  1. Hey, I’m also currently writing a long blog that almost no one will read, but at least I don’t do it three times a week. 

  2. There’s an interesting discussion to be had here about fairness. They said they were going to apply the changes retroactively because it wouldn’t be fair to newer users that they would operate under different rules. I think that it’s unfair to punish the old users for doing the things you wanted them to do at the time. But the truth is, I’m 100% convinced, the reason the rules were applied retroactively is because they didn’t want to have to write logic into the rep-calculation code to make events worth different amounts depending on when they happened. 

  3. If I cared more I would try to dig up that post... but I don’t. 

Javascript Date Expert

My most popular contribution to Stack Overflow, by far, is an answer to the question “How to add 30 minutes to a JavaScript Date object?”. That answer turns ten years old today. It has reached over half a million developers, and earned me over eight thousand fake internet points.

I kind of stopped being active on the site something like 8-9 years ago, though. I mainly use it passively now—I only go there when Google results send me there. I do still maintain my old answers if someone adds a comment saying there is an issue with it, although I usually won’t see those comments until the next time I end up on Stack Overflow and notice a red number in the header.

Sometimes, don't be friendly to the user

I’ve recently come to the revelation that sometimes it’s okay—desirable, even—to go out of your way to make software that is not user-friendly or easy to use. In specific situations.

Consider a nuclear weapons facility with a plastic box1 over the launch button2, or the familiar “in case of emergency break glass” boxes with an axe or fire alarm or something3. What these have in common is that obstacles are put in place between the user and the system they control in order to artificially make certain actions more difficult. Say, the action of butt-dialing a nuclear holocaust.

This is not user-friendly; this is, in fact, making the device more difficult for the user.

A while back, I added something similar to some of my code. One of my responsibilities is to write/maintain some DevOps tools that are used to deploy updates to various servers. Deployments can be pretty difficult, so I made this tool as easy to use as possible. I made it so easy, in fact, that people would accidentally deploy to the wrong server. Like, deploying to a production server in the middle of the day. Uh-oh!

My first fix for this was to make the user type the name of the deployment target that they had just selected. But even this was not enough, because people would blindly type in the name without thinking about it. But, based on a consistent server naming convention, I can tell whether the deployment target is a production server or not. When I detect this happening, I put up yet another dialog in front of the user:

Dialog box: Slow down pardner! It looks like you are deploying to production! If this is really what you meant to do, enter "deploy to production" into the box below.

This serves a purpose similar to the glass over the fire alarm: it forces the user to slow down and consider what they are doing. And because this is an internal tool, I get to have a little more fun with the verbiage. :)

  1. I have always thought these things should have a cool name, but as far as I can tell they don’t have one. 

  2. I’m not sure if this actually exists or if it is just from the movies. My attempts to google it mainly turned up photos of movie props. 

  3. I’ve always thought this is a little strange. Like, “hey we’ve got an emergency here”, “I know what we should do! Let’s put some broken glass on the ground!” 

Introducing Everytime

Time zones are hard. Everytime makes them easy!

Everytime sits in your system tray, and it shows the current time in as many time zones as you want. Get it on GitHub

Everytime screencap

Introducing Chord-o-matic

Warning: I wrote this blog in 2018. That is a long time ago, especially on the internet. My opinions may have changed since then. Technological progress may have made this information completely obsolete. Proceed with caution.

I’ve now released what is quite possibly my most ambitious side project, the Chord-o-matic Chord Player:

Chord-o-matic screenshot

This is an app that lets you select the notes that to play on a fretboard, and it tells you possible names for the chord, and why it gave the chord that name. It also lets you hear what the chord will sound like.

My reasons for writing this app come from some frustrations that I have trying to adapt music for guitar. At church, I play guitar for the kids’ choir about every other month, and the music I have to work with is never actually written for guitar. So I start with sheet music that is intended for piano and singing. The problem is I read sheet music at a first grade level. Whereas someone more knowledgeable/experienced than me can just look at the music and say “G, D7, C, G, Am, G7, G” or whatever, I take several hours to get to that point. Usually I start with the sheet music, write down the name of each note, then go back and figure out what chord is being formed by the notes played at that moment. Then I figure out where is the best place to put the capo to play the song more easily.

One tool I found that helped me with this is the JamPlay Guitar Chord Finder, and if you look at that you will see that my app is heavily inspired it. I basically did an HTML5 rewrite of the app. There were a few things that bugged me about their app, and so I set out to change them:

  1. JamPlay uses Flash, which is quickly going extinct as browser manufacturers drop support for it. I wanted something written in HTML5.
  2. I needed the option to add a capo, and to alter tuning (i.e. down half step).
  3. I needed the ability to change the guitar tuning, or even to change the type of instrument (guitar, ukulele, etc.)

Upon setting out, there were two problems I would need to solve:

  1. The front-end to render the interactive guitar.
  2. The back-end1 to take a set of pitches and return the possible names of the fingered chord.

I expecteded that the first task would be the most difficult, especially considering my UI skills are not the greatest. But in actuality, I think I spent much more time spinning my wheels on the chord naming task. I assumed that there was some well-defined algorithm which took a set of pitches and returned chord names, and that all I would have to do is open the Wikipedia page or something and port the pseudocode to Javascript. As it turns out, there’s a lot of variation in chord names once you get out of the common chords (majors, minors, and sevenths). Different people have different reasonable interpretations, and many of the established names seem to actively work against any kind of algorithm2. So what I ended up with is a bunch of spaghetti code that I hope to go back to and clean up later, to the extent that it is even possible. One resource that I found extremely helpful for this is the ScalesChords Chord Namer, which lets you select a set of notes in a chord, and it generates possible names for that chord. And, most importantly, it tells you why it generated that particular name. All said and done, I think I learned as much music theory in the past few months as I have in the entire two decades I’ve been playing guitar.

  1. Technically, it’s all front-end, but this is the part that’s pure algorithm. 

  2. For example, you might think a seventh chord is a chord with a seventh in it, but it’s actually one with a flat seventh. A chord with a seventh is called a major seventh. Unless the fifth is flat and you have a minor third (diminished chord), to get a dim7 chord you take a diminished chord and add a double-flat seventh (i.e. sixth) instead of a flat seventh like you do with any other chord. The kind of mess that results in spaghetti code no matter how hard you try. 


Warning: I wrote this blog in 2017. That is a long time ago, especially on the internet. My opinions may have changed since then. Technological progress may have made this information completely obsolete. Proceed with caution.

Earlier today I tweeted:

I have wasted too many hours of my life debating whether to write "if(somearray.length == 0)" or "if(somearray.length <= 0)". I mean, I know .length could never return a negative... but what if it does???

I want to elaborate on this using more than 140 280 characters. The situation where I tend to do this is when I come upon code like this:

  function processStuff(stuff) {
    if(stuff.length > 0) {
      //this is basically the whole function
      //seems wasteful to indent this stuff
      //maybe another 100 lines of code
      return whatever;
    else {
      //throw an exception or return an error message or print an error message or something like that

Two problems:

  1. The majority of the code is indented twice.
  2. The else clause is very far from the corresponding if clause.

So the solution is to refactor so that the current else clause is at the top

  function processStuff(stuff) {
    if(stuff.length == 0) {
      //throw an exception or return an error message or print an error message or something like that

    //this is basically the whole function
    //look it doesn't have an extra unnecessary level of indention now!
    //maybe another 100 lines of code
    return whatever;

The problem now is that the before and after this refactoring is not strictly identical. The negation of stuff.length > 0 is stuff.length <= 0, not stuff.length == 0. The first code would have gone through the error condition if stuff.length is negative, but the refactored code won’t.

Now, I know that the length of an array will never return a negative in any programming language I’ve ever heard of. But, like I tweeted, what if it does?!

I want to ensure that I don’t break anything by refactoring. And it’s also not going to hurt anything if I write stuff.length <= 0. But then I wonder what the next person to see my code will think. “Is there some reason this idiot1 thought array length could be negative?”

And I go through this thought process everytime I encounter this situation, mentally debating the pros and cons, instead of just accepting that it doesn’t matter and moving on.

  1. Believe me, the last programmer was always an idiot. Especially when it was me. 

BigFraction now on Maven Central

Warning: I wrote this blog in 2017. That is a long time ago, especially on the internet. My opinions may have changed since then. Technological progress may have made this information completely obsolete. Proceed with caution.

My BigFraction Java library is now available on Maven Central, free to be used in any Java project built using Maven or any compatible build tool (Gradle, Ivy, etc.).

This project is something I started on my own nearly a decade ago, for my own use in solving Project Euler problems. About three years ago I put it on GitHub. Much to my surprise, several people found it and started using it. But the only way to use it was to check out the source code and build it yourself—not very practical to the way most Java projects are built today. I wanted to get the library on Maven central about a year ago, but I procrastinated for a long time thinking it would be a difficult process. Turns out, it is relatively easy, and completely free, to get your open source library hosted and indexed.

If you run into any issues, please report them on GitHub.

Half A Lifetime Ago

Warning: I wrote this blog in 2017. That is a long time ago, especially on the internet. My opinions may have changed since then. Technological progress may have made this information completely obsolete. Proceed with caution.

One of the cool things about being a software developer is this: if something doesn’t exist, and you want it to exist, you can make it exist. Today I was thinking about the fact that almost half of my life has been since high school. Then I started to wonder when exactly half a lifetime ago was.

This is easy enough to solve with one line of javascript:

new Date(Date.now()/2 + new Date(birthYear, birthMonth-1, birthDay)/2)

This seemed like the kind of thing that normal people would be interested, so I spent a little time this afternoon making a workable (but still pretty ugly) UI around this one line of javascript: tilde.ampersand.space/half-a-lifetime/

The code is also on GitHub: github.com/kiprobinson/halfALifetime

You Won't Believe How Many Hello World Programs Can Fit On A T-Shirt!

Warning: I wrote this blog in 2016. That is a long time ago, especially on the internet. My opinions may have changed since then. Technological progress may have made this information completely obsolete. Proceed with caution.

I’ve designed a t-shirt that is especially for programmers. It contains the simple hello world application, written in forty-seven different programming languages.

Click or Tap or Otherwise Activate This Hyperlink to Buy!

T-Shirt with Hello World in Forty-Seven Languages

Below is the “key”, for anyone interested. A few of these aren’t technically programming languages (like binary, QR), and a few are just frameworks within another language (like Angular, Swing). I’ve ordered one of the shirts myself and it looks pretty nice—I had to make sure of that before I offered it for sale. I’ll probably work on a version that works against a dark background, when I get the time.




public class Main {
  public static void main(String[] args) {
    System.out.print("hello world");


<input type="text" ng-model="sometext" />
<h1>hello {{ sometext }}</h1>


object HelloWorld extends App {
  println("hello world")


<?xml version="1.0"?>
<greeting>hello world</greeting>


program hello
  print *, "hello world"
end program hello


main = putStrLn "hello world"

8086 Assembler

.model small
.stack 100h
msg  db  'hello world$'
  mov  ah, 09h
  lea  dx, msg
  int  21h
  mov  ax, 4C00h
  int  21h
end start


<?php echo 'hello world' ?>


package main
import "fmt"
func main() {
  fmt.Println("hello world")


(print "hello world")

Flex (MXML)

<?xml version="1.0"?>
<Application xmlns="http://www.adobe.com/2006/mxml">
  <Label text="hello world" />


68 65 6c 6c 6f 20 77 6f 72 6c 64


createTextField("hello", 0, 0, 0, 100, 100);
hello.text = "hello world"


@echo off
echo hello world


print "hello world";


  DISPLAY 'hello world'.

Visual Basic

Imports System
Public Module modmain
   Sub Main()
     Console.WriteLine ("hello world")
   End Sub
End Module


write('hello world'),nl.


hello world


state start:
  pstr("hello world\n");




SELECT 'hello world' AS hello

Java (Swing)

javax.swing.JOptionPane.showMessageDialog(null, "hello world");


(let ((hello-world (lambda() (display "hello world")(newline))))


#include <cstdio>
int main() {
   puts("hello world");


puts 'hello world'


program HelloWorld;
  writeln('hello world');


Print["hello world"]


10 PRINT "hello world"


<cfoutput>hello world</cfoutput>


$(function(){$('body').text('hello world');});




···→··→ ···↲
→   ↲
·····→  →   ··→ ·→  ↲
→   ↲
·····→  →   ·→  →   ··↲
→   ↲
·····→  →   ·→  →   ··↲
→   ↲
·····→  →   ·→  →   →   →   ↲
→   ↲
·····→  ·→  →   ··↲
→   ↲
·····→  ·····↲
→   ↲
·····→  →   →   ·→  →   →   ↲
→   ↲
·····→  →   ·→  →   →   →   ↲
→   ↲
·····→  →   →   ··→ ·↲
→   ↲
·····→  →   ·→  →   ··↲
→   ↲
·····→  →   ··→ ··↲
→   ↲
·····→  ····→   ↲
→   ↲


Transcript show: 'hello world'.

C Sharp

public class Hello {
  public static void Main() {
    System.Console.WriteLine("hello world");


print("hello world")


document.write('hello world');


<% HelloWorldLabel.Text = "hello world"; %>
<asp:Label runat="server" id="HelloWorldLabel"></asp:Label>


Hello World program in Piet

Objective C

#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
  NSLog (@"hello world");
  return 0;


with Ada.Text_IO; use Ada.Text_IO;
procedure Hello is
  Put_Line("hello world");
end Hello;


QR Code encoding the text Hello World


#include <iostream>
int main() {
  cout << "hello world" << endl;


disp('hello world');