<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.0">Jekyll</generator><link href="https://team-coder.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://team-coder.com/" rel="alternate" type="text/html" /><updated>2021-02-04T18:12:51+00:00</updated><id>https://team-coder.com/feed.xml</id><title type="html">The Team Coder</title><subtitle>Software Development and Leadership</subtitle><entry><title type="html">Swift: The App Tracking Transparency APIs on iOS</title><link href="https://team-coder.com/app-tracking-transparency-apis/" rel="alternate" type="text/html" title="Swift: The App Tracking Transparency APIs on iOS" /><published>2021-02-02T08:00:00+00:00</published><updated>2021-02-02T08:00:00+00:00</updated><id>https://team-coder.com/app-tracking-transparency-apis</id><content type="html" xml:base="https://team-coder.com/app-tracking-transparency-apis/">&lt;p&gt;Apple just released some &lt;a href=&quot;https://developer.apple.com/news/?id=3ozbk628&quot;&gt;updates&lt;/a&gt; on their App Store Review Guideline. I guess for most app developers the most relevant point in this update is this one:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;You must receive explicit permission from users via the App Tracking Transparency APIs to track their activity.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I think it’s a good step towards more transparency and data protection but it also means some extra work for us developers. In this blog post I explain how to use Apple’s &lt;em&gt;App Tracking Transparency APIs&lt;/em&gt; in three simple steps.&lt;/p&gt;

&lt;h2 id=&quot;step-1-set-up-privacy-key-in-infoplist&quot;&gt;Step 1: Set up Privacy Key in Info.plist&lt;/h2&gt;

&lt;p&gt;The first thing we have to do is adding a new key in our app’s Info.plist file. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSUserTrackingUsageDescription&lt;/code&gt; key provides a message which is displayed along with the tracking authorization dialog. You can use it to explain the user why the tracking is necessary. So go ahead and add the key, like illustrated in this screen shot:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../images/posts/2021-02-02-app-tracking-transparency-apis/NSUserTrackingUsageDescription.png&quot; alt=&quot;the NSUserTrackingUsageDescription key in Info.plist&quot; /&gt;&lt;/p&gt;

&lt;p&gt;NOTE: Make sure to have at least Xcode 12.4 installed in order to use the App Tracking Transparency APIs.&lt;/p&gt;

&lt;h2 id=&quot;step-2-request-tracking-authorization&quot;&gt;Step 2: Request Tracking Authorization&lt;/h2&gt;

&lt;p&gt;Next we can implement the dialog for requesting the user’s permission for tracking. Here is how we do it:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;ATTrackingManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;requestTrackingAuthorization&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
            
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When the above code is executed the user will see the following dialog:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../images/posts/2021-02-02-app-tracking-transparency-apis/app-tracking-transparency-dialog.png&quot; alt=&quot;App Tracking Transparency dialog&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;step-3-determining-the-authorization-status&quot;&gt;Step 3: Determining the Authorization Status&lt;/h2&gt;

&lt;p&gt;Finally, we can find out if the user has granted us permissions  for tracking or not. We modify our previous code like this:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;AppTrackingTransparency&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;ATTrackingManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;requestTrackingAuthorization&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;authorized&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Yeah, we got permission :)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;denied&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Oh no, we didn't get the permission :(&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;notDetermined&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Hmm, the user has not yet received an authorization request&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;restricted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Hmm, the permissions we got are restricted&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;@unknown&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Looks like we didn't get permission&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note that we have to import &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AppTrackingTransparency&lt;/code&gt; in order to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ATTrackingManager&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;summing-up&quot;&gt;Summing Up&lt;/h2&gt;

&lt;p&gt;That’s it. It’s not very complicated. However, the challenge is now to only do the tracking if you got the permission and also to find a way to deal with a denied permission.&lt;/p&gt;</content><author><name>Robert Ecker</name></author><category term="dev" /><summary type="html">This article explains how to use the App Tracking Transparency APIs for user tracking on iOS.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://team-coder.com/images/posts/2021-02-02-app-tracking-transparency-apis/title-image.jpg" /><media:content medium="image" url="https://team-coder.com/images/posts/2021-02-02-app-tracking-transparency-apis/title-image.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">GitHub Pages and Jekyll</title><link href="https://team-coder.com/github-pages-and-jekyll/" rel="alternate" type="text/html" title="GitHub Pages and Jekyll" /><published>2020-06-14T06:00:00+00:00</published><updated>2020-06-14T06:00:00+00:00</updated><id>https://team-coder.com/github-pages-and-jekyll</id><content type="html" xml:base="https://team-coder.com/github-pages-and-jekyll/">&lt;p&gt;I have recently rebuilt this website with Jekyll and it is now deployed via GitHub Pages. In this article I will tell you why I did that and show you how I did it.&lt;/p&gt;

&lt;h2 id=&quot;about-github-pages-and-jekyll&quot;&gt;About GitHub Pages and Jekyll&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://pages.github.com&quot;&gt;GitHub Pages&lt;/a&gt; is a free web hosting service for static websites which are stored in Git repositories on GitHub. The website that is actually served is created by a generator, like &lt;a href=&quot;https://jekyllrb.com&quot;&gt;Jekyll&lt;/a&gt;, which allows us to use templates for building up the HTML and SASS for assembling the CSS.&lt;/p&gt;

&lt;h2 id=&quot;why-i-use-github-pages-and-jekyll&quot;&gt;Why I Use GitHub Pages and Jekyll&lt;/h2&gt;
&lt;p&gt;There seem to be endless ways and technologies for building a website. They range from setting up a Wordpress blog with almost no coding effort up to building a React frontend and a Node.js backend and setting up a MongoDB, all by yourself. Here are the reasons why I decided to use GitHub Pages and Jekyll for my blog:&lt;/p&gt;

&lt;h3 id=&quot;markdown-to-html&quot;&gt;Markdown to HTML&lt;/h3&gt;
&lt;p&gt;When I write down my thoughts I always use Markdown. It’s simple and doesn’t require blown-up writing software like Microsoft Word. I can basically use any text editor for it. One thing that Jekyll does is it converts my markdown articles into HTML pages which is exactly what I need.&lt;/p&gt;

&lt;h3 id=&quot;history-and-backups&quot;&gt;History and Backups&lt;/h3&gt;
&lt;p&gt;I like the idea of having a complete history of all the changes I do on my website. In Git I can always go back in time and see what I wrote when. I can see what were my original words before editing a blog post. I can also see how my page was set up two years ago. All those things come built-in since with GitHub Pages everything is in a Git repository (unlike Wordpress for example). Also doing backups is easy because there are no databases. Just files and directories. Obviously, having a local version of the Git repository on my machine is already like a backup.&lt;/p&gt;

&lt;h3 id=&quot;speed&quot;&gt;Speed&lt;/h3&gt;
&lt;p&gt;GitHub Pages are hosted on GitHub servers and those are pretty fast. The average loading time of team-coder.com became much shorter when I moved it to GitHub.&lt;/p&gt;

&lt;h2 id=&quot;how-i-set-up-github-pages-and-jekyll&quot;&gt;How I Set Up GitHub Pages and Jekyll&lt;/h2&gt;

&lt;p&gt;There are many different use cases for GitHub Pages and many different ways to set them up and build them. In this blog post I will not cover them all. Instead, I will let you know how I used GitHub Pages and Jekyll for building the blog that you are currently reading.&lt;/p&gt;

&lt;h3 id=&quot;step-1-setting-up-a-github-project&quot;&gt;Step 1: Setting Up a GitHub Project&lt;/h3&gt;
&lt;p&gt;For this blog, my first step was to create &lt;a href=&quot;https://github.com/team-coder/team-coder.com&quot;&gt;this GitHub repository&lt;/a&gt; in a GitHub organization which I created just for the Team Coder website. I could have also created the repository in my personal GitHub account but I prefer to have it independent from my personal account.&lt;/p&gt;

&lt;p&gt;GitHub already offers a ready-to-use &lt;em&gt;.gitignore&lt;/em&gt; file for Jekyll projects which I happily used when I created the repository.&lt;/p&gt;

&lt;h3 id=&quot;step-2-setting-up-jekyll&quot;&gt;Step 2: Setting Up Jekyll&lt;/h3&gt;
&lt;p&gt;I found the most straight-forward instructions for installing Jekyll and initiating the Jekyll project on &lt;a href=&quot;https://jekyllrb.com/docs/&quot;&gt;Jekyll’s official website&lt;/a&gt;. I did exactly those steps.&lt;/p&gt;

&lt;p&gt;Now, whenever I use my terminal to run this:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;bundle &lt;span class=&quot;nb&quot;&gt;exec &lt;/span&gt;jekyll serve
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;…my website becomes available at &lt;a href=&quot;http://localhost:4000&quot;&gt;http://localhost:4000&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;step-3-coding&quot;&gt;Step 3: Coding&lt;/h3&gt;
&lt;p&gt;Step 3 is the most interesting part and I decided to not loose too many words about it :-P
To be honest, the project that Jekyll sets up initially is pretty self-explanatory. Again, the &lt;a href=&quot;https://jekyllrb.com/docs/&quot;&gt;Jekyll website&lt;/a&gt; perfectly explains all the details. If it is helpful for you, you are welcome to have a look at the &lt;a href=&quot;https://github.com/team-coder/team-coder.com&quot;&gt;source code of team-coder.com&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;step-4-adding-content&quot;&gt;Step 4: Adding Content&lt;/h3&gt;
&lt;p&gt;I store all my blog posts as markdown files in the &lt;em&gt;_posts&lt;/em&gt; directory. For all the images I want to use in those posts I created an extra directory in the root of my project and called it &lt;em&gt;images&lt;/em&gt;. Among other images, like the Team Coder logo, it contains a directory called &lt;em&gt;posts&lt;/em&gt; and that contains directories for all of my blog posts. That way I have all my images separated and assigned to their posts which seems to be the most clean structure to me.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You can write HTML code in your markdown files as well. This can be helpful if you want to use structures that are not supported by Markdown, like tables with multiple rows in one cell. All you need is the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{::nomarkdown}&lt;/code&gt; tag like this:&lt;/p&gt;

&lt;div class=&quot;language-markdown highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;|Name |Bullet Points                                   |
|-----|------------------------------------------------|
|Joe  |{::nomarkdown}&lt;span class=&quot;nt&quot;&gt;&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;&lt;/span&gt;bullet point&lt;span class=&quot;nt&quot;&gt;&amp;lt;/li&amp;gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;{:/}|
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;step-5-publishing-the-website-on-githubio&quot;&gt;Step 5: Publishing the Website on github.io&lt;/h3&gt;
&lt;p&gt;Publishing the website on github.io is simple. There is a section called &lt;em&gt;GitHub Pages&lt;/em&gt; in the &lt;em&gt;Settings / Options&lt;/em&gt; menu of every repository on GitHub. Selecting the master branch as a source will publish the website and make it available on &lt;em&gt;https://TEAM-OR-USER-NAME.github.io/REPO-NAME&lt;/em&gt;.&lt;/p&gt;

&lt;h3 id=&quot;step-6-using-a-custom-domain&quot;&gt;Step 6: Using a Custom Domain&lt;/h3&gt;
&lt;p&gt;I don’t want to have &lt;em&gt;https://team-coder.github.io/team-coder.com&lt;/em&gt; as a domain for my blog. I want &lt;em&gt;https://team-coder.com&lt;/em&gt;. Setting that up requires some configuration. The instructions on &lt;a href=&quot;https://help.github.com/en/github/working-with-github-pages/managing-a-custom-domain-for-your-github-pages-site&quot;&gt;this GitHub page&lt;/a&gt; helped me to get the job done. After changing the records at my DNS provider it took a couple of hours until my GitHub Page was available on &lt;a href=&quot;https://team-coder.com&quot;&gt;https://team-coder.com&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;my-recommendation&quot;&gt;My Recommendation&lt;/h2&gt;
&lt;p&gt;Creating this website with Jekyll was a lot of fun. The flexibility is great, I did never reach the point where I couldn’t implement something for technical reasons. Building the layout with templates and SASS was also a plesant experience. I love how I can easily push my new blog posts as Markdown files to Github and have them rendered as HTML pages. The whole thing feels very lightweight and it is also much faster than the old version of this website. For a static website like this I can absolutely recommend using GitHub Pages with Jekyll.&lt;/p&gt;</content><author><name>Robert Ecker</name></author><category term="dev" /><summary type="html">I have recently rebuilt this website with Jekyll and it is now deployed via GitHub Pages. In this article I will tell you why I did that and show you how I did it.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://team-coder.com/images/posts/2020-06-14-github-pages-and-jekyll/title-image.jpg" /><media:content medium="image" url="https://team-coder.com/images/posts/2020-06-14-github-pages-and-jekyll/title-image.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">How to Overcome a Bad Habit</title><link href="https://team-coder.com/how-to-overcome-a-bad-habit/" rel="alternate" type="text/html" title="How to Overcome a Bad Habit" /><published>2019-07-02T10:00:00+00:00</published><updated>2019-07-02T10:00:00+00:00</updated><id>https://team-coder.com/how-to-overcome-a-bad-habit</id><content type="html" xml:base="https://team-coder.com/how-to-overcome-a-bad-habit/">&lt;p&gt;At least 40% of the things we do in our daily lives are habits. We don’t control them consciously. We just do what we are used to do. From an evolutionary perspective this is a valuable strategy. We have to spend less time on thinking and making decisions and can instead run away from a dangerous animal instantly. Today, we still have useful habits, like looking for cars before crossing a street. Many of our habits, however, are not necessary at all, some of them are even unhealthy.&lt;/p&gt;

&lt;p&gt;In this article I want to tell you about my coffee addiction and how I overcame it. For so many years I could not resist this hot drink. I had at least three coffees every day. When I didn’t get my coffee I became literally useless and sometimes angry. The headache would start and my craving for coffee would make me go crazy.&lt;/p&gt;

&lt;h2 id=&quot;the-goal&quot;&gt;The Goal&lt;/h2&gt;
&lt;p&gt;Fighting a habit can only work if you have a clear idea why you want to fight it. For me it was the realization that coffee was not good for my stomach. When I was younger I didn’t have a problem with it but today there seem to be some weird things going on in my stomach after I had a cup of coffee.&lt;/p&gt;

&lt;h2 id=&quot;the-trigger&quot;&gt;The Trigger&lt;/h2&gt;
&lt;p&gt;When I first wanted to get rid of my coffee addiction I thought that all I need is will power. I was so wrong. Whenever I was in the office, sitting at my desk for a while, it didn’t take long until the craving came up. I needed a coffee and even if my plan was to ignore it, I always found a good reason to make an exception.&lt;/p&gt;

&lt;p&gt;The first thing I had to do was to identify the triggers. What triggered me to have a coffee? I quickly realized that I always got myself a coffee when I was sitting in front of my computer for too long. It made me tired and this feeling of tiredness triggered my habit to go to the coffee machine.&lt;/p&gt;

&lt;p&gt;The trick is not to try to fight the triggers. They will always be there. Obviously there will always be situations where I feel tired. I understood that I have to accept those situations and find another way to deal with it.&lt;/p&gt;

&lt;h2 id=&quot;the-craving&quot;&gt;The Craving&lt;/h2&gt;
&lt;p&gt;Whenever I am triggered there is a craving inside me that starts to grow and quickly becomes very dominating. It’s important to identify that craving. What is it really that I craved? Was it the taste of coffee? No, not really. The coffee at our coffee machine is okay but there are other things which are much tastier. Was it the warmth that a cup of coffee spent? No, otherwise I wouldn’t drink it in the hot summer. What I was really craving was the energized feeling that I got out of the coffee.&lt;/p&gt;

&lt;p&gt;When I am triggered the craving comes inevitably. It’s almost impossible to suppress it. Like the trigger, I also have to accept the craving. But what can I do to fight the habit? There is one more variable…&lt;/p&gt;

&lt;h2 id=&quot;the-action&quot;&gt;The Action&lt;/h2&gt;
&lt;p&gt;The action is the part of the habit that can actually be controlled. In my case, the action was to stand up, go to the coffee machine and have a coffee. It was initiated by the trigger and driven by the craving. If I wanted to get rid of it I had to replace it with something else. So the question was, “What else can I do to satisfy the craving?”&lt;/p&gt;

&lt;p&gt;I found out that standing up and walking to the coffee machine already helped to energize my mind. I replaced the coffee with a glas of water which also boosted my energy. And I also started walking around for a couple  more minutes just to get my body stimulated. After such a 5 minutes break I have the same energy level as with a cup of coffee.&lt;/p&gt;

&lt;h2 id=&quot;how-to-make-it-easier&quot;&gt;How to Make It Easier&lt;/h2&gt;
&lt;p&gt;To make the change to the new action easier it would be helpful to make the old action impossible. An idea would be to remove the coffee machine from the kitchen. While this would have helped me, my colleagues would not have been very happy about this idea.&lt;/p&gt;

&lt;p&gt;But there are other things you can do to support your mission. I told everybody about my plan to not drink coffee anymore. When I was just about to fall into my old habit and take the coffee instead of the water, I didn’t want to look weak in front of my colleagues so I changed my mind and took the water.&lt;/p&gt;

&lt;h2 id=&quot;overcoming-the-habit&quot;&gt;Overcoming the Habit&lt;/h2&gt;
&lt;p&gt;The first days were very hard for me. I had headache and went crazy because of the physical absence of caffeine. However, I knew why I wanted to do it and I had a clear action plan. Whenever the craving was triggered I started my alternative action. After a couple of weeks it became easy. Today, I only drink coffee from time to time, but not because I need it. I only drink it in relaxed moments when I can enjoy the atmosphere.&lt;/p&gt;

&lt;p&gt;Habits always work in the same way. There is a trigger, a craving and an action. Accept the trigger, accept the craving! All you have to do is replacing the action with something else that satisfies the same craving. Many of my friends have used this strategy to overcome habits like smoking, drinking and watching series on Netflix. Have you also managed to take control over your habits? I would love to hear your stories!&lt;/p&gt;</content><author><name>Robert Ecker</name></author><category term="misc" /><summary type="html">At least 40% of the things we do in our daily lives are habits. We don’t control them consciously. We just do what we are used to do. From an evolutionary perspective this is a valuable strategy. We have to spend less time on thinking and making decisions and can instead run away from a dangerous animal instantly. Today, we still have useful habits, like looking for cars before crossing a street. Many of our habits, however, are not necessary at all, some of them are even unhealthy.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://team-coder.com/images/posts/2019-07-02-how-to-overcome-a-bad-habit/title-image.jpg" /><media:content medium="image" url="https://team-coder.com/images/posts/2019-07-02-how-to-overcome-a-bad-habit/title-image.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">What Improvisational Theatre Told Me About Leadership</title><link href="https://team-coder.com/what-improvisational-theatre-told-me-about-leadership/" rel="alternate" type="text/html" title="What Improvisational Theatre Told Me About Leadership" /><published>2019-07-01T10:00:00+00:00</published><updated>2019-07-01T10:00:00+00:00</updated><id>https://team-coder.com/what-improvisational-theatre-told-me-about-leadership</id><content type="html" xml:base="https://team-coder.com/what-improvisational-theatre-told-me-about-leadership/">&lt;p&gt;Improvisational theatre is a special form of theatre where the actors have no storybook and therefore have no idea what will happen at the stage. The story is created spontaneously by the actors. There are no requisites. Every item that is needed for the story has to be imagined. When I first heard about it many years ago, this idea was so scary for me that I actually had to try it out. The lessons I have learned from it were mind-blowing. They not only shaped my character but also helped me to become a much better professional leader.&lt;/p&gt;

&lt;h2 id=&quot;the-3-principles-of-improvisational-theatre&quot;&gt;The 3 Principles of Improvisational Theatre&lt;/h2&gt;

&lt;h3 id=&quot;do-something&quot;&gt;Do Something&lt;/h3&gt;
&lt;p&gt;If nobody at the stage of an improvisational theatre offers any words or action, the whole theatre doesn’t work. And it’s the same for every organization. Employees have to express their ideas in order to improve a company. They have to be encouraged to take decisions. They have to be allowed to take risks and also to fail. What is more valuable, an employee who takes bold actions and earns $1 million for the company but also looses $500k or another one who doesn’t take any risk and makes only $100k without loosing anything?
As a leader you have to speak up, make decisions, and act. If you lead by example and encourage your employees to do the same, great things will happen!&lt;/p&gt;

&lt;h3 id=&quot;yes-and&quot;&gt;Yes, and…&lt;/h3&gt;
&lt;p&gt;Improvisational theatre can only work if all actors accept the ideas of each other. If one actor starts talking about a blue elephant and another actor refuses this idea, it won’t work. If, however, the other actor accepts the blue elephant and even adds his own ideas then the story will become even more exciting. All the actors have a positive and open mindset. Whereas most people in our Western culture tend to say “Yes, but…” (which basically means “No.”) actors in improvisational theatre always try to react with a “Yes, and…” attitude.
Banning the phrase “Yes, but…” has not only helped me in improvisational theatre. It also fundamentally shaped my leadership style. When I was younger I used to say those two words at least a million times each day (no, this is not an exaggeration)! It let to endless discussions and a lot of frustration. As soon as I started replacing “Yes, but…” with “Yes, and” something magical happened. Ideas started to grow. People started to ask me for my opinion. The solutions we found were always better than my initial ideas and everyone involved was happy about the outcome and motivated about implementing it. I wrote about a little exercise to understand the power of “Yes, and…” in &lt;a href=&quot;https://team-coder.com/how-one-word-changed-my-life&quot;&gt;this article&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;make-others-lookgood&quot;&gt;Make Others Look Good&lt;/h3&gt;
&lt;p&gt;The third reason why improvisational theatre works is that every actor tries to make the other actors look good. If someone has no idea what to say next, somebody else will chime in. Nobody would say anything that makes someone else look bad.
Unfortunately, in the real world, we often have a different picture. People want to look good and keep others small, especially in management. While this might work for some quick wins, it is usually not sustainable for individuals and definitely not for their companies. But if you as a leader make the people around you look good then you will harvest the fruits later. People will remember. You will find allies instead of enemies. If you are a manager, your employees will enjoy working for you. They will more likely give their best to make you proud and also to make you look good. It happens automatically. Maybe not instantly but in the long run you will be much more successful if you always try to make others look good.&lt;/p&gt;

&lt;h2 id=&quot;try-it-out-yourself-and-become-a-betterleader&quot;&gt;Try It Out Yourself and Become a Better Leader&lt;/h2&gt;
&lt;p&gt;If you have never tried improvisational theatre I encourage you to do it. You can find playing groups in many cities all over the world. Apply the 3 principles and you will become a better leader!&lt;/p&gt;</content><author><name>Robert Ecker</name></author><category term="leadership" /><summary type="html">Improvisational theatre is a special form of theatre where the actors have no storybook and therefore have no idea what will happen at the stage. The story is created spontaneously by the actors. There are no requisites. Every item that is needed for the story has to be imagined. When I first heard about it many years ago, this idea was so scary for me that I actually had to try it out. The lessons I have learned from it were mind-blowing. They not only shaped my character but also helped me to become a much better professional leader.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://team-coder.com/images/posts/2019-07-01-what-improvisational-theatre-told-me-about-leadership/title-image.jpg" /><media:content medium="image" url="https://team-coder.com/images/posts/2019-07-01-what-improvisational-theatre-told-me-about-leadership/title-image.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">How One Word Changed My Life</title><link href="https://team-coder.com/how-one-word-changed-my-life/" rel="alternate" type="text/html" title="How One Word Changed My Life" /><published>2019-06-28T10:00:00+00:00</published><updated>2019-06-28T10:00:00+00:00</updated><id>https://team-coder.com/how-one-word-changed-my-life</id><content type="html" xml:base="https://team-coder.com/how-one-word-changed-my-life/">&lt;p&gt;How often did you say, “yes, but” today? If you are like most people in the Western culture, then I guess you said it quite often. We like to say it because it helps us to stay in our comfort zones. When we say “Yes, but” then what we basically mean is “No.” It’s our automatic defensive reaction against potential change. No change means we can stay in our comfort zones.&lt;/p&gt;

&lt;p&gt;The problem with this defensive reaction is that it blocks not only innovation but can also be very annoying for others. There is a nice exercise that you can try out with a partner. Set yourselves a goal like planning a vacation. One of you starts with a suggestion where to go. The other person starts her reaction with “yes, but…” Then for a couple of minutes both persons must always start their replies with “yes, but.” What you can usually observe is that you will get stuck quickly and, in the end, there won’t be any satisfying idea where to go on vacation.&lt;/p&gt;

&lt;p&gt;There is a way out of this dilemma, though. A solution that is so simple that it actually works. The only thing you have to do is to replace the “Yes, but…” with “Yes, and…” The effect is amazing! Instead of the blocking reaction there will be openness that can easily make both parties feel satisfied and also produce valuable results. What comes out is not just the idea of a single person but a bigger idea that is often better and, most importantly, supported by both participants.&lt;/p&gt;

&lt;p&gt;You can try it out yourself with another simple exercise. It’s basically the same game as before. Together with your partner you try to plan a vacation again. This time, however, you don’t start your responses with “Yes, but…” but with “Yes, and…” Do it for a couple of minutes and you will be impressed about the outcome!&lt;/p&gt;

&lt;p&gt;After I first did those exercises at an improvisational theater training, I was impressed how often people actually say “Yes, but…” And I was also kind of shocked how often I said it. I felt like changing this small behavior might really make a huge impact. So, after the training I told my wife to remind me every time she catches me saying “yes, but…” It was very funny in the beginning because I said it at least a million times each day. But quickly I started anticipating those evil words before speaking them out loud and I was able to actively turn it around. Today I never say “Yes, but” anymore. This doesn’t mean that I always agree. I’m still free to say “no”. But I first think about a “Yes, and…” option and usually I find one. Opening up with this little rhetorical trick did not only create valuable opportunities in my live but also let to richer relationships both privately and professionally.&lt;/p&gt;

&lt;p&gt;I encourage you to try it yourself! Find a way to become aware of your “buts” and replace them with “ands”. As soon as you do it you will see the magic happen!&lt;/p&gt;</content><author><name>Robert Ecker</name></author><category term="misc" /><summary type="html">How often did you say, “yes, but” today? If you are like most people in the Western culture, then I guess you said it quite often. We like to say it because it helps us to stay in our comfort zones. When we say “Yes, but” then what we basically mean is “No.” It’s our automatic defensive reaction against potential change. No change means we can stay in our comfort zones.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://team-coder.com/images/posts/2019-06-28-how-one-word-changed-my-life/title-image.jpg" /><media:content medium="image" url="https://team-coder.com/images/posts/2019-06-28-how-one-word-changed-my-life/title-image.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">The Problem With High Test Coverage</title><link href="https://team-coder.com/test-coverage/" rel="alternate" type="text/html" title="The Problem With High Test Coverage" /><published>2017-11-21T10:00:00+00:00</published><updated>2017-11-21T10:00:00+00:00</updated><id>https://team-coder.com/the-problem-with-high-test-coverage</id><content type="html" xml:base="https://team-coder.com/test-coverage/">&lt;p&gt;Last week I attended Dan North’s workshop “Testing Faster”. Dan North is the originator of the term &lt;em&gt;Behavior Driven Development&lt;/em&gt; (BDD). The whole workshop was amazing but there was one thing which really surprised me. Since BDD is basically another way of Test Driven Development (TDD), I would have expected that having a high test coverage was one of Dan’s goals when writing software. But what I learned was that he actually doesn’t care about the overall test coverage. He explained that in a very convincing way. In this article I wrote down what I learned about the test coverage.&lt;/p&gt;

&lt;h2 id=&quot;the-meaning-of-test-coverage&quot;&gt;The Meaning of Test Coverage&lt;/h2&gt;
&lt;p&gt;The test coverage (also known as code coverage) is a number which tells you how much of your production code is covered by automated tests. If you don’t have any automated tests you have a test coverage of 0%. If every single line of your production code is executed by at least one automated test you have a coverage of 100%. Having a high number might feel great but even 100% doesn’t mean that there are no bugs in your code. It only tells you whether the use cases which you have written tests for are working as expected or not.&lt;/p&gt;

&lt;h2 id=&quot;the-cost-of-testing&quot;&gt;The Cost of Testing&lt;/h2&gt;
&lt;p&gt;Automated tests can save you a lot of money! They can detect bugs before they are deployed to the production system which can prevent big damage. They can also help you to design your code in a way that makes it easy to maintain and extend in the future. But writing tests is not for free. It takes time and that time could also be spent on other things. Dan calls it the opportunity costs. Don’t get me wrong on this point. I don’t say that tests are a bad idea. They are not. In fact, they can be very important. But I want to encourage you to think about what makes sense to test and what not.&lt;/p&gt;

&lt;h2 id=&quot;the-risk-plane&quot;&gt;The Risk Plane&lt;/h2&gt;
&lt;p&gt;So how do we decide what to test? Imagine a software system which looks like this:
&lt;img src=&quot;../images/posts/2017-11-21-the-problem-with-high-test-coverage/component-graph.jpg&quot; alt=&quot;graph with components and their dependencies to each other&quot; /&gt;&lt;/p&gt;

&lt;p&gt;There are many components and dependencies between them. Now let’s add a coordinate system to the graph. The more a component is on the right side of the graph the more likely it is to break. The more impact a failure in a certain component would have the higher we draw it on the vertical axis. Let’s take a look at the &lt;em&gt;risk plane&lt;/em&gt;:
&lt;img src=&quot;../images/posts/2017-11-21-the-problem-with-high-test-coverage/risk-plane.jpg&quot; alt=&quot;component graph with impact on the x-axis and likelihood on the y-axis&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now imagine that the test coverage of our system is 80%. Sounds like quite a good number. But look at the component on the top right corner. It is very likely that something will break in that component and the impact of a failure would be very high. Having that in mind, 80% is actually quite low for that part. On the other hand: The component on the lower left corner is very unlikely to break. And even if it breaks the impact will be low. So does it really make sense to spend so much time on testing this component in order to keep the test coverage high? Wouldn’t it be more useful to spend our time on writing tests for the components on the upper right corner or even to build new features? Every hour we spend on coding means money invested by our company. It is our responsibility as software developers to make reasonable decisions on how to spend that money.&lt;/p&gt;

&lt;h2 id=&quot;the-stakeholder-planes&quot;&gt;The Stakeholder Planes&lt;/h2&gt;
&lt;p&gt;Dan North says, “The goal of testing is to increase the confidence for stakeholders through evidence”. &lt;em&gt;Evidence&lt;/em&gt; can be provided by our tests. &lt;em&gt;Increasing&lt;/em&gt; doesn’t necessarily mean to reach the 100%. It requires some pragmatism to decide how much effort to spend in which situation. And who are the persons we are doing that for? It’s the &lt;em&gt;stakeholders&lt;/em&gt;! It is not enough to tell them that we are great developers and everything is going to be alright. We should give them evidence. They should know which behavior is assured by tests. Developers tend to have a blind spot. Most developers think that their code is great and works. But the stakeholders do usually not have that much confidence in the developers which is why they need the evidence.&lt;/p&gt;

&lt;p&gt;Often there are many kinds of stakeholders. They can be users, people from the security department, the customer support and many others. We can build software which is very unlikely to fail but if it is illegal we still cannot ship it. This is why we have to extend our model with another axis. We have to add planes for our stakeholders:
&lt;img src=&quot;../images/posts/2017-11-21-the-problem-with-high-test-coverage/risk-planes.jpg&quot; alt=&quot;component diagram with additional z-axis for stakeholders&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Usually, the stakeholders see the software from different perspectives. Sometimes aspects that you didn’t even think about are essential to them. Maybe it is extremely important that certain user roles must not access certain data. That would require a bigger testing effort. Talking to all kinds of your stakeholders is very helpful. Ask them what is the most important thing that you should concentrate on. On which part would they spend the most effort. If you do that with every stakeholder you will get a good idea of where to draw your components in the risk planes and how much testing effort to put on which component.&lt;/p&gt;

&lt;h2 id=&quot;the-pragmatic-way&quot;&gt;The Pragmatic Way&lt;/h2&gt;
&lt;p&gt;What Dan North made really clear to me is that the test coverage doesn’t tell much about the quality of the software. 80% can be too little for one component and it can be a waste of time for another component. When we write code we should first understand our stakeholders. What is really important? We should estimate the impact and the likelihood of potential bugs and pragmatically decide how much effort to spend on which component. We have to keep in mind that we are paid for our work. Every hour that we spend on coding costs money. It’s our responsibility as professional software developers to spend that money wisely.&lt;/p&gt;</content><author><name>Robert Ecker</name></author><category term="dev" /><summary type="html">Last week I attended Dan North’s workshop “Testing Faster”. Dan North is the originator of the term Behavior Driven Development (BDD). The whole workshop was amazing but there was one thing which really surprised me. Since BDD is basically another way of Test Driven Development (TDD), I would have expected that having a high test coverage was one of Dan’s goals when writing software. But what I learned was that he actually doesn’t care about the overall test coverage. He explained that in a very convincing way. In this article I wrote down what I learned about the test coverage.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://team-coder.com/images/posts/2017-11-21-the-problem-with-high-test-coverage/title-image.jpg" /><media:content medium="image" url="https://team-coder.com/images/posts/2017-11-21-the-problem-with-high-test-coverage/title-image.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">A Good Manager is Like a Gardener</title><link href="https://team-coder.com/good-manager/" rel="alternate" type="text/html" title="A Good Manager is Like a Gardener" /><published>2017-08-10T10:00:00+00:00</published><updated>2017-08-10T10:00:00+00:00</updated><id>https://team-coder.com/a-good-manager-is-like-a-gardener</id><content type="html" xml:base="https://team-coder.com/good-manager/">&lt;p&gt;Since I attended a Management 3.0 workshop a couple of weeks ago there is one thing that I cannot get out of my mind. It was a simple metaphor: A good manager is like a gardener. Imagine a garden full of vegetables, fruits and other plants. The gardener’s job is to create as much value as possible out of the garden. Value might be the fruits that the plants create. The more tomatoes, strawberries and potatoes grow the more value comes out of the garden.&lt;/p&gt;

&lt;p&gt;What can the gardener do to create more value? Would it be helpful to go to the tomato plant and tell it to grow faster? To create more tomatoes? Definitely not. Are there any benefits the gardener should offer the tomato plant for growing faster? I don’t think so. But what can the gardener do? He can change the environment. He can create an optimal environment for the tomato plant and all the other plants to grow and create fruits. The gardener can give them water, maybe also a little bit of fertilizer. He can rearrange the plants if he realizes that two of them have a bad influence on each other. Maybe one of them is too dominant and represses the other one. He can also protect the plants from too much direct sun light by creating some shadow areas.&lt;/p&gt;

&lt;p&gt;In my opinion, a good manager should do what a gardener would do: Not telling his people what to do but helping them to grow. Creating an environment where everybody is save and where everybody can improve, be productive and be happy.&lt;/p&gt;</content><author><name>Robert Ecker</name></author><category term="leadership" /><summary type="html">Since I attended a Management 3.0 workshop a couple of weeks ago there is one thing that I cannot get out of my mind. It was a simple metaphor: A good manager is like a gardener. Imagine a garden full of vegetables, fruits and other plants. The gardener’s job is to create as much value as possible out of the garden. Value might be the fruits that the plants create. The more tomatoes, strawberries and potatoes grow the more value comes out of the garden.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://team-coder.com/images/posts/2017-08-10-a-good-manager-is-like-a-gardener/title-image.jpg" /><media:content medium="image" url="https://team-coder.com/images/posts/2017-08-10-a-good-manager-is-like-a-gardener/title-image.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Give Up Perfection!</title><link href="https://team-coder.com/give-up-perfection/" rel="alternate" type="text/html" title="Give Up Perfection!" /><published>2017-07-04T10:00:00+00:00</published><updated>2017-07-04T10:00:00+00:00</updated><id>https://team-coder.com/give-up-perfection</id><content type="html" xml:base="https://team-coder.com/give-up-perfection/">&lt;p&gt;I wanted to write about that topic for weeks or maybe even months. But I never started. Until now! Something was holding me back from writing this article. It was almost like a fear. Maybe the fear of not being good enough. I was not sure what exactly to write down and how to write it. I didn’t even come up with a good title for that article and without a great title I didn’t want to start writing at all. The title has to be short and crispy. It has to catch the reader’s attention! It has to seem relevant to search engines. It has to be as perfect as the whole content of the article.&lt;/p&gt;

&lt;p&gt;This desire for perfection is the reason why I have never published this article. It is the reason why instead of an interesting blog post, that could have inspired at least a few people, I have released nothing. But today all of a sudden it became crystal clear to me! There is no perfection. Life is so complex, there are so many possible solutions for every problem. What I like somebody else might hate and what I don’t like could be a life-changing inspiration for somebody else.&lt;/p&gt;

&lt;p&gt;I don’t want to strive for perfection anymore. I want to actually get stuff done. I want to sing out loud even if I’m not a perfect singer. I want to release that feature to the customers even if it is not perfect, yet. I want to tell my opinion even if not everybody at the table will agree. And I finally want to publish this blog post even if it is not perfect.&lt;/p&gt;

&lt;p&gt;I didn’t want to release the last article I wrote without letting a native English speaking friend of me having a look on it. I was afraid that there might be a grammar mistake in my text. That would be fatal because it would make the whole blog post imperfect! People might think that I’m not a professional! Bullshit! Maybe some people would realize that I’m not a native speaker of the English language but does that make me any less reliable on the topic I write about? I don’t think so! In fact, there are professionals who’s native language is obviously not English and I still look up to them and admire them for being so professional.&lt;/p&gt;

&lt;p&gt;I guess there are certain areas where perfection would indeed be a desirable goal. Like in nuclear power stations, in space missions or in certain medical fields. But for writing a blog post? Come on! Seriously, the important thing in a blog post is the basic idea behind it. Not that every word is perfect. And I think that this applies to most things in life. The ideas are important. The messages you want to tell. The feelings that you want to share and the actual things that are important to you.&lt;/p&gt;

&lt;p&gt;Perfection is a nice direction but it’s not a goal that must be reached. It can motivate you to get better but you should never let you pull down by the unachievable illusion that everything must be perfect.&lt;/p&gt;

&lt;p&gt;Someone once told me that the perfect blog post has about 1500 words. That would mean that I have about 1000 words to go. Guess what? This will be the last paragraph and it feels great! I will stop here and just call this article „Give Up Perfection!“. Even if this article is not perfect I hope that I could make my message clear. There is no perfection and even if there was something like that we usually wouldn’t need it. Instead we should concentrate on the really important stuff and just do it!&lt;/p&gt;</content><author><name>Robert Ecker</name></author><category term="misc" /><summary type="html">I wanted to write about that topic for weeks or maybe even months. But I never started. Until now! Something was holding me back from writing this article. It was almost like a fear. Maybe the fear of not being good enough. I was not sure what exactly to write down and how to write it. I didn’t even come up with a good title for that article and without a great title I didn’t want to start writing at all. The title has to be short and crispy. It has to catch the reader’s attention! It has to seem relevant to search engines. It has to be as perfect as the whole content of the article.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://team-coder.com/images/posts/2017-07-04-give-up-perfection/title-image.jpg" /><media:content medium="image" url="https://team-coder.com/images/posts/2017-07-04-give-up-perfection/title-image.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">How to Build a Twitter Bot with Python</title><link href="https://team-coder.com/twitter-bot-with-python/" rel="alternate" type="text/html" title="How to Build a Twitter Bot with Python" /><published>2017-05-24T10:00:00+00:00</published><updated>2017-05-24T10:00:00+00:00</updated><id>https://team-coder.com/how-to-build-a-twitter-bot-with-python</id><content type="html" xml:base="https://team-coder.com/twitter-bot-with-python/">&lt;p&gt;I have built a &lt;a href=&quot;https://twitter.com/socrabot_&quot;&gt;Twitter&lt;/a&gt; bot which searches Twitter for tweets about software craftsmanship and retweets them if they are interesting. In this tutorial I will tell you how you can easily build your own Twitter bot with Python and run it on a Raspberry Pi or any other Unix system!&lt;/p&gt;

&lt;h2 id=&quot;preparation&quot;&gt;Preparation&lt;/h2&gt;

&lt;h3 id=&quot;creating-an-account-for-the-twitter-bot&quot;&gt;Creating an Account for the Twitter Bot&lt;/h3&gt;
&lt;p&gt;If you want to have a bot user on Twitter the first thing you have to do is &lt;a href=&quot;https://twitter.com/signup&quot;&gt;creating an account&lt;/a&gt; for it. When you are logged in with your new bot account you have to set up a new app on the &lt;a href=&quot;https://apps.twitter.com/app/new&quot;&gt;Twitter Application Management website&lt;/a&gt;. Your bot will use this new app to communicate with the Twitter API later. You don’t need to provide a callback URL. After creating the app on Twitter you can leave the website and continue with the next step.&lt;/p&gt;

&lt;h3 id=&quot;installing-the-dependencies&quot;&gt;Installing the Dependencies&lt;/h3&gt;
&lt;p&gt;For this tutorial I assume that Python is already installed on your machine. There is only one more thing you have to prepare: Installing a library that makes it easy to connect to the Twitter API. There are multiple Python libraries for doing that. For my Twitter bot I use a very lightweight one called &lt;a href=&quot;https://github.com/ryanmcgrath/twython&quot;&gt;Twython&lt;/a&gt;. You can install it with your favorite command line tool with the following command:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pip3 &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;twython
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;setting-up-the-git-repository&quot;&gt;Setting up the Git Repository&lt;/h3&gt;

&lt;p&gt;Having your code in a Git repository is always a good idea. For the bot that you will build it is particularly important. Create a new Git repository for it and push it to a platform like &lt;a href=&quot;https://github.com/&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;tweeting-hello-world-with-python&quot;&gt;Tweeting Hello World with Python&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;../images/posts/2017-05-24-how-to-build-a-twitter-bot-with-python/twitter.png&quot; alt=&quot;twitter icon&quot; class=&quot;img-align-left&quot; /&gt;
Now that all the preparation is done the fun part can begin: Writing the code for your Twitter bot! First create the Python file which will contain the source code. Call it &lt;em&gt;tweetbot.py&lt;/em&gt;. Then use your favorite Python editor (I recommend PyCharm) to write the following code into your Python file:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;twython&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Twython&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;API_KEY&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'YOUR TWITTER API KEY'&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;API_SECRET&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'YOUR TWITTER API SECRET'&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ACCESS_TOKEN&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'YOUR TWITTER ACCESS TOKEN'&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ACCESS_TOKEN_SECRET&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'YOUR TWITTER ACCESS TOKEN SECRET'&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;twitter_client&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Twython&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;API_KEY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;API_SECRET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ACCESS_TOKEN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ACCESS_TOKEN_SECRET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;twitter_client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;update_status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Hello World!'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Go back to your application page on the Twitter website. There should be a tab called “Keys and Access Tokens”. On that page you will find the values for your &lt;em&gt;API key&lt;/em&gt;, &lt;em&gt;API secret&lt;/em&gt;, &lt;em&gt;access token&lt;/em&gt; and &lt;em&gt;access token secret&lt;/em&gt;. Use them in your Python script! The Twitter API needs them to identify your bot.&lt;/p&gt;

&lt;p&gt;If you now run the script you will see the new tweet on the timeline of your bot user :)&lt;/p&gt;

&lt;p&gt;Take your time to implement your own features for the bot! There are so many things that a Twitter bot could do!&lt;/p&gt;

&lt;h2 id=&quot;setting-up-a-raspberry-pi-for-the-twitter-bot&quot;&gt;Setting up a Raspberry Pi for the Twitter Bot&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;../images/posts/2017-05-24-how-to-build-a-twitter-bot-with-python/raspberrypi3.jpg&quot; alt=&quot;Raspberry Pi&quot; class=&quot;img-align-right&quot; /&gt;
I assume that you have written and run your Python script on your working computer. But this computer is probably not always on. Since your bot should not stop running when you close your notebook you need another place where you can deploy it! In this tutorial I will show you how I deploy my Twitter bot on a &lt;a href=&quot;https://www.raspberrypi.org/products/raspberry-pi-3-model-b/&quot;&gt;Raspberry Pi&lt;/a&gt;. Since the Raspberry Pi doesn’t need much energy and makes no noice I can run it 24/7 right on my desk!&lt;/p&gt;

&lt;p&gt;I have a special Linux distribution, called Raspbian, running on my Raspberry Pi. The steps I will show you usually also work on most of the other available Linux distributions. Basically, setting up the bot on a Linux server or in a Docker environment somewhere in the cloud is not so different from setting it up on a Raspberry Pi.&lt;/p&gt;

&lt;p&gt;Make sure that Python is installed on the device on which you want to run your bot. On Raspbian Python is already preinstalled. Also install Twython by running the same command like you did on your local machine before:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pip3 &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;twython
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In order to check out your Python script on the Raspberry Pi (or any other Unix-based server) the first thing you have to do on that device is &lt;a href=&quot;https://help.github.com/articles/checking-for-existing-ssh-keys/&quot;&gt;getting your public SSH key&lt;/a&gt;. If you don’t find it &lt;a href=&quot;https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/&quot;&gt;create a new one&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now go to the settings of your Twitter bot’s repository on GitHub (or wherever you host it) and register your public SSH key as a deploy key for that repository. You don’t need write access for that key.&lt;/p&gt;

&lt;p&gt;After adding the SSH key as a deploy key create a new directory at &lt;em&gt;~/Python/TweetBot&lt;/em&gt; on the Raspberry Pi. Navigate to that directory and check out the Git repository using the &lt;a href=&quot;https://help.github.com/articles/cloning-a-repository/&quot;&gt;git clone command&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;the-run-script&quot;&gt;The Run Script&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;../images/posts/2017-05-24-how-to-build-a-twitter-bot-with-python/terminal.jpg&quot; alt=&quot;Terminal icon&quot; class=&quot;img-align-left&quot; /&gt;
Now that everything is set up on the Raspberry Pi you will create a small Shell script. It will pull the latest version of the Twitter bot from your Git repository and run it.&lt;/p&gt;

&lt;p&gt;One directory above your checked-out repository (at &lt;em&gt;~/Python/TweetBot&lt;/em&gt;) create a new bash script and call it &lt;em&gt;run.sh&lt;/em&gt;. Write the following bash code into the file:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# go to the working directory (replace &quot;tweetbot&quot; with your repo name)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ~/Python/TweetBot/tweetbot

&lt;span class=&quot;c&quot;&gt;# get the latest version from the remote Git repository&lt;/span&gt;
git reset &lt;span class=&quot;nt&quot;&gt;--hard&lt;/span&gt;
git pull origin

&lt;span class=&quot;c&quot;&gt;# run the bot&lt;/span&gt;
python3 ./tweetbot.py
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;From now on when you want to run the bot on the Raspberry Pi you don’t run the Python file but the shell script. That ensures that you always run the latest version of the bot. You can modify the code on your working computer. As soon as you push it to the remote Git repository it will be executed the next time you run the shell script on the Raspberry Pi.&lt;/p&gt;

&lt;h2 id=&quot;continuity-with-cron-jobs&quot;&gt;Continuity with Cron Jobs&lt;/h2&gt;

&lt;p&gt;There is one last thing that you have to do if you want to have a real bot. You have to make the bot run continuously. Of course you could add a while loop to your script that lets it run forever. But a much more effective way is to start the script every 5 minutes. Let’s use a cron job for that!&lt;/p&gt;

&lt;p&gt;A cron job is a task that is executed again and again with a predefined time schedule. In the Unix world those kind of jobs often call shell scripts which do one special thing, like creating a backup or measuring and logging data.&lt;/p&gt;

&lt;p&gt;For setting up the cron job I used the following command to create a new file called &lt;em&gt;tweetbot&lt;/em&gt; at &lt;em&gt;/etc/cron.d&lt;/em&gt;.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo touch&lt;/span&gt; /etc/cron.d/tweetbot
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here is what I wrote into the file:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;*/5 * * * * pi /home/pi/Python/TweetBot/run.sh

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The system’s cron service will automatically detected the new cron file. It calls my script every five minutes. “pi” is the name of the user on the Unix system. Notice that there is a new line at the end of the file, which is important!&lt;/p&gt;

&lt;p&gt;After saving the file make it executable by typing the following command:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;chmod&lt;/span&gt; +x /etc/cron.d/tweetbot
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;One great benefit of cron jobs is that even if the code would crash sometimes it will fail once but restart after 5 minutes. When you now push code to the master branch of your Git repository it will be executed automatically within the next five minutes! This is already like the simplest version of a build server which is so cool!&lt;/p&gt;

&lt;h2 id=&quot;your-own-twitter-bot&quot;&gt;Your Own Twitter Bot&lt;/h2&gt;

&lt;p&gt;I hope with this article I could help you to get started. As soon as you have your infrastructure running you can build whatever you want. The possibilities are endless! I’m curious about your ideas for your own bot! Please tell me about it on Twitter!&lt;/p&gt;

&lt;p&gt;Ahh and don’t forget to follow &lt;a href=&quot;https://twitter.com/socrabot_&quot;&gt;my Twitter bot&lt;/a&gt; if you want to read the most interesting tweets about software craftsmanship!&lt;/p&gt;</content><author><name>Robert Ecker</name></author><category term="dev" /><summary type="html">I have built a Twitter bot which searches Twitter for tweets about software craftsmanship and retweets them if they are interesting. In this tutorial I will tell you how you can easily build your own Twitter bot with Python and run it on a Raspberry Pi or any other Unix system!</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://team-coder.com/images/posts/2017-05-24-how-to-build-a-twitter-bot-with-python/title-image.jpg" /><media:content medium="image" url="https://team-coder.com/images/posts/2017-05-24-how-to-build-a-twitter-bot-with-python/title-image.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">The Power of Fluid Teams</title><link href="https://team-coder.com/fluid-teams/" rel="alternate" type="text/html" title="The Power of Fluid Teams" /><published>2017-02-23T10:00:00+00:00</published><updated>2017-02-23T10:00:00+00:00</updated><id>https://team-coder.com/the-power-of-fluid-teams</id><content type="html" xml:base="https://team-coder.com/fluid-teams/">&lt;p&gt;Do you know this exciting feeling when you work on your own side project? The incredible motivation when you work on it and this magical feeling when you publish it! What is the difference between those kind of projects and the projects you are working on at work? I think the most relevant difference is that most people do what they are told to do at work instead of what they would love to do.&lt;/p&gt;

&lt;p&gt;Imagine a working environment where nobody tells you what to work on! How great would it be if you could work on what you really believe in! If you could talk to colleagues about your ideas and everybody who truly believes in it would join you. Teams would be fluid! They would form spontaneously and exist until the work is done. Then you could join another team that convinces you.&lt;/p&gt;

&lt;p&gt;What do you think how productive this would be? I think the potential would be amazing! Features would be developed so much quicker and with so much love!&lt;/p&gt;

&lt;p&gt;The question is what would happen with the tasks that nobody wants to do? Maybe, if nobody wants them done, it is not so important. If something doesn’t excite anybody from the company, maybe it also doesn’t excite most of the users.&lt;/p&gt;

&lt;p&gt;I would like to try it out but it’s hard to convince a company to give up all the control and hope that everything will be fine. I read that &lt;a href=&quot;http://www.valvesoftware.com/&quot;&gt;Valve&lt;/a&gt;, a software company from the United States, did it very successfully. Have you any experiences with experiments like that? I would love to hear about it!&lt;/p&gt;</content><author><name>Robert Ecker</name></author><category term="misc" /><summary type="html">Do you know this exciting feeling when you work on your own side project? The incredible motivation when you work on it and this magical feeling when you publish it! What is the difference between those kind of projects and the projects you are working on at work? I think the most relevant difference is that most people do what they are told to do at work instead of what they would love to do.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://team-coder.com/images/posts/2017-02-23-the-power-of-fluid-teams/title-image.jpg" /><media:content medium="image" url="https://team-coder.com/images/posts/2017-02-23-the-power-of-fluid-teams/title-image.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>