Mardy (Posts about informatica)http://mardy.it/categories/informatica.atom2024-02-02T20:10:58ZAlberto MardeganNikolalibSDL2 and VVVVVV for the Wiihttp://mardy.it/blog/2024/02/libsdl2-and-vvvvvv-for-the-wii.html2024-02-02T20:50:44+03:002024-02-02T20:50:44+03:00Alberto Mardegan<p>Just a quick update on something that I've been working on in my free time.</p>
<p>I recently refurbished my old Nintendo Wii, and for some reason I cannot yet
explain (not even to myself) I got into homebrew programming and decided to
port libSDL (the 2.x version -- a 1.x port already existed) to it. The result
of this work is already available via the <a href="https://devkitpro.org/">devkitPro</a>
distribution, and although I'm sure there are still many bugs, it's overall
quite usable.</p>
<p>In order to prove it, I ported the game <a href="https://thelettervsixtim.es/">VVVVVV</a>
to the Wii:</p>
<iframe src="https://vk.com/video_ext.php?oid=7200355&id=456239302&hd=1" width="640" height="360" allow="autoplay; encrypted-media; fullscreen;
picture-in-picture;" frameborder="0" allowfullscreen></iframe>
<p>During the process I had to fix quite a few bugs in my libSDL port and in a
couple of other libraries used by VVVVVV, which will hopefully will make it
easier to port more games. There's still an issue that bothers me, where the
screen resolution seems to be not totally supported by my TV (or is it the HDMI
adaptor's fault?), resulting in a few pixels being cut at the top and at the
bottom of the screen. But unless you are a perfectionist, it's a minor issue.</p>
<p>In case you have a Wii to spare, or wouldn't mind playing on the Dolphin
emulator, <a href="https://github.com/mardy/VVVVVV/releases/tag/v2.4.1_wii1">here's the link to the VVVVVV
release</a>. Have fun! :-)</p><p>Just a quick update on something that I've been working on in my free time.</p>
<p>I recently refurbished my old Nintendo Wii, and for some reason I cannot yet
explain (not even to myself) I got into homebrew programming and decided to
port libSDL (the 2.x version -- a 1.x port already existed) to it. The result
of this work is already available via the <a href="https://devkitpro.org/">devkitPro</a>
distribution, and although I'm sure there are still many bugs, it's overall
quite usable.</p>
<p>In order to prove it, I ported the game <a href="https://thelettervsixtim.es/">VVVVVV</a>
to the Wii:</p>
<iframe src="https://vk.com/video_ext.php?oid=7200355&id=456239302&hd=1" width="640" height="360" allow="autoplay; encrypted-media; fullscreen;
picture-in-picture;" frameborder="0" allowfullscreen></iframe>
<p>During the process I had to fix quite a few bugs in my libSDL port and in a
couple of other libraries used by VVVVVV, which will hopefully will make it
easier to port more games. There's still an issue that bothers me, where the
screen resolution seems to be not totally supported by my TV (or is it the HDMI
adaptor's fault?), resulting in a few pixels being cut at the top and at the
bottom of the screen. But unless you are a perfectionist, it's a minor issue.</p>
<p>In case you have a Wii to spare, or wouldn't mind playing on the Dolphin
emulator, <a href="https://github.com/mardy/VVVVVV/releases/tag/v2.4.1_wii1">here's the link to the VVVVVV
release</a>. Have fun! :-)</p>Will the internet forget russophobia?http://mardy.it/blog/2023/06/will-the-internet-forget-russophobia.html2023-06-04T10:41:02+03:002023-06-04T10:41:02+03:00Alberto Mardegan<p>I've often wondering what will happen when this horrific war in Europe will
finally be over. I won't be discussing politics here, but what is mostly
interesting to me is how (and if) all the companies who made high proclaims
about not doing business with Russia will justify their getting back into the
Russian market. They will probably count on the fact that the war will be long,
and that people will forget what these companies' stance was. After all, the
world has forget about all the companies who collaborated with the Nazi regime,
so we can expect the same to happen with this war.</p>
<p>But I don't think that's right: if you made a mistake, you should be held
accountable for it. You might be wondering what is the “mistake” I'm talking
about: that's <strong>russophobia</strong>, indeed. To put it simply, and make a concrete
example: if The Qt Company stops doing business with Russian companies and
blocks its downloads page to Russian IP addresses because of the war, <em>without
being forced by the government to do so</em>, but does not take similar measures
against other countries who wage wars which have caused way more deaths and
displacement of individuals, well, that's what I call “russophobia”. Of course,
I'm aware that there's way more than that, and that the hatred for all what is
Russian (including culture and sport competitions) is an even bigger issue, but
in this blog post I'm especially focused on the IT world, so please forgive my
semi-intentional narrow-mindness on this topic.</p>
<p>Now, I'm fully aware that we live in a mediatic bubble that directs our
decisions in a way that is almost automatic, and I'm sure that most people
working for companies who took russophobic decisions are not themselves
russophobic at all (and I'm not dismissing the possibility that even the very
same people who took these decisions might not be russophobic) and that these
decisions were taken on impulse, because “everyone else is doing the same” and
due to the media pressure that if you don't do that, you might get accused of
supporting the “wrong” side of the war.</p>
<p>But that's not an excuse, especially for “smart” people like IT engineers (and
I put the adjective between quotes <a href="http://mardy.it/blog/2022/11/the-idiotism-of-software-developers.html">for a
reason</a>), and especially after
the initial heat has passed and when, after more than one year of war, we
should have been exposed to different point of views and be able to evaluate
the situation more rationally. It has been therefore especially stunning for me
to learn that the Linux Kernel community, and hence The Linux Foundation, has
recently given room to russophobic behaviours, refusing a patch coming from the
Russian company Baikal (a CPU maker). For the record, the incriminated patch
was not related to supporting hardware produced by this company (not that this
would make the deed less serious, but at least one could have argued that there
could be some spot of logic in it):</p>
<div class="code"><pre class="code literal-block">From: Jakub Kicinski <kuba@kernel.org>
To: Serge Semin <Sergey.Semin@baikalelectronics.ru>
[...]
On Tue, 14 Mar 2023 01:42:24 +0300 Serge Semin wrote:
> From: Serge Semin <Sergey.Semin@baikalelectronics.ru>
We don't feel comfortable accepting patches from or relating
to hardware produced by your organization.
Please withhold networking contributions until further notice.
</pre></div>
<p>(<a href="https://lore.kernel.org/all/20230314103316.313e5f61@kernel.org/">here</a> the
link to the original discussion). One week later, someone denounced this as a
violation to the Code of Conduct committee (unfortunately the only link I could
find to this is coming from a <a href="https://www.opennet.ru/openforum/vsluhforumID3/129994.html#529">Russian IT
forum</a>, and any
other references seem to have been removed from DuckDuckGo and Google), only to
receive a reply that it was all fine.</p>
<p>To me this is not fine. The war will end, sooner or later, but it bothers me
that we never learn from the past and repeat the same mistakes over and over.
We apparently know a lot about propaganda, yet we fail to recognize it when it
influences our own mind and actions. My humble contribution is the creation of
a page where I list the companies who have taken russophobic actions, and, on
the opposite side, companies (like Flickr and Zorin OS) who have stood out for
positive messages and helpful actions. My hope is that some of the listed
companies will find the courage to review their actions, and either correct
their stance, or at least clarify their reasons. So, I hereby present</p>
<p style="text-align: center; font-size: 130%">
<a href="https://github.com/mardy/russophobia">Denouncing russophobia</a>
</p>
<p>where you'll find some of the good and some of the bad companies. I'm sure I'm
missing plenty of them: I just started recollecting my memories and searching
online a couple of days ago. I created this as a GitHub project, because indeed
I'm looking forward for contributions, to help me make the lists more complete.
I need to stress that the fact that a company has announced the suspension of
its business in Russia does not automatically make it russophobic: what we need
to look at is the <em>reason</em> for that decision: companies like LEGO and Nintendo,
for example, have suspended their operations citing logistic and financial
reasons; no judgement involved.</p>
<p>Let me repeat it once more, just to make sure there are no misunderstandings:
it's perfectly fine for businesses to take a stance on politics, and sometimes
it might be even praiseworthy; but if a company is international, and does not
apply the same reasoning to other armed conflicts, or seem to care only about
certain human rights violations and not others, then it's a case of double
standards which we need to be aware of, and make the company think twice about
it. And that's also the reason why you won't find any Ukrainian company among
the “bad” ones, because in their case the reaction is perfectly understandable
and they can hardly be accused of adopting double standards (well, technically
speaking, they are adopting double standards, but when you are so directly
impacted I think it does not deserve a blame): if it's your house which burns,
you should definitely scream about it, even if you previously have been silent
about your neighbour house's burning.</p>
<p><strong>I'm especially looking forward for more “good” companies</strong>, who have shown empathy
towards the people affected by the war (and maybe even collected money to help
them) while refraining from taking the judging role and forgetting about all
the injustice and suffering that other wars have caused (including on that very
same piece of land that suddenly appeared on all newspapers' front pages on
February 24th, 2022). I hope that these companies can serve as an example of
positive action, humanity, and love.</p><p>I've often wondering what will happen when this horrific war in Europe will
finally be over. I won't be discussing politics here, but what is mostly
interesting to me is how (and if) all the companies who made high proclaims
about not doing business with Russia will justify their getting back into the
Russian market. They will probably count on the fact that the war will be long,
and that people will forget what these companies' stance was. After all, the
world has forget about all the companies who collaborated with the Nazi regime,
so we can expect the same to happen with this war.</p>
<p>But I don't think that's right: if you made a mistake, you should be held
accountable for it. You might be wondering what is the “mistake” I'm talking
about: that's <strong>russophobia</strong>, indeed. To put it simply, and make a concrete
example: if The Qt Company stops doing business with Russian companies and
blocks its downloads page to Russian IP addresses because of the war, <em>without
being forced by the government to do so</em>, but does not take similar measures
against other countries who wage wars which have caused way more deaths and
displacement of individuals, well, that's what I call “russophobia”. Of course,
I'm aware that there's way more than that, and that the hatred for all what is
Russian (including culture and sport competitions) is an even bigger issue, but
in this blog post I'm especially focused on the IT world, so please forgive my
semi-intentional narrow-mindness on this topic.</p>
<p>Now, I'm fully aware that we live in a mediatic bubble that directs our
decisions in a way that is almost automatic, and I'm sure that most people
working for companies who took russophobic decisions are not themselves
russophobic at all (and I'm not dismissing the possibility that even the very
same people who took these decisions might not be russophobic) and that these
decisions were taken on impulse, because “everyone else is doing the same” and
due to the media pressure that if you don't do that, you might get accused of
supporting the “wrong” side of the war.</p>
<p>But that's not an excuse, especially for “smart” people like IT engineers (and
I put the adjective between quotes <a href="http://mardy.it/blog/2022/11/the-idiotism-of-software-developers.html">for a
reason</a>), and especially after
the initial heat has passed and when, after more than one year of war, we
should have been exposed to different point of views and be able to evaluate
the situation more rationally. It has been therefore especially stunning for me
to learn that the Linux Kernel community, and hence The Linux Foundation, has
recently given room to russophobic behaviours, refusing a patch coming from the
Russian company Baikal (a CPU maker). For the record, the incriminated patch
was not related to supporting hardware produced by this company (not that this
would make the deed less serious, but at least one could have argued that there
could be some spot of logic in it):</p>
<div class="code"><pre class="code literal-block">From: Jakub Kicinski <kuba@kernel.org>
To: Serge Semin <Sergey.Semin@baikalelectronics.ru>
[...]
On Tue, 14 Mar 2023 01:42:24 +0300 Serge Semin wrote:
> From: Serge Semin <Sergey.Semin@baikalelectronics.ru>
We don't feel comfortable accepting patches from or relating
to hardware produced by your organization.
Please withhold networking contributions until further notice.
</pre></div>
<p>(<a href="https://lore.kernel.org/all/20230314103316.313e5f61@kernel.org/">here</a> the
link to the original discussion). One week later, someone denounced this as a
violation to the Code of Conduct committee (unfortunately the only link I could
find to this is coming from a <a href="https://www.opennet.ru/openforum/vsluhforumID3/129994.html#529">Russian IT
forum</a>, and any
other references seem to have been removed from DuckDuckGo and Google), only to
receive a reply that it was all fine.</p>
<p>To me this is not fine. The war will end, sooner or later, but it bothers me
that we never learn from the past and repeat the same mistakes over and over.
We apparently know a lot about propaganda, yet we fail to recognize it when it
influences our own mind and actions. My humble contribution is the creation of
a page where I list the companies who have taken russophobic actions, and, on
the opposite side, companies (like Flickr and Zorin OS) who have stood out for
positive messages and helpful actions. My hope is that some of the listed
companies will find the courage to review their actions, and either correct
their stance, or at least clarify their reasons. So, I hereby present</p>
<p style="text-align: center; font-size: 130%">
<a href="https://github.com/mardy/russophobia">Denouncing russophobia</a>
</p>
<p>where you'll find some of the good and some of the bad companies. I'm sure I'm
missing plenty of them: I just started recollecting my memories and searching
online a couple of days ago. I created this as a GitHub project, because indeed
I'm looking forward for contributions, to help me make the lists more complete.
I need to stress that the fact that a company has announced the suspension of
its business in Russia does not automatically make it russophobic: what we need
to look at is the <em>reason</em> for that decision: companies like LEGO and Nintendo,
for example, have suspended their operations citing logistic and financial
reasons; no judgement involved.</p>
<p>Let me repeat it once more, just to make sure there are no misunderstandings:
it's perfectly fine for businesses to take a stance on politics, and sometimes
it might be even praiseworthy; but if a company is international, and does not
apply the same reasoning to other armed conflicts, or seem to care only about
certain human rights violations and not others, then it's a case of double
standards which we need to be aware of, and make the company think twice about
it. And that's also the reason why you won't find any Ukrainian company among
the “bad” ones, because in their case the reaction is perfectly understandable
and they can hardly be accused of adopting double standards (well, technically
speaking, they are adopting double standards, but when you are so directly
impacted I think it does not deserve a blame): if it's your house which burns,
you should definitely scream about it, even if you previously have been silent
about your neighbour house's burning.</p>
<p><strong>I'm especially looking forward for more “good” companies</strong>, who have shown empathy
towards the people affected by the war (and maybe even collected money to help
them) while refraining from taking the judging role and forgetting about all
the injustice and suffering that other wars have caused (including on that very
same piece of land that suddenly appeared on all newspapers' front pages on
February 24th, 2022). I hope that these companies can serve as an example of
positive action, humanity, and love.</p>Back to Maemo!http://mardy.it/blog/2023/01/back-to-maemo.html2023-01-08T22:48:52+03:002023-01-08T22:48:52+03:00Alberto Mardegan<p>New year, new job. After <a href="http://mardy.it/blog/2022/12/leaving-canonical-again.html">leaving
Canonical</a> I'm back to working on the same
software platform on which I started working back in 2006: <a href="http://mardy.it/blog/2023/01/maemo.org">Maemo</a>.
Well, not exactly the vanilla Maemo, but rather its evolution known as <a href="https://en.wikipedia.org/wiki/Aurora_OS_(Russian_Open_mobile_platform)">Aurora
OS</a>,
which is based on <a href="https://sailfishos.org/">Sailfish OS</a>. This means I'm
actually back to fixing the very same bugs I introduced back then when I was
working in Nokia, since a lot of the middleware has remained the same.</p>
<p>At the moment OMP (the company developing Aurora OS) is mostly (or even
<em>exclusively</em>, AFAIK) targeting business customers, meaning corporations such
as the Russian posts and the railway company, whereas the consumer market is
seen as something in the far away future. Just in case you were curious whether
there were any devices on sale with Aurora OS.</p>
<p>I should also explain why I've refused several very well paying job
opportunities from Western companies: it's actually for a reason that has been
bothering me since last March, and it's a very simple one. The fact is that
because of the sanctions against Russia I already had to change bank once (as
the one I was using fell under sanctions), and in these months I've always been
working with the fear of not being able to receive my salary, since new
sanctions are introduced every month and more and more banks are being added to
the blacklist. That's why I've restricted my job search to companies having an
official presence in Russia; and to my surprise (and from some point of view, I
could even say <em>disappointment</em>) the selection and hiring processes were so
quick that I received three concrete offers while I was still working my last
weeks at Canonical, and I joined OMP on that very Monday after my last Friday
at Canonical.</p>
<p>I mean, I could have rested a bit, at least until the Christmas holidays, but
no. ☺ Anyway, I'm so far very happy with my new job, and speaking Russian at
work is something totally new for me, both challenging and rewarding at the
same time.</p><p>New year, new job. After <a href="http://mardy.it/blog/2022/12/leaving-canonical-again.html">leaving
Canonical</a> I'm back to working on the same
software platform on which I started working back in 2006: <a href="http://mardy.it/blog/2023/01/maemo.org">Maemo</a>.
Well, not exactly the vanilla Maemo, but rather its evolution known as <a href="https://en.wikipedia.org/wiki/Aurora_OS_(Russian_Open_mobile_platform)">Aurora
OS</a>,
which is based on <a href="https://sailfishos.org/">Sailfish OS</a>. This means I'm
actually back to fixing the very same bugs I introduced back then when I was
working in Nokia, since a lot of the middleware has remained the same.</p>
<p>At the moment OMP (the company developing Aurora OS) is mostly (or even
<em>exclusively</em>, AFAIK) targeting business customers, meaning corporations such
as the Russian posts and the railway company, whereas the consumer market is
seen as something in the far away future. Just in case you were curious whether
there were any devices on sale with Aurora OS.</p>
<p>I should also explain why I've refused several very well paying job
opportunities from Western companies: it's actually for a reason that has been
bothering me since last March, and it's a very simple one. The fact is that
because of the sanctions against Russia I already had to change bank once (as
the one I was using fell under sanctions), and in these months I've always been
working with the fear of not being able to receive my salary, since new
sanctions are introduced every month and more and more banks are being added to
the blacklist. That's why I've restricted my job search to companies having an
official presence in Russia; and to my surprise (and from some point of view, I
could even say <em>disappointment</em>) the selection and hiring processes were so
quick that I received three concrete offers while I was still working my last
weeks at Canonical, and I joined OMP on that very Monday after my last Friday
at Canonical.</p>
<p>I mean, I could have rested a bit, at least until the Christmas holidays, but
no. ☺ Anyway, I'm so far very happy with my new job, and speaking Russian at
work is something totally new for me, both challenging and rewarding at the
same time.</p>Leaving Canonical, againhttp://mardy.it/blog/2022/12/leaving-canonical-again.html2022-12-03T10:03:58+03:002022-12-03T10:03:58+03:00Alberto Mardegan<p>For the <a href="http://mardy.it/blog/2017/04/looking-for-new-adventures.html">second time</a>, I'm being shown
the door at Canonical. Well, technically, this time it was me who handed over my
resignation, but that was only after I was told in very clear terms that I
would eventually be fired. No timeframe was given, but since I don't
particularly enjoy the feeling of checking my e-mail every morning to find out
whether this is the day when I'm being fired, I decided to take the initiative
and leave myself.</p>
<p>The reason? Those who know me well might suspect that it's related to some
complications with that fact that I'm living in Russia, or maybe with some
remarks I might have made about the war in Ukraine or about other current
events, since <a href="http://mardy.it/blog/2019/09/principles-and-privileges.html">I tent to be quite outspoken and
provocative</a>. Nothing of all that: it's about my
<strong>refusal to get vaccinated</strong> against COVID-19; unfortunately, it has now
become apparent that I'm not the only one leaving, and other employees who have
refused either to get vaccinated or to disclose their vaccination status are
also being shown the door (including people who have been in the company for
more than 10 years). This has sparked some internal discussions in the company, and
several different point of views have been voiced: from those who welcome this
policy and would like to see it extended to flu vaccinations (which makes a lot
of sense, since once you've accepted to renounce your freedom in order to
protect the weak, you should accept it for all transmissible diseases), to
those who voiced concerns about the legality of this move, or would have found
this reasonable one year ago but not in the current situation as restrictions
are getting lifted and the current variants are less scary than the previous
ones; those who pointed out that being vaccinated has little impact on
transmissibility of the virus; that we are mostly a remote company and we could
instead have exceptions to allow unvaccinated people (or people with a weak
immune system) to remotely attend the few in-person meetings we have;
that as long as there are no vaccination mandates for plane flights and other
guests attending the same hotel premises where we meet, mandating employees to
get vaccinated might not help a lot; and whether this is a decision that a
company should make, or shouldn't it rather lobby the politics to have it
mandated at state level. I think there's merit to all these arguments, but I'm
personally not particularly interested in discussing any of them, since my
point is another.</p>
<p>Before talking about that, though, let me clearly set one thing straight: I
hate lies, and <strong>Canonical's management is lying</strong> about this matter. The
vaccination mandate measure is being justified on the grounds that it allows
employees to travel (something that I've been able to do as unvaccinated
throughout the last two years, even when restrictions were at their peak) and,
most importantly, to protect our weaker colleagues. This is what I find most
disgusting: using genuine feelings like love and compassion to justify
repressive measures. No, dear Canonical, this has nothing to do with protecting
the weak; not only because a vaccinated person can still spread the virus (and
our employees know this from first-hand experience), but also because, if this
was the real reason, then you'd accept people who have recently recovered from
COVID-19, since <a href="https://academic.oup.com/cid/article/75/1/e545/6563799">immunisation after recovery is not worse than that of
vaccination</a>; but you
don't, as I was explicitly told by HR that any previous infection is irrelevant.
It's also significant that you didn't establish clear rules about how often
one needs to get vaccinated, since all recent scientific literature on vaccine
efficacy shows that this is not a minor detail. Why not just be honest with
ourselves, and admit it's <a href="https://www.enr.com/articles/52481-us-announces-revised-vaccine-mandate-rules-for-federal-contractors">just for
business</a>?
Being open about the fact that having a fully vaccinated workforce can grant us
access to more business deals would not change a lot in the practical life of
the (ex-)employees, but at least we won't feel that the company is treating us
as fools while embellishing its image with fake care and compassion. Or, if
there are other reasons, state them, because these ones don't stand up to logic
scrutiny.</p>
<p>Another thing that doesn't match (though maybe this is a timing issue, so I
cannot for sure call it out as a lie) is the fact that HR claims to have an
exemption process through which one could opt-out of the vaccination for
religious beliefs. Well, I was explicitly told in very clear terms by HR that
no exceptions would be made on either moral or religious grounds. But maybe
this has changed since the time I was told this (mid October) and now?</p>
<p>Here, finally, let me state why I believe that such a mandate is wrong. The
first thing I want to put on the table is that even though I see very little
reason for this mandate (given all what we know about the virus mutability and
infectiousness, the shortcomings of the vaccines, etc. — by the way, if you are
into science I suggest reading <a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC9062939/">this
article</a> which raises
some questions you won't hear in mainstream media and has a comprehensive
bibliography for further study), I recognize that in principle there are very
solid reasons for vaccination mandates, for example in the case where a virus
is extremely lethal, its symptoms otherwise uncurable and the vaccine is 100%
safe and highly effective. But even in that case, while getting vaccinated
myself, I would still oppose a mandate. Why? Because of freedom, which trumps
everything. The choice is never between a healthy life and freedom: if there's
no freedom, there's no life worth living. Even if some decision has very solid
reasons behind it, this doesn't automatically make it a good decision.</p>
<p>Let me make a few examples: if a company (I'm talking about companies here, but
the reasoning could be extended to states as well) decided that smokers will be
fired, or that those who drink alcoholics will be fired, or that you cannot eat
meat, or that you must take a pill whenever your head aches, or that
transgender people must undergo gender reassignment surgery, or that
everyone should wear a black band on their arm whenever a relative of a
colleague dies, or that employees' households must use the product made by the
employer, or that they have to excercise sports for at least two hours per
week, etc.; I would be categorically opposed to every single of these
impositions, despite recognising that there are reasons behind each of them,
and that I even dream of a world in which some of their goals are attained
(could we just all be fit and healthy?!). Because I think that personal freedom
is more important. You can always find good reasons to justify this or that
action; surely, if we think back at the fascist and totalitarian regimes of the
first half of last century, we must acknowledge that they were supported by the
(overwhelming?) majority of the population. An effective propaganda machine
could convince the population on this and that matter, but ultimately it's the
population who <em>reasoned</em> and accepted that storytelling. Nowadays the
situation is different, but the mechanisms are the same, except that propaganda
has become way more effective (<a href="http://mardy.it/blog/2022/11/the-idiotism-of-software-developers.html">or have we become
dumber?</a>) and aligned over the
same direction, thanks to the globalisation process.</p>
<p>I'm well aware that societies are made of rules and therefore inevitably
restrict personal freedom: Western societies, for example, forbid nudity in
public places, and that's something I accept because it's part of my culture;
it's a rule deeply entrenched in our history, and I don't feel it as a burden.
I'm convinced, however, that the evolution of human society should be that, as
we become more conscious, we should be moving towards more free societies, with
fewer rules and more tolerant for diversity.</p><p>For the <a href="http://mardy.it/blog/2017/04/looking-for-new-adventures.html">second time</a>, I'm being shown
the door at Canonical. Well, technically, this time it was me who handed over my
resignation, but that was only after I was told in very clear terms that I
would eventually be fired. No timeframe was given, but since I don't
particularly enjoy the feeling of checking my e-mail every morning to find out
whether this is the day when I'm being fired, I decided to take the initiative
and leave myself.</p>
<p>The reason? Those who know me well might suspect that it's related to some
complications with that fact that I'm living in Russia, or maybe with some
remarks I might have made about the war in Ukraine or about other current
events, since <a href="http://mardy.it/blog/2019/09/principles-and-privileges.html">I tent to be quite outspoken and
provocative</a>. Nothing of all that: it's about my
<strong>refusal to get vaccinated</strong> against COVID-19; unfortunately, it has now
become apparent that I'm not the only one leaving, and other employees who have
refused either to get vaccinated or to disclose their vaccination status are
also being shown the door (including people who have been in the company for
more than 10 years). This has sparked some internal discussions in the company, and
several different point of views have been voiced: from those who welcome this
policy and would like to see it extended to flu vaccinations (which makes a lot
of sense, since once you've accepted to renounce your freedom in order to
protect the weak, you should accept it for all transmissible diseases), to
those who voiced concerns about the legality of this move, or would have found
this reasonable one year ago but not in the current situation as restrictions
are getting lifted and the current variants are less scary than the previous
ones; those who pointed out that being vaccinated has little impact on
transmissibility of the virus; that we are mostly a remote company and we could
instead have exceptions to allow unvaccinated people (or people with a weak
immune system) to remotely attend the few in-person meetings we have;
that as long as there are no vaccination mandates for plane flights and other
guests attending the same hotel premises where we meet, mandating employees to
get vaccinated might not help a lot; and whether this is a decision that a
company should make, or shouldn't it rather lobby the politics to have it
mandated at state level. I think there's merit to all these arguments, but I'm
personally not particularly interested in discussing any of them, since my
point is another.</p>
<p>Before talking about that, though, let me clearly set one thing straight: I
hate lies, and <strong>Canonical's management is lying</strong> about this matter. The
vaccination mandate measure is being justified on the grounds that it allows
employees to travel (something that I've been able to do as unvaccinated
throughout the last two years, even when restrictions were at their peak) and,
most importantly, to protect our weaker colleagues. This is what I find most
disgusting: using genuine feelings like love and compassion to justify
repressive measures. No, dear Canonical, this has nothing to do with protecting
the weak; not only because a vaccinated person can still spread the virus (and
our employees know this from first-hand experience), but also because, if this
was the real reason, then you'd accept people who have recently recovered from
COVID-19, since <a href="https://academic.oup.com/cid/article/75/1/e545/6563799">immunisation after recovery is not worse than that of
vaccination</a>; but you
don't, as I was explicitly told by HR that any previous infection is irrelevant.
It's also significant that you didn't establish clear rules about how often
one needs to get vaccinated, since all recent scientific literature on vaccine
efficacy shows that this is not a minor detail. Why not just be honest with
ourselves, and admit it's <a href="https://www.enr.com/articles/52481-us-announces-revised-vaccine-mandate-rules-for-federal-contractors">just for
business</a>?
Being open about the fact that having a fully vaccinated workforce can grant us
access to more business deals would not change a lot in the practical life of
the (ex-)employees, but at least we won't feel that the company is treating us
as fools while embellishing its image with fake care and compassion. Or, if
there are other reasons, state them, because these ones don't stand up to logic
scrutiny.</p>
<p>Another thing that doesn't match (though maybe this is a timing issue, so I
cannot for sure call it out as a lie) is the fact that HR claims to have an
exemption process through which one could opt-out of the vaccination for
religious beliefs. Well, I was explicitly told in very clear terms by HR that
no exceptions would be made on either moral or religious grounds. But maybe
this has changed since the time I was told this (mid October) and now?</p>
<p>Here, finally, let me state why I believe that such a mandate is wrong. The
first thing I want to put on the table is that even though I see very little
reason for this mandate (given all what we know about the virus mutability and
infectiousness, the shortcomings of the vaccines, etc. — by the way, if you are
into science I suggest reading <a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC9062939/">this
article</a> which raises
some questions you won't hear in mainstream media and has a comprehensive
bibliography for further study), I recognize that in principle there are very
solid reasons for vaccination mandates, for example in the case where a virus
is extremely lethal, its symptoms otherwise uncurable and the vaccine is 100%
safe and highly effective. But even in that case, while getting vaccinated
myself, I would still oppose a mandate. Why? Because of freedom, which trumps
everything. The choice is never between a healthy life and freedom: if there's
no freedom, there's no life worth living. Even if some decision has very solid
reasons behind it, this doesn't automatically make it a good decision.</p>
<p>Let me make a few examples: if a company (I'm talking about companies here, but
the reasoning could be extended to states as well) decided that smokers will be
fired, or that those who drink alcoholics will be fired, or that you cannot eat
meat, or that you must take a pill whenever your head aches, or that
transgender people must undergo gender reassignment surgery, or that
everyone should wear a black band on their arm whenever a relative of a
colleague dies, or that employees' households must use the product made by the
employer, or that they have to excercise sports for at least two hours per
week, etc.; I would be categorically opposed to every single of these
impositions, despite recognising that there are reasons behind each of them,
and that I even dream of a world in which some of their goals are attained
(could we just all be fit and healthy?!). Because I think that personal freedom
is more important. You can always find good reasons to justify this or that
action; surely, if we think back at the fascist and totalitarian regimes of the
first half of last century, we must acknowledge that they were supported by the
(overwhelming?) majority of the population. An effective propaganda machine
could convince the population on this and that matter, but ultimately it's the
population who <em>reasoned</em> and accepted that storytelling. Nowadays the
situation is different, but the mechanisms are the same, except that propaganda
has become way more effective (<a href="http://mardy.it/blog/2022/11/the-idiotism-of-software-developers.html">or have we become
dumber?</a>) and aligned over the
same direction, thanks to the globalisation process.</p>
<p>I'm well aware that societies are made of rules and therefore inevitably
restrict personal freedom: Western societies, for example, forbid nudity in
public places, and that's something I accept because it's part of my culture;
it's a rule deeply entrenched in our history, and I don't feel it as a burden.
I'm convinced, however, that the evolution of human society should be that, as
we become more conscious, we should be moving towards more free societies, with
fewer rules and more tolerant for diversity.</p>The “idiotism” of software developershttp://mardy.it/blog/2022/11/the-idiotism-of-software-developers.html2022-11-08T20:11:55+03:002022-11-08T20:11:55+03:00Alberto Mardegan<p>Before you get angry at me for this title, please let me state that I count
myself in the number of the “idiots” and, secondly, that what I mean by
“idiotism” here is not to be intended as an offence, but as some traits of
mindset which are typical of very logical brains.</p>
<p>Some months ago I finished reading Dostoevskiy's “The Idiot”, a book about an
exceedingly good-hearted man, prince Lev Mishkin, whose behaviour was puzzling
the people around him so much that they thought of him as an idiot. Sure, the
fact that he was suffering from epilepsy didn't help, but it was far from being
the primary reason for their thinking, since his epileptic seizures were very
rare (if I remember correctly, only two occurred during the time of the story)
and everybody's opinion had already formed well ahead of witnessing him in such
a state.</p>
<p>He was an idiot because he was open, trustful, and especially because he could
not “read between the lines” of what was been said to him: his social conduct
was straight, and although he was following at his best the customs that he had
been taught, he was supposedly awkward and unable to perceive and parse all the
messages that are implicitly conveyed by social behaviours and human
interactions. I added the word “supposedly” because, as a matter of fact, his
behaviours were all perfectly normal for me: I only noticed their awkwardness
when it was pointed out by the other characters, at which point I couldn't help
smiling and acknowledging that, indeed, that thing he did was weird.</p>
<p>However, he was a good and caring person, and not without talents: he had an
interest in calligraphy, and everybody liked to listen to him, as his speech
was insightful and his thoughts were original. I wonder how many of my readers
can identify themselves in such a character?</p>
<p>I definitely can. I won't get into the details, but I've felt many times on me
the amused or puzzled glance of people (like that time in high school when I
could not open a door in front of dozens of people, and I heard them say “So,
that guy is the genius of mathematics?” — I'll never forget that!), often
without understanding the reason for their reactions. Still, generally people
seem to like my company and be genuinely interested in talking to me.</p>
<p>So, what's wrong with prince Lev Mishkin, me, and maybe with you too? Well, a few
things, I would say. I'm not going to claim any scientific truth on what I'm
going to say, these are just my own impressions and deductions, which seem
to be shared by other people in the interwebs too, judging from a quick search
I did; take them for what they are.</p>
<p>The first thing I notice is some common traits between us and autistic people:
we tend to work better with things, rather than with people; we can to focus on
a certain thing (work, a mathematical problem, a game) and forget about the
world around us; we have our unique hobbies, like solving puzzles, arguing
about a specific and very narrow topic, learning artificial (both human and
programming) languages; it's as if we needed to build a small, better world
where we would feel safe and at ease.</p>
<p>The other thing, which I actually consider harmful and which I put efforts to
change in my own life, is the fact that it's extremely easy to get us
interested into a specific aspect of a problem, and make us forget (or just not
notice) the big picture. That small part that we are looking at is stimulating
and challenging, and we are led to think that it's core of the issue, and maybe
of all the issues that affect our world. What is often missing is the ability
to take one step back and try to look at the issue from a different angle, and
especially the ability to listen for counter arguments; I mean, we do listen to
them, but since we have, in a way, “gamified” the issue, even when we think
that we are open to listen for the other side, we are in reality trying to win
the counter-arguments, rather than genuinely trying to understanding them.</p>
<p>Another thing which we have, is faith. Yes, you read it right: even though the
IT world is probably the one with the highest percentage of atheists, men
always need something to believe in. We just don't realize it, but we do hold a
blind trust in certain persons and authorities. This does not mean that this
trust lives forever and cannot be broken, but this generally does not occur
because of a conscious realization of ours. Much more often than we'd like to
admit, the reason why we lose faith in a certain person or authority is because
<em>the rest of the persons and authorities that we trust has told us so</em>. In
other words, even if there's undoubtedly a reasoning of our own, the full
realisation and conviction occurs after having collected and compared the
opinions (or statements) of those we trust. The net result is that the IT
population is the one most trustful of the mainstream media, because it's the
mainstream media who has more “voice”: that's where the most <em>reputable</em>
journalists, scientists, activists are (and “reputable” is the key word here,
since this reputation is recursively created by the mainstream media
themselves or by their sponsors).</p>
<p>I might be biased by my own experience here, but it seems to me that there
isn't a group of people more homogenous in their political (and generally,
world) views than that of IT workers. When, in 2018, I saw the leaked video of
Google's co-founder Sergei Brin and other executives' reaction at Trump's
presidential victory, what I found most surprising was not the contents of the
speech, as they were mostly mainstream opinions, but rather the fact that all
this could be said in a company meeting. Something like this, I though, could
never happen in an European company, as political matters are a conventional
tabu in the work environment. But the point is that Brin and others could say
those words only because <em>they knew</em> that the overwhelming majority of the
audience shared the same opinion. I don't think you could find the same
homogeneity of thought among shop assistants or philosophy professors.</p>
<p>Assuming that you have followed me this far into my rambling, and that you
recognize that there might be some truth in what I wrote, you might now be
wondering if there's a way to counterbalance our “idiotic” traits.
Unfortunately I don't have a full answer, as myself am only halfway there (but
maybe I'm too optimistic here? and does this road even ever end?), but there
are a few things that I think are absolutely worth trying:</p>
<ul>
<li>
<p>Talk with people. Better if face to face, or at least in a video call; just
1-on-1, avoid groups, or you'll get on the defensive and try to defend your
position for the sake of not losing the argument in front of an audience. But
it's not a fight. Your goal when talking should not be that of convincing or
getting convinced, but rather just to <em>understand</em> the other points of view.</p>
</li>
<li>
<p>Read both sides of the narrative. Try to see the other party's argument as
they themselves present it, and not how it is presented in the media you
usually read. Media often use this trick, to either invite “clown
representatives” of the other point of view just to ridicule it, or they give them
too little time, or extrapolate their answer out of context, just to make
them appear unsensible.</p>
</li>
<li>
<p>Always assume that other people are smart, and that no one is bad.</p>
</li>
<li>
<p>Whatever the argument, try to answer the key question: “Cui bono?” (who
profits?) to be at least aware of all the hidden interests behind this and
that. They don't necessarily invalidate a position, but they must be
considered.</p>
</li>
<li>
<p>Lose faith. The only faith you are allowed to keep is the faith in God (or
Gods), if you have it: but men, theories, institutions, authorities
(including religious ones!), these must always be assumed to be imperfect and
not blindly trusted. People serve their interests or can be manipulated. Try
always to start from a clean table and an empty mind, and see if they have
enough arguments to convince you. </p>
</li>
<li>
<p>Do never assume “They can not <em>all</em> be wrong” or “If this were wrong, at
least some media would report it”. It just doesn't work this way, this is
again a matter of having faith in the majority. Think of how many times in
(recent) history you were presented an unambiguous truth, which later came
out to be a scam (Iraq war being a famous one).</p>
</li>
<li>
<p>Defocus. You might be spending a lot of energy into something that's not
worth it. I mean, feel free to pursue whatever hobbies you like, as long as
they make you feel better. But if you think you have a <em>mission</em>, think twice
about it. Think about the world you'd like to live in, and whether/how this
mission contributes to it.<sup id="fnref:saudi"><a class="footnote-ref" href="http://mardy.it/blog/2022/11/the-idiotism-of-software-developers.html#fn:saudi">2</a></sup></p>
</li>
<li>
<p>Ask questions. Be curious. Be challenging. For any topic, there are questions
that have not been answered in mainstream media<sup id="fnref:refugees"><a class="footnote-ref" href="http://mardy.it/blog/2022/11/the-idiotism-of-software-developers.html#fn:refugees">1</a></sup>. Find the answer,
then find explanations, never stopping at the first satisfactory one, but
always get at least two competing answers. From here, ask more questions,
rinse and repeat. And at every step ask yourself this: why didn't I know
about this? Is someone trying to hide the truth from me?</p>
</li>
<li>
<p>Aim at improving. Whenever you read something or talk to people, keep a
humble attitude and try to be challenged. Your goal should be that every
reading and every dialog should make you wiser, even if what you initially
read and heard sounded like garbage. There are always reasons for all these
thoughts you disagree with.</p>
</li>
<li>
<p>Reach out to the people nearby. Try not just to be sympathetic to the needs of
some population living far away from you, which the media has singled out as
being those needing your compassion, and try instead (or in addition to that)
to be sympathetic and helpful to the people around you. To your neighbours,
to those you see in the public transport and, first and foremost, to your
relatives.</p>
</li>
</ul>
<p>Summing up, what I want you to realize is that we IT workers are easily
exploitable. All those thought manipulation techniques represent a problem to
everyone, but it's particularly with us that they tend to be especially
effective; as a matter of fact, I've found that awareness of how the power
controls us is higher among uneducated people, because they are more
distrustful of the media and just tend to consume less of it. We, on the other
hand, are not only well educated to respect the authority (see <a href="https://www.youtube.com/watch?v=wv6TyJ1AbRM">Noam Chomsky on
education</a>), but our logical,
detail-focused mind can be easily externally controlled by continuously
stimulating it to focus on specific things and not others.</p>
<p>How would Dostoevskiy call us?</p>
<div class="footnote">
<hr>
<ol>
<li id="fn:refugees">
<p>My favourite one is: which country hosts more refugees from Ukraine? <a class="footnote-backref" href="http://mardy.it/blog/2022/11/the-idiotism-of-software-developers.html#fnref:refugees" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
<li id="fn:saudi">
<p>I was recently surprised when I read people in a forum who were
discussing avoiding doing business with Saudi Arabia because of their human
rights record. Seriously? We are talking about a government who has indirectly
caused the death of more than 300 thousands people in Yemen, and your main
reason to criticize them is human rights? It's like asking the police to arrest
a killer because before the assassination he misgendered his victim! Yet the
elephant in the room continues to go unseen. <a class="footnote-backref" href="http://mardy.it/blog/2022/11/the-idiotism-of-software-developers.html#fnref:saudi" title="Jump back to footnote 2 in the text">↩</a></p>
</li>
</ol>
</div><p>Before you get angry at me for this title, please let me state that I count
myself in the number of the “idiots” and, secondly, that what I mean by
“idiotism” here is not to be intended as an offence, but as some traits of
mindset which are typical of very logical brains.</p>
<p>Some months ago I finished reading Dostoevskiy's “The Idiot”, a book about an
exceedingly good-hearted man, prince Lev Mishkin, whose behaviour was puzzling
the people around him so much that they thought of him as an idiot. Sure, the
fact that he was suffering from epilepsy didn't help, but it was far from being
the primary reason for their thinking, since his epileptic seizures were very
rare (if I remember correctly, only two occurred during the time of the story)
and everybody's opinion had already formed well ahead of witnessing him in such
a state.</p>
<p>He was an idiot because he was open, trustful, and especially because he could
not “read between the lines” of what was been said to him: his social conduct
was straight, and although he was following at his best the customs that he had
been taught, he was supposedly awkward and unable to perceive and parse all the
messages that are implicitly conveyed by social behaviours and human
interactions. I added the word “supposedly” because, as a matter of fact, his
behaviours were all perfectly normal for me: I only noticed their awkwardness
when it was pointed out by the other characters, at which point I couldn't help
smiling and acknowledging that, indeed, that thing he did was weird.</p>
<p>However, he was a good and caring person, and not without talents: he had an
interest in calligraphy, and everybody liked to listen to him, as his speech
was insightful and his thoughts were original. I wonder how many of my readers
can identify themselves in such a character?</p>
<p>I definitely can. I won't get into the details, but I've felt many times on me
the amused or puzzled glance of people (like that time in high school when I
could not open a door in front of dozens of people, and I heard them say “So,
that guy is the genius of mathematics?” — I'll never forget that!), often
without understanding the reason for their reactions. Still, generally people
seem to like my company and be genuinely interested in talking to me.</p>
<p>So, what's wrong with prince Lev Mishkin, me, and maybe with you too? Well, a few
things, I would say. I'm not going to claim any scientific truth on what I'm
going to say, these are just my own impressions and deductions, which seem
to be shared by other people in the interwebs too, judging from a quick search
I did; take them for what they are.</p>
<p>The first thing I notice is some common traits between us and autistic people:
we tend to work better with things, rather than with people; we can to focus on
a certain thing (work, a mathematical problem, a game) and forget about the
world around us; we have our unique hobbies, like solving puzzles, arguing
about a specific and very narrow topic, learning artificial (both human and
programming) languages; it's as if we needed to build a small, better world
where we would feel safe and at ease.</p>
<p>The other thing, which I actually consider harmful and which I put efforts to
change in my own life, is the fact that it's extremely easy to get us
interested into a specific aspect of a problem, and make us forget (or just not
notice) the big picture. That small part that we are looking at is stimulating
and challenging, and we are led to think that it's core of the issue, and maybe
of all the issues that affect our world. What is often missing is the ability
to take one step back and try to look at the issue from a different angle, and
especially the ability to listen for counter arguments; I mean, we do listen to
them, but since we have, in a way, “gamified” the issue, even when we think
that we are open to listen for the other side, we are in reality trying to win
the counter-arguments, rather than genuinely trying to understanding them.</p>
<p>Another thing which we have, is faith. Yes, you read it right: even though the
IT world is probably the one with the highest percentage of atheists, men
always need something to believe in. We just don't realize it, but we do hold a
blind trust in certain persons and authorities. This does not mean that this
trust lives forever and cannot be broken, but this generally does not occur
because of a conscious realization of ours. Much more often than we'd like to
admit, the reason why we lose faith in a certain person or authority is because
<em>the rest of the persons and authorities that we trust has told us so</em>. In
other words, even if there's undoubtedly a reasoning of our own, the full
realisation and conviction occurs after having collected and compared the
opinions (or statements) of those we trust. The net result is that the IT
population is the one most trustful of the mainstream media, because it's the
mainstream media who has more “voice”: that's where the most <em>reputable</em>
journalists, scientists, activists are (and “reputable” is the key word here,
since this reputation is recursively created by the mainstream media
themselves or by their sponsors).</p>
<p>I might be biased by my own experience here, but it seems to me that there
isn't a group of people more homogenous in their political (and generally,
world) views than that of IT workers. When, in 2018, I saw the leaked video of
Google's co-founder Sergei Brin and other executives' reaction at Trump's
presidential victory, what I found most surprising was not the contents of the
speech, as they were mostly mainstream opinions, but rather the fact that all
this could be said in a company meeting. Something like this, I though, could
never happen in an European company, as political matters are a conventional
tabu in the work environment. But the point is that Brin and others could say
those words only because <em>they knew</em> that the overwhelming majority of the
audience shared the same opinion. I don't think you could find the same
homogeneity of thought among shop assistants or philosophy professors.</p>
<p>Assuming that you have followed me this far into my rambling, and that you
recognize that there might be some truth in what I wrote, you might now be
wondering if there's a way to counterbalance our “idiotic” traits.
Unfortunately I don't have a full answer, as myself am only halfway there (but
maybe I'm too optimistic here? and does this road even ever end?), but there
are a few things that I think are absolutely worth trying:</p>
<ul>
<li>
<p>Talk with people. Better if face to face, or at least in a video call; just
1-on-1, avoid groups, or you'll get on the defensive and try to defend your
position for the sake of not losing the argument in front of an audience. But
it's not a fight. Your goal when talking should not be that of convincing or
getting convinced, but rather just to <em>understand</em> the other points of view.</p>
</li>
<li>
<p>Read both sides of the narrative. Try to see the other party's argument as
they themselves present it, and not how it is presented in the media you
usually read. Media often use this trick, to either invite “clown
representatives” of the other point of view just to ridicule it, or they give them
too little time, or extrapolate their answer out of context, just to make
them appear unsensible.</p>
</li>
<li>
<p>Always assume that other people are smart, and that no one is bad.</p>
</li>
<li>
<p>Whatever the argument, try to answer the key question: “Cui bono?” (who
profits?) to be at least aware of all the hidden interests behind this and
that. They don't necessarily invalidate a position, but they must be
considered.</p>
</li>
<li>
<p>Lose faith. The only faith you are allowed to keep is the faith in God (or
Gods), if you have it: but men, theories, institutions, authorities
(including religious ones!), these must always be assumed to be imperfect and
not blindly trusted. People serve their interests or can be manipulated. Try
always to start from a clean table and an empty mind, and see if they have
enough arguments to convince you. </p>
</li>
<li>
<p>Do never assume “They can not <em>all</em> be wrong” or “If this were wrong, at
least some media would report it”. It just doesn't work this way, this is
again a matter of having faith in the majority. Think of how many times in
(recent) history you were presented an unambiguous truth, which later came
out to be a scam (Iraq war being a famous one).</p>
</li>
<li>
<p>Defocus. You might be spending a lot of energy into something that's not
worth it. I mean, feel free to pursue whatever hobbies you like, as long as
they make you feel better. But if you think you have a <em>mission</em>, think twice
about it. Think about the world you'd like to live in, and whether/how this
mission contributes to it.<sup id="fnref:saudi"><a class="footnote-ref" href="http://mardy.it/blog/2022/11/the-idiotism-of-software-developers.html#fn:saudi">2</a></sup></p>
</li>
<li>
<p>Ask questions. Be curious. Be challenging. For any topic, there are questions
that have not been answered in mainstream media<sup id="fnref:refugees"><a class="footnote-ref" href="http://mardy.it/blog/2022/11/the-idiotism-of-software-developers.html#fn:refugees">1</a></sup>. Find the answer,
then find explanations, never stopping at the first satisfactory one, but
always get at least two competing answers. From here, ask more questions,
rinse and repeat. And at every step ask yourself this: why didn't I know
about this? Is someone trying to hide the truth from me?</p>
</li>
<li>
<p>Aim at improving. Whenever you read something or talk to people, keep a
humble attitude and try to be challenged. Your goal should be that every
reading and every dialog should make you wiser, even if what you initially
read and heard sounded like garbage. There are always reasons for all these
thoughts you disagree with.</p>
</li>
<li>
<p>Reach out to the people nearby. Try not just to be sympathetic to the needs of
some population living far away from you, which the media has singled out as
being those needing your compassion, and try instead (or in addition to that)
to be sympathetic and helpful to the people around you. To your neighbours,
to those you see in the public transport and, first and foremost, to your
relatives.</p>
</li>
</ul>
<p>Summing up, what I want you to realize is that we IT workers are easily
exploitable. All those thought manipulation techniques represent a problem to
everyone, but it's particularly with us that they tend to be especially
effective; as a matter of fact, I've found that awareness of how the power
controls us is higher among uneducated people, because they are more
distrustful of the media and just tend to consume less of it. We, on the other
hand, are not only well educated to respect the authority (see <a href="https://www.youtube.com/watch?v=wv6TyJ1AbRM">Noam Chomsky on
education</a>), but our logical,
detail-focused mind can be easily externally controlled by continuously
stimulating it to focus on specific things and not others.</p>
<p>How would Dostoevskiy call us?</p>
<div class="footnote">
<hr>
<ol>
<li id="fn:refugees">
<p>My favourite one is: which country hosts more refugees from Ukraine? <a class="footnote-backref" href="http://mardy.it/blog/2022/11/the-idiotism-of-software-developers.html#fnref:refugees" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
<li id="fn:saudi">
<p>I was recently surprised when I read people in a forum who were
discussing avoiding doing business with Saudi Arabia because of their human
rights record. Seriously? We are talking about a government who has indirectly
caused the death of more than 300 thousands people in Yemen, and your main
reason to criticize them is human rights? It's like asking the police to arrest
a killer because before the assassination he misgendered his victim! Yet the
elephant in the room continues to go unseen. <a class="footnote-backref" href="http://mardy.it/blog/2022/11/the-idiotism-of-software-developers.html#fnref:saudi" title="Jump back to footnote 2 in the text">↩</a></p>
</li>
</ol>
</div>Deride, a generator of mock objects for unit testinghttp://mardy.it/blog/2022/11/deride-a-generator-of-mock-objects-for-unit-testing.html2022-11-05T09:51:41+03:002022-11-05T09:51:41+03:00Alberto Mardegan<p>If you have been writing C++ classes for mocking out your C or C++
dependencies, you know how tedious it is. I generally write small classes with
just a handful of methods, so it's generally bearable, but when using
third-party code I'm usually not that lucky. If the dependency is a C library
this becomes especially tricky, both because they might be larger than what you
can handle, and both because the lack of an object-oriented design might not
offer you an easy solution to store the mock object data.</p>
<p>But fear no more, <a href="https://pypi.org/project/deride/">Deride</a> is here!</p>
<p>I won't spend too many words describing it, since you can read its description
from the link above, where you will also find some example code. More examples,
by the way, can be found in the <code>example/</code> folder in the <a href="https://gitlab.com/mardy/deride">code
repository</a>, where you can see how it can be
used to mock both pure C++ and <code>QObject</code>-based classes, and C libraries.</p>
<p>What is most important for me to say now, is that the project is in alpha
state, meaning that I've tried it on a handful of header files only; it's
highly likely that it will not work on many real-life scenarios, and if that
happens I warmly invite you to <a href="https://gitlab.com/mardy/deride/-/issues">inform me by filing a bug
report</a> providing the include file
that was not properly processed.</p>
<p>I leave you with a short example of a unit test, written using Deride. The
class under test is called <code>Stable</code>, and internally it uses objects of type
<code>Horse</code>, that we decided to mock. We used Deride to generate the mocked
implementation and a <code>MockHorse</code> class which can be used to control the mocked
objects. When building the test, we won't link against the original
<code>horse.cpp</code>, but we'll only use the original <code>horse.h</code>; the implementation will
be found in <code>mock_horse.cpp</code>, generated by Deride. And in the corresponding
<code>mock_horse.h</code> file we'll find the <code>MockHorse</code> class with all the
<code>on<method>Called()</code> hooks which we can use to install our callbacks (either to
reimplement the object behaviour, or to just be notified on when its methods
are called).</p>
<div class="code"><pre class="code literal-block"><span class="w"> </span><span class="cm">/* This MockHorse is the object created by Deride</span>
<span class="cm"> * |</span>
<span class="cm"> * |</span>
<span class="cm"> * \|/</span>
<span class="cm"> * V</span>
<span class="cm"> */</span>
<span class="w"> </span><span class="k">using</span><span class="w"> </span><span class="n">Mock</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Animals</span><span class="o">::</span><span class="n">MockHorse</span><span class="p">;</span>
<span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">list</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span><span class="w"> </span><span class="n">horseNames</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s">"Tom"</span><span class="p">,</span>
<span class="w"> </span><span class="s">"Dick"</span><span class="p">,</span>
<span class="w"> </span><span class="s">"Harry"</span><span class="p">,</span>
<span class="w"> </span><span class="p">};</span>
<span class="w"> </span><span class="cm">/* We could use a vector, but let's be explicit */</span>
<span class="w"> </span><span class="n">Mock</span><span class="w"> </span><span class="o">*</span><span class="n">mockTom</span><span class="p">;</span>
<span class="w"> </span><span class="n">Mock</span><span class="w"> </span><span class="o">*</span><span class="n">mockDick</span><span class="p">;</span>
<span class="w"> </span><span class="n">Mock</span><span class="w"> </span><span class="o">*</span><span class="n">mockHarry</span><span class="p">;</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">createdHorses</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="w"> </span><span class="c1">// onConstructorCalled() is created by Deride and called when the mocked</span>
<span class="w"> </span><span class="c1">// Horse object is created</span>
<span class="w"> </span><span class="n">Animals</span><span class="o">::</span><span class="n">MockHorse</span><span class="o">::</span><span class="n">onConstructorCalled</span><span class="p">([</span><span class="o">&</span><span class="p">](</span><span class="k">const</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="w"> </span><span class="o">&</span><span class="n">name</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="s">"Horse instantiated: "</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="n">name</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
<span class="w"> </span><span class="n">createdHorses</span><span class="o">++</span><span class="p">;</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">name</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="s">"Tom"</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">mockTom</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Mock</span><span class="o">::</span><span class="n">latestInstance</span><span class="p">();</span>
<span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">name</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="s">"Dick"</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">mockDick</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Mock</span><span class="o">::</span><span class="n">latestInstance</span><span class="p">();</span>
<span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">name</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="s">"Harry"</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">mockHarry</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Mock</span><span class="o">::</span><span class="n">latestInstance</span><span class="p">();</span>
<span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span><span class="w"> </span><span class="c1">// should not be reached</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">});</span>
<span class="w"> </span><span class="n">Stable</span><span class="w"> </span><span class="n">stable</span><span class="p">;</span>
<span class="w"> </span><span class="n">stable</span><span class="p">.</span><span class="n">createHorses</span><span class="p">(</span><span class="n">horseNames</span><span class="p">);</span>
<span class="w"> </span><span class="cm">/* It's at this point that the contructor callbacks we defined above will</span>
<span class="cm"> * have been called. Let's double-check that indeed that's the case.</span>
<span class="cm"> */</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">createdHorses</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">3</span><span class="p">);</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">stable</span><span class="p">.</span><span class="n">count</span><span class="p">()</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">3</span><span class="p">);</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">mockTom</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="k">nullptr</span><span class="p">);</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">mockDick</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="k">nullptr</span><span class="p">);</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">mockHarry</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="k">nullptr</span><span class="p">);</span>
<span class="w"> </span><span class="cm">/* Prepare for mocking the jump; these methods are generated by Deride and</span>
<span class="cm"> * allow setting the return value for the corresponding jumpHeight() method</span>
<span class="cm"> * from the original Horse class. */</span>
<span class="w"> </span><span class="n">mockTom</span><span class="o">-></span><span class="n">setJumpHeightResult</span><span class="p">(</span><span class="mf">1.5</span><span class="p">);</span>
<span class="w"> </span><span class="n">mockDick</span><span class="o">-></span><span class="n">setJumpHeightResult</span><span class="p">(</span><span class="mf">1.7</span><span class="p">);</span>
<span class="w"> </span><span class="n">mockHarry</span><span class="o">-></span><span class="n">setJumpHeightResult</span><span class="p">(</span><span class="mf">1.3</span><span class="p">);</span>
<span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="w"> </span><span class="n">highestJumper</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">stable</span><span class="p">.</span><span class="n">findHighestJumper</span><span class="p">();</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">highestJumper</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="s">"Dick"</span><span class="p">);</span>
</pre></div>
<p>In my closing words I'd like to thank the <a href="https://clang.llvm.org/">Clang
project</a>, which Deride is using to parse and interpret
the input files, and <a href="https://pypi.org/project/Jinja2/">Jinja2</a>, the templating
engine used to generate the mock code.</p><p>If you have been writing C++ classes for mocking out your C or C++
dependencies, you know how tedious it is. I generally write small classes with
just a handful of methods, so it's generally bearable, but when using
third-party code I'm usually not that lucky. If the dependency is a C library
this becomes especially tricky, both because they might be larger than what you
can handle, and both because the lack of an object-oriented design might not
offer you an easy solution to store the mock object data.</p>
<p>But fear no more, <a href="https://pypi.org/project/deride/">Deride</a> is here!</p>
<p>I won't spend too many words describing it, since you can read its description
from the link above, where you will also find some example code. More examples,
by the way, can be found in the <code>example/</code> folder in the <a href="https://gitlab.com/mardy/deride">code
repository</a>, where you can see how it can be
used to mock both pure C++ and <code>QObject</code>-based classes, and C libraries.</p>
<p>What is most important for me to say now, is that the project is in alpha
state, meaning that I've tried it on a handful of header files only; it's
highly likely that it will not work on many real-life scenarios, and if that
happens I warmly invite you to <a href="https://gitlab.com/mardy/deride/-/issues">inform me by filing a bug
report</a> providing the include file
that was not properly processed.</p>
<p>I leave you with a short example of a unit test, written using Deride. The
class under test is called <code>Stable</code>, and internally it uses objects of type
<code>Horse</code>, that we decided to mock. We used Deride to generate the mocked
implementation and a <code>MockHorse</code> class which can be used to control the mocked
objects. When building the test, we won't link against the original
<code>horse.cpp</code>, but we'll only use the original <code>horse.h</code>; the implementation will
be found in <code>mock_horse.cpp</code>, generated by Deride. And in the corresponding
<code>mock_horse.h</code> file we'll find the <code>MockHorse</code> class with all the
<code>on<method>Called()</code> hooks which we can use to install our callbacks (either to
reimplement the object behaviour, or to just be notified on when its methods
are called).</p>
<div class="code"><pre class="code literal-block"><span class="w"> </span><span class="cm">/* This MockHorse is the object created by Deride</span>
<span class="cm"> * |</span>
<span class="cm"> * |</span>
<span class="cm"> * \|/</span>
<span class="cm"> * V</span>
<span class="cm"> */</span>
<span class="w"> </span><span class="k">using</span><span class="w"> </span><span class="n">Mock</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Animals</span><span class="o">::</span><span class="n">MockHorse</span><span class="p">;</span>
<span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">list</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span><span class="w"> </span><span class="n">horseNames</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="s">"Tom"</span><span class="p">,</span>
<span class="w"> </span><span class="s">"Dick"</span><span class="p">,</span>
<span class="w"> </span><span class="s">"Harry"</span><span class="p">,</span>
<span class="w"> </span><span class="p">};</span>
<span class="w"> </span><span class="cm">/* We could use a vector, but let's be explicit */</span>
<span class="w"> </span><span class="n">Mock</span><span class="w"> </span><span class="o">*</span><span class="n">mockTom</span><span class="p">;</span>
<span class="w"> </span><span class="n">Mock</span><span class="w"> </span><span class="o">*</span><span class="n">mockDick</span><span class="p">;</span>
<span class="w"> </span><span class="n">Mock</span><span class="w"> </span><span class="o">*</span><span class="n">mockHarry</span><span class="p">;</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">createdHorses</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="w"> </span><span class="c1">// onConstructorCalled() is created by Deride and called when the mocked</span>
<span class="w"> </span><span class="c1">// Horse object is created</span>
<span class="w"> </span><span class="n">Animals</span><span class="o">::</span><span class="n">MockHorse</span><span class="o">::</span><span class="n">onConstructorCalled</span><span class="p">([</span><span class="o">&</span><span class="p">](</span><span class="k">const</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="w"> </span><span class="o">&</span><span class="n">name</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">cout</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="s">"Horse instantiated: "</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="n">name</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
<span class="w"> </span><span class="n">createdHorses</span><span class="o">++</span><span class="p">;</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">name</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="s">"Tom"</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">mockTom</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Mock</span><span class="o">::</span><span class="n">latestInstance</span><span class="p">();</span>
<span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">name</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="s">"Dick"</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">mockDick</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Mock</span><span class="o">::</span><span class="n">latestInstance</span><span class="p">();</span>
<span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">name</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="s">"Harry"</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">mockHarry</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Mock</span><span class="o">::</span><span class="n">latestInstance</span><span class="p">();</span>
<span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span><span class="w"> </span><span class="c1">// should not be reached</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">});</span>
<span class="w"> </span><span class="n">Stable</span><span class="w"> </span><span class="n">stable</span><span class="p">;</span>
<span class="w"> </span><span class="n">stable</span><span class="p">.</span><span class="n">createHorses</span><span class="p">(</span><span class="n">horseNames</span><span class="p">);</span>
<span class="w"> </span><span class="cm">/* It's at this point that the contructor callbacks we defined above will</span>
<span class="cm"> * have been called. Let's double-check that indeed that's the case.</span>
<span class="cm"> */</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">createdHorses</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">3</span><span class="p">);</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">stable</span><span class="p">.</span><span class="n">count</span><span class="p">()</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">3</span><span class="p">);</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">mockTom</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="k">nullptr</span><span class="p">);</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">mockDick</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="k">nullptr</span><span class="p">);</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">mockHarry</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="k">nullptr</span><span class="p">);</span>
<span class="w"> </span><span class="cm">/* Prepare for mocking the jump; these methods are generated by Deride and</span>
<span class="cm"> * allow setting the return value for the corresponding jumpHeight() method</span>
<span class="cm"> * from the original Horse class. */</span>
<span class="w"> </span><span class="n">mockTom</span><span class="o">-></span><span class="n">setJumpHeightResult</span><span class="p">(</span><span class="mf">1.5</span><span class="p">);</span>
<span class="w"> </span><span class="n">mockDick</span><span class="o">-></span><span class="n">setJumpHeightResult</span><span class="p">(</span><span class="mf">1.7</span><span class="p">);</span>
<span class="w"> </span><span class="n">mockHarry</span><span class="o">-></span><span class="n">setJumpHeightResult</span><span class="p">(</span><span class="mf">1.3</span><span class="p">);</span>
<span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="w"> </span><span class="n">highestJumper</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">stable</span><span class="p">.</span><span class="n">findHighestJumper</span><span class="p">();</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">highestJumper</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="s">"Dick"</span><span class="p">);</span>
</pre></div>
<p>In my closing words I'd like to thank the <a href="https://clang.llvm.org/">Clang
project</a>, which Deride is using to parse and interpret
the input files, and <a href="https://pypi.org/project/Jinja2/">Jinja2</a>, the templating
engine used to generate the mock code.</p>Scrum, agility and the human factorhttp://mardy.it/blog/2022/10/scrum-agility-and-the-human-factor.html2022-10-29T10:17:14+03:002022-10-29T10:17:14+03:00Alberto Mardegan<p>I've been working in Scrum teams for 15 years now, give or take. Different
companies, different approaches, from loosely following the agile principles to
a stricter implementation of the Scrum methodology. The only invariant being
that in practice Scrum is never followed by the book, but every company and
team makes its own adaptations, which makes it hard for everyone to voice
statements and critiques that could be considered universally true. That's why I
will refrain from taking this road, and instead I'll try to point out a few
aspects and behaviours that I've personally noticed during my career, good and
bad ones (but of course, since I'm old and bitter, more bad than good).</p>
<p>Scrum's focus on communication is, in my opinion, where most of its value lies
on: it's indeed important that other team members know what you are doing, and
that management has an idea of the progress being made. Hence daily standups
and the scrum board, and demos and retrospective at the end of each sprint.</p>
<p>It makes sense, on paper. And in practice as well, if you find yourself in a
team which is not really a team but a group of individuals with communication
problems. But that should not be the rule, and that's my main criticism of
Scrum: it's <strong>a very good system for managing poorly skilled developers</strong>.</p>
<p>In a highly skilled team, all of the benefits that Scrum is supposed to bring
are already a given: back in 2006-2008, in Nokia, most of our communication was
occurring in IRC and mailing lists. The fact that some of our co-workers were
<a href="https://www.collabora.com/">remote</a> indeed acted as a push for this choice.
The same occurred in my early years at Canonical, where (at least in my team)
we had a video conference only once per week: if the communication is already
happening in an open (to the team members) place, there's no need for further
synchronisation points. And if the managers and product owners are also
monitoring these discussions, they know perfectly well how the situation is and
can report it further up.</p>
<h4>Demos</h4>
<p>What about demos? Having always worked on middleware and system programming,
where there's very little to <em>show</em>, I've never been fond of demos. Our team
demos have always been boring and of little significance for most of their
spectators. And while it can take a lot of time to prepare a demo, if we
already communicated what he have done in this sprint, what's the point of
spending more time for the demo? Is it a lack of trust? Or is it a way to make
the team proud of its accomplishments?
In any case, the same could be achieved in a more efficient way: have a
specialized person (maybe from the QA team) prepare and run all the demos. In
this way you'd not only achieve those goals, but you'd also make sure that
there's no cheating (ehmm…) and that bugs are noticed right away.</p>
<h4>Story estimations</h4>
<p>Luckily so far I've been involved in only two projects where it was required to
estimate the complexity of the backlog stories. But it was enough to convince
me that there's something fundamentally wrong with it. On one hand, we are
being told that we should estimate <em>complexity</em>, and not <em>time</em>, but then the
story points are being used to decide how many stories can fit in a
sprint. It can make sense to estimate the complexity, indeed, because it's an
intrinsic property of the story, which typically does not depend on the actual
person who sits down to work on it; but then what can we use this value for?
And how much time are we willing to spend in order to figure out this nearly
useless magic number? We keep the whole team sitting down together while
throwing estimates, and then question them; and indeed, in order to let other
people express a reasonable estimate we should also explain the story with a
certain level of detail. And while this sounds like a worthwhile thing to do
(explaining the story, I mean), it's probably better to do that in written
form, and ask the team members to read all the stories <em>before</em> the grooming
session. This is what we have been doing at some point, except that most of the
time there would be at least one colleague who hadn't done his homework, so you
still had to either retell the story during the meeting, or have the complexity
discussion anyway since not all estimates were in agreement.</p>
<p>Having a clear description on all the stories (where a “clear description”
could even be just a link to a bug report, if that contains enough information)
does not cost a lot of time, as long as the description is written by a single
developer and not during a meeting with the whole team. It brings the benefit
that while writing the story one might realize that there's more to it and this
can lead to the creation of additional stories <em>before</em> one actually starts the
sprint.</p>
<p>If, for whatever reason, a point score is absolutely required (just because
upper management wants so), then this should probably happen as the description
is being written, and can be set by the author alone; no need to gather the
whole team for this (since, in any case, the score is inevitably linked to how
the story's creator presents it).</p>
<h4>Sprint planning</h4>
<p>It is my firm believe that a team member with no stories assigned should always
be allowed to drag the topmost story from the backlog (who should be kept in
the desired order by the product owner) into the sprint, without needing any
kind of approval from above.</p>
<p>Unfortunately, I've been working on teams where this was actively discouraged,
if not prohibited. The rationale being that all stories that we bring into the
sprint are a commitment, and that once the <em>TODO</em> column is empty, everybody who
is free of other work should help their colleagues to complete their stories
which are still in progress. This sounds good in theory, but in practice it
makes little sense, unless the stories still in progress can be reasonably
split into smaller parts (and most of the times they can't).</p>
<p>So, a lot of effort is made in order to plan a sprint so that all of its
stories can be completed, and at the end of the sprint one can look at the
burn-down chart and feel proud of that diagonal line having gotten so close to
the horizontal axis. Except that everybody knows that we are just fooling
ourselves, because that beautiful graph is only the result of us undercommitting
on the sprint planning and then avoiding to bring in more stories into the
sprint once we had the resources to do so.</p>
<h4>Every developer is worth 1</h4>
<p>It seems to me that Scrum works under the assumption that all members of a team
are interchangeable, and that it does not matter which developer takes up which
story. It has been like this at least in one of the projects I worked in: as
soon as you'd finish working on your story, it was mandatory to pick the
topmost story from the <em>TODO</em> column, whatever it might be. Not the second or
the third one: you were allowed to pick the first one only. The reason for this
is that we had some stories that no one wanted to work on, and they'd risk
getting delayed forever. But this “solution” caused another issue, because if
the topmost item in the <em>TODO</em> column was an uninspiring story, this made so
that developers would be slower and hesitant in finishing their current
stories; no one would openly talk about that, but it was something you could
easily sense, as people started to find issues in their code, adding more unit
tests than usual, or “inadvertently” picking up the <em>second</em> topmost story from
the <em>TODO</em> column.
So, a problem that could have been easily solved by authority (just let the PO
or the lead developer decide who should do what) would become another source of
inefficiency.</p>
<p>A slightly related issue is the fact that if a team is very inhomogeneous, and
we estimate the stories just by their complexity, we can't really predict
whether our sprint will be a successful one, because it all depends on which
developer works on which story. Believe it or not, I happened to complete
in a handful of hours a story that a teammate had been working on for almost
one month (I assume he was also slacking off, but the point remains): at the
standups he was always reporting “good progress”, until I took the chance of
him having a day off and I stole the story from him. One might argue that even if
a complexity estimation gives no forecast on when the story will be completed,
it can still be used in cases like this, to detect the underperformers. This
is totally true, but that's the subject of <a href="http://mardy.it/blog/2022/10/performance-review.html">another blog
post</a>.</p>
<h4>Rearranging developers in homogeneous teams</h4>
<p>Besides, it should not come as a surprise that developers can have very
different skills, up to a factor of hundreds, if we take the extremes, and this
can be due to very different reasons: a low performance could be due to one
being a junior developer, to personality issues, or just to a congenic lack of
an analytic mindset.</p>
<p>If on one side it makes sense to mix junior and experienced developers in the
same team in order to boost the productivity and skills of the junior
developers, the same does not hold true for good and bad developers: if one
hasn't acquired the needed coding skills after a couple of years of work
experience, it's unlikely that continuing to have this developer work side by
side with more experienced ones will bring much benefit to him. On the opposite
side, it can stress out the more productive developer and demotivate him. Now
that a long time has passed, I can say that this is exactly what happened to me
in a couple of occasions during my career (and the fact that these colleagues
continuously argued and did not recognize their shortcomings did not help).</p>
<p>You will never get a perfectly homogenous team, since people always have
different experience and skills; anyways, a little of gradation is healthy,
because it stimulates all team members to compete in improving, by seeing each
other as a model to surpass. But this only works if the target is felt as
reachable (otherwise the lowest skilled developer won't have enough motivation)
and worth reaching (otherwise the highest skilled developer will feel he has
nothing to learn from the others).</p>
<p>That's why, in my opinion, it's worth rearranging teams along skill levels: the
teams with lower skill levels can benefit from being Scrum managed, because
Scrum sets up a frame inside which a low-skilled developer can still be
productive (albeit at a slower pace) thanks to the continuous monitoring and
feedback. Highly skilled teams — which, incidentally, does not only mean good
coders, but also good teammates with prioritization and communication skills,
and understanding the project goals and nearly capable of managing themselves —
could do very well even without Scrum, and just need a project owner who sets
the goals and defines the high-level stories (generally called “epics”), which
they can then break into smaller tasks by themselves. Adding more Scrum to
such teams might not lead to any improvement.</p>
<h4>What about managers?</h4>
<p>I tend to think on a similar vein when it comes to managers (be it project
manager or product owner): my impression is that Scrum is most beneficial when
the team has a poor manager, because it sets some rules that make the figure of
the manager less relevant and reduce it to a role that can be easily performed
by almost anyone. Here I might be totally wrong, of course, since I've never
worked as a manager and there are aspects of their job that are less visible
and that I might be overlooking; but again, I think that a good manager makes
Scrum redundant. Being crystal clear about the team goals, setting up a work
environment that stimulates every team member to give his best, being able to
notice early when things are not going as planned or when someone is
underperforming or not feeling at ease, making sure that the current
development stage is well understood by the rest of the project, etc.: all
these things are also Scrum's goals, so if they are already happening, the
company should cherish this manager as a role model and question whether
Scrum would be really beneficial here.</p>
<h4>Conclusion</h4>
<p>In other words, summing up, one company/department should consider introducing
Scrum once a problem has been detected; “as long as the boat goes, let it go”,
as a <a href="https://www.youtube.com/watch?v=pVGGCf_i1y4">popular Italian song</a> says.</p><p>I've been working in Scrum teams for 15 years now, give or take. Different
companies, different approaches, from loosely following the agile principles to
a stricter implementation of the Scrum methodology. The only invariant being
that in practice Scrum is never followed by the book, but every company and
team makes its own adaptations, which makes it hard for everyone to voice
statements and critiques that could be considered universally true. That's why I
will refrain from taking this road, and instead I'll try to point out a few
aspects and behaviours that I've personally noticed during my career, good and
bad ones (but of course, since I'm old and bitter, more bad than good).</p>
<p>Scrum's focus on communication is, in my opinion, where most of its value lies
on: it's indeed important that other team members know what you are doing, and
that management has an idea of the progress being made. Hence daily standups
and the scrum board, and demos and retrospective at the end of each sprint.</p>
<p>It makes sense, on paper. And in practice as well, if you find yourself in a
team which is not really a team but a group of individuals with communication
problems. But that should not be the rule, and that's my main criticism of
Scrum: it's <strong>a very good system for managing poorly skilled developers</strong>.</p>
<p>In a highly skilled team, all of the benefits that Scrum is supposed to bring
are already a given: back in 2006-2008, in Nokia, most of our communication was
occurring in IRC and mailing lists. The fact that some of our co-workers were
<a href="https://www.collabora.com/">remote</a> indeed acted as a push for this choice.
The same occurred in my early years at Canonical, where (at least in my team)
we had a video conference only once per week: if the communication is already
happening in an open (to the team members) place, there's no need for further
synchronisation points. And if the managers and product owners are also
monitoring these discussions, they know perfectly well how the situation is and
can report it further up.</p>
<h4>Demos</h4>
<p>What about demos? Having always worked on middleware and system programming,
where there's very little to <em>show</em>, I've never been fond of demos. Our team
demos have always been boring and of little significance for most of their
spectators. And while it can take a lot of time to prepare a demo, if we
already communicated what he have done in this sprint, what's the point of
spending more time for the demo? Is it a lack of trust? Or is it a way to make
the team proud of its accomplishments?
In any case, the same could be achieved in a more efficient way: have a
specialized person (maybe from the QA team) prepare and run all the demos. In
this way you'd not only achieve those goals, but you'd also make sure that
there's no cheating (ehmm…) and that bugs are noticed right away.</p>
<h4>Story estimations</h4>
<p>Luckily so far I've been involved in only two projects where it was required to
estimate the complexity of the backlog stories. But it was enough to convince
me that there's something fundamentally wrong with it. On one hand, we are
being told that we should estimate <em>complexity</em>, and not <em>time</em>, but then the
story points are being used to decide how many stories can fit in a
sprint. It can make sense to estimate the complexity, indeed, because it's an
intrinsic property of the story, which typically does not depend on the actual
person who sits down to work on it; but then what can we use this value for?
And how much time are we willing to spend in order to figure out this nearly
useless magic number? We keep the whole team sitting down together while
throwing estimates, and then question them; and indeed, in order to let other
people express a reasonable estimate we should also explain the story with a
certain level of detail. And while this sounds like a worthwhile thing to do
(explaining the story, I mean), it's probably better to do that in written
form, and ask the team members to read all the stories <em>before</em> the grooming
session. This is what we have been doing at some point, except that most of the
time there would be at least one colleague who hadn't done his homework, so you
still had to either retell the story during the meeting, or have the complexity
discussion anyway since not all estimates were in agreement.</p>
<p>Having a clear description on all the stories (where a “clear description”
could even be just a link to a bug report, if that contains enough information)
does not cost a lot of time, as long as the description is written by a single
developer and not during a meeting with the whole team. It brings the benefit
that while writing the story one might realize that there's more to it and this
can lead to the creation of additional stories <em>before</em> one actually starts the
sprint.</p>
<p>If, for whatever reason, a point score is absolutely required (just because
upper management wants so), then this should probably happen as the description
is being written, and can be set by the author alone; no need to gather the
whole team for this (since, in any case, the score is inevitably linked to how
the story's creator presents it).</p>
<h4>Sprint planning</h4>
<p>It is my firm believe that a team member with no stories assigned should always
be allowed to drag the topmost story from the backlog (who should be kept in
the desired order by the product owner) into the sprint, without needing any
kind of approval from above.</p>
<p>Unfortunately, I've been working on teams where this was actively discouraged,
if not prohibited. The rationale being that all stories that we bring into the
sprint are a commitment, and that once the <em>TODO</em> column is empty, everybody who
is free of other work should help their colleagues to complete their stories
which are still in progress. This sounds good in theory, but in practice it
makes little sense, unless the stories still in progress can be reasonably
split into smaller parts (and most of the times they can't).</p>
<p>So, a lot of effort is made in order to plan a sprint so that all of its
stories can be completed, and at the end of the sprint one can look at the
burn-down chart and feel proud of that diagonal line having gotten so close to
the horizontal axis. Except that everybody knows that we are just fooling
ourselves, because that beautiful graph is only the result of us undercommitting
on the sprint planning and then avoiding to bring in more stories into the
sprint once we had the resources to do so.</p>
<h4>Every developer is worth 1</h4>
<p>It seems to me that Scrum works under the assumption that all members of a team
are interchangeable, and that it does not matter which developer takes up which
story. It has been like this at least in one of the projects I worked in: as
soon as you'd finish working on your story, it was mandatory to pick the
topmost story from the <em>TODO</em> column, whatever it might be. Not the second or
the third one: you were allowed to pick the first one only. The reason for this
is that we had some stories that no one wanted to work on, and they'd risk
getting delayed forever. But this “solution” caused another issue, because if
the topmost item in the <em>TODO</em> column was an uninspiring story, this made so
that developers would be slower and hesitant in finishing their current
stories; no one would openly talk about that, but it was something you could
easily sense, as people started to find issues in their code, adding more unit
tests than usual, or “inadvertently” picking up the <em>second</em> topmost story from
the <em>TODO</em> column.
So, a problem that could have been easily solved by authority (just let the PO
or the lead developer decide who should do what) would become another source of
inefficiency.</p>
<p>A slightly related issue is the fact that if a team is very inhomogeneous, and
we estimate the stories just by their complexity, we can't really predict
whether our sprint will be a successful one, because it all depends on which
developer works on which story. Believe it or not, I happened to complete
in a handful of hours a story that a teammate had been working on for almost
one month (I assume he was also slacking off, but the point remains): at the
standups he was always reporting “good progress”, until I took the chance of
him having a day off and I stole the story from him. One might argue that even if
a complexity estimation gives no forecast on when the story will be completed,
it can still be used in cases like this, to detect the underperformers. This
is totally true, but that's the subject of <a href="http://mardy.it/blog/2022/10/performance-review.html">another blog
post</a>.</p>
<h4>Rearranging developers in homogeneous teams</h4>
<p>Besides, it should not come as a surprise that developers can have very
different skills, up to a factor of hundreds, if we take the extremes, and this
can be due to very different reasons: a low performance could be due to one
being a junior developer, to personality issues, or just to a congenic lack of
an analytic mindset.</p>
<p>If on one side it makes sense to mix junior and experienced developers in the
same team in order to boost the productivity and skills of the junior
developers, the same does not hold true for good and bad developers: if one
hasn't acquired the needed coding skills after a couple of years of work
experience, it's unlikely that continuing to have this developer work side by
side with more experienced ones will bring much benefit to him. On the opposite
side, it can stress out the more productive developer and demotivate him. Now
that a long time has passed, I can say that this is exactly what happened to me
in a couple of occasions during my career (and the fact that these colleagues
continuously argued and did not recognize their shortcomings did not help).</p>
<p>You will never get a perfectly homogenous team, since people always have
different experience and skills; anyways, a little of gradation is healthy,
because it stimulates all team members to compete in improving, by seeing each
other as a model to surpass. But this only works if the target is felt as
reachable (otherwise the lowest skilled developer won't have enough motivation)
and worth reaching (otherwise the highest skilled developer will feel he has
nothing to learn from the others).</p>
<p>That's why, in my opinion, it's worth rearranging teams along skill levels: the
teams with lower skill levels can benefit from being Scrum managed, because
Scrum sets up a frame inside which a low-skilled developer can still be
productive (albeit at a slower pace) thanks to the continuous monitoring and
feedback. Highly skilled teams — which, incidentally, does not only mean good
coders, but also good teammates with prioritization and communication skills,
and understanding the project goals and nearly capable of managing themselves —
could do very well even without Scrum, and just need a project owner who sets
the goals and defines the high-level stories (generally called “epics”), which
they can then break into smaller tasks by themselves. Adding more Scrum to
such teams might not lead to any improvement.</p>
<h4>What about managers?</h4>
<p>I tend to think on a similar vein when it comes to managers (be it project
manager or product owner): my impression is that Scrum is most beneficial when
the team has a poor manager, because it sets some rules that make the figure of
the manager less relevant and reduce it to a role that can be easily performed
by almost anyone. Here I might be totally wrong, of course, since I've never
worked as a manager and there are aspects of their job that are less visible
and that I might be overlooking; but again, I think that a good manager makes
Scrum redundant. Being crystal clear about the team goals, setting up a work
environment that stimulates every team member to give his best, being able to
notice early when things are not going as planned or when someone is
underperforming or not feeling at ease, making sure that the current
development stage is well understood by the rest of the project, etc.: all
these things are also Scrum's goals, so if they are already happening, the
company should cherish this manager as a role model and question whether
Scrum would be really beneficial here.</p>
<h4>Conclusion</h4>
<p>In other words, summing up, one company/department should consider introducing
Scrum once a problem has been detected; “as long as the boat goes, let it go”,
as a <a href="https://www.youtube.com/watch?v=pVGGCf_i1y4">popular Italian song</a> says.</p>Performance reviewshttp://mardy.it/blog/2022/10/performance-review.html2022-10-27T08:47:14+03:002022-10-27T08:47:14+03:00Alberto Mardegan<p>It happened a few times during my career, that I found myself in a team with a
colleague whose productivity was close to zero. In most of these cases it was
simply a matter of people who hadn't the skills and happened to choose the wrong
career path, and in one case it was actually an excellent developer, but just
slacking off. Regardless of the case, in many of these occasions it looked like
the team manager hadn't noticed the poor performance of the individual in
question, whereas this was rather obvious to the rest of the team. I'm not
sure why the managers didn't notice the black sheep, but the point is that none
of the other developers did raise the issue either: why would I report a fellow
colleague, who might risk losing his job because of my evil tongue?</p>
<p>So, Scrum to the rescue? Not quite. As a matter of fact, while it is true that an
underperformer could be easily spotted by seeing how often he fails to complete
his stories in the timeframe suggested by the story points, this information is
generally accessible to the product owner, whereas the line manager might not
attend the Scrum meetings at all (as was the case in a previous project of
mine, where the line manager was completely detached from the project); and
even if the line manager had this information, it's not a given that he'd make
use of it — as a matter of fact, I cannot say with certainty that the line
managers did not notice those underperforming colleagues of mine; maybe they
noticed, but failed to intervene for some reason?</p>
<p>It sounds like this might be
<a href="https://en.wikipedia.org/wiki/360-degree_feedback">360</a> material.
Unfortunately, in my experience the 360 reviews are a waste of time for the
most part, but that might be because they had been badly implemented in the
companies where I worked in. In these reviews I get to rate my colleagues
using a set of predefined statements which generally look positive, such as
“Often delivers more than expected” or “Always meets the expectations”, but
each of which imply a very different rating. I can see that the reason why the
system uses this kind of sentences is because no one wants to explicitly assign
a bad rating to a colleague, so all the possible answers have a “positive”
feeling. The problem with this is that the shades of meaning in these
sentences is not obvious at all, so one risks ending up picking sentences
almost at random.</p>
<p>A system that would allow a company to get a honest feedback, without requiring
employees to say bad things about their colleagues, could be based on the idea
that your colleagues have usually a good sense of how well you are doing. To
me, it would make more sense if the performance review consisted of a question
like this:</p>
<blockquote>
<p>Please make a list of those colleagues that in your opinion are more valuable
to your team or to the company in general.</p>
</blockquote>
<p>Then the company should sum up these lists and have a look at who is <em>not</em>
there, or whose name appears way too few times in relation to the number of
people who have worked with him or her. Then this information would not only be
available to the direct line manager, but also to upper line managers, who
might be willing to judge the situation with more objectivity and be able to
decide to move the person to another team.</p>
<p>The presentation of this question could indeed be very different from what I've
suggested here, for example it could be something like “Make a list of
colleagues you'd be most happy to work (or continue working) with”, or it could
include some personal feedback: in that way, if the only good thing that people
have to say about a developer is “He's a very nice guy”, well, you could
imagine that we are not dealing with a strong developer after all.</p>
<p>On the opposite side of the spectrum, the people whose names appear more often
in the <em>star colleagues</em> lists are probably the employees that the company
should cherish and try hard not to lose. Salary increases, bonuses and all
other gratifications that can help in retaining them should be primarily
connected to the colleagues' direct feedback, rather than to semi-obscure
metrics which might not capture their real value.</p><p>It happened a few times during my career, that I found myself in a team with a
colleague whose productivity was close to zero. In most of these cases it was
simply a matter of people who hadn't the skills and happened to choose the wrong
career path, and in one case it was actually an excellent developer, but just
slacking off. Regardless of the case, in many of these occasions it looked like
the team manager hadn't noticed the poor performance of the individual in
question, whereas this was rather obvious to the rest of the team. I'm not
sure why the managers didn't notice the black sheep, but the point is that none
of the other developers did raise the issue either: why would I report a fellow
colleague, who might risk losing his job because of my evil tongue?</p>
<p>So, Scrum to the rescue? Not quite. As a matter of fact, while it is true that an
underperformer could be easily spotted by seeing how often he fails to complete
his stories in the timeframe suggested by the story points, this information is
generally accessible to the product owner, whereas the line manager might not
attend the Scrum meetings at all (as was the case in a previous project of
mine, where the line manager was completely detached from the project); and
even if the line manager had this information, it's not a given that he'd make
use of it — as a matter of fact, I cannot say with certainty that the line
managers did not notice those underperforming colleagues of mine; maybe they
noticed, but failed to intervene for some reason?</p>
<p>It sounds like this might be
<a href="https://en.wikipedia.org/wiki/360-degree_feedback">360</a> material.
Unfortunately, in my experience the 360 reviews are a waste of time for the
most part, but that might be because they had been badly implemented in the
companies where I worked in. In these reviews I get to rate my colleagues
using a set of predefined statements which generally look positive, such as
“Often delivers more than expected” or “Always meets the expectations”, but
each of which imply a very different rating. I can see that the reason why the
system uses this kind of sentences is because no one wants to explicitly assign
a bad rating to a colleague, so all the possible answers have a “positive”
feeling. The problem with this is that the shades of meaning in these
sentences is not obvious at all, so one risks ending up picking sentences
almost at random.</p>
<p>A system that would allow a company to get a honest feedback, without requiring
employees to say bad things about their colleagues, could be based on the idea
that your colleagues have usually a good sense of how well you are doing. To
me, it would make more sense if the performance review consisted of a question
like this:</p>
<blockquote>
<p>Please make a list of those colleagues that in your opinion are more valuable
to your team or to the company in general.</p>
</blockquote>
<p>Then the company should sum up these lists and have a look at who is <em>not</em>
there, or whose name appears way too few times in relation to the number of
people who have worked with him or her. Then this information would not only be
available to the direct line manager, but also to upper line managers, who
might be willing to judge the situation with more objectivity and be able to
decide to move the person to another team.</p>
<p>The presentation of this question could indeed be very different from what I've
suggested here, for example it could be something like “Make a list of
colleagues you'd be most happy to work (or continue working) with”, or it could
include some personal feedback: in that way, if the only good thing that people
have to say about a developer is “He's a very nice guy”, well, you could
imagine that we are not dealing with a strong developer after all.</p>
<p>On the opposite side of the spectrum, the people whose names appear more often
in the <em>star colleagues</em> lists are probably the employees that the company
should cherish and try hard not to lose. Salary increases, bonuses and all
other gratifications that can help in retaining them should be primarily
connected to the colleagues' direct feedback, rather than to semi-obscure
metrics which might not capture their real value.</p>MiTubo 1.4 adds feed foldershttp://mardy.it/blog/2022/10/mitubo-14-adds-feed-folders.html2022-10-10T17:40:09+03:002022-10-10T17:40:09+03:00Alberto Mardegan<p>Exactly one month has passed since the previous release, just the right time
needed to complete the feafure I've been working on since several weeks and to
fix a few bugfixes introduced with the previous release. So it's time a new
release of <a href="https://gitlab.com/mardy/mitubo">MiTubo</a>:</p>
<p></p><center>
<video id="video" controls preload="metadata" width="100%">
<source src="http://mardy.it/archivos/videos/mitubo-1.4.webm" type="video/webm">
</source></video>
<p></p></center>
<p>I realized that I'm not that good at making release videos, but the point of
the video above is to show that you can organize your feeds into folders. When
clicking on a folder, a page opens with the folder's contents; but you can also
directly click on a feed, as long as its preview is visible in the folder's
delegate, and then the feeds open directly. This means that if you organize the
feeds inside your folders so that the favourite ones are at the top, they'll
also be visible in the folder preview and you'll be able to jump to them in
just one click.</p>
<p>Maybe I'm not that good with textual explanations either, so why don't you
check it out for yourself? ☺ Get it at
<a href="http://www.mardy.it/mitubo">mardy.it/mitubo</a> (builds for Linux, Ubuntu Touch,
Windows and macOS are available)!</p><p>Exactly one month has passed since the previous release, just the right time
needed to complete the feafure I've been working on since several weeks and to
fix a few bugfixes introduced with the previous release. So it's time a new
release of <a href="https://gitlab.com/mardy/mitubo">MiTubo</a>:</p>
<p></p><center>
<video id="video" controls preload="metadata" width="100%">
<source src="http://mardy.it/archivos/videos/mitubo-1.4.webm" type="video/webm">
</source></video>
<p></p></center>
<p>I realized that I'm not that good at making release videos, but the point of
the video above is to show that you can organize your feeds into folders. When
clicking on a folder, a page opens with the folder's contents; but you can also
directly click on a feed, as long as its preview is visible in the folder's
delegate, and then the feeds open directly. This means that if you organize the
feeds inside your folders so that the favourite ones are at the top, they'll
also be visible in the folder preview and you'll be able to jump to them in
just one click.</p>
<p>Maybe I'm not that good with textual explanations either, so why don't you
check it out for yourself? ☺ Get it at
<a href="http://www.mardy.it/mitubo">mardy.it/mitubo</a> (builds for Linux, Ubuntu Touch,
Windows and macOS are available)!</p>MiTubo 1.3: sorting of QML ListView via Drag&Drophttp://mardy.it/blog/2022/09/mitubo-13-sorting-of-qml-listview-via-dragdrop.html2022-09-10T13:38:51+03:002022-09-10T13:38:51+03:00Alberto Mardegan<p>One feature that I've been asked to add to
<a href="https://gitlab.com/mardy/mitubo">MiTubo</a>, and that indeed becomes more and
more important as the number of subscriptions increases, is the ability to
group subscriptions into folders. I've spent a good amount of time implementing
the needed support in the C++ backend, which is now able to handle nested
folders too, but given that building the UI parts was not a quick task and
seeing how much time has passed since the last release, I thought of releasing
a partial implementation of the whole feature, consisting only of the ability
to manually sort the subscriptions via drag&drop (that, is no folder support).
It turns out this is already not a trivial work!</p>
<p>I found a <a href="https://agateau.com/2016/reordering-a-listview-via-dragndrop-3/">nice tutorial on ListView DnD
sorting</a> by
the great Aurélien Gâteau which I found very inspiring, and while I didn't
actually reuse the same code (mostly because I was already halfway through with
my implementation, which I started before finding his tutorial), it was helpful
to have it as a reference. I added a few animations to make it look more
pleasant, and I'm rather satisfied with the result:</p>
<p></p><center>
<video id="video" controls preload="metadata" width="100%">
<source src="http://mardy.it/archivos/videos/mitubo-1.3.webm" type="video/webm">
</source></video>
<p></p></center>
<p>I'm not showing you the code yet (though, indeed, you can find it in the
<code>DraggableListView</code> and <code>DraggableDelegate</code> items <a href="https://gitlab.com/mardy/mitubo/-/tree/master/src/desktop/qml">in the source
repository</a>)
because it's not yet in a shape where it's generally reusable in other
projects, but if I happen to need the same feature elsewhere I'll eventually
try to turn it into a couple fully reusable components.</p>
<p>Anyway, here's what's new in this latest MiTubo release:</p>
<ul>
<li>Subscriptions can be sorted by means of Drag&drop</li>
<li>For systems with python 3.5 or older (such as Ubuntu Touch), use the daily
builds of <a href="https://youtube-dl.org/">youtube-dl</a> instead of the official
releases</li>
<li>Implement <strong>PeerTube search</strong> (this should reserve a post of its own!)</li>
</ul>
<p>You can get it <a href="http://www.mardy.it/mitubo">at the usual place</a>. This time
there are only Linux and Windows builds as I'm a bit lazy to make a macOS
version, but should you need it, don't hesitate to ask!</p><p>One feature that I've been asked to add to
<a href="https://gitlab.com/mardy/mitubo">MiTubo</a>, and that indeed becomes more and
more important as the number of subscriptions increases, is the ability to
group subscriptions into folders. I've spent a good amount of time implementing
the needed support in the C++ backend, which is now able to handle nested
folders too, but given that building the UI parts was not a quick task and
seeing how much time has passed since the last release, I thought of releasing
a partial implementation of the whole feature, consisting only of the ability
to manually sort the subscriptions via drag&drop (that, is no folder support).
It turns out this is already not a trivial work!</p>
<p>I found a <a href="https://agateau.com/2016/reordering-a-listview-via-dragndrop-3/">nice tutorial on ListView DnD
sorting</a> by
the great Aurélien Gâteau which I found very inspiring, and while I didn't
actually reuse the same code (mostly because I was already halfway through with
my implementation, which I started before finding his tutorial), it was helpful
to have it as a reference. I added a few animations to make it look more
pleasant, and I'm rather satisfied with the result:</p>
<p></p><center>
<video id="video" controls preload="metadata" width="100%">
<source src="http://mardy.it/archivos/videos/mitubo-1.3.webm" type="video/webm">
</source></video>
<p></p></center>
<p>I'm not showing you the code yet (though, indeed, you can find it in the
<code>DraggableListView</code> and <code>DraggableDelegate</code> items <a href="https://gitlab.com/mardy/mitubo/-/tree/master/src/desktop/qml">in the source
repository</a>)
because it's not yet in a shape where it's generally reusable in other
projects, but if I happen to need the same feature elsewhere I'll eventually
try to turn it into a couple fully reusable components.</p>
<p>Anyway, here's what's new in this latest MiTubo release:</p>
<ul>
<li>Subscriptions can be sorted by means of Drag&drop</li>
<li>For systems with python 3.5 or older (such as Ubuntu Touch), use the daily
builds of <a href="https://youtube-dl.org/">youtube-dl</a> instead of the official
releases</li>
<li>Implement <strong>PeerTube search</strong> (this should reserve a post of its own!)</li>
</ul>
<p>You can get it <a href="http://www.mardy.it/mitubo">at the usual place</a>. This time
there are only Linux and Windows builds as I'm a bit lazy to make a macOS
version, but should you need it, don't hesitate to ask!</p>