API Data Manipulation and Tolkien

Andrew Lahr
4 min readFeb 7, 2021

Bet you’ve never heard those two phrases in the same headline…

I’m four weeks into Flatiron’s full-time software engineering program, and I have to say that the amount of information I’ve processed in the past month has turned my brain into a soft, mushy, and barely usable organ.

Thankfully, I’ve managed to finish my first project — a Ruby CLI program, with some time to spare. But there was a particularly challenging part of this program that I wanted to share with potential readers, in the hope that it might help you understand a concept that really challenged my own understanding of APIs and data manipulation.

Firstly, I’d like to share an overview of what my project does. Feel free to skip over this if you’d like to get right to the technical part.

#WHAT IS TOLKIEN TINDER?

Tolkien Tinder is simple, somewhat goofy CLI app that brings the digital dating world to Middle Earth.

The program imports and collects all of the Tolkien characters included in the “One API to Rule them All,” located at https://the-one-api.dev/.

The collected character list includes ALL characters found within the Tolkien universe, including the Silmarillion, and many of them have little or no data keys other than their name.

To address this, the program collects a list of movie quotes from the API that also contains unique character IDs that match the character data found in the character list. It uses that ID to filter the original list of characters into a smaller and more data-rich collection of characters, while also allowing the app to let users match and “start a conversation” with their character by returning a movie quote to the user.

Users can select what types of characters they’d like to “match” with my inputting the three fictional races that interest them most at the beginning of the program. The program then returns a filtered list of characters based on the races submitted by the user. Then, the user can choose to learn more about their potential match by entering either ‘yes’ or ‘no’ into the command line. If the user does opt to learn more about their character, the program displays all known information about the character.

If the user likes what they see, they can opt to “match” with said character by swiping right, or to see their next potential match by swiping left (in both cases, the user simply types ‘swipe right’ or ‘swipe left’ into the console). In Tolkien Tinder, “matching” is the same as starting a conversation with a character. Of course, the program is really only returning a random movie quote from the character to the user to simulate a real-world conversation that might occur on a modern dating app.

After the user has gone through their entire custom list, they are prompted to either exit or restart the program.

The most technically challenging part of writing this program was taking two API calls and cross-referencing them to create a pool of potential matches with movie quotes and attributes, which is necessary for the functionality of the app itself.

The first step was to create a method that iterated over a very large list of movie quotes and returned a unique list of character ID values that could be used to filter the larger character list into a shorter and more usable list. Note how this method only returns one unique ID value from the|”character”| key for each hash with a movie quote, regardless of how many times it is encountered. So even if a character had 100 quotes, it would only return their character ID once. @@quote_hash in this method represents the raw data we pulled from the API.

def self.unique_characters_with_quotesquote_array = []@@quote_hash.each do |key, value|if value.class != Integervalue.collect do |quote|quote_array <<  quote["character"] unless quote_array.include? quote["character"]endendendquote_arrayend

Then, I had to iterate over @@character_hash, the raw data from the API that included every character included in all of Tolkien’s books. I used the return value of the above method to significantly cut down the amount of characters to be used in our app by only including those that had movie quotes.

def self.character_list_with_statscharacter_array =[]@@character_hash.each do |key, value|if value.class != Integervalue.each do |character_stats|if self.unique_characters_with_quotes.include? character_stats["_id"]character_array << character_statscharacter_array.each do |character|character.each do |key, attribute| #This sets the character's attributes to 'not provided' if the API (or Tolkien himself) didn't supply a value.if attribute == ""character[key] = "Not provided"endendendendendendendcharacter_arrayend

By shoveling in only those characters whose [“_id”] values matched the [“character’] value of the quote hash, I was able to return a list of characters that supported the functionality of the Tolkien Tinder app.

You may notice that each method included an if statement that only returns true if the value.class is not equal to an integer. This is because the end of each list included an integer value which created an error for the .include and .collect methods, so I simply sidestepped that issue with boolean logic.

In the end, I was able to filter a largely unusable list of hundreds of Tolkien characters down to under 50 character hashes with more plentiful attribute data (largely because they all had movie quotes and thus were more fleshed out). I was also able to guarantee that each character had at least one movie quote to return to the user if they decided to “swipe right” and start a conversation.

All in all, I’d say it was a good lesson in the malleability of API data, and I’m feeling much more confident going forward regarding data manipulation and the power of class methods in collecting the data you need, versus the data you get from external sources.

--

--

Andrew Lahr

Former copywriter and aspiring software engineer. Open to both coding and writing opportunities.