Kartones Blog

Be the change you wanna see in this world

Naming bugs for fun

Going for a walk today, I remembered how, at previous jobs, we used to give funny names to certain types of bugs that either happened from time to time, or were different and posed unique challenges. I'm probably missing more, but the following small list are all that I recall :)

Cinderella bug: For example, a bug (or failing test) that only presents himself around midnight. Usually relates to datetime issues.

Spring/Fall bug: Variant of the previous one, caused by dailight saving. Not handling timezones can also help making it (or other variants) happen.

The poltergeist: You feel it, you sense it but you cannot see its source.

Schrödinger's variables: Issues with compilers or interpreters causing broken data structures to crash and/or report having and not having multiples values at the same time when inspected. I have a precise example of this one from late 2010/early 2011, in which I got Javascript error under Internet Explorer 9 beta incorrectly reporting success:true for a scenario that was erroring. It said it was a boolean but it's value was neither true nor false, and at the same time was not true and not false. Here is the screenshot I took for fun:

IE9 Beta Schrödinger's boolean

Gotta catch them all bug: When somebody applies Pokemon exception handling (capture Exception, Error or the corresponding language equivalent to the parent exception type) and the real bug gets shallowed by the handler, either raising a different error or being just hidden until found.

The It works on my machine!: Bug that surfaces on environments other than local/dev. More often than it should applies to tests, breaking when run via CI but not locally. Usually relates to to diferent configurations, different packages, or even different operating systems (Mac vs Linux, Ubuntu vs Alpine, ...).

The orphan: nobody takes responsability/ownership of this bug so it remains unfixed.

The destroyer of worlds: fatal bug that either crashes the whole system or breaks thousands of tests. Writing the post I found the alternate name Hindenbug.

The Hydra: A bug that, upon fixing, causes (or simply uncovers) more bugs to appear.

The Yeti: A bug reported, probably multiple times, but that nobody is able to reproduce/find it. Alternate name: Loch ness monster bug

The inmortal: A bug no matter how many times you try to kill, you're never able to fully get rid of.

Heisenbug: A bug that changes how it behaves when you try to triage or debug it.

The Padron pepper bug: A joke of a famous spanish food, of which some peppers are hot and some not. Applied to bugs, a bug that is not deterministic, sometimes happens and sometimes not.

Course Review: English Speaking Patterns Mastery (Udemy)

English Speaking Patterns Mastery: Upgrade your English contains 19 English patterns to improve the vocabulary and conversation quality. I knew a few of them but combining the new ones and practicing the others, as usual a good run for the cost.

My only complaint is that, as there are so many examples of each pattern, it becomes way too repetitive to listen to so many similar ones. I'd instead have more items than so many repetitions, but not a big deal.

Course Review: English Idioms Launch (Udemy)

English Idioms Launch: Upgrade your speaking and listening contains 60 idioms in blocks of four per chapter/section, and as other courses from the same author feature quite a few examples of each, with listening, speaking and pronunciation exercises.

Some of the examples are too similar and feel repetitive, but it still works as practice. What was a bit dull was the "roleplaying" combining each block of four idioms, I get the reasoning behind but ends up sounding a bit forced together.

Still, interesting for its ~5 hours of content.

Work life hacks: Noise-free Gmail and muting Slack

I seriously think there are very few 10x engineers, but instead that a productive engineer is one that knows how to focus on the task at hand for long periods of time. Apart from other actions to achieve discipline and concentration, I love to do pomodoros (usually 45 min long), but at work I noticed there were two things annoying me since long, long ago: Gmail with high volume of mails, and Slack notifications of unread messages.

Here is how I inverted the control and now I can check the email or work chat whenever I want (between pomodoros or at idle times).

Removing noise from Gmail

First, an image of my work Gmail will give you context of where do I want to arrive with my "settings":

Minimalistic Gmail

I once read about the zero inbox concept regarding email: Develop some rules for your mail client so you don't have those huge unread counters. I, for example, can't handle an unread counter (I get stressed), so this idea was a nice solution. In my case, what I do is have a pending label, that I apply to any email that requires something from my side (a reply, a follow up if after a few days I have no answer, etc.).

This system allows me to keep zero unread emails by quickly checking their contents and manually labelling them. But just combining Github, error logging, CI build reports and a few more sources you can easily get from dozens to even hundreds of daily emails.

So I also heavily use filters to usually "apply label X, and archive", and if is not important also "mark as read". As you can configure each label to display on the left sidebar "only if unread", this means the sidebar itself hides the complexity (you can have dozens of labels if you want) until there are unread emails. And when those arrive, you can check and mark as pending or not.

Teaching people to use BCC field is a plus, but being humans, there will be mistakes, people forgetting about it, etc., so I've became used to filter sometimes even certain senders (as if they were spam), based on my mental metrics of "has this person ever sent a relevant email?", "do I even care about offtopic emails of topic xxxx?", etc. It sounds antisocial, but to me is exactly the same as being slammed lots of postal mails on my mailbox, just because it's digital and easier to do doesn't means you should write everything to everyone.

Extra tip: Do not enable the "unreads counter badge" advanced feature. For personal email might be cool, for work I dislike to see the counter at the favicon if I have to use the web browser.

Muting Slack notifications

Slack can be a useful communication tool, but also an overwhelming source of distractions and a concentration-breaker. I've never fully liked it not because of the product itself, but because of the use and abuse vs ways to protect yourself from it.

Focusing on reducing noise, these are the actions I've taken to only read it between pomodoros or when I'm really not busy:

  • No desktop notifications (this includes direct messages)
  • Disabling @here and @channel notifications everywhere
  • Using favourites to keep a list on the left sidebar of the really important channels and direct conversations
  • Muting every non-important for daily work channel. This combined with the previous point acts as a 3 lists classification: 1) Favourite 2) normal 3) muted
  • No email notifications: This is just noise, if I have closed the app/web it is on purpose
  • No phone notifications: Personal rule here: If it's my personal phone, no work chat app installed. But if it's a work device, if I'm not active on Slack it's because a) I'm not working or b) I'm busy (like in a meeting)

But, there was one thing I couldn't get to disable and forced me to directly close the browser tab; I use the web client, and the favicon always shows you unreads and private messages/mentions. Few days ago I got tired of the situation and, as I use Chrome for work, searched for some extension to replace or fix the favicon of a tab... and found Tab Modifier perfectly suiting my needs.

This is a sample config to force Slack to remain with their default favicon (which is also prettier):

Tab Modifier configuration to mute Slack click to see full size

With this hack, I can finally check the browser as many times as I want without being distracted of having unread slack messages.

We live in a world full of digital noise: From ads and videos to lots and lots of emails. While educating people is and will always be an ongoing task (after all, few things are so critical can't wait 30-40 minutes), with some effort we can regain some control and reduce that noise.

My latest side project: Finished Games

This post is a mere declaration of intentions and brief explanation of where I spend lately not-tiny-but-neither-huge blocks of spare time when at home. Still, can be of some interest if you do Python and Django.

I won't enter into details of the project purpose (you can read it) other than mentioning that Finished Games is a small website to catalog and track your videogames playing history. You can also check a live demo at https://finishedgames.kartones.net (to me the most useful part is the user catalog). Note: Game and Platform catalogs are not totally imported yet, just a few hundred samples to do some real usage scenarios.

The tech stack is mainly Python 3.5, Django 2.1, Docker & Docker-compose (for testing and development, not required for production). It only has at the time of writing this blog post less than 50 lines of Javascript so I wouldn't consider it a "main" technology (be advised it uses ES2015 without polyfills on purpose so no old browsers neither IE). In local it uses SQLite for storage.

Everything is dockerized to ease testing and not polluting your computer with Python packages you might not desire to keep. Initial setup requires you to run the migrations (for now, I want to add a first-run aware bootstrapper) but other than that, [commands are as simple as make run, make test, make coverage, etcetera. Check the README to see many of them in action.

Regarding Django the project includes installed django-debug-toolbar but with just a few modules, mainly to be used to detect unoptimized queries. I would recommend it to be switched off in production, it's easily configurable.

Testing is done with Pytest, Coverage + Pytest-cov, plus the code is fully type-annotated so there are MyPy & Flake8 "linter tests" so tests won't pass if you don't type the code or have it clean (almost no custom rules except 120 chars line length and default double quotes). Continuous integration is using CircleCI and just rans the same tests as make test.

I'm doing my best to build the code in a legible, pythonic and simple (I'd add "clean" but not in the craftmanship meaning) way. It is an ongoing effort, and as I'm iterating quite fast from an initial MVP sometimes a piece of code might be pending some deeper testing or refactor, but in time it will come.

The code includes as many Django best practices as I'm being able to apply, from avoiding N+1 query problems using .select_related(), how to properly instantiathe the defined User auth model (did you know you it can be overriden so you should never directly import the model?), statics configuration for development and production, class-based views for non-trivial views (or multi-verb HTTP endpoints), named url paths...

I'm very pragmatic so I didn't wanted to reinvent any wheel if not needed. That's why I've chosen simple yet beautiful CSS: Finished Games main site screenshot

But also by trying to do as less as possible I'm heavily relaying on Django Admin to all the CMS management, only extending it with extras I really need to build: Custom actions, custom filters (including context-based smart filtering), field decorators, hand-made views... Finished Games admin screenshot

Everything that can be configured using existing ModelAdmin features is done, like list_display, list_filter, search_fields, readonly_fields or ordering.

Instead of the classic scripts folder so prone of becoming a dumpster, I'm sticking to Django commands for any operation, django migrations for any database change (even if is a mere DB field description/comment update): Django command example output

Settings files use a simple hierarchy: base.py defines things, then dev.py, test.py or prod.py (not included, but provided a prod.py.sampl placeholder) inherit from it, and optionally if you define a local.py it can override dev.py values (handly for testing some production setting locally, careful to not abuse or pollute it!).

There are some tests and many more will come once I reach the point of being able to import hundreds of games quickly (really only remains a batch import feature, as one by one import is already implemented), after all code coverage wasn't added for nothing. Pytest plugs correctly to django so coverage is accurate (at least more accurate than not properly configuring it). As the first catalog source adapters are defining both the fetch/import API and the database structure in this case I'm prioritizing quick iteration and manual verification over tests. Once settled tests will harden the code as much as possible. Plan is not to do hundreds of view integration tests but a few ones will be provided to showcase how to test Django views (so my future self can easily remember how it's done). Similar scenario for Django Commands, I'll do some basic testing but won't mock the whole universe regarding data sources, instead focusing on testing FetchedGame and FetchedPlatform entities and their interactions with the import process.

The code doesn't contains any super-algorithm nor does anything clever, the coolest piece being a token bucket rate limit implementation (sample usage as a method decorator here) that mostly comes from StackOverflow and Wikipedia (at least the tests are built from scratch by me), but I've never been a brilliant mind creating amazing algorithms, I just "get shit done".

As the README mentions, there's a roadmap but is the only thing I'm keeping private for now, as I want to work on this project at my pace, with my rules and as much as I want/decide to. For example, initially I was decided to migrate it to Django REST framework and React/Redux for a version 2.0, but now I'm not totally sure I'm going to do it, as a classic/non-SPA approach is working so nice for now (and I can just do any other side project focusing on Javascript). That doesn't means that if somebody leaves issues, pull requests or comments I will ignore them, far from it, but my priorities might not be the same as others.

The license is Unlicense so you can do whatever you want except helding me liable for any problem :)

Ok, enough talking, show me the code and leave me alone! https://github.com/Kartones/finished-games

Closing up, I'm having a great time with the project as I'm combining building a tool I really want to use with being able to go deeper into some Python packages/libraries I don't use so much in my daily work. And for once it'll be a non-totally useless project to showcase on my Github profile.

Previous entries