Coding Guidelines

  • Your code should look nice and be legible. Use an automated code formatter. Keep your functions short (under a page of text) and your classes/files reasonably long (1000+ LOC should ring an alarm). Always delete commented-out code – it’s already in the Git repository if it’s ever needed again.
  • Respect the Single Responsibility Principe. One class/file should either talk to the DB, or output GUI, not both.
  • Give clear, descriptive names to your classes, functions and variables. This is art (and it’s really hard), so practice it.
  • Extract commonly used numbers, strings etc. into (well named) constants. “Magic numbers” in code are bad.
  • Respect the Don’t Repeat Yourself principle. Reuse existing code, refactor code that looks similar or performs similar tasks. Copy-paste is worse than plague.
  • Write documentation with common sense. Prefer good names and short functions to comments. Document your public APIs/interfaces.
  • Prefer functional style of programming, avoid side-effects.
  • Treat any warnings from your compiler/toolchain as important and helpful information.
  • Crash early, once you detect a problem throw an exception and log some data to help you fix it later. Set up the application so that any errors will be sent to you by mail.
  • Use a build/dependency management system, such as Maven, CocoaPods or similar.

Git Guidelines

Commit content

Any code deployed to production (be it a web application, mobile application, …) must have been committed into the repository earlier. Commits should deal with one thing (~1 issue) and one thing only. Commit early, polish later.

Commit message

Write an English sentence describing the commit. If a commit deals with an issue from the issue tracker, start the sentence with the issue key.

Example: “#1234 fixing the froboozle”

Branching model

Follow this: http://nvie.com/posts/a-successful-git-branching-model/

No-nos

  • Don’t commit “only at the end of the day”.
  • Never commit a configuration file or any other file that would disclose a password or some secret key.

Infrastructure Guidelines

Intro

We use 3 environments: development, testing and production.

Application will know which database to connect to, which resources to use, etc from a configuration file, or better, environment variables (http://12factor.net/config).

Application code always lives in Git. It is deployed to the various environments either as a Git checkout, or using a specialized tool (Jenkins + rsync or such).

Development

Typically, this is the localhost of each of the developers. This is the only environment where code changes are allowed. It’s possible for the database structure or resources configuration to get temporarily out of sync with the code base.

Testing & Production

Testing serves to allow testers (internal or external with customer) to try out changes in the application before it hits the production. The purpose of production is probably clear :)

One important rule: application changes should (must) be deployed atomically. This means that if I change some code that needs an updated database schema, I must upgrade the schema at the same time (atomically) as I deploy the updated code – otherwise the application could crash or even corrupt data.

Of course, never deploy to production anything that was not previously verified on testing.

Upgrade procedure

  1. Take the application down – redirect to static server, other instance, …
  2. Upgrade the database (execute the SQL patch).
  3. Upgrade the code base (git pull or rsync or whatever).
  4. Start the application.

Surviving an OS upgrade

Upgrading your operating system could be a harrowing experience. However, with some forward thinking, you can survive it quite unharmed.

Allocate around 1 man-day for the upgrade, the same as for migrating to another computer or such. You might think it will be less, but just in case – make sure you won’t need to be productive on the day of the upgrade. Pick Saturday if you can.

Continue…

How to get database ID timestamp

Let’s say you have a single sequence in your database handing out IDs for all the rows that need one. How to tell when a specific ID has been assigned?

For this trick to work you will need at least one table with ID and a timestamp:

The more such tables you have, the more precise will the results be. You will also need to have the created grow monotonically with respect to the ID – higher ID must mean later creation time!

Here comes the main SELECT:

The first part WITH events AS () will put together all the ID-created pairs in your database. It might look like this (if someone did care to sort by time/ID):

Having the ID but not the time, we can see where the ID would fit in this table. Therefore the rest of the SELECT interpolates the time by finding the lower and upper bound and taking an average. For example, if our ID is 1290, we can see it must be between 2015-04-25 16:34:09 and 2015-04-26 01:30:00. My select simply does LOWER + (UPPER - LOWER) / 2, but you could do a linear interpolation instead :)

Finally, we can put all of this into a nice function:

AirPlay on Raspberry Pi

One of the Pis from our hackaton made it to my home to build some cool projects. “Lagometer” using PiGlow and realPad on rPi (get it?) are still work in progress, today I want to share one simpler project: rPi as an AirPlay host.

It works like this: you send multimedia (audio, video, photos) from one device (typically an iPod, iPhone or an iPad) to another, host device (Apple TV, WiFi speakers or so).  The host can even be a pair of “dumb” speakers connected to an AirPort Express router, which is really cool and really silly at the same time – you typically want to place your router someplace else than you would your speakers. Here’s where rPi comes into the play.

Continue…

Code auto-format

A short one for IDE users: whichever Church of Indentation (2 spaces? 4 spaces? tab?…) you subscribe to, try setting up the Code auto-format to match your style and make a habit of re-formatting your code before saving. Sure, some code is better left hand-formatted, but on the average it’s better looking code for negligible effort!
Continue…

Raspberry Pi Hackaton

A few days ago the EASYCORE team had a hackaton in our Node5 offices. Present were Marian, Matej, Marek and Michal, so it was supposed to be mmmmawesome! (It was.)

The aim of our hackaton was to use a Raspberry Pi to do something one would use a computer for, but said computer would be too much of an overkill. We thought along the lines of an office presence system – one that would scream “late-comer!” and perhaps feed into a dashboard useful for remote workers.

Continue…

Zombie refactoring

You know the feeling: it’s Friday afternoon and the brain just refuses to work. At times like these it is helpful to have some stashed TODOs somewhere in your code and just start refactoring: it usually does not need too much creativity and you can do it on autopilot. Best of all, it’s still very  important work, so it’s not like you are slacking off. Bestest of it: time flies real fast!

(Good music helps with this, too.)

Preferences

This is somehow similar to the last practice. It’s useful whenever I create GUI tool, even a simple one. The development process often looks like this: run – set up controls – oh I forgot something – change the code – run – set up controls … Setting up the controls every single time is incredibly dull and error-prone.

Two possibilities open up here. Either the whole GUI state can be stored on exit and loaded on start, or there could be an export-import settings button. As to the format of the settings, plaintext is the king. For example: Java’s Properties handle this task well, the key=value format is good enough for most cases.