Move indexes backwards by 1
This commit is contained in:
16
blog/content--01
Normal file
16
blog/content--01
Normal file
@ -0,0 +1,16 @@
|
||||
<header>
|
||||
<h1>My Little Blog</h1>
|
||||
<aside>Hi. I write about my career and various technologies that I experiment with.</aside>
|
||||
</header>
|
||||
|
||||
<ul>
|
||||
<li><a href="blog-007">2020-06-08 Some Website Design and CSS</a></li>
|
||||
<li><a href="blog-007">2020-05-22 Optimizing Web Pages and File Sizes</a></li>
|
||||
<li><a href="blog-006">2020-05-21 A Hit of Kubernetes</a></li>
|
||||
<li><a href="blog-005">2020-03-02 The SBC Change</a></li>
|
||||
<li><a href="blog-004">2019-09-18 ? Matched Expression Does Not Print in Perl</a></li>
|
||||
<li><a href="blog-003">2019-08-29 Configuring Dynamic DNS Records</a></li>
|
||||
<li><a href="blog-002">2019-08-07 The Migration</a></li>
|
||||
<li><a href="blog-001">2019-06-20 The First Entry</a></li>
|
||||
</ul>
|
||||
<hr>
|
@ -1,16 +1,23 @@
|
||||
<header>
|
||||
<h1>My Little Blog</h1>
|
||||
<aside>Hi. I write about my career and various technologies that I experiment with.</aside>
|
||||
<h1>The First Entry</h1>
|
||||
</header>
|
||||
|
||||
<ul>
|
||||
<li><a href="blog-007">2020-06-08 Some Website Design and CSS</a></li>
|
||||
<li><a href="blog-007">2020-05-22 Optimizing Web Pages and File Sizes</a></li>
|
||||
<li><a href="blog-006">2020-05-21 A Hit of Kubernetes</a></li>
|
||||
<li><a href="blog-005">2020-03-02 The SBC Change</a></li>
|
||||
<li><a href="blog-004">2019-09-18 ? Matched Expression Does Not Print in Perl</a></li>
|
||||
<li><a href="blog-003">2019-08-29 Configuring Dynamic DNS Records</a></li>
|
||||
<li><a href="blog-002">2019-08-07 The Migration</a></li>
|
||||
<li><a href="blog-001">2019-06-20 The First Entry</a></li>
|
||||
</ul>
|
||||
<h2>What is this website running on?</h2>
|
||||
<p>It is running on an aging HP netbook hand-me-down from my sister. It runs on an Intel Atom N450 with a measly 1GB RAM. I use it to host various other services for my personal use, and I take it as a challenge to keep RAM usage low.</p>
|
||||
|
||||
<p>I once thought of joining the mainstream by purchasing a VPS or subscribing to those fancy websites such as Squarespace, but I've learnt a lot building everything from ground up. In hindsight, I would have done it all over again because in the end, it was worth it.</p>
|
||||
|
||||
<h2>What distribution do I use? </h2>
|
||||
<p>Strictly Debian. Debian has yet fail me. Its stability remains undefeated compared to all others and patches come faster than lightning. Debian frees me from worrying about how I conduct my learning activities and the licensing burdens of software involved. I propose to agree to disagree with all others who have a different opinion.</p>
|
||||
|
||||
<h2>Why do you compose your website in this specific format? </h2>
|
||||
<p>To reduce bandwidth costs and system load. I needed to deliver a beautiful and readable format at a minimal amount of page size, so I plagiarized <a href="http://bestmotherfuckingwebsite.com">bestmotherfuckingwebsite.com</a> (all credits to the site creator). I greatly admire the simplicity involved to produce such a stunning website. I find it a golden standard that websites should adhere to, when compared to the mess that most websites are these days. When I have time, I would like to play with web design to improve upon his design, but I find it hard to improve upon perfection.</p>
|
||||
|
||||
<h2>Is this a Q&A?</h2>
|
||||
<p>I have not pinned down the style and format of how I want to keep writing these blogs. I use too many I's, which violate the readability of this site. Too much white blinds the eyes. This site might get cached in Google or stored in WayBack Machine way longer than I might consider to keep it running on my server. Things change; so will my decisions with this site down the line.</p>
|
||||
|
||||
<hr>
|
||||
<p><div class="navbar">
|
||||
<div><a href="blog-000">Prev</a></div>
|
||||
<div><a href="blog-002">Next</a></div>
|
||||
</div></p>
|
||||
|
@ -1,23 +1,18 @@
|
||||
<header>
|
||||
<h1>The First Entry</h1>
|
||||
<h1>The Migration</h1>
|
||||
</header>
|
||||
|
||||
<h2>What is this website running on?</h2>
|
||||
<p>It is running on an aging HP netbook hand-me-down from my sister. It runs on an Intel Atom N450 with a measly 1GB RAM. I use it to host various other services for my personal use, and I take it as a challenge to keep RAM usage low.</p>
|
||||
<p>I've been moving from a rented place to another place, so I've been busy with those affairs instead of getting productive with my hobbies. Long story short, there were massive issues with my move and I was terribly preoccupied. </p>
|
||||
|
||||
<p>I once thought of joining the mainstream by purchasing a VPS or subscribing to those fancy websites such as Squarespace, but I've learnt a lot building everything from ground up. In hindsight, I would have done it all over again because in the end, it was worth it.</p>
|
||||
<p>Many important events have since been announced, mainly the release of RHEL8 and Debian 10. With this, Debian Stretch is counting down to its final hours. In typical Debian fasion, Buster is rock solid and is still as lean as it can be. They even have legacy support for iptables. I am very impressed. I am hoping that a team will pick up extended support for Stretch. The release of RHEL8 has been very unfortunate. I have been planning to take the RHCSA exam but I am worried that the exam will be testing on RHEL8 instead. If you have not read the changes, RHEL8 has made a rather radical departure from RHEL7, just like how RHEL7 did with its predecessor too. The release of AppStreams, the deprecation of yum, nftables and the like. </p>
|
||||
|
||||
<h2>What distribution do I use? </h2>
|
||||
<p>Strictly Debian. Debian has yet fail me. Its stability remains undefeated compared to all others and patches come faster than lightning. Debian frees me from worrying about how I conduct my learning activities and the licensing burdens of software involved. I propose to agree to disagree with all others who have a different opinion.</p>
|
||||
<p>Looks like I would have to postpone taking my exam in the mean time.</p>
|
||||
|
||||
<h2>Why do you compose your website in this specific format? </h2>
|
||||
<p>To reduce bandwidth costs and system load. I needed to deliver a beautiful and readable format at a minimal amount of page size, so I plagiarized <a href="http://bestmotherfuckingwebsite.com">bestmotherfuckingwebsite.com</a> (all credits to the site creator). I greatly admire the simplicity involved to produce such a stunning website. I find it a golden standard that websites should adhere to, when compared to the mess that most websites are these days. When I have time, I would like to play with web design to improve upon his design, but I find it hard to improve upon perfection.</p>
|
||||
|
||||
<h2>Is this a Q&A?</h2>
|
||||
<p>I have not pinned down the style and format of how I want to keep writing these blogs. I use too many I's, which violate the readability of this site. Too much white blinds the eyes. This site might get cached in Google or stored in WayBack Machine way longer than I might consider to keep it running on my server. Things change; so will my decisions with this site down the line.</p>
|
||||
<p>This is a rather short post, because I just wanted to update right after configuring the web server to work with the router. Thanks for reading.</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<p><div class="navbar">
|
||||
<div><a href="blog-000">Prev</a></div>
|
||||
<div><a href="blog-002">Next</a></div>
|
||||
<div><a href="blog-001">Prev</a></div>
|
||||
<div><a href="blog-003">Next</a></div>
|
||||
</div></p>
|
||||
|
@ -1,18 +1,22 @@
|
||||
<header>
|
||||
<h1>The Migration</h1>
|
||||
<h1>Configuring Dynamic DNS Records</h1>
|
||||
</header>
|
||||
|
||||
<p>I've been moving from a rented place to another place, so I've been busy with those affairs instead of getting productive with my hobbies. Long story short, there were massive issues with my move and I was terribly preoccupied. </p>
|
||||
<p>After moving to the new place, I realized that my website kept going down every other day. This immediately struck my interest as my IP address kept changing. At first, I thought it was a trigger-happy housemate restarting the Internet connection every time the average ping deviated by a few milliseconds. After configuring my A records for like the third time, I felt it was time to investigate.</p>
|
||||
|
||||
<p>Many important events have since been announced, mainly the release of RHEL8 and Debian 10. With this, Debian Stretch is counting down to its final hours. In typical Debian fasion, Buster is rock solid and is still as lean as it can be. They even have legacy support for iptables. I am very impressed. I am hoping that a team will pick up extended support for Stretch. The release of RHEL8 has been very unfortunate. I have been planning to take the RHCSA exam but I am worried that the exam will be testing on RHEL8 instead. If you have not read the changes, RHEL8 has made a rather radical departure from RHEL7, just like how RHEL7 did with its predecessor too. The release of AppStreams, the deprecation of yum, nftables and the like. </p>
|
||||
<p>After a couple times of Googling, it turns out that the ISP at this new place is a smaller ISP. This ISP rotates the IP address every couple of days. So how would the laborious process of identifying my IP address, and then updating my A records be inevitable? Turns out not.</p>
|
||||
|
||||
<p>Looks like I would have to postpone taking my exam in the mean time.</p>
|
||||
<p>The solution was to use Dynamic DNS, which actively updates my A records with my registrar. To do so, I had to install ddclient on my Debian install. However, the available ddclient on Debian Stretch was rather out of date. Getting the newer version was a simple affair of adding Buster's Unstable repos, then enabling it to start during boot. But wait, isn't Debian Buster already in stable? Turns out I had already configured ddclient some time ago prior moving to this new place, a time where Buster was still brewing in Unstable. What a pleasant surprise when I fired up sources.list.d only to find that everything was already there. Thank you, past self. </p>
|
||||
|
||||
<p>This is a rather short post, because I just wanted to update right after configuring the web server to work with the router. Thanks for reading.</p>
|
||||
<h2>If ddclient was already configured, why would I still have issues with a IP address?</h2>
|
||||
|
||||
<p> After a bit of sleuthing, it turns out that I had to enable Dynamic DNS with my registrar, Namecheap. I had to also change my A records to what Namecheap calls A+ Dynamic DNS Records. With my A+ Dynamic DNS Records ready and ddclient's configuration double checked, I hesitantly left my server to its own devices.</p>
|
||||
|
||||
<p>It has been almost two weeks since that day, and everything is working fine. No downtime, no more stressful hours worrying about my server as I was stranded at work. What a relief. Well that's all I have to write for this post. Thanks for reading.</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<p><div class="navbar">
|
||||
<div><a href="blog-001">Prev</a></div>
|
||||
<div><a href="blog-003">Next</a></div>
|
||||
<div><a href="blog-002">Prev</a></div>
|
||||
<div><a href="blog-004">Next</a></div>
|
||||
</div></p>
|
||||
|
@ -1,22 +1,61 @@
|
||||
<header>
|
||||
<h1>Configuring Dynamic DNS Records</h1>
|
||||
<h1>? Matched Expression Does Not Print in Perl</h1>
|
||||
</header>
|
||||
|
||||
<p>After moving to the new place, I realized that my website kept going down every other day. This immediately struck my interest as my IP address kept changing. At first, I thought it was a trigger-happy housemate restarting the Internet connection every time the average ping deviated by a few milliseconds. After configuring my A records for like the third time, I felt it was time to investigate.</p>
|
||||
<p>I decided to name this post to the name of the Stack Overflow question I posted, because it depicts how a simple question had guided me into the rabbit hole that is regular expressions. For those who are familiar with Perl and regexes, this might be trivial; for others who are not, this might be boring. I don't think there is any position in between. Anyway, let's get started.</p>
|
||||
|
||||
<p>After a couple times of Googling, it turns out that the ISP at this new place is a smaller ISP. This ISP rotates the IP address every couple of days. So how would the laborious process of identifying my IP address, and then updating my A records be inevitable? Turns out not.</p>
|
||||
<p>I had this question when I was trying to use Perl to filter text, mainly in the form </p>
|
||||
<div style="text-align:center"><code>printf "Some text\n" | perl -pe 's/text/fun/'</code></div>
|
||||
<p>to get</p>
|
||||
<div style="text-align:center"><code>Some fun</code> .</div>
|
||||
<p> So I want to preface the situation here that I was using Perl as a part of a larger Bash script, not Perl scripting on its own.
|
||||
|
||||
<p>The solution was to use Dynamic DNS, which actively updates my A records with my registrar. To do so, I had to install ddclient on my Debian install. However, the available ddclient on Debian Stretch was rather out of date. Getting the newer version was a simple affair of adding Buster's Unstable repos, then enabling it to start during boot. But wait, isn't Debian Buster already in stable? Turns out I had already configured ddclient some time ago prior moving to this new place, a time where Buster was still brewing in Unstable. What a pleasant surprise when I fired up sources.list.d only to find that everything was already there. Thank you, past self. </p>
|
||||
<p>So, we have a string of text</p>
|
||||
<div style="text-align:center"><code>This is a string.</code></div>
|
||||
<p>However, sometimes we get </p>
|
||||
</p>
|
||||
<div style="text-align:center"><code>This is a test string.</code></div>
|
||||
<p>We want to match</p>
|
||||
<div style="text-align:center"><code>This string</code> ,</div>
|
||||
<p>but when the second string appears, we want to match the <code>test</code> word as well. So, the regular expression has to match</p>
|
||||
<div style="text-align:center"><code>This (test) string</code></div>
|
||||
<p>Sounds straightforward, right?</p>
|
||||
|
||||
<h2>If ddclient was already configured, why would I still have issues with a IP address?</h2>
|
||||
<h2>How do we set out to print an optionally matched substring?</h2>
|
||||
|
||||
<p> After a bit of sleuthing, it turns out that I had to enable Dynamic DNS with my registrar, Namecheap. I had to also change my A records to what Namecheap calls A+ Dynamic DNS Records. With my A+ Dynamic DNS Records ready and ddclient's configuration double checked, I hesitantly left my server to its own devices.</p>
|
||||
<p>In our case, the substring is <code>test</code>, and it is optionally matched. Prior to this problem, I was using this</p>
|
||||
<div style="text-align:center"><code>s/.*(This).*(string).*/$1 $2/</code> ,</div>
|
||||
<p> I "selected" the matched subtrings as groups, and then proceeded to only print said substrings, leaving the rest behind. It worked. To have a group that is matched zero or 1 times, we use the <code>?</code> operator. This was exactly my case with the <code>test</code> substring, so naturally, it made sense to do this right?</p>
|
||||
<div style="text-align:center"><code>s/.*(This).*(test)?.*(string).*/$1 $2 $3/</code></div>
|
||||
<p>Except that it didn't work.</p>
|
||||
|
||||
<p>It has been almost two weeks since that day, and everything is working fine. No downtime, no more stressful hours worrying about my server as I was stranded at work. What a relief. Well that's all I have to write for this post. Thanks for reading.</p>
|
||||
<p>The above expression gave me</p>
|
||||
<div style="text-align:center"><code>This string</code> .</div>
|
||||
<p>A sad, double-spaced emptiness in between the first and second substring. Clearly something went wrong. I will skip you through and just let you know how we will end up with the final result.</p>
|
||||
<p>One of the issues with my expression was the use of <code>.*</code> . In regular expressions, using it means it will match any character of any length with <b>greedy</b> matching. Regex engines will use a process known as backtracking to do the matching. It means they swallow up as much of the input feed as they can, and then spit it back bit by bit to match the next part. In my expression, the <code>.*</code> after <code>(This)</code> matches the rest of the line : there is nothing left in the input feed. Since the next part was optional, matching nothing was still considered acceptable and Perl went by its merry way, which was <code>.*(string).*</code> . Here, the matching was mandatory, so it backtracks from the rest of the line to the point where it matches. No issues here. </p>
|
||||
|
||||
<p>So, we use <b>non-greedy matching</b> then, right? We replace <code>.*</code> with <code>.*?</code> and everything will be fine. Turns out no. We still get the same string</p>
|
||||
<div style="text-align:center"><code>This string</code> .</div>
|
||||
<p>This is because non-greedy matching matches the shortest string it can, which was nothing. In turn, the <code>(test)?</code> group does not match the next part of the input feed, but it is OK because it is optional, and then etc. In the end, this does not work out either. Turns out my expression required a rewrite, not a small fix. This is the solution I learnt from the amazing guys over at Stack Overflow.</p>
|
||||
|
||||
<div style="text-align:center"><code>s/.*?(This)(?:(?!test).)*(test)?.*?(string).*/$1 $2 $3/</code></div>
|
||||
|
||||
<p>I hope I did not bore you at this point, because there is a lot to decipher from solution. The first part is</p>
|
||||
<div style="text-align:center"><code>?!(test).</code></div>
|
||||
<p><code>?!</code> means <b>negative lookahead</b>. It means the matches fail when it matches <code>test</code> in the input feed. The <code> . </code> behind the group is a single character wildcard. Combining with the external parentheses,</p>
|
||||
<div style="text-align:center"><code>?:( ... )*</code></div>
|
||||
<p>we get a very interesting interaction. <code>?:</code> means <b>non-capturing group</b>. Any matches by this non-capturing group is dropped. While <code>*</code> means a match of any length. Combining all three of the previous interactions into</p>
|
||||
<div style="text-align:center"><code>?:(?!(test).)*</code> ,</div>
|
||||
<p>we get the following : Match <b>any character of any length that is not the pattern <code>test</code></b> , into a non-capturing group. When the pattern is found in the input feed, <b>the matching stops the input feed at that point, leaving the pattern intact at the start of the input feed</b>. In turn, the next part of the expression is our <code>(test)?</code> , where it will match our perfectly placed pattern from the input feed! This finally means our optional capturing group finally worked, and the rest is history. We finally get our highly anticipated</p>
|
||||
<div style="text-align:center"><code>This test string</code></div>
|
||||
|
||||
<p>Thank you for sticking around until the end. I learnt a great deal about how regex engines behave, and many more functions of regular expressions from this small question. Was diving into the rabbit hole worth it? Hell yes. Thanks again for reading.</p>
|
||||
|
||||
<p>P.S. I also learnt a lot about HTML for this post. All hail divs.</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<p><div class="navbar">
|
||||
<div><a href="blog-002">Prev</a></div>
|
||||
<div><a href="blog-004">Next</a></div>
|
||||
<div><a href="blog-003">Prev</a></div>
|
||||
<div><a href="blog-005">Next</a></div>
|
||||
</div></p>
|
||||
|
@ -1,61 +1,20 @@
|
||||
<header>
|
||||
<h1>? Matched Expression Does Not Print in Perl</h1>
|
||||
<h1>The SBC Change</h1>
|
||||
</header>
|
||||
|
||||
<p>I decided to name this post to the name of the Stack Overflow question I posted, because it depicts how a simple question had guided me into the rabbit hole that is regular expressions. For those who are familiar with Perl and regexes, this might be trivial; for others who are not, this might be boring. I don't think there is any position in between. Anyway, let's get started.</p>
|
||||
<p>Over the past few months, I had a bit of spare cash in hand, so I thought it was time for an upgrade. But which upgrade path should I take? I agonized over this decision for a very long time. Should I pick up a used 1U server? Should I build a new PC with all these new Ryzen options? Or should I just upgrade my current desktop? In the end, I ended up with the most economical solution of all: the humble Raspberry Pi 4. I built it together with a fan, heatsinks, and a fan to remove more heat. It is powered by the official USB-C charger. That is all. Here is a picture of it in all its glory. I swear I will take a better picture of it one day.</p>
|
||||
|
||||
<p>I had this question when I was trying to use Perl to filter text, mainly in the form </p>
|
||||
<div style="text-align:center"><code>printf "Some text\n" | perl -pe 's/text/fun/'</code></div>
|
||||
<p>to get</p>
|
||||
<div style="text-align:center"><code>Some fun</code> .</div>
|
||||
<p> So I want to preface the situation here that I was using Perl as a part of a larger Bash script, not Perl scripting on its own.
|
||||
<img src="../images/20200302-rpi.webp" margin=auto alt="Raspberry Pi 4">
|
||||
|
||||
<p>So, we have a string of text</p>
|
||||
<div style="text-align:center"><code>This is a string.</code></div>
|
||||
<p>However, sometimes we get </p>
|
||||
</p>
|
||||
<div style="text-align:center"><code>This is a test string.</code></div>
|
||||
<p>We want to match</p>
|
||||
<div style="text-align:center"><code>This string</code> ,</div>
|
||||
<p>but when the second string appears, we want to match the <code>test</code> word as well. So, the regular expression has to match</p>
|
||||
<div style="text-align:center"><code>This (test) string</code></div>
|
||||
<p>Sounds straightforward, right?</p>
|
||||
<p>You are still reading? Well I was planning to have a lab of my own for all kinds of applications, you see. I was also blinded by the plethora of stuff to experiment with. But I got greedy. Looking at the terabytes of LRDIMMs you can fit into a 2U hyperscale server does things to your mind. Never mind the fact that it was all just a pipe dream. I would never have the cash the buy all that RAM nor the applications to fully utilize said RAM. Same goes for all the CPU cores too. Do I *REALLY* need a 44-thread CPU running a few hundred watts on idle? Nah.</p>
|
||||
|
||||
<h2>How do we set out to print an optionally matched substring?</h2>
|
||||
<p>What about upgrading my CPU then? Turns out my CPU is so old there are no upgrade options that can justify forking any amount of money for it. I'd rather just build a new PC with the money. But then, even a new build with Ryzen 3600 still costs a pretty penny. Also, I would have to find a space somewhere to fit another micro-ATX case with all its cables and heat ventilation concerns.</p>
|
||||
|
||||
<p>In our case, the substring is <code>test</code>, and it is optionally matched. Prior to this problem, I was using this</p>
|
||||
<div style="text-align:center"><code>s/.*(This).*(string).*/$1 $2/</code> ,</div>
|
||||
<p> I "selected" the matched subtrings as groups, and then proceeded to only print said substrings, leaving the rest behind. It worked. To have a group that is matched zero or 1 times, we use the <code>?</code> operator. This was exactly my case with the <code>test</code> substring, so naturally, it made sense to do this right?</p>
|
||||
<div style="text-align:center"><code>s/.*(This).*(test)?.*(string).*/$1 $2 $3/</code></div>
|
||||
<p>Except that it didn't work.</p>
|
||||
|
||||
<p>The above expression gave me</p>
|
||||
<div style="text-align:center"><code>This string</code> .</div>
|
||||
<p>A sad, double-spaced emptiness in between the first and second substring. Clearly something went wrong. I will skip you through and just let you know how we will end up with the final result.</p>
|
||||
<p>One of the issues with my expression was the use of <code>.*</code> . In regular expressions, using it means it will match any character of any length with <b>greedy</b> matching. Regex engines will use a process known as backtracking to do the matching. It means they swallow up as much of the input feed as they can, and then spit it back bit by bit to match the next part. In my expression, the <code>.*</code> after <code>(This)</code> matches the rest of the line : there is nothing left in the input feed. Since the next part was optional, matching nothing was still considered acceptable and Perl went by its merry way, which was <code>.*(string).*</code> . Here, the matching was mandatory, so it backtracks from the rest of the line to the point where it matches. No issues here. </p>
|
||||
|
||||
<p>So, we use <b>non-greedy matching</b> then, right? We replace <code>.*</code> with <code>.*?</code> and everything will be fine. Turns out no. We still get the same string</p>
|
||||
<div style="text-align:center"><code>This string</code> .</div>
|
||||
<p>This is because non-greedy matching matches the shortest string it can, which was nothing. In turn, the <code>(test)?</code> group does not match the next part of the input feed, but it is OK because it is optional, and then etc. In the end, this does not work out either. Turns out my expression required a rewrite, not a small fix. This is the solution I learnt from the amazing guys over at Stack Overflow.</p>
|
||||
|
||||
<div style="text-align:center"><code>s/.*?(This)(?:(?!test).)*(test)?.*?(string).*/$1 $2 $3/</code></div>
|
||||
|
||||
<p>I hope I did not bore you at this point, because there is a lot to decipher from solution. The first part is</p>
|
||||
<div style="text-align:center"><code>?!(test).</code></div>
|
||||
<p><code>?!</code> means <b>negative lookahead</b>. It means the matches fail when it matches <code>test</code> in the input feed. The <code> . </code> behind the group is a single character wildcard. Combining with the external parentheses,</p>
|
||||
<div style="text-align:center"><code>?:( ... )*</code></div>
|
||||
<p>we get a very interesting interaction. <code>?:</code> means <b>non-capturing group</b>. Any matches by this non-capturing group is dropped. While <code>*</code> means a match of any length. Combining all three of the previous interactions into</p>
|
||||
<div style="text-align:center"><code>?:(?!(test).)*</code> ,</div>
|
||||
<p>we get the following : Match <b>any character of any length that is not the pattern <code>test</code></b> , into a non-capturing group. When the pattern is found in the input feed, <b>the matching stops the input feed at that point, leaving the pattern intact at the start of the input feed</b>. In turn, the next part of the expression is our <code>(test)?</code> , where it will match our perfectly placed pattern from the input feed! This finally means our optional capturing group finally worked, and the rest is history. We finally get our highly anticipated</p>
|
||||
<div style="text-align:center"><code>This test string</code></div>
|
||||
|
||||
<p>Thank you for sticking around until the end. I learnt a great deal about how regex engines behave, and many more functions of regular expressions from this small question. Was diving into the rabbit hole worth it? Hell yes. Thanks again for reading.</p>
|
||||
|
||||
<p>P.S. I also learnt a lot about HTML for this post. All hail divs.</p>
|
||||
<p>Which brings me back to the little Raspberry Pi 4. 4 cores, 4GB of RAM, 32GB of storage, and gigabit Ethernet. After giving myself a wake up call, I realized nothing fit my needs quite like this open-source oriented SBC. Yes, it isn't 'FSF certified' free, but given the reputation the Raspberry Pi Foundation has built over the years, I am more than happy to support their cause. I look forward to migrating my experiments to this new addition to the family.</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<p><div class="navbar">
|
||||
<div><a href="blog-003">Prev</a></div>
|
||||
<div><a href="blog-005">Next</a></div>
|
||||
<div><a href="blog-004">Prev</a></div>
|
||||
<div><a href="blog-006">Next</a></div>
|
||||
</div></p>
|
||||
|
@ -1,20 +1,16 @@
|
||||
<header>
|
||||
<h1>The SBC Change</h1>
|
||||
<h1>A Hit of Kubernetes</h1>
|
||||
</header>
|
||||
|
||||
<p>Over the past few months, I had a bit of spare cash in hand, so I thought it was time for an upgrade. But which upgrade path should I take? I agonized over this decision for a very long time. Should I pick up a used 1U server? Should I build a new PC with all these new Ryzen options? Or should I just upgrade my current desktop? In the end, I ended up with the most economical solution of all: the humble Raspberry Pi 4. I built it together with a fan, heatsinks, and a fan to remove more heat. It is powered by the official USB-C charger. That is all. Here is a picture of it in all its glory. I swear I will take a better picture of it one day.</p>
|
||||
<p>The website is back online after almost several months. This post is just to show that I'm still alive and well. So, yeah. I tried Kubernetes for my Raspberry Pi. Specifically k3s. It didn't turn out great. Surprise surprise, containers and k8s really turns the concept of system administration on its head. What are charts? Why are kubectl and kubeadm separate commands? Why is everything hidden behind layers and layers of administration and configuration?</p>
|
||||
|
||||
<img src="../images/20200302-rpi.webp" margin=auto alt="Raspberry Pi 4">
|
||||
<p>It is obvious that Kubernetes is a extremely powerful and revolutionary tool. What's even more obvious is that I'm completely unprepared for this. Well, the takeaway here is that I need to read more documentation and tutorials.</p>
|
||||
|
||||
<p>You are still reading? Well I was planning to have a lab of my own for all kinds of applications, you see. I was also blinded by the plethora of stuff to experiment with. But I got greedy. Looking at the terabytes of LRDIMMs you can fit into a 2U hyperscale server does things to your mind. Never mind the fact that it was all just a pipe dream. I would never have the cash the buy all that RAM nor the applications to fully utilize said RAM. Same goes for all the CPU cores too. Do I *REALLY* need a 44-thread CPU running a few hundred watts on idle? Nah.</p>
|
||||
|
||||
<p>What about upgrading my CPU then? Turns out my CPU is so old there are no upgrade options that can justify forking any amount of money for it. I'd rather just build a new PC with the money. But then, even a new build with Ryzen 3600 still costs a pretty penny. Also, I would have to find a space somewhere to fit another micro-ATX case with all its cables and heat ventilation concerns.</p>
|
||||
|
||||
<p>Which brings me back to the little Raspberry Pi 4. 4 cores, 4GB of RAM, 32GB of storage, and gigabit Ethernet. After giving myself a wake up call, I realized nothing fit my needs quite like this open-source oriented SBC. Yes, it isn't 'FSF certified' free, but given the reputation the Raspberry Pi Foundation has built over the years, I am more than happy to support their cause. I look forward to migrating my experiments to this new addition to the family.</p>
|
||||
<p>On a side note, I have moved the css stylesheet to a separate file to reduce the amount of HTML per page. Huzzah.</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<p><div class="navbar">
|
||||
<div><a href="blog-004">Prev</a></div>
|
||||
<div><a href="blog-006">Next</a></div>
|
||||
<div><a href="blog-005">Prev</a></div>
|
||||
<div><a href="blog-007">Next</a></div>
|
||||
</div></p>
|
||||
|
@ -1,16 +1,34 @@
|
||||
<header>
|
||||
<h1>A Hit of Kubernetes</h1>
|
||||
<h1>Optimizing Web Pages and File Sizes</h1>
|
||||
</header>
|
||||
|
||||
<p>The website is back online after almost several months. This post is just to show that I'm still alive and well. So, yeah. I tried Kubernetes for my Raspberry Pi. Specifically k3s. It didn't turn out great. Surprise surprise, containers and k8s really turns the concept of system administration on its head. What are charts? Why are kubectl and kubeadm separate commands? Why is everything hidden behind layers and layers of administration and configuration?</p>
|
||||
<p>In my last post, I mentioned moving the CSS stylesheet to a separate file so that browsers cache it when browsing the site. While the need to optimize file sizes is really unnecessary, I still do it as a learning exercise. My pages are only a few kB at most, but I plan to nickel and dime every byte I can.</p>
|
||||
|
||||
<p>It is obvious that Kubernetes is a extremely powerful and revolutionary tool. What's even more obvious is that I'm completely unprepared for this. Well, the takeaway here is that I need to read more documentation and tutorials.</p>
|
||||
<h3>Relative Link Paths</h3>
|
||||
|
||||
<p>On a side note, I have moved the css stylesheet to a separate file to reduce the amount of HTML per page. Huzzah.</p>
|
||||
<p>While this may come off as a obvious for most, I didn't know it was an option until I found it. Relative link paths encouraged me to finally organize my messy web root directory. Trimming off the full website path is probably the largest improvement I made. </p>
|
||||
|
||||
<h3>Optimizing Image Size</h3>
|
||||
|
||||
<p>In <a href="blog-005">A SBC Change</a>, I included a picture of my RPi. It was just too massive to add it to the website, so here's how I optimized it :
|
||||
<ul>
|
||||
<li>Use webp instead of PNG or JPEG because webp retains more detail with smaller file sizes.</li>
|
||||
<li>Strip all EXIF data from the image.</li>
|
||||
<li>Compressed to 85% with webp's lossy algorithm.</li>
|
||||
<li>Reduce the picture's resolution.</li>
|
||||
</ul>
|
||||
These methods reduced the file size to about 55kB: a size that I'm much more comfortable with without losing too much detail.
|
||||
</p>
|
||||
|
||||
<h3>async property when loading CSS stylesheet</h3>
|
||||
<p>The CSS stylesheet was blocking the rendering of the web page so adding the async property shaved a whopping 20ms off the time it took to render this page.</p>
|
||||
|
||||
<h3>Removing the annoying favicon 404 request</h3>
|
||||
<p>So, I don't plan on having a favicon for the site. The idea of the supporting so many sizes and formats just for a tiny icon just doesn't sit well with me. So, I redirected the icon to a "black hole". It no longer performs a HTTP request that will return a 404 error. Again, this shaves another 20ms off my loading time and tons of lines off my Apache access logs.</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<p><div class="navbar">
|
||||
<div><a href="blog-005">Prev</a></div>
|
||||
<div><a href="blog-007">Next</a></div>
|
||||
<div><a href="blog-006">Prev</a></div>
|
||||
<div><a href="blog-008">Next</a></div>
|
||||
</div></p>
|
||||
|
@ -1,34 +1,20 @@
|
||||
<header>
|
||||
<h1>Optimizing Web Pages and File Sizes</h1>
|
||||
<h1>Some Website Design and CSS</h1>
|
||||
</header>
|
||||
|
||||
<p>In my last post, I mentioned moving the CSS stylesheet to a separate file so that browsers cache it when browsing the site. While the need to optimize file sizes is really unnecessary, I still do it as a learning exercise. My pages are only a few kB at most, but I plan to nickel and dime every byte I can.</p>
|
||||
<p>I had some time to pick some - emphasis on some - CSS so that I can make this site more accessible. I was generally tackling several issues, such as a cumbersome navigation experience when browing this site.</p>
|
||||
|
||||
<h3>Relative Link Paths</h3>
|
||||
<h3>Added navigation bar at the top</h3>
|
||||
<p>For those who might have browsed here before, I previously did not have navbar. It was a nightmare to browse here because you would have to scrounge through text in paragraphs just to find my CV and links to nagivate the blog. So I went and added one. It's just a flexbox with space-between. I also went ahead and worked that class into the bottom bar which contained Prev and Next.</p>
|
||||
|
||||
<p>While this may come off as a obvious for most, I didn't know it was an option until I found it. Relative link paths encouraged me to finally organize my messy web root directory. Trimming off the full website path is probably the largest improvement I made. </p>
|
||||
<h3>Hyperlink colours and underlines</h3>
|
||||
<p>I didn't like how hyperlinks turned blue,red,etc. (Accent colours/theming of the site is still in progress) So, I added some class properties to remove the colours and only show the underline when under the cursor hover. That was all. Generally made the site browing experience more cohesive and consistent.</p>
|
||||
|
||||
<h3>Optimizing Image Size</h3>
|
||||
|
||||
<p>In <a href="blog-005">A SBC Change</a>, I included a picture of my RPi. It was just too massive to add it to the website, so here's how I optimized it :
|
||||
<ul>
|
||||
<li>Use webp instead of PNG or JPEG because webp retains more detail with smaller file sizes.</li>
|
||||
<li>Strip all EXIF data from the image.</li>
|
||||
<li>Compressed to 85% with webp's lossy algorithm.</li>
|
||||
<li>Reduce the picture's resolution.</li>
|
||||
</ul>
|
||||
These methods reduced the file size to about 55kB: a size that I'm much more comfortable with without losing too much detail.
|
||||
</p>
|
||||
|
||||
<h3>async property when loading CSS stylesheet</h3>
|
||||
<p>The CSS stylesheet was blocking the rendering of the web page so adding the async property shaved a whopping 20ms off the time it took to render this page.</p>
|
||||
|
||||
<h3>Removing the annoying favicon 404 request</h3>
|
||||
<p>So, I don't plan on having a favicon for the site. The idea of the supporting so many sizes and formats just for a tiny icon just doesn't sit well with me. So, I redirected the icon to a "black hole". It no longer performs a HTTP request that will return a 404 error. Again, this shaves another 20ms off my loading time and tons of lines off my Apache access logs.</p>
|
||||
<p>Overall, I added quite a bit of HTML/CSS and size to my pages, but I think it's worth it. IMO, the accessibility and user experience really improved. If you have any kind of input about these changes, I would certainly welcome an email about it.</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<p><div class="navbar">
|
||||
<div><a href="blog-006">Prev</a></div>
|
||||
<div><a href="blog-008">Next</a></div>
|
||||
<div><a href="blog-007">Prev</a></div>
|
||||
<div><a href="blog-000">Next</a></div>
|
||||
</div></p>
|
||||
|
@ -1,20 +0,0 @@
|
||||
<header>
|
||||
<h1>Some Website Design and CSS</h1>
|
||||
</header>
|
||||
|
||||
<p>I had some time to pick some - emphasis on some - CSS so that I can make this site more accessible. I was generally tackling several issues, such as a cumbersome navigation experience when browing this site.</p>
|
||||
|
||||
<h3>Added navigation bar at the top</h3>
|
||||
<p>For those who might have browsed here before, I previously did not have navbar. It was a nightmare to browse here because you would have to scrounge through text in paragraphs just to find my CV and links to nagivate the blog. So I went and added one. It's just a flexbox with space-between. I also went ahead and worked that class into the bottom bar which contained Prev and Next.</p>
|
||||
|
||||
<h3>Hyperlink colours and underlines</h3>
|
||||
<p>I didn't like how hyperlinks turned blue,red,etc. (Accent colours/theming of the site is still in progress) So, I added some class properties to remove the colours and only show the underline when under the cursor hover. That was all. Generally made the site browing experience more cohesive and consistent.</p>
|
||||
|
||||
<p>Overall, I added quite a bit of HTML/CSS and size to my pages, but I think it's worth it. IMO, the accessibility and user experience really improved. If you have any kind of input about these changes, I would certainly welcome an email about it.</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<p><div class="navbar">
|
||||
<div><a href="blog-007">Prev</a></div>
|
||||
<div><a href="blog-000">Next</a></div>
|
||||
</div></p>
|
5
blog/quote--01
Normal file
5
blog/quote--01
Normal file
@ -0,0 +1,5 @@
|
||||
<blockquote>
|
||||
"We don't rise to the level of our expectations, we fall to the level of our training."
|
||||
<br>
|
||||
- Archilochus
|
||||
</blockquote>
|
@ -1,5 +1,5 @@
|
||||
<blockquote>
|
||||
"We don't rise to the level of our expectations, we fall to the level of our training."
|
||||
“Fate rarely calls upon us at a moment of our choosing."
|
||||
<br>
|
||||
- Archilochus
|
||||
- Optimus Prime
|
||||
</blockquote>
|
||||
|
@ -1,5 +1,6 @@
|
||||
<blockquote>
|
||||
“Fate rarely calls upon us at a moment of our choosing."
|
||||
“Listen to the mustn'ts, child. <br>Listen to the don'ts. <br>Listen to the shouldn'ts, the impossibles, the won'ts. <br>Listen to the never haves, <br>then listen close to me... <br>Anything can happen, child. <br>Anything can be.”
|
||||
<br>
|
||||
- Optimus Prime
|
||||
- Shel Silverstein
|
||||
</blockquote>
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
<blockquote>
|
||||
“Listen to the mustn'ts, child. <br>Listen to the don'ts. <br>Listen to the shouldn'ts, the impossibles, the won'ts. <br>Listen to the never haves, <br>then listen close to me... <br>Anything can happen, child. <br>Anything can be.”
|
||||
“Nothing in this world can take the place of persistence. Talent will not; nothing is more common than unsuccessful men with talent. Genius will not; unrewarded genius is almost a proverb. Education will not; the world is full of educated derelicts. Persistence and determination alone are omnipotent. The slogan Press On! has solved and always will solve the problems of the human race.”
|
||||
<br>
|
||||
- Shel Silverstein
|
||||
- Calvin Coolidge
|
||||
</blockquote>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<blockquote>
|
||||
“Nothing in this world can take the place of persistence. Talent will not; nothing is more common than unsuccessful men with talent. Genius will not; unrewarded genius is almost a proverb. Education will not; the world is full of educated derelicts. Persistence and determination alone are omnipotent. The slogan Press On! has solved and always will solve the problems of the human race.”
|
||||
"How lucky am I to have something that makes saying goodbye so hard."
|
||||
<br>
|
||||
- Calvin Coolidge
|
||||
- Winnie the Pooh
|
||||
</blockquote>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<blockquote>
|
||||
"How lucky am I to have something that makes saying goodbye so hard."
|
||||
<br>
|
||||
- Winnie the Pooh
|
||||
“It's like in the great stories, Mr. Frodo. The ones that really mattered. Full of darkness and danger they were. And sometimes you didn't want to know the end… because how could the end be happy? How could the world go back to the way it was when so much bad had happened? But in the end, it’s only a passing thing… this shadow. Even darkness must pass.”
|
||||
<br>
|
||||
- Bilbo Baggins
|
||||
</blockquote>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<blockquote>
|
||||
“It's like in the great stories, Mr. Frodo. The ones that really mattered. Full of darkness and danger they were. And sometimes you didn't want to know the end… because how could the end be happy? How could the world go back to the way it was when so much bad had happened? But in the end, it’s only a passing thing… this shadow. Even darkness must pass.”
|
||||
“You know, I used to think it was awful that life was so unfair. Then I thought, wouldn't it be much worse if life were fair, and all the terrible things that happen to us come because we actually deserve them? So, now I take great comfort in the general hostility and unfairness of the universe.”
|
||||
<br>
|
||||
- Bilbo Baggins
|
||||
- Marcus Cole
|
||||
</blockquote>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<blockquote>
|
||||
“You know, I used to think it was awful that life was so unfair. Then I thought, wouldn't it be much worse if life were fair, and all the terrible things that happen to us come because we actually deserve them? So, now I take great comfort in the general hostility and unfairness of the universe.”
|
||||
<br>
|
||||
- Marcus Cole
|
||||
I see now that the circumstances of one's birth are irrelevant. It is what you do with the gift of life that determines who you are.
|
||||
<br>
|
||||
- Mewtwo
|
||||
</blockquote>
|
||||
|
@ -1,5 +1 @@
|
||||
<blockquote>
|
||||
I see now that the circumstances of one's birth are irrelevant. It is what you do with the gift of life that determines who you are.
|
||||
<br>
|
||||
- Mewtwo
|
||||
</blockquote>
|
||||
|
||||
|
@ -1 +0,0 @@
|
||||
|
Reference in New Issue
Block a user