<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>don&#39;t just talk agile - walk agile!</title>
    <link>https://walkagile.com/</link>
    <description>Recent content on don&#39;t just talk agile - walk agile!</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-US</language>
    <managingEditor>peterhaefliger@yahoo.com (Peter Häfliger)</managingEditor>
    <webMaster>peterhaefliger@yahoo.com (Peter Häfliger)</webMaster>
    <copyright>Peter Häfliger</copyright>
    <lastBuildDate>Wed, 22 Apr 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://walkagile.com/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Learning Lithuanian</title>
      <link>https://walkagile.com/lithuanian/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><author>peterhaefliger@yahoo.com (Peter Häfliger)</author>
      <guid>https://walkagile.com/lithuanian/</guid>
      <description>&lt;p&gt;I have been studying Lithuanian since mid-2025 and want to share some of my experiences here.&lt;/p&gt;&#xA;&lt;p&gt;At the moment, the following links are only stubs, but I will soon add some (hopefully) useful content.&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://walkagile.com/materials/lithuanian/nouns/&#34;&gt;Nouns&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://walkagile.com/materials/lithuanian/verbs/&#34;&gt;Verbs&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://walkagile.com/materials/lithuanian/links/&#34;&gt;Links&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;</description>
      <content:encoded><![CDATA[<p>I have been studying Lithuanian since mid-2025 and want to share some of my experiences here.</p>
<p>At the moment, the following links are only stubs, but I will soon add some (hopefully) useful content.</p>
<ul>
<li><a href="/materials/lithuanian/nouns/">Nouns</a></li>
<li><a href="/materials/lithuanian/verbs/">Verbs</a></li>
<li><a href="/materials/lithuanian/links/">Links</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>Links to useful resources</title>
      <link>https://walkagile.com/materials/lithuanian/links/</link>
      <pubDate>Wed, 22 Apr 2026 00:00:00 +0000</pubDate><author>peterhaefliger@yahoo.com (Peter Häfliger)</author>
      <guid>https://walkagile.com/materials/lithuanian/links/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://walkagile.com/images/960px-Under_construction_icon-green.svg.png&#34; alt=&#34;Under Construction&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;(Source: &lt;a href=&#34;https://commons.wikimedia.org/wiki/File:Under_construction_icon-green.svg&#34;&gt;Under construction icon-green&lt;/a&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="/images/960px-Under_construction_icon-green.svg.png" alt="Under Construction"></p>
<p>(Source: <a href="https://commons.wikimedia.org/wiki/File:Under_construction_icon-green.svg">Under construction icon-green</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>Nouns</title>
      <link>https://walkagile.com/materials/lithuanian/nouns/</link>
      <pubDate>Wed, 22 Apr 2026 00:00:00 +0000</pubDate><author>peterhaefliger@yahoo.com (Peter Häfliger)</author>
      <guid>https://walkagile.com/materials/lithuanian/nouns/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://walkagile.com/images/960px-Under_construction_icon-green.svg.png&#34; alt=&#34;Under Construction&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;(Source: &lt;a href=&#34;https://commons.wikimedia.org/wiki/File:Under_construction_icon-green.svg&#34;&gt;Under construction icon-green&lt;/a&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="/images/960px-Under_construction_icon-green.svg.png" alt="Under Construction"></p>
<p>(Source: <a href="https://commons.wikimedia.org/wiki/File:Under_construction_icon-green.svg">Under construction icon-green</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>Verbs</title>
      <link>https://walkagile.com/materials/lithuanian/verbs/</link>
      <pubDate>Wed, 22 Apr 2026 00:00:00 +0000</pubDate><author>peterhaefliger@yahoo.com (Peter Häfliger)</author>
      <guid>https://walkagile.com/materials/lithuanian/verbs/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://walkagile.com/images/960px-Under_construction_icon-green.svg.png&#34; alt=&#34;Under Construction&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;(Source: &lt;a href=&#34;https://commons.wikimedia.org/wiki/File:Under_construction_icon-green.svg&#34;&gt;Under construction icon-green&lt;/a&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="/images/960px-Under_construction_icon-green.svg.png" alt="Under Construction"></p>
<p>(Source: <a href="https://commons.wikimedia.org/wiki/File:Under_construction_icon-green.svg">Under construction icon-green</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>From Lithuania with Love - Part 2</title>
      <link>https://walkagile.com/blog/from-lithuania-with-love-part-2/</link>
      <pubDate>Sun, 28 Sep 2025 00:00:00 +0000</pubDate><author>peterhaefliger@yahoo.com (Peter Häfliger)</author>
      <guid>https://walkagile.com/blog/from-lithuania-with-love-part-2/</guid>
      <description>&lt;p&gt;&lt;em&gt;This is the second part of of an article about my first trip to Lithuania earlier this month. The first part can be found &lt;a href=&#34;https://walkagile.com/blog/from-lithuania-with-love-part-1/&#34;&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;day-5-museum-of-occupations-and-freedom-fights-and-stotis-district-walk&#34;&gt;Day 5: Museum of Occupations and Freedom Fights and Stotis District Walk&lt;/h2&gt;&#xA;&lt;p&gt;&lt;em&gt;Friday, September 12th&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;I love the bakeries in Lithuania! What could be better than starting a day like this:&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://walkagile.com/images/blog/from-lithuania-with-love/day_5_breakfast.jpg&#34; alt=&#34;Breakfast&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;As the day was rather rainy, I dedided to go to a museum. Vilnius has a broad range of museums for art, history, technology etc. I decided for an art museum, the &lt;a href=&#34;https://mo.lt/en/&#34;&gt;MO Museum&lt;/a&gt;. Unfortunately, when I got there, they told me that they were in reform and only one temporary video gaming exhibition was accessible. As I thought that this would not be very interesting for me, I went to the &lt;a href=&#34;https://olkm.lt/en/&#34;&gt;Museum of Occupations and Freedom Fights&lt;/a&gt; instead. There are many photographs on display and artefacts like uniforms, letters, pamphlets, tools and small works of art, documenting the fight of the partisans who spent years in the woods after World War II to fight the Soviet occupation until well into the fifties. Other rooms show the works of the KGB and the deportations to the Altai region and further to Siberia. If I had not already read &lt;a href=&#34;https://rutasepetys.com/&#34;&gt;Rūta Šepetys&amp;rsquo;&lt;/a&gt; novel &lt;a href=&#34;https://rutasepetys.com/books/between-shades-of-gray/&#34;&gt;Between Shades of Gray&lt;/a&gt;, mentioned in the &lt;a href=&#34;https://walkagile.com/blog/from-lithuania-with-love-part-1/&#34;&gt;first part of this article&lt;/a&gt;, I would probably have been completely terrified, but now I was already prepared for these horrors. On a more positive note, the museum also shows the political and civil movement which gained strength in the seventies and eighties and eventually led to independence in the nineties.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><em>This is the second part of of an article about my first trip to Lithuania earlier this month. The first part can be found <a href="/blog/from-lithuania-with-love-part-1/">here</a>.</em></p>
<h2 id="day-5-museum-of-occupations-and-freedom-fights-and-stotis-district-walk">Day 5: Museum of Occupations and Freedom Fights and Stotis District Walk</h2>
<p><em>Friday, September 12th</em></p>
<p>I love the bakeries in Lithuania! What could be better than starting a day like this:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_5_breakfast.jpg" alt="Breakfast"></p>
<p>As the day was rather rainy, I dedided to go to a museum. Vilnius has a broad range of museums for art, history, technology etc. I decided for an art museum, the <a href="https://mo.lt/en/">MO Museum</a>. Unfortunately, when I got there, they told me that they were in reform and only one temporary video gaming exhibition was accessible. As I thought that this would not be very interesting for me, I went to the <a href="https://olkm.lt/en/">Museum of Occupations and Freedom Fights</a> instead. There are many photographs on display and artefacts like uniforms, letters, pamphlets, tools and small works of art, documenting the fight of the partisans who spent years in the woods after World War II to fight the Soviet occupation until well into the fifties. Other rooms show the works of the KGB and the deportations to the Altai region and further to Siberia. If I had not already read <a href="https://rutasepetys.com/">Rūta Šepetys&rsquo;</a> novel <a href="https://rutasepetys.com/books/between-shades-of-gray/">Between Shades of Gray</a>, mentioned in the <a href="/blog/from-lithuania-with-love-part-1/">first part of this article</a>, I would probably have been completely terrified, but now I was already prepared for these horrors. On a more positive note, the museum also shows the political and civil movement which gained strength in the seventies and eighties and eventually led to independence in the nineties.</p>
<p>I only fotographed the following two panels which caught my attention because they are so scaringly relevant today:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_5_freedom_fights_museum_1.jpg" alt="Freedom Fights Museum 1"></p>
<p>&ldquo;Eventually, on 10 October1939, the Soviet Union &hellip; forced Lithuania to sign an agreement accepting conditions detrimental to the sovereign state. &hellip; the country had to allow 20,000 Red Army troops to be stationed on its soil. &hellip; <strong>The Soviet Union justified this demand by quoting the need to protect its borders</strong>, but later events showed that it was the beginning of Lithuania&rsquo;s occupation.&rdquo;</p>
<p><img src="/images/blog/from-lithuania-with-love/day_5_freedom_fights_museum_2.jpg" alt="Freedom Fights Museum 2"></p>
<p>&ldquo;Accusing Lithuania of violating the treaty, it delivered an ultimatum demanding that additional Red Army troops be allowed to enter Lithuania. <strong>It also demanded the formation of a government acceptable to the Soviet Union</strong> &hellip;&rdquo;</p>
<p>Does this sound familiar in any way? Same old song sung again today in Ukraine, isn&rsquo;t it?</p>
<p>For the afternoon, I had already booked another free guided walking tour in advance from home, this time with <a href="https://www.vilniuswithlocals.com/">vilniuswithlocals.com</a>. Our very friendly and competent <a href="https://www.vilniuswithlocals.com/about-us">guide Indrė</a> showed us <a href="https://www.vilniuswithlocals.com/tours/alternative-vilnius">&ldquo;alternative Vilnius&rdquo;</a> around the Stotis (Train Station) District.</p>
<p>The tour started at Halės market, built 1906 in the time of the Russian Empire:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_5_hales_turgus.jpg" alt="Halės Market"></p>
<p>There are other buildings from that epoch in the neighbourhood, as well as buildings from the Soviet era when architecture tried to imitate the style of the Russian Empire. There are residential early-Soviet brick buildings and later-Soviet large-panel buildings. The picture below shows surviving traditional wooden houses on the right and a corner of <a href="https://cybercity.lt/">Cyber City</a> (the office complex where the DevOpsDays had been held the day before) on the left:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_5_cyber_city.jpg" alt="Cyber City"></p>
<p>It&rsquo;s a district in transformation where different epochs live side by side. It had been a dangerous area in the first years of Lithuanian independence in the nineties when suddenly there was unemployment instead of communist full-employment and many people had not yet found a new perspective, which led some of them to engage in criminal activities. One measure taken to improve conditions in the neighbourhood was street art. There are dozens of large mural paintings of which I will just share a small selection:</p>
<p>The first is by <a href="https://en.wikipedia.org/wiki/OSGEMEOS">&ldquo;os gêmeos&rdquo;</a> (&ldquo;the twins&rdquo;), brazilian twin brothers and artists from São Paulo:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_5_street_art_1.jpg" alt="Vilnius Street Art 1"></p>
<p>Indrė told us that the twins&rsquo; grandfather had emigrated to Brazil from Lithuania and never got a chance to come back to visit his home country because of the War and the Cold War. So the grandsons included him in this mural: He is the little man with green trousers and a hat sitting in the main figure&rsquo;s hand. So he did eventually manage to travel back to his beloved Lithuania, even if only in a piece of art.</p>
<p>Another great painting is &ldquo;funky Einstein&rdquo; by Lithuanian artist Ettoja:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_5_street_art_2.jpg" alt="Vilnius Street Art 2"></p>
<p>Right across the street from Halės market, there is this mural by italian artist <a href="https://www.millo.biz/">Millo</a>:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_5_street_art_3.jpg" alt="Vilnius Street Art 3"></p>
<p>And I especially like this one by Lithuanian artist <a href="https://www.ernestzacharevic.com/">Ernest Zacharevic</a>:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_5_street_art_4.jpg" alt="Vilnius Street Art 4"></p>
<h2 id="day-6-kaunas">Day 6: Kaunas</h2>
<p><em>Saturday, September 13th</em></p>
<p>I had not booked anything for Saturday, but I had always had the vague idea of using this one free day to go somewhere outside the city of Vilnius. There are several popular sites easily reachable by public transport, e.g. <a href="https://en.wikipedia.org/wiki/Trakai_Island_Castle">Trakai Island Castle</a>.</p>
<p>Eventually, I decided to visit Lithuania&rsquo;s second-largest city <a href="https://en.wikipedia.org/wiki/Kaunas">Kaunas</a>:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_6_kaunas_1.jpg" alt="Kaunas 1"></p>
<p>Trains go between Vilnius and Kaunas roughly every hour, and the same goes for buses. The trip takes a bit more than an hour. I decided to take the train. We don&rsquo;t have intercity buses in Switzerland, but a very reliable train system, so it&rsquo;s the train I am used to travel by. The train coaches are very comfortable and tickets can conveniently be bought <a href="https://ltglink.lt/en">online</a>. The journey goes through small villages and large forests. The rain had stopped but the day was still a bit cloudy. Not hot, not cold: perfect for a city trip!</p>
<p>Walking from the train or bus station, one enters the city center through a square in the &ldquo;new town&rdquo; where also the tourist office is located. The staff at the tourist office is very friendly and can provide information and a city map. The square is dominated by the formerly orthodox Church of St. Michael the Archangel (also known as the Garrison Church), built in the 1890ies in the time of the Russian Empire:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_6_kaunas_2.jpg" alt="Kaunas 2"></p>
<p>Walking down Laisvės Alėja (&ldquo;Liberty Avenue&rdquo;) towards the old town, there are other nice sights like this fountain:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_6_kaunas_3.jpg" alt="Kaunas 3"></p>
<p>The old town of Kaunas is built on the headland where the Neris river (coming from Vilnius) flows into the Neman river which then goes on to form the border between Lithuania in the north and Kaliningrad Oblast in the south and finally flows into the Curonian Lagoon, separated from the Baltic Sea by the Curonian Spit. South of the new town of Kaunas, there is an island in the Neman river: Nemunas Island. It hosts a <a href="https://mokslosala.lt/en/home-page/">Science Museum with a Planetarium</a> and many sports facilities, including Žalgirio Arena, home of the Žalgiris Kaunas basketball team:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_6_kaunas_4.jpg" alt="Kaunas 4"></p>
<p>And, as in Vilnius, there is a lot of street art:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_6_kaunas_5.jpg" alt="Kaunas 5"></p>
<h2 id="day-7-life-church-vilnius">Day 7: Life Church Vilnius</h2>
<p><em>Sunday, September 14th</em></p>
<p>I am a reborn Christian and like to attend worship service most Sundays at <a href="https://www.buchegg.church/en/">Buchegg Church</a> in Zürich. When I am abroad on a Sunday, I usually check whether there is an evangelic church where I could worship. I was lucky to find that there is such a church in Vilnius just a 20 minutes&rsquo; walk from my hotel to the north, north of the Šnipiškės skyscrapter district:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_7_sunday_1.jpg" alt="Life Church 1"></p>
<p>It&rsquo;s called <a href="https://gyvenimobaznycia.lt/">Life Church</a> and located at Kalvarijų gatvė 85 (Calvary Street? What an address for a church!) &hellip;</p>
<p><img src="/images/blog/from-lithuania-with-love/day_7_sunday_2.jpg" alt="Life Church 2"></p>
<p>&hellip; in an old theater building:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_7_sunday_3.jpg" alt="Life Church 3"></p>
<p>I was glad that I could finish this rich and happy week of travel with an inspiring message from Pastor Tony Miller (&ldquo;Seed, Time, and Harvest&rdquo;) &hellip;</p>
<p><img src="/images/blog/from-lithuania-with-love/day_7_sunday_4.jpg" alt="Life Church 4"></p>
<p>&hellip; and the worship led by their wonderful band:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_7_sunday_5.jpg" alt="Life Church 5"></p>
<p>The whole service has been recorded and can be watched on <a href="https://www.youtube.com/watch?v=6ei6pAujB5A">youtube</a>. If nothing else, take at least a few minutes and let yourself be touched by the band&rsquo;s beautiful rendering of &ldquo;I trust in God&rdquo; at 32:00: <em>&quot;<a href="https://www.youtube.com/live/6ei6pAujB5A?si=dYwpOgsZb6lOhmGe&amp;t=1920">I sought the Lord and He heard and He answered, that&rsquo;s why I trust Him!</a>&quot;</em></p>
<p>After this, I was ready to wrap up the week and say goodbye to beautiful Lithuania. I took a last stroll through the art district of Užupis:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_7_sunday_6.jpg" alt="Sunday Night 1"></p>
<p>And I finally climbed the castle hill of Gediminas Tower to take in a last view of the Šnipiškės skyline behind King Mindaugas Bridge:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_7_sunday_7.jpg" alt="Sunday Night 2"></p>
<h2 id="day-8-vilnius---zürich">Day 8: Vilnius - Zürich</h2>
<p><em>Monday, September 15th</em></p>
<p>After the sunny Sunday, Monday was cloudy again. Time to pack my bags, buy some last-minute presents (Lithuania has very nice chocolate, even for Swiss standards!) and have another sweet breakfast:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_8_breakfast.jpg" alt="Breakfast"></p>
<p>My flight went at 4 in the afternoon. Vilnius airport has just been modernized a few months ago and now has the last generation of security scanners. No need to take electronic devices or liquids out of your hand luggage. Very comfortable! This time, time difference worked in my favour: I had two hours in Vienna again and landed in Zürich by 8.</p>
<h2 id="cuisine">Cuisine</h2>
<p>In a large city like Vilnius, you can of course get food from almost any place in the world. But when I am in Lithuania, I don&rsquo;t want to eat Japanese or German food. I did go to the very nice Portuguese restaurant <a href="https://galodoporto.lt/">Galo do Porto</a>, though, because on Saturday night when I came home from the exciting trip to Kaunas, I felt a bit tired and lonely and homesick for my wife&rsquo;s cooking. Brazilian cuisine has certain similarities to Portuguese cuisine, and the restaurant&rsquo;s &ldquo;rabada&rdquo; (oxtail stewed in red wine sauce) made me more than happy!</p>
<p>There are the usual fastfood places like Mc Donald&rsquo;s or Kentucky Fried Chicken if you have no time for a real meal (for example when you&rsquo;re in a hurry between an old town walk, a balloon flight and the finishing of your presentation slides). There is also a burger place called Hesburger, apparently a Finnish group common in Finland and the baltic states but unknown elsewhere.</p>
<p>I tried it all, from Hesburger to &ldquo;Lucky Bagel&rdquo; at Kalvarijų gatvė 55 and from the food stands at Halės market to real restaurants like <a href="https://www.restoranasoneforall.lt/">One for All</a> in Užupis or <a href="https://lokys.lt/">Lokys</a> in the old town.</p>
<p>Vilnius also sports several award-winning fine dining places. The DevOpsDays organizers treated us to an exclusive speakers&rsquo; dinner after the first day of the conference. They took us to <a href="https://www.dziaugsmas.com/">Džiaugsmas</a> where every dish is a composition of tastes and textures:</p>
<p><img src="/images/blog/from-lithuania-with-love/food_6.jpg" alt="Fine Dining 1"></p>
<p><img src="/images/blog/from-lithuania-with-love/food_7.jpg" alt="Fine Dining 2"></p>
<p><img src="/images/blog/from-lithuania-with-love/food_8.jpg" alt="Fine Dining 3"></p>
<p>I do not usually go to places like this. But that&rsquo;s the beauty of travelling, isn&rsquo;t it: doing things which you would not usually do, taking in new sights, sounds, smells and tastes, expanding your horizon.</p>
<p>I usually like it simpler. Food that can be enjoyed without the composer&rsquo;s explanation. I therefore loved the following two of the country&rsquo;s specialties:</p>
<p>Cepelinai, a kind of potato dumplings:</p>
<p><img src="/images/blog/from-lithuania-with-love/food_1.jpg" alt="Cepelinai 1"></p>
<p>Diverse fillings are available, like cottage cheese or minced meat:</p>
<p><img src="/images/blog/from-lithuania-with-love/food_2.jpg" alt="Cepelinai 2"></p>
<p>And they can also be fried:</p>
<p><img src="/images/blog/from-lithuania-with-love/food_3.jpg" alt="Cepelinai 3"></p>
<p>And then there is Šaltibarščiai, the refreshing cold pink soup made of beetroot and kefir, usually served with potatoes &hellip;</p>
<p><img src="/images/blog/from-lithuania-with-love/food_4.jpg" alt="Šaltibarščiai 1"></p>
<p>&hellip; and sometimes with an egg:</p>
<p><img src="/images/blog/from-lithuania-with-love/food_5.jpg" alt="Šaltibarščiai 2"></p>
<h2 id="language">Language</h2>
<p>Now, what about the language? Do you need to understand Lithuanian to travel there? The answer is clear: No, absolutely not. At least not in the two large cities I have visited. All the waiters, vendors, guides and other staff speak perfect English, and most things can be resolved online in English anyway.</p>
<p>That said, Lithuanian is a very beautiful language worth learning for its own sake, not just as a means for travel. As mentioned earlier, I plan to write a separate article about the Lithuanian language later. I will continue my classes because they are fun and they make my life richer.</p>
<p>Despite its long history, independent Lithuania is a young country, and as the power which has occupied it for almost 200 years is threatening it again, Lithuanians celebrate their own unique culture and language.</p>
<p>There is one letter in the Lithuanian alphabet which appears in no other alphabet of any other language in the world: the e with one dot: ė</p>
<p>A monument to this unique letter was unveiled last year in the center of Kaunas, in a little square near the technical university, opposite Vienybės aikštė (&ldquo;Union Square&rdquo;). It&rsquo;s simply called &ldquo;Taškas&rdquo; (&ldquo;Dot&rdquo;) and it&rsquo;s beautiful in its very simplicity: Just a large dot (1.5 meters in diameter, 4 tons in weight) &hellip;</p>
<p><img src="/images/blog/from-lithuania-with-love/day_6_kaunas_6.jpg" alt="Kaunas Monument to the Letter e 1"></p>
<p>&hellip; with a shiny mirrored metal surface &hellip;</p>
<p><img src="/images/blog/from-lithuania-with-love/day_6_kaunas_7.jpg" alt="Kaunas Monument to the Letter e 2"></p>
<p>&hellip; and many words with the letter ė engraved:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_6_kaunas_8.jpg" alt="Kaunas Monument to the Letter e 3"></p>
<p><em>What a nice triplet to close with:</em></p>
<p><em><strong>gerovė - saulė - laisvė</strong></em></p>
<p><em>prosperity - sun - freedom</em></p>
]]></content:encoded>
    </item>
    <item>
      <title>From Lithuania with Love - Part 1</title>
      <link>https://walkagile.com/blog/from-lithuania-with-love-part-1/</link>
      <pubDate>Sat, 27 Sep 2025 00:00:00 +0000</pubDate><author>peterhaefliger@yahoo.com (Peter Häfliger)</author>
      <guid>https://walkagile.com/blog/from-lithuania-with-love-part-1/</guid>
      <description>&lt;p&gt;&lt;em&gt;I am not usually a travel blogger, but colleagues keep looking at me with surprise and asking me why I took a week of leave from work and a trip to Vilnius just to deliver a five-minutes talk at the local DevOpsDays. While this sounds a bit crazy indeed, there is of course a lot more to Lithuania than just the devops community. This is the first part of an article in which I try to paint the bigger picture. The second part can be found &lt;a href=&#34;https://walkagile.com/blog/from-lithuania-with-love-part-2/&#34;&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><em>I am not usually a travel blogger, but colleagues keep looking at me with surprise and asking me why I took a week of leave from work and a trip to Vilnius just to deliver a five-minutes talk at the local DevOpsDays. While this sounds a bit crazy indeed, there is of course a lot more to Lithuania than just the devops community. This is the first part of an article in which I try to paint the bigger picture. The second part can be found <a href="/blog/from-lithuania-with-love-part-2/">here</a>.</em></p>
<h2 id="how-it-all-started">How it all started</h2>
<p>I must admit that a year and a half ago, I did not even know which of the three baltic states was which. And I didn&rsquo;t know anybody from any of them. This changed in April 2024 when I met Evelina at the DevOpsDays Zürich. <a href="https://evelinarimkute.ch/">Evelina Rimkutė</a> is a Lithuanian Test Manager living in Switzerland. Her inspiring ignite talk on the power of one story point can be seen on <a href="https://vimeo.com/showcase/11113419?video=942924969">vimeo</a> or <a href="https://www.youtube.com/watch?v=EaFLd-RBUYo">youtube</a>. A few weeks after the event, she published a beautifully designed and crafted <a href="https://evelinarimkute.ch/Get-my-book/">book</a> on Lithuanian figures of speech:</p>
<p><img src="/images/blog/from-lithuania-with-love/book_cover_lithuanian_wit.jpg" alt="book cover lithuanian wit"></p>
<p>Being a language aficionado, this of course caught my interest&hellip;</p>
<p>I started reading about Lithuanian and Lithuania. I plan to write a separate article about the language later. In these first two posts I want to focus on my first visit to the country.</p>
<p>I had always been more oriented towards the west than the east. I had been a high school exchange student in the United States in 1991/92. While after my return to Switzerland I did have two years of Russian language classes in high school and even participated in a three-week exchange with a school in Barnaul in the West Siberian Altai region in 1995, my interest later turned west again: I first went to Portugal to learn Portuguese and then for an IAESTE internship to Brazil. And when I later got married to my Brazilian wife, family vacations were mainly spent in Switzerland, western Europe, Brazil and the United States.</p>
<p>And now, after 30 years, I suddenly started looking east again.</p>
<p>As I have observed in the meantime that not only me, but many people know only very little about Lithuania, I will start with some simple facts:</p>
<p>It is the southernmost of the three baltic states:</p>
<p><img src="/images/blog/from-lithuania-with-love/about_lithuania_1.jpg" alt="Facts &amp; Figures 1"></p>
<p><em>(Map taken from <a href="https://commons.wikimedia.org/wiki/File:Lithuania_in_Europe.svg">Wikimedia Commons</a>)</em></p>
<p>It&rsquo;s sometimes called the southernmost country of Northern Europe. It is further south than Denmark.</p>
<p>Zooming in, we see something which I found very counter-intuitive:</p>
<p><img src="/images/blog/from-lithuania-with-love/about_lithuania_2.jpg" alt="Facts &amp; Figures 2"></p>
<p><em>(Map taken from <a href="https://geology.com/world/lithuania-satellite-image.shtml">geology.com</a>)</em></p>
<p>It has no border to Russia in the east, but it has a border to Russia in the west! Kaliningrad Oblast is a Russian exclave. Lithuania&rsquo;s other neighbours are Latvia in the north, Belarus in the east and Poland in the south.</p>
<p><a href="https://en.wikipedia.org/wiki/Lithuania">Wikipedia</a> tells us that the country is not very densely populated:</p>
<p><img src="/images/blog/from-lithuania-with-love/about_lithuania_3.jpg" alt="Facts &amp; Figures 3"></p>
<p>It is about 1.5 times the size of Switzerland but has only 1/3 of the population. It&rsquo;s a very flat country: The highest hill is less than 300 meters high.</p>
<p>Lithuania has had a long and diverse history, sometimes great, sometimes tragic:</p>
<p><img src="/images/blog/from-lithuania-with-love/about_lithuania_4.jpg" alt="Facts &amp; Figures 4"></p>
<p>It was once a Grand Duchy, extending over Poland and Ukraine down to the Black Sea. Later it formed a Union and then a Commonwealth with Poland and adopted Catholicism. After the Partitioning of the Polish-Lithuanian Commonwealth, Lithuania became part of the Russian Empire. Independence was only reinstated after World War I and ended abruptly with the Soviet occupation in 1940 which lasted (only interrupted by the Nazi-German occupation for three years in 1941 - 1944) until Independence could finally be declared again after the fall of the Iron Curtain in 1990. Lithuania became a member of NATO and of the European Union in 2004 and of the Schengen Agreement in 2007. The country adopted the Euro as its currency in 2015.</p>
<p>Reading about Lithuania and its rich history opened my eyes to so many things I had never known or long forgotten or just not been fully aware of. That we were already two years into the Russian invasion of Ukraine gave the topic addional relevance. From my high-school history classes and countless Hollywood movies, my view of World War II had been largely determined by the Nazi atrocities in the west (like France) and east (like Poland) and by the concentration camps and the Holocaust. But now the Soviet terror suddenly gained focus. I was shocked to read stories of Lithuanians rounded up in the middle of the night and loaded into cattle carts where they would spend weeks and months on their way to Siberia where they would die of hunger, cold, sickness or simply the exhaustion of unbearably hard labour, horrors which I had previously only known from Holocaust movies like &ldquo;Schindler&rsquo;s List&rdquo; or slave trade accounts like Alex Haley&rsquo;s &ldquo;Roots&rdquo;. If you are brave enough, read <a href="https://rutasepetys.com/">Rūta Šepetys&rsquo;</a> novel <a href="https://rutasepetys.com/books/between-shades-of-gray/">Between Shades of Gray</a>:</p>
<p><img src="/images/blog/from-lithuania-with-love/book_cover_between_shades_of_gray.jpg" alt="book cover betweem shades of gray"></p>
<h2 id="a-vague-travel-plan-suddenly-getting-concrete">A vague travel plan suddenly getting concrete</h2>
<p>Luckily, my work contract grants me six weeks of annual leave, and while I naturally spend most of it with my family, my wife and my kids allow me to take one week for a personal project, in the last ten years usually a marathon trip. I also had several races planned for this year, but then I hurt my achilles tendon in February and had to cancel all of them. Suddenly, I had the time and mental space to consider a trip to Lithuania. And then around April I discovered that there are <a href="https://devopsdays.org/">DevOpsDays</a> in <a href="https://devopsdays.lt/">Vilnius</a> as well and applied for an ignite talk. I was of course extremely happy when my proposal got accepted on July 1st and I immediately started planning my trip: Booking flights and a hotel room, researching things to see and to do and signing up for some last-minute language classes.</p>
<h2 id="day-1-zürich---vilnius">Day 1: Zürich - Vilnius</h2>
<p><em>Monday, September 8th</em></p>
<p>There is only one direct flight from Zürich to Vilnius with Air Baltic in the middle of the night. At my advanced age, arriving at the hotel at 3 in the morning is not a good idea. It would just be jet lag at its finest! I therefore decided to fly with Austrian Airlines via Vienna. That meant two flights of roughly 1.5 hours each with a two-hour stop in between, leading to a total of 5 hours plus 1 hour time difference. I boarded the plane in Zürich at 9 in the morning and arrived in Vilnius at 3 in the afternoon.</p>
<p>I stayed at the Courtyard by Marriot Vilnius City Center hotel on Rinktinės Street, a clean and quiet business hotel with friendly and very supportive staff. It&rsquo;s a great location just a ten minutes&rsquo; walk from the old town, north of the Neris river across Karaliaus Mindaugo Tiltas (King Mindaugas Bridge). Getting there from the airport turned out to be very easy: Bus 3G goes directly to Žaliasis Tiltas (Green Bridge) from where it is just an 800 m walk eastward to the hotel. Tickets can conveniently be paid by card inside the bus.</p>
<p>As the weather was rather cloudy on that first evening and as I still had to polish the slides for my talk once more (yes, call me a perfectionist &hellip;), I just went for a quick dinner at some burger place and then back to the hotel to work.</p>
<h2 id="day-2-old-town-walk-and-balloon-flight">Day 2: Old Town Walk and Balloon Flight</h2>
<p><em>Tuesday, September 9th</em></p>
<p>In the morning of the my first full day, I did a free (i.e. tip-based or &ldquo;you pay what you want&rdquo;) <a href="https://vilniusfreetour.lt/old-town-tour/">Old Town Walking Tour</a> which I had booked a few days earlier from home with <a href="https://vilniusfreetour.lt/">vilniusfreetour.lt</a>. Our <a href="https://vilniusfreetour.lt/meet-a-guide/">guide Ugnė</a> did a fantastic job showing us around the old town with its churches, university district, courtyards and the presidential palace as well as the city hall. This historic city center is one of the largest in Europe which has survived the wars still more or less in its original shape. To give you just a few impressions:</p>
<p>King Mindaugas Monument in front of the Lithuanian National Museum and Gediminas Tower:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_2_old_town_mindaugas_monument.jpg" alt="Mindaugas Monument"></p>
<p>Courtyard of the Presidential Palace:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_2_old_town_courtyard_presidential_palace.jpg" alt="Courtyard of the Presidential Palace"></p>
<p>St. Anne&rsquo;s Church:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_2_old_town_st_annes_church.jpg" alt="St. Anne’s Church"></p>
<p>St. John&rsquo;s Church Bell Tower in the University District:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_2_old_town_st_johns_church_bell_tower.jpg" alt="St. John’s Church Bell Tower"></p>
<p>And finally the townhall square with the <a href="https://en.wikipedia.org/wiki/Portal_%28sculptures%29">Portal</a>, a sculpture which allows a kind of videoconferencing with other squares in other cities around the world:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_2_old_town_townhall_square.jpg" alt="Townhall Square"></p>
<p>In the afternoon I did a balloon flight. Hot air ballooning is very popular in Vilnius and other parts of Lithuania. As I had never done a ballon flight before, I did not want to miss this adventure! As the weather forecast was not good for the second half of the week, I had already booked it for Tuesday a few days earlier from home. There are many providers. After some quick research, I had decided for <a href="https://balloon.lt/">balloon.lt</a> which certainly was a good choice. Our pilot <a href="https://balloon.lt/about/">Saulius</a> was very friendly and very competent!</p>
<p>Flights take place around sunrise or sunset. The whole adventure takes about four hours: The crew pick all the passengers up at their hotel or apartment and take them to the launch site where the whole group (in our case six passengers, the pilot and two members of the ground crew) help unfolding and inflating the balloon. As soon as the nearby airport&rsquo;s flight security allows for take-off, the balloons (on that day a group of six from various providers) take off. The flight takes about one hour, and after landing the balloon needs to be deflated, folded and put back into the trailer before the flight can be celebrated with a glass of prosecco and the the passengers are all brought back to their hotel.</p>
<p>Was I scared? I must admit that at the beginning I was. I did not expect to be but I was. Initially the balloon had to rise high very quickly. That scared me, even more so as I am rather tall and was suddenly (unnecessarily) afraid of toppling over and falling out of the basket. I bent my knees a bit to be lower, and I did not look straight down but only towards the horizon. But after some time I got used to it, and once we had flown over the TV Tower and out of the city, the pilot could go lower over the woods and I was able to enjoy it even more.</p>
<p>It&rsquo;s a very beautiful, unique experience! No sound except for the occasional burning of the gas for rising further or just to prevent descending, no wind (as the balloon moves with the wind), just quiet peace in the beautful sunset. To share some of my impressions:</p>
<p>Ready for take-off at Vingis Park, 3 km west of the old town:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_2_balloon_1.jpg" alt="Balloon 1"></p>
<p>In the air over the forest at Vingis Park:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_2_balloon_2.jpg" alt="Balloon 2"></p>
<p>Flying over the TV tower, 326.5 m (1,071 ft) tall:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_2_balloon_3.jpg" alt="Balloon 3"></p>
<p>Flying out of the city, westward:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_2_balloon_4.jpg" alt="Balloon 4"></p>
<p>Outside the city, over the woods:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_2_balloon_5.jpg" alt="Balloon 5"></p>
<p>Already quite relaxed and enjoying it:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_2_balloon_6.jpg" alt="Balloon 6"></p>
<p>Only source of energy for vertical movement:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_2_balloon_7.jpg" alt="Balloon 7"></p>
<p>4 of the 5 other ballons in view:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_2_balloon_8.jpg" alt="Balloon 8"></p>
<p>Close to sunset and approaching the landing site:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_2_balloon_9.jpg" alt="Balloon 9"></p>
<p>The ground crews with vans and trailers already waiting at the landing site:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_2_balloon_10.jpg" alt="Balloon 10"></p>
<h2 id="days-3-and-4-devopsdays">Days 3 and 4: DevOpsDays</h2>
<p><em>Wednesday, September 10th, and Thursday, September 11th</em></p>
<p>On Wednesday and Thursday, I attended the <a href="https://devopsdays.lt/">DevOpsDays Vilnius 2025</a>. It was a fantastic event, full of interesting and thought-provoking talks, networking, fun, games and good food in a very welcoming atmosphere. As I have already shared some impressions together with a transcript and the slides of my own talk in a <a href="/blog/linguistic-silos/">separate article</a>, I will only add a few more things:</p>
<p>The event took place at <a href="https://cybercity.lt/">Cyber City</a>, a modern office space for tech start-ups (and unicorns) at the site of former textile factory Sparta:</p>
<p><img src="/images/blog/from-lithuania-with-love/dod_cyber_city.jpg" alt="DevOpsDays 1"></p>
<p>I like how they preserved the old chimney in the midst of the new shiny glass buildings. It reminds me a bit of Sihlcity, a mall at the site of a former paper factory, close to the Avaloq headquarters in Zürich.</p>
<p>The following four pictures have been taken by the DevOpsDays Vilnius organization and made available on <a href="https://www.flickr.com/photos/201468802@N03/albums/72177720329128794/">flickr</a> while all the other pictures in this article (including the one above) are my own.</p>
<p>More than 200 attendees listening intently in the main auditorium, here to <a href="https://www.linkedin.com/in/r-magalhaes/">Ricardo Miguel Magalhães</a>&rsquo;s talk on DevSecOps:</p>
<p><img src="/images/blog/from-lithuania-with-love/dod_ricardo_magalhaes_devsecops.jpg" alt="DevOpsDays 2"></p>
<p>Chill-out zone in the lobby:</p>
<p><img src="/images/blog/from-lithuania-with-love/dod_quiet_zone.jpg" alt="DevOpsDays 3"></p>
<p>Time for networking and playing games:</p>
<p><img src="/images/blog/from-lithuania-with-love/dod_games.jpg" alt="DevOpsDays 4"></p>
<p>And finally the after-event at Sparta Bar:</p>
<p><img src="/images/blog/from-lithuania-with-love/dod_after_event.jpg" alt="DevOpsDays 5"></p>
<p>There were two more participants from Switzerland: The picture above shows me on the right with keynote speaker <a href="https://www.linkedin.com/in/nadinebroghammer/">Nadine Broghammer</a> and speaker <a href="https://speakerdeck.com/janmoser">Jan Moser</a> (left), in their middle Lithuanian ignite speaker <a href="https://www.linkedin.com/in/albertas-grinkevi%C4%8Dius-9b7856138/">Albertas Grinkevičius</a>.</p>
<p>To chill down a bit after the second day of this exciting event, I walked the three kilometers back to the hotel. Approaching the river from the south side offered me a perfect view of the Šnipiškės district skyline across Baltasis Tiltas (White Bridge):</p>
<p><img src="/images/blog/from-lithuania-with-love/day_4_skyline.jpg" alt="DevOpsDays 6"></p>
<p>Zooming in to the Vilnius City Municipality Building on the right, you can see one of the many examples of the clear stand taken by the brave citizens and authorities in Vilnius and Lithuania:</p>
<p><img src="/images/blog/from-lithuania-with-love/day_4_the_hague.jpg" alt="DevOpsDays 7"></p>
<p><em>I still had three more days for sightseeing which I used for another guided walking tour, this time through the more modern Stotis District with its mix of old and new buildings and its great international street art, for a visit to the Museum of Occupations and Freedom Fights, for a train trip to Lithuania&rsquo;s second-largest city Kaunas and for attending Sunday service at an American gospel church right in the center of Vilnius. If you want to know more, check out the second part of this article <a href="/blog/from-lithuania-with-love-part-2/">here</a>.</em></p>
]]></content:encoded>
    </item>
    <item>
      <title>don&#39;t just say the same, mean the same - how to overcome linguistic silos</title>
      <link>https://walkagile.com/blog/linguistic-silos/</link>
      <pubDate>Sat, 20 Sep 2025 00:00:00 +0000</pubDate><author>peterhaefliger@yahoo.com (Peter Häfliger)</author>
      <guid>https://walkagile.com/blog/linguistic-silos/</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a transcript of the ignite talk which I have given at the &lt;a href=&#34;https://www.devopsdays.lt/&#34;&gt;DevOpsDays Vilnius 2025&lt;/a&gt; last week.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://walkagile.com/images/blog/linguistic-silos/presenting_2.jpg&#34; alt=&#34;1. picture 1&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;em&gt;If you don&amp;rsquo;t know what an ignite talk is, you might want to check out my &lt;a href=&#34;https://walkagile.com/blog/wholesome-talk/&#34;&gt;previous article&lt;/a&gt; about my first such talk given at the DevOpsDays Zürich last year where I explain the format and how to best prepare for it.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;em&gt;I had a great two days at this event which was perfectly organized. Kudos to the organizing team! As at the DevOpsDays Zürich which I have already attended twice, the atmosphere was extremely welcoming and inclusive as probably best illustrated by the &amp;ldquo;Pac Man Rule&amp;rdquo; which asks participants not to stand in closed circles but always leave room for others to join in:&lt;/em&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><em>This is a transcript of the ignite talk which I have given at the <a href="https://www.devopsdays.lt/">DevOpsDays Vilnius 2025</a> last week.</em></p>
<p><img src="/images/blog/linguistic-silos/presenting_2.jpg" alt="1. picture 1"></p>
<p><em>If you don&rsquo;t know what an ignite talk is, you might want to check out my <a href="/blog/wholesome-talk/">previous article</a> about my first such talk given at the DevOpsDays Zürich last year where I explain the format and how to best prepare for it.</em></p>
<p><em>I had a great two days at this event which was perfectly organized. Kudos to the organizing team! As at the DevOpsDays Zürich which I have already attended twice, the atmosphere was extremely welcoming and inclusive as probably best illustrated by the &ldquo;Pac Man Rule&rdquo; which asks participants not to stand in closed circles but always leave room for others to join in:</em></p>
<p><img src="/images/blog/linguistic-silos/pac_man_rule.jpg" alt="2. picture 2"></p>
<p><em>The name tags also had a &ldquo;handle&rdquo; (or rather an instruction on how the person wanted to be handled?) for which one could choose from three stickers:</em></p>
<ul>
<li><em>Come talk to me (I might be too shy to talk to you first)</em></li>
<li><em>I will talk to you if I want to talk (otherwise please do not talk to me)</em></li>
<li><em>Don&rsquo;t talk to me at all (I am here for the presentations, not for conversation)</em></li>
</ul>
<p><img src="/images/blog/linguistic-silos/name_tag.jpg" alt="3. picture 3"></p>
<p><em>You immediately know what you&rsquo;re at with anybody you encounter :-) Expectations well managed!</em></p>
<p><em>But now to the transcript of my talk:</em></p>
<p>Laba diena. Mano vardas yra Peter.</p>
<p>That&rsquo;s about all I can say in Lithuanian. But I want to learn more because I love your language.</p>
<p>I love languages in general. That&rsquo;s why I talk about language.</p>
<p><img src="/images/blog/linguistic-silos/dodvilnius2025_ignite_peterhaefliger_linguisticsilos_pg01.png" alt="4. slide 1"></p>
<p>Linguists distinguish between &ldquo;concepts&rdquo; and their &ldquo;labels&rdquo; or &ldquo;terms&rdquo; or &ldquo;names&rdquo;.</p>
<p>Obviously, different languages use different labels. And as the cover does not change a book, the label will not change a concept.</p>
<p><img src="/images/blog/linguistic-silos/dodvilnius2025_ignite_peterhaefliger_linguisticsilos_pg02.png" alt="5. slide 2"></p>
<p>Because a house is still a house, even if you call it namas, and a rose by any other name would smell as sweet (as Juliet says in Shakespeare&rsquo;s play).</p>
<p><img src="/images/blog/linguistic-silos/dodvilnius2025_ignite_peterhaefliger_linguisticsilos_pg03.png" alt="6. slide 3"></p>
<p>On the other hand, using the same term for different concepts is already more confusing.</p>
<p><img src="/images/blog/linguistic-silos/dodvilnius2025_ignite_peterhaefliger_linguisticsilos_pg04.png" alt="7. slide 4"></p>
<p>But when languages use different concepts, it gets really bad.</p>
<p>I am from Switzerland. We have 4 official national languages. 3 of them we share with our neighbours Germany, France and Italy.</p>
<p>But languages come in flavours, styles and dialects.</p>
<p><img src="/images/blog/linguistic-silos/dodvilnius2025_ignite_peterhaefliger_linguisticsilos_pg05.png" alt="8. slide 5"></p>
<p>I am from the German-speaking part. I learnt French at school. French French.</p>
<p><img src="/images/blog/linguistic-silos/dodvilnius2025_ignite_peterhaefliger_linguisticsilos_pg06.png" alt="9. slide 6"></p>
<p>And then I served in the Swiss Army as a quartermaster sergeant. And a captain ordered a &ldquo;dîner&rdquo; for his 100 soldiers. And then he called me angrily at 12:15:</p>
<ul>
<li>&ldquo;Where&rsquo;s my dîner?!&rdquo;</li>
<li>&ldquo;Well, it will be served at 6 in the evening, of course.&rdquo;</li>
</ul>
<p>A very uncomfortable situation&hellip;</p>
<p><img src="/images/blog/linguistic-silos/dodvilnius2025_ignite_peterhaefliger_linguisticsilos_pg07.png" alt="10. slide 7"></p>
<p>What&rsquo;s the problem here? The problem is that while for a Frenchman &ldquo;dîner&rdquo; is the evening meal, for a French-speaking Swiss it is lunch!</p>
<p><img src="/images/blog/linguistic-silos/dodvilnius2025_ignite_peterhaefliger_linguisticsilos_pg08.png" alt="11. slide 8"></p>
<p>And English is not much better!</p>
<p>According to Wikipedia, dinner is a meal <em>of any size</em> eaten <em>at any time of the day</em>! And the meaning as the evening meal is only <em>becoming</em> standard in <em>most</em> places.</p>
<p><img src="/images/blog/linguistic-silos/dodvilnius2025_ignite_peterhaefliger_linguisticsilos_pg09.png" alt="12. slide 9"></p>
<p>Another real-world example:</p>
<p>My Ukraininan colleague Olha usually said at the daily stand-up something like &ldquo;We have met with David yesterday to discuss the solution.&rdquo;</p>
<p>How many people have met?</p>
<p><img src="/images/blog/linguistic-silos/dodvilnius2025_ignite_peterhaefliger_linguisticsilos_pg10.png" alt="13. slide 10"></p>
<p>At least 3, right?</p>
<p>But then I learnt that many times only 2 people would have met.</p>
<p>What&rsquo;s going on here? Is Olha using the queen&rsquo;s plural on herself? Is she such an arrogant diva?</p>
<p><img src="/images/blog/linguistic-silos/dodvilnius2025_ignite_peterhaefliger_linguisticsilos_pg11.png" alt="14. slide 11"></p>
<p>Well, no, because in Slavic languages there is the &ldquo;inclusive we&rdquo;. A very nice concept which we lack in English or German.</p>
<p><img src="/images/blog/linguistic-silos/dodvilnius2025_ignite_peterhaefliger_linguisticsilos_pg12.png" alt="15. slide 12"></p>
<p>Then there is the gender of the sun.</p>
<p>In German it&rsquo;s female, in Italian male. Maybe because in Germany, people used to long for some sweet <em>warmth</em> after a long cold winter, while in Italy they always knew the destructive force of the <em>hot</em> sun.</p>
<p><img src="/images/blog/linguistic-silos/dodvilnius2025_ignite_peterhaefliger_linguisticsilos_pg13.png" alt="16. slide 13"></p>
<p>Experience and culture shape langage.</p>
<p>And research done by linguists like <a href="http://lera.ucsd.edu/">Lera Boroditsky</a> shows that this also works the other way round: Language shapes the mental model and even the perception of the world.</p>
<p><img src="/images/blog/linguistic-silos/dodvilnius2025_ignite_peterhaefliger_linguisticsilos_pg14.png" alt="17. slide 14"></p>
<p>Bridges are male in Spanish and female in German. And Spanish people tend to describe bridges with male attributes like &ldquo;strong&rdquo;, while Germans tend to use female attributes like &ldquo;beautiful&rdquo; or &ldquo;elegant&rdquo;.</p>
<p><img src="/images/blog/linguistic-silos/dodvilnius2025_ignite_peterhaefliger_linguisticsilos_pg15.png" alt="18. slide 15"></p>
<p>So in a linguistically diverse team, even if we all seem to speak the same language, we have different linguistic backgrounds which can create linguistic barriers or silos.</p>
<p><img src="/images/blog/linguistic-silos/dodvilnius2025_ignite_peterhaefliger_linguisticsilos_pg16.png" alt="19. slide 16"></p>
<p>Now what does all of this have to do with devops?</p>
<p>Well, devops is about overcoming the friction created by silos, and thus about collaboration.</p>
<p><img src="/images/blog/linguistic-silos/dodvilnius2025_ignite_peterhaefliger_linguisticsilos_pg17.png" alt="20. slide 17"></p>
<p>How can we overcome linguistic silos?</p>
<p>We need to accept and embrace diversity and recoginize our own hidden assumptions by stepping out of our silos, for example by learning other languages.</p>
<p><img src="/images/blog/linguistic-silos/dodvilnius2025_ignite_peterhaefliger_linguisticsilos_pg18.png" alt="21. slide 18"></p>
<p>And we need to formulate explicit requirements, define terms, challenge terms, maybe even create our own team terms and metaphors.</p>
<p><img src="/images/blog/linguistic-silos/dodvilnius2025_ignite_peterhaefliger_linguisticsilos_pg19.png" alt="22. slide 19"></p>
<p>Time&rsquo;s up already! Thank you for listening! You&rsquo;re allowed to talk to me afterwards!</p>
<p><em>(pointing at my name tag with the &ldquo;Come talk to me&rdquo; sticker)</em></p>
<p>And if you do it in Lithuanian, please keep it slow and easy! Ačiū!</p>
<p><img src="/images/blog/linguistic-silos/dodvilnius2025_ignite_peterhaefliger_linguisticsilos_pg20.png" alt="23. slide 20"></p>
<p><em>The full PDF slide deck can be found <a href="/files/blog/linguistic-silos/dodvilnius2025_ignite_peterhaefliger_linguisticsilos.pdf">here</a>.</em></p>
<p><img src="/images/blog/linguistic-silos/presenting_1.jpg" alt="24. picture 4"></p>
]]></content:encoded>
    </item>
    <item>
      <title>wholesome talk - language patterns for feedback and learning</title>
      <link>https://walkagile.com/blog/wholesome-talk/</link>
      <pubDate>Sun, 21 Apr 2024 00:00:00 +0000</pubDate><author>peterhaefliger@yahoo.com (Peter Häfliger)</author>
      <guid>https://walkagile.com/blog/wholesome-talk/</guid>
      <description>&lt;p&gt;&lt;em&gt;This article is about the ignite talk which I have given at the &lt;a href=&#34;https://www.devopsdays.ch/&#34;&gt;DevOpsDays Zurich 2024&lt;/a&gt; earlier this week.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://walkagile.com/images/blog/wholesome-talk/speaking.jpg&#34; alt=&#34;1. picture 1&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;em&gt;I had never spoken at any conference before. As a product owner and former scrum master, I am used to facilitating events with my team or presenting to customers. In such informal settings, the speaker usually speaks freely and abuses the slides as notes to remember what they want to say. That&amp;rsquo;s why most such slides contain much too much text. In the extreme case, they contain the full speech and would better just be sent out for everyone to read by themself instead of being read aloud to the gathered audience.&lt;/em&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><em>This article is about the ignite talk which I have given at the <a href="https://www.devopsdays.ch/">DevOpsDays Zurich 2024</a> earlier this week.</em></p>
<p><img src="/images/blog/wholesome-talk/speaking.jpg" alt="1. picture 1"></p>
<p><em>I had never spoken at any conference before. As a product owner and former scrum master, I am used to facilitating events with my team or presenting to customers. In such informal settings, the speaker usually speaks freely and abuses the slides as notes to remember what they want to say. That&rsquo;s why most such slides contain much too much text. In the extreme case, they contain the full speech and would better just be sent out for everyone to read by themself instead of being read aloud to the gathered audience.</em></p>
<p><em>So the first thing to invest in for a conference talk is the slides: They should only contain the main message points and visual elements to support the message, lighten the mood or entertain the audience. They should not distract the audience from what the speaker is saying. The listener should not have to constantly decide whether they want to read or listen. When I handed in my slides, I thought that I had stripped them down to the minimum. Looking at them today, I would greatly reduce the text even further.</em></p>
<p><em>The full PDF slide deck can be found <a href="/files/blog/wholesome-talk/dodzurich2024_ignite_peterhaefliger_wholesometalk.pdf">here</a>.</em></p>
<p><em>The <a href="https://en.wikipedia.org/wiki/Ignite_%28event%29">ignite</a> format is quite special: The speaker hands in 20 slides which are auto-advanced every 15 seconds, 5 minutes in total. During the talk, the speaker has no control over their slides; they just advance every 15 seconds. That probably makes free speaking a bad idea because the talk might fall behind or run ahead of the slides.</em></p>
<p><em>Good timing must be practiced:</em></p>
<ul>
<li><em>when some words are hard to pronounce or twist your tongue &ndash;&gt; find alternatives</em></li>
<li><em>when a slide always advances too fast &ndash;&gt; shorten the text or split the slide into two</em></li>
<li><em>when you always have to wait for a slide to advance &ndash;&gt; merge two slides into one</em></li>
</ul>
<p><em>I would assume that slam poets work similarly. If you love language, rhythm and flow, the preparation process is a lot of fun. I had the privilege of work colleagues who supported me with their feedback.</em></p>
<p><em>But even with all that thorough preparation, with the perfect instructions we got from the organizers on where to stand on the stage and how to hold the microphone and with the awesome introduction by Dirk, the master of ceremonies, I was quite nervous when I finally entered the stage. I appeared very calm to the audience (you can check out the video recording <a href="https://vimeo.com/942923466">here</a>), but believe me: I wasn&rsquo;t.</em></p>
<p><em>And here&rsquo;s the full transcript of the talk:</em></p>
<p>Good afternoon! My name is Peter Häfliger, I&rsquo;m a business analyist and product owner at Avaloq and, as Dirk mentioned, I would like to speak about &ldquo;wholesome talk - language patterns for feedback and learning&rdquo;.</p>
<p><img src="/images/blog/wholesome-talk/dodzurich2024_ignite_peterhaefliger_wholesometalk_pg01.png" alt="2. slide 1"></p>
<p>It&rsquo;s a special topic for me because usually I tell people that the <em>walk</em> is more important than the <em>talk</em>. But that&rsquo;s when they are just using agile buzzwords instead of applying agile principles and living agile values.</p>
<p><img src="/images/blog/wholesome-talk/dodzurich2024_ignite_peterhaefliger_wholesometalk_pg02.png" alt="3. slide 2"></p>
<p>I recently came to understand that there is a different type of talk which actually enables and supports the walk. And the eye-opener was this book by <a href="https://davidmarquet.com/">David Marquet</a>: <a href="https://davidmarquet.com/books/leadership-is-language/">&ldquo;Leadership is Language&rdquo;</a>. David Marquet is better known for his first book <a href="https://davidmarquet.com/turn-the-ship-around-book/">&ldquo;Turn the Ship Around!&rdquo;</a>.</p>
<p><img src="/images/blog/wholesome-talk/dodzurich2024_ignite_peterhaefliger_wholesometalk_pg03.png" alt="4. slide 3"></p>
<p>I call this type of talk &ldquo;wholesome talk&rdquo;. It consists of language patterns which invite feedback and foster learning.</p>
<p><img src="/images/blog/wholesome-talk/dodzurich2024_ignite_peterhaefliger_wholesometalk_pg04.png" alt="5. slide 4"></p>
<p>But for this to work, there is one important precondition: Leaders must care about feedback and diversity of opinion.</p>
<p>Some leaders don&rsquo;t want any feedback because they are so convinced of their own genius.</p>
<p>They are not curious.</p>
<p>They don&rsquo;t want to learn.</p>
<p>They will never walk agile.</p>
<p><img src="/images/blog/wholesome-talk/dodzurich2024_ignite_peterhaefliger_wholesometalk_pg05.png" alt="6. slide 5"></p>
<p>A tragic implementation of this anti-pattern to agility is Mao&rsquo;s Great Leap Forward.</p>
<p>If you want to read about the devastating effects of Mao&rsquo;s genius on the Chinese economy, check out <a href="https://timharford.com/">Tim Harford</a>&rsquo;s book <a href="https://timharford.com/books/undercovereconomist/">&ldquo;The Undercover Economist&rdquo;</a>. The last chapter.</p>
<p><img src="/images/blog/wholesome-talk/dodzurich2024_ignite_peterhaefliger_wholesometalk_pg06.png" alt="7. slide 6"></p>
<p>Because feedack hits you anyway - sooner or later.</p>
<p>And in Agile and DevOps, we want to get it as soon as possible, while we can still react and adapt.</p>
<p><img src="/images/blog/wholesome-talk/dodzurich2024_ignite_peterhaefliger_wholesometalk_pg07.png" alt="8. slide 7"></p>
<p>But leaders must be careful because they can stifle feedback even without intending to.</p>
<p>Leaders are convincing.</p>
<p>They are charismatic, experienced, visionary or even all three of that at once.</p>
<p>If they present their ideas and opinions first&hellip;</p>
<p><img src="/images/blog/wholesome-talk/dodzurich2024_ignite_peterhaefliger_wholesometalk_pg08.png" alt="9. slide 8"></p>
<p>&hellip; the others will listen but no one will speak up.</p>
<p>That&rsquo;s why leaders have to listen first and speak last.</p>
<p>They have to do everything they can to flatten the Power Gradient.</p>
<p><img src="/images/blog/wholesome-talk/dodzurich2024_ignite_peterhaefliger_wholesometalk_pg09.png" alt="10. slide 9"></p>
<p>Imagine you&rsquo;re a leader or expert or senior team member and you approach your colleagues like this, even stressing and highlighting all your experience and expertise. Well, who could then say anything against your opinion?!</p>
<p><img src="/images/blog/wholesome-talk/dodzurich2024_ignite_peterhaefliger_wholesometalk_pg10.png" alt="11. slide 10"></p>
<p>You will only get alternative viewpoints if you actively invite them and if you communicate with your colleagues on eye level.</p>
<p><img src="/images/blog/wholesome-talk/dodzurich2024_ignite_peterhaefliger_wholesometalk_pg11.png" alt="12. slide 11"></p>
<p>There is other mistakes you should avoid, for example the Seven Sins of Questioning. One of them is binary questions.</p>
<p>The problem with binary questions is that they force a 55% yes into a 100% yes, and they put the full responsibility onto the receiver of the question.</p>
<p>And if then anything goes wrong: &ldquo;Well, it was <em>you</em> who said it was safe!&rdquo;</p>
<p><img src="/images/blog/wholesome-talk/dodzurich2024_ignite_peterhaefliger_wholesometalk_pg12.png" alt="13. slide 12"></p>
<p>So don&rsquo;t use binary questions!</p>
<p>Use &ldquo;how?&rdquo; questions or &ldquo;what?&rdquo; questions instead:</p>
<p>How safe is it?</p>
<p>What&rsquo;s your tension with this approach?</p>
<p>What might go wrong?</p>
<p>What would be the alternatives?</p>
<p><img src="/images/blog/wholesome-talk/dodzurich2024_ignite_peterhaefliger_wholesometalk_pg13.png" alt="14. slide 13"></p>
<p>Even worse than binary questions are self-affirming binary questions because they really just force affirmation onto the receiver.</p>
<p>You will not learn anything new from the answers.</p>
<p>So ask open questions instead: Explicitly ask what you are missing.</p>
<p><img src="/images/blog/wholesome-talk/dodzurich2024_ignite_peterhaefliger_wholesometalk_pg14.png" alt="15. slide 14"></p>
<p>And don&rsquo;t ask &ldquo;why?&rdquo; because it might put the receiver into defensive mode.</p>
<p>If you don&rsquo;t want your curiosity to be mistaken for criticism, ask &ldquo;what?&rdquo; questions again or open questions.</p>
<p><img src="/images/blog/wholesome-talk/dodzurich2024_ignite_peterhaefliger_wholesometalk_pg15.png" alt="16. slide 15"></p>
<p>And finally, studies have shown that if you praise a child for being good at something, they will choose a simpler task next to get praised again for being good.</p>
<p><img src="/images/blog/wholesome-talk/dodzurich2024_ignite_peterhaefliger_wholesometalk_pg16.png" alt="17. slide 16"></p>
<p>If, on the other hand, you praise them for behaviour, they will choose a more complex task next.</p>
<p>And that&rsquo;s a natural reaction because we all crave for praise, and we all want to feel competent and we all want to be good at what we are doing.</p>
<p><img src="/images/blog/wholesome-talk/dodzurich2024_ignite_peterhaefliger_wholesometalk_pg17.png" alt="18. slide 17"></p>
<p>But while being good is good, getting better is better.</p>
<p>That&rsquo;s why we want feedback and learning.</p>
<p>And then one day we will indeed do great leaps - even through fire!</p>
<p><img src="/images/blog/wholesome-talk/dodzurich2024_ignite_peterhaefliger_wholesometalk_pg18.png" alt="19. slide 18"></p>
<p>So let&rsquo;s quickly recap:</p>
<p><img src="/images/blog/wholesome-talk/dodzurich2024_ignite_peterhaefliger_wholesometalk_pg19.png" alt="20. slide 19"></p>
<p>And with that, time&rsquo;s up already!</p>
<p><img src="/images/blog/wholesome-talk/dodzurich2024_ignite_peterhaefliger_wholesometalk_pg20.png" alt="21. slide 20"></p>
<p>Sorry, no time for feedback now - approach me later anytime!</p>
<p>Thank you!</p>
<p><em>I did mention that I was quite nervous, right? So imagine my relief when it was over and had gone well without any major blunders! (Again, the video recording can be found <a href="https://vimeo.com/942923466">here</a>.) The following picture was taken right after I had left the stage and received some extra presents from the organizers:</em></p>
<p><img src="/images/blog/wholesome-talk/afterwards.jpg" alt="22. picture 2"></p>
]]></content:encoded>
    </item>
    <item>
      <title>Backtracking algorithms: experiment, inspect and adapt</title>
      <link>https://walkagile.com/blog/backtracking-algorithms/</link>
      <pubDate>Thu, 29 Feb 2024 00:00:00 +0000</pubDate><author>peterhaefliger@yahoo.com (Peter Häfliger)</author>
      <guid>https://walkagile.com/blog/backtracking-algorithms/</guid>
      <description>&lt;p&gt;In this article I tell the story of a beautiful &lt;strong&gt;picture&lt;/strong&gt; which represents an interesting mathematical &lt;strong&gt;problem&lt;/strong&gt; whose algorithmic &lt;strong&gt;solution&lt;/strong&gt; has some &lt;strong&gt;analogy&lt;/strong&gt; to the agile way of solving problems and making progress.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-picture&#34;&gt;The picture&lt;/h2&gt;&#xA;&lt;p&gt;My former high school math teacher &lt;a href=&#34;https://www.linkedin.com/in/hansruediwidmer/&#34;&gt;Hansruedi Widmer&lt;/a&gt; (&amp;ldquo;retired as a teacher, not as a mathematician&amp;rdquo;) daily posts mathematical puzzles, bits of history or just &amp;ldquo;fun facts&amp;rdquo; on X (formerly known as twitter). Two years ago, on March 1&lt;sup&gt;st&lt;/sup&gt;, 2022, which was the 60&lt;sup&gt;th&lt;/sup&gt; day of the year, he tweeted the following (translation from German is mine):&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>In this article I tell the story of a beautiful <strong>picture</strong> which represents an interesting mathematical <strong>problem</strong> whose algorithmic <strong>solution</strong> has some <strong>analogy</strong> to the agile way of solving problems and making progress.</p>
<h2 id="the-picture">The picture</h2>
<p>My former high school math teacher <a href="https://www.linkedin.com/in/hansruediwidmer/">Hansruedi Widmer</a> (&ldquo;retired as a teacher, not as a mathematician&rdquo;) daily posts mathematical puzzles, bits of history or just &ldquo;fun facts&rdquo; on X (formerly known as twitter). Two years ago, on March 1<sup>st</sup>, 2022, which was the 60<sup>th</sup> day of the year, he tweeted the following (translation from German is mine):</p>
<blockquote>
<p>As it is day 60: The numbers from 1 to 60 can be paired in such a way that the sum of every pair is one of the square numbers 3<sup>2</sup>, 6<sup>2</sup>, 7<sup>2</sup>, 8<sup>2</sup>, 9<sup>2</sup>.</p>
<p><img src="/images/blog/backtracking-algorithms/rainbow_squares.jpg" alt="rainbow squares"></p>
<p>— <!-- raw HTML omitted --><a href="https://twitter.com/HansruediWidmer/status/1498540361827954689">tweet</a> by <a href="https://twitter.com/HansruediWidmer">Hansruedi Widmer</a> on March 1<sup>st</sup>, 2022<!-- raw HTML omitted --></p>
</blockquote>
<p>I found (and still find) this drawing (figure 1) very beautiful, like a piece of art, and I wanted to know more about the underlying mathematical problem:</p>
<ol>
<li>Is there more than one solution which satisfies the given constraints?</li>
<li>And if yes, how can they be found?</li>
</ol>
<p>I have been thinking, experimenting and writing about this problem every once in a while, time and again, but something (new job, continuing professional education, family) always got in the way of finishing this article. But finally, on the occasion of the 60<sup>th</sup> day of this year - which, because it is a leap year, is not on March 1<sup>st</sup> but on February 29<sup>th</sup> - I got it done. I hope you enjoy reading it as much as I enjoyed writing it.</p>
<h2 id="the-problem">The problem</h2>
<p>I asked Hansruedi, but all he could tell me without further investigation was that 93 pairs could be formed with the numbers from 1 to 60 whose sum was an element of the set {9, 36, 49, 64, 81}. The solution was to choose 30 out of these 93 pairs such that every number from 1 to 60 was included exactly once.</p>
<p>The 93 pairs can easily be found by iterating over all numbers i from 1 to 60 and checking for every number j between (i + 1) and 60 whether the sum of i and j is an element of the above set of square numbers:</p>
<ul>
<li>1 can be paired with 8 (to yield 9), with 35 (to yield 36) and with 48 (to yield 49)</li>
<li>2 can be paired with 7 (to yield 9), with 34 (to yield 36) and with 47 (to yield 49)</li>
<li>3 can be paired with 6 (to yield 9), with 33 (to yield 36) and with 46 (to yield 49)</li>
<li>4 can be paired with 5 (to yield 9), with 32 (to yield 36), with 45 (to yield 49) and with 60 (to yield 64)</li>
<li>5 can be paired with 31 (to yield 36), with 44 (to yield 49) and with 59 (to yield 64)</li>
<li>and so on</li>
</ul>
<p>Alternatively, of course, the pairs can be found the inverse way, by iterating over all numbers i from 60 down to 1 and checking for every number j between (i - 1) and 1 whether the sum of i and j is an element of the target set.</p>
<p>A table with all pairs sorted in different ways can be found <a href="/materials/blog/backtracking-algorithms/table-pairs/">here</a>.</p>
<p>The difficult part is to find 30 pairs out of these 93 which satisfy the additional constraint that every number from 1 to 60 is included exactly once.</p>
<p>As Hansruedy had not investigated this any further, I had to give it a try myself.</p>
<h2 id="the-solution">The solution</h2>
<h3 id="1hahahugoshortcode8s11hbhb-attempt-a-dead-end">1<sup>st</sup> attempt: a dead end</h3>
<p>Maybe pushed a bit into this direction by Hansruedi&rsquo;s very mathematical problem description (&ldquo;Choose 30 out of these 93 pairs such that &hellip;&rdquo;) I tried exactly that: Somehow generate all possible subsets of 30 pairs out of the whole set of 93 pairs and then apply the additional constraints. None of my experiments worked, and if you look at the sheer dimension of the problem, it becomes obvious that none of them could work, at least not with today&rsquo;s computers:</p>
<p><a href="https://www.mathsisfun.com/combinatorics/combinations-permutations.html">Combinatorics</a> tells us that the number of possible ways to choose 30 pairs out of 93 is</p>
<p>&ldquo;93 choose 30&rdquo; = 93! / (30! x (93-30)!) = 93! / (30! x 63!)</p>
<p>which is 2.200 x 10<sup>24</sup>, i.e. 2.2 septillion, which is an enormous number (22 followed by 23 zeroes).</p>
<p>A web search led me to the <a href="https://old.maa.org/sites/default/files/pdf/awards/college.math.j.46.4.264.pdf">paper from the Mathematical Association of America( MAA)</a> from which the above picture must have been taken. I learned that the problem is called &ldquo;rainbow squares&rdquo; because of the way in which the pairs with equal sum are marked with the same color, or simply &ldquo;rainbow pairs&rdquo; for the more general case where the sums are subject to some constraint different from being square numbers (e.g. polynomials or Fibonacci numbers).</p>
<p>I also learned from this paper that the number of solutions for the numbers from 1 to 60 where the sum is constraint to be <em>any</em> square, i.e. {4, 9, 16, 25, 36, 49, 64, 81, 100} is 4,366,714! But how many solutions would there be with the narrower constraint set {9, 36, 49, 64, 81}? And how could they be found?</p>
<h3 id="2hahahugoshortcode8s13hbhb-attempt-slowly-getting-there">2<sup>nd</sup> attempt: slowly getting there</h3>
<p>As the purely mathematical approach had not worked, I tried to think about the problem more <em>procedurally</em>: Not in terms of selecting pairs but in terms of drawing the beautful picture shown in figure 1: If I had a sheet of paper with the circle of numbers from 1 to 60 and five colored pencils, how would I go about drawing such a picture?</p>
<p>Starting with the empty &ldquo;circle&rdquo; (figure 2):</p>
<p><img src="/images/blog/backtracking-algorithms/backtracking_1_empty.png" alt="backtracking 1: empty circle"></p>
<p>I would begin with the lowest number - 1 - and <em>tentatively</em> mark a pair for it. I could use any of the three possible pairs shown in the <a href="/materials/blog/backtracking-algorithms/table-pairs/">reference table</a>, so to do it sistematically, I would just choose the first one from the second column in the table. This is the lowest pairing, which is 8 (figure 3):</p>
<p><img src="/images/blog/backtracking-algorithms/backtracking_2_1_pair.png" alt="backtracking 2: 1 pair"></p>
<p>I would do the same for the next three numbers 2 to 4 (figure 4):</p>
<p><img src="/images/blog/backtracking-algorithms/backtracking_3_4_pairs.png" alt="backtracking 3: 4 pairs"></p>
<p>As the numbers 5 to 8 are already paired, I would continue with 9 to 17 (figure 5):</p>
<p><img src="/images/blog/backtracking-algorithms/backtracking_4_13_pairs.png" alt="backtracking 4: 13 pairs"></p>
<p>And 18 (figure 6):</p>
<p><img src="/images/blog/backtracking-algorithms/backtracking_5_14_pairs.png" alt="backtracking 5: 14 pairs"></p>
<p>Again, as the numbers 19 to 27 are already paired, I would continue with 28 to 30 (figure 7):</p>
<p><img src="/images/blog/backtracking-algorithms/backtracking_6_17_pairs.png" alt="backtracking 6: 17 pairs"></p>
<p>And then all the numbers from 32 to 40 which have not already been paired (figure 8):</p>
<p><img src="/images/blog/backtracking-algorithms/backtracking_7_23_pairs.png" alt="backtracking 7: 23 pairs"></p>
<p>And as numbers 41 to 44 have already been paired, I would now like to continue wth 45, but there is a problem: As can be seen in the <a href="/materials/blog/backtracking-algorithms/table-pairs/">reference table</a>, there is no more pairing possible for 45. What to do now?</p>
<p>As I have said at the beginning, I have just marked the pairs <em>tentatively</em>, so I can now trace back and erase the latest pair marked ([40 - 41]) (figure 9):</p>
<p><img src="/images/blog/backtracking-algorithms/backtracking_8_22_pairs.png" alt="backtracking 8: 22 pairs"></p>
<p>Unfortunately, this is not enough because at this point I have no alternative for number 40 than to pair it with 41. So I have to trace further back until I arrive at the number for which there is an alternative path forward. This is number 30 (figure 10):</p>
<p><img src="/images/blog/backtracking-algorithms/backtracking_9_16_pairs.png" alt="backtracking 9: 22 pairs"></p>
<p>Instead of pairing 30 with 34, I now pair it with 51 (figure 11):</p>
<p><img src="/images/blog/backtracking-algorithms/backtracking_10_17_pairs.png" alt="backtracking 10: 17 pairs"></p>
<p>And continue forward from there until I run into another dead end, which happens to be at number 45 again (figure 12):</p>
<p><img src="/images/blog/backtracking-algorithms/backtracking_11_24_pairs.png" alt="backtracking 10: 17 pairs"></p>
<p>So I have to trace back to 30 again, but as there is no third alternative besides 34 and 51 for 30, I have to trace yet another step back to 29 and pair it with 52 instead of 35 (figure 13):</p>
<p><img src="/images/blog/backtracking-algorithms/backtracking_12_16_pairs.png" alt="backtracking 12: 16 pairs"></p>
<p>And from here I can move forward again. And back and forth and back and forth again&hellip; And if there is a solution, I will eventually find it. But how long will it take?</p>
<p>Millions of repetions of the same small, simple step? Sounds like the perfect problem to write a program for!</p>
<p>This type of algorithm is called <a href="https://en.wikipedia.org/wiki/Backtracking">backtracking algorithm</a> as I remembered from the time I had once implemented a Sudoku solver in Ruby some 20 years earlier. <a href="https://en.wikipedia.org/wiki/Sudoku_solving_algorithms">Sudoku</a> is a very typical application of backtracking, as is the <a href="https://en.wikipedia.org/wiki/Eight_queens_puzzle">Eight Queens Problem</a> with which the algorithm is usually illustrated in textbooks. But the rainbow squares problem is equally well suited to illustrate backtracking, as I hope to have shown above.</p>
<p>I implemented the algorithm in python. The program file can be found <a href="/files/blog/backtracking-algorithms/Rainbow_Squares_backtracking_first_version.py">here</a> and its output file <a href="/files/blog/backtracking-algorithms/Rainbow_Squares_Solutions_backtracking_first_version.txt">here</a>. I will not explain the program here; I will explain the final version at the end of this solution section.</p>
<p>This first version worked exactly as shown in the figures above. It found 5294 solutions but ran 48 minutes on my machine (normal laptop, not quite new, nothing optimized, so the measurement is just for relative comparison with the improvements shown further below). That was disappointing and unexpected, because for an average Sudoku, a backtracking algorithm finds the solutions in a few seconds or even less than a second. Analysis showed that the algorithm had performed 5.2 billion tentative steps whereas an average Sudoku only requires something between 10,000 and 100,000 or in an extreme case maybe a million steps. The reason is that Sudokus are very highly constraint puzzles where many alternatives can be excluded early on. For this problem, on the other hand, even the first solution is only found after more than 47 million steps which means I could never have found it by hand within my lifetime.</p>
<h3 id="3hahahugoshortcode8s14hbhb-attempt-backward-is-faster">3<sup>rd</sup> attempt: backward is faster</h3>
<p>How could the algorithm for the rainbow squares be improved? I found a hint in the <a href="https://old.maa.org/sites/default/files/pdf/awards/college.math.j.46.4.264.pdf">AMM paper</a> mentioned above where for a simpler problem (numbers only from 1 to 18, not to 60) they ask whether it would be better to start with small pairs or large ones and answer that &ldquo;The latter is in fact more efficient since it presents fewer choices early on.&rdquo; That the same holds for our problem with numbers from 1 to 60 can be seen in the <a href="/materials/blog/backtracking-algorithms/table-pairs/">reference table</a>: While the twelve smallest numbers can form three or even four pairs each, the twelve largest numbers can only form two pairs each.</p>
<p>I changed the algorithm to run backwards from 60 to 1. Again, the program file can be found <a href="/files/blog/backtracking-algorithms/Rainbow_Squares_backtracking_reversed.py">here</a> and its output file <a href="/files/blog/backtracking-algorithms/Rainbow_Squares_Solutions_backtracking_reversed.txt">here</a>. And again, I will not explain the program here; I will explain the final version at the end of this solution section.</p>
<p>Running backwards reduced the number of tentative steps from 5.2 billion to 112 million and the execution time on the same machine from 48 to 2 minutes! And the first soluton is found after only 61 steps. This could be done by hand.</p>
<p>Why does the direction in which the algorithm runs have such a massive effect? The answer is that conceptually, the algorithm searches a tree of possibilities. Running it from 60 to 1 instead of from 1 to 60 changes the structure of this tree (figure 14):</p>
<p><img src="/images/blog/backtracking-algorithms/backtracking_tree_structure.png" alt="backtracking as tree traversal"></p>
<p>Starting with the largest pairs yields a tree which is narrower but deeper as - with a bit of imagination - could already have been seen in the <a href="/materials/blog/backtracking-algorithms/table-pairs/">reference table</a>. Or as the <a href="https://old.maa.org/sites/default/files/pdf/awards/college.math.j.46.4.264.pdf">AMM paper</a> states: &ldquo;&hellip; it presents fewer choices early on.&rdquo;</p>
<p>Another strategy which might be worth exploring is to run from 1 to 60 but for each number start with the highest-number pairing instead of the lowest one, i.e. pair 1 first with 48, 2 with 47, 3 with 46, 4 with 60 and so on. Thinking in terms of the tree, this means leaving the structure of the tree unchanged but exploring different branches first. I have not tried this.</p>
<p>I was not so interested in exploring these kinds of optimization any further because they are highly dependant on the concrete problem. Does the statement &ldquo;&hellip; it presents fewer choices early on&hellip;&rdquo; still hold if the target set is not a set of square numbers but e.g. of prime numbers? This would have to be analyzed for every case separately.</p>
<h3 id="4hahahugoshortcode8s15hbhb-and-final-attempt-fast-forward">4<sup>th</sup> and final attempt: fast forward</h3>
<p>The generic algorithm might benefit from tree optimization techniques, either up-front before starting the traversal, or even at every step of the search. But I have no experience with such techniques and have not explored them any further.</p>
<p>Besides the two optimization techniques just mentioned (optimizing the tree and optimizing the order in which the subtrees are searched at any given node), there is only one more area for optimization: making sure that all possible information is taken into account at every step to decide whether to continue the search in this direction or not.</p>
<p>Looking at my paper figures again and thinking a bit more about the forward and backward running algorithms, I suddenly found the missing piece: In the first version of my algorithm, on the first traversal &ldquo;down the tree&rdquo;, I chose the 11<sup>th</sup> pair to be [15 - 21] as shown in figure 5 because that&rsquo;s the first option listed for 15 in the second column of the <a href="/materials/blog/backtracking-algorithms/table-pairs/">reference table</a> and because the number 21 is not yet used by any other pair which means it is still available (figure 15):</p>
<p><img src="/images/blog/backtracking-algorithms/backtracking_13_10_pairs.png" alt="backtracking 13: 10 pairs"></p>
<p>But taking also the fourth column of the table into account (for all numbers greater than 15), I see that 60 can only be paired with 4 and 21. As 4 is already paired with 5, I cannot pair 15 with 21 now; I have to leave 21 free to be paired with 60. I will therefore try the second option for 15 right away, which is 34. I thus save myself from taking a wrong turn at this junction and traversing many additional subtrees which would not yield any result. 16 on the other hand can be paired with 20 as in the initial version of the algorithm (figure 16):</p>
<p><img src="/images/blog/backtracking-algorithms/backtracking_14_12_pairs.png" alt="backtracking 14: 12 pairs"></p>
<p>Taking this effect of the current pairing on potential future pairings into account allows to stop and retrace much earlier, i.e. cut off huge subtrees of the search tree which otherwise would have been traversed without any result.</p>
<p>If this additional check is incorporated into the forward-running algorithm which before took almost an hour to run and executed 5.2 billion steps, the program reaches roughly the same execution time as the backward-running algorithm (around 2 minutes) and uses less than 2 million steps! The number of steps is massively smaller even than for the backward-running algorithm (which needs 112 million steps) but unfortunately there is no further improvement on execution time as more checks have to be performed at every step. Performance-wise, the two effects seem to cancel each other out. Nevertheless, this final version of the algorithm is superior to the backward-running version because the optimization applied is more general, i.e. independent of the concrete problem and its tree structure. It will generally perform better also for other target sets like Fibonacci numbers or prime numbers. Of course, the different optimization strategies could all be combined, but as explained above, I had no interest in analysing specific optimizations for specific trees any further.</p>
<p>As promised, I will now show and explain the full program in its final version:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-py" data-lang="py"><span class="line"><span class="ln">  1</span><span class="cl"><span class="kn">import</span> <span class="nn">functools</span>
</span></span><span class="line"><span class="ln">  2</span><span class="cl">
</span></span><span class="line"><span class="ln">  3</span><span class="cl"><span class="c1"># function which calculates and returns the set of all possible pairs of numbers</span>
</span></span><span class="line"><span class="ln">  4</span><span class="cl"><span class="c1"># from 1...N which satisfy the condition that their sum is in the targets set</span>
</span></span><span class="line"><span class="ln">  5</span><span class="cl"><span class="k">def</span> <span class="nf">possible_pairings</span><span class="p">(</span><span class="n">N</span><span class="p">,</span> <span class="n">targets</span><span class="p">):</span>
</span></span><span class="line"><span class="ln">  6</span><span class="cl">  <span class="n">result_list</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="ln">  7</span><span class="cl">  <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">N</span><span class="o">+</span><span class="mi">1</span><span class="p">):</span>
</span></span><span class="line"><span class="ln">  8</span><span class="cl">    <span class="n">result_list</span><span class="o">.</span><span class="n">append</span><span class="p">([])</span>
</span></span><span class="line"><span class="ln">  9</span><span class="cl">  <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">N</span><span class="o">+</span><span class="mi">1</span><span class="p">):</span>
</span></span><span class="line"><span class="ln"> 10</span><span class="cl">    <span class="k">for</span> <span class="n">j</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">N</span><span class="o">+</span><span class="mi">1</span><span class="p">):</span>
</span></span><span class="line"><span class="ln"> 11</span><span class="cl">      <span class="k">if</span> <span class="n">i</span> <span class="o">!=</span> <span class="n">j</span> <span class="ow">and</span> <span class="n">i</span> <span class="o">+</span> <span class="n">j</span> <span class="ow">in</span> <span class="n">targets</span><span class="p">:</span>
</span></span><span class="line"><span class="ln"> 12</span><span class="cl">        <span class="n">result_list</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">j</span><span class="p">)</span>
</span></span><span class="line"><span class="ln"> 13</span><span class="cl">  <span class="k">return</span> <span class="n">result_list</span>
</span></span><span class="line"><span class="ln"> 14</span><span class="cl">
</span></span><span class="line"><span class="ln"> 15</span><span class="cl"><span class="c1"># global counter to keep track of the number of solutions found</span>
</span></span><span class="line"><span class="ln"> 16</span><span class="cl"><span class="n">solution_count</span> <span class="o">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="ln"> 17</span><span class="cl">
</span></span><span class="line"><span class="ln"> 18</span><span class="cl"><span class="c1"># global counter to keep track of the number of recursive solver calls</span>
</span></span><span class="line"><span class="ln"> 19</span><span class="cl"><span class="n">recursion_count</span> <span class="o">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="ln"> 20</span><span class="cl">
</span></span><span class="line"><span class="ln"> 21</span><span class="cl"><span class="c1"># recursive solver procedure</span>
</span></span><span class="line"><span class="ln"> 22</span><span class="cl"><span class="k">def</span> <span class="nf">solve</span><span class="p">(</span><span class="n">pos</span><span class="p">):</span>
</span></span><span class="line"><span class="ln"> 23</span><span class="cl">
</span></span><span class="line"><span class="ln"> 24</span><span class="cl">  <span class="k">global</span> <span class="n">recursion_count</span>
</span></span><span class="line"><span class="ln"> 25</span><span class="cl">  <span class="n">recursion_count</span> <span class="o">=</span> <span class="n">recursion_count</span> <span class="o">+</span> <span class="mi">1</span>
</span></span><span class="line"><span class="ln"> 26</span><span class="cl">
</span></span><span class="line"><span class="ln"> 27</span><span class="cl">  <span class="c1"># if all positions in the circle have been taken,</span>
</span></span><span class="line"><span class="ln"> 28</span><span class="cl">  <span class="c1"># a solution to the puzzle has been found</span>
</span></span><span class="line"><span class="ln"> 29</span><span class="cl">  <span class="k">if</span> <span class="n">pos</span> <span class="o">==</span> <span class="n">N</span><span class="o">+</span><span class="mi">1</span><span class="p">:</span>
</span></span><span class="line"><span class="ln"> 30</span><span class="cl">    <span class="k">global</span> <span class="n">solution_count</span>
</span></span><span class="line"><span class="ln"> 31</span><span class="cl">    <span class="n">solution_count</span> <span class="o">=</span> <span class="n">solution_count</span> <span class="o">+</span> <span class="mi">1</span>
</span></span><span class="line"><span class="ln"> 32</span><span class="cl">    <span class="n">log</span> <span class="o">=</span> <span class="s2">&#34;After &#34;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">recursion_count</span><span class="p">)</span> <span class="o">+</span> <span class="s2">&#34; total calls to &#39;solve()&#39;: &#34;</span>
</span></span><span class="line"><span class="ln"> 33</span><span class="cl">    <span class="n">log</span> <span class="o">=</span> <span class="n">log</span> <span class="o">+</span> <span class="s2">&#34;solution no &#34;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">solution_count</span><span class="p">)</span> <span class="o">+</span> <span class="s2">&#34;: &#34;</span>
</span></span><span class="line"><span class="ln"> 34</span><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="n">log</span><span class="p">)</span>
</span></span><span class="line"><span class="ln"> 35</span><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="n">used_pairs</span><span class="p">)</span>
</span></span><span class="line"><span class="ln"> 36</span><span class="cl">
</span></span><span class="line"><span class="ln"> 37</span><span class="cl">  <span class="c1"># if the current position in the circle has already been taken by the second</span>
</span></span><span class="line"><span class="ln"> 38</span><span class="cl">  <span class="c1"># element of a pair placed earlier, then move on to the next position</span>
</span></span><span class="line"><span class="ln"> 39</span><span class="cl">  <span class="k">elif</span> <span class="n">pos_taken</span><span class="p">[</span><span class="n">pos</span><span class="o">-</span><span class="mi">1</span><span class="p">]:</span>
</span></span><span class="line"><span class="ln"> 40</span><span class="cl">    <span class="n">solve</span><span class="p">(</span><span class="n">pos</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="ln"> 41</span><span class="cl">  <span class="k">else</span><span class="p">:</span>
</span></span><span class="line"><span class="ln"> 42</span><span class="cl">
</span></span><span class="line"><span class="ln"> 43</span><span class="cl">    <span class="c1"># else iterate over all possible pairs for the current position</span>
</span></span><span class="line"><span class="ln"> 44</span><span class="cl">    <span class="k">for</span> <span class="n">paired_pos</span> <span class="ow">in</span> <span class="n">possible_pairs</span><span class="p">[</span><span class="n">pos</span><span class="o">-</span><span class="mi">1</span><span class="p">]:</span>
</span></span><span class="line"><span class="ln"> 45</span><span class="cl">
</span></span><span class="line"><span class="ln"> 46</span><span class="cl">      <span class="c1"># if the position of the pair&#39;s second element is also available...</span>
</span></span><span class="line"><span class="ln"> 47</span><span class="cl">      <span class="k">if</span> <span class="ow">not</span> <span class="n">pos_taken</span><span class="p">[</span><span class="n">paired_pos</span><span class="o">-</span><span class="mi">1</span><span class="p">]:</span>
</span></span><span class="line"><span class="ln"> 48</span><span class="cl">
</span></span><span class="line"><span class="ln"> 49</span><span class="cl">        <span class="c1"># ... then remember the currently used pair</span>
</span></span><span class="line"><span class="ln"> 50</span><span class="cl">        <span class="c1"># and tentatively mark both positions in the circle.</span>
</span></span><span class="line"><span class="ln"> 51</span><span class="cl">        <span class="n">used_pairs</span><span class="o">.</span><span class="n">append</span><span class="p">([</span><span class="n">pos</span><span class="p">,</span> <span class="n">paired_pos</span><span class="p">])</span>
</span></span><span class="line"><span class="ln"> 52</span><span class="cl">        <span class="n">pos_taken</span><span class="p">[</span><span class="n">pos</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
</span></span><span class="line"><span class="ln"> 53</span><span class="cl">        <span class="n">pos_taken</span><span class="p">[</span><span class="n">paired_pos</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
</span></span><span class="line"><span class="ln"> 54</span><span class="cl">
</span></span><span class="line"><span class="ln"> 55</span><span class="cl">        <span class="c1"># The above three lines already simulate the current move; </span>
</span></span><span class="line"><span class="ln"> 56</span><span class="cl">        <span class="c1"># check its effects before actually making the move </span>
</span></span><span class="line"><span class="ln"> 57</span><span class="cl">        <span class="c1"># and stepping one level down the tree.</span>
</span></span><span class="line"><span class="ln"> 58</span><span class="cl">
</span></span><span class="line"><span class="ln"> 59</span><span class="cl">        <span class="c1"># positive assumption: all future pairs reachable, i.e. for</span>
</span></span><span class="line"><span class="ln"> 60</span><span class="cl">        <span class="c1"># every position not yet taken, there exists a pair position</span>
</span></span><span class="line"><span class="ln"> 61</span><span class="cl">        <span class="c1"># not yet taken</span>
</span></span><span class="line"><span class="ln"> 62</span><span class="cl">        <span class="n">all_future_pos_reachable</span> <span class="o">=</span> <span class="kc">True</span>
</span></span><span class="line"><span class="ln"> 63</span><span class="cl">
</span></span><span class="line"><span class="ln"> 64</span><span class="cl">        <span class="c1"># for every future position, try to prove assumption wrong </span>
</span></span><span class="line"><span class="ln"> 65</span><span class="cl">        <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">pos</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">N</span><span class="o">+</span><span class="mi">1</span><span class="p">):</span>
</span></span><span class="line"><span class="ln"> 66</span><span class="cl">          <span class="k">if</span> <span class="ow">not</span> <span class="n">pos_taken</span><span class="p">[</span><span class="n">p</span><span class="o">-</span><span class="mi">1</span><span class="p">]:</span>
</span></span><span class="line"><span class="ln"> 67</span><span class="cl">                      
</span></span><span class="line"><span class="ln"> 68</span><span class="cl">            <span class="c1"># negative assumption: no more pair position available</span>
</span></span><span class="line"><span class="ln"> 69</span><span class="cl">            <span class="n">paired_p_reachable</span> <span class="o">=</span> <span class="kc">False</span>
</span></span><span class="line"><span class="ln"> 70</span><span class="cl">
</span></span><span class="line"><span class="ln"> 71</span><span class="cl">            <span class="c1"># try to prove assumption wrong </span>
</span></span><span class="line"><span class="ln"> 72</span><span class="cl">            <span class="k">for</span> <span class="n">paired_p</span> <span class="ow">in</span> <span class="n">possible_pairs</span><span class="p">[</span><span class="n">p</span><span class="o">-</span><span class="mi">1</span><span class="p">]:</span>
</span></span><span class="line"><span class="ln"> 73</span><span class="cl">              <span class="k">if</span> <span class="ow">not</span> <span class="n">pos_taken</span><span class="p">[</span><span class="n">paired_p</span><span class="o">-</span><span class="mi">1</span><span class="p">]:</span>
</span></span><span class="line"><span class="ln"> 74</span><span class="cl">                <span class="n">paired_p_reachable</span> <span class="o">=</span> <span class="kc">True</span>
</span></span><span class="line"><span class="ln"> 75</span><span class="cl">                
</span></span><span class="line"><span class="ln"> 76</span><span class="cl">            <span class="k">if</span> <span class="ow">not</span> <span class="n">paired_p_reachable</span><span class="p">:</span>
</span></span><span class="line"><span class="ln"> 77</span><span class="cl">              <span class="n">all_future_pos_reachable</span> <span class="o">=</span> <span class="kc">False</span>
</span></span><span class="line"><span class="ln"> 78</span><span class="cl">
</span></span><span class="line"><span class="ln"> 79</span><span class="cl">        <span class="k">if</span> <span class="n">all_future_pos_reachable</span><span class="p">:</span>        
</span></span><span class="line"><span class="ln"> 80</span><span class="cl">          <span class="c1"># move on to the next position</span>
</span></span><span class="line"><span class="ln"> 81</span><span class="cl">          <span class="n">solve</span><span class="p">(</span><span class="n">pos</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="ln"> 82</span><span class="cl">
</span></span><span class="line"><span class="ln"> 83</span><span class="cl">        <span class="c1"># trace back by releasing the used pair </span>
</span></span><span class="line"><span class="ln"> 84</span><span class="cl">        <span class="c1"># and unmarking the two positions in the circle</span>
</span></span><span class="line"><span class="ln"> 85</span><span class="cl">        <span class="n">used_pairs</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
</span></span><span class="line"><span class="ln"> 86</span><span class="cl">        <span class="n">pos_taken</span><span class="p">[</span><span class="n">pos</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="kc">False</span>
</span></span><span class="line"><span class="ln"> 87</span><span class="cl">        <span class="n">pos_taken</span><span class="p">[</span><span class="n">paired_pos</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="kc">False</span>
</span></span><span class="line"><span class="ln"> 88</span><span class="cl">
</span></span><span class="line"><span class="ln"> 89</span><span class="cl"><span class="c1"># upper bound N of the interval of numbers 1...N in the circle</span>
</span></span><span class="line"><span class="ln"> 90</span><span class="cl"><span class="n">N</span> <span class="o">=</span> <span class="mi">60</span>
</span></span><span class="line"><span class="ln"> 91</span><span class="cl">
</span></span><span class="line"><span class="ln"> 92</span><span class="cl"><span class="c1"># set of target numbers for the pairs</span>
</span></span><span class="line"><span class="ln"> 93</span><span class="cl"><span class="n">targets</span> <span class="o">=</span> <span class="p">(</span><span class="mi">9</span><span class="p">,</span> <span class="mi">36</span><span class="p">,</span> <span class="mi">49</span><span class="p">,</span> <span class="mi">64</span><span class="p">,</span> <span class="mi">81</span><span class="p">)</span>
</span></span><span class="line"><span class="ln"> 94</span><span class="cl">
</span></span><span class="line"><span class="ln"> 95</span><span class="cl"><span class="c1"># the set of possible pairs which satisfy the target </span>
</span></span><span class="line"><span class="ln"> 96</span><span class="cl"><span class="n">possible_pairs</span> <span class="o">=</span> <span class="n">possible_pairings</span><span class="p">(</span><span class="n">N</span><span class="p">,</span> <span class="n">targets</span><span class="p">)</span>
</span></span><span class="line"><span class="ln"> 97</span><span class="cl">
</span></span><span class="line"><span class="ln"> 98</span><span class="cl"><span class="c1"># list of the positions 1 ... N to keep track of </span>
</span></span><span class="line"><span class="ln"> 99</span><span class="cl"><span class="c1"># which are already taken and which are still unoccupied</span>
</span></span><span class="line"><span class="ln">100</span><span class="cl"><span class="n">pos_taken</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="ln">101</span><span class="cl"><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">N</span><span class="o">+</span><span class="mi">1</span><span class="p">):</span>
</span></span><span class="line"><span class="ln">102</span><span class="cl">  <span class="n">pos_taken</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="kc">False</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">103</span><span class="cl">
</span></span><span class="line"><span class="ln">104</span><span class="cl"><span class="c1"># list of all the pairs currently used in the backtracking algorithm</span>
</span></span><span class="line"><span class="ln">105</span><span class="cl"><span class="n">used_pairs</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="ln">106</span><span class="cl">
</span></span><span class="line"><span class="ln">107</span><span class="cl"><span class="n">log</span> <span class="o">=</span> <span class="s2">&#34;Calculating Rainbow Pairs for 1 ... &#34;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">N</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">108</span><span class="cl"><span class="n">log</span> <span class="o">=</span> <span class="n">log</span> <span class="o">+</span> <span class="s2">&#34; for target set &#34;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">targets</span><span class="p">)</span> <span class="o">+</span> <span class="s2">&#34;:&#34;</span>
</span></span><span class="line"><span class="ln">109</span><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">log</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">110</span><span class="cl"><span class="nb">print</span><span class="p">()</span>
</span></span><span class="line"><span class="ln">111</span><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">&#34;Possible partner positions for each position 1 ... &#34;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">N</span><span class="p">)</span> <span class="o">+</span> <span class="s2">&#34;:&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">112</span><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">possible_pairs</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">113</span><span class="cl"><span class="nb">print</span><span class="p">()</span>
</span></span><span class="line"><span class="ln">114</span><span class="cl">
</span></span><span class="line"><span class="ln">115</span><span class="cl"><span class="n">li</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="k">lambda</span> <span class="n">li</span><span class="p">:</span> <span class="nb">len</span><span class="p">(</span><span class="n">li</span><span class="p">),</span> <span class="n">possible_pairs</span><span class="p">))</span>
</span></span><span class="line"><span class="ln">116</span><span class="cl"><span class="n">num_pos_pairs</span> <span class="o">=</span> <span class="nb">round</span><span class="p">(</span><span class="n">functools</span><span class="o">.</span><span class="n">reduce</span><span class="p">(</span><span class="k">lambda</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">:</span> <span class="n">a</span><span class="o">+</span><span class="n">b</span><span class="p">,</span> <span class="n">li</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">117</span><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">&#34;Number of possible pairs: &#34;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">num_pos_pairs</span><span class="p">))</span>
</span></span><span class="line"><span class="ln">118</span><span class="cl">
</span></span><span class="line"><span class="ln">119</span><span class="cl"><span class="n">solve</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">120</span><span class="cl">
</span></span><span class="line"><span class="ln">121</span><span class="cl"><span class="nb">print</span><span class="p">()</span>
</span></span><span class="line"><span class="ln">122</span><span class="cl"><span class="n">log</span> <span class="o">=</span> <span class="s2">&#34;Calculation terminated. &#34;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">solution_count</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">123</span><span class="cl"><span class="n">log</span> <span class="o">=</span> <span class="n">log</span> <span class="o">+</span> <span class="s2">&#34; solutions found with &#34;</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">recursion_count</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">124</span><span class="cl"><span class="n">log</span> <span class="o">=</span> <span class="n">log</span> <span class="o">+</span> <span class="s2">&#34; calls to recursive solver function.&#34;</span>
</span></span><span class="line"><span class="ln">125</span><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">log</span><span class="p">)</span></span></span></code></pre></div><p>The main program begins on line 89:</p>
<ul>
<li>90: Definition of the interval 1 &hellip; N = 60</li>
<li>93: Definition of the set of target numbers {9, 36, 49, 64, 81}</li>
<li>96: Calculation of the set of possible pairings. The term &ldquo;set&rdquo; is actually imprecise here as the <code>solve</code> procedure depends on the data structure exactly as returned by the auxiliary function <code>possible_pairings</code>: a list of N lists where each list corresponds to the possible pairings for number i, i running from 1 to N. This corresponds exactly to the fourth column of the <a href="/materials/blog/backtracking-algorithms/table-pairs/">reference table</a>. Because each pair is listed twice, the total number of pairs in our example is 186.</li>
<li>98 - 105: The two data structures <code>pos_taken</code> and <code>used_pairs</code> together correspond to my paper drawings: They track the current state of the partial solution:
<ul>
<li><code>pos_taken</code> keeps track of which positions in the circle are already marked by a pair. The list is initialized with all <code>False</code> values as initially no position is taken.</li>
<li><code>used_pairs</code> keeps track of the pairs used in the current partial solution. This is needed to print the solution when one has been found. The list is initially empty.</li>
</ul>
</li>
<li>107 - 117: Some initial output</li>
<li>119: Execution of the <code>solve</code> procedure for the first position. As this is a recursive procedure, it will execute again and again until all solutions have been found.</li>
<li>121 - 125: Some final output</li>
</ul>
<p>The main program depends on functions, procedures and variables defined and implemented in lines 1 - 76.</p>
<p>Lines 1 - 19 contain a function implementation and the definition of two counters:</p>
<ul>
<li>5 - 13: Function <code>possible_pairings</code> calculates the list of possible pairings. In the problem section above, I said that the 93 pairs can easily be found by iterating over all numbers i from 1 to 60 and checking for every number j between (i + 1) and 60 whether the sum of i and j is an element of the above set of square numbers. As in the final version of the program we consider forward and backward information, we need all pairs listed twice, once for the lower number and once for the higher number. That&rsquo;s why j also runs from 1 to 60, not only from (i + 1) to 60.</li>
<li>16: Definition of a counter for the number of solutions already found.</li>
<li>19: Defintion of the number of recursions already executed, i.e. the number of times procedure <code>solve</code> has already been called.</li>
</ul>
<p>Lines 21 - 87 contain the definition and implementation of the <code>solve</code> procedure which contains all the backtracking logic:</p>
<ul>
<li>25: Increment the recursion counter</li>
<li>29: If we are at position N+1, a solution has been found:
<ul>
<li>31: Increment the solution counter</li>
<li>32 - 35: Print the current solution</li>
<li>Do nothing more in this recursive step. This means: Jump back to the context of the caller of <code>solve(N+1)</code> which in turn is an execuction of <code>solve</code>, namely <code>solve(N)</code>.</li>
</ul>
</li>
<li>39/40: Else if we are at a positition smaller than N+1 which is already taken (i.e. paired with a lower position), then we move on to the next position, i.e. recursively call <code>solve(pos+1)</code>.</li>
<li>41: Else (i.e. if we are at a positition smaller than N+1 which is <em>un</em>occupied):
<ul>
<li>44: We loop over all possible pair positions of the current position:
<ul>
<li>47: If a possible pair position is not already taken (i.e. paired with a lower position), then
<ul>
<li>51 - 53: Tentatively add the current position and the current pair position to the list of used  pairs and mark the current position and the possible pair position as taken.</li>
<li>55 - 77: These 23 lines are the main improvement over the initial version of the program, causing the execution time to improve by a factor of 24 and the number of recursive calls to decrease by a factor of more than 2500: Check for all positions not yet taken, whether there also exists a possible pairing not yet taken.</li>
<li>79/81: Only if all future positions are still reachable, keep the current pair and move on to the next position, i.e. call <code>solve(pos+1)</code>.</li>
<li>83 - 87: At this point, either <code>solve(pos+1)</code> has been executed (which includes all its recursive executions) because all future position were still reachable with the current pair, or it has not been executed because at least one future position would no longer have been reachable. In the first case, we are now on the way up the tree again and have to undo the current pairing made in lines 51 - 53. In the second case, we could not make the step down the tree and have to undo the (tentative) pairing just the same.</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>The program file can be found <a href="/files/blog/backtracking-algorithms/Rainbow_Squares_backtracking_final_version.py">here</a> and its output file <a href="/files/blog/backtracking-algorithms/Rainbow_Squares_Solutions_backtracking_final_version.txt">here</a>. The output file shows that the final version of the program finds the solutions in the same order as the initial version but just performs a lot less unneccessary steps.</p>
<h2 id="the-analogy">The analogy</h2>
<p>I like backtracking algorithms for several reasons. Remember the drawing of the Rainbow Squares Circle which got me started with this article? I do not only find this drawing very beautiful, but also the algorithm which allowed me to find the solutions to this puzzle. I find the concept of backtracking very elegant. I like to watch animations of backtracking algorithms like for example <a href="https://commons.wikimedia.org/wiki/File:Eight-queens-animation.gif">this one</a> for the <a href="https://en.wikipedia.org/wiki/Eight_queens_puzzle">Eight Queens Puzzle</a>.</p>
<p>Backtracking algorithms in their efficiency also remind me a lot of the agile way of working: experiment, inspect and adapt: try something, measure its effect, and if it does not work, then try something else. But do it systematically and empirically.</p>
<p>The three empirical pillars of scrum are transparency, inspection and adaptation. Transparency and inspection are important here: We have been able to improve the efficiency of the algorithm massively by including information previously ignored. If something does not work, it is crucial to fail at the earliest possible moment and not waste time exploring dead ends any further. As the <a href="https://scrumguides.org/">scrum guide</a> states:</p>
<ul>
<li>Transparency enables inspection. Inspection without transparency is misleading and wasteful.</li>
<li>Inspection enables adaptation. Inspection without adaptation is considered pointless.</li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>Table of pairs whose sum is one of the given square numbers</title>
      <link>https://walkagile.com/materials/blog/backtracking-algorithms/table-pairs/</link>
      <pubDate>Thu, 29 Feb 2024 00:00:00 +0000</pubDate><author>peterhaefliger@yahoo.com (Peter Häfliger)</author>
      <guid>https://walkagile.com/materials/blog/backtracking-algorithms/table-pairs/</guid>
      <description>&lt;p&gt;The following table lists all 93 pairs which can be formed with the numbers from 1 to 60 whose sum is an element of the set {9, 36, 49, 64, 81}:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;The first column lists the numbers i from 1 to 60.&lt;/li&gt;&#xA;&lt;li&gt;The second column lists all the numbers greater than i with which i can be paired. That&amp;rsquo;s the column used by the first (slow) version of the python program.&lt;/li&gt;&#xA;&lt;li&gt;The third column lists all the numbers smaller than i with which i can be paired. That&amp;rsquo;s the column used by the second (backward) version of the python program.&lt;/li&gt;&#xA;&lt;li&gt;The fourth column lists all the numbers with which i can be paired, smaller or greater. That&amp;rsquo;s the column used by the third (fast forward) version of the python program.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;i&lt;/th&gt;&#xA;          &lt;th&gt;higher pairs&lt;/th&gt;&#xA;          &lt;th&gt;lower pairs&lt;/th&gt;&#xA;          &lt;th&gt;all pairs&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;1&lt;/td&gt;&#xA;          &lt;td&gt;8, 35, 48&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;8, 35, 48&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;2&lt;/td&gt;&#xA;          &lt;td&gt;7, 34, 47&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;7, 34, 47&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;3&lt;/td&gt;&#xA;          &lt;td&gt;6, 33, 46&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;6, 33, 46&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;4&lt;/td&gt;&#xA;          &lt;td&gt;5, 32, 45, 60&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;5, 32, 45, 60&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;5&lt;/td&gt;&#xA;          &lt;td&gt;31, 44, 59&lt;/td&gt;&#xA;          &lt;td&gt;4&lt;/td&gt;&#xA;          &lt;td&gt;4, 31, 44, 59&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;6&lt;/td&gt;&#xA;          &lt;td&gt;30, 43, 58&lt;/td&gt;&#xA;          &lt;td&gt;3&lt;/td&gt;&#xA;          &lt;td&gt;3, 30, 43, 58&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;7&lt;/td&gt;&#xA;          &lt;td&gt;29, 42, 57&lt;/td&gt;&#xA;          &lt;td&gt;2&lt;/td&gt;&#xA;          &lt;td&gt;2, 29, 42, 57&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;8&lt;/td&gt;&#xA;          &lt;td&gt;28, 41, 56&lt;/td&gt;&#xA;          &lt;td&gt;1&lt;/td&gt;&#xA;          &lt;td&gt;1, 28, 41, 56&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;9&lt;/td&gt;&#xA;          &lt;td&gt;27, 40, 55&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;27, 40, 55&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;10&lt;/td&gt;&#xA;          &lt;td&gt;26, 39, 54&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;26, 39, 54&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;11&lt;/td&gt;&#xA;          &lt;td&gt;25, 38, 53&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;25, 38, 53&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;12&lt;/td&gt;&#xA;          &lt;td&gt;24, 37, 52&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;24, 37, 52&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;13&lt;/td&gt;&#xA;          &lt;td&gt;23, 36, 51&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;23, 36, 51&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;14&lt;/td&gt;&#xA;          &lt;td&gt;22, 35, 50&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;22, 35, 50&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;15&lt;/td&gt;&#xA;          &lt;td&gt;21, 34, 49&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;21, 34, 49&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;16&lt;/td&gt;&#xA;          &lt;td&gt;20, 33, 48&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;20, 33, 48&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;17&lt;/td&gt;&#xA;          &lt;td&gt;19, 32, 47&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;19, 32, 47&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;18&lt;/td&gt;&#xA;          &lt;td&gt;31, 46&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;31, 46&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;19&lt;/td&gt;&#xA;          &lt;td&gt;30, 45&lt;/td&gt;&#xA;          &lt;td&gt;17&lt;/td&gt;&#xA;          &lt;td&gt;17, 30, 45&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;20&lt;/td&gt;&#xA;          &lt;td&gt;29, 44&lt;/td&gt;&#xA;          &lt;td&gt;16&lt;/td&gt;&#xA;          &lt;td&gt;16, 29, 44&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;21&lt;/td&gt;&#xA;          &lt;td&gt;28, 43, 60&lt;/td&gt;&#xA;          &lt;td&gt;15&lt;/td&gt;&#xA;          &lt;td&gt;15, 28, 43, 60&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;22&lt;/td&gt;&#xA;          &lt;td&gt;27, 42, 59&lt;/td&gt;&#xA;          &lt;td&gt;14&lt;/td&gt;&#xA;          &lt;td&gt;14, 27, 42, 59&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;23&lt;/td&gt;&#xA;          &lt;td&gt;26, 41, 58&lt;/td&gt;&#xA;          &lt;td&gt;13&lt;/td&gt;&#xA;          &lt;td&gt;13, 26, 41, 58&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;24&lt;/td&gt;&#xA;          &lt;td&gt;25, 40, 57&lt;/td&gt;&#xA;          &lt;td&gt;12&lt;/td&gt;&#xA;          &lt;td&gt;12, 25, 40, 57&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;25&lt;/td&gt;&#xA;          &lt;td&gt;39, 56&lt;/td&gt;&#xA;          &lt;td&gt;24, 11&lt;/td&gt;&#xA;          &lt;td&gt;11, 24, 39, 56&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;26&lt;/td&gt;&#xA;          &lt;td&gt;38, 55&lt;/td&gt;&#xA;          &lt;td&gt;23, 10&lt;/td&gt;&#xA;          &lt;td&gt;10, 23, 38, 55&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;27&lt;/td&gt;&#xA;          &lt;td&gt;37, 54&lt;/td&gt;&#xA;          &lt;td&gt;22, 9&lt;/td&gt;&#xA;          &lt;td&gt;9, 22, 37, 54&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;28&lt;/td&gt;&#xA;          &lt;td&gt;36, 53&lt;/td&gt;&#xA;          &lt;td&gt;21, 8&lt;/td&gt;&#xA;          &lt;td&gt;8, 21, 36, 53&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;29&lt;/td&gt;&#xA;          &lt;td&gt;35, 52&lt;/td&gt;&#xA;          &lt;td&gt;20, 7&lt;/td&gt;&#xA;          &lt;td&gt;7, 20, 35, 52&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;30&lt;/td&gt;&#xA;          &lt;td&gt;34, 51&lt;/td&gt;&#xA;          &lt;td&gt;19, 6&lt;/td&gt;&#xA;          &lt;td&gt;6, 19, 34, 51&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;31&lt;/td&gt;&#xA;          &lt;td&gt;33, 50&lt;/td&gt;&#xA;          &lt;td&gt;18, 5&lt;/td&gt;&#xA;          &lt;td&gt;5, 18, 33, 50&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;32&lt;/td&gt;&#xA;          &lt;td&gt;49&lt;/td&gt;&#xA;          &lt;td&gt;17, 4&lt;/td&gt;&#xA;          &lt;td&gt;4, 17, 49&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;33&lt;/td&gt;&#xA;          &lt;td&gt;48&lt;/td&gt;&#xA;          &lt;td&gt;31, 16, 3&lt;/td&gt;&#xA;          &lt;td&gt;3, 16, 31, 48&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;34&lt;/td&gt;&#xA;          &lt;td&gt;47&lt;/td&gt;&#xA;          &lt;td&gt;30, 15, 2&lt;/td&gt;&#xA;          &lt;td&gt;2, 15, 30, 47&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;35&lt;/td&gt;&#xA;          &lt;td&gt;46&lt;/td&gt;&#xA;          &lt;td&gt;29, 14, 1&lt;/td&gt;&#xA;          &lt;td&gt;1, 14, 29, 46&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;36&lt;/td&gt;&#xA;          &lt;td&gt;45&lt;/td&gt;&#xA;          &lt;td&gt;28, 13&lt;/td&gt;&#xA;          &lt;td&gt;13, 28, 45&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;37&lt;/td&gt;&#xA;          &lt;td&gt;44&lt;/td&gt;&#xA;          &lt;td&gt;27, 12&lt;/td&gt;&#xA;          &lt;td&gt;12, 27, 44&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;38&lt;/td&gt;&#xA;          &lt;td&gt;43&lt;/td&gt;&#xA;          &lt;td&gt;26, 11&lt;/td&gt;&#xA;          &lt;td&gt;11, 26, 43&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;39&lt;/td&gt;&#xA;          &lt;td&gt;42&lt;/td&gt;&#xA;          &lt;td&gt;25, 10&lt;/td&gt;&#xA;          &lt;td&gt;10, 25, 42&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;40&lt;/td&gt;&#xA;          &lt;td&gt;41&lt;/td&gt;&#xA;          &lt;td&gt;24, 9&lt;/td&gt;&#xA;          &lt;td&gt;9, 24, 41&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;41&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;40, 23, 8&lt;/td&gt;&#xA;          &lt;td&gt;8, 23, 40&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;42&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;39, 22, 7&lt;/td&gt;&#xA;          &lt;td&gt;7, 22, 39&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;43&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;38, 21, 6&lt;/td&gt;&#xA;          &lt;td&gt;6, 21, 38&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;44&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;37, 20, 5&lt;/td&gt;&#xA;          &lt;td&gt;5, 20, 37&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;45&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;36, 19, 4&lt;/td&gt;&#xA;          &lt;td&gt;4, 19, 36&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;46&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;35, 18, 3&lt;/td&gt;&#xA;          &lt;td&gt;3, 18, 35&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;47&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;34, 17, 2&lt;/td&gt;&#xA;          &lt;td&gt;2, 17, 34&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;48&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;33, 16, 1&lt;/td&gt;&#xA;          &lt;td&gt;1, 16, 33&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;49&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;32, 15&lt;/td&gt;&#xA;          &lt;td&gt;15, 32&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;50&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;31, 14&lt;/td&gt;&#xA;          &lt;td&gt;14, 31&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;51&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;30, 13&lt;/td&gt;&#xA;          &lt;td&gt;13, 30&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;52&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;29, 12&lt;/td&gt;&#xA;          &lt;td&gt;12, 29&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;53&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;28, 11&lt;/td&gt;&#xA;          &lt;td&gt;11, 28&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;54&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;27, 10&lt;/td&gt;&#xA;          &lt;td&gt;10, 27&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;55&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;26, 9&lt;/td&gt;&#xA;          &lt;td&gt;9, 26&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;56&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;25, 8&lt;/td&gt;&#xA;          &lt;td&gt;8, 25&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;57&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;24, 7&lt;/td&gt;&#xA;          &lt;td&gt;7, 24&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;58&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;23, 6&lt;/td&gt;&#xA;          &lt;td&gt;6, 23&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;59&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;22, 5&lt;/td&gt;&#xA;          &lt;td&gt;5, 22&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;60&lt;/td&gt;&#xA;          &lt;td&gt;&lt;/td&gt;&#xA;          &lt;td&gt;21, 4&lt;/td&gt;&#xA;          &lt;td&gt;4, 21&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;</description>
      <content:encoded><![CDATA[<p>The following table lists all 93 pairs which can be formed with the numbers from 1 to 60 whose sum is an element of the set {9, 36, 49, 64, 81}:</p>
<ul>
<li>The first column lists the numbers i from 1 to 60.</li>
<li>The second column lists all the numbers greater than i with which i can be paired. That&rsquo;s the column used by the first (slow) version of the python program.</li>
<li>The third column lists all the numbers smaller than i with which i can be paired. That&rsquo;s the column used by the second (backward) version of the python program.</li>
<li>The fourth column lists all the numbers with which i can be paired, smaller or greater. That&rsquo;s the column used by the third (fast forward) version of the python program.</li>
</ul>
<table>
  <thead>
      <tr>
          <th>i</th>
          <th>higher pairs</th>
          <th>lower pairs</th>
          <th>all pairs</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>1</td>
          <td>8, 35, 48</td>
          <td></td>
          <td>8, 35, 48</td>
      </tr>
      <tr>
          <td>2</td>
          <td>7, 34, 47</td>
          <td></td>
          <td>7, 34, 47</td>
      </tr>
      <tr>
          <td>3</td>
          <td>6, 33, 46</td>
          <td></td>
          <td>6, 33, 46</td>
      </tr>
      <tr>
          <td>4</td>
          <td>5, 32, 45, 60</td>
          <td></td>
          <td>5, 32, 45, 60</td>
      </tr>
      <tr>
          <td>5</td>
          <td>31, 44, 59</td>
          <td>4</td>
          <td>4, 31, 44, 59</td>
      </tr>
      <tr>
          <td>6</td>
          <td>30, 43, 58</td>
          <td>3</td>
          <td>3, 30, 43, 58</td>
      </tr>
      <tr>
          <td>7</td>
          <td>29, 42, 57</td>
          <td>2</td>
          <td>2, 29, 42, 57</td>
      </tr>
      <tr>
          <td>8</td>
          <td>28, 41, 56</td>
          <td>1</td>
          <td>1, 28, 41, 56</td>
      </tr>
      <tr>
          <td>9</td>
          <td>27, 40, 55</td>
          <td></td>
          <td>27, 40, 55</td>
      </tr>
      <tr>
          <td>10</td>
          <td>26, 39, 54</td>
          <td></td>
          <td>26, 39, 54</td>
      </tr>
      <tr>
          <td>11</td>
          <td>25, 38, 53</td>
          <td></td>
          <td>25, 38, 53</td>
      </tr>
      <tr>
          <td>12</td>
          <td>24, 37, 52</td>
          <td></td>
          <td>24, 37, 52</td>
      </tr>
      <tr>
          <td>13</td>
          <td>23, 36, 51</td>
          <td></td>
          <td>23, 36, 51</td>
      </tr>
      <tr>
          <td>14</td>
          <td>22, 35, 50</td>
          <td></td>
          <td>22, 35, 50</td>
      </tr>
      <tr>
          <td>15</td>
          <td>21, 34, 49</td>
          <td></td>
          <td>21, 34, 49</td>
      </tr>
      <tr>
          <td>16</td>
          <td>20, 33, 48</td>
          <td></td>
          <td>20, 33, 48</td>
      </tr>
      <tr>
          <td>17</td>
          <td>19, 32, 47</td>
          <td></td>
          <td>19, 32, 47</td>
      </tr>
      <tr>
          <td>18</td>
          <td>31, 46</td>
          <td></td>
          <td>31, 46</td>
      </tr>
      <tr>
          <td>19</td>
          <td>30, 45</td>
          <td>17</td>
          <td>17, 30, 45</td>
      </tr>
      <tr>
          <td>20</td>
          <td>29, 44</td>
          <td>16</td>
          <td>16, 29, 44</td>
      </tr>
      <tr>
          <td>21</td>
          <td>28, 43, 60</td>
          <td>15</td>
          <td>15, 28, 43, 60</td>
      </tr>
      <tr>
          <td>22</td>
          <td>27, 42, 59</td>
          <td>14</td>
          <td>14, 27, 42, 59</td>
      </tr>
      <tr>
          <td>23</td>
          <td>26, 41, 58</td>
          <td>13</td>
          <td>13, 26, 41, 58</td>
      </tr>
      <tr>
          <td>24</td>
          <td>25, 40, 57</td>
          <td>12</td>
          <td>12, 25, 40, 57</td>
      </tr>
      <tr>
          <td>25</td>
          <td>39, 56</td>
          <td>24, 11</td>
          <td>11, 24, 39, 56</td>
      </tr>
      <tr>
          <td>26</td>
          <td>38, 55</td>
          <td>23, 10</td>
          <td>10, 23, 38, 55</td>
      </tr>
      <tr>
          <td>27</td>
          <td>37, 54</td>
          <td>22, 9</td>
          <td>9, 22, 37, 54</td>
      </tr>
      <tr>
          <td>28</td>
          <td>36, 53</td>
          <td>21, 8</td>
          <td>8, 21, 36, 53</td>
      </tr>
      <tr>
          <td>29</td>
          <td>35, 52</td>
          <td>20, 7</td>
          <td>7, 20, 35, 52</td>
      </tr>
      <tr>
          <td>30</td>
          <td>34, 51</td>
          <td>19, 6</td>
          <td>6, 19, 34, 51</td>
      </tr>
      <tr>
          <td>31</td>
          <td>33, 50</td>
          <td>18, 5</td>
          <td>5, 18, 33, 50</td>
      </tr>
      <tr>
          <td>32</td>
          <td>49</td>
          <td>17, 4</td>
          <td>4, 17, 49</td>
      </tr>
      <tr>
          <td>33</td>
          <td>48</td>
          <td>31, 16, 3</td>
          <td>3, 16, 31, 48</td>
      </tr>
      <tr>
          <td>34</td>
          <td>47</td>
          <td>30, 15, 2</td>
          <td>2, 15, 30, 47</td>
      </tr>
      <tr>
          <td>35</td>
          <td>46</td>
          <td>29, 14, 1</td>
          <td>1, 14, 29, 46</td>
      </tr>
      <tr>
          <td>36</td>
          <td>45</td>
          <td>28, 13</td>
          <td>13, 28, 45</td>
      </tr>
      <tr>
          <td>37</td>
          <td>44</td>
          <td>27, 12</td>
          <td>12, 27, 44</td>
      </tr>
      <tr>
          <td>38</td>
          <td>43</td>
          <td>26, 11</td>
          <td>11, 26, 43</td>
      </tr>
      <tr>
          <td>39</td>
          <td>42</td>
          <td>25, 10</td>
          <td>10, 25, 42</td>
      </tr>
      <tr>
          <td>40</td>
          <td>41</td>
          <td>24, 9</td>
          <td>9, 24, 41</td>
      </tr>
      <tr>
          <td>41</td>
          <td></td>
          <td>40, 23, 8</td>
          <td>8, 23, 40</td>
      </tr>
      <tr>
          <td>42</td>
          <td></td>
          <td>39, 22, 7</td>
          <td>7, 22, 39</td>
      </tr>
      <tr>
          <td>43</td>
          <td></td>
          <td>38, 21, 6</td>
          <td>6, 21, 38</td>
      </tr>
      <tr>
          <td>44</td>
          <td></td>
          <td>37, 20, 5</td>
          <td>5, 20, 37</td>
      </tr>
      <tr>
          <td>45</td>
          <td></td>
          <td>36, 19, 4</td>
          <td>4, 19, 36</td>
      </tr>
      <tr>
          <td>46</td>
          <td></td>
          <td>35, 18, 3</td>
          <td>3, 18, 35</td>
      </tr>
      <tr>
          <td>47</td>
          <td></td>
          <td>34, 17, 2</td>
          <td>2, 17, 34</td>
      </tr>
      <tr>
          <td>48</td>
          <td></td>
          <td>33, 16, 1</td>
          <td>1, 16, 33</td>
      </tr>
      <tr>
          <td>49</td>
          <td></td>
          <td>32, 15</td>
          <td>15, 32</td>
      </tr>
      <tr>
          <td>50</td>
          <td></td>
          <td>31, 14</td>
          <td>14, 31</td>
      </tr>
      <tr>
          <td>51</td>
          <td></td>
          <td>30, 13</td>
          <td>13, 30</td>
      </tr>
      <tr>
          <td>52</td>
          <td></td>
          <td>29, 12</td>
          <td>12, 29</td>
      </tr>
      <tr>
          <td>53</td>
          <td></td>
          <td>28, 11</td>
          <td>11, 28</td>
      </tr>
      <tr>
          <td>54</td>
          <td></td>
          <td>27, 10</td>
          <td>10, 27</td>
      </tr>
      <tr>
          <td>55</td>
          <td></td>
          <td>26, 9</td>
          <td>9, 26</td>
      </tr>
      <tr>
          <td>56</td>
          <td></td>
          <td>25, 8</td>
          <td>8, 25</td>
      </tr>
      <tr>
          <td>57</td>
          <td></td>
          <td>24, 7</td>
          <td>7, 24</td>
      </tr>
      <tr>
          <td>58</td>
          <td></td>
          <td>23, 6</td>
          <td>6, 23</td>
      </tr>
      <tr>
          <td>59</td>
          <td></td>
          <td>22, 5</td>
          <td>5, 22</td>
      </tr>
      <tr>
          <td>60</td>
          <td></td>
          <td>21, 4</td>
          <td>4, 21</td>
      </tr>
  </tbody>
</table>
]]></content:encoded>
    </item>
    <item>
      <title>More Fun with Retrospectives: Check your rearview mirror!</title>
      <link>https://walkagile.com/blog/more-fun-with-retrospectives/</link>
      <pubDate>Fri, 15 Dec 2023 00:00:00 +0000</pubDate><author>peterhaefliger@yahoo.com (Peter Häfliger)</author>
      <guid>https://walkagile.com/blog/more-fun-with-retrospectives/</guid>
      <description>&lt;p&gt;&lt;em&gt;This is the translation of &lt;a href=&#34;https://blog.hslu.ch/informatik-wb/2023/11/08/voll-retro/&#34;&gt;my blog post written in German&lt;/a&gt; as an assignment for the CAS DevOps Leadership and Agile Methods which I am currently doing at the &lt;a href=&#34;https://www.hslu.ch/en/&#34;&gt;Lucerne University of Applied Sciences and Arts&lt;/a&gt;. The translation is rather free, as self-translations usually are, because the author can allow themself full liberties. But let me first explain the context of the course assignment:&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;em&gt;During the course, a colleague brought up the question of how shy team members can be encouraged to speak up in a retro. I answered that there are techniques  and tools like &lt;a href=&#34;https://www.funretrospectives.com/&#34;&gt;Fun Retrospectives&lt;/a&gt; which I had described in &lt;a href=&#34;https://walkagile.com/blog/funretrospectives/&#34;&gt;my very first post on this blog&lt;/a&gt;. The teacher then mentioned &lt;a href=&#34;https://retromat.org/en/&#34;&gt;Retromat&lt;/a&gt; and I decided to compare the two and give a general introduction to retrospectives in my blog post assignment.&lt;/em&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><em>This is the translation of <a href="https://blog.hslu.ch/informatik-wb/2023/11/08/voll-retro/">my blog post written in German</a> as an assignment for the CAS DevOps Leadership and Agile Methods which I am currently doing at the <a href="https://www.hslu.ch/en/">Lucerne University of Applied Sciences and Arts</a>. The translation is rather free, as self-translations usually are, because the author can allow themself full liberties. But let me first explain the context of the course assignment:</em></p>
<p><em>During the course, a colleague brought up the question of how shy team members can be encouraged to speak up in a retro. I answered that there are techniques  and tools like <a href="https://www.funretrospectives.com/">Fun Retrospectives</a> which I had described in <a href="/blog/funretrospectives/">my very first post on this blog</a>. The teacher then mentioned <a href="https://retromat.org/en/">Retromat</a> and I decided to compare the two and give a general introduction to retrospectives in my blog post assignment.</em></p>
<p><em>Contrary to the more technical text-based theme I use here, the university&rsquo;s wordpress theme asked for a &ldquo;featured image&rdquo; to be displayed not only at the top of the post itself but also as a thumbnail in the list of posts. So the first challenge was to find a picture (in the public domain) which would somehow illustrate my topic of retrospectives and get the site&rsquo;s visitor interested enough to click and read the article.</em></p>
<p><em>How can a retrospective be visualized in a catchy image? Over the course of the article&rsquo;s evolution, I chose three different pictures:</em></p>
<h3 id="1-flashlight">1. Flashlight</h3>
<p><em>My first idea was a flashlight because the goal of a retro is to</em> uncover <em>obstacles or</em> bring <em>challenges from dark hidden corners</em> into full light:</p>
<p><img src="/images/blog/more-fun-with-retrospectives/1_Fenix_P1D_LED_flashlight.jpg" alt="Featured image “Flashlight”"></p>
<p>(Source: <a href="https://commons.wikimedia.org/wiki/File:Fenix_P1D_LED_flashlight_%282739718566%29.jpg">Fenix P1D LED flashlight</a>)</p>
<h3 id="2-antenna">2. Antenna</h3>
<p><em>My second idea was an antenna because the goal of the retro can only be reached if every voice is</em> heard:</p>
<p><img src="/images/blog/more-fun-with-retrospectives/2_apex_antenna.jpg" alt="Featured image “Antenna”"></p>
<p>(Source: <a href="https://commons.wikimedia.org/wiki/File:APEX_Antenna.jpg">APEX Antenna</a>)</p>
<h3 id="3-retro-car-with-rearview-mirror">3. Retro car with rearview mirror</h3>
<p><em>My third idea was a &ldquo;retro&rdquo; car&rsquo;s rearview mirror because in a retro the team reflects on the</em> past <em>course to make adjustments to the</em> future <em>course:</em></p>
<p><img src="/images/blog/more-fun-with-retrospectives/3_retro_car_rearview_mirror.jpg" alt="Featured image “Retro car”"></p>
<p>(Source: <a href="https://commons.wikimedia.org/wiki/File:Look_back_again_%287664606152%29.jpg">Look back again</a>)</p>
<p><em>The third idea is the one I stayed with. I simply like the tone of the picture the most and I like the &ldquo;retro&rdquo; pun.</em></p>
<p><em>Which one would you have chosen?</em></p>
<p><em>Congratulations! You have chosen well and the reader has clicked. So here is the translated article:</em></p>
<h1 id="retrospectives-dont-forget-to-check-your-rearview-mirror">Retrospectives: Don&rsquo;t forget to check your rearview mirror!</h1>
<p><strong>Agile teams do regular retrospectives or &ldquo;retros&rdquo; to reflect on the development process and their collaboration and to identify possibilities for improvement. Structures, techniques and tools like Fun Retrospectives or Retromat can help to evaluate the current course and change the lane or take the appropriate turn.</strong></p>
<p>A question for starters: How do you feel right now that you have decided to read this article? In one word: Interested? Curious? Impatient?</p>
<p>The question is a check-in activity called <a href="https://www.funretrospectives.com/one-word/">One Word</a>. It is described in Fun Retrospectives. <a href="https://www.funretrospectives.com/">Fun Retrospectives</a> describes a <a href="https://caroli.org/en/a-7-step-agenda-for-effective-retrospectives/">7-Step Agenda for Effective Retrospectives</a> while <a href="https://retromat.org/en/">Retromat</a> builds retrospectives from the 5 steps described in the <a href="https://pragprog.com/">Pragmatic Programmers</a> book <a href="https://pragprog.com/titles/dlret/agile-retrospectives/">Agile Retrospectives</a>. They are compared in the following table:</p>
<p><img src="/images/blog/more-fun-with-retrospectives/4_Table_steps_funretrospectives_retromat.png" alt="Comparision Fun Retrospectives and Retromat"></p>
<p>The following three phases are the common denominator of the two structures:</p>
<ul>
<li>Set the Stage (Engergizer / Check-in)</li>
<li>Main Course (Gather Data / Generate Insights / Decide what to do)</li>
<li>Closing / Check-out</li>
</ul>
<p>Both platforms offer a variety of activities for each step. A few examples are described in the following sections.</p>
<h2 id="set-the-stage">Set the Stage</h2>
<p>Fun Retrospectives divides this phase into four smaller steps. For &ldquo;Set the Context&rdquo; and &ldquo;Prime Directive&rdquo; see <a href="/blog/funretrospectives/">my earlier post</a> or <a href="https://caroli.org/en/a-7-step-agenda-for-effective-retrospectives">this article</a> by Fun Retrospectives&rsquo; co-author <a href="https://caroli.org/en">Paulo Caroli</a>. An Energizer is an icebreaker to wake the participants up and to loosen any initial tension. One example is <a href="https://www.funretrospectives.com/fun-fact">Fun Fact</a> for a newly-formed team whose members do not yet know much about each other: Every member writes something about themself on a sticky note, for example a hobby or a favourite song. The group then tries to guess which fun fact is about which member. This can be very surprising and much fun!</p>
<p>Check-in activities, on the other hand, are needed to feel the mood in the room and gauge the engagement level of the participants. <a href="https://www.funretrospectives.com/one-word/">One Word</a> has already been mentioned. Another frequently described activity is ESVP - Explorer, Shopper, Vacationer, Prisoner - (see for example <a href="https://retromat.org/en/?id=1">here</a> or <a href="https://www.funretrospectives.com/esvp-explorer-shopper-vacationer-prisoner">here</a>) where every participant classifies themself as one of the following:</p>
<ul>
<li><strong>Explorers</strong>: Are eager to discover new ideas and insights. They want to learn everything they can about the iteration/release/project.</li>
<li><strong>Shoppers</strong>: Will look over all the available information and be happy to go home with one useful new idea.</li>
<li><strong>Vacationers</strong>: Aren&rsquo;t interested in the work of the retrospective but are happy to be away from the daily grind.</li>
<li><strong>Prisoners</strong>: Feel they have been forced to attend and would rather be doing something else.</li>
</ul>
<p>The following screenshot shows the real-world example of a highly motivated team with which I facilitated a retro last year:</p>
<p><img src="/images/blog/more-fun-with-retrospectives/5_ESVP.png" alt="Screenshot ESVP"></p>
<p>Nice! With this group, the main course can start! If, on the other hand, a larger part of the team felt like vacationers or even prisoners, then the facilitator would have to consider stopping and canceling the event. There is no point in a retro if the participants are either not interested in learning anything or lack the psychological safety to address their problems and pain points.</p>
<h2 id="main-course">Main Course</h2>
<p>In the main course phase, information is gathered first: What went well in the defined context, what did not? There are numerous templates for this. Most are simply used to group topics into two, three or four categories. The activities&rsquo; names speak for themselves: <a href="https://www.funretrospectives.com/www-activity-worked-well-kinda-worked-didnt-work">WWW: Worked Well, kinda Worked, didn’t Work</a>, <a href="https://www.funretrospectives.com/the-3-ls-liked-learned-lacked">3Ls: Liked, Learned, Lacked</a> oder <a href="https://www.funretrospectives.com/open-the-box">Add, Remove, Recycle</a>. Another activity described in several places (for example <a href="https://retromat.org/en/?id=19">here</a> or <a href="https://www.funretrospectives.com/anchors-and-engine">here</a>) is Engines &amp; Anchors where topics are grouped by what drives the team forward and what holds the team back:</p>
<p><img src="/images/blog/more-fun-with-retrospectives/6_engines_and_anchors.png" alt="Screenshot Engines &amp; Anchors"></p>
<p>The screenshot shows a real-world example, anonymized. The underlying drawing by <a href="https://www.linkedin.com/in/h%C3%A9ctorhjure/">Héctor Horacio Jure</a> has been taken with his permission from this <a href="https://medium.com/@hectorhjure/scrum-toolkit-retrospective-1a8d7334d97a">medium article</a>.</p>
<p>Fun Retrospectives seems to assume that the action items follow more or less automatically from these topics. Just rev the engines and cut the anchors! Templates with category names like &ldquo;Add, Remove, Recycle&rdquo; do indeed imply the corresponding actions. Retromat, on the other hand, describes activities like <a href="https://retromat.org/en/?id=8">5 Whys</a> or <a href="https://retromat.org/en/?id=26">Speed Dating</a> to generate further insights. If the collected topics only describe symptoms, these additional activities can help to find the underlying causes. More inspiration can be found in <a href="https://www.liberatingstructures.com/">Liberating Structures</a>.</p>
<h2 id="closing">Closing</h2>
<p>For closing, both platforms offer check-out activities. They allow the team to express mutual <a href="https://retromat.org/en/?id=15">appreciation</a> or the facilitator to feel the mood again with <a href="https://www.funretrospectives.com/one-word-before-leaving">one word</a>. Therefore, I ask the starter question again before leaving: How do you feel now that you have read my article? Again in one word: Bored or disappointed? I hope not! Still interested? Informed? Or even inspired?</p>
]]></content:encoded>
    </item>
    <item>
      <title>Why names in programs matter</title>
      <link>https://walkagile.com/draft/why-names-in-programs-matter/</link>
      <pubDate>Thu, 20 Apr 2023 00:00:00 +0000</pubDate><author>peterhaefliger@yahoo.com (Peter Häfliger)</author>
      <guid>https://walkagile.com/draft/why-names-in-programs-matter/</guid>
      <description>&lt;p&gt;I would like to play around a bit with the &lt;a href=&#34;https://go.dev/&#34;&gt;go programming language&lt;/a&gt;. It is not a bad idea to learn a new programming language every once in a while to get to know different ways of thinking about computational problems. I did that extensively in the first years of my professional career when I was working abroad and had a lot of time during my lonely hotel nights. I do it very little today where I prefer to spend my free time with my family.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I would like to play around a bit with the <a href="https://go.dev/">go programming language</a>. It is not a bad idea to learn a new programming language every once in a while to get to know different ways of thinking about computational problems. I did that extensively in the first years of my professional career when I was working abroad and had a lot of time during my lonely hotel nights. I do it very little today where I prefer to spend my free time with my family.</p>
<p>I mostly work with Oracle SQL and PL/SQL in my job. The last time I played around with alternative languages was in 2019 when I studied some data science with R and Python. Now I would like to learn some go because it&rsquo;s the language in which HUGO is written, the static site generator which I use to render this site. To get started, I evaluated several resources and finally decided to buy John Arundel&rsquo;s book <a href="https://bitfieldconsulting.com/books/love">&ldquo;For the Love of Go&rdquo;</a>. A great book, as far as I can tell after the first three chapters.</p>
<p>In these first chapters, a <code>calculator</code> package is built. It contains, amongst others, the functions <code>Add</code> and <code>Multiply</code>:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1">// Package calculator does simple calculations.</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">calculator</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="c1">// Add takes two numbers and returns the result </span><span class="w">
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="c1">// of adding them together.</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">Add</span><span class="p">(</span><span class="nx">a</span><span class="p">,</span><span class="w"> </span><span class="nx">b</span><span class="w"> </span><span class="kt">float64</span><span class="p">)</span><span class="w"> </span><span class="kt">float64</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="w">  </span><span class="k">return</span><span class="w"> </span><span class="nx">a</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">b</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="c1">// Multiply takes two numbers and returns the result </span><span class="w">
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="c1">// of multiplying one by the other.</span><span class="w">
</span></span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">Multiply</span><span class="p">(</span><span class="nx">a</span><span class="p">,</span><span class="w"> </span><span class="nx">b</span><span class="w"> </span><span class="kt">float64</span><span class="p">)</span><span class="w"> </span><span class="kt">float64</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="w">  </span><span class="k">return</span><span class="w"> </span><span class="nx">a</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nx">b</span><span class="w">
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><p>I like the way packages and functions are introduced with this practical example, and I especially like the test-driven approach promoted by the book and by the language itself. A <code>calculator_test</code> package is presented immediately. It contains test functions for all the functions in the <code>calculator</code> package:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">calculator_test</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="s">&#34;calculator&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="s">&#34;testing&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">TestAdd</span><span class="p">(</span><span class="nx">t</span><span class="w"> </span><span class="o">*</span><span class="nx">testing</span><span class="p">.</span><span class="nx">T</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="w">  </span><span class="nx">t</span><span class="p">.</span><span class="nf">Parallel</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="w">  </span><span class="kd">var</span><span class="w"> </span><span class="nx">want</span><span class="w"> </span><span class="kt">float64</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">5</span><span class="w">
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="w">  </span><span class="nx">got</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">calculator</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="w">  </span><span class="k">if</span><span class="w"> </span><span class="nx">want</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="nx">got</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="w">    </span><span class="nx">t</span><span class="p">.</span><span class="nf">Errorf</span><span class="p">(</span><span class="s">&#34;want %f, got %f&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">want</span><span class="p">,</span><span class="w"> </span><span class="nx">got</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">TestMultiply</span><span class="p">(</span><span class="nx">t</span><span class="w"> </span><span class="o">*</span><span class="nx">testing</span><span class="p">.</span><span class="nx">T</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="w">  </span><span class="nx">t</span><span class="p">.</span><span class="nf">Parallel</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="w">  </span><span class="kd">var</span><span class="w"> </span><span class="nx">want</span><span class="w"> </span><span class="kt">float64</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">20</span><span class="w">
</span></span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="w">  </span><span class="nx">got</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">calculator</span><span class="p">.</span><span class="nf">Multiply</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="mi">5</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="w">  </span><span class="k">if</span><span class="w"> </span><span class="nx">want</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="nx">got</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="w">    </span><span class="nx">t</span><span class="p">.</span><span class="nf">Errorf</span><span class="p">(</span><span class="s">&#34;want %f, got %f&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">want</span><span class="p">,</span><span class="w"> </span><span class="nx">got</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="ln">23</span><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="ln">24</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><p>What I do <em>not</em> like about the above code snippets, however, is the names of the two functions under test.</p>
<p><code>Add</code> and <code>Multiply</code> are verbs in imperative mood. They are <em>commands</em>. Commands make good names for <em>procedures</em> but not for functions. Procedures like <code>write</code>, <code>draw</code>, <code>save</code> should do what their name implies, and they should not return any result. <code>TestAdd</code> and <code>TestMultiply</code> are good examples: They do what their name implies, namely test the function they claim to test, and they do not return a result. <em>Functions</em>, on the other hand, do return a result<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>, and they should be <em>named by what they return</em>.</p>
<p>If we name the functions by what they return, namely the <code>Sum</code> and the <code>Product</code> of two numbers:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1">// Package calculator does simple calculations.</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">calculator</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="c1">// Returns the sum of a and b.</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">Sum</span><span class="p">(</span><span class="nx">a</span><span class="p">,</span><span class="w"> </span><span class="nx">b</span><span class="w"> </span><span class="kt">float64</span><span class="p">)</span><span class="w"> </span><span class="kt">float64</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="w">  </span><span class="k">return</span><span class="w"> </span><span class="nx">a</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">b</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="c1">// Returns the product of a and b.</span><span class="w">
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">Product</span><span class="p">(</span><span class="nx">a</span><span class="p">,</span><span class="w"> </span><span class="nx">b</span><span class="w"> </span><span class="kt">float64</span><span class="p">)</span><span class="w"> </span><span class="kt">float64</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="w">  </span><span class="k">return</span><span class="w"> </span><span class="nx">a</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nx">b</span><span class="w">
</span></span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><p>then the code which calls them is more expressive:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="ln">1</span><span class="cl"><span class="nx">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">calculator</span><span class="p">.</span><span class="nf">Sum</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="nx">p</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">calculator</span><span class="p">.</span><span class="nf">Product</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="mi">5</span><span class="p">)</span></span></span></code></pre></div><p>This reads as:</p>
<ul>
<li>Let <code>s</code> be the <strong>sum</strong> of 2 and 3.</li>
<li>Let <code>p</code> be the <strong>product</strong> of 4 and 5.</li>
</ul>
<p>I find this a lot more intuitive than any of the following:</p>
<ul>
<li>Let <code>s</code> be the <em>result</em> of <em>adding</em> 2 and 3.</li>
<li><em>Multiply</em> 4 by 5 and assign the <em>result</em> to <code>p</code>.</li>
</ul>
<p>While the first is only cumbersome, the second is actually an overspecification and violates the principle of separation of concerns as I will elaborate on further below.</p>
<p>Or, in the context of the above <code>calculator_test</code> package:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="ln">1</span><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">TestSum</span><span class="p">(</span><span class="nx">t</span><span class="w"> </span><span class="o">*</span><span class="nx">testing</span><span class="p">.</span><span class="nx">T</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w">  </span><span class="nx">t</span><span class="p">.</span><span class="nf">Parallel</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w">  </span><span class="kd">var</span><span class="w"> </span><span class="nx">want</span><span class="w"> </span><span class="kt">float64</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">5</span><span class="w">
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="w">  </span><span class="nx">got</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">calculator</span><span class="p">.</span><span class="nf">Sum</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="w">  </span><span class="k">if</span><span class="w"> </span><span class="nx">want</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="nx">got</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="w">    </span><span class="nx">t</span><span class="p">.</span><span class="nf">Errorf</span><span class="p">(</span><span class="s">&#34;want %f, got %f&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">want</span><span class="p">,</span><span class="w"> </span><span class="nx">got</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="w">  </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="ln">8</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><p>As the function under test is named by what it returns, line 4 nicely reads: &ldquo;We got the sum of 2 and 3&rdquo;. This is followed by the check on line 5: &ldquo;If what we want is not what we got, then &hellip;&rdquo;.<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup></p>
<p>Unfortunately, some programming languages treat procedures just as functions which do not return any result (as go seems to do, judging from the implementation of the <code>calculator_test</code> package where <code>TestAdd</code> and <code>TestMultiply</code> are declared as <code>func</code> even though they are procedures) or which maybe return something like <code>void</code>. If you only program in languages which handle procedures this way, then my insistence on different naming patterns might seem a mere matter of taste. But there are languages which distinguish strongly between functions (which are <em>called</em>) and procedures (which are <em>executed</em>).</p>
<p>To Oracle, calling a function which returns a value is conceptually equal to selecting a value from a table, so the syntax is the same. For our example above, it would be:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="ln">1</span><span class="cl"><span class="k">select</span><span class="w"> </span><span class="n">calculator</span><span class="p">.</span><span class="k">Sum</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">)</span><span class="w"> </span><span class="k">from</span><span class="w"> </span><span class="n">dual</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="k">select</span><span class="w"> </span><span class="n">calculator</span><span class="p">.</span><span class="n">Product</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="mi">5</span><span class="p">)</span><span class="w"> </span><span class="k">from</span><span class="w"> </span><span class="n">dual</span><span class="p">;</span></span></span></code></pre></div><p>A procedure, on the other hand, needs to be executed:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="ln">1</span><span class="cl"><span class="k">exec</span><span class="w"> </span><span class="n">calculator</span><span class="p">.</span><span class="k">Start</span><span class="p">;</span></span></span></code></pre></div><p>With a function, the caller asks for something (in our example for the sum or the product of two numbers), while with a procedure, they ask (a package or module or object) to do something (in our example the calculator to start). It is sometimes argued that asking for a result is asking to compute that result (in our example: asking for the sum is asking to add and asking for the product is asking to multiply). But that&rsquo;s not true because the value could also be cached. Obeying the principle of separation of concerns, it should make no difference to the caller of the <code>Product</code> function whether the calulator multiplies the inputs to calculate the result or whether it selects the result from a pre-computed table.<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup> Asking for a result is <em>not</em> asking to compute it.</p>
<p>For the sake of completeness: There is a small variation to the recommendation that functions should be named by what they return and it applies to boolean functions, i.e. functions which return either true or false. They usually answer a yes/no question and their name  should reflect this. Boolean function names often denote a logical predicate or a property or quality of an object which can be true or false:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="ln">1</span><span class="cl"><span class="k">if</span><span class="w"> </span><span class="nx">button</span><span class="p">.</span><span class="nx">Enabled</span><span class="w"> </span><span class="p">{</span><span class="o">...</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="k">if</span><span class="w"> </span><span class="nx">customer</span><span class="p">.</span><span class="nx">Retired</span><span class="w"> </span><span class="p">{</span><span class="o">...</span><span class="p">}</span></span></span></code></pre></div><p>or maybe</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="ln">1</span><span class="cl"><span class="k">if</span><span class="w"> </span><span class="nx">button</span><span class="p">.</span><span class="nx">IsEnabled</span><span class="w"> </span><span class="p">{</span><span class="o">...</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="k">if</span><span class="w"> </span><span class="nx">customer</span><span class="p">.</span><span class="nx">IsRetired</span><span class="w"> </span><span class="p">{</span><span class="o">...</span><span class="p">}</span></span></span></code></pre></div><p>or, to take up the above PL/SQL calculator example again:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="ln">1</span><span class="cl"><span class="k">begin</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w">  </span><span class="k">if</span><span class="w"> </span><span class="n">calculator</span><span class="p">.</span><span class="k">Off</span><span class="w"> </span><span class="k">then</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w">    </span><span class="n">calculator</span><span class="p">.</span><span class="k">Start</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="w">  </span><span class="k">end</span><span class="w"> </span><span class="k">if</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="k">end</span><span class="p">;</span></span></span></code></pre></div><p>But do names in programs really matter? After all, they are just names. Probably not if you regard a program merely as a set of instructions for a machine. The compiler will remove them anyway. Then you might just as well name your functions f<sub>1</sub> to f<sub>n</sub>. But if you understand a program as a text to communicate interface specifications, design patterns, data structures and algorithm implementations to your fellow programmers, then you should definitely care.</p>
<p>Fortunately, my developer colleagues at Avaloq do care about function and procedure and variable names and about many other small things which make our code more readable, understandable and maintainable.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>In fact, functions should <em>not do anything but</em> return a result. To be more precise, they should not produce any abstract side-effects. That&rsquo;s what <a href="https://bertrandmeyer.com/">Bertrand Meyer</a> calls the <strong>Command-Query Separation Principle</strong>. It guarantees referential transparency and can be informally understood as &ldquo;asking a question should not change the answer&rdquo;. For a rigorous definition and explanation, see Bertrand&rsquo;s classic book &ldquo;Object-Oriented Software Construction, 2<sup>nd</sup> edition&rdquo; (OOSC-2), pg. 751. The book&rsquo;s full text has recently been made <a href="https://bertrandmeyer.com/OOSC2/">freely available online</a>.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>While I am writing this, I wonder if quality would improve if code were read aloud. Should we not only have code reviews, but also &ldquo;code slams&rdquo;? Maybe not, but code certainly benefits from being <em>explained</em>: If the reviewer does not only read your code but you actually have to explain it to them, you will catch many things which just &ldquo;don&rsquo;t sound right&rdquo;.</p>
<p>And while I am writing about explaining code to the reviewer, my colleague <a href="https://www.linkedin.com/in/uguerel/">Uğur Gürel</a> points me to <a href="https://en.wikipedia.org/wiki/Rubber_duck_debugging">Rubber Duck Debugging</a>. So the idea seems to be quite accepted that explaining code (or a concept or a design) to someone (even a rubber duck) helps uncover its flaws because it forces you to to rigorously think and reason about it instead of just glossing over it (&ldquo;I know that this works - somehow&hellip;&rdquo;).&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:3">
<p>That&rsquo;s what Bertrand Meyer calls the  <strong>Uniform Access Principle</strong>: &ldquo;All services offered by a module should be available through a uniform notation, which does not betray whether they are implemented through storage or through computation.&rdquo; For a detailed explanation, see &ldquo;Object-Oriented Software Construction, 2<sup>nd</sup> edition&rdquo; (OOSC-2), pg. 57, <a href="https://bertrandmeyer.com/OOSC2/">freely available online here</a>.&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    <item>
      <title>Software Development as a multidisciplinary endeavor</title>
      <link>https://walkagile.com/blog/software-development-multidisciplinary/</link>
      <pubDate>Tue, 04 Apr 2023 00:00:00 +0000</pubDate><author>peterhaefliger@yahoo.com (Peter Häfliger)</author>
      <guid>https://walkagile.com/blog/software-development-multidisciplinary/</guid>
      <description>&lt;p&gt;Last summer I came across an advertisement for a teaching assignment at a swiss university for a module called &amp;ldquo;Software Engineering Basics&amp;rdquo;. I applied and was even invited to an interview, but eventually they chose another candidate with a track record in education. But even if not successful, the application process proved to be a valuable opportunity for learning and self-reflection. When I applied, I knew of course that I lacked the teaching background, but more importantly, I had to ask myself whether I had the necessary domain expertise.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Last summer I came across an advertisement for a teaching assignment at a swiss university for a module called &ldquo;Software Engineering Basics&rdquo;. I applied and was even invited to an interview, but eventually they chose another candidate with a track record in education. But even if not successful, the application process proved to be a valuable opportunity for learning and self-reflection. When I applied, I knew of course that I lacked the teaching background, but more importantly, I had to ask myself whether I had the necessary domain expertise.</p>
<p>At that moment I had been a technical business analyst for six years, and before that I had been a team lead for six years, so my job title had not actually been &ldquo;software engineer&rdquo; for twelve years. Was I qualified to teach a class on software engineering? Or would the developers in my team just laugh at me?</p>
<p>But what is software development? And is it only done by engineers?</p>
<p>I was fortunate to start my career in 2001 at <a href="https://www.software-pioneers.com/sdm">sd&amp;m - software design &amp; management</a>, a german software project company which unfortunately does not exist any longer because it has been bought and fully integrated into another company. They did not sell software products but software development projects and they relied on the customers for business domain expertise. The company&rsquo;s employees were all generalists with a university degree in computer science, mathematics or some closely related engineering field. Except for some managers and architects, they were all called &ldquo;software engineers&rdquo; even if they were assigned to all phases of the development cycle - then usually very waterfall: requirements engineering, design, implementation, testing, documentation and roll-out.</p>
<p>When I later joined Avaloq in 2008, the situation was a bit different. There were &ldquo;developers&rdquo;, &ldquo;business analysts&rdquo; and &ldquo;managers&rdquo;. The company was very technology-driven and the developers were deservedly proud of their work. But some of them crossed the thin line between pride and arrogance: They would look down on business analysts and did not have much respect for managers anyway. Maybe this was a part of the pattern described by <a href="https://www.vikramchandra.com/">Vikram Chandra&rsquo;s</a> reflection on macho culture in the American software industry in his great book <a href="https://www.vikramchandra.com/publications/mirrored-mind-geek-sublime">Geek Sublime</a>.</p>
<p>Fortunately, this has changed with the agile transformation which has swept through the industry in the last years. Scrum promotes cross-functional teams whose members are all called &ldquo;developers&rdquo; even if some of them are mostly analyzing, testing or documenting rather than programming. That&rsquo;s a positive cultural change because it recognizes the fact that software development is more than mere coding. Some universities have started to acknowledge this and create more interdisciplinary computer science tracks like the <a href="https://www.fhnw.ch/en/computer-science/degree-programmes/offerings/programmes/icompetence">iCompetence programme</a> at the <a href="https://www.fhnw.ch/en">University of Applied Sciences and Arts Northwestern Switzerland</a>.</p>
<p>Today I am a product owner. That&rsquo;s one of the only two roles (or accountabilities) which the scrum framework knows <em>besides</em> developers (the other one is the scrum master). But what&rsquo;s my professional purpose other than developing software? The term &ldquo;filmmaker&rdquo; usually refers to the director or producer, not to the person actually holding the camera. In the same sense, I will always consider myself a software developer, even if my contribution is not in writing code but in identifying customer requirements, reconciling stakeholder priorities and maximizing value. That&rsquo;s why in my <a href="https://www.linkedin.com/in/peter-h%C3%A4fliger-89b107103/">linkedin</a> and similar profiles, I call myself &ldquo;agile software developer and product owner&rdquo;.</p>
<p>A related thought concerns the topic of diversity, for example gender diversity. One way to promote women in tech is to get girls passionate about programming. My Avaloq colleague <a href="https://www.linkedin.com/in/lkripa/">Lara</a> and her team do a great job introducing swiss schoolgirls to coding with their non-profit organization <a href="https://girlscodetoo.ch/">GirlsCodeToo</a>. A complementary approach is to open software development teams to profiles other than programmers, for example UX designers. This will automatically attract a higher percentage of female applicants. And the professional diversity will be beneficial for everybody: As they work together in a scrum or kanban team, engineers will absorb some design thinking over time while designers will start to think a bit like programmers (abstract, functional, object- and service-oriented).</p>
<p>Software development is a multidisciplinary endeavor. That&rsquo;s why I still love my job!</p>
]]></content:encoded>
    </item>
    <item>
      <title>Fun Retrospectives</title>
      <link>https://walkagile.com/blog/funretrospectives/</link>
      <pubDate>Thu, 30 Mar 2023 00:00:00 +0000</pubDate><author>peterhaefliger@yahoo.com (Peter Häfliger)</author>
      <guid>https://walkagile.com/blog/funretrospectives/</guid>
      <description>&lt;p&gt;&lt;em&gt;This first post is an updated version of an article which I have written in January 2021 for an older blog of mine which I have since discontinued. It was the time when we had to prepare our first distributed/online retrospectives during the Corona lockdown. It describes my experience with &lt;a href=&#34;https://www.funretrospectives.com/&#34;&gt;Fun Retrospectives&lt;/a&gt;, a book, website and very helpful online retro tool.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;&#xA;&lt;p&gt;For those who do not know the term “retrospective” (or “retro” for short), I cite the following method-independent definition:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><em>This first post is an updated version of an article which I have written in January 2021 for an older blog of mine which I have since discontinued. It was the time when we had to prepare our first distributed/online retrospectives during the Corona lockdown. It describes my experience with <a href="https://www.funretrospectives.com/">Fun Retrospectives</a>, a book, website and very helpful online retro tool.</em></p>
<h2 id="introduction">Introduction</h2>
<p>For those who do not know the term “retrospective” (or “retro” for short), I cite the following method-independent definition:</p>
<blockquote>
<p>Another agile practice is the retrospective, in which a team having finished a development iteration takes time off further development
to reflect on the experience and the lessons learned, with the goal of improving its development process.</p>
<p>— <!-- raw HTML omitted --><a href="https://bertrandmeyer.com/">Bertrand Meyer</a>: <a href="https://bertrandmeyer.com/2014/06/02/accurately-analyzing-agility/">Agile! The Good, the Hype and the Ugly</a>, pg. 9<!-- raw HTML omitted --></p>
</blockquote>
<p>Retrospectives are an important agile practice. They facilitate the team’s self-organization and continuous improvement.</p>
<p>The concept was of course not invented by the agile movement. When I started my career in the software industry more than twenty years ago, we used to have a “touch-down” meeting at the end of every project, as we used to have a “kick-off” meeting at the beginning of every project. In other settings, these touch-downs were simply called “lessons-learnt” sessions.</p>
<p>The achievement of the agile movement lies in the importance and value it has given to retrospectives. Scrum development teams do a retro after every sprint, which usually means every 2 to 4 weeks.</p>
<p>There are many books on the theory, philosophy and psychology of retrospectives. Far out at the practical end of the spectrum, there is &ldquo;Fun Retrospectives&rdquo; by Paulo Caroli and Tainã Caetano, a <a href="https://www.amazon.com/gp/product/B08GHYCF2W?pf_rd_r=5KJH4Q5VQN2W0G9FNCG5&amp;pf_rd_p=6fc81c8c-2a38-41c6-a68a-f78c79e7253f">book</a> and <a href="https://www.funretrospectives.com/">website</a> which contain a wealth of techniques and activities to “break the ice” in a retro, to get the conversation going and to help uncover the real, hidden issues which bother the team members. Again, the general idea is of course not new: Good facilitators have known such games and activities in pre-agile times. But the book is a good starting point for the novice and a great source of inspiration even for the experienced scrum master.</p>
<p>These types of activities were developed for in-person meetings, as agile methods in general were developed for personal interaction, with developers sharing (depending on the method) one room, one desk, one keyboard or even one lunchbox. But some of the activities can easily be performed in a distributed setting. And, fortunately, the authors have built an online tool where they have implemented a few of them. They have, in fact, implemented their full <a href="https://caroli.org/en/a-7-step-agenda-for-effective-retrospectives/">7-Step Agenda for Effective Retrospectives</a>.</p>
<p>Let’s look at how to successfully prepare and execute such an online retrospective.</p>
<h2 id="preparation">Preparation</h2>
<p>To prepare a retrospective for your team, just create a <a href="https://app.funretrospectives.com/new">new agenda</a> and configure the seven steps:</p>
<h3 id="1-context">1. CONTEXT</h3>
<p>Set the context for the meeting, for example “last sprint” or “last delivery” or “last week’s major incident”. This will align the participants’ expectations as to the scope of the retro. As we are nearing the end of the first quarter, we’ll set the context to “Q1/2023” in the example and then click the <strong>NEXT</strong> button:</p>
<p><img src="/images/blog/funretrospectives/1_context.png" alt="1. context"></p>
<h3 id="2-prime-directive">2. Prime Directive</h3>
<p>For retrospectives, this is the well-known</p>
<blockquote>
<p>Regardless of what we discover, we understand and truly believe that everyone did the best job they could, given what they knew at the time,
their skills and abilities, the resources available, and the situation at hand.</p>
<p>&mdash; Norm Kerth: Project Retrospectives: A Handbook for Team Reviews</p>
</blockquote>
<p>There are similar prime directives for futurespectives and team building meetings. As we’ll do a normal retrospective in the example, we&rsquo;ll choose &ldquo;Retrospective&rdquo; and then click the <strong>NEXT</strong> button again:</p>
<p><img src="/images/blog/funretrospectives/2_prime_directive.png" alt="2. prime directive"></p>
<h3 id="3-energizer">3. Energizer</h3>
<p>Choose a first activity to break the ice and get the participants engaged. At the time of this writing, three activities are available: <a href="https://www.funretrospectives.com/guess-my-favorite-song/">Guess who likes it</a>, <a href="https://www.funretrospectives.com/the-roulette-asks/">The roulette asks</a> and <a href="https://www.funretrospectives.com/fun-fact/">Fun Fact</a>. Alternatively, a custom table can be created or the activity can be skipped by choosing &ldquo;None&rdquo;. We’ll choose “Guess who likes it” in the example and then click the <strong>NEXT</strong> button again:</p>
<p><img src="/images/blog/funretrospectives/3_energizer.png" alt="3. energizer"></p>
<h3 id="4-check-in">4. Check-in</h3>
<p>Choose an activity which allows the participants to reflect and communicate their mood and feelings about the retrospective and the group of participants. At the time of this writing, four activities are available: <a href="https://www.funretrospectives.com/safety-check/">Safety Check</a>, <a href="https://www.funretrospectives.com/esvp-explorer-shopper-vacationer-prisoner/">Explorer, Shopper, Vacationer, Prisoner</a>, <a href="https://www.funretrospectives.com/happiness-radar/">Happiness Radar</a> and <a href="https://www.funretrospectives.com/one-word/">One Word</a>. Alternatively, a custom table can be created or the activity can be skipped by choosing &ldquo;None&rdquo;. We’ll choose “Safety Check” in the example and then click the <strong>NEXT</strong> button again:</p>
<p><img src="/images/blog/funretrospectives/4_check_in.png" alt="4. check-in"></p>
<h3 id="5-main-course">5. Main Course</h3>
<p>Choose an activity for the main part of the retrospective where you want to collect feedback about the iteration (or whatever context you have chosen). At the time of this writing, four activities are available: <a href="https://www.funretrospectives.com/www-activity-worked-well-kinda-worked-didnt-work/">WWW: Worked well, kinda Worked, didn’t Work</a>, <a href="https://www.funretrospectives.com/the-3-ls-liked-learned-lacked/">The 3 Ls: Liked, Learned, Lacked</a>, <a href="https://www.funretrospectives.com/open-the-box/">Open the Box: Add, Remove, Recycle</a> and <a href="https://www.funretrospectives.com/hopes-and-concerns/">Hopes &amp; Concerns</a>. Alternatively, a custom table can be created. We’ll choose “Open the Box: Add, Remove, Recycle” in the example:</p>
<p><img src="/images/blog/funretrospectives/5_main_course.png" alt="5. main course"></p>
<p>All the main course activities allow the participants to post cards with items to be discussed. The cards can be colored for categorization. The default colors are yellow (for category “People”), blue (for category “Process”) and red (for category “Tools”):</p>
<p><img src="/images/blog/funretrospectives/5a_main_course_config.png" alt="5.a. main course config"></p>
<p>You can change the colors (by clicking on them) or change the labels (by clicking on the <strong>pen</strong> icons) to group the items along different categories. We&rsquo;ll leave the default configuration unchanged and click the <strong>NEXT</strong> button again.</p>
<h3 id="6-filtering">6. Filtering</h3>
<p>Define the voting scheme on the items collected in the main course. <a href="https://www.funretrospectives.com/dot-voting/">Dot Voting</a> provides feedback about the relative importance of the items to the majority of the participants whereas <a href="https://www.funretrospectives.com/select-one-and-talk/">Select one and talk</a> allows every participant to discuss the item most important to them. The other voting schemes do not seem to be enabled yet at the time of this writing. We’ll choose Dot Voting in the example and then click the <strong>NEXT</strong> button again:</p>
<p><img src="/images/blog/funretrospectives/6_filtering.png" alt="6. filtering"></p>
<h3 id="7-check-out">7. Check-out</h3>
<p>Choose an activity to close the meeting. At the time of this writing, three very different activities are available: While <a href="https://www.funretrospectives.com/one-word-before-leaving/">One word before leaving</a> allows each participant to communicate their feelings at the end of the meeting and <a href="https://www.funretrospectives.com/token-of-appreciation/">Token of appreciation</a> fosters appreciation and acknowlegement between team members, <a href="https://www.funretrospectives.com/the-who-what-when-steps-to-action/">Who-What-When Steps to Action</a> helps to define follow-up actions, deadlines and accountabilities. Alternatively, a custom table can be created or the activity can be skipped by choosing &ldquo;None&rdquo;.  We’ll choose “One word before leaving” in the example and then click the <strong>COMPLETE</strong> button and then the <strong>CREATE RETROSPECTIVE</strong> button:</p>
<p><img src="/images/blog/funretrospectives/7_check_out.png" alt="7. check-out"></p>
<h3 id="agenda">Agenda</h3>
<p>This will create the retrospective and show you the agenda (which is called Summary because it will serve as a summary at the end) with the Context, the Prime Directive, the activities chosen for the different courses (Energizer, Check-in, Main Course and Check-out), the filtering (voting scheme) and the skeleton of the main course action items to be elaborated:</p>
<p><img src="/images/blog/funretrospectives/8_agenda.png" alt="8. agenda"></p>
<p>You can navigate to the different courses, for example to the Energizer:</p>
<p><img src="/images/blog/funretrospectives/9_energizer.png" alt="9. energizer"></p>
<p>And you can add titles or column names for some of the activies. As an example, let&rsquo;s add instructions for the Energizer activity:</p>
<p><img src="/images/blog/funretrospectives/10_energizer_configured.png" alt="10. energizer configured"></p>
<p>Once everything is correctly configured, you can copy the link (URL) from your browser&rsquo;s address field and send it to the participants.</p>
<h2 id="execution">Execution</h2>
<p>The participants can open the board simply by following the link. Of course you will need a separate tool like skype or zoom for audio (and possibly video) interaction.</p>
<p>After the reading of the Context and Prime Directive from the agenda/summary, all participants need to navigate to the Energizer activity. In our example, they can enter the title of their favorite movie and hit Enter to make it visible to the others:</p>
<p><img src="/images/blog/funretrospectives/11_energizer_executed.png" alt="11. energizer executed"></p>
<p>Guessing who likes what will be a lot of fun and warm the players up for the more serious discussions to come.</p>
<p>After the Energizer activity, all participants need to navigate to the Check-in activity which in our example is ESVP (Explorer, Shopper, Vacationer, Prisoner) where each participant can anonymously reveal their feelings and expectations towards this retrospective:</p>
<p><img src="/images/blog/funretrospectives/12_check_in.png" alt="12. check-in"></p>
<p>Every participant can hit the button corresponding to the character which fits them most. Once the button is pressed, the count will be anonymously revealed. A participant who does not want to participate in this activity can reveal the count with the <strong>REVEAL</strong> button:</p>
<p><img src="/images/blog/funretrospectives/13_check_in_executed.png" alt="13. check-in executed"></p>
<p>After the Check-in, all participants need to navigate to the Main Course. In our example, they can enter items which they would like to add, remove or recycle (i.e. keep) into the respective column and hit Enter to make them visible to the others:</p>
<p><img src="/images/blog/funretrospectives/14_main_course_executed.png" alt="14. main course executed"></p>
<p>Moving over one of the posts with the mouse shows additional steering elements to modify the post:</p>
<p><img src="/images/blog/funretrospectives/15_main_course_single_post.png" alt="15. main course single post"></p>
<p>Posts can be edited with the pen icon or deleted with the trashcan icon. Their color can be changed for categorization with the color dots.</p>
<p>Posts can be moved around between rows or columns when the mouse is placed on the three dots at the top of the card. By moving the cards around, the posts can be ordered or clustered.</p>
<p>After all the items have been collected and discussed, they can be voted on with the +/- buttons if dot voting is enabled. The vote count appears in the upper right corner of the card.</p>
<p>Finally, action items can be discussed and written down with the second pen icon at the bottom of the card.</p>
<p>After the Main Course of the retrospective, all participants need to navigate to the Check-out activity. In our example, they can let the others know with one word how they feel after the retro and hit Enter to make it visible to the others:</p>
<p><img src="/images/blog/funretrospectives/16_check_out_executed.png" alt="16. check-out executed"></p>
<p>The action items defined in the Main Course have been added to the summary which can be printed and distributed or stored away:</p>
<p><img src="/images/blog/funretrospectives/17_summary.png" alt="17. summary"></p>
<p>This allows to check at the beginning of the next retro whether this retro’s action items have been implemented. In a real-world example, the action items should of course not only have a responsible person assigned but also a deadline.</p>
<h2 id="caveats">Caveats</h2>
<p>The tool is free and easy to use. As it is not a commercial tool (and not paid for by advertisements either), it does, however, lack production quality. This manifests itself in a number of drawbacks which you should keep in mind if you want to use it safely and effectively and avoid frustration or even security issues:</p>
<ul>
<li>There are no accounts, no log-ins, no passwords. This makes it extremely easy to use but means of course that the data entered is out there on the web, unprotected. Everybody who guesses the link can access it. This is no problem if every participant strictly adheres to the rule that absolutely no personal or classified data whatsoever (names or other personal data of the participants, customer-identifying data or the company’s secrets of trade) may be entered into the board.</li>
<li>Any participant can modify text entered by another participant or other attributes of a post like the color. Even the colors of the categories or their labels or the activities’ titles or column names could be changed by any participant during the meeting. This is no problem if every participant only does so with explicit permission of the author of the post or the facilitator.</li>
<li>Participants can post more than once even where they are supposed to post only once (e.g. in the “Who likes it” or “One Word” activities). Likewise, this is no problem if simply no participant does this.</li>
<li>The number of votes seems to be limited to five votes per participant which might not be quite sufficient if there are many items to vote on.</li>
<li>As some actions are not undoable, the facilitator should make sure that all participants understand these limitations beforehand. It might therefore be advisable to not include the link in the meeting invitation but only send it out during the meeting after some introductory explanations.</li>
<li>To ensure that the participants navigate in sync and are always on the same page, it helps if the facilitator can share his screen through a separate video channel.</li>
</ul>
<p>Again, the tool is free to use without any installation. And in summary, it works well if all participants play by the rules and use common sense and good will. Just give it a try! And whatever tool you use, have a look at the Fun Retrospectives <a href="https://www.amazon.com/gp/product/B08GHYCF2W?pf_rd_r=5KJH4Q5VQN2W0G9FNCG5&amp;pf_rd_p=6fc81c8c-2a38-41c6-a68a-f78c79e7253f">book</a> or <a href="https://www.funretrospectives.com/">website</a> if you are looking for inspiration.</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
