For my first Flatiron Project I recalled a dilemma from my pre-COVID days: My friends and I (poor musicians) were always on the hunt for cheap drinks in various neighborhoods after side-hustles and before shows—but how to find a good Happy Hour? Bars often don’t advertise them on their sites and Yelp & Google Places don’t track them. I would sit on Yelp and hunt through listings, juggling dollar signs and phone numbers, calling annoyed bartenders and reading reviews, but I dreamed of another option.

“Happy Hour” is a Command Line Interface application that allows users to track down Happy Hour information for bars in major US cities. Users are provided with up to 20 bar options with their addresses and price points——they must then select a bar to investigate for Happy Hour opportunities. They are then given all reviews that mention the bar’s Happy Hour. As Happy Hours can be as elusive and ever-changing as the wind, a phone number is always provided when possible for details or confirmation. In denser area, bars are provided within walking distance (500 meters), otherwise, bars are provided within driving distance(10,000 meters).

The journey from “bin/run”—

You are greeted in the CLI class and prompted for a location in the format of an address or description, ex: “87 S St NW Washington DC”, “Lower East Side, NYC,” “Madison, WI”. It then calls upon the GoogleApi.make_request method with the users input as the argument.

This method utilizes the Geocoder gem to 1. create a nil return for an invalid input or 2. turn valid input into longitude and latitude coordinates for use in the Google API GET request. With valid responses, the latitude and longitude returns must be rounded to 5 decimals places per (unspecified!) Google API place request conventions. Those coordinates are then interpolated into the url for the GET request, with the optional specifications of type, keyword, and radius. Also necessary to the request is the data type you’d like to receive (here, JSON) and an interpolated API key which is saved as a constant. We then use the gem HTTParty to send the GET request, passing in the url as an argument. The close_bars url has a radius of 500 meters. If HTTParty returns an array of less than 5 results, the radius is expanded to 10000 meters and HTTParty GETs again!

We then pass that result in as an argument for our self.create_bars method within the Api Class. This iterates over the array and creates new instances of the Bar class parsing through that data:

Pay particular attention the value of the soon-to-be price key. To turn “1”s, “2”s, and “3”s into “$”, “$$”, or “$$$,” we convert the string into an integer. That number then becomes an argument for creating a new array of that many dollar signs. These are then joined back from an array into a single string! 🤯

This method, finally, instantiates a new instance of Bar from the desired data parsed from the object.

We now have an array of bars in our Bar class , and bonus—we’ve abstracted away some dependency by iterating through the hash and creating only the key and value pairs present for the new instance.

But what if I wanted to abstract away even MORE dependency?? I could also move the creation of readers and writers into the initialize method! Let’s do it:

Nice! Now my code is way more dynamic. If I decide to expand the information each Bar instance retains, I need only add it to the create_bars method!

These bars are then presented to the user via the CLI to make a selection. This selection calls the get_reviews method that will send us back to the GoogleAPI, where we now need to make a separate request to get reviews based on the place_id stored previously.

For this we use the request format covered here: Place details. The retrieved phone and review information are then added to the relevant Bar instance.

Next! The Bar class has a method for going through all of the review data and extracting any reviews containing mentions of “happy hour” into a new array that will then be shown to the user via the CLI! Whether or not any reviews contain happy hour mentions, the user always sees a phone number when available. This way they can call.

From here the user can chose to revisit the bar selection to find the Happy Hour details for another stored spot, or they can exit the program!!

Catch it in action:

I learned A LOT creating this CLI Application. Here are but-a-few takeaways:

  1. The Yelp API is easier to use than the Google API in my humble opinion, but if it’s reviews you want, go with Google. Yelp only returns 3 reviews at a time, and only the first sentence of each. I then thought, “no problem, I’ll scrape the Yelp api for further review details”—NOPE. The Yelp interface is very complicated and I was unable to scrape it using Nokogiri. Hence, the switch to Google. Starting over was quite a blow!
  2. I’m currently using the GoogleAPI free trial, but eventually, they would start charging me. To avoid anyone using my API key and racking up $$$ on my account, I’ve restricted my keys access to only my IP address. Setup here. Tip: this requires your public IP address.
  3. After I set up the bones of my application, I utilized almost every trick here: Making your Ruby Application Cute, including the colorize and tty-prompt gems AND an ascii (prounced ‘ass-key’) image! Thanks Alexandra!

The code shown above is but a fraction of the application’s files! To view the entire, updated github repository, check it out here:

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store