On this page:
Introduction (5 minutes)
JSON (95 minutes)
Before you go...
6.7

Lab 4 JSON

home work!

Purpose: This lab aims to provide you a practical example of the usefulness of nested recursive data structures.

Textbook References: Chapter 19: The Poetry of S-Expressions, Chapter 20: Incremental Refinement, Chapter 21: Refining Interpreters, Chapter 22: The Commerce of XML

Introduction (5 minutes)

This lab relies on the ability for us to parse JSON, and get JSON from the internet. Parsing JSON is not trivial, so we’re providing a library that does this for you.

To get the parser, open DrRacket, click File > Install .plt File... and in the Web tab type in http://www.ccs.neu.edu/course/cs2500accel/code/cs2500f16-jsonlab.plt and hit enter. When the file is finished installing you will no longer have the option to "Abort".

To use this library, add (require cs2500f16-jsonlab) at the top of your file.

JSON (95 minutes)

Goals: Practice working with mutually recursive data. Practice working with tree-structured data.

JSON is a lightweight data-interchange format. Originally developed as part of JavaScript, it is now one of the most popular formats for exchanging data on the web. Unlike many other formats, JSON aims to be easy for humans to read, making it nicer to work with. You can learn more about JSON by reading the official spec.

; A JSON is one of:
; - String
; - Number
; - Boolean
; - 'null
; - JSONArray
; - JSONObject
 
; A JSONArray is a [List-of JSON])
 
; A JSONObject is a [List-of JSONPair]
 
; A JSONPair is a (list Symbol JSON)
 
; Interpretation: JSON values are standardized representations of
; atomic values, lists of values (JSONArray), and collections of
; name/value pairs (JSONObject).

Sample Problem Provide some examples of a JSON, a JSONArray, a JSONObject, and a JSONPair. You can give some simple examples, but also provide some more nested examples to show how the data definitions are intertwined

Sample Problem Write a template for JSON. Note that JSONObjects and JSONArrays both contain JSON, so you must write a template that is mutually recursive. Since the template is just a comment, feel free to assume you’ve already completed the json-pair?, json-object?, and json-array? functions.

Exercise 1 Write the functions json-pair?, json-object?, json-array?, and json? that when given any input return a Boolean. These functions should only return true when the given input is valid. Be sure to check the whole value (i.e. all values in an array). You will notice that these functions are mutually recursive, just like the templates we wrote!

Exercise 2 Design the function json=? that will determine if two JSONs are equal. Note that two JSONObjects are equal if all of their pairs are equal. For the sake of simplicity, you can assume order matters here.

Exercise 3 Design json=?.v2 which doesn’t care about the order of pairs in JSONObjects.

Many web services provide JSON-formatted data through their application programming interfaces, or APIs. We’re going to use weather data from OpenWeatherMap as our test data today. The following code fetches the current 5-day forecast and parses it into a JSON value:

(define weather-data (string->json (get-url "http://tinyurl.com/hmsbkb6")))

Exercise 4 Design a function find-value that takes a JSONObject and a Symbol and returns the value from the first JSONPair whose name matches the given Symbol. This will be helpful for the later exercises. Be sure to test your function thoroughly!

Exercise 5 Design a function max-temp which, given a JSON for a single day’s forecast, returns the maximum temperature from the data as a Number (look at the data you got back from the weather service to see what label they use for the maximum temperature).

Exercise 6 Design a function average-humidity which, given a JSON for a single day’s forecast, returns the humidity from the data as a Number.

Exercise 7 Design a function current-weather which given a JSON for a multi-day forecast returns a [Listof String] of all the "description"s of the current weather from the data for the latest data point.

Exercise 8 We’ve given you the function to parse JSON-formatted text; now it’s your turn to transform it back! Design the function serialize-json that takes as JSON value and formats it as a String. Here are the formatting instructions for each case:

  • Strings are wrapped in double quotes. You can write a double quote in a string using backslash to "escape" the quote, as in "\"".

  • Numbers are converted to strings with number->string.

  • Booleans are converted to the string "true" or "false".

  • The special null symbol is transformed to the string "null".

  • JSONArrays are formatted like "[string1,string2,string3,]", where each string represents the serialization of an element of the array.

  • JSONObjects are formatted like "{name1:value1,name2:value2,name3:value3,}", where each name/value pair comes from each JSONPair (use symbol->string to convert the symbol to a string).

(Real-world JSON does not allow trailing commas in lists or objects, but we can ignore that case for now).

The following check should pass:
(check-expect
(serialize-json
 (list 5 'null false
       (list (list 'greeting
                   (list (list 'formal "hello")
                         (list 'informal "howdy")
                         (list 'garbage (list true 1)))))))
"[5,null,false,{greeting:{formal:\"hello\",informal:\"howdy\",garbage:[true,1,],},},]")

Exercise 9 Design the function weather-graph which given a JSON for a multi-day forecast and a Symbol representing the name of a field in the "temp" section of the data will return an image showing a bar graph of the values for that Symbol for each day in the forecast.

Before you go...

If you had trouble finishing any of the exercises in the lab or homework, or just feel like you’re struggling with any of the class material, please feel free to come to office hours and talk to a TA or tutor for additional assistance.