<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Gridranger</title><link href="https://blog.gridranger.dev/" rel="alternate"/><link href="https://blog.gridranger.dev/feeds/all.atom.xml" rel="self"/><id>https://blog.gridranger.dev/</id><updated>2026-05-18T12:03:00+03:00</updated><entry><title>Mobile OSes (featuring Fairphone 5)</title><link href="https://blog.gridranger.dev/mobile-oses-featuring-fairphone-5" rel="alternate"/><published>2026-05-16T17:03:00+03:00</published><updated>2026-05-17T13:27:00+03:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2026-05-16:/mobile-oses-featuring-fairphone-5</id><summary type="html">&lt;h2&gt;How to select a mobile OS&lt;/h2&gt;
&lt;p&gt;Perhaps Android was a great idea back in the old days, but since Google transformed it into a spyware platform, Google Android devices are effectively working against their owners. That's why I started to look for alternatives, and perhaps you have the same reason …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;How to select a mobile OS&lt;/h2&gt;
&lt;p&gt;Perhaps Android was a great idea back in the old days, but since Google transformed it into a spyware platform, Google Android devices are effectively working against their owners. That's why I started to look for alternatives, and perhaps you have the same reason for reading this article now.&lt;/p&gt;
&lt;p&gt;I started drafting this post on 20 November 2025. It took a while to get it into its final shape. I'll summarize all the things I've learned and experienced about alternative smartphone OSes. Most of the credit isn't mine as I've read tons of helpful posts and discussions on this topic on Mastodon and on various sites. I hope I can spare you some time with this, so you don't have to spend as much time as I did collecting this info.&lt;/p&gt;
&lt;p&gt;If you find mistakes, misinterpretations, or anything outdated, feel free to reach out through the comment section (click the 💬 button at the bottom of the screen). I'll be happy to fix, improve, and update this article.&lt;/p&gt;
&lt;p&gt;I tried these OSes on Fairphone 5. It's no longer available to buy, but most things written here are true for other devices running the same OSes. I will mark those parts that are Fairphone 5-specific.&lt;/p&gt;
&lt;h3&gt;Grouping OSes&lt;/h3&gt;
&lt;p&gt;First, there are the customized, degoogled Android versions that are built on top of the &lt;a href="https://source.android.com"&gt;AOSP (Android Open Source Project)&lt;/a&gt;, a free and open-source base for all Androids. Commercial stock Android versions are built on top of the same foundation. Most degoogled variants are forked from &lt;a href="https://lineageos.org"&gt;LineageOS&lt;/a&gt;, as it is popular, has a large supporting community, and has a &lt;a href="Stefanie Jane"&gt;long history&lt;/a&gt;. Back in 2014, I, too, flashed its predecessor on my &lt;a href="/my-phones#samsung-galaxy-ace"&gt;very first Android device&lt;/a&gt;, and I loved it.&lt;/p&gt;
&lt;p&gt;Examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;AOSP based:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CalyxOS&lt;/li&gt;
&lt;li&gt;GrapheneOS&lt;/li&gt;
&lt;li&gt;LineageOS&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;LineageOS based:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;/e/OS&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;iodéOS&lt;/strong&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Second, there are the mobile Linux distributions. These are closer to traditional Linux OSes than Android and emphasize openness. They are mostly community-driven and open-source, even if they have some closed-source components. (Note: Some components of SailfishOS are proprietary and closed-source, but otherwise it belongs here.)&lt;/p&gt;
&lt;p&gt;Examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Mobian&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;postmarketOS&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SailfishOS&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ubuntu Touch&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This article will discuss the ones written in bold.&lt;/p&gt;
&lt;p&gt;As a last comment here: yes, Android is built on top of the Linux kernel, but the whole stack is different otherwise. Commercial Androids are closed, vendor-locked ecosystems where proprietary software dominates the system. The mentality behind the system is very different from that of Linux.&lt;/p&gt;
&lt;h3&gt;Trade-offs&lt;/h3&gt;
&lt;p&gt;It's important to clarify beforehand that replacing Android with a different OS comes with compromises. This list helps to avoid any disappointment that would come later in the process. These aren't Fairphone 5-specific but are true for all Android devices that can run alternative OSes. Things usually lost are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;You can't pay with your phone.&lt;/strong&gt; This works almost exclusively with Google's software. Neither can degoogled Androids make it available, nor can mobile Linux distributions. I won't repeat it for every alternative.&lt;/p&gt;
&lt;p&gt;Explanation: Google pretends to be a gatekeeper of security. Funny, isn't it, after they turned out to be one of the largest spyware companies in the world. The real reason is to lock users and developers into their ecosystem. There are some rare banking applications that work without Google's API and are perfectly secure, but that's less than 1%. Some degoogled Android variants provide a collection of services called microG to make most applications work. Unfortunately, microG also doesn't support any API for NFC payments.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The main camera will not work.&lt;/strong&gt; Although secondary cameras (like ultra-wide) and selfie cameras might work to a certain degree, for many devices, there is no solution so far to make the main camera work properly.&lt;/p&gt;
&lt;p&gt;On these devices, the images taken are noisier, blurrier, and more discolored than the camera would be capable of under stock Android. The reason is the chipset manufacturer's decision to force you to use Google's product. Monopoly men scratch each other's backs. There is also the lack of proprietary post-processing software that is included in stock Androids by the manufacturers. Both are hard to replicate.&lt;/p&gt;
&lt;p&gt;On other devices, where it was solved, the full camera module works perfectly. Thanks for &lt;a href="https://mementomori.social/@ancientsounds@mastodonapp.uk/116585864926864734"&gt;the correction&lt;/a&gt;, Ancient Sounds. These are great news.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The fingerprint sensor is not supported everywhere.&lt;/strong&gt; Degoogled Androids and mobile Linux distros relying on the Halium compatibility layer (Ubuntu Touch, Sailfish OS) usually support them. But it is not always solved on other mobile Linux distributions. The usual explanation is that the manufacturer doesn't share the driver to maintain security, but that sounds fishy. I don't think Lenovo notebooks' fingerprint sensors are less secure just because they work out of the box under Linux.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Different app selection.&lt;/strong&gt; Leaving Google behind is saying goodbye to the Play Store. It means you might not be able to run all applications.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Degoogled Androids&lt;/em&gt;: Some offer a store like Aurora, which allows you to install and run most apps from the Play Store. Even from other regions. Others are shipped with F-Droid (which can install Aurora, by the way). Although these two are usually enough in most cases, it can still happen that your favorite app (or a necessary one, like your banking app) does not work without Google. To avoid surprises, check it before you migrate. For example, you can check if your banking app is available for /e/OS &lt;a href="https://community.e.foundation/t/list-banking-apps-on-e-os/33091"&gt;here&lt;/a&gt; and the same for SailfishOS &lt;a href="https://forum.sailfishos.org/t/banking-apps-on-sailfish-os/18438"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Mobile Linux OSes&lt;/em&gt;: They can't run Android apps natively, but they can run an app called Waydroid. This can run a full Android environment (usually a version of the degoogled LineageOS) and you can install applications inside. Apps run inside have the same restrictions as I wrote about the degoogled Androids above. Also, virtualizing a second OS on your phone can take its toll on your phone's battery life. In some cases, Android apps installed on Waydroid can be launched directly from the menu. This is a great convenience feature, but Waydroid will run silently in the background, so even if you don't have to launch it manually, it will drain the battery.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;GPS&lt;/strong&gt;: GPS might position slower under mobile Linux or not work at all.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;4G/5G voice calls&lt;/strong&gt; (also known as LTE calls, Voice over LTE, or VoLTE): It doesn't work on all mobile Linux distributions and all devices alike. Your geographical region (provider and country) can also influence it. Search for your device, OS, mobile operator combo to avoid unpleasant surprises.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Tech background&lt;/em&gt; (contains jargon, feel free to skip): 4G was data-only initially. To simplify: your phone used 4G for browsing, but when it made a call, it executed a so-called CSFB or 'circuit-switched fallback' and used the 3G or even the 2G networks to make the call. A new technological advancement called IMS (IP Multimedia Subsystem) was required to enable voice calls that are 'packet-switched', meaning they are digitized, compressed, and transmitted as IP packets like everything on the internet from emails to streaming. 4G and 5G voice can be problematic if the OS can't register the device to the IMS or can't communicate with it properly.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;File system access&lt;/strong&gt;: Whether it is good or bad depends on one factor: the intention behind locking it.&lt;/p&gt;
&lt;p&gt;Android's file system is locked for security reasons and to prevent users or apps from damaging it. Its consistency is also important to ensure over-the-air upgrades won’t break. In my opinion, the most important reason is to make consumers forget that they hold a universal, &lt;a href="https://en.wikipedia.org/wiki/Turing_completeness"&gt;Turing-complete&lt;/a&gt; computer in their hands. This allows the manufacturer to be the one who decides what the people who paid for the device can do with it. Absurd, if you ask me.&lt;/p&gt;
&lt;p&gt;Opinion: although I don't like locked file systems on my personal device, this can be important for others. Also, generally, it might be better to have it locked, but what I feel is important is to have a choice.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;No eSIM support&lt;/strong&gt;: It's handy if available, but not important for everyone. It's a generic issue, I won't mention it again for all OSes. It's not possible to make it work yet due to missing drivers.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Work profile&lt;/strong&gt;: In order to have a work profile, managed by your employer, you must have a Google Android. Neither degoogled Androids nor mobile Linux OSes support it. There can be some solutions to have multiple instances of the same software on your device, but that is not the same as what companies need. If your job requires a work profile, you must remain on Google Android or keep a secondary phone. I kept my &lt;a href="/my-phones#hmd-nokia-x10"&gt;Nokia X10&lt;/a&gt; for this purpose. It's a generic issue, I won't mention it again for all OSes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Mobile OSes&lt;/h2&gt;
&lt;h3&gt;Ubuntu Touch&lt;/h3&gt;
&lt;p&gt;Links: &lt;a href="https://www.ubuntu-touch.io/"&gt;official site&lt;/a&gt; | &lt;a href="https://devices.ubuntu-touch.io/device/fp5/release/noble/"&gt;for Fairphone 5&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I had high hopes for Ubuntu Touch and was also informed about its drawbacks. I didn't want to have unrealistic expectations.&lt;/p&gt;
&lt;p&gt;The installation was about 95% smooth. Impressive! Still, my opinion is that Ubuntu Touch has a long way to go before it can be a daily driver. For me, at least.&lt;/p&gt;
&lt;p&gt;The plus side:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It's Linux!&lt;/li&gt;
&lt;li&gt;You have terminal access!&lt;/li&gt;
&lt;li&gt;It was simple to install Waydroid and easy to use.&lt;/li&gt;
&lt;li&gt;The UI is great: if you use Waydroid, it's easy to switch back and forth.&lt;/li&gt;
&lt;li&gt;The task manager is easy to use.&lt;/li&gt;
&lt;li&gt;Device speed is perfect.&lt;/li&gt;
&lt;li&gt;Fingerprint sensor works.&lt;/li&gt;
&lt;li&gt;Plugging my Fairphone 5 into my docking station with USB-C attached my two daisy-chained displays, keyboard, and mouse. Zero configuration or installation was required. I can't emphasize enough how awesome it was! But remember, that's a device-dependent feature. Ubuntu Touch is capable of this, but it needs the device to support it too. For example, neither the Fairphone 4 nor the Fairphone 6 support external devices under Ubuntu Touch. &lt;/li&gt;
&lt;li&gt;Syncing contacts was fairly straightforward. (On the other OSes too, but I didn't know what to expect here.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Issues I expected (it's a short list because the Fairphone 5 is one of the best-supported devices):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Main camera doesn't work, but it is device-specific. On OnePlus 6T, for example, the camera works without issues.&lt;/li&gt;
&lt;li&gt;VoLTE can have issues.&lt;/li&gt;
&lt;li&gt;GPS is slow at first.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Things that surprised me:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ubuntu Touch's own app store, &lt;a href="https://next.open-store.io/apps/"&gt;Open Store&lt;/a&gt;, is almost empty. As of now (2026-05-12), it has 583 apps. Just to compare: F-Droid has 4-5000 and the Play Store has 2-4 million. And even from this less than 600 apps, about 60% of the ones I tried were broken. Many are outdated and abandoned by their developers.&lt;/li&gt;
&lt;li&gt;I was prepared for the fact that you can't use native Debian, Flatpak, Snap, or Alpine packages. It uses its own packaging format: Click. I tried to tinker with Libertine, which is a compatibility layer to make application installation possible. The guides are great, actually, the installation worked well too, but the installed apps didn't. I tried three different apps before giving up.&lt;/li&gt;
&lt;li&gt;There is no integrated password manager. UTPass is recommended, but it didn't work.&lt;/li&gt;
&lt;li&gt;Morph browser, which is the default one on Ubuntu Touch, was not up to the challenge when I tried it in November 2025. One-third of the commonly visited websites didn't work with it. It also failed Cloudflare verification. While using it, I was treated as a bot or an AI scraper and locked out from many sites. Based on Georg Weissenbacher's &lt;a href="https://mementomori.social/@GeorgWeissenbacher@fediscience.org/116586332534163157"&gt;update&lt;/a&gt;, the new Qt6-based version performs better.&lt;/li&gt;
&lt;li&gt;I tried out uWolf, which is a Ubuntu Touch port of &lt;a href="https://next.open-store.io/app/uwolf.chromiumos-guy/"&gt;LibreWolf&lt;/a&gt; (a Firefox variant). To access the tabs, I had to hide the keyboard. Once hidden, it never came back. I was almost screaming.&lt;/li&gt;
&lt;li&gt;When I used Waydroid, there was no shared clipboard between Android apps and Linux apps. At least, I haven't found it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I ended up using Waydroid for everything, and I wasn't too happy about it. I felt that I could have simply installed /e/OS instead.&lt;/p&gt;
&lt;p&gt;After removing Ubuntu Touch from my device, I received the advice that I could have unlocked the filesystem and used &lt;code&gt;apt&lt;/code&gt;. It may have its quirks but should be doable, although standard Debian apps are usually not optimized for mobile screens, so even this would not solve everything magically. Unlocking the filesystem can mess up future updates, on the other hand.&lt;/p&gt;
&lt;p&gt;I know there are people using Ubuntu Touch as a daily driver. It's not impossible, but it's also not convenient for everyone.&lt;/p&gt;
&lt;h3&gt;SailfishOS by Jolla&lt;/h3&gt;
&lt;p&gt;Links: &lt;a href="https://jolla.com"&gt;official site&lt;/a&gt; | &lt;a href="https://forum.fairphone.com/t/sailfish-os-for-fairphones-devices/114527"&gt;for Fairphone 5&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!info]
&lt;strong&gt;Disclaimer:&lt;/strong&gt; I might be a bit positively biased toward Jolla. I've never met the team, but the founders once worked for the same company I do. It feels like they would be my distant relatives. I do my best to put it aside and write without bias, but it felt fair to disclose this.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The next OS I tried was SailfishOS. Considering the fact that Jolla was involved in the development of a Russian &lt;a href="https://en.wikipedia.org/wiki/Aurora_OS_(Russian_Open_mobile_platform)"&gt;SailfishOS fork&lt;/a&gt;, at first, I wasn't sure if I could trust it. Competitors are eager to generate a mist of uncertainty about Russian governmental infiltration of Jolla, and to imply that users might be exposed to spying by the &lt;a href="https://en.wikipedia.org/wiki/Federal_Security_Service"&gt;FSB&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This is absolute nonsense, in my opinion. Doing business with Russia wasn't rare in Finland before the war in Ukraine, as Russia is a neighboring country. I doubt that any Finn would take part in such a scheme. But you don't have to trust my opinion on this. You can check it yourself by running this &lt;a href="https://sailfishos-chum.github.io/pkgs/sailshark/"&gt;open-source Wireshark app for SailfishOS&lt;/a&gt; and inspecting all the packets. Users would have noticed any suspicious activity already, or if SailShark selectively ignored some packets.&lt;/p&gt;
&lt;p&gt;That said, I was totally amazed by SailfishOS. Its user interface works differently than Android's, but it took me about 5 minutes to master it. Not because I'm that special, but because it's so intuitive.&lt;/p&gt;
&lt;p&gt;The plus side:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Installation was well documented and worked just like it was written.&lt;/li&gt;
&lt;li&gt;It's Linux!&lt;/li&gt;
&lt;li&gt;You have terminal access!&lt;/li&gt;
&lt;li&gt;You can unlock the filesystem (it can mess up updates here too).&lt;/li&gt;
&lt;li&gt;It was fast, smooth, and had nice aesthetics.&lt;/li&gt;
&lt;li&gt;Applications worked well, both stock ones and the ones from the Jolla store (~300 apps).&lt;/li&gt;
&lt;li&gt;You can also install apps from &lt;a href="https://openrepos.net"&gt;OpenRepos&lt;/a&gt; (~1000-2000 apps).&lt;/li&gt;
&lt;li&gt;If you use an &lt;a href="https://docs.sailfishos.org/Support/Supported_Devices/"&gt;officially supported device&lt;/a&gt;, you can run a native compatibility layer (Android AppSupport) that lets you run most (but not all) Android apps.&lt;/li&gt;
&lt;li&gt;VoLTE calls work.&lt;/li&gt;
&lt;li&gt;The fingerprint sensor works.&lt;/li&gt;
&lt;li&gt;If I remember correctly, it also supported an external screen. I should have documented it at the time, but I think the second screen did not work through the daisy-chain, while the first display did. It's also a device-dependent feature, but the OS support is there. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Issues I expected (&lt;a href="https://forum.sailfishos.org/t/sailfish-os-for-fairphones-devices/21516"&gt;source&lt;/a&gt;) (These are only true for community-supported phones; Jolla's own phones do not struggle with these.):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The main camera doesn't work. &lt;/li&gt;
&lt;li&gt;Video playback isn't perfect (uses software rendering).&lt;/li&gt;
&lt;li&gt;Not all kinds of Wi-Fi networks are supported.&lt;/li&gt;
&lt;li&gt;Fairphone 5 is not an officially supported device, so I couldn't use the Android AppSupport. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Kudos to the community for creating and maintaining this version. There were no unpleasant surprises. I loved it. And actually, that was the problem why I abandoned it. The whole experience was so perfect, I couldn't cope with the blurry photos and the missing AAS (Android AppSupport).&lt;/p&gt;
&lt;p&gt;Since then, I received the hint that Waydroid is also working on Fairphone 5 with SailfishOS, even if it's less convenient than the official AAS.&lt;/p&gt;
&lt;p&gt;This is a great OS, and honestly, I would buy a new &lt;a href="https://commerce.jolla.com/products/jolla-phone-sep-ii-2026"&gt;Jolla phone&lt;/a&gt; just to enjoy the experience and support the team. However, I chose Fairphone 5 to lessen my consumer footprint, so buying a new phone would be quite hypocritical. I hope I can still buy a Jolla device once my Fairphone is retired 5-10 years from now.&lt;/p&gt;
&lt;h3&gt;iodéOS by iodé&lt;/h3&gt;
&lt;p&gt;Links: &lt;a href="https://iode.tech/iodeos/"&gt;official site&lt;/a&gt; | &lt;a href="https://iode.tech/installation/"&gt;for Fairphone 5&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My next stop was iodéOS. It's maintained by a French company and is based on LineageOS, and features microG.&lt;/p&gt;
&lt;p&gt;The plus side:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Installation was smooth.&lt;/li&gt;
&lt;li&gt;It has nice privacy tools: tracker blocking and connection analysis. I loved them.&lt;/li&gt;
&lt;li&gt;Nice stuff preinstalled: Aurora Store and F-Droid.&lt;/li&gt;
&lt;li&gt;MicroG, an open-source module, is there to solve most application compatibility issues for Android apps relying on Google services.&lt;/li&gt;
&lt;li&gt;Banking worked well.&lt;/li&gt;
&lt;li&gt;It has Thunderbird and a secure Firefox variant (I don't like them, but you might).&lt;/li&gt;
&lt;li&gt;Fingerprint sensor, GPS, and VoLTE worked.&lt;/li&gt;
&lt;li&gt;For Fairphone 5, external screen works with a USB-C cable, but only one display worked, mirroring the phone's screen instead of extending it as a desktop. It was pretty useless.&lt;/li&gt;
&lt;li&gt;Updating it was smooth.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Issues I expected:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It's an Android with a non-unlockable file system.&lt;/li&gt;
&lt;li&gt;The main camera doesn't work.&lt;/li&gt;
&lt;li&gt;It has freemium security. The basic package is free, but you can pay a couple of euros for advanced privacy options. Well, I don't like freemium things by default. And also, making advanced privacy available for money tastes a bit like protection money. Privacy should not be monetized. It is a fundamental human right. And yes, I know it's not expensive, but not all people can afford to throw a couple of euros in every direction. But to be fair, even their free security tier is great and perhaps the others are even better, and the work the iodé team does deserves support.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It was nice and convenient, but it was lacking the wow factor of SailfishOS. And soon I realized that if I use a LineageOS fork anyway, I could use one with a working camera.&lt;/p&gt;
&lt;h3&gt;/e/OS by Murena&lt;/h3&gt;
&lt;p&gt;Links: &lt;a href="https://murena.com/smartphones/"&gt;official site&lt;/a&gt; | &lt;a href="https://images.ecloud.global/dev/FP5/"&gt;for Fairphone 5&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This part is more Fairphone-specific than the previous ones, although /e/OS supports &lt;a href="https://doc.e.foundation/devices"&gt;a wide range of devices&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For Fairphone 5, /e/OS has two variants: an official version for those who bought the device from Murena and a community edition for those who bought a compatible device from other vendors and installed Murena's software on it. There aren't many differences between the two, but the camera software is different in the official version.&lt;/p&gt;
&lt;p&gt;Both versions seem to contain the low-level driver and the image-processing logic for the main camera. At least my phone takes decent pictures with the community edition. Significantly better ones than with Ubuntu Touch, SailfishOS, or even with iodéOS.&lt;/p&gt;
&lt;p&gt;Although the community version doesn't have Fairphone's own camera app, which should squeeze all the juice out of the device, it's not far behind. With some tinkering, you can put the official camera app on the community edition, but it's complicated, and the gain is said to be insignificant. (&lt;a href="https://community.e.foundation/t/fairphone-5-camera-app-com-fp5-camera-only-available-in-murena-version/69901"&gt;You can read more about it here.&lt;/a&gt;) &lt;/p&gt;
&lt;p&gt;The plus side:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Main camera*, fingerprint sensor, GPS, and VoLTE work.&lt;/li&gt;
&lt;li&gt;It has great privacy options, like geolocation faking, IP address hiding, and ad and tracker blocking.&lt;/li&gt;
&lt;li&gt;It has its own app store that shows the content of Aurora and F-Droid. It also shows you a privacy analysis of the apps based on external services. So you don't have to install it to see if it's spying for Google, Facebook, or anyone else. You are also notified if an already installed application introduces something new and fishy. &lt;/li&gt;
&lt;li&gt;MicroG, an open-source module, is there to solve most application compatibility issues for Android apps relying on Google services.&lt;/li&gt;
&lt;li&gt;Updates come regularly and smoothly.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;*Note: It is Fairphone 5-specific, the main camera might not function perfectly on all devices running /e/OS!&lt;/p&gt;
&lt;p&gt;Expected issues:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It's Android with a locked file system.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There were no unexpected issues with this OS, but it was full of apps wanting me to lock into Murena's freemium services. They might be good, I haven't tried them. I considered them bloatware, trashed them, and replaced them with ones I liked more. You can do the same by running the following commands from a PC:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;adb&lt;span class="w"&gt; &lt;/span&gt;shell&lt;span class="w"&gt; &lt;/span&gt;pm&lt;span class="w"&gt; &lt;/span&gt;uninstall&lt;span class="w"&gt; &lt;/span&gt;--user&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;foundation.e.mail
adb&lt;span class="w"&gt; &lt;/span&gt;shell&lt;span class="w"&gt; &lt;/span&gt;pm&lt;span class="w"&gt; &lt;/span&gt;uninstall&lt;span class="w"&gt; &lt;/span&gt;--user&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;foundation.e.calendar
adb&lt;span class="w"&gt; &lt;/span&gt;shell&lt;span class="w"&gt; &lt;/span&gt;pm&lt;span class="w"&gt; &lt;/span&gt;uninstall&lt;span class="w"&gt; &lt;/span&gt;--user&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;foundation.e.notes
adb&lt;span class="w"&gt; &lt;/span&gt;shell&lt;span class="w"&gt; &lt;/span&gt;pm&lt;span class="w"&gt; &lt;/span&gt;uninstall&lt;span class="w"&gt; &lt;/span&gt;--user&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;foundation.e.browser
adb&lt;span class="w"&gt; &lt;/span&gt;shell&lt;span class="w"&gt; &lt;/span&gt;pm&lt;span class="w"&gt; &lt;/span&gt;uninstall&lt;span class="w"&gt; &lt;/span&gt;--user&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;foundation.e.tasks
adb&lt;span class="w"&gt; &lt;/span&gt;shell&lt;span class="w"&gt; &lt;/span&gt;pm&lt;span class="w"&gt; &lt;/span&gt;uninstall&lt;span class="w"&gt; &lt;/span&gt;--user&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;org.sufficientlysecure.keychain&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# password storage I didn&amp;#39;t trust&lt;/span&gt;
adb&lt;span class="w"&gt; &lt;/span&gt;shell&lt;span class="w"&gt; &lt;/span&gt;pm&lt;span class="w"&gt; &lt;/span&gt;uninstall&lt;span class="w"&gt; &lt;/span&gt;--user&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;com.generalmagic.magicearth&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;# maps app I didn&amp;#39;t like&lt;/span&gt;
adb&lt;span class="w"&gt; &lt;/span&gt;shell&lt;span class="w"&gt; &lt;/span&gt;pm&lt;span class="w"&gt; &lt;/span&gt;uninstall&lt;span class="w"&gt; &lt;/span&gt;--user&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;org.lineageos.twelve&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="c1"&gt;# music player I didn&amp;#39;t need&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;postmarketOS&lt;/h3&gt;
&lt;p&gt;Links: &lt;a href="https://postmarketos.org"&gt;official site&lt;/a&gt; | &lt;a href="https://wiki.postmarketos.org/wiki/Fairphone_5_(fairphone-fp5)"&gt;for Fairphone 5&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I haven't installed it, but I am preparing for it. PostmarketOS, which is based on the minimalist Alpine Linux distribution, is famous for giving a second chance to devices abandoned by their manufacturers. However, it can also be a great choice for currently supported devices.&lt;/p&gt;
&lt;p&gt;The plus side:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You can have Alpine packages, Flatpaks, and perhaps some AppImages too (rare). (Good to know that Alpine packages are sometimes called 'apk's, but they are not the same as Android packages, which are also called 'apk's. Alpine and Android can't install each other's apps.) Also, an app is useful only if it is optimized for mobile screens too. Snap packages don't work.&lt;/li&gt;
&lt;li&gt;You can run Waydroid and run Android apps there (at the cost of extra battery power).&lt;/li&gt;
&lt;li&gt;GPS works, though it might position slower at first.&lt;/li&gt;
&lt;li&gt;The filesystem is not locked.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Known issues:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The main camera doesn't work.&lt;/li&gt;
&lt;li&gt;VoLTE can have issues.&lt;/li&gt;
&lt;li&gt;The fingerprint sensor doesn't work (in some rare cases it might work, but not on FP5).&lt;/li&gt;
&lt;li&gt;Fairphone 5 has some audio issues affecting calls too. This is device-specific and has been solved, but the fix is not yet available in the stable release.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Selecting a device&lt;/h2&gt;
&lt;h3&gt;About my Fairphone 5&lt;/h3&gt;
&lt;p&gt;I installed Ubuntu Touch the day after I received my Fairphone 5. It was a Christmas present from my wife and family. But I couldn't wait with it until then. I mean, I tried different OSes to find the right one for me, then put the phone away and inserted the SIM card only on Christmas Eve. The phone is definitely awesome. Its size is perfect for me, it's comfortable to hold, and the screen is beautiful. I'm also satisfied.&lt;/p&gt;
&lt;p&gt;But it is good to remember that all of us have different tastes in device size, different expectations about device capabilities, and also different priorities. For those who care less about the camera, SailfishOS might be better on FP5 than it is for me, but if they care more about taking pictures, even the Fairphone line might be out of the question.&lt;/p&gt;
&lt;p&gt;So before choosing the device and OS for yourself, lay out your priorities. Also, check the list of missing functionalities to see if any of them is a dealbreaker.&lt;/p&gt;
&lt;p&gt;I'll explain how I selected mine. I don't think that my choice is the best for everyone, but even if you do not make the same decisions I did, the aspects could be useful for you.&lt;/p&gt;
&lt;h3&gt;My selection process&lt;/h3&gt;
&lt;p&gt;When I started to degoogle, replacing Android was a challenge. I enjoyed paying with my phone, navigating with it, accessing my data in the cloud, and so on. But I had other priorities too:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;No Google, Meta, or Microsoft should be on board.&lt;/li&gt;
&lt;li&gt;The device should be sustainably created and easy to repair.&lt;/li&gt;
&lt;li&gt;The manufacturer should have as few imperialist ties as possible. I don't need any autocrats having a hidden ear on board or even having economic gain from my purchase.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I gave a lot of thought to &lt;a href="https://www.shift.eco/en/"&gt;Shiftphone&lt;/a&gt;. Some of their devices are shipped with ShiftOS, their own LineageOS-based Android variant, but they have devices capable of running /e/OS too. I like the company's attitude and views on sustainability, and I think they create decent devices. But Fairphone relies less on Chinese suppliers, and I decided in their favor.&lt;/p&gt;
&lt;p&gt;I almost chose &lt;a href="https://grapheneos.org"&gt;GrapheneOS&lt;/a&gt;. It is privacy-focused and highly secure with great reviews. On the other hand, I didn't like the idea of degoogling by buying a Google device, not even secondhand. I couldn’t imagine myself advocating degoogling while carrying a Google-branded phone. While I was trying to cope with the idea, I came across their posts on Mastodon and also checked their articles. I was quite shocked by their attitude.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!warning]
&lt;strong&gt;This paragraph is not about facts, but my own impressions.&lt;/strong&gt; I felt they approached things defensively. Treating others, potential customers and competitors alike, like that is rare in Mastodon and more common on X and Facebook. The "my way or the highway" attitude I perceived in their posts reminded me of the self-entitled culture of today's tech bros. Many of their arguments are perfectly valid, yet something still feels off.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Putting aside their communication, I would like to emphasize that they create serious value, and their current releases serve their users excellently. Google Pixel phones with a highly secure, degoogled OS are truly a premium solution.&lt;/p&gt;
&lt;p&gt;But there was one more reason I didn't choose them, but looked for something else. Just like the other tech-bro-led companies, due to its vast wealth, Google stopped being reliable, both as a business partner and as a service provider. It seems they have no moral reservations about doing whatever comes to mind. This has not been about profit or market share for a long time. Many of their actions, which violate norms and threaten both individuals and society, bring them only marginal benefits. It is as if their only goal is to show that they can get away with doing these.&lt;/p&gt;
&lt;p&gt;I asked myself: what if Google managed to kill off other Android variants, either legally or by introducing such a change that throws them under the bus. Since I wanted a long-serving device, I wanted a plan B for this case. So the device I was about to choose had to be able to run non-Android mobile OSes.&lt;/p&gt;
&lt;p&gt;Fairphone was the logical choice. Their devices have a &lt;a href="https://forum.fairphone.com/t/operating-systems-for-fairphones/11425"&gt;history of supporting many OSes&lt;/a&gt;. I chose the Fairphone 5 over the 6 because it gave me a wider selection of compatible OSes to choose from.&lt;/p&gt;
&lt;p&gt;Now, half a year later, I'm sure I made the right choice.&lt;/p&gt;
&lt;p&gt;For a long time, Google has preferred to put important business logic into proprietary code instead of AOSP, forcing other Android version developers to work harder. It's not about blocking them, but about making their work unfeasible. &lt;/p&gt;
&lt;p&gt;&lt;a href="https://mementomori.social/@quantum_splash@mastodon.social/116574848946386938"&gt;Google also penalizes people for using other Androids.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;They also work to make it harder to develop Android apps and want to collect data about developers. It's said to be for the users' security. But is it? They don't care about users' security when they collect and sell insane amounts of user data, which sometimes ends up helping kidnappers, criminals, and scammers, or even oppressive regimes. They also don't care about security, when they let the Play Store be flooded with fishy scammer applications or ones that explicitly aim to create addiction to exploit users later. But when they want to obstruct competition, user security suddenly becomes important. &lt;/p&gt;
&lt;p&gt;I respect the enthusiastic professionals behind the alternative Android versions, but I doubt Google can be fought with its own software. Call me paranoid, but I wanted a device that would still give me options if Android alternatives became less viable in the future. Now, I eagerly follow how postmarketOS progresses.&lt;/p&gt;
&lt;p&gt;And what would be even better for me than my current device? Of course, a sustainable, repairable phone developed and manufactured in the EU. It should run important apps under mobile Linux while offering full camera support, without relying on Android at all. I hope there will be such devices available in 5-10 years. (Governments and financial institutions should stop forcing you to use devices compromised by tech bros.)&lt;/p&gt;
&lt;p&gt;As usual in life, there is no perfect option. Sacrificing some comfort is not too much for freedom and privacy.&lt;/p&gt;
&lt;p&gt;I'd like to read about your journey or your plans. What are your priorities, and how did or will you decide?&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Updates:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ancient Sounds&lt;/strong&gt;: The main camera support is device-specific under Ubuntu Touch, so there are devices running UT that can use the main camera. (&lt;a href="https://mementomori.social/@ancientsounds@mastodonapp.uk/116585864926864734"&gt;source&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Georg Weissenbacher&lt;/strong&gt;: Fingerprint sensors work on Halium based mobile Linuxes; Morph's new version is improved (&lt;a href="https://mementomori.social/@GeorgWeissenbacher@fediscience.org/116586332534163157"&gt;source&lt;/a&gt;) &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;🤝 Thanks for your corrections and updates, people reading this article can now have even more accurate info.&lt;/p&gt;</content><category term="Tech"/><category term="Degoogling"/><category term="Linux"/></entry><entry><title>Daily sparks - May 2026</title><link href="https://blog.gridranger.dev/daily-sparks-may-2026" rel="alternate"/><published>2026-05-08T19:29:00+03:00</published><updated>2026-05-18T12:03:00+03:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2026-05-08:/daily-sparks-may-2026</id><summary type="html">&lt;h3&gt;2026. May 18 Monday&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;My blog has been listed by &lt;a href="https://bubbles.town/"&gt;bubbles.town&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2026. May 16 Saturday&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;I published a new post today: &lt;a href="/mobile-oses-featuring-fairphone-5"&gt;Mobile OSes (featuring Fairphone 5)&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A new plugin I wrote for my blog also went live. It automatically generates links for all headings in my posts. If I …&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;h3&gt;2026. May 18 Monday&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;My blog has been listed by &lt;a href="https://bubbles.town/"&gt;bubbles.town&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2026. May 16 Saturday&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;I published a new post today: &lt;a href="/mobile-oses-featuring-fairphone-5"&gt;Mobile OSes (featuring Fairphone 5)&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A new plugin I wrote for my blog also went live. It automatically generates links for all headings in my posts. If I set a &lt;code&gt;TableOfContents&lt;/code&gt; property for a post it also generates a table of contents widget at the top of the post.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2026. May 15 Friday&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;We visited an art fair in &lt;a href="https://www.kaapelitehdas.fi/en/events/teos-2026-nykytaiteen-myyntitapahtuma"&gt;The Cable Factory&lt;/a&gt;. I enjoyed it more last time.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I saw some wild animals today. In the morning, a fox decided to lie in the sun on the road. It wasn’t afraid of our bus. It stayed there while people got off at the bus stop, then slowly walked away to let the bus pass. On the way home, I saw a deer walking between the trees. At home, I also saw a squirrel roaming around the parking lot. It must have looked the same as I did when I forgot where I parked my car. (That was back when I still had a car.)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2026. May 13 Wednesday&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Today was a gloomy, rainy day. Although I felt impatient and grumpy all the time, I made it through the day without being a jerk to anyone. This effort is worth celebrating.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2026. May 12 Tuesday&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;I greeted a new member on the Fediverse, &lt;a href="https://mementomori.social/@Lori_Noctis@mastodon.social"&gt;Lori_noctis&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2026. May 11 Monday&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Pi3 is back in business: my &lt;a href="https://www.navidrome.org/"&gt;Navidrome&lt;/a&gt; is up.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2026. May 10 Sunday&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;My only achievement today was moving my Raspberry Pi 3B+ half a meter away. It had been dropping its connection ever since I booted it up two days ago. My first thought was that the issue was caused by interference from the new Wi-Fi card in my desktop PC. I didn’t trust myself. I tried to find a software or configuration fix. Two days and two reinstalls later, I simply moved the device on my desk. No dropped connections since. I should trust my instincts more.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2026. May 9 Saturday&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;I feel a ray of hope since a shameful era seems to have ended in my home country.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I managed to fix my Steam Deck thanks to &lt;a href="https://steamcommunity.com/app/1675200/discussions/0/4039230033360772172/"&gt;this article&lt;/a&gt; after it locked itself into a boot loop, unable to access BIOS, boot device selection mode, or recovery mode.  &lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2026. May 8 Friday&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;We visited the Japanese cherry tree gardens in Helsinki.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="My old black-and-white miniature poodle smells a cherry blossom." src="../images/2026-05-08-cherry-poodle.jpg"&gt;&lt;/p&gt;
&lt;h3&gt;2026. May 7 Thursday&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Finished &lt;em&gt;Across the Grooves&lt;/em&gt; for the first time. It’s a game with a great story and a unique mood.&lt;/li&gt;
&lt;/ul&gt;</content><category term="Blog"/><category term="Adventure"/><category term="Daily sparks"/><category term="Gaming"/><category term="Linux"/><category term="Poodle"/></entry><entry><title>Who knows that you blog?</title><link href="https://blog.gridranger.dev/who-knows-that-you-blog" rel="alternate"/><published>2026-04-30T23:27:00+03:00</published><updated>2026-04-30T23:27:00+03:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2026-04-30:/who-knows-that-you-blog</id><summary type="html">&lt;h1&gt;Who knows that you blog?&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;[!info]
This post is a response to &lt;a href="https://forkingmad.blog"&gt;David&lt;/a&gt;'s one &lt;em&gt;&lt;a href="https://forkingmad.blog/who-knows-that-you-blog/"&gt;Who knows that you blog?&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It has always felt strange to show what I write to people I know.&lt;/p&gt;
&lt;p&gt;Most of my readers don't know me in person, and that feels natural. But when the …&lt;/p&gt;</summary><content type="html">&lt;h1&gt;Who knows that you blog?&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;[!info]
This post is a response to &lt;a href="https://forkingmad.blog"&gt;David&lt;/a&gt;'s one &lt;em&gt;&lt;a href="https://forkingmad.blog/who-knows-that-you-blog/"&gt;Who knows that you blog?&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It has always felt strange to show what I write to people I know.&lt;/p&gt;
&lt;p&gt;Most of my readers don't know me in person, and that feels natural. But when the actual and digital worlds blend, it can be strange.  &lt;/p&gt;
&lt;h2&gt;When people you know start reading you&lt;/h2&gt;
&lt;p&gt;Sometimes I mention to a friend or relative that I have a blog. It's rare, but it happens. It's even rarer for them to actually read it. That's how it should be: people should read me only if they are interested.&lt;/p&gt;
&lt;p&gt;I'd be ashamed to expect anyone to read me when they weren't.&lt;/p&gt;
&lt;p&gt;But it would feel off if someone I know reads my blog not out of genuine interest, but to learn things about me instead of just asking me directly.  &lt;/p&gt;
&lt;p&gt;Perhaps it's because I was stalked by a former partner. It was creepy to get questions like:&lt;/p&gt;
&lt;p&gt;"Why did you congratulate XY on their new job on Facebook? Who are they? Do you often chat in secret?"&lt;/p&gt;
&lt;p&gt;Or:&lt;/p&gt;
&lt;p&gt;"In your latest blog post you wrote this and that about someone. Did you mean it about me or someone else? Whom did you think of?"&lt;/p&gt;
&lt;p&gt;And the answer never mattered. She had already decided on the worst possible explanation and dismissed everything else as a lie.&lt;/p&gt;
&lt;h2&gt;Meeting readers in person&lt;/h2&gt;
&lt;p&gt;In university, I met about half a dozen people who followed my blog and the short stories I wrote. Most of the time, it was painfully awkward.&lt;/p&gt;
&lt;p&gt;They already had an impression of who they thought I was. Like sort of a parasocial relationship. They approached me with enthusiasm and openness, and all I could say was "I'm glad you like it". Then I froze.&lt;/p&gt;
&lt;p&gt;I was bullied a lot in school. Feeling that the other person behaved overly friendly toward me rang an alarm, and I shut myself off emotionally, suspecting that they wanted to manipulate me into something.&lt;/p&gt;
&lt;p&gt;Most of the time, I must have looked cold, emotionally distant, or outright arrogant.&lt;/p&gt;
&lt;h2&gt;Boundaries&lt;/h2&gt;
&lt;p&gt;The most important thing for me is my boundaries.&lt;/p&gt;
&lt;p&gt;Most of my family knows I blog, but the only time we talked about it was when I mentioned getting a domain name. Whether they read it or not doesn't affect our relationship, and from that, I feel my privacy is respected. My wife encourages me to blog, but she only reads a post when we talk about it.&lt;/p&gt;
&lt;p&gt;When my former partner kept checking my online activity, she used it to control me. It was an unacceptable violation, still I felt powerless to stand up for myself.  &lt;/p&gt;
&lt;p&gt;When fellow students from the university started to behave as if we knew each other, they crossed a line. It was less of a problem, but it touched earlier pain points.  &lt;/p&gt;
&lt;h2&gt;Why I keep blogging&lt;/h2&gt;
&lt;p&gt;You might ask: why do I blog if I don't like these things happening?&lt;/p&gt;
&lt;p&gt;First, I try not to let bad experiences dictate my actions. I can’t avoid this all the time, but I do my best.&lt;/p&gt;
&lt;p&gt;Second, I feel an internal drive to write and tell stories. I touched on this topic briefly in my post: &lt;a href="https://blog.gridranger.dev/along-the-edge/"&gt;Along the Edge&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Finally, I’ve learned a lot from the philosophy of the Python language. Instead of overstraining myself to avoid every bad thing, as I once did, I focus on living normally and learning to handle unpleasant things as they come.&lt;/p&gt;</content><category term="Blog"/><category term="Blogging"/><category term="Me"/><category term="Writing"/><category term="Writing prompt"/></entry><entry><title>How I dash</title><link href="https://blog.gridranger.dev/how-i-dash" rel="alternate"/><published>2026-03-22T21:45:00+02:00</published><updated>2026-03-23T10:15:00+02:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2026-03-22:/how-i-dash</id><summary type="html">&lt;h1&gt;How I dash&lt;/h1&gt;
&lt;p&gt;Reading &lt;a href="https://skryblans.com/the-em-dash-conununundrum/"&gt;the em dash conununundrum&lt;/a&gt; by &lt;a href="https://cupoftea.social/@scribblanitea"&gt;scribblans&lt;/a&gt; and &lt;a href="https://forkingmad.blog/em-dashes/"&gt;Em dashes&lt;/a&gt; by &lt;a href="https://gofer.social/@daj"&gt;David&lt;/a&gt; brought my unusual relationship with these punctuation marks to the surface.&lt;/p&gt;
&lt;p&gt;Let's start with how my native language typesets dialogues differently from English. They are typed like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!quote]
&lt;em&gt;Antal Szerb: The Pendragon Legend, translated …&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;</summary><content type="html">&lt;h1&gt;How I dash&lt;/h1&gt;
&lt;p&gt;Reading &lt;a href="https://skryblans.com/the-em-dash-conununundrum/"&gt;the em dash conununundrum&lt;/a&gt; by &lt;a href="https://cupoftea.social/@scribblanitea"&gt;scribblans&lt;/a&gt; and &lt;a href="https://forkingmad.blog/em-dashes/"&gt;Em dashes&lt;/a&gt; by &lt;a href="https://gofer.social/@daj"&gt;David&lt;/a&gt; brought my unusual relationship with these punctuation marks to the surface.&lt;/p&gt;
&lt;p&gt;Let's start with how my native language typesets dialogues differently from English. They are typed like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!quote]
&lt;em&gt;Antal Szerb: The Pendragon Legend, translated by Len Rix&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;– Tell me – he asked, with some embarrassment, as we strolled along: –, you’re a bloody German, aren’t you?&lt;/p&gt;
&lt;p&gt;– Oh, no. I’m Hungarian.&lt;/p&gt;
&lt;p&gt;– Hungarian?&lt;/p&gt;
&lt;p&gt;– Hungarian.&lt;/p&gt;
&lt;p&gt;– What’s that? Is that a country? Or are you just having me on?&lt;/p&gt;
&lt;p&gt;– Not at all. On my word of honour, it is a country.&lt;/p&gt;
&lt;p&gt;– And where do you Hungarians live?&lt;/p&gt;
&lt;p&gt;– In Hungary. Between Austria, Romania, Czechoslovakia and Yugoslavia.&lt;/p&gt;
&lt;p&gt;– Come off it. Those places were made up by Shakespeare. – And he roared with laughter. – Alright, so you’re a Hungarian… Good country, that. And what language do you Hungarians speak?&lt;/p&gt;
&lt;p&gt;– Hungarian.&lt;/p&gt;
&lt;p&gt;– Say something in Hungarian.&lt;/p&gt;
&lt;p&gt;It was some years since I had last spoken the language and, strangely moved, I recited some Ady:&lt;/p&gt;
&lt;p&gt;– &lt;em&gt;Mikor az ég furcsa, lila-kék&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;S találkára mennek a lyányok,&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Ó, be titkosak, különösek&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Ezek a nyári délutánok.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;(Under a strange, lilac-blue sky / The girls stroll to their assignations; /  Mysterious, enigmatic / Summer afternoons.)&lt;/p&gt;
&lt;p&gt;– Very nice. But you don’t fool me. That was Hindustani. It means: „Noble stranger, may the Gods dance on your grave in their slippers.” I’ve heard that one before. However, since you’re the first Hungarian I’ve met, let’s do something to celebrate this splendid friendship.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Those are en dashes. Since there is no button for them on the keyboard, non-technical people struggle to type them on PC. The most common text editor, Word has some automation to replace hyphens with them. But it doesn't handle every situation well. This functionality is sometimes buggy in newer Word versions, and even on old versions, it worked only with the correct locale settings. In Word, the secret combo, &lt;code&gt;Ctrl+NumPadMinus&lt;/code&gt;, fixed that issue for me back then.&lt;/p&gt;
&lt;p&gt;But, as I wrote &lt;a href="/intersecting-interests"&gt;earlier&lt;/a&gt;, I had ambitions to be an author at the same time I was learning to write HTML. Of course, I wanted to type the right characters on web pages too, so I learned the HTML codes for them together with &lt;code&gt;&amp;amp;bdquo;&lt;/code&gt; and &lt;code&gt;&amp;amp;rdquo;&lt;/code&gt;, the special marks used for quotations. Even my small Python library, which converts a Markdown project to an ebook, has a special ruleset to handle these characters.&lt;/p&gt;
&lt;p&gt;Also, besides real and internal character dialogues, en dashes are sometimes used to insert additional info into sentences. But nowadays, people prefer parentheses for the same role. I still prefer en dashes because they make the text less dense, giving the reader a slight pause to process the switch back and forth more smoothly. They also create unique patterns on the page, helping me form a mental image of the page so I can locate sections I remember more easily.&lt;/p&gt;
&lt;p&gt;In English text, I almost never use en or em dashes. Even when I use AI to help me proofread my text, it receives my prompt like this: "&lt;em&gt;Check text, fix only typos and grammar errors. List findings. No em dash suggestions.&lt;/em&gt;"&lt;/p&gt;
&lt;p&gt;Yes, I use AI. Not for writing or translating, but for proofreading. I simply cannot do that effectively with my own text. Not even in my native language. Oh, and instead of replacing the version patched by the AI, I prefer to fix everything one by one, to learn from my mistakes and to make the final decisions myself.&lt;/p&gt;
&lt;p&gt;So I'm not avoiding en or em dashes to pretend I'm not using AI, but because I wouldn't use them in English anyway. They just won't come naturally. Once they do, they'll appear in the text.&lt;/p&gt;
&lt;p&gt;Let me wrap up this post with this: although en dashes are used for dialogues in my language, you can find em dashes used for the same purpose in older books and newspapers. Here is a part of the dialogue above, printed in the 1964 release:&lt;/p&gt;
&lt;p&gt;&lt;img alt="A page from an old edition of The Pendragon Legend. It's in my native language. It contains the first few senteces of the quote above. Em dashes are used instead of en dashes. The font is a Times-like serif. The paper is slightly yellowed." src="../images/2026-03-22-3.jpg"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!info]
The book I quoted above has a special place in my heart.&lt;/p&gt;
&lt;p&gt;It is the first novel by &lt;a href="https://en.wikipedia.org/wiki/Antal_Szerb"&gt;Antal Szerb&lt;/a&gt;, a Hungarian author and scholar. His essays are as compelling as his novels and short stories, thanks to his kind, lighthearted humor and his ability to capture the essence of complex things into clear, accessible prose.&lt;/p&gt;
&lt;p&gt;Although he traveled a lot across Europe earlier in his life, he chose to remain in Hungary during the 1940s and was beaten to death by fascists in a concentration camp.&lt;/p&gt;
&lt;p&gt;Unlike him, the book’s protagonist moves to London in the 1930s to avoid the rise of fascism. Like Szerb, however, he is a literary scholar. Driven by his passion for old manuscripts, he travels to Wales, where he unravels an assassination attempt and solves a murder.&lt;/p&gt;
&lt;/blockquote&gt;</content><category term="Personal"/><category term="Me"/><category term="Reading"/><category term="Writing"/></entry><entry><title>Wander Navigator</title><link href="https://blog.gridranger.dev/navigator" rel="alternate"/><published>2026-03-09T22:33:00+02:00</published><updated>2026-03-09T22:33:00+02:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2026-03-09:/navigator</id><content type="html"/><category term="Blog"/><category term="Tools"/></entry><entry><title>I dream of...</title><link href="https://blog.gridranger.dev/i-dream-of" rel="alternate"/><published>2026-03-03T22:33:00+02:00</published><updated>2026-03-03T22:33:00+02:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2026-03-03:/i-dream-of</id><summary type="html">&lt;h2&gt;Robot Framework&lt;/h2&gt;
&lt;p&gt;In my dream, I was on a formal reception. Holding a glass of champagne, Mr. Trump walked up to me. He was actually shorter, than he looks in the news. He asked about my work, so I told him a couple of things of Python and the Robot …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Robot Framework&lt;/h2&gt;
&lt;p&gt;In my dream, I was on a formal reception. Holding a glass of champagne, Mr. Trump walked up to me. He was actually shorter, than he looks in the news. He asked about my work, so I told him a couple of things of Python and the Robot Framework. I was relieved when he moved on. But then, moments later, he gave a public speech saying:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;"Let me tell you, this just came in, it’s the best news, maybe ever. We have the most incredible humanoid robots. Nobody’s seen anything like it. The most advanced, the most powerful, believe me. The strongest army of robots ever built. And they’re ready. Ready to unleash on our enemies. And they won’t know what hit them."&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Great, I thought. After all this, this is going to be fun explaining to him that the Robot Framework has nothing to do with actual robots.&lt;/p&gt;</content><category term="Personal"/><category term="Python"/><category term="Me"/><category term="Post streams"/></entry><entry><title>Intersecting interests</title><link href="https://blog.gridranger.dev/intersecting-interests" rel="alternate"/><published>2026-02-28T21:37:00+02:00</published><updated>2026-02-28T21:37:00+02:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2026-02-28:/intersecting-interests</id><summary type="html">&lt;h1&gt;Intersecting interests&lt;/h1&gt;
&lt;p&gt;I’m a developer with a degree in philology and linguistics. This combination often surprises people. But for me, both are about crafting and interpreting texts, whether in code or in stories.&lt;/p&gt;
&lt;h2&gt;The Lego detective and playing with configs&lt;/h2&gt;
&lt;p&gt;The software I used most as a child wasn …&lt;/p&gt;</summary><content type="html">&lt;h1&gt;Intersecting interests&lt;/h1&gt;
&lt;p&gt;I’m a developer with a degree in philology and linguistics. This combination often surprises people. But for me, both are about crafting and interpreting texts, whether in code or in stories.&lt;/p&gt;
&lt;h2&gt;The Lego detective and playing with configs&lt;/h2&gt;
&lt;p&gt;The software I used most as a child wasn’t a game. It was Microsoft Publisher under Windows 3.1. Typing stories with my two pointing fingers was the ultimate game. One with no limits. &lt;/p&gt;
&lt;p&gt;The main character was my Lego private investigator, my favorite minifigure. I always treasured the small plastic parts from the sets. When they were disassembled, everything was sorted by color and later by type. This internal drive to classify parts and understand their relationships made object-oriented programming easy for me to grasp later on.&lt;/p&gt;
&lt;p&gt;&lt;img alt="A black-and-white photo of me as a child, playing on the family’s oldest PC. The old mechanical keyboard forced me to press the spacebar with four fingers." src="../images/2026-02-28-old-times.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Sure, I played a lot of video games, but we had an office PC, not a gaming rig. My father had a small publishing company. He edited the books on our PC before taking them to print. To play, I had to learn how to get out the most of that hardware. I was five or six, when I learned to use color emulation software to make games run in black and white. Later, I taught myself to edit config files through trial and error, forcing games to run at 640×480 when they defaulted to higher resolutions. Back then, there was no internet to search for answers and no one to ask. But I had plenty of time, patience, and curiosity to explore, listen and guess. Sometimes, solving the problem was more exciting than playing the game.&lt;/p&gt;
&lt;h2&gt;Epic stories and wild animated GIFs&lt;/h2&gt;
&lt;p&gt;The early experiments set the stage for my teenage years, when I started to use Word instead of Publisher. My mom, an IT teacher, taught me how to manage styles and keep formatting clean. FrontPage was also available, so I started creating webpages and static websites for fun.&lt;/p&gt;
&lt;p&gt;One of them was a small Fighting Fantasy-inspired role-playing game with scanned hand-drawn graphics and sound effects collected from video games using an app called GAP (Game Audio Player). I also created an interactive map of my Lego City among other things. Everything was brightly colored, flashy, and full of animated GIFs, of course.&lt;/p&gt;
&lt;p&gt;To be clear: FrontPage wrote terribly messy HTML. Through trial and error, I learned to clean up its output and write clean HTML manually.&lt;/p&gt;
&lt;p&gt;I also wrote a lot of fiction. Epic high fantasy stories and space operas. I tried to create my own universes. I never wrote about elves or orcs, Asimov-like robots, or Star Wars-like stuff. My kingdoms and planets were inhabited by creatures of my own ideas. Looking back, I think, they were too simple and boring. I hated evil plots, treason and anything that would make a compelling conflict. I preferred exploration and adventure. Writing about it was exciting, but reading it was less so. No wonder I never became a successful author.&lt;/p&gt;
&lt;p&gt;But I enjoyed visiting my school's creative writing group. I also built a website as a publication platform for the group. Later, as we connected with others interested in writing, authors joined from every corner of the country, and even from abroad.&lt;/p&gt;
&lt;p&gt;Config tinkering evolved into basic web design, complete with a bit of JavaScript added, and it aligned perfectly with my creative writing ambitions.&lt;/p&gt;
&lt;h2&gt;From hobbies to studies&lt;/h2&gt;
&lt;p&gt;I always knew that I would work with computers for a living, yet I saw IT faculties unnecessarily tormenting students with outdated parts of the curriculum, producing in countless programming graduates who never wanted to touch code again. My goal at that time was to become a working, self-sufficient adult as soon as possible, not to let myself be screwed over for years.&lt;/p&gt;
&lt;p&gt;So I went for a master's degree in arts instead, where I could leverage my interest in literature and linguistics. I was particularly fascinated by psychology. It was like debugging one's own life. Obviously, I loved psycholinguistics and sociolinguistics too.&lt;/p&gt;
&lt;p&gt;I also took a special minor program designed to bridge computer science and the arts. It was awesome. Our work ranged from researching obscure pieces of sci-fi literary history to studying what kind of metadata could describe medieval codices to make it fully reproducible. We explored many fascinating topics.&lt;/p&gt;
&lt;p&gt;&lt;img alt="A 14-inch gray notebook from the nineties. The lid is open, but the machine is turned off. It has a built-in floppy drive at the front and an infrared port. Speakers are built into the display bezel at the top. There is also a manual brightness control slider below one of the speakers. In the background, the back of a 17-inch IBM CRT monitor is visible." src="../images/2026-02-28-NecVersa4060H.jpg"&gt;&lt;/p&gt;
&lt;p&gt;I was one of the first students to take notes with a laptop. I bought it from an online auction site that was fairly new. The nearly 10-year-old laptop cost me about €50. It was a NEC Versa 4060h with Pentium I CPU and 640×480 screen resolution. It had no USB ports and only a 3.5" floppy drive so it took me an entire sunny summer afternoon in the garden to move the full Win98 SE and the Office installer to the hard drive. I loved being able to sit under a tree with a computer and no cables. Under Win98 I could attach a network card to the extension slot (PCMCIA) to connect a LAN cable. I overhauled Word with custom hotkeys, so I could take notes at lightning speed during university lectures.&lt;/p&gt;
&lt;p&gt;My fellow students started emailing me for my notes. It was faster than borrowing and photocopying handwritten notes. The only downside was that I occasionally made mistakes. And they spread. During one exam, the teacher said: "Oh, you're the one with the laptop. There's a typo on page 3. Almost the entire class learned it wrong." I hadn’t realized how widely my notes had spread until then.&lt;/p&gt;
&lt;p&gt;I also used the laptop for writing, focusing on realistic, smaller-scale subjects rather than epic fantasy or sci-fi. I explored how people deal with trauma, how couples can navigate everyday hardships without hurting each other. I focused on how to build trust, cope with imperfection, and, above all, how to establish emotional safety for oneself and together. These stories were far from perfect, but a regular audience formed on the portal where I published them, and they enjoyed reading them.&lt;/p&gt;
&lt;h2&gt;Seeking simplicity in tooling&lt;/h2&gt;
&lt;p&gt;By the time I earned my master’s degree four years later, I had published a collection of short stories and a scholarly monograph. I got an IT job in the government sector first, then became a developer &lt;a href="/company-culture#2025-11-13-breaking-the-code"&gt;at a Finnish company&lt;/a&gt;. I removed every trace of my presence from the creative writing portals and for a while, I only wrote for my blog. But writing had always been a way to connect with my innermost self. When I became trapped in an abusive relationship, I used writing to create hope, imagine a way out, and cope with my situation afterward.&lt;/p&gt;
&lt;p&gt;By that time, Word had become over-developed, slow and distractive, so I no longer used it for writing. I felt nostalgic for the first word processor I had ever used, &lt;a href="https://winworldpc.com/product/xywrite/ii-plus-v110"&gt;XyWrite II&lt;/a&gt;. So I turned to distraction-free writing in Markdown. I started with &lt;a href="https://www.calmlywriter.com/online/"&gt;Calmly&lt;/a&gt; and later purchased Typora. I also built a &lt;a href="https://framagit.org/gridranger/bookbuilder"&gt;tool to generate EPUB files from a Markdown project&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I stored the text in Git, a source code version control system that is primarily used by developers. Each evening, when I pushed (uploaded) the changes before going to sleep, an automated script generated a new ebook version. The next day, during my commute, I reviewed the latest version, added notes and corrections, and processed them that evening.&lt;/p&gt;
&lt;p&gt;Nowadays, I use PyCharm to write my blog posts in Markdown. It is an integrated development environment, a source code editor with many built-in tools to help Python development. My blog also includes Python code, the &lt;a href="https://getpelican.com"&gt;Pelican framework&lt;/a&gt; and my own custom plugins, which help me convert my nearly raw-text posts into the website you are reading now.&lt;/p&gt;
&lt;h2&gt;Finding simplicity in writing&lt;/h2&gt;
&lt;p&gt;When I learned to code, it felt self-evident. One step after another, it always felt like writing a story I want to tell. Like expressing my thoughts in a different language that happened to be a programming language rather than a human one. Literary works have their own structural elements, which you build a story from like Lego bricks. And it is the same with programming.&lt;/p&gt;
&lt;p&gt;Some scripts consist of a single file, much like a short story, others are built from many chapter-like classes. Have you ever played Fighting Fantasy? Following the execution flow of a program reminds me of playing such gamebooks. &lt;/p&gt;
&lt;p&gt;As I gained work experience, I felt drawn to clean coding, a practice of writing code that is easy to read, maintain, and understand.&lt;/p&gt;
&lt;p&gt;I realized that I could write well-tested and cleanly written source code faster than doing it hastily and ugly. Adding the time spent fixing undetected defects as they randomly appear, rushed work often ends up being slower than clean coding. What was interesting to observe was how refining my clean code skills also influenced the way I wrote my blog posts and stories. Instead of focusing solely on content, my attention shifted to the linguistic machinery that conveyed my thoughts. Improving this layer resulted in better, more consumable content.&lt;/p&gt;
&lt;p&gt;Simplicity and clarity are key principles of clean coding. Some enjoy writing dense code: chaining function calls and using one-liners as much as possible, as if they want to highlight their expertise by making the code unnecessarily hard to read.&lt;/p&gt;
&lt;p&gt;Learning to write code that is easy to read made me realize I wanted to pay more attention to clarity when writing normal text. I used to write long, complex sentences. I tried to pack too much into a single sentence. And I had spent too much time studying 19th-century rhetorical speeches, where convoluted sentences were a way to show off professionalism and knowledge, and the style stuck with me. Now, I see that shorter, clearer sentences allow me to communicate my thoughts far more effectively.&lt;/p&gt;
&lt;p&gt;Accuracy in naming is another important aspect of clean coding. Instead of using single letters or abbreviations, using slightly longer and more descriptive variable names can help you to understand that part of the code later, when you don't remember exactly what is happening there. Descriptive names also help your fellow coders grasp your intentions and follow your logic. Even errors in the code become easier to spot when the variable name reveals that the value is completely different from what the original developer expected.&lt;/p&gt;
&lt;p&gt;After learning these principles, my natural language writing skills improved as well. I began to notice and became able to fix cases where I used ambiguous phrasing, skipped a word or two, or left too much room for misunderstanding. Just because something is clear to me doesn't mean it will be clear to others.&lt;/p&gt;
&lt;h2&gt;Final thoughts&lt;/h2&gt;
&lt;p&gt;Currently, I don't feel any inner drive to write fiction. However, I feel that whatever I write including emails, blog posts and Mastodon toots, I can now create with better structure and more understandable text than before I learned to code. I’ve also become more disciplined and have learned to better understand the reader’s viewpoint. In this way, programming has improved my writer’s empathy and helped me focus more on the reader or listener.&lt;/p&gt;
&lt;p&gt;What started as a childhood love for stories and my Lego hero, has grown into a career where I see language and logic intertwined. The journey never ends, and I can’t wait to see where it leads next.&lt;/p&gt;</content><category term="Personal"/><category term="Blogging"/><category term="Clean code"/><category term="Lego"/><category term="Me"/><category term="Work"/><category term="Writing"/><category term="Writing prompt"/></entry><entry><title>Along the Edge</title><link href="https://blog.gridranger.dev/along-the-edge" rel="alternate"/><published>2026-02-20T00:05:00+02:00</published><updated>2026-02-20T00:05:00+02:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2026-02-20:/along-the-edge</id><summary type="html">&lt;h1&gt;Along the Edge&lt;/h1&gt;
&lt;p&gt;It was one of those afternoons when I was too tired to do anything but play something casual. I installed the visual novel, &lt;em&gt;Along the Edge&lt;/em&gt;, which I had gotten for free a couple of days earlier. For me, it was definitely awesome yet anything but casual …&lt;/p&gt;</summary><content type="html">&lt;h1&gt;Along the Edge&lt;/h1&gt;
&lt;p&gt;It was one of those afternoons when I was too tired to do anything but play something casual. I installed the visual novel, &lt;em&gt;Along the Edge&lt;/em&gt;, which I had gotten for free a couple of days earlier. For me, it was definitely awesome yet anything but casual. It brought dormant memories to the surface and made me face complex feelings.&lt;/p&gt;
&lt;p&gt;The game is about a talented math PhD student, Daphné. To steer her life in a new direction after a painful trauma, she moves to a remote village in the French countryside, where she inherits her family's estate. Multigenerational secrets, personal drama, and local intrigue all blend together with a hint of supernatural (if the player chooses to believe in it).&lt;/p&gt;
&lt;p&gt;Similarly to my post related to &lt;em&gt;&lt;a href="/road-96-my-journey/"&gt;Road 96&lt;/a&gt;&lt;/em&gt;, this one is not so much about the game as it is about sharing flashes of my own personal story.&lt;/p&gt;
&lt;p&gt;&lt;img alt="A screenshot from the game. The castle tower the protagonist inherits stands surrounded by snow. The scene is quite artistic. All images in the game resemble paintings." src="../images/2026-02-20-the-tower.jpg"&gt;&lt;/p&gt;
&lt;h2&gt;Warm welcome for those who return&lt;/h2&gt;
&lt;p&gt;During my first playthrough, my curiosity quickly carried me past the scene where the main character is greeted as a long-lost family member by the old couple taking care of her late grandmother's estate. But on the second playthrough, it evoked a memory.&lt;/p&gt;
&lt;p&gt;Years after I revisited a &lt;a href="/family-history#adventure"&gt;castle once owned by my ancestors&lt;/a&gt; in the medieval era, my cousin and I spent a short holiday visiting a village that belonged to our family in the 19th century.&lt;/p&gt;
&lt;p&gt;We attended a service in the local church, after which the pastor came and introduced himself. He knew everyone in his congregation closely and made it a point to meet the new members. We told him we were on a vacation to learn more about our family. He kindly guided us to a lady who worked at the mayor's office. She was helpful and curious, and when she heard that we were descendants of the noble family that once lived there, she spoke to us as kindly as if we were already beloved members of the community.&lt;/p&gt;
&lt;p&gt;She showed us the parish archives and helped us look up dates and names from old birth records to fill in a couple of blank spaces and missing dates in our genealogy tree. It felt as though we brightened her day and she did the same for ours.&lt;/p&gt;
&lt;p&gt;&lt;img alt="A screenshot from the video game: Daphné holds old family photographs above a wooden drawer." src="../images/2026-02-20-old-photos.jpg"&gt;&lt;/p&gt;
&lt;h2&gt;Silent stones&lt;/h2&gt;
&lt;p&gt;We lodged in a modern guesthouse at the edge of the village. Being close to the forest, it was convenient for hiking and gathering firewood for grilling. The old cemetery was also nearby.&lt;/p&gt;
&lt;p&gt;The name of our ancestry was engraved on almost every second stone. It felt like looking back into the past. Many people who came before us had once lived there, with their own stories of happiness and tragedies. All of this became something you could almost touch. Being there also changed the sensation of time and history itself. It stretched out, and there was a long, unbroken chain leading to us. It was almost a spiritual experience.&lt;/p&gt;
&lt;p&gt;That was also the place where we found the flower the village got its name from.&lt;/p&gt;
&lt;p&gt;&lt;img alt="A landscape shot from a hilltop at the edge of a village. In the valley, you can see a vineyard, a winding road, and green fields in the background. In the foreground, there are a few trees and a small building. Tree branches partially cover the sky." src="../images/2026-02-20-at-the-edge-of-the-village.jpg"&gt;&lt;/p&gt;
&lt;h2&gt;The broken chain&lt;/h2&gt;
&lt;p&gt;At a certain point in the visual novel, Daphné must face the thought that she is her family's last offspring and that the lineage ends with her. She is in the midst of coping with this deep and painful personal wound when it takes on another dimension. There is a belief in the community that her family's spiritual power keeps the village safe.&lt;/p&gt;
&lt;p&gt;This motif stirred up feelings in me that are difficult to face. I have accepted the fact that I won't have a child of my own. But for me, this is not about passing on genes. It is about the family legacy.&lt;/p&gt;
&lt;p&gt;Stories and anecdotes about generations before me. Values I project onto my ancestors to motivate myself to become the best version of myself.&lt;/p&gt;
&lt;p&gt;Experiences of living through war and concentration camps, to remember and ensure it never happens again to others. Losing wealth and social status due to the cruelty of history but keeping dignity. Gaining a name while preserving backbone and humility. Starting from almost nothing but a passion for knowledge and justice, and becoming a respected member of the community. Being there for others when they face a crisis.&lt;/p&gt;
&lt;p&gt;My father's brother wrote books about family history. My maternal grandfather collected vast amounts of genealogical data that my mom continued to expand and organize. And my favorite storyteller was my mother's godmother. She never ran out of tales. I loved listening to her as she introduced me to relatives who died before I was born and to places that no longer exist.&lt;/p&gt;
&lt;p&gt;In December, I baked cookies using a roughly 150-year-old family recipe. They taste wonderful, and I always think fondly of how they connect the generations of our family. While making them this year, grief filled me for a moment when it struck me that I can't pass this on. Of course, it was just an old recipe. Yet, at that moment, it represented every cherished thought of my family that I can't pass on.&lt;/p&gt;
&lt;p&gt;Or can I? The chain doesn’t break as long as the stories live on and the values survive and refine.&lt;/p&gt;</content><category term="Personal"/><category term="Adventure"/><category term="Family history"/><category term="Gaming"/><category term="Me"/></entry><entry><title>My oldest things</title><link href="https://blog.gridranger.dev/my-oldest-things" rel="alternate"/><published>2026-01-24T21:10:00+02:00</published><updated>2026-01-24T21:10:00+02:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2026-01-24:/my-oldest-things</id><summary type="html">&lt;h1&gt;My oldest things&lt;/h1&gt;
&lt;p&gt;What do centuries-old stones, a self-winding watch and child's sock have in common?  &lt;/p&gt;
&lt;p&gt;Such time capsules often hide in our cupboards: lost treasures, family heirlooms, old diaries or dry pressed flowers. It is not their monetary value that matters, but the stories they tell. &lt;/p&gt;
&lt;p&gt;After reading similar …&lt;/p&gt;</summary><content type="html">&lt;h1&gt;My oldest things&lt;/h1&gt;
&lt;p&gt;What do centuries-old stones, a self-winding watch and child's sock have in common?  &lt;/p&gt;
&lt;p&gt;Such time capsules often hide in our cupboards: lost treasures, family heirlooms, old diaries or dry pressed flowers. It is not their monetary value that matters, but the stories they tell. &lt;/p&gt;
&lt;p&gt;After reading similar posts from &lt;a href="https://wrywriter.ca/2026/01/22/whats-the-oldest-thing-you/"&gt;Alex&lt;/a&gt;, &lt;a href="https://forkingmad.blog/what-is-the-oldest-thing-you-own/"&gt;David&lt;/a&gt; and &lt;a href="https://thomasrigby.com/posts/what-is-the-oldest-thing-you-own/"&gt;Thomas&lt;/a&gt;, I started to think of my own list.&lt;/p&gt;
&lt;h3&gt;Stones from an old castle wall&lt;/h3&gt;
&lt;p&gt;I've written about &lt;a href="/family-history#adventure"&gt;the castle my ancestors owned&lt;/a&gt; in the past. I have two small stones that fell from its wall, stored in a sealed plastic envelope. The castle was built in the early 13th century and last rebuilt in the 17th century. The stones hold only sentimental value for me.&lt;/p&gt;
&lt;h3&gt;Accessories from my paternal grandfather&lt;/h3&gt;
&lt;p&gt;After he passed away, I received his Swiss-made automatic watch. The kind you don't have to charge, or change the battery in, or wind. It winds itself as you move. I used it for nearly ten years.&lt;/p&gt;
&lt;p&gt;I also inherited a few pairs of cufflinks. One was an original Art Deco piece with mother-of-pearl inlay and was a particular favorite of mine. I often wore cufflinked shirts during my university years and throughout my thirties.&lt;/p&gt;
&lt;h3&gt;Old science fiction books&lt;/h3&gt;
&lt;p&gt;I attended a sci-fi history seminar at the university for a few semesters. Although Edgar Rice Burroughs' Mars series is not a sci-fi by definition, I always feel it as part of the genre. I’m glad I found old early-translated volumes of the series from the mid-1920s in antiquarian bookshops. (&lt;em&gt;A Princess of Mars&lt;/em&gt;, &lt;em&gt;The Warlord of Mars&lt;/em&gt; and &lt;em&gt;Thuvia, Maid of Mars&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;When I was a kid, I absolutely loved the series. I saw it as standing for things that mattered to me, like the idea of universal peace between countries with different cultures and between people of different skin colors. What usually got in the way of that peace were petty rulers, acting out of political self-interest.&lt;/p&gt;
&lt;p&gt;It was only much later that I started to notice the sexism, ageism, colonialism, and the kinds of racism the author himself was blind to. While its value system feels unmistakably dated today, for its own time it might have been relatively progressive in the United States, and even more so when published in interwar Eastern Europe.&lt;/p&gt;
&lt;h3&gt;My uncle's novels&lt;/h3&gt;
&lt;p&gt;One was released in 1962 and the other in 1975. These are more than just old or interesting books for me. The first follows the story of a handful of ordinary people during the 1956 revolution. The other one is about surviving a concentration camp as a child during WW2. Both stories draw from his personal experiences.&lt;/p&gt;
&lt;p&gt;These books are pieces of literature and family history to me at the same time. They remind me, along with the castle’s stones, that our personal story is deeply intertwined with history.&lt;/p&gt;
&lt;h3&gt;An unused sock from the 80s&lt;/h3&gt;
&lt;p&gt;I kept some clothes from my early childhood. One of them is a white sock in its original packaging. The packaging features a famous cartoon fox pulling on a sock.&lt;/p&gt;
&lt;p&gt;This item might not tell a grand historical tale, but it makes me remember how caring my parents were. The packaging is intact with the cartoon fox bright and cheerful. It is a witness of a childhood where even the smallest things were treasured. It also tells how lucky a generation I belong to. It’s true that I’ve lived through economic and existential crises, but Europe has been stable enough so far that I haven’t had to experience war. That stability allows me to keep and take joy even in such small things.&lt;/p&gt;
&lt;h2&gt;Things I don't have anymore&lt;/h2&gt;
&lt;p&gt;I let go of a good deal of interesting stuff when I &lt;a href="/road-96-my-journey"&gt;left my home country&lt;/a&gt;. Some of them would have been old enough to be on the list.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The top hat of my great-grandfather.&lt;/strong&gt; It was custom-made for him. The workshop that manufactured it was once in the building just across the street from the university I attended. I wore the hat once for a photoshoot. Later, it was donated to a museum.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Capitaly game board that my other uncle made.&lt;/strong&gt; &lt;a href="https://boardgamegeek.com/boardgame/18618/capitaly"&gt;Capitaly&lt;/a&gt; was a local Monopoly variant released between the two world wars. He made the board for family use, perhaps in the 1950s. It is now in a big board game box somewhere at my parents' place.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Space Lego sets from the 70s.&lt;/strong&gt; I managed to buy some old classic space Lego sets when online auction platforms were still young and sellers were more average people rather than second-hand merchants making a business for a living. Getting the missing parts and replacing the worn and broken ones wasn't easy, but I tried my best. I sold these sets to a collector friend. Perhaps one day, I will write more about the role Lego once played in my life.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;What are the oldest things you own? I’d be glad to hear their stories in the comments or in reply posts.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Some items I mention in the post. The cufflinks, a stone and the watch. Behind them there are three books: one dark red and two grey ones. In the background you can see the snowy forest through the balcony." src="../images/2026-01-24-Oldests.jpg"&gt;&lt;/p&gt;</content><category term="Personal"/><category term="Family history"/><category term="Lego"/><category term="Me"/><category term="Reading"/></entry><entry><title>My Phones</title><link href="https://blog.gridranger.dev/my-phones" rel="alternate"/><published>2026-01-13T23:43:00+02:00</published><updated>2026-05-17T13:11:00+03:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2026-01-13:/my-phones</id><summary type="html">&lt;h1&gt;My Phones&lt;/h1&gt;
&lt;h2&gt;Ericsson A2618&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.gsmarena.com/ericsson_a2618-193.php"&gt;This black device&lt;/a&gt; was my first mobile phone. I got it in 2001. I remember reading an SMS-based news service on its tiny screen during high school lunch breaks after September 11.&lt;/p&gt;
&lt;p&gt;It was a bulky but durable device. Once, I remember, I was playing basketball …&lt;/p&gt;</summary><content type="html">&lt;h1&gt;My Phones&lt;/h1&gt;
&lt;h2&gt;Ericsson A2618&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.gsmarena.com/ericsson_a2618-193.php"&gt;This black device&lt;/a&gt; was my first mobile phone. I got it in 2001. I remember reading an SMS-based news service on its tiny screen during high school lunch breaks after September 11.&lt;/p&gt;
&lt;p&gt;It was a bulky but durable device. Once, I remember, I was playing basketball in the schoolyard. When I jumped up to take a shot, it slipped out of the inside pocket of my jacket and hit the concrete with a loud smack. It didn’t even get a scratch.&lt;/p&gt;
&lt;p&gt;One day, sitting by the piano, I tried to figure out the notes of the &lt;em&gt;Imperial March&lt;/em&gt; from &lt;em&gt;Star Wars&lt;/em&gt; so I could type them in as letters into the ringtone editor. I didn’t use it as a ringtone. I was simply curious whether I could do it. I never figured out how to control the rhythm, but I got most of the notes right, I guess.&lt;/p&gt;
&lt;p&gt;This phone later became my father’s first mobile phone.&lt;/p&gt;
&lt;p&gt;📱 It was my primary phone for 2.5 years.
⌛ It served more than 5 years. &lt;/p&gt;
&lt;h2&gt;Nokia 5510&lt;/h2&gt;
&lt;p&gt;I got &lt;a href="https://en.wikipedia.org/wiki/Nokia_5510"&gt;this one&lt;/a&gt; for X-mas from my parents in 2003. It was awsome. There was a hidden 3310 inside it. The phone featured a full keyboard and the iconic Snake game.&lt;/p&gt;
&lt;p&gt;It also had 64 MB internal storage as part of its media player feature. But you could use the internal memory just like any USB stick if you carried a cable. Back then, I wrote short stories and carried my drafts as Word documents in my pocket. I could work on them anywhere, way before the Google Docs was even invented.&lt;/p&gt;
&lt;p&gt;I also used the phone as a voice recorder with an external mic for interviews I made for the school paper.&lt;/p&gt;
&lt;p&gt;I loved this phone. I even joined the Nokia Care program, for cheaper service fees. It came with a cool plastic membership card with my name on it. Too bad I threw it away a few years later. I had no idea I’d end up working for the company one day.&lt;/p&gt;
&lt;p&gt;📱 2.5 years
⌛ 5 years&lt;/p&gt;
&lt;h2&gt;Nokia 6800 I.&lt;/h2&gt;
&lt;p&gt;After having a QWERTY phone, there was no way I'd go back to multi-tap SMS typing. In 2006, I bought my first &lt;a href="https://en.wikipedia.org/wiki/Nokia_6800_series#Nokia_6800"&gt;6800&lt;/a&gt; second-hand, complete with all its accessories in the box.&lt;/p&gt;
&lt;p&gt;It was a Symbian phone with a color display and white backlight. You could load custom wallpapers onto it, and I even installed a Sudoku game.&lt;/p&gt;
&lt;p&gt;I loved it how a traditional mobile phone could transform into a comfortable text-writing device with its dead-simple mechanism whenever I was writing SMS messages or taking notes. No fragile hidden cables to worry about.&lt;/p&gt;
&lt;p&gt;📱 2 years
⌛ at least 3 years (more if it was sold after the theft, I didn't know how to blacklist it)&lt;/p&gt;
&lt;p&gt;&lt;img alt="My Nokia 6800, halfway between the traditional and QWERTY state. It is lying on a classic Nokia-logo microfiber cleaning cloth. Next to it, on the screen of the Nokia X10, you can see the part of this post about it displayed in a browser." src="../images/2026-01-13-Nokias.jpg"&gt;&lt;/p&gt;
&lt;h2&gt;Nokia 6800 II.&lt;/h2&gt;
&lt;p&gt;In 2008, I was robbed, and the thief took my phone along with my bag. By then it was already an old model, so I could buy another one cheaply second-hand. It wasn’t exactly the same. It was much more worn. The screen was scratched, there was cracked near the hinge, and the screen’s color temperature had a yellowish tint. But it was still pretty awesome.&lt;/p&gt;
&lt;p&gt;I still have it in my drawer.&lt;/p&gt;
&lt;p&gt;📱 5 years
⌛ at least 7 years&lt;/p&gt;
&lt;h2&gt;Nokia 2760&lt;/h2&gt;
&lt;p&gt;I got &lt;a href="https://www.gsmarena.com/nokia_2760-1975.php"&gt;this flip phone&lt;/a&gt; as company phone in late 2008. It had a camera, but I've never used it. My primary device was still my 6800, and I didn't need a camera.&lt;/p&gt;
&lt;p&gt;📱 2 years
⌛ 3.5 years&lt;/p&gt;
&lt;h2&gt;Nokia 3110 Classic&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.gsmarena.com/nokia_3110_classic-pictures-1862.php"&gt;This model&lt;/a&gt; replaced the 2760 as a company phone in 2010. I only used it for company calls and still used my 6800 for everything else.&lt;/p&gt;
&lt;p&gt;📱 4 years
⌛ at least 4 years (if it was not reused as company phone)&lt;/p&gt;
&lt;h2&gt;Samsung Galaxy Ace&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Samsung_Galaxy_Ace"&gt;The Ace&lt;/a&gt; was my first smartphone. I got it for X-mas in 2013. I remember, my first app was Sky Map. Mobile gaming was never my thing.&lt;/p&gt;
&lt;p&gt;It was a sturdy little phone, not too fast, but unbreakable. Its size was perfect and its rubber back gave it a great grip.&lt;/p&gt;
&lt;p&gt;Back then, Android seemed free and fair. I trusted Google. That’s something I feel completely ashamed of now. They seemed like the good guys, promoting openness in contrast to their arrogant competitors. Either the temptation of power and money corrupted them, or they were rotten from the start. In the end, no one cares, and it makes no difference today.&lt;/p&gt;
&lt;p&gt;I also tried out some unofficial Android ROMs on my Ace, like CyanogenMod.&lt;/p&gt;
&lt;p&gt;Although it had only a single core, I also used it in my BOINC cluster. It served less then the other phones because there were no compatible work units for it after a while. Eventually it was donated for reuse.&lt;/p&gt;
&lt;p&gt;📱 3 years
⌛ at least 7 years (if it could not been reused)&lt;/p&gt;
&lt;h2&gt;Nokia Lumia 625&lt;/h2&gt;
&lt;p&gt;On my first day at Nokia, I received &lt;a href="https://en.wikipedia.org/wiki/Nokia_Lumia_625"&gt;a Nokia phone&lt;/a&gt; as a company device. It was awesome. It had almost zero useful apps in the store, but I loved the tile based system. I still think that it held a lot of untapped potential. It’s a shame that, as usual, Microsoft tried to force its Windows mobile OS through with influence rather than brains.&lt;/p&gt;
&lt;p&gt;While the iPhone championed elitism and Android (at the time) embraced openness, Microsoft spent years unable to figure out how to attract developers and users.&lt;/p&gt;
&lt;p&gt;The company recollected this device after I got my next phone.&lt;/p&gt;
&lt;p&gt;📱 2 years
⌛ 2 years&lt;/p&gt;
&lt;h2&gt;Xiaomi Redmi 3S&lt;/h2&gt;
&lt;p&gt;A couple of years later, I had the chance to choose a new company phone as a benefit. I could either pick a device from the company catalog for free or buy my own and get reimbursed up to a hundred euros. &lt;a href="https://www.gsmarena.com/xiaomi_redmi_3s_prime-pictures-8250.php"&gt;The Redmi 3S&lt;/a&gt; cost around €87, and it was impressive. It had large-capacity battery, four high-performance CPU cores, four energy-saving ones, dual-SIM capability, a streamlined UI, and a metal casing for excellent heat dissipation. It was my first phone with a fingerprint reader which you could even use for scrolling.&lt;/p&gt;
&lt;p&gt;At the time, Xiaomi was just an interesting new start-up, still about carving a name for itself with a great value-to-price ratio. Later they lost my trust completely.&lt;/p&gt;
&lt;p&gt;I really liked this phone, even though I didn't use it for too long.&lt;/p&gt;
&lt;p&gt;📱 6 months
⌛ 4.5 years&lt;/p&gt;
&lt;h2&gt;Vernee Thor&lt;/h2&gt;
&lt;p&gt;One day, my partner at the time had her Xperia break, and we needed a new phone quickly. We had little money to spend, and among the budget phones the Vernee Thor had impressive reviews on reliable sites. Even better than the Redmi 3S and it cost the same. And the delivery time was just two days, not three weeks as it would have been with the 3S.&lt;/p&gt;
&lt;p&gt;The reviews weren’t just mistaken. It was by far the worst phone I’ve ever used. Random parts of the screen didn't detect any touches, including the status bar on the top and parts of the keyboard.&lt;/p&gt;
&lt;p&gt;She didn't have the patience to deal with this sorry excuse for a phone, so I offered to swap phones with her until the next payday, so we could buy a proper one.&lt;/p&gt;
&lt;p&gt;I sold it for fraction of its original price to an Android developer to use as a test phone.&lt;/p&gt;
&lt;p&gt;📱 2 weeks
⌛ probably less than 1 year&lt;/p&gt;
&lt;h2&gt;Xiaomi Redmi 4X&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Redmi_4X"&gt;This phone&lt;/a&gt; had the same internal hardware as the 3S with a slightly smaller screen and size. The speakers were positioned differently, and it was made from black aluminum instead of matte silver magnesium alloy.&lt;/p&gt;
&lt;p&gt;Since it was pretty much the same as the other phone, and she didn't want to move her data again, she kept the 3S and I used this. I used this phone a lot. I also began to use it for BOINC grid computing. It could only solve CPU projects but could use all 8 cores and thanks to its good heat dissipation it didn't overheat. I could also use it as a hand warmer in winter.&lt;/p&gt;
&lt;p&gt;I also replaced its stock Android with a custom ROM for better performance, improved security, and longer battery-life.&lt;/p&gt;
&lt;p&gt;Later when I had the Nokia 7.1, I added this phone to my computing cluster. I had its battery replaced during the COVID-19 lockdown to keep it in working shape. My cousin also used it too for a couple of weeks while her phone was being repaired. To this day I still use it for a spare SIM in the family.&lt;/p&gt;
&lt;p&gt;📱 2.5 years
⌛ 8 years and still counting&lt;/p&gt;
&lt;h2&gt;Samsung Galaxy Note&lt;/h2&gt;
&lt;p&gt;I posted on the company bulletin board that I was looking for old phones to use for scientific projects. One of my coworkers contributed &lt;a href="https://hu.wikipedia.org/wiki/Samsung_Galaxy_Note"&gt;this phone&lt;/a&gt; to my cluster. After replacing the stylus and getting a new battery, this device it was good as new.&lt;/p&gt;
&lt;p&gt;Although it had only 2 CPU cores, it was a reliable device. I applied a battery tweak to all the devices in the cluster to prevent them from continuously charging, even if they were plugged in the whole time. With this simple trick this device worked hard reliably for years. When I shut down the BOINC cluster, I donated it to a project that repurposed old devices to help detect illegal deforestation in rainforests.&lt;/p&gt;
&lt;p&gt;🔬 It was part of my BOINC cluster for 4 years
⌛ at least 5 years&lt;/p&gt;
&lt;h2&gt;Samsung Galaxy S4 Mini Plus&lt;/h2&gt;
&lt;p&gt;I bought &lt;a href="https://en.wikipedia.org/wiki/Samsung_Galaxy_S4_Mini"&gt;this phone&lt;/a&gt; real cheap from another coworker for my cluster. With four cores it did its fair share of the work for years. It was donated to the rainforest project too.&lt;/p&gt;
&lt;p&gt;🔬 4 years
⌛ at least 5 years&lt;/p&gt;
&lt;h2&gt;HMD Nokia 7.1&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Nokia_7.1"&gt;This device&lt;/a&gt; was my next phone after the 4X. It served as both personal and company phone. It performed well and had a decent camera unit that handled dark areas and nighttime photos surprisingly well.&lt;/p&gt;
&lt;p&gt;However, the phone was too large for my taste. It also had glass covered backside, so I had to clean it more often and handle it more carefully than my other phones. I've never cracked or broken any of my phones, and I wanted to keep it that way.&lt;/p&gt;
&lt;p&gt;Compared to metal-bodied phones, this design felt like a major step backward. The glass back made it slide on some surfaces, and the heat dissipation was also poor. I couldn't even use it for BOINC research.&lt;/p&gt;
&lt;p&gt;📱 2.5 years
⌛ 4.5 years&lt;/p&gt;
&lt;p&gt;&lt;img alt="HMD Nokia X10 and Xiaomi Redmi 4X with their screen turned on. They are showing their section of this very post on their screens." src="../images/2026-01-13-Smarts.jpg"&gt;&lt;/p&gt;
&lt;h2&gt;HMD Nokia X10&lt;/h2&gt;
&lt;p&gt;I got &lt;a href="https://www.gsmarena.com/nokia_x10-10840.php"&gt;my next phone&lt;/a&gt; in 2022. For a long time, I used it for as personal device too, and I still use it as my company phone. It isn't as high-performing as the 7.1 was, and its camera is also worse. But I use it for 4 years now, and it works fine. Even the battery life is still great.&lt;/p&gt;
&lt;p&gt;This device had a perfectly centered, preinstalled screen protector! Frankly, why is it not an industry standard?&lt;/p&gt;
&lt;p&gt;📱 3 years
⌛ 4 years and still counting&lt;/p&gt;
&lt;h2&gt;Samsung Galaxy S24&lt;/h2&gt;
&lt;p&gt;I used &lt;a href="https://en.wikipedia.org/wiki/Samsung_Galaxy_S24"&gt;it&lt;/a&gt; as a company phone for 9 months while I was working for another company.&lt;/p&gt;
&lt;p&gt;I liked its small size, and both the camera unit and the screen was amazing. But it was my first phone since my Galaxy Ace that had serious compass issues. I had to recalibrate it roughly every 5 minutes. Even when it worked, it still showed the wrong direction by 90 degrees. I didn’t expect this from a flagship phone.&lt;/p&gt;
&lt;p&gt;Maybe it was just an issue with this specific unit, not a widespread problem with the entire series.&lt;/p&gt;
&lt;p&gt;📱 9 months
⌛ at least 9 months&lt;/p&gt;
&lt;h2&gt;Fairphone 5&lt;/h2&gt;
&lt;p&gt;When I started to work for Nokia in Finland, I got back to my X10 instead of ordering a new phone to avoid waste.&lt;/p&gt;
&lt;p&gt;I got the &lt;a href="https://en.wikipedia.org/wiki/Fairphone_5"&gt;Fairphone 5&lt;/a&gt; for X-mas 2025. It meant a lot to me to move away from Google's spyware integrated into Android itself (I also wrote a &lt;a href="/mobile-oses-featuring-fairphone-5"&gt;separate post&lt;/a&gt;) about it. Now it's my private phone, while I kept the X10 to run all the Microsoft apps I need for work.&lt;/p&gt;
&lt;p&gt;The display is beautiful, the cameras are okay, and I like its size and metal frame. I've also tried a couple of different OS-es on it. I plan to write another post of my experiences with them.&lt;/p&gt;
&lt;p&gt;📱 since Dec 2025
⌛ since Dec 2025&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;📱 Average usage time: 2 years 8 months (not counted here: 3S, Thor, S4, Note, Fairphone 5)&lt;/p&gt;
&lt;p&gt;⌛ Average service time: 5 years 4 months (not counted here: Thor, S24, Fairphone 5)&lt;/p&gt;</content><category term="Personal"/><category term="BOINC"/><category term="Degoogling"/><category term="Nokia"/><category term="Post streams"/><category term="Writing"/></entry><entry><title>Road 96 - My Journey</title><link href="https://blog.gridranger.dev/road-96-my-journey" rel="alternate"/><published>2025-12-20T01:55:00+02:00</published><updated>2025-12-20T01:55:00+02:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-12-20:/road-96-my-journey</id><summary type="html">&lt;h1&gt;Road 96 - My Journey&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;[!warning]
&lt;strong&gt;Content warning:&lt;/strong&gt; This post stream is &lt;strong&gt;not about video games&lt;/strong&gt; but addresses deeply sensitive topics that may be distressing for some. Please proceed only if you feel prepared.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;The game&lt;/h2&gt;
&lt;p&gt;I rarely buy full-price video games, and before buying anything I always think carefully to …&lt;/p&gt;</summary><content type="html">&lt;h1&gt;Road 96 - My Journey&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;[!warning]
&lt;strong&gt;Content warning:&lt;/strong&gt; This post stream is &lt;strong&gt;not about video games&lt;/strong&gt; but addresses deeply sensitive topics that may be distressing for some. Please proceed only if you feel prepared.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;The game&lt;/h2&gt;
&lt;p&gt;I rarely buy full-price video games, and before buying anything I always think carefully to avoid impulse buys. But &lt;em&gt;Road 96&lt;/em&gt;? I bought it as soon as I read about it. And I played it through on the very same Saturday. This was in the summer of 2022.&lt;/p&gt;
&lt;p&gt;I was twice as old as the teenagers in the game’s story, who try to flee across the border. Even at the cost of their lives, they want to leave Petria behind. This fictional country is a modern dictatorship masquerading as a democracy, much like what my homeland has become since 2010.&lt;/p&gt;
&lt;p&gt;Even though I played the game in my mid-thirties, I wanted exactly what those teenagers did: to escape the country and never look back. Experiencing their story made me both envious and inspired.&lt;/p&gt;
&lt;p&gt;In this post stream I'll write about my journey. One where the miles traveled were perhaps the simplest part.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Campfire at night. Beyond the fire lies a valley. In the valley, there is a campsite with caravans. The lights of windows and string lights are visible. On the right, the corner of a portable radio can be seen. There are captions on the picture quoting Zoe, a character in the game: &amp;quot;My dad says I'm lucky because I have a privileged life here. But that life disgusts me, especially now that I know...&amp;quot;" src="../images/2025-12-14-petria-0.jpg"&gt;&lt;/p&gt;
&lt;h2&gt;Reasons to leave&lt;/h2&gt;
&lt;p&gt;You might wonder what were my reasons. I was privileged: a cis, straight, white man. I had friends, a job I loved, and a stable income.&lt;/p&gt;
&lt;p&gt;But beyond the walls of my home and the windows of my office, the world around me was utterly inhuman. Outside, there was a country where the government mocked and targeted anyone who wasn’t cis or straight. The elderly were pushed to the margins of society. Homelessness wasn’t met with support, but with criminalization. Everyone had learned to look the other way when a child was beaten or a woman harassed in broad daylight. Domestic violence had somehow become part of the 'traditional values'. Rapists were kept in high regard and pedophiles preached about family values. Grifters were considered clever, while being honest was seen as a weakness. The stress festered until some people snapped and lashed out at strangers in the street, simply because the media had labeled them 'agents of external enemies'.&lt;/p&gt;
&lt;p&gt;I didn’t want to live in a world like this. But I felt completely powerless. I voted in elections. I attended peaceful protests and supported NGOs fighting for good causes and protection of victims. There was, however, a trap in all of this. Even the greatest effort failed to bring any deep change. And in the meanwhile, all of us who were trying, were sustaining this whole aberrant system with our taxes.&lt;/p&gt;
&lt;p&gt;I couldn't stomach funding a regime actively building a patriarchal fascist dictatorship under the guise of EU membership. My tax money is also my vote. I wanted it to support a country that upholds humanist European values.&lt;/p&gt;
&lt;p&gt;The only way for me was to move.&lt;/p&gt;
&lt;p&gt;&lt;img alt="A crowd waits for the inauguration of an oil well. Everyone is wearing the ruling party’s baseball caps, jackets, and T-shirts. The event’s fencing is lined with banners displaying the words &amp;quot;Tyrak 1996&amp;quot;. In the background, a roadside billboard displays a portrait of a balding man in a suit against a red backdrop, with the caption: &amp;quot;President Tyrak.&amp;quot; The area is surrounded by a disproportionate number of patrol cars and police officers for the size of the crowd. A few pine trees stand in the background, with mountains visible in the distance." src="../images/2025-12-14-petria-1.jpg"&gt;&lt;/p&gt;
&lt;h2&gt;Examples to follow&lt;/h2&gt;
&lt;p&gt;As a child in the early 1990s, family acquaintances would visit when they came home from abroad, where they worked and lived. They had moved to Austria and Germany during the communist period. They left to break free from a system that had taken an entire country hostage. As a child, I did not understand this. But after a temporary easing, when a Russian puppet government came to power again in the 2010s, I understood why they had chosen to emigrate.&lt;/p&gt;
&lt;p&gt;I remember that when I was a small child, my grandparents took my sister and me to visit a friend of theirs whose son had just come home from Germany for a visit. As I listened to the conversation while quietly eating cake, I sensed something alongside the joy and pride. Something no one said out loud, but everyone felt. Moving abroad is very hard. For those who stay behind and for those who leave alike. He must have had a serious reason to make that decision.&lt;/p&gt;
&lt;p&gt;At the time, I didn’t find the idea frightening or liberating; I simply accepted it with a child’s matter-of-fact understanding that there could be a reason important enough to make it worth taking on.&lt;/p&gt;
&lt;h2&gt;Forces that hold people back&lt;/h2&gt;
&lt;p&gt;I wasn't the only one thinking that way. Every year, roughly a city’s worth of people leave the country, about 30 to 40&amp;nbsp;000 in total. And even more people would like to do so.&lt;/p&gt;
&lt;p&gt;Yet so many who long to leave never do. Some stay because of elderly parents, for example. Others believe that moving abroad would be too disruptive to their children’s lives. As if anything could be worse than the inhumane, steadily deteriorating public education system at home. There are also those who think they would not be able to cope in another language, another environment, or on their own. Moving can also mean losing existential stability, falling back in career or even losing your prospering business entirely. As many people, as there are reasons.&lt;/p&gt;
&lt;p&gt;Judging by the government’s rhetoric, it seems very deliberate that citizens are meant to be kept in place by precisely reasons like this. The whole country has become a prison. People have lost their freedom. They had no way to fight back, and although there are no walls, most will never leave.&lt;/p&gt;
&lt;p&gt;Because doing so demands painful sacrifices from you and your loved ones, if you even have the means to leave at all.&lt;/p&gt;
&lt;p&gt;My country’s prime minister stated that citizens living abroad are, in fact, traitors. Ironic that a government voting in Moscow’s favor within the EU, and having suffocated democracy at home, labels as traitors those citizens who refuse to become its hostages. But it's better to be taken seriously. In the 1950s, those who emigrated were declared enemies of the state. Their property was seized, they were sentenced to prison or forced labor in absentia. The authorities also ruined the lives of the family members they left behind.&lt;/p&gt;
&lt;p&gt;&lt;img alt="A small lake between reddish cliffs. With pine trees and other vegetation surrounding the lake. There is a small waterfall on the other side partially hidden by the trees." src="../images/2025-12-14-petria-2.jpg"&gt;&lt;/p&gt;
&lt;h2&gt;Deciding where to go&lt;/h2&gt;
&lt;p&gt;We weren’t sure how long the country would remain in the EU or how long the borders would stay open, so we didn’t want to delay our move too long.&lt;/p&gt;
&lt;p&gt;Canada, Finland, US, UK. These are the countries I remember from the shortlist we wrote with my wife. Because of the rise of populism, we’ve removed the last two from our list. We didn’t want to jump out of the frying pan into the fire.&lt;/p&gt;
&lt;p&gt;In the end, we chose Finland. I had worked for a Finnish company for ten years, and it was far more humane than most multinationals. I loved working with my Finnish colleagues. When I was there on a business trip in 2022, I was struck by how seamlessly technology and nature coexisted. Respect for nature was also important to us.&lt;/p&gt;
&lt;p&gt;We didn't expect Finland (or any other country) to be perfect. But we knew that Finnish people respect human rights, and are generally more honest and solution focused than the society was around us. We didn't think that life will be easier or our financial situation would improve, but we knew we could expect a fairer and more mentally healthy environment. A place to live without compromising who we are.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;To be continued...&lt;/em&gt;&lt;/p&gt;</content><category term="Personal"/><category term="Post streams"/><category term="Me"/><category term="Gaming"/></entry><entry><title>Custom Font in JetBrains Terminal</title><link href="https://blog.gridranger.dev/custom-font-in-jetbrains-terminal" rel="alternate"/><published>2025-12-12T20:16:00+02:00</published><updated>2026-01-24T14:06:00+02:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-12-12:/custom-font-in-jetbrains-terminal</id><summary type="html">&lt;h1&gt;How to Use Custom Font in JetBrains Terminal&lt;/h1&gt;
&lt;p&gt;It was tantalizing. I have a favourite terminal font: an old IBM VGA variant. I also updated it with &lt;a href="https://www.nerdfonts.com"&gt;Nerd Fonts&lt;/a&gt; icons and glyphs. I can use it in Konsole, PyCharm, and WebStorm, but it wasn't selectable as a terminal font for …&lt;/p&gt;</summary><content type="html">&lt;h1&gt;How to Use Custom Font in JetBrains Terminal&lt;/h1&gt;
&lt;p&gt;It was tantalizing. I have a favourite terminal font: an old IBM VGA variant. I also updated it with &lt;a href="https://www.nerdfonts.com"&gt;Nerd Fonts&lt;/a&gt; icons and glyphs. I can use it in Konsole, PyCharm, and WebStorm, but it wasn't selectable as a terminal font for either IDE’s reworked terminal.&lt;/p&gt;
&lt;p&gt;I generated italic, bold, and bold-italic variants for it and even tweaked the font metadata, but it still never showed up as a selectable font in the terminal settings.&lt;/p&gt;
&lt;p&gt;So I set it directly in the configuration file. And finally: it worked!&lt;/p&gt;
&lt;p&gt;Here’s how you can do it too:&lt;/p&gt;
&lt;p&gt;1.) Locate the config folder. &lt;code&gt;~/.config/JetBrains/PyCharmCE202?.?/options&lt;/code&gt; in my KDE Neon. It should be &lt;code&gt;%APPDATA%\Roaming\JetBrains\PyCharm202?.?\options&lt;/code&gt; in Windows. For other products (like WebStorm), use the corresponding folder. Keep an eye on the version. You’ll probably want to use the most recent one.&lt;/p&gt;
&lt;p&gt;2.) Open up your IDE. Set the desired font for the &lt;strong&gt;editor&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;3.) Save or Apply the change then close the IDE.&lt;/p&gt;
&lt;p&gt;4.) Open &lt;code&gt;editor-font.xml&lt;/code&gt;. It will look like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;application&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;component&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;DefaultFont&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;VERSION&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;FONT_SIZE&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;16&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;FONT_SIZE_2D&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;16.0&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;FONT_FAMILY&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;MxPlusIBMVGA9x16 Nerd Font Mono&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;FONT_BOLD_SUB_FAMILY&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Regular&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/component&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/application&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;5.) Copy the line with the &lt;code&gt;FONT_FAMILY&lt;/code&gt; setting. You can copy the whole file if you want to, but the update the 2nd line to &lt;code&gt;&amp;lt;component name="TerminalFontOptions"&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;6.) Open &lt;code&gt;terminal-font.xml&lt;/code&gt;. Its structure is the same. Paste or replace the &lt;code&gt;FONT_FAMILY&lt;/code&gt; line.&lt;/p&gt;
&lt;p&gt;7.) Launch your IDE again. Now, it will have the font you've just set:&lt;/p&gt;
&lt;p&gt;&lt;img alt="A screenshot of my PyCharm Terminal using a custom font, zsh with p10k custom theme. It shows the output of a git status command from this blog's own repo." src="../images/2025-12-12-terminal.png"&gt;&lt;/p&gt;
&lt;p&gt;You can set a different editor font after that. It won’t affect the terminal font. We simply used the editor’s setting to get the exact configuration to paste into the terminal’s configuration file.&lt;/p&gt;
&lt;p&gt;You can also change the terminal font size from the UI without losing your font setting. But if you select a different terminal font, the custom one might disappear from the dropdown.&lt;/p&gt;</content><category term="Development"/><category term="Linux"/></entry><entry><title>Snowfall</title><link href="https://blog.gridranger.dev/snowfall" rel="alternate"/><published>2025-11-30T20:16:00+02:00</published><updated>2025-11-30T20:16:00+02:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-11-30:/snowfall</id><summary type="html">&lt;h1&gt;Snowfall&lt;/h1&gt;
&lt;p&gt;Last winter, I read an article about how creatively snowfall decorations were used on static websites, and that this tradition has almost completely disappeared since the rise of Web 2.0.&lt;/p&gt;
&lt;p&gt;I decided that when I build my own static blog, it will definitely be full of snowflakes in …&lt;/p&gt;</summary><content type="html">&lt;h1&gt;Snowfall&lt;/h1&gt;
&lt;p&gt;Last winter, I read an article about how creatively snowfall decorations were used on static websites, and that this tradition has almost completely disappeared since the rise of Web 2.0.&lt;/p&gt;
&lt;p&gt;I decided that when I build my own static blog, it will definitely be full of snowflakes in winter. This is the blog I planned back then, and the snowfall started yesterday!&lt;/p&gt;
&lt;p&gt;Here you can find the code snippet I use: &lt;a href="https://framagit.org/gridranger/gridranger.frama.io/-/snippets/7593"&gt;Websnow 2025&lt;/a&gt;. Feel free to use it or modify it to have similar animation on your site. You can also post your snowy site to &lt;a href="https://mementomori.social/@david_bardos/115634200410109564"&gt;this stream on Mastodon&lt;/a&gt;. Or you can use the tag &lt;code&gt;#websnow2025&lt;/code&gt;.&lt;/p&gt;</content><category term="Blog"/><category term="Blogging"/></entry><entry><title>Refactoring: Yeelight GUI</title><link href="https://blog.gridranger.dev/refactoring-yeelight-gui" rel="alternate"/><published>2025-10-28T23:39:00+02:00</published><updated>2025-10-28T23:39:00+02:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-10-28:/refactoring-yeelight-gui</id><summary type="html">&lt;p&gt;I'd like to contribute to open source projects, but I don't have enough time to do so regularly for any specific project nowadays. The best I can do is clean up some small abandoned code bases that I find useful.&lt;/p&gt;
&lt;p&gt;And there's another thing. Lately, I've been thinking a lot …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I'd like to contribute to open source projects, but I don't have enough time to do so regularly for any specific project nowadays. The best I can do is clean up some small abandoned code bases that I find useful.&lt;/p&gt;
&lt;p&gt;And there's another thing. Lately, I've been thinking a lot about getting a phone that doesn't run Android at all but Ubuntu Touch instead. But this raises a few questions. One of them is how to control my smart bulb? A Python app that runs on any desktop Linux might do the trick. I looked for a UI for the &lt;code&gt;yeelight&lt;/code&gt; Python library and I found this one: &lt;a href="https://github.com/Ryszard-S/yeelight-GUI"&gt;Ryszard-S/yeelight-GUI&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It looked unmaintained. I forked it (&lt;a href="https://framagit.org/gridranger/yeelight-gui"&gt;gridranger/yeelight-gui&lt;/a&gt;), cleaned up the code and fixed some minor issues. For example, the bulb list no longer forgets the selected bulb when a new scene is picked. Auto-detection is also improved. Additional button clicks after setting the color temperature and brightness are no longer necessary. Setting the values apply them automatically. Instead of failing silently when the config is missing or invalid, a default one is loaded. Cursor is animated while the app is looking for bulbs on the network. And so on.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Two versions of the same application. They feature the same functions like turning the lights on and off, changing color, color temperature, brightness or predefined scenes of the selected smartbulbs. The newer version is smaller as it has two less buttons and smaller font size. The color of the widgets are light and dark yellow (old gold and reef gold) while the background of the application is dark gray (mineshaft grey)." src="../images/2025-10-29-gui-new.png"&gt;&lt;/p&gt;
&lt;p&gt;Most of the credit goes to &lt;a href="https://gitlab.com/stavros"&gt;Stavros Korokithakis&lt;/a&gt; who maintains the &lt;a href="https://gitlab.com/stavros/python-yeelight"&gt;python-yeelight&lt;/a&gt; library that serves as the foundation of this app. Also to &lt;a href="https://github.com/Ryszard-S"&gt;Ryszard-S&lt;/a&gt; who wrote the original code that I cleaned up.&lt;/p&gt;
&lt;p&gt;I'll use it on my desktop for a couple of days to see if it's comfortable and, if not, what needs to be changed.&lt;/p&gt;
&lt;p&gt;Further plans:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create a Pip-installable package that allows you to launch the app by running a single binary.&lt;/li&gt;
&lt;li&gt;Store the configuration file in the user's home folder (~/.local/share/yeelight-gui for Linux and somewhere under the AppData for Windows).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Any additional ideas and contributions are welcome.&lt;/p&gt;</content><category term="Development"/><category term="Clean code"/><category term="Python"/><category term="Degoogling"/><category term="Linux"/></entry><entry><title>Gaming backlog</title><link href="https://blog.gridranger.dev/gaming-backlog" rel="alternate"/><published>2025-10-05T18:12:01+03:00</published><updated>2025-10-05T18:12:01+03:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-10-05:/gaming-backlog</id><summary type="html">&lt;h1&gt;A new gaming backlog&lt;/h1&gt;
&lt;p&gt;I like playing video games and developing things. And I also like to writing lists to keep track of various things. Like what I played and when. You can keep track of the games you plan to play, the ones you are playing now, and the …&lt;/p&gt;</summary><content type="html">&lt;h1&gt;A new gaming backlog&lt;/h1&gt;
&lt;p&gt;I like playing video games and developing things. And I also like to writing lists to keep track of various things. Like what I played and when. You can keep track of the games you plan to play, the ones you are playing now, and the ones that you have already played. It is like a task list, Kanban board or project backlog.&lt;/p&gt;
&lt;h2&gt;The history of my gaming history&lt;/h2&gt;
&lt;p&gt;Back in the old days, I had a cloud based spreadsheet to keep track of my gaming records. Searching and editing were lightning fast. But it was quite boring to look at it.&lt;/p&gt;
&lt;p&gt;Later, I've found a service I used for a long time: &lt;a href="https://backloggery.com"&gt;Backloggery&lt;/a&gt;. Tt has a lot of great features, but it didn't recognize all the platforms I used. Also registering new records and filling in their data required navigating to two different screens located in different places in the app. It didn't find it comfortable.&lt;/p&gt;
&lt;p&gt;I migrated to &lt;a href="https://gremlin.hu"&gt;Gremlin&lt;/a&gt; after that. I liked it too. It's pretty decent and tracks board games too. The staff is friendly and helpful. It's a community-built database and a social platform at the same time. You can see and like others' progress, reviews and such. But since Gremlin is not international, I've only found a few people with similar gaming tastes.&lt;/p&gt;
&lt;h2&gt;Creating an own backlog&lt;/h2&gt;
&lt;p&gt;These times are about taking back the ownership of your own data. It requires effort, but gives you higher control in return.&lt;/p&gt;
&lt;p&gt;I wanted a gaming backlog with some statistical capabilities similar to Backloggery's, but I wanted to edit my data faster. I also didn't want to store covers and screenshots, but I wanted something more than plain text.&lt;/p&gt;
&lt;p&gt;So, I decided to create my own database. It's a python plugin for my Pelican static site generator. I record my stuff into a CSV. It's a comma separated table, that can be edited with spreadsheet editors and text editors alike. This method allows me to maintain the data quickly. My plugin generate nice charts from it. Also, my favorite games have their on colored floppy disk icons, that recall some of their characteristic colors.&lt;/p&gt;
&lt;p&gt;There is also a rating system. Games start 3 hearts, they can lose and get additional ones. I may later extend the statistics with a tagging system.&lt;/p&gt;
&lt;p&gt;You can access it by following this link to the &lt;a href="/backlog"&gt;Gaming Backlog&lt;/a&gt; or using the Start menu-like menu in the top left corner to check it. I've just made it working.&lt;/p&gt;
&lt;p&gt;&lt;img alt="This is a screenshot of the blog with the Gaming Backlog page open. Colorful statistics and filter checkboxes are visible. In the lower part of the picture, some game data is visible. Each game has a colorful floppy disk icon in its own color." src="../images/2025-10-05-gaming-backlog.jpg"&gt;&lt;/p&gt;</content><category term="Blog"/><category term="Python"/><category term="Blogging"/><category term="Gaming"/></entry><entry><title>Clean patching</title><link href="https://blog.gridranger.dev/clean-patching" rel="alternate"/><published>2025-09-29T18:12:01+03:00</published><updated>2025-09-29T18:12:01+03:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-09-29:/clean-patching</id><summary type="html">&lt;h1&gt;Clean patching&lt;/h1&gt;
&lt;p&gt;When it comes to patching and mocking, Python's built-in libraries are amazing. But if you write a lot of tests you will start to hate patching expressions like this decorator:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;    &lt;span class="nd"&gt;@patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;myapp.mycode.imported_name&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;or this &lt;code&gt;with&lt;/code&gt; statement:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;myapp.mycode.imported_name&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;mock_imported_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;The problems&lt;/h2&gt;
&lt;p&gt;First …&lt;/p&gt;</summary><content type="html">&lt;h1&gt;Clean patching&lt;/h1&gt;
&lt;p&gt;When it comes to patching and mocking, Python's built-in libraries are amazing. But if you write a lot of tests you will start to hate patching expressions like this decorator:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;    &lt;span class="nd"&gt;@patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;myapp.mycode.imported_name&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;or this &lt;code&gt;with&lt;/code&gt; statement:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;myapp.mycode.imported_name&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;mock_imported_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;The problems&lt;/h2&gt;
&lt;p&gt;First of all, they require a lot of typing, and second, they are very fragile.&lt;/p&gt;
&lt;p&gt;Typing is prone to typos and copy-paste-errors. And if you refactor your code and move &lt;code&gt;mycode&lt;/code&gt; to another module, you will have to change all the patching expressions in your tests. Although powerful IDEs like PyCharm can help you with that to some extent, manually fixing the remaining patch statements is still a pain.&lt;/p&gt;
&lt;p&gt;Good news: you can avoid the whole stuff with clean coding and some Python magic. You can take the magic literally as we will use a so-called magic attribute. (an attribute with double underscores at the beginning and the end of their names, like &lt;code&gt;__doc__&lt;/code&gt; or &lt;code&gt;__name__&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;So, if you hate unnecessary typing and wasting time fixing your once well-written code at refactor time, read on.&lt;/p&gt;
&lt;h2&gt;The solution&lt;/h2&gt;
&lt;p&gt;You can tackle it from three directions. The first one is trivial. If you test a lot, then you are already using it: mock the method instead of patching it like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;test_object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Mock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Unlike patching, it won't reset the method to the original object later, but that shouldn't be a problem in most cases since you should reset your test object between tests with method-level setups anyway.&lt;/p&gt;
&lt;p&gt;Then there are the properties. We can't use value assignment on them.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Screenshot from an early Pokémon game. The trainer faces the text '@property'. The message box below says: 'Developer uses Mock. It's not very effective..." src="../images/2025-09-29-property-mocking.jpg"&gt;&lt;/p&gt;
&lt;p&gt;But &lt;code&gt;patch.object&lt;/code&gt; comes to the rescue. You can call it with the class the property belongs to. Since we're talking about unit tests, the class being tested is already imported to be used in the test setup. This will be the solution:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;    &lt;span class="nd"&gt;@patch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyClass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;property_to_mock&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_callable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;PropertyMock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;return_value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;mock_value&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;test_some_method_using_the_property&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mocked_property&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Mock&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Great! We're fine with methods and properties then. But how to deal with patching imported names? This approach works best for explicit imports, like &lt;code&gt;from json import loads&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;TestMyClass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;namespace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyClass&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="vm"&gt;__module__&lt;/span&gt;

    &lt;span class="nd"&gt;@patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;namespace&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.loads&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# imported as `from json import loads` in the module&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;test_some_method_where_json_loads_is_used&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mocked_loads&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Mock&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Beautiful, isn't it? The module name is used dynamically, and you can reuse it anywhere. No more novel-length patching expressions that break during refactoring!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Longer self-explanatory code examples you can try out:&lt;/p&gt;
&lt;h3&gt;src/myapp/mycode.py&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;json&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;loads&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;MyCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;MY_JSON&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;quot;&amp;quot;{&amp;quot;content&amp;quot;: &amp;quot;Hello, World!&amp;quot;}&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

    &lt;span class="nd"&gt;@property&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;my_property&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MY_JSON&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;content&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;my_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MY_JSON&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;content&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;my_other_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;:)&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;my_method&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;my_property&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;:(&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;tests/test_myapp/test_mycode.py&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;unittest.mock&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Mock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PropertyMock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;patch&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;myapp.mycode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MyCode&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;TestMyCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# define this so you don&amp;#39;t have hardcode anything when you patch:&lt;/span&gt;
    &lt;span class="n"&gt;namespace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyCode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="vm"&gt;__module__&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;setup_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;test_object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyCode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# Instead of this:&lt;/span&gt;
    &lt;span class="c1"&gt;# @patch(&amp;quot;myapp.mycode.loads&amp;quot;, return_value={&amp;quot;content&amp;quot;: &amp;quot;test text&amp;quot;})&lt;/span&gt;
    &lt;span class="c1"&gt;# use this:&lt;/span&gt;
    &lt;span class="nd"&gt;@patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;namespace&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.loads&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;return_value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;content&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;test text&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;test_my_property&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mocked_loads&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Mock&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Act&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;test_object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;my_property&lt;/span&gt;
        &lt;span class="c1"&gt;# Assert&lt;/span&gt;
        &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;test text&amp;quot;&lt;/span&gt;
        &lt;span class="n"&gt;mocked_loads&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;assert_called_once_with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;test_object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MY_JSON&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Instead of this:&lt;/span&gt;
    &lt;span class="c1"&gt;# @patch(f&amp;quot;myapp.mycode.MyCode.my_property&amp;quot;, new_callable=PropertyMock, return_value=&amp;quot;test text&amp;quot;)&lt;/span&gt;
    &lt;span class="c1"&gt;# use this:&lt;/span&gt;
    &lt;span class="nd"&gt;@patch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;my_property&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_callable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;PropertyMock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;return_value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;test text&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;test_my_other_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mocked_property&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Mock&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Arrange&lt;/span&gt;
        &lt;span class="c1"&gt;# If you reinstantiate the test instance between tests (you should) &lt;/span&gt;
        &lt;span class="c1"&gt;# than for method mocking, use Mock directly:&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;test_object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;my_method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Mock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;return_value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;test text&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;# Act&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;test_object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;my_other_method&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="c1"&gt;# Assert&lt;/span&gt;
        &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;:)&amp;quot;&lt;/span&gt;
        &lt;span class="n"&gt;mocked_property&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;assert_called_once&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;test_object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;my_method&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;assert_called_once&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;pyproject.toml&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;[tool.pytest.ini_options]&lt;/span&gt;
&lt;span class="n"&gt;addopts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;--cov&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;pythonpath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;src&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;testpaths&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;tests&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;[tool.coverage.run]&lt;/span&gt;
&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;src&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;[tool.ruff]&lt;/span&gt;
&lt;span class="n"&gt;exclude&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;.venv&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;lint&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ignore&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;E501&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;lint&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;E&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;F&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;W&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;C901&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;I&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;N&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;UP&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;YTT&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;ANN&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;SLF&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;RET&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;TC&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;PTH&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;preview&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;target-version&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;py313&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;requirements.txt&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pytest-cov==7.0.0
ruff==0.8.3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Development"/><category term="Clean code"/><category term="Python"/></entry><entry><title>Company culture</title><link href="https://blog.gridranger.dev/company-culture" rel="alternate"/><published>2025-09-09T19:22:00+03:00</published><updated>2025-11-13T16:24:00+02:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-09-09:/company-culture</id><summary type="html">&lt;h2&gt;2025-11-13 Breaking the code&lt;/h2&gt;
&lt;p&gt;After finishing &lt;em&gt;Stargate: SG-1&lt;/em&gt; and &lt;em&gt;Stargate: Atlantis&lt;/em&gt; for the first time, we started watching &lt;em&gt;Stargate: Universe&lt;/em&gt;. Funny enough, my own job at Nokia began almost exactly like Eli’s did: with a mysterious puzzle from an unknown source.&lt;/p&gt;
&lt;p&gt;I worked in the government sector back then …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;2025-11-13 Breaking the code&lt;/h2&gt;
&lt;p&gt;After finishing &lt;em&gt;Stargate: SG-1&lt;/em&gt; and &lt;em&gt;Stargate: Atlantis&lt;/em&gt; for the first time, we started watching &lt;em&gt;Stargate: Universe&lt;/em&gt;. Funny enough, my own job at Nokia began almost exactly like Eli’s did: with a mysterious puzzle from an unknown source.&lt;/p&gt;
&lt;p&gt;I worked in the government sector back then as an application administrator but I also took part in acceptance testing. One day, a teammate sent me a link to a page with programming puzzles.&lt;/p&gt;
&lt;p&gt;These were nowhere near as difficult as Eli's assignment. I wasn't the first or the only one to solve them. But after I finished, the site asked for my resume. I sent it in, not knowing who, or what, was on the other end.&lt;/p&gt;
&lt;p&gt;That was more than 11 years ago.&lt;/p&gt;
&lt;p&gt;I may not have ended up on a top-secret space mission. But since I'm writing this post from Finland, I can say that my life took a whole new direction thanks to those few puzzles.&lt;/p&gt;
&lt;h2&gt;2025-09-17 Rainy days&lt;/h2&gt;
&lt;p&gt;It has been raining almost continuously over the last couple of days. I forgot to take my umbrella to work last Friday. It was sunny in the morning and I didn't expect it to change. But it did. How awesome that there are umbrellas in the office that you can borrow in case of emergency!&lt;/p&gt;
&lt;p&gt;&lt;img alt="A plain blue folding umbrella lies closed on a darker blue blanket. The handle of the umbrella features the old Nokia logo. The same logo is also embroidered in white onto the blanket." src="../images/2025-09-17-umbrella.png"&gt;&lt;/p&gt;
&lt;h2&gt;2025-09-09 Well-being day&lt;/h2&gt;
&lt;p&gt;Once I might write a bit more about my work, but now I just wanted to share how cool shopping bag I got on today's wellbeing day. I like the stickers celebrating Bell Labs' historical achievements too! &lt;/p&gt;
&lt;p&gt;&lt;img alt="A stylish reusable shopping bag in Nokia blue color with white text saying &amp;quot;Nokia Bell Labs - 100 years innovating. There is also a sticker sheet depicting various things: building blocks with the letters UNIX, the Telstar 1 satellite, the Bell Labs HQ in Murray Hill, an astronaut, the first transistor, the Holmdel Horn Antenna that discovered the cosmic microwave radiation, and some logos." src="../images/2025-09-09-merch.png"&gt;&lt;/p&gt;</content><category term="Tech"/><category term="Nokia"/><category term="Post streams"/><category term="Stargate"/><category term="Work"/></entry><entry><title>KDE Neon</title><link href="https://blog.gridranger.dev/kde-neon" rel="alternate"/><published>2025-09-07T22:47:00+03:00</published><updated>2025-09-07T22:47:00+03:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-09-07:/kde-neon</id><summary type="html">&lt;p&gt;I replaced Linux Mint with KDE Neon. I'll update this post with my experiences.&lt;/p&gt;
&lt;h2&gt;🤝 KDE and me&lt;/h2&gt;
&lt;p&gt;This is not the first time I have tried KDE. I first did so about 15 years ago. Back then, I tried lots of things, including Windows Vista, Open Solaris and Ubuntu with …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I replaced Linux Mint with KDE Neon. I'll update this post with my experiences.&lt;/p&gt;
&lt;h2&gt;🤝 KDE and me&lt;/h2&gt;
&lt;p&gt;This is not the first time I have tried KDE. I first did so about 15 years ago. Back then, I tried lots of things, including Windows Vista, Open Solaris and Ubuntu with both Gnome 2 and Unity. I experimented with them, but I wasn't impressed, so I went on with Windows 7.&lt;/p&gt;
&lt;p&gt;The next time I came across KDE was when I launched my Steam Deck for the first time in 2023. At first, I didn't recognise it, and I was surprised at how much it had matured over the years.&lt;/p&gt;
&lt;p&gt;A couple of months later, when I started planning how to leave Microsoft, Google and the other tech giants behind since they started supporting Trump, my friends recommended KDE. I chose Linux Mint instead, but I also wanted to try the KDE Plasma shell. It didn't go well. Plasma didn't worked. While I was trying to fix it, I broke the Cinnamon too. 😅 I had to reinstall Mint to fix everything.&lt;/p&gt;
&lt;p&gt;Although I liked Linux Mint, I still wanted to try Plasma. A few months later, I decided to try it again, replacing Mint entirely with KDE Neon.&lt;/p&gt;
&lt;h2&gt;👓 KDE Neon - The first impressions&lt;/h2&gt;
&lt;p&gt;💿 &lt;strong&gt;Installation:&lt;/strong&gt; I had a rough start. I wanted to do a manual partition setup to preserve my &lt;code&gt;/home&lt;/code&gt; partition. The installer reported that KDE Neon needs a 300 MB &lt;code&gt;boot/efi&lt;/code&gt; partition. I checked, what else it needs, and I misinterpreted some old articles, and I created both a 100 MB &lt;code&gt;boot&lt;/code&gt; and an 300 MB &lt;code&gt;boot/efi&lt;/code&gt; partitions.&lt;/p&gt;
&lt;p&gt;Obviously, it didn't work. Finally, it took me seven attempts to install it. By that point, I had realised that I only needed a 500 MB &lt;code&gt;boot/efi&lt;/code&gt; partition, and that I had to reboot the live installer after each failed attempt; otherwise, the partitions couldn't be accessed for the new installation.&lt;/p&gt;
&lt;p&gt;But in the end, it booted up nicely. The only issue was that the audio devices reported an error. Only? Well...&lt;/p&gt;
&lt;p&gt;🚫 &lt;strong&gt;No KDE apps worked:&lt;/strong&gt; The next issue came, when I wanted to launch an app. Neither Dolphin (file manager), Kate (notepad) nor Konsole (terminal emulator) worked. Thankfully, I could use the CTRL+ALT+F3 shortcut to hide the desktop and access a command line, which helped me find out what was going on.&lt;/p&gt;
&lt;p&gt;The root cause was a library that had only been installed partially.  &lt;code&gt;sudo apt --reinstall libpulse0&lt;/code&gt; and a reboot fixed it.&lt;/p&gt;
&lt;p&gt;🪄 &lt;strong&gt;The magic of Linux:&lt;/strong&gt; Two hours after installation, everything that worked under Mint was up and running. Most things worked without any reinstallation. Since my home directory was preserved, everything just worked as if nothing had happened. I was more than satisfied. It was amazing.&lt;/p&gt;
&lt;h2&gt;📆 Next days&lt;/h2&gt;
&lt;p&gt;📋 &lt;strong&gt;Clipboard:&lt;/strong&gt; Windows now has an advanced multi-item clipboard with integrated emoji board. I use both frequently, so having something like them integrated is a good thing. While they are less streamlined than their Windows counterparts, they work well.&lt;/p&gt;
&lt;p&gt;💨 &lt;strong&gt;Steam:&lt;/strong&gt; I reinstalled Steam from a &lt;code&gt;.deb&lt;/code&gt; installer, but it didn't launch next time. It was the desktop file. It pointed to the wrong place. It took me some time to figure out, how to fix all wrong entries and then how to make the shell recognise the changes. (I tired the flatpack installation too, but it didn't solve the issue as the problem was with the desktop entry. I use the official deb now.)&lt;/p&gt;
&lt;p&gt;🔒 &lt;strong&gt;Lockscreen crash:&lt;/strong&gt; The desktop environment would crash every time it was left unattended for a while. Nothing but reboot solved it. It turned out to be an NVIDIA-specific issue. I managed to solve it following this &lt;a href="https://www.reddit.com/r/kde/comments/13e02dl/how_to_fix_the_sleepsuspend_issueglitch_with/"&gt;reddit post&lt;/a&gt; and this &lt;a href="https://wiki.archlinux.org/title/NVIDIA/Tips_and_tricks#Preserve_video_memory_after_suspend"&gt;Arch Linux article&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It's a bit disappointing that the first article is more than two years old, and it has not been fixed. I mean, enabling three services and adding a setting entry to a file sounds pretty trivial for the devs to fix, but can be impossible for non-technical people, especially that finding the articles took a lot of searching.&lt;/p&gt;
&lt;p&gt;🔄 &lt;strong&gt;Couldn't update the system:&lt;/strong&gt; The entire system update froze to the point that it wasn't even able to tell what's wrong. Using the console and learning how to use &lt;code&gt;pkcon&lt;/code&gt; uncovered the problem. A Linux firmware security update was unavailable at the source (501). &lt;a href="https://askubuntu.com/a/1555574"&gt;This article&lt;/a&gt; helped me to &lt;code&gt;wget&lt;/code&gt; and install it manually. Again: servers can be unavailable anytime. Why isn't this handled by the update manager?&lt;/p&gt;
&lt;p&gt;🌙 &lt;strong&gt;No automatic light/dark mode:&lt;/strong&gt; This will be added in the next minor update to KDE Plasma. Neither Windows nor Linux Mint had it built-in.&lt;/p&gt;
&lt;p&gt;🎮 &lt;strong&gt;Increased stability:&lt;/strong&gt; I appreciate that &lt;a href="space-colony"&gt;Space Colony&lt;/a&gt; (a retro Windows game) doesn't crash on task switching like it did under Mint.&lt;/p&gt;
&lt;h2&gt;✅ Summary&lt;/h2&gt;
&lt;p&gt;All in all, I'm happy with KDE Neon. I feel it still suffers the usual Linux desktop environment issue: there are critical stuff (apps not work, system update not work, VGA issue) that can't be fixed without technical knowledge.&lt;/p&gt;
&lt;p&gt;But hey, it's still great with a bit a learning, so give it a try! One day, it could become as straightforward to install and use as Windows for everyone.&lt;/p&gt;</content><category term="Tech"/><category term="Degoogling"/><category term="Linux"/><category term="Gaming"/><category term="Space Colony"/></entry><entry><title>Blaugust - Summary</title><link href="https://blog.gridranger.dev/blaugust-summary" rel="alternate"/><published>2025-08-31T10:43:00+03:00</published><updated>2025-08-31T10:43:00+03:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-08-31:/blaugust-summary</id><summary type="html">&lt;p&gt;Blaugust ends today, so I think it's time to summarize. I really enjoyed it!&lt;/p&gt;
&lt;p&gt;First, it reopened the blogosphere for me. I used to follow many blogs before the advent of Facebook. Most of those were abandoned by their authors, who moved to social media. Now, through Mastodon, I've found …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Blaugust ends today, so I think it's time to summarize. I really enjoyed it!&lt;/p&gt;
&lt;p&gt;First, it reopened the blogosphere for me. I used to follow many blogs before the advent of Facebook. Most of those were abandoned by their authors, who moved to social media. Now, through Mastodon, I've found a plethora of meaningful and interesting blogs. I'm also glad that many of them are static, like mine.&lt;/p&gt;
&lt;p&gt;Secondly, it inspired me to blog more frequently. I started this blog in March, and I wrote more than half of the posts in August. It was great reading about certain topics on other blogs and reflecting on them on my own. It gave me a sense of belonging.&lt;/p&gt;
&lt;p&gt;Thirdly, I received feedback from new readers who found my blog, and I'm grateful for it. 😊&lt;/p&gt;
&lt;p&gt;I'm well aware of my aversion to deadlines and repetition, so I didn't expect to receive the Rainbow Diamond or Gold Awards. I wrote 14 posts in August and just missed the Silver Award, landing in the &lt;strong&gt;Bronze&lt;/strong&gt; tier instead.🥉 🎉 As a first-time baluguster, I'm also happy about the &lt;strong&gt;Newbie Blogger Award&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;But besides of posting, Balugust also made me want to implement long-planned new features to my blog like the &lt;a href="tags"&gt;Tags&lt;/a&gt; window, or the pinned icons (&lt;a href="pages/my-computer"&gt;My Computer&lt;/a&gt; &amp;amp; &lt;a href="pages/network-neighborhood"&gt;Network neighborhood&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Overall, I enjoyed the event and plan to continue following the new blogs I discovered. I also feel encouraged to post more frequently than I did before August.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;The Blaugust logo is from the &lt;a href="https://aggronaut.com/blaugust-media-kit/"&gt;Blaugust Media Kit&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;The original version of this post is part of the Blaugust 2025 series on my blog along with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="about-gridranger"&gt;About Gridranger&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="space-colony"&gt;Space Colony&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="friendships-in-my-life"&gt;Friendships in my life&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="jousting-in-video-games"&gt;Jousting in video games&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/helsinki-biennial"&gt;Helsinki Biennial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/data-encryption"&gt;Data &amp;amp; Encryption&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/intro-through-traits"&gt;Intro through traits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/hospital-visit"&gt;Hospital visit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/win-31-nostalgia"&gt;Win 3.1 Nostalgia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/poets-of-the-fall"&gt;Poets of the Fall&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/project-done"&gt;Project done!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/video-games-that-made-me-learn"&gt;Video games that made me learn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/blaugust-introduction"&gt;Blaugust&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Blog"/><category term="Blaugust2025"/><category term="Blogging"/></entry><entry><title>About Gridranger</title><link href="https://blog.gridranger.dev/about-gridranger" rel="alternate"/><published>2025-08-24T11:46:59+03:00</published><updated>2025-08-24T16:42:40+03:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-08-24:/about-gridranger</id><summary type="html">&lt;p&gt;Usernames are something we choose for ourselves. We use them to express ourselves, and sometimes we hide behind them. Some of them are connected to our real name, like a nickname. Others have no connection to us.&lt;/p&gt;
&lt;p&gt;This is the story behind mine.&lt;/p&gt;
&lt;p&gt;The first username I used for a …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Usernames are something we choose for ourselves. We use them to express ourselves, and sometimes we hide behind them. Some of them are connected to our real name, like a nickname. Others have no connection to us.&lt;/p&gt;
&lt;p&gt;This is the story behind mine.&lt;/p&gt;
&lt;p&gt;The first username I used for a long time was given to me by my best friend from high school. I used it for more than ten years. It wasn't as hard back then to clear your data from the internet as it is now.  I had a list what to remove to leave no trace in search engines. It took me years to choose a new username, and that was &lt;em&gt;Gridranger&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The word 'grid' has many different meanings for me.&lt;/p&gt;
&lt;h3&gt;The Neon Grid from the 80s&lt;/h3&gt;
&lt;p&gt;The game grid from the 1982 movie Tron is a place where anthropomorphized programs play for survival. This movie was the first feature film built upon using lots of CGI.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Three blue lightcycles speed through a black plane covered with a white grid. Lightcycles are closed-cockpit motorcycles that can create solid walls of light in their trace." src="../images/2025-08-24-game-grid.png"&gt;&lt;/p&gt;
&lt;p&gt;The way it depicted the grid influenced many creative minds. From music videos to toy box decorations, the neon grid became an iconic design element of the 80s.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Box artwork of a Lego set from 1990. It features a small red spacecraft with light neon green accessories." src="../images/2025-08-24-m-tron.png"&gt;&lt;/p&gt;
&lt;p&gt;I loved Lego M-trons by the way. Some of their sets had small, strong magnets inside, hence for the letter M in their name.&lt;/p&gt;
&lt;p&gt;Synthwave album covers still use neon grids to capture the spirit of that decade.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Screenshot of Synthwave album covers from Spotify. 4 out of 6 feature a neon grid." src="../images/2025-08-24-synthwave.png"&gt;&lt;/p&gt;
&lt;h3&gt;Grid computing&lt;/h3&gt;
&lt;p&gt;Before 'cloud computing' became the trendy buzzword, 'grid computing' was already way to distribute resources among loosely connected computers in a network. Database administration was part of my work when migration started at my workplace from Oracle 11g (grid) to Oracle 12c (cloud).&lt;/p&gt;
&lt;h3&gt;Volunteer research&lt;/h3&gt;
&lt;p&gt;For years, I (or rather, my home computers) participated in many &lt;a href="https://en.wikipedia.org/wiki/Berkeley_Open_Infrastructure_for_Network_Computing"&gt;BOINC&lt;/a&gt; projects. BOINC is a volunteer research framework based on grid computing. Have you heard of &lt;a href="https://en.wikipedia.org/wiki/SETI@home"&gt;SETI@home&lt;/a&gt;, for example? That was the forerunner of the BOINC projects. I registered and started using the SETI computational screensaver in the early 2000s. But that was only the beginning. There was a bunch of other projects I took part in.&lt;/p&gt;
&lt;p&gt;I run a lot of different projects, from medical ones (COVID, Zika, cancer, and AIDS research) to astronomical ones (neutron stars and SETI), as well as some math ones. Besides my home PC, I have collected old Android phones and created a small home cluster with them. I experimented to find the optimal workload for their CPUs. Then, for just a few cents of electricity per day, they did the work.&lt;/p&gt;
&lt;p&gt;My overclocked Raspberry Pi also did its fair share. I used a &lt;a href="https://flirc.tv/collections/case"&gt;full aluminum&lt;/a&gt; case for passive cooling and took advantage of the waste heat to keep my balcony above the dew point in the winter, thus avoiding mold growth.&lt;/p&gt;
&lt;p&gt;Although I haven't run any projects in the past couple of years, I'm still in the top 0.33% of BOINC users.&lt;/p&gt;
&lt;p&gt;&lt;img alt="This is a certificate dated March 21, 2020, from SETI@Home regarding the work I have done since starting to use my new username. The certificate features an aerial view of the Arecibo Observatory." src="../images/2025-08-24-seti.png"&gt;&lt;/p&gt;
&lt;p&gt;I was devastated when the Arecibo Observatory was damaged beyond repair. Not only was it the source of data for the SETI@home project, it was also a symbol of humanism to me, reminding me of Carl Sagan. I'm a member of the BOINC team named after him.&lt;/p&gt;
&lt;h3&gt;The 'ranger' part&lt;/h3&gt;
&lt;p&gt;I loved the Space Ranger series by Isaac Asimov. One of his earliest works. Yes, he wrote much better novels than those, but they are still great. To me, they symbolize that positive values will prevail, even in the harshest circumstances.&lt;/p&gt;
&lt;p&gt;I hope that one day, good will dominate greed, selfishness, and ignorance in cyberspace.&lt;/p&gt;
&lt;h3&gt;The icon&lt;/h3&gt;
&lt;p&gt;The icon, avatar, or profile picture that I use hasn't changed much since I drew it. It's a 5.25-inch floppy disk with a transparent side that reveals an identity disc inside, in the style of the original 1982 Tron movie, instead of a magnetic disk. A couple of months later, I corrected the color of the logo. This week, after seven years, I updated it again to replace the text on the label with my own handwriting.&lt;/p&gt;
&lt;p&gt;&lt;img alt="This is a 5.25-inch floppy disk that hides a 1982 Tron-style identity disk inside. There is a disk label on the top right. There are three variations of this logo. The second and third variations have corrected colors for the identity disc. The first two have the word &amp;quot;Gridranger&amp;quot; written in a typeface that imitates handwriting. The last logo has the same text written in my actual handwriting." src="../images/2025-08-24-logos.png"&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;The original version of this post is part of the Blaugust 2025 series on my blog along with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="space-colony"&gt;Space Colony&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="friendships-in-my-life"&gt;Friendships in my life&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="jousting-in-video-games"&gt;Jousting in video games&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/helsinki-biennial"&gt;Helsinki Biennial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/data-encryption"&gt;Data &amp;amp; Encryption&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/intro-through-traits"&gt;Intro through traits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/hospital-visit"&gt;Hospital visit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/win-31-nostalgia"&gt;Win 3.1 Nostalgia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/poets-of-the-fall"&gt;Poets of the Fall&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/project-done"&gt;Project done!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/video-games-that-made-me-learn"&gt;Video games that made me learn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/blaugust-introduction"&gt;Blaugust&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Personal"/><category term="Blaugust2025"/><category term="Blogging"/><category term="Writing"/><category term="Lego"/><category term="BOINC"/><category term="Raspberry PI"/><category term="Reading"/></entry><entry><title>Space Colony</title><link href="https://blog.gridranger.dev/space-colony" rel="alternate"/><published>2025-08-19T23:21:10+03:00</published><updated>2025-08-19T23:21:10+03:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-08-19:/space-colony</id><summary type="html">&lt;h3&gt;Shortly about the game&lt;/h3&gt;
&lt;p&gt;I haven't played this game in a long time. I first tried in 2004, perhaps as a demo version from a gaming magazine disc. Later, I bought a second-hand physical copy. I was thrilled, when the HD edition was released on Steam.&lt;/p&gt;
&lt;p&gt;It's like a space …&lt;/p&gt;</summary><content type="html">&lt;h3&gt;Shortly about the game&lt;/h3&gt;
&lt;p&gt;I haven't played this game in a long time. I first tried in 2004, perhaps as a demo version from a gaming magazine disc. Later, I bought a second-hand physical copy. I was thrilled, when the HD edition was released on Steam.&lt;/p&gt;
&lt;p&gt;It's like a space Sims that was never released. Exploration, mining, task management, humorous animations, cool aliens and androids. The voice-over is funny, and I like how the diverse crew becomes a big, efficient team. You start to like each one of the crew members.&lt;/p&gt;
&lt;p&gt;I don't mind that it's not in true 3D, or that the characters are pre-generated. Overall, I think the game has a nice concept and a great atmosphere. With ambient music and the slow, steady breathing sounds of the oxygen generator, this game gave its players a meditative ASMR experience even before it was cool.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Biodomes of a planetary base with their roof being transparent. You can see two smaller biodomes acting as sleeping quarters. Each bed has different bedspreads mirroring their owner's taste. Next to them there are other biodomes with sports and medical facilities. There is also bigger recreational biodome with bar, restaurant hot tub and sauna." src="../images/2025-08-19-sc.png"&gt;&lt;/p&gt;
&lt;h3&gt;Taking a fresh look&lt;/h3&gt;
&lt;p&gt;It simply ignites my imagination. Just picture yourself having sauna or chilling in a hot tub, looking up at the galaxy above through the thin glass ceiling of a biodome. Just a wall away, there is a harsh wilderness. As I write this, I feel it sounds a bit like unwinding in a mökki (a Finnish holiday home) in the middle of a forest.&lt;/p&gt;
&lt;p&gt;My imagination complements the graphics like it did with games of the 80's. I usually play on easy mode without speed-up to let myself think and enjoy the mood.&lt;/p&gt;
&lt;p&gt;As an adult, I'm less interested in choosing my favorite character and finding the perfect match for them. I more interested how the different characters may feel in the situation.&lt;/p&gt;
&lt;p&gt;And I was shocked by the cruelty of the space chicken farmer unit. The sound of that machine is anything but funny. I didn't notice it earlier, but it is something that makes you think about the meat industry. Perhaps shocking the players with it will have an impact.&lt;/p&gt;
&lt;p&gt;&lt;img alt="A planetary base from above with roof off. On the left, there is an astronaut boarding off a shuttle. On the right, inside the base, lots of different people tending their jobs: a farmer boy, an urban girl, a geeky Russian scientist, a girl dressed in full pink, a muscular bald Norwegian man dressed after his love of metal music." src="../images/2025-08-19-sc2.png"&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;The original version of this post is part of the Blaugust 2025 series on my blog along with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="friendships-in-my-life"&gt;Friendships in my life&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="jousting-in-video-games"&gt;Jousting in video games&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/helsinki-biennial"&gt;Helsinki Biennial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/data-encryption"&gt;Data &amp;amp; Encryption&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/intro-through-traits"&gt;Intro through traits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/hospital-visit"&gt;Hospital visit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/win-31-nostalgia"&gt;Win 3.1 Nostalgia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/poets-of-the-fall"&gt;Poets of the Fall&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/project-done"&gt;Project done!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/video-games-that-made-me-learn"&gt;Video games that made me learn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/blaugust-introduction"&gt;Blaugust&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Games"/><category term="Blaugust2025"/><category term="Sims"/><category term="Space Colony"/></entry><entry><title>Friendships in my life</title><link href="https://blog.gridranger.dev/friendships-in-my-life" rel="alternate"/><published>2025-08-16T09:46:40+03:00</published><updated>2025-08-16T09:46:40+03:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-08-16:/friendships-in-my-life</id><summary type="html">&lt;p&gt;This &lt;a href="https://notes.jeddacp.com/on-making-friends-as-an-adult/"&gt;note by Jedda&lt;/a&gt; (and later &lt;a href="https://gobino.be/the-double-edged-sword-of-social-happiness/"&gt;gobino's post&lt;/a&gt;) made me want to share my experiences with friendships, but it took a while, because I was always &lt;a href="/intro-through-traits"&gt;shy&lt;/a&gt; to write about my feelings.&lt;/p&gt;
&lt;p&gt;I was a cheerful, extroverted kid who made friends easily. But before I turned eight, my school was …&lt;/p&gt;</summary><content type="html">&lt;p&gt;This &lt;a href="https://notes.jeddacp.com/on-making-friends-as-an-adult/"&gt;note by Jedda&lt;/a&gt; (and later &lt;a href="https://gobino.be/the-double-edged-sword-of-social-happiness/"&gt;gobino's post&lt;/a&gt;) made me want to share my experiences with friendships, but it took a while, because I was always &lt;a href="/intro-through-traits"&gt;shy&lt;/a&gt; to write about my feelings.&lt;/p&gt;
&lt;p&gt;I was a cheerful, extroverted kid who made friends easily. But before I turned eight, my school was taken over by a church. It was never about spiritual life, but rather petty power and politics. The best teachers resigned instantly, and most of the parents took their kids to other schools. I was one of them.&lt;/p&gt;
&lt;p&gt;I didn't lose all my friends. My best friend and I continued in the same class. But I lost at least six or eight friends whom I considered close. I was never able to feel a sense of belonging again. I felt like a worthless outsider in my new class, and felt the same way later in high school. I also lost the ability to form and nurture new friendships. Of course, I had a great friend in high school too, and I still treasure his friendship, even though we live half a world apart. The problem wasn't with the others. It was my poor self-esteem that isolated me.&lt;/p&gt;
&lt;p&gt;During my university years, I hardly felt a sense of community around me. I was solely focused on getting my master's degree as quickly as possible. In hindsight, I see that I missed out on some valuable friendships, but at the time, I was blind to that.&lt;/p&gt;
&lt;p&gt;Starting my career gave me back some of my long-lost sense of self-worth. It meant a lot, and, after a long time, I was making friends again. It didn't last long, unfortunately. I got together with my later first wife, who had strong opinions about whom I could keep in contact with. After the divorce, it took me some time for me to recover. Instead of being shy and restricting myself to small-talk, I became my original chatty, easygoing self again.&lt;/p&gt;
&lt;p&gt;I also reflected a lot on my earlier life. I even went to therapy. I realized, that my level of satisfaction always correlated with one single thing: the quality of my friendships. On the other hand, I experienced the situation that Jedda wrote about. My cousin and I  talked a lot about it.&lt;/p&gt;
&lt;p&gt;Finding people sharing the same interests, values or hobbies wasn't easy. Fortunately, I worked for a large company, so gaming and board gaming and our passion for our work created some common ground with others.&lt;/p&gt;
&lt;p&gt;Things were going well, until my girlfriend (now wife) and I decided to move abroad. It hasn't been easy to keep in touch with friends back home, especially since we're dealing with different problems in our lives.&lt;/p&gt;
&lt;p&gt;Though I have made some new acquaintances since moving, but I still feel isolated. Not only because of the new place but also because of my beloved furry friend, my poodle, is getting older. He never had any separation anxiety when he was young, but now, he can't be left alone. I have a lot to thank him for, and I hope he stays with me for a long time. His friendship is also great gift of life.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;The original version of this post is part of the Blaugust 2025 series on my blog along with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="jousting-in-video-games"&gt;Jousting in video games&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/helsinki-biennial"&gt;Helsinki Biennial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/data-encryption"&gt;Data &amp;amp; Encryption&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/intro-through-traits"&gt;Intro through traits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/hospital-visit"&gt;Hospital visit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/win-31-nostalgia"&gt;Win 3.1 Nostalgia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/poets-of-the-fall"&gt;Poets of the Fall&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/project-done"&gt;Project done!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/video-games-that-made-me-learn"&gt;Video games that made me learn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/blaugust-introduction"&gt;Blaugust&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Personal"/><category term="Blaugust2025"/><category term="Me"/><category term="Poodle"/></entry><entry><title>Jousting in video games</title><link href="https://blog.gridranger.dev/jousting-in-video-games" rel="alternate"/><published>2025-08-14T20:20:20+03:00</published><updated>2025-08-14T20:20:20+03:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-08-14:/jousting-in-video-games</id><summary type="html">&lt;p&gt;Many games allow gamers to play as knights in shining armor, but only a few let you become more than a simple warrior by allowing you to actually mount a horse and grab a lance. Yet doing this really stirred my imagination, perhaps because of the stories I heard about …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Many games allow gamers to play as knights in shining armor, but only a few let you become more than a simple warrior by allowing you to actually mount a horse and grab a lance. Yet doing this really stirred my imagination, perhaps because of the stories I heard about my ancestors as a child.&lt;/p&gt;
&lt;p&gt;The first game I played that featured jousting was Lego Island 2. In it, the player had to defeat an enemy knight at a jousting tournament. That was one of the best parts of the game for me. The game's visuals were outdated even at the time of its release, so they look extremely odd now [2015].&lt;/p&gt;
&lt;p&gt;&lt;img alt="Two Lego knights are rushing towards each others on horseback with lances in their hands. There are small tents with spectators behind them. In the background there are Lego trees and a silhouette of a castle. The whole image is really low-poly and blurry." src="../images/2025-08-14-lego-island-jousting.png"&gt;&lt;/p&gt;
&lt;p&gt;The next game that gave me the experience of mounted lance combat was Mount &amp;amp; Blade and its expansion, Warband. Though their graphics also looked outdated compared to other games of their time, these games featured large-scale battles between medieval armies in which the players could participate. Unlike in Lego Island, where jousting was only a minor part of the game, Mount &amp;amp; Blade was built to simulate mounted combat and featured detailed lance control options. The following video shows two different ways to use the lance.&lt;/p&gt;
&lt;p&gt;The underarm thrust is weaker, but needs less balancing and can be used at low speeds. The couched lance charge is what we all know well from jousting tournaments in movies.&lt;/p&gt;
&lt;div style="position: relative; padding-top: 56.25%;"&gt;&lt;iframe title="Warband - Mounted combat" width="100%" height="100%" src="https://video.hardlimit.com/videos/embed/dtzmatz4jjpTr5LJHtxaL9" frameborder="0" allowfullscreen="" sandbox="allow-same-origin allow-scripts allow-popups allow-forms" style="position: absolute; inset: 0px;"&gt;&lt;/iframe&gt;&lt;/div&gt;

&lt;p&gt;The third game I would like to write about is Last Knight, a casual game. It is a running game for smart devices, in which the protagonist constantly moves forward with a more or less constant speed and the player only has to evade obstacles and defeat enemies along the way.&lt;/p&gt;
&lt;p&gt;I'm not fond of this genre because I see only two situations that would interest me with this mechanic. One is when someone is running away from an unstoppable force, like when Indiana Jones is running from the big rock. The other is when you're riding a horse and you need a constant speed so use your lance. Last Knight is exactly that.&lt;/p&gt;
&lt;p&gt;It looks like a humorous fairy tale, and you can ride and lance as much as you want. Unfortunately, this game annoys you with bugs like randomly switching camera angles and frame rate drops. But it's so fun that you always want to play just one more round.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Here was a trailer of Last Knight embedded from YouTube here.&lt;/em&gt; &lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Trivia:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;The original version of this post was published on one of my old blogs on 2015-03-28. I used the &lt;a href="/project-done"&gt;Blogger Takeout Viewer&lt;/a&gt; to make the text reusable.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;If you watch the video closely you can see a coat of arms painted on the shields and displayed over the head of the players' soldiers. That crest was given to one of my ancestors in the 14th century. See &lt;a href="/family-history"&gt;Family history&lt;/a&gt;.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;The original version of this post is part of the Blaugust 2025 series on my blog along with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/helsinki-biennial"&gt;Helsinki Biennial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/data-encryption"&gt;Data &amp;amp; Encryption&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/intro-through-traits"&gt;Intro through traits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/hospital-visit"&gt;Hospital visit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/win-31-nostalgia"&gt;Win 3.1 Nostalgia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/poets-of-the-fall"&gt;Poets of the Fall&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/project-done"&gt;Project done!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/video-games-that-made-me-learn"&gt;Video games that made me learn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/blaugust-introduction"&gt;Blaugust&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Games"/><category term="Blaugust2025"/><category term="Gaming"/><category term="Mount &amp; Blade"/><category term="Lego"/><category term="Revived post"/><category term="Family history"/></entry><entry><title>Helsinki Biennial</title><link href="https://blog.gridranger.dev/helsinki-biennial" rel="alternate"/><published>2025-08-13T20:28:40+03:00</published><updated>2025-08-13T20:28:40+03:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-08-13:/helsinki-biennial</id><summary type="html">&lt;p&gt;My wife and I spent the last two Saturdays on Vallisaari to visit the &lt;a href="https://helsinkibiennaali.fi/en/"&gt;Helsinki Biennial&lt;/a&gt;. It was amazing! I've never seen an exhibition before that blended with nature so organically before.&lt;/p&gt;
&lt;p&gt;It clearly shows that human ingenuity can coexist with and complement nature. Many of the exhibited objects were …&lt;/p&gt;</summary><content type="html">&lt;p&gt;My wife and I spent the last two Saturdays on Vallisaari to visit the &lt;a href="https://helsinkibiennaali.fi/en/"&gt;Helsinki Biennial&lt;/a&gt;. It was amazing! I've never seen an exhibition before that blended with nature so organically before.&lt;/p&gt;
&lt;p&gt;It clearly shows that human ingenuity can coexist with and complement nature. Many of the exhibited objects were inspiring and touching. Viewing them filled me with harmony. It all felt like a step toward a healthier future.&lt;/p&gt;
&lt;p&gt;And it was so great that we could bring our dogs with us to enjoy the long hike. Because, yes, you had to walk a while to get from one object to the next. I really appreciated it, as it gave us time to think and to discuss what we saw instead of overwhelming us.&lt;/p&gt;
&lt;p&gt;My personal favorites were the &lt;a href="https://helsinkibiennaali.fi/en/artist/hans-rosenstrom/"&gt;singing tree trunks&lt;/a&gt; and the &lt;a href="https://helsinkibiennaali.fi/taiteilija/juan-zamora/"&gt;bioluminescent garden&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Bioluminescent tree branches under black light in an otherwise dark room. Futuristic, romantic and natural at the same time." src="../images/2025-08-13-bioluminescence.png"&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;The original version of this post is part of the Blaugust 2025 series on my blog along with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/data-encryption"&gt;Data &amp;amp; Encryption&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/intro-through-traits"&gt;Intro through traits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/hospital-visit"&gt;Hospital visit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/win-31-nostalgia"&gt;Win 3.1 Nostalgia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/poets-of-the-fall"&gt;Poets of the Fall&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/project-done"&gt;Project done!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/video-games-that-made-me-learn"&gt;Video games that made me learn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/blaugust-introduction"&gt;Blaugust&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Culture"/><category term="Blaugust2025"/><category term="Adventure"/></entry><entry><title>Data &amp; Encryption</title><link href="https://blog.gridranger.dev/data-encryption" rel="alternate"/><published>2025-08-12T22:05:39+03:00</published><updated>2026-01-14T01:19:00+02:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-08-12:/data-encryption</id><summary type="html">&lt;p&gt;&lt;strong&gt;TLDR:&lt;/strong&gt; &lt;a href="https://forkingmad.blog/obsessed-with-encryption/"&gt;David's post about encryption&lt;/a&gt; made me think, and my opinion is that encryption has missed the mark lately.&lt;/p&gt;
&lt;h3&gt;Your data only makes money when it's used against others or directly against you&lt;/h3&gt;
&lt;p&gt;Meta, Alphabet, Microsoft, Apple, Amazon, and the hundreds of other vendors listed as ones with &lt;em&gt;legitimate interest …&lt;/em&gt;&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;TLDR:&lt;/strong&gt; &lt;a href="https://forkingmad.blog/obsessed-with-encryption/"&gt;David's post about encryption&lt;/a&gt; made me think, and my opinion is that encryption has missed the mark lately.&lt;/p&gt;
&lt;h3&gt;Your data only makes money when it's used against others or directly against you&lt;/h3&gt;
&lt;p&gt;Meta, Alphabet, Microsoft, Apple, Amazon, and the hundreds of other vendors listed as ones with &lt;em&gt;legitimate interest&lt;/em&gt; in the cookie settings list want to learn as much as they can about you. To oversimplify it, they can monetize this info by convincing you to spend your money as they suggest and even to embrace political ideas that serve autocrats. Both of them are against your interests.&lt;/p&gt;
&lt;p&gt;You might say that you can't be indoctrinated, but the truth is that even the smartest, most critical thinker can be manipulated by controlling the information they can access. Even the life of those who don't use the internet can be affected.&lt;/p&gt;
&lt;p&gt;As we have seen in the last couple of years, these data brokers sell other people's life and freedom, including those of the people of their own country, without hesitation.&lt;/p&gt;
&lt;h3&gt;End-to-end encryption means little to law-abiding citizens, yet it still makes data brokers richer&lt;/h3&gt;
&lt;p&gt;Shall we encrypt everything then, to keep the greedy data miners and the corrupt governments away? -- Not so fast.&lt;/p&gt;
&lt;p&gt;Companies that guarantee end-to-end encryption can still wiretap your entire communication as they please unless the client- and the server-side codes are open source. Even then, they should provide evidence that they run the unmodified code on their servers. Without this, end-to-end encryption is an empty promise. Just remember how Meta's messenger collected messages before encrypting them to be sent, or Google's trick to read all what you type through your keyboard app.&lt;/p&gt;
&lt;p&gt;Of course, E2E encryption still helps people hide from law enforcement cheaply, and usually it's not a good thing.&lt;/p&gt;
&lt;h3&gt;What I see as a solution: regulation.&lt;/h3&gt;
&lt;p&gt;Big data can be used as a weapon. It can cause genocide and can flip democracies into autocracies. It is not only cleaner than an atomic bomb, but it also doesn't trigger a military response. Should anyone be allowed to own such dangerous technology and do as they please? I don't think so.&lt;/p&gt;
&lt;h3&gt;My wishlist&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Data collection should be limited. (No power to any actor to arm itself.)&lt;/li&gt;
&lt;li&gt;Storing data should also be limited. (No stockpiling weapons for a coup.)&lt;/li&gt;
&lt;li&gt;Brokering data should not be done without safeguards. (Arms may be traded, but let's not arm autocrats against ourselves.)&lt;/li&gt;
&lt;li&gt;Encrypted message providers should be strongly community-audited. (No secret data collection.)&lt;/li&gt;
&lt;li&gt;They should also provide law enforcement with a limited and hard-to-access and controlled way to listen in if they are entitled by a court order. (Encrypt if you insist, but criminals should not enjoy safety.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This way you won't need to encrypt your birthday wishes to friends or your shopping list to your partner end-to-end. You also don't help autocrats or organized crime.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;The original version of this post is part of the Blaugust 2025 series on my blog along with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/intro-through-traits"&gt;Intro through traits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/hospital-visit"&gt;Hospital visit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/win-31-nostalgia"&gt;Win 3.1 Nostalgia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/poets-of-the-fall"&gt;Poets of the Fall&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/project-done"&gt;Project done!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/video-games-that-made-me-learn"&gt;Video games that made me learn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/blaugust-introduction"&gt;Blaugust&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Tech"/><category term="Blaugust2025"/><category term="Security"/></entry><entry><title>Intro through traits</title><link href="https://blog.gridranger.dev/intro-through-traits" rel="alternate"/><published>2025-08-10T13:18:12+03:00</published><updated>2025-11-01T20:47:35+02:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-08-10:/intro-through-traits</id><summary type="html">&lt;h2&gt;The game&lt;/h2&gt;
&lt;p&gt;My wife and I enjoy playing some psychological games from time to time. They help us stay in sync by creating a safe space where we can openly and playfully discuss  anything including our feelings or each other's strengths and weaknesses.&lt;/p&gt;
&lt;p&gt;A couple of days ago, I mentioned …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;The game&lt;/h2&gt;
&lt;p&gt;My wife and I enjoy playing some psychological games from time to time. They help us stay in sync by creating a safe space where we can openly and playfully discuss  anything including our feelings or each other's strengths and weaknesses.&lt;/p&gt;
&lt;p&gt;A couple of days ago, I mentioned The Sims 3 in a &lt;a href="/video-games-that-made-me-learn"&gt;post&lt;/a&gt;. This gave me the idea to use Sims to help me structure the introduction I wanted to write for Blaugust's &lt;a href="https://nerdgirlthoughts.game.blog/2025/07/25/blaugust-2025-calendar-weekly-prompts/"&gt;introduce yourself week&lt;/a&gt;. To make it more interesting, we turned it into a game.&lt;/p&gt;
&lt;p&gt;We went through all the traits in The Sims 3 and selected those that best describe us. Then, we ranked them to find the five most fitting positive and the three most fitting negative traits for each of us.&lt;/p&gt;
&lt;p&gt;It was pretty funny! We laughed a lot while answering for questions like "Am I more of a &lt;em&gt;snob&lt;/em&gt; or &lt;em&gt;shy&lt;/em&gt;?" and "Is being a &lt;em&gt;lone wolf&lt;/em&gt; or a &lt;em&gt;night owl&lt;/em&gt; a positive or a negative trait?" Both of us marked the other as a &lt;em&gt;great kisser&lt;/em&gt;. But can being a great kisser be a core part of anyone's personality?&lt;/p&gt;
&lt;h2&gt;The selected traits&lt;/h2&gt;
&lt;p&gt;&lt;img alt="There are icons in two lines. The first line has five of them: a computer mouse, two shaking hands, a man looking through a magnifying glass, a laughing mask, a bowing silhouette. The second line has three icons: a somewhat crazy mask that is crying and smiling at the same time, a figure of woman touching her forehead theatrically, and a blushing head that trying to hide behind its own hair." src="../images/2025-08-09-traits.png"&gt;&lt;/p&gt;
&lt;p&gt;The positive ones are: &lt;em&gt;computer whiz&lt;/em&gt;, &lt;em&gt;friendly&lt;/em&gt;, &lt;em&gt;perceptive&lt;/em&gt;, &lt;em&gt;good sense of humor&lt;/em&gt;, &lt;em&gt;proper&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The negative ones are: &lt;em&gt;neurotic&lt;/em&gt;, &lt;em&gt;dramatic&lt;/em&gt;, &lt;em&gt;shy&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;Positive ones&lt;/h3&gt;
&lt;h4&gt;Computer whiz&lt;/h4&gt;
&lt;p&gt;For me, using computers is more than just work, it is a passion. I love learning, creating things and doing it on a sustainable way.&lt;/p&gt;
&lt;h4&gt;Friendly&lt;/h4&gt;
&lt;p&gt;I open up easily once I feel safe (as I also shy). I also do my best not to intentionally hurt others, although this is also a flaw that renders me defenseless against abusive people. &lt;/p&gt;
&lt;h4&gt;Perceptive&lt;/h4&gt;
&lt;p&gt;Recognizing patterns helped me a lot when I was trying to figure out English video games in the early '90s without understanding the language. It also speeds up how quickly I learn at work.&lt;/p&gt;
&lt;p&gt;The dark side of this coin that it sometimes isolates me from others.&lt;/p&gt;
&lt;h4&gt;Good sense of humour&lt;/h4&gt;
&lt;p&gt;I usually try to see the funny side of things, and also use humour as a shield. The more tired I am, the more and crazier my puns become.&lt;/p&gt;
&lt;h4&gt;Proper&lt;/h4&gt;
&lt;p&gt;I simply respect others and their boundaries.&lt;/p&gt;
&lt;h3&gt;Negative ones&lt;/h3&gt;
&lt;h4&gt;Neurotic&lt;/h4&gt;
&lt;p&gt;I'm confident when my mistakes only affect me, but I get stressed trying to deliver the optimal outcomes for others. This makes me seem strange because I don't stress in situations where others usually do. At the same time, I worry a lot about trivial things.&lt;/p&gt;
&lt;h4&gt;Dramatic&lt;/h4&gt;
&lt;p&gt;I'm inexperienced with quarrels and arguments, so I try to discuss and resolve issues before they escalate. However, there are  situations when I can react with despair and express how miserable I feel.&lt;/p&gt;
&lt;h4&gt;Shy&lt;/h4&gt;
&lt;p&gt;I would rather use my map than ask for directions. I'm bad at asking for help and communicating my needs. Sometimes, I'm afraid of bothering others. I also feel uncomfortable with sudden displays of interest.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;The original version of this post is part of the Blaugust 2025 series on my blog along with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/hospital-visit"&gt;Hospital visit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/win-31-nostalgia"&gt;Win 3.1 Nostalgia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/poets-of-the-fall"&gt;Poets of the Fall&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/project-done"&gt;Project done!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/video-games-that-made-me-learn"&gt;Video games that made me learn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/blaugust-introduction"&gt;Blaugust&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Personal"/><category term="Blaugust2025"/><category term="Sims"/><category term="Me"/><category term="Gaming"/></entry><entry><title>Hospital visit</title><link href="https://blog.gridranger.dev/hospital-visit" rel="alternate"/><published>2025-08-08T23:16:10+03:00</published><updated>2025-08-08T23:16:10+03:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-08-08:/hospital-visit</id><summary type="html">&lt;p&gt;I had an MRI today. It was a big deal for me, even though it was just a routine checkup. There are two reasons for that.&lt;/p&gt;
&lt;p&gt;I usually calm and relaxed at the doctor's office. I'm also fine with loud noises and confined spaces. But it was the first MR …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I had an MRI today. It was a big deal for me, even though it was just a routine checkup. There are two reasons for that.&lt;/p&gt;
&lt;p&gt;I usually calm and relaxed at the doctor's office. I'm also fine with loud noises and confined spaces. But it was the first MR since I got my titanium implants. I contacted the hospital, where I had my surgery. It took almost a month of phoning, messaging an emailing, but it was confirmed that the implant is MR-safe. I trusted the answer, but I knew that I should actively communicate this topic to the radiology staff. And that was a bit stressful.&lt;/p&gt;
&lt;p&gt;And that is related to the other reason. The healthcare system can make people feel vulnerable, worried, and powerless. And in country I came from, people compensate these feelings with snappiness. The staff that has to endure this is stressed, underpaid and often frustrated. Some doctors and nurses are kind, of course (like my GP was), but there are also many who are rude, outright abusive, or just indifferent. They treat you condescendingly like you were a mix of a broken device and a silly child.&lt;/p&gt;
&lt;p&gt;If you're used to that, it's hard to forget. Even though I knew that I'd be treated humanely since this is Finland, but I couldn't really imagine it.&lt;/p&gt;
&lt;p&gt;It's hard to emphasize how seriously impressed I am. I spent less than 25 minutes in the building. During that time, I helped an elderly lady catch the elevator. A nurse checked my appointment. 5 minutes later, a different nurse called me by name, and led me to a room where I could change. We discussed my implants. A few of minutes later I was let into the MR-room. I got all the instructions kindly from both her and a radiologist. The checkup went well, we said goodbye, and I got dressed and left.&lt;/p&gt;
&lt;p&gt;The hospital was huge and clean and everyone was supportive and treated me equally. It is totally normal, I guess. I'm still having a hard time believing it.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;The original version of this post is part of the Blaugust 2025 series on my blog along with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/win-31-nostalgia"&gt;Win 3.1 Nostalgia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/poets-of-the-fall"&gt;Poets of the Fall&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/project-done"&gt;Project done!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/video-games-that-made-me-learn"&gt;Video games that made me learn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/blaugust-introduction"&gt;Blaugust&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Personal"/><category term="Blaugust2025"/></entry><entry><title>Win 3.1 nostalgia</title><link href="https://blog.gridranger.dev/win-31-nostalgia" rel="alternate"/><published>2025-08-06T22:37:08+03:00</published><updated>2025-08-06T22:37:08+03:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-08-06:/win-31-nostalgia</id><summary type="html">&lt;p&gt;Obviously, the design of my page is inspired by nostalgia. Old Windows versions may look obsolete today, but after DOS, they were amazing. I know a lot about their shortcomings and issues, but deep down, I remember how cutting-edge the star and the labyrinth screensavers felt.&lt;/p&gt;
&lt;p&gt;Whenever I select a …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Obviously, the design of my page is inspired by nostalgia. Old Windows versions may look obsolete today, but after DOS, they were amazing. I know a lot about their shortcomings and issues, but deep down, I remember how cutting-edge the star and the labyrinth screensavers felt.&lt;/p&gt;
&lt;p&gt;Whenever I select a typeface resembling the &lt;a href="https://en.wikipedia.org/wiki/Code_page_437"&gt;IBM 437 VGA&lt;/a&gt; character set for my terminal, it feels like coming home. I know that there are more ergonomic, state-of-the-art monospace typefaces, but whenever I see this one, I relive the enthusiasm of my six-year-old self who had just booted up the computer on an endless Saturday morning. Receiving the prompt opened the gate to the endless possibilities.&lt;/p&gt;
&lt;p&gt;I'll get back into this topic in a later post, but for now, I'd like to write  about that piece of nostalgia I just added to my blog. I really liked Win 3.1. Before I left the Microsoft ecosystem, I worked on a Python-based Program Manager clone, that automatically populated the program groups with icons, offering a window-based experience. (It is designed to be platform independent, by the way, but I haven't finished the Linux part yet.)&lt;/p&gt;
&lt;p&gt;&lt;img alt="A Program Manager clone written in Python runs on Windows 11. Applications are organized into thematic groups that can be shown or hidden based on the user's needs for the current session. An open panel shows how to edit an automatically created icon. Emojis indicate whether the fields are valid. In the background you can see Windows XP's default wallpaper, Bliss, featuring green hills and a blue sky with clouds." src="../images/2025-08-06-progman-py.png"&gt;&lt;/p&gt;
&lt;p&gt;The new feature is a tag-based list of posts that pays tribute to the same Win 3.1 shell with its arrangement and hidden wallpaper.&lt;/p&gt;
&lt;p&gt;&lt;img alt="It shows the blog's current state. Blue background with icons. Grey tray and home menu above like in Windows XP. In the foreground, is an open window with nine child windows inside. Each tag has a child window featuring the icons of the posts that it has tagged." src="../images/2025-08-06-win31nostalgy.png"&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;The original version of this post is part of the Blaugust 2025 series on my blog along with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/poets-of-the-fall"&gt;Poets of the Fall&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/project-done"&gt;Project done!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/video-games-that-made-me-learn"&gt;Video games that made me learn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/blaugust-introduction"&gt;Blaugust&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Blog"/><category term="Blaugust2025"/><category term="Blogging"/><category term="Linux"/><category term="Python"/></entry><entry><title>Poets of the Fall</title><link href="https://blog.gridranger.dev/poets-of-the-fall" rel="alternate"/><published>2025-08-05T20:24:53+03:00</published><updated>2025-08-05T20:24:53+03:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-08-05:/poets-of-the-fall</id><summary type="html">&lt;p&gt;Today, while listening to Spotify, I suddenly realized that I've been listening to &lt;a href="https://poetsofthefall.com"&gt;Poets of the Fall&lt;/a&gt; for over 20 years.&lt;/p&gt;
&lt;p&gt;I listen to a lot of music and enjoy many different genres. Classical music, jazz, rock &amp;amp; roll, techno, ambient and many other styles: they all have their place in …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Today, while listening to Spotify, I suddenly realized that I've been listening to &lt;a href="https://poetsofthefall.com"&gt;Poets of the Fall&lt;/a&gt; for over 20 years.&lt;/p&gt;
&lt;p&gt;I listen to a lot of music and enjoy many different genres. Classical music, jazz, rock &amp;amp; roll, techno, ambient and many other styles: they all have their place in my life. What I listen to depends heavily on my mood and what I'm doing. No matter what I'm doing, though, there are always a couple of Poets songs that fit perfectly.&lt;/p&gt;
&lt;p&gt;I guess I lack the blind enthusiasm to consider myself a fan of the band (or any other), but I really love their music. Many important memories of my life tied to some of their songs.&lt;/p&gt;
&lt;p&gt;I can see myself driving in a snowstorm as teenager listening to &lt;em&gt;Late Goodbye&lt;/em&gt;. I remember playing &lt;em&gt;Locking Up the Sun&lt;/em&gt; in the first apartment I rented on my own. I clung to &lt;em&gt;Change&lt;/em&gt; during some difficult years and I had days when the only sunshine I felt was when I heard the first chords of &lt;em&gt;Children of the Sun&lt;/em&gt; from my random playlist.&lt;/p&gt;
&lt;p&gt;Attending the &lt;em&gt;Ultraviolet&lt;/em&gt; concert is a memory that reminds me of the positive change in my life that was already happening. During the COVID lockdown, I followed the monthly &lt;em&gt;Alexander Theater Sessions&lt;/em&gt;. Their &lt;em&gt;Ghostlight&lt;/em&gt; concert was our first date with my wife.&lt;/p&gt;
&lt;p&gt;&lt;img alt="My own photo taken on the Ultraviolet concert. The band plays in the background illuminated by bright deep blue lights. In the front there are black silhuettes of people listening to them." src="../images/2025-08-05-potf-cover.png"&gt;&lt;/p&gt;
&lt;p&gt;Their album trilogy of hardships, coping and renewal matched quite well how my life went on.&lt;/p&gt;
&lt;p&gt;Every artist and band convey theirs own views and values, and I always appreciated the sensitivity and humanity I find in the Poets of the Fall-songs.&lt;/p&gt;
&lt;p&gt;I'm looking forward to seeing them perform live again and buying a new album of theirs. &lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;The original version of this post is part of the Blaugust 2025 series on my blog along with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/project-done"&gt;Project done!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/video-games-that-made-me-learn"&gt;Video games that made me learn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/blaugust-introduction"&gt;Blaugust&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Personal"/><category term="Blaugust2025"/><category term="Music"/></entry><entry><title>Project done!</title><link href="https://blog.gridranger.dev/project-done" rel="alternate"/><published>2025-08-03T21:25:59+03:00</published><updated>2025-08-04T01:18:59+03:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-08-03:/project-done</id><summary type="html">&lt;p&gt;Though I wasn't aware of Blaugust when I started the development of my Blogger Takeout Viewer app, it feels just right that it's finished now.&lt;/p&gt;
&lt;p&gt;Since writing my very first post, I've always wanted some kind of continuity. Migrating my old posts to a new blog shows where I came …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Though I wasn't aware of Blaugust when I started the development of my Blogger Takeout Viewer app, it feels just right that it's finished now.&lt;/p&gt;
&lt;p&gt;Since writing my very first post, I've always wanted some kind of continuity. Migrating my old posts to a new blog shows where I came from and how I changed over time and how I changed with time. TBH, I've never fully finished any post-copy activities, but I've always wanted to.&lt;/p&gt;
&lt;p&gt;Now, that I've decided &lt;a href="/degoogling"&gt;to leave Google behind&lt;/a&gt;, I can't wait forever. Of course Google Takeout helped me retrieve all my data, but Google did its best to provide it in a useless form. The feed was unordered, and the picture links didn't point to the image folder that was in the Takeout file but to the original cloud location.&lt;/p&gt;
&lt;p&gt;That's why I created this app. It reads your feed, pulls the images, saves them in an organized manner, fixes the links and cleans up the posts. You can quickly copy the posts, or save them one-by-one, or export them to separate files or to a huge single one.&lt;/p&gt;
&lt;p&gt;It is possible to make a post on my new blog, that has all the content from one of my old blogs. &lt;a href="/treasure-of-the-pirate-king"&gt;Like I did here manually earlier.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Of course there is always room for improvement. Metadata can be included in Pelican's format now, but the source is open, so if you use Jekyll or any other framework, you can add new export formats. I look forward to receive ideas and merge requests in the &lt;a href="https://framagit.org/gridranger/blogger-takeout-viewer"&gt;repository&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I'll be glad if you find this tool helpful for leaving Blogger behind in a more comfortable way.&lt;/p&gt;
&lt;p&gt;&lt;img alt="A screenshot of a Linux Mint desktop with a Skyrim background. Three windows are open. The first one is a text editor displaying the raw feed of an old blog of mine. In the foreground there is the Blogger Takeout Viewer app displaying the same post in a cleaned-up Markdown format. On the left side of the app, there is a tree structure showing the posts by date. On the right, there is the cleaned text. Below it are the thumbnails of the images and the metadata of the post. At the top there are buttons offering load, copy, and export options. Behind the Blogger Takeout Viewer on the right, there a WYSIWYG Markdown editor called Typora that shows the exported result of the same post." src="../images/09-takeout-viewer-done.png"&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;The original version of this post is part of the Blaugust 2025 series on my blog along with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/video-games-that-made-me-learn"&gt;Video games that made me learn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/blaugust-introduction"&gt;Blaugust&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Development"/><category term="Blogging"/><category term="Blaugust2025"/><category term="Python"/><category term="Degoogling"/></entry><entry><title>Video games that made me learn</title><link href="https://blog.gridranger.dev/video-games-that-made-me-learn" rel="alternate"/><published>2025-08-02T22:27:44+03:00</published><updated>2025-08-02T22:27:44+03:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-08-02:/video-games-that-made-me-learn</id><summary type="html">&lt;p&gt;Video games are (at least partially) simplified models of the reality.
They can model anything: sword-fighting with a simple click, personality changes of player and the world's feedback to it, evolution of species, history or cultures, etc. Of course, it is up to the player to understand what are the …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Video games are (at least partially) simplified models of the reality.
They can model anything: sword-fighting with a simple click, personality changes of player and the world's feedback to it, evolution of species, history or cultures, etc. Of course, it is up to the player to understand what are the things that work in reality too and what other things are there only for fun or to over-simplify something. You better not mix up the two, otherwise you can have a baad time.&lt;/p&gt;
&lt;p&gt;The following lists might be extended later.&lt;/p&gt;
&lt;h2&gt;Useful things I learned&lt;/h2&gt;
&lt;p&gt;Managing my mood better from &lt;strong&gt;Sims&lt;/strong&gt;: Sims 3 uses little moodlets to express the hidden components the characters' mood. These are state icons that can represent anything from hunger to loneliness, sharing a successful blog post, or enjoying a good joke, being embarrassed or inspired, being energized from workout or feeling down from unsatisfied thirst for coffee. &lt;a href="https://sims.fandom.com/wiki/List_of_Moodlets_(The_Sims_3)"&gt;There are an insane amount of them.&lt;/a&gt; They all last for a certain amount of time. Hitting your thumb with a hammer might annoy you for a couple of minutes, but being promoted makes you proud for days. Some has positive score and some has negative effect. Their sum has a high impact on the affected character's overall mood. It taught me to listen to myself better when I'm frustrated or feeling off without apparent reason. Can I find out what my moodlets would be? Can I cancel out some negative ones? How could I add some positive ones?&lt;/p&gt;
&lt;p&gt;Keeping a financial balance and how to invest from &lt;strong&gt;Transport Tycoon&lt;/strong&gt;: I got this game from my cousin. She mailed me her disks when I was 8 or 9. I couldn't understand most of the texts at first because English is not my native language. But I was amazed by the game's complexity. It took me weeks to figure out what the different buttons and widgets do. It was awesome! As the world changed over time, the company flourished if you played well. I loved the implementation of the finance charts. They taught me how to look at my current situation and plan ahead.&lt;/p&gt;
&lt;p&gt;&lt;img alt="A screenshot of the open source remake. You can see an orthographic 3d landscape with trees, cities, roads, trucks, rails and trains. There is a grey finance pane open showing the last tree years' opex, capex and revenue in details." src="../images/08-ottd.png"&gt;&lt;/p&gt;
&lt;p&gt;Basic pros and cons of government types from &lt;strong&gt;Civilization&lt;/strong&gt;: The first DOS based implementation remained my favourite with its wonderful pixel graphics and tile based maps. Sure, one shouldn't try to learn history or philosophy from it. But, even as a kid I noticed that autocracies scored worse at science but the people didn't care about wars. Democratic nations, on the other hand, didn't tolerate long wars, and it was more expensive to maintain their society. But on the long run they performed much better (at least for my strategy) and had lower corruption. These were rough simplifications without any explanation, but now, as adult I understand more of this.&lt;/p&gt;
&lt;p&gt;&lt;img alt="This is a screenshot from the 1991 game Civilization that looks like a newspaper. The headline reads: &amp;quot;Greek government changed to Despotism!&amp;quot; Below you can see the new cabinet. The defense minister is a thin, soldier with too many decorations; he resembles a general from a banana republic. The domestic advisor is an aggressively looking officer, implying that it is a police state. The foreign minister is a blonde woman with a sour expression and a large golden cross on her necklace. She seems xenophobic. The science advisor is a man wearing a Hawaiian shirt and many gold chains. He has a five o'clock shadow. He doesn't look like he has anything to do with science. The last two bear an uncanny resemblance to some of Trump's second cabinet members." src="../images/08-civ.png"&gt;&lt;/p&gt;
&lt;h2&gt;Things you shouldn't learn but fun&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Sims 3&lt;/strong&gt;: You can teleport if you meditate deep enough. Of course, it can happen that this is true, simply no one meditated deep &lt;em&gt;enough&lt;/em&gt; to experience it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Transport Tycoon&lt;/strong&gt;: Passengers don't care about their destination, as long as they can fit on the bus.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Civilization&lt;/strong&gt;: Building a stadium will make people of the city more satisfied. I lived in a country where the prime minister thought it would work. It didn't.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;The first version of this post is part of the Blaugust 2025 series on my blog along with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/blaugust-introduction"&gt;Blaugust&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Games"/><category term="Sims"/><category term="Transport Tycoon"/><category term="Civilization"/><category term="Blaugust2025"/><category term="Gaming"/><category term="Python"/></entry><entry><title>Blaugust: Introduction</title><link href="https://blog.gridranger.dev/blaugust-introduction" rel="alternate"/><published>2025-08-01T13:12:11+03:00</published><updated>2025-08-01T13:12:11+03:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-08-01:/blaugust-introduction</id><summary type="html">&lt;p&gt;&lt;img alt="Bluish-reddish text banner saying: 2025 Blaugust - Festival of blogging" src="../images/blaugust2025tpbk2.webp"&gt;&lt;/p&gt;
&lt;p&gt;Hi, I'm Dávid (he/him). I develop in python, enjoy walks in the nature with my family and play computer games, board games. I love to learn and solve things.&lt;/p&gt;
&lt;p&gt;I heard about the Blaugust just recently from &lt;a href="https://mementomori.social/@hamatti@mastodon.world"&gt;Juhis&lt;/a&gt; on his blog, &lt;a href="https://hamatti.org/"&gt;hamatti.org&lt;/a&gt;. I can't resist the idea of …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="Bluish-reddish text banner saying: 2025 Blaugust - Festival of blogging" src="../images/blaugust2025tpbk2.webp"&gt;&lt;/p&gt;
&lt;p&gt;Hi, I'm Dávid (he/him). I develop in python, enjoy walks in the nature with my family and play computer games, board games. I love to learn and solve things.&lt;/p&gt;
&lt;p&gt;I heard about the Blaugust just recently from &lt;a href="https://mementomori.social/@hamatti@mastodon.world"&gt;Juhis&lt;/a&gt; on his blog, &lt;a href="https://hamatti.org/"&gt;hamatti.org&lt;/a&gt;. I can't resist the idea of taking part in such an interesting event. It's like us challenging ourselves to post more often. Inspiring! I can't wait to find new interesting blogs thanks to the event. And as for my posting frequency, I'll do my best instead of making big promises.&lt;/p&gt;
&lt;p&gt;I've started blogging in December 2005 during my university years. I wrote about many things: books I've read, video games I've played, movies I've watched, and thoughts I've had. I rarely write about my feelings, but maybe I should learn to do so.&lt;/p&gt;
&lt;p&gt;I tried out a bunch of platforms over the past two decades, Blogger, WordPress, and Write.as, but ultimately, I decided that owning my data is the best. I don't self-host, but I use GitLab Pages on FramaGit. It's a static site generated with Python's &lt;a href="https://getpelican.com/"&gt;Pelican&lt;/a&gt; framework from Markdown files. It makes me possible to have a custom minimalist design and simple way of posting.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;The Blaugust logo is from the &lt;a href="https://aggronaut.com/blaugust-media-kit/"&gt;Blaugust Media Kit&lt;/a&gt;.&lt;/p&gt;</content><category term="Blog"/><category term="Blaugust2025"/><category term="Blogging"/></entry><entry><title>Blogger Takeout Viewer</title><link href="https://blog.gridranger.dev/blogger-takeout-viewer" rel="alternate"/><published>2025-07-26T23:46:48+03:00</published><updated>2025-07-26T23:46:48+03:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-07-26:/blogger-takeout-viewer</id><summary type="html">&lt;p&gt;I'm working on cutting ties with Google. Although I could download my blogs' content from Google Takeout, that doesn't mean the received material is usable. There was an Atom feed for each blog and an album folder for pictures. For my blog about Python game development, it was easy to …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I'm working on cutting ties with Google. Although I could download my blogs' content from Google Takeout, that doesn't mean the received material is usable. There was an Atom feed for each blog and an album folder for pictures. For my blog about Python game development, it was easy to find the images for the posts. However, that isn't the case for most blogs. The posts are also in random order in the exported feed. Reading and reusing the data is anything but easy.&lt;/p&gt;
&lt;p&gt;So, I quickly created a new project that visualizes blog posts in Markdown. The next step will be to show the metadata too on the UI. It has already been parsed in the business logic. Then, I plan to implement a solution that pairs the posts with their pictures.&lt;/p&gt;
&lt;p&gt;The project is available here: &lt;a href="https://framagit.org/gridranger/blogger-takeout-viewer"&gt;https://framagit.org/gridranger/blogger-takeout-viewer&lt;/a&gt; But it is far from being ready yet. &lt;/p&gt;
&lt;p&gt;&lt;img alt="A screenshot of a simple app window. On the left hand side there is a tree structure showing posts by the date of their publishing. On the right hand side there is a large text pane showing the content of the post." src="../images/06-blogger-takeout-viewer.png"&gt;&lt;/p&gt;</content><category term="Development"/><category term="Python"/><category term="Blogging"/><category term="Degoogling"/></entry><entry><title>Treasure of the Pirate King</title><link href="https://blog.gridranger.dev/treasure-of-the-pirate-king" rel="alternate"/><published>2025-07-15T00:57:26+03:00</published><updated>2025-07-15T00:57:26+03:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-07-15:/treasure-of-the-pirate-king</id><summary type="html">&lt;h1&gt;The Treasure of the Pirate King&lt;/h1&gt;
&lt;p&gt;I just found the short blog I wrote while developing this video board game. That's what got me started learning Python development. I had an idea for a board game and wanted to test it on a large scale to see if it was …&lt;/p&gt;</summary><content type="html">&lt;h1&gt;The Treasure of the Pirate King&lt;/h1&gt;
&lt;p&gt;I just found the short blog I wrote while developing this video board game. That's what got me started learning Python development. I had an idea for a board game and wanted to test it on a large scale to see if it was balanced. Learning Python sounded like fun for that purpose. I read Gérard Swinnen's GNU-licensed book about Python programming and learned the basics out of pure curiosity. Back then, I had no idea how much Python would change my life by opening the door to a new passion and profession.&lt;/p&gt;
&lt;h2&gt;Getting started - 2013-02-26&lt;/h2&gt;
&lt;p&gt;Now that I have planned the game, the first step is to create the pathfinding algorithm. I created a class that renders the board, as well as a method that calculates the possible target spaces the player can land on. I also added a method that adds a wind modifier to the rolled value. For now, it's just a stub that returns a modifier of 0.&lt;/p&gt;
&lt;p&gt;&lt;img alt="A screenshot where a part of an IDLE (built-in Python editor) window is visible. A Tkinter board with some green spaces on white background is also there." src="../images/pirate-king/v0-0-1.png"&gt;&lt;figcaption&gt;The debug messages in the Python Shell window says that "I can take 6 steps" to all (W, N, S and E) directions.&lt;/figcaption&gt;&lt;/p&gt;
&lt;h2&gt;Running Python scripts from Notepad++ - 2013-02-28&lt;/h2&gt;
&lt;p&gt;So far, I've always run my code with Idle, the editor bundled with the Python distributions. But I miss the flexibility of Notepad++ from it. Now, I took a deep breath and configured Np++ to get the script running capability. The steps I took were:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I installed NPPExec plugin under the Plugin manager in the Extensions menu.&lt;/li&gt;
&lt;li&gt;In the Extensions menu Execute... option I save the following to commands:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;d:&lt;span class="se"&gt;\u&lt;/span&gt;serapps&lt;span class="se"&gt;\P&lt;/span&gt;ython33&lt;span class="se"&gt;\p&lt;/span&gt;ython&lt;span class="w"&gt; &lt;/span&gt;-u&lt;span class="w"&gt; &lt;/span&gt;-i

&lt;span class="w"&gt;    &lt;/span&gt;d:&lt;span class="se"&gt;\u&lt;/span&gt;serapps&lt;span class="se"&gt;\P&lt;/span&gt;ython33&lt;span class="se"&gt;\p&lt;/span&gt;ython&lt;span class="w"&gt; &lt;/span&gt;-u&lt;span class="w"&gt; &lt;/span&gt;-i&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;FULL_CURRENT_PATH&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;img alt="Screenshot of the Execute... panel of Notepad++" src="../images/pirate-king/NPPExecSR.png"&gt;&lt;/p&gt;
&lt;p&gt;I also set to start the console automatically once NP++ launches and start the Python interpreter inside under Extensions / NPPExec menu / Advanced options... This way I'll always have a Python console to experiment. And I can launch the script I edit by pressing F6.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Screenshot of the game cannon battle." src="../images/pirate-king/NPPExecBB.png"&gt;&lt;figcaption&gt;An example app from the Python book I learned from. It is running under Notepad++&lt;/figcaption&gt;&lt;/p&gt;
&lt;h2&gt;Language module - 2013-03-06&lt;/h2&gt;
&lt;p&gt;I'm done with the language selector part of the game. Language resources won't be part of the code but are stored in simple XMLs so they can be extended even without any development experience.&lt;/p&gt;
&lt;p&gt;I also wrote the settings save/load part to preserve the player's configuration preferences between sessions.&lt;/p&gt;
&lt;p&gt;&lt;img alt="You can see part of the code and the language selector." src="../images/pirate-king/language-selector.png"&gt;&lt;figcaption&gt;Languages to select: English, Pirate dialect and Hungarian. Don't judge me on mixing languages in method and variable names. It was my first project. 😅 I've never done that later.&lt;/figcaption&gt;&lt;/p&gt;
&lt;h2&gt;Porting - 2013-03-10&lt;/h2&gt;
&lt;p&gt;The language, I use to write the program, has two competing versions. Python 3 is definitely the future, but plenty of packages only support Python 2. For example, I can't find a suitable package to display vector-graphic images in TkInter. If I find only a Python 2 module for the purpose, I'll have to upgrade that for Python 3 myself. It's cool that there 2to3.py exists, but I wonder if a greenhorn like me can use it to convert full packages without breaking them.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Command line screenshot of using 2to3.py" src="../images/pirate-king/2to3.png"&gt;&lt;/p&gt;
&lt;h2&gt;The game board - 2013-03-12&lt;/h2&gt;
&lt;p&gt;It's done. It seems vector graphic rendering is not supported under TkInter. The solution I've found would have multiplied the game's size tenfold, so I scrapped the idea. It still looks great. The trade-off is that I have to pre-render the graphical assets to the highest resolution and that will cap the game to 1920×1080. Of course, I can reexport them later once the higher resolutions displays are more common. Everything else besides the pngs scales dynamically. For lower resolutions downscaling is easy at game load and on resolution change.&lt;/p&gt;
&lt;p&gt;&lt;img alt="This is the board of a pirate themed desktop board game. It features a map of the Caribbean as the background. Around and across the board there are spaces with different images. Its main colors are the different shades of brown and red to resemble an aged paper map. The images are cartoonish vector drawings." src="../images/pirate-king/irl-board.png"&gt;&lt;figcaption&gt;Image of the planned game board exported from Inkscape. The towns are starting fields but serve also as bases for the players. Many of the fields change the wind direction, or grant extra turn, or make you miss a turn. Others give you treasure or lead you to battle. Outlines to show where the drawing decks and discard piles go. The ships on the sides serves as the battlefield for PvP and PvE encounters.&lt;/figcaption&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="This is the board of the video game version. Images on all fields are rotated so that the user can see them from their perspective. There are no ships on the sides nor is there a place for the cards." src="../images/pirate-king/screenshot-of-the-board.png"&gt;&lt;figcaption&gt;Screenshot of the board from the game developed in Python (1024×768)&lt;/figcaption&gt;&lt;/p&gt;
&lt;h2&gt;Stubborn error - 2013-03-18&lt;/h2&gt;
&lt;p&gt;I've found an error. But not in my code this time.&lt;/p&gt;
&lt;p&gt;Since I started using a dropdown widget from the Ttk package, my app has been started throwing an exception on exit. I could simply suppress it, but I hate to ignore problems. I recreated the issue in a sample code and uploaded it to &lt;a href="http://stackoverflow.com/questions/15448914/python-tkinter-ttk-combobox-throws-exception-on-quit/15455715"&gt;Stackowerflow&lt;/a&gt;. The community helped me to overcome the issue in properly.&lt;/p&gt;
&lt;h2&gt;Saving module - 2013-03-25&lt;/h2&gt;
&lt;p&gt;This is finished too. It will do the writing and reading operations.&lt;/p&gt;
&lt;p&gt;As it can be seen in the image below, the test method passes the data of the three players to the class that serializes it, than starts the saving process.&lt;/p&gt;
&lt;p&gt;As a next step, we create a new instance of the data manager class, load the data back from the saved XML and print it. The content of the data as well as its structure will remain the same. Using XML helps me during the development because I can easily create saves with corner cases.&lt;/p&gt;
&lt;p&gt;&lt;img alt="A Notepad++ screenshot showing a short Python code snippet." src="../images/pirate-king/saving-module.png"&gt;&lt;figcaption&gt;Developers delight: when they can read back what they wrote.&lt;/figcaption&gt;&lt;/p&gt;
&lt;h2&gt;The last 18 days - 2013-04-12&lt;/h2&gt;
&lt;p&gt;Since my last update, I progressed with baby steps only. But many small steps together mean a lot of progress:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The method for calculating the wind modifier is ready. Wind direction changes and influences the possible movement of ships similarly to real wind. Displaying the current wind speed and direction is also complete.&lt;/li&gt;
&lt;li&gt;The GUI now shows the player's wealth and crew.&lt;/li&gt;
&lt;li&gt;The cities are partially complete. You can hire new crew members and buy larger ships.&lt;/li&gt;
&lt;li&gt;The saving/loading module has been updated to keep track of the changes. It also saves info such as the number of turns left to skip, and the number of sailors that can be hired in the ports. The number of ships sunk by each player is also recorded.&lt;/li&gt;
&lt;li&gt;The turn skip mechanics have been implemented.&lt;/li&gt;
&lt;li&gt;All ship types are implemented (schooner, brig and frigate).&lt;/li&gt;
&lt;li&gt;Fixed some bugs (e.g. a phantom board appearing after starting a second game, then changing the resolution; the player can't stay in the port if roll less than three, etc.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="There is a pop-up message over the game board telling the player that their turn has to be skipped." src="../images/pirate-king/skipped-turn.png"&gt;&lt;figcaption&gt;The message says: "Helmsman Snouty* skips this turn. He has one more turn to skip." - *His name is an untranslatable pun.&lt;/figcaption&gt;&lt;/p&gt;
&lt;h2&gt;Event cards - 2013-04-24&lt;/h2&gt;
&lt;p&gt;Once I've finished the cities, it was time to focus on the event and treasure cards. On the board game version players draw cards from these two decks at different times. In the video game version they are pulled and applied automatically. Players are only informed about the cards, and can take actions when decisions must be made.&lt;/p&gt;
&lt;p&gt;Now, the cards are shuffled and shown randomly. The next step is to implement saving and loading the state of drawing decks and the discard piles. Then I'll continue with the actual implementation of the events.&lt;/p&gt;
&lt;p&gt;&lt;img alt="A pop-up window appears over the game map, showing an event card. The card is in black and white and features a compass with a large question mark." src="../images/pirate-king/event-card.png"&gt;&lt;figcaption&gt;A screenshot of the Python implementation. The text on the card is "Broken compass - The islands have not moved, your compass is broken. You miss a turn while use the stars to figure out the right direction."&lt;/figcaption&gt;&lt;/p&gt;
&lt;h2&gt;Battle - 2013-06-01&lt;/h2&gt;
&lt;p&gt;Over the past month, I haven't had enough time or energy to continue developing the game as much as I would have liked, but I won't give up on the project. I'm working on the battle module, which is the most complex remaining task. The fight mechanics are working, and you can assign sailors to different locations on the ship. You can win or lose. The only pieces missing are the skills that would make battles more tactical and interesting.&lt;/p&gt;
&lt;p&gt;&lt;img alt="The image shows the battle window with the opposing crews on the sides and the greyed out extra abilities on the top." src="../images/pirate-king/battle.png"&gt;&lt;figcaption&gt;The extra abilities in order: gun, rifle, caltrop, grenade, grapeshot, greek fire, monkey attack, siren horn, sirens&lt;/figcaption&gt;&lt;/p&gt;
&lt;h2&gt;Memory leak - 2013-07-12&lt;/h2&gt;
&lt;p&gt;&lt;img alt="This picture shows a part of the console and the game's UI at the same time." src="../images/pirate-king/bumms-turn.png"&gt;&lt;figcaption&gt;I become paranoid when there is an issue and log everything. I log the cards in the decks and piles, the available ship upgrades, and the next player.&lt;/figcaption&gt;&lt;/p&gt;
&lt;p&gt;I'm done with the battle implementation, but there's still much to be done. Progress isn't always visible or exciting. However, small, boring steps are important, too.&lt;/p&gt;
&lt;p&gt;I experienced something interesting last week. I noticed in Task Manager that, whenever I load a saved state, the amount of RAM used by the game increases. I ran a quick test and discovered that the increase was caused by the graphical content. The memory claimed by the images is not released until the game uses more than half a GB. Considering that 30-40 MB is required to play a single party, that's way too much.&lt;/p&gt;
&lt;p&gt;I went through the code and found no leaks, so I posted the whole situation on &lt;a href="https://stackoverflow.com/questions/17337986/memory-leaks-when-image-discarded-in-python"&gt;Stackoverflow&lt;/a&gt;. I was relieved by the answers. It seems it isn't a memory leak, but the way how Python and Windows minimizes the effort of returning and reclaiming the memory once allocated. &lt;/p&gt;
&lt;h2&gt;Windows - 2013-07-17&lt;/h2&gt;
&lt;p&gt;I encountered a strange issue. I wanted to prevent players from closing the battle screen. I added a penalty for doing so, as well as a brief warning message. However, when the warning is displayed, the battle window ends up behind the main window. Therefore, even if the player chooses not to leave, they will no longer be able to find the battle.&lt;/p&gt;
&lt;p&gt;&lt;img alt="There are three small TkInter windows over a PowerShell window. The Beta window sank behind the Alpha window when the Gamma window opened." src="../images/pirate-king/window-issue.png"&gt;&lt;figcaption&gt;I've recreated the issue with simpler code.&lt;/figcaption&gt;&lt;/p&gt;
&lt;p&gt;I couldn't find a solution to this problem on Google because I couldn't come up with the right keywords. So, I wrote a small test app to recreate the issue with Windows Alpha, Beta, and Gamma. While doing so, I found the solution. The warning message's parent was the main window instead of the battle screen. Cleaning up the hierarchy fixed the problem.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Three small TkInter windows over a PowerShell window. Alpha window is in the background, beta is over it and Gamma is on the top." src="../images/pirate-king/window-issue-fixed.png"&gt;&lt;figcaption&gt;Window Alpha stays were it should&lt;/figcaption&gt;&lt;/p&gt;
&lt;h2&gt;Past 80% - 2013-08-26&lt;/h2&gt;
&lt;p&gt;As it says in the title, the game is more than 80% complete. I've reimplemented the classes that display the cards, and half of the card events have been implemented. However, that was the simpler half, as 30 treasure cards and 20 battle cards have the same functionality, differing only in their arguments. It will take a while to complete the full game, but we're getting closer.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;I never finished the game. Later, I rewrote the entire game from scratch to simplify it and clean up the code. Through these two development processes, I learned a lot about clean coding. I improved my use of scopes, namespaces, data classes, and states. I also improved my unit testing and project management skills. The second time around, I got further, up to ~95%. But I still haven't finished it. Yet. 😉&lt;/p&gt;</content><category term="Development"/><category term="Board games"/><category term="Gaming"/><category term="Python"/><category term="Post streams"/><category term="Revived post"/></entry><entry><title>Chimera Squad</title><link href="https://blog.gridranger.dev/chimera-squad" rel="alternate"/><published>2025-06-20T11:05:54+03:00</published><updated>2025-06-20T11:05:54+03:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-06-20:/chimera-squad</id><summary type="html">&lt;h1&gt;Things I enjoyed about Chimera Squad&lt;/h1&gt;
&lt;p&gt;👾 Shorter missions and more granular saves - I have less time now than I used to, but I can still play full missions. The shortness can still be balanced out with difficulty.&lt;/p&gt;
&lt;p&gt;👾 Less realistic graphical style - I liked the visuals of the previous installments, but …&lt;/p&gt;</summary><content type="html">&lt;h1&gt;Things I enjoyed about Chimera Squad&lt;/h1&gt;
&lt;p&gt;👾 Shorter missions and more granular saves - I have less time now than I used to, but I can still play full missions. The shortness can still be balanced out with difficulty.&lt;/p&gt;
&lt;p&gt;👾 Less realistic graphical style - I liked the visuals of the previous installments, but I was amazed by this style. This episode also had higher performance than XCOM 2 and required less space.&lt;/p&gt;
&lt;p&gt;👾 Characters you can get to know and remember - I like games with small optional dialogue scenes. My favorites were Verge, the sectoid gentleman and Patchwork, the curious drone pilot.&lt;/p&gt;
&lt;p&gt;👾 Mixed turn order - It's similar to Final Fantasy X's battle system. It added a new puzzle layer I liked.&lt;/p&gt;
&lt;p&gt;👾 Diversity - The team is open to everyone and only skills matter. Aliens, hybrids, humans, men, women, people of color, people with disabilities, and people with different life traumas all work together to make their city a better place to live. I really enjoyed that. If there's any way for the world to heal after the events of XCOM 2, this is it.&lt;/p&gt;</content><category term="Games"/><category term="Gaming"/></entry><entry><title>About the icons</title><link href="https://blog.gridranger.dev/about-the-icons" rel="alternate"/><published>2025-04-21T01:15:30+03:00</published><updated>2026-03-23T01:14:00+02:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-04-21:/about-the-icons</id><summary type="html">&lt;p&gt;I use icons that recall the Win XP era, when home users finally got an NT-based Windows version that made both work and gaming  more stable than ever before. The overall design was also inspired from Windows 2003 Server Edition. I worked a lot with it.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;How I dash&lt;/strong&gt;: Character …&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;p&gt;I use icons that recall the Win XP era, when home users finally got an NT-based Windows version that made both work and gaming  more stable than ever before. The overall design was also inspired from Windows 2003 Server Edition. I worked a lot with it.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;How I dash&lt;/strong&gt;: Character map from Windows XP.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wander Navigator&lt;/strong&gt;: Netscape Navigator.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;I dream of...&lt;/strong&gt;: Favorites icon from Win XP. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Intersecting interests&lt;/strong&gt;: Wordpad icon from Windows Vista.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Alng the Edge&lt;/strong&gt;: official icon of the video game.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;My Oldest things&lt;/strong&gt;: Icon of syncapp.exe from Win XP.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;My Phone&lt;/strong&gt;: Old smart device icon from shell32.dll of Win XP.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Maximize, restore and close icons, light/dark mode icon&lt;/strong&gt;: Icons from the &lt;a href="https://www.iconarchive.com/show/material-icons-by-pictogrammers.html"&gt;Material Design Icons&lt;/a&gt; set by the &lt;a href="https://pictogrammers.com"&gt;Pictogrammers&lt;/a&gt; team.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Road 96&lt;/strong&gt;: The offical icon of the game.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Snowfall&lt;/strong&gt;: Desktop icon of Ski Region Simulator from 2013.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Refactoring: Yeelight GUI&lt;/strong&gt;: An official XP icon, bu I have no idea what it was used for.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gaming Backlog&lt;/strong&gt; (menu item): Floppy box icon from the once-famous disk catalogue app "Where Is It?".&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gaming Backlog&lt;/strong&gt; (post): 5.25" floppy drive icon from Win 95 Plus.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Clean Patching&lt;/strong&gt;: PyWin32 logo from the early WinXP era.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Company culture&lt;/strong&gt;: The icon of Office Communicator. It was a variant of the MSN messenger I loved so much.  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;KDE Neon&lt;/strong&gt;: KDE's official icon.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;About Gridranger&lt;/strong&gt;: An icon drawn by me.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Space Colony&lt;/strong&gt;: The game's official desktop icon.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Friendships in my life&lt;/strong&gt;: People icon from Windows XP.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Jousting in video games&lt;/strong&gt;: Icon of Mount &amp;amp; Blade: Warband.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Helsinki Biennial&lt;/strong&gt;: An official XP icon, bu I have no idea what it was used for.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Data &amp;amp; Encryption&lt;/strong&gt;: Security icon from XP.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Intro through traits&lt;/strong&gt;: Icon of the Sims 2 standalone Sim creator.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hospital visit&lt;/strong&gt;: One of the remote desktop executable's icons in XP.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Win 3.1 Nostalgia&lt;/strong&gt;: Win 3.1 progman.exe icon. That was the shell there instead of explorer.exe in later installments.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Poets of the Fall&lt;/strong&gt;: Win XP audio CD icon.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Video games that made me learn&lt;/strong&gt;: Sims 2 University expansion icon. The post mentions Sims 3, Transport Tycoon and Civilization. The last two being DOS games have no Windows icons. Sims 3 has no learning related icon and Sims 2 icons fit better to the WinXP/2003 design anyway.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Blaugust&lt;/strong&gt;, &lt;strong&gt;Blaugust - Summary&lt;/strong&gt;: Win XP's Wordpad icon.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Blogger Takeout Viewer&lt;/strong&gt;: Windows Live Writer icon.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Treasure of the Pirate King&lt;/strong&gt;: Windows XP's Backgammon icon.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chimera Squad&lt;/strong&gt;: Windows XP's gampad settings icon.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Family History&lt;/strong&gt;: Of course this icon is not my family crest. It is from the Heroes of Might and Magic 3 released in 1999-2000.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Random Facts About Me&lt;/strong&gt;: MSN / Windows Live Messenger icon for Windows Vista.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Degoogling&lt;/strong&gt;: Windows XP's recycle bin icon.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Python-related articles&lt;/strong&gt;: The Python logo as an icon.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Archives&lt;/strong&gt;: This icon is borrowed from WinRar.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Category icon&lt;/strong&gt;: This is a folder icon from XP, but I can't remember where it was used.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Categories icon&lt;/strong&gt;: My Documents icon from XP.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;This post&lt;/strong&gt;: This is the icon from IconForge, a free app I used to create and edit icons when I was a kid. A bit ugly but pretty nostalgic for me.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RSS/ATOM feed icon&lt;/strong&gt;: &lt;a href="https://wmh.github.io/hunbook/tools/fatcow-icons.html"&gt;https://wmh.github.io/hunbook/tools/fatcow-icons.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Blog"/><category term="Blogging"/></entry><entry><title>Family history</title><link href="https://blog.gridranger.dev/family-history" rel="alternate"/><published>2025-04-14T18:44:58+03:00</published><updated>2025-04-19T00:37:21+03:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-04-14:/family-history</id><summary type="html">&lt;h2&gt;Adventure&lt;/h2&gt;
&lt;p&gt;The best pizza I've ever tasted was in Italy, of course. There's a secluded village in the Apls where I stayed. The inn was cosy, and from the large windows of the dining room you could see a deep valley full of vineyards. While I was eating, the chef …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Adventure&lt;/h2&gt;
&lt;p&gt;The best pizza I've ever tasted was in Italy, of course. There's a secluded village in the Apls where I stayed. The inn was cosy, and from the large windows of the dining room you could see a deep valley full of vineyards. While I was eating, the chef came over and asked me how I was enjoying the food. He was obviously proud of his work and had every reason to be. He also asked me why I'd gone there, if it wasn't for the local wines. Well, I'd been on quite an adventure.&lt;/p&gt;
&lt;p&gt;I was happy to share that I was looking for a lost castle that used to belong to my ancestors. I first heard about it when I was a kid. My grandma's sister showed me an old photograph of it, but she didn't know where it was. Every so often I'd try to find it online by its name, and one day I finally did. It wasn't too far from that village. The locals weren't sure what to think about my idea of a ruin in the nearby forest.&lt;/p&gt;
&lt;p&gt;&lt;img alt="This is a high-quality scan of a photograph from from the 1920s. It was black and white, but it got a sepia tone. The top of a weak wooden fence is the closest thing. This is between the photographer and a steep ravine. On the next mountaintop there is a ruined castle tower partially covered by trees. Behind the ruin, far in a deep valley, there is a road going through a forest. High mountains can be seen on the horizon." src="../images/castleruin-old.png"&gt;&lt;/p&gt;
&lt;p&gt;I understood why they weren't aware of it. If you look at old drawings of this ruin from the early 19th century, you'll see that trees were growing out of the main tower. Even 150 years ago, nature had already reclaimed it. OK, I started to worry a bit, but didn't falter. So on the next morning, I just strolled into the forest, and followed one path after another, little by little closing on the GPS coordinate.&lt;/p&gt;
&lt;p&gt;And there it was! With some epic mountains in the background, there stood the ruins from the photograph. The crumbling walls had trees growing over them. The turret that used to be next to the drawbridge was missing -- it had fallen into a ravine below.&lt;/p&gt;
&lt;p&gt;I put my hands on the walls that had been abandoned at least three centuries years ago.&lt;/p&gt;
&lt;p&gt;It was lovely and tranquil, just the sound of birdsong and a breeze coming off the mountains.&lt;/p&gt;
&lt;p&gt;A piece of forgotten family history rediscovered.&lt;/p&gt;
&lt;p&gt;&lt;img alt="A wooded hilltop. In the distance, in the trees, stands a small figure, that was me 15 years ago. Above the treetops rises a huge tower of a partially demolished castle. Beyond the window of the tower you can see the blue of the sky, because the other walls no longer stand." src="../images/castleruin.png"&gt;&lt;/p&gt;
&lt;h2&gt;A piece of my family's history&lt;/h2&gt;
&lt;p&gt;Back in the 14th century, one of my ancestors saved a king from certain death by rescuing him from the clutches of a group of 'Saracen warriors', as the grant of arms says. The king must have been very grateful, as the family name and the crest could be inherited by the female branch in the absence of a male heir.&lt;/p&gt;
&lt;p&gt;Listening to my grandmother's sister tell stories about the family history was fun and amazing. But finding the actual genealogical papers in my grandfather's study decades later: that was incredible.&lt;/p&gt;</content><category term="Personal"/><category term="Adventure"/><category term="Family history"/><category term="Post streams"/></entry><entry><title>Random facts about me</title><link href="https://blog.gridranger.dev/random-facts-about-me" rel="alternate"/><published>2025-04-05T22:51:00+03:00</published><updated>2025-07-15T00:59:09+03:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-04-05:/random-facts-about-me</id><summary type="html">&lt;h2&gt;Learning Python&lt;/h2&gt;
&lt;p&gt;The first programming language I learned was Python. I learnt it myself from Gérard Swinnen's book to write automated tests for a pirate-themed board game I had invented (graphics made with Inkscape and GIMP).&lt;/p&gt;
&lt;p&gt;Although the development was stuck at ~87% completion and never finished, Python and automated …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Learning Python&lt;/h2&gt;
&lt;p&gt;The first programming language I learned was Python. I learnt it myself from Gérard Swinnen's book to write automated tests for a pirate-themed board game I had invented (graphics made with Inkscape and GIMP).&lt;/p&gt;
&lt;p&gt;Although the development was stuck at ~87% completion and never finished, Python and automated testing became my speciality and paved my career.&lt;/p&gt;
&lt;p&gt;&lt;img alt="A pirate themed board game's board. There are over-the-top images of ships on the sides. On the middle there is a square shaped board with 45 fields. The background is a map of the Caribbean Sea. Some cities are marked with red X on the map: Curacao, Tortuga, Port Royal, Havanna and Martinique." src="../images/board.png"&gt;&lt;/p&gt;
&lt;p&gt;While degoogling myself, I've also found the blog I wrote during development. You can read it here, in this post: &lt;a href="/treasure-of-the-pirate-king"&gt;Treasure of the Pirate King&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Learning Linux&lt;/h2&gt;
&lt;p&gt;I learned the basics of Linux just to satisfy my curiosity at the age of 11 on a weekly workshop. Who would have thought that I would be working with Linux servers, and one day having Linux on my PC would feel more natural than using Windows.&lt;/p&gt;
&lt;p&gt;My 11-year-old self would have been amazed at the vision of smartphones, Raspberries, k8s clouds and SteamDeck consoles.&lt;/p&gt;
&lt;p&gt;Though I worry a lot about technology being misused, it's refreshing to remember how inspiring technology is.&lt;/p&gt;
&lt;h2&gt;My first PC&lt;/h2&gt;
&lt;p&gt;The first computer I used regularly was an i286 running DOS. It had a black and white display and a large 5.25" floppy drive. On one of my floppies, I had 12-20 games like Alley Cat, Battle Chess, DigDug and Pac-Man clones. My favourite was Space Commanders II. I was 4 or 5.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Screenshot of the game Space Commanders II featuring the player's spacecraft and multiple lines of space invaders." src="../images/spacecommandersii.png"&gt;&lt;/p&gt;
&lt;h2&gt;MSN Messenger&lt;/h2&gt;
&lt;p&gt;I miss MSN Messenger. It wasn't so bad being online only occasionally. And Solitaire Showdown was great too. I liked the simplicity and the graphics too. Seems I wasn't the only one who loved it. I've just come across a remake project: &lt;a href="https://github.com/T1mmos/cards2.0"&gt;T1mmos/cards2.0&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Screenshot of the original Solitaire Showdown game." src="../images/solitaireshowdown.png"&gt;&lt;/p&gt;</content><category term="Personal"/><category term="Python"/><category term="Board games"/><category term="Gaming"/><category term="Linux"/><category term="Post streams"/></entry><entry><title>Degoogling</title><link href="https://blog.gridranger.dev/degoogling" rel="alternate"/><published>2025-03-08T10:38:00+02:00</published><updated>2025-10-12T17:57:00+03:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-03-08:/degoogling</id><summary type="html">&lt;p&gt;Greetings Programs,&lt;/p&gt;
&lt;p&gt;as a first post, I'll create for myself a degoogle checklist to track my progress of leaving the GAFAM behind.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Selection criteria:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;preferably from Europe&lt;/li&gt;
&lt;li&gt;don't cooperate with autocrats&lt;/li&gt;
&lt;li&gt;being open source is a big plus&lt;/li&gt;
&lt;li&gt;being free and open source is even better&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Color codes:
🟥 looking for …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Greetings Programs,&lt;/p&gt;
&lt;p&gt;as a first post, I'll create for myself a degoogle checklist to track my progress of leaving the GAFAM behind.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Selection criteria:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;preferably from Europe&lt;/li&gt;
&lt;li&gt;don't cooperate with autocrats&lt;/li&gt;
&lt;li&gt;being open source is a big plus&lt;/li&gt;
&lt;li&gt;being free and open source is even better&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Color codes:
🟥 looking for ideas; 🟦 testing a candidate; 🟨 not replaced fully; ✅ replaced&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;status&lt;/th&gt;
&lt;th&gt;original&lt;/th&gt;
&lt;th&gt;candidate&lt;/th&gt;
&lt;th&gt;notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Windows&lt;/td&gt;
&lt;td&gt;KDE Neon&lt;/td&gt;
&lt;td&gt;I can also recommend Linux Mint.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🟨&lt;/td&gt;
&lt;td&gt;Android by Google&lt;/td&gt;
&lt;td&gt;/e/OS&lt;/td&gt;
&lt;td&gt;Tried native Linux Ubuntu Touch and Sailfish OSes. This would be the long therm solution but they don't work fully just yet for me. I liked them, but they didn't had all the features I need. I also tried Iodé OS, but it didn't have driver for the main camera. I use /e/OS now.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Android Camera&lt;/td&gt;
&lt;td&gt;Open Camera&lt;/td&gt;
&lt;td&gt;Android Cam is integrated to Google Pics, so it has to go.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Office&lt;/td&gt;
&lt;td&gt;OnlyOffice&lt;/td&gt;
&lt;td&gt;Tried Nextcould, running it on a raspberry constantly is not much cheaper than Proton and that seems to be better. I might pay for Proton once they fixed their Drive. Libre Office was too oldschool for me.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Microsoft Lens&lt;/td&gt;
&lt;td&gt;MakeACopy&lt;/td&gt;
&lt;td&gt;This document scanner seems to be working well.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Chrome / Edge&lt;/td&gt;
&lt;td&gt;Vivaldi&lt;/td&gt;
&lt;td&gt;I moved to Edge, then Ms started cooperate with autocrats...&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;GBoard&lt;/td&gt;
&lt;td&gt;FlorisBoard&lt;/td&gt;
&lt;td&gt;Has better accented letter placement for non-Englinsh languages than HeliBoard.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Github&lt;/td&gt;
&lt;td&gt;Framagit&lt;/td&gt;
&lt;td&gt;Even pages part works perfectly. This very page is hosted there right now.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Blogger&lt;/td&gt;
&lt;td&gt;GitLab pages + Pelican @ Framagit&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🟨&lt;/td&gt;
&lt;td&gt;Google / Bing&lt;/td&gt;
&lt;td&gt;Startpage&lt;/td&gt;
&lt;td&gt;just started to accept Bing, when Ms ruined itself in my eyes. Not perfect as Ecosia uses Bing behind the scenes and Startpage uses Google.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Google Caller&lt;/td&gt;
&lt;td&gt;Fossfiy Phone&lt;/td&gt;
&lt;td&gt;Important: don't disable the default app, emergency calls work only if that is still enabled!&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Google Contacts&lt;/td&gt;
&lt;td&gt;Fossify Contacts + Proton Contacts&lt;/td&gt;
&lt;td&gt;I use Fossify for the phone, Filen for backup and Proton for the mail.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Google Drive / OneDrive&lt;/td&gt;
&lt;td&gt;Filen&lt;/td&gt;
&lt;td&gt;Filen seems to be fine. Proton drive is out of the question until they won't make Pictures accessible on file level.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Google Files (Android)&lt;/td&gt;
&lt;td&gt;Fossify File Manager + com.android.documentsui&lt;/td&gt;
&lt;td&gt;I didn't like FX's UI. If only I could use com.android.documentsui...&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🟥&lt;/td&gt;
&lt;td&gt;Google Lens&lt;/td&gt;
&lt;td&gt;?&lt;/td&gt;
&lt;td&gt;AR translation is important me but I've found no suitable candidates so far.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🟨&lt;/td&gt;
&lt;td&gt;Google Maps&lt;/td&gt;
&lt;td&gt;Here We Go&lt;/td&gt;
&lt;td&gt;Magic Earth worked well but it featured no desktop version. Let's see how the former Nokian map app performs.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Google Messages&lt;/td&gt;
&lt;td&gt;Fossify Messages&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Google Passwords&lt;/td&gt;
&lt;td&gt;ProtonPass&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Google Photos&lt;/td&gt;
&lt;td&gt;Fossify Gallery&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Google Translate&lt;/td&gt;
&lt;td&gt;DeepL&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Gmail / Outlook&lt;/td&gt;
&lt;td&gt;Proton Mail (Plus)&lt;/td&gt;
&lt;td&gt;Noone understands how to spell @tuta.com. Vivaldi mail looked fine, but I don't want to chain myself to a browser again. Proton is capable to download old content from Outlook and Gmail, and that spared me a lot of time.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Facebook&lt;/td&gt;
&lt;td&gt;Mastodon&lt;/td&gt;
&lt;td&gt;that was the first step&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Instagram&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;I don't use it anymore&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🟦&lt;/td&gt;
&lt;td&gt;Messenger&lt;/td&gt;
&lt;td&gt;?&lt;/td&gt;
&lt;td&gt;That's a hard one. It would be nice to move to Signal, but how make my contacts move?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Copilot / ChatGPT&lt;/td&gt;
&lt;td&gt;Le Chat (Mistral)&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Microsoft Authenticator&lt;/td&gt;
&lt;td&gt;Proton Authenticator&lt;/td&gt;
&lt;td&gt;I used Ente Auth first to avoid putting too many eggs into the Proton basket, but Ente is now funded by GitHub (Microsoft), so I had to dump them.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🟨&lt;/td&gt;
&lt;td&gt;PlayStore&lt;/td&gt;
&lt;td&gt;Aurora, f-Droid&lt;/td&gt;
&lt;td&gt;not a full solution but better&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🟨&lt;/td&gt;
&lt;td&gt;YouTube&lt;/td&gt;
&lt;td&gt;Freetube / NewPipe&lt;/td&gt;
&lt;td&gt;not a full solution but better&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Completeness: 82%&lt;/p&gt;
&lt;p&gt;Others will be added later.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;These times offer a unique opportunity for companies. They can decide whether they go for short term profit by serving
autocratic regimes or by praying on those to want alternatives to GAFAM apps. Or they can work for the freedom of all
by supporting those who are looking for solution.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Sites that can help you select alternatives:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://european-alternatives.eu/"&gt;European Alternatives - european-alternatives.eu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.rebeltechalliance.org/"&gt;Rebel Tech Alliance - rebeltechalliance.org&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://framasoft.org/"&gt;Framasoft - framasoft.org&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.chatons.org/"&gt;Chatons - chatons.org&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Tech"/><category term="Degoogling"/><category term="Linux"/></entry><entry><title>Discovering the web-browser module</title><link href="https://blog.gridranger.dev/discovering-the-web-browser-module" rel="alternate"/><published>2025-02-02T15:39:24+02:00</published><updated>2025-02-02T15:39:24+02:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-02-02:/discovering-the-web-browser-module</id><summary type="html">&lt;p&gt;I like that after more than a decade of using Python I can still find something new in it.&lt;/p&gt;
&lt;p&gt;Today I used the &lt;code&gt;webbrowser&lt;/code&gt; module for the first time. It allows you to open URLs in the browser installed on the system. It's not new, but I've never had a …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I like that after more than a decade of using Python I can still find something new in it.&lt;/p&gt;
&lt;p&gt;Today I used the &lt;code&gt;webbrowser&lt;/code&gt; module for the first time. It allows you to open URLs in the browser installed on the system. It's not new, but I've never had a reason to use it before.&lt;/p&gt;
&lt;p&gt;It can be used from the command line or from a script, and is very customisable. You can choose the type of web browser, whether to open the page in a new window or tab, and whether to run in the foreground or background.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Sources: &lt;a href="https://docs.python.org/3/library/webbrowser.html"&gt;docs.python.org&lt;/a&gt;&lt;/p&gt;</content><category term="Development"/><category term="Python"/></entry><entry><title>`partial` and `partialmethod`</title><link href="https://blog.gridranger.dev/partial-and-partialmethod" rel="alternate"/><published>2025-01-30T12:43:03+02:00</published><updated>2025-01-30T12:43:03+02:00</updated><author><name>gridranger</name></author><id>tag:blog.gridranger.dev,2025-01-30:/partial-and-partialmethod</id><summary type="html">&lt;p&gt;Have you ever heard of &lt;code&gt;functools.partial()&lt;/code&gt; and &lt;code&gt;functools.partialmethod()&lt;/code&gt;? I've only recently encountered them in a TkInter home project, although they've been around since Python 3.4.&lt;/p&gt;
&lt;p&gt;I’m sure you're familiar with the concept of &lt;code&gt;lambda&lt;/code&gt; functions (in short: anonymous functions that are declared on-the-fly in the middle …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Have you ever heard of &lt;code&gt;functools.partial()&lt;/code&gt; and &lt;code&gt;functools.partialmethod()&lt;/code&gt;? I've only recently encountered them in a TkInter home project, although they've been around since Python 3.4.&lt;/p&gt;
&lt;p&gt;I’m sure you're familiar with the concept of &lt;code&gt;lambda&lt;/code&gt; functions (in short: anonymous functions that are declared on-the-fly in the middle of your code).&lt;/p&gt;
&lt;p&gt;Well, in general a &lt;code&gt;partial&lt;/code&gt; object is very close to a &lt;code&gt;lambda&lt;/code&gt; function. But I find it more useful. Let's see an example of both.&lt;/p&gt;
&lt;h3&gt;Using them instead of lambda&lt;/h3&gt;
&lt;p&gt;We have a nice TkInter Button and every time we press it, we want to print "Hello World" to the console.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;tkinter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;tk&lt;/span&gt;

&lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tk&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Tk&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Tkinter Button Example&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;on_button_click&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Hello World&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tk&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Click Me!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;on_button_click&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# 👈&lt;/span&gt;
&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pady&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mainloop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Since the &lt;code&gt;print&lt;/code&gt; function needs argument, we cannot use print as the value of the &lt;code&gt;command&lt;/code&gt; keyword argument of the &lt;code&gt;Button&lt;/code&gt;. An argumentless method is needed as an intermediate method.&lt;/p&gt;
&lt;p&gt;Let's simplify it with &lt;code&gt;lambda&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;tkinter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;tk&lt;/span&gt;

&lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tk&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Tk&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Tkinter Button Example&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tk&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Click Me!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Button clicked!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pady&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mainloop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;With &lt;code&gt;partial&lt;/code&gt;, we can do the same.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;functools&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;partial&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;tkinter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;tk&lt;/span&gt;

&lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tk&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Tk&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Tkinter Button Example&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tk&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Click Me!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;partial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Button clicked!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pady&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mainloop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Okay, but why use &lt;code&gt;partial&lt;/code&gt; when lambda is there without any import?&lt;/p&gt;
&lt;p&gt;Well, &lt;code&gt;partial&lt;/code&gt; objects seem to be slightly faster since &lt;code&gt;lambda&lt;/code&gt; functions are different objects at each time they are executed, while &lt;code&gt;partial&lt;/code&gt; objects stay the same "frozen" variants of existing methods.&lt;/p&gt;
&lt;p&gt;They are also easier to read and debug then &lt;code&gt;lambda&lt;/code&gt; expressions. At debug time, you can look inside the &lt;code&gt;partial&lt;/code&gt; as a normal object and access the body of the underlying function, documentation, etc.&lt;/p&gt;
&lt;h3&gt;Using them as aliases&lt;/h3&gt;
&lt;p&gt;You can also use &lt;code&gt;partial&lt;/code&gt; objects to create aliases to function or method calls with the same argument set, make your code more organized and readable.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;functools&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;partial&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;print_my_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;hr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;partial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;+-----------------------------------+&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;hr&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;hr&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;hr&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Inside class definition&lt;/h3&gt;
&lt;p&gt;The same effect can be achieved within class definitions. This is where &lt;code&gt;partialmethod&lt;/code&gt; comes in. The sample class below will have 4 fully functional methods, but half of the lines can be saved.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;functools&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;partialmethod&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;ToggleExample&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;_set_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;
        &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;State is now:&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;turn_on&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;partialmethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_set_state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;turn_off&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;partialmethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_set_state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;toggle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;partialmethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_set_state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Faster to type and cleaner than defining them one by one, and runs faster and is more readable and easier to debug than &lt;code&gt;lambda self: self._set_state(True)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I've also found a &lt;a href="https://stackoverflow.com/a/78491128"&gt;example&lt;/a&gt; with generators where &lt;code&gt;partial&lt;/code&gt;'s behavior was more predictable than that of &lt;code&gt;lambda&lt;/code&gt;'s.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Sources:
🔗 &lt;a href="https://docs.python.org/3/library/functools.html#functools.partial"&gt;partial&lt;/a&gt;
🔗 &lt;a href="https://docs.python.org/3/library/functools.html#functools.partialmethod"&gt;partialmethod&lt;/a&gt;
🔗 &lt;a href="https://stackoverflow.com/questions/11828410/differences-between-functools-partial-and-a-similar-lambda"&gt;python - Differences between functools.partial and a similar lambda? - Stack Overflow&lt;/a&gt;&lt;/p&gt;</content><category term="Development"/><category term="Python"/></entry></feed>