<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://peergum.github.io/atom.xml" rel="self" type="application/atom+xml" /><link href="https://peergum.github.io/" rel="alternate" type="text/html" /><updated>2026-09-13T01:23:32+00:00</updated><id>https://peergum.github.io/atom.xml</id><title type="html">Phil “PeerGum” Hilger</title><subtitle>Full-Stack and Firmware Development + DevOps</subtitle><author><name>Phil Hilger</name></author><entry><title type="html">Bi-Weekly Post #6 - Back to Go</title><link href="https://peergum.github.io/open%20source/coding/devices/biweekly-post-6/" rel="alternate" type="text/html" title="Bi-Weekly Post #6 - Back to Go" /><published>2024-04-29T05:00:00+00:00</published><updated>2024-04-29T05:00:00+00:00</updated><id>https://peergum.github.io/open%20source/coding/devices/biweekly-post-6</id><content type="html" xml:base="https://peergum.github.io/open%20source/coding/devices/biweekly-post-6/"><![CDATA[<p>The way things are going, I better make these posts bi-weekly. Issue is not so much the lack of
time, but rather the strong involvement I have with the projects I dive in. Lately, I’m back to my
e-ink writing device.</p>

<p>Remember when I started my “N0vel1st” (read “novelist”, not “novel 1st”) project back in 2022, right
after I bought an (expensive) <a href="https://astrohaus.com/traveler/">FreeWrite Traveler</a> (big mistake!) and realized it was absolutely not
the device I was expecting? The Traveler was slow, had a poor UI, and felt like a device that had not been
thought through. My device would be all the Traveler was not: a nice UI, simple but efficient,
useful features, and proper communication with the cloud. Unfortunately, my freelancing activity then took all my time, and the N0vel1st was relegated to the
lowest priority, pretty much the same as writing a novel itself…</p>

<p>Since my freelancing activity decreased, I’ve spent more time back to learning and practicing my
software development skills, initiating p-xo, a friend meeting site similar to meetup, but with a
better interface. P-xo’s development started in PHP, with Vue.JS+Inertia in the front end. But then
I came to the realization that PHP may not be the best choice to continue with. Being a decent
PHP developer is nice, but I believe PHP still is for a niche market, mostly used by small to
medium companies, but with not bright future in sight. I might be wrong, but something tells me the
future of development in not in PHP. P-xo also got paused when I decided to try and focus on ML
(<a href="https://en.wikipedia.org/wiki/Machine_learning">Machine Learning</a>) because the project would need that at some point, and my knowledge of
that area was minimal.</p>

<p>So, it came to me I had several options in front of me:</p>
<ul>
  <li>Dig into Python, which is intimately connected with ML. I know some Python, but my experience is
really minimal</li>
  <li>Reinforce my knowledge of Go, which is growing as a powerful and reliable back-end language</li>
  <li>Start learning Rust, whose demand is increasing rapidly</li>
</ul>

<p>Well, you know what I chose: getting back to Go. For that purpose, I had two options: continue Peer-Z, the project I had started in 2016 (as Peer-X)
and lightly reworked in the past years, or just reboot n0vel1st, but in Go. After seeing that many
people showed some interest in ZeroWriter, a DYI open-source project with the same intent as n0vel1st, I
decided that I would make n0vel1st public and open-source, so people could both enjoy my work and
improve it or build on it.</p>

<p>First step was to port to Go some low level C code for the e-ink drivers: I had never worked with 
CGO in the past (a way to compile and integrate C code in Go), and my initial tests left me rather
unsatisfied. Using “unsafe” code in Go felt sketchy… So, I opted for a full rework of the drivers
in Go. I found a decent <a href="https://github.com/stianeikeland/go-rpio">GPIO/SPI driver on Github</a>, and used that as a foundation for the new e-ink
driver. That part went fast, and I could quickly initialize and load some bitmaps on the display.</p>

<p>Second step was to start working on a decent interface, and that included writing nice viewing
features: menus, windows, etc. I quickly built a first windowing system, and then started working
on text, porting the <a href="https://github.com/adafruit/Adafruit-GFX-Library">Adafruit GFX Library</a> from C to Go (again, not willing to use CGO).</p>

<p>Eventually, I noticed my handling of buffers was subpar, so I’m currently working on redoing that
part, with a better usage of memory and to improve interactions with the e-ink display: e-ink 
technology is nice, but refreshing a full page (1448x1072 in the case of the 6” display I use) can
take around 1s, sometimes more, so it requires handling particularly well partial refreshes of the
screen, e.g. when typing characters.</p>

<p>Hopefully I’ll have this done by the end of this week, with the occasional interruptions caused by
applying to jobs…</p>

<p>Some pictures coming soon, along with new repositories on GitHub.</p>

<p>While I’m working on that, enjoy your week and talk to you soon!</p>]]></content><author><name>Phil Hilger</name></author><category term="Open Source" /><category term="Coding" /><category term="Devices" /><category term="biweekly" /><category term="activity" /><category term="coding" /><category term="go" /><category term="hardware" /><category term="e-ink" /><category term="raspberry-pi" /><summary type="html"><![CDATA[The way things are going, I better make these posts bi-weekly. Issue is not so much the lack of time, but rather the strong involvement I have with the projects I dive in. Lately, I’m back to my e-ink writing device.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://peergum.github.io/%7B%22thumbnail%22=%3E%22/assets/images/e-ink-device.png%22,%20%22name%22=%3E%22AI%20generated%20image%20of%20an%20e-ink%20device%22%7D" /><media:content medium="image" url="https://peergum.github.io/%7B%22thumbnail%22=%3E%22/assets/images/e-ink-device.png%22,%20%22name%22=%3E%22AI%20generated%20image%20of%20an%20e-ink%20device%22%7D" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Weekly Post #5 - The Downsides of Open Source</title><link href="https://peergum.github.io/open%20source/coding/vulnerabilities/weekly-post-5/" rel="alternate" type="text/html" title="Weekly Post #5 - The Downsides of Open Source" /><published>2024-04-11T05:00:00+00:00</published><updated>2024-04-11T05:00:00+00:00</updated><id>https://peergum.github.io/open%20source/coding/vulnerabilities/weekly-post-5</id><content type="html" xml:base="https://peergum.github.io/open%20source/coding/vulnerabilities/weekly-post-5/"><![CDATA[<p>Two weeks without my regular weekly post! What am I doing?! Well, been busy on the MacOS Vue mini-project
and I didn’t see the time fly. That should tell me I should start doing planning for myself…
Anyways, today I’m going to just talk about Open Source and its potential pitfalls.</p>

<p>I’ve been using open-source code for ages, personally and professionally. I’ve been contributing to
the community too, to the best of my abilities. And yet, as great and amazing it is, there are
strong pitfalls that most people tend to ignore, including myself. The recent news about the
<a href="https://en.wikipedia.org/wiki/XZ_Utils_backdoor">xz utils backdoor</a> have been an eye opener. But let’s start from what open-source code is, and
how I and other people use it.</p>

<p>Most obvious case is bundled software. For instance, if you want to set up a web
site or blog for yourself and you’re no developer, then the easiest is to go to wordpress.com (or
any equivalent) and just create your blog. Done. You’re in business. And you’re indirectly using
open-source software (with possible added proprietary components). Yay! You assume wordpress.com
is a great business, and maybe you even pay them for additional services, because you trust them:
they wrote the code afterall…</p>

<p>If you’re a web admin, a simple web developer or web designer, then you might just go to wordpress.org
and grab the whole package, or even more likely, your hosting provider already offers the option to
install it for you. You’re now really using explicitly an open-source package. You may tune it the
way you want, adding plugins and themes, and whatever other stuff you can grab and is free, and
make it your new home online. Amazing! By the way, have you ever wondered <em>who</em> wrote all these
plugins and stuff?</p>

<p>If you’re a developer, and are assigned, or assign yourself, a project, you have usually two
ways to handle it: either you build it from scratch, or you put someone else’s code together and
add the glue to make it work. The former seems and is the long way home, and most people, myself
included, would take the latter path to happiness (and hopefully pay). So the role of a developer
often becomes one of an architect: find the best materials, and design a house that will use them,
according to the buyer’s specification. And then the architect puts their hard hat and goes hands
on… But then, again, are the materials used to the norm? who built them, who tested them, who
approved them in the first place?</p>

<p>In the three cases above, you’re in the hand of a great unknown: people. The more people worked on
an open-source project (the “building material”), the more chances it has been tested, inspected,
reviewed, and approved. The smaller the project (like the ones I write on my own) the more you’re
in the hand of a small number of developers, and sometimes even just one person. And that’s when you’re
just in great danger…</p>

<p>At the end of March this year, a German developer, Andres Freund, was wondering why his linux
system was slow when login in, and after some investigations that most people, including developers,
would likely <strong>not</strong> do, he figured that an open-source package he had installed actually had a
backdoor in it. What is a backdoor you ask? Well, just imagine letting the door to your yard open,
while you leave your house triple-locked and with the metallic blinds closed and the alarm system
on, which alarm system may well be just beside the garden door.</p>

<p>So, a widely used package had been corrupt by a developer that pretended patching fix and
adding tests over a two years’ period, while he was actually slowly planting and activating a
backdoor in the package. To our luck, the vulnerable versions of the package had not yet been
officially integrated into the linux distributions. We all can breathe again… or can we?</p>

<p>What this shows is, we tend to overtrust the open-source community.</p>

<p>Don’t take this the wrong way: I’m a fervent supporter and I believe technology has been progressing
fast thanks to people sharing for the sake of sharing, and using each other’s effort to build
things. Actually, open-source code is part of <strong>every single appliance you use today</strong>. That should
tell you the level of reliance we have on the community, community that is actually even supported
by big companies.</p>

<p>Actually, choosing proprietary technology over open-source will not decrease the risk, because
closed-source software 99.9% of the time (yes I drew that from my magic hat, but I just didn’t
to say 100%) uses open-source packages. It could actually be <strong>worse</strong>, because the companies you
buy your software or software packages from don’t have their code publicly inspected and approved,
so having a group of mis-intentioned developers in a company could lead to an easy hackable product.</p>

<p>And this goes to scary levels too: do you trust your remote-controlled lights, your TV, or even
your car? Well, the bad news is, they use open-source code too, and nobody will guarantee you the
code is 100% clean and safe. You can test 1 million hours or times any appliance, and it will work
fine, but that doesn’t mean there’s no backdoor in them. And even without thinking backdoor, just
a vulnerability nobody thought of could prevent your favorite device to fail at some point, 
intentionally or not.</p>

<p>But don’t panic. If you’re an end user, there’s pretty much <strong>nothing</strong> you can do about it. If
you’re a software developer, there is something you can do, and it’s called <strong>due diligence</strong>:</p>
<ul>
  <li>check <strong>who</strong> wrote the packages you use</li>
  <li>check their <strong>credibility</strong>
    <ul>
      <li>do they have a name?</li>
      <li>are they easy to find online or are they “invisible”?</li>
      <li>how long have they been coding?</li>
      <li>how many packages did they release?</li>
      <li>are they working with a group of other <strong>credible</strong> developers (recursive rule)</li>
    </ul>
  </li>
  <li>check <strong>what</strong> the package is entitled to do/access, and if those are strictly necessary</li>
  <li>compare packages with others offering similar functionalities</li>
  <li>check commits if you can to see code changes</li>
  <li>be doubtful of recent committers, who did <strong>not</strong> commit significant changes/fixes but
slowly acquire a “reputation” as a formal committer (in the xz hack case, the culprit had been
committing a few useless changes over two years)</li>
  <li>if you can write an equivalent in a short time, do it rather than use someone else’s work</li>
  <li>remember that the bigger the package and team responsible for it, the easier it can be
infiltrated if the team is lax and let’s everyone commit changes without reviewing them thoroughly
first</li>
</ul>

<p>Now, most of us don’t have the time for that due diligence, so… you can now start to panic: the
world is doomed.</p>

<p>Enjoy the rest of the week in the meantime, and remember to put your tin foil hat on to stay safe 🤪</p>]]></content><author><name>Phil Hilger</name></author><category term="Open Source" /><category term="Coding" /><category term="Vulnerabilities" /><category term="weekly" /><category term="activity" /><category term="opensource" /><category term="vulnerabilities" /><category term="coding" /><category term="macos-vue" /><summary type="html"><![CDATA[Two weeks without my regular weekly post! What am I doing?! Well, been busy on the MacOS Vue mini-project and I didn’t see the time fly. That should tell me I should start doing planning for myself… Anyways, today I’m going to just talk about Open Source and its potential pitfalls.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://peergum.github.io/%7B%22thumbnail%22=%3E%22/assets/images/backdoor-drawing.png%22,%20%22name%22=%3E%22AI%20generated%20backdoor%20drawing%22%7D" /><media:content medium="image" url="https://peergum.github.io/%7B%22thumbnail%22=%3E%22/assets/images/backdoor-drawing.png%22,%20%22name%22=%3E%22AI%20generated%20backdoor%20drawing%22%7D" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Weekly Post #4</title><link href="https://peergum.github.io/learning/coding/jobs/novel%20writing/weekly-post-4/" rel="alternate" type="text/html" title="Weekly Post #4" /><published>2024-03-20T17:00:00+00:00</published><updated>2024-03-20T17:00:00+00:00</updated><id>https://peergum.github.io/learning/coding/jobs/novel%20writing/weekly-post-4</id><content type="html" xml:base="https://peergum.github.io/learning/coding/jobs/novel%20writing/weekly-post-4/"><![CDATA[<p>I missed a week. That happens! Too much to do, too deeply involved in projects, or far less interesting
activities (taxes, anyone?), too many things to read online (learning new things, looking for technical answers,
or just going through the rabbit hole, one among so many others, of economy, housing, people, AI, businesses,
and when the world’s likely going to end because of us, dumb humans…), there’s ALWAYS an excuse,
good I think, for other things to stall. Well, at least it’s my own projects that stall, not professional
work (I only spend time looking for things online that are work related, don’t get me wrong)</p>

<p>Anyways, these last two weeks, I’ve been learning more about ANTLR4 - I’m 40% through with the ANTLR bible -
and I think it’s really a great improvement over the classic lex/yacc or flex/bison parsers. I initially
started learning about ANTLR for the Neutro project (inventing a gender-neutral language), but I’m not sure
at this point there will be an easy way to implement a parser for that natural language, even though it has
some logic in it that make it possibly slightly less natural 🙃) Eventually, I might as well create a new
programming language of some sort, for some purpose to determine at some point. Because why not create a
language for fun, even though it may never be used by anyone with common sense? Or will it…?</p>

<p>My search for a job has also shown me that being a Senior Software Developer is all relative. I’m skilled in
PHP, with half a decade of significant years of professional experience (not your usual “web developer” that hardly
understand programming, data structure, protocols or cloud-related stuff) and even more for personal coding on
my own projects (PHP, Laravel, Go, Vue, Node, Javascript, and blah-blah-blah), but that often doesn’t seem to
be enough. I realized several things:</p>

<ol>
  <li>I compete with job hoppers from the big five (or six), which contrary to
me have no interest in the position they apply to, but rather to the name of the companies and the corresponding
salaries, and do so only to be able to hop to a bigger one not even a year later. Some post (and comments) on
LinkedIn had me ranting for a bit, but since there’s nothing I can do about it, it’s already in the past.</li>
  <li>I compete with tons of incompetent people with inflated resumes (possibly AI-generated) which may be better
than me at marketing themselves. I’m good, skilled and efficient, but then it’s my word against someone else’s,
and I’m not a good self-salesperson (some people are born salesmen, rather than developers, I’m a born
developer but the heck of a salesperson 😄)</li>
  <li>I’m definitely NOT skilled enough in some highly-seeked for languages, like Java, Python, and React (Native).
Sure I can learn, and I learn fast, but again, companies don’t seem to care, they think they’ll get the perfect
candidate on day one, and that candidate will IMMEDIATELY produce results… Who am I to tell them it’s an utopia?</li>
  <li>I have so much to learn about so many things and practices. Will the rest of my life be enough???</li>
</ol>

<p>Last week, I was thinking about a novel I (re-)started working on while tanning at the pool in
Mexico (why not make pleasurable rhyme with useful?), last January. I’ve started a side project a few weeks ago,
with relation to that novel, and it includes building a site to accompany the novel, but a fun site, not a boring
dumb thing aimed at selling ads or the novel itself. I can’t enter into more details unfortunately, but all this
to say I came to the idea of simulating a Mac OS interface in the site, using Vue.js, and started coding that. It
actually works pretty well, despite a few things I need to fix, and not everything in the interface is functional,
but many things seem “real”. I will likely distribute the interface itself, as an open-source npm/github project,
since it may be useful to others too. Note that I said it’s a simulation/emulation, but not the actual
thing, meaning there’s no point in people trying to hack it, because there’s no Mac anywhere in sight (besides the
one I’m currently typing on…). More about this in a future weekly post, or maybe even a dedicated one.</p>

<p>Oh, I almost forgot, I also started reading Stephen King’s book “On Writing”, before the ANTLR one, and that book
led me to buy another one referenced by King, “The Elements of Style” by William Strunk Jr, which is quite old (1918)
but gives all the proper grammar I should be using for writing. Fortunately, my English is not that bad, so I already
know most of the rules and it’s mostly a brain-refresher 😅</p>

<p>Plan for this week, or at least half of what is left, is to continue with the MacOS simulation, apply to a few more
jobs, post my final tax return, and everything else I can fit in any day… oh, and tonight is pickleball. Can’t hurt
to do a bit of sport 🤪</p>]]></content><author><name>Phil Hilger</name></author><category term="Learning" /><category term="Coding" /><category term="Jobs" /><category term="Novel Writing" /><category term="weekly" /><category term="activity" /><category term="coding" /><category term="learning" /><category term="golang" /><category term="java" /><category term="ANTLR4" /><category term="languages" /><category term="MacOS" /><category term="emulation" /><category term="vue.js" /><category term="developer" /><category term="novel" /><category term="writing" /><summary type="html"><![CDATA[I missed a week. That happens! Too much to do, too deeply involved in projects, or far less interesting activities (taxes, anyone?), too many things to read online (learning new things, looking for technical answers, or just going through the rabbit hole, one among so many others, of economy, housing, people, AI, businesses, and when the world’s likely going to end because of us, dumb humans…), there’s ALWAYS an excuse, good I think, for other things to stall. Well, at least it’s my own projects that stall, not professional work (I only spend time looking for things online that are work related, don’t get me wrong)]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://peergum.github.io/%7B%22thumbnail%22=%3E%22/assets/images/books.png%22,%20%22name%22=%3E%22AI%20generated%20books%20pixel%20drawing%22%7D" /><media:content medium="image" url="https://peergum.github.io/%7B%22thumbnail%22=%3E%22/assets/images/books.png%22,%20%22name%22=%3E%22AI%20generated%20books%20pixel%20drawing%22%7D" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Weekly Post #3</title><link href="https://peergum.github.io/learning/coding/jobs/taxes/weekly-post-3/" rel="alternate" type="text/html" title="Weekly Post #3" /><published>2024-03-06T17:00:00+00:00</published><updated>2024-03-06T17:00:00+00:00</updated><id>https://peergum.github.io/learning/coding/jobs/taxes/weekly-post-3</id><content type="html" xml:base="https://peergum.github.io/learning/coding/jobs/taxes/weekly-post-3/"><![CDATA[<p>Last week has been more of the same: jobs, taxes, ANTLR v.4, but I also spent time on some interesting programming
challenge, the <strong>one billion row challenge</strong> AKA “1BRC”; I’ll get there in a bit.</p>

<p>Most of LinkedIn readings are boring: self-promotion, big companies marketing, people complaining,
people posting useless charts with blinking/moving lines and what not, people posting useless or weird AI
generated stuff, but occasionally, there’s an interesting post coming out of the lot, and it’s
usually about coding - YAY! - and about how to either do things better (patterns and stuff) or
just some coding challenge. But, since I mentioned AI generated pictures, let me first explain what the featured one in this post
is supposed to mean.</p>

<p>In the past, when I was posting blogs, I used to do a quick Google Image search about the topic I
wanted to blog about, then either capture and slightly modify one interesting picture, or just use
the link to that picture, which often ended in a missing picture after a while… Now, thanks to AI,
I just go to Bing.com. I used to hate Bing, but lately I have to say I’ve been impressed by their
progress, as long as you don’t use their search engine; unfortunately, their self-censoring is giving
either no answer or just dumb ones on many occurrences. But for AI genrated pictures, Bing is THE
site to go. I’m not sure how many AI pictures you can generate for free in a day, but as far as I’m
concerned, I seem to be able to get a few for my occasional posts so that’s perfect.</p>

<p>But perfection in the AI world is quite relative. First, unless you ask specifically for certain words,
the generated picture will likely have scrambled <s>eggs</s> words. Also, most things generated are
usually highly disturbing: a combination of impossible, fantastic, ingenious, weird, and frankly crazy.
For instance, today I asked Bing to generate the “picture of a grammar parser”. Yes, I know: what 
could a grammar parser even be? Honestly, I don’t know, but I was curious to see what AI would think
it is. And to my surprise, Bing generated four pictures of <strong>colored birds standing on books</strong>…</p>

<p>My first reaction was: “is a parser some kind of bird?!?”. So I checked Google (yeah, I didn’t trust
Bing too much on that one…), and no: no trace of any parser birds. But well, that doesn’t matter,
because everyone knows that the picture is just there to call attention (which is why you’re reading
this, to my knowledge) and what could be nicer than a colorful bird posing on books? And totally related
to my learning of ANTLR (the books, not the bird…). But let’s get back to the coding challenge first.</p>

<p>So, what is the One Billion Rows Challenge, you ask. Well, here’s the link: <a href="https://github.com/gunnarmorling/1brc">1brc</a>. Yes, that’s a
bit technical if you’re not into coding. Simply put, the challenge is about reading one billion rows from
a file in the minimal amount of time, each row representing a city and a temperature; while reading the
file, program has to calculate the minimum, maximum, and average temperature per city (cities can appear
several times with different temperatures). It is a very simple problem, but the size of the input
file is what makes things interesting. Oh, and I just realized I didn’t read about this challenge in
LinkedIn, but rather in Reddit, in <a href="https://www.reddit.com/r/golang/">r/golang</a> subreddit, and it was referring to a <a href="https://benhoyt.com/writings/go-1brc/">post</a> from
Ben Hoyt (a coder, doh!) about how he optimized his code (in Go, rather than the original Java) step-by-step to
to have it eventually run in 4s, rather than the initial 1m45s. Respect! That was actually a very educational
post, and overall it just convinced me that Go is an amazing language (although I knew it already…)</p>

<p>As a side note, one thing I always found complex in Go is the fact it treats strings as an array of
bytes, but in the same time, the base of the language, as far as characters are concerned, is runes,
which are the UTF-8 representation of characters. So any character transformation you do pretty quickly
and easily in any other language, like PHP, Java, Javascript, C/C++, Python, can become some burden in
Go. Go “interfaces” (handled in go like some kind of omnishaped variables), are the other complexity in
the language, IMHO. But these complexities are also what make the language so much more powerful than
any other language I’ve been learning. Go has a <strong>steep</strong> learning curve. But when you master it - or
at least get an understanding of the way it works - you cannot avoid being amazed. I have the strong
conviction that Go is <strong>the language of the future</strong> and will one day be the replacement for C/C++ and
Java in the back-end. And to be clear, runes and interfaces are only the tip of the iceberg. Once you’ll
start working with go routines and channels, you’ll wonder why other languages don’t have those features.</p>

<p>Anyways, back to my week. After spending some time reading and learning about this challenge, I continued
my self-training in ANTLR v.4. I have to say, ANTLR is amazing too, because it allows to separate the
grammar from the code (if you’re lost here, please check my previous weekly post about ANTLR), at least in
v.4 since v.3 didn’t have that feature. And using ANTLR is quite simple and straight-forward: I built a
mini-grammar for a pseudo language in a few hours, and it parsed correctly almost from the first attempt;
antlr was pretty clear about where there may be issues, and I could even visualize a tree representation 
of an attempt to parse a test program. So at this point, I feel pretty confident about creating a simple
grammar. I’ll likely rework a quick tool I had done in the past, some sort of a calculator that shows
values in all possible formats (including time values), and that was using flex/bison for the grammar part;
I’ll probably work on this after I read about the implementation of the code itself, which also doesn’t
seem very complicated. Plus side of ANTLR: by default it generates code in Java, but generating code in
Go is as simple. I’ll likely do a dedicated post on ANTLR at that point.</p>

<p>Other than that, the rest of my week was pretty boring, with job search and taxes. Did I mention I
hate doing accounting?</p>

<p>Talk to you again next week!</p>]]></content><author><name>Phil Hilger</name></author><category term="Learning" /><category term="Coding" /><category term="Jobs" /><category term="Taxes" /><category term="weekly" /><category term="activity" /><category term="coding" /><category term="learning" /><category term="golang" /><category term="java" /><category term="ANTLR4" /><category term="languages" /><category term="1BRC" /><summary type="html"><![CDATA[Last week has been more of the same: jobs, taxes, ANTLR v.4, but I also spent time on some interesting programming challenge, the one billion row challenge AKA “1BRC”; I’ll get there in a bit.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://peergum.github.io/%7B%22thumbnail%22=%3E%22/assets/images/grammar_parser_AI.jpg%22,%20%22name%22=%3E%22AI%20generated%20grammar%20parser...%20go%20figure!%22%7D" /><media:content medium="image" url="https://peergum.github.io/%7B%22thumbnail%22=%3E%22/assets/images/grammar_parser_AI.jpg%22,%20%22name%22=%3E%22AI%20generated%20grammar%20parser...%20go%20figure!%22%7D" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">8 Queens</title><link href="https://peergum.github.io/learning/coding/practice/8queens/" rel="alternate" type="text/html" title="8 Queens" /><published>2024-03-02T05:00:00+00:00</published><updated>2024-03-02T05:00:00+00:00</updated><id>https://peergum.github.io/learning/coding/practice/8queens</id><content type="html" xml:base="https://peergum.github.io/learning/coding/practice/8queens/"><![CDATA[<p><strong>updated on March 3</strong>: added some explanations on how the code works.</p>

<p>Last week, or was it the week before that, I read on LinkedIn about a well-known problem: the 8-queens.
You have to place 8 queens on a chess board, in positions where no queen can capture another one.</p>

<p>After a quick thinking, I determined that the simplest method was likely through a recursion, and I
started coding it in Go.</p>

<p>Some obvious considerations:</p>
<ul>
  <li>there can only be one queen per row, and one per column</li>
  <li>there can only be one queen per diagonal</li>
</ul>

<p>So the recursion works this way:</p>
<ul>
  <li>start from row 0 column 0 (considering a 0-based 8x8 array)</li>
  <li>if position is empty (value 0), mark the position with a 1 and mark all positions that can’t be used anymore with -1,</li>
  <li>if position is either 1 or 0, go back to previous row, next column, if possible</li>
  <li>then iterate to next row, column 0 (recursion)</li>
  <li>if we reached last row (7), then we’re done, show result, go back to next column of previous row</li>
  <li>iterate with next column</li>
</ul>

<p>With this method, if no position in a row works, we won’t go down the other rows, whih saves time
and effort. Also, the method must clean the table and redraw current state, each time we do another
attempt, so we need to store the current position to do the redraws (queens and unavailable positions)</p>

<p>After a few bugs and some troubleshooting (mostly related to the cleaning/redraw process) , I eventually got some code running that gave me the 92
possible positions for the queens, in 3.9 ms, without any optimization and no representation of
the results, just the count of results.</p>

<p>A very slightly modified version showed the results in a simple graphical way.</p>

<p>The code:</p>
<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">package</span> <span class="n">main</span>

<span class="k">import</span> <span class="s">"fmt"</span>

<span class="k">var</span> <span class="p">(</span>
	<span class="n">board</span>   <span class="p">[</span><span class="m">8</span><span class="p">][</span><span class="m">8</span><span class="p">]</span><span class="kt">int</span>
	<span class="n">queens</span>  <span class="p">[</span><span class="m">8</span><span class="p">]</span><span class="kt">int</span>
	<span class="n">counter</span> <span class="kt">int</span>
<span class="p">)</span>

<span class="k">func</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
	<span class="k">for</span> <span class="n">c</span> <span class="o">:=</span> <span class="k">range</span> <span class="m">8</span> <span class="p">{</span>
		<span class="n">clean</span><span class="p">(</span><span class="m">0</span><span class="p">)</span>
		<span class="n">choose</span><span class="p">(</span><span class="m">0</span><span class="p">,</span> <span class="n">c</span><span class="p">)</span>
	<span class="p">}</span>
	<span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="n">counter</span><span class="p">)</span>
<span class="p">}</span>

<span class="k">func</span> <span class="n">choose</span><span class="p">(</span><span class="n">r</span> <span class="kt">int</span><span class="p">,</span> <span class="n">c</span> <span class="kt">int</span><span class="p">)</span> <span class="p">{</span>
	<span class="k">if</span> <span class="n">board</span><span class="p">[</span><span class="n">r</span><span class="p">][</span><span class="n">c</span><span class="p">]</span> <span class="o">==</span> <span class="m">0</span> <span class="p">{</span>
		<span class="n">setQueen</span><span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="n">c</span><span class="p">)</span>
	<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
		<span class="k">return</span>
	<span class="p">}</span>
	<span class="k">if</span> <span class="n">r</span> <span class="o">&lt;</span> <span class="m">7</span> <span class="p">{</span>
		<span class="k">for</span> <span class="n">i</span> <span class="o">:=</span> <span class="k">range</span> <span class="m">8</span> <span class="p">{</span>
			<span class="n">clean</span><span class="p">(</span><span class="n">r</span> <span class="o">+</span> <span class="m">1</span><span class="p">)</span>
			<span class="n">choose</span><span class="p">(</span><span class="n">r</span><span class="o">+</span><span class="m">1</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span>
		<span class="p">}</span>
	<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
		<span class="n">counter</span><span class="o">++</span>
		<span class="c">//display()</span>
		<span class="k">return</span>
	<span class="p">}</span>
<span class="p">}</span>

<span class="k">func</span> <span class="n">clean</span><span class="p">(</span><span class="n">q</span> <span class="kt">int</span><span class="p">)</span> <span class="p">{</span>
	<span class="k">for</span> <span class="n">r</span> <span class="o">:=</span> <span class="k">range</span> <span class="m">8</span> <span class="p">{</span>
		<span class="k">for</span> <span class="n">c</span> <span class="o">:=</span> <span class="k">range</span> <span class="m">8</span> <span class="p">{</span>
			<span class="n">board</span><span class="p">[</span><span class="n">r</span><span class="p">][</span><span class="n">c</span><span class="p">]</span> <span class="o">=</span> <span class="m">0</span>
		<span class="p">}</span>
	<span class="p">}</span>
	<span class="k">for</span> <span class="n">r</span> <span class="o">:=</span> <span class="k">range</span> <span class="n">q</span> <span class="p">{</span>
		<span class="n">setQueen</span><span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="n">queens</span><span class="p">[</span><span class="n">r</span><span class="p">])</span>
	<span class="p">}</span>
<span class="p">}</span>

<span class="k">func</span> <span class="n">setQueen</span><span class="p">(</span><span class="n">r</span> <span class="kt">int</span><span class="p">,</span> <span class="n">c</span> <span class="kt">int</span><span class="p">)</span> <span class="p">{</span>
	<span class="n">board</span><span class="p">[</span><span class="n">r</span><span class="p">][</span><span class="n">c</span><span class="p">]</span> <span class="o">=</span> <span class="m">1</span>
	<span class="k">for</span> <span class="n">i</span> <span class="o">:=</span> <span class="k">range</span> <span class="m">8</span> <span class="p">{</span>
		<span class="k">if</span> <span class="n">i</span> <span class="o">!=</span> <span class="n">c</span> <span class="p">{</span>
			<span class="n">board</span><span class="p">[</span><span class="n">r</span><span class="p">][</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="o">-</span><span class="m">1</span>
		<span class="p">}</span>
		<span class="k">if</span> <span class="n">i</span> <span class="o">!=</span> <span class="n">r</span> <span class="p">{</span>
			<span class="n">board</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">c</span><span class="p">]</span> <span class="o">=</span> <span class="o">-</span><span class="m">1</span>
		<span class="p">}</span>
		<span class="k">if</span> <span class="n">r</span><span class="o">-</span><span class="n">i</span> <span class="o">&gt;=</span> <span class="m">0</span> <span class="o">&amp;&amp;</span> <span class="n">c</span><span class="o">-</span><span class="n">i</span> <span class="o">&gt;=</span> <span class="m">0</span> <span class="o">&amp;&amp;</span> <span class="n">board</span><span class="p">[</span><span class="n">r</span><span class="o">-</span><span class="n">i</span><span class="p">][</span><span class="n">c</span><span class="o">-</span><span class="n">i</span><span class="p">]</span> <span class="o">==</span> <span class="m">0</span> <span class="p">{</span>
			<span class="n">board</span><span class="p">[</span><span class="n">r</span><span class="o">-</span><span class="n">i</span><span class="p">][</span><span class="n">c</span><span class="o">-</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="o">-</span><span class="m">1</span>
		<span class="p">}</span>
		<span class="k">if</span> <span class="n">r</span><span class="o">+</span><span class="n">i</span> <span class="o">&lt;</span> <span class="m">8</span> <span class="o">&amp;&amp;</span> <span class="n">c</span><span class="o">+</span><span class="n">i</span> <span class="o">&lt;</span> <span class="m">8</span> <span class="o">&amp;&amp;</span> <span class="n">board</span><span class="p">[</span><span class="n">r</span><span class="o">+</span><span class="n">i</span><span class="p">][</span><span class="n">c</span><span class="o">+</span><span class="n">i</span><span class="p">]</span> <span class="o">==</span> <span class="m">0</span> <span class="p">{</span>
			<span class="n">board</span><span class="p">[</span><span class="n">r</span><span class="o">+</span><span class="n">i</span><span class="p">][</span><span class="n">c</span><span class="o">+</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="o">-</span><span class="m">1</span>
		<span class="p">}</span>
		<span class="k">if</span> <span class="n">r</span><span class="o">-</span><span class="n">i</span> <span class="o">&gt;=</span> <span class="m">0</span> <span class="o">&amp;&amp;</span> <span class="n">c</span><span class="o">+</span><span class="n">i</span> <span class="o">&lt;</span> <span class="m">8</span> <span class="o">&amp;&amp;</span> <span class="n">board</span><span class="p">[</span><span class="n">r</span><span class="o">-</span><span class="n">i</span><span class="p">][</span><span class="n">c</span><span class="o">+</span><span class="n">i</span><span class="p">]</span> <span class="o">==</span> <span class="m">0</span> <span class="p">{</span>
			<span class="n">board</span><span class="p">[</span><span class="n">r</span><span class="o">-</span><span class="n">i</span><span class="p">][</span><span class="n">c</span><span class="o">+</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="o">-</span><span class="m">1</span>
		<span class="p">}</span>
		<span class="k">if</span> <span class="n">r</span><span class="o">+</span><span class="n">i</span> <span class="o">&lt;</span> <span class="m">8</span> <span class="o">&amp;&amp;</span> <span class="n">c</span><span class="o">-</span><span class="n">i</span> <span class="o">&gt;=</span> <span class="m">0</span> <span class="o">&amp;&amp;</span> <span class="n">board</span><span class="p">[</span><span class="n">r</span><span class="o">+</span><span class="n">i</span><span class="p">][</span><span class="n">c</span><span class="o">-</span><span class="n">i</span><span class="p">]</span> <span class="o">==</span> <span class="m">0</span> <span class="p">{</span>
			<span class="n">board</span><span class="p">[</span><span class="n">r</span><span class="o">+</span><span class="n">i</span><span class="p">][</span><span class="n">c</span><span class="o">-</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="o">-</span><span class="m">1</span>
		<span class="p">}</span>
	<span class="p">}</span>
	<span class="n">queens</span><span class="p">[</span><span class="n">r</span><span class="p">]</span> <span class="o">=</span> <span class="n">c</span>
<span class="p">}</span>

<span class="k">func</span> <span class="n">display</span><span class="p">()</span> <span class="p">{</span>
	<span class="k">var</span> <span class="n">x</span> <span class="kt">rune</span>
	<span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"  "</span><span class="p">)</span>
	<span class="k">for</span> <span class="n">ic</span> <span class="o">:=</span> <span class="k">range</span> <span class="m">8</span> <span class="p">{</span>
		<span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"%d "</span><span class="p">,</span> <span class="n">ic</span><span class="o">+</span><span class="m">1</span><span class="p">)</span>
	<span class="p">}</span>
	<span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">()</span>
	<span class="k">for</span> <span class="n">ir</span><span class="p">,</span> <span class="n">r</span> <span class="o">:=</span> <span class="k">range</span> <span class="n">board</span> <span class="p">{</span>
		<span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"%d "</span><span class="p">,</span> <span class="n">ir</span><span class="o">+</span><span class="m">1</span><span class="p">)</span>
		<span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">c</span> <span class="o">:=</span> <span class="k">range</span> <span class="n">r</span> <span class="p">{</span>
			<span class="k">if</span> <span class="n">c</span> <span class="o">==</span> <span class="m">1</span> <span class="p">{</span>
				<span class="n">x</span> <span class="o">=</span> <span class="sc">'o'</span>
			<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="n">c</span> <span class="o">==</span> <span class="m">0</span> <span class="p">{</span>
				<span class="n">x</span> <span class="o">=</span> <span class="sc">' '</span>
			<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
				<span class="n">x</span> <span class="o">=</span> <span class="sc">'·'</span>
			<span class="p">}</span>
			<span class="n">fmt</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"%c "</span><span class="p">,</span> <span class="n">x</span><span class="p">)</span>
		<span class="p">}</span>
		<span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">()</span>
	<span class="p">}</span>
	<span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">()</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The result:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>% go build
% ./main
92
% hyperfine ./main
Benchmark 1: ./main
  Time (mean ± σ):       3.9 ms ±   0.4 ms    [User: 3.4 ms, System: 0.4 ms]
  Range (min … max):     3.5 ms …   8.9 ms    262 runs
 
  Warning: Command took less than 5 ms to complete. Note that the results might be inaccurate because hyperfine can not calibrate the shell startup time much more precise than this limit. You can try to use the `-N`/`--shell=none` option to disable the shell completely.
  Warning: The first benchmarking run for this command was significantly slower than the rest (8.9 ms). This could be caused by (filesystem) caches that were not filled until after the first run. You should consider using the '--warmup' option to fill those caches before the actual benchmark. Alternatively, use the '--prepare' option to clear the caches before each timing run.
</code></pre></div></div>

<p>Uncommenting the <code class="language-plaintext highlighter-rouge">//display()</code> section, we can see the 92 results:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>% ./main
  1 2 3 4 5 6 7 8 
1 o · · · · · · · 
2 · · · · o · · · 
3 · · · · · · · o 
4 · · · · · o · · 
5 · · o · · · · · 
6 · · · · · · o · 
7 · o · · · · · · 
8 · · · o · · · · 

  1 2 3 4 5 6 7 8 
1 o · · · · · · · 
2 · · · · · o · · 
3 · · · · · · · o 
4 · · o · · · · · 
5 · · · · · · o · 
6 · · · o · · · · 
7 · o · · · · · · 
8 · · · · o · · · 

  1 2 3 4 5 6 7 8 
1 o · · · · · · · 
2 · · · · · · o · 
3 · · · o · · · · 
4 · · · · · o · · 
5 · · · · · · · o 
6 · o · · · · · · 
7 · · · · o · · · 
8 · · o · · · · · 

  1 2 3 4 5 6 7 8 
1 o · · · · · · · 
2 · · · · · · o · 
3 · · · · o · · · 
4 · · · · · · · o 
5 · o · · · · · · 
6 · · · o · · · · 
7 · · · · · o · · 
8 · · o · · · · · 

  1 2 3 4 5 6 7 8 
1 · o · · · · · · 
2 · · · o · · · · 
3 · · · · · o · · 
4 · · · · · · · o 
5 · · o · · · · · 
6 o · · · · · · · 
7 · · · · · · o · 
8 · · · · o · · · 

  1 2 3 4 5 6 7 8 
1 · o · · · · · · 
2 · · · · o · · · 
3 · · · · · · o · 
4 o · · · · · · · 
5 · · o · · · · · 
6 · · · · · · · o 
7 · · · · · o · · 
8 · · · o · · · · 

  1 2 3 4 5 6 7 8 
1 · o · · · · · · 
2 · · · · o · · · 
3 · · · · · · o · 
4 · · · o · · · · 
5 o · · · · · · · 
6 · · · · · · · o 
7 · · · · · o · · 
8 · · o · · · · · 

  1 2 3 4 5 6 7 8 
1 · o · · · · · · 
2 · · · · · o · · 
3 o · · · · · · · 
4 · · · · · · o · 
5 · · · o · · · · 
6 · · · · · · · o 
7 · · o · · · · · 
8 · · · · o · · · 

  1 2 3 4 5 6 7 8 
1 · o · · · · · · 
2 · · · · · o · · 
3 · · · · · · · o 
4 · · o · · · · · 
5 o · · · · · · · 
6 · · · o · · · · 
7 · · · · · · o · 
8 · · · · o · · · 

  1 2 3 4 5 6 7 8 
1 · o · · · · · · 
2 · · · · · · o · 
3 · · o · · · · · 
4 · · · · · o · · 
5 · · · · · · · o 
6 · · · · o · · · 
7 o · · · · · · · 
8 · · · o · · · · 

  1 2 3 4 5 6 7 8 
1 · o · · · · · · 
2 · · · · · · o · 
3 · · · · o · · · 
4 · · · · · · · o 
5 o · · · · · · · 
6 · · · o · · · · 
7 · · · · · o · · 
8 · · o · · · · · 

  1 2 3 4 5 6 7 8 
1 · o · · · · · · 
2 · · · · · · · o 
3 · · · · · o · · 
4 o · · · · · · · 
5 · · o · · · · · 
6 · · · · o · · · 
7 · · · · · · o · 
8 · · · o · · · · 

  1 2 3 4 5 6 7 8 
1 · · o · · · · · 
2 o · · · · · · · 
3 · · · · · · o · 
4 · · · · o · · · 
5 · · · · · · · o 
6 · o · · · · · · 
7 · · · o · · · · 
8 · · · · · o · · 

  1 2 3 4 5 6 7 8 
1 · · o · · · · · 
2 · · · · o · · · 
3 · o · · · · · · 
4 · · · · · · · o 
5 o · · · · · · · 
6 · · · · · · o · 
7 · · · o · · · · 
8 · · · · · o · · 

  1 2 3 4 5 6 7 8 
1 · · o · · · · · 
2 · · · · o · · · 
3 · o · · · · · · 
4 · · · · · · · o 
5 · · · · · o · · 
6 · · · o · · · · 
7 · · · · · · o · 
8 o · · · · · · · 

  1 2 3 4 5 6 7 8 
1 · · o · · · · · 
2 · · · · o · · · 
3 · · · · · · o · 
4 o · · · · · · · 
5 · · · o · · · · 
6 · o · · · · · · 
7 · · · · · · · o 
8 · · · · · o · · 

  1 2 3 4 5 6 7 8 
1 · · o · · · · · 
2 · · · · o · · · 
3 · · · · · · · o 
4 · · · o · · · · 
5 o · · · · · · · 
6 · · · · · · o · 
7 · o · · · · · · 
8 · · · · · o · · 

  1 2 3 4 5 6 7 8 
1 · · o · · · · · 
2 · · · · · o · · 
3 · o · · · · · · 
4 · · · · o · · · 
5 · · · · · · · o 
6 o · · · · · · · 
7 · · · · · · o · 
8 · · · o · · · · 

  1 2 3 4 5 6 7 8 
1 · · o · · · · · 
2 · · · · · o · · 
3 · o · · · · · · 
4 · · · · · · o · 
5 o · · · · · · · 
6 · · · o · · · · 
7 · · · · · · · o 
8 · · · · o · · · 

  1 2 3 4 5 6 7 8 
1 · · o · · · · · 
2 · · · · · o · · 
3 · o · · · · · · 
4 · · · · · · o · 
5 · · · · o · · · 
6 o · · · · · · · 
7 · · · · · · · o 
8 · · · o · · · · 

  1 2 3 4 5 6 7 8 
1 · · o · · · · · 
2 · · · · · o · · 
3 · · · o · · · · 
4 o · · · · · · · 
5 · · · · · · · o 
6 · · · · o · · · 
7 · · · · · · o · 
8 · o · · · · · · 

  1 2 3 4 5 6 7 8 
1 · · o · · · · · 
2 · · · · · o · · 
3 · · · o · · · · 
4 · o · · · · · · 
5 · · · · · · · o 
6 · · · · o · · · 
7 · · · · · · o · 
8 o · · · · · · · 

  1 2 3 4 5 6 7 8 
1 · · o · · · · · 
2 · · · · · o · · 
3 · · · · · · · o 
4 o · · · · · · · 
5 · · · o · · · · 
6 · · · · · · o · 
7 · · · · o · · · 
8 · o · · · · · · 

  1 2 3 4 5 6 7 8 
1 · · o · · · · · 
2 · · · · · o · · 
3 · · · · · · · o 
4 o · · · · · · · 
5 · · · · o · · · 
6 · · · · · · o · 
7 · o · · · · · · 
8 · · · o · · · · 

  1 2 3 4 5 6 7 8 
1 · · o · · · · · 
2 · · · · · o · · 
3 · · · · · · · o 
4 · o · · · · · · 
5 · · · o · · · · 
6 o · · · · · · · 
7 · · · · · · o · 
8 · · · · o · · · 

  1 2 3 4 5 6 7 8 
1 · · o · · · · · 
2 · · · · · · o · 
3 · o · · · · · · 
4 · · · · · · · o 
5 · · · · o · · · 
6 o · · · · · · · 
7 · · · o · · · · 
8 · · · · · o · · 

  1 2 3 4 5 6 7 8 
1 · · o · · · · · 
2 · · · · · · o · 
3 · o · · · · · · 
4 · · · · · · · o 
5 · · · · · o · · 
6 · · · o · · · · 
7 o · · · · · · · 
8 · · · · o · · · 

  1 2 3 4 5 6 7 8 
1 · · o · · · · · 
2 · · · · · · · o 
3 · · · o · · · · 
4 · · · · · · o · 
5 o · · · · · · · 
6 · · · · · o · · 
7 · o · · · · · · 
8 · · · · o · · · 

  1 2 3 4 5 6 7 8 
1 · · · o · · · · 
2 o · · · · · · · 
3 · · · · o · · · 
4 · · · · · · · o 
5 · o · · · · · · 
6 · · · · · · o · 
7 · · o · · · · · 
8 · · · · · o · · 

  1 2 3 4 5 6 7 8 
1 · · · o · · · · 
2 o · · · · · · · 
3 · · · · o · · · 
4 · · · · · · · o 
5 · · · · · o · · 
6 · · o · · · · · 
7 · · · · · · o · 
8 · o · · · · · · 

  1 2 3 4 5 6 7 8 
1 · · · o · · · · 
2 · o · · · · · · 
3 · · · · o · · · 
4 · · · · · · · o 
5 · · · · · o · · 
6 o · · · · · · · 
7 · · o · · · · · 
8 · · · · · · o · 

  1 2 3 4 5 6 7 8 
1 · · · o · · · · 
2 · o · · · · · · 
3 · · · · · · o · 
4 · · o · · · · · 
5 · · · · · o · · 
6 · · · · · · · o 
7 o · · · · · · · 
8 · · · · o · · · 

  1 2 3 4 5 6 7 8 
1 · · · o · · · · 
2 · o · · · · · · 
3 · · · · · · o · 
4 · · o · · · · · 
5 · · · · · o · · 
6 · · · · · · · o 
7 · · · · o · · · 
8 o · · · · · · · 

  1 2 3 4 5 6 7 8 
1 · · · o · · · · 
2 · o · · · · · · 
3 · · · · · · o · 
4 · · · · o · · · 
5 o · · · · · · · 
6 · · · · · · · o 
7 · · · · · o · · 
8 · · o · · · · · 

  1 2 3 4 5 6 7 8 
1 · · · o · · · · 
2 · o · · · · · · 
3 · · · · · · · o 
4 · · · · o · · · 
5 · · · · · · o · 
6 o · · · · · · · 
7 · · o · · · · · 
8 · · · · · o · · 

  1 2 3 4 5 6 7 8 
1 · · · o · · · · 
2 · o · · · · · · 
3 · · · · · · · o 
4 · · · · · o · · 
5 o · · · · · · · 
6 · · o · · · · · 
7 · · · · o · · · 
8 · · · · · · o · 

  1 2 3 4 5 6 7 8 
1 · · · o · · · · 
2 · · · · · o · · 
3 o · · · · · · · 
4 · · · · o · · · 
5 · o · · · · · · 
6 · · · · · · · o 
7 · · o · · · · · 
8 · · · · · · o · 

  1 2 3 4 5 6 7 8 
1 · · · o · · · · 
2 · · · · · o · · 
3 · · · · · · · o 
4 · o · · · · · · 
5 · · · · · · o · 
6 o · · · · · · · 
7 · · o · · · · · 
8 · · · · o · · · 

  1 2 3 4 5 6 7 8 
1 · · · o · · · · 
2 · · · · · o · · 
3 · · · · · · · o 
4 · · o · · · · · 
5 o · · · · · · · 
6 · · · · · · o · 
7 · · · · o · · · 
8 · o · · · · · · 

  1 2 3 4 5 6 7 8 
1 · · · o · · · · 
2 · · · · · · o · 
3 o · · · · · · · 
4 · · · · · · · o 
5 · · · · o · · · 
6 · o · · · · · · 
7 · · · · · o · · 
8 · · o · · · · · 

  1 2 3 4 5 6 7 8 
1 · · · o · · · · 
2 · · · · · · o · 
3 · · o · · · · · 
4 · · · · · · · o 
5 · o · · · · · · 
6 · · · · o · · · 
7 o · · · · · · · 
8 · · · · · o · · 

  1 2 3 4 5 6 7 8 
1 · · · o · · · · 
2 · · · · · · o · 
3 · · · · o · · · 
4 · o · · · · · · 
5 · · · · · o · · 
6 o · · · · · · · 
7 · · o · · · · · 
8 · · · · · · · o 

  1 2 3 4 5 6 7 8 
1 · · · o · · · · 
2 · · · · · · o · 
3 · · · · o · · · 
4 · · o · · · · · 
5 o · · · · · · · 
6 · · · · · o · · 
7 · · · · · · · o 
8 · o · · · · · · 

  1 2 3 4 5 6 7 8 
1 · · · o · · · · 
2 · · · · · · · o 
3 o · · · · · · · 
4 · · o · · · · · 
5 · · · · · o · · 
6 · o · · · · · · 
7 · · · · · · o · 
8 · · · · o · · · 

  1 2 3 4 5 6 7 8 
1 · · · o · · · · 
2 · · · · · · · o 
3 o · · · · · · · 
4 · · · · o · · · 
5 · · · · · · o · 
6 · o · · · · · · 
7 · · · · · o · · 
8 · · o · · · · · 

  1 2 3 4 5 6 7 8 
1 · · · o · · · · 
2 · · · · · · · o 
3 · · · · o · · · 
4 · · o · · · · · 
5 o · · · · · · · 
6 · · · · · · o · 
7 · o · · · · · · 
8 · · · · · o · · 

  1 2 3 4 5 6 7 8 
1 · · · · o · · · 
2 o · · · · · · · 
3 · · · o · · · · 
4 · · · · · o · · 
5 · · · · · · · o 
6 · o · · · · · · 
7 · · · · · · o · 
8 · · o · · · · · 

  1 2 3 4 5 6 7 8 
1 · · · · o · · · 
2 o · · · · · · · 
3 · · · · · · · o 
4 · · · o · · · · 
5 · o · · · · · · 
6 · · · · · · o · 
7 · · o · · · · · 
8 · · · · · o · · 

  1 2 3 4 5 6 7 8 
1 · · · · o · · · 
2 o · · · · · · · 
3 · · · · · · · o 
4 · · · · · o · · 
5 · · o · · · · · 
6 · · · · · · o · 
7 · o · · · · · · 
8 · · · o · · · · 

  1 2 3 4 5 6 7 8 
1 · · · · o · · · 
2 · o · · · · · · 
3 · · · o · · · · 
4 · · · · · o · · 
5 · · · · · · · o 
6 · · o · · · · · 
7 o · · · · · · · 
8 · · · · · · o · 

  1 2 3 4 5 6 7 8 
1 · · · · o · · · 
2 · o · · · · · · 
3 · · · o · · · · 
4 · · · · · · o · 
5 · · o · · · · · 
6 · · · · · · · o 
7 · · · · · o · · 
8 o · · · · · · · 

  1 2 3 4 5 6 7 8 
1 · · · · o · · · 
2 · o · · · · · · 
3 · · · · · o · · 
4 o · · · · · · · 
5 · · · · · · o · 
6 · · · o · · · · 
7 · · · · · · · o 
8 · · o · · · · · 

  1 2 3 4 5 6 7 8 
1 · · · · o · · · 
2 · o · · · · · · 
3 · · · · · · · o 
4 o · · · · · · · 
5 · · · o · · · · 
6 · · · · · · o · 
7 · · o · · · · · 
8 · · · · · o · · 

  1 2 3 4 5 6 7 8 
1 · · · · o · · · 
2 · · o · · · · · 
3 o · · · · · · · 
4 · · · · · o · · 
5 · · · · · · · o 
6 · o · · · · · · 
7 · · · o · · · · 
8 · · · · · · o · 

  1 2 3 4 5 6 7 8 
1 · · · · o · · · 
2 · · o · · · · · 
3 o · · · · · · · 
4 · · · · · · o · 
5 · o · · · · · · 
6 · · · · · · · o 
7 · · · · · o · · 
8 · · · o · · · · 

  1 2 3 4 5 6 7 8 
1 · · · · o · · · 
2 · · o · · · · · 
3 · · · · · · · o 
4 · · · o · · · · 
5 · · · · · · o · 
6 o · · · · · · · 
7 · · · · · o · · 
8 · o · · · · · · 

  1 2 3 4 5 6 7 8 
1 · · · · o · · · 
2 · · · · · · o · 
3 o · · · · · · · 
4 · · o · · · · · 
5 · · · · · · · o 
6 · · · · · o · · 
7 · · · o · · · · 
8 · o · · · · · · 

  1 2 3 4 5 6 7 8 
1 · · · · o · · · 
2 · · · · · · o · 
3 o · · · · · · · 
4 · · · o · · · · 
5 · o · · · · · · 
6 · · · · · · · o 
7 · · · · · o · · 
8 · · o · · · · · 

  1 2 3 4 5 6 7 8 
1 · · · · o · · · 
2 · · · · · · o · 
3 · o · · · · · · 
4 · · · o · · · · 
5 · · · · · · · o 
6 o · · · · · · · 
7 · · o · · · · · 
8 · · · · · o · · 

  1 2 3 4 5 6 7 8 
1 · · · · o · · · 
2 · · · · · · o · 
3 · o · · · · · · 
4 · · · · · o · · 
5 · · o · · · · · 
6 o · · · · · · · 
7 · · · o · · · · 
8 · · · · · · · o 

  1 2 3 4 5 6 7 8 
1 · · · · o · · · 
2 · · · · · · o · 
3 · o · · · · · · 
4 · · · · · o · · 
5 · · o · · · · · 
6 o · · · · · · · 
7 · · · · · · · o 
8 · · · o · · · · 

  1 2 3 4 5 6 7 8 
1 · · · · o · · · 
2 · · · · · · o · 
3 · · · o · · · · 
4 o · · · · · · · 
5 · · o · · · · · 
6 · · · · · · · o 
7 · · · · · o · · 
8 · o · · · · · · 

  1 2 3 4 5 6 7 8 
1 · · · · o · · · 
2 · · · · · · · o 
3 · · · o · · · · 
4 o · · · · · · · 
5 · · o · · · · · 
6 · · · · · o · · 
7 · o · · · · · · 
8 · · · · · · o · 

  1 2 3 4 5 6 7 8 
1 · · · · o · · · 
2 · · · · · · · o 
3 · · · o · · · · 
4 o · · · · · · · 
5 · · · · · · o · 
6 · o · · · · · · 
7 · · · · · o · · 
8 · · o · · · · · 

  1 2 3 4 5 6 7 8 
1 · · · · · o · · 
2 o · · · · · · · 
3 · · · · o · · · 
4 · o · · · · · · 
5 · · · · · · · o 
6 · · o · · · · · 
7 · · · · · · o · 
8 · · · o · · · · 

  1 2 3 4 5 6 7 8 
1 · · · · · o · · 
2 · o · · · · · · 
3 · · · · · · o · 
4 o · · · · · · · 
5 · · o · · · · · 
6 · · · · o · · · 
7 · · · · · · · o 
8 · · · o · · · · 

  1 2 3 4 5 6 7 8 
1 · · · · · o · · 
2 · o · · · · · · 
3 · · · · · · o · 
4 o · · · · · · · 
5 · · · o · · · · 
6 · · · · · · · o 
7 · · · · o · · · 
8 · · o · · · · · 

  1 2 3 4 5 6 7 8 
1 · · · · · o · · 
2 · · o · · · · · 
3 o · · · · · · · 
4 · · · · · · o · 
5 · · · · o · · · 
6 · · · · · · · o 
7 · o · · · · · · 
8 · · · o · · · · 

  1 2 3 4 5 6 7 8 
1 · · · · · o · · 
2 · · o · · · · · 
3 o · · · · · · · 
4 · · · · · · · o 
5 · · · o · · · · 
6 · o · · · · · · 
7 · · · · · · o · 
8 · · · · o · · · 

  1 2 3 4 5 6 7 8 
1 · · · · · o · · 
2 · · o · · · · · 
3 o · · · · · · · 
4 · · · · · · · o 
5 · · · · o · · · 
6 · o · · · · · · 
7 · · · o · · · · 
8 · · · · · · o · 

  1 2 3 4 5 6 7 8 
1 · · · · · o · · 
2 · · o · · · · · 
3 · · · · o · · · 
4 · · · · · · o · 
5 o · · · · · · · 
6 · · · o · · · · 
7 · o · · · · · · 
8 · · · · · · · o 

  1 2 3 4 5 6 7 8 
1 · · · · · o · · 
2 · · o · · · · · 
3 · · · · o · · · 
4 · · · · · · · o 
5 o · · · · · · · 
6 · · · o · · · · 
7 · o · · · · · · 
8 · · · · · · o · 

  1 2 3 4 5 6 7 8 
1 · · · · · o · · 
2 · · o · · · · · 
3 · · · · · · o · 
4 · o · · · · · · 
5 · · · o · · · · 
6 · · · · · · · o 
7 o · · · · · · · 
8 · · · · o · · · 

  1 2 3 4 5 6 7 8 
1 · · · · · o · · 
2 · · o · · · · · 
3 · · · · · · o · 
4 · o · · · · · · 
5 · · · · · · · o 
6 · · · · o · · · 
7 o · · · · · · · 
8 · · · o · · · · 

  1 2 3 4 5 6 7 8 
1 · · · · · o · · 
2 · · o · · · · · 
3 · · · · · · o · 
4 · · · o · · · · 
5 o · · · · · · · 
6 · · · · · · · o 
7 · o · · · · · · 
8 · · · · o · · · 

  1 2 3 4 5 6 7 8 
1 · · · · · o · · 
2 · · · o · · · · 
3 o · · · · · · · 
4 · · · · o · · · 
5 · · · · · · · o 
6 · o · · · · · · 
7 · · · · · · o · 
8 · · o · · · · · 

  1 2 3 4 5 6 7 8 
1 · · · · · o · · 
2 · · · o · · · · 
3 · o · · · · · · 
4 · · · · · · · o 
5 · · · · o · · · 
6 · · · · · · o · 
7 o · · · · · · · 
8 · · o · · · · · 

  1 2 3 4 5 6 7 8 
1 · · · · · o · · 
2 · · · o · · · · 
3 · · · · · · o · 
4 o · · · · · · · 
5 · · o · · · · · 
6 · · · · o · · · 
7 · o · · · · · · 
8 · · · · · · · o 

  1 2 3 4 5 6 7 8 
1 · · · · · o · · 
2 · · · o · · · · 
3 · · · · · · o · 
4 o · · · · · · · 
5 · · · · · · · o 
6 · o · · · · · · 
7 · · · · o · · · 
8 · · o · · · · · 

  1 2 3 4 5 6 7 8 
1 · · · · · o · · 
2 · · · · · · · o 
3 · o · · · · · · 
4 · · · o · · · · 
5 o · · · · · · · 
6 · · · · · · o · 
7 · · · · o · · · 
8 · · o · · · · · 

  1 2 3 4 5 6 7 8 
1 · · · · · · o · 
2 o · · · · · · · 
3 · · o · · · · · 
4 · · · · · · · o 
5 · · · · · o · · 
6 · · · o · · · · 
7 · o · · · · · · 
8 · · · · o · · · 

  1 2 3 4 5 6 7 8 
1 · · · · · · o · 
2 · o · · · · · · 
3 · · · o · · · · 
4 o · · · · · · · 
5 · · · · · · · o 
6 · · · · o · · · 
7 · · o · · · · · 
8 · · · · · o · · 

  1 2 3 4 5 6 7 8 
1 · · · · · · o · 
2 · o · · · · · · 
3 · · · · · o · · 
4 · · o · · · · · 
5 o · · · · · · · 
6 · · · o · · · · 
7 · · · · · · · o 
8 · · · · o · · · 

  1 2 3 4 5 6 7 8 
1 · · · · · · o · 
2 · · o · · · · · 
3 o · · · · · · · 
4 · · · · · o · · 
5 · · · · · · · o 
6 · · · · o · · · 
7 · o · · · · · · 
8 · · · o · · · · 

  1 2 3 4 5 6 7 8 
1 · · · · · · o · 
2 · · o · · · · · 
3 · · · · · · · o 
4 · o · · · · · · 
5 · · · · o · · · 
6 o · · · · · · · 
7 · · · · · o · · 
8 · · · o · · · · 

  1 2 3 4 5 6 7 8 
1 · · · · · · o · 
2 · · · o · · · · 
3 · o · · · · · · 
4 · · · · o · · · 
5 · · · · · · · o 
6 o · · · · · · · 
7 · · o · · · · · 
8 · · · · · o · · 

  1 2 3 4 5 6 7 8 
1 · · · · · · o · 
2 · · · o · · · · 
3 · o · · · · · · 
4 · · · · · · · o 
5 · · · · · o · · 
6 o · · · · · · · 
7 · · o · · · · · 
8 · · · · o · · · 

  1 2 3 4 5 6 7 8 
1 · · · · · · o · 
2 · · · · o · · · 
3 · · o · · · · · 
4 o · · · · · · · 
5 · · · · · o · · 
6 · · · · · · · o 
7 · o · · · · · · 
8 · · · o · · · · 

  1 2 3 4 5 6 7 8 
1 · · · · · · · o 
2 · o · · · · · · 
3 · · · o · · · · 
4 o · · · · · · · 
5 · · · · · · o · 
6 · · · · o · · · 
7 · · o · · · · · 
8 · · · · · o · · 

  1 2 3 4 5 6 7 8 
1 · · · · · · · o 
2 · o · · · · · · 
3 · · · · o · · · 
4 · · o · · · · · 
5 o · · · · · · · 
6 · · · · · · o · 
7 · · · o · · · · 
8 · · · · · o · · 

  1 2 3 4 5 6 7 8 
1 · · · · · · · o 
2 · · o · · · · · 
3 o · · · · · · · 
4 · · · · · o · · 
5 · o · · · · · · 
6 · · · · o · · · 
7 · · · · · · o · 
8 · · · o · · · · 

  1 2 3 4 5 6 7 8 
1 · · · · · · · o 
2 · · · o · · · · 
3 o · · · · · · · 
4 · · o · · · · · 
5 · · · · · o · · 
6 · o · · · · · · 
7 · · · · · · o · 
8 · · · · o · · · 

92
% hyperfine ./main
Benchmark 1: ./main
  Time (mean ± σ):       7.3 ms ±   0.4 ms    [User: 4.8 ms, System: 2.5 ms]
  Range (min … max):     7.0 ms …  12.3 ms    202 runs
 
  Warning: The first benchmarking run for this command was significantly slower than the rest (12.3 ms). This could be caused by (filesystem) caches that were not filled until after the first run. You should consider using the '--warmup' option to fill those caches before the actual benchmark. Alternatively, use the '--prepare' option to clear the caches before each timing run.
</code></pre></div></div>

<p>Some optimization of this code are possible, since many solutions are symmetries, horizontal or vertical, or rotations of others.
Also the cleaning/redrawing process could be optimized a way we don’t always redraw the whole thing,
but rather just remove the last added queen/unavailable positions.</p>

<p>I’ll leave these optimizations for later or someone else. Many other projects to tackle first…</p>]]></content><author><name>Phil Hilger</name></author><category term="Learning" /><category term="Coding" /><category term="Practice" /><category term="activity" /><category term="coding" /><category term="learning" /><category term="golang" /><category term="practice" /><category term="8_queens" /><summary type="html"><![CDATA[updated on March 3: added some explanations on how the code works.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://peergum.github.io/%7B%22thumbnail%22=%3E%22/assets/images/chess.jpg%22,%20%22name%22=%3E%22AI%20generated%20chess%20picture%22%7D" /><media:content medium="image" url="https://peergum.github.io/%7B%22thumbnail%22=%3E%22/assets/images/chess.jpg%22,%20%22name%22=%3E%22AI%20generated%20chess%20picture%22%7D" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Weekly Post #2</title><link href="https://peergum.github.io/learning/coding/jobs/weekly-post-2/" rel="alternate" type="text/html" title="Weekly Post #2" /><published>2024-02-26T17:00:00+00:00</published><updated>2024-02-26T17:00:00+00:00</updated><id>https://peergum.github.io/learning/coding/jobs/weekly-post-2</id><content type="html" xml:base="https://peergum.github.io/learning/coding/jobs/weekly-post-2/"><![CDATA[<p>Last week started as a “going to do some Go” week, but quickly, some posts and articles
about recent language issues (in French originally) with gender-neutrality adaptation
(and often consecutive dismissal or refusal) sent me through the rabbit hole of linguistics,
translations and language creation.</p>

<p>And here I was, deciding to start a new project (again!), this time about the creation of a
gender-neutral language called Neutro. I started pondering what the language would like and
quickly built a new page where I’d detail the steps of this creation.</p>

<p>At some point, confronted with grammar and vocabulary choices, I realized it would likely be
convenient to build translators to and from English for Neutro, like some kind of <a href="https://en.wikipedia.org/wiki/Test-driven_development">TDD</a>
(Test-Driven Development), and I started digging back into lex/flex-yacc/bison and how to do
that in Go (because, why do that in C if I can practice Go instead…).</p>

<p>If you’re not familiar with lexers and parsers, <a href="https://en.wikipedia.org/wiki/Lex_(software)">Lex</a> and Yacc<a href="https://en.wikipedia.org/wiki/Yacc">yacc</a> are the ancestors of semantical and
analytical parsing, created far back in the 70s, and later adapted under GNU to <a href="https://en.wikipedia.org/wiki/Flex_(lexical_analyser_generator)">Flex</a> and <a href="https://en.wikipedia.org/wiki/GNU_Bison">Bison</a>.
Mostly these tools take some parsing rules as input, respectively at character and grammar level, and transform
them into C code. I used them in the past to parse documents (in 1998, specifically, to automatically
create work requests from <a href="https://www.sita.aero/solutions/sita-at-airports/sita-communications-and-data-exchange/sitatex-services/">SITATEX</a> messages, while working at <a href="https://en.wikipedia.org/wiki/SITA_(business_services_company)">SITA/Equant</a>).</p>

<p>After a bit of experimentation, and the realization that these lexers and parsers would largely be
inconvenient to generate Go code, I turned to reddit <a href="https://www.reddit.com/r/golang/">r/golang</a>, where I eventually discovered
<a href="https://www.antlr.org">ANTLR4</a>.</p>

<p>ANTLR4 is something similar to lex/yacc, and has been developed during the last 25 years, and
can generate code in most popular languages, including Go. Version 4 even offers the strong benefit
of allowing developers to separate the grammar from the code, which lex and yacc didn’t allow. So,
I ended buying the Bible of ANTLR, <a href="https://amzn.to/3uXaMQ1">The Definitive ANTLR 4 Reference</a>, and started
reading it.</p>

<p>This week will likely be dedicated to experimenting with ANTLR4, continue looking for jobs, and…
taking care of tax chore, AKA “the main downside of being a freelancer”.</p>

<p>Talk to you next week, and in the meantime, enjoy your taxes too ;)</p>]]></content><author><name>Phil Hilger</name></author><category term="Learning" /><category term="Coding" /><category term="Jobs" /><category term="weekly" /><category term="activity" /><category term="coding" /><category term="learning" /><category term="golang" /><category term="java" /><category term="lex/yacc" /><category term="flex/bison" /><category term="ANTLR4" /><category term="neutro" /><category term="languages" /><summary type="html"><![CDATA[Last week started as a “going to do some Go” week, but quickly, some posts and articles about recent language issues (in French originally) with gender-neutrality adaptation (and often consecutive dismissal or refusal) sent me through the rabbit hole of linguistics, translations and language creation.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://peergum.github.io/%7B%22thumbnail%22=%3E%22/assets/images/wordobulator.png%22,%20%22name%22=%3E%22AI%20generated%20wordobulator%20machine%22%7D" /><media:content medium="image" url="https://peergum.github.io/%7B%22thumbnail%22=%3E%22/assets/images/wordobulator.png%22,%20%22name%22=%3E%22AI%20generated%20wordobulator%20machine%22%7D" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Weekly Post #1</title><link href="https://peergum.github.io/learning/coding/jobs/weekly-post-1/" rel="alternate" type="text/html" title="Weekly Post #1" /><published>2024-02-20T15:00:00+00:00</published><updated>2024-02-20T15:00:00+00:00</updated><id>https://peergum.github.io/learning/coding/jobs/weekly-post-1</id><content type="html" xml:base="https://peergum.github.io/learning/coding/jobs/weekly-post-1/"><![CDATA[<p>So, I decided I should just try to post at least once a week. It’s good for writing practice, it helps
summarizing the activity from last week, and maybe it will give (someone) a feeling of progress…
This will be my kind of standup meeting (for the week… not going to bore you everyday, LOL)</p>

<p>Last week (actually possibly starting with the week before that), along with continuing applying to several jobs, and receiving several thank you letters,
I decided to make a few changes in my activities. Some internal restructuring if you will. I decided
to refocus my development and learning skills.</p>

<p>Firstly, p-xo is a bit on-hold. I realized that coding it with Laravel + InertiaJS + Vue.js might not
be the best strategy. I know it’s a MVP, but since I’m the only one working on it, I need to make it
worth my while. Laravel-Inertia-Vue (let’s call that “LIV” for now) is great to get something off the ground
quickly, but it also means locking it in to that ecosystem, which leads me to my second point…</p>

<p>I don’t want to get stuck in PHP+Laravel. PHP is great and you can build things fast with it. It’s a
bit like a web-bash or web-awk if you want. You script it to do whatever you want quickly. The (huge)
downside is, it’s looked down by the developer community, because it’s not strongly typed. In other
words, it’s the new BASIC. I think that opinion tends to be a little bit of an overreaction,
and PHP can be a powerful scripting language with not much to envy to Java, C++ or other OOP languages,
but the market being what it is, it doesn’t really matter what I think or like, the main objective
being you need to use what the market uses otherwise you’re just a marginal coder that nobody wants
in their team. Another issue with LIV is, Inertia is a BIG bandwidth consumer, not to mention it
even passes the list of APIs you use in any requests. So much for security, IMHO!</p>

<p>So, I eventually opted for another strategy. I initially though, what about using Laravel as a
front-end and refreshing my skills in Java? So I powered up JetBrains IDEA, and started a quick
RESTFUL API development using SpringBoot, which was a great idea, because I realized the concept of
RESTFUL APIs slightly incomplete. SpringBoot’s tutorial opened my eyes with their reference to the <a href="https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven">Roy Fielding’s
“controversy” or argument</a>,
in which he argues most people tend to code incomplete RESTFUL APIs. Like most people, I used to
think that as long as I provided all the proper methods (GET, POST, PUT, DELETE,
and optionally HEAD and OPTIONS) to manage a resource and made all of them but POST idempotent, I’d
be building RESTFUL APIs. Fact is, an actual RESTFUL API also needs to be self-descriptive and include
links in its responses. I’d rather avoid a bad or imprecise paraphrasing of Roy Fielding’s message, so I
invite you to check the link above, and his following post too, where he slightly clarifies his
message. What I took away from all this is, if you use SpringBoot AND Spring <a href="https://en.wikipedia.org/wiki/HATEOAS">HATEOAS</a>,
you’re much closer to a creating proper RESTFUL API. But then another realization hit me.</p>

<p>Java is great. I did code in Java several years ago at Lasso Datasystems (now part of ECI Software Solutions),
when the development team decided to migrate all APIs away from PHP and implement Java APIs instead. Java
is likely one of the most common development environment used today (or its one of its JVM variants, like Kotlin), thanks to its portability and not
having to buy expensive licenses to develop with it. Yet, from a developer’s perspective, coding with
Java means being likely part of a pool of 60-80% (pure estimate on my part) of the coder population, only
second to Python, which obviously helps getting a job, but also increases competition for that job. With
this in mind, I eventually opted to focus on another language.</p>

<p>Golang (or more formally, simply “Go”) is a programming language that Google started developing around 15 years ago. I
got introduced to the language by my friend and colleague Charles Krempeaux while we were working at Trulioo,
back in 2013, and quickly came to love the efficiency and specificities of the languages. Even though the
language is not yet ranked among the 15 most used languages, many companies are starting to pick it up, for
backend solutions mainly. Go, a compiled language like Java or C/C++, is particularly championing concurrency and
networking, and that’s one of the main reason why I decided to focus on improving my skills in Go, adding to
the fact Go developers are not (yet) legion, mostly due to some steep learning curve (itself related to
the language being strongly typed, and character handling far more complex, yet powerful, that most languages).</p>

<p>Another learning area I intend to spend time on is Machine Learning (and indirectly AI, or vice-versa). I will
need to understand ML to develop some recommendations in p-xo, and I believe it’s currently also something
useful to present to future employers, all the more with current AI trend; I believe this trend is going to fade
away in the next five years, when everyone realizes that “AI” is just fashion rebranding of the old good “ML”
most people was finding boring because it’s clearly coding with statistics and probabilities, and people who
love Maths that much are not so many… (hence data scientists are mostly PhD people…)</p>

<p>Well, I think that completes my summary of the last two weeks. I’ll talk to you again next week with
some more (hopefully good) news…</p>]]></content><author><name>Phil Hilger</name></author><category term="Learning" /><category term="Coding" /><category term="Jobs" /><category term="weekly" /><category term="activity" /><category term="coding" /><category term="learning" /><category term="golang" /><category term="java" /><category term="AWS" /><category term="CloudFormation" /><category term="Lambda" /><summary type="html"><![CDATA[So, I decided I should just try to post at least once a week. It’s good for writing practice, it helps summarizing the activity from last week, and maybe it will give (someone) a feeling of progress… This will be my kind of standup meeting (for the week… not going to bore you everyday, LOL)]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://peergum.github.io/%7B%22thumbnail%22=%3E%22/assets/images/squirrel.jpg%22,%20%22name%22=%3E%22learning%20squirrel%22%7D" /><media:content medium="image" url="https://peergum.github.io/%7B%22thumbnail%22=%3E%22/assets/images/squirrel.jpg%22,%20%22name%22=%3E%22learning%20squirrel%22%7D" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Bye, Yahoo!</title><link href="https://peergum.github.io/email%20services/yahoo!/bye-yahoo/" rel="alternate" type="text/html" title="Bye, Yahoo!" /><published>2024-02-05T18:49:00+00:00</published><updated>2024-02-05T18:49:00+00:00</updated><id>https://peergum.github.io/email%20services/yahoo!/bye-yahoo</id><content type="html" xml:base="https://peergum.github.io/email%20services/yahoo!/bye-yahoo/"><![CDATA[<p>I opened my first decent email account in 1997, on Yahoo!, right after letting go of hosted email at CompuServe, which I had to
check in a browser, and installed Netscape Mail to read it directly using POP3 at the time
(I used IMAP4 later, for more convenience)</p>

<p>At the time, I thought Yahoo! was the best search engine, and their email could be checked online or offline (after retrieval).
Google was still in its infancy and Gmail only appeared in 2004.</p>

<p>Yahoo! served me well for the time I had it (more than 25 years!), but I eventually moved to Gmail around 2008. From then I
kept both accounts since I still used accounts that were registered using Yahoo! Mail.</p>

<p>But for the last decade, Yahoo! has mostly provided me with SPAM, more SPAM, and even more SPAM. To be honest, 99% of the
SPAM I get is from Yahoo! So, I assume my account ended in far too many leaks, that were sold to spammers eveywhere.</p>

<p>So, after updating the last few accounts using my Yahoo! email address, I decided to close that account, with a small
virtual tear.</p>

<p>So long, Yahoo!</p>]]></content><author><name>Phil Hilger</name></author><category term="Email Services" /><category term="Yahoo!" /><category term="closing" /><category term="yahoo!" /><category term="account" /><category term="email" /><summary type="html"><![CDATA[I opened my first decent email account in 1997, on Yahoo!, right after letting go of hosted email at CompuServe, which I had to check in a browser, and installed Netscape Mail to read it directly using POP3 at the time (I used IMAP4 later, for more convenience)]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://peergum.github.io/%7B%22thumbnail%22=%3E%22/assets/images/yahoo-artistic.jpg%22,%20%22name%22=%3E%22artistic%20AI-generated%20version%20of%20Yahoo&apos;s%20logo%22%7D" /><media:content medium="image" url="https://peergum.github.io/%7B%22thumbnail%22=%3E%22/assets/images/yahoo-artistic.jpg%22,%20%22name%22=%3E%22artistic%20AI-generated%20version%20of%20Yahoo&apos;s%20logo%22%7D" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">PartyRock, and why AI is not ready yet to replace coders</title><link href="https://peergum.github.io/coding/ai/partyrock/" rel="alternate" type="text/html" title="PartyRock, and why AI is not ready yet to replace coders" /><published>2023-12-13T16:33:00+00:00</published><updated>2023-12-13T16:33:00+00:00</updated><id>https://peergum.github.io/coding/ai/partyrock</id><content type="html" xml:base="https://peergum.github.io/coding/ai/partyrock/"><![CDATA[<p>Using #PartyRock, the new app generator from Amazon.com, I tried to “create an app that would show the best algorithm in PHP to solve a specific problem, and the syntax of the PHP functions used”.</p>

<p>PartyRock in no time generated me a simple app, and then I submitted to the app the following problem to the app: “given a string of alphabetic characters and symbols, I want to reverse the alphabetic characters but keep the symbols at the same place”. I found that problem in a javascript coding test recently, and was wondering the best way to do something similar in PHP.</p>

<p>This is what PartyRock offered for the algorithm part:</p>

<hr />

<p>“Here is one way to reverse the alphabetic characters while keeping the symbols in place in PHP:</p>
<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">function</span> <span class="n">reverseAlpha</span><span class="p">(</span><span class="nv">$str</span><span class="p">)</span> <span class="p">{</span>
 <span class="nb">preg_match_all</span><span class="p">(</span><span class="s1">'/\w+|\W+/'</span><span class="p">,</span> <span class="nv">$str</span><span class="p">,</span> <span class="nv">$matches</span><span class="p">);</span>

 <span class="nv">$result</span> <span class="o">=</span> <span class="s1">''</span><span class="p">;</span>
 <span class="k">foreach</span> <span class="p">(</span><span class="nv">$matches</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">as</span> <span class="nv">$part</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">if</span> <span class="p">(</span><span class="nb">ctype_alpha</span><span class="p">(</span><span class="nv">$part</span><span class="p">))</span> <span class="p">{</span>
   <span class="nv">$result</span> <span class="mf">.</span><span class="o">=</span> <span class="nb">strrev</span><span class="p">(</span><span class="nv">$part</span><span class="p">);</span> 
  <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
   <span class="nv">$result</span> <span class="mf">.</span><span class="o">=</span> <span class="nv">$part</span><span class="p">;</span>
  <span class="p">}</span>
 <span class="p">}</span>

 <span class="k">return</span> <span class="nv">$result</span><span class="p">;</span>
<span class="p">}</span>

<span class="nv">$str</span> <span class="o">=</span> <span class="s1">'abc123$%^xyz'</span><span class="p">;</span>
<span class="k">echo</span> <span class="nf">reverseAlpha</span><span class="p">(</span><span class="nv">$str</span><span class="p">);</span> <span class="c1">// 'zyx123$%^cba'</span>
</code></pre></div></div>

<p>The key steps are:</p>

<ol>
  <li>
    <p>Use preg_match_all() to split the string into an array of alphabetic and non-alphabetic parts.</p>
  </li>
  <li>
    <p>Loop through the parts array.</p>
  </li>
  <li>
    <p>For alphabetic parts, reverse using strrev().</p>
  </li>
  <li>
    <p>For non-alphabetic parts, append as-is.</p>
  </li>
  <li>
    <p>Join the reversed alphabetic and unchanged non-alphabetic parts back into a string.</p>
  </li>
</ol>

<p>This allows us to reverse only the alphabetic characters while preserving the symbols in their original positions.”</p>

<hr />

<p>Sounded great, but running it, it just doesn’t give the expected output “zyx123$%^cba”, but rather “abc123$%^zyx”</p>

<p>The main reason is, instead of grouping by letters, the code grouped by words and non-words: w+ and W+ in the regular expression syntax, rather than by letters, so then it reversed the the letters inside the groups. Second issue is, the “w” character class considers numbers can be part of a word, but the ctype_alpha function checks every character is alphabetic, not alphanumeric, so the first group (abc123) is not even reversed, which would still fail to solve the problem…</p>

<p>In the PHP Syntax part, where I was expecting to see the syntax of functions like preg_match, strrev, etc… that were used in the result code, PartyRock instead gave me ANOTHER way to do it (not sure why… maybe some misunderstanding here), calling it “PHP Syntax”.</p>

<hr />

<p>“Here is a sample PHP code to reverse the alphabetic characters while keeping the symbols in place:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">function</span> <span class="n">reverseAlpha</span><span class="p">(</span><span class="nv">$str</span><span class="p">)</span> <span class="p">{</span>

 <span class="c1">// Split string into an array of characters</span>
 <span class="nv">$chars</span> <span class="o">=</span> <span class="nb">str_split</span><span class="p">(</span><span class="nv">$str</span><span class="p">);</span>

 <span class="c1">// Reverse the alphabetic characters</span>
 <span class="nv">$alphaChars</span> <span class="o">=</span> <span class="nb">preg_replace</span><span class="p">(</span><span class="s1">'/\W/'</span><span class="p">,</span> <span class="s1">''</span><span class="p">,</span> <span class="nv">$str</span><span class="p">);</span> 
 <span class="nv">$revAlphaChars</span> <span class="o">=</span> <span class="nb">strrev</span><span class="p">(</span><span class="nv">$alphaChars</span><span class="p">);</span>

 <span class="c1">// Map original string to reversed alpha chars</span>
 <span class="nv">$map</span> <span class="o">=</span> <span class="nb">str_split</span><span class="p">(</span><span class="nv">$revAlphaChars</span><span class="p">);</span>
 <span class="nv">$result</span> <span class="o">=</span> <span class="s1">''</span><span class="p">;</span>
 <span class="k">foreach</span> <span class="p">(</span><span class="nv">$chars</span> <span class="k">as</span> <span class="nv">$char</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">if</span> <span class="p">(</span><span class="nb">ctype_alpha</span><span class="p">(</span><span class="nv">$char</span><span class="p">))</span> <span class="p">{</span>
   <span class="nv">$result</span> <span class="mf">.</span><span class="o">=</span> <span class="nb">array_shift</span><span class="p">(</span><span class="nv">$map</span><span class="p">);</span> 
  <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
   <span class="nv">$result</span> <span class="mf">.</span><span class="o">=</span> <span class="nv">$char</span><span class="p">;</span>
  <span class="p">}</span>
 <span class="p">}</span>

 <span class="k">return</span> <span class="nv">$result</span><span class="p">;</span>

<span class="p">}</span>

<span class="nv">$str</span> <span class="o">=</span> <span class="s1">'abc123$%^xyz'</span><span class="p">;</span>
<span class="k">echo</span> <span class="nf">reverseAlpha</span><span class="p">(</span><span class="nv">$str</span><span class="p">);</span> <span class="c1">// 'zyx123$%^cba'</span>
</code></pre></div></div>

<p>The key steps are:</p>

<ol>
  <li>
    <p>Split the string into an array of characters.</p>
  </li>
  <li>
    <p>Reverse only the alphabetic characters.</p>
  </li>
  <li>
    <p>Map the original string to the reversed alphabetic characters.</p>
  </li>
  <li>
    <p>Build the result string by taking either the reversed alphabetic char or the original symbol.</p>
  </li>
</ol>

<p>This reverses the alphabetic characters while keeping the symbols in their original order.”</p>
<hr />

<p>Again, sounded promising, but this time the result shown was “zyx123$%^321”, instead of the expected “zyx123$%^cba”.</p>

<p>Looking at the code, it seems it started the way I had myself started the javascript version, by reversing just the alphabetical
characters first. Yet, AI does it wrong because, once more, it considers numeric characters as alphabetical, keeping
the numbers in its supposed alphabetical only chain (it removes any non alphanumeric character using \W in a regular
expression). Then it reverses any purely aphabetical character in it and, thanks to ctype_alpha, rescans the initial
chain and replaces with its assumedly reversed chain… which starts fine, but ends badly due to the mistake made earlier.</p>

<p>So, AI failed in both examples, not by the lack of knowledge (both algorithms were smart, but badly executed).</p>

<h2 id="these-would-be-my-fixes-in-both-cases">These would be my fixes in both cases:</h2>

<p>case 1: actually, reversing characters in each set doesn’t make much sense, since the number of characters per set may differ,
e.g. if you submit ab123cde (result: ed123cba), then you’d get ab-123-cde, which when reversed would give ba-123-edc, but
reversing the order of the alphabetic sets would give edc-123-ba, which would be wrong. I think this method is not
really going anywhere.</p>

<p>case 2:</p>
<ol>
  <li>split into characters</li>
  <li>select alphabetic characters only and reverse them</li>
  <li>replace each alphabetic character from initial string by next one in the reversed string, keep others unchanged.</li>
</ol>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>function reverseAlpha($str) {

    // Split string into an array of characters
    $chars = str_split($str);

    // Reverse the alphabetic characters
    $alphaChars = preg_replace('/[[:^alpha:]]/', '', $str);
    $revAlphaChars = strrev($alphaChars);

    // Map original string to reversed alpha chars
    $map = str_split($revAlphaChars);
    $result = '';
    foreach ($chars as $char) {
        if (ctype_alpha($char)) {
            $result .= array_shift($map);
        } else {
            $result .= $char;
        }
    }

    return $result;

}

$str = 'ab123$%^xyz';
echo reverseAlpha($str); // 'zy123$%^xba'
</code></pre></div></div>
<p>Note that I changed the example to have a group of 2 alphabetic characters and a group of 3 to be sure things work
as expected. And voilà! It worked.</p>

<h2 id="summary-of-it-all">Summary of it all</h2>

<p>AI can get good ideas for an algorithm, but that’s not necessary the case, yet the execution
seems to be failing for some reason. I have a feeling that the failure of the overall process is related to the
existence of steps in the generation, rather than an overall flow. E.g.:</p>
<ol>
  <li>figure an algorithm</li>
  <li>convert the algorithm to text</li>
  <li>convert the algorithm to code</li>
</ol>

<p>Each of the steps above can go slightly wrong, but if they do, then the result can go fairly wrong (exponentially 
growing the level of error).</p>

<p>So, having AI code for me? Well, not without control, tests and fixes…
Have a nice day!</p>]]></content><author><name>Phil Hilger</name></author><category term="Coding" /><category term="AI" /><category term="coding" /><category term="skills" /><category term="PHP" /><category term="PartyRock" /><category term="AI" /><summary type="html"><![CDATA[Using #PartyRock, the new app generator from Amazon.com, I tried to “create an app that would show the best algorithm in PHP to solve a specific problem, and the syntax of the PHP functions used”.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://peergum.github.io/%7B%22thumbnail%22=%3E%22/assets/images/partyrock.jpg%22,%20%22name%22=%3E%22artistic%20AI-generated%20representation%20of%20AWS&apos;%20PartyRock%22%7D" /><media:content medium="image" url="https://peergum.github.io/%7B%22thumbnail%22=%3E%22/assets/images/partyrock.jpg%22,%20%22name%22=%3E%22artistic%20AI-generated%20representation%20of%20AWS&apos;%20PartyRock%22%7D" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Geodb</title><link href="https://peergum.github.io/geodb/" rel="alternate" type="text/html" title="Geodb" /><published>2023-11-30T00:00:00+00:00</published><updated>2023-11-30T00:00:00+00:00</updated><id>https://peergum.github.io/geodb</id><content type="html" xml:base="https://peergum.github.io/geodb/"><![CDATA[<p>I just released Laravel GeoDB version 1.0.0, an opensource package to help developers handle cities, states and countries in their Laravel apps.</p>

<p>Read more about it <a href="/projects/2023%20-%20laravel-geodb">here</a>.</p>

<p>Package provides data for:</p>
<ul>
  <li>252 countries</li>
  <li>50K states/regions</li>
  <li>4.6M cities</li>
  <li>all with population, elevation, currency, and latitude/longitude information</li>
  <li>updatable on-demand with new data updates from GeoNames</li>
</ul>

<p>It is available open-source on:</p>
<ul>
  <li>GitHub: https://github.com/peergum/geodb</li>
  <li>Packagist: https://packagist.org/packages/peergum/geodb</li>
</ul>

<p>Enjoy!</p>]]></content><author><name>Phil Hilger</name></author><summary type="html"><![CDATA[I just released Laravel GeoDB version 1.0.0, an opensource package to help developers handle cities, states and countries in their Laravel apps.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://peergum.github.io/%7B%22thumbnail%22=%3E%22/assets/images/laravel-geodb.png%22,%20%22name%22=%3E%22Laravel-GeoDB%20logo%22%7D" /><media:content medium="image" url="https://peergum.github.io/%7B%22thumbnail%22=%3E%22/assets/images/laravel-geodb.png%22,%20%22name%22=%3E%22Laravel-GeoDB%20logo%22%7D" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>