I am trying to grab this data and print into a string of text i am having the worst! issues getting this to work.
Here is the source i am working with to get a better understanding i am working on an envirmental controller and my sonoff switch combined
https://github.com/FirstCypress/LiV/blob/master/software/liv/iotConnectors/sonoff/sonoff.py this code works for two pages once completed so ignore the keys for tempature etc
m = json.loads(content)
co2 = m["Value"]
I need the value of "Value" under the "TaskValues" it should be either a 1 or a 0 in almost any case how would i pulled that key in the right form?
"Sensors":[
{
"TaskValues": [
{"ValueNumber":1,
"Name":"Switch",
"NrDecimals":0,
"Value":0
}],
"DataAcquisition": [
{"Controller":1,
"IDX":0,
"Enabled":"false"
},
{"Controller":2,
"IDX":0,
"Enabled":"false"
},
{"Controller":3,
"IDX":0,
"Enabled":"false"
}],
"TaskInterval":0,
"Type":"Switch input - Switch",
"TaskName":"relias",
"TaskEnabled":"true",
"TaskNumber":1
}
],
"TTL":60000
}
You can get it by
m['Sensors'][0]['TaskValues'][0]['Value']
"Value" is nested in your json, as you've mentioned. To get what you want, you'll need to traverse the parent data structures:
m = json.loads(content)
# This is a list
a = m.get('Sensors')
# This is a dictionary
sensor = a[0]
# This is a list
taskvalue = sensor.get('TaskValues')
# Your answer
value = taskvalue[0].get('Value')
Related
I've gone through other similar problems here, but still can't identify my problem.
I have this JSON data returned from an API call:
{
"Open": {
"1638316800000": 120.5400009155,
"1640995200000": 106.1399993896,
"1643673600000": 67.2799987793,
"1646092800000": 65.4300003052,
"1648771200000": 50.1800003052,
"1651104000000": 31.5699996948
},
"High": {
"1638316800000": 126.75,
"1640995200000": 106.8000030518,
"1643673600000": 71.5,
"1646092800000": 66.5400009155,
"1648771200000": 50.2599983215,
"1651104000000": 31.6900005341
},
"Low": {
"1638316800000": 88.4000015259,
"1640995200000": 50.0,
"1643673600000": 53.5,
"1646092800000": 33.4599990845,
"1648771200000": 30.5799999237,
"1651104000000": 30.5209999084
},
"Close": {
"1638316800000": 103.6900024414,
"1640995200000": 65.7399978638,
"1643673600000": 67.5599975586,
"1646092800000": 50.2400016785,
"1648771200000": 31.2199993134,
"1651104000000": 30.6100006104
}
}
All I'm trying to do is assign the "Close" data to a new variable close and return close instead of the entire dictionary response.
Here is what I'm currently trying and I've tried different variations and all keep returning "string indices must be integers"
#app.route("/history")
def display_history():
symbol = request.args.get('symbol', default="AAPL")
period = request.args.get('period', default="1y")
interval = request.args.get('interval', default="1mo")
quote = yf.Ticker(symbol)
hist = quote.history(period=period, interval=interval)
data = hist.to_json()
close = data["Close"]
return close
You are trying to use data, which is a string with json format, as your interpreter told you.
In order to read it as a dictionary with the key "Close", you can use the function loads from json package. It deserializes the string to a Python dictionary :
data = hist.to_json()
data = json.loads(data)
close = data["Close"]
Additionally, it appears that Ticker.history(), from yfinance module, returns a pandas Dataframe. If it is the case, you can use this instead :
data = hist.to_dict()
close = data['Close']
This way, the data is not converted to Json then back to Python dictionary again but straight to a dictionary.
I have a JSON file containing the list of price changes of all cryptocurrencies
I want to extract all 'percentage' for all the coins.
Using the code below it throws TypeError: string indices must be integers (which I know is totally wrong, Basically trying to understand how can I search for percentage and get its value for all items)
with open('balance.txt') as json_file:
data = json.load(json_file)
for json_i in data:
print(json_i['priceChangePercent'])
Any help is appreciated
I have attached the json file hereJSON FILE
Below is the sample of JSON file for those who dont want to open link
{
"ETH/BTC":{
"symbol":"ETH/BTC",
"timestamp":1630501910299,
"datetime":"2021-09-01T13:11:50.299Z",
"open":0.071579,
"close":0.0744,
"last":0.0744,
"previousClose":0.071585,
"change":0.002821,
"percentage":3.941,
"average":null,
"baseVolume":178776.0338,
"quoteVolume":13026.89979053,
"info":{
"symbol":"ETHBTC",
"priceChange":"0.00282100",
"priceChangePercent":"3.941",
"count":"279051"
}
},
"LTC/BTC":{
"symbol":"LTC/BTC",
"timestamp":1630501909389,
"datetime":"2021-09-01T13:11:49.389Z",
"open":0.003629,
"close":0.00365,
"last":0.00365,
"previousClose":0.003629,
"change":2.1e-05,
"percentage":0.579,
"average":null,
"baseVolume":132964.808,
"quoteVolume":485.12431556,
"info":{
"symbol":"LTCBTC",
"priceChange":"0.00002100",
"priceChangePercent":"0.579",
"count":"36021"
}
},
"BNB/BTC":{
"symbol":"BNB/BTC",
"timestamp":1630501910176,
"datetime":"2021-09-01T13:11:50.176Z",
"open":0.009848,
"close":0.010073,
"last":0.010073,
"previousClose":0.009848,
"change":0.000225,
"percentage":2.285,
"average":null,
"baseVolume":220645.713,
"quoteVolume":2187.75954249,
"info":{
"symbol":"BNBBTC",
"priceChange":"0.00022500",
"priceChangePercent":"2.285",
"count":"130422"
}
},
If it is single dictionary, it could be done the following way:
data['LTC/BTC']['info']['priceChangePercent']
Extract it using list comprehension.
percentage_list = [value['percentage'] for value in data.values()]
priceChangePercent_list = [value['info']['priceChangePercent'] for value in data.values()]
print(percentage_list)
print(priceChangePercent_list)
[3.941, 0.579, 2.285]
['3.941', '0.579', '2.285']
try this bro
t = []
for key, value in a.items():
if "info" in value and "priceChangePercent" in value["info"]:
t.append(value["info"]["priceChangePercent"])
I have two dictionaries of data which needs to be compared and fetch the respective data from one dictionary to another:
netname = []
netstatus = []
Dict1:
data1: {
"node1":["id1",["net1","net2"]],
"node2":["id2",["net3","net4"]],
"node3":["id3",["net5","net1"]],
"node4":["id4",["net2","net5"]],
....
....
....
}
Dict2:
data2: {
"detail1":["net1","id1","netone","available"],
"detail2":["net2","id2","nettwo","available"],
"detail3":["net1","id3","netthree","not available"],
"detail4":["net4","id4","netfour","not available"],
"detail5":["net5","id4","netfive","available"],
"detail6":["net2","id2","netsix","available"],
....
....
}
I am trying to get the complete details of each of every node in a tabular format using prettytable:
The code I am trying here is:
for node,values in data1.items():
id = values[0]
networks = values[1]
for network in networks:
if any(any(network in x for x in netlist) for netlist in data2.values()):
if any((network in y for y in data2.values() if y[0] == network and y[1] == id)):
for val in data2.values():
if (val[0] == network and val[1] == id):
nwinfo = netname.append(val[2])
nwstatus = netstatus.append(val[3])
else:
print("node id",id,"is not registered in network",network)
else:
print("Node is not registered in any networks..")
when I executed this code, I am getting false values. Do the any(condition) correct here or do I need to add anything to display the correct values after comparing data1 with data2.
First any() condition in the above script is to check if id of data1 dict is present in entire dict data2
second any() condition in the above script is to check if the id is connected to respective network or not
In the above case, I want to check if the id and the net(n) should be compared properly in dict1 and dict2 and display the respective values.
One way forward would be to reshape your inputs to make the join easier. I would do that with comprehensions based around a new "key" that would be the combination of "id" and "net".
You can uncomment the print statements to get a better look at what the reshaping is doing if you like.
data1 = {
"node1":["id1",["net1","net2"]],
"node2":["id2",["net3","net4"]],
"node3":["id3",["net5","net1"]],
"node4":["id4",["net2","net5"]],
}
data2 = {
"detail1":["net1","id1","netone","available"],
"detail2":["net2","id2","nettwo","available"],
"detail3":["net1","id3","netthree","not available"],
"detail4":["net4","id4","netfour","not available"],
"detail5":["net5","id4","netfive","available"],
"detail6":["net2","id2","netsix","available"],
}
data1_reshaped = [
f"{cell}:{row[0]}"
for row in data1.values() for cell in row[1]
]
#print(data1_reshaped)
data2_reshaped = {
f"{x[0]}:{x[1]}": {"name": x[2], "status": x[3]}
for x in data2.values()
}
#print(data2_reshaped)
netname = []
netstatus = []
## now it is a simple lookup based on an array of keys
for key in data1_reshaped:
match = data2_reshaped.get(key)
if not match:
continue
netname.append(match["name"])
netstatus.append(match["status"])
print(netname)
print(netstatus)
This should give you:
['netone', 'netthree', 'netfive']
['available', 'not available', 'available']
If in the end you want something more like:
{
'netone': 'available',
'netthree': 'not available',
'netfive': 'available'
}
The join step even simpler.
i am currently doing a data science project (beginner) and have the following scenario :
I have a dataframe with Pincode , address and city (approx 57000 rows)
I need the geo coordinates of the same
i am trying to use the Bing Map API to get the coordinates in python. But i am stuck at parsing the Json response.
pincodelist=[]
import json
i=0
for i in range(5): #just trying with first 5 rows
countryRegion = "IN"
locality = df_all.iloc[13,6] #references the location column
postalCode =df_all.iloc[13,12] #references the pincode column
addressLine = df_all.iloc[13,0] #references the address
BingMapsKey = 'my api key'
url="http://dev.virtualearth.net/REST/v1/Locations?countryRegion="+str(countryRegion)+"&locality="+str(locality)+"&postalCode=" + str(postalCode)+"&addressLine="+str(addressLine)+"&key="+str(BingMapsKey)
# make the GET request
results = requests.get(url).json()
pincodelist.append([
addressLine,
postalCode,
results(['resourceSets']['resources']['bbox'])])
print(pincodelist)
I get the following error:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-198-396207c04bc6> in <module>
20 addressLine,
21 postalCode,
---> 22 results(['resourceSets']['resources']['bbox'])])
23 print(pincodelist)
24
TypeError: list indices must be integers or slices, not str
can somebody please help me how to parse this json response? the info i need is "bbox" which contains the coordinates.
{
"authenticationResultCode":"ValidCredentials",
"brandLogoUri":"http://dev.virtualearth.net/Branding/logo_powered_by.png",
"copyright":"Copyright © 2020 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.",
"resourceSets":[
{
"estimatedTotal":1,
"resources":[
{
"__type":"Location:http://schemas.microsoft.com/search/local/ws/rest/v1",
"bbox":[
12.91842713075696,
77.56459359208381,
12.926152565898313,
77.57516165693963
],
"name":"Banashankari, India",
"point":{
"type":"Point",
"coordinates":[
12.922289848327637,
77.56987762451172
]
},
"address":{
"adminDistrict":"KA",
"adminDistrict2":"Bengaluru",
"countryRegion":"India",
"formattedAddress":"Banashankari, India",
"locality":"Bengaluru"
},
"confidence":"High",
"entityType":"Neighborhood",
"geocodePoints":[
{
"type":"Point",
"coordinates":[
12.922289848327637,
77.56987762451172
],
"calculationMethod":"Rooftop",
"usageTypes":[
"Display"
]
}
],
"matchCodes":[
"Good"
]
}
]
}
],
"statusCode":200,
"statusDescription":"OK",
"traceId":"4e23d3d9bef84411846539f3113cc06b|DU00000D7F|0.0.0.1|Ref A: F8AB7E576A9B47B1A86B3DE04F1058A9 Ref B: DB3EDGE1616 Ref C: 2020-05-24T11:30:41Z"
}
Also would be helpful if you can refer any other location data service considering the numbers of rows to query. As a student a paid service is not feasible for me.
resourceSets is a list of objects, as can be seen by the square brackets that follow the key, so you need to specify a numeric index to get an element out of it. The same goes for the resources key.
{'resourceSets': [{'estimatedTotal': 1, 'resources': [{'__type': ...
In you example, there is only one resourceSet, so we can just get the first element:
# resource sets - a list
resource_sets = results['resourceSets']
# resource set object
resource_set = resource_sets[0]
# resources - a list
resources = resource_set['resources']
# first resource
resource = resources[0]
# bbox - a list with 4 numbers inside
bbox = resource['bbox']
# Or in one line:
results['resourceSets'][0]['resources'][0]['bbox']
Parse the response into json using json.parse.
I tried doing it in javaScript and assigned the json response to a variable t.
was able to extract using this reference, some keys have list as their values that could be the problem you are facing.
t.resourceSets[0].resources[0].bbox
(4) [12.91842713075696, 77.56459359208381, 12.926152565898313, 77.57516165693963]
I'm struggling with my json data that I get from an API. I've gone into several api urls to grab my data, and I've stored it in an empty list. I then want to take out all fields that say "reputation" and I'm only interested in that number. See my code here:
import json
import requests
f = requests.get('my_api_url')
if(f.ok):
data = json.loads(f.content)
url_list = [] #the list stores a number of urls that I want to request data from
for items in data:
url_list.append(items['details_url']) #grab the urls that I want to enter
total_url = [] #stores all data from all urls here
for index in range(len(url_list)):
url = requests.get(url_list[index])
if(url.ok):
url_data = json.loads(url.content)
total_url.append(url_data)
print(json.dumps(total_url, indent=2)) #only want to see if it's working
Thus far I'm happy and can enter all urls and get the data. It's in the next step I get trouble. The above code outputs the following json data for me:
[
[
{
"id": 316,
"name": "storabro",
"url": "https://storabro.net",
"customer": true,
"administrator": false,
"reputation": 568
}
],
[
{
"id": 541,
"name": "sega",
"url": "https://wedonthaveanyyet.com",
"customer": true,
"administrator": false,
"reputation": 45
},
{
"id": 90,
"name": "Villa",
"url": "https://brandvillas.co.uk",
"customer": true,
"administrator": false,
"reputation": 6
}
]
]
However, I only want to print out the reputation, and I cannot get it working. If I in my code instead use print(total_url['reputation']) it doesn't work and says "TypeError: list indices must be integers or slices, not str", and if I try:
for s in total_url:
print(s['reputation'])
I get the same TypeError.
Feels like I've tried everything but I can't find any answers on the web that can help me, but I understand I still have a lot to learn and that my error will be obvious to some people here. It seems very similar to other things I've done with Python, but this time I'm stuck. To clarify, I'm expecting an output similar to: [568, 45, 6]
Perhaps I used the wrong way to do this from the beginning and that's why it's not working all the way for me. Started to code with Python in October and it's still very new to me but I want to learn. Thank you all in advance!
It looks like your total_url is a list of lists, so you might write a function like:
def get_reputations(data):
for url in data:
for obj in url:
print(obj.get('reputation'))
get_reputations(total_url)
# output:
# 568
# 45
# 6
If you'd rather not work with a list of lists in the first place, you can extend the list with each result instead of append in the expression used to construct total_url
You can also use json.load and try to read the response
def get_rep():
response = urlopen(api_url)
r = response.read().decode('utf-8')
r_obj = json.loads(r)
for item in r_obj['response']:
print("Reputation: {}".format(item['reputation']))