Intentional Learning

I was going through my phone’s gallery when I spotted a photo of Izma from The Emperor’s New Groove. It took me by surprise, because I discovered the movie just this year and was absolutely in love with it, especially the Izma character. But the image in my phone’s gallery was from 2018 in the form of a meme. Weird internet stuff. Anyway, I digress. So what are we talking about today.

Ah yes, intentional learning.

Growing up, we all have natural interests. Be it art, science, music or dance, or computers (sigh..). We are motivated to learn new things around our interests. And from time to time, we discover new interests. School is interesting in that regard. You’re thrown in between a bunch of other kids with completely different and random interests, and there’s osmosis of interests happening when we see that other kid in the class drawing something or reading a book about the solar system or they see us playing a new game or so.

But that diversity of interests decreases once we enter university. The people we’re with have chosen a similar course and chances are that they had a similar set of interests. There’s still a fair bit of interesting diversity, and it is still possible to meet people from courses other than ours and see what life outside is like.

But for me the biggest difference was getting out of university and starting full time work. Many small to medium sized workplaces hire people of specific types depending on their culture and/or domain, understandably so. Many are open to diversity of thoughts and ideas, but of course not too open so as to not destroy the culture that they’re trying to cultivate in the first place (which, of course, is important but to what extent is a separate discussion in itself). What happens then is that we end up in bubbles of people with similar interests as us.

Of course, like with many things, this isn’t a black or white, good or bad situation. On the bright side, our spiked growth (say a particular hard skill we’re trying to hone) in a field can really skyrocket when surrounded by the right people and mentors. That of course has a very positive impact on our careers and professional growth.

But what I found lacking was exposure to experiences, interests and hobbies that were far outside of my bubble. And since I wasn’t exposing myself to interests and hobbies outside of the ones that already existed, I was also not meeting people who had these drastically different interests or hobbies (or opinions, for that matter).

For this very reason, I am trying intentional learning. The basic premise is very simple. Find a new skill, hobby or interest and just learn to get good enough, what ever that means, but not perfect. So far this year, I’ve worked on my Chess skills, learned some German, learned a couple of songs on Ukulele, tried my hands on sketching and painting and picking up some photography basics now. Of course, the goal is not to become proficient or professional in any capacity, but just experience the joy of being a complete novice in a new field and seeing how far I can take it.

The side effect is that the curiosity and learning muscles stays in good shape for when one has to learn something new (which proved to be useful when studying for a certification exam recently). The other side effect is becoming more conversationally accessible to a wider part of the population, sharing interests with more and more people. Yet another side effect is that it makes one more empathetic and open minded. Playing chess isn’t any more worthy than making memes or playing guitar or learning programming. Sure, some skills are valued more in the world we live in due to a multitude of reasons, but it takes effort to build any skill and as such nothing can and should be dismissed as unimportant or unworthy of pursuing.

The real joy, however, is in the process of learning; going from not being able to do something to being able to, building muscle memory, watching amateur and pro videos of people doing it on YouTube and being able to talk to someone or join communities with the same interest.

And instead of looking at people who’ve honed that skill their whole life and getting sad that you’ll never reach there, find joy in the fact that you can instead get good enough at it and then move on to hundreds of new skills and hobbies, getting a taste of the different ways to be alive, to exist. You’ll also retain this phase of your interest in your memories, which will feel nostalgic when long time from today you encounter this skill or hobby in some form or the other or meet someone embarking on their journey into it.

In closing

I hope that was interesting to read and motivates a few of you to pick up some random new hobbies or learn something totally different, unrelated to your work or life and see how it goes. I am convinced it has some real merits over the demerits. From my perspective, the biggest demerit is that we end up spreading too thin over a bunch of thing, while not mastering anything. Personally, I’m okay with that right now. But depending on where you stand, it may or may not be. But having said that, it isn’t black or white and leaves a lot of room in the middle to play around and see what works best.

Thank you for reading. Following is a personal message unrelated to the article.

I took a long break from writing, but it is good to write something again. If you visited this website in the last four months anticipating a new post, apologies for the delay and thank you for being a super-reader of my blog. Until next time!

Guide To A Sane WordPress Workflow

Like most things in life, WordPress isn’t perfect. But for a publishing platform, it is quite up there with the best in the business. For writing, I haven’t had any complaints so far, but when it came to customization or workflows around maintaining a theme, I was a little lost.

To me it somehow felt very liberating and restricting at the same time. Liberating, because of the ecosystem; themes, plugins, hosting platforms, tons of helpful resources and support. Restricting, if and when you want to build a custom theme and don’t speak much PHP, general added complexity compared to a static site generator, having to deal with hosting providers, updates and added maintenance work.

But depending on the requirements, WordPress might actually make a lot of sense as a publishing platform (well, of course. It powers 40% of the web). My blog used to be hosted on Github Pages with Jekyll as the site generator until I made the switch to WordPress a couple of months ago. What I did struggle with was finding a setup that offered a smooth workflow around managing a custom theme with self hosted WordPress instance.

This article is an attempt at fixing that and aggregating some useful tips. I’ll try to cover the following:

  • A self hosted WordPress website that’s affordable yet stable
  • Continuous deployment pipeline for custom themes
  • Backups that are reliable
  • CDN and caching
  • Securing the website

Let’s get started.

Platform setup

I decided to go with AWS Lightsail one click WordPress install. You’ll find more information on the Bitnami WordPress page about the stack. It is lightweight and runs perfectly fine on a 512MB RAM / 1vCPU instance. Once behind a CDN and page cache, the website can handle a fair number of visitors.

Continuous Deployment (CD) pipeline (optional: Continuous Integration)

This step assumes you have a custom WordPress theme or source code of a theme available on a GitHub repository. You only need to follow this step if you think you’ll be making frequent changes to your theme files and would like to have a pipeline for the automatic deploy of the theme (say, for example, when you commit a change to the master branch of your repository). Alternatively, you can always create a zip file of the theme and upload it manually via the WordPress admin panel if you prefer to keep things simple.

Assuming you have a theme hosted on GitHub, you’ll need to make use of Travis CI to build your code (if there’s any CSS or JS that needs to be transpiled), test it (if there are any checks) and then upload the files to the AWS LightSail instance using secure copy (scp). Following are some resources to help you get started.

Backups

For backups, I’m using a couple of strategies but I think either one should suffice for my usecase.

AWS Lightsail snapshots

I’d recommend enabling automatic daily snapshots of your instance in AWS Lightsail. So if things go very south, you will lose 1 day’s worth of data at most. Since my blog’s content is rarely updated, this means this works near perfectly.

WPVivid WordPress plugin

WPVivid is a nice plugin that offers more precise backups, meaning you can choose to backup just your database, or files, or both. It also has cron functionality and offer 12 hourly backups (more frequent if you’re a paying customer). WPVivid allows you to transfer the backups to Google Drive, AWS S3, Dropbox among many other third party providers.

Server health monitoring and alerts

I’m using New Relic to monitor the health of the WordPress instance. It isn’t necessary as AWS Lighsail already comes with basic dashboards for monitoring CPU performance and burst usage (giving a rough idea about whether the server is sweating under load), but if you’d like to go a bit fancy with the whole monitoring thing and set up alerts for throughput, error rate etc, New Relic is quite good.

New Relic really shines at showing you the external services your instance is talking to, database operations and the CPU usage share per plugin that you have installed on your WordPress website. That information can help you debug any services / plugins that are slowing down your website or doing something strange behind your back.

AWS metrics
Metrics in AWS Lightsail
Metrics in New Relic
Metrics in New Relic

Both AWS Lightsail alerts and New Relic alerts support multiple channels, so feel free to use SMS, email, Slack or whatever your preferred way of getting alerted is.

CDN and Caching

My go-to CDN for any personal website is Cloudflare and that is what I’m using here. I didn’t have any problems with the admin interface behind the CDN and all seems to work very well. I have a page rule that overwrites cache control headers from WordPress and forces everything under /wp-content/* to be cached.

For page caching, I’m using a plugin called WP Total Cache. It was the most popular performance optimization plugin and was recommended to me. It has a “Page Cache” option which needs to be enabled and set to use disk as cache store.

Security

To secure the Lightsail instance, I’m following some basic good practices and a plugin to help me set up some blocking rules.

  1. Lightsail instance is as close to stock as possible making sure there are no random packages installed from my side on the instance.
  2. Disable port 80, and if you’re using a reverse proxy CDN like Cloudflare, only allow Cloudflare IPs to your origin server.
  3. As with Lightsail, WordPress installation should be close to stock with minimal plugins.
  4. Wordfence WordPress plugin for
    1. 2FA authentication
    2. Banning incorrect login attempts, or login attempts using generic usernames like admin, administrator or root.
    3. reCAPTCHA on the login page (you’ll need API keys from Google)
    4. Disable xmlrpc if you’re not planning on using apps. Enable 2FA on it, or disable login via xmlrpc.
    5. Go through all the options that Wordfence has to offer and use whatever makes sense for your use case. I found them to be quite useful and intuitive.
  5. In general, keep stuff up to date.

Conclusion

That’s it for this article. If you have any questions or suggestions, please feel free to write to me. Thank you for reading.

The Best Time Of Your Life Is Right Now

Humans are fragile creatures. The illusion of stability and control we have in our lives is comical. Our mind seems to have mastered the art of separating itself from the world events. We almost know it. It is hard not to if you spend any time on internet social medias or any form of conventional news sources. Unfortunate things happen, lives end or get ruined for reasons so trivial that’d make you not want to believe it.

Yet, when it comes to our own lives, we’re fairly certain about our timelines. There’s career, that promotion, getting a house, getting married and so on. There’s always the end of life to be content with what we have; be grateful. Now’s the time to be at unrest, to complain and wish for more, to hustle. And not like it is our fault. The society is truly designed to make you feel exactly this way, discontent at every single stage of your life. Get good grades or you’d not get into a good university, study hard or you’d not have a good job, work harder or you’d not get that promotion, don’t plateau in your career or you’d not be able to afford a house, keep working to be able to enjoy a happy retirement and so on.

And what if you’re still not able to enjoy your life finally at 65? Oh those are just the guidelines, too bad it didn’t work out for you. Guess what, it is called 1% for a reason. Try again in the next one. And of course, thank you for your participation in the rat race.

So, what’s my point?

The point that I’m trying to make is that if something is important enough to you, do it without waiting for some special phase of life to come by. No one knows how tomorrow will look like. If this entire pandemic has taught us anything, it is that we have no control over the future, not tomorrow and much less months or years in the future. The present is the only thing we have for certain, so why not make the best of it; by treating it like it is the peak of our health, wealth, social skills and so on.

And how do we do that?

By being grateful for what we have. It is only when we consciously  recognize how lucky we are to have all the things that we do, do we start valuing it. Being able to move around on your own, see, hear, talk, travel, read, write, meet friends, drink coffee, enjoy a sunset or snow; little things that many people might not have the good fortune to experience.

The world is like a nasty slot machine. Luck plays a huge role in almost everything we do, and it starts right at the moment you’re born. We are the product of our circumstances. There’s not much we can do about that, except that we recognize our privileges and act accordingly. Have a chance to do something good for someone? Do it. Realize your actions might’ve caused hurt? Apologize. Have people that pull you back? Filter.

Time really is the only real currency that we have. While it does seem like a tragedy to not know how much more of it do we have left, I think it is a blessing in disguise. Think of the last time you had a deadline for an assignment. Did you wait for the very last moment to do it? If you’re like most people then probably yes. That’s probably what would happen if we knew exactly how long we have to live. We would procrastinate everything until the last moment, wasting away most of it. Fortunately for us, we don’t, and each day can be lived as if it is the deadline for that life’s assignment, doing the things that matter the most to us.

So to summarize, there probably will never be a better time to do certain things, and that’s if you’re lucky to live a full life without many problems. If you’re in your teenage years, you probably have the time to learn something thoroughly, spend time with friends and family, have fun, see clearly if you’re into that. If you’re in your twenties, you have the best balance between intelligence, energy, time and maybe some money too. Later in life you get better with relationships, your emotional intelligence grows and the life experiences you accumulate make you wiser while you’re getting rusty physically. Basically, we live through different interpretations of ‘peak’ throughout our lives, and there’s no one big peak that’s going to solve all your problems and make you happy.

So make the most of your now; make memes, draw comics, write code, learn music, dance, sing, make someone’s day, be vulnerable, be nice, prioritize yourself, talk to random strangers and share stories, gift without a reason, sleep, cry, hug, do whatever you have to. But make your now count.

Thank you for reading!

Life Goes Full Circle – Blog Back To WordPress

Happy new year all!

We’re finally out of 2020, yaay! It has been, for lack of a better word, an interesting year. Not intending on becoming Abhi News Network, I’ll spare you from having to read about the events of the past year for the thousandth time. Like many people, I realized my full nerd potential and learned how to live indoors for weeks at a time. I also unlocked a new hobby, Chess. Some other things like traveling and in-person events definitely took a backseat but can’t do much about that.

This short post is about moving this blog back to WordPress. I say back, but the fact is that this website was never on WordPress. I started this blog on ghost.org back in early 2014, but had to quickly move it away from there in spite of absolutely loving Ghost (mostly because of the $5/month fees). Next up was Blogger before finally settling on GitHub Pages which, by the way, if you’re just starting out with blogging and can find your way around git on a terminal, you should give a try. Now, feeling the need for a much more elaborate CMS, I’ve migrated to WordPress running on AWS Lightsail. It does cost money, but this time I can afford it.

Before this blog existed, I used to write on WordPress on an older blog. That feels like an eternity ago, which it was in internet time. I used to write about latest smartphones and compare them against each other (nothing that actually needed to be done by hand, now that I think about it; 8mp vs 5mp camera, 1gb vs 2gb ram and so on). I would walk into Samsung stores and try to make ‘hands-on’ videos of their latest phones. I can’t imagine doing that today, mostly because of how much the smartphone industry has expanded since 2012-13. Also because it doesn’t interest me anymore.

With WordPress, I hope to be able to write on the go using nothing more than just a browser. “On the go” might take some more time to become a normal everyday phrase again, but when that happens, I’ll be ready with my Thinkpad and a backpack. To not need a text editor to write Markdown/HTML, terminal to commit and push, and to see previews without a developer server would be very liberating. I’m excited about this future.

I’ll end this article with a nice picture I took today. Hope you enjoy looking at it as much as I did looking at Stitch in my house today.

Thank you for reading!

On Reaching 1500 Elo On Lichess.org!

Back in May, I wrote an article on the basics of Chess. Today, I’m super excited to announce and celebrate the milestone of breaking into the 1500s on Lichess.org rapid (barely, but surely).

When I started playing chess back in late December last year, I had little idea where I stood on the chess skills ladder. I knew how the pieces moved and how a game is won, lost or drawn. I also knew castling rules and that queen is kinda important.

But alas, there was a lot more to this beautiful game than just knowing how each piece moved. So after losing a few games in a bar in Amsterdam, I created a Lichess.org account to practice with the computer and online strangers.

I quickly realized I played very bad. It came as a surprise (although in hindsight, I see why it shouldn’t have been one). To me, chess was like cycling. I learned how to play chess exactly like I learned how to ride a bike. You just learn it once (often at a young age) and that’s it, that’s all there is to it, you think.

But as with anything else, chess (or cycling) can be thought of as a skill that can be honed with training. What I think was happening was–I was in a competitive chess environment, playing with the bare minimum understanding of the game against people who treated it like a skill. I was losing most games I played, unsurprisingly. In fact, I had a losing streak of 41 games from January till March and also reached my lowest Elo rating of 863 in the same month.

That’s the 2-percentile among lichess.org users–a little embarrassing

Then came the pandemic and the whole world changed around us. Remote working, lockdown, stay at home etc meant there was a lot of time to invest in a new hobby. It could’ve been German language studies, or something useful, but no. My mind chose the game of chess to become obsessed with.

Over the course of the following months, I played hundreds of games in the evenings, watched videos on chess theory over lunch and thought about chess while in shower. Interestingly, I wasn’t alone. There’s a huge surge of people (re)discovering this game and getting into the community just like I did.


Finally, like the title says, I reached 1500 today. That’s more than 600 rating points gain since March this year. I believe it is purely a function of the time I’ve put into it and nothing else. While it remains debatable whether that’s a wise thing to do, I do recommend giving chess a shot if you’ve not played it in years, especially if you’re in some kind of lockdown or prefer staying indoors and are looking for a new hobby. It is even more fun if you can compete over Elo rating with a friend!

If there’s any general takeaway from this whole exercise, it is that with enough practice and motivation, seemingly impossible things become possible. The world is full of arbitrary things. Chess and other such games, surely, but also many more allegedly important things like career prospects or learning a new language. Just things made by us for ourselves. So it follows that mastering German or getting the dream job could be similarly approached–immersion, finding that bit of motivation, finding people to have friendly competition with and seeing the results and improvements immediately (and some of that sweet sweet luck, of course).

I leave you at that until next time. Thank you for reading!

Become A 10x <anything> [fail]

Beware the barrenness of a busy life.

– Socrates (from my quotes file)

Today, we’re going to learn how to be a 10x anything. We’re going to do that by putting slack on mute. But not the simple way. That works, but don’t expect 10x results. Also, this guide assumes that the most distraction during worktime comes from Slack. If that’s not the case for you, you might end up with ~4.5x results (scientific).

What we’ll essentially be doing is:

  • Set up Pi-hole on our home network. Pi-hole is a DNS based ad blocker which sinks requests if they’re for ad network.
  • Use Pomodoro app on KDE to trigger scripts when the focus session starts and ends. If you haven’t heard about Pomodoro technique, read up more here: https://en.wikipedia.org/wiki/Pomodoro_Technique.
  • The scripts themselves will block any website / app that you don’t want distracting you when the focus time is on.

Pi-hole

Pi-hole is amazing! No, seriously. It blocks all ads and tracking, has a very good interface which supports custom rules for each device, groups and more. All of this is free, open source and pure. Did you star the repository already?

Pi hole can not only block DNS queries for ads/tracking networks, but also anything you ask it to. We’ll use it to block Slack on our network.

Raspberry Pi

We need something to run the Pi-hole, so grab a Pi zero or a normal Raspberry Pi. A virtual machine / docker would work but then you need that thing running 24/7.

Pomodoro app that supports scripts

I’m sure your operating system of choice has a Pomodoro app made for it. The trick here is to find one that supports executing scripts on certain events like focus time start and end.

As you can see, Fokus on the KDE store supports this functionality and is perfect for me since I’m already on KDE.

Router with custom DNS setting

We need to change the DNS settings in our router and point it to our Raspberry Pi’s IP address. As a backup, we still keep 1.1.1.1. Most routers support this setting. If for some reason you’re not able to do it at the router level, you can still set custom DNS on each of your device, which is a bit more work.

Ability to not overthink

Given how futile this whole exercise is, if you start questioning yourself why am I even doing any of this when you could just mute Slack?, this exercise (or this blog) is not for you.

Tutorial (kinda)

The initial setup is very standard. Install Pi-hole on your Raspberry pi by following their official guide. Get the Pomodoro app up and running.

Once that’s done, we create a directory on our computer and create two files in it: focus-start.sh and focus-end.sh and mark them executable

$ mkdir hackerman && cd hackerman
$ touch focus-start.sh focus-end.sh
$ chmod +x focus-start.sh focus-end.sh

As the file names suggest, the focus-start.sh will execute when our focus time starts and focus-end.sh executes when our focus time ends. It should look like this in Fokus, our pomodoro app.

So now that this is configured, we need to enable passwordless ssh access to our Raspberry Pi. I followed this guide here. What that enables is just typing ssh [email protected] will log us into the Pi without a password.

Next, we open our files and add the commands to enable and disable Slack’s domain using a wildcard blacklist/whitelist entry.

# focus-start.sh
ssh [email protected] "pihole --wild 'slack.com'"

# focus-start.sh
ssh [email protected] "pihole --wild 'slack.com' -d"

The focus-end.sh command is only different in that has the -d flag, which removes the wildcard domain from the blacklist. We can even try running that command on the terminal and verifying if it creates an entry in Pi-hole. Remember to substitute raspberrypi.local with your Raspberry Pi’s hostname / IP address.



That’s it. The other command works as expected too, removing the slack.com’s wildcard entry at our discretion.

So, how does it (not) work?

Theoretically, we’re sinking any DNS query for slack.com and any of its subdomain meaning the APIs won’t work once the blacklist entry has been created. But there are a couple of problems with our approach.

One, Slack’s messages are transferred over Websocket and once that’s established (when you open the website / app), it doesn’t need DNS to work (resolve) for sending and receiving messages.

Even if it did, DNS queries are cached (by a variety of entities like browsers, operating systems etc), so it isn’t like this is fool proof and starts working the second it is turned on.

Third, many apps use their own DNS and have little regard for your home DNS. For example, I tried to block Whatsapp this way (using this list) and it just doesn’t work, at least on Android.

A complete fail then?

Not exactly. You can still block websites that you open in browsers, like reddit.com and youtube.com if you spend too much time on those like me. In any case, it is a fun way to learn about how web apps, DNS and ad blocking work and involves a lot of trial and error to get things to work. Oh and yes, we do have a network wide ad blocker which is what Pi-hole does best, so there’s also that.

That’s it for this one. Thank you for reading.

DIY Web Analytics

I’ve long established that adding heavy duty analytics and tracking scripts to my blog pages isn’t the right thing to do. Personally, it is also a bit liberating to not know which article of mine is getting a lot of traffic and which isn’t, because then I’m not biased by what the internet is searching for and can write about pretty much anything that I feel like writing about. 10 programming languages you should learn in 2020 has exactly the same weight as Let me tell you a funny story from last night, so which one do think I’d write about?

The analytics and tracking world has come a long way and is viewed very negatively in the light of recent internet incidents. But it started off very simple and had a very simple and non-malicious idea at its core: Getting to know your user better so that you can serve them better.

That thought made me search for a simple analytics solution that I could run on my blog for a couple of weeks and get enough insights to make informed decisions regarding the frontend design changes while not compromising on the privacy of the visitors. If I’m completely honest, I was also just curious to know these things with no agenda behind it.

I looked into Simple Analytics, a nice solution that does exactly what I needed (perhaps a bit more than that), but a little expensive for me at USD 19 a month. There are also self hosted analytics solutions like Plausible, but that was too much work for realizing this simple thought. So I decided to put something together quickly and the following is what I ended up implementing.

Client side JavaScript

On the client side, I needed to get the data that interested me. It was details like the browsers used by my visitors, platform, width of their screens etc. More technically, the user agent, platform, screen width, referrer and the current page’s url (although I don’t plan on using it for this article. Spoiler: One of my lowest effort articles is pulling more than half of all pageviews which is a bit saddening).

1
2
3
4
5
6
7
8
9
10
11
if (!('doNotTrack' in navigator) || !(navigator.doNotTrack === '1')) {
  let analytics = 

  analytics["href"] = window.location.href
  analytics["userAgent"] = navigator.userAgent
  analytics["width"] = window.innerWidth
  analytics["referrer"] = document.referrer
  analytics["platform"] = navigator.platform

  navigator.sendBeacon(ANALYTICS_ENDPOINT, JSON.stringify(analytics
}

There’s not much happening here. Just checking if the user prefers to not be tracked, else get the desired data and POST it to our analytics endpoint using the navigator.sendBeacon API.

Server

We need to implement the endpoint that’s listening for the POST requests from our client browsers. I decided to go with Firebase’s functions for handling the request and Firebase’s realtime database to store the data.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const functions = require('firebase-functions'
const admin = require('firebase-admin'

admin.initializeApp

const cors = require('cors')({
  origin: true,


exports.handler = functions.https.onRequest(async (req, res) => {
  if(req.method === 'POST') {
    const snapshot = await admin.database().ref('/hit').push(JSON.parse(req.body
    return cors(req, res, () => {
      res.json({ message: 'success' 
    
  }
  else {
    res.json({ message: 'have a good day!' 
  }

Now this is super bad code for a variety of reasons, but it worked for my temporary needs. I deployed this, waited for a couple of weeks and had some data to answer some basic questions about my blog’s visitors.

Parsing data

So at this point I had let this code run long enough to have accumulated couple of hundred entries. It was time to analyze. Firebase allows you to easily export the database in JSON format. Using some basic Python-fu, I created lists of each dimension and passed these lists to Python’s builtin collections.Counter (which is perfect since I’m only interested in aggregated stats), and then take the top 5 most frequent items using the .most_common method. Finally, we plot bar charts for these top 5 values across each dimension using Matplotlib to visualize the results.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import json
from collections import Counter, defaultdict
from user_agents import parse
import matplotlib.pyplot as plt

analytics_data = defaultdict(list)


def plot_chart_from_ctr(ctr):
    most_common = ctr.most_common(5)
    x, y = [item[0] for item in most_common], [item[1] for item in most_common]
    x = [str(i) for i in x]
    plt.bar(x, y)
    plt.show()


def driver():
    with open('export.json', 'r') as output:
        data = json.load(output)
        hit = data['hit']
        entries = []
        for item in hit:
            entries.append(hit[item])

        analytics_data['height'] = []
        for item in entries:
            analytics_data['width'].append(item['width'])
            analytics_data['href'].append(item['href'])
            analytics_data['platform'].append(item['platform'])
            analytics_data['referrer'].append(item['referrer'])
            analytics_data['userAgent'].append(item['userAgent'])

    browser_family = []
    for agent in analytics_data['userAgent']:
        user_agent = parse(agent)
        browser_family.append(user_agent.browser.family)

    ctr_browser_family = Counter(browser_family)
    plot_chart_from_ctr(ctr_browser_family)

    ctr_platform = Counter(analytics_data['platform'])
    plot_chart_from_ctr(ctr_platform)

    ctr_referrer = Counter(analytics_data['referrer'])
    plot_chart_from_ctr(ctr_referrer)

    ctr_width = Counter(analytics_data['width'])
    plot_chart_from_ctr(ctr_width)


if __name__ == '__main__':
    driver()

The questions

What are the most common browsers?

I would’ve guessed this to be the case for browsers, but not in Chrome’s favour to this extent 🙁

What are the most common platforms?

Win32 is still the majority platform among my visitors and there’s some Apple action going on. There’s also a healthy chunk of Linux X86_64 visitors. The armv7l and armv8l may contain Android devices but hard to tell.

What are the most common referrers?

Unsurprisingly, most of the traffic comes through Google.

What are the most common screen widths?

There’s a healthy mix of screen resolutions with the most frequent being 360px.

In closing

So that’s it for this little article. I’m happy with the outcome given how little effort went into this whole assignment. I hope you enjoyed reading it. As always, write me an email in case you have any comments!

Thank you for reading.

A Tale Of Internet Speeds

Similar to the last two articles, this one is about the little improvements I’m making to my workstation. So far, I got a gaming mouse and a mechanical keyboard, a nice desk pad and a 24in full HD monitor from Dell to add to my existing setup (while we’re at it, do checkout my setup page here).

For this one, I’ll be talking about internet speed, and the upgrade associated with it. This upgrade is special in more than one way and hence, I want to go into a bit of history, my history with internet bandwidth.

Ever since adolescence, internet has been a basic necessity for me and the people from my age group (even before it becoming a source of livelihood for many of us). One of my first memories of the internet is this screen:

I distinctly remember this from my first computer*, an HP desktop PC with a Pentium Dual Core processor and 1 GB RAM, since it also had 100Mbps LAN card. Not knowing the difference between hardware capabilities and internet bandwidth, I naively assumed that when I get a broadband connection, that’s the speed I’ll see. But little did I know it would take more than a decade to reach this milestone.

*which practically didn’t exist by the time I started writing on this blog, and as a result there’s very little, if any, mention of my first computer here.

Life at 10KB/s

Back in those days, in around 2008-2009, we didn’t have broadband at home. My PC was barely 6 months old and I had realized that there’s only so much GTA Vice City one can play and be entertained.

My dad had this Nokia Expressmusic 5310 phone that supported Edge network, so slightly faster 2G. I figured out that if I can get internet on that phone, I could use the CD that came it to tether internet to my PC. I remember it was INR 98 or 99 for unlimited 2G data then.

It worked, but the speeds were really miserable. On a good day, keeping the phone on the window sill, I would get around 10KB/s or 80kbps which is close to the promised speed of 16.8KB/s or 135kbps. At those speeds, speed test websites like speedtest.net just don’t load, much less show you your network speeds. Facebook, which people used back then, took more than a couple of minutes, literally, to load. Needless to say, Youtubing or any sort of video streaming was out of question.

Even download small files, like a couple of megabytes, was a challenge, and I would almost never download directly using the browser. I would always use the fancy bloated download managers which supported resume functionality and parallel connections (not like it made a difference, but who knew).

I was on Windows XP, no firewall or antivirus software, downloading these shady browser plugin and download mangers. Those were the wild days!

Nmap download adventure

One incident worth mentioning is the download of Nmap, a network scanning tool. It was around 15MB in size, and believe it or not, it took me many months worth of trying to finally download it. The download would always fail and no download manager helped. But when it finally did, my joy knew no bounds and it genuinely made me happy. It is a bit weird that I still remember it so vividly, but it was special in a way.

So anyway, the struggle continued for a while. For the next couple of years I would ask friends or my aunt to download me anything that was more than 20MB in size.

Emergence of broadband

I finally got a broadband connection. It was a 2Mbps connection capped to 1GB of data. 1 whole gigabyte of data for the whole month. It definitely improved things a bit, but on the whole it was still painful. Now the internet was fast enough to watch a Youtube video in 720p. But if I did, that’d pretty much be the only thing I did that month.

I ‘upgraded’ to a 512Kbps unlimited connection which was a lot better. This was, in fact, my first real broadband. Usable, and unlimited. 65 kilobytes a second isn’t bad, especially for browsing the web or download a GB or two of data overnight. That also started this whole phase of my life when night time was download time. I remember the disappointment I used to have after checking the download progress first thing in the morning and realizing the download failed halfway through.

But yes, the internet was within reach.

Real broadband speeds

I changed ISP a couple of years later as the first one was too bad in terms of service, and got a local one with Google and torrent peering. Basically, any website owned by google would work at higher speed, which would typically be around a couple of MB/s. Even speeds of up to 40mbps weren’t unheard of, as long as you’re able to find it on a Google service. This same ISP later upgraded my connection to some 8mbps for free.

That was my first time breaking the 1MB/s barrier. Major achievement.

The upgrades after this were incremental, if I’m being honest. I think I was at 25mbps by the time I left for Germany. After settling down here in Germany, I opted for a 50Mbps link. 50Mbps is exactly like 16Mbps for 90% of the time (unless of course you’re downloading stuff in a hurry).

So in that sense, I already knew that going 100Mbps isn’t going to bring any meaningful change to most of my surfing habits. But it does feel like a big change, psychologically. Remember that image from before, the one which says 100Mbps speed on the LAN interface status page? I’ve finally maxed that out, a little over 11 years later.

My 13 year old self might find it unimaginable to think of what a 12MB/s broadband connection feels like, which is a bit of a jump from his humble 10KB/s flaky dial-up connection tethered off a 2G mobile phone.

Edit – 31/07/22

I moved into a new flat that supposedly has a gigabit internet connection. I’m getting 500+ mbps speeds consistently which is unbelievable. I also got a phone that supports 5G which also pulls data at rates upwards of 500 mbps. I’m living the dream!

In closing

I’ve mentioned this a few times before, but I’ll do it again. Adulting, getting a job and living on your own has little meaning to it if you don’t realize those childhood dreams, which for me is overkilling on tech stuff and buying 8 year old laptops off ebay.

Having said that, I might actually make use of the bump in upload speed, which does bottleneck my offsite backup plans. Stay tuned for updates on that front. Also, downloading ISOs and doing system updates are a delight these days.

Finally, I’d probably never feel the same level of joy that I felt on getting a real broadband after years of doing sub-10KB/s on mobile data. But that makes me think of all the things that I’m getting started on, my professional career, a new language that I’m learning, Chess, or anything that I’m a newbie at. With each passing milestone, the next one becomes a little less exciting. Keeping that in mind, I should try to celebrate any incremental progress that I make in any of these things. That was just a long way of saying that the journey matters more than the goal.

Thank you for reading!

IKBC MF108 V3 Unboxing And Review

Lenovo recently released their Thinkpad TrackPoint Keyboard II which I got super excited about. I could finally use a keyboard identical to my laptop’s while not having the laptop down on my desk, something that’s bad for posture and causes neck strain. But while looking at it, and some other options, I found some very pretty mechanical keyboards from brands that I had never heard of before. After a few days of searching the web and watching review videos, I decided to go for a mechanical keyboard instead of the Lenovo one. That’s the prelude to my journey of acquiring my first mechanical keyboard.

In this little article, I’ll talk about mechanical keyboards in general, and then talk specifically about the one that I chose. If you’re here just for the review of IKBC MF108, feel free to skip to the actual review.

What is a mechanical keyboard?

Unlike a membrane based keyboard found on most laptops and many cheaper desktop keyboards that we’re all familiar with, mechanical keyboards have a separate switch for each key. The switch action is similar to how a household electrical switch works; with a metal contact completing the circuit and registering a ‘click’. The kind of switch determines how the switch will react to being pressed (if it will make a click sound, or if it will have a tactile feedback, or if it will be heavy or light etc). I recommend this helpful video to get a better idea.

Mechanical keyboards are, generally speaking, more expensive than their membrane counterparts. They also last quite a bit longer, which is mostly due to quality materials that go into their manufacturing (Cherry claims 50 million clicks for the Cherry MX Blue switches). These keyboards can be customized with a wide variety of keycaps (the part that we touch with our fingertips while typing), switches (the part that actually registers the keypress – look at the image below) and the case (the enclosure for all of the components).

Cherry MX Blue, a popular switch from Cherry GmbH, a keyswitch manufacturer, in action. Notice the tactile bump on the way down – Source

Cherry MX switches beneath the keycaps on my IKBC MF108. The switches are transparent to allow for the backlight to shine through the switch’s case

Apart from the functional stuff, many of the mechanical keyboards have some sort of backlighting, even fully customizable RGB for aesthetics (and for typing in the dark if you need to look at certain keys).

IKBC MF108 V3

Okay, so let’s get to the meat of this article. My first mechanical keyboard and my thoughts after having owned it for the last four days or so.

Build quality

As soon as the delivery person hands you the package containing the keyboard, you’ll notice the weight. It is heavy, and not in the way of a sensation or feeling. It is literally heavy. How heavy, you might ask. Very. You’d probably not be able to pick it up with just one hand, and to someone unsuspecting, they might think it is glued to the desk if they try picking it up. It weights around 2.5 kilograms, and can cause serious injury if you drop it on your foot.

I made a very amateur unboxing video that’s embedded below. It shows what you get in the retail box and my initial impressions. I’ll link some timestamps in the video description so that you can skip to points of interest (it is a super long video of me fiddling with stuff).

Connectivity

It comes with a USB cable (USB-C port in the center on the back) and connected seamlessly to my laptop running Ubuntu. I don’t mind the lack of bluetooth/wireless. Would’ve been nice for some minimalistic desk setup, but I’m not very keen on such things.

Included accessories

A couple of accessories are included with the keyboard. Extra blue and red keycaps which are fairly low quality. A dust cover that doesn’t fit. The USB cable feels nice to the touch.

Overall I’d expect more quality in the accessories department for the price. On the bright side, the part that actually matters–the keyboard itself–looks uncompromised on quality. My unboxing video has timestamp to the point where I show all of these accessories.

RGB backlight

Key labels are nice and crisp, and it is a pleasure looking at the keyboard in dark

I loved the backlight. The lights can be controlled from the keyboard itself (brightness, per key color, prebuilt modes, stopwatch functionality etc) and thankfully doesn’t need a software (it is especially important if you don’t run Windows OS as most of these software are made exclusively for Windows).

Typing and click-y sound

I’m not super fast at typing, but could type at roughly the same speed as on my laptop at around ~65wpm.

Double shot ABS keycaps

This keyboard features ABS double shot keycaps. ABS is considered inferior as compared to PBT found on many other competing keyboards. This article goes into the difference in detail. Since this is my first keyboard, I don’t have a taste so can’t comment. Also, it is fairly easy to replace keycaps whenever you feel the need for change.

Price and purchasing – Shout out to CandyCase

It is retailing for EUR 190 at CandyKeys at the time of my writing, which is exactly what I paid for it. It is hard to get an ANSI layout keyboard, or any mechanical keyboard for that matter, here in Europe (slightly envious of my friends in the US right now).

I can highly recommend CandyKeys and its founder David (who handles the support@ email address). Super quick with the support and provides honest recommendations (didn’t expect that). The processing took a couple of days after payment and so did the shipping. Overall, very satisfied with the service so far.

Certain misconceptions about mechanical keyboards

Mechanical keyboards are only for gamers: They certainly are for gamers but a lot of people who work with computers, including software developers, also prefer these keyboards because typing on them is a joy.

Mechanical keyboards are loud: Some are, while others aren’t. There are tons of options when it comes to choosing the switches.

Mechanical keyboards are gimmicky: There’s no shortage of bright blinking mechanical keyboards that scream “look at me”, but there also are very professional beautiful keyboards that’d sit on your desk without a hint of the brilliancy unless someone decides to take a closer look.

Leopold FC660C

Mechanical keyboards will make your friends/colleagues go wow!: Most people will roll their eyes if you start talking about your beautiful keyboard or how nice the clicks sound. Probably the only people who’ll care are a bunch of random internet strangers over at r/MechanicalKeyboards, so make sure you post a snap of your new keyboard there.

Mechanical keyboards make you a 10x programmer (or gamer): I honestly think it doesn’t make that huge of a difference in your overall productivity. They certainly are a joy to type on and add character to your workstation, but is it worth spending hundreds of Euros on? Depends on what you currently have. Probably a secondary monitor would do you more good 🙂 But hey, if you can afford one and it brings you happiness everytime you look at it, go for it!

In closing

That’s it for my keyboard review article. I hope you found it useful. Your first keyboard doesn’t have to be super expensive. There are plenty of good quality keyboards in 60% or TKL sizes (more on sizes here: keyboardco.com) that would’ve been my first priority had they been in stock. Ducky, Leopold, Anne Pro are some of the brands I kept hearing about all over the place (perhaps good marketing?) so do check them out.

Before deciding on the switch type, I went to a nearby electronics store to try the different switches on the keyboards on display there. I’d recommend you do the same if this is your first time, just like me. If you have any questions or comments, feel free to write me an email.

Thank you for reading (and watching)!

So we’re making it a thing now? 6th Anniversary Of Blog

I wrote a blog birthday blog post last year, and the year before that and for whatever reason, one after the first year but none in between. So I think we can really say I’m making this a thing going forward. But that’s okay, as there’s something happening around this time every year. This year our senses are clogged by the news from the pandemic going on around the world which I touched upon a bit back in April.

Compared to April, things are much better right now here in Germany. We can go out and meet friends, eat at restaurants and shop for our favourite stuff. Life’s slowly getting back to normal, although there’s still that element of fear of catching the virus. Things aren’t as good in India, so it is anyone’s guess when I get to visit home next ‍♂️

As for my blog, this year wasn’t super active apart from a few posts and some cosmetic changes to the template. An interesting moment was a blog post getting featured in RealPython‘s newsletter! I’m quite proud of that.

I want to move the blog away from Jekyll, maybe to something Python based. Don’t get me wrong. I love Jekyll on Github Pages, but it is just too straightforward with rarely any problems to fix. I want something that’d break, allowing me to fix things and learn. But all of that is still to happen. Hopefully I find a stretch of time to finally make the move to a different blogging platform in the near future.

As for the rest of the year, I plan on making my workstation a little better, so expect small tech gear reviews here and there from the purchases I make. You can also expect more on Python programming and infosec as that’s on the agenda. So yeah, that’s it for this blog birthday celebration on a slow lazy Sunday afternoon. Cheers, I’ll see you in the next one.

Thank you for reading!