Getting error using gender.py - python

am trying to tell gender by first name.
I been using this code from:
[https://github.com/block8437/gender.py/blob/master/gender.py][1]
import requests, json
def getGenders(names):
url = ""
cnt = 0
if not isinstance(names,list):
names = [names,]
for name in names:
if url == "":
url = "name[0]=" + name
else:
cnt += 1
url = url + "&name[" + str(cnt) + "]=" + name
req = requests.get("https://api.genderize.io?" + url)
results = json.loads(req.text)
retrn = []
for result in results:
if result["gender"] is not None:
retrn.append((result["gender"], result["probability"], result["count"]))
else:
retrn.append((u'None',u'0.0',0.0))
return retrn
Everything was working for 2 days, I have not change anything in the code. I been passing different names in it on and off for 2 days. Suddenly I got this error:
string indices must be integers
on this line:
if result["gender"] is not None:
First, I want to know why this would suddenly happen? Second, How can I fix it?

Iterating through a dictionary iterates through the keys in a dictionary.
results = {"name":"peter","gender":"male","probability":"0.99","count":796}
[result for result in results] # ['count', 'gender', 'name', 'probability']
Iterating through a list iterates through the items of a list.
results = [{"name":"peter","gender":"male","probability":"0.99","count":796}]
[result for result in results] # [{'count': 796, 'gender': 'male', 'name': 'peter', 'probability': '0.99'}]
According to the API description at https://genderize.io/, there are two response formats: a json object for a single name lookup (which json.loads would return as a dictionary), and a list of objects for multiple lookups (which json.loads would return as a list of dictionaries). See the response for
https://api.genderize.io/?name=peter
compared to
https://api.genderize.io/?name[0]=peter
It seems like your error is the result of getting a response in the first format when you are expecting the second. Why might this have changed? Thats a question for the API you are using. It looks to me like your request should always be in the multi-name request format but I can't speak for how they are actually responding.
As for fixing this, you could check the type and wrap naked dictionaries in a list:
retrn = []
if not isinstance(results, list):
results =[results]
for result in results:
if result["gender"] is not None:
retrn.append((result["gender"], result["probability"], result["count"]))
else:
retrn.append((u'None',u'0.0',0.0))

Related

how to get a value from a json text Python

import requests
import json
r = requests.get("https://api.investing.com/api/search/?t=Equities&q=amd") # i get json text from this api
data = json.loads(r.text)
if data['articles'][0]['exchange'] == 'Sydney': # the error is here KeyError: 'exchange'
print('success')
else:
print('fail')
if i want to get the url '/equities/segue-resources-ltd' by checking if the 'exchange' is 'Sydney' which is stored in this part of the json text, {"id":948190,"url":"/equities/segue-resources-ltd","description":"Segue Resources Ltd","symbol":"AMD","exchange":"Sydney","flag":"AU","type":"Equities"}
If i'm understanding this correctly, the exchange identifier only appears in part of the json response. So, in order to get your result using the same data variable in your question, we can do this:
result = [val["url"] for val in data["quotes"] if val["exchange"] == "Sydney"]
We are using a list comprehension here, where the loop is only going through data["quotes"] instead of the whole json response, and for each item in that json subset, we're returning the value for key == "url" where the exchange == "Sydney". Running the line above should get you:
['/equities/segue-resources-ltd']
As expected. If you aren't comfortable with list comprehensions, the more conventional loop-version of it looks like:
result = []
for val in data["quotes"]:
if val["exchange"] == "Sydney":
result.append(val["url"])
print(result)
KeyError: 'exchange' means that the dictionary data['articles'][0] did not have a key 'exchange'.
Depending on your use case, you may want to iterate over the whole list of articles:
for article in data['articles']:
if 'exchange' in article and article['exchange'] == 'Sydney':
... # Your code here
If you only want to check the first article, then use data['articles'][0].get('exchange'). The dict.get() method will return None if the key is not present instead of throwing a KeyError.

How can I iterate the entries of an API?

I have this api : https://api.publicapis.org/entries
And I wat to iterate key entries of it. I tried as it follows :
r = requests.get('https://api.publicapis.org/entries')
entries = [] #initializing the vector entries
for i in entries: #iterating it
return(i.text) #trying to print the entries
Then I received the following error :
TypeError: The view function did not return a valid response. The function either returned None or ended without a return statement.
How can I solve this problem ?
For that particular API endpoint, you should be fine with
resp = requests.get('https://api.publicapis.org/entries')
resp.raise_for_status() # raise exception on HTTP errors
entries = resp.json()["entries"] # parse JSON, dig out the entries list
# ... do something with entries.
You can use json.loads to parse response text.
Let me add the full code.
import requests
import json
r = requests.get('https://api.publicapis.org/entries')
entries = json.loads(r.text)['entries'] #initializing the vector entries
for i in entries: #iterating it
API = i['API']
Description = i['Description']

Unable to retun multiple dicitonary sets in python

I'm querying a REST API url & I'm trying to return all the dictionary sets, but only able to return one key pair.
Dictionary Output in the print statement inside for loop is the expected output, when when returned only one set of key pair is appearing.
Expected Dictionary looks like:
{'IncidentID': 'IM10265'}
{'IncidentID': 'IM10266'}
{'IncidentID': 'IM10267'}
{'IncidentID': 'IM10268'}
Code:
import json , requests
sm1 = requests.get('http://Rest Url', auth=('XX','YY'))
z = json.loads(sm1.text)
def get_im_list():
incidentlist_access = z['content']
for im_data in incidentlist_access:
Access_imslist = im_data['Incident']
print(Access_imslist)
#print(type(Access_imslist))
#return Access_imslist
data = get_im_list()
#print(data)
So when when I'm un-commentating
return Access_imslist & print(data)
I'm only receiving the output as:
{'IncidentID': 'IM10265'}
not the complete dictionary.
Every time you loop through the data, Access_imslist gets overwritten, so when you (presumably) return Access_Imlist it's only returning the last value.
You need to create a data structure outside of the for loop, add each bit of data to it, then return that instead. Something like:
def get_im_list():
incident_data = []
incidentlist_access = z['content']
for im_data in incidentlist_access:
incident_data.append(im_data['Incident'])
return incident_data
hope that helps!
you need to define a variable list , and then append the Access_imslist values to that variable.
like this :
data = []
def get_im_list():
incidentlist_access = z['content']
for im_data in incidentlist_access:
Access_imslist = im_data['Incident']
data.append(Access_imslist)
print(data)

Loop List Python for Variable

Im trying to loop through a list and insert the 'extensionid' into the URL
extensionid = ['1234','12356']
url = '/restapi/v1.0/account/~/extension/'+extensionid+'/presence'
params = {
'dndStatus': "TakeAllCalls",
}
resp = platform.get(url, params,)
print ((resp.text()))
But I get the error
url = '/restapi/v1.0/account/~/extension/'+extensionid+'/presence'
TypeError: can only concatenate str (not "list") to str [Finished in
1.121s
What am I doing wrong?
Thanks!
You probably need.
extensionid = ['1234','12356']
url = '/restapi/v1.0/account/~/extension/{}/presence'
params = {
'dndStatus': "TakeAllCalls",
}
for id in extensionid: #iterate each id
resp = platform.get(url.format(id), params) #form URL and query.
print ((resp.text()))
extensionid is a list of strings.
So, you cannot concatenate a list with a string as error is telling you.
To access a specific item of the list you have to use an index.
For example:
extensionid[0] // it contains 1234
extensionid[1] // it contains 12356
So, your url can be written like this:
url = '/restapi/v1.0/account/~/extension/'+extensionid[0]+'/presence'
In this case it will be evaluated by python as:
url = '/restapi/v1.0/account/~/extension/1234/presence'
Please consider this simple documentation about lists:
https://www.programiz.com/python-programming/list
To iterate the elements of a list you can use:
for element in extensionid:
url='/restapi/v1.0/account/~/extension/'+ element +'/presence'
print(url)

listproperty GAE to string method

So my problem below is that when it sends the json object lets say I have multiple items in the lists? well it sends that many objects except changing that field once in the dict that i created above. For some reason , even though I use the for loops above to create a string from the list it doesn't actually make it so and i get 15 objects instead of 1 object with maybe a field that has 15 things in it separated by commas.
my expected output should be
name,special1,special2,special3..etc, review1,review2
instead i get
name,special1,review1
name,special2,review1
name,special3,review1
etc..
name,special1,review2
name,special1,review3
My main question is how do I convert the list to an array or even just to a string(like a toString Method) so that my json dump doesn't spit out multiples?
class store(db.Model):
mykey = db.StringProperty(db.Key)
storeSpecial = db.ListProperty(item_type=str)
reviews = db.ListProperty(item_type=str)
storeName = db.StringProperty()
#later in the code
qy1 = GqlQuery("SELECT storeName,storeSpecial,reviews FROM store WHERE mykey =:1",dataInput)
records_to_send = []
for i in qy1:
rev =""
for k in i.review:
rev = rev + str(k) + ","
spec = ""
for k2 in i.storeSpecial:
spec = spec + str(k2) + ","
output = {"store name": i.storeName,"specials": spec,"reviews":rev}
records_to_send.append(output)
self.response.out.write(json.dumps(records_to_send))
I'm not really sure what you want, your example is confusing. If you use JSON, why not just keep it as list? Why do you change it to a string?
It seems you want something like this
for store in qy1:
records_to_send.append({'store name': store.storeName, 'specials': store.storeSpecial}, 'reviews': store.reviews})

Categories

Resources