KaliTrue’s first update

Well, it took longer than I expected, but within the next few days (today is November 18, 2025) I will be releasing my first update to the KaliTrue app, my iOS (iPhone) app to assist people in calibrating their displays so that they show accurate colors.

So the best way to show the changes is to show you a comparison of the old vs. the new. So, here’s the old “Main” screen:

And here’s the new version:

There’s a couple of things to note here:

  • The target white-point can now be shown – in the example, you can see “Monitor/Display” as well as an icon of a monitor. You can choose from showing just the text, just the icon, both, or none.
  • The animation that plays when you’re measuring now looks more like a target… the old one was supposed to convey a “display” but it fell short of that goal, and I felt a “target” would be more appropriate.
  • The menu at the bottom now supports Apples Liquid Glass.
  • The change people should be most excited about is that the app now shows measurements in tenths-of-percent, as compared to whole percent values in the old version. This will make it easier to see the effects of changing the color settings on your display.
  • The old version considered anything better than 97% as calibrated. The new version now lets the user select the desired accuracy, in tenths percent, from 97% to 99%.

Now let’s see the old “Settings” screen:

And now the new one:

Note there are now two new settings:

  • White Point Display – lets you choose how to display the target white point
  • Maximum Deviation Considered “OK” – Lets you set, in tenths of a percent, the desired accuracy considered to be calibrated, from 97% (the default) to 99%.

I’m excited to be releasing this update, and I hope my users are too!

An Open Letter to Aggressive Men

I originally posted these thoughts to FaceBook on November 10, 2013, nearly 12 years ago, but it may be more relevant today, so I’m re-posting.

A few nights ago, something happened to me that is still bothering me days later. I was driving along the roadway, and I needed directions to a gym I knew was nearby. I pulled up alongside a female pedestrian in my car and called through my passenger side window, “Excuse me, can you help me?” She turned away and sped up a little. I didn’t realize at first why. I matched her walking speed and called again, this time a little louder… “Excuse me, can you help me?”  Suddenly, the reason she was ignoring me was clearly conveyed by her body language… my pulling over alongside her, on a dark street, had somehow made her very, VERY nervous.

I felt bad. I felt bad for her because I had a hunch why she was nervous. Here was a loud, large male, approaching, and nearly “cornering” her. Now the question is, what do I do about it? I could drive away, but then she would be walking home nervous and wondering if this person would drive around the corner and wait for her to walk by.  I decided to try just once to lessen her nervousness and did the only thing I could think of… I called out, “I was looking for the GoodLife Fitness, and I thought it was in this block”. As I did so, I swung my car away from her so she had several “escape” routes… conveying friendly body language as well as one can using a car. She seemed to relax right away and said, “Oh… sorry…. it’s back the other way, one block”. I bid her good night and left. I wanted to get away from her and let her forget how she felt for a brief moment. It was a horrible feeling.

Earlier this year, I was walking to my car, which was parked a few streets away. A few seconds after I passed a female walking in the other direction, I realized I had forgotten my laptop and decided to go back to my house and get it.  I turned around and broke into a run. My sudden direction and speed change must have been taken for aggression by the female, because she let out a sound that can be best described as one of fear and began to run, all the while looking back at me. I stopped my run immediately and waited for her to “get away”. I said nothing. What could I say?

These are not isolated incidents. I have had women react this way to me before when they are alone. And I know it’s not me. It’s the way some men treat women that has caused this. My being 6’2” and of stocky build doesn’t help.

When I first decided to write this, I felt like I should apologize to women for the behaviour of some of those of my gender who have created this culture of fear. But I have decided that’s not the message I want to convey. That’s not the correct audience. This letter needs to be directed at the ones who have caused this problem.

So this letter is to you men who hit women, you men who don’t treat women with respect and dignity, I am pissed off at you. I am pissed off because you have not only made it impossible for many women to feel safe in what should be innocuous situations, but you have made it impossible for men who aren’t assholes to break into a run or ask a young lady for directions. You have created a culture of fear and distrust. You have sullied the reputation of my gender, and I am sick of it.

Now many of you may be thinking there are aggressive women too who have contributed to this culture of fear, and I say, yes, I guess that must be true to some degree. You may also point out that there are some males who because of their smaller stature or physical appearance or even their mannerisms may also experience fear and distrust of their own gender. But I am tired of the “yes buts” being used to counter an argument. I am not going to let you diffuse this one that easily. The unfortunate truth of the matter is that there are still far too many men who display aggression in situations where aggression is not appropriate, and those men are ruining it for the rest of us who are decent, reasonable folks.

We’ve had enough. The women who don’t feel safe answering a stranger’s query for directions have had enough. And not just women… this one is for the children who learn fear from witnessing their moms’ abusive boyfriends and fathers’ behaviour; this one is for the slender male who doesn’t feel safe walking home at night; this one is for the transsexual who has to deal with these situations and much, MUCH more; this one is for the gay man who does not feel safe walking home alone from the gay bar.

All these groups and all the decent men too are a huge majority to your minority. So to you, Mr. aggressive “man”, the decent men of this world have had enough of your crap, and it’s time for you to think about what it is that defines a “real man”. I’m going to help you with it. A real man is one who knows he’s accountable for his actions. A real man is one who knows how to control his anger, his rage, his behaviour, and how to communicate with another human being to resolve a situation. Real men are not bullies. It’s time for you to grow up and become a real man. If you want to show the world how truly strong you are, showing restraint and control in all situations is the best way to do it.

As I write this letter, I know it’s mostly only going to be seen by those who already know all of this. None of the men who need to read this letter will ever read it. And even if some of them did… would it really make a difference? Here again, thanks to the behaviour of a few, I feel powerless, helpless. I wish I knew what I could do to change this situation.

What’s up with Jamie’s state of app development?

So just a quick update… yes I am still developing apps! My first app has already been released, https://KaliTrue.app is the page to check it out and there’s a link there to get the app.

Since releasing the app a few weeks back I have taken some quick staycation time with my spouse… we got to spend a long weekend at the inaugural https://guitarsandgasoline.com music festival and that was a lot of fun. I got to celebrate a friends 60th birthday, and I am jealous he only looks 45. I got to spend some quality time with my camera… lots of flower pics mostly! And I have also been doing some administrative tasks for both my business and my spouses.

But in the back of my mind is/was always “what’s next?” Do I start work on the paid version of KaliTrue? Do I start another app? I have kind of been thinking of doing both at the same time, which would be interesting.

I’m honestly doing a lot of thinking about what my next app should be. In terms of making money as an indie dev, games are the gold standard… they make the most money, but I have never been a gamer myself and I think that puts me at somewhat of a disadvantage. Also, games would probably benefit from UIKit and I have been focusing on SwiftUI (in English? My focus has been on a framework that is less suited to games.)

The next best way to make more money is to charge a lot for a niche app… but nothing comes to mind, and it’s not a guarantee.

So I find myself constantly thinking…. what should my next app be. I have a small list that I add to when I have an idea, and occasionally I triage the list and throw out ideas that–for one reason or another–are not worth pursuing even if the idea itself is solid. For example, ideas that have a very narrow appeal, or ideas that require huge development effort… think 12-18 month projects.

And so, I keep thinking…. day-and-night… what to build! And this is where you come in I guess… I have asked before of my friends and fans… what app idea do you have that you would like to see built? I’ve had several friends and family come up with ideas, but more than half have already been done, and done well enough that it’s not worth the time risk to try an improved implementation. And besides, I would prefer more unique ideas.

But hey, if you have an idea, shoot me an email at my business quick-contact email: labs_clothes_5l@icloud.com and we can talk. If you wanna just throw me an idea and I take it on wholly, then you get credit and maybe even an honorarium. If you want to get more involved in the process… helping me design it… taking on the marketing of the product… then we can make a partnership arrangement. I have already been talking to two parties about ideas, one where I am little more than that coder and if it works out they stand to make the bulk of the money.

So… get your brain in gear and think… what iPad, iPhone, or Mac app do you wish existed?

I published an app!

I did a thing!

I wanted to name this post “I did a thing™️“, in honor of the person who introduced me to the phrase, Jeremy Clarkson. He often uses that phrase when he does something, especially some easy thing so many other people have done before him, and which are a bigger deal to him than to anyone else. But alas, I am also marketing myself and my apps, so I had to be less stylistic and more professional. I promise, resisting the urge to appear clever was not easily executed.

So as a lot of you already know, on Valentine’s day 2025 I wrote the first line of code for what was to be my first app (iOS app to be specific.) Well, yesterday, June 3, 2025 I released that app, and you can see its web page here: https://KaliTrue.app

But while that’s something that makes me happy, I would like to talk about the process a bit, because while many of you get that accomplishing a goal should bring happiness, the entire process of working toward that goal brought me happiness. As I wrote in a version of this post when I started “… and I’ve been having the time of my life since then, working on that app every day. Yeah, even on weekends… even if only for a few hours. More than once I have found myself glancing at the clock only to find out it was already working on the beginnings of the next day.”

My friends became concerned that I had not taken a break in the first 5 weeks, and that I might “burn out”, so I did finally take a day off. After that I decided that unless there was some pressing reason to work weekends, I would take them off, and for the most part I got better at taking breaks. Well… I took breaks from coding, but I often found myself investigating ideas, looking for new techniques… just exploring the field… but that is my idea of taking time off… more of a shift from one thing to another related thing, rather than a complete break.

April came, and with it some non-coding duties had accumulated to the point where they needed to be addressed, so I was forced to take some time off. It was a bit of a whirlwind actually… broken water heater, half-installed (and leaking) dishwasher, and helping out a friend with a move… April just didn’t exist as far as my project was concerned!

And then in May I got back to it and like I said, yesterday, I finished! My new app, my first app, is now live. It has a web-page: https://KaliTrue.app where you read more about it, and will also find a link to download it for your iPhone, should you wish to do so!

I was surprised by the amount of administration the whole project involved. Forms for taxation, not just for Canada, but for some other countries as well. Forms for export compliance. Documentation on my privacy policy. Declarations about the safety of my app for kids… good news, my app has a 4+ rating so looks like I am good on that, although if your 4-year-old enjoys using my app, an app designed to help calibrate displays for color correctness, then you may want to enroll them in some kind of gifted program and get them off the computer!

Despite the paperwork and related admin, I enjoyed the whole process… and today I am just cleaning up some post-release tasks. Marketing mostly… putting links to my work where I think they might drive people to download it. This weekend I am taking a vacation with my spouse… who is also a small business owner. We’re going to a music festival.

And then, starting next Monday I will begin writing code again. Some code to improve my KaliTrue app, maybe preparing the paid version (don’t worry, there will always be a free version and I will never make previously free features and content paid), maybe working on my next idea…

Ahh, who am I kidding… the dishes are done, festival tickets picked up, clothes for the festival washed and folded, social media posts done… maybe I can do a little work on the next app today…. <Jamie wanders off to write more code>

Thanks to….

I would like to give a special thanks to the people who supported me through this. Family. Friends. Other developers who welcomed me into their clubs, especially Ottawa CocoHeads and iOSDevHappyHour. Educators who share their knowledge, but especially educators Sean Allen and Paul Hudson, the latter being the creator of, among other things, the excellent (and free) online course 100 Days of SwiftUI.

I would like to especially thank Ben, a fellow developer with so much experience I will be honored the day I can call him a peer, who offered to review my code and provide feedback, for free. I expected a simple “yeah, you’re on the right track” at best… but what I got was an itemized breakdown of all my code… professionally reviewed, without judgement, and with an eye to helping me improve. And yes, followed up with an encouraging “you’re on the right track”. I don’t know how to thank you enough, but I will keep my promise to pay-it-forward.

I’d like to specifically thank a handful of people in my local iOS group, Ottawa CocoHeads, but I can’t recall specific names, and the chats on our chat server have long expired. I promise to do a better job in the future to document those who selflessly gave me their time.

And finally, I would like to thank my beta testers, who humored me through this process and patiently tested 21 releases of my app! Five of you were anonymous, but 13 of you were not, and I owe you all a debt of gratitude. Thanks to:
• JP (my patient spouse and financial backer)
• Carmen (my first official–and professional–tester!)
• David (who also helped me with accuracy testing)
• Dean (who became not only my surrogate “average user”, but the idea man I didn’t know I needed. Dean helped me nail down the design of the most visible part of the UI early in the process. Dean also asked a lot of tough questions that led to a better product in the end)
• Doug (who also inspired me to do my very best, especially for my documentation)
• Ira
• Jeff (who patiently suffered through way too many “how about if I did this” questions, accuracy testing, and “should I be going indie?” chats)
• Mark
• Miguel
• Phil (also a great mentor!)
• Richard
• Rob (who could ask for a more supportive brother)
• Russ (not an app tester, but a tester of much of my infrastructure… an equally important role)
• Tom

Rename my app or not? (The “fallout” phase)

Well, I have taken some time to think about how to handle the issue with the naming of my app (see my May 13 blog entry if you want more detail) and I can basically proceed in one of two ways:

  1. Register the .app domain for my app with the existing name, i.e., keep the name I have been using since I started writing the app
  2. Find a new name and begin the work of re-branding, including acquiring domains

So, I could register the .app domain for my app with the existing name. This approach would be incredibly simple, but it would not be straightforward. As I mentioned, the .com domain is already registered, and by a startup that is branding themselves with the name. Even though they beat me to the name by just a few months, they did beat me fair-and-square. They have not, however, registered the .app domain, leaving anyone free to do so for now. So I could register it for myself, for my business, but using that name comes with a risk.

If their business succeeds, then as they grow there might come a point where they will notice I have their name registered as a .app domain and would have a good chance of forcing me to stop using the domain, especially if they decide to trademark the name (they haven’t yet). It’s too late for me to trademark it as they have “prior art” and would easily be granted the rights in court… and besides, I honestly feel grating the .app domain would be a crappy thing for me to do.

And even if I did grab the .app domain, I would always be in a risk position where they could come after it at some unknown point in the future, and then I would be forced to re-brand anyway.

And then there’s the professionalism consideration. I too am starting a new business, and willfully deciding to use another business’e’s name as the name for my app should be a warning sign to my future clients that I either lack competencies, or worse—I might be unscrupulous.

Even if I do re-brand, I could still register the current name as a .app and sit on it, hoping to someday sell it back to the business to cover my costs for my domains, but that just doesn’t feel right either, and I feel it sends the wrong message about what kind of businessperson I am.

So this means that I am going ahead with the second scenario, finding a new name and then begin the painful process of re-branding the app, only this time I will know to grab the .app domain! 

This situation is just one in the adventure that is starting your own business. This lesson I learned from the school of hard knocks… I’m creating this business on my own, using skills I have acquired on my own over time. Had I professional training in starting a business, such as an MBA, or a mentor, sure I might have avoided this minor setback, but I don’t have formal business training nor any mentors, but this is how I have done plenty of things in my life, and it’s a process I actually enjoy, and am confident I will succeed in this endeavour, as I have in the past doing things “my way”. The more than three decades of success I have had as a self-taught software developer, having even held engineering roles in several Fortune 100 companies, helps me justify that confidence.

I’ve already begun the search for the new name, but now I am faced with another decision… do I register the .ca and the .com domains as well, or just the .app domain? These domain names cost money, incurring an ongoing annual cost, a cost I am not expecting to recover from sales of my first app… so I need to do a cost-benefit analysis to determine if the .com and .ca are worth it… I guess I will begin that process after I decide on the new name! 

UPDATE! I have a new name – KaliTrue, and a new domain as well, KaliTrue.app

My App Name is Taken! :(

(TL;DR I am renaming my app soon… and please sponsor my friend!)

I owe my friend Grant a debt of gratitude… and you can help me thank him by sponsoring him in “The Friends for Life Bike Rally”, which I mention at the end of this long message.

So today, May 13, 2025, I was on Facebook Messenger catching up with a friend I had last spoken with going on six months back! We both have a passion for cycling, and he’s participating in a fundraiser this summer, and I asked him to ping me when the event gets close as I might wish to volunteer.

He started the chat with the obligatory “how have you been” and I responded that things were going well, and I have been busy working on my first iPhone/iPad app and was excited to be in a position to publish it soon. He responded with excitement, writing “You’re doing an app? Cool!” so naturally I wanted to send him a link to the project page. Since I was walking at the time I didn’t have the link handy, so I figured I would just Google “MoniTrue” (the app name) to get my project page and send him the link. That’s when my day changed….

You can imagine my horror/surprise when that Google search landed me on a website, not my own, using the name MoniTrue! I was gutted. My first thought was this means someone had “stolen” my app name, surely, as I had done what I had thought was a sufficiently thorough search back in the spring… to be sure I was choosing a unique name. Sure I found some hits on the word… a gamer’s profile, a service in another language… but no one was using MoniTrue as a business or product name.

My plans for the day had just changed… I would now have to either find a new name, or go after the person using “my” product name, using my existing project page to prove “prior art” and hope they would surrender the name rather than having to get involved in a legal fight. Then I looked closer.

I checked the registration date for their domain, and found out they beat me to it—possibly by just a few months. There would be no fight… they had the prior art… they owned the name, meaning I would now have to find a new name for my app.

Of course I now wanted to understand how this happened… how did I miss this? Well, it turns out the domain name did have a history going back to 2014 when it appears to have been a Russian file sharing site! It appears to have been abandoned after that and squatted until 2022, finally being re-registered by a business in 2024. It’s had so few changes since then it’s still not in the Wayback Machine, and only recently has it shown up in a Google search! When I checked Google, it didn’t show up because Google had not yet indexed it.

I have learned my lesson! When vetting a business or product name, don’t just Google it, but check for the domain as well! I should have known this, but such are the growing pains of business proprietorship. Thankfully I learned this valuable lesson early in my journey… and thankfully I had only invested time into this endeavor.

So now I am spending the day coming up with a new name, and then re-branding the app and everything associated with it. Sigh!

And despite this setback, I am grateful to my friend Grant for accidentally causing me to discover the issue! And so, to thank him, I am asking those of you that have the means to do so, to donate to his fundraising effort by sponsoring him!

He’s riding in “The Friends for Life Bike Rally”, which is “the only volunteer-led ride that brings people together for an inclusive, supportive, and life-changing challenge that inspires much-needed help for people living with HIV/AIDS in Toronto, Kingston, and Montréal.”

If you would like to sponsor Grant, please go to this link which will forward you to his fundraising page: Tinyurl.com/Grant-2025

And now I have to go… I have to think up a new name for my app!

UPDATE! I have a new name – KaliTrue, and a new domain as well, KaliTrue.app. There is also a followup to this post which you can find here.

Thoughts on managing oneself as an independent software developer

When I worked in the corporate world, I would sometimes be sent for training. Mentally, I put the training in two categories:

  1. Training HR wants us to take – includes everything from diversity to hazardous materials handling, but never *directly* related to the task of programming. Usually “soft skills.”
  2. Training to make me a better programmer – from programming languages to support tools.

Let’s talk a little about category 2.

As an independent developer, I now see this category in a completely different light! I used to look forward to such training… an opportunity to make myself a better programmer. My company paid for this training… something I appreciated, but until now I never realized they paid for it in two ways:

  1. Financially – my employer took on the financial burden of my training.
  2. Logistically – my employer took on the schedule hit of my training.

Now that I am independent, I feel the financial hit directly. I always knew there was a financial component to employee training, but it becomes very real when one has to spend money on their own training.

But I am also feeling the “logistical” hit. It is something I was never completely aware of as a corporate developer. My team/project lead took that on. They had to make room in the schedule for this training, for me and every other developer… time that they were *not* developing. Ideally, the training would make the person a better developer, and the schedule hit would be made up in increased productivity… but therein lies a question: how to choose what to train for and for how long, to have a net positive outcome! 

Do you send your employee off to a 2-year program to make them an expert in all things Python (or Swift, or C++)… or do you send them to a one-week boot camp to become better at multi-threading… with multi-threading being the current hot issue in your project.

The answer is obvious… you get your employees trained to fill in the gaps in their knowledge that equate to the gaps in your projects’ immediate needs. And if you’re a good manager/leader, you develop a feel for this. You identify the gaps that would most benefit from employee training, and you also identify the employees who will bring you the most value should they receive said training.

This is a dance I am learning now, but the dance floor is a bed of hot coals! As project lead, I am pushing for delivery of that last 10% of the code to get to v1.0, and in so doing, I am seeing gaps in my team’s skillset (this past 2 weeks it’s been Swift 6 new concurrency model) and having to determine how much I need to improve the team’s comfort with that skill to move forward with the project. Except I am also the development team… and I love to learn… so when I sat down to better my knowledge of Swift Concurrency (especially in light of Swift v6 improvements in that area), I wanted to know it all.

And so it comes back to a recurring theme for my new role as an independent software developer… how do I fill the roles that used to be provided for me through the corporate structure? It’s meant I have had to learn to be an architect, a team lead, a project lead, a manager, a technical writer, all while continuing to get better as a developer in a new (to me) language on a new (to me) platform.

It’s been fun for sure… but it’s also helped me appreciate just how much goes into the creation of a software product. It’s a life cycle, and I continue to learn.

Why do Jamie’s apps use American English?

The KaliTrue app is the first app release by me, Jamie Cashin, who happens to hail from Canada. So why then does the app contain American English terms such as “color” where one might expect a Canadian to have used Canadian English terms such as “colour”?

Well, this is a decision taken by me for many reasons and since you’re reading this article, you must be interested in my thinking. If so, please read on!

For most of my career, I worked in the embedded space, meaning no one could directly see the results of my work. If you’re not familiar with the term embedded, let me simplify it for you. Most of the software I have written (up until the spring of 2018) would inspect values in hardware, or react to changes in values in hardware, and then take some action based on that. For example, I might have written code that monitors the temperature reported by some sensor, and when that temperature drops below a certain value, my software modified another value to tell a heater to turn on. There was nothing displayed to an operator… the software I wrote lived deep in the bowels of some machine.

My work was just part of a larger collection of software, shared among many developers. To make it possible for many people from various backgrounds to work efficiently on the same software base, it is common to standardize on English as the common language, and in particular, American English. If you were not aware, computer languages are just that… languages, and they enable programmers to write human-readable code, when a computer then translates to its own internal language, a set of specific instructions which the computer is then able to act upon, or “execute”, as we say in the biz.

So let’s say we have some code that when things are cold, it turns on a heater and makes a lamp red, and if things are normal it turns off the heater and makes the lamp green. This code might look something like this:

let currentCoolantTemp = getTemperatureOfEngineCoolant()
if currentCoolantTemp < 5 {
  coolantHeater(on)
  setLampColor(blue)
} else {
  coolantHeater(off)
  setLampColor(green)
}

Do you see the setLampColor part? Yeah, one might expect a Canadian to have written that as setLampColour, but because the software development team normally consists of people from all over the world, American English spelling is preferred to avoid confusion. It also makes it easier to find things in the code later… you only need to search for one term such as color or neighborhood, rather than color+colour or neighborhood/neighbourhood.

In 2018, through a fun misunderstanding I should blog about some day, I found myself in what’s known as the UX domain. UX is short for User eXperience, but you may have heard the related term GUI or UI for (Graphical) User Interface. Working in the UX space was a whole new way of thinking for me! For the first time in my career, actual people would see the results of my code! For example I might have written software that presented a screen to a driver, which would let them change the color of the lighting in their vehicle. The screen might therefor present text to them like so:

Your lighting color is currently Red

Again, the underlying software might store the current colour internally in a variable (a storage bucket) named currentColor but that is independent of the spelling presented to the user! And yet again, the value was presented with the American English spelling, color.

Now the reason for using American English for presentation to a user is probably easier to understand. The first version of most apps is written to present things in a manner palatable to the largest number of users (customers) and this usually means American English. Sometimes this ends up being the only version available, and Canadians, Brits, and the French all have to understand what “color” is.

Now it is possible to localize your app… where you as the developer provide translations for all the text that gets displayed to the user, into other locales. This can mean a simple variant on English, such as Canadian or British English (colour), or other languages entirely… couleur for my French friends!

And so we’re back to the original question… why will my first app be released initially American English, and why will all my future apps do so as well? Because of “market share”. You see it’s a simple fact that most of the people who will install my apps are American… so it’s wise for me to give them what they expect. Especially when non-Americans are so used to dealing with American English. This is where my customer base is… it pleases the vast majority of my customers.

So that answers the question… but you may now be wondering, well, what about my Canadian, British, French, Ukrainian, Mexican, Australian… and all other non-American customers? Don’t they deserve a more localized experience? Well, yes, of course they do! But the truth of the matter is I have to balance my development time between new app development, new feature development on my existing apps, bug fixes, and localization, and all these things take time! As unpalatable as it seems to you, and I agree it’s unpalatable, I will usually have to defer localization of an app to work on what pays the bills: new apps, and new features or bug fixes to profitable apps.

So there you have it… I have not “given in” to Americanization. Instead I have recognized the need for a small dev shop to prioritize work in order to maximize profitability. It sounds shallow, but as much as I truly enjoy the process of writing software, I can only do so if I continue to pay the bills, so localization (unless you’re willing to pay me for it!) takes a back burner.

Take care, and thanks for reading!


†Speaking of paying me, yes, I am available for hire or contract, and yes I am willing to talk to you about collaborating on your app idea! You can message me from my LinkedIn profile and you can find my socials linked from JamieCashin.com

I did it… I used AI to write code :(

My sad story

Sigh.

I feel so dirty.

I finally did it.

Yes, I used AI (ChatGPT) to write code.

Still with me? Good, because I would really like to explain myself!

So I have this backup drive that I’ve just been dumping files to for years, and I wanted to re-purpose the drive, possibly moving some of the content into the cloud. Because the drive had become a dumping ground, it contained many duplicates, i.e., multiple copies of identical files, so my first task would have to be identifying and subsequently removing duplicate content. While I knew this task would be massive (there’s 2.4TB of data), I am a software developer and so it was natural for me to write scripts to simplify this task.

The first thing I needed to do is—for each file on the drive—compare that file to all the other files on the drive to find any that were exact duplicates. Directly comparing the files to each other would be very time-consuming, so I needed to find a more efficient way. If only I could—for every file—generate some kind of fingerprint that —for all intents and purposes—could uniquely identify the content of said file.

Well, fortunately, there is a command-line tool md5sum that, given a file path, calculates a 16-bit value based on the content of the file. This 16-bit value, expressed as a 32-character string, behaves just like a fingerprint, uniquely identifying the file content such that two identical files (clones of each other) will generate the same md5sum, and this happens irrespective of filename!

Now there are other ways to generate this fingerprint (sha, for example), but I needed something that was extremely fast, while still having a low probability of collision, i.e., two different files having the same md5sum value. Well, md5sum is not only very fast, but the generated fingerprint has a near-zero probability of collision at just 1 in of 2^128 (see more at the end of this post).

Despite being fast, md5sum does have to perform some calculations based on the entire contents of each file, and all 671,406 files comprising 2.4TB resided on a very slow external drive, a 5,400 RPM physical disk, connected via USB3. Generating the file listing the md5sum and filename of every file on the external drive took a long time… I started it around 3 p.m. one afternoon and it was still running when I went to bed, but it was finished by the next morning.

Now I could take the results, a single file listing the fingerprint and pathname of each file on the external drive, and for each fingerprint, check if there were any matching fingerprints, and if there were, record the names of the duplicated files. I was able to implement this as a bash script, complete with progress reporting (so I could watch it run), in about 15 minutes, including testing it against a subset of data, manipulated to test all execution cases. Armed with my new bash script, I ran it against my data and while I was happy to see that it worked, I was sorely dismayed by its performance. It was taking nearly 3/4 second to process each file… that would take more than 7 days to finish!

Now I will admit my bash script could stand some improvement, but I knew that python could easily outperform bash task-for-task, so I decided I needed to rewrite my script in python. My relationship with python is interesting. Unlike other languages where I have tried to master, python has remained as something I feel I am still learning… when tasked with writing something in python, I take more of a “let’s get it to work” approach. This comes from the disposable nature of much of the python I have written… as with this exercise, I often write a python script to resolve a particular issue, use it, and then have no need for it any further. Sure I have written many “designed” or “engineered” python scripts, but more often than not, python is little more than a way to create a disposable tool.

And now I can get to the point of this post… here I was, with a bash script, that while working fine, would take days to complete its work. I knew that even though it was disposable, it was still worth the effort to write an equivalent python script to get my work done in a more timely manner. So I fired up vim and started to write the equivalent python script, and then it hit me: why not ask ChatGPT to take my bash script and convert it to python. It was worth a try, right?

I opened ChatGPT, typed “Convert the following bash script into python” and then pasted the bash script into the prompt, and pressed ENTER. In less than 15 seconds I had ChatGPT’s response… which I copied and then pasted into a file on my local drive, naming it doit.py. I expected I would have to do some work to get it working, confirmed by the fact that ChatGPT didn’t suggest the #!/usr/bin/python3 hash-bang to make the file executable natively rather than invoking python on the script. I fired it up and…

It just worked! No debugging… no futzing with it… it just worked. And it was much faster than the bash equivalent!

Now I will admit that yes, while it was faster, about 10 times so based on my wet-finger profiling of it, it could still benefit from some tweaking to make it even faster. But that was not the point of the exercise. The point was, could ChatGPT generate a python script from my bash variant, that was at the very least a good start? Yes, in this case it certainly could. Does this mean I will always have this trouble-free experience? Maybe not, especially as this test used a very simple bash script.

But I decided to see if ChatGPT could do better. I added “Can you rewrite it to make it faster” and it converted my script to use what’s known as a dictionary (something I was surprised to notice the original did not do). The new version finished in 0.68s. That’s quite an improvement over 7+ days!

But was this experiment a success? Yes, it most certainly was, and it motivates me to use this technique again, at least for my own personal needs.

Would I use this in a work environment where I am being paid to develop code? At this point, probably not, but probably not for the reasons you’re thinking. The main reason I would be uncomfortable using this in a work environment would be down to intellectual property ownership. I’m not going to take the intellectual property of my employer and paste it into ChatGPT… but for use at home, this capability is promising. My reticence to use this for commercial code would be mitigated if my employer had a locally running instance of some coding AI model, but that’s a topic for the future.

My experience with using ChatGPT to generate code, albeit driven by debug code I had written already, is very positive. I’d be interested to see how this is being used by others so feel free to let me know if you’ve done similar things or your company has embraced this idea.

Bonus

Bonus – how reliable is md5sum at generating a unique fingerprint for a file?

How confident am I that the 32-character value md5sum generates will be sufficient to uniquely identify the contents of a file? Well, the probability of any two hashes accidentally colliding is roughly 1 in 2^128.

But what is 2^128? Well, it’s a lot… specifically, you would have to compare 340,282,366,920,938,463,463,374,607,431,768,211,456 unique files for it to be likely that just two would have the same checksum!

For those wondering, 340,282,366,920,938,463,463,374,607,431,768,211,456 in words is:

  • Three hundred and forty undecillion,
  • two hundred and eighty-two decillion,
  • three hundred and sixty-six nonillion,
  • nine hundred and twenty octillion,
  • nine hundred and thirty-eight septillion,
  • four hundred and sixty-three sextillion,
  • four hundred and sixty-three quintillion,
  • three hundred and seventy-four quadrillion,
  • six hundred and seven trillion,
  • four hundred and thirty-one billion,
  • seven hundred and sixty-eight million,
  • two hundred and eleven thousand,
  • four hundred and fifty-six.

Credit for the spoken form of 2^128 goes to https://www.techtarget.com/whatis/feature/IPv6-addresses-how-many-is-that-in-numbers#:~:text=So%202%20to%20the%20power,numbers%20without%20resorting%20to%20math.

What’s wrong with Bluesky

Note that this article was written January 14, 2025 and represents the authors experience with Bluesky at and up to that time. Things may change following the publication of this article and the author may decide to revisit this article in the future.

I had high hopes for Bluesky, I really did.

But what is Bluesky you say? Well, paraphrased from the Bluesky Wikipedia article it’s a “microblogging social media service”, similar to X (Twitter). It began in 2019 as a research initiative at Twitter, becoming an independent company in 2021. Development for the social app accelerated in 2022 after Elon Musk’s acquisition of Twitter and subsequent severing of ties between the companies. It launched as an invite-only service in February 2023 and opened registrations in February 2024. It reached 20 million users by November 2024 [which is around when I joined.]

And Bluesky is the first social media platform in my opinion that seems to have gotten so many things right, and from the outset! It allows fantastic control over what content you actually see. You can choose among various “feeds” to control what you see and you can even create your own feeds! “The algorithm“ feed, named “Discover” is one of default feeds, and from my experience it does a good job of suggesting content that should match your interests. There’s also “Following” (I can’t recall the exact name) which presents just the content posted by people you follow. You can also select a content feed that is comprised of things that those whom you follow seem to be interested in–it’s kind of a “show me what my friends like.” And you can delete any feed you don’t want, including the default feeds.

And I have tons more great things to say about BlueSky, including its clean, easy-to-understand interface, the availability of a web-based interface, the consistent look-and-feel and usability across platforms. Yes I could go on, but I can’t continue to sing its praises while knowing it has one major flaw, and that flaw is so egregious that it has caused me to leave Bluesky (for now.) That flaw is Bluesky’s lack of follower control. What do I mean by follower control? I mean your ability to prevent people from simply following you, meaning anyone can add you to their follow list, without your consent.

You may be thinking “well so what, why should I care who is following me… have at it!”  Well, how would you feel if one day a white supremacy account decided to follow you on Bluesky. And shortly after that–and based on that account following you–similar hate groups began to follow you. Before long, you have dozens of unwanted white supremacy followers. And racists. And crypto-buds. You will have unwittingly become a marketer of all the things you do not support.

Sure you can simply block them… but here’s the problem. You see, BlueSky uses what is called a federated model for content distribution. You own your data. Sounds great right? Well, that data includes who you choose to follow, which means that the initial white supremacist account who chose to follow you, well, they own their follow data, and so you can’t ask the platform to delete that association because the platform, by design, has chosen not to interfere with peoples data, mainly since it doesn’t own that data!

And worse, even if you do block them, that block only applies to your experience with them. In fact, anyone can see who you have blocked, and who has blocked you just by entering your profile on clearsky.app. They don’t even have to be a member of Bluesky to do this, nor in fact do they need to provide any tracking information at all! So if someone has an agenda, say to spread their word of hate, all they have to do is check the accounts that they support to see who is blocking those accounts. Armed with this information–a list of accounts apparently opposed to their ideology–they can use that list to bombard you with new followers. And before you think that’s difficult, the tools to so are already available, and simple to use! They can simply add you to what is known as a “starter pack” which is a list of accounts packaged up so that anyone can follow all the accounts with just a few clicks. They can create and publish this list, and there’s nothing you can do about it. And so their followers—and yes, bots—can target you (and other like-minded people) specifically. Essentially, the tools are out there to profile you, and target you, for good or for bad.

Still think this is just alarmism? Well, after being a member of BlueSky since November of 2024 (I was a very early adopter), it wasn’t until I started posting regularly in early January 2025 that my followers list started to grow quickly and I soon noticed it contained many accounts whose ideologies I do not support, pretty much as I describe in the scenario earlier. Realizing this I decided to “curate” my followers list which was easy at first, but within just a week I found I was spending more time curating my followers list than I was actually consuming content! This was a problem, and it’s what lead me to investigate it, and subsequently it’s what motivated me to leave, and to write this blog entry.

So as mentioned, I did some investigation on this and found many interesting discussions, but I would like to draw your attention to this one: https://github.com/bluesky-social/social-app/issues/1160#issuecomment-1677642129 

“This is something we’ve discussed pretty heavily internally — we don’t yet know how to do it reliably.

The issue is that every user controls their own dataset. When I “follow” somebody, what I’m doing is publishing a follow record on my account. When I block somebody, same thing: I publish a block record. A block record can override the behaviors of a follow record, but it can’t force-remove the follow record from somebody else’s repository

We have discussed a voluntary removal of the follow record. That is, if somebody blocks me, my server automatically deletes my follow record. The only concern is that it’s impossible to force. A server that’s misbehaving (intentionally or not) wouldn’t delete the follow record, so there would be some confusing scenarios where soft-blocks don’t work. That led to some discussion of whether we could try to enforce voluntary behaviors by social pressure (eg “Follow the protocol or your server will be penalized”) but we haven’t established a framework for that kind of governance yet so we’re hesitant to move forward with it.”

So as you can see, they’re aware of this issue, and that post was from mid August 2023, five months ago and the issue still exists. In fact, Bluesky was opened for general, no-invite-needed availability with this issue still in place, and it’s still an issue as of the time of this writing, nearly two years after invite-only launch.

I’m a software developer, and I can speculate on ways they could fix this, but despite my experience in this area in general, I don’t know the challenges the team face regarding how to fix this issue. More concerning to me is that I have yet to be able to determine their timeline for fixing this issue, including if they intend to fix it at all! And I am not alone in my concern… see github bluesky-social social-app issue #1160 for the ongoing discussion. I have followed this issue so that I can update this blog entry should there (ever) be a resolution.

So here we are. Bluesky… so close, and yet so far! I love everything about it except this one issue, and until it’s resolved, I can’t be a member.

Sigh.