I recently decided to switch my Twitter account from French to English. As I previously blogged a lot in French, I think now it’s the right time to start blogging in English.
The main purpose of this blog is to:
Thanks for reading this short introduction. While waiting for the next articles, you can already subscribe to my good old RSS feed.
]]>I have tried many methods and tools to overcome this failure : notebook, post-it, Google Keep, text files… I have to admit that none had worked for me. I didn’t know how to gather all my notes in one place. And above all, I was unable to capitalize on these notes. A real bazaar.
However, I discovered the Zettelkasten method a year ago[1]. And I think I found the system I was missing to take notes, organize them, improve them and capitalize on them. Since then, I have two brains, I have increased my productivity, and I don’t forget anything.
This is what my notes network looks like after a year with nearly 400 notes and over 130k words):
Today, I’d like to share with you what I’ve learned on my note-taking journey.
Writing enhances certain parts of your brain and boosts your learning abilities which is why I keep a small note with me pretty much all the time to jot down important pieces of information.
And it works very well for me. I remember better what I wrote. And anyway, I have a backup plan with my notes. I can come back to them later whenever I need.
It’s not only to remember. These notes will come in handy one day. Copying/pasting a note is very rewarding.
Plus, sometimes I need to go back to basics. So even the simplest note is valuable.
So write down all your thoughts: to-do list, your goals, minutes of meeting, comments on podcasts and shows…
Write them down at all times, lest you forget them. When taking notes, try to stick to the essentials to be effective.
Honestly, learning without taking note has become a black hole for me.
I write every day to get used to writing. It’s not easy but doable with perseverance. In this way, I become more comfortable and get better at it day to day.
But also so as not to forget what I learned on D-Day. I write it down when it’s still fresh in my head.
I have many interests. Some may overlap. The connections between each topic are key to navigating my mind. Moreover, some complex concepts have interdependencies with many notions.
To achieve that, I primarily use internal links (aka wikilink) between notes. On the same way, I use and abuse of tags. I’ve always been a big fan of tags. It’s a very simple tool to organize objects without creating a hierarchy.
When I feel a tag becomes an important notion. That it should be developed. So I replace it with a placeholder[2].
Whenever I have the opportunity, I divide my notes into smaller ones. This way I can reuse them anytime. Also, it will be easier to navigate and get to the core concept.
For example, I started a note on the JVM. Step by step, I completed it. Then at some point, I had to extract everything related to the garbage collector in a dedicated note, as well as the performance aspects, the different implementations in another one, etc…
Now I have a central note on the JVM with specialized branches (garbage collector, implementations, performances…) that I can link directly into other notes.
I refine my notes as I learn, like the Feynman learning technique.
My understanding of the concepts improves as the notes change.
So, I need to move or restructure them because I have a better understanding.
Quickly, standard notes appeared: project idea, study of architecture concepts, curation of topic, web review, tutorial…
I created a template for each one. So all notes have the same structure, I save time and I have a checklist on the aspects to dig into.
I have already mentioned it. Sharing my notes allows me to explain understandings or thoughts at the speed of light.
I need to explain a concept? I copy/paste my note on the subject to share the content. Do I have to list the advantages or disadvantages of such an approach? I copy/paste my note on this approach to share my concerns.
Easy and blasting fast!
Before, I used a CMS to prepare my articles. They were isolated from my notes with no link to them. Moreover, these articles could be forgotten in this side tool.
Now they are part of my thought pattern. Every day is an opportunity to complete a long-term article in small steps. And when the article is ready, I can publish it as it is.
I know many of you are now wondering which tools I use to take notes. I don’t think there is a perfect tool. But rather, there are tools that are suitable for everyone. Even so, here in a nutshell is my environment for taking notes.
There are many ways to take notes[3]. Since I decided to follow more or less the slip box method, I used Zettelkasten oriented tools. Likewise, since I use development tools, it seemed obvious to me to adopt a code approach. That’s why I use:
Today, these notes are my secondary brain. They allow me to reduce my mental load. I am relieved and no longer forget what I learn and know.
I brain dump once at the end of my working day and a second time before going to bed.
Do you, and how do you manage your notes? What did you learn?
Links point to a note to create. ↩︎
Emmanuel Bernard has explored several. ↩︎
just
, a powerful task runner that simplifies your development workflow. Whether you need shortcuts to frequently used commands or want to manage project-specific tasks, just
is here to make your life easier. In this article, we’ll explore the features of just
and its usefulness in enhancing your productivity. Get ready to discover how just
can help you efficiently handle your projects with ease.
The first time I heard about just[1], I wondered what its added value was compared to the alias
command. Then, after a second reminder[2], it clicked!
This kind of tool allows you to create shortcuts to tasks that are specific to a project. Please note that this tool is not intended to replace a project lifecycle management tool like Maven, Gradle, or NPM. Instead, it is designed to quickly access commands that are regularly executed on a project.
Furthermore, if like me, you use multiple computers, you have to maintain alias
on all of these machines. With just
, all the shortcuts are committed to the project. There’s no need to copy the alias
from one machine to another anymore.
So, if you find yourself typing the same commands over and over again, I recommend taking a look at this type of tool, as it will increase your productivity.
After understanding the concept of task runner and being convinced of its usefulness, I looked for the tool that best suited my needs.
I didn’t conduct an in-depth analysis, but here are the 2 solutions I tried.
Following Guillaume’s recommendation, I first tried just. This command-line tool is multi-OS (MS Windows, GNU/Linux & Mac OS).
The configuration of tasks, called “recipes”, is done in a .justfile
file. Its format is inspired by make
.
I used this justfile
to evaluate the tool:
alias cs := chuck-search
default:
just --list
# display hello world
hello:
echo "Hello world!"
# display a random Chuck Norris fact
@chuck:
curl -s https://api.chucknorris.io/jokes/random|jq -Cr .value
# search a Chuck Norris fact
chuck-search QUERY:
curl -s https://api.chucknorris.io/jokes/search?query=|jq -Cr .result[0].value
# list categories of Chuck Norris facts
chuck-categories:
curl -s https://api.chucknorris.io/jokes/categories|jq -Cr .[]
# display all given arguments
args *ARGS:
node -e "console.log(process.argv)"
cs
alias is a shortcut for the chuck-search
recipe.just
command without arguments.@
before the name of a command hides the executed commands.hello
displays the classic “Hello world!”chuck
returns a random Chuck Norris factchuck-search
returns a Chuck Norris fact containing the keyword passed as a parameterchuck-categories
lists the categories of Chuck Norris factsargs
displays all passed arguments using Node.jsTherefore, if I want to display a joke about “computers”, I simply type just cs computer
and I get this response:
curl -s https://api.chucknorris.io/jokes/search?query=computer|jq -Cr .result[0].value
Chuck Norris doesn't use a computer because a computer does everything slower than Chuck Norris.
I didn’t need to configure commands with environment variables, but just
can load them from a .env
file.
If you want to learn more about the capabilities of just
, I recommend reading the cheat sheet.
Being used to writing everything in Markdown files, including all useful commands, I became interested in the tool Maid.
This tool is written in Node.js and is therefore multi-OS (MS Windows, GNU/Linux, Mac OS). Its principle is very similar to just
, with the difference that tasks are declared in a Markdown file named maidfile.md
.
Here is the maidfile.md
file that allowed me to test maid
:
# Runbook / How to
## hello
It displays a hello world.
```bash
echo "Hello world!"
```
## chuck
Display a random Chuck Norris fact.
![Chuck Norris](https://api.chucknorris.io/img/chucknorris_logo_coloured_small@2x.png)
```bash
curl -s https://api.chucknorris.io/jokes/random|jq -Cr .value
```
## chuck:search
Search a Chuck Norris fact.
```bash
curl -s https://api.chucknorris.io/jokes/search?query=$1|jq -Cr .result[0].value
```
## chuck:categories
List categories of Chuck Norris facts.
```bash
curl -s https://api.chucknorris.io/jokes/categories|jq -Cr .[]
```
## args
Display all given arguments.
```js
console.log(process.argv)
```
You can list all tasks with the maid help
command. So, if I want to display a joke about “computers”, I simply type maid chuck:search computer
and I get this response:
[00:35:36] Starting 'chuck:search'...
Chuck Norris doesn't use a computer because a computer does everything slower than Chuck Norris.
[00:35:36] Finished 'chuck:search' after 318 ms...
After testing these two tools, which one is better suited to my use cases?
I really like the idea of being able to write my tasks in Markdown files. In fact, I’ve been doing that for a long time already. It allows me to better document my tasks.
However, just
stands out for its offered features. Here are the tested features that I needed:
Feature | Just | Maid |
---|---|---|
Arguments | Defined in the recipe | Appended at the end of the command |
Alias | ✔️ | ✖️ |
Accessible from subdirectories | ✔️ | ✖️ |
Multi-line description | ✖️ | ✔️ |
Task chaining | ✔️ | Syntax in the description or hooks |
Quiet mode | Defined in the recipe | CLI parameter (--quiet ) |
Except for multi-line description, just
supports all the features I needed.
Do the examples of tasks used not seem realistic to you? Here’s a real example of a .justfile
on one of my projects:
alias gst := git-st
alias gcd := git-ci-dt
# List all files to commit with last update date
@git-st:
git status -s | while read mode file; do echo "${mode}" $(stat -c %y "${file}") "${file}"; done|sort -k1,4
# Commit at a given COMMIT_DATE with a COMMENT
@git-ci-dt COMMIT_DATE COMMENT:
GIT_COMMITTER_DATE="{{COMMIT_DATE}}" git commit --date="{{COMMIT_DATE}}" -m "{{COMMENT}}"
The 2 commands are:
gst
(git-st
) lists all modified files with their last update date.gcd
(git-ci-dt
) creates a git commit at a given date with a specific comment.In conclusion, just
has joined my arsenal of tools to increase my productivity. Once again, I recommend exploring this category of tools, which are task runners or project-specific command executors.
With great power there must also come great responsibility.
I think we developers have an important mission. But the importance of this mission forces us to be rigorous and to question ourselves.
A few weeks ago, a colleague and I were working on a presentation about IT professions. Specifically, we were introducing the roles of developers and architects to aspiring young engineers.
As I contemplated the core mission of a developer, it struck me:
Our job is to automate things.
Indeed, we automate real-world business processes and various computer tasks.
Truth be told, software’s primary aim is to save time and, consequently, money for clients. Considering how much time a service saves for its clients helps determine the price they’re willing to pay. Additionally, reducing the risk of errors holds real value.
An excellent example is Rebase by Pieter Levels, aiding entrepreneurs in moving to Portugal. His service automated an administrative process, offering expertise and saving time for clients. 🤝
We noted that this inclination towards automation is intense among developers. Everything should be automated. In fact, in my recent design principles, I even launched:
Automate all the things!
It’s an extreme application of the DRY (Don’t Repeat Yourself) principle, but applied to task execution. Some developers even have a principle of never doing the same thing twice. Personally, I question it after the second time (somewhat akin to Write Everything Twice).
Yet, this week, reading Olivier’s tweet, I remembered I held a more moderate view on automation.
Olivier emphasizes what to automate and the quality level to deliver. Between Quick and Dirty and a fully polished development, the effort differs. In a fast-paced, competitive world, finding a balanced approach seems prudent.
I revisit his approach later in the article, taking an extreme viewpoint. But let’s focus now on a topic close to my heart: what tasks should truly be automated?
In a world with finite resources, automating everything isn’t feasible. Hence, choices must be made. Here, I present a tool in the form of an assessment grid to prioritize task automation.
Nearly 10 years ago, Henrik Kniberg’s test classification in his presentation “What is an agile tester?” struck me. This classification prioritizes tests for automation based on the risk of functionality failure, automation effort, and manual testing cost. In truth, it also lacks test frequency consideration.
A feature with high risk, lengthy manual testing, and low automation effort should take precedence over a feature with low risk, minimal manual execution effort, and significant automation effort.
Here, the calculation of ROI (Return on Investment) from test automation is evident.
Although the author touches on risk, it’s not fully developed.
Automation isn’t just about speed and productivity. It’s also about making operations safer and reducing the potential for error.
Hence, I can’t help but link this to the risk matrix, which includes:
This grid is used in risk management, useful for security assessments or probable risks in a hosting or data center.
I also apply it to assess tasks for automation. What’s the probability of an error in a manual task? What’s the impact of that error?
Consequently, some tasks with extremely low execution frequency but critical error impacts might be automated. For instance, infrastructure creation – what if you lose your entire production infrastructure? How long is an acceptable timeframe to rebuild it error-free? So even if this operation will only be performed once or twice, you’ll want to automate it because of its criticality.
By combining these two evaluation grids, a robust tool emerges to prioritize tasks for automation (not just tests). It’s what we practice daily at work. For each task open to automation, we inquire:
Answering these five questions allows us to make informed decisions on task automation.
Personally, I’ve taken to jotting down everything I do, a continuous documentation of sorts[1]. I maintain a kind of notebook for each task, enabling me to replay it manually with less need for contemplation and with a grip on the error risk (though still fallible). For repetitive tasks, I ponder:
Using these four questions, I decide whether to automate a task.
Finally, let’s revisit Olivier’s thoughts:
“We can’t automate everything.”
“We don’t have time to do everything perfectly or even neatly.”
About 2 years ago at BreizhCamp, I attended a fascinating talk by François-Guillaume Ribreau and Sébastien Brousse, explaining how they took the principles of lean startup and eXtreme Programming to the extreme with what they call eXtreme Lean. It heavily relies on Fake it till you make it.
Their approach is pragmatic – no need to code features perfectly until client traction is proven. However, they do not compromise on test automation. It’s the eXtreme Programming aspect, providing agility with a safety net.
In summary, yes, our mission is to automate everything. But we lack infinite resources to achieve that. Prioritization is essential. Thus, calculating the ROI of each automation becomes necessary. And it will help us to find the right balance.
So let’s automate tasks that genuinely save us time within our capacity to produce, and leave ourselves the means to conquer the world[2].
I elaborate more on this in my post about the Zettelkasten method - what I learned about the journey of note-taking. ↩︎
Or at least our market.😜 ↩︎