Gotta Code ’Em All!

Ryan Bollettino
5 min readJan 9, 2021

or How I Learned to Stop Worrying and Love the Pry

Seven or so weeks into my Flatiron courses and it was time to put up or shut up. Could we pull, parse and premiere a working CLI application that pulled relevant data from an API? The next twenty days or so turned into a rollercoaster of peaks and valleys; self-doubt, despair, revelations, elations, and a serious love-affair with my coffee maker.

within lies salvation

After rummaging through countless websites I was getting stymied trying to find something both interesting and manageable for my project. Marvel Universe would be amazing, and the amount of data was making me salivate, but after spending a day and a half trying to create an everchanging API key that combined a public and private key as well as a current time stamp — I cut bait. Other sites didn’t provide that je ne sais quoi that I needed to get excited.

And then I saw it. Something I had contributed to for the last three years. Something that drained my wallet and maddened me as it’s presence grew exponentially around my house. Yes, you guessed it, my son’s Pokemon collection (addiction). There was an API dedicated to these creatures, and it was something I knew a little about, and could get some good intel from my son if need be.

Pokémon TCG API by Andrew Backes

HTTParty On, Dudes!

The API that pokemontcg.io provided a nested hash that composed of a “deck” of 100 Pokémon cards. The initial challenge was what to use to pull and parse this data. In class, we had learned about using the open-uri gem, NET:HTTP, and JSON.parse combined with iteration to pull and parse our information for our Class instances. But testing and many trials were not providing what I wanted. After reviewing my notes and a little research, I realized that HTTParty was exactly what I needed. It does all the parsing for you within the gem, so you only need to worry about iteration and then the fun part, pulling that data out.

def self.get_pokemon_data            #pulls data hash from URL
response = HTTParty.get(cards_url)
#converts JSON data into nested array that we'll call 'response'
data = response["cards"]
data.each do |pokemon_data| #assigns each array to new
PokemonClass.new(pokemon_data) #instance within the class Pokemon
end
end

Pry, Baby, Pry

“Pry will save your sanity” was the great revelation for me over Winter Break while I worked on my code. During Phase 1 and the First Mile, we were encouraged to use binding.pry and play around until we got comfortable with it. But I never really felt like I had the time or the understanding of how and where I should be using it. I am a n00b. I will be the first to admit it, and I felt unsure about what the end result of pry was. Oh, i’m so glad I gave it another try.

The API I had was hashes inside or arrays inside of hashes. And I was not comfortable with my hash knowledge either. So, I hit the books again, did some more research during the week-long ‘black-out’ and came out the other side very comfortable with pulling this info. Some was easier than others. Once my Pokemon class instances were created from my parsed data pokemon_data — getting names, numbers and hit points were a cinch:

self.name = pokemon_data["name"]
#=> "Snorlax"
self.pokedex_no = pokemon_data["nationalPokedexNumber"]
#l=> "403"
self.hp = pokemon_data["hp"]
#=> "120"

But pride goeth before the fall, and that was all too true when I tried to access the “attacks” and “weaknesses” of these Pokemon. Both of these arrays (within my original hash) contained their own collection of nested hashes, with each cards containing 0–2 “attacks” and 0–1 “weaknesses”, so there was no one size fits all that was going to work for this aspect. Any “attack” cards that returned a nil value was breaking my code (and my spirit). Pry was huge in helping me lock down the specific path I had to navigate to get my data, but…

Good Luck Noob!:

{"cards": [
{"attacks": [
{"cost": [
"Colorless"
],
"name": "Intelligence Gathering",
"text": "Draw cards until you have 6 cards in your hand.",
"damage": "10",
"convertedEnergyCost": 1 },
{"cost": ["Colorless",
"Colorless"],
"name": "Bee Revenge",
"text": "This attack does 10 more damage for each Pokémon in your discard pile.",
"damage": "20+",
"convertedEnergyCost": 2}

…no matter what I did with iterations, if/else statements, mapping into new arrays, I could not get the code to kick out what I wanted. It was only after some conferencing and talking through the problem out loud did I realize that I needed to actually have a two-pronged attack.

Let’s Hash It Out

Having a great crew to discuss issues with when coding is so huge. All too often I think we get stuck inside of our head and countless Google returns and our brain becomes a mishmash of “maybe this?” and “where do I put that?”. I clearly remember being stuck, and once I spoke out loud and heard myself, I instantly realized what I had to do before a colleague said nearly the exact same solution. So, in these early days of learning, I cannot stress enough the importance of stepping back and laying out your intentions.

Figured it out!

class PokemonClass
def initialize(pokemon_data)
self.attacks = pokemon_data["attacks"]
end
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class Cli
def pokemon_attacks
if d.attacks == nil
puts "Attacks:".white + " There are no Attacks for this card.".green
else
@attack_array = []
d.attacks.each do |x|
@attack_array << x["name"]
end
puts "Attacks: #{@attack_array.join(", ").light_green}"
end
end
#=> "Attacks: Upstream, Tail Slap"

The code above was my solution to solving:

  • I took the initial “attacks” hash from the overall API pull self.attacks that was in my PokemonClass class file,
  • Then, in my Cli class file, created an if/else statement for that data in order to deal with the nil values that were breaking the flow. My nil values could now return a clean message to the user.
  • For attacks that had one or two values from the [:name] key, I iterated through that data in a separate method, dumped it into a new array, and returned it in a cleaned up, light-green string.

Takeaways

Pry is your buddy, it’s your pal, it’ll help you out when times get tough. It helps you see the goal even if you don’t know how to get there…yet.

Talk it out when you are way too inside your own head. Having a reliable network of people around you that you can bounce ideas off of when you’ve hit a wall is one of the greatest resources at your disposal. Not to mention seeing how other people approach a problem gives you more tools in your toolbox for future endeavors.

The Valley Is Real. I hit a deep dark place during this, full of self-doubt and wondering it this was the right path. But, now on the other side, I know that I can create, and that learning how to learn again is going to provide challenges and rewards, as long as I stay focused and try everything twice.

--

--

Ryan Bollettino

Current Software Engineer student at Flatiron School, 11 year Math Teacher, 20 year thespian.