Every time I tapped my phone’s weather app, I would think the same thing: “Wow. The background looks just like the sky outside my window. It’s magic. ” I’ve never been so happy to be wrong. As it turns out, a rudimentary version of the exact same feature only takes half an hour and a few changes to three files. Check out the code on Github and the app on Heroku. First, some background. The task: build a weather app.
I wanted to make an app that would automatically detect the user’s location and show her the weather where she was. Luckily, I had just used the Geocoder gem in another application, so I was saved a trip to Google to figure out how to do the deed. Geocoder made it easy to detect a site visitor’s IP address, translate it into a set of latitude and longitude coordinates, and determine a city and region from that data.
Once I had the city and region from that gem, I could call the data from the Open Weather API for that city and region. The API provides all kinds of data: wind speed, probability of rain, temperatures, highs, lows, weather descriptions, and more. For this app, I only printed the current temperature and daily high and low to the view.
I didn’t want to print the description to the view: where’s the fun in telling people what the weather is? Let’s show them, the way the geniuses at Apple do it.
The gameplan: make the background of my app conditional on the weather as described by the API.
The API offers some options for this: it has a description of the weather. It has a little icon to show you the weather in a little visual symbol. It has a three-digit code to describe different weather situations. I chose to use the three-digit code. Each weather description in the system corresponds to a three-digit code, and there are a lot of them. and I think a series of integers looks cleaner in code than a morass of strings, so I went with the three-digit codes. The tradeoff of that, of course, is that a person doesn’t know from looking at “200, 201, 202” immediately what weather that represents as opposed to “thunderstorm with light rain”, “thunderstorm with heavy rain”, “thunderstorm with some other kind of rain…” If I were building this app for production and I were working with other programmers, I probably would have used descriptions instead of three-digit codes for this very reason. But, I’m the only one working on this code, so my house, my rules.
OK. What this actually entailed: 1
. I put a conditional class in the application.html.erb view. This is the html that applies to every page of an app. This one only has one page, so I could also just put it in the page HTML. In the end, that looks like this:
2. I defined @weather_code (that variable you cocked your eyebrow at in the above picture) using the three-digit-codes from the API. The following screenshot depicts the most exciting method you’ve ever seen in your life; I just know it
This method lives inside the weather.rb model in the app. It’s not an ActiveRecord model (the app doesn’t need a database on account of it gets all its data from the Open Weather API); but it’s a good spot for doing all the temperature measurement conversions and other technical logic, like this beaut here.
Look at that case block. (For those who have never seen a case block: it’s just a different syntax for a massive column of if statements. You’d get the same thing from this: if @three_digit_code == 200 || @three_digit_code == 201 || (yes, you have to do that for each case–this is why I used the case block) @weather_code = “thunderstorm” end …and just do that for all of them.)
See why I picked the three digit codes? Imagine that thing with strings instead of three digit codes. It’d be huge and gross-looking (but nonetheless clearer unless you were me, which I get, and which is why I would have gone with the strings if anyone but me were going to work on this thing).
Like I said, there are a lot of codes. I didn’t feel like finding that many backgrounds for all the different weathers. So instead, I separated it into thirteen categories: clouds, thunderstorm, sunny, hot, cold, snow, hurricane, tornado, hail, and others. For all the different kinds of thunderstorm, the page is just going to get a @weather_code (and therefore body class) of thunderstorm. 3. I defined a different background in the CSS for each different body class, like so:
This involved searching Google for thirteen images to use for the different background images. This is what I mean by a rudimentary application: if we wanted to make this app Apple fancy, we’d need a different image for each little different weather code. And we’d want to use some flash, some javascript, God forbid a video, or some other method to make them moving pictures for wandering clouds or pouring rain. However, this is an implementation of the same concept. The difference I just described is a difference of degree, not of kind.
And here is why it matters, people. I probably hear, explicitly and implicitly, from every media source from CNN to WIRED about the “genius, amazing, wonderful freaks of nature” that walk among our revered tech community. And I don’t mean to knock them: many of those people are brilliant and amazing, have done worthwhile things, and deserve recognition. Nevertheless, all that hype sometimes has a side effect of making less hallowed programmers feel unable, unworthy, useless. After all, they’re not magical like the secretive geniuses at [insert talk-of-the-town tech company du jour].
Wrong. Y’all, there is no magic.
And you know what? Once you have a good foundation in a programming language of your choice, and provided you have some penchant for problem solving and some patience for a few frustrations, you can make whatever it is you want to make . . . no magic required. And that, y’all, is more inspiring than any magic could ever be. Check out the code on Github and the App on Heroku (can’t run locally due to IP address requirement).