Category Archives: Notes

September 27, 2025: Weekly Notes 2025/15

  • According to https://plantaddicts.com/are-lantana-poisonous/ and https://www.youtube.com/watch?v=x0Ecq1O_lzM and seeds and other parts as well are poisonous.
    • This plant is now ubiquitous — its everywhere in my neighborhood. Kaalu likes to eat its leaves. Ookie is fond of its green berries. Now, I am alarmed and thinking of cutting down most of them in my neighborhood.
  • Replacing the AMT unit of my Tata Nano XTA will cost me :rupee:1,30,000 which is a bit crazy. A local mechanic Gajendra (Vinayaka Motors) seems to found a cheaper solution which is affordable. Let’s see how it goes.
    • Nano is getting a bit smaller for me now. I usually travel with 3 people (including me), one medium size dog and luggage. Nano is barely enough. I am looking for spacious car with good safety rating. Looks like Tata Tiago may be a good candidate.
    • I did some browsing on https://www.spinny.com/ and OLX for comparing prices of second hand cars. Spinny is a good place to buy a car but for selling. I’ll probably sell Tata Nano XTA using the mechanic and buy one from Spinny. I am still not buying a new car!
  • I am at age when the proverb “can’t teach an old new tricks” is more and more applicable. Also working with a different age group is becoming a challenge since weights on values changes with age. The young can spend 10x time on the a task due to bad planning or execution, redo is four time, waste a lot of time and still declare it a “win”. I guess it is what is it 🤷🏾.
  • How can you judge a programmer from her resume? Its not hard.
    • Lemma: How you do anything is the way you do everything!
    • Means carelessness you show in your resume will also be present in the code you are going to write. If your resume is careless written, has typos, and handing sentence, your code will have similar bugs. It shows you don’t care about your work!
    • If your resume is verbose, disjointed and have bad formatting, means your code will also be similar. It also shows, you don’t think about “why”. If you write and send your resume without asking “why” this resume for this job, you are going to do the same thing at job. You will write code without every asking “why”. If may be fine for some people!
    • I personally give a lot of weight to formatting and presentation, perhaps as much as I give to the content. If you don’t format and layout your resume neatly, that means you are not into UX or DX. Working with you is going to be a lot of pain. You code will probably work but a few folks will be able to read and understand it. You lack empathy! Be kind to your reader. Make your resume easy on eyes — pick right font, use non-hostile layout and keep is short.

September 20, 2025: Weekly Notes 2025/14

  • The automatic gear shift of my car Tata Nano XTA is bricked. My local mechanic at Carz Tec made it worse. Today, I managed to send it to the nearby Tata Service Center Adishakti Cars using TVS Roadside Assistant service.
    • The first person TVS Roadside Assistant assigned the ticket didn’t show up at my place. He would never tell me the time. He supposed to come at 5pm. But at 11:30pm he was still 20 km away but claiming to be at the shared location😠. Finally they arranged someone who can read the map.
    • Install a tow hook in your car and/or find out where it is. Also keep a small cable with you.
    • I still don’t have experience with Adishakti Cars. Let’s see how it goes.
  • I found BBC Radio 4 – In Our Time podcast. So far, I am really enjoying it. I listened to a few old podcasts. Work in 20th century was excellent. I like the soft spoken host and his style. He invites a few experts to the studio and discuss a grand theme with them. The town square of European and American public discourse seem to be so vastly different. While intellectuals seems to be more common in Europian public discussions, no one seems to give a shit about what they think in the USA! By no mean, I mean to suggest that it a bad or a good thing.
  • When you onboard a new member to your team, how long does it take for them to become productive? Especially when they are not familiar with tooling. I suspect the negative compounding effect to be very strong. They will spend a lot of time dealing with papercuts from not knowing tools, frameworks and possessing tribal knowledge of the codebase. Also the story of the codebase is not an easy thing to acquire.

September 6, 2025: Weekly Notes 2025/12

  • I ordered https://www.oreilly.com/library/view/typescript-cookbook/9781098136642/ early this week. The packaging smelled like kerosene so I returned it. Today, I got a less-stinky replacement. Whey did they wrap the book in such a stinky paper! The book is great. Its my second book on TS after https://effectivetypescript.com/ Can’t wait to read it. Already referred to it on Enum which are pretty finicky in TS.
    • It’s very impressive how much typescript can do while maintaining such a great compatibility with JS.
  • I am more and more concerned about stability of OS on my laptop. Which is funny because during my college days, I’d spend whole week on installing different login manager, window manager and OSes. I had Gentoo on the lab desktop and a Puppy Linux pen-drive with me all the time. These days, if anything is slightly different than muscle memory, I gets annoyed.
  • I am very close to replace my OpenSUSE TW with Debian 13 today. I want a robust base. Appimage is pretty good these days and I don’t see any reason for using a bleeding edge OS. OpenSUSE is a great OS but I wish zypper ref was faster and parallel download is available a year ago.
    • I may have to install Windows on my laptop since a few software (like Notion) has no good app on Linux. Also some of the consultancy work I do needs Windows e.g. kernel mini-filter etc. Also the sound quality in meetings is not very great on Linux. Not really a fault of Linux when vendors don’t spend anything on Linux.
  • Are there startups where folks worked 9 to 5 and succeeded?

August 23, 2025: Weekly Notes 2025/10

  • Context switching is very hard. I feel it. And everyone seem to agree. Apparently, it takes roughly 23 minutes to recover after “hey, got one minute?” interruption. Surprisingly, there is very little in written literature to back this “23 mins” number https://news.ycombinator.com/item?id=44999373.
  • My car (Tata Nano XTA) refused to start a couple of weeks ago. I thought old battery but turns out broken rubber pipes, rusted and leaking metal pipes causing engine to go “cold”. Until a few years ago, Tata cars used to suffer from metal rusting, but according to r/carsindia, they are much better these days. Anyway the car spent a week in garage and I spent roughly 14,000 (Car Didn’t Start) to fix it. The car being out in the open is also making things worse. I don’t park it inside the building since rat chewed wires a couple of times.
  • I learnt about “Residuality Theory” in software architecture on GOTO Tech Podcast. I kind of like it. I did more digging and found Residuality Theory: A Rebellious Take on Building Systems That Actually Survive.

Cost of storing videos as “good enough” frames

I am going to do something terrible — store videos in a SQL database!

I have some requirements that makes it an acceptable plan. I am building a “stream store” S. Once videos are stored in S, users should be able to fetch a video segment (in color or grayscale) between two given timestamps at a given FPS. One should also be able to annotate frame later e.g., “this frame has a face in it”. I’ll read the incoming video stream and save data as frames to a database (in addition to storing raw videos on a backup server).

The primary job of S is to provide frames for CV analysis, so serving pixel-perfect video stream is not a requirement.

  • The stored frames should be “good enough” can our CV algorithms/pipeline works without a performance drop.
  • The cost of storing frames should be as low as possible as long as the above requirement is met.

I am going to extract frames from video as JPEG — a lossy compression format. But what should be the quality of JPEG?

Experiments

I downloaded a sample mkv file — 1080p at 30 FPS to do simple analysis.

https://filesamples.com/samples/video/mkv/sample_1280x720.mkv

FPS 23.976
Duration 28.237
Size on disk 16.63 MB

I wrote a script that extract frames from the mkv using ffmpeg. The argument -qscale:v set the quality of frames: 2 is the best and 32 is the worst.

  • ffmpeg -i ../sample_1280x720.mkv '%04d.png' generates PNG folder which is 1.3 GB, almost 78x of original size. PNG is a lossless format. This is as bad as its get.
  • ffmpeg -i ../sample_1280x720.mkv '%04d.jpg' generates JPEG with default quality picked by ffmpeg. It generates 33 MB of data. Almost 1.94x more. Great!
  • ffmpeg -i ../sample_1280x720.mkv -qscale:v 2 '%04d.jpg' generates JPEG with best possible quality. The generated size is 188 MB (almost 11x more!).

I did the same on a different file recorded at 60fps (original size . The data is below.

Size of frames (various FPS)

A few things to note

  • A video recorded at 60FPS takes more than twice the size compared to fps=30 case. Note video are using codec H264 (MPEG-4 AVC (part 10) (avc1)) which AFAIK compresses pretty well if two consecutive frames don’t differ too much. So this is expected.
  • Our recordings have the same feature. The interesting events happens rarely. We might drop many frames from the database after doing a quick analysis to figure out if they contain something interesting or not. So in the end, we don’t even have to store so many frame.

I think qscale:v=20 is a good default for my use case. Also I don’t have to extract frames at the same rate as they are recording. I am interested in events at the timescale of ~100ms and anything faster than 20FPS is overkill. i can just extract at 30 fps.

ffmpeg has a handy cli option -filter:v "fps=30" to fix the extraction fps to 30. Here is bonus rust code that does this. Don’t copy-paste blindly, it may not work.

/// Explode the given video into JPEG frames.
///
/// - *path*: Path of video file
/// - *fps*: Extract these many frames per seconds. The video may contain
///   more or less frames in a second.
pub fn extract_jpegs<P: AsRef<Path> + std::fmt::Debug>(
    path: P,
    fps: u16,
    recording_start_timestamp_ms: i64
) -> anyhow::Result<usize> {
    anyhow::ensure!(path.as_ref().exists(), "{:?} does not exists", path);
    tracing::debug!(
        "Extracting frames from {:?} for fps={fps} and jpg qscale {:?}.",
        path.as_ref(),
        self.qscale
    );

    let inst = Instant::now();
    let mut cmd = std::process::Command::new(&self.ffmpeg_bin_path);
    cmd.arg("-i").arg(path.as_ref());

    // Extract at a given fps. Thanks <https://askubuntu.com/a/1019417/39035>.
    cmd.arg("-filter:v").arg(format!("fps={fps}"));

    if let Some(qscale) = self.qscale {
        tracing::debug!("Setting qscale to {qscale}");
        cmd.arg("-quality:v");
        cmd.arg(qscale.to_string());
    }

    cmd.arg(self.frame_directory.join("%05d.jpg"));
    let output = cmd.output()?;
    anyhow::ensure!(
        output.status.success(),
        "Command failed\n.{}\n{}",
        String::from_utf8_lossy(&output.stdout),
        String::from_utf8_lossy(&output.stderr)
    );

    tracing::debug!(
        "Extraction to {:?} is complete, took {:?}.",
        &self.frame_directory,
        inst.elapsed()
    );
}

August 16, 2025: Weekly Notes 2025/09

  • Ookie daycare has independence day celebration. Anu found a costume for her.
    ookie-aug15-1 -- Independence Day celebration at Ookie Daycare ookie-aug15-2 -- Ookie in street on tri-cycle
  • Notion raised the Plus plan’s monthly cost from $5 to $12, which I grudgingly paid. I guess time to ask for a raise 😆. Even though AI is often pushed down my throat, Notion is very good at what it does. I use it for nearly all of my work.
    • It was is just too much hassle in migrating to Joplin or Obsidian. Besides publishing and syncing services cost roughly the same.
  • Notion is mostly being built in a high-income country and I am in a medium income country. I understand that I need to pay this price. We need more software and service that are built and used by folks in same income range like Zoho is for business. Only if they have something good for personal use.
  • At work, I am more willing to take responsibilities and ownership — lead role. I was reluctant before and wanted to remain IC for a while to avoid dealing with people problems. I was naive, people problems always find you!
  • This week went into learning about what is current in software architectures and system design. This blog Everything I know about good system design was timely.
    • And I didn’t do any planned work on my personal projects. Perhaps time has come to make peace with the fact and I can do only one or a few things in life properly.

Stress testing my router to know max transfer speed over WiFi/LAN

https://www.speedtest.net/ is great tool for learning about your internet connection speed.

If you are in a local environment, how do you figure out available bandwidth? Use cases: copying large files from one internal machine to another internal machine? Or running a local streaming service.

You can usehttps://iperf.fr/. You need two machines capable or running iperf3.

To test WiFi speed, at least one of connected via Wi-Fi. Both can also be connected by WiFi (worst case). My recommendation is to test in both cases.

  • Install iperf3 on both machines A and B.
  • Run iperf3 -s on machine A or use iperf3 -s -D to keep it running as daemon. Handy if you plan to test periodically.
  • Run iperf3 -c <ip_of_A> on machine B.

Sample output

Here is sample output at my home when both devices are connected by WiFi.

On a machine with IP 191.168.1.142, I run iperf3 in server mode.

$ iperf3 -s -D

Then on second machine

$ iperf3 -c 192.168.1.142
Connecting to host 192.168.1.142, port 5201
[  5] local 192.168.1.131 port 38888 connected to 192.168.1.142 port 5201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec  12.8 MBytes   107 Mbits/sec    0    124 KBytes       
[  5]   1.00-2.00   sec  13.2 MBytes   111 Mbits/sec    0    124 KBytes       
[  5]   2.00-3.00   sec  13.1 MBytes   110 Mbits/sec    0    124 KBytes       
[  5]   3.00-4.00   sec  13.6 MBytes   114 Mbits/sec    0    124 KBytes       
[  5]   4.00-5.00   sec  13.0 MBytes   109 Mbits/sec    0    124 KBytes       
[  5]   5.00-6.00   sec  12.6 MBytes   106 Mbits/sec    0    124 KBytes       
[  5]   6.00-7.00   sec  11.2 MBytes  94.4 Mbits/sec    0    124 KBytes       
[  5]   7.00-8.00   sec  10.4 MBytes  87.0 Mbits/sec    0    124 KBytes       
[  5]   8.00-9.00   sec  13.0 MBytes   109 Mbits/sec    0    124 KBytes       
[  5]   9.00-10.00  sec  13.1 MBytes   110 Mbits/sec    0    124 KBytes       
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec   126 MBytes   106 Mbits/sec    0            sender
[  5]   0.00-10.01  sec   126 MBytes   105 Mbits/sec                  receiver

iperf Done.

Here we go. I have some idea how fast I can transfer data between two computers on my local network.

August 9, 2025: Weekly Notes 2025/08

  • August 9, 2025 is Rakshabandhan which is a big festival. For many years, it has stopped being exciting for me, just like Holi and Diwali. When I was a kid, Rakhi used to be an exciting day. My three buas will visit us, stay over for a day or two and bring sweets and of course rakhi for their brother (my dad). The sweet of the season was ghevar. I don’t find that kind of ghevar here in Bengaluru. Perhaps you won’t find it in any big city unless you search for it. The sweets made in the villages and town are cheap. There is just not enough margin for shopkeepers/online platform to sell them.
  • I finally got a hard copy of one of my all-time favorite book. When I read this book last time a few years ago, I had no strong feeling about project management. This time the intentions are different. The reread is a very different experience.
  • https://pocketcasts.com/podcasts/9d4880a0-6a51-0139-3424-0acc26574db2/8c1458b3-3c4c-4be5-9429-5eb681d41172 was a good podcast. It resonated with me quite strongly.


    Ninety-five, [perhaps] 99% of the applications on the planet are and should remain monoliths. Full stop, end of story… I mean, I love distributed systems. I’ve lived in it for about 25 years, and, like, I just get joy from doing this kind of thing. And I read the papers, and, like, I find it super exciting… The vast majority of you should only be dragged kicking and screaming into distributed systems rather than starting from the beginning.” — Randy Shoup


    image.png -- A Classic Book: The Mythical Man-Month
  • I need to plan my weekends a bit more seriously. Last three weekends were not very productive.

  • I wrote a few (wip) design docs at work. Doing a good job at them is really hard and time-consuming! Totally agree with Writing a good design document and many comments on HN on this topic.

    > Think of a design document like a proof in mathematics. The goal of a proof is to convince the reader that the theorem is true. The goal of a design document is to convince the reader the design is optimal given the situation. The most important person to convince is the author. The act of writing a design document helps to add rigor to what are otherwise vague intuitions. Writing reveals how sloppy your thinking was (and later, code will show how sloppy your writing was).

August 2, 2025: Weekly Note 2025/07

  • My energy is coming back after a couple of weeks of mild flu like symptoms. I still have occasional cough. I have 500km left to run to complete 1000km of run this year i.e. 5 months and 500km. Not bad!
  • This week was pretty boring, work-wise, routine CRUD stuff. Creating a UI that can CRUD a database properly turns out to be much harder than I expected. I am not yet sure what I did wrong. This maybe in the nature of the problem. I’ve selected a few courses/reading material on database design in hope to discover more. My working hypothesis is that it was inevitable because we simultaneously build and used the portal — waterfall model is from the days when web-development was mostly about this kind of work.
  • Software Radio had a good podcast https://se-radio.net/2025/07/se-radio-679-wesley-beary-on-api-design/ this week. It covered API design in many other episodes. Also learnt about Zalando RESTful API and Event Guidelines
  • I did a couple of interviews at work. One candidate was passable, but his CTC demands were way too high. Can’t blame a guy for trying!
  • Please keep your JD to the point and “boring”. If you add fluff, you invite fluff! I imagine a very few engineer who enjoys development getting excited about other things. You can mention anything else at the end. Especially if you don’t want to read unrelated things in a resume, keep them out of JD as well.
  • While reviewing a candidate profile, I ended up logging to leetcode after so many years. One this led to another, and I ended up doing a few problems this week. Not gonna lie, I thoroughly enjoyed it. I won’t be surprised if I end up spending more time there! That mean my project of writing a parser for netlist file will get delayed a bit.
  • Read A Group is Its Own Worst Enemy by Clay Shirky, an old classic. I learnt about this article from crell blog.

June 29, 2025: Weekly Note 2025/02

  • For the last couple of weeks, Ookie has been going to a day-care for a few hours. She gets to play with other kids there. “Playing with other kids” has been the reason for sending her there. After a few days of fuss, she now seems to be enjoying her time there. My very friendly neighbors think that she is too young to go to day-care!
  • Somehow I managed to run 400 km so far! My pace has been slowest. I still need to complete 600 km in the second half of the year.
    • I’ve started paying for RUNALYZE. It is nice that more and more services are offering purchase-parity plan for subscription for Indian users. I’ve been using jonasoreland/runnerup: A open source run tracker for a long time to sync my runs with Runalyze/Strava. One dollar=Rs 100, but it is roughly Rs 30 in purchase parity, so you have to reduce the pricing by third for Indian users! If you are doing this, I’d be happy to work for you for a purchase parity adjusted salary😛.
  • I added another small tool that generates QR codes with a logo. You can find it here https://tools.maxflow.in/tool/qrcodes.
  • I had a minor meltdown at work 😭. Not proud of it. It’s hard to keep cool when many co-workers write almost empty email without a subject/body to report bugs. I’ve been trying to get them to use GitLab issues for a few months now. Either, I need to disengage from work a little at this workplace, or find a place where co-workers are adults and not only they come to work but also know how to structure and plan it.
  • I read Programming as theory building : Naur.pdf and found it illuminating. I am pretty sure I’d have yawned reading it some 10 years ago. This article — written a year before I was born — put “programmers” at the center of software development. I don’t think I can reduce this article to soundbites. Do read. I learnt about this article from HN.

naur-prog-as-theory-building.png -- Naur - Programming as theory building
– I wrote another small utility to remind me that a LWN article has finally become open. I am not able to pay for LWN subscription due to HDFC Bank related issues and I forget to revisit the link when it is open. Perhaps I can rent a VPS in this money and read the article two weeks later?! LWN is a great resource and I feel bad for not paying for it though!
– My Wallet from Budgetbakers is no longer syncing with HDFC Bank. Their support is working on the issue. HDFC seem to have changed their login flow again! My another bank, DBS Bank, doesn’t have saving account API🤣. I opened account here thinking that they are “tech-savvy”!
– I’ve been thinking about hiring a lot these days. At my current company which is an early stage startup, they have been struggling to hire a dev for the last 5 months! I was part of a few interviews — some went well and most were meh, but not able to hire for 5 months feels a bit extreme!
– Both mango trees in my street has mangoes this year! Here is my daughter Ookie playing with her friend. Fortunately, like many streets in Bengaluru, this street is a dead end and have no traffic.

signal-2025-06-28-192959_002.jpeg -- Ookie trying to convince her co-worker to use Rust while Kalu the fifth doing her stuff

July 26, 2025: Weekly Note 2025/06

  • I’ve been a little sick this whole week — a mild cold and occasional coughing. Running was a bit slow, and it took some effort to go out and run. Perhaps some flu.
  • Almost everyone I knew from college has left or about to leave my neighborhood — for search of job, education, status, money or other foo and bars. Sometimes I wonder if there is a point anymore in investing time in people these days?! I wish I am wrong. I have cultivated a few good relationships with my neighbors. Making friends become harder and harder as you age. Looks like it is a universal problem in industrial part of our civilization — at least major newspapers often write articles about it.
  • I am excited about what PHP has been doing lately. The language has added a few QoL improvements. Most recently the https://wiki.php.net/rfc/pipe-operator-v3.
  • I am thinking of writing down what I learnt about hiring for a startup (in Indian context) in a blog post. A lot of advice I find on internet is not very effective in our style of society.
  • I’ve been itching to pickup combinatorics — every problem requires a different trick, and the subject doesn’t require ten courses before making any progress. Like linear algebra, it is very computer friendly. One can do it a hobby or as profession.
    • I plan to implement some routing algorithms for PCB routing to integrate into KiCAD. https://github.com/freerouting/freerouting the inspiration. Of course, it is in Rust with Python bindings generated using PyO3.

July 19, 2025: Weekly Note 2025/05

  • Kaalu The Fifth leg pain is better than last week. Fish oil and supplement is working. I need to add fish/fish oil to her diet. Her mother is Labrador, and Labrador are apparently susceptible to arthritis.
  • Ookie is enjoying her time at day-care. Last Friday, she played really hard at day care. Tired, she slept through the night without waking up a single time.
  • Nothing much to report from work this week — a good thing, I guess. Every time I change the schema of the database, the Rust code stops compiling. I am using SQLX which checks type against database schema at compile time. So I get to know the issue before it is deployed. I have a lot of respect of SQLX (and Rust) these days. Also, the PHP8 codebase doesn’t have a good test coverage yet. I need to spend a week or two to write e2e tests.
  • I was doing some analysis for a friend which may be very useful later at work as well. I learnt a few things about tSNE, one of them is How to Use t-SNE Effectively. The amazing book Foundation of data science by Blum, Hopcroft, Kannan has a chapter on clustering, where tSNE has been discussed extensively.
  • I’ve been making notes from the book A Philosophy of Software Design — John Ousterhout here in this database . I’ll publish a few notes on LinkedIn over the next few days.
  • I am as surprised as anyone would be, learning about Data alignment for speed: myth or reality? – Daniel Lemire’s blog. Apparently, it doesn’t matter if you align your data or not!!

July 12, 2025: Weekly Note 2025/04

  • I took a few interviews this week. One candidate was amazing and one was pretty good. A rare week with two good interviews! Interviewing is hard and I am becoming more and more sympathetic towards interviewers.
    • I grew up in North India. Compared to candidates from there, South Indian candidates almost never lie during interviews — with or without a straight face. I also find them to be better co-workers. There have been a few notable exceptions on both sides though.
  • I got a new color printer with ink tank this time. It is from Brother, which has pretty good Linux support. I downloaded script from their support page, ran it and it set up the printer without any fuss. Previous one was a HP with cartridges and refilling them was always a pain. Also, hplip is not always up to date. It is nice to take a printout of an important document such as resume and read with attention they deserve. Many candidates spent days on them!
  • I was looking for a general database migration tool for PHP. Found Phinx and quite like it. Codeigniter inbuilt database migration wasn’t usable because I moved my project from FastAPI and earlier migration were handled by https://github.com/sqlalchemy/alembic. If you don’t setup your database with CI4, it’s not easy to use it for migrations!
    • No matter how well you plan your database, there will always be need for migration since business requirements keeps changing. Alembic is great if you are in Python world!
    • I totally understand if someone get the temptation of using No-SQL in the beginning of a project and later continued with it!
  • I finished a few courses at Coursera. Most of them are related to “soft skills”. You don’t have to spend hours doing assignments in these courses.
    With that little time investment, I got a lot of insightful tips and knowledge. Do not discount “easy courses”. Many things sound easy once there are told and this fact should not reduce their value. I wouldn’t even think of these titbits and tips otherwise.
  • We went out for dinner last night. It was for Anzal’s farewell (at https://maps.app.goo.gl/uun78ux8QCDEnKKS9.). A dog friendly place, they have food for them on the menu. But Kaalu was spooked by a giant rat in bushes and spend most of her time on high-alert. She definitely did not enjoy it. Ookie, on the other hand, had a good time.
  • Kaalu The Fifth limping has gotten a little better. Fish oil and omega fatty acids are helping, and it looks like she is having https://www.petmd.com/dog/conditions/musculoskeletal/osteoarthritis-in-dogs
  • I read a few interesting articles
  • I am active on LinkedIn again. I deleted my LinkedIn profile twice, more recently last January. Perhaps third time a charm?!

Change extension of a file using PHP

Following is not the most efficient solution out there. But if you are fan of regex, it is easy to read and maintain.

PHP
/**
* Change extension of a given filepath. If filename does not have extension,
* the new extension is simply appended.
*
* @param string $newExt May or may not start with .
*/
function changeExtension(string $filepath, string $newExt): string
{
$ext = str_starts_with($newExt, '.') ? $newExt : '.' . $newExt;
return preg_replace('/\.[^.]+$/', '', $filepath) . $ext;
}

July 5, 2025: Weekly Note 2025/03

  • I finally finished a version EHR app that I had been developing for last 6 months. I expected it to be over in 2 to 3 months — along with a real time trainer app. I had to rewrite it in PHP as a monolith from Vue3/FastAPI (frontend/backend). I discussed some of mistakes I made in . Moreover, I should have spent a significant more time on planning and talking to stakeholder, a kind of discovery phase where I force ideas out of people and put them into tickets. Another lesson learnt is that don’t take “another developer joining soon” too seriously. Despite what I write in my resume, I consider this project a professional failure in planning and execution!
  • This failure lead me to https://www.coursera.org/specializations/real-world-engineering-management. I am taking this short course and enjoying it. I’ve already learnt a lot from it. A few speakers are accomplished IC turned manager. I liked a couple of soundbites from it
    1. Product manager is a advocate for customers.
    2. Engineering manager advocates for, well, engineers.
  • Working at this other startup made me notice a few things — how small small things adds up to make a huge difference. I notice them because I have something to compare against from my previous startup. Many founders perhaps don’t recognize them because they have nothing to compare against. Perhaps everyone should work at a startup (successful one, if you are lucky) before starting their own? Or at least get someone from a friendly startup as resident observer for a while?
  • I have been thinking about 247df64abb1a495fb464959900c07b42 -- A reddit user (c-digs) comment on scalable systems
    I’d love to discuss some of these ideas with some candidates in their final round of interviews — if I get the chance.
  • There are some exciting changes coming to PHP-8.5 (https://php.watch/versions/8.5). Especially |> and functions to get first and last element of an array!
  • Kaalu The Fifth was limping last night. I sensed some pain when she was climbing sofa. She is overweight — she likes to eat outside and neighbors are really love her! I ordered fish-oil and a few supplements for her joints.
  • I rewrote my resume using LaTeX (again!). I was dreading installing the whole TexLive just to compile one page of resume, but thanks to The Tectonic Typesetting System — The Tectonic Typesetting System, the UX is much better.
  • Loved the podcast https://se-radio.net/2025/06/se-radio-671-carson-gross-on-htmx/.
  • Running 20 km this week looks like a challenge — one more day is left and 7 more km to run.

Use curl to upload files to S3 bucket

First, export the relevant environment variables e.g. S3_ACCESS_KEY, S3_SECRET_KEY, S3_REGION

To upload a file foo.gz to path /backups/db/foo.gz , use the following command.

curl --progress-bar \
          -X PUT \
          --user "${S3_ACCESS_KEY}":"${S3_SECRET_KEY}" \
          --aws-sigv4 "aws:amz:${S3_REGION}:s3" \
          --upload-file foo.gz \
          "https://${S3_BUCKET}.s3.${S3_REGION}.amazonaws.com/backups/db/foo.gz"

Note that you would a recent version (Feb 2021) of curl that natively supports aws v4 signature authentication (https://curl.se/docs/manpage.html#–aws-sigv4). for older version of curl, you may to send special headers (idk)!

June 22, 2025: Weekly Notes 2025/01

I guess, from now on, I am writing weekly notes every weekend. I learnt about weekly notes from Thej many years ago.

Currently, I am at a early stage startup. I joined them early this year after quitting my startup Subconscious Compute (more on it some other day). I’ve been building them an EHR platform to collect responses and related APIs though I was hired to do something totally different. First, a summary of what I’ve been doing here.

I started with Vue3 and fastapi and learnt Typescript along the way. It started off well. I managed to launch a demo version in a month. Most of its users are not technical and this was the first time I built a web-system for non-developers. And quickly realized why there is so much fuss about designing UI for non-tech users.

  • If you are a solo developer or a very small team, DO NOT split your frontend and backend — it creates more than 2x work. For a non-technical leadership (which might think they understand tech), it is a simple ask for adding or changing something trivial at UI, but for you it is migrating your schema, APIs and frontend models. And what is worse, you will make mistakes. You should only change things in one place. DRY and ensuring Single Source of Truth (SSoT).
  • So I bit the bullet and rewrote it in PHP8 & Codeigniter4. DX is now much better. First, I don’t have to switch between Python and Typescript/Javascript. Second, the system now crashes if someone submit invalid value rather than accepting wrong/empty values. The database schema validates the value. Perhaps I’ll add validator in the form/UI using </> htmx – high power tools for html.

This week

  • I explored a few server side qr code scanners. The most commonly used one is mchehab/zbar which doesn’t work well when image is tilted or rotated. Another tool rxing-core/rxing: cRustacean Crossing did a better job (it is in Rust). For example, in the following image, zbar detected no qr-code while rxing was able to detect two. Usually folks will do the qr code scanning using browser or camera at phone. There are some use cases where image needs to uploaded to server for QR scanning.

    IMG_20250618_185815 -- Sample QR Codes. This image contains 4 QR codes for testing various QR detection cli tools.

  • I wrote a Gitlab job to create backup of PostgreSQL server. It runs every 4 hours, uses pg_dump to create a dump, compress it and then Use curl to upload files to S3 bucket.

  • I found https://builtin.com/ on https://fosstodon.org/@ansate@social.coop/114707324371116735. It’s matches are pretty relevant. I’ve been updating my resume and thinking of reaching out to my network for opportunities.

Equivalent of `apt autoremove` for zypper (or removing unneeded packages using zypper)

zypper pa --unneeded | grep '^i' | cut -d\| -f3 | xargs sudo zypper -n remove
  • zypper pa --unneeded lists unneeded packages.
  • grep '^i' selects lines that starts with i (installed package)
  • cut d\| -f3 selects third field after cutting line at delimited |
  • And the last one runs sudo zypper -n remove on the output.

On older version of zypper, following script may be useful.

https://github.com/dilawar/Scripts/blob/master/zypper_autoremove.sh

Using monolog with codeigniter4

The standard logger in codeigniter4 is fine but its no monolog!

To use monolog codeigniter4, add the following to your app/Config/Service.php file. You can read more about supported handlers and formatters in monolog documentation. See https://github.com/Seldaek/monolog/blob/main/doc/02-handlers-formatters-processors.md#formatters. and there are many third party handlers and formatters available.

  • Note that I am logging to syslog rather than to a file (this won’t work on Windows). I think logging to syslog is better if you already have a scrapper running. And also, correlating with web-server logs is bit easier. Perhaps I am mistaken.
  • I am using a third party formatter http://github.com/bramus/monolog-colored-line-formatter to add colors to console logger. I think colors are a good idea if you need to scroll and look at the logs while developing.
<?php

// app/Config/Services.php 

use Bramus\Monolog\Formatter\ColoredLineFormatter;
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\BrowserConsoleHandler;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\SyslogHandler;
use Monolog\Logger;

class Services Extends BaseService 
{
    // Other services are not shown.

    /**
     * Use monolog logger.
     *
     * - Logs to syslogs
     * - Logs to console (colored)
     * - Logs to browser console (development only).
     */
    public static function logger(bool $getShared = true): Logger
    {
        if ($getShared) {
            return static::getSharedInstance('logger');
        }

        $logger = new Logger('my-portal');
        $consoleHandler = new StreamHandler('php://stdout', \Monolog\Level::Info);
        $consoleHandler->setFormatter(new ColoredLineFormatter());
        $logger->pushHandler($consoleHandler);

        // Also log to syslog
        $facilityName = "local6"; // See list here https://en.wikipedia.org/wiki/Syslog#Facility_levels
        $sysLogHandler = new SyslogHandler('my-portal', $facilityName);
        $formatter = new LineFormatter("%channel%.%level_name%: %message% %extra%");
        $sysLogHandler->setFormatter($formatter);
        $logger->pushHandler($sysLogHandler);

        if(ENVIRONMENT === "development") {
            $logger->pushHandler(new BrowserConsoleHandler());
        }

        return $logger;
    }
}

Continue to use your log_message function as before, and perhaps comment out all but one handlers in app/Config/Logger.php file.

I think once service with alias logger is added, most handlers in file app/Config/Logger.php stops working by themselves.