I want to print "identifier":"OPTSTKHDFC25-08-2022PE1660.00" in python - python

I tried below code but it gave
TypeError: string indices must be integers
from nsepython import *
import pandas as pd
import json
positions = nse_optionchain_scrapper ('HDFC')
json_decode = json.dumps(positions,indent = 4, sort_keys=True,separators =(". ", " = "))
print(json_decode['data'][0]['identifier'])

print(json_decode['filtered']['data'][0]['PE']['identifier'])

json_decode = json.dumps(positions,indent = 4, sort_keys=True,separators =(". ", " = "))
You can't build a JSON string (which is what json.dumps does) and then try to access part of the result as if it were the original data structure. Your json_decode is just a string, not a dict; as far as Python is concerned it has no structure beyond the individual characters that make it up.
If you want to access parts of the data, just use positions directly:
print(positions['data'][0]['identifier'])
You can encode just that bit to JSON if you like:
print(json.dumps(positions['data'][0]['identifier'])
but that's probably just a quoted string in this case.
So I'm not sure what your goal is. If you want to print out the JSON version of positions, great, just print it out. But the JSON form is for input and output only; it's not suitable for messing around with inside your Python code.

Related

How to parse JSON with a list of lists?

I am trying to parse a "complicated" JSON string that is returned to me by an API.
It looks like this:
{
"data":[
["Distance to last strike","23.0","miles"],
["Time of last strike","1/14/2022 9:23:42 AM",""],
["Number of strikes today","1",""]
]
}
While the end goal will be to extract the distance, date/time, as well as count, for right now I am just trying to successfully get the distance.
My python script is:
import requests
import json
response_API = requests.get('http://localhost:8998/api/extra/lightning.json')
data = response_API.text
parse_json = json.loads(data)
value = parse_json['Distance to last strike']
print(value)
This does not work. If I change the value line to
value = parse_json['data']
then the entire string I listed above is returned.
I am hoping it's just a simple formatting issue. Suggestions?
You have an object with a list of lists. If you fetch
value = parse_json['data']
Then you will have a list containing three lists. So:
print(value[0][1])
will print "23.0".

How to change html hyperlink based on python output?

Hi I'm new to using html and python. But I need to use html and python interchangeably.
For example,
if python output = 30302,
then I need to put '30302' in the hyperlink.
www.google.com/< output> = www.google.com/30302
html = 'www.google.com/'
python = < output>
how would I combine those two?
The problem
I guess that you wanna create a new string from two parts, i.e. you have a string "www.google.com/" and a variable output with integer 30302 and you wanna get the "www.google.com/30302" (for the future, always provide full examples of your code).
So how can you do it?
Convert int to str and concatenate strs
result = "www.google.com/" + str(output)
str(x) will turn x into a string
Formatting
"www.google.com/{}".format(31415)" is equivalent to the "www.google.com/31415" string,
so result = "www.google.com/{}".format(output)" also will work
in python 3 we also have f-stings:
f"www.google.com/{31415}" == "www.google.com/31415"
result = f"www.google.com/{output}"

How do I present my output as a Pandas dataframe?

CHECK_OUTPUT_HERE
Currently, the output I am getting is in the string format. I am not sure how to convert that string to a pandas dataframe.
I am getting 3 different tables in my output. It is in a string format.
One of the following 2 solutions will work for me:
Convert that string output to 3 different dataframes. OR
Change something in the function so that I get the output as 3 different data frames.
I have tried using RegEx to convert the string output to a dataframe but it won't work in my case since I want my output to be dynamic. It should work if I give another input.
def column_ch(self, sample_count=10):
report = render("header.txt")
match_stats = []
match_sample = []
any_mismatch = False
for column in self.column_stats:
if not column["all_match"]:
any_mismatch = True
match_stats.append(
{
"Column": column["column"],
"{} dtype".format(self.df1_name): column["dtype1"],
"{} dtype".format(self.df2_name): column["dtype2"],
"# Unequal": column["unequal_cnt"],
"Max Diff": column["max_diff"],
"# Null Diff": column["null_diff"],
}
)
if column["unequal_cnt"] > 0:
match_sample.append(
self.sample_mismatch(column["column"], sample_count, for_display=True)
)
if any_mismatch:
for sample in match_sample:
report += sample.to_string()
report += "\n\n"
print("type is", type(report))
return report
Since you have a string, you can pass your string into a file-like buffer and then read it with pandas read_csv into a dataframe.
Assuming that your string with the dataframe is called dfstring, the code would look like this:
import io
bufdf = io.StringIO(dfstring)
df = pd.read_csv(bufdf, sep=???)
If your string contains multiple dataframes, split it with split and use a loop.
import io
dflist = []
for sdf in dfstring.split('\n\n'): ##this seems the separator between two dataframes
bufdf = io.StringIO(sdf)
dflist.append(pd.read_csv(bufdf, sep=???))
Be careful to pass an appropriate sep parameter, my ??? means that I am not able to understand what could be a proper parameter. Your field are separated by spaces, so you could use sep='\s+') but I see that you have also spaces which are not meant to be a separator, so this may cause a parsing error.
sep accept regex, so to have 2 consecutive spaces as a separator, you could do: sep='\s\s+' (this will require an additional parameter engine='python'). But again, be sure that you have at least 2 spaces between two consecutive fields.
See here for reference about the io module and StringIO.
Note that the io module exists in python3 but not in python2 (it has another name) but since the latest pandas versions require python3, I guess you are using python3.

"list indices must be integers" error, when trying to use keys from a dictionary

I tried to use the openweathermap.org rest API inside python. When I tried to assign a key from the dictionary I created with the JSON data this error occurred.
-list indices must be integers or slices, not str
I'm new to python and I couldn't find a solution to this matter.
The code snip I wrote:
import requests
from pprint import pprint
lokka = str(input("What is the location you need information of?"))
#takes the location as "lokka"
hellload = requests.get("http://api.openweathermap.org/data/2.5/weather?q="+ lokka +"&appid=xxxxxxxxxxxxxxxxx&units=metric")
#the rest api's load will be taken to the account of hellload
jputha = hellload.json()
#json data will be converted to a dictionary
#print (jputha)
#---------------------------------------------------------
#from now onward I'll be kickin the hell out the jsons
long = str(jputha["coord"]["lon"])
lat = str(jputha["coord"]["lat"])
wthr = str(jputha["weather"]["main"])
temp = str(jputha["main"]["temp"])
winspd = str(jputha["wind"]["speed"])
print(long)
print(lat)
print(wthr)
print(temp)
print(winspd)
According to OpenWeatherMap's documentation, the JSON response from the API looks like this:
{"coord":
{"lon":145.77,"lat":-16.92},
"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04n"}],
"base":"cmc stations",
"main":{"temp":293.25,"pressure":1019,"humidity":83,"temp_min":289.82,"temp_max":295.37},
"wind":{"speed":5.1,"deg":150},
"clouds":{"all":75},
"rain":{"3h":3},
"dt":1435658272,
"sys":{"type":1,"id":8166,"message":0.0166,"country":"AU","sunrise":1435610796,"sunset":1435650870},
"id":2172797,
"name":"Cairns",
"cod":200}
where the weather key contains a list of dicts rather than a dict, so if you simply want the first weather data from the list, you should use [0] to obtain the value of the first index instead:
wthr = str(jputha["weather"][0]["main"])

How to decode a JSON with Python?

I am trying to decode a JSON with Python. Here is a little snippet of what the JSON looks like.
b'{"success":true,"data":[{"id":26,"name":"A","comment":"","start_time_plan":null,"start_time_actual":"2016-09-13 00:00:00","start_time_delta":null,"start_time_score":null,"start_time_score_achievement":null,"start_time_traffic_light":null,"end_time_plan":null,"end_time_actual":"2016-09-13 00:00:00","end_time_delta":null,"end_time_score":null,"end_time_score_achievement":null,"end_time_traffic_light":null,"status":0,"measure_schedule_revision_id":63,"responsible_user_id":3,"created_time":"2016-09-13 11:29:14","created_user_id":3,"modified_time":"2016-09-21 16:33:41","modified_user_id":3,"model":"Activity"},{"id":27,"name":"B","comment":"","start_time_plan":null,"start_time_actual":"2016-09-13 00:00:00","start_time_delta":null,"start_time_score":null,"start_time_score_achievement":null,"start_time_traffic_light":null,"end_time_plan":null,"end_time_actual":"2016-09-13 00:00:00","end_time_delta":null,"end_time_score":null,"end_time_score_achievement":null,"end_time_traffic_light":null,"status":0,"measure_schedule_revision_id":63,"responsible_user_id":3,"created_time":"2016-09-13 11:29:48","created_user_id":3,"modified_time":"2016-10-16 18:14:36","modified_user_id":1,"model":"Activity"}
I am trying to get a hold of start_time_deltaand end_time_delta and produce a little scatter plot. But somehow I can't decode the JSON.
Here is what I do:
#falcon api
u = 'https://myurl.com'
#urllib3 + poolmanager for requests
import urllib3
http = urllib3.PoolManager()
import json
r = http.request('GET', u)
json.loads(r.data.decode('utf-8'))
end = json.loads(r.data['end_time_delta'])
start = json.loads(r.data['start_time_delta'])
This is the error I get: byte indices must be integers or slices, not str
How come? And how do I solve the problem?
You are ignoring the return value of json.loads() here:
json.loads(r.data.decode('utf-8'))
You then try to decode the same raw again and try to use that as the decoded Python result. Call json.loads() once, and use the resulting Python dictionary:
result = json.loads(r.data.decode('utf-8'))
start = result['data'][0]['start_time_delta']
end = result['data'][0]['end_time_delta']
Because top-level dictionary 'data' key points to a list of results, I used 0 to get to the first of those and extract the data you want.
If you need to extract those data points for every dictionary in that list, you'd have to use a loop:
for entry in result['data']:
start = entry['start_time_delta']
end = entry['end_time_delta']
# do something with these two values, before iterating to the next

Categories

Resources