My First CLI Project at Flatiron…
“WOW! I never thought in a million years I’d be able to do what I can do now! This school has definitely opened my eyes to a whole new world.. The time and effort I put into this project was definitely worth the learning boost!” -Me
This project uses a Harry Potter spells API with my Command Line Interface. It will give a list of 80 different spells and give information about a spell the user chose. The first thing I did was create a GitHub repository with my newly named project, ‘wizard-spells’. I then cloned it to my computer and opened it in Visual Studio Code. BOOM! I can now start creating my files, writing my code, and learning more along the way! I created my first three folders:
NOTE: I didn’t use a gem to install any folders/files! (The LICENSE and README.md files were automatically created from making a new GitHub Repository and check-marking their designated boxes.)
After I created the folders above, I started creating new files to go into those empty folders:
Creating these files and folders seemed a little overwhelming at first, but the more time I put into them the more I started to understand why I needed them! Lets go ahead and fill these lonely files with some friendly code, starting with environment.rb inside the “config”, or configuration, folder(../config/environment.rb):
It may not look like much, but this little bunch of code is VERY important. The first two lines are absolute paths that allow us to use external tools for our project. The last three lines are saying to require the other files we already created within our project (relative), and allow us to utilize them throughout the project.
Now for the run file inside the binary(bin) folder:
I added a shebang line(#!/usr/bin/env ruby). This lets the file know it’s in Ruby Language mode! We have another “require_relative” line of code leading to a familiar file path(look above!). The run file is going to use all the code in the environment file! The last line of code (CLI.new.run) has a purpose that will be explained later!
Now it’s time for the fun part! Let’s create our classes for each file in the library(lib) folder:
Once I initially got to this part my brain started flipping out on me, but after looking back at a few lecture videos I knew what to do! Starting off with the API class:
In the initialize method I created an instance variable(@url) so I can access it throughout my methods! Then I created two more instance methods: “get_spell_data” and “create_spell_objects”. In the “get_spell_data” instance method, I stored the url data into a local variable(spell_array) and used the HTTparty tool to JSON.parse that data for me. Then I created spell objects using the “create_spell_objects” method (it’s pretty self explanatory what each method is doing, since I named them for their purpose) and iterated over the stored hashes of data, creating a new spell for each hash!
Now that we have our data parsed and ready to go, lets take a look at our Spells class:
To start, we’ll make a class variable called @@all, and set it equal to an empty array. This is going to store the data from before inside of that array! Then we’ll create another initialize method with a parameter, “spell_hash”. In the body of this method we start by iterating through “spell_hash”, and then taking out the key and value in that hash. Next we created attribute accessors and set the key equal to a value. The word “self” refers to the current object we are dealing with, which in this case is the “initialize” instance method . Essentially we created a new instance or object of the Spell class, set the data to key/value pairs by iteration, and now we grab all of that and put it inside(shovel << into) the @@all array. The “get_spell_name” method is just getting the spell names with “self.spell”. All “self.all” is doing is returning us the new array full of data!
Time for the CLI! I really enjoyed this part, however it is a bit long so I’ll try my best to explain it :) :
Here we create yet another instance method called initialize. We call this method by using “.new”. We are using the “get_spell_data” method from the API class (see above) and using that data inside our CLI class. Remember the line “CLI.new.run” in the run file inside the binary(bin) folder? The run file is the executable file, so to start our CLI we added a “run” method! The code will be read line by line based on the conditions that are met, so I’ll go ahead and put more code below. (NOTE: Be sure to look back now and then to make sense of what’s happening!) Starting with the greeting:
After the “greeting” method it will read the “menu” method. After that it will list your spells using the “spell_list” method. In the “spell_list” method I set different variables to different values and used them in a “while” loop with a counter. It’s essentially listing all the spells in the array until it reaches its max length(80 total), and allowing it to start with the number 1, rather than 0 (All objects in an array start with an index of 0). I know there are more DRY (Don’t Repeat Yourself) ways to code this out, but this way helps ME to keep track of what’s what. After it lists the spells it will prompt the user with a string and wait patiently for the users input! (BELOW)
If the users input doesn’t equal to ‘exit’ then it will run the “choose_spell(input)” method with an argument, which takes the users input as an integer that should be between 1 and 80. If it’s a VALID choice, it will puts out the spell’s name AND effect. Otherwise it will puts out the string under ‘else’ and ask to reshow the menu:
If the input is equal to “y” then it will loop back to show the list of spells again! If the users input is equal to “n”, it will end the program. If the input is NOT equal to either option then it will puts out (BELOW):
WOOHOOO! We just created a Command Line Interface using an API! I’m sure I could have elaborated a bit more in this blog, but someday I’ll come back to it and fix it up! I absolutely love programming, even if I don’t fully understand 100% of it. While typing this blog I quite literally looked back through my notes and googled things I wasn’t sure about. I’ll keep posting more and more about my coding journey and learning experience! Until next time, thank you for reading!