banterly.net_ghost4.rss.xml - sfeed_tests - sfeed tests and RSS and Atom files
(HTM) git clone git://git.codemadness.org/sfeed_tests
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
banterly.net_ghost4.rss.xml (179684B)
---
1 <?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Banterly]]></title><description><![CDATA[Vectors Before Words]]></description><link>https://www.banterly.net/</link><image><url>https://www.banterly.net/favicon.png</url><title>Banterly</title><link>https://www.banterly.net/</link></image><generator>Ghost 4.10</generator><lastBuildDate>Sat, 31 Jul 2021 21:34:38 GMT</lastBuildDate><atom:link href="https://www.banterly.net/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[New in Git: switch and restore]]></title><description><![CDATA[To my surprise, I recently found out about 2 new additions to the list of high-level commands: git restore and git switch
2 ]]></description><link>https://www.banterly.net/2021/07/31/new-in-git-switch-and-restore/</link><guid isPermaLink="false">6104e623e41c03003b1e132f</guid><category><![CDATA[git]]></category><category><![CDATA[checkout]]></category><category><![CDATA[programming]]></category><category><![CDATA[it]]></category><dc:creator><![CDATA[Dragos Barosan]]></dc:creator><pubDate>Sat, 31 Jul 2021 21:25:28 GMT</pubDate><media:content url="https://www.banterly.net/content/images/2021/07/1200px-Git-logo.svg.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><blockquote>
3 <img src="https://www.banterly.net/content/images/2021/07/1200px-Git-logo.svg.png" alt="New in Git: switch and restore"><p>"When I see a door with a push sign, I pull first to avoid conflicts" - anonymous</p>
4 </blockquote>
5 <p>For those that work with git for some time, it is not often that you get to discover new things about it. That is if you exclude the plumbing commands which probably most of us don't know by heart and most likely that's for the better. To my surprise, I recently found out about 2 new additions to the list of high-level commands:</p>
6 <ul>
7 <li><code>git restore</code></li>
8 <li><code>git switch</code></li>
9 </ul>
10 <p>To understand why they came to be, let's first visit our old friend <code>git checkout</code>.</p>
11 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2021/07/5i7rkq.jpg" class="kg-image" alt="New in Git: switch and restore" loading="lazy" width="500" height="500"></figure><!--kg-card-begin: markdown--><h1 id="checkoutthis">Checkout this</h1>
12 <p><code>git checkout</code> is one of the many reasons why newcomers find git confusing. And that is because its effect is context-dependent.<br>
13 The way most people use it is to switch the active branch in their local repo. More exactly, to switch the branch to which HEAD points. For example, you can switch to the <code>develop</code> branch if you are on the <code>main</code> branch:</p>
14 <p><code>git checkout develop</code></p>
15 <p>You can also make your HEAD pointer reference a specific commit instead of a branch(reaching the so-called detached HEAD state):</p>
16 <p><code>git checkout f8c540805b7e16753c65619ca3d7514178353f39</code></p>
17 <p>Where things get tricky is that if you provide a file as an argument instead of a branch or commit, it will discard your local changes to that file and restore it to the branch state.<br>
18 For example, if you checked out the develop branch and you made some changes to the test.txt file, then you can restore the file as it is in the latest commit of your branch with:</p>
19 <p><code>git checkout -- test.txt</code></p>
20 <h3 id="amethodtothemadness">A method to the madness</h3>
21 <p>If you first look at these two behaviors you might think that it doesn't make any sense, why have one command do 2 different actions? Well, things are a little more subtle than that. If we look at the <a href="https://git-scm.com/docs/git-checkout">git documentation</a>, we can see that the command has an extra argument that is usually omitted:</p>
22 <p><code>git checkout <tree-ish> -- <pathspec></code></p>
23 <p>What is <code><tree-ish></code> ? It can mean a lot of different things, but most commonly it means a commit hash or a branch name. By default that is taken to be the current branch, but it can be any other branch or commit. So for example if we are in the <code>develop</code> branch and want to change your test.txt file to be the version from the main branch you can do it like this:</p>
24 <p><code>git checkout main -- test.txt</code></p>
25 <p>With this in mind, maybe things start to make sense. When you provide just a branch or commit as an argument for <code>git checkout</code>, then it will change all your files to their version in the corresponding revision, but if you also specify a filename, it will only change the state of that file to match the specified revision.</p>
26 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2021/07/5i7qyz.jpg" class="kg-image" alt="New in Git: switch and restore" loading="lazy" width="750" height="500" srcset="https://www.banterly.net/content/images/size/w600/2021/07/5i7qyz.jpg 600w, https://www.banterly.net/content/images/2021/07/5i7qyz.jpg 750w" sizes="(min-width: 720px) 720px"></figure><!--kg-card-begin: markdown--><h1 id="newkidsontheblock">New kids on the block</h1>
27 <p>So even if things may start to make sense after reading the previous paragraphs, we must admit that it is still confusing especially for newcomers. That's why in version <a href="https://github.com/git/git/blob/master/Documentation/RelNotes/2.23.0.txt">2.23 of git</a>, two new commands have been introduced to replace the old git checkout(<code>git checkout</code> is still available, but people new to git should start with these ones preferably). As you would expect, they basically each implement one of the two behaviors described previously, splitting <code>git checkout</code> in two.</p>
28 <h3 id="switch">Switch</h3>
29 <p>This one implements the behavior of git checkout when running it only against a branch name. So you can use it to switch between branches or commits.</p>
30 <p><code>git switch develop</code></p>
31 <p>While with <code>git checkout</code> you can switch to a commit and transition into a detached HEAD state, by default git switch does not allow that. You need to provide the -d flag:</p>
32 <p><code>git switch -d f8c540805b7e16753c65619ca3d7514178353f39</code></p>
33 <p>Another difference is that with git checkout you can create and switch to the new branch in one command using the -b flag:<br>
34 <code>git checkout -b new_branch</code></p>
35 <p>You can do the same with the new one, but the flag is -c:<br>
36 <code>git switch -c new_branch</code></p>
37 <h3 id="restore">Restore</h3>
38 <p>This one implements the behavior of git when running it against a file. You can restore, as the name suggests, the state of a file to a specified git revision(the current branch by default)</p>
39 <p><code>git restore -- test.txt</code></p>
40 <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h1 id="conclusion">Conclusion</h1>
41 <p>These methods are still marked experimental, but for all intents and purposes they are here to stay so by all means I encourage everyone to start using them since they will probably make a lot more sense in your head and also it will make git just a little bit less confusing to new users.</p>
42 <p>More details about the two commands can be found in their git documentation:</p>
43 <ul>
44 <li><a href="https://git-scm.com/docs/git-switch">git switch</a></li>
45 <li><a href="https://git-scm.com/docs/git-restore">git restore</a></li>
46 </ul>
47 <!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Writing my first Intellij plugin]]></title><description><![CDATA[As of today, I am happy to announce the first version of my first plugin is available for free to download. The Java Builder Guided Completion Intellij plugin has its home on Github, as an open-source project.]]></description><link>https://www.banterly.net/2021/01/26/writing-my-first-intellij-plugin/</link><guid isPermaLink="false">600d7d1d1b26570039d36f0f</guid><category><![CDATA[intellij]]></category><category><![CDATA[plugin]]></category><category><![CDATA[open-source]]></category><category><![CDATA[development]]></category><category><![CDATA[Java]]></category><category><![CDATA[jetbrains]]></category><category><![CDATA[psi]]></category><dc:creator><![CDATA[Dragos Barosan]]></dc:creator><pubDate>Tue, 26 Jan 2021 10:42:37 GMT</pubDate><media:content url="https://www.banterly.net/content/images/2021/01/cover-1.PNG" medium="image"/><content:encoded><![CDATA[<img src="https://www.banterly.net/content/images/2021/01/cover-1.PNG" alt="Writing my first Intellij plugin"><p></p><!--kg-card-begin: markdown--><p>As of today, I am happy to announce the first version of my first plugin is available for free to download. The Java Builder Guided Completion Intellij plugin has its home on Github, as an open-source project, and you can visit it <a href="https://github.com/banterly91/Java-Builder-Guided-Completion-Intellij-Plugin">here</a> for more info. Alternatively, you can download directly from the JetBrains marketplace by clicking <a href="https://plugins.jetbrains.com/plugin/15695-builder-guided-completion">here</a> or just search for it in the Intellij IDE.</p>
48 <p>Due to work and family obligations, this took more time than expected, but still, quite a big chunk of time was spent on figuring out how some things work in the Intellij platform and how to set up things correctly, rather than actual development. Because of this, I decided to write this article where I will give you some tips that would have helped me big time if I knew them beforehand.</p>
49 <p>I will follow up this article with part 2 where I will explain more the implementation details of the plugin I developed. I am keeping it separate from this one since that will mostly contain information specific to the project, while in this one I will be presenting more general information.</p>
50 <h2 id="solvingaproblem">Solving a problem</h2>
51 <p>Firstly, if you are planning on writing a plugin(or any piece of software actually) you should be solving a problem, either one that does not have any solutions yet or one that has bad solutions. In the following I will be describing the problem I was trying to solve, then I will continue with some technical advice on developing an Intellij plugin that will most likely save you a lot of precious time and make you avoid frustrations that might persuade you to give up on your idea altogether.</p>
52 <h3 id="builders">Builders</h3>
53 <p>If you are coming from the Java or C# world(and not only) I assume you are familiar with the <a href="https://refactoring.guru/design-patterns/builder">Builder</a> pattern.</p>
54 <p>It always irked me the wrong way that, while being a lot better than the alternative telescopic constructor, the builder pattern construct is not very friendly to the users of the API exposing it. Using the Builder class in my IDE, I do not know what parameters are absolutely required for successfully building the target object, which ones are optional, and maybe which ones are mutually incompatible. Of course, I can figure it out at runtime, but that would result in a lot of trial and error attempts. Another way of finding this kind of info is by reading the documentation, but many times there is no documentation and still, it is quite inconvenient.</p>
55 <h3 id="solutions">Solutions</h3>
56 <p>My first attempt at solving this problem was to define a series of Builder interfaces that would all be implemented by the Builder class. Each interface would define a mandatory method that would return the Builder object as the next interface in the chain. I found out I was not the only one to come up with this concept and it actually has a name: the Step Builder Pattern. <a href="http://rdafbn.blogspot.com/2012/07/step-builder-pattern_28.html">Here</a> you can read more details about it and see some examples.</p>
57 <p>In practice, it turns out that the Step Builder pattern is not ideal as <a href="https://github.com/rzwitserloot/lombok/wiki/FEATURE-IDEA:-%22Mandatory%22-fields-with-@Builder">this post</a> explains. Essentially it makes things quite inflexible and there are a lot of corner cases that cannot be easily tackled with this approach.</p>
58 <p>The previously mentioned post actually was the inspiration for my final solution. I decided to go on with their suggestion and implement a plugin for Intellij that would mostly meet the requirements described by the Lombok developer. Actually part of the roadmap is to integrate with the Lombok plugin. For now bellow there is an example on what the plugin does.</p>
59 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.banterly.net/content/images/2021/01/exampleintellij.PNG" class="kg-image" alt="Writing my first Intellij plugin" loading="lazy" width="634" height="143" srcset="https://www.banterly.net/content/images/size/w600/2021/01/exampleintellij.PNG 600w, https://www.banterly.net/content/images/2021/01/exampleintellij.PNG 634w"><figcaption>Guided Completion Example</figcaption></figure><!--kg-card-begin: markdown--><h2 id="technicaltips">Technical Tips</h2>
60 <p>Now let us get started with some Intellij platform quirks that you should know in order to save time and focus on your actual development.</p>
61 <h3 id="1extensionpointshelp">1. Extension Points Help</h3>
62 <p>Extension Points are quite a central concept in Intellij plugin development. They basically allow you to modify the behavior of the IDE in quite sophisticated ways. The list is quite long and most of the time you have no idea what you are supposed to do to make stuff work with an extension point.<br>
63 I discovered it quite late, but luckily there is a tool that JetBrains has provided that allows anyone to search for a particular Extension Point and it will return a list of open-source plugins that have implemented it, and even more, it will point you to the specific file in the repository of the project containing the implementation.<br>
64 You can access it <a href="https://plugins.jetbrains.com/intellij-platform-explorer">here</a>. My recommendations are:</p>
65 <ol>
66 <li>get from <a href="https://plugins.jetbrains.com/docs/intellij/extension-point-list.html">here</a> a list of all extension points</li>
67 <li>search for the one that you think will probably help you to accomplish your objective</li>
68 <li>look at the related platform class which may have some documentation</li>
69 <li>look for other plugins implementing it since that will most likely answer a lot of the questions you have.</li>
70 </ol>
71 <h3 id="2enablejavafunctionality">2. Enable Java functionality</h3>
72 <p>My plugin is in Java developed for Java. I had a lot of headaches when looking at some code examples that I wanted to use in my plugin and when trying them out they did not work at all. Eventually, I discovered that the Java functionality has been <a href="https://blog.jetbrains.com/platform/2019/06/java-functionality-extracted-as-a-plugin/">extracted out from the core Intellij platform</a>. In order to access that functionality you need to do the following:</p>
73 <ul>
74 <li>declare in your plugin.xml file the following:</li>
75 </ul>
76 <pre><code class="language-xml"><depends>com.intellij.modules.java</depends>
77 </code></pre>
78 <ul>
79 <li>if you are using the gradle-intellij-plugin(as you should) then you also need to tell gradle about this dependency:</li>
80 </ul>
81 <pre><code class="language-groovy">intellij {
82 plugins = ['com.intellij.java']
83 // ...
84 }
85 </code></pre>
86 <p>The above is for groovy based graddle. For kotlin based graddle use:</p>
87 <pre><code class="language-kotlin">intellij {
88 setPlugins("java")
89 // ...
90 }
91 </code></pre>
92 <h3 id="psiviewer">PsiViewer</h3>
93 <p>In the Intellij platform, the contents of a file are structured under a construct called the PSI(Program Structure Interface) Tree. For your plugin you might need to interact with this PSI tree either to read its contents or even modify it.<br>
94 A very helpful tool that will allow you to experiment and discover how these trees and their elements look like is the <a href="https://plugins.jetbrains.com/plugin/227-psiviewer">PsiViewer</a> plugin. It lets you have a live view of the tree structure of a file you have open.</p>
95 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2021/01/Wxcu58lbCnE6HAgrRJSYTQ.png" class="kg-image" alt="Writing my first Intellij plugin" loading="lazy" width="791" height="663" srcset="https://www.banterly.net/content/images/size/w600/2021/01/Wxcu58lbCnE6HAgrRJSYTQ.png 600w, https://www.banterly.net/content/images/2021/01/Wxcu58lbCnE6HAgrRJSYTQ.png 791w" sizes="(min-width: 720px) 720px"></figure><!--kg-card-begin: markdown--><p>Here there is also a small quirk that I had to figure out. After you install the plugin, in order to have it available you need to set in the bin/idea.properties file the following and then restart the IDE:</p>
96 <pre><code>idea.is.internal=true
97 </code></pre>
98 <h3 id="debugging">Debugging</h3>
99 <p>For sure you will want to debug your plugin in order to solve some issue or just to discover how things work internally in Intellij.<br>
100 First, you should be happy to know that you do not need to create any special Intellij configuration or task, assuming you are using the gradle-intellij-plugin. If you check your gradle tasks under the Intellij directory you have the runIde task. Executing this task will launch a new Intellij session containing any modification you did in your project(so including whatever your plugin implemented). If you want to debug you need to execute the task with <em>Debug</em> instead of <em>Run</em>.</p>
101 <p>If you try to do this as-is, you will probably encounter quite fast when debugging a <em>ProcessCanceledException</em> which will result in you unable to continue with your debugging session. Had to dig a little on how to get rid of it but in the end, I found out I need to basically start the test IDE with the following two options</p>
102 <ul>
103 <li><em>-Didea.auto.reload.plugins=false</em></li>
104 <li><em>-Didea.ProcessCanceledException=disabled</em></li>
105 </ul>
106 <p>The way I managed to do this was with the following configuration in my kotlin based build.gradle:</p>
107 <pre><code class="language-kotlin"> withType<org.jetbrains.intellij.tasks.RunIdeTask> {
108 jvmArgs("-Didea.auto.reload.plugins=false")
109 jvmArgs("-Didea.ProcessCanceledException=disabled")
110 }
111 </code></pre>
112 <h2 id="tobecontinued">To be continued</h2>
113 <p>This was a fun experience for me and will try to improve on the current version of the plugin so please try it out and give any feedback. Continue to follow this blog if you want to know more about the actual plugin implementation in my next post.</p>
114 <!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Top 8 positive outcomes in the coronavirus pandemic aftermath]]></title><description><![CDATA[Not only do they predict such things without any real basis, but they seem to be taking some strange pleasure in doing knowing that they are inflicting a sense of panic in the mind of the public]]></description><link>https://www.banterly.net/2020/04/05/top-8-positive-outcomes-of-the-coronavirus-pandemic/</link><guid isPermaLink="false">5e8a0831f380a7003878f75c</guid><category><![CDATA[coronavirus]]></category><category><![CDATA[pandemic]]></category><category><![CDATA[positive]]></category><category><![CDATA[COVID-19]]></category><dc:creator><![CDATA[Dragos Barosan]]></dc:creator><pubDate>Sun, 05 Apr 2020 10:00:00 GMT</pubDate><media:content url="https://www.banterly.net/content/images/2020/04/The-Silver-Lining-to-Filing-Bankruptcy-Lee-Legal-DC-VA-MD.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><blockquote>
115 <img src="https://www.banterly.net/content/images/2020/04/The-Silver-Lining-to-Filing-Bankruptcy-Lee-Legal-DC-VA-MD.jpg" alt="Top 8 positive outcomes in the coronavirus pandemic aftermath"><p>"Too many people miss the silver lining because they're expecting gold." - Maurice Setter</p>
116 </blockquote>
117 <p>As you all know, maybe too much which is partly the point of this post, we are living though times due to the COVID-19 pandemic. Today I will be trying something different from what you normally see in news articles and social media during these times. But to begin with I want to throw some words at what I think it is truly irresponsible behavior.</p>
118 <h2 id="doomsayersclub">Doomsayers Club</h2>
119 <p>Monitoring the online sphere during the last few weeks, I observed something strange: a lot of people sharing on social media or on online forums like Reddit posts that are claiming we are living the early stages of some sort of apocalyptic scenario: be it the coming of World War 3, the collapse of civilization as we know it or something else in that spirit. Not only do they predict such things without any real basis, but they seem to be taking some strange pleasure in doing knowing that they are inflicting a sense of panic in the mind of the public. Even IF, and that is a very big IF, such scenarios would be true, it literally does not help anyone to induce panic and yell in public how we are all doomed. To anyone else thinking of talking about this topic please either come up with solutions to the problems you think you identify or keep your desperation for yourself. The only place for doomsayers is in Heartstone.</p>
120 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2020/04/200px-Doomsayer-467-.png" class="kg-image" alt="Top 8 positive outcomes in the coronavirus pandemic aftermath" loading="lazy"></figure><!--kg-card-begin: markdown--><h2 id="journalismfailsusagain">Journalism fails us again</h2>
121 <p>I want to put in the same category the journalists who either do not understand how exponential growth works and how pandemics evolve or just want to generate the most click-bait title.</p>
122 <p>Everyday I see a titles that are either misleading or are meant to induce a sentiment into the reader that is really not warranted by reality.</p>
123 <p>I will give two example of titles that I see almost every day.</p>
124 <ul>
125 <li>"The number of new cases has skyrocketed" - this I saw a lot even when the rate of increase in new cases, percentage wise, has kept the same for a couple of days or even decreased which is one of the main things to look at rather than absolute numbers.</li>
126 <li>"Scary new number of deaths today: 1000". Regarding this one, let us put things into perspective a little:
127 <ul>
128 <li>At the time of this writing there have been reported 65 000 deaths worldwide due to COVID-19 in the approximately 3 months since this crisis started.</li>
129 <li>In the first 10 hours of this day it is estimated that 65 000 deaths have taken place in the world for various reasons. So in 10 hours you have as many deaths as due to the coronavirus in 3 months and yet no one is putting scary titles about that.</li>
130 <li>Since the beginning of the year it is estimated around 15 000 000 people have passed away in total. If we make some quick maths, the total number of deaths attributed to COVID-19 out of all deaths this year is only 0.5%. You read that right: 0.5% of deaths are categorised as "scary" while the big majority of 99.5% are mostly ignored.</li>
131 </ul>
132 </li>
133 </ul>
134 <p>Looking at the examples above I hope you understand why the scary and panic inducing titles I see from journalists every day make me angry. All I have to say to them is "Shame!" since they are not only not bringing any positive contribution to the table, but they bring a lot of negativity.</p>
135 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2020/04/giphy--1-.gif" class="kg-image" alt="Top 8 positive outcomes in the coronavirus pandemic aftermath" loading="lazy"></figure><!--kg-card-begin: markdown--><p>Do not get me wrong, I am not downplaying the issue and it is good governments all over the world have taken measures so these numbers do not become indeed scary, I am just saying that if we take things into perspective a bit, so far, they are not so bad as you would be led to believe if you watch certain TV programmes or read some articles.</p>
136 <h2 id="puttingsomepositivelightintoallthismess">Putting some positive light into all this mess</h2>
137 <p>Today I want to do the opposite of what I mentioned above. I will compile a list of possible positive outcomes that could come as a result of this pandemic. Maybe some can be called only wishful thinking, but someone has to think it befor it can become reality.</p>
138 <p>Before I begin I want to be clear, I am not dismissing all the negative impact this situation has had over the world from not only a public health perspective(both physical and psychological), but also from an economic one. The purpose is to contra balance the kind of people I mentioned in the intro.</p>
139 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2020/04/0b6fda92ddd516789d8e7621ba2fb05f.jpg" class="kg-image" alt="Top 8 positive outcomes in the coronavirus pandemic aftermath" loading="lazy"></figure><!--kg-card-begin: markdown--><h3 id="betterpersonalhygiene">Better personal hygiene</h3>
140 <p>"Wash your hands thoroughly when coming from outside!", "Sneeze or cough on your elbow or in a tissue, not in the air!", these have been common advice that most of us received since we were little kids, but few actually pursued them thoroughly. Now people started to take them seriously and with the pandemic set to still loom over the world for probably at least a couple of months more, this period may be long enough that these personal hygiene actions will become a habit that will improve all of our health outcomes for the future.</p>
141 <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h3 id="preparedforthenextpandemic">Prepared for the next pandemic.</h3>
142 <p>COVID-19 has shown that the world is not prepared for an epidemic of this scale and a lot of quick decisions and improvisation had to be done to maintain the virus under control while also making sure people can still survive in isolation. Since this situation affected everyone, including the rich who's profits are dwindling a lot during this time, most likely the world leaders will(either at their own initiative or under the pressure of their big sponsors) take precautions and have in hand the proper protocols and resources to deal with the next pandemic which will inevitably come at some point.</p>
143 <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h3 id="antivaxxerswillbelessmainstream">Anti-vaxxers will be less mainstream</h3>
144 <p>Most anti-vaxxers, at least the moderate ones, consider vaccines too high of a risk because they never saw the damage the illnesses they are meant to protect us from can do.<br>
145 Now with the whole world witnessing how much global health and economic damage can the absence of only one vaccine do, most likely a lot of the anti-vaxx movement will lose its steam and some of its members will turn their back to their pseudoscience and start vaccinating. Also there is a hope that a lot of the non mandatory vaccines(i.e. the seasonal flu vaccine) will have an uptake in being taken by the general population.</p>
146 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2020/04/funny-anti-vaxx-memes-9-5c6fd24492737__700.jpg" class="kg-image" alt="Top 8 positive outcomes in the coronavirus pandemic aftermath" loading="lazy"></figure><!--kg-card-begin: markdown--><h3 id="morerelaxedwfhpolicies">More relaxed WFH policies</h3>
147 <p>The current situation has forced organizations to widen the range of what activities can be performed by their employees from home in order to maintain operations online as much as possible. If this forced experiment proves to be successful, then it may change the norm that all work has to be done from the workplace office if possible otherwise. This change could result in benefits for both the employee and the employer:</p>
148 <ul>
149 <li>The employee saves on commute time, time which he can spend on learning something new, taking a hobby or spending time with his friends or family. Also the working hours would be more flexible allowing him to take care of some chores during the day and working more in the evening.</li>
150 <li>For employers, it would allow them to transform their local pool of candidates to a global pool. Also with less employees working from the office, less office space would be required which would reduce expenses with rent being quite high in the hot areas of most big cities.</li>
151 <li>As an extra benefit, less commuters will mean less traffic which means less pollution from which the environment will surely benefit.</li>
152 </ul>
153 <p>Of course this is not possible for everyone and some may just prefer to work from an office, so working from the company office cannot be fully removed, but at least maybe WFH or work outside of the office will become an option in places that traditionally did not even consider it.</p>
154 <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h3 id="animalsadopted">Animals adopted</h3>
155 <p>With people suffering from loneliness during these times of isolation, there have been reports of a big uptake in animal adoption from shelters. That is great not only for the animals that are saved from possible euthanasia, but also there are proven health benefits that come as a result of owning a pet. The only downside of this situation is the risk that once people go back to their normal lives they may discover they do not have that much time anymore to commit to their newly adopted pets. Hopefully, with still no end in sight of the isolation period, there will be enough time for the owners and pets to form an inseparable relationship.</p>
156 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2020/04/shutterstock_1043814685.jpg" class="kg-image" alt="Top 8 positive outcomes in the coronavirus pandemic aftermath" loading="lazy"></figure><!--kg-card-begin: markdown--><h3 id="universalbasicincome">Universal basic income</h3>
157 <p>There are a lot of jobs that cannot be performed from home. As a result a lot of people lost their jobs or their activity has been indefinitely suspended, loosing their source of income. Governments have promoted some measures to assure some relief for people in this situation(probably not enough for a lot) like suspending mortgage payments, paying a percent of salaries for employees whose companies revenue was affected or even sending direct payments into the account of people who qualify. These measures have given new boost to the idea of Universal Basic Income which has been in the public debate for some time.<br>
158 The idea is that if we as a society can survive and even prosper without the need of everyone working because of the various technological advancements, then we can afford to pay a basic amount to allow everyone to live decently regardless of what path they pursue in life. This would allow people to spend their time exploring their interests and maybe preparing for occupations that cannot still be automated (i.e. physics researcher). This is not possible these days for a lot of people: for example if you are born into a poor family you will have to start working menial jobs from a young age and will probably not have an opportunity(or at least it would be quite hard) to go into higher education or take a career which requires a lot of upfront education(doctor, lawyer etc). Of course there is also a lot of criticism on the idea of universal income that has to be taken into consideration, but as with the WFH norm, this crisis may change the status quo at least by a little bit.</p>
159 <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h3 id="lessfocusonfastmassivegrowthandmoreonsustainablegrowth">Less focus on fast massive growth and more on sustainable growth</h3>
160 <p>Another thing that has been exposed during this pandemic is the amount of unsustainable business practices that a lot of corporations have been doing that have now left them exposed during crisis time(i.e. massive stock buybacks, burning all available money with the hope of some future profit). Unless governments will completely bail out all these bad actors, companies will hopefully start thinking of more sustainable growth strategies that will have them covered even during a rainy day.</p>
161 <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h3 id="lessdividemoreempathy">Less divide, more empathy</h3>
162 <p>Polarization has been skyrocketing in the last decade so one of the hopes is that COVID-19 will act as a global common enemy that will make people stand together rather than fighting over different ideological issues. This is similar to the great mobilization that happened with the populations of the countries involved in the great wars of the past. We can already see some signs of that with multiple home owners reducing the rent for affected tenants, multiple ad hoc organizations offering to do the shopping for people part of vulnerable groups (i.e. the elderly) and companies offering to produce medical equipment and supplies for hospitals. One can only hope this behavior keeps going even when humanity surpasses this crisis.</p>
163 <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h2 id></h2>
164 <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h2 id="shareyourthoughts">Share your thoughts!</h2>
165 <p>Those are some of the main positive ideas I identified. If you make an effort to forget for a moment all the negativity that surrounds us, what silver linings can you see from this all situation?</p>
166 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2020/04/share-1314738_960_720.jpg" class="kg-image" alt="Top 8 positive outcomes in the coronavirus pandemic aftermath" loading="lazy"></figure>]]></content:encoded></item><item><title><![CDATA[Why what you have been taught about DFS is wrong(at least partially)]]></title><description><![CDATA[The student runs the two versions of DFS and he sees that the results are the same so he quickly memorizes the BFS algorithm and the two small differences to transform it into DFS and he lives a happy life with the thought that he basically learned 2 algorithms for the price of one.]]></description><link>https://www.banterly.net/2020/02/09/why-what-you-have-been-thaught-about-dfs-is-wrong-at-least-partially/</link><guid isPermaLink="false">5e3fe1da8a086b00389654bf</guid><category><![CDATA[Algorithms]]></category><category><![CDATA[Graph]]></category><category><![CDATA[Traversal]]></category><category><![CDATA[DFS]]></category><category><![CDATA[BFS]]></category><category><![CDATA[programming]]></category><category><![CDATA[Java]]></category><dc:creator><![CDATA[Dragos Barosan]]></dc:creator><pubDate>Sun, 09 Feb 2020 20:43:55 GMT</pubDate><media:content url="https://www.banterly.net/content/images/2020/02/meme2.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><blockquote>
167 <img src="https://www.banterly.net/content/images/2020/02/meme2.jpg" alt="Why what you have been taught about DFS is wrong(at least partially)"><p>"The trouble with the world is not that people know too little, it's that they know so many things that just aren't so." - Mark Twain</p>
168 </blockquote>
169 <p>Sadly for me (I guess happily for my sanity) sometimes when I read and learn new things I do not fully put them through my thought filter and I just accept them as they are stated. Today I am going to talk about such a case and I hope it will help you remove one of the many misconceptions that we live with.</p>
170 <p>For some crazy reason, recently I revisited the two well known graph traversal algorithms, Depth-First Search (DFS for short) and Breadth First Search (BFS for short) and came to some conclusions and realizations which apparently were interesting enough to wake me up from my months long hibernation since I last wrote a post.</p>
171 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2020/02/meme-new-version.jpg" class="kg-image" alt="Why what you have been taught about DFS is wrong(at least partially)" loading="lazy"></figure><!--kg-card-begin: markdown--><p>For the case where the details of the two algorithms are a little bit fuzzy and also to setup the scene for the grand reveal at the end I will go through the process of how usually DFS and BFS are taught (at least in my experience and as far as I see how it is mostly taught on the Internet if you search for these two algorithms). First we need an example graph. We will work with the one shown below:</p>
172 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2020/02/exampleGraph-1.PNG" class="kg-image" alt="Why what you have been taught about DFS is wrong(at least partially)" loading="lazy"></figure><!--kg-card-begin: markdown--><h2 id="breadthfirstsearch">Breadth First Search</h2>
173 <p>BFS starts with a node of the graph which will act as a root node in the context of the algorithm. From the root, it will continue exploring the graph by traversing completely a level at a certain depth before going to the next one. Since we are traversing a graph we have to be careful to not visit the same node twice.<br>
174 For the example above the traversal order would be:</p>
175 <ul>
176 <li>Level 0: 1</li>
177 <li>Level 1: 2 -> 3 -> 4</li>
178 <li>Level 2: 5 -> 6 -> 7</li>
179 <li>Level 3: 8 -> 9</li>
180 </ul>
181 <p>The classic implementation of this algorithm is iterative and involves a Queue which will mostly take care for us that the order of traversal is breadth first. A set is used also to keep track of discovered nodes: before adding any node to our queue of nodes to visit, we first check this set if the node was already previously added to the queue. One example of such an implementation is given below:</p>
182 <pre><code class="language-java">void breadthFirstTraversal(Node root) {
183 if (root == null)
184 return;
185
186 //Create and initialize the set which
187 //will contain discovered nodes
188 Set<Node> discovered = new HashSet<>();
189 discovered.add(root);
190
191 //Create and initialize queue which
192 //will contain the nodes left to visit
193 Deque<Node> queue = new ArrayDeque<>();
194 queue.offer(root);
195
196 while (!queue.isEmpty()) {
197 Node current = queue.poll();
198
199 //visit the node; in this case just print
200 // the node value
201 System.out.println(current.getValue());
202
203 for (Node child : current.getChildren()) {
204 //add to the queue any child node of the
205 //current node that has not already been discovered
206 //and also add it to the set of
207 //discovered nodes
208 if (!discovered.contains(child)) {
209 queue.offer(child);
210 discovered.add(child);
211 }
212 }
213 }
214 }
215 </code></pre>
216 <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h2 id="depthfirstsearch">Depth First Search</h2>
217 <p>Now that we know what BFS is, it should be intuitive how using a DFS traversal style would work. Instead of going level by level, the algorithm will start with a root node and then fully explore one branch of the graph before going to the next one. For our example graph (which I am showing below again so it is easy to follow) the traversal order would be:</p>
218 <ul>
219 <li>Branch 1: 1 -> 2 -> 5 -> 8 -> 7 > 9</li>
220 <li>Branch 2: 6</li>
221 <li>Branch 3: 3 -> 4</li>
222 </ul>
223 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2020/02/exampleGraph-2.PNG" class="kg-image" alt="Why what you have been taught about DFS is wrong(at least partially)" loading="lazy"></figure><!--kg-card-begin: markdown--><p>DFS lends itself quite nicely to a recursive approach so the classic implementation looks something like this.</p>
224 <pre><code class="language-java">void depthFirstTraversal(Node root){
225 if(root == null){
226 return;
227 }
228
229 //initialize the set which will contain
230 // our discovered nodes
231 Set<Node> discovered = new HashSet<>();
232 //call the recursive function starting
233 //with the provided root
234 dfsRecursive(root, discovered);
235 }
236
237 void dfsRecursive(Node current, Set<Node> discovered){
238 //mark the node as discovered
239 discovered.add(current);
240
241 //visit the node; in this case we just
242 //print the value of the node
243 System.out.println(current.getValue());
244
245 //recursively call the function on all of
246 //the children of the current node if
247 //they have not already been discovered
248 for(Node child : current.getChildren()){
249 if(!discovered.contains(child)) {
250 dfsRecursive(child, discovered);
251 }
252 }
253 }
254 </code></pre>
255 <p>At this point your teacher will say: "You know what? To help you out to see that these algorithms are not that different, let me show you how to implement DFS iteratively". They will mention that it is almost the same as BFS except two differences:<br>
256 1. Use a stack instead of a queue.<br>
257 2. Check if we have visited a node after we pop from the stack. This is opposed to checking before we add a node to the stack as we do in BFS where we check a node before adding it to the queue.</p>
258 <p>The classic implementation looks something like this (even on Wikipedia it is explained somewhat similarly):</p>
259 <pre><code class="language-java">void depthFirstTraversalIterative(Node root){
260 if (root == null)
261 return;
262
263 //Create the set which
264 // will contain discovered nodes
265 Set<Node> discovered = new HashSet<>();
266
267 //Create and initialize stack which
268 // will contain the nodes left to visit
269 Deque<Node> stack = new ArrayDeque<>();
270 stack.push(root);
271
272 while (!stack.isEmpty()) {
273 Node current = stack.pop();
274
275 if(!discovered.contains(current)){
276 discovered.add(current);
277
278 //visit the node; in this case just print
279 // the node value
280 System.out.println(current.getValue());
281
282 //add to the stack all the children
283 //of the current node
284 for(Node child : current.getChildren()){
285 stack.push(child);
286 }
287 }
288 }
289 }
290 </code></pre>
291 <p>The student runs the two versions of DFS and he sees that the results are the same so he quickly memorizes the BFS algorithm and the two small differences to transform it into DFS and he lives a happy life with the thought that he basically learned 2 algorithms for the price of one. One of such students being me.</p>
292 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2020/02/meme3.jpg" class="kg-image" alt="Why what you have been taught about DFS is wrong(at least partially)" loading="lazy"></figure><!--kg-card-begin: markdown--><h2 id="diggingdeeper">Digging deeper</h2>
293 <p>A more inquisitive mind will stop and ask: Wait a minute, where do those two differences between DFS and BFS come from? Good question! Let us explore!</p>
294 <p>The first one is usually answered with the following: When implementing DFS recursively a stack is used implicitly behind the scene to store the data while visiting the graph so it only makes sense that we explicitly also use a stack for the iterative approach right? Sounds reasonable.</p>
295 <p>The second difference is not usually discussed though and here things actually get interesting.<br>
296 First let's ask ourselves why in the BFS implementation we check if the node is visited before we add it to the queue?<br>
297 To answer that let's see what happens if we check after we poll the node from the queue. We will zoom in at the moment we visit node 3.<br>
298 Node 4 will in both cases be already in our queue. If we do what we usually do and mark node 4 as discovered before adding it to the queue, then we will have the information that node 4 is already discovered and we would not add it again to the queue. This situation is shown in the picture below.</p>
299 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2020/02/example1-1.PNG" class="kg-image" alt="Why what you have been taught about DFS is wrong(at least partially)" loading="lazy"></figure><!--kg-card-begin: markdown--><p>With the change that we made, the discovered nodes set does not have node 4 as a member so we will add it again to the queue. The situation is shown below.</p>
300 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2020/02/image-9.png" class="kg-image" alt="Why what you have been taught about DFS is wrong(at least partially)" loading="lazy"></figure><!--kg-card-begin: markdown--><p>Since the queue is a First In First Out structure, it turns out that from a result perspective this difference does not matter since we will anyway first visit the node that we first added to the queue and we mark it then as discovered. When trying to visit again the same node we will see it as already visited. The main take away is that we want to mark nodes as discovered before adding them to the queue so we do not have duplicates in the queue, this mainly helping with the memory profile of the algorithm since the number of nodes in the queue will be kept to the minimum required.</p>
301 <p>If we turn our attention to the DFS iterative version we can think that maybe it makes sense also there to do the same thing as in BFS and mark as discovered nodes before we add them to the stack, so let's do it! With this small modification the visiting order of the example graph (again shown below for convenience) will be:</p>
302 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2020/02/exampleGraph-3.PNG" class="kg-image" alt="Why what you have been taught about DFS is wrong(at least partially)" loading="lazy"></figure><!--kg-card-begin: markdown--><ul>
303 <li>Branch 1: 1 -> 2 -> 5 -> 8</li>
304 <li>Branch 2: 6</li>
305 <li>Branch 3: 7 -> 9</li>
306 <li>Branch 4: 3</li>
307 <li>Branch 5: 4</li>
308 </ul>
309 <p>Wait what? We get different result than in the recursive approach...that cant be right!?</p>
310 <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h2 id="beingmisled">Being misled</h2>
311 <p>So what is happening here? We need to realize that just by using a stack for our iterative implementation because the recursive implementation uses one will not auto-magically make the two behave the same.</p>
312 <p>If you think a little more in depth about what the recursive version actually does you will notice that, as opposed to the iterative version, we do not save on the implicit stack all the children of the current node, we only save the current node and implicitly we also save on which of the children we will recursively call the algorithm next! For example for the root node we never save anywhere on any stack node 3 and 4, we only get to visit them because this recursive approach implicitly provides us a backtracking mechanism where once a path is completely explored we can go to the next path.</p>
313 <p>In our iterative approach we save all the children on the stack with the hope that the Last In First Out behavior of the stack will give us the DFS behavior of the recursive implementation. As we saw, this only works when we mark a node as discovered after we pop it from the stack( I will let as an exercise to go through the traversal and understand exactly where the result difference comes from). As in the BFS case that we studied above, this will result in having the same node multiple times in our stack.</p>
314 <p>So I think here is where people are misled because when we take all into account the situation can be resumed like this:</p>
315 <ul>
316 <li>When we implement BFS we are being taught that we do not want duplicates in our Queue so we must mark nodes as discovered before adding them.</li>
317 <li>When we implement iterative DFS we are being taught to forget about not wanting duplicates in our data structure(this case the stack) because now we just want to mimic the recursive implementation so we will sacrifice our principle from the queue implementation.</li>
318 </ul>
319 <p>The second teaching seems contradictory with the first one. If this is done just to save the students from the extra complexity, then I think that is wrong because the whole purpose of studying these algorithms should be to understand their inherent workings not for people to be able to memorize them more easily.</p>
320 <p>Because of the differences between the inner workings of the recursive implementation and the classic iterative implementation the two can have vastly different behaviors in terms of memory depending on the graph structure. A prominent case that illustrates this is a star graph: a single central node surrounded by a large number (say, 1000) of child leaf nodes. An example shown below, but with only a couple of nodes.</p>
321 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2020/02/starGraph.PNG" class="kg-image" alt="Why what you have been taught about DFS is wrong(at least partially)" loading="lazy"></figure><!--kg-card-begin: markdown--><p>If you run the iterative version of DFS that we saw previously on this graph using the central node as the starting point, the stack size will grow to 1000 since we will be adding all the child nodes to the stack before going to the next iteration. The recursive DFS algorithm will need an implicit stack depth of only 1 to traverse this entire graph. That is 1000 vs 1 in terms of memory requirements!</p>
322 <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h2 id="truedfs">True DFS</h2>
323 <p>The good news is that once we actually understand what the recursive implementation actually does we can implement an iterative version that indeed has the same behavior, not one that only pretends to do. What we need to do is explicitly code the backtracking behavior of the recursive DFS implementation. We will do this by keeping in the stack info about which child of a node we need to visit, rather then the node itself. The algorithm implementation follows with some inline comments to explain what is happening:</p>
324 <pre><code class="language-java">// data structure for storing the required info on the stack
325 class TraversalInfo{
326 Node parent;
327 int childPos;
328
329 public TraversalInfo(Node parent, int childPos) {
330 this.parent = parent;
331 this.childPos = childPos;
332 }
333
334 public Node getParent() {
335 return parent;
336 }
337
338
339 public int getChildPos() {
340 return childPos;
341 }
342
343 public void setChildPos(int childPos) {
344 this.childPos = childPos;
345 }
346 }
347
348 void trueDepthFirstTraversalIterative(Node root){
349
350 //as always create and initialize
351 //the set of discovered nodes
352 Set<Node> discovered = new HashSet<>();
353 discovered.add(root);
354
355 //create and initialize the stack which will
356 //indicate which node to visit next. You can
357 //observer that we are not saving anymore directly
358 //what node to visit next, but a parent node and
359 //the index of its child that we should visit next
360 Deque<TraversalInfo> stack = new ArrayDeque<>();
361 stack.push(new TraversalInfo(root, 0));
362
363 //we visit the root node before going
364 //into our loop
365 System.out.println(root.getValue());
366
367
368 while (!stack.isEmpty()) {
369 TraversalInfo current = stack.pop();
370 Node currentParent = current.getParent();
371 int currentChildPos = current.getChildPos();
372
373 //we check if there are more child nodes
374 if(currentChildPos < currentParent.getChildren().size()){
375 Node child = currentParent.getChildren().get(currentChildPos);
376 //we save in the stack the next child index
377 //together with its parent
378 current.setChildPos(currentChildPos + 1);
379 stack.push(current);
380
381 //check if current child discovered already
382 if(!discovered.contains(child)){
383 //add it to the set of discovered nodes
384 discovered.add(child);
385 //visit the child; in this case just print out its value
386 System.out.println(child);
387 //add to the stack the info for visiting its child nodes
388 //starting from the first one
389 stack.push(new TraversalInfo(child, 0));
390 }
391 }
392 }
393 }
394
395 </code></pre>
396 <p>As we can see this implementation is a little more complex than the one we are used to. Here we use an extra data structure to keep the required info, but there is an alternative implementation using an extra stack which I will leave as an exercise for anyone curious enough to try it out.</p>
397 <p>In some circles this iterative implementation and the recursive one are called True DFS, while the iterative one that we saw in the beggining is called a pseudo DFS traversal since at the surface level it mimics the True DFS algorithm, but if you look at its inner workings it does not.</p>
398 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2020/02/meme1.jpg" class="kg-image" alt="Why what you have been taught about DFS is wrong(at least partially)" loading="lazy"></figure><!--kg-card-begin: markdown--><h2 id="closingremarks">Closing remarks</h2>
399 <p>Let me know in the comments for how many of you this was obvious from the start and how many actually lived with the iterative DFS implementation without questioning it.</p>
400 <p>Also let me know of any other simmilar example that you may have.</p>
401 <p>If you like the content do not forget to subscribe!</p>
402 <!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Enums - one of the underrated features of Java]]></title><description><![CDATA[I remember when I was first learning programming and stumbled upon enums, my first reaction was "*this is cute, but is it really useful for something?*" and "*do people really use this thing?*". ]]></description><link>https://www.banterly.net/2019/07/28/one-of-the-more-underrated-features-of-java/</link><guid isPermaLink="false">5d346f471bc9e50038192a17</guid><category><![CDATA[Java]]></category><category><![CDATA[programming]]></category><category><![CDATA[enum]]></category><category><![CDATA[pattern]]></category><dc:creator><![CDATA[Dragos Barosan]]></dc:creator><pubDate>Sun, 28 Jul 2019 09:07:29 GMT</pubDate><media:content url="https://www.banterly.net/content/images/2019/07/member-1.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://www.banterly.net/content/images/2019/07/member-1.jpg" alt="Enums - one of the underrated features of Java"><p>I remember when I was first learning programming and stumbled upon enums, my first reaction was "<em>this is cute, but is it really useful for something?</em>" and "<em>do people really use this thing?</em>". Well, coming to present time, I can answer that yes, they are really useful, and that probably people do not use them as much as they should.<br>
403 For a while know, I became more and more amazed on how useful enums are as a concept and in how many ways they can be used in practice and today I decided to share with you my thoughts on it.</p>
404 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2019/07/member.jpg" class="kg-image" alt="Enums - one of the underrated features of Java" loading="lazy"></figure><!--kg-card-begin: markdown--><p>Let's see what enums are and more importantly how can you use them. As a warning I will be focusing in my examples on Java, but I am sure at least some of the use cases can be applied to other programming languages.</p>
405 <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h2 id="whatisanenum">What is an enum?</h2>
406 <p>In Java enum is short for Enumerated type and in other parts it is also known as enumeration, factor (e.g. R language) or categorical variable in statistics (yes it is also present in Math, actually it kinda comes from there). Although not exactly the same in functional languages, in that paradigm they can be considered a degenarated form of tagged unions or sum types.</p>
407 <p>They are data types that consist of a set of named values called either elements, members or enumerators of the type.</p>
408 <p>Basically they define a type of which only certain values are possible, values which have a name (or tag) associated with them. A variable declared to be of an enum type can only be assigned values that are predefined in the definition of that enum.</p>
409 <p>Specific to Java, an enum has quite an extended behavior: it is like a class that can have only a fixed set of instances and this fixed set is hardcoded in the source code that defines the enum. We will come back to this later to see why it is useful.</p>
410 <p>If this sounds too abstract, let us give an example that will introduce also the first use case for enums.</p>
411 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2019/07/366dtb.jpg" class="kg-image" alt="Enums - one of the underrated features of Java" loading="lazy"></figure><!--kg-card-begin: markdown--><h3 id="theworldwithoutenums">The world without enums</h3>
412 <p>Let's imagine that we have a function that accepts as a parameter a day of the week. One naive way to design this would be to have that parameter as a String type:</p>
413 <pre><code class="language-java">public void function(String dayOfWeek){
414 //do stuff
415 }
416 </code></pre>
417 <p>And a user would call it like this:</p>
418 <pre><code class="language-java">// some logic
419 function("Thursday");
420 // some other logic
421 </code></pre>
422 <p>One big problem with this is that a user could pass anything to our function as a parameter, not just the name of a weekday:</p>
423 <pre><code class="language-java">// some logic
424 function("banterly");
425 // some other logic
426 </code></pre>
427 <p>A user could either be making a typo, pass in a wrong value or just do it because he is not clear on what he should pass as a value to the function (e.g. should it be the day of the week with a capital or without?). Either way, he has no way of knowing if he passed a bad value until runtime, when hopefully the function will have some sort of validation on the input and throw an exception. In the worst case there is no validation and incorrect behavior can propagate undetected in the flow of the program.</p>
428 <p>Another serious implication is performance degradation: if the function has to do a lot of equality checks with the received parameter (which it will have to do if it employs some sort of validation to check that the value is indeed a weekday), then a lot of string comparisons will have to take place which are not very beneficial for performance critical applications.</p>
429 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2019/07/performance.jpg" class="kg-image" alt="Enums - one of the underrated features of Java" loading="lazy"></figure><!--kg-card-begin: markdown--><p>I am already hearing some of you guys saying: "<em>wait a minute sir, we can use the following idiom for this use case: define a set of int constants that would represent the days of the week</em>":</p>
430 <pre><code class="language-java">public static final int MONDAY = 1;
431 public static final int TUESDAY = 2;
432 public static final int WEDNESDAY = 3;
433 public static final int THURSDAY = 4;
434 public static final int FRIDAY = 5;
435 public static final int SATURDAY = 6;
436 public static final int SUNDAY = 7;
437
438 public void function(int weekOfDay){
439 //do stuff
440 }
441
442 //call it later like this
443 function(SUNDAY);
444
445 </code></pre>
446 <p>This solves the performance problem and it allows the users to pass in predefined values in a relatively safe manner, but notice that I said it allows, not that it forces them: users can still pass anything to the function and make it behave in an incorrect way. Not only this, but this idiom does not introduce any namespace for the defined values which can lead to name conflicts like the following scenario:</p>
447 <pre><code class="language-java">//traffic lights
448 public static final int GREEN = 0;
449 public static final int ORANGE = 1;
450 public static final int RED = 2;
451
452 //for fruits
453 public static final int PEAR = 0;
454 public static final int ORANGE = 1; // will give a compile error since ORANGE is already defined above
455 public static final int APPLE = 2;
456 </code></pre>
457 <p>If defined in the same class the above will not compile, so you will have to prefix each name with some sort of identifier:</p>
458 <pre><code class="language-java">public static final int TRAFFIC_LIGHT_ORANGE = 1;
459 public static final int FRUIT_ORANGE = 1;
460 </code></pre>
461 <p>Another issue with these definitions is that a function can now accept either a fruit or a traffic light and produce the same output which does not make sense and the compiler has no way to complain about this.</p>
462 <p>I hope this entire essay convinced you why it is not a good idea to use any of the two described approaches. So what is the solution? While of course the subject of this article.</p>
463 <h3 id="usingenumsempoweringtheuserandthecompiler">Using enums - Empowering the user and the compiler</h3>
464 <p>Let us define a very simple enum that will represent the days of the week.</p>
465 <pre><code class="language-java">enum Weekday {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY}
466 </code></pre>
467 <p>Now we can define our function to take a parameter of type Weekday:</p>
468 <pre><code class="language-java">public void function(Weekday weekday){
469 //do stuff
470 }
471
472 // later on we call it
473 function(Weekday.TUESDAY);
474 </code></pre>
475 <p>This will mean that a user can only pass in one of the values defined for the Weekday enum, otherwise the compiler will complain. This comes with the following benefits:</p>
476 <ul>
477 <li>No risk of the user accidentally typing a wrong input or a malicious user intentionally doing so.</li>
478 <li>The user knows what he needs to pass in by just looking at the signature of the method.</li>
479 <li>Another benefit over the previous two methods is that the enum types give you access for free on iterating over their possible values in case you ever need it.</li>
480 <li>Using enums opens the door for using EnumSet and EnumMap, two type safe and performant implementations of the Set and Map interfaces, otherwise you would have to do some ugly things to satisfy certain usecases. Will give an example for EnumSet here and leave you to discover the EnumMap yourself. If a function requires possibly a combination of input values, then if you are using the constant int pattern you would have to assign powers of 2 to your values and then do bitwise operations on the values:</li>
481 </ul>
482 <pre><code class="language-java">//obsolete idiom
483 public class Renderer{
484 public static final int COLOR_RED = 1;
485 public static final int COLOR_BLUE = 2;
486 public static final int COLOR_ORANGE = 4;
487 public static final int COLOR_GREEN = 8;
488
489 public void draw(int colors){
490 // draw
491 }
492 }
493 </code></pre>
494 <p>Calling the draw function for colors blue and red would be something like this</p>
495 <pre><code class="language-java">renderer.draw(COLOR_RED | COLOR_BLUE);
496 </code></pre>
497 <p>With an EnumMap you do not have to apply any of those tricks, things just work and besides that you have type safety and the performance that comes with these structures:</p>
498 <pre><code class="language-java">public class Renderer{
499 public enum Color{RED, BLUE, GREEN, ORANGE}
500
501 public void draw(Set<Color> colors){
502 //draw
503 }
504 }
505 </code></pre>
506 <p>We now can call the draw method like this:</p>
507 <pre><code class="language-java">renderer.draw(EnumSet.of(Color.RED, Color.BLUE))
508 </code></pre>
509 <ul>
510 <li>Enum values are by definition the only instances created of the enum type, guaranteed by the JVM, so if your logic needs to compare enum values you can safely use the == operator to perform a reference equality check. It is the fastest way to compare two objects and also no need to worry about null values(if you would use the equals method, which by default just defers to reference comparison anyway, you would have to worry about the order of the operators in order to avoid possible null pointer exceptions).</li>
511 <li>It helps the compiler identify attempts to compare incompatible types which can avoid programming errors that would be identified only at runtime:</li>
512 </ul>
513 <pre><code class="language-java">enum Weekday {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY}
514 enum Color{BLACK, WHITE};
515
516 if(Color.BLACK.equals(Weekday.Monday); // does not throw a compile error since the equals signature specifies Object as the parameter type
517 if(Color.BLACK == Weekday.Monday); // does not compile because the compiler can detect the incompatible types attempting to be compared by reference
518 </code></pre>
519 <p>So to recap, if your function or logic needs to use a parameter or variable of a type that has only certain limited possible values, use an enum, that will make everyone happy.</p>
520 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2019/07/3670yj.jpg" class="kg-image" alt="Enums - one of the underrated features of Java" loading="lazy"></figure><!--kg-card-begin: markdown--><h2 id="thecuriouscaseofthesingleton">The curious case of the Singleton</h2>
521 <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><p>The singleton pattern is used to ensure that a type of object is instantiated once and only once.<br>
522 The classical best practice approach is to use something like the following:</p>
523 <pre><code class="language-java">public class Singleton{
524 private static final Singleton INSTANCE = new Singleton();
525
526 private Singleton(){};
527 public static Singleton getInstance(){
528 return INSTANCE;
529 }
530 public void doSomething(){
531 //do stuff
532 }
533
534 //other methods ...
535 }
536 </code></pre>
537 <p>While this works, there are some issue:</p>
538 <ul>
539 <li>If you want your singleton class to be serializable you need not only have it implement the Serializable interface, but also the <em>readResolve</em> method that will return the singleton value otherwise new instances can be created(this is explained a little more further on)</li>
540 <li>The class could still be instantiated with a new instance through the use of the Reflection API.</li>
541 </ul>
542 <p>In light of these issues Joshua Bloch recommends, in his famous book Effective Java, an even better way of doing things. Since enums guarantee that only the values listed in its definition will ever be instantiated, then a single value enum can act as a singleton. That is possible because in Java the enum allows users to do things similar with what they can for a class definition: you can define methods, fields and even implement interfaces. One of the only things you cannot do with an enum is extend other classes so if you singleton has this requirement then this solution will not work for you.</p>
543 <p>So our example from above would become:</p>
544 <pre><code class="language-java">public enum Singleton{
545 INSTANCE;
546
547 public void doSomething(){
548 // do stuff
549 }
550
551 // other methods
552 }
553 </code></pre>
554 <p>First of all this looks a lot cleaner right? Now how does this solve the 2 problems lister earlier. Let's see:</p>
555 <ul>
556 <li>I will not enter in all the details of how serialization in Java works, but usually when deserializing an object, the deserializer creates a new instance of the object being deserialized with the values from the serialized form. That is why we have to implement the <em>readResolve</em> method which gets called by the deserializer to provide the opportunity to the deserialized object itself to specify what object to return. This is mostly used for handling singletons since the object to be returned is actually in one of its fields and we do not want a new instance since that would break the Singleton property. But enum serialization and deserialization work differently than for normal java objects. The only thing that gets serialized is the name of the enum value even if it has other fields defined. Then on the deserialization side the name is read and since the enum type can have only the values specified in its definition, the enum <em>valueOf</em> method is used with the deserialized name to get the desired instance. So in short, using enums gives you free serializable behavior.</li>
557 <li>The enum type actually extends the java Enum class. The reason that reflection cannot be used to instantiate objects of enum type is because the java specification disallows and that rule is hardcoded in the implementation of the <em>newInstance</em> method of the <em>Constructor</em> class, which is usually used for creating objects via reflection:</li>
558 </ul>
559 <pre><code class="language-java">if ((clazz.getModifiers() & Modifier.ENUM) != 0)
560 throw new IllegalArgumentException("Cannot reflectively create enum objects");
561 </code></pre>
562 <p>So as a best practice, unless one of the caveats from above applies to you, use an enum for you singletons.</p>
563 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2019/07/36716k.jpg" class="kg-image" alt="Enums - one of the underrated features of Java" loading="lazy"></figure><!--kg-card-begin: markdown--><h2 id="astrategyforstrategy">A strategy for Strategy</h2>
564 <p>One of the latest things I realized an enum is actually really useful for is implementing the strategy pattern.</p>
565 <p>Lets have a quick recap of the pattern: The Strategy Pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. The pattern allows the algorithm to vary independently from clients that use it.</p>
566 <p>If that definition sounds to abstract let's showcase its classic implementation with a simple example.</p>
567 <p>First we need to identify a case where we could apply this pattern:<br>
568 Let us imagine we have a bar and since we want to attract customers we have different pricing strategies depending on the time of the day (if when describing the problem you start using the strategy word its a good sign you might consider applying this pattern):</p>
569 <ul>
570 <li>we have the normal hours where clients are charged the full price of what they consume</li>
571 <li>we have the morning happy hour where clients are charged 0.5 of what they consume</li>
572 <li>we have the afternoon happy hour where clients are charged 0.75 of what they consume.</li>
573 </ul>
574 <p>So we define an interface that encapsulates this logic(don't ever use double for this kind of calculations, using them here just for simplicity):</p>
575 <pre><code class="language-java">interface BillingStrategy{
576 double bill(double rawPrice);
577 }
578 </code></pre>
579 <p>Then we define different classes that implement the <em>BillingStrategy</em> interface with specific behavior:</p>
580 <pre><code class="language-java">public MorningHappyHourBilling implements BillingStrategy{
581 double bill(double rawPrice){
582 return rawPrice * 0.5;
583 }
584 }
585
586 public EveningHappyHourBilling implements BillingStrategy{
587 double bill(double rawPrice){
588 return rawPrice * 0.75;
589 }
590 }
591
592 public FullPriceBilling implements BillingStrategy{
593 double bill(double rawPrice){
594 return rawPrice ;
595 }
596 }
597 </code></pre>
598 <p>Then we define a <em>BillCalculator</em> that would be used by the bar:</p>
599 <pre><code class="language-java">BillCalculator {
600 private BillingStrategy billingStrategy = new FullPriceBilling() ;
601
602 public void setBillingStrategy(BillingStrategy billingStrategy){
603 this.billingStrategy = billingStrategy;
604 }
605
606 public void printBill(int price, String customer){
607 System.out.format("Bill for customer %s is %f", customer, this.billingStrategy.bill(price);
608 }
609 }
610 </code></pre>
611 <p>As you can see, now the hypothetical <em>Bar</em> class when using the <em>BillCalculator</em> can modify during runtime the behavior of the calculator whenever it needs, in this case whenever the happy hour interval is present.</p>
612 <p>Now you might say: "this is nice and all, but it brings quite some overhead":</p>
613 <ul>
614 <li>we have to define a new interface</li>
615 <li>we need to define a new class for each possible strategy,</li>
616 </ul>
617 <p>You are right, usually thats the tradeoff when using design patterns, they provide flexibility at the expense of more abstraction overhead. Luckily for this pattern, we can actually do better by using our old friend the enum.</p>
618 <p>Instead of defining an interface, we will define an enum as the type of the BillingStrategy and its values will be the 3 different billing strategies:</p>
619 <pre><code class="language-java">public enum BillingStrategy{
620 MORNING_HAPPY_HOUR{
621 @Override
622 public double bill(double price){
623 return rawPrice * 0.5;
624 }
625 },
626 AFTERNOON_HAPPY_HOUR{
627 @Override
628 public double bill(double price){
629 return rawPrice * 0.75;
630 }
631 },
632 FULL_PRICE{
633 @Override
634 public double bill(double price){
635 return rawPrice;
636 }
637 }
638
639 public abstract double bill(double price);
640 }
641 </code></pre>
642 <p>Now we can redefine our BillCalculator like this:</p>
643 <pre><code class="language-java">BillCalculator {
644 private BillingStrategy billingStrategy = BillingStrategy.FULL_PRICE;
645
646 public void setBillingStrategy(BillingStrategy billingStrategy){
647 this.billingStrategy = billingStrategy;
648 }
649
650 public void printBill(int price, String customer){
651 System.out.format("Bill for customer %s is %f", customer, this.billingStrategy.bill(price);
652 }
653 }
654 </code></pre>
655 <p>A lot cleaner right?</p>
656 <p>As an added bonus, if you are familiar with the State pattern you know that its implementation is basically the same as the Strategy pattern, it differs only in intent and some other specific details, so as a consequence we can also implement that one using the enum technique we showcased above.</p>
657 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2019/07/obama.jpg" class="kg-image" alt="Enums - one of the underrated features of Java" loading="lazy"></figure><!--kg-card-begin: markdown--><h2 id="conclusion">Conclusion</h2>
658 <p>That is all I have for now to share and I hope at least some of you discovered something new reading this.</p>
659 <p>If you have some other great use cases for enums or some insights about them from other languages, let me know.</p>
660 <p>If you enjoyed the article you can subscribe or like our facebook page(do not worry about spam, I write something or post every few months if that):<br>
661 <a href="https://www.facebook.com/pg/banterly.net/posts/">https://www.facebook.com/pg/banterly.net/posts/</a></p>
662 <!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[On developer happiness and where to find it.]]></title><description><![CDATA[<!--kg-card-begin: markdown--><blockquote>
663 <p>"Success is getting what you want, happiness is wanting what you get" - W.P. Kinsella</p>
664 </blockquote>
665 <p>A trend that started in companies for a few years now has been for managers to concern themselves with developer happiness. Today we will explore this topic and try to find out</p>]]></description><link>https://www.banterly.net/2019/01/06/developer-hapiness-and-where-to-find-it/</link><guid isPermaLink="false">5c30fe28a6b7a300c04ad4d8</guid><category><![CDATA[happiness]]></category><category><![CDATA[software]]></category><category><![CDATA[developer]]></category><category><![CDATA[management]]></category><category><![CDATA[jobsatisfaction]]></category><dc:creator><![CDATA[Dragos Barosan]]></dc:creator><pubDate>Sun, 06 Jan 2019 12:22:02 GMT</pubDate><media:content url="https://www.banterly.net/content/images/2019/01/post2-1.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><blockquote>
666 <img src="https://www.banterly.net/content/images/2019/01/post2-1.jpg" alt="On developer happiness and where to find it."><p>"Success is getting what you want, happiness is wanting what you get" - W.P. Kinsella</p>
667 </blockquote>
668 <p>A trend that started in companies for a few years now has been for managers to concern themselves with developer happiness. Today we will explore this topic and try to find out an answer to the following questions:</p>
669 <ul>
670 <li>Why the hell would companies care about developer happiness?</li>
671 <li>What would actually make a developer happy?</li>
672 </ul>
673 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2019/01/download-1.jpg" class="kg-image" alt="On developer happiness and where to find it." loading="lazy"></figure><!--kg-card-begin: markdown--><p>As you read, keep in mind that this is not supposed to be an absolute truth that everyone should obey. I will just share some ideas based on several discussions with people in the industry mixed in with some of my own ideas and, on purpose, I will leave a blurred line between the two.</p>
674 <p>The ideas expressed will probably be biased towards the western society, since that is where I live. People in different geographical areas with different cultures may have a complete opposite perception on the topic at hand.</p>
675 <p>If anyone wants to express some insights from different perspectives I encourage you to do so in the comments.<br>
676 With this small disclaimer in place lets see what we have here.</p>
677 <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h2 id="whydeveloperhappiness">Why developer happiness?</h2>
678 <p>First question you may have is: why am I talking about developer happiness and not employees happiness in general? Two main reasons are outlined bellow.</p>
679 <p>First of all, development is my profession right now, so I know most about this specific niche of employee happiness.</p>
680 <p>Secondly, the thing is that in general companies do not care that much about employee happiness(of course there are exceptions), unless they can directly correlate it with an increase of profits.<br>
681 The reason why developers are these days in the privileged position of companies starting to care about their work happiness is due to the fact that there is a high demand for their skills in the market and a limited supply that still does not match that demand, although in the future things may change with more and more people going into the computer science curriculum.</p>
682 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2019/01/download--2-.jpg" class="kg-image" alt="On developer happiness and where to find it." loading="lazy"></figure><!--kg-card-begin: markdown--><p>This status quo means that developers have a lot more opportunities in moving across companies if they are not happy in their current one, a situation that can quickly turn into a high turnover rate for a company that does not try to have some prevention policies in place.</p>
683 <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h2 id="thecostsofahighturnoverrate">The costs of a high turnover rate</h2>
684 <p>So why would a company care if it has a high turnover rate, cant they just replace a leaving employee with a new one? Well there some costs associated with this process, both real costs(i.e. direct costs) and opportunity costs(i.e. indirect costs). I list some bellow, but if I miss anything please let me know in the comments.</p>
685 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2019/01/graphic_for_blog_employeeturnover.png" class="kg-image" alt="On developer happiness and where to find it." loading="lazy"></figure><!--kg-card-begin: markdown--><p><a href="https://www.vocoli.com/blog/january-2015/the-hidden-costs-of-employee-turnover-and-how-to-reduce-it/">Image Source</a></p>
686 <h4 id="directcosts">Direct costs:</h4>
687 <ul>
688 <li>Recruiter fees - when using external recruiters their fee is usually between 15 and 30 percent of the new hires first year salary.</li>
689 <li>Advertising the open position on different channels like job websites, linkedin or other social media.</li>
690 <li>In some cases external training for the new employee.</li>
691 <li>Travel expenses if the candidate is brought in from a foreign country for the interview.</li>
692 </ul>
693 <h4 id="indirectcosts">Indirect costs</h4>
694 <ul>
695 <li>Loss of productivity caused by the team having one less member.</li>
696 <li>Loss of productivity caused by team members interviewing candidates.</li>
697 <li>Even after a good candidate is found, there will be extra loss of productivity while the new hire gets accustomed to the project, company processes and tools. If the old employee has been working for quite a while in the company, the gap of knowledge he leaves will take a lot more time to fill in.</li>
698 <li>A high turnover rate also impacts the morale of the other employees which can result in a further decrease of productivity.</li>
699 <li>A place with a high turnover rate may become infamous in the job market as an unhappy workplace and could make it even more difficult to replace someone, driving up both the direct and indirect costs.</li>
700 </ul>
701 <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h2 id="whatcancompaniesdoaboutit">What can companies do about it?</h2>
702 <h4 id="numbersanddata">Numbers and data</h4>
703 <p>Some companies may still not look seriously at the problem of employee retention since the indirect costs will most probably not appear on the balance sheets that end up on the desk of the upper management at the end of the year, and these hidden costs may far outweigh the direct costs, but are harder to quantify into a concrete number. So the first step to take would be to try to make rough estimates of the total costs of replacing an employee. With a concrete number in hand to raise the alarm, upper management will be more incentivized to take action.</p>
704 <h4 id="theexitinterview">The exit interview</h4>
705 <p>Secondly they should have in place the so called exit interviews: a talk with an employee who decided to leave in which he can be asked about what determined him to take the decision of moving on to a different place.</p>
706 <p>This activity should be carefully planned since it is easy to gather false data from it. For example some employees may want to leave on a good relationship with the company so will not express all of his complaints or he may leave because they do not like the manager and if the manager is the one handling the exit interview of course that will lead to a situation with no benefits for either party.</p>
707 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2019/01/exit.PNG" class="kg-image" alt="On developer happiness and where to find it." loading="lazy"></figure><!--kg-card-begin: markdown--><p><a href="https://timewellspent.kronos.com/">Image Source</a></p>
708 <p>The exit interview is useful not only to find causes of dissatisfaction, but to also avoid false positives: it could turn out that a spike in turnover rate over a period may have nothing to do with the happiness of the employees, but it just happened that by coincidence multiple persons had personal reasons for leaving, not workplace related(e.g. moving back to their native country, moving to an office closer to their home to shorten the commute time, starting their own business or moving on to a freelancer career path etc).</p>
709 <h4 id="awareness">Awareness</h4>
710 <p>Of course another action point would be to have a pulse of all employees feelings about their work status by continuously gathering this kind of data. This can be done either through 1 on 1 meetings between employees and managers, on-line surveys or office gatherings of the teams in which they can express themselves.</p>
711 <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h2 id="whatbringsdeveloperhapiness">What brings developer hapiness?</h2>
712 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2019/01/x11.png" class="kg-image" alt="On developer happiness and where to find it." loading="lazy"></figure><!--kg-card-begin: markdown--><p><a href="https://xkcd.com/963/">Image Source</a></p>
713 <h3 id="money">Money</h3>
714 <p>Lets first get rid of the elephant in the room. Usually when companies come up with initiatives to raise developer happiness, what they mean is doing that without increasing monetary compensation. Some of them do this because they do not have the money, some just because they want to save costs in order to increase profits and others because they do not consider that to be an effective retention strategy.</p>
715 <p>There are a couple of points to be made here. First is that some people will always seek as much as an increase possible in their compensation and truly not care about anything else. Others, which I think is the majority, once they reach a level that can sustain the lifestyle they desire, will not care as much about an increase in compensation as they care about other factors which I will list later. Of course this satisfactory compensation level can vary greatly from person to person so few assumptions can be made here. Usually people who are in their first couple of years in their careers will not be at the level they desire so they are the most likely to look for significant salary increases.</p>
716 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2019/01/156_large.jpg" class="kg-image" alt="On developer happiness and where to find it." loading="lazy"></figure><!--kg-card-begin: markdown--><p>It is known that the best method to increase your salary significantly is to leave for another company, since internal increases are usually 2 or 3 times smaller than by the ones gained through job switching. This is somewhat a weird situation considering the high cost of replacing someone as I explainer earlier. Taking the previous 2 facts into account we can infer that this is one of the reasons which contributes to higher turnover rate in younger developers rather than in more senior ones.</p>
717 <p>Of course there are companies who just cant afford to pay as much money as some of the bigger corporations can. Their main option is to compensate the difference in some other ways: startups give a decent part of equity of the company as an incentive, others give a lot more free days, shorter working hours or complete flexibility to the employee in term of his working schedule.</p>
718 <p>Another aspect worth mentioning is that even if an employee is satisfied with his current level of compensation, if he constantly hears from friends in the industry and on-line sources how much more money is being offered for a similar position as his in another company, then he will start thinking about jumping the boat, so companies should at least be careful to match the average compensation for the sector in whatever geographical area they are based.</p>
719 <p>One last point regarding this topic is that an increase in salary is like an instant gratification pill of happiness. It feels great, but the feeling wears off quickly. If the increase happens only once a year, the happiness caused by the increase will for sure disappear well before the next one. As a consequence, many advocate for multiple smaller increases spread out throughout the year. This would also coincide with a policy of continuous performance reviews instead of the classical end of year review.</p>
720 <p>I guess there is more to say about this aspect so let me know in the comments of what you think.</p>
721 <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h3 id="management">Management</h3>
722 <p>In the end probably most of the other subjects can be tied to this one, but here I am specifically targeting managers as individuals and their behavior.</p>
723 <p>For a developer there are two aspects to this topic</p>
724 <ul>
725 <li><strong>his direct manager</strong> - the one to whom he directly reports</li>
726 <li><strong>upper management</strong> - the ones that control the company and its finances.</li>
727 </ul>
728 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2019/01/humor10.png" class="kg-image" alt="On developer happiness and where to find it." loading="lazy"></figure><!--kg-card-begin: markdown--><h4 id="directmanager">Direct manager</h4>
729 <p>This relationship is very important since, for a developer, his direct manager is basically the interface between him and the company.<br>
730 Because of this, when talking about loyalty, the developer will most of the time be loyal to his manager and not to the company. Managers that cannot foster that sense of loyalty towards them will have a higher turnover rate in their teams.</p>
731 <p>An employee wants to feel appreciated, trusted and cared for by the company and that is his managers responsibility to convey to him. Most of the time that would translate in making time for frequent 1 on 1 meetings, fighting with upper management to satisfy the desires of the team, advising him on the path to career growth and creating a relaxed working environment.</p>
732 <p>In a lot of cases, what the employee wants will go against the desires of the company and that is why being a good manager is a difficult job, you have to reconcile these two different agendas.</p>
733 <p>In Daniel Pinks book <em><strong>Drive</strong></em> it is argued that the best thing to do to motivate someone is to create and amplify his intrinsic drive via 3 axis:</p>
734 <ul>
735 <li>Autonomy - Everyone wants to express himself and have a degree of freedom in his actions. Some examples that would satisfy this need are: official free time for the developer to work on whatever he wants or learn something new that is not directly tied to his day to day job, flexible working hours, contributing to the design of the features and products, not only implementing them.</li>
736 <li>Mastery - developers want to get better at what they do and need their managers guidance in order to achieve this growth. One proven way to do this is using Goldilocks assignments: assignments that are not very easy since that would lead to boredom and lack of motivation, but also not too hard since that would lead to high anxiety and probably poor results. On this axis the developer also wants to feel that focus is also put on quality not only on number of features since that would allow him to show off is increasing mastery of the domain.</li>
737 <li>Purpose - Everyone needs a purpose for what they are doing. If in a team the only reason why developers come to work is money, then that company will probably not have the most engaged people and will also have to provide salaries higher than average to attract people. The purpose can be a company wide one, but managers can create a purpose specifically for their team which will further motivate and engage the team members. Once this purpose is clearly identified it should be ubiquitous(start every meeting with it, have some poster with it in the team working place) in order to always remind everyone of the importance of their work. The purpose has to be a believable one otherwise it can backfire and everyone will just think its some corporate bs.</li>
738 </ul>
739 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2019/01/tools.png" class="kg-image" alt="On developer happiness and where to find it." loading="lazy"></figure><!--kg-card-begin: markdown--><p><a href="https://xkcd.com/1629/">Image Source</a></p>
740 <h4 id="uppermanagement">Upper management</h4>
741 <p>No matter how hard the direct manager tries, if the people in control of the company and its finances will see the development offices as a cost center instead of a profit center, then the developers will fully feel the consequences of that attitude: there wont be any budget for trainings, conferences, tools or team events. Most often this attitude is present in industries that do not have technology as their core product that is being sold to customers, with a simple example being the banking industry, although these days things are starting to change.</p>
742 <p>One of the most cited problems from developers perspective about big companies management is a lack of transparency regarding decisions made and lack of accountability for those decisions. There are numerous cases of tools or technology stacks being chosen for different projects in companies without a clear explanation of why they were chosen, they are just imposed on the developers. And when further down the line those tools and stacks clearly provide a big impedance to productivity, the persons actually responsible for those decisions are either already promoted to another project or nobody dares to touch them. Involving developers in the decisions that will affect their day to day job seems almost like a no-brainer, but few of the bigger companies do that in a transparent and meaningful way.</p>
743 <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h3 id="benefits">Benefits</h3>
744 <p>Benefits are an excellent way to provide extra value to employees in a cheaper and more efficient way than higher pay. For one thing benefits are not taxed the way an increase in salary is taxed so the employee will get a lot more than if the money would be invested towards their compensation. So allocating a budget for an employee to attend conferences, trainings or to cover his commute travel expenses could end up being a win win situation for both the employee and employer. The list of which benefits are taxed and which not varies per country so check it out with your local tax authority.<br>
745 Another thing is that some benefits scale better than salary increases: having fresh fruits every day in the office or installing a relaxation zone with different games can have the same effect that a small increase in pay to all employees would bring, but at a fraction of the cost.</p>
746 <!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h3 id="thelistofdeveloperhappinessgenerators">The list of developer happiness generators</h3>
747 <!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://www.banterly.net/content/images/2019/01/12e6636aadbe2f3795384f42bc822c7f--work-week-cyanide-happiness.jpg" class="kg-image" alt="On developer happiness and where to find it." loading="lazy"></figure><!--kg-card-begin: markdown--><p><a href="https://www.pinterest.es/pin/351703052126011841/">Image Source</a></p>
748 <p>Since this article became longer than I wanted I will leave you with a compiled list of stuff that can improve developer happiness and which I did not discuss in a lot of detail:</p>
749 <ul>
750 <li>Team events, not only company events - team events are usually more personal and bonding than company events.</li>
751 <li>Minimal bureaucracy - No need for 5 committees approval for each small request.</li>
752 <li>Communication and interaction with customers - it brings a lot of joy to know your customers and to hear from them how are they using what you built. It also brings motivation to do better for them once you have concrete face behind the abstract concept of users.</li>
753 <li>Flexible schedule - no hard enforced scheduled working hours, allow working from home sometimes</li>
754 <li>Good tools - The easier it is to use the tools required to do the job the happier and eager will the developer be to start working on a task. If possible the best is to let him use the tools he desires(or the team desires)..</li>
755 <li>Office where you can focus when you work. That is why a lot of developers are opposed to open office plans.</li>
756 <li>Properly equipped office: 2 monitors(or 1 big one), a nice chair, a good laptop etc.</li>
757 <li>Good work life balance - when developers start having families this becomes even more important.</li>
758 <li>Management transparency - clear communications on why certain decisions are made. As mentioned if developers could also have their voice heard for aspects that affects their job, it would be even better.</li>
759 <li>Clear responsibilities of persons in the company and clear examples that good decisions and behaviors are rewarded while bad ones are punished.</li>
760 <li>Investment in human resources</li>
761 </ul>
762 <!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[The fatal flaw of blockchain]]></title><description><![CDATA[Today I want to talk about something else, about a realization that I had somewhere during this year that ultimately led me to give up on this technology, even though I was quite invested in it for a while. ]]></description><link>https://www.banterly.net/2018/07/29/the-fatal-flaw-of-blockchain/</link><guid isPermaLink="false">5b5c1c0ded2fa500bf626dad</guid><category><![CDATA[blockchain]]></category><category><![CDATA[ethereum]]></category><category><![CDATA[technology]]></category><category><![CDATA[cryptocurrencies]]></category><dc:creator><![CDATA[Dragos Barosan]]></dc:creator><pubDate>Sun, 29 Jul 2018 22:33:15 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><blockquote>
763 <p>"Conceal a flaw, and the world will imagine the worst" - Marcus Valerius Martial</p>
764 </blockquote>
765 <p>In my <a href="https://www.banterly.net/2016/12/31/blockchain-beyond-the-hype-of-bitcoin-and-ethereum/">previous post</a> about blockchain I touched on how blockchain works with the hope that it will help some of you guys understand at a quick glance what is it all about. For those that wanted a deep dive in the subject I also created a blockchain <a href="https://www.banterly.net/2018/02/21/why-have-i-been-gone-for-so-long/">course on udemy</a> which is available for free right now.</p>
766 <p>Today I want to talk about something else, about a realization that I had somewhere during this year that ultimately led me to give up on this technology, even though I was quite invested in it for a while. This realization is why I now think that the technology is deeply flawed and most probably it will not succeed, except for maybe some very fringe applications.</p>
767 <h2 id="shortblockchainrecap">Short blockchain recap</h2>
768 <p>In case you were too lazy to go to any of the resources indicated above, let me do a very very quick summary on the main concept of blockchain, not going in the technical details.</p>
769 <p><img src="https://www.banterly.net/content/images/2018/07/Capture.PNG" alt="Capture" loading="lazy"><br>
770 <a href="https://medium.com/creativeblockchain/the-blockchain-illustrated-6e8bc80a217c">Source</a></p>
771 <p>The main idea of blockchain is that of decentralization, more specifically, the idea being promoted is that you can construct a decentralized and distributed system which you can just trust without making use of any 3rd centralized party. The main construct behind this system is a distributed database, or distributed ledger how it is usualy called in the blockchain world. This ledger is not controlled by any one entity, but as a whole by the majority of the node of the network (miners in blockchain terms).</p>
772 <p>Truth be told, there are <strong>a lot</strong> of problems with blockchain technology at this moment. Just to mention a few:</p>
773 <ul>
774 <li><strong>No proven use cases</strong> - even as a currency it arguably failed for now due to the high fees and price instability</li>
775 <li><strong>No proven scalability solution</strong> - a few solutions are being proposed or in early adoption, but nothing proven is out there for now to match the number of transactions per second that credit card companies can do, while at the same time keeping the advertised properties of blockchain</li>
776 <li><strong>No proven solution for private data storage</strong> - there are some advanced cryptomagic solutions being proposed and tested, but no proven and usable solutions exists for now so most information on the blockchain is public and accessible to everyone</li>
777 <li><strong>The tendency of blockchain networks to become centralized</strong> - the emergence of corporations with datacenters constructed solely for mining cryptocurrencies and the emergence of large mining pools are one of the main causes.</li>
778 </ul>
779 <h2 id="decentralizationatadisadvantage">Decentralization at a disadvantage</h2>
780 <p>Actually, arguably the only success stories in the blockchain world, Bitcoin and Ethereum, are worse than their centralized counterparts in every technical comparison point possible: a lot slower, a lot less user friendly and less stable/resilient.</p>
781 <p>The only advantage they could claim is that they operate in a trustless decentralized environment. Besides the fact that this claim can actually be argued to not be true (at least not completely), is this property actually worth trading for all the other benefits that usually centralized systems come with? Some may argue that yes, but I dare to say that the majority of the population will not agree.</p>
782 <p>I am not saying decentralization is bad, just that centralized systems usualy offer better performance and user experiences than their decentralized ones. I am sure if all other aspects were equal then decentralization would win, but as history proves, for the reasons mentioned above, most of us migrated to centralized service providers: Facebook or Twitter for social networking, Youtube for video sharing or Amazon for shopping.<br>
783 The internet itself, which was considered the go-to model of a decentralized system, is now considered quite centralized with a surprisingly small number of ISPs controlling the flow of traffic across the globe.</p>
784 <h2 id="beingoptimisticdidnothelp">Being optimistic did not help</h2>
785 <p>Even with all this problems being evident to me, I wanted to ignore them and be optimistic, because I saw that a lot of money was being thrown into researching new solutions for these problems, attracting a lot of smart people that could maybe provide a decentralized experience on par with the centralized one.<br>
786 It is true that this money also attracted a lot of scammers who got rich by taking advantage of people believing that they could switch the economic classes around by buying cryptocurrencies or investing in ICOs with the hope of becoming the new oligarchs and the old ones becoming poor once the cryptocurrency revolution would complete (This is actually a very interesting topic for another time).</p>
787 <p><img src="https://www.banterly.net/content/images/2018/07/there-amp-039-re-time-where-i-amp-039-m-being-way-too-optimistic_o_4298771.jpg" alt="there-amp-039-re-time-where-i-amp-039-m-being-way-too-optimistic_o_4298771" loading="lazy"></p>
788 <p>I realized that even when ignoring all these issues, there is one problem of blockchain that cannot be solved by any technical solution. This is because the issue is rooted in the core of the technology and once you take that out you don't really have a blockchain technology to speak of.</p>
789 <h2 id="thehypegeneratingpromise">The hype-generating promise</h2>
790 <p>Let us assume we have the perfect blockchain system: scalable, fast, good privacy, easy to use and completely decentralized. I said earlier that such a blockchain system is basically, from the users point of view, a public decentralized ledger that they can trust. And why can they trust it? It is because of a property that is always associated in media circles (and not only) with blockchains and with the ledger it provides: Immutability. The narrative goes that everyone can trust a blockchain system because it ensures, with its underlying magic, that the data it stores cannot be altered.</p>
791 <p>I am here to tell you that things are not so black and white. It is actually one of the misconceptions that acts as a litmus test for me to see if someone talking about blockchain really has any idea about it.</p>
792 <p><img src="https://www.banterly.net/content/images/2018/07/thecakeisalie.jpg" alt="thecakeisalie" loading="lazy"></p>
793 <h2 id="thenotsohypegeneratingtruth">The not so hype-generating truth</h2>
794 <p>My guess is that this misconception comes from the fact that the technology uses as an underlying data structure the blockchain, which indeed is immutable in the sense that you cannot alter anything from previous blocks since the chain of hashes would not match anymore.</p>
795 <p>But if we think in terms of the distributed ledger that is constructed on top of the blockchain, we can change the ledger very well with hard forks. Usually this hard forks can only happen with the agreement of the majority of the miners.</p>
796 <p><img src="https://www.banterly.net/content/images/2018/07/9wsxhj0rhstz.png" alt="9wsxhj0rhstz" loading="lazy"><br>
797 <a href="https://www.reddit.com/r/Bitcoin/comments/78g5k2/how_bitcoin_forks_proliferate_xkcd_edit/">Source</a></p>
798 <p>This leads me to the following statement which I think everyone needs to remember as a rule for every future interaction they will have with this technology:</p>
799 <blockquote>
800 <p>The blockchain distributed ledger is not immutable, it is just a collection of facts on which the majority agrees, but if the majority agrees to change the facts then they can do that.</p>
801 </blockquote>
802 <h2 id="decentralizationhelps">Decentralization helps...</h2>
803 <p>Following this rule, we can see why private blockchains (all miners controlled by one entity) don't make any sense. There is no magic happening here, if one entity controls all the miners then it can decide to do whenever they want forks in order to change history or the rules of the chain. A fully private blockchain represents a fully mutable distributed ledger. It is basically a completely inefficient database, so next time you hear your boss talking about stuff like this please confront him and present the facts.</p>
804 <p>That is why most people will tell you it is important for the majority to be distributed as much as possible between multiple entities, it reduces the risk of agreements on changing history. Notice I said it reduces risk, not that it eliminates it. Even with our perfect blockchain network, completely decentralized across a very large number of miners, there is a chance that a hard fork will happen and change the previously agreed upon facts.</p>
805 <h2 id="theissueemerges">The issue emerges</h2>
806 <p>We need to realize that ultimately this ledger's underlying infrastructure (the miners) is run by human beings, not by some algorithmic machines. And human beings, even if they are independent of each other, tend to align their ideas in some area of interest to a few possible choices. As an example think of political parties, only 4 or less strong parties exist in most democratic countries, even though there are tens of millions of independent voters.</p>
807 <p>That is all fine until we realize that this effect may intersect with the functioning of the blockchain system. It may very be the case that some event happens that makes the majority of the miners (even though independent entities) to have a common interest in changing the history of the blockchain. In that case all the hyped immutability of the blockchain is gone. This was the truth that struck me: even with completely decentralized blockchain environments, majorities can can formed. And once you have that, you basically get a dictatorship of the majority.</p>
808 <h2 id="historyalreadytaughtus">History already taught us</h2>
809 <p>You may say that this is all hypothetical and the chances of this actually happening are close to nonexistent. The thing is, it has already happened. We just have to look a couple of years ago and find the infamous DAO hack event.</p>
810 <p><img src="https://www.banterly.net/content/images/2018/07/2ewqau.jpg" alt="2ewqau" loading="lazy"></p>
811 <p>Short summary of what happenened then:</p>
812 <ul>
813 <li>The DAO is setup on the Ethereum blockchain network.</li>
814 <li>The DAO gathers from its crowdsale 150 million dollars worth of ether.</li>
815 <li>A hacker takes 50 million dollars worth of ether from the DAO using a security hole in the DAO smart contracts.</li>
816 <li>In fear of Ethereum losing further investors and to maintain the value of Ether, the Ethereum community <em>"decides"</em> to break the promise of immutability and alter the blockchain. A hard fork was done making it so that every investor gets his money back.</li>
817 </ul>
818 <p>The reason why I put "decides" between quotes is because the way it was handled cannot be considered fully transparent. Ultimately the miners had to decide for the hard fork and the process for this is quite controversial. In order to mine the old chain, the miners had to put a special parameter at the start of the miner software, while if they started the software like they would always do with no parameter, they would implicitly vote for the hardfork. Basically miners who for some reason did not vote at all were counted as voters for the hardfork.</p>
819 <h2 id="thefatalflaw">The fatal flaw</h2>
820 <p>With the previous example in mind I hope you realize, the same way I did, the problem: the skeleton of the blockchain system is made by humans, and not by some sort of elite, but by the masses (since everyone can become a miner). Masses usually don't make decisions based on reality, facts or long term consequences, most people make decisions on the basis of social identities, partisan loyalties and quick personal gains.</p>
821 <p><img src="https://www.banterly.net/content/images/2018/07/1526884_555108344578264_1517449958_n-1.jpg" alt="1526884_555108344578264_1517449958_n-1" loading="lazy"></p>
822 <p>If you think about it, this does not sound like the kind of decision making you would depend on to properly manage your money, properties, freedom, voting, medical information and all other things considered as blockchain applications...</p>
823 <p>...except that is exactly on what blockchain systems are based on.<br>
824 And this is the <em><strong>fatal flaw</strong></em> of blockchain.</p>
825 <!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Mastering blockchain-beyond cryptomania now live on Udemy!]]></title><description><![CDATA[I got the inspiration of sharing the knowledge with a lot more people, just like I wanted to do with this blog and Udemy was a platform that I used in the past and looked like the perfect place to create content for an online course. ]]></description><link>https://www.banterly.net/2018/02/21/why-have-i-been-gone-for-so-long/</link><guid isPermaLink="false">5a8d20ee809a68002240f7f1</guid><category><![CDATA[blockchain]]></category><category><![CDATA[udemy]]></category><category><![CDATA[course]]></category><category><![CDATA[cryptocurrencies]]></category><dc:creator><![CDATA[Dragos Barosan]]></dc:creator><pubDate>Wed, 21 Feb 2018 07:50:21 GMT</pubDate><media:content url="https://www.banterly.net/content/images/2018/02/1518936808342855--2-.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://www.banterly.net/content/images/2018/02/1518936808342855--2-.jpg" alt="Mastering blockchain-beyond cryptomania now live on Udemy!"><p>Hi guys, my last post here was a while ago and if anyone is wondering why this big gap, well there are two reasons:</p>
826 <ol>
827 <li>I was in the process of changing jobs in that period so it took quite a big chunk of my time for a couple of months.</li>
828 <li>I was working on a project that I am finally proud to announce is live: A course on blockchain technologies on the Udemy platform.</li>
829 </ol>
830 <p>After I held a guest lecture at my former master program on the topic of cryptocurrencies and blockchain, I got the inspiration of sharing the knowledge with a lot more people, just like I wanted to do with this blog and Udemy was a platform that I used in the past and looked like the perfect place to create content for an online course.</p>
831 <p>After more than 4 months of work, I am proud to present:</p>
832 <h2 id="masteringblockchainbeyondcryptomania">Mastering blockchain - Beyond cryptomania</h2>
833 <iframe width="560" height="315" src="https://www.youtube.com/embed/SBdw5NVD8RI" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
834 <p>Since you are a reader of mine, I will offer you special limited (100 enrolments available for now) free access to the course. You can access it with a special 100% off discount by using the following link:<br>
835 <a href="https://www.udemy.com/mastering-blockchain-beyond-cryptomania/?couponCode=BLOGFREE">https://www.udemy.com/mastering-blockchain-beyond-cryptomania/?couponCode=BLOGFREE</a></p>
836 <p>Can't wait to see you on the course and have your feedback.</p>
837 <!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[I'm not dead :)]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Hi guys, this is just a short update that I have not forgotten about this blog and I will keep posting articles.</p>
838 <p><img src="https://www.banterly.net/content/images/2017/07/download-1.jpg" alt="It's true!" loading="lazy"></p>
839 <p>I was just busy in the last months with multiple things, but I am preparing something big for the end of August. I will keep you updated.</p>
840 <p>In</p>]]></description><link>https://www.banterly.net/2017/07/23/im-not-dead/</link><guid isPermaLink="false">5a8aec0b421f76001702e0c7</guid><dc:creator><![CDATA[Dragos Barosan]]></dc:creator><pubDate>Sun, 23 Jul 2017 13:20:33 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Hi guys, this is just a short update that I have not forgotten about this blog and I will keep posting articles.</p>
841 <p><img src="https://www.banterly.net/content/images/2017/07/download-1.jpg" alt="It's true!" loading="lazy"></p>
842 <p>I was just busy in the last months with multiple things, but I am preparing something big for the end of August. I will keep you updated.</p>
843 <p>In the meantime you can now follow me on my new twitter account and I will leave you with a nice song to enjoy your day.</p>
844 <iframe width="560" height="315" src="https://www.youtube.com/embed/K1b8AhIsSYQ" frameborder="0" allowfullscreen></iframe><!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[The Monty Hall problem explained]]></title><description><![CDATA[<!--kg-card-begin: markdown--><blockquote>
845 <p>"If something doesn't make sense it means that one of your assumptions is wrong" - Gregory House</p>
846 </blockquote>
847 <p>If you want to present to your friend a problem that he will probably get wrong, you do not have to look for advanced physics problems, google interview questions</p>]]></description><link>https://www.banterly.net/2017/02/11/the-monty-hall-problem-explained-2/</link><guid isPermaLink="false">5a8aec0a421f76001702e0c0</guid><category><![CDATA[puzzle]]></category><category><![CDATA[probabilities]]></category><category><![CDATA[brain-teaser]]></category><category><![CDATA[monty hall]]></category><category><![CDATA[math]]></category><category><![CDATA[fun]]></category><dc:creator><![CDATA[Dragos Barosan]]></dc:creator><pubDate>Sat, 11 Feb 2017 21:02:08 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><blockquote>
848 <p>"If something doesn't make sense it means that one of your assumptions is wrong" - Gregory House</p>
849 </blockquote>
850 <p>If you want to present to your friend a problem that he will probably get wrong, you do not have to look for advanced physics problems, google interview questions or Sherlock Holmes mysteries. No...it is enough to look at a family friendly game show that makes you pick a door.</p>
851 <p>Of course the previous paragraph alludes to the (in)famous Monty Hall Problem, named after the original host of the <em><strong>Let's make a deal</strong></em> TV show. He presented to the contestants a similar challenge (I do not know how true this is since I was not around back then). It was formulated by a reader of Parade magazine and answered by Marilyn vos Savant.</p>
852 <p><img src="https://www.banterly.net/content/images/2017/02/MHDealPromo5x7.jpg" alt loading="lazy"></p>
853 <p>It is renowned not only because of its counter-intuitive answer, but also because of its reputation of making even people with a certain certified intellectual value (e.g. a PhD degree) disagree with the answer once it is revealed. Here are some samples of the original letters Savant received after she published her answer (you can find more on her <a href="http://marilynvossavant.com/game-show-problem/">site</a>):</p>
854 <blockquote>
855 <p><em>May I suggest that you obtain and refer to a standard textbook on probability before you try to answer a question of this type again?</em> - Charles Reid, Ph.D. University of Florida</p>
856 </blockquote>
857 <blockquote>
858 <p><em>Maybe women look at math problems differently than men.</em> - Don Edwards Sunriver, Oregon</p>
859 </blockquote>
860 <blockquote>
861 <p><em>I am sure you will receive many letters on this topic from high school and college students. Perhaps you should keep a few addresses for help with future columns.</em> - W. Robert Smith, Ph.D. Georgia State University</p>
862 </blockquote>
863 <p>I am sure everyone who tried to present this problem to their acquaintances got similar responses.</p>
864 <p>What I will do in this article is present the problem and answer it. Most importantly, I will then try to show as many as possible explanations with the hope that at least one will trigger the illuminating "Aha!" moment that I think is so wonderful when trying to understand a tricky subject.</p>
865 <h3 id="themontyhallproblem">The Monty Hall Problem</h3>
866 <p>The story goes like this:</p>
867 <p><img src="https://www.banterly.net/content/images/2017/02/Capture2.PNG" alt loading="lazy"></p>
868 <p><img src="https://www.banterly.net/content/images/2017/02/Capture.PNG" alt loading="lazy"></p>
869 <p><img src="https://www.banterly.net/content/images/2017/02/Capture-1.PNG" alt loading="lazy"></p>
870 <p><img src="https://www.banterly.net/content/images/2017/02/Capture-2.PNG" alt loading="lazy"></p>
871 <p>This is it. The famous Monty Hall problem resumes to the simple question: Is it better to switch or to stay with your original choice ?(of course assuming you want to win the car, although I can't blame those who would choose the goat over the car).</p>
872 <p>Think of what you would do and go on and read the next of the article afterwards.</p>
873 <h3 id="thesolution">The solution</h3>
874 <p><img src="https://www.banterly.net/content/images/2017/02/359b162052a6a1ab3eca8f54f858e14156ca3f1f0b9b7b31c7aa258f80a57426.jpg" alt loading="lazy"><br>
875 Maybe surprisingly for some, the answer is that it is always better to switch. In fact, you double your chances of winning if you switch rather than stay with you original choice. With switching you have 66.6% chance of winning the car, while not switching gives you a 33.3% chance of winning.</p>
876 <h3 id="explanationsranked">Explanations Ranked</h3>
877 <p>I will next rank all the explanations that I am aware of. Please post other ones in the comments if you have good ones.</p>
878 <h4 id="5informationmatters">5. Information Matters</h4>
879 <p>Many people have the misconception that since there are two doors, then the chances of either having the car is 50%. That is because it is so deeply embedded in the human intuition that the probabilities are evenly distributed among the number of unknowns. This is also reinforced by the fact that if a player switches 50% of the time, he will indeed win 50% of the time.</p>
880 <p>One of the sources for this mistake is that people disregard the fact that information was actually given to them by Monty Hall when he reveals one of the goats. When you first pick your door you have a \(\frac{1}{3}\) chance of getting the right door. Then when Monty opens one of the remaining two doors, he will reveal a goat. Basically the remaining door has defeated in the battle of probability the one with the goat and stole its odds, becoming a \(\frac{2}{3}\) favorite against your door.</p>
881 <h4 id="4takeallpossiblecases">4. Take all possible cases</h4>
882 <p>An easy way to explain this will be to ask the non believer to take all the possible cases and see what is the result. This is illustrated in the simple diagram bellow:</p>
883 <p><img src="https://www.banterly.net/content/images/2017/02/Capture-3.PNG" alt loading="lazy"></p>
884 <p>As you can see, if you do not switch, you can only win if you initially picked the car. If you switch, you win if you picked the goat initially. The latter is twice as likely to happen than the former, since there are 2 goats in the game and only one car.</p>
885 <h4 id="3multipledoors">3. Multiple doors</h4>
886 <p>This explanation is where most of the people realize that they were actually fooled by Monty's shenanigans. Imagine that instead of 3 doors there are 100 doors. You still pick 1 of them randomly with the chance of it hiding the car being 1%. From the remaining 99 doors, Monty opens all of them except one. Do you still think there is a 50% chance between your door and the remaining door ? Don't you get the feeling that there is something special about that door not being opened, while 98 other doors were opened ? Remember your door does not have the same special status since it was protected from being opened by the fact that you chose it and Monty was not allowed to open it.</p>
887 <h4 id="2tryityourself">2. Try it yourself</h4>
888 <p>Another great way to convince you of the truth is to try this experiment. Luckily it is very easy to do so. You can go to this <a href="http://www.stayorswitch.com/">link</a> and play the game. The site aggregates the results of all those who played. You will see that the theoretical result matches with the real one.</p>
889 <h4 id="1doingthemath">1. Doing the math</h4>
890 <p>Now we get to the serious part.</p>
891 <p>As a warning, skip this part if you are not a fan of probabilities and math. I am not a mathematician, so any feedback regarding the rigorosity of this proof is welcomed. Still reading? Good. Let's do this.</p>
892 <p><img src="https://www.banterly.net/content/images/2017/02/14608107_1180665285312703_1558693314_n.jpg" alt loading="lazy"><br>
893 This is actually not trivial, even though it does look like a very simple problem at first glance. The main difficulty comes in defining the right model to do our analysis, so we will start with that.</p>
894 <p>We will use <a href="https://en.wikipedia.org/wiki/Random_variable">random variables</a> to model the possible choices in this game. There are 4 that have a role here:</p>
895 <ul>
896 <li>D: the the door containing the car.</li>
897 <li>P: the first door selected by the player.</li>
898 <li>H: the door opened by the host.</li>
899 <li>X: the final door selected by the player.</li>
900 </ul>
901 <p>Since each variables will represent a door, they can only have as possible values the doors identifiers: 1, 2 and 3(or A,B and C as in the pictures, but it is a little bit clearer with numbers).</p>
902 <p>We will now impose some restrictions based on some common sense:</p>
903 <ul>
904 <li>The first thing you will notice is that the host cannot open a door that is selected by the player, so <strong>P ≠ H</strong> and <strong>X ≠ H</strong>.</li>
905 <li>The second thing to notice, and this is very important, is that the host will not open the door with the car. This is the main source of controversy for some that assume that he can open the door with the car. To be fair the <a href="http://marilynvossavant.com/game-show-problem/">original enunciation</a> of the problem is not very clear about this aspect. In conclusion <strong>D ≠ H</strong>.</li>
906 </ul>
907 <p>It is fair to assume that the car is randomly hidden behind one of the doors, which leads to a uniform distribution with an equal chance for each door to hide the car. Taking that into account, the <a href="https://en.wikipedia.org/wiki/Probability_density_function">probability density function</a> of the door containing the car is:</p>
908 <p>\[P(D = i)=\frac{1}{3}\ for\ i∈\{1,2,3\} \]</p>
909 <p>The player will first choose randomly a door, since he has no information that will modify the decision in favor of one of the doors. This leads to the uniform distribution and the probability density function of his first choice will be as follows:<br>
910 \[P(P = j)=\frac{1}{3}\ for\ j∈\{1,2,3\} \]</p>
911 <p>Next we define the conditional density function of the door the host opens, in other words how probable is that he will open one of the doors given that he knows where the car is and what door the player first chose. Recall from our restrictions that the host cannot open the door chosen by the player or the door where the car is. If the player chooses the door with the car, the host can open any of the two other doors, but if the player chooses a door with a goat, the host is obligated to open the only other door that does not contain the car. In conclusion:</p>
912 <p>\[<br>
913 P(H = k ∣ D = i, P = j) = \left\{<br>
914 \begin{array}{ll}<br>
915 1,\ i≠j,i≠k,k≠j \\<br>
916 \frac{1}{2},\ i=j,k≠i \\<br>
917 0,\ k=i,k=j<br>
918 \end{array}<br>
919 \right. for\ i,j,k∈\{1,2,3\}<br>
920 \]</p>
921 <p>The probability density function of the player's second choice is conditioned by the knowledge he has so far (i.e. what door he choose in the first step and what door the host opened). Recall that (obviously) the player cannot choose the door that is open. Here we introduce a parameter <em><strong>s</strong></em> to indicate how probable is that the player will switch his door for the one offered by Monty Hall. In the extreme cases this will be:</p>
922 <ul>
923 <li>If the player never switches, <em><strong>s=0</strong></em></li>
924 <li>If the player always switches, <em><strong>s=1</strong></em></li>
925 </ul>
926 <p>Taking all these facts into account we get the following:</p>
927 <p>\[<br>
928 P(X = l ∣ P = j, H = k) = \left\{<br>
929 \begin{array}{ll}<br>
930 s,\ l≠j,l≠k,k≠j \\<br>
931 1-s,\ l=j,k≠j \\<br>
932 0,\ k=l,k=j<br>
933 \end{array}<br>
934 \right. for\ l,j,k∈\{1,2,3\}\ with\ j≠k<br>
935 \]</p>
936 <p>We will now unite all these functions in one giant one that will be able to describe any event that happens in this game that we modeled mathematically. Using the <a href="http://depts.gpc.edu/~mcse/CourseDocs/math1431/1431_Supplements/WeissConditionalProbMultiRule.pdf">multiplication rule of conditional probabilities</a>, we have the following:</p>
937 <p>\(P(D=i,P=j,H=k,X=l)=<br>
938 P(D=i) \times P(P=j) \times P(H=k∣D=i,P=j) \times P(X=l∣P=j,H=k)\)</p>
939 <p>\[i,j,k,l∈\{1,2,3\}\]</p>
940 <p>Remember that the first two terms are constant so the formula above becomes:</p>
941 <p>\(P(D=i,P=j,H=k,X=l)=<br>
942 \frac{1}{9} \times P(H=k∣D=i,P=j) \times P(X=l∣P=j,H=k)\)</p>
943 <p>\[i,j,k,l∈\{1,2,3\}\]</p>
944 <p>We are almost done. The only remaining thing in our setup is to define our winning condition. That is that the second door choice of the player will be the same as the door that is hiding the car, so X=D.</p>
945 <p>Now it is calculating time. We have to sum the probabilities of all scenarios where our winning condition holds. If we take all possible terms it will be quite a long sum, so we will do some simplifications. First we directly remove all terms of our sum that are zero, those being the impossible scenarios(e.g. the host opens the same door as where the car is). Let us take now all the winning scenarios for the winning door being door number 1 (D=1) using the above defined functions:</p>
946 <p>\(\frac{1}{9} \times P(H=2∣D=1,P=1) \times P(X=1∣P=1,H=2) = \frac{1}{9}\times\frac{1}{2}\times(1-s)=\frac{1-s}{18}\)<br>
947 \(\frac{1}{9} \times P(H=3∣D=1,P=1) \times P(X=1∣P=1,H=3) =<br>
948 \frac{1}{9}\times\frac{1}{2}\times(1-s)=\frac{1-s}{18}\)<br>
949 \(\frac{1}{9} \times P(H=3∣D=1,P=2) \times P(X=1∣P=2,H=3) =<br>
950 \frac{1}{9}\times1\times s=\frac{s}{9}\)<br>
951 \(\frac{1}{9} \times P(H=2∣D=1,P=3) \times P(X=1∣P=3,H=2)=<br>
952 \frac{1}{9}\times1\times s=\frac{s}{9}\)</p>
953 <p>Added up we get:</p>
954 <p>\(P(D=1,P=j,H=k,X=1)= \frac{1+s}{9}\)</p>
955 <p>But this is equal with the probabilities of the scenarios where D=X=2 and D=X=3. Knowing this, we can multiply the previous result with 3 and we will get:</p>
956 <p>\(P(D=X)=\frac{1+s}{3}\)</p>
957 <p>This is expressing the probability of winning the car using the parameter <em><strong>s</strong></em> to indicate the likelihood of switching from the initial choice. If we take the two extreme cases we will have the following results:</p>
958 <ul>
959 <li>The player never switches: \(P(D=X)=\frac{1}{3}\)</li>
960 <li>The player always switches: \(P(D=X)=\frac{2}{3}\)</li>
961 </ul>
962 <p>As you can see we made the proof that switching is always better than staying.</p>
963 <p>All I can say is <em><strong>Q.E.D.</strong></em></p>
964 <!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[An intriguing C++ quiz that might challenge you more than you think]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p><img src="https://www.banterly.net/content/images/2017/01/download--5--1.jpg" alt loading="lazy"><br>
965 I was recently looking through my university days archive (ahh the days when I found learning surface integrals exciting) and came across this following problem that I created for myself trying to understand how C++ inheritance works. It was not obvious to me back then and I remember that even</p>]]></description><link>https://www.banterly.net/2017/01/22/a-c-quiz-that-even-some-experienced-developers-have-trouble-with-2/</link><guid isPermaLink="false">5a8aec0a421f76001702e0bb</guid><category><![CDATA[learning]]></category><category><![CDATA[c++]]></category><category><![CDATA[programming]]></category><category><![CDATA[OOP]]></category><dc:creator><![CDATA[Dragos Barosan]]></dc:creator><pubDate>Sun, 22 Jan 2017 09:23:01 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p><img src="https://www.banterly.net/content/images/2017/01/download--5--1.jpg" alt loading="lazy"><br>
966 I was recently looking through my university days archive (ahh the days when I found learning surface integrals exciting) and came across this following problem that I created for myself trying to understand how C++ inheritance works. It was not obvious to me back then and I remember that even for TAs and some developers it was not very clear what was the deal, with some getting the answer right but not the <em>why</em>. I still find it intriguing today so I decided to share it, hoping that it may also be intriguing for others.</p>
967 <p>I will first show the problem. Try to answer it for yourself and post the solution in the comments if you want. Afterwards you can scroll down for a complete explanation and see if you were right.</p>
968 <h1 id="theproblem">The problem</h1>
969 <p>Assume that we have the following two very simple classes:</p>
970 <pre><code>class Parent {
971 public:
972 virtual void print(){
973 std::cout<<"I am the parent class"<<std::endl;
974 }
975 };
976
977 class Derived : public Parent {
978 public:
979 virtual void print(int x){
980 std::cout<<"I am the derived class"<<std::endl;
981 }
982 };
983 </code></pre>
984 <p>What will each of the following two small pieces of code do and why?</p>
985 <pre><code>int main(){
986 Derived *derived=new Derived;
987 derived->print();
988 return 0;
989 }
990
991 int main(){
992 Parent *derived = new Derived;
993 derived->print();
994 return 0;
995 }
996 </code></pre>
997 <p>That is it. I know that maybe for some of you this is completely obvious so then just consider it a validation of your knowledge. For the others try to answer and then go to the next section to see if you got it right.</p>
998 <h1 id="thesolution">The solution</h1>
999 <p><img src="https://www.banterly.net/content/images/2017/01/1i2lo9.jpg" alt loading="lazy"></p>
1000 <ul>
1001 <li>The first case fails</li>
1002 <li>The second case will print: <em><strong>"I am the parent class"</strong></em></li>
1003 </ul>
1004 <p>The first example has to do with the dominance(or name hiding) mechanism. What that means is that a declaration of a function in a derived class will hide all ancestral functions, regardless of their signature. This surprises some, but the reason for this is that name lookup precedes overload resolution and they are independent steps in the compilation process. So in our case even though there is a function in the <code>Parent</code> class that matches the signature of the function we are calling in <code>main()</code>, the compiler never considers it. In the end we get <code> error: no matching function for call to 'Derived::print()'</code>.</p>
1005 <p>Now the question comes...why didn't the second one also fail, since we are still using a <code>Derived</code> object to call <code>print()</code>?</p>
1006 <p>The key here is that name lookup does not start with the actual type of the object, but with the declared type of the object. In other words it starts with the type of the variable which references/points to the actual object. In our second case we have a <code>Derived</code> object being stored(yeah I know, its address) in a <code>Parent</code> pointer variable, so our compiler will look in the <code>Parent</code> class for the <code>print()</code> function. It does find it and compilation succeeds correctly and at runtime we get the corresponding output.</p>
1007 <p>I hope you found this as interesting as me and see you next time for, I hope, a much longer and full of content post.</p>
1008 <!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[4 things that you (probably) did not know you could do in Git]]></title><description><![CDATA[<!--kg-card-begin: markdown--><blockquote>
1009 <p>"Git good" - anonymous</p>
1010 </blockquote>
1011 <p><img src="https://www.banterly.net/content/images/2017/01/git.png" alt loading="lazy"><br>
1012 Since everyone these days is becoming a developer, there is a high chance that you are one of them. Even if you are not, you still probably use a version control system in your day to day work (if not...whats wrong with you!</p>]]></description><link>https://www.banterly.net/2017/01/15/4-things-that-you-probably-did-not-know-you-could-do-in-git/</link><guid isPermaLink="false">5a8aec0a421f76001702e0b6</guid><category><![CDATA[git]]></category><category><![CDATA[vcs]]></category><category><![CDATA[learning]]></category><category><![CDATA[sysadmin]]></category><dc:creator><![CDATA[Dragos Barosan]]></dc:creator><pubDate>Sun, 15 Jan 2017 09:21:08 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><blockquote>
1013 <p>"Git good" - anonymous</p>
1014 </blockquote>
1015 <p><img src="https://www.banterly.net/content/images/2017/01/git.png" alt loading="lazy"><br>
1016 Since everyone these days is becoming a developer, there is a high chance that you are one of them. Even if you are not, you still probably use a version control system in your day to day work (if not...whats wrong with you!?), with the most popular option being Git. You know the basics (i.e. <em>git add</em>, <em>git commit</em>, <em>git push</em>, <em>git pull</em>) and even the more advanced stuff (i.e. <em>git reset</em>, <em>git stash</em>, <em>git checkout</em>), but today I will go into four more unknown commands that can actually be very useful. Why four? Because everyone stops at three (<a href="http://www.imdb.com/title/tt1475582/">Sherlock</a> reference right there). By the way, in case you are from Mars, the above image is from <a href="https://xkcd.com/1597/">xkcd</a>.</p>
1017 <h4 id="gitbisect">Git bisect</h4>
1018 <p>If you are in a well organized development environment, this command should be almost useless to you. But it could happen that you are just working on a small project at home, or your company is still figuring out your continuous integration setup, or even that your dog ate your tests and the following situation arises.<br>
1019 <img src="https://www.banterly.net/content/images/2017/01/1hfav8.jpg" alt loading="lazy"></p>
1020 <p>You are happily developing cool new features for your application when news start coming to you about something not working properly in the released version. You try to see what's wrong in the code, but cannot figure it out, so you decide to find the commit which introduced the bug. How do you do that? Well here is where your old friend <em>binary search</em> comes to help and git also gives you a hand with the <em><strong>git bisect</strong></em> command.</p>
1021 <p>The idea is simple. You pick a commit from history, using <em>git log</em>, where you know for sure that your app was free of this particular bug. Then you use <em>git bisect</em> to do a binary search for the commit that introduced the bug. If this sounds too abstract, let's look at an example.</p>
1022 <p>Let's say we have passionate people who want to save awesome songs in git so they last for posterity. Being well educated, they commit often, so one verse at a time. The latest project was <a href="https://www.youtube.com/watch?v=DuwY8U1AY7k">Candy Mountain</a> on which the team has worked on. They kept adding verses and in the end everything looked good. This is the latest version present in the git repo:</p>
1023 <pre><code>[bdl@composer]$cat amazing_lyrics
1024 Oh! When you're down and looking for some cheering up
1025 Then just head right on up to the candy mountain cave
1026 When you get inside you'll find yourself a cheery land
1027 Such a happy and joyful and perky, merry land
1028 They've got lollipops and gummy drops and candy things
1029 Oh so many things that will brighten up your day
1030 It's impossible to wear a frown in candy town
1031 It's the mecca of love, the candy cave
1032 They've got jelly beans and coconuts with little hats
1033 Candy rabbits, chocolate bunnies, it's a wonderland of sweets
1034 Ride the candy train to town and hear the candy band
1035 Candy bells it's a treat as they march across the land
1036 Cherry ribbons stream across the sky into the ground
1037 Turn around
1038 It astounds!
1039 It's a dancing candy tree
1040 In the candy cave imagination runs so free
1041 So now Charlie, please will you go into the cave
1042 </code></pre>
1043 <p>Then you think that you should evolve your setup with some tests. You develop the amazing <em>check_song.py</em> software (contact me if you want a copy), which checks if the lyrics match with the original, even if they are incomplete. You run it for the first time against the song version in the repo and you see the following:</p>
1044 <pre><code>[bdl@composer]$ python check_song.py amazing_lyrics
1045 WOW!! LYRICS DO NOT MATCH WITH THE ORIGINAL!! YOU ARE RUINING A GREAT SONG.
1046 </code></pre>
1047 <p>Disaster!!! There is an error in the lyrics, even tough looking at them they seem ok. Going one by one through each commit, trying to figure out where the error was introduced, is going to take a long time. Luckily we heard about <em>git bisect</em> recently from an awesome article.<br>
1048 We checkout the first commit and verify that it is correct(in general select a commit that you know for sure does not have the bug you are looking for). For convenience we tagged our first commit as <em>first_verse</em> and our latest commit as <em>bad_verse</em>:</p>
1049 <pre><code>[dragos@composer]$git checkout first_verse
1050 [dragos@composer]$python check_song.py amazing_lyrics
1051 GOOD JOB! THE SONG IS INTACT
1052 </code></pre>
1053 <p>Now we know our guilty commit is somewhere in between these ranges and we are ready to start the search:</p>
1054 <pre><code>[dragos@composer]$git bisect start
1055 [dragos@composer]$git bisect good first_verse
1056 [dragos@composer]$git bisect bad bad_verse
1057 Bisecting: 8 revisions left to test after this (roughly 3 steps)
1058 [9a2b4ea392d81192b3f0971dc9e0388b0827f10d] Adding amazing ninth verse
1059 </code></pre>
1060 <p>You see what happened? After giving the two commits between which we want to search (here we used two tags which point to those specific commits), git automatically checked out the commit in the middle of the range. Now we have to check if the buggy verse is still here and inform git about it.</p>
1061 <pre><code>[dragos@composer]$python check_song.py amazing_lyrics
1062 GOOD JOB! THE SONG IS INTACT
1063 [dragos@composer]$git bisect good
1064 Bisecting: 4 revisions left to test after this (roughly 2 steps)
1065 [eada803203224f16fb0760255575473ff3353cbc] Adding amazing thirteenth verse
1066 </code></pre>
1067 <p>With this info, git did a checkout on the commit halfway between this good commit and the last commit...we just got rid of half of our commits that we had to search in. We repeat the process until we find the commit that introduced the error.</p>
1068 <pre><code>[dragos@composer]$python check_song.py amazing_lyrics
1069 WOW!! LYRICS DO NOT MATCH WITH THE ORIGINAL!! YOU ARE RUINING A GREAT SONG. [dragos@composer]$git bisect bad
1070 Bisecting: 1 revision left to test after this (roughly 1 step)
1071 [4b9da3dddf2dcaeb11f3e64746e67cf40882e507] Adding amazing eleventh verse
1072 [dragos@composer]$python check_song.py amazing_lyrics
1073 WOW!! LYRICS DO NOT MATCH!! YOU ARE RUINING THIS GREAT SONG.
1074 [dragos@composer]$git bisect bad
1075 Bisecting: 0 revisions left to test after this (roughly 0 steps)
1076 [634f0ad38519901d7db8885ed67a9c4122f7d756] Adding amazing tenth verse
1077 [dragos@composer]$python check_song.py amazing_lyrics
1078 GOOD JOB! THE SONG IS INTACT
1079 [dragos@composer]$git bisect good
1080 4b9da3dddf2dcaeb11f3e64746e67cf40882e507 is the first bad commit
1081 commit 4b9da3dddf2dcaeb11f3e64746e67cf40882e507
1082 Author: bad_person <bad.person@mail.com>
1083 Date: Fri Jan 13 00:23:04 2017 +0100
1084 Adding amazing eleventh verse
1085 :100644 100644 6b805f5880efc6b3aca886c33b892a3c54c69bcd
1086 ab327e224638a8bb744a78d9c1985c80bdb8e852 M amazing_lyrics
1087 </code></pre>
1088 <p>In the end we found the guilty commit so now we can see what was the error:</p>
1089 <pre><code>[dragos@composer]$git bisect reset 4b9da
1090 Previous HEAD position was 634f0ad... Adding amazing tenth verse
1091 HEAD is now at 4b9da3d... Adding amazing eleventh verse
1092 [dragos@composer]$git diff HEAD^ HEAD
1093 diff --git a/amazing_lyrics b/amazing_lyrics
1094 index 6b805f5..ab327e2 100644
1095 --- a/amazing_lyrics
1096 +++ b/amazing_lyrics
1097 @@ -7,4 +7,5 @@ Oh so many things that will brighten up your day
1098 It's impossible to wear a frown in candy town
1099 It's the mecca of love, the candy cave
1100 They've got jelly beans and coconuts with little hats
1101 -Candy rats, chocolate bats, it's a wonderland of sweets
1102 +Candy rabbits, chocolate bunnies, it's a wonderland of sweets
1103 +Ride the candy train to town and hear the candy band
1104 </code></pre>
1105 <p>Aha! So someone did not like candy rats and chocolate bats. Now we know. We are free to fix this small error in a new commit.</p>
1106 <p>In conclusion, this is useful when you know the behavior that changed, but not what code caused it.</p>
1107 <h4 id="gitblame">Git blame</h4>
1108 <p>This is maybe the most known command on the list, but since I met a lot of people who are not aware of it, I decided to include it.</p>
1109 <p><em>Git blame</em> annotates your files with information about each line. You are shown the hash of the latest commit that modified the line, the author and the date.</p>
1110 <p>As an example we can take the file from our previous section:</p>
1111 <pre><code>[dragos@compser]$git blame amazing_lyrics
1112 ^d5c5a92 (bdl 2017-01-13 00:06:29 +0100 1) Oh! When you're down and looking for some cheering up
1113 fa76d21a (bdl 2017-01-13 00:07:17 +0100 2) Then just head right on up to the candy mountain cave
1114 bab5fc16 (bdl 2017-01-13 00:07:58 +0100 3) When you get inside you'll find yourself a cheery land
1115 b96e74ec (bdl 2017-01-13 00:08:50 +0100 4) Such a happy and joyful and perky, merry land
1116 aa5c8716 (bdl 2017-01-13 00:12:05 +0100 5) They've got lollipops and gummy drops and candy things
1117 2b26aaf7 (bdl 2017-01-13 00:14:48 +0100 6) Oh so many things that will brighten up your day
1118 7e06c9bb (best_guy 2017-01-13 00:15:45 +0100 7) It's impossible to wear a frown in candy town
1119 104cfd46 (best_guy 2017-01-13 00:16:11 +0100 8) It's the mecca of love, the candy cave
1120 5e259be9 (bdl 2017-01-13 00:16:53 +0100 9) They've got jelly beans and coconuts with little hats
1121 b743274c (bad_person 2017-01-13 00:23:04 +0100 10) Candy rabbits, chocolate bunnies, it's a wonderland of sweets
1122 b743274c (bad_person 2017-01-13 00:23:04 +0100 11) Ride the candy train to town and hear the candy band
1123 896d4c44 (bdl 2017-01-13 00:25:32 +0100 12) Candy bells it's a treat as they march across the land
1124 6e788500 (bdl 2017-01-13 00:27:23 +0100 13) Cherry ribbons stream across the sky into the ground
1125 33bbe8ef (bdl 2017-01-13 00:28:02 +0100 14) Turn around
1126 1efad606 (bdl 2017-01-13 00:29:47 +0100 15) It astounds!
1127 9352d03d (bdl 2017-01-13 00:30:45 +0100 16) It's a dancing candy tree
1128 140da6b7 (random_guy 2017-01-13 00:31:17 +0100 17) In the candy cave imagination runs so free
1129 eb97f1c2 (bdl 2017-01-13 00:31:52 +0100 18) So now Charlie, please will you go into the cave
1130 </code></pre>
1131 <p>Looking at this, we could notice that there are two lines modified by the same commit, which doesn't conform to our "one verse, one commit" policy. This could make us curious and look at the commit and find out that was where our error was introduced.<br>
1132 Another use is if you just don't understand what a piece of code does, you can look up who committed it and go ask.</p>
1133 <p><strong>Fun fact #1</strong>: If a commit hash has the <strong>^</strong> sign in front of it, then the associated line is unmodified since the creation of the file.</p>
1134 <p><strong>Fun fact #2</strong>: Git can track even line movements across files. So if you decide to refactor a big code or configuration file in multiple smaller ones and you <em>git blame</em> the smaller files, then git will show you the original commit in the big file and the name of the big file. All this by just adding the <em><strong>-C</strong></em> option.</p>
1135 <h4 id="gitreflog">Git reflog</h4>
1136 <p>Probably you were told to avoid using <em>git reset --hard</em> because it is a destructive operation. That is because it does not only modify the HEAD(<em>--soft</em>) and the index(<em>--mixed</em>), but also your working directory. If you had uncommitted work, then you are screwed.</p>
1137 <p><img src="https://www.banterly.net/content/images/2017/01/1hndjf.jpg" alt loading="lazy"></p>
1138 <p>What you may not know is that there is (mostly) nothing to worry about if you have everything committed and by some circumstances you do a hard reset. That is because <em>git reflog</em> has your back. Of course this is just an example and it can be useful at any times when you have lost commits and you want to recover them.</p>
1139 <p><em>Reflog</em> is a local structure that records where your HEAD and branch references have pointed to in the past. This is not shared with anyone else, everyone has their own <em>reflog</em>. It is important to mention that it does not record information forever, after a configurable amount of time information will be removed from the <em>reflog</em>.</p>
1140 <p><strong>Example time!!</strong></p>
1141 <p>Let's look at our current commit history.</p>
1142 <pre><code>[dragos@composer]$git log --pretty=oneline
1143 8ef8a6b18d4c76497a0cd5b0104336f8253d33a4 first commit of checking software
1144 eb97f1c20d82226f4d04e96237bf6956fa09e345 Adding amazing eighteenth verse
1145 140da6b784e33367e200349e6da5c0ddc48e7ef8 Adding amazing seventeenth verse
1146 9352d03d455b4c646f3de91abd2aacd2998f34b8 Adding amazing sixteenth verse
1147 ...
1148 </code></pre>
1149 <p>Just as a reminder: what <em>git reset</em> does is that it moves the pointer of the current branch(and the HEAD implicitly) to a new commit, updating the index if <em>--mixed</em>(this being the default if no flag is specified) is used or updating the index and the working directory if <em>--hard</em> is used (if still troubled by it, an excellent explanation can be found <a href="https://git-scm.com/book/en/v2/Git-Tools-Reset-Demystified">here</a>). For some reason we are not satisfied with the latest commit so we will reset to the previous one(you can reset to any commit by specifying some sort of reference to it)</p>
1150 <pre><code>[dragos@composer]$git reset HEAD^
1151 [dragos@composer]$git log --pretty=oneline
1152 eb97f1c20d82226f4d04e96237bf6956fa09e345 Adding amazing eighteenth verse
1153 140da6b784e33367e200349e6da5c0ddc48e7ef8 Adding amazing seventeenth verse
1154 9352d03d455b4c646f3de91abd2aacd2998f34b8 Adding amazing sixteenth verse
1155 1efad606e509a3eca835678ebf2e9c2fffaae45c Adding amazing fifteenth verse
1156 ...
1157 </code></pre>
1158 <p>We notice that the latest commit from our previous <em>git log</em> output is not present anymore. But it was not deleted, it's just not visible anymore in the normal functionality of <em>git log</em>, because by default it just walks the commit ancestry chain.</p>
1159 <p><img src="https://www.banterly.net/content/images/2017/01/Capture3.PNG" alt loading="lazy"></p>
1160 <p>We realize that actually the commit we reset was actually perfect and we want to restore it. But how? Well we can just use <em>git reset</em> and make our branch point to that commit again, but how do we get the reference to that commit, since it does not appear in <em>git log</em> anymore. Here is where <em>git reflog</em> steps in.</p>
1161 <pre><code>[dragos@composer]$git reflog
1162 eb97f1c HEAD@{0}: reset: moving to HEAD^
1163 8ef8a6b HEAD@{1}: commit: first commit of checking software
1164 eb97f1c HEAD@{2}: checkout: moving from d5c5a925da0dc687e8a7d5d40111bbd930fd5a02 to master
1165 d5c5a92 HEAD@{3}: checkout: moving from master to first
1166 ...
1167 </code></pre>
1168 <p>The list goes longer, but for our case we are only interested in the top two entries. From the output we can see to which commit was HEAD pointing previously and where it is pointing now (indicated by <em>HEAD@{0}</em>). So to move our branch back to how it was before we can use either directly the desired commit hash (i.e. 8ef8a6b) or a reference to it (i.e. HEAD@{1}). Be careful and realize that if we move our HEAD around then HEAD@{1} will most probably point to some other commit. So let's reset the reset:</p>
1169 <pre><code>[dragos@composer]$git reset HEAD@{1}
1170 [dragos@composer]$git log --pretty=oneline
1171 8ef8a6b18d4c76497a0cd5b0104336f8253d33a4 first commit of checking software
1172 eb97f1c20d82226f4d04e96237bf6956fa09e345 Adding amazing eighteenth verse
1173 140da6b784e33367e200349e6da5c0ddc48e7ef8 Adding amazing seventeenth verse
1174 9352d03d455b4c646f3de91abd2aacd2998f34b8 Adding amazing sixteenth verse
1175 ...
1176 </code></pre>
1177 <p>As we can see, things are back to normal. So the next time you panic because of a git reset gone wrong, don't forget you have a guardian angel out there under the name of <em>reflog</em>.</p>
1178 <p><img src="https://www.banterly.net/content/images/2017/01/download--1-.jpg" alt loading="lazy"></p>
1179 <p><strong>Fun fact #3</strong>: I said before that by default <em>git log</em> will only show you the commits in the ancestry chain. You can make it walk the reflog chain instead, by specifying the <em>-g/--walk-reflogs</em> flag.</p>
1180 <h4 id="commitranges">Commit ranges</h4>
1181 <p>You reached the final section, congratulations for going the extra mile.</p>
1182 <p><img src="https://www.banterly.net/content/images/2017/01/download.jpg" alt loading="lazy"></p>
1183 <p>Here we will see how to specify range of commits using three methods, each useful for its own purpose. They are especially handy when managing multiple branches. Before we dive into them, below there is the picture of the commit tree on which we will be working on.</p>
1184 <p><img src="https://www.banterly.net/content/images/2017/01/Capture1.PNG" alt loading="lazy"></p>
1185 <h5 id="doubledot">Double dot</h5>
1186 <p>I guess you used this one, even if you did not know fully what it actually does. Your typical usage was probably just to filter the commits that you see from the same branch, something like the following (I eliminated the hashes from the output, showing only the corresponding tags):</p>
1187 <pre><code>[dragos@composer]$git log --pretty=oneline B..F
1188 F
1189 D
1190 </code></pre>
1191 <p>So this shows the commits between the range specified without including the left-most object (i.e. B in this case). But what would happen if we try this with commits that are each on a different branch? Let's try some more examples:</p>
1192 <pre><code>[dragos@composer]$git log --pretty=oneline G..F
1193 F
1194 D
1195 [dragos@composer]$git log --pretty=oneline F..G
1196 G
1197 E
1198 [dragos@composer]$git log --pretty=oneline C..G
1199 G
1200 E
1201 [dragos@composer]$git log --pretty=oneline G..C
1202 C
1203 </code></pre>
1204 <p>If you have not deduced exactly what this does form the previous outputs then SPOILER ALERT, because I'm going to tell you. Using this notation you see all commits not reachable from the first specified commit(going only backwards of course), but reachable from the second specified commit. Please go back to the picture and previous examples to see that this makes sense.</p>
1205 <p>One useful usage of this is before you want to push your changes to a remote.</p>
1206 <p><code>[dragos@composer]$git log --pretty=oneline origin/master..HEAD</code></p>
1207 <p>The output of the above command will represent the commits that you will upload to master on origin when using <em>git push</em> (Considering of course that you recently did a <em>git pull</em> so your remote references are up-to-date)</p>
1208 <h5 id="multiplebranches">Multiple branches</h5>
1209 <p>So the double dot is all fine and cool, but what do we do when we want to specify more than two branches, such as seeing what commits are in any of several branches that aren’t in the branch you’re currently on. It turns out that the double dot notation is just a shorthand for another syntax. If you specify the <em>^</em> character or <em>--not</em> before any reference, then <em>git log</em> will show you only commits that cannot be reached from those references. To understand, the following commands are equivalent:</p>
1210 <pre><code>[dragos@composer]$git log --pretty=oneline G..F
1211 [dragos@composer]$git log --pretty=oneline ^G F
1212 [dragos@composer]$git log --pretty=oneline F --not G
1213 </code></pre>
1214 <p>And an example with multiple branches:</p>
1215 <pre><code>[dragos@composer]$git log --pretty=oneline G --not H F
1216 G
1217 </code></pre>
1218 <h5 id="tripledot">Triple dot</h5>
1219 <p>The last method that we are covering for specifying commit ranges is the triple dot notation. You could say that it provides an exclusive disjunction of the sets of commits reachable from two specified references. In normal words it basically specifies all the commits that are reachable by either of two references but not by both of them.</p>
1220 <p>Last example and you can go on with your life:</p>
1221 <pre><code>[dragos@composer]$git log --pretty=oneline C...G
1222 49a59058100707187ac6e8980e77e45e57785407 G
1223 4f1615031ededc27944ed43f4fc410b69a637919 E
1224 b73244c413956a356ed5076b5b87f087d978ba2f C
1225 </code></pre>
1226 <h4 id="goodbye">Goodbye</h4>
1227 <p>Thats it guys, I hope you learnt at least one thing from this and also had some fun. If you want to be alerted if there is a new post press the big subscribe button underneath the comments. Don't worry I dont have time to write too much so I will not spam you.<br>
1228 <img src="https://www.banterly.net/content/images/2017/01/1ho2ql.jpg" alt loading="lazy"></p>
1229 <!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Blockchain - Beyond the Hype of Bitcoin and Ethereum]]></title><description><![CDATA[<!--kg-card-begin: markdown--><blockquote>
1230 <p>"You can't stop things like Bitcoin. It will be everywhere and the world will have to readjust. World governments will have to readjust" - John McAfee, Founder of McAfee</p>
1231 </blockquote>
1232 <p>I am sure by now everyone at least heard in some context of Bitcoin, maybe in the</p>]]></description><link>https://www.banterly.net/2016/12/31/blockchain-beyond-the-hype-of-bitcoin-and-ethereum/</link><guid isPermaLink="false">5a8aec0a421f76001702e0af</guid><category><![CDATA[blockchain]]></category><category><![CDATA[bitcoin]]></category><category><![CDATA[ethereum]]></category><category><![CDATA[money]]></category><category><![CDATA[hype]]></category><category><![CDATA[future]]></category><dc:creator><![CDATA[Dragos Barosan]]></dc:creator><pubDate>Sat, 31 Dec 2016 09:03:45 GMT</pubDate><media:content url="https://www.banterly.net/content/images/2016/12/download--3-.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><blockquote>
1233 <img src="https://www.banterly.net/content/images/2016/12/download--3-.jpg" alt="Blockchain - Beyond the Hype of Bitcoin and Ethereum"><p>"You can't stop things like Bitcoin. It will be everywhere and the world will have to readjust. World governments will have to readjust" - John McAfee, Founder of McAfee</p>
1234 </blockquote>
1235 <p>I am sure by now everyone at least heard in some context of Bitcoin, maybe in the news or maybe even in your favorite <a href="https://en.bitcoin.it/wiki/Bitcoin_references_in_TV_Shows">TV series</a>. For most people this is just an obscure technology (the name or its classification as a cryptocurrency doesn't help too much in understanding it either) used by suspicious individuals who want to purchase illegal merchandise or by hackers to fund their...well...their hacking or whatever suspicious individuals do.</p>
1236 <p><img src="https://www.banterly.net/content/images/2016/12/65-1.png" alt="Blockchain - Beyond the Hype of Bitcoin and Ethereum" loading="lazy"></p>
1237 <p>While that may be one of its uses, the truth is that there are a lot of legitimate uses that bitcoin enables with more and more places accepting Bitcoin as a means of payment these days. But what's most interesting is the underlying mechanism that makes Bitcoin work, <strong>the blockchain</strong>. And, if you have been paying attention, then you know that blockchain was one of the most buzzed and hyped technologies in 2016, as it can be seen in <a href="http://www.gartner.com/newsroom/id/3412017">Gartner's 2016 Hype Cycle for Emerging Technologies</a> picture illustrated bellow. If you decide to read on you will not only understand how bitcoin works, but will get to see how deep the rabbit's hole really goes.<br>
1238 <img src="http://na2.www.gartner.com/imagesrv/newsroom/images/emerging-tech-hc-2016.png;wa59f7b006c484099e" alt="Blockchain - Beyond the Hype of Bitcoin and Ethereum" loading="lazy"></p>
1239 <br>
1240 <h4 id="somewordsaboutcryptocurrencies">Some words about cryptocurrencies</h4>
1241 <p>Each blockchain has an associated digital currency (aka <strong>cryptocurrency</strong>) that is independent and exists only within the world of that blockchain. The most known example is of course Bitcoin, but there are a lot more than you would expect (more than 700 at the time of this writing). You can get a list of them and their value compared to the US dollar <a href="https://coinmarketcap.com/">here</a>. Maybe you will say "Wait, that money doesn't really exist...it's just some numbers that exist on a computer". In our day and age this is also the case for most conventional currencies, they are just numbers in the bank's datacenters, with cash becoming more and more rare. In fact Bitcoin has been <a href="http://www.bankofcanada.ca/2016/03/staff-working-paper-2016-14/">compared</a> with currencies which are based on the gold standard. Without going into much details, think about the fact that the value of something usually comes from its scarcity and by how big the demand for it is...the same applies for cryptocurrencies.</p>
1242 <h4 id="blockchainthedatastructure">Blockchain - The data structure</h4>
1243 <p>So what is blockchain? The name is pretty revealing, it is a chain of blocks. Each block contains a number of transactions that have taken place. These transactions deal with the associated cryptocurrency of that blockchain (as discussed earlier). Together, all blocks form the entire history of transactions that took place since the inception of the blockchain, you can think of it as a ledger. As you might expect, there is a block 0 in this chain and it is a very special block. It is here where the initial amount and distribution of the new cryptocurrency takes place. So if you decide to launch a new digital coin make sure to allocate some for you in the beginning...who knows maybe you stumble upon the next Bitcoin.</p>
1244 <p><img src="https://www.banterly.net/content/images/2016/12/Picture3.png" alt="Blockchain - Beyond the Hype of Bitcoin and Ethereum" loading="lazy"></p>
1245 <p>Inside the block there is other information, which varies according to blockchain implementations (e.g. timestamp of the block and metadata about the transactions). What is always there is a pointer (<strong>a hash pointer</strong> to be more exact) which indicates what was the previous block. That is how the chain is constructed and the blocks tied to each other. To get a little more technical, in Bitcoin, the way this works is that each block has a hash of the previous block's header. A hash is a one way mathematical function that applied to any input, it will generate a fixed size output. Since we want our transactions to be secure, what we need in the context of blockchain is a cryptographic secure hash function (in bitcoin that being <a href="https://en.wikipedia.org/wiki/SHA-2">SHA256</a>), which has the following 3 extra properties:</p>
1246 <ul>
1247 <li>you can only find the input value corresponding to an output value by random trials</li>
1248 <li>a small change to a message should change the hash value so extensively that the new hash value appears uncorrelated with the old hash value</li>
1249 <li>you cannot find two inputs with the same output value easily</li>
1250 </ul>
1251 <p>Congratulations, you know the basics of the blockchain data structure...now let's go distributed!</p>
1252 <h4 id="blockchainthenetwork">Blockchain - The network</h4>
1253 <p>The whole point of cryptocurrencies is to function on a decentralized infrastructure. That's why we have the blockchain network, a peer to peer network where the peers are the so called <strong>miners</strong>.</p>
1254 <p><img src="https://www.banterly.net/content/images/2016/12/Picture4.png" alt="Blockchain - Beyond the Hype of Bitcoin and Ethereum" loading="lazy"><br>
1255 If you were ever intrigued by the term miner here is where the mystery will be revealed. The term miner refers to the nodes that are part of the network. For public blockchains (like Bitcoin), everyone can join and become a miner (yes, even you), while for permissioned blockchains there is in place some sort of access control (public vs permissioned vs private blockchains is an another entire article by itself).</p>
1256 <p>Miners have three big roles:</p>
1257 <ul>
1258 <li>They all keep a full copy of the current blockchain that they have already reached a consensus on (under the form of the data structure described earlier). In other words, they all have access to the entire history of valid transactions that took place on the blockchain. This can become quite a burden on the miners, with the current Bitcoin chain having a size of over <a href="https://bitinfocharts.com/">114 GB</a> (so if you want to become a miner, better free up some space). This makes the entire process quite inefficient, so a lot of research has been made on new blockchains to eliminate this requirement.</li>
1259 <li>Each of them constructs independently a new block containing new transactions coming from the users of the blockchain. It is also their duty to validate and forward the transactions to the other miners. Since it can happen that they receive more transactions than available space in a new block, mechanisms exist in order to prioritize.</li>
1260 <li>They must reach a consensus on what block will be added to the canonical chain.</li>
1261 </ul>
1262 <p>How is that consensus reached and how can we trust this network since there is no central authority that regulates this network and everyone is out there for himself ?</p>
1263 <p>To answer this we have to turn away from a pure scientific answer, because this is one of the rare cases where things work better in practice than in theory. But theory is catching up fast, especially with all the hype that is surrounding this field lately.</p>
1264 <h4 id="consensusbeatingtheodds">Consensus - Beating the odds</h4>
1265 <p>This is one of the holy grails of Computer Science, <strong>Distributed Consensus</strong> aka Byzantine Fault Tolerance. It is named so after the <a href="http://research.microsoft.com/en-us/um/people/lamport/pubs/byz.pdf">Byzantine Generals Problem</a> which tells the story of multiple Byzantine generals, found in different camps, having to coordinate for a successful attack or retreat under unreliable circumstances (really exciting stuff there, I encourage you to read about it in the link I provided). In general, computer scientists achieved pessimistic results about this topic, with a number of impossibilities proven.</p>
1266 <p>Why blockchain works is because it departs from classical distributed systems (e.g. distributed databases) in two essential ways:</p>
1267 <ul>
1268 <li>It introduces the idea of offering incentives to miners to play nice and follow the rules of the game. Being associated with a currency, a natural mechanism is provided for doing so</li>
1269 <li>It embraces randomness. It acts on probabilities more than on certainties, and with the passing of time these probabilities grow towards 100%</li>
1270 </ul>
1271 <p>Let's enumerate the steps in which Bitcoin tries to reach consensus:</p>
1272 <ol>
1273 <li>A "random" miner is selected by the network</li>
1274 <li>The selected miner sends a local new block to the other miners</li>
1275 <li>The other miners validate the received new block. A basic check is that the hash pointer points to the latest block that is already part of the canonical blockchain. Another important check is that the users have enough balance in their accounts to complete the transactions (information that can be gained from the blockchain that everybody has available)</li>
1276 <li>If it is valid, they discard their local new block and add to the blockchain the received block</li>
1277 </ol>
1278 <p>If you think about it carefully, this mechanism prevents a lot of common attacks, as long as there are more than 50% honest nodes:</p>
1279 <ul>
1280 <li><strong>The Double Spend Attack</strong> - An attacker might try to spend his available money two times to different parties. This requires a little more explanation that you can find <a href="http://eprint.iacr.org/2012/248.pdf">here</a>. The basic idea is that if you receive a payment from someone via blockchain from a newly added block and immediately accept it, another block can come in with another transaction that is invalidating your received payment. Within a range of probabilities, the network may choose that second block as the right one, even though morally the block containing your payment is the right one. The conclusion is that if you are receiving a payment, then it is wise for you to wait for a number of more blocks to be added, because each new added block increases the probability of your payment becoming accepted by the network. For bitcoin it is recommended that you should wait 6 blocks before confirming the payment<br>
1281 <img src="https://www.banterly.net/content/images/2016/12/DoubleSpend.PNG" alt="Blockchain - Beyond the Hype of Bitcoin and Ethereum" loading="lazy"></li>
1282 <li><strong>Stealing money</strong> - if one of the users would try to include in the transactions money they don't have, even if they control some of the miners, the majority of the miners will reject the transactions as invalid</li>
1283 <li><strong>Denial of service</strong> - if some miners want to block someones transactions, they can refuse to add his transactions in their new blocks, but since a "random" miner is selected each time a new block is added, this can only result in a minor delay or inconvenience for the user.</li>
1284 </ul>
1285 <p>This looks fine technically, but it still doesn't answer how the "random" selection works and why we assume 51% of the network will do the right thing...</p>
1286 <h4 id="embracingtherandomness">Embracing the randomness</h4>
1287 <p>What is the problem? We are trying to make unrelated entities (which in the end are human, because the mining nodes are controlled by humans) to cooperate.<br>
1288 Sure enough, blockchains come up with incentives to promote good behavior. Usually this incentives come under two forms:</p>
1289 <ul>
1290 <li><strong>A block reward</strong> - every miner who is "randomly" selected to add a new block will receive the so-called block reward. This is a predetermined amount of the currency associated with that blockchain. This is usually pretty important at the start of a new blockchain, helping its bootstrap process. The catch is that your reward is valid only if your block is valid. So you should try your best to make sure that your block has all the correct information and all the transactions contained within are valid as well. As an example for bitcoin the block reward is 12 bitcoins and is halving every four years. At the time of this writing a bitcoin is valued at $767, so you would get $9204 for one mined block...not bad.</li>
1291 <li><strong>The transaction fee</strong> - Again this works in different ways for different blockchains, but the main idea is that the user of the blockchain network can choose to reserve a small portion of the transaction amount. That money will be earned, as with the block reward, by the node which has the luck of adding the block containing the transaction. This also works as a transaction prioritization system: miners will most probably add first the transactions that offer a high transaction fee.</li>
1292 </ul>
1293 <p>This looks pretty neat, but as long as there is something to gain, humans will act in their own interest, even contrary to the common good. If you don't believe me, look it up. There's even a cool named economic theory about it, the <a href="https://en.wikipedia.org/wiki/Tragedy_of_the_commons">Tragedy of the commons</a>.<br>
1294 <img src="https://www.banterly.net/content/images/2016/12/TragedyOfTheDick.jpg" alt="Blockchain - Beyond the Hype of Bitcoin and Ethereum" loading="lazy"><br>
1295 Image source <a href="https://xkcd.com/958/">xkcd</a><br>
1296 This incentives system creates the "free for all" problem. Everyone would join in the hope of hitting the jackpot. This leads to another problem: attackers could create unlimited nodes to join the network until they have more than 50%, which is pretty bad as discussed earlier. Also the problem of selecting "random" nodes is still left open.</p>
1297 <p>There are multiple ways of solving these issues, which in the end turn out to be interrelated. For simplification they could be expressed under the (famous?) <a href="https://en.wikipedia.org/wiki/Prisoner%27s_dilemma">Prisoners Dilemma</a>: A story about two prisoners and each has the option of either keeping silent or ratting out the other. The essential ideas are that each prisoner is better off choosing to betray regardless of the other player's choice, and that the greatest benefit goes to who betrays when the other cooperates. The prisoners might both be better off if they both cooperate rather than both betray, but since they have no way to ensure cooperation, they will both choose to betray.</p>
1298 <p><img src="https://www.banterly.net/content/images/2016/12/prisoners-dilemma.png" alt="Blockchain - Beyond the Hype of Bitcoin and Ethereum" loading="lazy"><br>
1299 Image source <a href="http://thedeclination.com/virtue-signalling-game-theorys-cheat-code/">thedeclination</a></p>
1300 <p>To understand how to solve the dilemma we must turn to biology. The idea is that when two animals want and must cooperate, they must communicate their honest intentions to one another in a believable way. In order to make lying implausible, the signal must impose a cost on the signaler that would make it very costly to cheat. In other words, the signal itself must be a handicap. This is the so called [Handicap Principle]. (<a href="https://en.wikipedia.org/wiki/Handicap_principle">https://en.wikipedia.org/wiki/Handicap_principle</a>). And this can be applied to blochains under different forms, the most well-known being Proof of Work and Proof of Stake. Bitcoin is using Proof of Work so we will focus on that.</p>
1301 <p>Here's the scoop:​ The key idea behind proof‐of‐work is that we approximate the selection of a random node by instead selecting nodes in proportion to a relatively scarce resource that we hope nobody can monopolize (e.g. Bitcoin uses processor power, while others use computer memory). How, you ask? Well lets see.</p>
1302 <p>In Bitcoin all miners are required to solve a puzzle (i.e. the <a href="https://en.wikipedia.org/wiki/Hashcash">Hashcash</a> puzzle, basically they have to find the input to a certain hash function for a given output range). This puzzle can only be solved by brute force, so basically it is only by chance that you can find the right answer, one could say even almost random. That's why "random" was always between quotes, because we are only doing an approximation (maybe surprisingly, true randomness is hard to get by). Even if a miner has a lot more computing power than others, it will not always be the one to solve the puzzle, it will only increase its chances of doing so proportional to the total computing power in the network. And it is pretty important to be the first to solve the puzzle because that miner will be the one who will be adding the new block to the blockchain. So as long as no one has a higher percentage than 50% of the total computing power in the network, the network is secure. This in fact represents the mining process and that's why the nodes are called miners.</p>
1303 <p>This continuous puzzle solving has a cost for the miners: first in terms of the hardware required to mine and secondly in terms of consumed electricity. This costs provides an entry barrier to attackers who cannot just create for free new nodes to join the network and increase their chance of winning the "block adding lottery".</p>
1304 <p>The Proof of Stake system is an alternative with the advantage, among other, that it doesn't require the useless energy consumption that Proof of Work entitles. In this system, the chance of getting selected to add a new block depends on the amount of stake you have in the currency associated with the blockchain. This system is not trivial because most of the times it comes with the "nothing at stake" and "monopoly" problems. You can read more about it <a href="https://en.bitcoin.it/wiki/Proof_of_Stake">here</a>.</p>
1305 <p>That's it folks. If you reached this far, most of the high level mysteries of blockchain have been revealed and probably you also have a lot of questions (you can ask in the comments and I will try my best to answer).</p>
1306 <p>There is one more thing that was promised since the beginning of this article...</p>
1307 <h4 id="ethereumtheworldcomputer">Ethereum - The world computer</h4>
1308 <p>As you may have noticed, our click bait title contains also a reference to Ethereum. Initially I wanted to talk more in-depth about Ethereum, but that would turn this article into such a mammoth of an article that even I would become afraid of start reading (reminds me of the feeling I had when I wanted to start reading Dostoyevsky's The Brothers Karamazov). So just a few words for now and I will maybe describe in a future post more details about it.</p>
1309 <p><img src="https://www.banterly.net/content/images/2016/12/Screen-Shot-2016-02-24-at-10.42.13-AM-e1456328600212.png" alt="Blockchain - Beyond the Hype of Bitcoin and Ethereum" loading="lazy"><br>
1310 Image source <a href="http://www.coindesk.com/7-cool-decentralized-apps-built-ethereum/">coindesk</a><br>
1311 Ethereum takes blockchain and goes with it to the next level. You don't use the network and its currency just to transfer money, you use it to transfer, store and execute code. It acts like a trusted and secure distributed computing platform of which anyone can become part and anyone can use. From here the possibilities are endless. Some applications include:</p>
1312 <ul>
1313 <li>Decentralized investment funding (although the most famous one, <a href="http://www.coindesk.com/understanding-dao-hack-journalists/">The DAO</a>, ended up pretty bad)</li>
1314 <li>Decentralized options exchange</li>
1315 <li>Releasing music as a digital contract</li>
1316 <li>Decentralized voting system</li>
1317 </ul>
1318 <p>This all works by introducing the notion of smart contracts. It is supposed to be the equivalent of a paper contract with features like being fully self-executing, self-enforcing and easy to manage. It's mainly because of this that the whole world has gone crazy over blockchain in the last two years. Banks, startups, fintechs are all getting in on the hype train. After the dust settles we may really have something that will change how to world works.</p>
1319 <p>Before the closing words, if you really want to know more of the technicalities of Bitcoin and blockchains, I strongly recommend you the excellent Coursera course <strong>Bitcoin and Cryptocurrency Technologies</strong> provided by Princeton University and the accompanying textbook (The draft version is available for free <a href="https://d28rh4a8wq0iu5.cloudfront.net/bitcointech/readings/princeton_bitcoin_book.pdf?a=1">here</a>)</p>
1320 <h4 id="tuneinforthenextepisode">Tune in for the next episode</h4>
1321 <p>Next time we will get our hands dirty and try to make some Bitcoin transactions, we will try to install our own Ethereum blockchain and build some cool simple stuff on it. Or maybe it will be completely something else...who knows?</p>
1322 <p>If you want more do not forget to subscribe.</p>
1323