My First Project — a CLI App

Kunal Shah
6 min readNov 30, 2020

--

Oh boy. It’s finally here. The first project I am going to create during my time at Flatiron School. It is time to finally put the first 3 weeks of learning into my own project. No pre-created files with starter code like in lab assignments. It’s just me and an empty blank slate. Starting from scratch can be pretty scary, right?

The CLI Project is a command-line interface that takes external data either via an API or scraping a website and provides the user an ability to manipulate it. For this project, a user should be seeing information in a list view and then going one level deep to see more detailed information. When I first thought about creating this project on my own, I’ll be honest: I was nervous and a little scared. It’s like taking off the training wheels that the lab assignments provided.

GIF on Giphy

My CLI project is based on League of Legends. It is a PC game in the category of Multiplayer Online Battle Arena. It’s a game I play in the spare time that gives me a break from everything else. In League of Legends, you can choose from over 150 characters — called Champions — to play the game. Each champion is unique and I figured my project could provide those champions and give detailed information on them. Additionally, I knew Riot Games (owner of League of Legends) provides APIs because there are a lot of sites that provide tools for gamers to get better at the game and those tools have to get their data from Riot.

Now I had my idea for a project and I found the relevant API data, so it’s just a matter of presenting the data to a user via a CLI. First, I took the time to write out a notes section of what I wanted to accomplish regarding the flow of my gem. I even took the time to replicate a similar-looking flow diagram to the instruction planning section provided. Having done this, I found myself making great progress, and within a couple of hours had my API class built out and had code written for my CLI class of what I expected the user to interact with and see.

Let me tell you, comments are your best friend. I was able to give myself little notes I could reference back to while I coded as I moved around between different files. Having done some decent planning and using the knowledge from previous lab assignments, I surprised myself with how much I had done in a few hours.

But I wanted to provide more functionality. In League of Legends, champions are categorized into 6 types. Additionally, all champions require a different amount of skill to master, some much more difficult than others. Thus, I wanted users to be able to find champions based on those categories as well. However, this presented the overarching challenge for my project. My first issue was that for ‘type’, some champions had multiple types, which when I parsed through the API data, were given in arrays. I needed to figure out a way to make sure a champion was included for the ‘type’ the user wanted even if they had both types. My second issue was for ‘difficulty’. The data regarding the ‘difficulty’ was a key-value pair found in a hash where the has was the initialized value. Thus, I could not easily use #attr_accessor attributes to gain access to those values.

To solve these issues, I dropped into Pry to play around with my API data to see what code I would need to access through data with multiple nested hashes and create my champion instances. I even took a pen and paper and physically wrote out a flow diagram of how I expected my code to iterate through the data to get the exact value I wanted. After some trial and error, I was able to create a collection of instances. Being able to work with individual instances, I ended up creating two different finder methods: one for ‘type’, one for ‘difficulty’. I used the #select iterator so it would collect all the object instances based on the ‘type’ or ‘difficulty’ I (or the user) wanted. Now I had an easier way to generate lists based on ‘type’ or ‘difficulty’ using my #self.all class method.

GIF by The Daily Show on Giphy

Once I got a working CLI project, I had my brother come and use it. He played around with it and actually got my code to break. My first thought was “Oh no! Not cool man!” But quickly it changed to “Why? Why is my code doing that?” When I was asking for a specific champion, my code was not properly taking the input and checking if it was a valid input. So even when my brother typed in nonsense, he was getting the last champion’s details. It was a valuable lesson in testing out your code in unexpected ways to see how it responds.

Once he could no longer break my application, I started employing some DRY (Don’t Repeat Yourself) to refactor my code. However, here comes my overarching challenge. With the extended functionality I wanted in my CLI project, ‘type’ and ‘difficulty’ were giving me issues refactoring. Normally, if you have repeating code, you can place that code in a method once, and then just call it as needed.

“What do you do when you have code that is very similar, but slightly different?”

For example, when I fixed the code after my brother broke it was regarding a user choosing a specific champion to know about. It arises three times in my code either after seeing the full list of the champions, the champions by ‘type’, or the champions by ‘difficulty’. The code is almost identical.

“There has to be a way to refactor this! I’m repeating myself too much.”

At the writing of this blog post, I have spent some time reviewing default arguments, keyword arguments, and conditional logic as a possible solution to refactoring 3 similar methods into 1 method that can take in arguments and appropriately determine whether it is ‘difficulty’, ‘type’, or neither to then print out the correct champion list.

I thoroughly enjoyed making my own project. The feeling of making something tangible from scratch was immensely gratifying. The fact that I could do it provided a confidence boost that I am learning and can actually code. I actually spent time during Thanksgiving day and weekend doing this project. I could have waited until the actual project week to start, but I was eager and motivated to work on it.

The journey is going to get harder as I learn more, but that will make it all the more satisfying when I master it. So often we just want everything to be easy. However, if you are passionate about something, then nothing is hard. Instead, it’s a fun challenge waiting to be overcome. That is how I see programming as I go through this immersive software engineering course. The material is not easy and comes in fast, but I’m thoroughly enjoying tackling each topic or problem as it comes.

Takeaways:

  • Have a connection with the project you are creating. It makes the project more enjoyable to work on and provides motivation and energy because you’re passionate about it.
  • Take the time to make a game plan; write out how you expect a user to use your application
  • Comments. Comments. Comments. They give yourself and others an idea of what you are trying to do with your code; leave yourself notes so you don’t forget
  • Embrace the unknown; use tools like Pry with some trial and error to test out your code and see the results as you code
  • Have someone try and break your code; it will show you bugs, holes in your code that can fix up to make an even better product
  • Belief; every step you take, you learn something and add to your toolbox; you know a lot more than you think
  • Welcome the challenge; that delayed gratification is so worth it

If you want to check it out yourself, check out my repo here.

The Journey Continues!

--

--

Kunal Shah
Kunal Shah

Written by Kunal Shah

Full Stack Web Developer | Flatiron School Software Engineering Graduate | TV Show Enthusiast. Pittsburgh Sports Fanatic.

No responses yet