<?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>DEV Community: Eddie Prislac</title>
    <description>The latest articles on DEV Community by Eddie Prislac (@eprislac).</description>
    <link>https://dev.to/eprislac</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%2F179858%2Fd50d8623-4a05-45fa-b44d-5491eeb5a33a.jpeg</url>
      <title>DEV Community: Eddie Prislac</title>
      <link>https://dev.to/eprislac</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/eprislac"/>
    <language>en</language>
    <item>
      <title>A simple script to extract email addresses</title>
      <dc:creator>Eddie Prislac</dc:creator>
      <pubDate>Tue, 21 Apr 2020 18:03:20 +0000</pubDate>
      <link>https://dev.to/vetswhocode/a-simple-script-to-extract-email-addresses-5b7e</link>
      <guid>https://dev.to/vetswhocode/a-simple-script-to-extract-email-addresses-5b7e</guid>
      <description>&lt;p&gt;I'm a big fan of automating processes... if I need a long command or series of commands to accomplish a task more than once, my instinct is to take that command and turn it into an easy to remember, re-usable script. My task today was to take an exported set of applications I receive over the apply-forms channel in the VWC slack group and grab all the email addresses out of it, so I could perform one single mass mailing.&lt;/p&gt;

&lt;p&gt;The problem:&lt;/p&gt;

&lt;p&gt;VWC has a channel to which every application gets piped in our Slack group, called 'apply-forms'. We also have a slack app called 'export' that will export every message from a given slack channel between two given dates to JSON format... pretty handy when you get behind on answering applications. However, the JSON that it spits out is relevant to generic messages, not messages that are broken down into what could be a further JSON object... in other words, the key-value pairs from each application that render nicely in the 'apply-forms' channel all come out as one long string. This means, were I a more patient man, I'd go through each of those by hand and manually cut-and-paste each email address individually into a separate form. However, anyone who's ever read one of my posts before or dealt with me in person knows that I am most definitely not a patient man, nor am I a man that has an abundance of free time. Screw that noise... how do we write a script to do this instead?&lt;/p&gt;

&lt;p&gt;The solution:&lt;br&gt;
Grep.&lt;br&gt;
Yep, grep.&lt;br&gt;
The following snippet proved more than able to accomplish exactly the task I needed done, in a little under a second:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="s1"&gt;'[[:alnum:]+\.\_\-]*@[[:alnum:]+\.\_\-]*'&lt;/span&gt; slack-export-privategroup-2020-04-21T1603Z.json | &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; vwc-emails.txt.  

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



&lt;p&gt;In this example, &lt;code&gt;slack-export-privategroup-2020-04-21T1603Z.json&lt;/code&gt; is the file containing my exported JSON, and &lt;code&gt;vwc-emails&lt;/code&gt; is the file into which I'm exporting my email addresses.&lt;/p&gt;

&lt;p&gt;This bit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="s1"&gt;'[[:alnum:]+\.\_\-]*@[[:alnum:]+\.\_\-]*'&lt;/span&gt; slack-export-privategroup-2020-04-21T1603Z.json   

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



&lt;p&gt;is my grep command, in which I tell grep to output the results of using the included regex command on the aforementioned input file. We then pipe (&lt;code&gt;|&lt;/code&gt;) that output into &lt;code&gt;sort&lt;/code&gt; and &lt;code&gt;uniq&lt;/code&gt; to get them alphabetized and remove duplicates... the &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; at the end just before the output file tells zsh to push that output into &lt;code&gt;vwc-emails.txt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Pretty neat, huh? It is, yeah, and my end result was a nicely ordered one-to-a-line file of every unique email address, ready to be copy/pasted into the 'to' line of a new email.&lt;/p&gt;

&lt;p&gt;But it's waaaay too damned long to remember.&lt;/p&gt;

&lt;p&gt;How to fix that? Good question... the answer is "put that shit in an executable".&lt;/p&gt;

&lt;p&gt;Whenever I have a long command or chain of commands such as this one, I find it easiest to create a file for the command and place it in the &lt;code&gt;bin&lt;/code&gt; directory of my home folder, which I have already conveniently mapped to my &lt;code&gt;$PATH&lt;/code&gt;. I give the file the name &lt;code&gt;snatchmail&lt;/code&gt;, open it up in vim, and paste my command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="s1"&gt;'[[:alnum:]+\.\_\-]*@[[:alnum:]+\.\_\-]*'&lt;/span&gt; slack-export-privategroup-2020-04-21T1603Z.json | &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; vwc-emails.txt   

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



&lt;p&gt;Not quite good enough. For one, the shell will not know which interpreter I'm using, so we need a shebang line (okay, so zsh would just execute the grep command anyways without it, but a shebang can also help to remind you which language you're using, and which interpreter will be used, in case you need to come back to it):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="c"&gt;#!/bin/zsh&lt;/span&gt;

&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="s1"&gt;'[[:alnum:]+\.\_\-]*@[[:alnum:]+\.\_\-]*'&lt;/span&gt; slack-export-privategroup-2020-04-21T1603Z.json | &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; vwc-emails.txt   

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



&lt;p&gt;Still not quite there, though.&lt;/p&gt;

&lt;p&gt;See, my filenames will not always be the same... export will always name the new file with the current date and time, and I don't want to just keep adding email addresses to the same file.&lt;/p&gt;

&lt;p&gt;Luckily, zsh makes this stupid-simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="c"&gt;#!/bin/zsh&lt;/span&gt;

&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="s1"&gt;'[[:alnum:]+\.\_\-]*@[[:alnum:]+\.\_\-]*'&lt;/span&gt; &lt;span class="nv"&gt;$1&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$2&lt;/span&gt;

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



&lt;p&gt;I've here replaced my filenames with two numbered params, &lt;code&gt;$1&lt;/code&gt; and &lt;code&gt;$2&lt;/code&gt;, with &lt;code&gt;$1&lt;/code&gt; being my input file, and &lt;code&gt;$2&lt;/code&gt; being my output file. I can now exit vim, reload my shell, and execute the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;
snatchmail slack-export-privategroup-2020-04-21T1603Z.json  vwc-emails2.txt   

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



&lt;p&gt;And voila: my command executes, and I now have the same result as that long grep chain, by entering one command with an input and output filename.&lt;/p&gt;

&lt;p&gt;I enjoy writing scripts like this. It appeals to my natural affinity for problem solving, and allows me to save loads of time. I hope you will take inspiration from this post and experiment with your own time-saving scripts, and I encourage you to post any you come up with in the comments below. Thanks for reading!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cover image "Software Development Community" by Michael Kappel is licensed under CC BY-NC 2.0&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;a href="https://rietta.com/blog/grep-extract-e-mail-addresses-from-a-text-file/"&gt;https://rietta.com/blog/grep-extract-e-mail-addresses-from-a-text-file/&lt;/a&gt;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>zsh</category>
      <category>grep</category>
      <category>scripting</category>
    </item>
    <item>
      <title>Bad Spaghetti - a case against service objects</title>
      <dc:creator>Eddie Prislac</dc:creator>
      <pubDate>Tue, 21 Apr 2020 14:50:29 +0000</pubDate>
      <link>https://dev.to/vetswhocode/bad-spaghetti-a-case-against-service-objects-1k4c</link>
      <guid>https://dev.to/vetswhocode/bad-spaghetti-a-case-against-service-objects-1k4c</guid>
      <description>&lt;p&gt;As stated in my last post, I recently started a new gig, and I'm running into many of the same Rails anti-patterns I ran into when I first started with my old team, the biggest being the rampant use of Service Objects.&lt;br&gt;
To explain to you why this is bad, I first need to describe, for the uninitiated, what service objects are and the problem they attempt to solve.&lt;/p&gt;

&lt;p&gt;A service object is a PORO (Plain Old Ruby Object) that abstracts one responsibility away from your domain model... it has one job and it's meant to do it well. The idea is to take all of your business logic out of your model, so it can remain as thin (or thinner) than your controller. In theory, this sounds like a good idea, right? Your code gets encapsulated into tidy little bite-sized, easy-to-test bits. In theory. This of course assumes that the developer working on the project adheres to the single-responsibility principle and never tries to shoe-horn in additional functionality. This is where most implementations of service objects I've encountered in the wild break down, as inevitably, the business team will request new functionality that seems small enough to just tack on as an afterthought... this adds side-effects, which leads to patching, quick-fixes, and work-arounds, until your nice little single-responsibility PORO has evolved into a lovecraftian tentacle-monster of spaghetti-code. It's difficult to read, nearly impossible to debug, and has introduced needless complexity to your application. Worse, it may even be impacting your performance. To give an example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bo3q6_h3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/2ch8w4xlvpsg50x9fv0q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bo3q6_h3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/2ch8w4xlvpsg50x9fv0q.png" alt='""Contessa with squid"" by Pomax is licensed under CC BY-NC-ND 2.0'&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The app I'm currently working on generates statistics for mailing lists. This, under the current model, has a call to a microservice, which is hooked into an api, which passes the call down to a service object, which is meant to generate statistics for each mailing that is sent out by an organization.&lt;/p&gt;

&lt;p&gt;This service object calls another service object and passes each individual mailing as a new object, to another service object to generate the statistics needed for each individual mailing. For each individual mailing, it's making individual calls to query objects (similar to service objects, but meant specifically to execute a specific query - which these were, by the way, not doing) to see which email it was delivered to, whether that email has been read, whether delivery was bounced etc... all along the way, individual calls are being made to the database for each tiny bit of information that needs to be compiled into bigger units of information. It was like a Rube Goldberg device in code form.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--M0CWI67h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tqggqe5bb0v8iapvk4rh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--M0CWI67h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tqggqe5bb0v8iapvk4rh.png" alt='"Indianapolis Childrens Museum 08-02-2010 59 - Rube Goldberg Machine" by David441491 is licensed under CC BY-NC-ND 2.0 '&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For a mailing that was only sent out to say, 30-50 users, the cost of this operation may have seemed almost negligible. However, when our organization started to incur larger clients who had larger lists of subscribers, lists numbering in the thousands, the page began to fail, horribly... timing out as tens of thousands of calls might need to be made to the database for each line in a ten-record paginated call. It was painful to watch, and even more painful to debug. Problem #1 I was facing was that the app was not working, but Problem #2 was that the previous developer, while adhering to this weird service object pattern, had no such qualms about domain name-spacing, or even naming routes, controllers, and models in a way that was anything close to coherent. Half the service objects were crammed in with the models, while the other half were in the services directory, and which got stuck where appeared to be arbitrary. I found myself having to start at &lt;code&gt;rake routes&lt;/code&gt;, searching for which controller action was matched to which path, when it should have been obvious from the name. From there, I immersed myself in the foul sewage of service object after service object, objects which initiated struct after struct in an endless cycle of obfuscation by abstraction, passing huge parameter hashes from one service till the next, with no clear indicator where the actual data was coming from, and how it was being obtained. I inevitably reached the bottom... multiple query objects which needed to be called individually for each email address to which a given mailing was sent, whose results would then be tabulated and passed back up the chain. The business logic used to obtain the numbers I needed was buried so far that the business team I was working with could not tell me what data I needed to query for each statistic, and the code was so complex it wasn't doing me any favors. When I eventually deciphered how the numbers were obtained, I chucked out the lot of it.&lt;/p&gt;

&lt;p&gt;You may think that's a bit extreme. Someone put a lot of hard work into abstracting all those bits of code away from the domain model, after all. Yeah, and they did a right good job of breaking the app, without even realizing it. Even worse, they wasted &lt;em&gt;my&lt;/em&gt; time by creating a codebase so dense, it took me nearly a week to discern the root cause of the issue.&lt;/p&gt;

&lt;p&gt;It's the wasting of my time I deem to be unforgivable here, in case you're wondering.&lt;/p&gt;

&lt;p&gt;Done well, any pattern you implement should result in your codebase being easier to navigate and harder to break. If it does the opposite, you're not only wasting your time, but the time of every developer who comes after you, your business team, and your clients. You're being too smart for your own and everyone else's good, and over-engineering your solution.&lt;/p&gt;

&lt;p&gt;So, if I'm chucking out the baby with the bathwater, what do I replace it with? Well, I looked at the base of the problem... here I have this page that needs to display a data structure we don't have readily available in the db, because it's comprised of counts of values that are stored in other database tables.  Approaching this within the existing service object architecture resulted in the aforementioned thousands of database calls for each individual data-point in each individual row in a ten-row table. Rails sucks at doing this on its own, but SQL eats problems like this for lunch, and asks for seconds. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IQ6ukQah--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/orcqjkh0i74ffxczpdfp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IQ6ukQah--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/orcqjkh0i74ffxczpdfp.jpg" alt="&amp;quot;Timmy's Spaghetti 2&amp;quot; by PhotoChet is licensed under CC BY-NC-SA 2.0"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once I knew exactly how the data-points related to each other, it was easy to create a SQL view, and an ActiveRecord class based on that view, which I could query to get the all data I needed. This cut my DB round-trips down to exactly one, and reduced my query time exponentially. I was now getting speed gains of anywhere between 50-75%. What's more, there was no complex business logic to abstract away from the model... it was read-only, with any business logic baked into the SQL view, so only needed the queries that were already provided by ActiveRecord::Base. Best of all, the page was no longer breaking every time our largest client attempted to access it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--24oW2iEB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/y46h6kf635rj2c2p980m.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--24oW2iEB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/y46h6kf635rj2c2p980m.jpg" alt='"Hammer Head" by cogdogblog is licensed under CC0 1.0 '&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm not saying that every bad service object architecture could be replaced with custom database views. I'm damn sure not saying they should, either. Doing so would be irresponsible, and would make me guilty of doing the same thing the previous dev did... blindly adhering to a practice, and implementing said practice badly. (I really don't even want to blame the previous dev for this so much... from what I was told, he only had a few months to throw all of this together, and was working on his own... and crunch-time development is a rant for another day.) There's an old adage that goes: "When you're holding a hammer, every problem looks like a nail". Developers that blindly stick to design patterns without understanding why they should be implemented, and when they should be avoided, are looking at their problems as nails, and their pattern as a hammer, when in truth, sometimes you need a screwdriver. Sometimes you need a chisel. Hell, sometimes, there are only tiny nuances, and all you need is a smaller hammer. Examine each situation prior to implementation... try to understand how each part of your application will be used to solve it, which parts will be stressed and how to avoid those stresses, and how to make your code's intent readily apparent to anyone who might need to maintain it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cover image "Spaghetti and sausages" by HatM is licensed under CC BY-NC-SA 2.0&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;All Images obtained from &lt;a href="https://search.creativecommons.org/"&gt;https://search.creativecommons.org/&lt;/a&gt; , and attributed separately in their 'alt' text&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Further Reading:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://avdi.codes/service-objects/"&gt;https://avdi.codes/service-objects/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.codewithjason.com/rails-service-objects/"&gt;https://www.codewithjason.com/rails-service-objects/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.toptal.com/ruby-on-rails/rails-service-objects-tutorial"&gt;https://www.toptal.com/ruby-on-rails/rails-service-objects-tutorial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.netguru.com/codestories/database-views-and-how-to-use-them-in-a-ror-based-app"&gt;https://www.netguru.com/codestories/database-views-and-how-to-use-them-in-a-ror-based-app&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>antipattern</category>
    </item>
    <item>
      <title>Git Gud: Create a .gitmessage</title>
      <dc:creator>Eddie Prislac</dc:creator>
      <pubDate>Fri, 03 Apr 2020 19:55:38 +0000</pubDate>
      <link>https://dev.to/vetswhocode/git-gud-create-a-gitmessage-4ibj</link>
      <guid>https://dev.to/vetswhocode/git-gud-create-a-gitmessage-4ibj</guid>
      <description>&lt;h3&gt;
  
  
  New Job - Old Problems
&lt;/h3&gt;

&lt;p&gt;I started a new position recently. A good friend from a previous team invited me to come work with him, and soon after starting, I began to see why I'd come to mind, as his new team's issues mirrored a good many of the issues we'd faced together at NBC when we started there. The first one staring me in the face was one of the most obvious (at least as a coder): the git commit messages.&lt;/p&gt;

&lt;p&gt;I'm going to be perfectly frank. You should NOT be using &lt;code&gt;git commit -m "&amp;lt;insert message here&amp;gt;"&lt;/code&gt; when committing code. While yes, this is concise, it may not be as clear as you think, and more often than not, if you try to get informative with it, you're going to end up exceeding the max allotted space for that message. &lt;code&gt;git commit -m&lt;/code&gt; is for hobbyists, for dabblers. It's the bare minimum information you should be including in your commit. As professionals, we should be providing more context, making things easier for those who come after us, and heck, why not, ourselves, while we're at it.&lt;/p&gt;

&lt;p&gt;In order to provide a more informative git history, we should be using a &lt;code&gt;.gitmessage&lt;/code&gt; template file, and favor using &lt;code&gt;git commit&lt;/code&gt; over &lt;code&gt;git commit -m '&amp;lt;message&amp;gt;'&lt;/code&gt; when writing commits.'&lt;/p&gt;

&lt;p&gt;This format also has the added bonus of being able to automatically populate the subject and description of a pull-request on Github. (Provided you can manage to keep your branch history clean... but more on that in another post)&lt;/p&gt;

&lt;p&gt;The below code snippet is the .gitmessage template I personally use, and  can be pasted directly into a &lt;code&gt;.gitmessage&lt;/code&gt; file, to be placed in your own home directory.&lt;/p&gt;

&lt;p&gt;The headings (ISSUE, DESCRIPTION, STEPS TO TEST, REFERENCES, and CHANGELIST) should be uncommented prior to saving&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# &amp;lt;type&amp;gt;:(&amp;lt;ref number&amp;gt;) &amp;lt;short summary&amp;gt; 
#   |           |               |
#   |           |               +-&amp;gt; Summary in present tense
#   |           +-&amp;gt; Refers to story/card/issue #
#   +-&amp;gt; Type: feat|bug|chore|fix|refactor|style|test
# Commit subject line should not exceed 50 characters.
# Remainder of gitmessage should wrap at 72 characters.
# Use github-flavored markdown for formatting and links
# (links should not be line-wrapped)
#
# __ISSUE:__
# _&amp;lt;type&amp;gt;_ - *&amp;lt;issue name&amp;gt;*
# \[[#&amp;lt;issue number](&amp;lt;issue url)\]
#
# __DESCRIPTION:__
# Why do we need this commit?
#
# ___STEPS TO TEST:__
# Step-by-step instructions for practical testing
#
# __REFERENCES:__ # (optional)
# Links to reference materials that may provide context
# ie:
# 1. [Better commit messages with a gitmessage template](https://thoughtbot.com/blog/better-commit-messages-with-a-gitmessage-template) - Matt Sumner
# 2. [5 useful tips for a better commit message](https://thoughtbot.com/blog/5-useful-tips-for-a-better-commit-message) - Caleb Hearth
# 3. [A note about commit messages](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) - Tim Pope
# 4. [Linus' thoughts on commit messages](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) - Linus Torvalds
# 5. [Semantic commit messages](https://seesparkbox.com/foundry/semantic_commit_messages) - Jeremy Mack
# 6. [Github Flavored Markdown Spec](https://github.github.com/gfm/)
#
# __CHANGELIST:__
# Files Changed
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;.gitmessage&lt;/code&gt; file should then be referenced under the 'commit' tag in your &lt;code&gt;~/.gitconfig&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
[commit]
  template = ~/.gitmessage
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Usage Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fix: Update commit instructions (#1)

__ISSUE:__
_fix_ - *Update commit instructions*
\[[#1](http://fake.com/1)\]

__DESCRIPTION:__
The README.md file needed to be updated to correct outdated procedures

__STEPS TO TEST:__
1. Open Github
2. Navigate to the project
3. Read the README - text should be updated, spelled correctly,
   use proper grammar, and be clear and concise

__REFERENCES:__ # (optional)
1. [Link to a fake reference](http://fake.com)

__CHANGELIST:__
modified - README.md
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I'm not just talking out of turn here, either... nor am I saying anything new; a lot of cool people feel your git messages should be more informative, and the work I brushed up on to write this article can be found in my list of references below. I invite you to read them yourself, and feel free to use my template, or experiment and come up with your own.&lt;/p&gt;

&lt;p&gt;Until next time!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://thoughtbot.com/blog/better-commit-messages-with-a-gitmessage-template"&gt;Better commit messages with a gitmessage template&lt;/a&gt; - Matt Sumner&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://thoughtbot.com/blog/5-useful-tips-for-a-better-commit-message"&gt;5 useful tips for a better commit message&lt;/a&gt; - Caleb Hearth&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html"&gt;A note about commit messages&lt;/a&gt; - Tim Pope&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html"&gt;Linus' thoughts on commit messages&lt;/a&gt; - Linus Torvalds&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://seesparkbox.com/foundry/semantic_commit_messages"&gt;Semantic commit messages&lt;/a&gt; - Jeremy Mack&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.github.com/gfm/"&gt;Github Flavored Markdown Spec&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>git</category>
      <category>github</category>
    </item>
    <item>
      <title>Dealing With 'No'</title>
      <dc:creator>Eddie Prislac</dc:creator>
      <pubDate>Fri, 30 Aug 2019 03:58:53 +0000</pubDate>
      <link>https://dev.to/vetswhocode/dealing-with-no-21k8</link>
      <guid>https://dev.to/vetswhocode/dealing-with-no-21k8</guid>
      <description>&lt;h2&gt;
  
  
  How to deal with rejection
&lt;/h2&gt;

&lt;p&gt;As a lifelong nerd and self-taught web developer, I've had a long time to get used to rejection, whether it be in my personal life, applying for a job, or submitting a PR to an open-source project. Rejection can be rough... it deals a heavy blow to the ego, and can be extremely frustrating. However, it's only the end if you let it be.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rejection when applying for a job
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FDfIueC---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/vcqdamgbqv5qalh6r2wi.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FDfIueC---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/vcqdamgbqv5qalh6r2wi.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm leading off with this, because my position at Vets Who Code as Head FNG Wrangler is very much like that of a company recruiter. We have an interview process to decide who gets in, and while we'd love to include everyone who applies, people often don't. The position of a job interviewer is a rough one... they have a set of criteria that they're looking for when trying to fill a position, and they often have to wade through dozens and sometimes hundreds of applicants who may not meet those criteria to find one or two that do. Even then, they may not have more than one position, and have to make a choice between qualified applicants. It's difficult for a job-seeker to put themselves in the position of their interviewer, as their concentration is on their own need and situation. Being told you're unqualified or just not right for a position is definitely disheartening, but it's not the end of the world, and it doesn't mean you should stop trying. Some options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Review your skillset:&lt;/strong&gt; Maybe you really didn't have what they were looking for, or weren't as quick with the answers they were looking for. If you find your skillset lacking, look for tutorials, classes, etc... do the research and improve your chances for the next time. If you're lacking in experience, try contributing to open-source projects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review the job market:&lt;/strong&gt; Look at the position you were applying for, and look into what kind of competition you're facing. Maybe the market is over-saturated, and you might be better off seeking something slightly different.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review your resume:&lt;/strong&gt; Your resume is the first impression you give any prospective employer, and most interviewers see loads of them each day. Ask yourself... is this resume presenting me as someone who can do what they want? What about it makes me stand out? Is it saying anything about me that it shouldn't?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review your performance in the interview:&lt;/strong&gt; As a baby dev, this one was my downfall nine times out of ten. Like I said, I'm a lifelong nerd, and this has less to do with my intelligence and more with a severe lack of interpersonal skills. I'm often unaware of how certain things I say or do can be unnerving or off-putting to others, or how my appearance affected people's opinion of me, and I often get nervous when speaking with strangers. It took me a lot of practice both in front of a mirror, with my wife, and with friends, to learn how to present myself in a way that would appeal to potential employers. Going to job interview is like reading for a part as an actor, you're better off if you rehearse.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thank your interviewer for their time, no matter what:&lt;/strong&gt; Be respectful and courteous, even, and especially if, you're rejected. It may be that while you're not what they're looking for for this particular position, your skills may be exactly what they're looking for in another. Having a poor attitude may preclude you from consideration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep Trying:&lt;/strong&gt; This should go without saying... if you're out of work, it's not like you have a choice.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Rejection when presenting an idea
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2U5dSQfY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/kpvns1ltx9ogc5do3seg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2U5dSQfY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/kpvns1ltx9ogc5do3seg.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
Say you're trying to get a startup off the ground and you're looking for capital. You've prepared your business plan, your technical requirements, your state of mind... you're ready and raring to go. You go to meet with a VC, make your presentation, and they shoot you down. You see your dreams going up in flames right before your eyes. This kind of rejection can be like watching somebody kick your baby, it can be heartbreaking, at best; at worst, infuriating. What do you do?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;See above:&lt;/strong&gt; Particulars aside, this sort of rejection is very similar to being rejected for a job, and in most cases, reviewing what you presented and how you've presented yourself can work wonders in improving your chances for the next time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep calm and carry on:&lt;/strong&gt; A professional attitude will carry you far when dealing with any sort of rejection. Keep your bearing, and ask questions... the right questions, with the right attitude. This leads to my next bullet-point...&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Take any advice you get to heart:&lt;/strong&gt; Most VC's have very good reasons for turning down projects... they're in the business of making money by providing money, and they wouldn't be very successful if they didn't have a good idea of what would make money and what wouldn't. It may be that they've seen an idea similar to yours perform poorly, or maybe your market research has a flaw. Listen respectfully, and use their free advice to your advantage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Learn when to give up (without really giving up):&lt;/strong&gt; Be open to the idea that the cat-rental mobile app that you dreamed up and lovingly molded into a business proposal just might not be a great idea. That doesn't necessarily mean you have no business creating a startup, only that you have no business creating &lt;em&gt;that&lt;/em&gt; startup. It's the same as if an author has had a story rejected by an editor: there may be pacing issues in the piece, or there may not be an audience for it. This doesn't mean the author is necessarily bad... most successful authors have had tons of rejections before having a piece accepted. Save yourself some heartache, and take good advice when it's offered. If you've presented the same idea multiple times to different VCs, and you keep hearing the same thing, chances are they're right and you're wrong. Learn to accept it and move on to the next thing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Rejection of a pull-request
&lt;/h3&gt;

&lt;p&gt;Ok, you have the job/startup/open-source project for which you contribute, and you've submitted a request for Peer Review, to merge your latest feature or bug-fix... and it's rejected. OH NOES! There's 3 days of work, all for nothing! Ok, so this type of rejection isn't quite as hard to take, but as a developer, even a seasoned one, it's the sort you're likely to receive most often, so you'd better know how to deal with it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Your peers are not Hitler for rejecting your pull-request:&lt;/strong&gt;
Don't treat them like it. Remember, they took time out of their day to review your work, and they likely have just as much to do as you. Likewise, these are your peers, and they're going to need to work with your code at some point in the future. Be thankful for their input, and acknowledge it accordingly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assume your peers know just as much, or more than you do:&lt;/strong&gt; If you know beyond the shadow of a doubt you're the smartest person in the room, you're in the wrong room. There's nothing to learn if you're a genius among idiots, and that's a good way to grow stagnant. Statistically though, this is not going to be the case. If they can provide a valid argument against something you've done in your code, pay attention to it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;React to input quickly:&lt;/strong&gt; As I stated before, your peers are just as busy as you are, so take their advice to heart and move on it quickly. If you have a good reason for what you did, and can back it up, don't be afraid to discuss it a little... they may give in and see your point of view. If not, make the suggested changes and be done with it, don't drag it out just for the sake of winning an argument. All you're doing at that point is slowing your team's velocity and making everyone look bad, and worse, uncomfortable with you... Which brings me to my last bullet point...&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;As always, be polite and receptive:&lt;/strong&gt; Nothing short of hurling hate speech (or office supplies) at your co-workers/boss/random strangers will get you kicked off a team faster than consistently arguing with everyone, not even poor performance. If you find yourself consistently arguing over PR rejections, re-examine your own practices and adjust accordingly. Otherwise, you may un-intentionally find yourself back at the start of this article (going through multiple rejections, while searching for a new job).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What if you're the one who has to say 'No'?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P7svx00h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/kp1uct961jsrpdns4apj.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P7svx00h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/kp1uct961jsrpdns4apj.jpeg" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
When you're the one who has to say no, you still need to remember to be polite, and reasonable. Bear in mind that not everyone who you deal with will have read this article (and I'm certain many who have, won't heed it). They may whine, cry, beg, hurl insults, etc..., upon getting rejected. If you're an interviewer or a VC, they may spam your email, begging for another chance. Be as polite as possible, but make it clear that this time it's a "No", not a "maybe", not a '"we'll see". Attempting to spare someone's feelings by being unclear in your language only drags things out, and hearing someone pour out their own hard-luck story as to why they need this job/funding/whatever because they've spotted that you might be a weak touch can be soul-crushing. Indeed, it kills me a little each time I have to turn down an applicant, especially since our whole purpose at Vets Who Code is to help veterans get a leg up on their lives after leaving the military. There have been quite a few who believe that they're entitled to our help, simply for the fact that we exist to help folks like them, but that just isn't the case... our resources are limited, and our applicants are many; we can't accept everyone. Likewise, a job interviewer has only so many positions, a VC only so much resources, a reviewer only so much patience. It's difficult to say no to a potential employee, entrepreneur, or peer, but inevitably at some point, necessary. Don't let it wear you down.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--b2YxQZmk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/kbe1eq8knal6nff293zb.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--b2YxQZmk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/kbe1eq8knal6nff293zb.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
"No" can be depressing. "No" can be gut-wrenching and cruel. But taken with the right attitude, "No" can be an opportunity for learning and growth. When someone tells you 'no', it's neither the end of the world, nor is it your final defeat. The most successful people in the world all have their own rejection moments, and the difference between them and those less successful is that they didn't let those failures stop them... they picked themselves up, brushed themselves off, and gave it another go.&lt;/p&gt;

</description>
      <category>career</category>
      <category>beginners</category>
      <category>motivation</category>
    </item>
    <item>
      <title>Why does ‘5’ + 0 equal 50?</title>
      <dc:creator>Eddie Prislac</dc:creator>
      <pubDate>Sat, 08 Jun 2019 21:51:27 +0000</pubDate>
      <link>https://dev.to/vetswhocode/why-does-5-0-equal-50-5bh8</link>
      <guid>https://dev.to/vetswhocode/why-does-5-0-equal-50-5bh8</guid>
      <description>&lt;p&gt;&lt;em&gt;Common JS noob mistakes with type coercion, and how to avoid them&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--29vBEaZw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2ANn6gQKbJqjfqQe6RbkSHpQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--29vBEaZw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2ANn6gQKbJqjfqQe6RbkSHpQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  A short preface:
&lt;/h3&gt;

&lt;p&gt;Lately in &lt;a href="http://vetswhocode.io"&gt;Vets Who Code&lt;/a&gt;, our head honcho, &lt;a href="https://twitter.com/JeromeHardaway"&gt;Jerome Hardaway&lt;/a&gt;, has been posting little code challenges, for the purpose of warming everyone up each morning, and getting our new troops prepared for the cohort we have starting in September.&lt;/p&gt;

&lt;p&gt;These are not meant to be difficult problems, just a little something to wake up everyone’s brains in the morning.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qyXkkpQA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/357/1%2AolTzK29TYEM3awxjahbOkQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qyXkkpQA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/357/1%2AolTzK29TYEM3awxjahbOkQ.png" alt=""&gt;&lt;/a&gt;&lt;a href="http://vetswhocode.io"&gt;Vets Who Code&lt;/a&gt; is a non-profit org where we train vets, free of cost, to be badass React devs, and help them get jobs in the industry. The above pic is of Jerome, dressed in the contemporary uniform common during his time in the military. (I kid, of course. He got out of the Air Force a mere 10 years ago, and has a great sense of humor — at least I hope so, those guns ain’t photoshopped).&lt;/p&gt;

&lt;p&gt;However, my brain does not like to be woken up in the morning. I work from home, and tend to work late, into the wee hours of morning. More commonly than not, I tend to rise about an hour before my first morning meeting.&lt;/p&gt;

&lt;p&gt;By the time standup rolls around, my brain’s still attempting to assimilate the caffeine from my first two cups of &lt;a href="https://deathwishcoffee.com/"&gt;Death Wish Coffee&lt;/a&gt; (not a paid promo, I just love their high-octane brew, and they deserve the publicity).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aAgH4lcy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AgXEdwWVZIHdEQIqVoIzukA.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aAgH4lcy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AgXEdwWVZIHdEQIqVoIzukA.jpeg" alt=""&gt;&lt;/a&gt;I will, however, accept sponsorship if they offer. I like money (and/or free coffee). * (see footnote 1)&lt;/p&gt;

&lt;p&gt;Wake my brain up earlier then it’s prepared to, and my cranky ass becomes possessed with a desire to rip shit up. This goes against best practices for working at home, I know. I cop to the fact that I, like many others, struggle to maintain the discipline and motivation it takes to maintain such a lifestyle. I’m working on it, but there are still some mornings where I’m not quite there yet.&lt;br&gt;&lt;br&gt;
It was when I was in this state of mind that I started to notice some common mistakes which appeared in quite a few of the submissions. Keep in mind, the folks that make these submissions have not started our program yet, they’re waiting their turn, so I really shouldn’t be so hard on them. However, it’s in their best interests to learn this stuff early, so with that in mind, let’s get started…&lt;/p&gt;
&lt;h3&gt;
  
  
  An example problem:
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Write a JS function to calculate the sum of two given numbers.&lt;br&gt;&lt;br&gt;
If either param or the sum of both params are equal to 50, return _ _true&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Sounds simple right?&lt;br&gt;&lt;br&gt;
At first glance, something like this may seem passable:&lt;/p&gt;


&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;fiftyOrSumOfFifty&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;num2&lt;/span&gt;&lt;span class="p"&gt;)&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="nx"&gt;num1&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;num2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;num2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&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="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&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;&lt;strong&gt;Note:&lt;/strong&gt; This was not taken from a specific student’s code, I’m not trying to call anybody out on the quarterdeck. Rather, this was the most common solution I saw, cleaned up a little, formatting-wise… and it’s not surprising, really. Given the fact that the students had little to no prior instruction outside of the pre-work they’d done to be accepted into the program, I’m actually quite happy to see something like it, even with its issues.&lt;/p&gt;

&lt;p&gt;It even works, if you feed it the right params…&lt;/p&gt;


&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fiftyOrSumOfFifty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// returns `true`&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fiftyOrSumOfFifty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// returns `false`&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fiftyOrSumOfFifty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// returns `true`&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fiftyOrSumOfFifty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// returns `true`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--S5i3OaYY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/834/1%2AmNdFP43_sl6B6CSpXUCcJQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--S5i3OaYY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/834/1%2AmNdFP43_sl6B6CSpXUCcJQ.png" alt=""&gt;&lt;/a&gt;Yup.&lt;/p&gt;

&lt;p&gt;However, like I told you before, the sweetness of my creamer and that awesome caffeine buzz (thanks again, Death Wish!) had yet to overcome the bitterness of my morning funk, and I decided to start feeding it params it might not like. This leads to common JS noob mistake numero uno:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Not accounting for parameter type&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;JS is a weakly-typed language. As opposed to strongly-typed languages, which enforce the type of params allowed&lt;sup id="a1"&gt;1&lt;/sup&gt;, JS lets you stick any old thing into the params, and will happily feed you an answer, if it’s capable. However, that answer may not be the one we’re looking for. For example, in the above code, what happens if we feed a string to the function fiftyOrSumOfFifty?&lt;/p&gt;


&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fiftyOrSumOfFifty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;50&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// returns `true`&lt;/span&gt;
&lt;span class="c1"&gt;// and...&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fiftyOrSumOfFifty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;5&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// also returns `true`&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fiftyOrSumOfFifty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;5&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// also returns `true`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--saLHOwR0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/250/1%2AHZFuB76i-I4qV6GGW0HXlg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--saLHOwR0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/250/1%2AHZFuB76i-I4qV6GGW0HXlg.gif" alt=""&gt;&lt;/a&gt;WHAT THE…. WHAT?&lt;/p&gt;

&lt;p&gt;So, here’s what’s happening: as I said before, JS does not care if you feed it the wrong type of params. Because it’s a loosely-typed language, it will accept anything for a param.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ANYTHING.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You could feed it an Integer, Float, String, Boolean, Array, or nothing at all (null) if you wanted, and if it's able to do something with that param that fits into the code you've written, JS will return something, without throwing an error. In the first case above where we submit a string, we're submitting a value that can be coerced to a type that can indeed equal 50, and so returns true. That actually leads into the next common mistake, and we'll get to that in a second. It's related to this one, but in a much more specific way. In the third string example, we're submitting '5', a string, and 0, an integer. Why does this return true? Because you can use the + operator on a string, and it will work.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;It just won't sum the two params&lt;sup id="a3"&gt;3&lt;/sup&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;When you use the + operator on a pair of strings, it &lt;em&gt;concatenates&lt;/em&gt; the strings; that is, it sticks the second directly on to the tail end of the first. In the example function, this means that eventually, because neither param is equivalent to 50, the params get passed on to the summing operation, which, because we have provided a string for one of the params, now becomes a concatenation operation, and '5' + 0 evaluates as '50'.&lt;/p&gt;

&lt;p&gt;Why does this work the same in the second example as in the third, where we are submitting two params of different types? Because JS utilizes a trick called&lt;br&gt;&lt;br&gt;
&lt;em&gt;type coercion&lt;/em&gt;... if handed two vars of different types in an operation like +, it will attempt to convert one of the vars into the first type that makes sense, which in this case means that both are treated as strings, and the 0 gets tacked on to the '5' as '0', resulting in '50', which will return true.&lt;/p&gt;

&lt;p&gt;But wait a minute… if the + operator converted it to a string, why is that&lt;br&gt;&lt;br&gt;
'50' (a string, that is, text), evaluating as equal to 50 (a number)?&lt;br&gt;&lt;br&gt;
That should not be!&lt;/p&gt;

&lt;p&gt;Well, yes and no… I’m coming to that, stop being so impatient.&lt;/p&gt;

&lt;p&gt;First, remember how I told you that you could also slip an Array into the params? Well, one way you can get around the whole string concatenation bit I mentioned previously, is to parse your params as floats (ex: parseFloat('15') // returns 15)... when you do this to an Array, however, something interesting happens:&lt;/p&gt;


&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(parseFloat(['50', 25])) // returns... 50??? WTH!!!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;When you use parseFloat on an Array, it only parses the first item in the Array! Does the weirdness never cease? This surprised me, and I only just discovered this oddness as I was typing out this article, as I'd honestly never thought to try parsing an Array as a Float before. It’s actually so unheard-of to do this, &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/parseFloat"&gt;it’s not even given a mention in MDN’s documentation&lt;/a&gt;. Just goes to show you can learn something new every day. I decided to avoid the issue altogether, and if either param was an array (ex: &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray"&gt;Array.isArray(num1)&lt;/a&gt;...), I'd just return false.&lt;/p&gt;

&lt;p&gt;Anyways, getting back to type coercion…&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;=== &amp;gt; ==&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The example function is evaluating equality using the == ('double-equals') operator, which &lt;em&gt;infers type&lt;/em&gt;. This means that, like the + operator coerces the type of the var and changes its function from 'sum' to 'concatenate', the double-equals operator is looking at the two vars and saying to itself: &lt;em&gt;“Hey, one of these things is not like the other... but maybe it could be, if they had the same type? Let's try that!”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kam391Cl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/998/1%2AwumtkNDr9qIOfSFXN9AE5w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kam391Cl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/998/1%2AwumtkNDr9qIOfSFXN9AE5w.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since &lt;code&gt;'50'&lt;/code&gt; can be parsed as &lt;code&gt;50&lt;/code&gt;, &lt;code&gt;'50' == 50&lt;/code&gt; evaluates true. This is actually a pretty easy mistake to make, especially if coming over to JS from another language, as most other programming languages don't do this with their double-equals operator - the &lt;code&gt;==&lt;/code&gt; operator in most other languages will function much like the &lt;code&gt;===&lt;/code&gt; (triple-equals) operator does in JS, and will perform strict equivalence evaluation... that is, a string will NEVER be equal to a number, no matter how similar the text inside the string may be. In other languages, the &lt;code&gt;===&lt;/code&gt; operator does not necessarily function the same way; For instance, in Ruby, &lt;code&gt;===&lt;/code&gt; can be used to compare type&lt;sup id="a9"&gt;9&lt;/sup&gt;&lt;/p&gt;


&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;String === 'bacon' # evaluates to `true`
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;…and so, a JS newbie, when coming from Ruby, may not expect it to function&lt;br&gt;&lt;br&gt;
the way it does in JS, or even be aware of its existence. In Ruby, &lt;code&gt;==&lt;/code&gt; does what &lt;code&gt;===&lt;/code&gt; does in JS. Excusable, if you're new to the language, but use of &lt;code&gt;==&lt;/code&gt; to check equivalence is a habit that should be broken swiftly when training new JS devs, lest they fall into a bad habit. There are just too many side-effects that using this operator can produce. Instead of using &lt;code&gt;==&lt;/code&gt;, &lt;code&gt;===&lt;/code&gt; (triple-equals) should be used when checking equality, as it does not perform any type-conversion&lt;sup id="a2"&gt;2&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;Speaking of bad habits that ought to be broken swiftly:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Excessive conditionals and returns, or, ‘Failure to refactor’&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This can be attributed to lack of experience. Refactoring ones code to be more efficient eventually comes to be a habit, but it’s one that must be learned and self-enforced. The given example uses one if to check a condition and return true if that condition returns true, then uses else if to check another statement and return true if that statement returns true, then finally utilizes an else statement to return false if all else fails. Think about that sentence for a moment. The conditions themselves are &lt;em&gt;already returning a boolean value&lt;/em&gt;. We don't need the conditional, at all. With the application of the &lt;code&gt;||&lt;/code&gt; (logical 'or'&lt;sup id="a6"&gt;6&lt;/sup&gt;](#6)) operator, we can do: &lt;/p&gt;


&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;condition1&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="nx"&gt;condition2&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="nx"&gt;condition3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;...and avoid the use of the conditional statements, altogether.&lt;/p&gt;
&lt;h3&gt;
  
  
  Wrapping up:
&lt;/h3&gt;

&lt;p&gt;Here’s my first solution to the problem; it allows string params, so long as they can parse to floats and pass the conditions, to return true. I chose to do that because JS is primarily meant for the web, and if you’re doing DOM manipulation, it’s all text until you parse it to be otherwise (or use a number input, I guess; if you want the whole truth, I over-thought it). It will not, however, allow Arrays, undefined, or null, or any other data type that I’ve thought of aside from numbers and strings, to eval to true:&lt;/p&gt;


&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const numOrSumFifty = (num1, num2) =\&amp;gt; !anyArr(num1, num2) &amp;amp;&amp;amp; any50(num1, num2)

const any50 = (num1, num2) =\&amp;gt; {
 return numIs50(num1) || numIs50(num2) || numIs50(sum(num1, num2))
}

const anyArr = (num1, num2) =\&amp;gt; Array.isArray(num1) || Array.isArray(num2)

const numIs50 = num =\&amp;gt; parseFloat(num) === 50

const sum = (num1, num2) =\&amp;gt; parseFloat(num1) + parseFloat(num2)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;However, had I chosen not to allow string params (which I probably should have done in the first place; over-engineering is an anti-pattern in and of itself, after all), this function could easily boil down to something much, much simpler:&lt;/p&gt;


&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const numOrSumFifty =
 (num1, num2) =\&amp;gt; num1 === 50 || num2 === 50 || num1 + num2 === 50
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2kb-zm9E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/808/1%2A2bc_aP-TStF7HJ-X3ucb1A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2kb-zm9E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/808/1%2A2bc_aP-TStF7HJ-X3ucb1A.png" alt=""&gt;&lt;/a&gt;How I felt about my past self, after refactoring my code.&lt;/p&gt;

&lt;p&gt;Remember what I said about failure to refactor? Always check yourself, kids.&lt;/p&gt;

&lt;p&gt;I wrote my functions out in repl.it &lt;sup id="a8"&gt;8&lt;/sup&gt; as Jest &lt;sup id="a7"&gt;7&lt;/sup&gt; examples, rather than straight JS examples, so I could write test suites for the functions (You can find the first &lt;a href="https://repl.it/@eprislac/numOrSumFifty"&gt;here&lt;/a&gt;, and the ‘no-string-params’ example &lt;a href="https://repl.it/@eprislac/numOrSumFifty-noStrings"&gt;here&lt;/a&gt;). I invite you to write your own tests for the suites in a fork and try to break my functions. If you can think of a case I haven’t, I’ll be more than happy to update my code, and credit you for the find; I love peer review! None of us is above reproach, and if I’ve gotten something wrong, I’d rather know and be able to fix it, than be left in the dark.&lt;/p&gt;

&lt;p&gt;And with that, I hope I’ve shed a little light on some of the mistakes one can commonly make with Javascript’s loose typing as a novice JS dev (and a couple even a pro can make, if they’re not careful). Until next time!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;References:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;span id="f1"&gt;&lt;a href="https://en.wikipedia.org/wiki/Strong_and_weak_typing"&gt;&lt;em&gt;&lt;em&gt;Strong and weak typing&lt;/em&gt;&lt;/em&gt;&lt;/a&gt; | ↩&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span id="f2"&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness"&gt;&lt;em&gt;&lt;em&gt;Loose equality and sameness&lt;/em&gt;&lt;/em&gt;&lt;/a&gt; | ↩&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span id="f3"&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Examples"&gt;&lt;em&gt;&lt;em&gt;Arithmetic Operators&lt;/em&gt;&lt;/em&gt;&lt;/a&gt; | ↩&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span id="f4"&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/parseFloat"&gt;&lt;em&gt;&lt;em&gt;parseFloat&lt;/em&gt;&lt;/em&gt;&lt;/a&gt; | ↩&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span id="f5"&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray"&gt;&lt;em&gt;&lt;em&gt;isArray&lt;/em&gt;&lt;/em&gt;&lt;/a&gt; | ↩&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span id="f6"&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators"&gt;&lt;em&gt;&lt;em&gt;Logical Operators&lt;/em&gt;&lt;/em&gt;&lt;/a&gt; | ↩&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span id="f7"&gt;&lt;a href="https://jestjs.io/"&gt;&lt;em&gt;&lt;em&gt;Jest: Delightful Javascript Testing&lt;/em&gt;&lt;/em&gt;&lt;/a&gt; | ↩&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span id="f8"&gt;&lt;a href="https://repl.it/"&gt;&lt;em&gt;&lt;em&gt;Repl.it&lt;/em&gt;&lt;/em&gt;&lt;/a&gt; | ↩&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;
&lt;span id="f9"&gt;&lt;a href="http://www.zenruby.info/2016/05/ruby-operators-equality-comparison.html"&gt;&lt;em&gt;&lt;em&gt;Ruby operators equality comparison&lt;/em&gt;&lt;/em&gt;&lt;/a&gt; | ↩&lt;/span&gt;
&lt;/li&gt;
&lt;/ol&gt;




</description>
      <category>programming</category>
      <category>javascript</category>
      <category>typecoercion</category>
      <category>novice</category>
    </item>
    <item>
      <title>Adaptive Best Practices</title>
      <dc:creator>Eddie Prislac</dc:creator>
      <pubDate>Thu, 14 Mar 2019 15:26:25 +0000</pubDate>
      <link>https://dev.to/vetswhocode/adaptive-best-practices-53oa</link>
      <guid>https://dev.to/vetswhocode/adaptive-best-practices-53oa</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AUqX8w6VliDiYknE8hCyxGg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AUqX8w6VliDiYknE8hCyxGg.jpeg"&gt;&lt;/a&gt;image courtesy of Markus Spiske on &lt;a href="https://unsplash.com/photos/qjnAnF0jIGk" rel="noopener noreferrer"&gt;unsplash.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published Nov 10, 2015 on my website,&lt;/em&gt; &lt;a href="http://semperfried.com/best-practices/2015/11/20/adaptive-best-practices.html" rel="noopener noreferrer"&gt;&lt;em&gt;semperfried.com&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’ve been reading up on best practices lately, not just in software, but in general, and came across Lindsey Dunn’s article entitled &lt;a href="http://www.beckershospitalreview.com/healthcare-blog/best-practices-don-t-matter-here-s-what-does.html" rel="noopener noreferrer"&gt;Best practices don’t matter, here’s what does…&lt;/a&gt;. The article raises some great points about the blind implementation of best practices and argues for an adaptive culture, citing Toyota’s great success, and how they teach the adaptive methods. Now, this may leave some scratching their heads a bit… you may ask what an article in an online hospital review magazine and an automobile manufacturer’s decisions about best practices have to do with software development. There are some that will be reading the linked article and in their head, they’re bare-chested, swinging their shirts around their heads, and screaming “WOO-HOO!!! THERE’S NO RULES!!!”. You guys, put your shirt back on, and all of you bear with me for a moment, there is a point to this.&lt;/p&gt;

&lt;p&gt;The quote that struck me the most from the article goes like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“We know we cannot implement perfect processes because, first of all, we are human and humans aren’t perfect. Secondly we know that, even if we design a perfect process, the environment will change around that process in unknown and unknowable ways. Therefore, although we work hard to design the best process possible, it is much more important for us to know when our processes fail and then improve them or the environment around them as quickly, simply and easily at the lowest-cost possible.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, identify process failures, then rapidly implement new ‘best practices’ to solve them. While on the surface, the article seems to speak against best practices, the point it actually makes is that we can’t be blind slaves to them; If something in your process breaks or changes, what you previously thought of as a best practice could end up not being so great after all (it’s kind of a “best practice” in and of itself, when you think about it — ironic, huh?). How this relates to software development should be obvious, by now, as this is the essence of the Agile programming model, and a metaphor for the pace at which technology and product life-cycle changes can affect our lives as developers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Case 1:&lt;/strong&gt; In 2010, OpenStruct was listed in &lt;a href="http://rails-bestpractices.com/posts/2010/08/25/use-openstruct-when-advance-search/" rel="noopener noreferrer"&gt;Rails Best Practices&lt;/a&gt;, and as late as 2013, Ruby devs were singing the praises of &lt;a href="http://www.schneems.com/2014/12/15/hashie-considered-harmful.html" rel="noopener noreferrer"&gt;OpenStruct over Hashie::Mash&lt;/a&gt;. Of course, by this time people were already starting to &lt;a href="http://rubyrailroad.com/2013/06/04/pass-openstruct-or-object-to-controller-from-view/" rel="noopener noreferrer"&gt;doubt&lt;/a&gt;, and with improvements to the Ruby 2.x codebase in 2015, there’s now evidence that POROs constructed with keyword args greatly outperform not only OpenStruct, but Hash as well, prompting at least one dev to make the argument that &lt;a href="http://palexander.posthaven.com/ruby-data-object-comparison-or-why-you-should-never-ever-use-openstruct" rel="noopener noreferrer"&gt;you should never, ever use OpenStruct&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Case 2:&lt;/strong&gt; Everyone remember the &lt;a href="https://en.wikipedia.org/wiki/Waterfall_model" rel="noopener noreferrer"&gt;Waterfall model&lt;/a&gt;? When software development first became a thing, there was no process model for development cycles, so the Waterfall model was straight-up lifted from production and manufacturing- and for a while, it was the de-facto standard for working on projects in the industry; Although there were naysayers and mutations to the model, it worked, more or less, for a very long time.&lt;/p&gt;

&lt;p&gt;Nothing lasts forever, though.&lt;/p&gt;

&lt;p&gt;When &lt;a href="https://en.wikipedia.org/wiki/Agile_software_development" rel="noopener noreferrer"&gt;Agile software development&lt;/a&gt; was introduced in 2001, its’ iterative nature, short timeframes, feedback loops, and instant-gratification feel left a lot of us wondering why we’d ever wasted our time with Waterfall. One of my least-favorite phrases in the English language is ‘This is the way we’ve always done it’ (as if that was any justification whatsoever to continue doing something, even when you know that there may be better options available), and Agile seemed to fit my way of thinking to a tee, at the time.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The 12 Principles of the Agile Manifesto:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Customer satisfaction by early and continuous delivery of valuable software&lt;/p&gt;

&lt;p&gt;Welcome changing requirements, even in late development&lt;/p&gt;

&lt;p&gt;Working software is delivered frequently (weeks rather than months)&lt;/p&gt;

&lt;p&gt;Close, daily cooperation between business people and developers&lt;/p&gt;

&lt;p&gt;Projects are built around motivated individuals, who should be trusted&lt;/p&gt;

&lt;p&gt;Face-to-face conversation is the best form of communication (co-location)&lt;/p&gt;

&lt;p&gt;Working software is the principal measure of progress&lt;/p&gt;

&lt;p&gt;Sustainable development, able to maintain a constant pace&lt;/p&gt;

&lt;p&gt;Continuous attention to technical excellence and good design&lt;/p&gt;

&lt;p&gt;Simplicity — the art of maximizing the amount of work not done — is essential&lt;/p&gt;

&lt;p&gt;Self-organizing teams&lt;/p&gt;

&lt;p&gt;Regular adaptation to changing circumstance&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AJ_gjHIcjDIgS5rmk2-TtJg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AJ_gjHIcjDIgS5rmk2-TtJg.jpeg"&gt;&lt;/a&gt;image courtesy of Daria Nepriakhina, from &lt;a href="https://unsplash.com/photos/zoCDWPuiRuA" rel="noopener noreferrer"&gt;unsplash.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agile wasn’t perfect, either, though — there have been many refinements since it was introduced (one might say that this itself fits in with the spirit of Agile, as it’s all about responding to changes and quickly adapting accordingly), and even outright challenges to it’s assumptions… The &lt;a href="https://en.wikipedia.org/wiki/Software_craftsmanship" rel="noopener noreferrer"&gt;Software Craftsmanship&lt;/a&gt; manifesto is one such response. Nowadays, I tend to be in the middle of this argument — there’s no reason why Software Craftsmanship and Agile can’t live side-by-side in harmony. “Projects are built around motivated individuals who should be trusted” — why should they be trusted? If a dev devotes him/herself to the rigors of precision, predictability, measurement, risk mitigation, and professionalism, there’s no reason to have any doubt. Adaptability is a high mark of professionalism in many organizations (the U.S. Marine Corps is one of these — “Adapt and Overcome” is one of the mantras they drill into you in basic training), and should be viewed as such in the software industry. “Working software is the principal measure of progress”; When one applies a professional mindset (and toolset) for testing and gauging the quality of one’s own code, working software is a natural outcome, (and exercising them falls in line with “Continuous attention to technical excellence and good design”). Moreover, applying said disciplines can lead to seeking out more ways to automate existing processes, allowing one to “…maximize the amount of work not done”.&lt;/p&gt;

&lt;p&gt;So OpenStruct goes from being a best practice to something that’s frowned upon as being not only un-performant, but relatively dangerous from a security point-of-view. Waterfall goes from being the only game in town, to being beat out by Agile, which in turn is challenged by the Software Craftsmanship crowd. There’s a lesson that we can learn from this (aside from “not using OpenStruct, or Waterfall methodologies”) The lesson is this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“The best way of doing something now is not necessarily the way it was best done yesterday, and almost certainly not the best way available in the future”.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Change is the only constant. Best Practices are good rules to follow (and I’ll never argue against them, on the whole) — they help us develop a sense of discipline and professionalism in our daily work, and most often do help us write better code. However, without the ability and willingness to learn new things and adapt to changes in the industry, you’ll eventually find your “best practices” will have you practicing the wrong thing.&lt;/p&gt;




</description>
      <category>agile</category>
      <category>programming</category>
      <category>bestpractices</category>
    </item>
    <item>
      <title>A career without a mentor, and why I wish I’d had one.</title>
      <dc:creator>Eddie Prislac</dc:creator>
      <pubDate>Wed, 06 Mar 2019 18:59:43 +0000</pubDate>
      <link>https://dev.to/vetswhocode/a-career-without-a-mentor-and-why-i-wish-i-d-had-one-1oem</link>
      <guid>https://dev.to/vetswhocode/a-career-without-a-mentor-and-why-i-wish-i-d-had-one-1oem</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VhnI2BeO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/450/1%2AimdsUaZ8eulJWtKQv_Fqog.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VhnI2BeO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/450/1%2AimdsUaZ8eulJWtKQv_Fqog.jpeg" alt=""&gt;&lt;/a&gt;Not my Grandpa’s actual computer, but the same model. My Grandma also had a cat pretty similar to the one in the pic as well.&lt;/p&gt;

&lt;p&gt;I first got into coding kind of by accident. My uncle, who is roughly the same age as I am, had experimented with programming when we were young, messing around with writing simple games on his dad’s Tandy-1000 (an antiquated bit of hardware today, but back when Grandpa got it, that thing was mind-blowing to us… it was like being a cave-man who’d discovered a portal into the future). I was impressed with him, but not enough to pick it up myself at the time… I was more interested in honing my artistic skills drawing and painting. It wasn’t until the web became something familiar with consumers quite a few years later that I actually started to take notice. I’d moved in with my uncle and started to dabble with Macromedia Flash, as its visually-oriented tools made a lot of sense to me. I rarely touched any of the backing code, however, focusing instead on the graphical end of things. This dalliance was interrupted by my entry into the Marine corps, and it wouldn’t be until I was able to purchase my first computer (a cheap eMachine) about a year into my enlistment, that I began to seriously endeavor to learn anything useful. However, this being the days when the internet was still in its adolescence and Google was just starting to be a thing, I spent a lot of time learning through trial-and-error.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lEmyGfpu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/468/1%2AGy2qoS_KPxvmjkzlKWGHTw.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lEmyGfpu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/468/1%2AGy2qoS_KPxvmjkzlKWGHTw.jpeg" alt=""&gt;&lt;/a&gt;Not what actually happened, but when spending $500 on a computer drains your bank account, installing Linux on a computer whose hardware doesn’t fully support it feels kind of like this.&lt;/p&gt;

&lt;p&gt;My first real lesson was when I decided to learn something about this ‘Linux’ thing I’d been hearing about. I was sort of familiar with UNIX and knew a lot of important systems ran it, so thought it might be useful to learn a similar OS. I purchased a book on Linux and an actual hard-copy of RedHat from the PX on our base, and proceeded to install the OS on my machine… only to discover to my horror that the dial-up, 56kbps winmodem that came with my computer was not supported by Linux. I’d lost the ability to access the internet, negating the usefulness of my computer in a little less than an hour. I spent the rest of the night reformatting my hard drive and reinstalling Windows ME (yes, it was that long ago). This was the first occurrence of breaking something, and then learning on my own how to fix it, that would become my normal pattern of learning in the years to come.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0PPU0fly--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AH_5wA4z9hwRjI9HltzrOYQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0PPU0fly--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AH_5wA4z9hwRjI9HltzrOYQ.png" alt=""&gt;&lt;/a&gt;A blurry pic of the crew I worked with to put in the solar field at The Marine Corps Air-Ground Combat Center, Twentynine Palms. That goof with the big ears on the top-right? That’s me.&lt;/p&gt;

&lt;p&gt;Skipping forward a few years, I’d taken some programming courses at the local community college, and gotten married. Facing my imminent exit from the Corps upon my EAS, I’d taken a job from a temp agency, doing construction work on base, with the promise that there would be more work with the crew upon completion… a promise that was not fulfilled. The temp agency, however, had a job opening for a tech director, and they saw I had some computer experience, so offered me the position. What I didn’t know at the time, was that ‘Tech Director’ actually meant ‘The only guy on staff that knows anything about computers and needs to install and keep everything running, as well as design and write all the content for the company website’… a position I was woefully unprepared for. While I gave it my best shot, I was unsurprisingly let go from that position about six months later. Despite my failure, I was determined to make my way in the industry… my next job came in the form of a recommendation from one of my old Sergeants… he had a buddy who had started his own tech company, and needed some help. His company, as it turns out, handled network wiring. Not exactly what I’d wanted, but it still involved a lot of work with computers, so I spent much of the next year running network cable in warehouses and office buildings. In my spare time, I worked on the company’s website, and honed my skills in HTML and CSS to the best of my abilities. This was working out great, I thought… until it turned out that my employer was spending all the company’s funds (including as it turns out, my payroll) on his new girlfriend. I discovered this one morning when, after having deposited my paycheck and payed my bills for the month, I woke up to a negative balance of a few thousand dollars, as my employer had cancelled my paycheck after issuing it to me, and then skipped town. Dejected, I spent much of the next year in a protracted legal action against my former boss. I was awarded a $12k settlement, of which I’ve never actually seen a dime. I also didn’t work in tech for the next couple of years. I did, however, find work at the local Pizza Hut, as an assistant manager. There, I worked alongside two Cisco-certified engineers who had also been having trouble finding work, due to the fact that the ‘dot-com bubble’ had just burst, and there was now a glut of similarly-skilled tech-workers in southern California who were now finding themselves in the same position… out of work and wondering just why they’d bothered dropping so much cash on training and certification. I thought, if these guys, so much more qualified than I was, were having such a hard time finding employment in their chosen field, there was little hope for me. My salvation came in the form of that uncle I mentioned earlier, who recommended that I come back home to Texas and apply at the company he now worked for.&lt;/p&gt;

&lt;p&gt;Skipping ahead a year or so, I was now working for that company in Houston, and again, much of my duties involved pulling cable (as well as providing IT support and computer repair for the boss’ family, ugh), but I was afforded much more time to hone my web development skills, as I was also to take over management of the company’s various websites. All for the low, low wage of $10/hr. Again, I found myself in the position of the company’s lone developer, so did most of my learning on the internet. At first, I did so through a couple of online colleges — both of which restructured their GI Bill programs so as to make them totally unworkable by anyone who was also trying to support a family of six while attending school, forcing me to eventually drop out. After that, I relied on various message boards, tutorial sites, books, and so on, trying desperately to consume any and all knowledge I could, and struggling to keep up with the constant inflow of new information. I went off in several different directions, but eventually learned enough C# to get roped into writing a bit of concierge software to control the automation systems for one of the high-end condominiums we were servicing. I had not, however, learned anything about version-control systems at this point… not that it really mattered, because a last-minute hardware change to a Linux-based tablet platform required me to rewrite the entire software from the ground up in PHP. It was at this point I was offered a job writing Flash apps for twice what I was making at the position I was then in.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HDex4gOJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/975/1%2App-gADKXk1XteycmSBA87Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HDex4gOJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/975/1%2App-gADKXk1XteycmSBA87Q.png" alt=""&gt;&lt;/a&gt;So yeah, this is how I was starting to feel, except minus four arms and everything piled on top of me, instead of being expertly juggled.&lt;/p&gt;

&lt;p&gt;At this new company, I found myself in the strange position of being the lone Flash (and later, lone OSS) developer at a mainly Microsoft-based development shop. While I got to do a lot of design work at this company as well, my duties once again included supporting the various websites the company relied on, as well as doing a lot of application architecture and UX engineering… basically, if there was a job the company was offered that did not require a certified C# or SQL-Server engineer, the job fell to me. I continued to learn all I could, from all the sources available to me, but it was still pretty aimless… I was starting to get really perturbed by the thought that, despite all the experience I was getting, I’d always be in a position where I’d be a jack-of-all-trades, and a master of none. I decided to deep-dive into Ruby development, as Ruby’s syntax had always appealed to me, and its package ecosystem was pretty mature. I landed a gig building a Ruby application for a logistics company that supported the oil industry, again doubling my salary. Wow, this is working out great, I again thought… and it did, until the bottom fell out of the oil industry a short while later, and the project was cancelled.&lt;/p&gt;

&lt;p&gt;Once again, I was out of work, but that didn’t last for long. Over the course of the past decade, I’d garnered enough experience to finally be seriously considered for an awesome position with the company with which I’m currently employed. I now work from home, I write Ruby, SQL, and Javascript code all day, and make good money for it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bm9xdmjG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AuNXfPI_VKFmwIFUbxUtsWA.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bm9xdmjG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AuNXfPI_VKFmwIFUbxUtsWA.jpeg" alt=""&gt;&lt;/a&gt;Ok, yeah. Here it is…&lt;/p&gt;

&lt;p&gt;The story I’ve just shared, while it seems long-winded, is actually the short version. I told you all that, so I could tell you this… the long, rough, winding road I undertook to get where I am today could have, for the most part, been avoided, if only I’d had someone to guide me down the right path. A mentor. Someone who’d already established themselves, and knew what it would take for me to get where they are. When I first discovered Vets Who Code, I was immediately impressed with their program, and wanted to contribute in any way possible. Here was a community that, by assigning established mentors to veterans who were just starting out in the industry, was able to impart years worth of the right knowledge in months, and allow fledgling developers to achieve what it had taken me over a decade to do on my own. The difference having a mentor makes is obvious to one who’s made his way without one. While coming up, I had no one to warn me of dubious employers or poorly-defined positions, or even what a fair wage was for a developer. I had no one to point me at the tech which would best serve me when looking for work, or the best-practices and tools which I’d need to work with that tech. Even what I’d learned through nearly completing a computer science degree had not prepared me for the realities of the business, nor had it given me any sense of direction. I had the basic knowledge, but no focus. The VWC program provides our troops (at no cost to them, aside from the work we expect them to put in) all that I was missing… real-life experience with the industry-standard tools and tech of the trade, and the guidance to parlay those skills into a well-paying position. While most paid coding boot-camps will give you the knowledge, few of them will give you the community, and the guidance. To me, that’s where our program really provides its value. Had this program existed when I first began my journey, I have no doubt my career path would have been radically different. I’ve watched graduates of the program score gigs I would have killed for when starting out, and some I’m a little envious of now, if I’m being perfectly honest. As a mentor in the program, I’m damned proud of all of our troops and their continued success, and strongly encourage any vet interested in becoming a developer to give the program a shot. And if you’re reading this and are already established in the industry, I invite you to volunteer as a mentor… help make a fellow vets’ path to success that much easier; the road they have ahead of them is tough enough as it is.&lt;/p&gt;




</description>
      <category>mentorship</category>
      <category>career</category>
      <category>programming</category>
      <category>stories</category>
    </item>
  </channel>
</rss>
