Skip to content

Martin Lees Posts

How to easily image search with python

image search with python

This is the second time that I’m writing on how to do image search with python. The first blog post. That I wrote about the subject got a lot of interest and even today I regularly get people commenting on it or coming to the github repo asking for help. So I figured it was time for a refresher.

Python imagesearch is now a pip-eable package

I have put a bit of work to put the library as a package. In order to allow you to just pip the library. This is a much better solution than me saying nonsense like “copy the file in your project”. Now it is as easy as doing :

pip3 install python-imagesearch

The above will probably fail or you won’t be able to use the library as you need extra packages depending on your os :

Linux

sudo pip3 install python3-xlib
sudo apt-get install -y scrot python3-tk python3-dev python3-opencv -y


MacOs

brew install opencv
pip3 install -U pyobjc-core
pip3 install -U pyobjc

Windows

No extra installation steps needed 🙂

Quick start

The simplest example to do image search with python is this:

from python_imagesearch.imagesearch import imagesearch

pos = imagesearch("./github.png")
if pos[0] != -1:
print("position : ", pos[0], pos[1])
else:
print("image not found")

Simply search for one occurrence of the image “github.png” on the screen and print its x/y position

Other functions

imagesearcharea

Performs an image search on a specific rectangle of the screen, it’s very useful to speed up searches as there will be less screen space to search.
It’s also useful to focus the search only on a specific part of the screen to reduce the chances of having a false positive.

pos = imagesearcharea("./github.png", 0, 0, 800, 600)
if pos[0] != -1:
    print("position : ", pos[0], pos[1])
else:
    print("image not found")

Input:
image : path to the image file (see opencv imread for supported types)
precision : the higher, the lesser tolerant and fewer false positives are found default is 0.8
im : a PIL image, usefull if you intend to search the same unchanging region for several elements

Output:
the top left corner coordinates of the element if found as an array [x,y] or [-1,-1] if not

region_grabber

Useful to optimize imagesearcharea or imagesearch calls, by getting an already processed image you can perform multiple searches on it with minor speed gains. Here’s an example

# non -optimized way :
time1 = time.clock()
for i in range(10):
    imagesearcharea("./github.png", 0, 0, 800, 600)
    imagesearcharea("./panda.png", 0, 0, 800, 600)
print(str(time.clock() - time1) + " seconds (non optimized)")

# optimized way :

time1 = time.clock()
im = region_grabber((0, 0, 800, 600))
for i in range(10):
    imagesearcharea("./github.png", 0, 0, 800, 600, 0.8, im)
    imagesearcharea("./panda.png", 0, 0, 800, 600, 0.8, im)
print(str(time.clock() - time1) + " seconds (optimized)")

# sample output :

# 0.5233619831305721 seconds (non optimized)
# 0.4075934110084374 seconds (optimized)

Input: a tuple containing the 4 coordinates of the region to capture tuple should contain coordinates of : topx, topy, bottomx, bottomy

Output: a PIL image of the area selected.

imagesearch_loop

Searches for an image on screen continuously until it’s found, useful to make a waiting script until x image appears. For instance waiting for the end of a loading screen.

from python_imagesearch.imagesearch import imagesearch_loop

pos = imagesearch_loop("./github.png", 1)
print("position : ", pos[0], pos[1])

Input:
image : path to the image file (see opencv imread for supported types)
time : Waiting time after failing to find the image (seconds)
precision : the higher, the lesser tolerant and fewer false positives are found default is 0.8

Output:
the top left corner coordinates of the element if found as an array [x,y]

imagesearch_numLoop

Searches for an image on screen continuously until it’s found or max number of samples reached.

from python_imagesearch.imagesearch import imagesearch_numLoop

pos = imagesearch_numLoop("./github.png", 1, 50)
if pos[0] != -1:
print("position : ", pos[0], pos[1])
else:
print("image not found")

Input:
image : path to the image file (see opencv imread for supported types)
time : Waiting time after failing to find the image
maxSamples: maximum number of samples before function times out.
precision : the higher, the lesser tolerant and fewer false positives are found default is 0.8

Output: the top left corner coordinates of the element if found as an array [x,y]

imagesearch_region_loop

Very similar to imagesearch_loop except it works with regions

from python_imagesearch.imagesearch import imagesearch_region_loop

pos = imagesearch_region_loop("./github.png", 1, 0, 0, 800, 600)
print("position : ", pos[0], pos[1])

Input:
image : path to the image file (see opencv imread for supported types)
time : Waiting time after failing to find the image
x1 : top left x value
y1 : top left y value
x2 : bottom right x value
y2 : bottom right y value
precision : the higher, the lesser tolerant and fewer false positives are found default is 0.8


Output:
the top left corner coordinates of the element as an array [x,y]

imagesearch_count

Counts how many occurrences there are of the image there are on the screen.

from python_imagesearch.imagesearch import imagesearch_count

count = imagesearch_count("./github.png")
print(count)

Input:
image : path to the target image file (see opencv imread for supported types)
precision : the higher, the lesser tolerant and fewer false positives are found default is 0.9

Output:
the number of times a given image appears on the screen.
optionally an output image with all the occurances boxed with a red outline.

imagesearch_from_folder

Performs an imagesearch on all the images in a folder. This function was done by kadusalles

from python_imagesearch.imagesearch import imagesearch_count

results = str(imagesearch_from_folder('./', 0.8))
print(results)

Input:
path: to the folder containing the images (supported image types are jpg, gif, png and jpeg)
precision : the higher, the lesser tolerant and fewer false positives are found default is 0.9

Output:
A dictionnary with all the images where the key is the image path and the value is it’s position

Conclusion

And that’s about it ! Now you should be able to easily perform Image search with python. If you are interested in the actual code or want to contribute feel free to head on over to the github repository : https://github.com/drov0/python-imagesearch and if you liked my article, come to see more at https://brokencode.io

How to use local go modules with golang with examples

Image result for golang modules"

When coding I like to put everything inside of folders depending on what they do. I almost always got specific directories for utils, parser, etc. So here’s a complete guide on how to use local go modules with golang

When I started using go modules I was migrating a project from dep which followed this architecture. I had an utils directory, and another directory which handled all parsing for my data input into structs. But then I ended up needing functions from the utils directory. I was stuck and couldn’t find how to make directories importable everywhere in the project (like dep used to). Because relative imports are a nightmare with go modules (removing the gopath has a toll after all).

So after quite a bit of fuming and searching all of the web for a solution that is elegant and not something like some crazy relative imports, I found this solution and since I struggled so much to find the solution I figured that I would share it with you all.

The example project

Here’s our example project directory structure :
├── go.mod
├── hello
│   ├── go.mod
│   └── hello.go
├── main.go
├── README.md
└── utils
├── go.mod
└── multigreet.go

You can also see the example code on my github repository here : https://github.com/drov0/GolangLocalModulesExample

The code is relatively straightforward : I have two directories, hello and utils that I want to import from the main.go file. And when things get a little tricky is that I want to import the hello directory inside of the utils directory.

The code for the hello.go file that we want to import is this super complicated function :

package hello

func Hello(name string) string {
   return "hello " + name
}

The code for the addAndGreet.go file is a bit more complex :

package utils

import (
"example.org/hello"
"strconv"
)

func AddAndGreet(name string, a, b int) string {
return hello.Hello(name) + " " + strconv.Itoa(a + b)
}

Notice how we are importing "example.org/hello".

Finally here’s the main.go file :

package main

import (
"example.org/hello"
"example.org/utils"
"fmt"
)

func main() {
fmt.Println(hello.Hello("martin"))
fmt.Println(utils.AddAndGreet("martin", 2, 3))
}

Obviously the modules example.org/hello or example.org/utils do not exist so these imports make zero sense to our compiler so let’s help him out a bit

Importing local modules in main.go

So first we simply have to convert all of our directories into go modules. For that we need to add a go.mod at the root of every directories.
Then inside of that go.mod give them whatever name that we want as module name. but bear in mind that it has to be an url. In my example I put this:

module example.org/hello in the go.mod for the hello directory
module example.org/utils in the go.mod for the utils directory

The import makes a bit more sense now huh ? but we are not done yet.

The replace keyword

This is where the magic happens, go.mod files have a few keywords that can be very useful, one of them is replace what replace does is that it takes a module path (eg : example.org/hello) and replaces it with a direct or relative path.

here’s the syntax for the replace keyword :

replace url.com/of/the/module => /direct/path/to/files

Note that replace also works with relative paths.

The main go.mod

module example.com/localmodexample

go 1.13

require (
example.org/hello v0.0.0
example.org/utils v0.0.0

)

replace (
example.org/hello => ./hello
example.org/utils => ./utils
)

Usuall go module dependencies work with versions, so to use local go modules with golang you have to set v0.0.0

Finally after the require, I just tell the compiler that those urls are local and can be found in the same directory under ./hello and ./utils. The great thing about this main go.mod file is that now even the utils module will know where to find the hello module because the url have been replaced.

Conclusion

And that’s all you need to know to use local go modules with golang. Hopefully this will save you all the hours I put into it. Keep in mind that you can find the complete code on my github : https://github.com/drov0/GolangLocalModulesExample

I know it’s been a while since my last post but I got quite busy. But now I should be able to make posts more often on this blog.

Building a time tracker using arduino and blockchain tangletime part 2



Hello, This is part 2 of my project tangletime aka “Building a time tracker using arduino and blockchain”. Where I take you along my project to build an IOT time tracker using arduino and the IOTA blockchain. If you haven’t, please consider reading the first part .

Now that the plan is laid out. It’s time to plan for the hardware. We need those components :

An arduino board, a bluetooth module, a gyroscope and lots of cables and resistors to combine all of that together.

For the arduino board, cables and resistors I bought the Freenove RFID Starter Kit V2.0 with UNO R3. It’s an awesome starter kit with basically everything you need. Then for the Bluetooth module I bought the HC 05 and the gyroscope is the MPU 6050. ultimately with a more mature product, I think I’ll go for a beetle BLE, as it’s super small, cheap and handles Bluetooth out of the box. But that’s for a later stage.

I want to make as little calculations on the board as possible to lower the power usage and to make it easier to code. The idea is simple : connect the board to the gyroscope and whenever we detect a new stable orientation. Send that orientation to via the Bluetooth module to a connected phone.

The Bluetooth module with arduino

My HC-05 was not easy to tame, I found lots of tutorials online, most of them contradicting themselves on how to wire it. The main takeaway was that if you wire it to the 0/1 port, you need to unplug those before uploading your schematics to the board.

To test things out without using the gyroscope, I quickly plugged the infrared sensor included with the freenove kit, the part name is 1838B. I like it because it’s super easy to plug (it’s like 4 jumper cables). I could go with reading serial from my computer but I figured it would be nicer this way.

Arduino schematic for the bluetooth and IR module.
The Bluetooth module and IR module connection


I’m sorry for the clarity of the image, but everything is there I promise.

As for the code it was pretty straightforward :

/*
    IR remote keypad
   0 : FF6897
   1 : FF18E7
   2 : FF6897
   3 : FF7A85
   4 : FF10EF
   5 : FF38C7
   6 : FF5AA5

*/

#include <IRremote.h>
#include <SoftwareSerial.h>
SoftwareSerial EEBlue(10, 11); // RX | TX


int RECV_PIN = 12;        // Infrared receiving pin
IRrecv irrecv(RECV_PIN); // Create a class object used to receive class
decode_results results; // Create a decoding results class object

void setup()
{
  Serial.begin(9600); // Initialize the serial port and set the baud rate to 9600
  Serial.println("UNO is ready!");  // Print the string "UNO is ready!"
  irrecv.enableIRIn(); // Start the receiver
  EEBlue.begin(9600);
}


char value_to_char(unsigned long val)
{
  if (val == 16738455)
    return '0';
  else if (val == 16724175)
    return '1';
  else if (val == 16718055)
    return '2';
  else if (val == 16743045)
    return '3';
  else if (val == 16716015)
    return '4';
  else if (val == 16726215)
    return '5';
  else if (val == 16734885)
    return '6';
  else if (val == 4294967295)
    return 'X';
  else 
    return '?';
  

}

void loop() {

// if we recieve an IR message, send it via the bluetooth module.
  if (irrecv.decode(&results)) {
    // Waiting for decoding
    Serial.println(results.value); // Print out the decoded results 
    Serial.println(value_to_char(results.value)); // Print out the corresponding character

    EEBlue.write(value_to_char(results.value));

    irrecv.resume(); // Receive the next value
  }

  // Feed any data from bluetooth to Terminal.
  if (EEBlue.available())
  {
    Serial.println(EEBlue.read());
  }

  // Feed all data from termial to bluetooth
  if (Serial.available())
    EEBlue.write(Serial.read());

  delay(100);

}

To test everything, I used an app called “Bluetooth terminal HC-05” which basically allows you to send and receive data from the HC-05. It’s a lifesaver when you are working on the hardware side and don’t want to spend time making a quick and dirty app just to receive Bluetooth data.

Screenshot of the mobile app recieving bluetooth data
It works !

The final arduino setup

I wrote a whole article on the subject that you can find here ! So I’ll skip the details on how to set it up. And go straight to how I use it.

So here’s the “final” setup in terms of hardware. As for the code now all that’s left to do is to find all the x/y/z values for each side of the cube. But I don’t have a cube yet, and the arduino UNO board is way too big. So for now I’m going to make a first proof of concept where the time tracker only has two sides : register if the board is pointing left or right.

So after a few tests I realize that getting consistent reading is not as easy as I thought it would, there is a non negligible drift on the z value. There is probably some fine tuning necessary in the future in terms of which value = which side. but for now I only care about the x value since I want to know if the board is pointing left (x ~= -80) or right (x ~= 80)

Which translates to this code :

#include <SoftwareSerial.h>
#include <MPU6050_tockn.h>
#include <Wire.h>
MPU6050 mpu6050(Wire);
SoftwareSerial EEBlue(10, 11); // RX | TX
int pos = 0; // unset = 0, left = 1, right = 2 

void setup()
{
  Serial.begin(9600); // Initialize the serial port and set the baud rate to 9600
  Serial.println("UNO is ready!");  // Print the string "UNO is ready!"
  Wire.begin();
  mpu6050.begin();
  // offsets that I previously calculated using mpu6050.calcGyroOffsets(true);
  mpu6050.setGyroOffsets(-1.58, 0.69, -1.71);
  EEBlue.begin(9600);
}



void loop() {

  mpu6050.update();
  float x = mpu6050.getAngleX();
  float y = mpu6050.getAngleY();
  
  if (x < -50)
  {
    if (pos <= 1)
    {
      EEBlue.write("right\n");
      pos = 2;
    }
  }
  else if (x > 50)
  {
    if (pos == 0 || pos == 2)
    {
      EEBlue.write("left\n");
      pos = 1;
    }

  }

  Serial.println(x);
  
  Serial.println(pos);
}

Pretty easy right ? Here’s a little demo of the whole system :

Data is sent to the phone via Bluetooth
if that video didn’t work try this link

So now we have a system that can send data to a paired phone and detect orientation ! success ! Now all that’s left to do is to port that code to a production board, 3d print a cube, fit all of that inside, get the position data for each side (side 1 is x/y, side 2 is x1,y1 etc…) And we are good to go on the hardware side !

If you have experienced drift issues with the MPU6050 and know a good fix. I would be interested. Please consider subscribing to the mailing list to avoid missing any future episode of this serie 🙂

MPU-6050 easily get x y z values tutorial

Hello, a few weeks ago I started working on a time tracker project. And one of the vital components was an MPU-6050 gyroscope, I needed a tutorial to get the x y z values. And I found many tutorials on it. But whenever I tried them I had a lot of problems noticeably with drift. The drift means that the readings were not stable at all. After 30 seconds some values had quadrupled even though the card itself was still. So I found a lot of answers that told me “yeah this is a common problem”. But not really any help in solving it. So here’s a full MPU60-50 tutorial from start to finish that I wish I had when I wanted to use it.

Wiring

The wiring is pretty straightforward :

  • VCC to the 5V pin
  • GND to ground
  • SCL to the A4 pin
  • SDA to the A5 pin
  • INT to the 2 pin

The other pins are not useful for the most of the use cases. If you are interested nonetheless or want to know more about this chip I encourage you to read the documentation here : https://www.invensense.com/products/motion-tracking/6-axis/mpu-6050/

MPU 6050 wiring on an arduino UNO board
MPU 6050 wiring on an arduino UNO board

Reading the x y z values

Now that the wiring is done, it’s time to move onto the actual software. In order to get the x y z values we need to be able to read the raw values, there are a ton of tutorials on how to do that. But ultimately it’s not that useful as you need to make calculations on it for these values to really have meaning. After digging quite a while and trying out various tutorial like this one I realized that, while it’s quite interesting to make everything from scratch, when you want to build things quickly, it’s often better to use a library from someone who’s spent much more time than you on the problem.

Also none of those tutorials seemed to handle the part where you’re supposed to calculate offsets and calibrate the damn thing. And if you don’t calibrate it, you most likely will run into problems sooner or later.

The MPU6050 tockn library

Github user tockn created this awesome library called MPU6050_tockn (leave him a star if you can). Which does pretty much everything for you. Better yet, it’s available on the arduino library manager. So it’s extra easy to download it.

Screenshot of the arduino library manager with the MPU-6050_tockn library selected

Go ahead and download the library (I’m using 1.5.2). And now load up this code :

#include <MPU6050_tockn.h>
#include <Wire.h>

MPU6050 mpu6050(Wire);

void setup() {
  Serial.begin(9600);
  Wire.begin();
  mpu6050.begin();
  mpu6050.calcGyroOffsets(true);
}

void loop() {
  mpu6050.update();
  Serial.print("angleX : ");
  Serial.print(mpu6050.getAngleX());
  Serial.print("\tangleY : ");
  Serial.print(mpu6050.getAngleY());
  Serial.print("\tangleZ : ");
  Serial.println(mpu6050.getAngleZ());
}

After a few seconds of loading you should get this :

Serial monitor with X Y Z data
Serial monitor with X Y Z data

Success ! Keep in mind that you might still encounter drift issues especially on the z parameter. Also once your offsets are calculated, use mpu6050.setGyroOffsets(x, y, z); rather than calculating them each time. It’ll allow for a faster startup and less chances of you messing up the offset calculations by unintentionally moving it.

And that’s it for this tutorial on how to get x y z values on the MPU-6050. Feel free to leave a comment if you have any questions. And if you want to dig deeper, there is another example with more data from all the elements on the board (accelerometer/gyroscope and temperature) here.

Building a time tracker using arduino and blockchain tangletime part 1

This is my first try at IOT, in this series I’ll be using the IOTA blockchain and arduino to build a time tracker and take you along for the ride 🙂

Blog banner, with "tangletime part 1" as header and "Building a time tracker using arduino and blockchain" as subheading

For a whole year I’ve been working full time on my own projects, namely SteemPress and more recently my blog ! And I really like to optimize my time. But without reporting, it’s pretty hard to really know what to work on. I tried to just use my phone timer to try to see how long I was doing various things (reddit/code/email/etc). But when I’m focused on various things, I often forget to start/stop it. And it also ment that I had to do a lot of reporting by hand. Which was a pain. So I figured that I would be building a time tracker using arduino and blockchain.

Here’s the project idea : I want to build a small cube/hexagon or a polygon (I’m not sure on the number of sides I want on it yet). So that if I put it on a sides for an activity. Let’s say coding. It’ll start a timer that will only stop when I put it on another side. Technically I am always doing something so there shouldn’t be a need for a “doing nothing” side.
Here’s a few ideas for sides that I had :

  • Programming
  • Gaming
  • Sleeping
  • Grocery shopping
  • Reading/replying on slack/emails/discord
  • Reddit-ing
  • Going out

Arduino for the time tracker hardware

Arduino is one of, if not the most accessible platform to build hardware on. It’s basically lego mindstorms on steroids. There are tons of tutorials in every possible form imaginable and tons of compatible parts that you can buy everywhere. I advise you to find a local shop and go to them to talk about your project. They will be able to give you advice and prevent you from buying tons of hardware that is ultimately useless for your project.

This was also a prime opportunity for me to start working on it since I’ve been wanting forever to work on some hardware things. And create more internet of shit (great twitter account, highly recommend that you check him out).

Why blockchain ?

If you know me (or read my github) you’ll quickly notice that I work a lot with various blockchains. So I like to see how blockchains can improve things. One big issue that I have with IOT products is the fact that it only works until the people behind it continue to run their server. So you pay 50 euros for hardware that might at any moment turn off. And I don’t want this kind of stuff. Another thing is that I want to have control over my data and not have a random company be aware of pretty much all of my activities.

The IOTA blockchain

Disclaimer : I have a small stake in IOTA

The IOTA blockchain is one of a few blockchain that’s designed for IOT usage, some would argue that it’s not a blockchain and they would be kind of right : It’s a tangle. I’ll pass the details but long story short it has super fast transaction times, transactions are free (as long as you validate other people’s transactions). Since it’s one of the biggest cryptocurrencies, there’s a lot of support online on how to do IOT with it.

I’ve been wanting to do a small projects to test out that blockchain in real conditions so this sounds like a perfect use case. And this means that :

  • It’s decentralized : No need to run a server to host the data
  • Anyone can run a web app to display the data. If Alice doesn’t like the default setup she can go online and make her own or try the one that Bob put online.

I believe that for an use case like this, the hardware is not the limiting factor : it’s the software, what graphs you do, how you extrapolate on the data that’s important. And If this can be made open for anyone to hack, and anyone can have their own custom dashboard with exactly what they need. This would be really cool.

“Yeah you don’t give your data to a single company, you give it to everyone instead”

Not really because if I control what I send and how I send it, I can easily put encrypted data or just send like “activity 1” instead of “programming” (Sleep would be relatively easy to spot though, so encryption might be in order). But this is far down the line.

The plan

So there are four big parts to this project. First I need to make a proof of concept using hardware, just a very basic thing using gyroscopes that displays the orientation, send that using bluetooth to my computer or phone.

Then the second phase will be saving all of that on a local database and building a basic dashboard, most likely in the form of a phone app.

Then for the third phase I’ll add blockchain support. And if everything still holds together I will buy a pcb board, the smallest Arduino that I can find. Solder everything together, 3d print my cube/polygon and actually have my finalized product.

So hang on for the ride, consider subscribing if you haven’t already to get notified when I’ll publish the next part of this series.

And before we finish I got a question for you all. If I made this, would you be interested in downloading files to create your own ? Or if you are not really the tech type, to buy a pre-assembled one ?

How to plan for your death with code

Recently I’ve been going to a rock climbing trip with a friend. Although this is a relatively safe sport. It’s far from being the safest. So it got me thinking. “What if I make a mistake and fall to my death ?”

Banner of a cemetry with text "How to plan for your death with code"

I thought about the obvious facts like the sadness from my loved ones etc. But I also thought about more pragmatic things. I’m sure my bank account’s content can be transferred to them somehow. But I also hold some cryptocurrency. Which, by design, would be lost forever if I were to die with my private keys. Same goes for the various services that I run like steempress. If I were to die those would shut down and the vast amount of code locked away in private github repos might very well never be recovered (assuming github doesn’t help). Or even this blog, I plan on adding a ton of tutorials on it, what if it goes down because I no longer pay the bills ?

I was thinking, “I’m a programmer, I can probably plan for my death with code”. But here’s the problem. Let’s say I give an USB key to my loved ones with basically all of my passwords, private keys etc. It puts a huge risk on me because if that key were to be stolen, if one of my loved ones becomes rogue because of whatever reason. (we are talking about planning for death here so this is measures that should last several decades) I could lose so much.

The obvious answer is “fuck it, it’s a problem for the living and I’ll be dead” but it’s pretty egoistical so I wanted to find a solution. Another obvious solution would be to go to a lawyer and give the usb key to be handed out with my will. But that would be quite costly.

The solution

The idea is relatively simple. Create an encrypted usb drive using truecrypt and/or veracrypt. Ideally nest them. With all of the important information. And give those to your loved ones without the password. Therefore there is no risk if the usb key gets stolen. And if they manage to break the encryption they can go directly to their local intelligence agency and sell that 0day for a few millions, much more than the content of that drive because it’s that hard. So I’m not too worried about that happening.

Then write a small server that sends you “are you alive” emails every months. If you miss too many then the server will then send to your loved ones an email which will contain the password for the usb key. (And perhaps a few words like “don’t be sad I love you”)

This means that if your web server handling the are you alive checks gets compromised. The attacker will just get a random password that is useless without the file.

If you miss a test then you get more mails. This is done to prevent you from missing one email and being declared dead by the code. I setup a “failed test counter” send emails like so :

0-2 : every month
3-5 : every 3 weeks
5-7 : every 2 weeks
8-16 : every week

after 16 checks death is declared.

In total you need to be offline for about a little less than 6 months (26 weeks) for it to trigger.

Conclusion

There is still a ton of little things that you can add to that setup, like only sending parts of the key to each of your loved ones. So they have to get together to open the file and it’s not like the first one who opens the files can run with everything.

There are a few services that already offer death email counters but I would encourage you to code your own and even self host it. The less people you trust, the more secure this setup becomes.

I am definitely open to suggestions to make this more secure. Right now my biggest concern is an unforeseen bug or something that makes the code trigger the email while I’m still alive. Or something like me getting kidnapped/imprisoned for 6 months. But if I set the timer to longer than that. The info inside of it might no longer be relevant.

What I learned coding (almost) every day for a year and a half

Two years ago I started working on steem, it’s a really cool blockchain where your upvotes are worth actual money. There are quite a few decentralized apps tha run on Shortly after a startup called utopian.io launched where open source contributions were rewarded. I figured it couldn’t hurt to try and it was the extra motivation I needed to finally start working on open source.

I’ve been wanting to work on open source software for quite some time so I opened my github account and started coding, I mostly worked on my own projects releasing a ton of code snippets to help future developpers work on steem. But I also open sourced some of my personal libraries for instance https://github.com/drov0/python-imagesearch a python library to easily perform image search for automation. (I mostly used it to automate games at the time).

The plan was never to code every day at all but then, Github has one feature. One feature that made me work on it rather than, say, gitlab or bitbucket :

The contribution graph

The contribution graph is a simple thing, whenever you do a commit, open an issue or a pull request it’ll add a green square for the day. And the more actions you do that day the darker the square. You can’t really say “oh the square is super dark so you did a lot that day” but it’s a good rough metric.

I didn’t really take much attention to it at first, but the more I looked at it the more it was talking to me, it said

“Can you code every single day, for an entire year ?”

It was daunting at first but then I took on the challenge. And started coding. Around the same time I was launching as a side project my startup SteemPress, a plugin to connect wordpress and steem. And since I love programming it wasn’t hard for me to come home from 8 hours of programming (I was a software engineer working on embedded software) and then sit on my computer to work some more.

Little by little the squares started to fill and I felt prouder and prouder about my ongoing achievement. And this is where I learned my first big lesson

Consistency is hard

Coding every day sounds ok in a week, or even in a month. But then there are edge cases that you didn’t really thought about when you started in this whole endeavor :

  • What do you do if there’s an after-work party right after work and you know you won’t be home before midnight ?
  • What do you do if you get sick ?
  • What do you do if are on vacations ?
  • What do you do if you don’t want to work ?

This is where you are at a point where you think of the rules, a green square is just one commit, does adding a bit of documentation on a README on your phone count ? Does adding a line of comment count ? What is cheating and what is not ? In the end I decided that it was okay to edit readmes or adding comments as long as it was

  • Relevant (adding an useless line or fixing a typo is cheating)
  • Not too often (once every two weeks top)

The x effect

There are studies that show that if you do something every day for 30 to 45 days it becomes a habit. And that effect is greatly amplified if you have something physical like a box to tick if you did your daily habit correctly. There’s even a subreddit dedicated to that. At the time I wasn’t aware of it but Github and the graph sure as hell had that effect on me, over time consistency wasn’t as hard as before and became more of a habit, I was longing for my daily side project programming. It was thrilling. I learned a ton, taught myself a lot of new technologies and contributed to the open source community (and earned a few bucks while doing so).

But after a year and a half I decided to quit. Why you ask ?

Quitting

The contribution graph for 2019

I recently had a falling of motivation (it shows on my Github graph around march to may). During that time it was a real hassle to do my daily programming tasks, I didn’t want to do it but I still wanted my green mark so I was cheating more and more, making minor edits, making comments that aren’t really necessary etc. Finally I said “Stop, if you’re gonna cheat you might as well not push anything”. Also Github only adds things to the contribution graphs if you push to master, so I was sometimes working with bad practices because I didn’t want to use branches. (The contributions are counted when you merge the branch to master but it means not having green boxes for quite a while if you work on that branch for weeks). So I realized that this habit was doing more wrong than right. For me at least.

In conclusion

This was a great experience, if you go to my Github you can see that even though I said I “quit” I still push things very often and rarely miss a day, the difference is that I don’t push myself to program every day, I just let it happen. I definitely recommend that you check out steem and utopian.io and follow the same path as I did, it teaches you a lot, it’s also a good way of selling yourself and your skillset to future employers. It’s no longer “hey I love programming, trust me, I do” it’s “look at my Github, see how I code, see my skillset” and if the guy know what he’s talking about he’ll know.
Especially if you have good open source projects to show. In my experience people rarely check your Github but when they do it’s big plus to show your dedication.