I am currently building a Telegram Bot and getting JSON response on Google Places API to return nearby locations to users.
The json Response I get is as follows:
results" : [
{
"name" : "Golden Village Tiong Bahru",
"opening_hours" : {
"open_now" : true
},
"rating" : 4.2,
"types" : [ "movie_theater", "point_of_interest", "establishment" ],
"user_ratings_total" : 773
},
{
"name" : "Cathay Cineplex Cineleisure Orchard",
"opening_hours" : {
"open_now" : true
},
"rating" : 4.2,
"types" : [ "movie_theater", "point_of_interest", "establishment" ],
"user_ratings_total" : 574
}
]
My current code to get specific items in the dictionary
json.dumps([[s['name'], s['rating']] for s in object_json['results']], indent=3)
Current Results:
[
[
"Golden Village Tiong Bahru",
4.2
],
[
"Cathay Cineplex Cineleisure Orchard",
4.2
]
]
I would like to get the name and rating and display side by side instead:
Golden Village Tiong Bahru : 4.2,
Cathay Cineplex Cineleisure Orchard : 4.2
Please help.
Do you want json format as a result?
Then you can do:
json.dumps({
s['name']: s['rating']
for s in object_json['results']
}, indent=3)
If you want just string list:
lines = [f"{s['name']}: {s['rating']}" for s in object_json['results']]
Or you want to print only:
for s in object_json['results']:
print(f"{s['name']}: {s['rating']}")
You need 3.6 or higher python interpreter to use f-string(f"...").
I you don't, replace
f"{s['name']}: {s['rating']}" -> '{name}: {rating}'.format(**s)
Maybe with:
json.dumps([s['name'] + ": " + str(s['rating']) for s in object_json['results']], indent=3)
Related
How do you use a variable as a field to find a specific value within a mongodb database? I am trying to target a list inside of a list in my collection making use of an integer variable that is grabbed from wtforms. When I try to input the variable I get an error message of:
mongoengine.errors.OperationError: Update failed (Cannot create field 'studentSlot' in element {Attendance: [ [] ]})
the code segment:
if request.method == "POST":
if "form" in request.form and form.validate_on_submit():
klass = classes.objects(id = form.classid.data).first()
studentSlot = form.slotid.data
if klass:
studentSlot = form.slotid.data
klass.update(push__Attendance__studentSlot__1 = form.attended.data)
example document:
{
"_id" : ObjectId("637545927a45e617da1cba8e"),
"CourseName" : "Themes in U.S. History",
"Prerequiste" : [
],
"MinimumRequirement" : [
],
"Description" : "The course is an introduction to major issues in the history of the United States, from colonial times to the twentieth\r\ncentury. Topics may include: the origins of slavery and racism; industrialization and the growth of cities and suburbs;\r\nthe growth of the American empire; movements for social change.",
"RoomID" : NumberInt(31),
"BuildingID" : NumberInt(2),
"Type" : "Undergraduate",
"TimeSlot" : NumberInt(3),
"Credits" : NumberInt(4),
"MaxCapacity" : NumberInt(30),
"Day" : "Tuesday & Thursday",
"Professor" : ObjectId("638be8c63d5b3e062b56f8ea"),
"Enrolled" : [
ObjectId("6376b19ef448207c0a721245")
],
"Department" : "American Studies",
"Attendance" : [
[
]
],
"Grades" : [
],
"Year" : NumberInt(2022),
"Season" : "Spring",
"StartDate" : ISODate("2022-01-26T00:00:00.000+0000"),
"EndDate" : ISODate("2022-05-20T00:00:00.000+0000"),
"Crn" : "AS536",
"AttendanceDate" : [
]
}
If studentSlot in the last line is replaced with 0 (for example), it works perfectly fine. This would be suitable if I didn't need to grab the slotid number from the user.
So put simply how do I make the studentSlot variable be read as the variable as opposed to being read as a field that doesn't exist?
Any help is appreciated.
how i make a list from the values inside urban only for type gasolina?
{ ... "fuelUse" : {
"urban" : [
{
"value" : 6.2,
"unit" : "km/l",
"type" : "alcool"
},
{
"value" : 8.9,
"unit" : "km/l",
"type" : "gasolina"
}
],
},
...."fuelUse" : {
"urban" : [
{
"value" : 7.8,
"unit" : "km/l",
"type" : "alcool"
},
{
"value" : 10.4,
"unit" : "km/l",
"type" : "gasolina"
}
],
}
}
the output like: list = [ 8.9 , 10.4 ]
i tried to iterate in that way, but hav key error: 1
for c in cars:
for a in c['fuelUse']['urban']:
list.append(a[1]['value'])
try
list.append(a['value'])
instead of
list.append(a[1]['value'])
Since a is not a list, it is a single object, there is no need for further indexing.
If you would like the value of the second element, which type is gasolina, from each urban, you should loop through them, not the object's inside.
for c in cars:
for a in c['fuelUse']['urban']:
if a['type'] == 'gasolina':
list.append(a['value'])
I am not quite sure as you did not provide the entire data structure but according to your try it could be like this:
output = [x.get("value") for car in cars for x in car.get("fuelUse").get("urban") if x.get("type") == "gasolina"]
I am using google maps api with this python code to print a route between two points.
import requests, json
#Google MapsDdirections API endpoint
endpoint = 'https://maps.googleapis.com/maps/api/directions/json?'
api_key = 'AIzaSyCTPkufBttRcfSkA9zPYgivrYs9QEhdEEU'
#Asks the user to input Where they are and where they want to go.
origin = input('Where are you?: ').replace(' ','+')
destination = input('Where do you want to go?: ').replace(' ','+')
#Building the URL for the request
nav_request = 'origin={}&destination={}&key={}'.format(origin,destination,api_key)
request = endpoint + nav_request
#Sends the request and reads the response.
#response = urllib.request.urlopen(request).read()
r = requests.get('https://maps.googleapis.com/maps/api/directions/json?origin=Vigo&destination=Lugo&key=AIzaSyCTPkufBttRcfSkA9zPYgivrYs9QEhdEEU')
#Loads response as JSON
#directions = json.loads(response)
directions = r.json()
print(directions)
The problem is that my response gives me ZERO_RESULTS.
I´ve tried it manually in google chrome getting the next result:
{
"geocoded_waypoints" : [
{
"geocoder_status" : "OK",
"place_id" : "ChIJbYcwsYDOMQ0RDAVnKL9fMB8",
"types" : [ "locality", "political" ]
},
{
"geocoder_status" : "OK",
"place_id" : "ChIJk8GyYRRiLw0Rn9RLF60dRHs",
"types" : [ "locality", "political" ]
}
],
"routes" : [
{
"bounds" : {
"northeast" : {
"lat" : 43.0082848,
"lng" : -7.554997200000001
},
"southwest" : {
"lat" : 42.2392374,
"lng" : -8.720694999999999
}
},
"copyrights" : "Datos de mapas ©2019 Inst. Geogr. Nacional",
"legs" : [
{
"distance" : {
"text" : "188 km",
"value" : 188311
},
"duration" : {
"text" : "2h 11 min",
"value" : 7830
},
"end_address" : "Vigo, Pontevedra, España",
"end_location" : {
"lat" : 42.2406168,
"lng" : -8.720694999999999
},
"start_address" : "Lugo, España",
"start_location" : {
"lat" : 43.0082848,
[...]
However, when I try it online i get different geocoded waypoints and, therefore, zero_results.
'types': ['bar', 'establishment', 'food', 'point_of_interest', 'restaurant']}], 'routes': [], 'status': 'ZERO_RESULTS'}
How can I change geocoded_waypoint types??
As I can see from your example you try to get directions between two Spanish cities. However, when you specify only names of cities in origin and destination the service might resolve them to different countries due to ambiguity in parameters. For example, when I execute your request on my server that located in USA the destination Lugo is resolved to place ID ChIJi59iTw6wZIgRvssCUK9Ra84 which is a restaurant with name "Lugo's" located in 107 S Main St, Dickson, TN 37055, USA.
See place details
https://maps.googleapis.com/maps/api/place/details/json?placeid=ChIJi59iTw6wZIgRvssCUK9Ra84&fields=formatted_address,geometry,name,type&key=YOUR_API_KEY
As origin is located in Spain and destination in USA, the directions service cannot build a driving directions and returns ZERO_RESULTS.
In order to resolve ambiguity you should provide more precise origin and destination parameters or specify a region where you are searching results.
If I add region parameter in request I get expected route between Spanish cities
https://maps.googleapis.com/maps/api/directions/json?origin=Vigo&destination=Lugo®ion=ES&key=YOUR_API_KEY
You can see it in directions calculator:
https://directionsdebug.firebaseapp.com/?origin=Vigo&destination=Lugo®ion=ES
I hope my answer clarifies your doubt!
Sample JSON file below
{
"destination_addresses" : [ "New York, NY, USA" ],
"origin_addresses" : [ "Washington, DC, USA" ],
"rows" : [
{
"elements" : [
{
"distance" : {
"text" : "225 mi",
"value" : 361715
},
"duration" : {
"text" : "3 hours 49 mins",
"value" : 13725
},
"status" : "OK"
}
]
}
],
"status" : "OK"
}
I'm looking to reference the text value for distance and duration. I've done research but i'm still not sure what i'm doing wrong...
I have a work around using several lines of code, but i'm looking for a clean one line solution..
thanks for your help!
If you're using the regular JSON module:
import json
And you're opening your JSON like this:
json_data = open("my_json.json").read()
data = json.loads(json_data)
# Equivalent to:
data = json.load(open("my_json.json"))
# Notice json.load vs. json.loads
Then this should do what you want:
distance_text, duration_text = [data['rows'][0]['elements'][0][key]['text'] for key in ['distance', 'duration']]
Hope this is what you wanted!
I am attempting to parse some JSON that I am receiving from a RESTful API, but I am having trouble accessing the data in Python because it appears that there is an empty property name.
A sample of the JSON returned:
{
"extractorData" : {
"url" : "RetreivedDataURL",
"resourceId" : "e38e1a7dd8f23dffbc77baf2d14ee500",
"data" : [ {
"group" : [ {
"CaseNumber" : [ {
"text" : "PO-1994-1350",
"href" : "http://www.referenceURL.net"
} ],
"DateFiled" : [ {
"text" : "03/11/1994"
} ],
"CaseDescription" : [ {
"text" : "Mary v. JONES"
} ],
"FoundParty" : [ {
"text" : "Lastname, MARY BETH (Plaintiff)"
} ]
}, {
"CaseNumber" : [ {
"text" : "NP-1998-2194",
"href" : "http://www.referenceURL.net"
}, {
"text" : "FD-1998-2310",
"href" : "http://www.referenceURL.net"
} ],
"DateFiled" : [ {
"text" : "08/13/1993"
}, {
"text" : "06/02/1998"
} ],
"CaseDescription" : [ {
"text" : "IN RE: NOTARY PUBLIC VS REDACTED"
}, {
"text" : "REDACTED"
} ],
"FoundParty" : [ {
"text" : "Lastname, MARY H (Plaintiff)"
}, {
"text" : "Lastname, MARY BETH (Defendant)"
} ]
} ]
} ]
And the Python code I am attempting to use
import requests
import json
FirstName = raw_input("Please Enter First name: ")
LastName = raw_input("Please Enter Last Name: ")
with requests.Session() as c:
url = ('https://www.requestURL.net/?name={}&lastname={}').format(LastName, FirstName)
page = c.get(url)
data = page.content
theJSON = json.loads(data)
def myprint(d):
stack = d.items()
while stack:
k, v = stack.pop()
if isinstance(v, dict):
stack.extend(v.iteritems())
else:
print("%s: %s" % (k, v))
print myprint(theJSON["extractorData"]["data"]["group"])
I get the error:
TypeError: list indices must be integers, not str
I am new to parsing Python and more than simple python in general so excuse my ignorance. But what leads me to believe that it is an empty property is that when I use a tool to view the JSON visually online, I get empty brackets, Like so:
Any help parsing this data into text would be of great help.
EDIT: Now I am able to reference a certain node with this code:
for d in group:
print group[0]['CaseNumber'][0]["text"]
But now how can I iterate over all the dictionaries listed in the group property to list all the nodes labeled "CaseNumber" because it should exist in every one of them. e.g
print group[0]['CaseNumber'][0]["text"]
then
for d in group:
print group[1]['CaseNumber'][0]["text"]
and so on and so forth. Perhaps incrementing some sort of integer until it reaches the end? I am not quite sure.
If you look at json carefully the data key that you are accessing is actually a list, but data['group'] is trying to access it as if it were a dictionary, which is raising the TypeError.
To minify your json it is something like this
{
"extractorData": {
"url": "string",
"resourceId": "string",
"data": [{
"group": []
}]
}
}
So if you want to access group, you should first retrieve data which is a list.
data = sample['extractorData']['data']
then you can iterate over data and get group within it
for d in data:
group = d['group']
I hope this clarifies things a bit for you.