<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
  xmlns:atom="//www.w3.org/2005/Atom">
  <channel>
    <title>Piece of code</title>
    <description>This is blog is my two cents to the world. I have years of experience in web development with several languages. My passion is to help people to write better code more easily and  let them focus to writing code by automating all the other things.
</description>
    <link>https://www.pieceofcode.blog/</link>
    <atom:link href="https://www.pieceofcode.blog/feed.xml" rel="self" type="application/rss+xml" />
    <pubDate>Wed, 26 Jul 2023 20:21:56 +0000</pubDate>
    <lastBuildDate>Wed, 26 Jul 2023 20:21:56 +0000</lastBuildDate>
    <generator>Jekyll v4.3.2</generator>
    
      
    <item>
      <title>Cyberdeck part 2: The screen</title>
      <description>&lt;p&gt;Check out the other posts about the build:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;/2021/10/cyberdeck-part-1/&quot;&gt;Part 1: the beginning&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Part 2: the screen&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;or the new &lt;a href=&quot;/cyberdeck/&quot;&gt;Cyberdeck&lt;/a&gt;-page to make following easier.&lt;/p&gt;

&lt;p&gt;Continuing my cyberdeck build, I decided to mount the screen first as first part. Mainly because it’s the largest part after the case and I’m afraid to break it before attaching it.&lt;/p&gt;

&lt;p&gt;At first, I modeled brackets to top and bottom.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/cyberdeck/part_2_screen_bracket.jpg&quot; alt=&quot;Bottom bracket in place&quot; /&gt;&lt;/p&gt;

&lt;p&gt;They seemed to work well enough in first attempt.
&lt;img src=&quot;/images/cyberdeck/part_2_test_fitting_screen.jpg&quot; alt=&quot;Test fitting the screen&quot; /&gt;&lt;/p&gt;

&lt;p&gt;However, at this point I realized that I will need some side brackets to prevent screen moving sideways.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/cyberdeck/part_2_side_brackets.jpg&quot; alt=&quot;First draft&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I designed and printed brackets, but I made a mistake. I forgot that my design is not 100% accurate compared to the actual build. The rails I glued on the lid (and the bottom) are not in exact places where I designed them. Luckily, the left bracket was actually a perfect fit for the right side, so I only needed to adjust one bracket.&lt;/p&gt;

&lt;p&gt;The screen’s driver board had a control board which I wanted to use. A mount for it was relatively easy and quick to design and print.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/cyberdeck/part_2_control_board_mounted.jpg&quot; alt=&quot;Mount of screen controller&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And this is how I mounted the driver board.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/cyberdeck/part_2_behind_the_screen.jpeg&quot; alt=&quot;Behind the secreen&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;speakers&quot;&gt;Speakers&lt;/h1&gt;

&lt;p&gt;While testing the screen that it is working and control board is easy to access, I realized something. I’m missing sound! So a quick check to stores nearby and managed to find small stereo speakers for a bit less than 6 euros.&lt;/p&gt;

&lt;p&gt;Speakers’ own cases were too big for my use so I had to dissassemble them&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/cyberdeck/part_2_speakers.jpg&quot; alt=&quot;Speakers without their case.&quot; /&gt;
Speakers without their case.&lt;/p&gt;

&lt;p&gt;To attach them, mounts were needed. It took me couple of tries and test prints, but this is what I was happy with:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/cyberdeck/part_2_speaker_mount.jpg&quot; alt=&quot;Speaker mount&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And then it was time to mount the speaker&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/cyberdeck/part_2_speaker_mounted.jpg&quot; alt=&quot;Speaker in mount&quot; /&gt;&lt;/p&gt;

&lt;p&gt;As you can see from the image above, there is not too much of space, but do we really need that? I’d say no!&lt;/p&gt;

&lt;p&gt;And here is the final result of mounted speakers and control board:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/cyberdeck/part_2_final.jpg&quot; alt=&quot;Speakers mounted&quot; /&gt;&lt;/p&gt;
</description>
      <pubDate>Wed, 01 Mar 2023 06:00:00 +0000</pubDate>
      <link>https://www.pieceofcode.blog/2023/03/cyberdeck-part-2/</link>
      <guid isPermaLink="true">https://www.pieceofcode.blog/2023/03/cyberdeck-part-2/</guid>
          
          
      <category>poc</category>
          
      <category>cyberdeck</category>
          
      <category>communication</category>
          
    </item>
      
    
      
    <item>
      <title>Cyberdeck part 1</title>
      <description>&lt;p&gt;Edit 2023-03-DD: Added build log&lt;/p&gt;
&lt;h3&gt;Cyberdeck build log&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Part 1: the beginning&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;/2023/03/cyberdeck-part-2/&quot;&gt;Part 2: the screen&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;[Edit ends.]&lt;/p&gt;

&lt;p&gt;It’s been a while since the last post, but I though I’ll start to share some kind of build log from one of my current project: Cyberdeck.&lt;/p&gt;

&lt;p&gt;Ever since I saw that my friend &lt;a href=&quot;https://twitter.com/HJuva&quot;&gt;Heikki&lt;/a&gt; showed me his cyberdeck in the late summer of 2020, I immediately wanted to build one too. Not that I had any real world use for it, but it sounded really nice project where I can learn 3D design.&lt;/p&gt;

&lt;h2 id=&quot;what-is-cyberdeck&quot;&gt;What is cyberdeck?&lt;/h2&gt;

&lt;p&gt;Cyberdecks are basically portable, chunky computers that takes inspiration from cyberpunk. Check these examples from &lt;a href=&quot;https://www.youtube.com/watch?v=guGffGw3uDg&quot;&gt;Zack Freeman&lt;/a&gt; and &lt;a href=&quot;https://www.youtube.com/watch?v=H7X1Ed2UBz4&quot;&gt;Jay Doscher&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;plan&quot;&gt;Plan&lt;/h2&gt;

&lt;p&gt;The plan is to have a mobile station for electronics work. Therefore I went with the following component list:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Raspberry Pi 4 (4GB)&lt;/li&gt;
  &lt;li&gt;Breadboard&lt;/li&gt;
  &lt;li&gt;GPIO extender&lt;/li&gt;
  &lt;li&gt;12,5” 1080p screen&lt;/li&gt;
  &lt;li&gt;SSD for storage&lt;/li&gt;
  &lt;li&gt;Mechanical keyboard&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Wireless mouse&lt;/p&gt;

    &lt;p&gt;&lt;img src=&quot;/images/cyberdeck/parts.jpg&quot; alt=&quot;Few parts of the project&quot; /&gt;
&lt;em&gt;Few parts of the project&lt;/em&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;parts&quot;&gt;Parts&lt;/h2&gt;

&lt;p&gt;This table will contain list of used materials/parts as those are taken in use in the project. It will be updated during the project.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Part&lt;/th&gt;
      &lt;th&gt;Amount&lt;/th&gt;
      &lt;th&gt;For what&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;PLA&lt;/td&gt;
      &lt;td&gt;-&lt;/td&gt;
      &lt;td&gt;3D printer parts needs to be printed&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Case, 34x29x15cm&lt;/td&gt;
      &lt;td&gt;1pc&lt;/td&gt;
      &lt;td&gt;To hold all the tech and parts&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Heat insert M3 6mm long&lt;/td&gt;
      &lt;td&gt;~48pcs&lt;/td&gt;
      &lt;td&gt;For bottom rails’ holes and speaker mounts&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Heat insert M3 3mm long&lt;/td&gt;
      &lt;td&gt;~40pcs&lt;/td&gt;
      &lt;td&gt;For lid rails’ holes&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Screw M3 6mm long&lt;/td&gt;
      &lt;td&gt;~31pcs&lt;/td&gt;
      &lt;td&gt;For attaching components in part 2&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Nut M3&lt;/td&gt;
      &lt;td&gt;~3pcs&lt;/td&gt;
      &lt;td&gt;For attaching control board to it’s mount&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;12.5” FHD IPS&lt;/td&gt;
      &lt;td&gt;1pc&lt;/td&gt;
      &lt;td&gt;Screen that was meant for Thinkpad X240 / X250/X260/X270&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Driver board kit&lt;/td&gt;
      &lt;td&gt;1pc&lt;/td&gt;
      &lt;td&gt;For controlling the screen and getting HDMI out&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2.0 speakers&lt;/td&gt;
      &lt;td&gt;1pc&lt;/td&gt;
      &lt;td&gt;The cheapest speakers I found from the store&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Note: The amounts for heat inserts, nuts and screws are estimates at it’s best, can’t remember all used ones. I might do a proper counting once the whole project is more or less done.&lt;/p&gt;

&lt;h2 id=&quot;case&quot;&gt;Case&lt;/h2&gt;

&lt;p&gt;I went with Clas Ohlson’s &lt;a href=&quot;https://www.clasohlson.com/fi/p/41-1729&quot;&gt;34x29x15cm case&lt;/a&gt;. At first I was going to make the project to a smaller case that I had a spare one, but after calculations it proved to be too small for 12,5” Thinkpad screen. Earlier plans included 10” non-FullHD screen.&lt;/p&gt;

&lt;h2 id=&quot;design&quot;&gt;Design&lt;/h2&gt;

&lt;p&gt;The first step was to create a close copy of the case in Fusion360. I made only a quick mockup of the case, just to help with visualizing the project and plans.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/cyberdeck/design.png&quot; alt=&quot;Design&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The first problem was how to attach all the interior tech inside the case. I wanted something modular so I can later add, change or remove some parts. I came up with an idea of adding rails/bars in the lid and bottom of the case. Rails have holes for heat inserts, so I can attach my modules with screws.&lt;/p&gt;

&lt;p&gt;Here is a pic of the rails and bars before gluing
&lt;img src=&quot;/images/cyberdeck/before_glue.jpg&quot; alt=&quot;Before gluing&quot; /&gt;
&lt;em&gt;Vertical bars between the rails are only to help align horizontal rails straight when gluing them.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I glued the rails in one take with instant glue. I wasn’t happy with the result, since using instant glue, you have to be quite fast to get everything in place before glue dries. I decided to change tactics with bottom case’s rails.
&lt;img src=&quot;/images/cyberdeck/bottom_with_tape.jpg&quot; alt=&quot;Bottom with tape&quot; /&gt;&lt;/p&gt;

&lt;p&gt;By using the tape, I didn’t have such a hurry to get all rails glued and then placing them exactly where they should go.&lt;/p&gt;

&lt;p&gt;After glue was dryed long enough, I removed the vertical bars from the lid. And in the end, both ways (all in one go and one rail at the time) worked good enough-
&lt;img src=&quot;/images/cyberdeck/rails_done.jpg&quot; alt=&quot;Done!&quot; /&gt;
&lt;em&gt;That one black thing in the second bar from right is a pice of a glove that I manage to glue in to the rail..&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now starts the hard part: I need to start designing and thinking how I place all the parts in there.&lt;/p&gt;

&lt;p&gt;Shoutout to another &lt;a href=&quot;https://twitter.com/heikkistark&quot;&gt;Heikki&lt;/a&gt; for proofreading the post and giving some tips!&lt;/p&gt;
</description>
      <pubDate>Mon, 11 Oct 2021 06:00:00 +0000</pubDate>
      <link>https://www.pieceofcode.blog/2021/10/cyberdeck-part-1/</link>
      <guid isPermaLink="true">https://www.pieceofcode.blog/2021/10/cyberdeck-part-1/</guid>
          
          
      <category>poc</category>
          
      <category>cyberdeck</category>
          
      <category>communication</category>
          
    </item>
      
    
      
    <item>
      <title>Assume positive intention</title>
      <description>&lt;p&gt;In the past few years I’ve started to work mostly remotely. It’s been great journey so far and I’ve learned a lot. Mostly about myself. I’m going to share my learnings as separate posts every now and then. This first post is about assuming positive intentions.&lt;/p&gt;

&lt;h2 id=&quot;assume-positive-intention&quot;&gt;Assume positive intention&lt;/h2&gt;

&lt;p&gt;When you work remote, your communication is mostly text based, chat, mail or issue board. Problem with text is that it does not have expressions. So it’s quite easy to misunderstand someone, especially when compared to talking with someone face-to-face. More often I feel that if I don’t put smiley or emoji on my messages, I’ll be misunderstood. And on some cases when I read my own messages, they “sound” sarcastic with emojis in my mind. And I hate that. I like smileys and emojis, they are great for expressing feelings, but when you feel that you need to put them on most messages, there might be bigger issues.&lt;/p&gt;

&lt;p&gt;Of course there’s more variables in this. For example, if you’ve met the people you’re talking with before, you probably understand their intention better. Let’s have an example: you’re new in the company and doing a code review. Then you spot something that you don’t understand. You might comment something like ”Why you did it like this?” without thinking it further. In your mind, you mean to ”say” that in neutral, a bit confused tone. After reading it, you think that’s reasonable question so you leave it there.&lt;/p&gt;

&lt;p&gt;Then think about that you’ve written a piece of code that you’re really, really proud of. It’s perhaps the best code you ever wrote. Then you submit a pull request. After few hours someone asks the same question ”Why you did it like this?”. How do you read it? I bet that in most cases reader will go in to defensive mode. I know I took most comments in my first pull requests like that. And it’s okay to feel like that. But before you answer and defend your solution, take a step back and think:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;You both work on same project and probably want it to succeed&lt;/li&gt;
  &lt;li&gt;It’s really easy to do stupid errors when you work on some problem for a long time ( I do this all the time)&lt;/li&gt;
  &lt;li&gt;Perhaps you’ve actually made complex code that is hard to read, it can be (and in most cases it is) you, that come back to own code after a period and have to spend time to understand it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you work at the office and you get the comments like that, it’s easy to just go to have chat with the reviewer and ask what did they mean and get it solved. But on remotely, you cannot do that. It took me a while to not get the comments as personal attack and to try to understand the feedback of the comments.&lt;/p&gt;

&lt;p&gt;So even if it is hard to think it as a positive comment.&lt;/p&gt;
</description>
      <pubDate>Sun, 02 Dec 2018 06:00:00 +0000</pubDate>
      <link>https://www.pieceofcode.blog/2018/12/assume-positive-intention/</link>
      <guid isPermaLink="true">https://www.pieceofcode.blog/2018/12/assume-positive-intention/</guid>
          
          
      <category>poc</category>
          
      <category>remote</category>
          
      <category>communication</category>
          
    </item>
      
    
      
    <item>
      <title>Sometimes it&apos;s ok to take shortcuts</title>
      <description>&lt;p&gt;I’m kind of a developer who likes to do futureproof code and sometimes question decisions that impact on future requirements. Fore example, if there’s a service where a user has a profile, why won’t we separate those into two models so in future if/when we want to have multiple profiles per user, we just need to change “has_one” relation to “has_many”. It also means proper test coverage and code split in meaningful classes. In short: no shortcuts.&lt;/p&gt;

&lt;p&gt;However, there are times when shortcuts are fine and are required. One of those cases is when your doing POCs (proof of concepts). I encountered this recently and would like to share some of my findings.&lt;/p&gt;

&lt;h2 id=&quot;story-time&quot;&gt;Story time&lt;/h2&gt;

&lt;p&gt;Project X was an app that’s integrated to one external service A. Up to this date, that one service had been enough for the app as a source of the data. So some architectural decisions had been made of that. Now, with this POC, I had to jump into that project and integrate a second service B (which I had integrated in another project already, so I knew how to do it).&lt;/p&gt;

&lt;p&gt;We held a meeting with a few key individuals from the project X team and in the end we came up with a good plan. Our goal was to get a list of items from the service and show them in the mobile app. So let’s start.&lt;/p&gt;

&lt;p&gt;The external service is using oauth2 and has expiring tokens. Existing system did not support that kind of behaviour, so changes needed to be made. New API endpoint(s) for the mobile client -&amp;gt; changes needed. API tokens needs to be stored somewhere -&amp;gt; changes needed. New items will need to be updated at some point -&amp;gt; changes needed. So at least these three changes will need to be made:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;New endpoints&lt;/li&gt;
  &lt;li&gt;Store the tokens somewhere&lt;/li&gt;
  &lt;li&gt;Add support to refresh data from this source, as current architecture does not support it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Last two items are quite big ones (in the terms of coding) as those possibilities with the existing architecture have not been though in the first place. Next step is to think about some estimations and tasks that are required within the POC. The goal of our POC was: &lt;strong&gt;Show items in the mobile app&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Okay, we definetely need the endpoints for supporting oauth2 flow. At this point, it’s easy to create some hardcoded route, but if we use parameter to define the service to be used, we can take it in as a value and thus build the system to get settings related to that service in the background -&amp;gt; new services can be connected pretty much by just adding new settings. It will make future changes much smaller.&lt;/p&gt;

&lt;p&gt;Then we need to store the tokens when requesting the callback handler. We pause and realize that to meet the POC’s requirements, we don’t need to actually store the tokens. Just fetch the tokens by the authorization code and get the items directly in the callback handler. Win!&lt;/p&gt;

&lt;p&gt;Now that we have the data, we need to convert it to fit into the existing item’s structure. This means there will be no changes in existing architecture because of that. Can’t be counted as a win as it’s what one should do and would have been done anyway.&lt;/p&gt;

&lt;p&gt;Then the data refresh. Why do we need that? Well, to meet the POC’s requirements we don’t. So lets forget that. Another big win!&lt;/p&gt;

&lt;p&gt;In the end almost all of these changes were done by additions, just some minor changes was need in the existing architecture.&lt;/p&gt;

&lt;p&gt;During the final moments of the POC we received this comment, “But I can’t take that code to the production!”&lt;/p&gt;

&lt;p&gt;Yep, you can’t. But that wasn’t the intention at the beginning. Idea was to have a POC. It wasn’t meant to be shipped to production right after. For me POC’s are (and in generally they should be) the quickest and easiest way to test thing X. Take all the shortcuts you can and focus only on the requirements when planning. Also the scope and requirements for POC should be quite simple. If you want some data from external service, it’s probably enough to get just smallest subset of it, not all that you would use in the production code.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Shout out to &lt;a href=&quot;https://twitter.com/tweetmoorechris&quot;&gt;Chris Moore&lt;/a&gt; for proofreading and helping with the post&lt;/em&gt;&lt;/p&gt;
</description>
      <pubDate>Fri, 27 Apr 2018 06:00:00 +0000</pubDate>
      <link>https://www.pieceofcode.blog/2018/04/its-ok-to-take-shortcuts/</link>
      <guid isPermaLink="true">https://www.pieceofcode.blog/2018/04/its-ok-to-take-shortcuts/</guid>
          
          
      <category>poc</category>
          
      <category>architecture</category>
          
    </item>
      
    
      
    <item>
      <title>TDD as a design tool</title>
      <description>&lt;p&gt;&lt;em&gt;I will use Ruby in this example, and assume that the feature will be built inside rails. Also, this concentrates more on the process and leaves the actual implementation out&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;One of the reasons why I keep using TDD is that it helps my thinking process when I write code. It makes me think the feature before implenting it making the implementation part really straightforward.&lt;/p&gt;

&lt;h2 id=&quot;feature-spec&quot;&gt;Feature spec&lt;/h2&gt;
&lt;p&gt;Let’s say I need to create a feature where user can send a message to other user. I’d start with following feature-spec&lt;/p&gt;
&lt;div class=&quot;language-ruby 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;n&quot;&gt;feature&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;User can send a message&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;scenario&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;User logs in and sends a message to another user&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;FactoryGirl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;create&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:user&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;receiver&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;FactoryGirl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;create&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:user&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;sign_user_in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;password&quot;&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;click_link&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Messages&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;click_link&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Send a new message&quot;&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;fill_in&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;To&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;with: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;receiver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fill_in&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Message&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;with: &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Hello world!&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;click_button&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Send&quot;&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;have_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Message was sent successfully&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;receiver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;messages&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:receiver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;eq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;receiver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is the first draft of the flow I’d like that user has to go through for sending a message. Most probably it will need changes in the future, but the main point (for me) is try to make sending message as simple as possible. Also note that we’re testing only that user gets A) notification about successful sending and B) there was one message that were sent to correct receiver.&lt;/p&gt;

&lt;p&gt;At this point I start to run specs and write production code until I need to create a new class (e.g. controller).&lt;/p&gt;

&lt;h2 id=&quot;controller&quot;&gt;Controller&lt;/h2&gt;
&lt;p&gt;Next spec file will be for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MessagesController&lt;/code&gt; (as we don’t have controller named like that yet).&lt;/p&gt;

&lt;div class=&quot;language-ruby 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;no&quot;&gt;RSpec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;MessagesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;type: :controller&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;#create&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;receiver exists&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;message is sent with username&quot;&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;message is sent with userid&quot;&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;message is sent with email&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;receiver does not exist&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;message is not sent&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So before I write any line of tests, I try to write down the “features” of the class I’m testing. As this is a new feature and we’re missing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Message&lt;/code&gt; object, we’ll need to hop on to write spec file for that&lt;/p&gt;

&lt;p&gt;Note: In some cases, there’s no point for creating specs for controller (for example if action is just listing items, that can be tested in feature spec just fine). But in this example, we’re not sure how we’re going to implement the feature, so I’d follow the style and create the spec file (we can always refactor specs and remove them if they become obsolete).&lt;/p&gt;

&lt;h2 id=&quot;model&quot;&gt;Model&lt;/h2&gt;

&lt;p&gt;On the model, I follow same process as with controller (and other classes), drafting out what the class should do.&lt;/p&gt;

&lt;div class=&quot;language-ruby 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;no&quot;&gt;RSpec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;type: :model&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;#send_message&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;receiver exists&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;message is sent with username&quot;&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;message is sent with userid&quot;&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;message is sent with email&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;receiver does not exist&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;message is not sent&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As we can see, it’s pretty similar with our controller spec file. So after we’ve implemented &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Message&lt;/code&gt;, we can refactor the controller.&lt;/p&gt;

&lt;h2 id=&quot;refactor-controller-spec&quot;&gt;Refactor controller spec&lt;/h2&gt;

&lt;p&gt;So we have now tests to test that message can be sent with username, userid and email, we don’t need to test the same things in controller. Instead, we should just test that message is either sent or not.&lt;/p&gt;

&lt;div class=&quot;language-ruby 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;no&quot;&gt;RSpec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;MessagesController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;type: :controller&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;#create&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;receiver exist&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;message is sent&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;receiver does not exist&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;message is not sent&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now we’re testing two paths, happy and unhappy. And to be honest, we probably should get rid off the whole controller spec by adding unhappy-feature spec. But it’s ultimately up to you and how you like to test things.&lt;/p&gt;

&lt;p&gt;As feature specs are “expensive”, so we shouldn’t test everything there. But testing one happy and one unhappy path from end to end may serve the purpose.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;This is how I design my code with TDD. I’ve found it really helpful to keep focus on the thing I’m working on. I either think and design the functionality or I follow my decisions and write the code “without-thinking”.&lt;/p&gt;

</description>
      <pubDate>Sun, 01 Oct 2017 10:00:00 +0000</pubDate>
      <link>https://www.pieceofcode.blog/2017/10/tdd-as-design-tool/</link>
      <guid isPermaLink="true">https://www.pieceofcode.blog/2017/10/tdd-as-design-tool/</guid>
          
          
      <category>tdd</category>
          
      <category>rails</category>
          
      <category>ruby</category>
          
    </item>
      
    
      
    <item>
      <title>Moving the blog to GitLab and adding HTTPS-support</title>
      <description>&lt;p&gt;I decided to move my blog from &lt;a href=&quot;https://github.com&quot;&gt;GitHub&lt;/a&gt; to &lt;a href=&quot;https://gitlab.com&quot;&gt;GitLab&lt;/a&gt;. This also makes it possible to add support for HTTPS! This also changes the domain from .net to .blog.&lt;/p&gt;

&lt;p&gt;So if you’re subscriber (Thank you about that btw!), please updated the address to get future updates: &lt;a href=&quot;https://www.pieceofcode.blog/feed.xml&quot;&gt;https://www.pieceofcode.blog/feed.xml&lt;/a&gt;.&lt;/p&gt;
</description>
      <pubDate>Wed, 27 Sep 2017 10:00:00 +0000</pubDate>
      <link>https://www.pieceofcode.blog/2017/09/from-github-to-gitlab/</link>
      <guid isPermaLink="true">https://www.pieceofcode.blog/2017/09/from-github-to-gitlab/</guid>
          
          
      <category>gitlab</category>
          
    </item>
      
    
      
    <item>
      <title>Use android-sdk from Homebrew with Android Studio</title>
      <description>&lt;p&gt;I recently got a great idea for a mobile app. As I’ve used react and java in the past, but not objective-c and swift, I saw an opportunity to try &lt;a href=&quot;https://facebook.github.io/react-native/&quot;&gt;React Native&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;On the &lt;a href=&quot;https://facebook.github.io/react-native/docs/getting-started.html#&quot;&gt;Getting Started&lt;/a&gt;-guide there’re &lt;a href=&quot;https://facebook.github.io/react-native/docs/getting-started.html#2-install-the-android-sdk&quot;&gt;instructions&lt;/a&gt; for installing and configuring Android Studio. While this is pretty easy to do, I got a problem. I currently have an android phone (OnePlus 3) and I’ve already installed android-sdk through &lt;a href=&quot;https://brew.sh/&quot;&gt;Homebrew&lt;/a&gt;. The “problem” is that I don’t want to download all the tools etc. more than once. And if there’re updates, I’d like that I need to do the update only once.&lt;/p&gt;

&lt;h2 id=&quot;set-sdk-path&quot;&gt;Set SDK path&lt;/h2&gt;
&lt;p&gt;The solution is really simple, all you need to do, is to set the path in the Android Studio to point to the path where brew installed android-sdk (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/local/share/android-sdk&lt;/code&gt; on my machine).&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Open preferences and select &lt;em&gt;Appearance &amp;amp; Behavior&lt;/em&gt; -&amp;gt; &lt;em&gt;System Settings&lt;/em&gt; -&amp;gt; &lt;em&gt;Android SDK&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;Edit SDK path
&lt;img src=&quot;/images/2017-09-android/android-sdk.png&quot; alt=&quot;Edit SDK path&quot; /&gt;&lt;/li&gt;
  &lt;li&gt;Choose location
&lt;img src=&quot;/images/2017-09-android/set-path.png&quot; alt=&quot;Choose location&quot; /&gt;&lt;/li&gt;
  &lt;li&gt;Copy paste the path&lt;br /&gt;
&lt;img src=&quot;/images/2017-09-android/set-path-2.png&quot; alt=&quot;Copy paste the path&quot; /&gt;&lt;/li&gt;
  &lt;li&gt;Click &lt;em&gt;OK&lt;/em&gt;, &lt;em&gt;Next&lt;/em&gt;, &lt;em&gt;Next&lt;/em&gt;, wait for possible installations and then finally &lt;em&gt;Finish&lt;/em&gt; and you’re set!&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;install-packages-from-cli&quot;&gt;Install packages from CLI&lt;/h2&gt;

&lt;p&gt;You can of course use Android Studio to install all the packages, but in case you want to do it from CLI (e.g. in setup script or something), you can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sdkmanager&lt;/code&gt;. Here’s the command for installing packages stated in the &lt;a href=&quot;https://facebook.github.io/react-native/docs/getting-started.html&quot;&gt;Getting Started&lt;/a&gt;-guide:&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;sdkmanager &quot;add-ons;addon-google_apis-google-23&quot; &quot;platforms;android-23&quot; &quot;system-images;android-23;google_apis;x86_64&quot; &quot;system-images;android-23;default;x86_64&quot; &quot;platforms;android-23&quot; &quot;sources;android-23&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you get following error (as I did, not sure why, perhaps the docs are a bit outdated or something).&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;* What went wrong:
A problem occurred configuring project &apos;:app&apos;.
&amp;gt; The SDK Build Tools revision (23.0.1) is too low for project &apos;:app&apos;. Minimum required is 25.0.0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Just install needed build tools revision.&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;sdkmanager &quot;build-tools;25.0.0&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now the hardest part starts, the actual development. We’ll see if I ever get the app done, hopefully so.&lt;/p&gt;
</description>
      <pubDate>Sat, 23 Sep 2017 10:00:00 +0000</pubDate>
      <link>https://www.pieceofcode.blog/2017/09/android-sdk-cli-with-studio/</link>
      <guid isPermaLink="true">https://www.pieceofcode.blog/2017/09/android-sdk-cli-with-studio/</guid>
          
          
      <category>react-native</category>
          
      <category>android</category>
          
      <category>cli</category>
          
      <category>android-sdk</category>
          
    </item>
      
    
      
    <item>
      <title>Chasing productivity with iPad Pro</title>
      <description>&lt;p&gt;When it comes to productivity, I’ll try my best to get the best out of me during my work hours. I’m using &lt;a href=&quot;https://todoist.com/&quot;&gt;Todoist&lt;/a&gt; for tasks, Pomodoro when coding, weekly planning to get some idea of my upcoming week and bunch of other great tools on my work horse.&lt;/p&gt;

&lt;p&gt;Up until June this year, I had an iPad 4 mini and dual monitor setup at home and the &lt;a href=&quot;https://www.kiskolabs.com/en&quot;&gt;Kisko Labs’&lt;/a&gt; office (btw, you should definitely check out 360° view of our office from &lt;a href=&quot;https://goo.gl/maps/GP8xSQs1Pyq&quot;&gt;google maps&lt;/a&gt;).  But for some reason or another, I got interested in the new iPad Pro with Apple Pencil. I think I came up paperless sketching for the excuse to get this toy (my “old” iPad was functioning just fine).&lt;/p&gt;

&lt;p&gt;After browsing Reddit to see what apps-I-will-never-use I can install with pencil support, I found &lt;a href=&quot;https://www.duetdisplay.com/&quot;&gt;Duet&lt;/a&gt;. It’s a wonderful app which allows you to use your iPad as an additional screen with your laptop/computer. It supports both macOS and windows, but not Linux. I also found another app that does the same, but with Android support. I can’t remember the name of that app though.&lt;/p&gt;

&lt;p&gt;Anyway, that got me thinking about my setup when working remotely not-from-home. Now that I can have dual screen setup basically everywhere I go, why not use that very same setup at home and office too? I get the productivity boost from two screens mainly because I can see my dev-browser and terminal (I’m a vim+tmux user) at the same time. That need is fulfilled with the new setup.&lt;/p&gt;

&lt;p&gt;So I end up getting rid of the monitors at home and at the office.&lt;/p&gt;

&lt;p&gt;After being fully on this setup for a few weeks, it has worked for the purpose. One thing I’ve noticed is that it feels much easier to take the laptop from the desk and go e.g. to couch for an hour or two. Previously there was a small, temporary negative impact on the productivity when I got the MacBook from the desk. That’s because  the difference between resolutions on FullHD (1920x1080) and scaled (1680x1050) retina 13”. Also, the workspaces got rearranged as there’s one screen less. And the windows sizes. All those small things. Now I only share dev-browser to iPad, which keeps all other things in “correct” place regardless do I use the second screen or not.&lt;/p&gt;

&lt;h2 id=&quot;some-pictures&quot;&gt;Some pictures&lt;/h2&gt;

&lt;p&gt;The Setup.
&lt;img src=&quot;/images/chasing_productivity_1.jpg&quot; alt=&quot;The Setup&quot; /&gt;&lt;/p&gt;

&lt;p&gt;My view when working.
&lt;img src=&quot;/images/chasing_productivity_2.jpg&quot; alt=&quot;My view when working&quot; /&gt;&lt;/p&gt;

&lt;p&gt;iPad resting on top of MacBook.
&lt;img src=&quot;/images/chasing_productivity_3.jpg&quot; alt=&quot;iPad resting on top of MacBook&quot; /&gt;&lt;/p&gt;

&lt;p&gt;At the office without iPad.
&lt;img src=&quot;/images/chasing_productivity_4.jpg&quot; alt=&quot;At the office without iPad&quot; /&gt;&lt;/p&gt;

</description>
      <pubDate>Tue, 25 Jul 2017 10:00:00 +0000</pubDate>
      <link>https://www.pieceofcode.blog/2017/07/chasing-productivity-with-ipad-pro/</link>
      <guid isPermaLink="true">https://www.pieceofcode.blog/2017/07/chasing-productivity-with-ipad-pro/</guid>
          
          
      <category>remote</category>
          
      <category>productivity</category>
          
    </item>
      
    
      
    <item>
      <title>Switching to remote work</title>
      <description>&lt;p&gt;&lt;em&gt;This post was originally published at Kisko Labs’ &lt;a href=&quot;https://www.kiskolabs.com/stories/switching-to-remote-work/&quot;&gt;blog&lt;/a&gt; on last month.&lt;/em&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;In August last year I did something that I guess is usually considered as something you shouldn’t do. First, I told my employer that I might be leaving in the beginning of this year. Not long after that, I told that I might actually leave even a few months earlier. Then my plans changed again. The reason for thinking about leaving Kisko was purely personal.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;I wanted to go abroad and work 100% remotely, so I could explore the world.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Telling your boss that you’re planning to quit is often something uncomfortable, that you can end up postponing to the last moment. But being honest and direct about your plans early on could benefit both you and your employer – by boosting positive change.&lt;/p&gt;

&lt;h1 id=&quot;the-discussion&quot;&gt;The discussion&lt;/h1&gt;
&lt;p&gt;Instead of just announcing that I’m leaving, I wanted to try speaking openly about my career moves. Also to see, if my employer really is the career incubator, the supporter in all situations.&lt;/p&gt;

&lt;p&gt;It turned out it is. Speaking directly opened perhaps the most honest ‘development discussion’ I’ve ever had with an employer. I can’t say how it is in all other companies out there, but you might want to be part of one where you can have these kind of honest, constructive discussions. Our discussion – and discussions with my significant other – made me do the last change of plans, decide to continue at my current workplace.&lt;/p&gt;

&lt;p&gt;Kisko doesn’t have a lot of experience yet with actual remote workers, even though short periods of remote work are totally normal among the team and freelancers. By sharing thoughts, we’ve been able to help each other. I can start planning to move abroad and we, as a team, can find ways to make remote working possible for us.&lt;/p&gt;

&lt;h1 id=&quot;towards-remote-work&quot;&gt;Towards remote work&lt;/h1&gt;
&lt;p&gt;We’ve already taken a few steps forward. As a first step, we decided to measure how many Kiskonians feel that they could work remotely for a month. We took that as a goal during our last &lt;a href=&quot;https://en.wikipedia.org/wiki/OKR&quot;&gt;OKR&lt;/a&gt; season of last year. Results weren’t that good, only 3 out of 12 felt that they could do that (we didn’t measure how many actually would want to).&lt;/p&gt;

&lt;p&gt;As a second step, I took two personal goals for our first OKR season this year. First, to spend at least three weeks working abroad and secondly, to come up with at least three proposals on how we could/should change our way of working to give better support for remote workers.&lt;/p&gt;

&lt;p&gt;I’ve started to work from home more, even full weeks, but usually trying to visit the office about twice a week. I’ve also noticed that others have increased their remote-day count, and we’ve had more &lt;a href=&quot;https://www.kiskolabs.com/stories/remote-meetings/&quot;&gt;internal meetings with people participating remotely&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Focusing on remote work and doing serious research on it has made it possible to really optimize my ways of working for better productivity.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Experiments in time management, such as using weekly reviews and planning, have given me the freedom to arrange my work schedule closer to what I want it to be without sacrificing the quality or amount of work done. For example, I’ve been able to do gym sessions at noon, something I previously didn’t do because it felt like cheating. After a break I’ve been able to get back to work with better focus.&lt;/p&gt;
</description>
      <pubDate>Sat, 10 Jun 2017 10:00:00 +0000</pubDate>
      <link>https://www.pieceofcode.blog/2017/06/switching-to-remote-work/</link>
      <guid isPermaLink="true">https://www.pieceofcode.blog/2017/06/switching-to-remote-work/</guid>
          
          
      <category>remote</category>
          
    </item>
      
    
      
    <item>
      <title>Ease your RSpec upgrade with sed</title>
      <description>&lt;p&gt;I’ve been using linux on daily basis since 2008 and changed to OS X a couple of years ago. What I like these systems, is their powerful command line tools. Tools that helps me get my job done quicker and easier than with GUI.&lt;/p&gt;

&lt;p&gt;Even though I’ve been using a CLI so long, it’s just so amazing how powerful tools there are, and have been for decades. This time I’d like to share a tip which may save you a lot of time in future (it saved for me)!&lt;/p&gt;

&lt;p&gt;So, at the end of the last year and beginning of this year, I got to work with few Rails upgrades from 3.x to 4.x. This meant also that most of the gems needed to be upgraded.&lt;/p&gt;

&lt;p&gt;One of the problems was the renamed expectations &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;be_true&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;be_false&lt;/code&gt; (to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;be_truthy&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;be_falsey&lt;/code&gt; respectively) in the gem &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rspec-expectations&lt;/code&gt; on version &lt;a href=&quot;https://github.com/rspec/rspec-expectations/blob/master/Changelog.md#300beta1--2013-11-07&quot;&gt;3.0.0.beta1&lt;/a&gt;. It wasn’t a big change, but depending on the size of your test code base, it may mean a lot of work to you.&lt;/p&gt;

&lt;p&gt;But luckily, you can solve it in a few seconds with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sed&lt;/code&gt;&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;sed -i “” “s/be_true/be_truthy/g” spec/**/*_spec.rb
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Breaking down the command&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-i “”&lt;/code&gt; means in-place editing and by giving empty string for it, we do not want to use backup files. We have version control for that reason.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;“s/be_true/be_truthy/g”&lt;/code&gt; is the command we give to sed. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;s&lt;/code&gt; at the start tells the sed that we want to use regular expression &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;be_true&lt;/code&gt; and replace that with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;be_truthy&lt;/code&gt;. In this case, our regular expression is just plain text, but you can use more advanced patterns if you like. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;g&lt;/code&gt; at the end tells that we want replace all occurrences of our search pattern in a single file, not just the first one. You can read more about &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;s&lt;/code&gt; command from the &lt;a href=&quot;https://www.gnu.org/software/sed/manual/html_node/The-_0022s_0022-Command.html&quot;&gt;manual&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;spec/**/*_spec.rb&lt;/code&gt; this is the filter pattern for files I want the change med into. I’m using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;zsh&lt;/code&gt; so it may not work as is on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bash&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <pubDate>Mon, 10 Aug 2015 20:00:00 +0000</pubDate>
      <link>https://www.pieceofcode.blog/2015/08/ease-your-rspec-upgrade-with-sed/</link>
      <guid isPermaLink="true">https://www.pieceofcode.blog/2015/08/ease-your-rspec-upgrade-with-sed/</guid>
          
          
      <category>‘rails’</category>
          
      <category>‘rspec’</category>
          
      <category>‘sed’</category>
          
    </item>
      
    
      
    <item>
      <title>Reporting bugs in Open Source</title>
      <description>&lt;p&gt;I read a blog post from the authors of the CMS I use in several sites a couple of months ago about bug reporting. The post originated from its forum, where the core developer responded to criticism about bug report/feature request rejections.&lt;/p&gt;

&lt;p&gt;He wrote a big rant about how users should do some research before filling bug reports, so the reports will be done right. Also, this developer wrote how he is fed up with those reports which are missing some critical information he needs. Asking, those information of course consumes time, which he does not have.&lt;/p&gt;

&lt;p&gt;I have something in mind which I want to share with you.&lt;/p&gt;

&lt;p&gt;First of all, if you want some information, you have to ask it. Currently, in the reporting form of the system they use, contains fields for&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;software version&lt;/li&gt;
  &lt;li&gt;Who is it assigned for (how the hell end user would know that?)&lt;/li&gt;
  &lt;li&gt;version of the module (if it’s a bug of the module)&lt;/li&gt;
  &lt;li&gt;severity (I don’t think that user necessary knows this)&lt;/li&gt;
  &lt;li&gt;summary&lt;/li&gt;
  &lt;li&gt;description&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are no hints about what kind of information needs to be to written into the description field or any link to such documentation. So why do you blame your end users for crappy reports? How about looking in the mirror? You have to educate your users for writing better reports and guide them through the process. Just putting link to an example of “perfect report” may be enough. Or even better, show it side-by-side on the form. If you need a lot of technical details, you could (and should) use some kind of an automatic error report system.&lt;/p&gt;

&lt;p&gt;Secondly, there was a point that the developer doesn’t have time to check all existing combinations of settings, plugins and software. All I have to say is that, don’t make such combinations possible then. Don’t allow users to set any settings, or install any plugins. Of course it has impacts to your user base, but does it matter? At least you don’t get stupid and imperfect reports! Of course, there could be thousands of combinations and you cannot test them all. That’s why you may have to deal with incomplete reports and ask for more details. It’s the trade-off you need to take (in my opinion).&lt;/p&gt;

&lt;p&gt;I also like to point out that customer service is part of our job in these days as a developer. So if you don’t want to do that, hire someone to do it for you.&lt;/p&gt;
</description>
      <pubDate>Mon, 03 Aug 2015 20:00:00 +0000</pubDate>
      <link>https://www.pieceofcode.blog/2015/08/reporting-bugs-in-open-source/</link>
      <guid isPermaLink="true">https://www.pieceofcode.blog/2015/08/reporting-bugs-in-open-source/</guid>
          
          
      <category>‘open source’</category>
          
      <category>‘cms’</category>
          
    </item>
      
    
      
    <item>
      <title>First solution is not the best one</title>
      <description>&lt;p&gt;When you have a problem, you usually have to find a solution pretty quick. It’s kind of a shame, but it’s better to do something and fail than getting nothing done. At least you know what isn’t working. It’s important to get working solution first, but usually you stop there and forget the code. Therefore you should review earlier solutions and think how to improve your codebase.&lt;/p&gt;

&lt;p&gt;In here, I’d like to share how I started with one solution and ended up with another. Problem was: how to share membership details between Rails and WordPress. If you compare solutions 1 and 3, they differ a lot, but both solve the problem. Latter a little bit better than former (in my opinion).&lt;/p&gt;

&lt;h2 id=&quot;solution-1&quot;&gt;Solution 1&lt;/h2&gt;

&lt;p&gt;First I thought about sharing the session between these apps. Basically, we would create unique one-time hash in Rails when user logs in. Then the hash would be saved in to secure cookie within the same domain. WordPress would use custom-made plugin to get the hash from the cookie and use a command line script to get user details from the rails app. Pretty much customization and maintaining, and sharing session like this is pretty hard to get fully functional. So I dumped this after a month.&lt;/p&gt;

&lt;h2 id=&quot;solution-2&quot;&gt;Solution 2&lt;/h2&gt;

&lt;p&gt;Then I started to look SSO (Single Sing-On) solutions and found doorkeeper (https://github.com/doorkeeper-gem/doorkeeper). It uses OAuth and was pretty easy to install and get working. The problem was that there weren’t OAuth client plugins (other than preconfigured with Twitter/Facebook etc) for WordPress at the time. And I had no competence to create that kind of plugin. This solution didn’t allow either of the apps to have their own user registers. And I thought that users should be able to register either of the apps separately.&lt;/p&gt;

&lt;h2 id=&quot;solution-3&quot;&gt;Solution 3&lt;/h2&gt;

&lt;p&gt;I found wp-cli at some point middle of thinking solution 2. I started to think what if both apps could have their own users and I didn’t need to customize WordPress at all. I just needed some tool to use wp-cli from Ruby. So I created gem wpcli. How about syncing the membership details? In Rails there was field for username in WordPress and whenever that value will be changed, syncing is done. This requires also some kind of settings page, where roles from each app can be mapped to each other. For example, member in Rails would be premium customer in WordPress.&lt;/p&gt;

&lt;p&gt;This was done for spare time project, but I think that’s not relevant.&lt;/p&gt;

&lt;p&gt;So I strongly encourage to review already made solutions and to question those constantly. It’s one of the best ways to improve software over the time and more important, it helps you to improve your skills.&lt;/p&gt;
</description>
      <pubDate>Fri, 05 Dec 2014 12:35:00 +0000</pubDate>
      <link>https://www.pieceofcode.blog/2014/12/first-solution-is-not-the-best-one/</link>
      <guid isPermaLink="true">https://www.pieceofcode.blog/2014/12/first-solution-is-not-the-best-one/</guid>
          
          
      <category>integration</category>
          
      <category>rails</category>
          
      <category>wordpress</category>
          
    </item>
      
    
      
    <item>
      <title>Do not test your private methods</title>
      <description>&lt;p&gt;&lt;em&gt;This subject came in my mind after having discussion with my colleague who creates methods with default or protected scope to ease testing.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I’m not sure why even think that you should test your private methods. At least when you’re coding with TDD, you create one test, which test that method does what it should. After you get your test pass, you create another one, and another one. As long as you feel that it’s necessary to add functionality to method.&lt;/p&gt;

&lt;p&gt;When your method does what you want it to do, it’s time to refactor. While refactoring, you should run tests every time change is made, so that it’s easier to notice if/when you break something. Tests are something you rely during refactoring.&lt;/p&gt;

&lt;p&gt;After refactoring, you probably have method which uses private methods which you made to make code more readable and reusable. Now, think few minutes what would happen if you change visibility of those methods from private to for example protected or default.&lt;/p&gt;

&lt;p&gt;First, you can create tests for those methods and be happy. BUT, what about refactoring the public method you create at first place? Right, you cannot do it without touching those tests! Of course modern IDEs will rename methods or parameters almost automatically, but you lose your trust to your tests. If you change something, there is always possibility to break tests.&lt;/p&gt;

&lt;p&gt;Let’s think it from another point of view. Assume that you are working with project which has 2-3 full time developers. Then, on one pretty day, team gets a new member. This new member gets a task to add new functionality to some old classes which has tests. This new member starts with writing tests that fails. Then s/he starts to implement the method itself. After all tests are passing, s/he wants to refactor as there is same behavior on multiple places. Now, if someone has done his job right, there is tests only for public methods and our new member can refactor and trust that s/he doesn’t break anything as long as tests are passing.&lt;/p&gt;

&lt;p&gt;If there is protected or default methods with their own tests, s/he probably need to touch them as well. This creates a situation where new bugs might be introduced.&lt;/p&gt;

&lt;p&gt;Think about it, your tests should test that method does what it should do. Not how it does it or how many private methods are used to gain passing test.&lt;/p&gt;

&lt;p&gt;In the other hand what is the purpose of the private method? I’d say its purpose is to make code more readable and reusable in that specific class. Nothing else.&lt;/p&gt;
</description>
      <pubDate>Wed, 24 Apr 2013 19:54:00 +0000</pubDate>
      <link>https://www.pieceofcode.blog/2013/04/do-not-test-your-private-methods/</link>
      <guid isPermaLink="true">https://www.pieceofcode.blog/2013/04/do-not-test-your-private-methods/</guid>
          
          
      <category>java</category>
          
      <category>methods</category>
          
      <category>refactoring</category>
          
      <category>TDD</category>
          
      <category>testing</category>
          
    </item>
      
    
      
    <item>
      <title>Fresh start</title>
      <description>&lt;p&gt;As the time is passing too quickly nowadays (at least it feels like that), I felt the old pieceofcode.net-site was more like burden than a joy to keep up to date. It was time try something new and different and so I came up with an idea to write a blog.&lt;/p&gt;

&lt;p&gt;In this blog I will write things that touches my life at that specific time in world of programming. I have few projects coming up (with rails and wordpress) so there might come some good article ideas too. I’ll try to blog in English, but some articles might be in Finnish.&lt;/p&gt;

&lt;p&gt;In the meantime you can find me at least from &lt;a href=&quot;https://www.facebook.com/hasanen&quot;&gt;facebook&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/jonihasanen&quot;&gt;twitter&lt;/a&gt; and &lt;a href=&quot;https://github.com/hasanen/&quot;&gt;github&lt;/a&gt;.&lt;/p&gt;
</description>
      <pubDate>Wed, 10 Apr 2013 18:03:00 +0000</pubDate>
      <link>https://www.pieceofcode.blog/2013/04/fresh-start/</link>
      <guid isPermaLink="true">https://www.pieceofcode.blog/2013/04/fresh-start/</guid>
          
          
    </item>
      
    
  </channel>
</rss>
