#!/home/mark/opt/rakudo-star-2014.04/perl6 # # This following information is excerpted from Derrick's message and has # been slightly reformatted. Derrick Kearney # wrote on 2014-04-28 at 17:35:51 GMT: # # In our last meeting we learned about the JSON file format. I # created the sample json file I wanted to use for the first part of # the challenge. I uploaded the file to # http://www.csociety.org/~kearneyd/tmp/purduepm_json_challenge_1.json # # While I sort things out with my system, if you have a bit of extra # time, can you write a program that will do the following? # # 1) Read and Parse the JSON file. # # Read the json file into memory and parse it into data structures that # best fit the programming language you are using. There are 6 data # types you need to worry about: # # Primitive Types: # * null # * booleans # * strings # * numbers # # Structured Types: # * arrays # * objects # # More information about the json file format can be found at # http://json.org # # The file represents a dictionary, or hash table, or associative array. # # There is probably a library available in your programming language, # you can use to quickly read and parse the file. The json.org # website has a list of some libraries for popular programming # languages. # # After parsing the file into your language's data structures, you # should print the values stored in the data structures to stdout or # another file to make sure you are reading the data properly. Don't # just print the file after reading it. # # # 2) Fix the JSON file and write it back to disk. # # Here is where it gets tricky. Even though the json file was # syntactically correct, I made some mistakes in the data that is # stored in it. Here is a summary of what I wanted for each key in # the dictionary : # # (a) null_value should be a json NULL or None value, not a string. # (b) boolean_true should be a json true value, not false # (c) boolean_false should be a json false value, not true # (d) integer_number should be the integer representation of its current # value, not the floating point representation (i.e., 3) # (e) number_examples -> "not a number" should not even be in the # dictionary, lets remove it. # (f) in "array", the string "value5" should read "value4" to match "key4" # # Can you write a program to make these specific changes? Don't # forget to comment your code. If you find an interesting way of # addressing elements inside of the structure, please highlight that # in your code. For example, how would you find the value for "key4" # in the file? If there were multiple dictionary keys named "key4" # in the file, how could you make sure you were addressing the # correct one? # # The data in the outputted file should look something like like this: # # { # "null_value": null, # "boolean_true": true, # "boolean_false": false, # "string": "this is my string.", # "integer_number": 3, # "number_examples": { # "positive integer": 9, # "negative integer": -1, # "float": 2.3, # "positive_exponent": 4.35e+58, # "negative_exponent": 4.3508e-93 # }, # "array": [true,null,["value3"],{"key4":"value4"}] # } # # Note that the order of the keys (null_value, boolean_true, # boolean_false, ...) does not matter since the pairs of a json # object are unordered. # # We'll discuss how to perform these actions in the different # programming languages people chose to use in the next meeting on # May 20, 2014. # use v6; use JSON::Tiny; use LWP::Simple; # Read the file. my $fn = 'http://www.csociety.org/~kearneyd/tmp/purduepm_json_challenge_1.json'; my $text = LWP::Simple.get($fn); say ''; say 'JSON FILE TEXT READ:'; say $text; # Quota null because it is a Perl 6 keyword. $text.=subst(/\,null\,/, ',"null",'); say 'JSON FILE TEXT AFTER REPLACING ,null, WITH ,"null",:'; say "$text"; # Does the file parse ok? my $t = JSON::Tiny::Grammar.parse($text) ?? 'succeeded' !! 'failed'; say "The JSON parse $t."; # Get JSON data. my $from = from-json($text); my %from = $from; say ''; say 'FORMATTED HASHED JSON DATA:'; %from.keys.sort.map({say "$_ => %from{$_}"}); # (a) null_value should be a json NULL or None value, not a string. %from{'null_value'} = 'NULL'; say ''; say 'There is no documentation for JSON::Tiny, I don\'t'; say 'know what to use for a JSON NULL or None value.'; say 'FORMATTED HASHED JSON DATA AFTER CHANGING null_value FROM null TO NULL:'; %from.keys.sort.map({say "$_ => %from{$_}"}); # (b) boolean_true should be a json true value, not false %from{'boolean_true'} = True; say ''; say 'FORMATTED HASHED JSON DATA AFTER CHANGING boolean_true FROM False TO True:'; %from.keys.sort.map({say "$_ => %from{$_}"}); # (c) boolean_false should be a json false value, not true %from{'boolean_false'} = False; say ''; say 'FORMATTED HASHED JSON DATA AFTER CHANGING boolean_false FROM True TO False:'; %from.keys.sort.map({say "$_ => %from{$_}"}); # (d) integer_number should be the integer representation of its current # value, not the floating point representation (i.e., 3) %from{'integer_number'} = %from{'integer_number'}.floor(); say ''; say 'FORMATTED HASHED JSON DATA AFTER CHANGING integer_number FROM 3.14159 TO 3:'; %from.keys.sort.map({say "$_ => %from{$_}"}); # (e) number_examples -> "not a number" should not even be in the # dictionary, lets remove it. %from{'number_examples'}{'not a number'}:delete; say ''; say 'FORMATTED HASHED JSON DATA AFTER DELETING number_examples -> "not a number":'; %from.keys.sort.map({say "$_ => %from{$_}"}); # (f) in "array", the string "value5" should read "value4" to match "key4" $from{'array'}[3]{'key4'} = 'value4'; say ''; say 'I cheated by not searching array for the index of the'; say 'hash and instead just used 3 as the index of the hash.'; say 'FORMATTED HASHED JSON DATA AFTER CHANGING value5 TO value4:'; %from.keys.sort.map({say "$_ => %from{$_}"}); my $to = to-json(%from); say ''; say 'JSON DATA IS NOW:'; say $to; say ''; # $from = from-json($to); # say ''; # say 'JSON DATA:'; # say $from; # say ''; # # We're done. exit 0;