CS 105 - Understanding Our Algorithmic World

CS 105 - Exercise Nine

Goals

  • Learn how to get data from the web
  • Get some more practice with text and lists

Prerequisite

There is no starter code for this exercise, so go ahead and visit https://snap.berkeley.edu/snap/snap.html and make sure you are logged in.

Objective

In this exercise, we are going to learn how to fetch data from the web. We are going to be using a website called (OpenWeather)[https://openweathermap.org]. Our goal is to fetch information about the current temperature at various locations.

OpenWeather and APIs

OpenWeather provides a free (and not free, for heavy users) API for accessing weather information online. API stands for "Application Programming Interface", though that is not the most informative definition. For our purpose, it means that they have a server that we can request resources from. The API defines what sorts of questions we can ask / resources we can ask for.

They have a collection of different APIs available, but we will focus on the (current weather API)[https://openweathermap.org/current] for the moment.

Specifically, we will use their current weather by city name API (feel free to browse around and look at the other options).

To access the API, we will construct a URL.

We need to make a connection to OpenWeather's server, which is at api.openweather.org.

Then we request a resource: /data/2.5/weather

And the we add some query terms to the request. Here are the possible values we can add to the URL:

parametervalue
qrequiredThis will be three values separated by commas: city,state,country (e.g., middlebury,vt,us)
unitsoptionalThis determines the units used for reporting, we will use imperial
apikeyrequiredUse of the API is monitored and controlled through a unique API key. This makes sure that users are registered users. I will provide a key, though you can apply for one for free if you want to use the service behind this class.

Putting that all together, we can request the weather in Middlebury right now with

api.openweathermap.org/data/2.5/weather?q=middlebury,vt,us&units=imperial&appid=

I left off the API key to avoid publishing it on a public website. Check Piazza for a post containing the key.

Try this out in your web browser. Paste the link in and then add the API key on the end. Your web browser should display a JSON file in response (the same one I showed you in the lecture).

Reading JSON

Depending on your web browser, this may look like an ugly mass of punctuation all squeezed together.

Items in curly braces (e.g., {"lon":-73.17,"lat":44.02}) are objects, and they consist of comma separated properties. The property name is on the left of the colon and the value is on the right. So, this object has two properties: lon and lat, with values -73.17 and 44.02, respectively.

What makes this a little difficult to read is that values can be numbers (like the above), text (in double quotes), lists (comma separated values between square brackets), and other objects.

If you trace through carefully, you will see that the top level object has fourteen properties:

  • coord, the longitude and latitude of the report
  • weather, general conditions
  • base, internal parameter we don't care about
  • main, the main numeric weather status (i.e., temperature, pressure, humidty, etc...)
  • wind, wind speed and direction
  • clouds, percentage of cloud cover
  • rain, recent rainfall history
  • snow, recent snowfall history
  • dt, time of the observation
  • sys, internal parameters and sunrise and sunset
  • timezone, the timezone
  • id, the city id
  • name, the name of the city
  • cod , another internal parameter we don't care about

While I am sure that you can puzzle out what the current temperature is, and some of the other features, this is not the easiest way to interact with this data. Let's see what we can do in Snap!

Fetching data with Snap!

Buried in the Sensing palette, you will find url block.

This fetches data from remote websites and reports back their contents.

Paste the API call URL into the block and click on it (do not include the leading http:// ). Bang, we have all of the data! Of course, it is even harder to read now.

Fortunately, we have some tools to help us out. The split block has a superpower. It knows how to read JSON files!

Put the url block in the split block, and select json from the menu on the right. Now when you click the block, you will get this:

parsed JSON results

What exactly is that? Well, it is a list where every element is a list with two values. The first is the name of the property and the second is the value. Notice that many of the values are actually lists (they have the little ladder icon) -- in most cases these are themselves objects that have been split into this same structure.

Let's take a look at the wind property. The wind is in slot 6 of the list. But we are interested in the value associated with the wind, which is in slot 2 of the list at slot 6.

read wind values

Notice how we first asked for item 6 of the results, and then item 2 of what we read from item 6.

Of course, this result is a further object, which we need to unpack. This all gets a lot cleaner if we use some variables...

So, for example, to find the wind speed, we could do this:

read wind speed

Find the temperature

Now it is your turn. Start with this basic structure:

Starter script

Notice that I pulled out location as a variable to make it easier to change the location, and used the join block to glue the URL together.

Locate the current temperature and have the sprite tell us how warm (or cold) it is in the chosen location.

Note that the location format is important -- city,state code,country code with no spaces (e.g. middlebury,vt,us).

(Optional) Improve the interface

Having to type locations into the set variable block is a little bit of a pain. Use what you learned in the last exercise and have the sprite ask the user for a city before reporting the temperature there.

You could even go further and ask for the city and state separately and glue them all together to get the format right.

What I will be looking for

  • When I click the green flag, the sprite should say the current temperature
  • I can set the city either by setting the variable or because the sprite asked me for the city to observe.

Submitting

Share the project using the instructions from exercise 1.

Visit the exercise page on Canvas to submit the URL.