iterate through nested JSON object and get values with Python - json

I am using Python; and I need to iterate through JSON objects and retrieve nested values. A snippet of my data follows:
"bills": [
{
"url": "http:\/\/maplight.org\/us-congress\/bill\/110-hr-195\/233677",
"jurisdiction": "us",
"session": "110",
"prefix": "H",
"number": "195",
"measure": "H.R. 195 (110\u003csup\u003eth\u003c\/sup\u003e)",
"topic": "Seniors' Health Care Freedom Act of 2007",
"last_update": "2011-08-29T20:47:44Z",
"organizations": [
{
"organization_id": "22973",
"name": "National Health Federation",
"disposition": "support",
"citation": "The National Health Federation (n.d.). \u003ca href=\"http:\/\/www.thenhf.com\/government_affairs_federal.html\"\u003e\u003ccite\u003e Federal Legislation on Consumer Health\u003c\/cite\u003e\u003c\/a\u003e. Retrieved August 6, 2008, from The National Health Federation.",
"catcode": "J3000"
},
{
"organization_id": "27059",
"name": "A Christian Perspective on Health Issues",
"disposition": "support",
"citation": "A Christian Perspective on Health Issues (n.d.). \u003ca href=\"http:\/\/www.acpohi.ws\/page1.html\"\u003e\u003ccite\u003ePart E - Conclusion\u003c\/cite\u003e\u003c\/a\u003e. Retrieved August 6, 2008, from .",
"catcode": "X7000"
},
{
"organization_id": "27351",
"name": "Natural Health Roundtable",
"disposition": "support",
"citation": "Natural Health Roundtable (n.d.). \u003ca href=\"http:\/\/naturalhealthroundtable.com\/reform_agenda\"\u003e\u003ccite\u003eNatural Health Roundtable SUPPORTS the following bills\u003c\/cite\u003e\u003c\/a\u003e. Retrieved August 6, 2008, from Natural Health Roundtable.",
"catcode": "J3000"
}
]
},
I need to go through each object in "bills" and get "session", "prefix", etc. and I also need go through each "organizations" and get "name", "disposition", etc. I have the following code:
import csv
import json
path = 'E:/Thesis/thesis_get_data'
with open (path + "/" + 'maplightdata110congress.json',"r") as f:
data = json.load(f)
a = data['bills']
b = data['bills'][0]["prefix"]
c = data['bills'][0]["number"]
h = data['bills'][0]['organizations'][0]
e = data['bills'][0]['organizations'][0]['name']
f = data['bills'][0]['organizations'][0]['catcode']
g = data['bills'][0]['organizations'][0]['catcode']
for i in a:
for index in e:
print ('name')
and it returns the string 'name' a bunch of times.
Suggestions?

This might help you.
def func1(data):
for key,value in data.items():
print (str(key)+'->'+str(value))
if type(value) == type(dict()):
func1(value)
elif type(value) == type(list()):
for val in value:
if type(val) == type(str()):
pass
elif type(val) == type(list()):
pass
else:
func1(val)
func1(data)
All you have to do is to pass the JSON Object as Dictionary to the Function.
There is also this python library that might help you with this.You can find this here -> JsonJ
PEACE BRO!!!

I found the solution on another forum and wanted to share with everyone here in case this comes up again for someone.
import csv
import json
path = 'E:/Thesis/thesis_get_data'
with open (path + "/" + 'maplightdata110congress.json',"r") as f:
data = json.load(f)
for bill in data['bills']:
for organization in bill['organizations']:
print (organization.get('name'))`

refining to #Joish's answer
def func1(data):
for key,value in data.items():
print (str(key)+'->'+str(value))
if isinstance(value, dict):
func1(value)
elif isinstance(value, list):
for val in value:
if isinstance(val, str):
pass
elif isinstance(val, list):
pass
else:
func1(val)
func1(data)
Same as implemented here

This question is double nested so two for loops makes sense.
Here's an extract from Pluralsight using their GraphGL with an example that goes three levels deep to get either Progress, User or Course info:
{
"data": {
"courseProgress": {
"nodes": [
{
"user": {
"id": "1",
"email": "a#a.com",
"startedOn": "2019-07-26T05:00:50.523Z"
},
"course": {
"id": "22",
"title": "Building Machine Learning Models in Python with scikit-learn"
},
"percentComplete": 34.0248,
"lastViewedClipOn": "2019-07-26T05:26:54.404Z"
}
]
}
}
}
The code to parse this JSON:
for item in items["data"]["courseProgress"]["nodes"]:
print(item["user"].get('email'))
print(item["course"].get('title'))
print(item.get('percentComplete'))
print(item.get('lastViewedClipOn'))

Related

Attempting to retrieve a value from a JSON array in Groovy

I have a JSON object with an array (it is from the body of an HTTP response) that looks similar to the following:
{"people": [
{
"name": "john",
"city": "chicago",
"age": "22"
},
{
"name": "gary",
"city": "florida",
"age": "35"
},
{
"name": "sal",
"city": "vegas",
"age": "18"
}
]}
I'm trying to retrieve the "city" or "age" values by looking for a "name." e.g., when "name" = "sal," I'd expect to get "vegas" to be returned if I was asking for "city" or "18 if I had requested for "age." I'm attempting to do this in Groovy.
Don't even know where to start with the code. First time dealing with a JSON array. Any assistance is much appreciated.
I would recommend starting by reading Parsing and producing JSON documentation page. You will learn about the powerful groovy.json.JsonSlurper class that allows you to work with JSON documents efficiently.
When you create a JSON object representation with a method like:
def json = new JsonSlurper().parseText(rawJson)
You can access JSON document fields in the same way you access object properties. For instance, json.people will return you a list of people. Then, you can call the method like find(predicate) which returns a first result that matches the given predicate from a list. In this case, you can call something like:
def person = json.people.find { it.name == "sal" }
The it is a variable that keeps a reference to the object in the iteration process. It means that find iterates the list and searches for the first object that matches it.name == "sal".
When you find the person associated with the name, you can extract city and age fields in the same way as you would access object fields, e.g.
println person.age // prints 18
println person.city // prints vegas
Here is the full example:
import groovy.json.JsonSlurper
def rawJson = '''{"people": [
{
"name": "john",
"city": "chicago",
"age": "22"
},
{
"name": "gary",
"city": "florida",
"age": "35"
},
{
"name": "sal",
"city": "vegas",
"age": "18"
}
]}'''
def json = new JsonSlurper().parseText(rawJson) // creates JSON object
def person = json.people.find { it.name == "sal" } // finds the first person with name "sal"
assert person.city == "vegas" // calling person.city returns a city name
assert person.age == "18" // calling person.age returns age of a person
To learn more about processing JSON documents with Groovy, consider reading the documentation page I attached above. It will help you understand more complex use cases, and it will help you gain confidence in working with parsing JSON documents using Groovy. I hope it helps.

Get the Json object from a array of Json objects using Groovy

I want to get the productLines for the prodType ULTRA for the Json array below. I get the array of maps and uses findIndexValues to get the index but
it doesn't work. What am I missing? I looked at similar examples which are less complex in structure and did not see much difference from what I'm attempting
Here is my data:
def static modelData="""
{
"models": [
{
"transactionId": "01-PROD0021",
"prodCode": "ISN-2017WDE",
"product": "VASCULAR DNNT",
"prodType": "SDISCNT",
"productLines": [
{
"productLineId": "ELECT-2221",
"productDescriptor": "XTRA-SONIC DNNP",
"unitPrice": "",
},
{
"productLineId": "ELECT-2223",
"productDescriptor": "HEADPH",
"unitPrice": "1.33",
}
]
},
{
"transactionId": "01-PROD0024",
"prodCode": "ISN-5543XDR",
"product": "ULTRASOUND DEEP SONAR",
"prodType": "ULTRA",
"productLines": [
{
"productLineId": "MEDCN-XTR221",
"productDescriptor": "ELECTRONIC RESPR",
"unitPrice": "2.44",
},
{
"productLineId": "MEDCN-XTR376",
"productDescriptor": "SPNG ELECTRONIC DEFIB",
"unitPrice": "6.22",
}
}
]
]
}
"""
Here is my attempt:
def parsed = new JsonSlurper().parseText(modelData)
// Find index of the prodCode with 'ULTRA'
int [] vals=parsed.data.findIndexValues{
it -> it.key=='prodType' && it.value=='ULTRA'}
//Does not print anything
vals?.each {println "Found an index! ${it}" }
There's a couple of things wrong with the code:
1. You loop through a "data" node, where there is none. Use parsed.data
2. The each node is a map-like structure. Hence you check if the map contains a key prodType with value ULTRA. Use it.prodType == 'ULTRA'.
Pro-tip:
1. You can print what the data looks like on closures so that you will get to the solution quicker.
I was able to figure it out
def parsed = new JsonSlurper().parseText(modelData)
def vals = parsed.models.find{ it.prodType == 'ULTRA' }?.productLines

How to take All JSON Name From File and store it into string

I want to take all names from JSON delhi_hos file and store it in String, So that player can play That String. Right Now It plays one by one name. So Suggest Something Please.
JSON Example
[
{
"id": 1,
"name": "JW Marriott Hotel",
"country": "IN"
},
{
"id": 2,
"name": "Le Méridien Hotel",
"country": "IN"
},
{
"id": 3,
"name": "The Leela Palace Hotel",
"country": "IN"
}
]
My Code
if "Hospital".lower() in sentence.lower():
# print("Which City?")
# print("1.Surat \n 2.Pune \n 3.Delhi")
with open("store.txt", 'a') as store:
store.truncate(0)
if element['name'].lower() in sentence.lower():
for items in delhi_hos:
name3 = items.get('name')
print(name3)
my_text = "Near is " + name3
my_obj = gTTS(text=my_text, lang=language, slow=False)
my_obj.save("welcome.mp3")
os.system("mpg123.exe welcome.mp3")
with open("store.txt", "r+") as text_file:
text_file.truncate(0)
and I want Names From JSON file in string Like This
"JW Marriott Hotel Le Méridien Hotel The Leela Palace Hotel"
and the Store it in the variable.
var = "JW Marriott Hotel Le Méridien Hotel The Leela Palace Hotel"
So, I can use var as a input for my player to play this string.
My main Problem Is to convert all name into this string.
I don't know if I understand your question right. But as far as I understand, you simply want to have the values of the namefield in your JSON stringifyed.
I'm wondering why whats solution doesn't work as expected.
The simplest solution that comes to my mind would be:
names = ""
for item in delhi_hos:
names += item['name']
I suggest to start with small bites of a problem, when things don't work out. First add a print, when this works, assign variables, then add if statements and so on! Good Look!
I hope this solves your problem. Add proper indentation if any error comes.
import functools
obj = [
{
"id": 1,
"name": "JW Marriott Hotel",
"country": "IN"
},
{
"id": 2,
"name": "Le Méridien Hotel",
"country": "IN"
},
{
"id": 3,
"name": "The Leela Palace Hotel",
"country": "IN"
}
]
var = functools.reduce(lambda a, b : a + " " + b["name"], obj, "")
print(var)

Write a function which takes the tracking code as input. Look the tracking code up in the JSON then return the tracking code as output

I have a JSON file called "tracking.json".
[
{
"tracking_number": "IN175417577",
"status": "IN_TRANSIT",
"address": "237 Pentonville Road, N1 9NG"
},
{
"tracking_number": "IN175417578",
"status": "NOT_DISPATCHED",
"address": "Holly House, Dale Road, Coalbrookdale, TF8 7DT"
},
{
"tracking_number": "IN175417579",
"status": "DELIVERED",
"address": "Number 10 Downing Street, London, SW1A 2AA"
}
]
I wrote a function that reads this in my app.rb file:
def compare_content(tracking_number)
json_string = File.read("pages/tracking.json")
# Uses the JSON module to create an array from the JSON string
array_from_json = JSON.parse(json_string)
# Iterates through the array of hashes
array_from_json.each do |tracking_hash|
if tracking_number == tracking_hash["tracking_number"]
print "Package on its way"
else
print "Tracking Number does not exist"
end
end
end
The route to the pages is:
get "/:tracking_number/status" do
#tracking_number = params[:tracking_number]
compare_content(#tracking_number)
erb :status
end
The erb :status page is:
<h1>Status Pages: <%= #tracking_number %></h1>
<div>
<h3>Package is on its way</h3>
</div>
Back to Index
How do I show the status if the package matches the tracking number? Plus, if it doesn't how would I show that nothing matches?
Your code could be reduced to something like:
require 'json'
JSON_DATA = JSON[<<EOT]
[
{
"tracking_number": "IN175417577",
"status": "IN_TRANSIT",
"address": "237 Pentonville Road, N1 9NG"
},
{
"tracking_number": "IN175417578",
"status": "NOT_DISPATCHED",
"address": "Holly House, Dale Road, Coalbrookdale, TF8 7DT"
},
{
"tracking_number": "IN175417579",
"status": "DELIVERED",
"address": "Number 10 Downing Street, London, SW1A 2AA"
}
]
EOT
def compare_content(tracking_number)
msg = if JSON_DATA.any? { |h| tracking_number == h['tracking_number'] }
"Package on its way"
else
"Tracking Number does not exist"
end
puts msg
end
compare_content('IN175417577')
compare_content('IN175417560')
# >> Package on its way
# >> Tracking Number does not exist
You probably need to account for the status field to show whether the package is actually in transit.
Note, we seldom use print in Ruby. puts is smarter and knows when to add a trailing "\n". print never adds a trailing newline, so you're forced to do so explicitly. That is occasionally a good thing but grab puts usually, and keep print in your back pocket for those rare occasions you need it.

Unable to loop through JSON output from webservice Python

I have a web-service call (HTTP Get) that my Python script makes in which returns a JSON response. The response looks to be a list of Dictionaries. The script's purpose is to iterate through the each dictionary, extract each piece of metadata (i.e. "ClosePrice": "57.74",) and write each dictionary to its own row in Mssql.
The issue is, I don't think Python is recognizing the JSON output from the API call as a list of dictionaries, and when I try a for loop, I'm getting the error must be int not str. I have tried converting the output to a list, dictionary, tuple. I've also tried to make it work with List Comprehension, with no luck. Further, if I copy/paste the data from the API call and assign it to a variable, it recognizes that its a list of dictionaries without issue. Any help would be appreciated. I'm using Python 2.7.
Here is the actual http call being made: http://test.kingegi.com/Api/QuerySystem/GetvalidatedForecasts?user=kingegi&market=us&startdate=08/19/13&enddate=09/12/13
Here is an abbreviated JSON output from the API call:
[
{
"Id": "521d992cb031e30afcb45c6c",
"User": "kingegi",
"Symbol": "psx",
"Company": "phillips 66",
"MarketCap": "34.89B",
"MCapCategory": "large",
"Sector": "basic materials",
"Movement": "up",
"TimeOfDay": "close",
"PredictionDate": "2013-08-29T00:00:00Z",
"Percentage": ".2-.9%",
"Latency": 37.48089483333333,
"PickPosition": 2,
"CurrentPrice": "57.10",
"ClosePrice": "57.74",
"HighPrice": null,
"LowPrice": null,
"Correct": "FALSE",
"GainedPercentage": 0,
"TimeStamp": "2013-08-28T02:31:08 778",
"ResponseMsg": "",
"Exchange": "NYSE "
},
{
"Id": "521d992db031e30afcb45c71",
"User": "kingegi",
"Symbol": "psx",
"Company": "phillips 66",
"MarketCap": "34.89B",
"MCapCategory": "large",
"Sector": "basic materials",
"Movement": "down",
"TimeOfDay": "close",
"PredictionDate": "2013-08-29T00:00:00Z",
"Percentage": "16-30%",
"Latency": 37.4807215,
"PickPosition": 1,
"CurrentPrice": "57.10",
"ClosePrice": "57.74",
"HighPrice": null,
"LowPrice": null,
"Correct": "FALSE",
"GainedPercentage": 0,
"TimeStamp": "2013-08-28T02:31:09 402",
"ResponseMsg": "",
"Exchange": "NYSE "
}
]
Small Part of code being used:
import os,sys
import subprocess
import glob
from os import path
import urllib2
import json
import time
try:
data = urllib2.urlopen('http://api.kingegi.com/Api/QuerySystem/GetvalidatedForecasts?user=kingegi&market=us&startdate=08/10/13&enddate=09/12/13').read()
except urllib2.HTTPError, e:
print "HTTP error: %d" % e.code
except urllib2.URLError, e:
print "Network error: %s" % e.reason.args[1]
list_id=[x['Id'] for x in data] #test to see if it extracts the ID from each Dict
print(data) #Json output
print(len(data)) #should retrieve the number of dict in list
UPDATE
Answered my own question, here is the method below:
`url = 'some url that is a list of dictionaries' #GetCall
u = urllib.urlopen(url) # u is a file-like object
data = u.read()
newdata = json.loads(data)
print(type(newdata)) # printed data type will show as a list
print(len(newdata)) #the length of the list
newdict = newdata[1] # each element in the list is a dict
print(type(newdict)) # this element is a dict
length = len(newdata) # how many elements in the list
for a in range(1,length): #a is a variable that increments itself from 1 until a number
var = (newdata[a])
print(var['Correct'], var['User'])`