Last week, you probably wondered if there were a better way to grab data from a web service (e.g., one that gives the weather for a particular zip code). Luckily, there is, but pedagogically we decided to teach you how to slog through the mud (in the rare case that there was no other way) before teaching you to fly over it.
Just as you can call a block from a library loaded in Snap! that you didn't write yourself (like map
or substring
), the idea here is that there is a way to pass arguments into a program that lives on the web, and have it either:
We'll start easy, with Internet APIs that return simple, human-readable values. We'll start with the API you explored last week.
http://ipv4bot.whatismyipaddress.com/
. It should have "returned" your IP address. We used this in last week's lab. http://ipinfo.io/207.192.252.171/postal
.http://randomword.setgetgo.com/get.php
.If the Random Word API had 100 words in its database, and you could request a new random word at a rate of one per second, how long would it take until you could guarantee you had extracted every word from it?
You feel like hearing a joke, and you heard there was an internet API that could serve one up. Let's try it.
http://tambal.azurewebsites.net/joke/random
. Note that the joke is surrounded by strange characters. {"joke":"Two guys walk into a bar. You'd think the second one would have noticed."}
We could either user our scraping technique from the last lab to extract the joke, or we could learn how to extract it correctly. Rather than teach you the format of JSON, which you are welcome to read about on Wikipedia, we'll teach you how to work with it.
The basic idea is that JSON data is either one of three things:
true
and false
, and null is null
(an empty value in Snap!).[3, 2, 1, "Hike", true, false, null]
{"Course":"BJC", "Quarter":3, "Instructor":"Dan Garcia"}
, it means that the course is BJC, it's the 3rd quarter class (i.e., BJC.3x), and Dan is the instructor.Note that the elements of lists and the value of a key-value pair can also be one of those three things. So you can see how it can quickly become a very complicated mess of commas, colons, quotes, square and curly brackets:
{"coord":{"lon":-122.08,"lat":37.39}, "weather":[{"id":803, "main":"Clouds", "description":"broken clouds", "icon":"04n"}], "base":"cmc stations", "main":{"temp":282.47, "pressure":1022, "humidity":87, "temp_min":279.45, "temp_max":285.15}, "wind":{"speed":1.5, "deg":180}, "clouds":{"all":75}, "dt":1453619275, "sys":{"type":1, "id":471, "message":0.0036, "country":"US", "sunrise":1453648644, "sunset":1453685029}, "id":5375480, "name":"Mountain View", "cod":200}
Our philosophy in BJC is to shield you from JSON (say it with me, everyone: abstraction) by immediately converting it into Snap! lists. Then you have to figure out how to work with that, using either list operators or something to query value from the collection of key-value pairs. p.s. If you ever come face-to-face with JSON, and don't have Snap! handy, there are a few very good online JSON viewers that let you copy in JSON and view it in a tree format. Let's take a look at the blocks we provide you with to help, listify
(that takes JSON and Snap!-ifies it), and query
(that can return the value from a list of key-value pairs):
http
into a global variable, we like to call JSON
, then you never have to worry about your Internet connection or long delays to receive the same request over and over as you're debugging your query blocks "down river". listify
and query
.listify
block and create a program that (using appropriate calls to Query
, we've shown an example above to extract the temperature), on Green flag startup, says: In Mountain View, the weather is Clouds with the temperature of 282.47 Kelvin.
JSON
into another variable called LoL
(for lists-of-lists), make sure the LoL
watcher checkbox is checked, go to full-screen mode and expand the list by clicking the "grow" region in the bottom-right corner to see what's in it.appid
key (similar to a cookie) to know you're you. We've found the best results when we clicked on the link below By ZIP code, generated JSON for Mountain View (notice the URL added an appid
number?) Now just change the five numbers in the zip code to another one, and voilá! Then copy that URL and put it in your Snap! proxied http
call (without the http://
, remember), appid
and all.Instead of using Query
, you find that you could also explicitly walk down the Snap!-ified JSON list-of-lists by using the item( )of( )
block. What do you think of this idea?
Now let's see you whip up some quick, fun programs.
genderize.io
; create an app that (over an over) asks for a name and then says "I believe the chance that (name) is a (gender) is (probability)", with the values in parenthesis coming from the API call. E.g., the call https://api.genderize.io/?name=dan
returned {"name":"dan", "gender":"male", "probability":"0.98", "count":3240}
, which you would translate to: I believe the chance Dan is a male is 98%
jservice.io/api/random
, create an app that (over and over) shows the title and question from a random Jeopardy question, then when space bar is hit, shows the answer (but read as "what is (answer)?"). Note that sometimes there's HTML included in the results; we don't expect you to have to worry about that, but think about how you might clean that up if you're so inclined.