List slicing a json.loads file - python

What this code does it gets the values of a json.loads file. It gives me a list of dictionary that are organized by dates. This code works, my understanding is, i am taking the the first value in the list of dictionaries, so the first dictionary, but shouldn't. self.get_jsonparsed_data(self.ticker_text.get().upper())[0] work as well? In my case it doesn't, I was hoping if someone can explain why I does not work.
def get_jsonparsed_data(self, ticker):
#quote
url = (f"https://financialmodelingprep.com/api/v3/quote/{ticker}?)
response = urlopen(url)
data = response.read().decode("utf-8")
return json.loads(data)
def search_info(self):
#self.info.delete(0, END)
recent_filing = []
for header in self.get_jsonparsed_data(self.ticker_text.get().upper())[:1]:
recent_filing.append(header)
ticker = self.ticker_text.get()
#output dictionary values with proper format
try:
recent_filing_dict = recent_filing[0]
This works.
I get the first dictionary which is what i want but when i do self.get_jsonparsed_data(self.ticker_text.get().upper())[0] instead of self.get_jsonparsed_data(self.ticker_text.get().upper())[:1] it gives me an error
which pretty much is saying there isnt any values appended to recent_filing_dict. I was just hoping if someone can explain why?

"for" loops through iterable and self.get_jsonparsed_data(self.ticker_text.get().upper())[0] seemingly returns an item rather than iterable (list) while self.get_jsonparsed_data(self.ticker_text.get().upper())[:1] returns an iterable (single item list) which is iterated over by for loop

Related

How to continue iteration of JSON object/list with "for" loop nested in another "for" loop?

I'm trying to iterate through a JSON object/list to get the prices from the list. It works fine for the first "for" loop, but then for my program I need to have another "for" loop nested inside the first loop that effectively continues iterating again where the first loop left off.
edit: I apologise as I probably wasn't very clear as why I'm structuring this code this way. It probably isn't the best solution as I'm not very experienced with python but I'm trying to simulate the looping flow of price data based on historical prices from this JSON. So when the price is equal to something in the first loop, I was trying to continue the flow of data from where the last loop left off (the last price it read) in a nested loop with different if statements, now that the first one has been triggered. I understand this is probably a very poor way of getting around this problem and I'd be happy to hear suggestions on how to do it in a much simpler way.
for i in json:
time.sleep(1)
price = i['p']
if price == "0.00000183":
print("foo")
for i in json:
time.sleep(1)
price = float(i['p'])
if price == "0.00000181":
print("sold")
else:
continue
elif price == "0.00000185":
print ("sold")
break
else:
continue
Example segment of the JSON list:
[
{
"a":4886508,
"p":"0.00000182",
"q":"10971.00000000",
"f":5883037,
"l":5883037,
"T":1566503952430,
"m":1,
"M":1
},
{
"a":4886509,
"p":"0.00000182",
"q":"10971.00000000",
"f":5883038,
"l":5883038,
"T":1566503953551,
"m":1,
"M":1
},
{
"a":4886510,
"p":"0.00000182",
"q":"10971.00000000",
"f":5883039,
"l":5883039,
"T":1566503954431,
"m":1,
"M":1
}
]
You have 3 nested dicts inside the list and you’re using one value price to store all 3; therefore overwriting the value for every iteration.
I suggest using a simple list comprehension to get the price for each sub-dict.
[i['p'] for i in json]
This results in:
['0.00000182', '0.00000182', '0.00000182']
Although as a forewarning there is a builtin module called json so should you want to use that in the future you will need to use a more descriptive name; as well as your other naming conventions are very non informative in the first place consider better conventions.
P.S the price values are strings thus it’s meaningless to compare to int’s
Your sample code doesn't make much sense, so it's not clear what you're try to accomplish.
Ignoring that, if you use json.load() to read your file, the result will be a Python list of dictionaries (which are equivalent to JSON objects). Afterwards you can then just iterate through this list — you don't need to do anything else to go to the next dictionary/object.
Within each dictionary/object you can randomly access the key/value pairs it contains. If yoy want to iterate over them for some reason, you can used obj.keys(), obj.values(), or obj.items(), as you can with any dictionary.
Here's a small example of what I'm saying:
import json
filename = 'list_sample.json'
with open(filename) as json_file:
object_list = json.load(json_file)
for obj in object_list:
if obj['p'] == "0.00000183":
print("foo")
price = float(obj['p'])
print(price)
Use pandas
import pandas as pd
The question was how do I iterate through a json
I think the real question and goal is, how do I access my data from this object and gather insight from it.
That's the power of pandas. Now all of the information is available and easy to use.
If the data is inside a file, just as it's shown:
df = pd.read_json('file.json')
If the data is just a named object (e.g. data = [{...}, {...}, {...}])
df = pd.DataFrame(data)
Output of df:
Get p, or any of the other information:
p_list = df.p.tolist()
print(p_list)
>>> ['0.00000182', '0.00000182', '0.00000182']
You can write two loops using the same iterator object. You just need to create the iterator from your json list of dictionaries:
iterator = iter(json_data)
for i in iterator:
# stuff
for j in iterator: # start looping from where we left off
... # more stuff
Note that this only makes sense if the inner loop will be interrupted at some point by a break statement. Otherwise it will consume all of the iterator's contents and the outer loop will have nothing left. If you were expecting that, you should probably just break out of the outer loop and write the (formerly) inner loop at the same level:
for i in iterator:
if something():
break
for j in iterator: # iterate over the rest of the iterator's values
...
Note that I used json_data in my example code, rather than your variable name json. Using json as a variable name may be a bad idea because it may be the name of the module you're using to parse your data. Reusing the name may get confusing (json = json.load(filename) for instance can only be run once).
Apologies guys, I should've made it more clear that what I was looking for was probably simpler than what I made it out to be or how I described it. I basically just wanted to continue the second loop from where the first left off, with something like this which I have now found to be an alright solution.
elementCount = 0
for i in json:
time.sleep(1)
price = i['p']
elementCount = elementCount + 1
if price == "0.00000183":
print("foo")
for i in json[elementCount:]:
time.sleep(1)
price = float(i['p'])
if price == "0.00000181":
print("sold")
else:
continue
elif price == "0.00000185":
print ("sold")
break
else:
continue
I basically just didn't understand the format for continuing the iteration from a certain element in the list, like this [40:]. Thanks for all your answers and help.

Changing Json from API with Python

I have a json code from API and I want to get new chat members with the code below but I only get the first two results and not the last (Tester). Why? It should itereate through the whole json file, shouldn't it?
r = requests.get("https://api.../getUpdates").json()
chat_members = []
a = 0
for i in r:
chat_members.append(r['result'][a]['message']['new_chat_members'][0]['last_name'])
a = a + 1
Json here:
{"ok":true,"result":[{"update_id":213849278,
"message":{"message_id":37731,"from":{"id":593029363,"is_bot":false,"first_name": "#tutu"},"chat":{"id":-1001272017174,"title":"tester account","username":"v_glob","type":"supergroup"},"date":1537470595,"new_chat_participant":{"id":593029363,"is_bot":false,"first_name":"tutu "},"new_chat_member":{"id":593029363,"is_bot":false,"first_name":"\u7535\u62a5\u589e\u7c89\uff0c\u4e2d\u82f1\u6587\u5ba2\u670d\uff0c\u62c9\u4eba\u6e05\u5783\u573e\u8f6f\u4ef6\uff0c\u5e7f\u544a\u63a8\u5e7f\uff0cKYC\u6750\u6599\u8ba4\u8bc1\uff0c","last_name":"#tutupeng"},"new_chat_members":[{"id":593029363,"is_bot":false,"first_name":"\u7535\u62a5\u589e\u7c89\uff0c\u4e2d\u82f1\u6587\u5ba2\u670d\uff0c\u62c9\u4eba\u6e05\u5783\u573e\u8f6f\u4ef6\uff0c\u5e7f\u544a\u63a8\u5e7f\uff0cKYC\u6750\u6599\u8ba4\u8bc1\uff0c","last_name":"#tutu"}]}},{"update_id":213849279,
"message":{"message_id":37732,"from":{"id":658150956,"is_bot":false,"first_name":"Rebecca","last_name":"Lawson"},"chat":{"id":-10012720,"title":"v glob OFFICIAL","username":"v_glob","type":"supergroup"},"date":1537484441,"new_chat_participant":{"id":65815,"is_bot":false,"first_name":"Rebecca","last_name":"Lawson"},"new_chat_member":{"id":65815,"is_bot":false,"first_name":"Rebecca","last_name":"Lawson"},"new_chat_members":[{"id":65815,"is_bot":false,"first_name":"Rebecca","last_name":"Lawson"}]}},{"update_id":213849280,
"message":{"message_id":12,"from":{"id":696749142,"is_bot":false,"first_name":"daniel","language_code":"cs-cz"},"chat":{"id":696749142,"first_name":"daniel","type":"private"},"date":1537537013,"text":"/stat","entities":[{"offset":0,"length":5,"type":"bot_command"}]}},{"update_id":213849281,
"message":{"message_id":37740,"from":{"id":669620,"is_bot":false,"first_name":"Ivan","last_name":"Tester"},"chat":{"id":-100127201,"title":"test account","username":"v_glob","type":"supergroup"},"date":1537537597,"new_chat_participant":{"id":669620191,"is_bot":false,"first_name":"Ivan","last_name":"Tester"},"new_chat_member":{"id":669620191,"is_bot":false,"first_name":"Ivan","last_name":"Tester"},"new_chat_members":[{"id":669620191,"is_bot":false,"first_name":"Ivan","last_name":"Tester"}]}}]}
Because you iterate over the entire response dict. The top level only has two items, so that's what you iterate over. Note that you don't actually use the iterator variable, and you have a completely unnecessary separate counter.
Instead, you should be iterating over the result dict:
for result in r['result']:
if "new_chat_members" in result['message']:
chat_members.append(result['message']['new_chat_members'][0]['last_name'])
A colleague of mine has come up with a solution:
for i in l['result']:
chat_members.append(i['message']['new_chat_member']['first_name'])
To sum up: Iterate through 'result' with no positional arguments

dictionary that return website status code as key and website as value - py

Hey guys I need a bit of guidance with this problem ( .py noobie)
So I have a list of websites that have different status codes:
url_list=["http://www.ehow.com/foo-barhow_2323550_clean-coffee-maker-vinegar.html",
"http://www.google.com",
"http://livestrong.com/register/confirmation/",
"http://www.facebook.com",
"http://www.youtube.com"]
What i'm trying to return is a dictionary that returns the website's status code as key and the associated websites as values. Something like that:
result= {"200": ["http://www.google.com",
"http://www.facebook.com",
"http://www.youtube.com"],
"301": ["http://livestrong.com/register/confirmation/"],
"404": ["http://www.ehow.com/foo-barhow_2323550_clean-coffee-maker-vinegar.html"]}
What I have till now:
Function that gets the status code:
def code_number(url):
try:
u = urllib2.urlopen(url)
code = u.code
except urllib2.HTTPError, e:
code = e.code
return code
And a function should return the dictionary but is not working - the part where i got stuck. Basically I dont know how to make it insert in the same status code more than 1 url
result={}
def get_code(list_of_urls):
for n in list_of_urls:
code = code_number(n)
if n in result:
result[code] = n
else:
result[code] = n
return result
Any ideas please?! Thank you
collections.defaultdict makes this a breeze:
import collections
def get_code(list_of_urls):
result = collections.defaultdict(list)
for n in list_of_urls:
code = code_number(n)
result[code].append(n)
return result
Not sure why you had result as a global, since it's returned as the function's result anyway (avoid globals except when really indispensable... locals are not only a structurally better approach, but also faster to access).
Anyway, the collections.defaultdict instance result will automatically call the list argument, and thus make an empty list, to initialize any entry result[n] that wasn't yet there at the time of indexing; so you can just append to the entry without needing to check whether it was previously there or not. That is the super-convenient idea!
If for some reason you want a plain dict as a result (though I can't think of any sound reason for needing that), just return dict(result) to convert the defaultdict into a plain dict.
You could initialize every key of the dict with a list, to which you will append any websites that return the same status code. Example:
result={}
def get_code(list_of_urls):
for n in list_of_urls:
code = code_number(n)
if code in result:
result[code].append(n)
else:
result[code] = [n]
return result
I also think that the condition should be if code in result, since your keys are the return codes.

need help making a dictionary

Im still new to python and trying to teach myself and at the same time tying to make make a FIFA 14 autobuyer. Ive been working with an already made Library https://github.com/Fire30/Fifa14Client
What I'm trying to do is make a dictionary out of the information I get when searching for a specific card
The function used to search for a card is in WebAppFunctioner.py file and is
def search(self, type="player", lev="gold", pos="CAM", num=1, team="101059",
macr="", micr="", minb="", nat="", maxb="",
playStyle="", leag="", start=50, cat="",
definitionId="", maskedDefId=""):
the_url = self.TRANSFER_URL % (self.platform_string,type, lev, pos, num, team, macr, micr, minb, nat, maxb,
playStyle, leag, start, cat, definitionId, maskedDefId)
r = requests.post(the_url, headers=self.get_headers('GET'))
try:
json = r.json()
except:
raise BadRequestException("Could not complete search. No JSON object could be decoded")
if 'auctionInfo' in json:
card_list = json['auctionInfo']
return [Card.Card(card_dict) for card_dict in card_list]
elif 'code' in json:
raise FUTErrorCodeException("Could not get complete search.",json)
when I call function, print(func.search()), it makes a list of objects and prints each object in the terminal. Each object has a bunch of information in it and I am trying to take all the information and store it an a dictionary. I think that Card.py has exactly what I need except I dont really understand how to use it.
If the request is in fact valid the function should return a list of card dictionaries.
return [Card.Card(card_dict) for card_dict in card_list] is a list comprehension, which returns one or more of the results of card_dict (presumably the return value is a dict object) for each card that was in the auctionInfo json.
You shouldn't be expecting a dictionary back, but rather a list of dictionaries. If there is some unique identifier you could edit the code to be
if 'auctionInfo' in json:
card_list = json['auctionInfo']
return {some_unique_id: Card.Card(card_dict) for card_dict in card_list}
Edit: I had curly braces arount the some_unique_id k:v pair, that would have broken it.
Alternative: leave the function as is and handle it on the other side and just do a quick comprehension like:
{card.unique_id_thing:card for card in search()}

Trying to iterate over a JSON object

I am trying to iterate over a JSON object, using simplejson.
def main(arg1):
response = urllib2.urlopen("http://search.twitter.com/search.json?q=" + arg1) #+ "&rpp=100&page=15")
twitsearch = simplejson.load(response)
twitsearch = twitsearch['results']
twitsearch = twitsearch['text']
print twitsearch
I am passing a list of values to search for in Twitter, like "I'm", "Think", etc.
The problem is that there are multiple text fields, one each for every Tweet. I want to iterate over the entire JSON object, pulling out the "text" field.
How would I do this? I'm reading the documentation and can't see exactly where it talks about this.
EDIT: It appears to be stored as a list of JSON objects.
Trying to do this:
for x in twitsearch:
x['text']
How would I store x['text'] in a list? Append?
Note that
twitsearch['results']
is a Python list. You can iterate over that list, storing the text component of each of those objects in your own list. A list comprehension would be a good thing to use here.
text_list = [x['text'] for x in twitsearch['results']]
Easy. Figured it out.
tweets = []
for x in twitsearch:
tweets.append(x['text'])

Categories