Sunday, February 28, 2021

Answering Two sTuPiD qUeStIoNs

Unfortunately, I didn't die. I was just otherwise pre-occupied.

The last couple of days or so were socially more interesting than what I would normally do. I spent the evening of 元宵 having dinner at my other sister's parent's place, and then heading off to her place proper for a housewarming. The last time I wrote about being at my other sister's place, I was helping with the unpacking. It is rather confusing to look back and realise that a full month had passed since that day. The place is definitely more ready to be lived in than then since the carpentry work and other finishing touches were completed as well. It is a cosy place, and I am very glad that my other sister and my other brother-in-law are finally together at their own place---their story has been eleven years in the making.

Yesterday itself was also socially more interesting. I had gone to church of service, as always, but after that the care group met up for dinner at Khansama Tandoori Village. While researching the place for this entry, I realised that there are two such restaurants---the main page I linked to is the one purporting to be in 166 Serangoon Road, Singapore 218050, but the one we went to was at 87 Science Park Dr, Singapore 118260 instead. I think the Serangoon one is the main branch---it makes sense because it is right smack in the middle of Little India, while the one we went to is a side branch. Anyway, the food is delicious, and the company was good.

I was subtly reminded about the time I ate at one of the North Indian restaurants out in Little India with the Muramatsu Flutes technicians when Chara was in charge of taking them out for dinner at the most recent flute festival organised by MusicGear Singapore and The Band World.

It was a happy memory, bittersweet.

------

I spent the past couple of days working on a small Python3 script that answers a stupid question: just how many pages of reading do I have left out of my stash of e-books?

My first answer was based on only counting PDF pages, and it was 192.2k pages at an average size of 15.3k bytes per page.

That didn't feel right, because I didn't process the .mobi files. That made me spend upwards of a day doing research on it and debugging the only mobi Python library (mobi-python) that I could find that didn't generate too much junk. Unfortunately, the code is at alpha quality, and it really showed---the written LZ77 decompressor had mixed semantics on byte versus character that ran completely brokenly in Python3, among other things. I shimmed and patched as much as I could to get what I needed going, and somehow managed to get it to work.

The end result is this:
It's 227.8k pages to read, at an average size of 13.3k bytes per page.

The first version was also a single-process, single-threaded, sequential file processor. It took about 4m 42s to count those pages---this included the new mobi files processing.

So, I reworked it to use multiprocessing instead. Using 5 out of the 6 cores yielded a run-time of 1m 18s to count the same pages.

That would have been job finished, had I not asked the next stupid question: just how many pages of reading had I already done?

Now, some qualifiers. Not everything from my read list exists as an e-book, so whatever estimates I have are at best, a lower bound. The other thing is that I set up archives of about 1G bytes in size of the read e-books just for ease of making back-ups.

So to answer my second stupid question, I needed to process lists of files from the RAR archives. I used rarfile to handle this, and did a test run with it on some comic book archive files to test the tool chain, thus increasing more capability for the script. It worked well, and I started to run it on my actual archive files.

The bloody thing crashed. Something about requesting a read of 65k bytes but receiving 0 in return.

I was sick of debugging and shimming mobi-python to get it to work. I double checked the RAR archive file with the provided tools and it checked out. There was just something stupidly wrong with the low-level methods used by RarFile.extractall().

Angrily, I just created a direct call to the unrar tool that rarfile was using in the first place to extract the contents into some temporary directory location so that the original refactored directory-walking page-counting script could work.

There was some additional shenanigans needed to transform the temporary file location (in Cygwin-land) into a path that Windows could understand.

But to cut a long story short, the answer is 151.4k pages, at 28.6k bytes per page on average.
And so, to answer 2 stupid questions, I now have a weird Python3 script that can count pages. Hurrah...

I just want to point out that it supports both mobi and epub files, and the number of pages from these reflowable documents are themselves estimates. I also want to add that for some of the PDF that could not be processed by the pyPDF2 module, I ended up using a 1-nearest neighbour estimator to impute the unknown number of pages to generate the final statistics. Yay...

------

I have slowly made my way through Deep Learning, reaching 489/802 pages as at now. What a slog it has been, and what a slog it is going to continue to be. I think instead of heading down immediately to OpenStax College: Organisational Behaviour as originally planned, I might want to detour to some fiction for a bit. But we'll see.

Till the next update, I suppose.

Thursday, February 25, 2021

Procrastination While on Sabbatical?

I talked about a small music-scale exploration sub-project in the previous couple of posts. It's not completely done yet, but I thought I should just pen down some of the crazier things that I found while doing the preparatory coding work.

There are two main ways of doing this: either start from the pitch-class set and then identify the associated intervals as part of the scale (which, incidentally, is similar to assigning degrees to the intervals a la 简谱 or cipher notation with associated accidentals as needed), or start from the ``standard'' 7-degrees of intervals that form a scale and apply accidentals accordingly to derive the set of pitch-classes, eliminating repeated ones. An example of a repeated set could be something like {1,2,3,4,5,6,7}---this is the same as {1,1,2,3,4,5,6}, assuming 12-tone equal temperament.

I haven't started the exploration part yet, but have been doing preparatory coding. And one of the problems I was facing was identifying the intervals (relative to the tonic) by name. I coded up something while at the library at NEX yesterday, but I didn't like the result. I was trying to be clever when there was no need to do so, simply because the sizes of the input we were looking at was that small.

And so I wrote a much simpler brute force way with associated preference scoring (prefer intervals with larger numbers of degree-names used, prefer using one accidental over a mix of both accidentals, do not prefer the dreaded ``double flat'' (can appear as 𝄫3, 𝄫6, or 𝄫7), avoid running into the next octave (i.e. prefer 7 over 1′)). The results were much better, especially after applying the conversion to 简谱 from the identified intervals.

I will probably work more on it over time.

------

I procrastinated against reading Deep Learning by reading a few more chapters of Genesis from the ESV Study Bible. For those who are not familiar, a study bible is like the regular bible (in this case, the English Standard Version of the Protestant bible), but augmented with many footnotes, endnotes, and articles to explain the context and provide references to other parts of the bible for the annotated verse. Think of it as the extended version of English literature notes that one had to take back in the day when trying to study a book for the examinations, except in this case we are looking at 66 books instead of just 1. And yes, I am seeing this as a multi-year undertaking.

It's okay, if something is worth doing, it is worth over-doing, which segues into a reason why I know that I had to take a sabbatical to think about what I am doing with my so-called career.

I am a computer scientist by training, a software engineer/data analytics engineer by practice. There is this word, engineer, that comes with it the concept of ethics, but sadly, in my industry, such ethics are treated as bullshit. There are two levels of ethics violations that impinge upon my conscience: the I-won't-be-around-to-run-this-in-five-years-anyway mentality, and the degradation of humans into milkable products for peddling more useless crap.

For the former, I am referring to the tendency for programs (or ``apps'' to use the modern parlance) to be written slap-dashedly to meet business mandated deadlines, at the level of quality that would make a civil engineer blush. Even for those that are well-written and are feature complete, we see ever-increasing nonsensical ``updates'' that are to milk more cash instead of actually improving things---the most egregious of all are the so-called UI/UX updates that are completely tone-deaf to the actual needs of the users.

For the latter, I am talking about the incessant tracking and infringement of basic human rights through forced participation of such tracking schemes. I say ``forced participation'' because while it is possible to technically operate without any digital tracking devices like smartphones or even email accounts, from a practicality perspective, it would be impossible to do so, especially if one were to want to luxuriate in urban living. The social contract has been altered over the past twenty years to this point---participate in the digital economy, or forego your rights as a citizen of the world.

I don't mind using data analytics on machinery data to improve the operation of the machines. But I mind a lot when we are starting to treat people's movements and words/actions as machine-like input for a central committee to control---there is something inherently wrong with this approach. It's like after the Internet has percolated down to the masses that suddenly no one remembers what morality is, and what a good conscience means, and that everyone requires The Law just to behave.

It makes me sad, downright depressed actually. When I started writing my first computer program when I was thirteen years old, I thought how much fun it would be to continue writing clever computer programs that do computation for things that were simultaneously fun and can help people. Now, looking back from a position of twenty-three years later, I just feel bad for myself.

Everything that was good, has been corrupted.

------

On slightly less depressing matters, I had this urge to play some Tyrian 2000. And I did. It is a space-shooter that has some light level-up/upgrade elements. It is fun.

And that's all I have for today. Till the next update.

Wednesday, February 24, 2021

Not Every Day is a Good Day

I am not going to sugar coat things.

The past few entries may have demonstrated a certain overwhelmingly level of positive energy with all the various successes and triumphs that I seemed to have obtained in the things that I were working on.

But not every day is a good day like those. Today, for instance, isn't that good a day.

Granted, I finally finished reading the Rainbow anthology by Robert Wilks, and managed to sneak in Farewell to the Master by Harry Bates (source story for The Day the Earth Stood Still starring Keanu Reeves et al). I also had a nice steak at COLLIN'S, and finally started on some of the music-scale exploration project.

But it was not that good a day. Because intrusive thoughts had creeped into me again.

Nothing relating to the suicide, at least, in the corporeal sense. But a strong sense of committing social suicide kept on surfacing within my subconscious. I was out of the apartment today just to get a little sunlight and movement, and was at Serangoon NEX. Amid the hustle and bustle, I had this startling thought that I was never going to be gregarious, no matter what I did---all forms of gregariousness is literally a sham of sorts, a type of 敷衍.

The more I hermit up, the more I like hermitting up, because hermitting up has demonstrated almost no negative consequences whatsoever, just as long as there is enough money to fuel the needs of living in the city.

Yes, no man is an island. But it does get seductively close, especially when one realises that there is not really anything to live for in general, or rather, there isn't really anything else that is worth living for.

Quitting making music did come to my mind. Quitting whatever is left of my circle of friends came to my mind also. Both thoughts are intrusive, but the former one is going to be staunchly resisted by me---if I quit making music, I am literally killing off one of the few things that I do out of passion and not out of money, in which case I probably should plan to off myself as well. The latter one though... in many ways it has already been going down that path, what with my general aloofness to begin with, combined with spending the best years of my life studying abroad and then returning like a damn fool, and have whoever is left as my friends get married left and right with children.

Eh, ain't nobody got time for me. And that's without my active sabotaging of things.

I really shouldn't actively commit social suicide. Future-me is not going to like it. For the sake of my two best friends in the world (past-me and future-me), I am going to tell the intrusive thoughts to shut the hell up and go away.

I'm out of spoons for today. Till the next update.

Tuesday, February 23, 2021

Final Solution to Eileen-II's Temperature Issues?

Ooo, a somewhat early entry!

I got quite a few things done today, so let me begin.

The first thing that I did was complete The Outer Worlds, completing both the ``good ending'' (The Hope colonists revived) and the ``bad ending'' (Capitalism forever!). That happened at around 0200hrs this morning, and thus counts as a ``today'' thing, even though it was more of yesterday on extended time.

I spent some time in the morning replacing the elastic strap in my Roi backpack. This elastic strap holds the concert flute (Aurelia, in this case) in position. I have had this backpack since 2015, and after carrying it weekly with a nearly full load of flute/piccolo, music, and flute/piccolo stands, it has slowly fallen apart. The top handle's pleather has flaked off, and has a corduroy handle cover (made from an old pant leg) sewed in place by Chara, one of the two zipper sliders is no longer aligning the zipper and is kept permanently in one side, and the latest of course was the loss of elasticity of the strap that was used to hold the flute case down. I carefully unpicked it and sewed in a new one with 1 in thickness, and it is now as good as new.

I just can't wait for us to get back into rehearsals at the Chinese orchestra. I have a new double-width collapsible music stand that I can't wait to make use of---I only need to either buy a carrying case for it, or make one. I'll probably make one, but to do so would mean that I need to source for cloth (probably canvas), and set up the sewing machine. There is also that possibility that I end up hand-sewing it; it's not something new. I have a tendency of doing that most of the time anyway, except for that one time that I was patching back together my pen case for my fountain pens.

------

The last time I talked about Eileen-II, I mentioned about turning off hyper-threading to reduce run-time temperatures. There was only one small problem with that entry that I want to correct: the temperature did not drop to around 80°C---it was more like 89°C to 92°C, as compared to 95°C to 100°C when hyper-threading was turned on.

The other thing that I didn't mention was that the idle temperature was about 66°C.

I don't like these numbers at all. It's partly because such high numbers would imply a shortening of the lifespan of the components (in this case, the CPU), but more importantly such high numbers meant that when I was using the keyboard of Eileen-II herself I would end up actually burning myself slightly should I accidentally touch the institial parts of the frame instead of the plastic key caps of the keyboard.

I knew of a solution to this, but I have not had the wherewithal to do it, because of how time consuming it was---it was the pseudo-inverse of overclocking, a technique called undervolting using a tool like ThrottleStop. CPUs, like all electronic components, require a certain potential difference across it too provide enough electrical energy to do the computations that they need to do. Loosely speaking, for ``greater performance'', the CPU should get as much energy as it can take, which is indirectly controlled by regulating the voltage of the supply going into it.

But the catch is that ``greater performance'' is not the same as ``greater apparent performance'', the reason being that if the CPU gets too hot (for instance, 100°C), the CPU is forced to downclock itself to avoid burning itself from the excess heat. Following the math from this subsection on CPU power, this excess energy is proportional to the square of the voltage supplied.

Every CPU has its own sweet spot voltage where there is a minimal amount of energy that is supplied that can give the CPU its maximal performance without actually generating excessive thermal energy that forces a temperature-based shut down. For reasons of sanity, the factory defaults for the make of Eileen-II are set to be ``performance-oriented'', i.e. they do not attempt to find such a ``best'' voltage. This ensures that the machine will always attempt to run at its ``best performance'' regardless of the situation.

So yeah, the first thing I did then was to find out what that lowest voltage is. To help me with it, I turned off the Turbo Boost capability from within ThrottleStop, and carefully experimented on the voltage offset for the CPU Core and CPU Cache. This was the most time consuming part because if I ever went too low, the CPU would freeze up, and I would have to do a hard reset. Granted, with Eileen-II's specs, a hard reboot doesn't take too long, but it still takes time to pull off. The final values that I ended up was −90.8 mV---starting at the default −100.0 mV voltage offset was just too much and made Eileen-II crash. This led to an idle temperature of around 50°C.

I could try to tweak down to the 1.0 mV precision, but at this point, I don't think it is worth it.

The next thing that I tried to tackle was the way Turbo Boost worked. Disabling Turbo Boost was a good way to get low temperatures, but I didn't just want low temperatures---I wanted Eileen-II to actually run more powerfully if there's a need to, but without the whole hot-enough-to-burn-my-finger-tips thing.

Turbo Boost worked by applying a multiplier on the basic clock speed. For Eileen-II, the basic clock speed is 99.768 MHz (as reported by ThrottleStop). At the published ``base frequency'' of 2.60 GHz, we are looking at a multiplier of around 26×. The maximum reported frequency that the CPU can support is 5.1 GHz, which works out to around 50--51×. Thus, any multiplier larger than 26 and less than 51 are considered potential ``Turbo Boost ratios''.

At this point, I think a screenshot of the Fully Integrated Voltage Regulator (FIVR) screen will make things more enlightening.
Observe the lower left corner frame under ``Turbo Rate Limits''. The Max value is the maximum ratio that the CPU is reported to support---going any higher than that counts as overclocking (i.e. out of specifications). The table below lists down the multipliers to be used when Turbo Boost is triggered, sorted by the number of active Cores.

My understanding of active Cores are those that are assigned the particular process/thread to operate on [at 100% capacity].

Now I just want to point out that I live in Singapore, and naturally, am operating Eileen-II in Singapore. In case you were wondering, Singapore has a climate that is simply terrible for high performance electronics if one does not have/use air-conditioning.

So those default numbers in Turbo Ratio Limits that start at 50× for one active Core to 43× for 6 active Cores? Yeah, they are waaaaaaay too optimistic. For reference, the highest I ever saw the clock speed went was about 4.2 GHz, and even then, it immediately faced thermal throttling.

I went ahead to get my favourite prime number tester to generate the types of high CPU loads that I needed to benchmark the relationship between the multiplier and resultant temperature. I first did a full 6-core ``Small FFTs'' torture test with the undervolt conditions and Turbo Boost turned off. According to the options, the ``Small FFTs'' torture test tests the L1/L2/L3 caches, generating maximum power/heat/CPU stress, which was exactly what I wanted. The idea for this initial test is to spot the empirical distribution of which Cores have a tendency to run hotter than others. From this empirical distribution, I would then pick the hottest n cores when I am trying to tune the multiplier for n active Cores.

My goal was to ensure that no matter how many Cores are active, the maximum temperature of all the Turbo Boosted Cores do not exceed 85°C. There is no scientific reason why 85°C over other temperatures, but there are two good ones:
  1. 85°C is roughly the top end of the temperature where the frame is merely warm to the touch;
  2. Any lower temperature than 85°C would lead to a multiplier that is basically useless, in which case I might as well just turn the Turbo Boost off.
Empirically, the Cores from hottest to coolest on Eileen-II are Core 5, Core 3, Core 2, Core 4, Core 1, and Core 0.

One last piece of the puzzle was to do the actual assignment of Cores for the job. The way I did this was to pull up ``Task Manager'' with Ctrl-Shift-Esc, get it to show more details (this is by default for me), get to the ``Details'' tab, search for prime95.exe under the process name, right clicking on it to pull up the context menu, then selecting ``Affinity''. And from there, I would choose which Cores (or CPUs in this case) to assign prime95.exe to.

Then it was just a case of trial and error on the multipliers with careful execution of the ``Small FFTs'' torture test with the associated number of workers.

The multipliers that you see in the FIVR screenshot above are obtained through this process. Notice that at 6 active Cores, the multiplier is 30× (corresponding to a clock frequency of not more than 2993.04 MHz), and at a single active Core, the multiplier is 40× (clock frequency not more than 3990.72 MHz). These numbers are definitely much lower than the very optimistic defaults.

Notice that I am being very conservative here---I chose to ensure that the hottest Core spike does not exceed 85°C; this does not mean that the hottest Core will operate at 85°C. To illustrate this point, I have taken yet another screenshot, this time with a 6-core ``Small FFTs'' torture test with all the settings set up in the FIVR screenshot.
As you can tell, it runs much cooler now, with the lowest spike temperature being 78°C, and the highest spike temperature being 85°C. Notice also how the empirical distribution works for both the instantaneous measurement and the Max measurement.

That was not the end though. I re-ran the ``Small FFTs'' torture tests again from 6-core down to 1-core, but this time without forcing the processor affinity. The temperature profiles are definitely much cooler, since the fewer active Cores often meant that the workload was being shuffled randomly among all the available Cores, leading to less sustained work.

Hopefully I don't have to do anything more drastic to keep the temperatures at this comfortable level.

------

Technical nerdry aside, I also started reading a short anthology of poems/prose/plays by Robert Wilks. Rainbow: A Collection of Stories, Poems and Plays (Volume 2) is funny because it was actually my secondary two English Literature text book from back in the day. It is one of a few books that I kept from my secondary school days, mostly because past-me sort of knew that there would be one day where future-me would be interested in reading the wonderful writings from then. Thank you, past-me!

I have also watched Dick Tracy, a 1990 film about the eponymous comic-book detective. It's funny---I remembered that I loved the concept of Dick Tracy (he's a detective, and when I was young, I loved the idea of being a detective, and also a spy), but I never seemed to like read/watch anything about the character. And so, I rectified that today. To my surprise, Madonna was in it as well.

Woah.

The film itself was fun, but what really drew me in was how normalised all the comic book weirdness was---this is a testament on how well the film was directed/produced. Big coats in all the colours except black, canary yellow hat and coat while trying to be sneaky and somehow not getting seen, colourful back drops despite the 1930s ``hard-boiled'' aesthetic.

And Madonna sings like the nightingale she is. Ho yez.

Anyway, that's all I have for today. It's a long entry, no thanks to nerding out. Till the next update, I suppose.

Monday, February 22, 2021

[Short] Fiction LaTeX Toolchain Update and Other Stories

Ah... so close to completing The Outer Worlds! If only I didn't actually spend time working on other things... but I believe I am jumping the gun here.

I finally spent some time reading Deep Learning, and have something to admit---the more I read it, the more I am starting to agree with Brian that I am wasting my time. It is not that the concept of deep learning is bad, it is just that, unlike more ``stupid'' algorithms like say decision trees, or even some kind of Bayesian belief network, there seems to be nothing innately interesting about deep learning. I get that they are trying to attack the machine learning problem through the use of function composition as the way of generating complexity out of algorithmically simpler units, but there is almost nothing intuitive about it, just really dry tensor mathematics with a tinge of function optimisation in disguise.

Maybe it's because I'm only [nearly] halfway through the 802-page e-book (387 as at the time of writing). But honestly, it doesn't look like it is going to get any better. I can probably understand what goes into a deep learning system, but it is unlikely to draw me close in the way the other learning architectures would.

Heck, even SVMs are more appealing from the intuitive and theoretical aspect.

I think part of the reason is that a large part of deep learning is not amenable to proper human understanding, at least in the way it is being presented. It's a case of ``here, pick/design some deep learning architecture (equivalent to deciding on the basis functions, and the space of function composition to operate in), chuck enough data and time at it, and we can universally approximate the unknown function to `compress' the data representation for future prediction''.

But I should really be drawing conclusions after finishing the book. As I said though, it really doesn't seem to be getting any more interesting. If this is the kind of work that people are expecting data science to be, wow, it's probably the most hypocritcal thing for me to take up those kinds of jobs.

------

Deep Learning aside, I accidentally spent some time doing more fixes on my various toolchains, not necessarily related to the maintenance of my personal domain. I was actually debating on whether to work on Print Me for today when I realised that I still had Elizabeth left to complete.

For those who aren't familiar with my blog-based scribbles, I have a tendency to create nicely typeset versions of such ``serialised'' works after I have completed the story. That I hadn't generated one for Elizabeth was a hint that I haven't completed the story, despite the 25 parts that I have written thus far.

I tried building the PDF from the current writing so as to read the story as a whole to see what is left to write, and found some warnings that were being tossed at me by LaTeX---they had something to do with the weird margins that I was using. I fiddled about before finally realising that I had already fixed the style sheet that I was using for my fiction back in 2015---I just didn't propagate the changes. And so, I spent some time updating the pipelines for each of these standalone stories' typesetting, and regenerated those PDFs to replace the old [and bad] ones. The dates of the stories are still the same as before, but the margins are definitely more consistent.

Naturally, I didn't get to read Elizabeth to determine the amount of work left. I didn't work on Print Me either. Maybe tomorrow.

------

On one final note, I had finally bring myself to writing a quick tool to identify duplicate images by visual perception. The situation is this, I have a set of one thousand or so image files that I have been collecting over time to act as desktop background images. They tend to be of high resolution, and come from many sources, and so one of the first things that I did was to write a script that will rename them according to some schema that keeps their order and resolution ``obvious''.

Some images are just too lovely, and after a long enough time, I accidentally have some duplicates from accidentally redownloading them for storage again.

Visually inspecting which ones are similar from Windows Explorer alone was stupidly impossible, and it was obvious that I needed to use automation to help, specifically some kind of similarity comparison.

Armed with Pillow, I wrote a Python3 script that would convert each image into a row-vector of 20 dimensions, with each entry being a number from [-1,+1] representing absolute black and absolute white from a Lanczos-resampled grayscale conversion of the original image.

Similarity was then done using a variation of cosine similarity---I used the cosine-angle in radians and set the angle threshold to 0.01 to claim similarity.

Images that were similar were physically dumped into a directory representing the cluster, while images that had nothing similar to them were just copied wholesale.

From there, I could do the visual inspection (there were 10 clusters of similar images) and weed out what I didn't want, before re-running the renaming script on the unique-ified images.

Was it overkill? Maybe, especially when the images that were similar appeared to be exactly the same---it wasn't even the case that one was a higher resolution version of the same image as another. Since I did not have the wherewithal to actually see which of the similarity cases were there, it was just faster to use a more general algorithm.

The job was done, and I am happy.

------

I think that I have been writing a little too much about writing random scripts/updating various toolchains that I use to operate my cyberspace affairs. I suppose it is just the season---it seems that I am currently in the ``hot'' phase of programming useful scripts/fixing old ones.

There is still one more thing that is niggling at the back of my mind that I would want to do before I am ``programmed out'', and that involves music.

I may also want to do some lighter reading instead of Deep Learning, perhaps a short anthology of short stories, or even poems. I don't know which just yet, but I have some decent ideas. And they are likely to be dead-tree versions too, just for variety.

I think that's all I have for today. Maybe after I shower, I will try and finish up one of the endings for The Outer Worlds.

Maybe.

Anyway, till the next update.

Sunday, February 21, 2021

Website Tooling In Happiest State

Eh, while I was chasing weird Chromium related font rendering bugs, I fixed a couple of other nonsense as well.
  1. Added the ability to stack one Unifont character over another to facilitate in-line cipher notation information in a regular paragraph HTML element;
  2. Hunted down the missing mtime modifier for the minified-GZip generator for HTML files;
  3. Made the sitemap generator be idempotent for the minified-GZip generator.
My personal website is maintained through hand-coded HTML files that undergo minification via my own Python scripts. These scripts will also generate GZip versions of the various text files as a statically generated server-side support for HTTP Compression---I do this to avoid having to load the server with extra running processes that do the compression on the fly.

The problem with GZip is that it stores the mtime or modified time of the generated file in its content stream as well. This means that even if the byte-stream to be compressed is unchanged, the resulting GZip file will still have changes due to the different mtime field contents. This becomes a problem because I use rsync to ``publish'' the minified+gzipped files onto my web server, and [parts of] files are transferred according to the difference between the file to be sent and the file in existence on the server.

By fixing these bugs and doing the enhancement, I basically reduce the number of bytes that I need to send, since only the HTML files that were edited ought to be updated on the web server, as it should be. I'm glad that this stupid bug is finally laid to rest.

Incidentally, I was also messing around with lars, a Python3 framework for easy parsing of httpd log files, with the intention of setting up some analysis of the visitors that have come to my personal domain over the past decade and change.

So much for completing The Outer Worlds today. Well, there are still two more hours left before I ought to go turn in for the day, and maybe it is time to get into some gaming.

Truly now, till the next update.

Chasing the Combining Diacritical Characters in Chromium Problem

I spent a better part of the morning investigation a weird problem with respect to combining diacritical marks in the Unifont font as implemented in Chrome/Chromium.

Observe this combination of characters: . It should look like a `2' with a dot on top of it, something like this: .2. Unfortunately, if you are in Chrome/Chromium, you will see something like a `2' with a ``high dot'' to the right of it instead---the COMBINING DOT ABOVE character refuses to be composited upon the character representing the hindu-arabic numeral `2' character.

This is a problem when I have an article collection that requires the high dot to be at the right location to represent the correct pitch of the note in cipher notation. Generating images to replace it was a no-go---it was quite clear to me that Chromium is doing something rather stupid in its choice of how to interpret COMBINING DOT ABOVE.

I will first attach the composite screenshot indicating the solved form (on the left), the original discovered problem (in the centre), and the non-problem (on the right) before explaining what I did to discover the workaround. The first two lines were pure paragraph elements using the default font from my basic CSS file, while the next two lines used classes that forced the use of Unifont.
To be had, this was a problem that I had observed for a while, but had not really made any effort to studying the whys, until today when I was sufficiently annoyed.

The answer was to also provide the TrueType (TTF) font as part of the font-face specifications in the associated CSS file to act as the fallback font. Why the full TTF is required over the split WOFF2 for Chromium when Firefox/Waterfox can do it perfectly well is something I don't understand and don't want to waste time to find out.

Anyway, my first clue on the solution came about through inspecting the rendered font in Chromium's Dev-Tools screen. Instead of telling me that the rendered font was ``Unifont'', it was telling me nonsense like ``Arial'', which happens to be the browser-defined fallback font for Chromium that is subsumed under the ``sans-serif'' font-family. That didn't make any sense to me---Unifont is pan-unicode, and again, I have had no problems with it in Firefox/Waterfox, thus seeing that the browser decided to use a fallback font instead of the pan-Unicode one was patently impossible in my book.

I remembered from the old times of the use of the full Unifont WOFF/WOFF2 file from back in the day, and the problem persisted. So, the issue had nothing to do with the splitting of the WOFF2 file into fragments to facilitate better server response---it was likely something to do with the WOFF2 format that was not well-tolerated/parsed by Chromium.

On a whim, I tossed in the TTF version as a fallback to the split WOFF2 files, and what do you know, it worked. Except instead of a faster download of around 5 to 6 files of around 4 kiB, it was that, and the massive 13 MiB TTF file.

That workaround is just stupid. Either Firefox/Waterfox has a bug in font selection/rendering that is totally in my favour, or Chromium/Chrome has a bug in trying to interpret the proper Unicode code points and dealing with constructed combining diacritics.

The larger TTF file size has been mitigated somewhat through careful use of the GZip compression of the payload at the server side, but we're still talking about an extra overhead of around 15 MiB, which is the same amount of size used by all the rest of my content files.

But I keep telling myself, it is just a fallback, and when cached locally, should not keep downloading repeatedly.

------

In other news, I think that I can/will complete The Outer Worlds today. My next immediate goal will be to complete Deep Learning by the end of next week, and in the mean time, probably end up watching some TV series/anime/movies in the upcoming week just to change things up a little. Reading is fun and all, but it's probably cool to do other things as well, otherwise in what way is it considered a break/sabbatical?

Till the next update, I suppose.

Saturday, February 20, 2021

Shortened Day

They are right, you know. The days do pass faster when one has something to do, and is not really about whether one is having fun or not. Having something to do is a great way to not pay too close attention to the passage of time, which allows the subjective perception of time to shorten.

Take today for instance. I didn't do much---I read a bit more of Deep Learning, cleared a few more side quests of The Outer Worlds, watched more VODs from ESA Winter 2021, catch the latest video from ElectroBOOM, messed around with Windows registry API access with Python3, fixed some busted URL parsing in the JavaScript that supported the automated navigation generation, and went to church.

To me, it didn't feel as though I had just passed one day---it felt more of a passing of way less.

That's all I would want to write today though. Till the next update.

Friday, February 19, 2021

Video Watching

What a nice and quiet day.

I spent a little bit of time reworking a little on the blurbs that appear at the top and bottom of my blogs to make them less awkward sounding---I hope that I have achieved my goals through the adjustments.

I had also spent a little bit of time watching this introductory video on medieval recorder music, and certain rather interesting thoughts came to me, specifically, the part concerning the use of finger-based articulations over tongue-based articulations. Emily [in the video] pointed out that there were times where she would naturally resort to using finger articulations instead of tongue articulations for instruments that are generally ``always going on'', like the bag pipes (it is impossible to actually use tongue articulations since the purpose of the mouth is to replenish the bag of air via the one-way valve). These finger articulations are a cross between a mini-trill or some kind of mordent, and are most obvious when trying to separate out two notes of the same pitch. She also pointed out that more often than not, she is playing legato/slurred, and thus the finger articulations act as a way of keeping the legato playing while still allowing some distinction of the notes that are played.

In 笛子 technique, the so-called 南派 (southern style) 曲笛 playing uses lots of 打音 and 叠音 to articulate notes (for the gory details, do consider reading this section of my article). Noticeably, there is a severe lack of tongue-based techniques like 吐音, or anything that causes a severe ``break'' for the matter. Prior to the introduction of the G 大笛 (ambitus being roughly the same as the baroque flute), the largest 笛子 were of the 曲笛 range, i.e. about a fourth interval higher than the concert flute. At that ``low'' range, it was stylistically better to keep things in legato due to the less crisp nature of the tone.

I just found it interesting that a similar argument could be made for the restriction of techniques as part of a stylistic choice. Of course, these days under the 新派 concept of using the entire 笛子 family as a unified whole, there is hardly any restrictions of the sort any more. Bear in mind that back in the day, the 笛子 was not taken to be a virtuosic instrument---it was primarily an accompanying instrument for opera, and almost all instruments play about an octave higher [in general] compared to that of the more modern Western music tradition. It is interesting to note that the recorder family is one that is also treated similarly as the 笛子, with their actual pitches one octave higher than what is annotated. To say that there is some relationship between 笛子 and recorder is probably a mild understatement.

Anyway, that was roughly what I was thinking about for quite a bit.

------

In other news, European Speedrunner Assembly (ESA) Winter 2021 is currently in session, and I have been taking time here and there in between the [light] reading and The Outer Worlds to watch a run or two here and there. Of note is the runner Juh0rse---he is a fellow Singaporean, and his Minecraft Any % (1.16, Random Seed, Glitchless) run is hilariously painful [for him] and fun [for us] to watch. I've caught him on ESA Marathons before; he was mostly speedrunning horror games, and Bishi Bashi.

Which of course brings me to something fun: speedrunning. The short technical description of speedrunning is the process of getting from the start state of the program (game) to a determined end state of the program (like winning/ending screen) using nothing more than what the program provides (like only providing input from the controller, keyboard, or mouse, without using any external programs to assist), in as short a time as possible. Of course, it is more fun than that because the said program is a game, and there is usually nice graphics, sound/music, and hilarious artefacts to observe as well. But don't let the fun get in the way of what speedrunning is---it is a fun way of defining the type of hacker attitude necessary for software testing. Much of the techniques used in speedrunning can often be translated into some kind of software test technique or attack vector, with an understanding that it is much stricter because the gentlemen rules of speedrunning only allows input from what is normally allowed, i.e. one cannot do hardware re-soldering, or run some kind of ``trainer'' program. The ingenuity of the speedrunners in finding glitches and exploits that can be humanly executed is what makes it a most fun sport for me.

I would say that my introduction to the speedrunning sport is from the Games Done Quick (GDQ) series of charity marathons.

I have been following the GDQ series of marathons from back in 2011 when it was still run by Speed Demos Archive and Speedruns Live, complete with their own IRC channel on Freenode (#sdamarathon). In the early days, when I was still studying in the US, I even donated some money too, and would have Elyse running the live stream while I was working on Eileen. The GDQs then were more informal and friendly, and I loved the Midnight Crew, the unofficial title for all those on the graveyard (relative to the on-site time zone) shift. The graveyard shift then was fun because a more adult-friendly atmosphere was allowed; I don't mean gratuitous sex and violence, but more candid banter than would include some mild swears here and there as needed.

But as the marathons got larger, they got more organised, and from the organisation, corporate structures were put in place, and various things that were normal from the old cosy format was no longer allowed.

It gave GDQs a good polish of professionalism, but in the process, seemed to nullify its grassroots origin a little.

But ESA marathons are still small in comparison and still retain that charm.

In either case, I no longer watch them live that much, partly because I'm getting older and have things that need to be done in between that disallow marathoning, and partly because... well... it's been ten years, or nearly twenty GDQ marathons. I won't say that I've seen them all, but I have seen a lot. As such, I'm a little more discerning on which runs to catch and which to skip, and have found it easier to handle things in a more bite-sized fashion.

Alright, enough of a brain dump for today. Till the next update.

Wednesday, February 17, 2021

Chomp Chomp & [No] Hyper-threading

I needed some sunlight today, and so, I went out of the apartment to meet up with my friend for a late lunch out at Serangoon Garden Market & Food Centre (SGMFC in this entry). This is the superior food place compared to the [in]famous Chomp Chomp Food Centre that is within walking distance of the previous one.

The superiority of SGMFC against Chomp Chomp comes from three big points:
  1. Wider variety of food types for selection;
  2. Much more open and airy feel to it;
  3. Lack of an ``oppressive'' feel.
For comparison, when my friend and I were at Chomp Chomp, the seating was very claustrophobic, and there was even a police presence---how much more ``oppressive'' can it get? All that seriously undermines the type of good/open food centre that one is more accustomed to in Singapore.

The unfortunate thing is that SGMFC seems to be too much of a mouthful to remember, and is often incorrectly referred to as ``Chomp Chomp'', which was why when my friend suggested that we ``met at Chomp Chomp'', I counter-offered just waiting for him at the bus stop at the circus instead, since all the buses that entered that general region would end up stopping there. As it turned out, it was the right choice, since he really had meant SGMFC instead of Chomp Chomp after all.

We spent some time trying the different foods at SGMFC. I had some kway chap, some beef hor fun, some ming jiang kueh, and some soya bean drink with dessert of grass jelly with attap seeds. We then walked about the roads just seeing what was available, including entering the myVillage mall off Maju Road. The last time that I was at myVillage was nearly ten years ago, when I was much more active in the Singapore Geocaching scene. The place felt much smaller than I had remembered, and I think it was partly due to how the roof-top garden was cordoned off for whatever reason.

All in all, it was a nice couple of hours outside of the apartment.

------

In the first month of my sabbatical, I have basically come up with some kind of rough routine for myself to ensure that it is both productive and restful for me. Roughly speaking:
  1. No zero days---I need to do something each day.
  2. Weekly, attend church services.
  3. Daily devotionals from Bible in One Year 2020 with Nicky Gumbel---am already on Day 285
  4. Daily reading from my reading list.
  5. Daily, either play some music, or play some video game.
  6. Daily, try to write something, either a piece of music, a poem, a story, a computer program, or a blog entry.
  7. Weekly, get out of the apartment to do something different, or meet up with someone.
  8. Keep to OMAD for at least five days each seven-day week.
I think that is a pretty good set of activities to keep me going.

The thing about sabbaticals, I feel, is that there is a need to get some manner of new stimulation back into one's life to ensure that there is actually some thing that can lead to change. As an old programmers' adage goes, insanity is doing the same things and expecting different results. If doing the same things were making me happy, then I think there would be no need for a sabbatical in the first place.

Doing new things for new stimulations isn't the same as running away from an old life though. It has all the hallmarks from running away from an old life, but is different in the sense of the intention---it is not about running away from an old life, but discovering how to run towards a new life. For me personally, this is really about how to reshape my new life such that it is more Christ-centric.

``Hol up MT,'' one might begin, ``I thought you weren't the religious sort. Why are you starting to talk about this `Christ-centric' thing like you are one of those fundie-goons? Have you lost your marbles?''

No, I have not lost my marbles. One of the things that I have realised over the past fifteen years or so is that greed is the one big reason why things are the way they are in the world today. But to overcome the basic nonsense that is greed requires a different perspective, a different 座右铭, or motto for those of us who are not so conversant in Mandarin Chinese. There are many different ways of creating/finding/discovering such a motto, but for me, the idea of leading a Christ-centred life-style is the one the makes the most sense.

Am I disdaining other people's beliefs? No, you are free to think what you want. I know what I believe in, but it is not my place to force what I believe in on you, even though I may think that you are wrong. Belief is about faith, and faith is not science---the evidence behind faith is qualified through personal experience and third-party testimonies of experience and not quantified through repeatable and falsifiable hypotheses through the Scientific method. Faith is not something that is debatable, principally because faith defines the axioms from which all other reasoning (via regular logic) stem from.

Thus, to ``debate'' about faith is an impossible and unproductive approach---by definition, we can already have issues with agreeing with what are the basic tenets (axioms) that are innately true, and proceeding from there would just be a terribly angry waste of time by all. But I digress.

The reshaping of my new life through the filling of the emptiness within from the rejection of greed is one of the key reasons behind the need of a sabbatical. Mayhaps all that has happened thus far (the break-up of a five-year long relationship, the strong ``push'' factors out of my previous job) are mere pointers leading to this moment where I start to really think and meditate about what it is I want out of my life.

After all, I have been surviving on ``magical coincidences'' for too long, I think. Eventually, luck can and will run out, and at that point, what happens? But I will leave that discussion for another time.

------

In other news, I have decided to turn off hyper-threading on Eileen-II. Recalling the specifications of Eileen-II, she sports an Intel i7-10750H processor (6-core, 12MB cache, up to 5.1GHz with Turbo Boost). With hyper-threading on, that 6 [physical] cores appear as 12 [logical] cores, which, in theory, improves the overall throughput by reducing the idle time on each of the cores. So in cases where there are a lot of ``light'' threads that need to be run, hyper-threading can be a good way to squeeze out some extra level of performance.

It all sounds great, but I had been carefully monitoring the temperatures of Eileen-II while I was running The Outer Worlds. The GPU temperatures are generally alright (sub 80°C), but the CPU temperatures were ridiculous (staying at 95°C, spiking to 100°C where the turbo-boost from 2.6GHz to 4.7GHz was throttled back to about 3.5GHz sustained). Bear in mind that I am operating Eileen-II in a semi-open air apartment in hot and humid Singapore with no air-conditioning. Excess thermal energy is a big deal---running components that hot for too long is a great way to get the effective life span greatly reduced.

Anyway, I did more reading up, and realised that the hyper-threading model was not the right computation model for the types of loads that I was throwing at Eileen-II. I don't have a tendency to run many small tasks which use many threads---I tend to throw one or two heavy tasks at once instead. And since I actually have six physical cores (as opposed to the two physical cores of Edythe-III, hyper-threading is not a good trade-off.

With hyper-threading turned off, I was getting much lower CPU temperatures (about 80°C now), and not much change in GPU temperatures (still sub 80°C) while running the same The Outer Worlds. That's a big win for me.

I did not notice any slow downs or anything. That's also a big win for me.

And thus, that is my current set up for Eileen-II.

I don't have anything else to add for now, and so that's all for today. Till the next update, I suppose.

Tuesday, February 16, 2021

Emblem 3

Looking back, I realised that I wrote an entry explaining my first icon, but have not written anything about the change that I did in 2015, and the more recent one in 2020. So I suppose I should rectify this here.

And that's why this is entitled Emblem 3 instead.

Anyway, here is the relevant description from then as reference:
It is sort of the placemarker for me in the digital realm, I suppose. The significance is simple: M, MT are my initials, and the dotted image in the lower right corner is the Glider, a configuration of cells in Conway's Game of Life---a hacker emblem.

This means that I identify with the concept of the ``classical'' hacker (not the media-bastardised version that means breaking into computer systems and such).

Alright, enough of random thingamagigs. That said, it is only an emblem/coat of arms---I do not guarantee that everything that contains that symbol is indeed from me---please be discerning.
The new icon from 2015 is basically this:
The symbology is the same, but this time, we have a new negative space region that takes up half the viewable area. This symbolises the change that I have undergone, moving from a purely overly naïve believe-in-the-good-of-everyone type of person into one who knows of the Dark Side. But notice that the hacker emblem is still in the white---it means that no matter how the Dark Side occurs, I will not sacrifice my hacking ethics to it.

Some time after 2015 was when the whole ``circle cut out'' profile pictures became a thing. Naturally, it screwed up my emblem---it's decidedly square. The ``circle cut out'' damaged my emblem by just chopping random bits off---I find it deeply offensive that with all the talk about inclusion, that the trend of excluding people who don't really like to use their real ``human'' pictures as profile pictures. Eventually annoyed, I started looking for ways to transform my square emblem into something that is more circular, settling for a formula that maps all points of a unit square into points of the largest circle that can be inscribed within the same unit square. Naturally, I wrote a program to do it, and fine-tuned it more carefully so that it can generate the 16×16 favicon image more precisely than I can ever do by pixel art.

The end result in 2020 was this:
It looks a little funky because there isn't a border that circumscribes the circle, but that's usually not a problem---it is only one here because Blogger's manner of inserting images does not encircle things, and I am too lazy to attempt to fix it. Symbolically, it means that while I retain all the characteristics of what I wrote in 2009 and 2015, I am also starting to become more well-rounded as a person on a whole, carefully trying to adjust the sharp corners into rounded ones, becoming a person that is less abrasive than before.

To be fair, that last bit is probably going to be a work in progress. But it's okay!

I think that's all I would want to write for now. Till the next update.

Monday, February 15, 2021

Popping Colours

Hello! It's almost exactly a month since the start of my sabbatical, and what a month it has been. I won't summarise what has happened thus far, mostly because I have written quite a bit of it here already.

Instead, I will just continue with what I normally want to say.

First off, I'd like to make a small shout out to The_Laptop Writes..., my blog that features poems. It is the other blog that I sometimes update in lieu of writing something here. There are a few reasons why I might want to do that, but the main one is simple: sometimes I just don't feel like writing prose of any sort.

With that out of the way, I just want to report that the weird wrist pain that I have been facing with has been alleviated through the use of topical Ketoprofen in the form of a Kefentech-brand plaster. The idea here is less about the pain-killing effect and more on the anti-inflammatory effect. I can tolerate a lot of kinds of pain, and my personal philosophy is that pain is a strong symptom that something is wrong. Usually this something is either a breakage, or an increase in pressure somewhere. In cases where infection isn't suspected (e.g. no breakage of skin, no ``high pressure'' sensation, no obvious discolouration), it is usually the case that it is some kind of swelling from inflammation. Normally I would go for oral Ibuprofen pills, but since the wrist thing is sufficiently superficial as compared to say some deep muscle aches, I decided to make use of the topical approach instead.

Works like a charm.

I think I should be a little more careful with how I type with this new set up where I raised the height of Eileen-II differentially to improve the airflow. I still think that it is a good idea to keep doing so, because while running The Outer Worlds (which is a modern 3D game that burns lots of CPU and GPU), the overall fan speed and generated thermal energy are well tolerated.

------

With the Chinese Lunar New Year ``festivities'' weekend out of the way, it is back to something that is more mundane. I have managed to make a little progress through Deep Learning, but have been having lots of fun with watching welding videos, hydraulic press videos, and crazy ``game tester'' videos. It's all good fun.

I fixed my JavaScript text prettifier to take into account the `、' character, treating it like a `/' with the associated association rules, just in case. That text prettifier is really done by now, and these days I'm just identifying various edge cases to update.

All my blogs use it to ensure that the text looks as pretty as I can get away with.

I have also changed up the colours for the read-links on the sidebar. They now pop out of the dark background much better.

I think that's all I have for today; back to The Outer Worlds I go. Till the next update.

Saturday, February 13, 2021

The Outer Worlds

It's the second day of 辛丑 year, also the eve of ``Valentine's Day''.

And I realised that I had not written anything for nearly 3 days. What a shocker!

To rectify this, here I am again, writing a short blurb.

This year's Chinese New Year is very uneventful personally, mostly because there is nothing to be done for the Chinese Orchestra (we have not been rehearsing for nearly a whole year), no visiting (as stated before), and uh... no outings of any sort. I spent some time archive bingeing Sam and Fuzzy, which had an absolutely epic story arc that finally concluded and segued into something more piece-meal, over nearly 20 years.

That's a really long time for anything, including web comics. I've also powered through a littlee of the Deep Learning book, but got really tuckered out from reading, no thanks to the thing that I wrote that I will not write about on Wednesday.

Thanks to the 50% Steam sale, I purchased The Outer Worlds---just the base game though, and not the DLC(s)/Season Pass. It is an homage to games like Fallout New Vegas, Fallout 4, and BioShock, a first-person shooting RPG with a quasi-open world concept. It's fun, the writing is good, and the gunplay is good enough. I was looking for something of this sort for a while---Borderlands 3 was on my radar for quite a while, but people have been consistent in saying that the only good thing out of it was the gunplay and not the writing. I did mull over it, and frankly, of all the Borderlands games, I loved Borderlands 2 the most because it had good writing. I bought and played Borderlands: The Pre-Sequel, and it wasn't so good, and people were saying that it had better writing than Borderlands 3!

It plays closer to Fallout: New Vegas, what with similar mechanics, but it is definitely less buggy---I have not gotten Fallout: New Vegas to run nicely. It also looks a little dated these days. Ah well.

The more astute would ask, ``hey, didn't you say you were going to complete Feudal Alloy?'' Yes, yes, I know---I also said I was going to complete Halo 2 of The Master Chief Collection to some other folks. Patience---these are games that will be played.

It's just a matter of time. =)

One last piece of news---I somehow managed to bust up my right wrist. I think that it could be an overuse injury from typing at an odd angle (I have been keeping Eileen-II raised to improve airflow to keep the temperatures from going too high in non-airconditioned hot and humid Singaporean weather) for too long, again relating to the alluded to event-that-will-not-be-written-about on Wednesday. It'll heal.

After all, it's just a matter of time. =)

Okay, that's all I have for today. Till the next update.

Wednesday, February 10, 2021

One-key Flute Goodness

The end of 庚子 is upon us, and we are about to usher in 辛丑 in less than two days.

I feel older yet again. But that's not new.

I think what is new is that I am starting to seriously enjoy the freedom that I have from not having to be at anyone's beck and call. True, I am getting no income due to not having a paying job, but I am starting to feel fulfilled, an actual level of contentment within.

And to be disrupted from this... made me angry.

Anyway, apart from some things that I cannot write about here, I spent some time doing up a less crazy version of the fingering chart for my A415 one-key Stanesby Junior baroque flute.

It's only less crazy because the chart records what the fingers are doing as opposed to what the holes are doing. This is a subtle point that can drive one nuts.

The more astute may notice that the fingering pattern looks more piccolo than one-key flute, and they would be right since it is based on the piccolo woodwind diagram in Lilypond. Using the piccolo pattern means I can avoid having to write my own drawing pattern, but it is only a matter of time before I have to do that... assuming I want to create charts for the various dadi that I have.

Anyway, that's all I have for today. Till the next update.

Tuesday, February 09, 2021

OMAD Restart

I think I'm finally back on the bandwagon on my weight loss journey that I started roughly when I started at my last work place, going back to just having one meal a day. I suppose I am starting to be a little bored with snacking, and am otherwise occupied with enough activities that take my mind off that of food.

Is this a sign of improvement of my mental state? Can it last? Only time will tell. Also, 2019 was a life-time ago, given all that had transpired in between.

In other thoughts, I am not really a fan of ordering food to be delivered to the apartment when I am in Singapore, mostly for the reason that I literally live next to the neighbourhood centre where there are at least five different coffee shops [that sell food and are not those frou-frou cafés], making it supremely easy to grab almost whatever I want. When I was studying in the US, there were many reasons to rely on food delivery services, the most important of which was to avoid having to dress up to head out, especially in the winter months. That, coupled with the fact that the nearest food place was usually more than one mile away meant that if I was at home, one main meal would likely to be from a food delivery service.

I cooked at home back in the day, but it took time and effort, things that I was sorely lacking while grinding through what would turn out to be a rather bad post-graduate situation. So often times it was easier to just have something delivered instead. Groceries shopping without a car was tricky but not impossible---just piecewise purchases each time I left the apartment to head out to classes/the office.

However, back in Singapore, one of the few times that I did not mind using some kind of food delivery service was when I was trying to buy meals for more than myself, i.e. for my family. In this case, the convenience of not having to queue at different places and bring the said food back definitely overruled everything else.

That said, I would rather order from places where they fielded their own food delivery service, instead of relying on one of those pesky ``platforms''. Call it laziness from not wanting to create yet another account on something that I use rarely, or call it trying to vote with my wallet against exploitive practices---it doesn't matter.

So, none of that ``Grab Food'', ``Food Panda'', ``Deliveroo'', or ``Uber Eats'' (is that still alive?) for me.

And no, there really isn't much of a point that I am trying to make here. At best, it is just small talk to mark the passing of yet another day.

Till the next update, I suppose.

Monday, February 08, 2021

It's the Head Shave Man...

Welcome to Monday.

It was restful for the most part. I went ahead to get my head shaved at VR Hair Stylish. I like the place because it's cosy, and does an amazing job with the head shave/facial hair shave combination. The first time that I sported the shaved head look was about a year ago, when I was frustrated with the amount of distractions that I was getting while keeping some hair when the going was getting tough. The head shave was a literal symbol of ``go-time'' that meant nothing less than pure righteous anger and forward movement in spite of all obstacles.

It was an evolution of the shorter hair style that I had gotten into past 2015 or so when I started to realise that I was getting all kinds of weird hairline issues. There is the ``M''-shape aspect of it which had got to the point where trying to even keep a side parting would mean a horrible comb-over look, or to have a split up central tuft. It got worse over the recent years when the hairline closest to my temples were actively thinning.

Rather than wait to look ridiculous, I just chose to get started on the completely shaved head look. My skull is apparently round enough for the look to actually be somewhat decent, which is a plus to me of course. During the circuit breaker period last year was when I pulled up my old hair clippers to give myself a close cropping of no more than one-eighth inch---that was a length that I would be comfortable with, but between paying the neighbourhood barber for a quality head shave and the effort to take out the hair clipper to do-it-myself and then perform upkeep on the same clippers, I would rather the former.

I have also stopped growing my moustache. It wasn't that I hated it, but that with the current control regime, the old reason of it providing enough protection against an inflammed skin between the nostrils and the upper lip was no longer valid since my nose was no longer consistently in that bunged up state that necessitated lots of rubbing.

I suppose part of the reason was that I wanted to change my visual identity after the break-up, sort of like how women chop their hair down after they are done. But this is really secondary in nature.

Another different reason for the removal of the moustache [via shaving] is the dryness of some parts of the skin, sort of like dandruff, if it makes any sense. No, it is not diagnosed or anything, but an observation. The couple of months so far with the removed moustache has seemed to abate this particular problem.

I did say that things were restful for the most part, but there were one or two things that came up that made me freak out a little. But after praying for a bit, I feel better. I suppose part of being a believer is the knowing that I can literally cast my worries onto God, mostly because worries are just thoughts that cycle about with no productive outcome. Casting them unto God lets Him know about what is going on in my mind, and praying about them unto God informs Him of what I may actually be looking for deep within myself through the intervention of the Holy Spirit. And thus, in the end, the worries become less so because I am reminded of the love of God, and that it is His will that things will turn out the way they will be---I merely make my own choices out of my own free will.

One last thing before I end this entry is perhaps a little enlightenment of why I seem to be writing more often than before. I think the main reason is to provide a mechanism to mark time. When I am at work, marking time is easy due to the different tasks/phases of the projects, as well as the different [daily] interactions with various colleagues. But when I am camping out at home, every day can become very same-y without any observation; this makes the tracking of time beyond day/night problematic. Writing blog entries is a great way to ensure a certain mindfulness as I go through the day. That said, it is not a must that I will be writing entries every day. I do try to ensure that each day is not a ``zero'' day where nothing happens, but whether it is noteworthy (and safe) enough to be placed on this blog, or if it is private enough to go into the dead-tree journal is just a case of spur-of-the-moment judgement.

I am not going to lie, I do miss the days of being in a relationship where I could literally share my day with someone else, and have her share her day with me too. There is a certain level of intimacy and trust that is much closer than that of say the care group from church, or even my own parents. I miss that a lot, as well as the physicality of actually holding someone.

I can share my day with God, but it is... different. He doesn't share His day with me---the very concept of it is impossible to imagine, and by definition, unfathomable by mortal minds. It is more of a reverent-type of relationship between me and God that is not the same as between me and a significant other.

Does this mean that I am ready to start on another relationship [with a human female]? No, I don't know, but I don't think so. There are some other things to unpack and reshape, and it really isn't the right time now.

Till the next update, I suppose.

Sunday, February 07, 2021

Adi Parva Done

After a marathon session today, I have finally completed Adi Parva of The Mahabharata of Krishna-Dwaipayana Vyasa. This means I can finally start on the next ``big'' book of some importance: Deep Learning by Goodfellow et al.

I am not sure if I have mentioned this before, but literary style of The Mahabharata is very similar to that of The Book of the Thousand Nights and a Night---there exists a large framing story that contains the main narrative, followed by sub-narratives that come in as and when obvious unresolved hooks appear. It reads pretty fast for a large work, but it still is a large work.

------

Today we had our reunion lunch at my sister's place together with my brother-in-law and nephew. This is not normal, because we usually have my mum cooking and having my sister's family over instead. Thanks to the nonsense that is COVID-19, and my mother's recent medical issues, it was just not worth it to have it done the way we normally did. Instead, we ordered catering from Chilli Api Catering Pte Ltd. Ordering was relatively pain-free, and the delivery was prompt. The food that was delivered was still warm, was delicious, and was of the advertised quantity. Overall, it was a good experience---I think that we can seriously consider them for other such events in the future. Let's see if they can hang around long enough for that to happen again.

------

I was supposed to write an entry for yesterday, but I was just so tired at the end of the day. So I suppose I will write about it now then.

I spent much of the early afternoon on Saturday playing my various dizi, working from the 倍大 C and slowly making my way down to the 小 C, playing most pieces from memory. At the 曲笛 range of 大 C, I just played quite a few Chinese New Year pieces, changing keys without using the ``correct'' dizi. The C 曲笛 can comfortably play the keys of C-major (筒音作5), F-major (筒音作2), G-major (筒音作1), D-major (筒音作4), B♭-major (筒音作6), and E♭-major (筒音作3). But these are really nothing new---at this point, all these different fingering patterns are already innately understood and easy to apply by me. What is a little different is the need for the increased compass required when playing some of the Chinese New Year pieces using a different key---there is often times a need to jump to a high-octave tonic. It's not impossible, but it does take good control.

And it took me a while to get back the good control. A good warm up is always necessary before I can get a good tone, and that happens whether or not I have been playing throughout the week.

The late afternoon/early evening was spent at service at Pasir Panjang Christ Church. Main thing that I want to remember in public is the Thaxted tune that was used in the hymn O God Beyond All Praising, and that the hymn book is indeed Hymns of Praise, but is from Christian Nationals' Evangelism Commission (CNEC). No wonder it was this much harder to find it online---it is a very regional thing. What to do with this information, I currently do not know, and will just keep it here for future reference. God will guide the way forward.

Anyway, I subsequently met up with YT at Blk 340 Ang Mo Kio Ave 1 to check out the Deli Kopi Shop. Specifically, we were looking at the Mentaiko Maki from the ``Hot Jap'' stall. The price point of SGD8.90 for a basic Maki is reasonable, considering that the basic Maki itself had 8 pieces, each was larger than what I would normally put into my mouth. While there, YT introduced me to lok lok, which is basically JB-style skewered junk food; the stall in question was ``Loklok 1991's by Daniel & Meng''. The short answer is, it tastes damn bloody good. The way the skewered food items are cooked give them that nice char-feel without actually being so dry that they lose their original texture. The closest analogue I can come up with is, the texture of those so-called vegetable chips but with more ``natural'' flavour.

We did not happen upon them in a vacuum: review of the Maki, and the review of the loklok from Mothership respectively.

It was a good meet up with YT, catching up a little bit more on the goings-on since the call that we had with roticv. She's hanging on, I'm chillaxing, and we sort of co-bitched about the situation around us. But that's life after all, we talk to people, we commiserate with friends. And those of us who are believers will go to God in prayer to seek direction and clarity, knowing that while we have the agency of making our own decisions, that in the end, it is still the sovereign God whose Will determines the outcomes.

------

Oh, before I am done with today's entry, I want to add that Ding did send me a belated birthday greeting.

Till the next update I suppose.

Friday, February 05, 2021

Web Comics Crawling

Man, it has been a looooooooong while since I wrote an entry tipsy.

My choice of poison for the evening was the Absolut Oak. I am not usually one who goes about buying ``limited edition'' drinks, but this was bought from a friend a long while back while said friend was trying to off-load some of the things that was obtained when with a spouse-to-be that didn't. It was not something that I would normally get either (not really a vodka person), and the first time that I tried it, it tasted bad compared to the whiskeys that I was trying at the same time.

Funny enough, over time, the flavour profile became more palatable.

Anyway, the purpose of this entry isn't about talking about the spirits that I have been quaffing, but on what I had done for the day.

I updated some of the off-line copies of web comics that I have been following through careful crawling with my own scripts. These scripts had been written in Python2, but since that [version of the Python interpreter] is no longer going to be updated, I have taken the opportunity to update it to Python3 as well. The crawling principle is simple: from a given starting HTML page, find which is the comic image, download it, wait some time, then follow the ``next'' link to the next comic image and continue the process until we reach a loop or no way of proceeding.

I like to create off-line copies of my web comics for the simple reason of making it easier to go through the material at my own leisure. The creation of cbr files means that it is infinitely more portable than relying purely on the online access. I can just view them with any associated readers, like CDisplayEx on the PC or Perfect Viewer for Android.

I'm not linking to CDisplayEx because it allegedly has CandyOpen malware, which I honestly have not seen the effects of. I use MVPS hosts as the last line of defense at the O/S level to prevent connections to sketchy servers via DNS, so that may be a reason why I am not seeing any issues.

Or it could be that they have removed said malware. Who knows, really?

At the same time, I have been reading more of Adi Parva of The Mahabharata of Krishna-Dwaipayana Vyasa, clocking in at another 98 pages today. The current page count is 472/768 completed, and I seem to be on track to complete this first book by end of next week. Then I can start on something else, while slowly advancing my progress on Harrison’s Principles of Internal Medicine (20th Edition).

That's all I have for today. Till the next update.

Thursday, February 04, 2021

Meds and Fingering Charts

I would have written something yesterday, but I got tired. So it will be an entry today instead.

I ran some errands yesterday, and ended up at Five Guys @ Plaza Singapura for a lunch-dinner combination. As usual, I got a Bacon Cheeseburger ``all the way'' (i.e. all the toppings), Cajun fries (large), and a Corona Extra beer. Definitely delicious; I had been craving for some meat for quite a while. I think it is something that happens at least once a week, so I need to take that into consideration when I plan my going-out time.

I also dropped by Essentials Pharmacy to grab some of my standard medicines to deal with the sensitive skin issue. While I am no longer oozing serum from broken skin like a monster like in the bad old days, there is still some maintenance needed as the weather conditions get more and more unpredictable. I have a decent regime set up: basic mometasone furoate for skin inflammation control, use of loratidine and chlorpheniramine as oral anti-histamines for the day time and night time respectively. As for cleansing, Simple soap is used instead. As simple as it sounds, the soap seems to be exceedingly hard to find in Singapore for some reason, at least, if one is using the brick and mortar shops. But I digress.

I was listening to 李镇's 《走西口》 album from 1999 for most of the travel time, and am reminded about the beauty that is the expression of the humble bamboo 笛子. Yes, I play a lot of concert flute, but in the end, the dizi is still the superior expressive instrument, mostly because of how raw it gets when it comes to techniques of expression; it relies on emotive power over music theory to get what it wants across. 李镇's pieces were not highly complex musically, but they have a good sense of melody and feel in them that makes them oh-so-alluring. Good flute music is amazing too, don't get me wrong, but at some fundamental level it still relies heavily on the Western construct of music theory to bring out the beauty within.

Is that bad? No, it's just different, and I wish that more people would understand that and realise that everyone can stand to learn a bit more about how music is interpreted and performed by different peoples and cultures.

------

I spent much of today working on adding the new page of fingering charts on my 笛子 materials set of pages. It is, in many ways, pandering to the types of terms that are used by people to search and click into my web site. There are already ample information on fingering charts within, like concert pitch-bangdi mapping and concert pitch-qudi mapping, fingering pattern charts for the different tongyin, and even the most crazy 12-tone fingering pattern chart that provides additional information on how to find the right keys to change, but I suppose people are just fundamentally lazy.

I must admit that the dizi, when looked at from a very high performance level, is a very cerebral type of instrument. I tried my best to capture all these in ways that would make sense, but it seems like it might not be well appreciated.

And so, I pandered by writing up the fingering charts using Lilypond, and more specifically, the woodwind diagrams. The tin-whistle pattern sufficed for the 6-hole dizi, and it was what I ended up using.

If I want to do the same thing for the dadi and/or xiao, I will need to learn how to hack scm/define-woodwind-diagrams.scm and scm/display-woodwind-diagrams.scm. I had a quick glance into them---they are non-trivial to mess about with.

Apart from doing up the 6-hole dizi charts, I took the opportunity to put together a simplified generic saxophone fingering chart, with the original intension of adding in the altissimo stuff. As I worked through with my tenor saxophone, altissimo on the saxophone is hard---I was not even good with playing harmonics with the correct intonation on the horn. Without this strong fundamental, there was no way to tackle the altissimo register at all. So that's something I need to work on.

But that aside, here is the chart as it stands:
I don't really have anything else to say. Till the next update, perhaps.