My Futurama CLI for the Flatiron School

Matt Mason
3 min readJan 11, 2021

--

Have you ever had that moment where you truly felt lost? That’s how I felt when beginning my CLI Project. The training wheels were off, and it was time to prove what I could do on my own. The first thing that I needed to do was to figure out what I wanted to base my Flatiron project around. Originally I wanted to create project on the video game Destiny. My hope was to display information about weapons, their rarity and also some flavor text. The API resources that I could find were either needlessly complex, proprietary or needed API authentication. Unfortunately, this meant that I had to shift gears and fast.

I knew that I still wanted to do something that I was passionate about, and not simply because it had a free API. An episode of Futurama came on, and it was meant to be. I actually ended up using two Futurama APIs, one for quotes and one for characters.

The good news was that these APIs fulfilled my project requirements and I was on my way. I began creating the various classes that I would need like, Character, Quote, API and CLI. All of these were initially stubs, but it helped give me a sense of where I was going.

After some initial scaffolding and basic details added, I then dove into the API class, and began figuring out which remote data that I wanted to get about characters and quotes. Scraping info from the quotes API was very straightforward, and fortunately helped me write very succinct and easy to understand code.

The characters API on the other hand was much trickier as it meant that I would be scraping details like name, gender, species and occupation. I initially had no problems until I realized that halfway through that some of these details were nested inside a second hash. Fortunately this meant the API class looked good, but it meant my CLI class was a mess and you’ll see the original hard coded/non-refactored mess below.

YIKES

def character_details(character, id)     id = id.to_i 
if id >= 8
puts "Name: #{character.name["first"]} #{character.name["middle"]} #{character.name["last"]}"
puts "Species: #{character.info["species"]}" # if != character.info["Species"]
puts "Occupation: #{character.homePlanet}"
puts "Gender: #{character.info["gender"]}"
puts ""
sleep(0.5)
puts "Here Come Some Quotes..."
puts ""
sleep(1.75)
puts "Quotes:"
character.sayings.each_with_index do |s, i|
iplusone = i + 1
puts "#{iplusone}. #{s} "
sleep (0.25)
end
end
if id < 8
puts "Name: #{character.name["first"]} #{character.name["middle"]} #{character.name["last"]}"
puts "Species: #{character.gender}"
puts "Occupation: #{character.homePlanet}"
puts "Gender: #{character.occupation}"
puts "Species: #{character.gender}"
puts "Gender: #{character.occupation}"
puts "Occupation: #{character.homePlanet}"
puts ""
sleep(0.5)
puts "Here Come Some Quotes..."
puts "#{iplusone}. #{s} "
sleep (0.25)
end
end
end

After taking a step back, and breathing, I did some more research and realized that data binding in the API class would help clean up a lot of my issues, and remove having to guess which “gender, species or homePlanet” that I was selecting.

This Helped

def self.character 
uri = URI.parse(URL)
response = Net::HTTP.get_response(uri)
data = JSON.parse(response.body)
data.each do |c|
gender = c["gender"]
species = c["species"]
home_planet = c["home_planet"]
if info = c["info"]
gender = info["gender"]
species = info["species"]
home_planet = info["home_planet"]
end
Character.new(c["name"], gender, species, home_planet, c["occupation"], c["info"], c["sayings"])
end
end

Ahh Much Better

def character_details(character, id)        
puts "Name: #{character.name["first"]} #{character.name["middle"]} #{character.name["last"]}"
puts "Species: #{character.gender}"
puts "Gender: #{character.occupation}"
puts "Occupation: #{character.homePlanet}"
puts ""
sleep(0.5)
puts "Here Come Some Quotes..."
puts ""
sleep(1.75)
puts "Quotes:"
character.sayings.each.with_index do |s, i|
iplusone = i + 1
puts "#{iplusone}. #{s} "
sleep (0.15)
end

The rest of the project went much more smoothly, and I inserted some sleep methods, color and ASCII images to make the program feel more natural for users. The colorize gem is definitely your best friend to make this happen.

I will caution that although it went “smooth” after my initial headaches, it did not mean it was fast and there were a lot of mistakes along the way that slowed me down at times. There are also a few areas where refactoring will help, and also where understanding mistakes will help make the code understandable for other engineers.

On future projects, I definitely want to add more complexity so this means that I will need to:

  • Take my time
  • Make better plans
  • Ask more questions
  • Take a walk and sleep on tough concepts instead of driving myself crazy.

You can find my finished repo here

--

--

Matt Mason
Matt Mason

Written by Matt Mason

0 Followers

Founder, Brightr Travel. Learning, Flatiron School

No responses yet