<?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: Travis Woodward</title>
    <description>The latest articles on DEV Community by Travis Woodward (@iamtravisw).</description>
    <link>https://dev.to/iamtravisw</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%2F161584%2F32558b2c-a6dd-48fa-8bf2-676012c52b0d.png</url>
      <title>DEV Community: Travis Woodward</title>
      <link>https://dev.to/iamtravisw</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/iamtravisw"/>
    <language>en</language>
    <item>
      <title>I made a Voice-Activated Pokédex on Google Assistant called PokéPartner! Here's how.</title>
      <dc:creator>Travis Woodward</dc:creator>
      <pubDate>Wed, 29 Jan 2020 05:10:41 +0000</pubDate>
      <link>https://dev.to/iamtravisw/i-made-a-voice-activated-pokedex-on-google-assistant-called-pokepartner-here-s-how-m20</link>
      <guid>https://dev.to/iamtravisw/i-made-a-voice-activated-pokedex-on-google-assistant-called-pokepartner-here-s-how-m20</guid>
      <description>&lt;h2&gt;
  
  
  "Hey Google, Talk to Poké Partner"
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vi_nOo3c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://iamtravisw.com/content/images/2020/01/68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f7777772e706f6b65706172746e65722e636f2f706f6b656d6f6e2d6e696768742e6a7067.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vi_nOo3c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://iamtravisw.com/content/images/2020/01/68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f7777772e706f6b65706172746e65722e636f2f706f6b656d6f6e2d6e696768742e6a7067.jpeg" alt="I made a Voice-Activated Pokédex on Google Assistant called PokéPartner! Here's how."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It goes without saying that I'm a huge Pokémon fan. Ever since the original series came to the US and I watched Ash and Pikachu try to conquer Kanto, or when I put countless hours into Pokémon Blue and every Pokemon game since then... I've been hooked. Now my own daughter is watching the new series and has been playing Let's Go Eevee, and still throughout this entire time for more than 20 years I've wanted a talking Pokedex. Well, I got fed-up with waiting, so I made my own. In this article I will walk through my idea and execution of PokéPartner, the Google Home/ Assistant application that you can talk to about Pokémon.&lt;/p&gt;

&lt;p&gt;Resources:&lt;br&gt;&lt;br&gt;
&lt;a href="https://www.pokepartner.co/"&gt;Website&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/iamtravisw/pokepartner"&gt;Sourcecode&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is PokéPartner?
&lt;/h2&gt;

&lt;p&gt;PokePartner is a Google Assistant application that you can talk to in order to quickly get answers about Pokemon. I built it to solve a problem that I was having in my own household. During a battle with a Pokemon, I wanted to be able to ask my Google Home &lt;em&gt;"What's strong against Grass/ Fire type Pokemon"&lt;/em&gt; and get an answer right away, without grabbing my phone and looking at a type chart. Initially, that was it, I just wanted to know what Pokemon were strong or weak to other Pokemon.&lt;/p&gt;

&lt;h2&gt;
  
  
  Designing the Application
&lt;/h2&gt;

&lt;p&gt;So I had no idea how to build an application for Google Assistant. After a bit of digging around I came across &lt;a href="https://dialogflow.com/"&gt;Dialogflow&lt;/a&gt;, a user-friendly, intuitive, natural language processing tool, owned by Google. This took a lot of the mystery out of the application as it handled communication directly between the user and Google Assistant. I started to roughly design a diagram to figure out how I was going to process the data and return it to the user.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--F7T29u2I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://iamtravisw.com/content/images/2020/01/image-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--F7T29u2I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://iamtravisw.com/content/images/2020/01/image-1.png" alt="I made a Voice-Activated Pokédex on Google Assistant called PokéPartner! Here's how."&gt;&lt;/a&gt;Simple architecture for PokePartner application. &lt;/p&gt;

&lt;p&gt;There was no way that I was going to manually add all the data I needed for an application of this caliber, I needed an API that was pre-existing and established. Luckily, &lt;a href="https://pokeapi.co/"&gt;PokeAPI&lt;/a&gt; already existed. PokeAPI &lt;em&gt;provides all the Pokémon data you'll ever need in one place, easily accessible through a modern RESTful API&lt;/em&gt;. Perfect, exactly what I was looking for, and it was free! The only issue I had now was providing the data back to my users in a meaningful way. This means I had to actually build my own application to consume the data from PokeAPI and then return it back to my users that are using Dialogflow through Google Assistant.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building The Backend
&lt;/h2&gt;

&lt;p&gt;I ended up building a private Web API using C# and .NET Core 3.0. I built the directories into "Feature Folders" rather than Model-View-Controller (MVC) as I find the format to be cleaner, especially when you're not using traditional views. By creating feature folders, you essentially take all related files and stuff them into an easy to access directory. For larger applications, this makes a lot of sense instead of having everything scattered.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XMKUM_aJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://iamtravisw.com/content/images/2020/01/image-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XMKUM_aJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://iamtravisw.com/content/images/2020/01/image-2.png" alt="I made a Voice-Activated Pokédex on Google Assistant called PokéPartner! Here's how."&gt;&lt;/a&gt;Feature Folder idea for PokePartner.Api project.&lt;/p&gt;

&lt;p&gt;The application would be broken into three primary directories. Pokemon, Types and Services. Even though there is a Pokemon folder, there is only a model inside and that is due to right now PokePartner only supporting questions about Pokemon Types. However, the PokemonModel.cs file allows users to get PokemonTypes by their Names, which is a nice feature that I added after building the application.&lt;/p&gt;

&lt;p&gt;The biggest problem I wanted to solve was knowing what type of Pokemon to use against any single or dual type opponent Pokemon. For this I created a TypesController and built a few different API endpoints. The controller can answer questions about Pokemon on Offense of Defense, for Single or Dual type Pokemon. It can also answer questions about Pokemon types, based on the Pokemon name alone. Here's an example:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[HttpGet("defense/{type1}/{type2}")]
        public async Task&amp;lt;IActionResult&amp;gt; DualTypeChartAsDefender(string type1, string type2)
        {
            var types = new List&amp;lt;string&amp;gt;();
            types.Add(type1);
            types.Add(type2);

            var noEffect = new List&amp;lt;string&amp;gt;();
            var notVeryEffectiveRaw = new List&amp;lt;string&amp;gt;();
            var superEffectiveRaw = new List&amp;lt;string&amp;gt;();

            foreach (var t in types)
            {
                var apiType = await _pokeApi.RequestData($"type/{t}");
                var resultsType = JsonConvert.DeserializeObject&amp;lt;TypesModel&amp;gt;(apiType);

                foreach (var rt in resultsType.DamageRelations.DoubleDamageFrom)
                {
                    superEffectiveRaw.Add(rt.Name);
                }

                foreach (var rt in resultsType.DamageRelations.HalfDamageFrom)
                {
                    notVeryEffectiveRaw.Add(rt.Name);
                }

                foreach (var rt in resultsType.DamageRelations.NoDamageFrom)
                {
                    noEffect.Add(rt.Name);
                }
            }

            var json = TypesCalculator.CalculateDamage(superEffectiveRaw, notVeryEffectiveRaw, noEffect);
            return Ok(json);

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



&lt;p&gt;Each result on the controller will return if the Pokemon Type in question will be superEffective, notVeryEffective or have noEffect. Then we send the raw data to the TypesCalculator.cs file to handle the more detailed results. This was put into its own class and method so that it could be reused efficiently and it can return if the type matchup is superEffectiveX4, superEffectiveX2, notVeryEffectiveHalf, notVeryEffectiveQuarter, or NoEffect. Ultimately this is what gets returned back to the Google Assistant and to the user.&lt;/p&gt;

&lt;p&gt;In order to smoothly use the data from PokeAPI, I built Models for the data I was interested in and a Service to handle all the communication between my server and PokeAPI. Due to the complex nature of Pokemon data, I decided to use a model that would work well with the nestled JSON format. I came up with the following:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class TypesModel
    {
        [JsonProperty("damage_relations")]
        public DamageResult DamageRelations { get; set; }
    }

    public class DamageResult
    {
        [JsonProperty("double_damage_from")]
        public List&amp;lt;DamageData&amp;gt; DoubleDamageFrom { get; set; }

        [JsonProperty("double_damage_to")]
        public List&amp;lt;DamageData&amp;gt; DoubleDamageTo { get; set; }

        [JsonProperty("half_damage_from")]
        public List&amp;lt;DamageData&amp;gt; HalfDamageFrom { get; set; }

        [JsonProperty("half_damage_to")]
        public List&amp;lt;DamageData&amp;gt; HalfDamageTo { get; set; }

        [JsonProperty("no_damage_from")]
        public List&amp;lt;DamageData&amp;gt; NoDamageFrom { get; set; }

        [JsonProperty("no_damage_to")]
        public List&amp;lt;DamageData&amp;gt; NoDamageTo { get; set; }
    }

    public class DamageData
    {
        [JsonProperty("name")]
        public string Name { get; set; }
    }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And for communication with PokeAPI, my service ended up being extremely simple. I simply created an HttpClient and passed the request to the correct Uri, awaited a response and then returned the raw JSON to whichever method was requesting the data. It really is that simple to get started with RESTful APIs.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public async Task&amp;lt;string&amp;gt; RequestData(string endpoint) 
        {
            using (var client = new HttpClient())
            {
                var url = new Uri($"https://pokeapi.co/api/v2/{endpoint}");
                var response = await client.GetAsync(url);
                var results = await response.Content.ReadAsStringAsync();
                return results;
            }
        }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That was pretty much all I needed to do on the backend. Now it was time to move on to an area that I was unfamiliar with, Dialogflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the Interface
&lt;/h2&gt;

&lt;p&gt;So I am not an expert using Dialogflow or Firebase and I probably never will be. I won't be providing a tutorial on how to use Dialogflow, or an in-depth guide on how to setup Firebase for Dialogflow. However, &lt;a href="https://www.youtube.com/watch?v=9aHusGxntPw"&gt;here is a more detailed guide&lt;/a&gt; on Dialogflow that I watched before I got started. This video took the hesitation out of building a Google Assistant application for me. There are two major areas of Dialogflow I need to touch on for this to make sense:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Intents:&lt;/strong&gt; How users interact with your application.&lt;br&gt;&lt;br&gt;
For Intents I need users to be able to ask PokePartner questions like "What's super effective against Fire Type Pokemon?", or "What are Flying and Water type Pokemon weak to?" or "What is Pikachu weak to?". I was going to need at least three different Intents, so I ended up making three Intents: SingleType, DualType, and PokemonWeakness.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Un_VgLMO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://iamtravisw.com/content/images/2020/01/image-7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Un_VgLMO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://iamtravisw.com/content/images/2020/01/image-7.png" alt="I made a Voice-Activated Pokédex on Google Assistant called PokéPartner! Here's how."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It was pretty easy to add these intents. I just needed to add a list of what I thought commonly asked questions would be and then the natural language processing tool built into Dialogflow would handle similar sentences on it's own. The next problem to solve was how do I take a question like &lt;em&gt;"What should I use against bug type pokemon?"&lt;/em&gt; and get the right data? Technically you could have Dialogflow return a pre-written answer but can you imagine trying to do that for every scenario? That would be insane! Thankfully, I already wrote backend logic to handle this, by getting raw data from PokeAPI and then putting it into a format that was useful to me. But how did I get that to Dialogflow?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Fulfillment:&lt;/strong&gt; Integrating webhooks into Intents, to provide meaningful results.&lt;br&gt;&lt;br&gt;
By writing simple javascript and using Firebase, you're able to receive POST requests from Dialogflow. You do this by using an Inline Editor on Dialogflow in Google Cloud, which is powered by Cloud Functions for &lt;a href="https://firebase.google.com/"&gt;Firebase&lt;/a&gt;.  Here's a quick example of what a request looks like:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Single Type 
  function singleTypeHandler(agent){
    const type = agent.parameters.type.toLowerCase();  
    return axios.get(`/type/defense/${type}`)
    .then((result) =&amp;gt; {   
      agent.add(`${type} Type Pokémon are weak to ${result.data.superEffective}. So if you want to do the most damage, use one of those types.`); 
      if (result.data.notVeryEffective.length == 0 &amp;amp;&amp;amp; result.data.noEffect.length == 0) {
        // If pokemon has notVeryEffect and NoEffect
      } else if (result.data.noEffect.length == 0) {
        // If pokemon has Weakness but no NoEffects
        agent.add(` Do not use ${result.data.notVeryEffective} As those types are not very effective against ${type} Type Pokemon.`);
      } else {
        // If Pokemon has NoEffect only
        agent.add(`By the way, don't use ${result.data.noEffect} because it will have no effect.`);
      }
    }); 
  }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And that's pretty much it. Firebase handles all the complicated pieces. If you know how to write Javascript and RESTful APIs, you're in a great position to build Google Assistant applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Releasing the Application:
&lt;/h2&gt;

&lt;p&gt;It was finally time to publish my application. I decided to use a Google Cloud computing engine to publish the private backend API which was using C# and .NET Core. I also ended up publishing a "teaser website" to go along with the Google Assistant application, and I'm using a storage bucket for that, as the website is a simple static landing page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EuMhZ8fa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://iamtravisw.com/content/images/2020/01/image-8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EuMhZ8fa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://iamtravisw.com/content/images/2020/01/image-8.png" alt="I made a Voice-Activated Pokédex on Google Assistant called PokéPartner! Here's how."&gt;&lt;/a&gt;Screen capture from Google Cloud.&lt;/p&gt;

&lt;p&gt;Google makes it easy to publish your application by using their &lt;a href="https://actions.google.com"&gt;Actions Console&lt;/a&gt;. You just need to fill out the formal information and you should have your application either Approved or Denied within a few days. It took my application 3 days initially to get denied. It was denied because the name did not match the pronunciation of the name that I listed. Honestly, that was a good catch and once I fixed it, it was accepted same day.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xi8LIUtp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://iamtravisw.com/content/images/2020/01/image-9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xi8LIUtp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://iamtravisw.com/content/images/2020/01/image-9.png" alt="I made a Voice-Activated Pokédex on Google Assistant called PokéPartner! Here's how."&gt;&lt;/a&gt;Action Console by Google.&lt;/p&gt;

&lt;p&gt;That should vaguely cover everything. I've listed this project on my &lt;a href="https://github.com/iamtravisw/pokepartner"&gt;Github&lt;/a&gt; and the launch website can be found &lt;a href="https://www.pokepartner.co/"&gt;here&lt;/a&gt;. Note if you are going to attempt to use the application, just say &lt;strong&gt;"Hey Google, Talk to Poké Partner"&lt;/strong&gt;. But it's worth noting, you really need to over pronounce the é &lt;strong&gt;(Poke-EE-Partner).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hope someone finds a use for it! I've personally had a great time using this application while playing through Pokemon Sword and Pokemon Shield. However, it should be noted that at the time of writing this article, &lt;em&gt;PokeAPI has not yet added the latest generation of Pokemon to their API, so you won't be able to use any of their names yet&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I am hoping to add more to this project later, and I am happy to accept any additions to the work on Github! I'd like for it to become a free and easy to use resource for the Pokemon community.&lt;/p&gt;

&lt;p&gt;'&lt;em&gt;Pokemon Night' artwork by &lt;a href="https://www.artstation.com/joker-sheep"&gt;魔人 王&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
      <category>csharp</category>
      <category>googleassistant</category>
    </item>
    <item>
      <title>The Principles of Object Orientated Programming as explained by Pokémon</title>
      <dc:creator>Travis Woodward</dc:creator>
      <pubDate>Sun, 18 Aug 2019 15:22:20 +0000</pubDate>
      <link>https://dev.to/iamtravisw/the-principles-of-object-orientated-programming-as-explained-by-pokemon-4eo5</link>
      <guid>https://dev.to/iamtravisw/the-principles-of-object-orientated-programming-as-explained-by-pokemon-4eo5</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rBzFF9JJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://iamtravisw.com/content/images/2019/08/pexels-photo-1310847.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rBzFF9JJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://iamtravisw.com/content/images/2019/08/pexels-photo-1310847.jpeg" alt="The Principles of Object Orientated Programming as explained by Pokémon"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why Pokémon? Why not? Many of my peers grew up with Pokémon or now have kids that are watching Pokémon. Also, many beginners struggle to grasp the basics of Object Orientated Programming.  My hope is that mixing the four core principles with something so many people have seen will help it click. By making the topic less abstract (which is ironic) and more relatable, it could help someone grasp the basics. What more could we ask for? So let's get started!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: If you don't follow Pok&lt;/em&gt;é&lt;em&gt;mon, this article probably won't make much sense.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--T49O_XCX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/http://iamtravisw.com/content/images/2019/08/chancey.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--T49O_XCX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/http://iamtravisw.com/content/images/2019/08/chancey.gif" alt="The Principles of Object Orientated Programming as explained by Pokémon"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Object Orientated Programming?
&lt;/h3&gt;

&lt;p&gt;First; Object Orientated Programming (OOP) is a programming language model where Objects communicate with one another in order to solve a problem. Objects are snippets of code that can be reused so that you don't have to always rewrite it. Objects are used in classes and classes are just blue prints for those Objects. By using those blueprints (or classes) you can create instances of those Objects, which are essentially just versions of the original Object, built from the blueprint.&lt;/p&gt;

&lt;p&gt;Okay that was a lot in a small paragraph, but it's important that you understand that before proceeding. It's also the only part of this entire article that won't use Pokémon to help you learn, so make sure you grasp these concepts before reading rest. &lt;em&gt;Objects&lt;/em&gt; are used in classes. &lt;em&gt;Classes&lt;/em&gt; are blueprints. &lt;em&gt;Instances&lt;/em&gt; of objects are built from those classes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Encapsulation
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aNGe3Ky7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/http://iamtravisw.com/content/images/2019/08/pokeball.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aNGe3Ky7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/http://iamtravisw.com/content/images/2019/08/pokeball.gif" alt="The Principles of Object Orientated Programming as explained by Pokémon"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Encapsulation is the process of combining functions and data into a class. Data is not accessed directly but rather through functions within the class. The point of encapsulation is to restrict the access to your Object's components so that users aren't modifying your objects directly.&lt;/p&gt;

&lt;p&gt;Think of encapsulation as a Pokéball. Everyone knows how to use it, regardless of how it works on the inside. The Pokemon trainer doesn't have to know why it works, they just need to know how to throw it and play by the rules. In programming, the user doesn't have to know anything other than the interface you provide, and you only want to provide them with access to relevant information. This is called information hiding and it is important.&lt;/p&gt;

&lt;p&gt;In order to use Encapsulation properly, you will need to use access modifiers. Different languages use different variations of access modifiers, but in Java they are:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Public:&lt;/strong&gt; Code from anywhere in the application can access it.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Private:&lt;/strong&gt; Only code within the same class can access it.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Default:&lt;/strong&gt; When you don't define an access modifier for your class, you will be using the default access modifier. Code within the same class and package can access the code.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Protected:&lt;/strong&gt; The protected class has the same access as default with the addition of sub-classes having the ability to access the code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Inheritance
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--K1VkGBnQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/http://iamtravisw.com/content/images/2019/08/char.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--K1VkGBnQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/http://iamtravisw.com/content/images/2019/08/char.gif" alt="The Principles of Object Orientated Programming as explained by Pokémon"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Inheritance in programming is when one class acquires properties from another class. In Java a class can only be derived from one other class. We call the original class a parent class (or superclass). The derived class is called the child class (or subclass). This is where Pokémon as a comparison really starts to shine. Remember evolution? Remember when Charamader turned into Charmeleon. That's actually a great example of inheritance.&lt;/p&gt;

&lt;p&gt;Let's say you have a Charmader (Superclass) and it knows two basic moves. Scratch and Burn. Suddenly your Charmander is strong enough to evolve and it turns into Charmeleon (Subclass). Charmeleon learns a new move called Flamethrower, but it also still has access to Scratch and Burn because it inherited those abilities from Charmander (which was the Superclass). Whoa, that kind of makes sense right?&lt;/p&gt;

&lt;p&gt;That is the basic concept of Inheritance in object orientated programming. If you were writing a program you wouldn't want to write the same code over and over again, that's not efficient and it's a nightmare to manage. Instead you would extend your parent class with a new child class, and all of the original properties from the parent class will be extended to the child class. Same results, more efficient, but a lot less work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Polymorphism
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TiHT0rc9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/http://iamtravisw.com/content/images/2019/08/eevee.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TiHT0rc9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/http://iamtravisw.com/content/images/2019/08/eevee.gif" alt="The Principles of Object Orientated Programming as explained by Pokémon"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Polymorphism is the ability to take on many forms. In programming polymorphism means to process objects differently based on their data type. In other words, if you have one method, it may have multiple implementations for a certain class action. At the point the application runs (runtime), it will decide what to do.&lt;/p&gt;

&lt;p&gt;In Pokémon two characters show this ability prominently, Ditto and Eevee. Let's use Eevee as the example. If you have a parent class called Eevee with multiple child classes (Vaporeon, Leafeon, Jolteon, etc...), and then put Eevee in contact with an evolution stone... The corresponding child class would be called. So if Eevee came into touch with a water stone, the Vaporeon child class would be triggered at runtime and the Vaporeon code would be used opposed to Leafeon, Jolteon, etc...&lt;/p&gt;

&lt;p&gt;So how do you use Polymorphism? Well in Java, polymorphism can be either static or dynamic. Method Overloading is static and Method Overriding is dynamic. &lt;strong&gt;Overloading&lt;/strong&gt; is considered static because the method that is invoked is decided at the time of compilation. You use overloading when methods that share the &lt;em&gt;same name&lt;/em&gt; behave differently based on the arguments passed to the method. Here's an example in code:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Eevee {

    public void sound () {
        System.out.println("Eevee");
    }

    public void sound (int num) {
        for (int n : num) a
        {  
            System.out.println("Eevee");    
        }    
    }
}

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



&lt;p&gt;&lt;strong&gt;Overriding&lt;/strong&gt; is considered dynamic because it is resolved at runtime. Overriding  means that a derived class is implementing a method of its parent class. If that sounds confusing, think about the Eeveelution example we talked about. Here it is in code form:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Eevee{
    public void sound(){
        System.out.println("Eevee");
    }
}
class Vaporeon extends Eevee{
    public void sound(){
        System.out.println("Vaporeon");
    }
}

public class OverridingTest{
    public static void main(String [] args){
        Eevee eevee = new Vaporeon();
        eevee.Vaporeon();
    }
}

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



&lt;p&gt;In this example "Vaporeon" would be the output.&lt;/p&gt;

&lt;h3&gt;
  
  
  Abstraction
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ni_GL9IT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/http://iamtravisw.com/content/images/2019/08/trade.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ni_GL9IT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/http://iamtravisw.com/content/images/2019/08/trade.gif" alt="The Principles of Object Orientated Programming as explained by Pokémon"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Abstraction is the process of showing only relevant data to the users and hiding unnecessary information. A great example in Pokémon is trading with a friend. During this process, surely there is a lot going on behind the scenes. A lot of data is being transferred, files are being updated and objects are definitely being instantiated. However to the users, all you see is your Pokéball being sucked through a machine and disappearing before a new Pokéball lands before you. This is abstraction. That's it. It doesn't need to become anymore complicated than that.&lt;/p&gt;

&lt;h3&gt;
  
  
  Wrap it up
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SN4awGie--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/http://iamtravisw.com/content/images/2019/08/pikachu.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SN4awGie--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/http://iamtravisw.com/content/images/2019/08/pikachu.gif" alt="The Principles of Object Orientated Programming as explained by Pokémon"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It goes without saying that this was a simplified explanation of Object Orientated Programming but I hope that this article can help someone who may have been struggling to understand the concepts a little better. As with most things, programming is a skill and it takes a lot of practice to master. If these concepts aren't making complete sense, you should study them deeper because they &lt;em&gt;are&lt;/em&gt; the core fundamentals of OOP. Having a strong foundation is the best way to build your skills. I'll leave you all with the obligatory Pikachu GIF. Thanks for reading.&lt;/p&gt;

</description>
      <category>oop</category>
      <category>java</category>
      <category>newbie</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Tips for Writing an ETL Console Application in C# .NET Core</title>
      <dc:creator>Travis Woodward</dc:creator>
      <pubDate>Sun, 04 Aug 2019 00:12:50 +0000</pubDate>
      <link>https://dev.to/iamtravisw/tips-for-writing-an-etl-console-application-in-c-net-core-1ppd</link>
      <guid>https://dev.to/iamtravisw/tips-for-writing-an-etl-console-application-in-c-net-core-1ppd</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OfbYiA37--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://iamtravisw.com/content/images/2019/08/pexels-photo-577585.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OfbYiA37--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://iamtravisw.com/content/images/2019/08/pexels-photo-577585.jpeg" alt="Tips for Writing an ETL Console Application in C# .NET Core"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;First and foremost this is not a guide but an outline of my experience.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I was recently tasked with writing an ETL process at work and it was something that I really enjoyed doing. The goal was to take 20 million or more documents from a &lt;a href="https://www.marklogic.com/"&gt;Mark Logic&lt;/a&gt; database and move them into a &lt;a href="https://www.postgresql.org/"&gt;Postgres&lt;/a&gt;database. Easy enough. However the caveat was that all the data in Mark Logic is in an XML format and the desired data format in Postgres  is Json. Still, thanks to &lt;a href="https://www.newtonsoft.com/json"&gt;Json.NET&lt;/a&gt; this isn't too difficult a problem, just a few lines of code. I'll walk through the process that I went with below.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is ETL?
&lt;/h2&gt;

&lt;p&gt;An ETL process is a process to &lt;strong&gt;E&lt;/strong&gt; xtract &lt;strong&gt;T&lt;/strong&gt; ransform and &lt;strong&gt;L&lt;/strong&gt; oad data from one database to another. Depending on your datasets this could be an easy task or a very time consuming process. In my case, I was lucky enough that our principle engineer already had classes setup in our primary application that I could re-use to easily read the XML data from Mark Logic. A great example of why it's important to write clean, re-useable code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Planning the Application
&lt;/h2&gt;

&lt;p&gt;During the planning stages of the process I knew that I would be dealing with a lot of data. It might take N hours to load 5 million records, what if the application crashes before it reaches the end? We don't want to load the same 5 million records again. I would need to write a way to keep track of the records that were already inserted. In addition to that, I would need a configurable file that lets us manipulate it's contents after run-time. The file would need to be executable in any environment which presented challenges of it's own. These were my two biggest concerns, the actual extracting, transforming and loading of data was at the back of mind at this point.&lt;/p&gt;

&lt;h3&gt;
  
  
  Config File
&lt;/h3&gt;

&lt;p&gt;So one of the first things you're going to want to do is create a Config file. There are lots of options when it comes to creating a config, I went with using a json file. Here is a more detailed &lt;a href="https://garywoodfine.com/configuration-api-net-core-console-application/?fbclid=IwAR2F9Y3oEFGCQN3ZYKKOcbY5Py3N0TFXvxuTmRlroah3h2HlNTihuRWj7M0"&gt;guide&lt;/a&gt; by Gary Woodfine on setting up a Configuration file in .Net Core for console applications. By using a Json file for your configuration, you get to use Name-Value pairs which is a really easy and straightforward way to use your settings.&lt;/p&gt;

&lt;p&gt;My appsettings.json file is designed to hold three primary bits of information. First the batch size for the amount of files I want to move at once. There will be more on this in the next section below. Secondly the connection details for the MarkLogic database that I will be connecting to and grabbing data from. Finally, the Postgres database connection information that I will be inserting data into. Your results may vary depending on how complex your console applications becomes. This would be a great place to introduce additional settings.&lt;/p&gt;

&lt;h3&gt;
  
  
  Extract
&lt;/h3&gt;

&lt;p&gt;The Extraction process should be relatively straight forward. The goal is to grab the data and then break it into chunks that you can control better. For example, if you're writing an ETL process for 100,000,000 rows of data, you likely aren't going to do it all in one go. What if the process fails half way through? How much memory would that take to run the process? More than likely your program would crash for one reason or another. So instead you want to do this in increments.&lt;/p&gt;

&lt;p&gt;In my situation, I am grabbing all of the IDs from the original database (roughly 20 million at the time of writing) and then storing those IDs in chunks of 10,000. Then for 10,000 documents at a time I am using their IDs and grabbing the actual documents from MarkLogic. This is a setting in my appsettings.json file and it can be adjusted based on performance or requirements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Transform
&lt;/h3&gt;

&lt;p&gt;After grabbing the 10,000 documents by their Ids, I needed to transform the data from XML to Json. This is where the &lt;a href="https://www.newtonsoft.com/json"&gt;Json.NET&lt;/a&gt; library comes into play. With just a few simple lines of code Json.NET will translate most things to Json, however based on your needs, your results may very. Note the transform section will be short here, because the Json.NET library handled most of the heavy lifting for me.&lt;/p&gt;

&lt;h3&gt;
  
  
  Loading
&lt;/h3&gt;

&lt;p&gt;Loading should be pretty similar to extracting in the sense that you're connecting to a database using the information in your config file and then transferring data. In my case I am connecting to Postgres and inserting a single row for each document. This row holds the unique file ID, the Jsonb document, the created and updated dates and finally a transnational ID to help prevent duplicate data being added once the base loading was completed.&lt;/p&gt;

&lt;p&gt;Initially I was using INSERT statements for getting the data into Postgres however after some research I found that using insert statements were not the most efficent way to handle this. Postgres supports &lt;a href="https://www.postgresql.org/docs/9.2/sql-copy.html"&gt;COPY&lt;/a&gt;, which can transfer data between a file or text and a table in binary format. I found that using COPY opposed to INSERT saved me roughly 50% overall time in the loading process, which as you can imagine is more helpful as your dataset grows. I highly recommend researching if COPY is the right choice for you when writing an ETL process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing
&lt;/h3&gt;

&lt;p&gt;Testing is going to be an important step in your process. You don't want to just try to run your application in production, that's not a good place to find out you made an error in your transform logic or load logic. I highly recommend setting up a docker container with Postgres and connecting locally there first. You can set this to be an option in your appsettings.json file and you will be able to easily switch between environments. For setting up a Docker container for Postgres, here's a useful &lt;a href="https://hackernoon.com/dont-install-postgres-docker-pull-postgres-bee20e200198"&gt;article&lt;/a&gt;. Once you've tested your application, you're ready to transfer real data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mission Success
&lt;/h2&gt;

&lt;p&gt;At my company this console application is actively being used and it runs daily to continuously move data from one database to another. As always, there is room for optimization however for our needs this simple console application fits the bill pretty well. Thanks to using asynchronous tasks in the console application, I can create an order for which type of documents I want to pull and then run the application and have it do all the heavy lifting for me. The application does what it was created to do and gets us the results we need so I would call it a success.&lt;/p&gt;

&lt;h3&gt;
  
  
  TL;DR Tips Summarized
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Use Existing Code and Libraries when applicable.&lt;/li&gt;
&lt;li&gt;Asynchronous programming is likely something you'll want to use here.&lt;/li&gt;
&lt;li&gt;Create a Config File, this will help cut down on duplicate code.&lt;/li&gt;
&lt;li&gt;If you're dealing with a lot of data, break it into chunks.&lt;/li&gt;
&lt;li&gt;Transforming and Loading may be tightly knitted together thanks to libraries that can convert data from one format to another (like XML to Json). This isn't a bad thing.&lt;/li&gt;
&lt;li&gt;Explore all your options when trying to optimize your code. For example, when dealing with large chunks of data using Postgres, COPY is &lt;em&gt;a lot&lt;/em&gt; faster than INSERT.&lt;/li&gt;
&lt;li&gt;Create a Recovery Process. You don't want to get 19,000,000/ 20,000,000 rows of data moved and then have your application crash, only to have to do the first 19,000,000 records again.&lt;/li&gt;
&lt;li&gt;Test Locally first, Docker is great for this sort of thing.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>sql</category>
      <category>coding</category>
      <category>etl</category>
      <category>csharp</category>
    </item>
    <item>
      <title>5 Things I Wish I Knew Before My First Day of Being A Junior Software Engineer</title>
      <dc:creator>Travis Woodward</dc:creator>
      <pubDate>Sun, 28 Apr 2019 15:49:08 +0000</pubDate>
      <link>https://dev.to/iamtravisw/5-things-i-wish-i-knew-before-my-first-day-of-being-a-junior-software-engineer-4cfd</link>
      <guid>https://dev.to/iamtravisw/5-things-i-wish-i-knew-before-my-first-day-of-being-a-junior-software-engineer-4cfd</guid>
      <description>&lt;h1&gt;
  
  
  My list of things that I wish I knew before my first day as a Software Engineer.
&lt;/h1&gt;

&lt;p&gt;I've been an Associate Software Engineer for a little over 3 months now and I thought it would be a good time to write a helpful article for other junior engineers who are about to start out at a new job, or maybe for those who are actively applying for their first development position. This list may not be as relevant for you, however for me these were my five big points. Honestly, I wish that my school work covered these areas more. Collaboration is such a huge part of development and I feel like most of what I learned through school was theory and how to program as an individual engineer, not as part of a team.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So without further ado...&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. I wish I had more experience setting up and troubleshooting my work environment
&lt;/h2&gt;

&lt;p&gt;It's day 1, my only responsibility is getting my work environment setup and meeting my peers. Easy... right? Not so fast...&lt;/p&gt;

&lt;p&gt;So throughout my university experience and while doing personal projects, I had not setup Visual Studio one time. While I did have experience setting up Netbeans @WGU,  Eclipse @CSU and Rider and IntelliJ at home, I had no experience using Visual Studio. This isn't too surprising considering all of the IDEs I've used prior (except for Rider) were to development Java applications and now I am writing C# in .NET Core.&lt;/p&gt;

&lt;p&gt;My first day I ran into a handful of errors while trying to compile my code. I was troubleshooting most of the day and while our documentation was really well done, there were areas that were not covered in it, like handling specific errors that I was running into. I really think that a course on setting up an IDE work environment could be a valuable class in college. Apparently, some of my co-workers take their whole first week to setup their work machine, which now I can understand as it takes time to get everything exactly how you want it to be. Finally, a few days later I was able to get everything working smoothly with the help of our principle engineer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip to make it easier:&lt;/strong&gt; Once you accept a job offer, contact your boss and ask about the IDE and any plugins that the team uses. Take your time to learn the IDE and try downloading some projects from the internet and try getting them setup.&lt;/p&gt;

&lt;h1&gt;
  
  
  2. Wish I was more familiar with Git and using it with a team
&lt;/h1&gt;

&lt;p&gt;Git... Perhaps one of the most important areas of modern programming. Almost every company is either using git or some version of source control. For me, in school Git was simply not used, at all. There was no course on how to use Git, what it was, or why it was important. Luckily, I had used Git in some of my personal projects so I was not completely lost, but it was only to store projects on Github and not to collaborate.&lt;/p&gt;

&lt;p&gt;The problem is that git really shines at collaboration but there are some scary problems that you can run into while trying to merge your branch's code back into the trunk. These problems are especially scary at a junior level when you're afraid to make mistakes. Once you go to merge your code, if you see the build fail, I guarantee as a first time recently employed junior developer your heart will fall right into your stomach. It will be okay. You can fix pretty much any Git problem that you run into and your senior engineers know this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tips to make it easier:&lt;/strong&gt; Practice! Find projects that you are interested in and try to contribute to them, github is probably the best source for this. Take some of Gitlab's courses on Git... They're free. Finally, I have found that if I rebase my branch first before merging, I have a greater success rate because of how rebase works versus merge. Here's a great article on rebase vs merge.&lt;/p&gt;

&lt;h1&gt;
  
  
  3. Debugging code and using break points
&lt;/h1&gt;

&lt;p&gt;During my first week as a junior developer, I was tasked with writing some Unit Tests for existing code that was confirmed to be working. By the way, writing Unit Tests for existing code is a great way to learn the code base and get familiar with the structure of the application you're working on. During this time, I was very green at using break points and debugging. You can imagine how ill-prepared I felt to write tests, but I did it and I even found my first bug.&lt;/p&gt;

&lt;p&gt;In retrospect; I don't recall writing any Unit Tests at all during my time in college. I remember taking some software testing classes, but they were manual testing/ quality assurance classes. These were helpful for sure, but they helped very little with unit testing. While writing my first set of tests, I didn't realize that I could place a break point in the controller I was testing. Writing that now makes me feel a little silly, OF COURSE I can put break points in the controller I am testing but while I was writing the tests, I only thought to put break points in the test class.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tips to make it easier:&lt;/strong&gt; Write some unit tests for your personal projects. Test Driven Development is a big deal and a lot of companies use it. Where I am at now, we are not allowed to push out RESTful Web API Controllers/ end points without Unit Tests to go along with them. Also, ask your new team what they use for Unit Tests prior to starting and try to get familiar with it. At my job we use xUnit and I wish I had spent a little time with it prior to starting. It's not particularly difficult, but having that confidence boost in familiarity goes a long way.&lt;/p&gt;

&lt;h1&gt;
  
  
  4. Learning how to navigate my IDE better
&lt;/h1&gt;

&lt;p&gt;This could technically go with "I wish I had more experience setting up and troubleshooting my work environment" and "debugging code and using break points" but I felt it was important enough to have it's own section.&lt;/p&gt;

&lt;p&gt;Imagine this; You're in a 1-on-1 code review with your new supervisor. You bring your laptop into the room and you fumble around the shortcut keys and tabs while trying to run through your code with them. Sure, you're new and it's understandable that you may not be able to explain your code quickly, but fumbling around because you're unfamiliar with your IDE is something that you should be able to workout in a few weeks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tips to make it easier:&lt;/strong&gt; Learn the shortcut keys for your IDE (Visual Studio, VS Code, Intellij, etc...), it will help a ton! On your next home project, code in the IDE your job uses, just to get a bit more familiar with using it. Also if you're company uses extensions or plugins, it's a good idea to get familiar with those as well.&lt;/p&gt;

&lt;h1&gt;
  
  
  5. It's okay to learn on the job
&lt;/h1&gt;

&lt;p&gt;Okay, this is the most important point. Impostor syndrome is real.  It is okay to learn on the job, in-fact it is generally encouraged. There's a line of course; you still need to complete your work and focus on work related tasks, but learning is a continuous part of programming. When I got a job offer at my current job, I was very nervous about learning C# when I had previously only used Java and Python. I did some self-learning at home, but most of my C# coding skills definitely come from learning on the job.&lt;/p&gt;

&lt;p&gt;It's important to remember you are trying to land a junior level position. These positions are created with learning in mind. My company pays for a PluralSight and LinkedIn Learning subscription for it's developers so that we can learn new technologies or help junior engineers learn our current stack better. It's okay not to know everything and it's okay to ask questions. My advice is try to solve the problems on your own first, then try Google/ StackOverflow and if you are still stumped, ask one of your senior engineers if they can help you learn how to X.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tips to make it easier:&lt;/strong&gt; Learn to go with the flow and take advantage of the resources that are available to you. Become comfortable asking for help but become even more comfortable searching for solutions to your own problems. Again, it's a balance. You need to spend time trying to solve your own problems, that's expected... but it's also known that you are still learning and will need to ask for assistance at times. Also, please don't let impostor syndrome stop you from applying to junior level jobs. Get your resume out there, if you're passionate and know the basics, you can learn everything else!&lt;/p&gt;




&lt;p&gt;And that's my list of things that I wish I knew prior to my first day as a software engineer. Hopefully this list helps someone relax and prepare for their first junior software engineer position. Also, your results may vary... All companies are different, but this should be a good starting point for most any company. Good luck on your position as a software engineer!&lt;/p&gt;

&lt;p&gt;Please subscribe and follow me on my website for more posts like this: &lt;a href="https://iamtravisw.com"&gt;https://iamtravisw.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>coding</category>
      <category>juniordeveloper</category>
      <category>career</category>
    </item>
    <item>
      <title>Linux Tutorial: Make GIMP more like Photoshop</title>
      <dc:creator>Travis Woodward</dc:creator>
      <pubDate>Sun, 31 Mar 2019 02:17:14 +0000</pubDate>
      <link>https://dev.to/iamtravisw/linux-tutorial-make-gimp-more-like-photoshop-48f</link>
      <guid>https://dev.to/iamtravisw/linux-tutorial-make-gimp-more-like-photoshop-48f</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VGMdcR7q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://iamtravisw.com/content/images/2019/04/Screenshot-2018-10-23-at-4.11.21-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VGMdcR7q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://iamtravisw.com/content/images/2019/04/Screenshot-2018-10-23-at-4.11.21-PM.png" alt="Linux Tutorial: Make GIMP more like Photoshop" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The following instructions are heavily inspired by Bernard 't Hooft over at Udemy. I found instructions from his Windows 7, 8 and 10 course here: &lt;a href="https://www.udemy.com/make-gimp-work-as-photoshop/" rel="noopener noreferrer"&gt;https://www.udemy.com/make-gimp-work-as-photoshop&lt;/a&gt;. I know that many Linux users love GIMP but may still be missing that 'Photoshop feeling' so I wanted to share how to use his tutorial on a machine running Linux.&lt;/p&gt;

&lt;p&gt;Here's what the end result from this tutorial will bring you:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkgjrhp4uhoygmq8zc6ub.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkgjrhp4uhoygmq8zc6ub.png" alt="Linux Tutorial: Make GIMP more like Photoshop" width="640" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Prerequisites:&lt;/p&gt;

&lt;h4&gt;
  
  
  You should have flatpak installed, you'll need this to install GIMP 2.10 on Linux.
&lt;/h4&gt;

&lt;p&gt;Run the following commands:&lt;/p&gt;

&lt;p&gt;sudo apt-get update&lt;/p&gt;

&lt;p&gt;sudo apt-get install flatpak&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Install GIMP 2.10.X (2.10.6 at the time of writing)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Run the following command:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;sudo flatpak install &lt;a href="https://flathub.org/repo/appstream/org.gimp.GIMP.flatpakref" rel="noopener noreferrer"&gt;https://flathub.org/repo/appstream/org.gimp.GIMP.flatpakref&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: At the time of writing this, &lt;strong&gt;sudo apt-get install&lt;/strong&gt;  &lt;strong&gt;gimp&lt;/strong&gt; is still returning gimp 2.8 (an older version of GIMP. This tutorial is aimed at 2.10.6)&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Install Plugins
&lt;/h3&gt;

&lt;p&gt;We are going to be installing the following two plugins along with some other cool stuff:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Resynthesizer (Content Aware Filling)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Layer Via Copy&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2a. Download the .zip file from Bernard's course here:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.udemy.com/make-gimp-work-as-photoshop/learn/v4/t/lecture/12014132?start=0%5C" rel="noopener noreferrer"&gt;https://www.udemy.com/make-gimp-work-as-photoshop/learn/v4/t/lecture/12014132?start=0\&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: I think you'll need to enroll to see the files. It's a great course and goes beyond what I teach here. The primary difference is that my tutorial is aimed at Linux users. &lt;strong&gt;You want the Udemy file from Section 1: Part 3 'Installing Plugins'.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2b. Make sure GIMP is closed.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2c. Navigate to your GIMP folder.&lt;/strong&gt;    For me, on &lt;a href="https://www.reddit.com/r/crostini" rel="noopener noreferrer"&gt;Crostini&lt;/a&gt; it was in the following location:&lt;/p&gt;

&lt;p&gt;CD .var/app/org.gimp.GIMP/config/GIMP/&lt;/p&gt;

&lt;p&gt;It may be different for you if you are on a different version of Linux or have a more custom install. It's important to point out that if you installed GIMP previously, you will have a GIMP 2.8 folder. &lt;strong&gt;This is not the correct folder for your 2.10 plugins.&lt;/strong&gt; You may need to navigate around a bit to find the right folder. You can use the &lt;strong&gt;ls -a&lt;/strong&gt; command to see your hidden folders.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2d. (Optional but recommended) Make a backup of your current setup.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Run the following command:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;cp -R 2.10 2.10-backup&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2e. Copy and Paste all the contents from the Udemy folder to your 2.10 folder.&lt;/strong&gt;   You'll need to know your full directory name so open a new terminal window and type ' &lt;strong&gt;pwd&lt;/strong&gt;'. Mine is &lt;strong&gt;/home/iamtravisw/&lt;/strong&gt; so yours will likely be &lt;strong&gt;/home/YOURNAME/&lt;/strong&gt;. Once you have that, run the following command to copy your contents over to the 2.10 folder:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Run the following command:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;cp -a /home/YOURNAME/Udemy/. /home/YOURNAME/.var/app/org.gimp.GIMP/config/GIMP/2.10&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Open GIMP and Save Preferences.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By now GIMP should look a lot more familiar if you're coming from Photoshop like I did.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3a. You'll want to click the maximize icon to make GIMP full screen then go into the Edit &amp;gt; Preferences menu.  Click 'Window Management' then click 'Save Window Positions Now'.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are many other ways customize GIMP, this is just the tip of the iceberg. I am a novice GIMP user myself, however the Udemy course I mentioned at the start of this tutorial covers A LOT of additional information such as customizing the user interface of GIMP to be even more like Photoshop. I recommend watching what Bernard has to offer as it could be very educational and exactly what you need. Now that you have the skills and knowledge to apply his changes to your Linux version of GIMP you should be able to mimic what he does on Windows, but in Linux.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UPDATE:&lt;/strong&gt; Bernard 't Hooft has generously offered to let the readers of my blog have access to his new course, The Ultimate GIMP 2.10 Guide. &lt;a href="https://www.udemy.com/the-ultimate-gimp-guide-amazon-book-included/?couponCode=FREEGIMP210" rel="noopener noreferrer"&gt;By clicking here you can access the $199 course for free.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Happy editing!&lt;/p&gt;

&lt;p&gt;Travis W.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>photoshop</category>
      <category>gimp</category>
      <category>chromeos</category>
    </item>
    <item>
      <title>Why I'm leaving my 5+ year Career in Support to become a Developer</title>
      <dc:creator>Travis Woodward</dc:creator>
      <pubDate>Sun, 31 Mar 2019 02:11:43 +0000</pubDate>
      <link>https://dev.to/iamtravisw/why-i-m-leaving-my-5-year-career-in-support-to-become-a-developer-2i4i</link>
      <guid>https://dev.to/iamtravisw/why-i-m-leaving-my-5-year-career-in-support-to-become-a-developer-2i4i</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fiamtravisw.com%2Fcontent%2Fimages%2F2019%2F04%2Fpexels-photo-326424.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/http%3A%2F%2Fiamtravisw.com%2Fcontent%2Fimages%2F2019%2F04%2Fpexels-photo-326424.jpeg" alt="Why I'm leaving my 5+ year Career in Support to become a Developer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Picture this, it's 2013 and you just landed your first real "career". You're a software support employee for a great company with great benefits. You are 23 and have had to put college on hold due to some personal and financial reasons, so this job is really important to you. Oh, and your salary is higher than all of your friends. Sounds too good to be true, right? It wasn't.&lt;/p&gt;

&lt;p&gt;That was my situation in March 2013 when I started at the Greenbrier Companies. I owe a lot to this company. They pulled me out of a rough situation, they helped me take my chaotic life and make it stable, and rewarded me with great benefits such as paid time off and a big bonus each year. In 2016 they moved me away from Dayton, Ohio into a better, higher paying position in the beautiful state of Colorado. The move was taken care of, it was a very stress free situation.&lt;/p&gt;

&lt;p&gt;I went from being the primary software support analyst for software that I really loved and believed in (Track and Trace) to the software support lead for all of the software in the company. This is where my fairy tale story begins to fall apart. &lt;a href="https://www.iamtravisw.com/2018/09/moving-to-boulder-co.html" rel="noopener noreferrer"&gt;A year after my move to Boulder,&lt;/a&gt; I was still getting used to my new position. Even today, I am not sure if I ever reached my full potential at Greenbrier. While I believe I was very educated in the track and trace area, supporting the rest of the company really made me burn through my passion quickly. I simply didn't want to be there anymore. I didn't want to work with customers, I didn't want to start the problem solving process to simply hand it over to a developer to finish. I wanted to be the one to fix the problem.&lt;/p&gt;

&lt;p&gt;So what did I decide to do? Well, &lt;a href="https://www.iamtravisw.com/2018/09/returning-to-college.html" rel="noopener noreferrer"&gt;I went back to college&lt;/a&gt;. After my first term at CSU-Global I was sure that I wanted to switch careers. I no longer had the desire or passion to work directly with customers or triage 50-100 issues a day. I knew that I wanted to work on my skills and become the best developer that I could be. I really enjoyed being able to build something from nothing and share it with people. To be frank, my favorite part of my job that I enjoyed the most as a support employee once I moved to Boulder was the challenge to solve harder problems. Everything else that came with the Lead Support title was not important to me.&lt;/p&gt;

&lt;p&gt;For a long time, I felt really guilty about wanting to move on from my role at Greenbrier. I talked with my manager, who by the way is the best manger I've ever had. A completely reasonable, extremely intelligent person who I will not name for his own privacy. We came up with a plan to move me into a junior developer role at the company, but the catch was I would need to train agents and commit to a 6 month support engineer role first. That time is on top of the time it would take to get corporate to agree to hiring new employees, which for support has traditionally been months. That's a commitment I am not sure I can make, as I felt really miserable each day I came into work. It was starting to look like it would take more than a year to even start as a developer.&lt;/p&gt;

&lt;p&gt;At a new company I knew that my focus would be purely on becoming the best developer that I could be, I would not be weighed down by supporting the new support team or covering for a support employee when they are out of the office. My time would be spent purely on development. Knowing that I might be making a parallel move to a new company where my 6 years of tenure at Greenbrier would be lost, I still felt it would be worth it. Even if I don't get a nice bonus each year, or if my paid time off schedule is not as lenient. I know that it's the first step in having a successful career as a software engineer.&lt;/p&gt;

&lt;p&gt;So where am I at now? I am still at The Greenbrier Companies working as the only Software Support Analyst. I am also in college again, earning a degree in Computer Software and I really hope that I will be able to land a job as software engineer/ developer soon. I spend all of my spare time learning more about programming and becoming a better software engineer. I know that I have a bright future ahead of me, I'm just working through making my path now.&lt;/p&gt;

&lt;p&gt;So why am I leaving a 5+ year career as a support employee to become a developer? I guess I feel that I have outgrown the position and want to move into a role with more opportunity for career growth.&lt;/p&gt;

</description>
      <category>college</category>
      <category>career</category>
      <category>development</category>
      <category>support</category>
    </item>
  </channel>
</rss>
