In this post I will walk you through my ruby command line project — how it works, what challenges had to be overcome, and the most important lessons learned through the project.
Displaying NBA Game Data
Pure and simple, my command line application will gather input from a user to select an NBA basketball team. The user will then select the season they are interested in referencing.
After selecting a team and season the user is given the option to view the team’s overall wins/loss record for that season -
or to view the results of every individual game.
How it works
The program has a run file, and four files in the /lib folder that contain classes:
- api.rb — this file holds my methods to access the the API. I used two different endpoints of the API (teams and games). The application makes one call to the API to all the team data and two calls to get the game data (the maximum results per page is 50 and the typical NBA season is 83 games).
- cli.rb — This is the brain of my program and controls all the output. The run file initiates a new instance of the CLI class and runs the start method of that instance. From there the program move into the menu method, which is composed of many other other class methods that control the program flow.
- teamrb — Each time the program goes to the API to get team data, a new instance of the team class is created for each team. It is saved into an array containing all the teams called Team.all. This file also stores the division and conference of each team to give some additional insight to the user
- game.rb — Unlike the team class, which stores all the teams as an instance, the games are stored in a hash created when I call the game endpoint of the API. Since all the games cannot be displayed in one page of JSON data, the API call requires pagination (see below).
Lessons Learned (And Challenges Overcome)
- PRY is key to debugging
Over the first two months of the course PRY was mystifying. In some instances it seemed I understood how it worked. Not so in others. By the end of this project PRY was like a familiar tool in your workshop that feels just right in your hand.
For instance, in what was the most challenging part of the project PRY helped me through the method used to output the team’s overall record for a season:
x = get_games(year, input).sort.to_hx.each do |key, value|if value["home_team"] == @chosen_team_full_name && value["home_team_score"] > value["visitor_team_score"]@wins += 1elsif value["home_team"] == @chosen_team_full_name && value["home_team_score"] < value["visitor_team_score"]@losses += 1elsif value["visitor_team"] == @chosen_team_full_name && value["home_team_score"] > value["visitor_team_score"]@losses += 1elsif value["visitor_team"] == @chosen_team_full_name && value["home_team_score"] < value["visitor_team_score"]@wins += 1endendif self.chosen_team_full_name != nilself.chosen_team_nickname = self.chosen_team_full_name.split(" ").lastendputs "In #{year} the #{self.chosen_team_nickname} had a record of #{wins} wins and #{losses} losses."
The out output is supposed to look like Image 2 above. Many times during the project something would get off and I’d see something similar to this:
The warriors were not good in 1999, but I know they did not win 0 games! PRY is incredibly useful in situations like this to find what’s wrong and get your code on track.
2. Understanding the file structure
This project brought together all the concepts of what makes up a program in Ruby with it’s file structure. Two months ago it raised my blood pressure seeing Gemfiles, environment files, run files, etc. and not understanding their function. Now I understand how they all interact to create a working program.
3. Refactoring Code
The refactoring process was one of the best learning experiences of the project. At a certain point I had all the functionality working but I noticed some “cleaner” elements of projects done by my Flatiron peers. I noticed I had too many calls to the API and it was slowing my program down. I had many repeated blocks of code in my Cli class that were ripe to be put into methods and called back. This process made me think critically how to get the same result, but more concise and easier to understand by a new user.