<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Héctor de Isidro</title>
    <description>The latest articles on Forem by Héctor de Isidro (@hector6872).</description>
    <link>https://forem.com/hector6872</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F7563%2F91yVVDdg.jpg</url>
      <title>Forem: Héctor de Isidro</title>
      <link>https://forem.com/hector6872</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/hector6872"/>
    <language>en</language>
    <item>
      <title>Time is Money</title>
      <dc:creator>Héctor de Isidro</dc:creator>
      <pubDate>Tue, 06 Oct 2020 10:15:51 +0000</pubDate>
      <link>https://forem.com/hector6872/time-is-money-5a99</link>
      <guid>https://forem.com/hector6872/time-is-money-5a99</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1592495981488-073153776d9a" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1592495981488-073153776d9a" width="800" height="509"&gt;&lt;/a&gt;&lt;br&gt;
&lt;span&gt;Photo by &lt;a href="https://unsplash.com/@morganhousel" rel="noopener noreferrer"&gt;Morgan Housel&lt;/a&gt; on &lt;a href="https://unsplash.com/" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Anytime is taco time
&lt;/h3&gt;

&lt;p&gt;Sometimes you’re talking to a colleague or friend, you’re taking a shower, you’re staring at some wall, or you’re just walking around, &lt;strong&gt;and then a thought or an idea strikes you.&lt;/strong&gt; &lt;a href="https://en.wikipedia.org/wiki/Eureka_effect" rel="noopener noreferrer"&gt;Eureka&lt;/a&gt;!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Everything begins with an idea” — Earl Nightengale&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sometimes it’s something you need, other times it’s something you think might help others. Something you think it can bring value to you/them in some way. Something that someway can make your/their daily life easier. Something you/they sometimes lacked.&lt;/p&gt;

&lt;p&gt;Sometimes it’s not the best idea but &lt;a href="https://dev.to/hector6872/fun-sideproject-create-3llg"&gt;the perfect excuse to learn something new&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sometimes you just have to say no
&lt;/h3&gt;

&lt;p&gt;We have on average a lot of ideas along our life that seem amazing in our minds, but not &lt;strong&gt;all of them deserve to be developed&lt;/strong&gt;. It’s not whether the idea is good or bad — &lt;a href="http://www.todayifoundout.com/index.php/2016/05/deal-pet-rocks/" rel="noopener noreferrer"&gt;the weirdest ideas can give unexpected&lt;/a&gt; results though. It’s all about our limited time and resources.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“There are no bad ideas, just bad decisions” — Jacob Cass&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;It’s bad not to try,&lt;/strong&gt; as the old cliché goes, &lt;strong&gt;but it’s worse to start it and end up burying it&lt;/strong&gt; in our half-finished project cemetery, due to desperation, lack of planning and/or after realising that it’s completely out of our reach.&lt;/p&gt;

&lt;p&gt;We shouldn’t start a new project in a hurry without a minimum plan or a feasibility study.&lt;/p&gt;

&lt;h3&gt;
  
  
  Think twice before you act
&lt;/h3&gt;

&lt;p&gt;We should consider a few things before we start and the best way to confirm whether or not we should go deeper is to &lt;strong&gt;break down the idea into multiple questions&lt;/strong&gt;. That way, we will soon realize whether it is feasible or it’d better to leave it for later — so don’t forget to always write them down — and go for another one.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Don’t be afraid of the answers. Be afraid of not asking the questions” — Jennifer Hudson&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The questions you choose and the answers you get will depend on a wide range of factors — such as the size of the idea, its complexity, your previous experience, your mood, etc… — but &lt;strong&gt;only one thing is certain: if you don’t ask, the answer is already no.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Simple answers to simple questions
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;“Sometimes a simple question could have a complicated answer.” — Lisa Kleypas&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They must be short sentences, asking just one thing per question, straightforward and &lt;a href="https://en.wikipedia.org/wiki/Closed-ended_question" rel="noopener noreferrer"&gt;closed-ended&lt;/a&gt;. After all, this is not rocket surgery — at least not yet — so &lt;strong&gt;try to come up with questions and answers that helps you to make you a decision at a glance.&lt;/strong&gt; Perhaps the first “negative” answer would be enough for that.&lt;/p&gt;

&lt;h3&gt;
  
  
  Idea. Research. Discard. Repeat.
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;“Ideas are like insects. Many are born but few live to maturity.” — William Hertling&lt;/p&gt;
&lt;h2&gt;
  
  
  Don’t get me wrong. &lt;strong&gt;Every idea — good or not — has its beauty&lt;/strong&gt; and it would be amazing to develop each one of them to try our luck, but we must go for the best because as we all know: &lt;strong&gt;TIME IS MONEY (so spend it wisely)&lt;/strong&gt;.
&lt;/h2&gt;
&lt;/blockquote&gt;

&lt;p&gt;This article was originally published on &lt;a href="https://medium.com/datadriveninvestor/ideas-development-kit-1d43f9eb9a6d" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ideas</category>
      <category>productivity</category>
      <category>motivation</category>
    </item>
    <item>
      <title>fun SideProject.create()</title>
      <dc:creator>Héctor de Isidro</dc:creator>
      <pubDate>Sun, 29 Sep 2019 10:59:45 +0000</pubDate>
      <link>https://forem.com/hector6872/fun-sideproject-create-3llg</link>
      <guid>https://forem.com/hector6872/fun-sideproject-create-3llg</guid>
      <description>&lt;p&gt;&lt;a href="http://ozh.org/contribution/" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq6rt3g3axbcapx0ufycp.png" alt="Made by Github-like contribution graph" width="800" height="107"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;“The best way to learn is by doing” — Alex Spanos&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Although it is quite common to think of &lt;strong&gt;side projects&lt;/strong&gt; only as an additional source of income -and in fact many of them end up taking off and becoming successful businesses- the most are actually developed motivated by these more than possible other great benefits -beyond the economic- that they can bring us:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They provide &lt;strong&gt;an opportunity to practice and learn new skills, techniques and/or technologies&lt;/strong&gt; -related or not with our daily work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;They encourage our creativity&lt;/strong&gt; -breaking the monotony or routine of our day job- &lt;strong&gt;and self-development and improve our self-confidence&lt;/strong&gt;. In addition, as they often are projects end-to-end, they keep us motivated by pushing away from our confort zone which leads us to improve other important skills outside our day-to-day environment.&lt;/li&gt;
&lt;li&gt;They are directly related to the idea of the recovery process¹ that we need along the week: the stress and fatigue caused by our daily work can affect our mental and/or physical health in the long-term, so &lt;strong&gt;spending time on leisure activities such as passionately working on projects or personal ideas for diversion would have a significant impact on our recovery&lt;/strong&gt; -not forgetting that a good night’s sleep will still have higher priority.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;They can have a big impact on your career&lt;/strong&gt;. Showing people what we’ve done or what we’re capable of building, or having a &lt;em&gt;voice&lt;/em&gt; on a matter, can open up new job opportunities or promotions -and also some public recognition and reputation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;They can bring value to other people&lt;/strong&gt; and make their day-to-day life easier in some way² -which is nice and comforting.&lt;/li&gt;
&lt;li&gt;And last but not least, as we can keep the pressure at minimum and not take everything so seriously, &lt;strong&gt;they are fun&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Don't trust everything you see, even salt looks like sugar.
&lt;/h3&gt;

&lt;p&gt;There are side projects everywhere. A countless number of them, created out of different motivations or objectives. Great ideas, revolutionary or not, perfectly executed, turned into great solutions. But like everything else in this life, their success, repercussion, visibility and eventual economic benefits -some of them really end up paying some bills- will depend on several factors, including among them: a good amount of luck.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Luck is what happens when preparation meets opportunity" — Seneca&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If we google for information about side projects that has become successful companies, profitable businesses, we will see that almost always the same are listed: Twitter, Instagram, Gmail, Groupon… which are undoubtedly successful companies, but were they really born as mere side projects as we know them? Well, we could say that it's not entirely true…&lt;/p&gt;

&lt;p&gt;It's true that they fulfil the premise that they are projects created without being part of the main focus but when they are created within an existing company they are actually another value creation project for that company -even though they are not expressly related. Twitter (former Twttr, name inspired by Flickr at the time), for instance, was created from an idea that emerged in an emergency brainstorming session in a way to reinvent a dying podcasting company called Odeo. Something similar, due to a change in its business model, happened with Unsplash. Google offered Paul Buchheit -who was also the creator of the motto "Don't be evil", used within Google's corporate code of conduct- to work on the development of a project to create a "type of e-mail" which he enthusiastically accepted and which laid the foundations of Gmail -the well known e-mail client (it's worth mentioning that he built the very first version in a single day based on his experience working in another project within that same company: Google Groups). And so on…&lt;/p&gt;

&lt;p&gt;Now, taking into account those small but important details, we can say that, although it is an unpopular opinion: the closest thing to a genuine side project would be Facebook (former TheFacebook) because Mark Zuckeberg developed the bases of that social network -in just two weeks- when he was a student at Harvard -a few weeks after that another of his side projects, Facemash, was banned by that university.&lt;/p&gt;

&lt;p&gt;But don't get it wrong, not all projects of this type have to do with a certain degree of despair: it is strongly recommended that certain companies allocate resources to create these "side projects" -as long as they don't become simple and costly distractions- in order to take advantage of internal talent, avoid personal burnout, make learning part of their culture, test future plans or implementations, or send a message to the market that they are capable of building incredible things -aka enginering-as-marketing. &lt;/p&gt;

&lt;p&gt;As conclusion, we can say that developing "side projects" within a company -for instance, during an &lt;a href="https://twitter.com/Tech_LolaMarket/status/1112998074107027456]" rel="noopener noreferrer"&gt;internal hackathon&lt;/a&gt;- it's an investment that's really worth making and can end up in a decisive change in the business model or even spark a new undertaking. &lt;strong&gt;But we have to call a spade a spade.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  From busy to more busy
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;“The key is in not spending time, but in investing it” — Stephen R. Covey.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But all that glitters is not gold, &lt;strong&gt;all those rewards will have a very high price: our free time&lt;/strong&gt; -in most cases quite limited.&lt;/p&gt;

&lt;p&gt;We will have to carefully plan the project, every step we’re going to take -it’s hard to get back from work to keep working, so it’s better not to waste our most valuable resource staring at a wall without having an idea of what to do next- deducting the time we’re going to need from something else -but not from your real job: &lt;strong&gt;there is no side without main, keep in mind&lt;/strong&gt;- and probably postponing that new -and possibly not too good- series on Netflix.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“If you fail to plan, you are planning to fail!” — Benjamin Franklin&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here is one more skill that we will learn indirectly throughout our adventures developing side projects: how to plan well -the more we plan the better how we plan. And this is an important lesson -for projects as well as for life in general- because, although sometimes things just don’t turn out as planned, &lt;strong&gt;it’s better to have a plan that’s not too good than nothing at all&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  We can't move forward if we don't know where we're going.
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;"Plans are nothing. Planning is everything." — Dwight D. Eisenhower&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To plan is to determine what objective, goal or purpose we want to achieve or reach meanwhile planning is to decide beforehand how and when we are going to achieve that objective and the strategy, tasks and steps to accomplish it -combining forecasting with the preparation of the different possible scenarios and the way to react to them- as if it were a map (as we usually do when we travel: the trip is the plan and the route we would like to follow is the planning).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"No plan survives contact with the enemy" — Helmuth von Moltke&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No matter how good your planning is, either short-term or long-term, you will never be able to predict all the problems you will face³, since each stage has a high degree of uncertainty, not always evident -and even though we will never know what the future holds, working without minimal planning should never be an option⁴. &lt;/p&gt;

&lt;p&gt;Therefore, the key to success will be keeping the plan under constant review and adapting it -always changing some parts and not the whole- to cope with the changes without ever losing sight of our original destination -keeping the old plan alive while we work out the new one. In order to be able to do this, we must try to make the plan flexible enough because, although eventual changes and unexpected challenges can be overwhelming -they are part of the game anyway- there is nothing more frustrating and stressful than being stuck to a too rigid plan -often leading to a dead end. &lt;/p&gt;

&lt;h2&gt;
  
  
  Don’t forget to have fun
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“The prize is in the process” — Baron Baptiste&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Don’t forget that. This must be fun. So once we have decided to do it, we will have to pay close attention, along the way, not to make certain common mistakes in order to prevent our brilliant project from turning into hell:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Focus on one project at a time⁵.&lt;/strong&gt; Multi-tasking is only for computers. Normally if we start too many projects at once, we end up not finishing any of them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Start small, keep it simple.&lt;/strong&gt; Take baby steps. You’re more likely to succeed. Thinking about something too big usually ends up overwhelming us (and anyway we will always have time to complicate things, or not, when the time comes).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don’t get obsessed.&lt;/strong&gt; Prioritize the important things in life. Starting a new project is always exciting but we will have to stay calm and think about it as what it is: a hobby.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don’t put pressure on yourself.&lt;/strong&gt; We have neither inflexible delivery deadlines nor stakeholders waiting for what they paid for. Perfection simply does not exist.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don’t focus all your attention on a possible monetization or passive income&lt;/strong&gt; -it can be &lt;em&gt;a goal&lt;/em&gt;, but it’s not &lt;em&gt;the goal&lt;/em&gt;-. This generally leads us down paths that end up invalidating almost all the benefits described above. It is true that a few side projects may become full-time jobs, but it is also true that the vast majority suffer a high failure rate. Think of them as a project, not a job.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Be prepared to fail.&lt;/strong&gt; There are numerous reasons why a side project can fail. Never mind, you didn’t actually lose anything by failing. At least you have learned one thing, which you probably can take to your next project, making it easier in someway. Keep going.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;h2&gt;
  
  
  Enjoy the journey -which is the very real reward- and keep this always in mind: this is not your job, you can give up whenever you want.
&lt;/h2&gt;
&lt;/blockquote&gt;

&lt;p&gt;This article was originally published on &lt;a href="https://medium.com/@hector6872/fun-sideproject-make-b23d2af28fe8" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;[&lt;strong&gt;1&lt;/strong&gt;] John W. Rook &amp;amp; Professor Fred R. H. Zijlstra Faculty of Psychology (2006) The contribution of various types of activities to recovery, European Journal of Work and Organizational Psychology, 15:2, 218–240, DOI: &lt;a href="https://www.tandfonline.com/doi/abs/10.1080/13594320500513962" rel="noopener noreferrer"&gt;10.1080/13594320500513962&lt;/a&gt;&lt;br&gt;
[&lt;strong&gt;2&lt;/strong&gt;] “A business that makes nothing but money is a poor business.” — Henry Ford&lt;br&gt;
[&lt;strong&gt;3&lt;/strong&gt;] Even Mike Tyson once said something about this matter: “Everyone has a plan 'til they get punched in the mouth” &lt;br&gt;
[&lt;strong&gt;4&lt;/strong&gt;] "Victorious warriors win first and then go to war, while defeated warriors go to war first and then seek to win" — Sun Tzu, The Art of War&lt;br&gt;
[&lt;strong&gt;5&lt;/strong&gt;] “If you chase two rabbits, you will catch neither one.” — Russian proverb&lt;/p&gt;

</description>
      <category>entrepreneurship</category>
      <category>planning</category>
      <category>sideprojects</category>
    </item>
    <item>
      <title>Habits + Google Sheets = Profit!</title>
      <dc:creator>Héctor de Isidro</dc:creator>
      <pubDate>Fri, 22 Feb 2019 23:12:52 +0000</pubDate>
      <link>https://forem.com/hector6872/habits--google-sheets--profit-4if5</link>
      <guid>https://forem.com/hector6872/habits--google-sheets--profit-4if5</guid>
      <description>&lt;h2&gt;
  
  
  Because good habits are worth it
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdz9sjml77038gmcj5vah.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdz9sjml77038gmcj5vah.jpeg" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Update: after more than two years using the solution below, I finally decided to create my own native Android app. Give it a try!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://play.google.com/store/apps/details?id=com.hector6872.habits" rel="noopener noreferrer"&gt;&lt;strong&gt;Traction App for Android&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  What is a New Year Resolution?
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;New Year’s resolution&lt;/strong&gt; is a &lt;a href="https://www.history.com/news/the-history-of-new-years-resolutions" rel="noopener noreferrer"&gt;tradition&lt;/a&gt; in which we make a bunch of promises¹ -on the last days of the year or so- to ourselves to do something in order to improve our behaviour or lifestyle in a good way during the year ahead (i.e. quit smoking, eat less junk food, lose weight, do some form of exercise and/or stop saying JS is a real programming language²).&lt;/p&gt;

&lt;p&gt;Even though some they could be just a &lt;a href="https://github.com/hector6872/ResolutionBoard" rel="noopener noreferrer"&gt;personal goal or challenge&lt;/a&gt; (i.e. travel solo), almost every promise we make of this kind usually is -to a greater or lesser degree- &lt;strong&gt;a habit&lt;/strong&gt; (to either make or break it).&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a habit?
&lt;/h3&gt;

&lt;p&gt;A habit is the behaviour pattern, &lt;strong&gt;acquired through frequent repetition³&lt;/strong&gt;, we do often unconsciously -unintentionally and uncontrollably- in response to a known cue⁴.&lt;/p&gt;

&lt;h3&gt;
  
  
  What does Google have to do with all this?
&lt;/h3&gt;

&lt;p&gt;Most of us have ever promised to break some bad habit as a New Year’s resolution and then realise after summer holidays -at best- that we hadn’t even started. And then, once again, another year is gone…&lt;/p&gt;

&lt;blockquote&gt;
&lt;h1&gt;
  
  
  Tracking our habits⁵ every day — or at least once a week — is the best way to keep us motivated and gives us a glimpse of how well (or bad) we are doing it.
&lt;/h1&gt;
&lt;/blockquote&gt;

&lt;p&gt;I’ve tried a bunch of applications and websites to track habits but for whatever reason (pricing, lack of export options, uncertain future, etc…) I haven’t felt comfortable with any of them. Then, I talked to two huge organisation experts &lt;a href="https://dev.toundefined"&gt;Jesus Cerviño&lt;/a&gt; &amp;amp; &lt;a href="https://dev.toundefined"&gt;David.S&lt;/a&gt; -whom I’m lucky enough to have as co-workers- and I was told that I could do everything I wanted (and even more) with a powerful tool⁶ widely used: &lt;strong&gt;&lt;a href="https://www.google.com/sheets/about/" rel="noopener noreferrer"&gt;Google Sheets&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  First we make our habits, then our habits make us
&lt;/h2&gt;

&lt;p&gt;After doing some research I’ve created an improved &lt;strong&gt;&lt;a href="https://docs.google.com/spreadsheets/d/1pEvbxS_O7kb7jnMxRvLJhh2v7g4yvFesUV5_YmSVmrw/edit?usp=sharing" rel="noopener noreferrer"&gt;Habit Tracker template&lt;/a&gt;&lt;/strong&gt; based on the awesome work of &lt;a href="https://dev.toundefined"&gt;Harold Kim&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h1&gt;
  
  
  Log in to your Google Account, make a copy of my &lt;strong&gt;&lt;a href="https://docs.google.com/spreadsheets/d/1pEvbxS_O7kb7jnMxRvLJhh2v7g4yvFesUV5_YmSVmrw/edit?usp=sharing" rel="noopener noreferrer"&gt;Habit Tracker&lt;/a&gt;&lt;/strong&gt; template (File&amp;gt;Make a copy…) and fill down Activity column with your &lt;a href="https://en.wikipedia.org/wiki/SMART_criteria#Current_definitions" rel="noopener noreferrer"&gt;smart goals and habits&lt;/a&gt;.
&lt;/h1&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then, clear the sample data and you will be able to track your own habits putting a &lt;strong&gt;X&lt;/strong&gt; (or 😄/🙁 depending of your mood) on every cell you want to mark it as &lt;strong&gt;Done&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://lifehacker.com/jerry-seinfelds-productivity-secret-281626" rel="noopener noreferrer"&gt;Don’t break the chain!&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Streak&lt;/strong&gt; and &lt;strong&gt;Max Streak&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Progression&lt;/strong&gt; based on the value you have put in &lt;strong&gt;Expected&lt;/strong&gt; column (which has to be in days⁷)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Highlight current day&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Alternate colours every month&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Autohide columns based on date&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tip: you could even use the Habit Tracker as a habits related journal through the &lt;a href="https://www.prolificoaktree.com/google-sheets-comment-vs-note/" rel="noopener noreferrer"&gt;built-in notes feature&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h1&gt;
  
  
  Don’t forget to set up a recurring reminder (you can use also &lt;a href="https://www.google.com/calendar" rel="noopener noreferrer"&gt;Google Calendar&lt;/a&gt; btw) so you don’t forget to keep track of your habits. Then make a habit of this too!
&lt;/h1&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Above all, &lt;strong&gt;don’t be a slave of your (bad) habits…&lt;/strong&gt; and &lt;a href="https://imgflip.com/i/2sovqj" rel="noopener noreferrer"&gt;be like Bill&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;This article was originally published on &lt;a href="https://medium.com/@hector6872/habits-google-sheets-profit-aef90faba4f0" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;[1] The most common New Year’s Resolutions in &lt;a href="https://www.comresglobal.com/polls/bupa-new-year-resolution-survey/" rel="noopener noreferrer"&gt;UK&lt;/a&gt; (December 2015) and &lt;a href="http://d25d2506sfb94s.cloudfront.net/cumulus_uploads/document/366cvmcg44/New%20Year%20Survey,%20December%208%2011,%202017.pdf" rel="noopener noreferrer"&gt;US&lt;/a&gt; (December 2017)&lt;br&gt;[2] Just trolling, don’t feed me 🐟&lt;br&gt;[3] Developing a new habit takes between 18 and 254 days (66 days on average). Unfortunately, &lt;a href="https://jamesclear.com/new-habit" rel="noopener noreferrer"&gt;there are no magic numbers&lt;/a&gt;. &lt;br&gt;[4] A great tip about habits and willpower: &lt;em&gt;we should not focus on the behaviour but rather &lt;a href="https://markmanson.net/downloads/habits" rel="noopener noreferrer"&gt;focus on the cue&lt;/a&gt; (i.e. location, time of day, emotional state, belief, other people, etc…) to develop new habits (or to break them)&lt;/em&gt;&lt;br&gt;[5] &lt;a href="https://www.forbes.com/sites/ellevate/2015/06/08/what-gets-measured-gets-done-or-does-it/#4a373f0113c8" rel="noopener noreferrer"&gt;What gets measured gets done&lt;/a&gt;&lt;br&gt;[6] It’s free, multi-platform, allow us to export the data and works offline 💪&lt;br&gt;[7] Remember that a common year has 52 weeks (i.e. if you want to workout 3 times a week you just have to put in that cell &lt;code&gt;=3*52&lt;/code&gt;) 👨‍🎓&lt;/p&gt;




&lt;p&gt;&lt;a href="https://gist.github.com/hector6872/c285131c025569487e88df2e19d353fa" rel="noopener noreferrer"&gt;External links 👀&lt;/a&gt;&lt;/p&gt;

</description>
      <category>googlesheets</category>
      <category>productivity</category>
      <category>habits</category>
    </item>
    <item>
      <title>Internet of Things — from zero to DIY Bitcoin Ticker</title>
      <dc:creator>Héctor de Isidro</dc:creator>
      <pubDate>Fri, 22 Feb 2019 22:47:30 +0000</pubDate>
      <link>https://forem.com/hector6872/internet-of-things--from-zero-to-diy-bitcoin-ticker-2d1k</link>
      <guid>https://forem.com/hector6872/internet-of-things--from-zero-to-diy-bitcoin-ticker-2d1k</guid>
      <description>&lt;h2&gt;
  
  
  tl;dr &lt;a href="https://github.com/hector6872/DIY-Bitcoin-Ticker" rel="noopener noreferrer"&gt;source code&lt;/a&gt; &amp;amp; &lt;a href="https://imgur.com/gallery/Yuvjj67" rel="noopener noreferrer"&gt;gallery&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;I’m sure almost everyone has heard at least once about &lt;strong&gt;&lt;a href="https://www.arduino.cc/" rel="noopener noreferrer"&gt;Arduino&lt;/a&gt;&lt;/strong&gt; and/or &lt;strong&gt;&lt;a href="https://www.raspberrypi.org/" rel="noopener noreferrer"&gt;Raspberry Pi&lt;/a&gt;&lt;/strong&gt; &lt;em&gt;low cost computers&lt;/em&gt;. Both are used in countless ingenious &lt;strong&gt;DIY&lt;/strong&gt; &lt;a href="https://create.arduino.cc/projecthub" rel="noopener noreferrer"&gt;electronic&lt;/a&gt; &lt;a href="https://www.raspberrypi.org/forums/viewforum.php?f=15&amp;amp;sid=95585e4b93a16bf8879382a5025493a4" rel="noopener noreferrer"&gt;projects&lt;/a&gt;, on their own or by using one of the many expansion modules available, due to their low price and small credit-card size form factor (even smaller if we refer to &lt;a href="https://www.arrow.com/en/research-and-events/articles/raspberry-pi-3-vs-raspberry-pi-zero-w" rel="noopener noreferrer"&gt;Raspberry Pi Zero&lt;/a&gt; model).&lt;/p&gt;

&lt;p&gt;But they aren’t the only ones (in fact there are many): among the most popular is &lt;strong&gt;&lt;a href="http://www.nodemcu.com/index_en.html" rel="noopener noreferrer"&gt;NodeMCU&lt;/a&gt;&lt;/strong&gt; &lt;em&gt;aka The Arduino Killer&lt;/em&gt;🏆 (based on &lt;strong&gt;&lt;a href="https://www.espressif.com/en/products/hardware/esp8266ex/overview" rel="noopener noreferrer"&gt;ESP8266&lt;/a&gt;&lt;/strong&gt; wifi-&lt;a href="https://en.wikipedia.org/wiki/System_on_a_chip" rel="noopener noreferrer"&gt;soc&lt;/a&gt;)&lt;/p&gt;

&lt;h3&gt;
  
  
  What are their differences?
&lt;/h3&gt;

&lt;p&gt;They are &lt;a href="https://cybergibbons.com/uncategorized/arduino-misconceptions-4-the-arduino-is-obsolete-now-the-raspberry-pi-exists/" rel="noopener noreferrer"&gt;totally different concepts&lt;/a&gt; because they were conceived to perform different tasks: while &lt;strong&gt;Arduino&lt;/strong&gt; is actually an &lt;a href="https://www.rugged-circuits.com/10-ways-to-destroy-an-arduino/" rel="noopener noreferrer"&gt;almost indestructible&lt;/a&gt; open source¹ &lt;strong&gt;microcontroller&lt;/strong&gt; which we can start playing with using a simple script (in C/C++; one application at a time) from the minute one, &lt;strong&gt;Raspberry Pi&lt;/strong&gt; is a &lt;em&gt;full&lt;/em&gt; &lt;strong&gt;minicomputer&lt;/strong&gt;² on one small board (&lt;a href="https://en.wikipedia.org/wiki/Single-board_computer" rel="noopener noreferrer"&gt;SBC&lt;/a&gt;) that runs a dedicated &lt;a href="https://www.raspberrypi.org/downloads/" rel="noopener noreferrer"&gt;Linux OS distribution&lt;/a&gt; (so it can be programmed using a wide variety of languages) which allows us to run different programs very much like we do on our desktop computers.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“If your application is more about controlling things, the Arduino is probably a better choice. While if you need to process lots of data the PI is your best bet”&lt;br&gt;
 — &lt;a href="https://www.youtube.com/watch?v=7vhvnaWUZjE" rel="noopener noreferrer"&gt;Arduino vs Raspberry Pi — Which is best?&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That said, more like a microcontroller than a minicomputer, we have our hero &lt;strong&gt;&lt;a href="https://github.com/nodemcu/nodemcu-devkit" rel="noopener noreferrer"&gt;NodeMCU&lt;/a&gt;: an Arduino-compatible &lt;a href="https://github.com/esp8266/Arduino" rel="noopener noreferrer"&gt;dev&lt;/a&gt; board with built-in WIFI for &lt;a href="https://www.aliexpress.com/item/ESP8266-CH340G-NodeMcu-Lua-V3-ESP8266-CP2102-NodeMcu-Lua-V2-Wireless-Module-ESP8266-ESP-12E-Micro/32909262615.html" rel="noopener noreferrer"&gt;less than $5&lt;/a&gt;&lt;/strong&gt; that also supports &lt;a href="https://www.lua.org/" rel="noopener noreferrer"&gt;Lua&lt;/a&gt; scripting language (there are several variants of &lt;strong&gt;ESP8266&lt;/strong&gt; chipset out there but it’s highly recommended to buy from the &lt;a href="https://frightanic.com/iot/comparison-of-esp8266-nodemcu-development-boards/" rel="noopener noreferrer"&gt;second-generation&lt;/a&gt; &lt;strong&gt;ESP-12E&lt;/strong&gt; variant because it has a &lt;a href="https://tttapa.github.io/ESP8266/Chap02%20-%20Hardware.html" rel="noopener noreferrer"&gt;built-in power regulator&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  NodeMCU on Arduino IDE
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Arduino platform&lt;/strong&gt; has its own &lt;strong&gt;&lt;a href="https://www.arduino.cc/en/Main/Software" rel="noopener noreferrer"&gt;IDE&lt;/a&gt;&lt;/strong&gt; (more of an editor than an &lt;a href="https://imgflip.com/i/2nzd3m" rel="noopener noreferrer"&gt;IDE&lt;/a&gt; actually) available for free and it is quite easy to make it compatible with NodeMCU:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Install standalone Arduino IDE following &lt;a href="https://www.arduino.cc/en/Guide/HomePage" rel="noopener noreferrer"&gt;these instructions&lt;/a&gt; depending on your machine’s OS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Launch Arduino IDE&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Open &lt;em&gt;Preferences&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the link &lt;a href="http://arduino.esp8266.com/stable/package_esp8266com_index.json" rel="noopener noreferrer"&gt;http://arduino.esp8266.com/stable/package_esp8266com_index.json&lt;/a&gt; to &lt;em&gt;Additional Boards Manager URLs&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open &lt;em&gt;Boards Manager…&lt;/em&gt; (menu &lt;em&gt;Tools&lt;/em&gt; &amp;gt; &lt;em&gt;Board…&lt;/em&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Search for &lt;em&gt;ESP8266&lt;/em&gt; and install it&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open menu &lt;em&gt;Tools&lt;/em&gt; &amp;gt; &lt;em&gt;Board&lt;/em&gt;… and select &lt;em&gt;NodeMCU &lt;a href="https://frightanic.com/iot/comparison-of-esp8266-nodemcu-development-boards/" rel="noopener noreferrer"&gt;x.x…&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Done!&lt;/p&gt;

&lt;h3&gt;
  
  
  Hello world!
&lt;/h3&gt;

&lt;p&gt;Now that our development environment is ready, let’s verify that everything works well using one of the most easiest &lt;a href="https://www.arduino.cc/en/Tutorial/BuiltInExamples" rel="noopener noreferrer"&gt;examples included&lt;/a&gt;: &lt;strong&gt;&lt;a href="https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay" rel="noopener noreferrer"&gt;LED Blinking&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We will use stock “&lt;a href="https://www.arduino.cc/en/Main/FAQ#toc13" rel="noopener noreferrer"&gt;Arduino language&lt;/a&gt;” (limiting the project to a single file with .ino extension known as “sketch”) along this journey which is basically &lt;a href="https://www.arduino.cc/reference/en/" rel="noopener noreferrer"&gt;a set of C/C++ functions&lt;/a&gt; (IMO they have done an excellent job in general abstracting the different interfaces because even a beginner would able to read and understand easily almost all the code). Advanced use cases perhaps will need a &lt;em&gt;real&lt;/em&gt; IDE³ plus the use of plain C/C++ language.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Launch Arduino IDE&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Connect the board to the computer (it’s quite common to tape the back to ensure that no metal scrap can short-circuit the board)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select the correct &lt;code&gt;COM&lt;/code&gt; port for your serial adapter (&lt;em&gt;Tools&lt;/em&gt; &amp;gt; &lt;em&gt;Port…&lt;/em&gt;)⁴&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Load &lt;em&gt;Blink&lt;/em&gt; sketch (&lt;em&gt;File&lt;/em&gt; &amp;gt; &lt;em&gt;Examples&lt;/em&gt; &amp;gt; &lt;em&gt;ESP8266&lt;/em&gt; &amp;gt; &lt;em&gt;Blink&lt;/em&gt;). Nothing to explain here as we can see the code is very easy to understand⁵.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the following line to the very beginning of the example (because the example is written for an older module version and not for ESP-12): &lt;code&gt;#define LED_BUILTIN 2&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Upload it and wait a few seconds (the led should blink quickly during the uploading)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Welcome to life!&lt;/p&gt;

&lt;h3&gt;
  
  
  Serial monitor
&lt;/h3&gt;

&lt;p&gt;In order to make a real “Hello, World!” example we will modify the previous Blink example to print that well-known message.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Add &lt;code&gt;Serial.begin(9600); Serial.print(“Hello, World”);&lt;/code&gt; lines within &lt;code&gt;setup()&lt;/code&gt; method&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Upload it&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open &lt;em&gt;Serial Monitor&lt;/em&gt; (&lt;em&gt;Tools&lt;/em&gt; &amp;gt; &lt;em&gt;Serial Monitor&lt;/em&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select &lt;em&gt;9600 baud&lt;/em&gt; option in the drop-down list&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Push the &lt;em&gt;reset&lt;/em&gt; button on the board&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=iNkrF43SZEU" rel="noopener noreferrer"&gt;Logging&lt;/a&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  Who is out there?
&lt;/h2&gt;

&lt;p&gt;As we have seen before, our tiny and dirt cheap &lt;strong&gt;NodeMCU has a built-in WIFI chipset&lt;/strong&gt;. Therefore, the second thing we will do is display in the &lt;em&gt;Serial Monitor&lt;/em&gt; all the wireless networks available around us using again one of the included examples: &lt;em&gt;WifiScan&lt;/em&gt; (&lt;em&gt;Files&lt;/em&gt; &amp;gt; &lt;em&gt;Examples&lt;/em&gt; &amp;gt; &lt;em&gt;ESP8266WiFi&lt;/em&gt; &amp;gt; &lt;em&gt;WiFiScan&lt;/em&gt;).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Be sure to set the same baud rate in the code (&lt;code&gt;Serial.begin(xxx);&lt;/code&gt;) as in the Serial Monitor drop-down list.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Home is where the WIFI connects
&lt;/h3&gt;

&lt;p&gt;This time there is no example included showing us how to make the connection to our lovely Internet, so we will create a new script (&lt;em&gt;File&lt;/em&gt; &amp;gt; &lt;em&gt;New&lt;/em&gt;) containing the code below (as we can see the code is almost self-explanatory and doesn’t need any additional comment 🤞):&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;Check twice the ssid and/or password values before start to think the board is broken 😉&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Do you even fetch, bro?
&lt;/h3&gt;

&lt;p&gt;Now, it is time to start coding our project 👏, a &lt;strong&gt;Physical &lt;a href="https://bitcoin.org/en/" rel="noopener noreferrer"&gt;Bitcoin&lt;/a&gt; Ticker&lt;/strong&gt;, fetching some data from a well-known &lt;a href="https://pro.coinmarketcap.com/" rel="noopener noreferrer"&gt;free API&lt;/a&gt;⁶ (&lt;strong&gt;&lt;a href="https://coinmarketcap.com/" rel="noopener noreferrer"&gt;CoinMarketCap&lt;/a&gt;&lt;/strong&gt;).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Go to &lt;em&gt;Tools&lt;/em&gt; &amp;gt; &lt;em&gt;Manage Libraries&lt;/em&gt;, and search for &lt;strong&gt;&lt;a href="https://arduinojson.org/" rel="noopener noreferrer"&gt;ArduinoJson&lt;/a&gt;&lt;/strong&gt; (&lt;a href="https://arduinojson.org/v6/doc/upgrade/" rel="noopener noreferrer"&gt;6 or above&lt;/a&gt; version)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a new &lt;em&gt;sketch&lt;/em&gt; and paste the code below&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fill in &lt;code&gt;ssid&lt;/code&gt;, &lt;code&gt;password&lt;/code&gt; and &lt;code&gt;api_key&lt;/code&gt; variables (&lt;a href="https://pro.coinmarketcap.com/" rel="noopener noreferrer"&gt;get your API key here&lt;/a&gt;⁶)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Upload!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There is a &lt;a href="https://github.com/witnessmenow/arduino-coinmarketcap-api" rel="noopener noreferrer"&gt;wrapper around CoinMarketCap API&lt;/a&gt; available for NodeMCU but it seems pretty abandoned and old so we will use our own implementation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Rise &amp;amp; shine
&lt;/h2&gt;

&lt;p&gt;At this point we all agree on this: it makes no sense to use an &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Internet_of_things" rel="noopener noreferrer"&gt;IoT&lt;/a&gt;&lt;/strong&gt; device of any kind to dump the information to the &lt;em&gt;Serial Monitor&lt;/em&gt;. So, &lt;strong&gt;we should use a display to make our BitCoin Ticker really useful&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Although there are a vast offer of &lt;a href="https://en.wikipedia.org/wiki/I%C2%B2C" rel="noopener noreferrer"&gt;I2C&lt;/a&gt;/&lt;a href="https://en.wikipedia.org/wiki/Serial_Peripheral_Interface" rel="noopener noreferrer"&gt;SPI&lt;/a&gt; displays models (ie SSD1306 or SH1106 models) to buy (these kind of add-on boards are also known as “&lt;em&gt;shields&lt;/em&gt;”) we don’t want to mess around with cables, &lt;a href="https://en.wikipedia.org/wiki/General-purpose_input/output" rel="noopener noreferrer"&gt;GPIOs&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Breadboard" rel="noopener noreferrer"&gt;breadboards&lt;/a&gt;, voltages and &lt;a href="https://www.arduino.cc/glossary/en/" rel="noopener noreferrer"&gt;that sort of thing&lt;/a&gt; by the moment so, &lt;strong&gt;for just less than $7,&lt;/strong&gt; we can buy an &lt;a href="https://www.aliexpress.com/item/NODEMCU-Wifi-ESP8266-ESP-12F-For-Wemos-For-Arduino-ESP12F-0-96-0-96-Inch-OLED/32890892129.html" rel="noopener noreferrer"&gt;ESP8266+OLED&lt;/a&gt; built-in on &lt;a href="https://en.wikipedia.org/wiki/Printed_circuit_board" rel="noopener noreferrer"&gt;PCB&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Using the easiest (also the cheapest) option described above we must install the &lt;a href="https://github.com/olikraus/u8g2" rel="noopener noreferrer"&gt;U8g2lib&lt;/a&gt; library (even if we follow another path that library support &lt;a href="https://github.com/olikraus/u8g2/wiki/u8g2setupc#setup-function-reference" rel="noopener noreferrer"&gt;almost all types of displays&lt;/a&gt; so I can stop recommending it), paste the code below and upload it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We have to setup the display driver at the beginning using one of the default constructors the library give us. Printed on its back side we can find where SDA and SCL are &lt;a href="https://raw.githubusercontent.com/nodemcu/nodemcu-devkit/master/Documents/NODEMCU-DEVKIT-INSTRUCTION-EN.png" rel="noopener noreferrer"&gt;connect to&lt;/a&gt;. For example SDA-D1 and SCL-D2 means that the first one is connected to GPIO5 (D1) and the second to GPIO04 (D2). So later we use these values as data (5 in this case) and clock (4).&lt;br&gt;&lt;br&gt;
 Example working for the ESP8266+OLED said above: &lt;code&gt;U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(*/* rotation=*/ *U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ 4, /* data=*/ 5);&lt;/code&gt;&lt;br&gt;&lt;br&gt;
 For more details on those parameters refer to &lt;a href="https://github.com/olikraus/u8g2/wiki/u8g2reference#carduino-example" rel="noopener noreferrer"&gt;this&lt;/a&gt; example.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Where do we go from here?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“To infinity and beyond!” — &lt;a href="https://en.wikipedia.org/wiki/Buzz_Lightyear" rel="noopener noreferrer"&gt;Buzz Lightyear&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As we have already seen in a couple of hours and a few lines of code we can have our own &lt;strong&gt;&lt;a href="https://github.com/hector6872/DIY-Bitcoin-Ticker" rel="noopener noreferrer"&gt;Bitcoin Ticker&lt;/a&gt;&lt;/strong&gt; running. So based on this and reading in depth all the shared links we will able &lt;a href="https://imgur.com/gallery/Yuvjj67" rel="noopener noreferrer"&gt;to improve it&lt;/a&gt; or &lt;a href="https://www.esp8266.com/viewforum.php?f=11" rel="noopener noreferrer"&gt;start a new project&lt;/a&gt; totally different. &lt;strong&gt;No limits! 🚀&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Thanks for reading. If you enjoyed this article, feel free to hit that clap button 👏 as much as you can to help others find it.
&lt;/h3&gt;

&lt;p&gt;This article was originally published on &lt;a href="https://medium.com/@hector6872/internet-of-things-from-zero-to-diy-bitcoin-ticker-7ae22f5dd269" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;[1] We can buy an official &lt;strong&gt;Arduino&lt;/strong&gt; in &lt;a href="https://store.arduino.cc/" rel="noopener noreferrer"&gt;their online store&lt;/a&gt; &lt;a href="https://store.arduino.cc/arduino-uno-rev3" rel="noopener noreferrer"&gt;for about $25&lt;/a&gt; &lt;strong&gt;without WIFI module&lt;/strong&gt; (supporting the company to continue researching and improving their products) but as it is an open source product there are some manufacturers who have created perfect clones that we can buy for &lt;a href="https://www.aliexpress.com/item/One-set-high-quality-WEIYU-UNO-R3-CH340G-MEGA328P-Chip-16Mhz-UNO-R3/32865259855.html" rel="noopener noreferrer"&gt;less than $3&lt;/a&gt; (&lt;a href="https://www.ebay.com/sch/i.html?_nkw=arduino" rel="noopener noreferrer"&gt;Ebay&lt;/a&gt; is also a great place to buy them). &lt;br&gt;[2] One of the “biggest cons” of &lt;strong&gt;Raspberry Pi&lt;/strong&gt; is that its hardware is not open source (Broadcom has an agreement with the Foundation to sell its chipset on exclusivity) so we cannot buy any cheaper Chinese clone anywhere.&lt;br&gt;[3] There are more powerful &lt;a href="https://www.survivingwithandroid.com/2018/08/10-arduino-ide-alternative-to-start-programming.html" rel="noopener noreferrer"&gt;alternatives&lt;/a&gt; (personally I always stay as far as I can from that &lt;a href="https://giphy.com/gifs/vh1-AENSKmYsLY5S2F4QQK" rel="noopener noreferrer"&gt;Eclipse&lt;/a&gt; thing) to the official “IDE” such as &lt;strong&gt;&lt;a href="https://platformio.org/" rel="noopener noreferrer"&gt;PlatformIO&lt;/a&gt;&lt;/strong&gt; (which looks promising but perhaps quite complicated IMO) or this other &lt;strong&gt;&lt;a href="https://github.com/Microsoft/vscode-arduino" rel="noopener noreferrer"&gt;Visual Studio Code extension for Arduino&lt;/a&gt;&lt;/strong&gt; (which is backed by Microsoft)&lt;br&gt;[4] On &lt;strong&gt;macOS&lt;/strong&gt; you will probably have to install &lt;a href="https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers" rel="noopener noreferrer"&gt;one&lt;/a&gt; of these &lt;a href="https://github.com/nodemcu/nodemcu-devkit/wiki/Getting-Started-on-OSX" rel="noopener noreferrer"&gt;drivers&lt;/a&gt; (Bluetooth is not a valid port to uploading our sketches 😆) &lt;br&gt;[5] Anyway &lt;a href="https://arduino-esp8266.readthedocs.io/en/2.4.2/" rel="noopener noreferrer"&gt;here&lt;/a&gt; is your new Bible.&lt;br&gt;[6] They will be migrating their &lt;a href="https://coinmarketcap.com/api/" rel="noopener noreferrer"&gt;Public API&lt;/a&gt; to a “&lt;strong&gt;&lt;a href="https://pro.coinmarketcap.com/" rel="noopener noreferrer"&gt;Professional API&lt;/a&gt;&lt;/strong&gt;” on Dec 4th, 2018. For our intentions their &lt;strong&gt;&lt;a href="https://pro.coinmarketcap.com/pricing" rel="noopener noreferrer"&gt;FREE&lt;/a&gt;&lt;/strong&gt; &lt;a href="https://pro.coinmarketcap.com/signup?plan=0" rel="noopener noreferrer"&gt;tier&lt;/a&gt; meets our needs 😉&lt;/p&gt;




&lt;p&gt;&lt;a href="https://gist.github.com/hector6872/e659c389bafcf8663e5c084d67b3cfeb" rel="noopener noreferrer"&gt;External links 👀&lt;/a&gt;&lt;/p&gt;

</description>
      <category>arduino</category>
      <category>raspberrypi</category>
      <category>bitcoin</category>
      <category>diy</category>
    </item>
    <item>
      <title>A walk on the dark side</title>
      <dc:creator>Héctor de Isidro</dc:creator>
      <pubDate>Wed, 03 Oct 2018 09:47:47 +0000</pubDate>
      <link>https://forem.com/hector6872/a-walk-on-the-dark-side-14ei</link>
      <guid>https://forem.com/hector6872/a-walk-on-the-dark-side-14ei</guid>
      <description>&lt;h2&gt;
  
  
  There has been an Awakening…
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fraxwb42bsj8dczzmdfma.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fraxwb42bsj8dczzmdfma.jpeg" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This summer &lt;a href="https://twitter.com/jberlana" rel="noopener noreferrer"&gt;our tech lead&lt;/a&gt; told us that we were allowed to spend a percentage of our time &lt;a href="https://lolamarket.com/" rel="noopener noreferrer"&gt;at work&lt;/a&gt; doing or researching about something we weren’t used to (&lt;a href="https://www.businessinsider.com/google-20-percent-time-policy-2015-4?IR=T" rel="noopener noreferrer"&gt;a kind of Google’s “20% time policy”&lt;/a&gt;… but in the good way). There was only one condition: we would have to give a tech talk to the rest of the team on the chosen topic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Teaching is the best way to learn.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;Because I often make fun of the programming languages that my teammates use in their daily work (100% trolling just for fun I swear; &lt;a href="https://www.businessinsider.com/why-coders-get-into-religious-wars-over-programming-languages-2015-6?IR=T" rel="noopener noreferrer"&gt;I do not want to start any kind of nonsense programming language war&lt;/a&gt;) I thought it would be great to pay them back using a language I haven’t touched for ages: &lt;strong&gt;&lt;a href="https://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/" rel="noopener noreferrer"&gt;PHP&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Idea
&lt;/h2&gt;

&lt;p&gt;I’m a real fan of automation (&lt;a href="https://xkcd.com/1205/" rel="noopener noreferrer"&gt;even when we spend more time coding&lt;/a&gt; the thing than the time it actually saves us afterwards), so based on a function we all use at work almost every day known as “&lt;a href="https://confluence.atlassian.com/bitbucket/resolve-issues-automatically-when-users-push-code-221451126.html" rel="noopener noreferrer"&gt;automatic issue closing via commit messages&lt;/a&gt;” (I guess all web-based Git repository managers have a fancy name for that) I started to code &lt;strong&gt;a &lt;a href="https://medium.com/@hector6872/moving-from-github-to-bitbucket-30c12dd8aea5" rel="noopener noreferrer"&gt;Bitbucket&lt;/a&gt; Webhook¹.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Webho… what?
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Webhook" rel="noopener noreferrer"&gt;WebHook&lt;/a&gt; is a &lt;code&gt;HTTP&lt;/code&gt; callback&lt;/strong&gt;: a web application implementing a webhook will &lt;code&gt;POST&lt;/code&gt; a message (payload) to an user-defined &lt;code&gt;URL&lt;/code&gt; (web service) when something happens. It’s that simple.&lt;/p&gt;

&lt;p&gt;So, in my case, what I coded was a &lt;a href="https://medium.com/@hector6872/how-good-are-git-hooks-75ae4c3fe3f5" rel="noopener noreferrer"&gt;Githook&lt;/a&gt; but &lt;a href="https://www.reddit.com/r/ProgrammerHumor/comments/7zhco9/frontend_vs_backend/" rel="noopener noreferrer"&gt;on the other side&lt;/a&gt; (basically it connects Bitbucket+&lt;a href="https://developers.trello.com/" rel="noopener noreferrer"&gt;Trello&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;I don’t think it’s worth giving further details about my project itself but I can summarize everything in these points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Someone on the team pushes to a &lt;a href="https://confluence.atlassian.com/bitbucket/manage-webhooks-735643732.html" rel="noopener noreferrer"&gt;repo&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bitbucket sends a &lt;a href="https://confluence.atlassian.com/bitbucket/event-payloads-740262817.html" rel="noopener noreferrer"&gt;payload&lt;/a&gt; to our webservice&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It parses that information and then: &lt;strong&gt;do whatever we can imagine.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;It was very fun to get out of my &lt;a href="http://lmgtfy.com/?q=comfort+zone+where+the+magic+happens" rel="noopener noreferrer"&gt;comfort zone&lt;/a&gt; (I can’t tell how many years I’ve been coding exclusively for &lt;a href="https://play.google.com/store/apps/details?id=com.comprea.client" rel="noopener noreferrer"&gt;Android&lt;/a&gt; platform) and I can confirm that I’ve taken advantage of the great opportunity we have at work (I wish everyone had it): &lt;strong&gt;I have learned a lot&lt;/strong&gt; (and now I am able to troll them &lt;a href="https://twitter.com/Syknapse" rel="noopener noreferrer"&gt;even more&lt;/a&gt; 🤷).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PS: &lt;a href="https://lolamarket.com/jobs/" rel="noopener noreferrer"&gt;we’re hiring!&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclaimer
&lt;/h2&gt;

&lt;p&gt;There are neither slides (I splitted my tech talk into: a code review where my teammates got their revenge pointing up all my mistakes 😃 &amp;amp; a live demo) nor public repository (I don’t dare to make it public because I know it’s not as good as I’d like) but &lt;a href="https://twitter.com/Jokantaro" rel="noopener noreferrer"&gt;someone from my team &lt;/a&gt;(who’s a real Jedi in PHP) thought the idea could be improved (which I think is an amazing proposition because we can still learn about it) so maybe in the future we’ll release something based on this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://twitter.com/LolaMarket_tech" rel="noopener noreferrer"&gt;Stay tuned!&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This article was originally published on &lt;a href="https://medium.com/@hector6872/a-walk-on-the-dark-side-669213cc2260" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;[1] Even though it could be a simple script I demanded of myself to meet some requirements: neither use frameworks nor libraries of any kind, follow good practices, patterns and SOLID, and add some tests (&lt;a href="https://phpunit.de/" rel="noopener noreferrer"&gt;PHPUnit&lt;/a&gt; is love, my friends).&lt;/p&gt;




&lt;p&gt;&lt;a href="https://gist.github.com/hector6872/25fcd2ab507f2293c8ab8720983afcc4" rel="noopener noreferrer"&gt;External links 👀&lt;/a&gt;&lt;/p&gt;

</description>
      <category>career</category>
      <category>motivation</category>
      <category>php</category>
      <category>coding</category>
    </item>
    <item>
      <title>Object-oriented programming and Greek mythology</title>
      <dc:creator>Héctor de Isidro</dc:creator>
      <pubDate>Tue, 21 Aug 2018 08:10:23 +0000</pubDate>
      <link>https://forem.com/hector6872/object-oriented-programming-and-greek-mythology-6jg</link>
      <guid>https://forem.com/hector6872/object-oriented-programming-and-greek-mythology-6jg</guid>
      <description>&lt;h2&gt;
  
  
  Principles and laws
&lt;/h2&gt;

&lt;p&gt;We often find code like this and we do not give it any importance because it is quite common:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;model&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"whatever"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;.*&lt;/span&gt;&lt;span class="n"&gt;isNotEmpty&lt;/span&gt;&lt;span class="p"&gt;*())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  &lt;span class="c1"&gt;// &amp;lt;&amp;lt;&amp;lt; look at this !!!&lt;/span&gt;
    &lt;span class="nf"&gt;doThis&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;doThat&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;`model`&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="kd"&gt;data class&lt;/span&gt; &lt;span class="nc"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Color&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;RED&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alright, &lt;a href="https://www.youtube.com/watch?v=rSjK2Oqrgic" rel="noopener noreferrer"&gt;move on, nothing to see here, please disperse&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Then, for instance, the business requirements changes and we also have to check wether its &lt;code&gt;color&lt;/code&gt; is equals to &lt;code&gt;Color.GREEN&lt;/code&gt; to validate that model, forcing us to look for that &lt;code&gt;if&lt;/code&gt; throughout the project to update it, wasting time, making changes to a bunch of files (&lt;em&gt;aka &lt;a href="https://refactoring.guru/smells/shotgun-surgery" rel="noopener noreferrer"&gt;shotgun surgery code smell&lt;/a&gt;&lt;/em&gt;) and/or breaking something somewhere else.&lt;/p&gt;

&lt;p&gt;At the end, we will pray that those requirements will not change again. But they always can change.&lt;/p&gt;

&lt;p&gt;The problem here were not the requirements but the design: &lt;a href="https://martinfowler.com/bliki/TellDontAsk.html" rel="noopener noreferrer"&gt;why are we still asking instead of telling?&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Tell, don’t ask (TDA) principle about?
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Procedural code gets information then makes decisions. Object-oriented code tells objects to do things. &lt;br&gt;
 — Alec Sharp &lt;a href="https://www.amazon.com/Smalltalk-Example-Developers-Alec-Sharp/dp/0079130364" rel="noopener noreferrer"&gt;“Smalltalk By Example”&lt;/a&gt; McGraw-Hill, 1997&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Making decisions outside objects violates their encapsulation so &lt;strong&gt;instead of &lt;a href="https://www.martinfowler.com/bliki/GetterEradicator.html" rel="noopener noreferrer"&gt;asking objects about their state&lt;/a&gt; and then making a decision, we should tell objects what to do.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To tell is a command, to ask is a query.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We should stop using the infamous &lt;a href="https://en.wikipedia.org/wiki/Anemic_domain_model" rel="noopener noreferrer"&gt;Anemic Domain Model&lt;/a&gt; &lt;a href="https://www.martinfowler.com/bliki/AnemicDomainModel.html" rel="noopener noreferrer"&gt;antipattern&lt;/a&gt; everywhere and &lt;strong&gt;start placing the data and methods that operate on that data in the same place&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;model&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"whatever"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isValid&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;doThis&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;doThat&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;`model`&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="kd"&gt;data class&lt;/span&gt; &lt;span class="nc"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Color&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;RED&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;isValid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isNotEmpty&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="nc"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;GREEN&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By making the changes shown above we have hidden the implementation details, making our code easier to understand and &lt;a href="https://en.wikipedia.org/wiki/Don't_repeat_yourself" rel="noopener noreferrer"&gt;maintain&lt;/a&gt;: &lt;strong&gt;next time any changes around that model will not affect the rest of our project&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principles are not laws
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpjrh3zh9bd5ubh48y1si.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpjrh3zh9bd5ubh48y1si.jpeg" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We must always keep encapsulation in mind, but sometimes we have to find a balance between using &lt;strong&gt;TDA&lt;/strong&gt; or not because strictly obeying it as if it were a law has some drawbacks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;classes tend to be bigger,&lt;/strong&gt; increasing their complexity and making them more difficult to deal with&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;the number of responsibilities increases&lt;/strong&gt; (&lt;em&gt;“With great power comes great responsibility.” — &lt;a href="https://en.wikipedia.org/wiki/Uncle_Ben#%22With_great_power_comes_great_responsibility%22" rel="noopener noreferrer"&gt;Uncle Ben&lt;/a&gt;¹&lt;/em&gt;) and also their coupling (think here of the typical object that is a central part of an application: we do not want god objects)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;we may break other principles&lt;/strong&gt; such as &lt;a href="https://en.wikipedia.org/wiki/Single_responsibility_principle" rel="noopener noreferrer"&gt;SRP&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;h1&gt;
  
  
  Tell, don’t ask principle cannot be treated like the rule of thumb (like many other principles) because we often have to ask questions.
&lt;/h1&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Law of Demeter
&lt;/h2&gt;

&lt;p&gt;Normally related to the &lt;strong&gt;TDA&lt;/strong&gt; principle we often come across the &lt;a href="https://en.wikipedia.org/wiki/Law_of_Demeter" rel="noopener noreferrer"&gt;Law of Demeter&lt;/a&gt;² (&lt;em&gt;LoD aka “principle of least knowledge”&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LoD can be summed up as “friendship among objects”&lt;/strong&gt;: objects must be independent and be in touch only with its “closest immediate friends” and “don’t talk to strangers”.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A friend of my friend is…? (According to LoD) NOT my friend³.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Therefore, to achieve this behaviour we must obey this simple rule: any method of an object must only call the methods that belong to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;itself&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;its parameters (which are objects as well)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;any objects it creates/instantiates&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;its direct component objects&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;A&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;c&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;C&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nc"&gt;D&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Although some people boil down this &lt;em&gt;law&lt;/em&gt; to “counting dots” (where &lt;code&gt;model.getX().getY().doSomething()&lt;/code&gt; is wrong but &lt;code&gt;model.doSomethingXY()&lt;/code&gt; is fine &lt;em&gt;for no clear reason&lt;/em&gt;…) and tend to use too many wrapper classes (which is the most common outcome when we try to avoid &lt;strong&gt;LoD&lt;/strong&gt;), &lt;strong&gt;we should think of LoD more as a design guideline than a law for itself&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Imagine you are in a store and the item you are purchasing is $25&lt;br&gt;
Do you give the clerk $25?&lt;br&gt;
Or do you give the clerk your wallet and ley him/her retrieve the $25?&lt;br&gt;
 — Misko Hevery &lt;a href="https://youtu.be/RlfLCWKxHJ0?t=941" rel="noopener noreferrer"&gt;“The Clean Code Talks — Don’t Look For Things!”&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;


&lt;/blockquote&gt;

&lt;p&gt;Let’s see the typical paperboy example (described deeply in &lt;a href="http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/paper-boy/demeter.pdf" rel="noopener noreferrer"&gt;this paper&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Below is an excerpt of code that does not follow &lt;strong&gt;LoD&lt;/strong&gt; (either &lt;strong&gt;TDA&lt;/strong&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="c1"&gt;// given these classes&lt;/span&gt;

&lt;span class="kd"&gt;data class&lt;/span&gt; &lt;span class="nc"&gt;Neighbour&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Wallet&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Wallet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;data class&lt;/span&gt; &lt;span class="nc"&gt;Wallet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;money&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Float&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0F&lt;/span&gt;  &lt;span class="c1"&gt;// please forgive me :(&lt;/span&gt;

    &lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// when payday comes &lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Paperboy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;companion&lt;/span&gt; &lt;span class="k"&gt;object&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;PRICE&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;2f&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;earnings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Float&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0F&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getMoney&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;neighbour&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Neighbour&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;neighbour&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;money&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nc"&gt;PRICE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;neighbour&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;money&lt;/span&gt; &lt;span class="p"&gt;-=&lt;/span&gt; &lt;span class="nc"&gt;PRICE&lt;/span&gt;
        &lt;span class="k"&gt;true&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;false&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;The&lt;/span&gt; &lt;span class="n"&gt;question&lt;/span&gt; &lt;span class="n"&gt;here&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;have&lt;/span&gt; &lt;span class="n"&gt;you&lt;/span&gt; &lt;span class="n"&gt;ever&lt;/span&gt; &lt;span class="n"&gt;seen&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;paperboy&lt;/span&gt; 
&lt;span class="n"&gt;taking&lt;/span&gt; &lt;span class="n"&gt;money&lt;/span&gt; &lt;span class="n"&gt;directly&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;neighbour&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, to follow a “real world” scenario we should make use of &lt;strong&gt;LoD&lt;/strong&gt; (plus &lt;strong&gt;TDA&lt;/strong&gt;) like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="c1"&gt;// given these classes&lt;/span&gt;

&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Payer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Service&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Float&lt;/span&gt;
    &lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Service&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;data class&lt;/span&gt; &lt;span class="nc"&gt;Neighbour&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Wallet&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Wallet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Payer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Service&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Float&lt;/span&gt;
    &lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;hasEnoughMoney&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;true&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;false&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;hasEnoughMoney&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Float&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;money&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;

    &lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;data class&lt;/span&gt; &lt;span class="nc"&gt;Wallet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;money&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Float&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0F&lt;/span&gt; &lt;span class="c1"&gt;// ok, I know :(&lt;/span&gt;

    &lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// when payday comes&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Paperboy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;earnings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Float&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0F&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Service&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;companion&lt;/span&gt; &lt;span class="k"&gt;object&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;PRICE&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;2f&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getPaid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Payer&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;payer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;PRICE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;earnings&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="n"&gt;everything&lt;/span&gt; &lt;span class="n"&gt;seems&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;little&lt;/span&gt; &lt;span class="n"&gt;more&lt;/span&gt; &lt;span class="n"&gt;complex&lt;/span&gt; &lt;span class="n"&gt;but&lt;/span&gt; 
&lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;paperboy&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;good&lt;/span&gt; &lt;span class="n"&gt;guy&lt;/span&gt; &lt;span class="n"&gt;who&lt;/span&gt; &lt;span class="n"&gt;ask&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;his&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;her&lt;/span&gt; 
&lt;span class="n"&gt;money&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="n"&gt;doesn&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="n"&gt;take&lt;/span&gt; &lt;span class="n"&gt;anything&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;anyone&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;wallet&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;:)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Making the connection among objects as loose as possible (“making them a little shy”) will help us to promote flexibility and facilitate code maintenance&lt;/strong&gt; (thanks to isolation any future changes will not have much impact on our code base) as well as enable us to test them without using lots of &lt;a href="https://twitter.com/damianguy/status/4977743956?s=19" rel="noopener noreferrer"&gt;chained mocks&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h1&gt;
  
  
  “True friendship isn’t about being inseparable, but about being separated and knowing nothing will changes” —&lt;a href="https://en.wikipedia.org/wiki/Ted_(film)" rel="noopener noreferrer"&gt;Ted&lt;/a&gt;
&lt;/h1&gt;
&lt;/blockquote&gt;

&lt;p&gt;This article was originally published on &lt;a href="https://medium.com/@hector6872/object-oriented-programming-and-greek-mythology-14c9b1271e34" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;[1] In case you are curious about the true origin of this quote: &lt;a href="https://quoteinvestigator.com/2015/07/23/great-power/" rel="noopener noreferrer"&gt;https://quoteinvestigator.com/2015/07/23/great-power/&lt;/a&gt;&lt;br&gt;
[2] “It is so named for its origin in the Demeter Project, an adaptive programming and aspect-oriented programming effort. The project was named in honor of &lt;a href="https://en.wikipedia.org/wiki/Demeter" rel="noopener noreferrer"&gt;Demeter&lt;/a&gt;” — &lt;a href="https://en.wikipedia.org/wiki/Law_of_Demeter" rel="noopener noreferrer"&gt;Wikipedia&lt;/a&gt;&lt;br&gt;
[3] “A friend to all is a friend to none.” — Aristotle (who was also Greek)&lt;/p&gt;




&lt;p&gt;&lt;a href="https://gist.github.com/hector6872/ad1a39005ce8eb16a665cc1e8812f8e7" rel="noopener noreferrer"&gt;External links 👀&lt;/a&gt;&lt;/p&gt;

</description>
      <category>oop</category>
      <category>principles</category>
      <category>design</category>
      <category>demeter</category>
    </item>
    <item>
      <title>Sealed (Class) with love</title>
      <dc:creator>Héctor de Isidro</dc:creator>
      <pubDate>Thu, 02 Aug 2018 19:42:18 +0000</pubDate>
      <link>https://forem.com/hector6872/sealed-class-with-love-4c79</link>
      <guid>https://forem.com/hector6872/sealed-class-with-love-4c79</guid>
      <description>&lt;h2&gt;
  
  
  Our new best travel companion ❤️
&lt;/h2&gt;

&lt;p&gt;Among the many features that Kotlin brings to us to improve and facilitate our life while programming there are the &lt;strong&gt;Sealed Classes¹&lt;/strong&gt;. These, combined with other features such as &lt;a href="https://kotlinlang.org/docs/reference/typecasts.html#smart-casts" rel="noopener noreferrer"&gt;Smart&lt;/a&gt; &lt;a href="https://try.kotlinlang.org/#/Examples/Basic%20syntax%20walk-through/is-checks%20and%20smart%20casts/is-checks%20and%20smart%20casts.kt" rel="noopener noreferrer"&gt;Casting&lt;/a&gt; and &lt;a href="https://kotlinlang.org/docs/reference/control-flow.html#when-expression" rel="noopener noreferrer"&gt;When&lt;/a&gt; &lt;a href="https://try.kotlinlang.org/#/Examples/Basic%20syntax%20walk-through/Use%20when/Use%20when.kt" rel="noopener noreferrer"&gt;Expressions&lt;/a&gt;, will lead to &lt;strong&gt;a new and safer way to model our applications&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a Sealed Class?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7gpvvwwwughnqezg12r8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7gpvvwwwughnqezg12r8.png" width="800" height="567"&gt;&lt;/a&gt; &lt;span&gt;“&lt;a href="https://kotlinlang.org/docs/reference/sealed-classes.html" rel="noopener noreferrer"&gt;Sealed classes&lt;/a&gt; are used for representing restricted class hierarchies…” - &lt;a href="https://www.youtube.com/watch?v=9CS7j5I6aOc" rel="noopener noreferrer"&gt;Mind blown / Mind explosion&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sealed Classes are said to be "Enum Types on steroids"&lt;/strong&gt;: &lt;a href="https://en.wikipedia.org/wiki/Algebraic_data_type" rel="noopener noreferrer"&gt;they both are&lt;/a&gt; restricted hierarchies, they both represent a set, they both are types, and they both can contain associated data, but… the first ones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cannot be instantiated directly because they are &lt;code&gt;abstract&lt;/code&gt; (and therefore, &lt;a href="https://gist.github.com/hector6872/b69c89d5b070eb0eb2ecc809f921bd54" rel="noopener noreferrer"&gt;they can have both abstract and non abstract methods and fields&lt;/a&gt;) &lt;/li&gt;
&lt;li&gt;can have subclasses and these can have multiples instances² which can contain
their own state&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;the type of such associated data may be different&lt;/strong&gt; (see the example below)&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;span&gt;Tip: if a subclass doesn’t keep state, it can just be an &lt;strong&gt;object&lt;/strong&gt;.&lt;/span&gt;

&lt;blockquote&gt;
&lt;p&gt;Sealed Classes make our intentions clear (and their use also makes our code look cleaner)&lt;/p&gt;

&lt;p&gt;Limitation (if we can call it that): subclasses must be declared in the same &lt;strong&gt;Kotlin file&lt;/strong&gt; as the Sealed Class itself.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  What about Smart Casting and When Expressions?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;When Expression&lt;/strong&gt; is the best partner for Sealed Classes. &lt;strong&gt;Using it as an expression makes it exhaustive&lt;/strong&gt;: we will have to handle each and every one of its subclasses (or use an &lt;code&gt;else&lt;/code&gt; clause in the worst case scenario 😞 ) or Kotlin’s compiler will complaint. This means that &lt;strong&gt;if we add a new subclass in the future, it will have to be handled as well&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftbot088ea82yvr9agow5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftbot088ea82yvr9agow5.png" width="654" height="145"&gt;&lt;/a&gt;&lt;span&gt;Exhaustiveness Checking AKA let the compiler remind us we need to update our code&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Going even further, thanks to the Kotlin’s &lt;strong&gt;Smart Casting&lt;/strong&gt; feature, each subclass will be casted inside its &lt;code&gt;is&lt;/code&gt; own clause, allowing us to access safely to its specific fields (saying goodbye to possible &lt;code&gt;ClassCastException&lt;/code&gt; exceptions 🏆).&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;span&gt;Tip: when comparing an &lt;strong&gt;object&lt;/strong&gt;, as there’s only one instance, we don’t need to check its type, so we can avoid the use of the &lt;strong&gt;is&lt;/strong&gt; operator&lt;/span&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Using&lt;/strong&gt; &lt;code&gt;when&lt;/code&gt; &lt;strong&gt;as a statement doesn’t make it exhaustive.&lt;/strong&gt; Fortunately, &lt;a href="https://gist.github.com/hector6872/99b007c498c919404f9961715ecbe5a7" rel="noopener noreferrer"&gt;we can alter that behaviour&lt;/a&gt; by making use of another well-known Kotlin’s feature: &lt;a href="https://kotlinlang.org/docs/reference/extensions.html#extensions" rel="noopener noreferrer"&gt;extensions&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Ok, it seems quite cool but: can we test those Sealed Classes?
&lt;/h4&gt;

&lt;p&gt;Of course, &lt;strong&gt;we can&lt;/strong&gt;. In fact, &lt;strong&gt;we&lt;/strong&gt; &lt;strong&gt;MUST&lt;/strong&gt; do it 😉&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Using &lt;a href="http://site.mockito.org/" rel="noopener noreferrer"&gt;Mockito&lt;/a&gt; as mocking framework for unit tests in Kotlin has some issues with the &lt;a href="https://kotlinlang.org/docs/reference/null-safety.html" rel="noopener noreferrer"&gt;Kotlin’s Null-Safety&lt;/a&gt; feature because some of its matchers return &lt;a href="https://github.com/mockito/mockito/blob/release/2.x/src/main/java/org/mockito/ArgumentMatchers.java#L145" rel="noopener noreferrer"&gt;Nulls&lt;/a&gt;, so we’ll have to use &lt;a href="https://github.com/nhaarman/mockito-kotlin" rel="noopener noreferrer"&gt;Mockito-Kotlin&lt;/a&gt; library which among other things solves these issues.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Last words
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn6ekndzce7sk77g160ov.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn6ekndzce7sk77g160ov.jpeg" width="800" height="432"&gt;&lt;/a&gt;&lt;span&gt;&lt;a href="https://www.youtube.com/watch?v=apFIxtQdpek&amp;amp;t=33" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=apFIxtQdpek&amp;amp;t=33&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;The concept of the &lt;strong&gt;Sealed Classes&lt;/strong&gt; is very simple but it’s the basis of a lot of new ideas and workflows. Please, feel free to let me know how you use them and why by leaving a comment below or tweet me over on &lt;a href="https://twitter.com/hector6872" rel="noopener noreferrer"&gt;@hector6872&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This article was originally published on &lt;a href="https://medium.com/@hector6872/sealed-class-with-love-e554063aa9c6" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;[1] Yep, I’ve written a little about this &lt;a href="https://medium.com/@hector6872/presenters-and-views-meet-the-interface-segregation-principle-1cd6c98f46bb" rel="noopener noreferrer"&gt;before&lt;/a&gt; (look for &lt;em&gt;“BONUS: Kotlin developers”&lt;/em&gt; part)&lt;br&gt; [2] Remember that a single-element &lt;code&gt;Enum&lt;/code&gt; type is one of the best ways to implement a &lt;a href="http://www.drdobbs.com/jvm/creating-and-destroying-java-objects-par/208403883?pgno=3" rel="noopener noreferrer"&gt;Singleton&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://gist.github.com/hector6872/2a928d798055c78bfac4635679a04fed" rel="noopener noreferrer"&gt;External links 👀&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>testing</category>
      <category>enum</category>
      <category>mockito</category>
    </item>
    <item>
      <title>Moving from GitHub to Bitbucket</title>
      <dc:creator>Héctor de Isidro</dc:creator>
      <pubDate>Thu, 02 Aug 2018 19:42:08 +0000</pubDate>
      <link>https://forem.com/hector6872/moving-from-github-to-bitbucket-dhc</link>
      <guid>https://forem.com/hector6872/moving-from-github-to-bitbucket-dhc</guid>
      <description>&lt;h2&gt;
  
  
  W̶h̶y̶ ̶a̶n̶d̶ how
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; This post is not related in any way to &lt;a href="https://news.microsoft.com/2018/06/04/microsoft-to-acquire-github-for-7-5-billion/" rel="noopener noreferrer"&gt;Microsoft’s recent acquisition of GitHub&lt;/a&gt; (I don’t really have a very strong opinion about it; although I hope that won’t affect us at all).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F19z1kv7ypofr2npohzcv.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F19z1kv7ypofr2npohzcv.jpeg" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next month, my &lt;a href="https://github.com/hector6872" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; annual subscription will end and I don’t want to renew it in order to reduce the high number of online services I currently pay for.&lt;br&gt; &lt;strong&gt;tl;dr: I’ll continue to use GitHub but not for private repositories.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are many alternatives out there, but I’ve decided to migrate my private repositories to &lt;a href="https://bitbucket.org/hector6872/" rel="noopener noreferrer"&gt;Bitbucket&lt;/a&gt;¹ (mainly because I’m used to using it at &lt;a href="https://lolamarket.com/" rel="noopener noreferrer"&gt;work&lt;/a&gt;²). The biggest obstacle is that they don’t provide any tool to import all the repos at once (we have to do the chore one by one…) so &lt;strong&gt;I’ve created a&lt;/strong&gt; &lt;a href="https://gist.github.com/hector6872/af8655427e6ec7741a82516713d99ebf" rel="noopener noreferrer"&gt;script&lt;/a&gt;&lt;strong&gt;³&lt;/strong&gt; to fill that gap. &lt;strong&gt;You’re welcome, Bitbucket&lt;/strong&gt; &lt;code&gt;:wink:&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Moving checklist
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://lmgtfy.com/?q=install+python+2.7" rel="noopener noreferrer"&gt;Python 2.7&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://gist.github.com/hector6872/af8655427e6ec7741a82516713d99ebf" rel="noopener noreferrer"&gt;FromGithubToBitbucket.py&lt;/a&gt; script (don’t forget to make it executable using &lt;code&gt;chmod +x&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/settings/tokens" rel="noopener noreferrer"&gt;GitHub personal acces token&lt;/a&gt; (scopes needed: &lt;em&gt;repo&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://bitbucket.org/account" rel="noopener noreferrer"&gt;Bitbucket app password&lt;/a&gt; ➡️ Bitbucket settings ➡️ App passwords (permissions needed: &lt;em&gt;Repositories write&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://bitbucket.org/account" rel="noopener noreferrer"&gt;Bitbucket OAuth consumer&lt;/a&gt; ➡️ Bitbucket settings ➡️ OAuth ➡️ OAuth consumers (permissions needed: &lt;em&gt;Repositories write&amp;amp;admin&lt;/em&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;As you can see, we won’t expose any of our account passwords, so we can delete those temporary credentials afterwards.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Moving day
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/hector6872/af8655427e6ec7741a82516713d99ebf#file-fromgithubtobitbucket-py-L4" rel="noopener noreferrer"&gt;Fill in the credentials&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/hector6872/af8655427e6ec7741a82516713d99ebf#file-fromgithubtobitbucket-py-L15" rel="noopener noreferrer"&gt;Setup what kind of repo do we want to import&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;**Run the script **and follow the instructions&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://giphy.com/explore/victory-dance" rel="noopener noreferrer"&gt;Dance&lt;/a&gt;!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article was originally published on &lt;a href="https://medium.com/@hector6872/moving-from-github-to-bitbucket-30c12dd8aea5" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;[1] Even though &lt;a href="https://twitter.com/Syknapse" rel="noopener noreferrer"&gt;some people&lt;/a&gt; think it’s the ugliest one &lt;code&gt;:wink:&lt;/code&gt;&lt;br&gt; [2] Also, I tried &lt;a href="https://gitlab.com/" rel="noopener noreferrer"&gt;Gitlab&lt;/a&gt; long time ago and IMO their website was running slow and sluggish. Perhaps they have solved this by now, IDK &lt;code&gt;:shrug:&lt;/code&gt;&lt;br&gt; [3] It has been tested under Linux/MacOS. What about Windows users? Well, can you tell me why you’re still using Windows? &lt;code&gt;:trollface:&lt;/code&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://gist.github.com/hector6872/fb65d6ca42c719221dfa8989e6cfef98" rel="noopener noreferrer"&gt;External links 👀&lt;/a&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>bitbucket</category>
      <category>python</category>
      <category>git</category>
    </item>
    <item>
      <title>To Queue or not to Queue?</title>
      <dc:creator>Héctor de Isidro</dc:creator>
      <pubDate>Thu, 02 Aug 2018 19:41:55 +0000</pubDate>
      <link>https://forem.com/hector6872/to-queue-or-not-to-queue-4d2a</link>
      <guid>https://forem.com/hector6872/to-queue-or-not-to-queue-4d2a</guid>
      <description>&lt;h2&gt;
  
  
  That should not be a question
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6d0s1wfm6bij3b29ou39.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6d0s1wfm6bij3b29ou39.jpeg" width="800" height="530"&gt;&lt;/a&gt;&lt;span&gt;&lt;a href="https://flashbak.com/waiting-in-line-to-see-star-wars-1977-2000-26505/" rel="noopener noreferrer"&gt;Waiting In Line To See Star Wars: 1977–2000&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No one likes to stand in line¹.&lt;/strong&gt; Most people hate to waste their time queuing up. We spend an average of &lt;a href="https://www.mirror.co.uk/news/uk-news/fascinating-facts-about-how-we-spend-the-days-410973" rel="noopener noreferrer"&gt;6 months&lt;/a&gt; of our adult lives waiting our &lt;a href="http://www.dailymail.co.uk/travel/travel_news/article-3269123/How-time-spending-line-Infographic-reveals-hours-wasted-queuing-world-s-popular-tourist-attractions-s-Rome-patience-needed.html" rel="noopener noreferrer"&gt;turn&lt;/a&gt; — almost 3 days a year. There are &lt;a href="https://www.amazon.com/Does-Other-Line-Always-Faster/dp/0761181229" rel="noopener noreferrer"&gt;books&lt;/a&gt; about queues. &lt;a href="https://www.imdb.com/title/tt7663984/" rel="noopener noreferrer"&gt;Documentaries&lt;/a&gt;². Even &lt;a href="https://www.youtube.com/watch?v=_CBD2z51u5c" rel="noopener noreferrer"&gt;academic experts&lt;/a&gt; in queues. But then, when we are coding, we often forget to use &lt;code&gt;queues&lt;/code&gt; and end up messing around with &lt;code&gt;lists&lt;/code&gt; instead.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;All things work better when you use the right tool.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  FIFO or LIFO1!!!
&lt;/h4&gt;

&lt;p&gt;A &lt;a href="https://www.youtube.com/watch?v=IPxBKxU8GIQ" rel="noopener noreferrer"&gt;queue&lt;/a&gt; in a supermarket is &lt;strong&gt;FIFO.&lt;/strong&gt; The way we usually &lt;a href="https://media.giphy.com/media/8RH4MrJPTnVRK/giphy.gif" rel="noopener noreferrer"&gt;stack boxes&lt;/a&gt; is &lt;strong&gt;LIFO.&lt;/strong&gt; &lt;strong&gt;FIFO&lt;/strong&gt; stands for &lt;em&gt;“First In, First Out”³.&lt;/em&gt; &lt;strong&gt;LIFO&lt;/strong&gt; is the acronym for &lt;em&gt;“Last In, First Out”.&lt;/em&gt; That’s it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F72as6apqo8f1n3vv2oyz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F72as6apqo8f1n3vv2oyz.png" width="478" height="531"&gt;&lt;/a&gt;&lt;br&gt;
&lt;span&gt;I used &lt;a href="https://www.draw.io/" rel="noopener noreferrer"&gt;draw.io&lt;/a&gt; to draw this diagram. Awesome tool!&lt;/span&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When implementing &lt;strong&gt;FIFO&lt;/strong&gt; queues we usually use &lt;code&gt;add&lt;/code&gt;, &lt;code&gt;peek&lt;/code&gt; (returns, but does not remove, the head of the queue) and &lt;code&gt;poll&lt;/code&gt; (returns and removes the head of the queue) methods, while we refer to them, respectively, as &lt;code&gt;push&lt;/code&gt;, &lt;code&gt;peek&lt;/code&gt; and &lt;code&gt;pop&lt;/code&gt; in **LIFO **stacks.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;
  
  
  The STACK, the QUEUE and the DEQUE
&lt;/h4&gt;

&lt;p&gt;In a &lt;code&gt;stack&lt;/code&gt; we can only add and remove elements from one end (&lt;strong&gt;LIFO&lt;/strong&gt;), in a &lt;code&gt;queue&lt;/code&gt; we add elements to one end and remove them from the other (&lt;strong&gt;FIFO&lt;/strong&gt;) and, joining those two worlds we have the &lt;code&gt;deque&lt;/code&gt; (aka &lt;em&gt;“Double Ended Queue”&lt;/em&gt;) where we can add and remove elements from both ends. &lt;strong&gt;None of them allows random access to the elements.&lt;/strong&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;In JAVA you &lt;em&gt;should&lt;/em&gt; use &lt;code&gt;deque&lt;/code&gt; to model a &lt;code&gt;stack&lt;/code&gt; because the Stack class &lt;a href="https://keithwilliamstechblog.wordpress.com/2016/02/13/why-the-java-stack-class-is-bad/" rel="noopener noreferrer"&gt;is considered obsolete&lt;/a&gt; (it extends the Vector class and inherits all its methods, making it possible to break the &lt;strong&gt;LIFO&lt;/strong&gt; principle).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  So, &lt;a href="https://media.giphy.com/media/d3mlE7uhX8KFgEmY/source.gif" rel="noopener noreferrer"&gt;don’t reinvent the wheel&lt;/a&gt;⁴.
&lt;/h3&gt;

&lt;p&gt;This article was originally published on &lt;a href="https://medium.com/@hector6872/to-queue-or-not-to-queue-695af6e18bdb" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;[1] Ok, there are some &lt;a href="https://www.theatlantic.com/technology/archive/2011/10/how-long-people-waited-be-first-line-buy-apple-products/337087/" rel="noopener noreferrer"&gt;weird&lt;/a&gt; &lt;a href="https://www.independent.co.uk/life-style/gadgets-and-tech/news/iphone-x-latest-updates-news-apple-fans-queuing-photos-world-get-new-phone-a8035321.html" rel="noopener noreferrer"&gt;exceptions&lt;/a&gt;&lt;code&gt;:facepalm:&lt;/code&gt;&lt;br&gt; [2] There is always an alternative &lt;a href="https://www.youtube.com/watch?v=ZyNz8UHHrxE" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=ZyNz8UHHrxE&lt;/a&gt; (in Spanish)&lt;code&gt;:wink:&lt;/code&gt;&lt;br&gt; [3] Some people know it as FCFS (&lt;em&gt;“First Come, First Served”&lt;/em&gt;)&lt;br&gt; [4] And remember to give &lt;a href="https://lolamarket.com/" rel="noopener noreferrer"&gt;LolaMarket&lt;/a&gt; a chance. Awesome service!&lt;/p&gt;




&lt;p&gt;&lt;a href="https://gist.github.com/hector6872/014457aa59de0d78abb0f35e028760ca" rel="noopener noreferrer"&gt;External links 👀&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>kotlin</category>
      <category>java</category>
      <category>queue</category>
    </item>
    <item>
      <title>Presenters and Views meet The Interface Segregation Principle</title>
      <dc:creator>Héctor de Isidro</dc:creator>
      <pubDate>Thu, 02 Aug 2018 17:40:27 +0000</pubDate>
      <link>https://forem.com/hector6872/presenters-and-views-meet-the-interface-segregation-principle-11ia</link>
      <guid>https://forem.com/hector6872/presenters-and-views-meet-the-interface-segregation-principle-11ia</guid>
      <description>&lt;h2&gt;
  
  
  also known as “the 4th letter in the SOLID acronym”
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F31f9f4kguohrdd9owr5z.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F31f9f4kguohrdd9owr5z.jpeg" width="800" height="450"&gt;&lt;/a&gt;&lt;span&gt;&lt;a href="https://en.wikipedia.org/wiki/Superman_vs._Muhammad_Ali" rel="noopener noreferrer"&gt;Superman vs. Muhammad Ali Comic Book&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;There are several posts about the &lt;strong&gt;MVP&lt;/strong&gt;¹ pattern (or whatever fancy name some authors use to call it &lt;code&gt;:wink:&lt;/code&gt;) and even more of them explaining what &lt;strong&gt;SOLID&lt;/strong&gt;² stands for, so we will focus on:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; The contract between presenter and view&lt;/li&gt;
&lt;li&gt; Code reuse&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Speaking of MVP and contracts, some developers should read &lt;a href="http://blog.karumi.com/interfaces-for-presenters-in-mvp-are-a-waste-of-time/" rel="noopener noreferrer"&gt;this&lt;/a&gt; for goodness sake!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  DRY³
&lt;/h4&gt;

&lt;p&gt;Time and again we are told that we must &lt;strong&gt;avoid repetition and redundancy&lt;/strong&gt; because “the less code to maintain the better” but then we find ourselves typing almost the same interfaces over and over again an indefinite number of times.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;It’s almost pseudo-code, but I’m sure it’s not the first time you’ve seen something like that &lt;code&gt;:shrug:&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  KISS⁴
&lt;/h4&gt;

&lt;p&gt;What can we do to follow the DRY principle mentioned above? &lt;strong&gt;Applying the Interface Segregation Principle.&lt;/strong&gt; That’s it.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;What do you think?&lt;/strong&gt; From my point of view, among other benefits, it looks much cleaner, more refactor-friendly and certainly a better way to avoid monolithic interfaces with hundreds of methods.&lt;/p&gt;

&lt;h4&gt;
  
  
  BONUS: Kotlin developers
&lt;/h4&gt;

&lt;p&gt;Kotlin offers &lt;a href="https://kotlinlang.org/docs/reference/sealed-classes.html" rel="noopener noreferrer"&gt;Sealed classes&lt;/a&gt; whose best description is: &lt;a href="https://antonioleiva.com/sealed-classes-kotlin/" rel="noopener noreferrer"&gt;Enums with super-powers&lt;/a&gt;. Using this kind of class we may be able to go &lt;a href="https://imgflip.com/i/29qsz7" rel="noopener noreferrer"&gt;a little further&lt;/a&gt;.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;Further information about these &lt;strong&gt;Sealed Classes&lt;/strong&gt; is available &lt;a href="https://medium.com/@hector6872/sealed-class-with-love-e554063aa9c6" rel="noopener noreferrer"&gt;here&lt;/a&gt; &lt;code&gt;:trophy:&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Conclusion
&lt;/h4&gt;

&lt;p&gt;It’s true that we haven’t gone into the details but I think the code fragments shown above are worth more than a thousand words &lt;code&gt;:sunglasses:&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We here at &lt;a href="https://lolamarket.com/tienda" rel="noopener noreferrer"&gt;Lolamarket&lt;/a&gt; believe that our code looks way better using this so I encourage everyone to try it and leave a comment below or &lt;a href="https://twitter.com/hector6872" rel="noopener noreferrer"&gt;tweet&lt;/a&gt; me with any questions/suggestions!&lt;/p&gt;

&lt;p&gt;This article was originally published on &lt;a href="https://medium.com/@hector6872/presenters-and-views-meet-the-interface-segregation-principle-1cd6c98f46bb" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;[1] &lt;a href="https://en.wikipedia.org/wiki/Model%C3%A2%C2%80%C2%93view%C3%A2%C2%80%C2%93presenter" rel="noopener noreferrer"&gt;Model-View-Presenter&lt;/a&gt; (btw it’s impressive to know this architectural pattern is over 20 years old &lt;code&gt;:wow:&lt;/code&gt;)&lt;br&gt; [2] &lt;a href="http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod" rel="noopener noreferrer"&gt;SOLID&lt;/a&gt; (the acronym is not used in its original paper so look for the reference to “the first five principles of &lt;em&gt;class design&lt;/em&gt;” or even better go for a &lt;a href="http://lmgtfy.com/?q=solid+design+principles" rel="noopener noreferrer"&gt;easier explanation&lt;/a&gt;)&lt;br&gt; [3] &lt;a href="https://en.wikipedia.org/wiki/Don't_repeat_yourself" rel="noopener noreferrer"&gt;Don’t Repeat Yourself&lt;/a&gt; &lt;br&gt; [4] &lt;a href="https://en.wikipedia.org/wiki/KISS_principle" rel="noopener noreferrer"&gt;Keep It Short and Simple&lt;/a&gt; (politically correct variation)&lt;/p&gt;




&lt;p&gt;&lt;a href="https://gist.github.com/hector6872/00362163fe92e0d92e1e2d1d1fcacd84" rel="noopener noreferrer"&gt;External links 👀&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>mvp</category>
      <category>solid</category>
      <category>kotlin</category>
    </item>
    <item>
      <title>How good are Git Hooks?</title>
      <dc:creator>Héctor de Isidro</dc:creator>
      <pubDate>Wed, 01 Aug 2018 17:30:12 +0000</pubDate>
      <link>https://forem.com/hector6872/how-good-are-git-hooks-14ho</link>
      <guid>https://forem.com/hector6872/how-good-are-git-hooks-14ho</guid>
      <description>&lt;h2&gt;
  
  
  I’ve tried them and &lt;a href="https://venngage.com/blog/7-reasons-why-clicking-this-title-will-prove-why-you-clicked-this-title/" rel="noopener noreferrer"&gt;the answer will shock you&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;As developers we use Git (or at least we should) an uncountable number of times&lt;br&gt;
a day¹ so, because &lt;a href="https://media.giphy.com/media/TgHosMP8OADYO6onsC/giphy.gif" rel="noopener noreferrer"&gt;not all of us are machines yet&lt;/a&gt;, we can sometimes make a mistake as the result of the rush (i.e pushing a commit to master when it should go to dev). To try to cut down these kinds of slips we have &lt;strong&gt;Git Hooks’&lt;/strong&gt; help.&lt;/p&gt;
&lt;h3&gt;
  
  
  What are Git Hooks?
&lt;/h3&gt;

&lt;p&gt;Git Hooks are &lt;strong&gt;extensionless executable scripts²&lt;/strong&gt; you can place in your repository’s hooks folder (&lt;a href="https://git-scm.com/docs/git-config#git-config-corehooksPath" rel="noopener noreferrer"&gt;by default&lt;/a&gt; &lt;em&gt;.git/hooks&lt;/em&gt;)³ to trigger actions at certain points in Git’s execution. In other words: we can &lt;strong&gt;automate&lt;/strong&gt; what we always want to happen before/after using a &lt;code&gt;git&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffvowjfjeicc8zpkl6kv6.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffvowjfjeicc8zpkl6kv6.jpeg" width="553" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is a huge &lt;a href="https://github.com/git/git/blob/master/Documentation/githooks.txt#L42" rel="noopener noreferrer"&gt;list of hook types&lt;/a&gt;⁴ you can attach⁵ scripts to but here we will see just a few.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;Tip: they can always be bypassed adding the&lt;code&gt;--no-verify&lt;/code&gt; param&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I hope the code snippets attached below are self-explanatory.&lt;/p&gt;

&lt;h4&gt;
  
  
  Pre-commit
&lt;/h4&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h4&gt;
  
  
  Commit-msg
&lt;/h4&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h4&gt;
  
  
  Pre-push
&lt;/h4&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;As a good practice we could run our tests at this point as well 😉&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvehx4n4hndwnhd0zja3l.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvehx4n4hndwnhd0zja3l.jpeg" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Sharing hooks with our lovely team
&lt;/h3&gt;

&lt;p&gt;As the default hooks folder belongs to &lt;code&gt;.git&lt;/code&gt; folder which isn’t versioned we can use one of these strategies depending on our Git version⁶ to share hooks among our team members:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;version 2.9 or greater:&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;Tip: you can apply this configuration to all current (and future) repositories adding the &lt;code&gt;--global&lt;/code&gt; param&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;earlier version than 2.9:&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Said that, you can use this script I’ve created for lazy people like me:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;Another additional benefit of using a different folder than the default one is that we can keep them updated&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn8879aefz4uile33q70u.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn8879aefz4uile33q70u.jpeg" width="500" height="656"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Introducing Git Hooks⁷ repository
&lt;/h3&gt;

&lt;p&gt;In order to be able to run multiple hooks within each type avoiding the creation of a huge and cumbersome single script loaded of comments, I have created a &lt;a href="https://github.com/hector6872/GitHooks" rel="noopener noreferrer"&gt;public repository&lt;/a&gt; which offers a new structure to store our hooks: each type of hook (i.e. &lt;code&gt;pre-commit&lt;/code&gt;) launches the scripts we have stored in its corresponding subfolder (i.e &lt;code&gt;/pre-commit-hooks&lt;/code&gt;).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To disable or enable a hook you can use the &lt;code&gt;git-hooks-state.sh&lt;/code&gt; script (which basically is a &lt;code&gt;chmod&lt;/code&gt; alias that changes their executable permission depending on the new state indicated)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;I wish I didn’t have to say it but PRs are very welcome.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmftt6ujdmjxx1y0ztcyl.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmftt6ujdmjxx1y0ztcyl.jpeg" width="600" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PS: you will have a lot more spare time to configure your hooks if you start using &lt;a href="https://lolamarket.com/" rel="noopener noreferrer"&gt;LolaMarket&lt;/a&gt; to shop for groceries 😄&lt;/p&gt;

&lt;p&gt;This article was originally published on &lt;a href="https://medium.com/@hector6872/how-good-are-git-hooks-75ae4c3fe3f5" rel="noopener noreferrer"&gt;Medium&lt;/a&gt; &lt;/p&gt;




&lt;p&gt;[1] Remember, commit early and often.&lt;br&gt; [2] Use &lt;code&gt;chmod +x script.sh&lt;/code&gt; from terminal to make a script executable&lt;br&gt; [3] Every Git repository has a hooks folder which contains some disabled sample hook files but IMHO they are pretty useless 🔥. You can checkout the latest version &lt;a href="https://github.com/git/git/tree/master/templates" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;br&gt; [4] They are usually categorized into two main types: client side and server side&lt;br&gt; [5] It supports any scripting language that &lt;a href="https://github.com/hector6872/GitHook/issues/1" rel="noopener noreferrer"&gt;your system knows how to execute&lt;/a&gt;&lt;br&gt; [6] Use &lt;code&gt;git --version&lt;/code&gt; to find out your current version of Git&lt;br&gt; [7] Great naming, isn’t it? 😞&lt;/p&gt;




&lt;p&gt;&lt;a href="https://gist.github.com/hector6872/d2710acff24e29ba7164d4db48674a79" rel="noopener noreferrer"&gt;External links 👀&lt;/a&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>automation</category>
      <category>gist</category>
    </item>
  </channel>
</rss>
