Iterate through JSON from API for first True number? py2.7 - python

I am pretty new to Python, and am more used to JS, so I am a little lost on how to do this.
Basically I have a JSON from an API from Google, and the first result isn't always valid for what I need. But I do only need to the first result that returns true.
I am pretty sure I have the syntax wrong in more than one area, but I need the first imageUrl where [gi]['pagemap'] would be true.
item_len = len(deserialized_output['items'])
for gi in range(item_len):
def loop_tgi():
if deserialized_output['items'][gi]['pagemap'] is True:
imageUrl = deserialized_output['items'][gi]['pagemap']['cse_image'][0]['src']
break
loop_tgi()

You could iterate over items directly, without a use of index
in Python loop leak a variable, so when you break from the loop, gi variable would have what you need (or last value).
To overcome "or last value" we can use else close to check that we went through whole loop with no break
for gi in deserialized_output['items']:
if gi['pagemap'] is True:
break
else:
gi = None # or throw some sort of exception when there is no good elements
if gi: # checking that returned element is good
print(gi) # now we can use that element to do what you want!
imageUrl = gi['pagemap']['cse_image'][0]['src']
I am a bit worried about your gi['pagemap'] is True as later you try to access gi['pagemap']['cse_image']. It means that gi['pagemap'] is not a boolean, but some sort of object.
If this is dict, you could check if gi['pagemap']: that is True if this dict is not empty. but gi['pagemap'] is True would be False if gi['pagemap'] is {'cse_image':...}

Related

How to detect an empty paragraph in python-docx

Given a document containing a paragraph
d = docx.Document()
p = d.add_paragraph()
I expected the following technique to work every time:
if len(p._element) == 0:
# p is empty
OR
if len(p._p) == 0:
# p is empty
(Side question, what's the difference there? It seems that p._p is p._element in every case I've seen in the wild.)
If I add a style to my paragraph, the check no longer works:
>>> p2 = d.add_paragraph(style="Normal")
>>> print(len(p2._element))
1
Explicitly setting text=None doesn't help either, not that I would expect it to.
So how to I check if a paragraph is empty of content (specifically text and images, although more generic is better)?
Update
I messed around a little and found that setting the style apparently adds a single pPr element:
>>> p2._element.getchildren()
[<CT_PPr '<w:pPr>' at 0x7fc9a2b64548>]
The element itself it empty:
>>> len(p2._element.getchildren()[0])
0
But more importantly, it is not a run.
So my test now looks like this:
def isempty(par):
return sum(len(run) for run in par._element.xpath('w:r')) == 0
I don't know enough about the underlying system to have any idea if this is a reasonable solution or not, and what the caveats are.
More Update
Seems like I need to be able to handle a few different cases here:
def isempty(par):
p = par._p
runs = p.xpath('./w:r[./*[not(self::w:rPr)]]')
others = p.xpath('./*[not(self::w:pPr) and not(self::w:r)] and '
'not(contains(local-name(), "bookmark"))')
return len(runs) + len(others) == 0
This skips all w:pPr elements and runs with nothing but w:rPr elements. Any other element, except bookmarks, whether in the paragraph directly or in a run, will make the result non-empty.
The <w:p> element can have any of a large number of children, as you can see from the XML Schema excerpt here: http://python-docx.readthedocs.io/en/latest/dev/analysis/schema/ct_p.html (see the CT_P and EG_PContent definitions).
In particular, it often has a w:pPr child, which is where the style setting goes.
So your test isn't very reliable against false positives (if being empty is considered positive).
I'd be inclined to use paragraph.text == '', which parses through the runs.
A run can be empty (of text), so the mere presence of a run is not proof enough. The actual text is held in a a:t (text) element, which can also be empty. So the .text approach avoids all those low-level complications for you and has the benefit of being part of the API so much, much less likely to change in a future release.

Evaluating if variable in list python

I am using a RFID reader to scan multiple RFID tags. The readings are placed into a list. I am trying to check if a tag is in the reading. Using the 'if in' method is not working for me.
import mercury
import time
reader = mercury.Reader("tmr:///dev/ttyUSB0")
reader.set_region("EU3")
reader.set_read_plan([1], "GEN2")
tag1 = 'E2004005730702602190360B'
tag2 = 'E20040057307026421903619'
while True:
a = reader.read()
print (a)
print(type(a))
if tag1 in a:
print('tag1')
time.sleep(0.2)
break
if tag2 in a:
print('tag2')
time.sleep(0.2)
break
time.sleep(0.2)
My terminal is output is:
['E20040057307026421903619', 'E2004005730702602190360B']
<type 'list'>
So the if conditions is not executed when tag1 or tag2 are in a.
I can't seem to make it enter the if condition. Any advice?
It turns out the below answer doesn't work here, since "reader" is an object other than a file and a is a list already. A better solution for you might be to change your "if in"s to if any(tag1 == tag.epc for tag in a). Printing is misleading in this case since it seems the list is actually filled with objects that print as strings but won't compare equal to strings.
I'm going to leave the earlier answer since it might be helpful to people with similar problems.
=======================================================================
Assuming "reader" is a file, using reader.read() doesn't return a list. It returns a string. You won't get an interpreter error because strings are iterable, but you also won't get the results you expect!
EDIT: Using string1 in string2 will return True iff string1 is a substring of string2. However, it is still important to be careful, because other operations that are valid (like a[0]) will return unexpected results.
Try
import ast
a = ast.literal_eval(reader.read())
That will try to interpret the result of .read() as a list. If that doesn't work for you, look into regular expressions.
Looking at the documentation, it appears that you do not get a list of str, butTagReadData objects.
Try along these lines:
tag1 = b'E2004005730702602190360B'
tag2 = b'E20040057307026421903619'
a = reader.read()
for tag in a:
if tag1 == tag.epc:
print('tag1')
You should propably print the context of list object a ( reader.read() )
It will tell you the content or the purposed object, then understand what is the comparison about (the if statement)

Python-push and pop from list at the same time

I have a list and while I constantly append element to it, I want to check that it isn't empty and get element at the same time. Normally we wait all the elements append to the list and then we get element from list do something. In this case, we lose some time for waiting all elements add to the list. What knowledge do I need to acquire to make this happen (Multiprocessing, multiprocessing.dummy, asynchronous) ,sorry, I am still new for doing this, I think it's better for me to explain to you why I want to achieve this kind of effect,this problem came from a web crawler
import requests
from model import Document
def add_concrete_content(input_list):
"""input_list data structure [{'url': 'xxx', 'title': 'xxx'}...]"""
for e in input_list:
r = requests.get(e['url'])
html = r.content
e['html'] = html
return input_list
def save(input_list):
for e in input_list:
Document.create(**e)
if __name__ == '__main__':
res = add_concrete_content(list)
save(res)
"""this is I normally do, I save data to mysql or whatever database,but
I think the drawback is I have to wait all the html add to dict and then
save to database, what if I have to deal with tons of data? Can I save
the dict with the html first? Can I save some time? A friend of mine
said this is a typical producer consumer problem, probably gonna use
at least two threads and lock, because without lock, data probably
gonna fall into disorder"""
You're being vague. And I think there's a misconception in the way you want things to happen.
You don't need any extra python rock-science to do what you want:
you can check if the list is empty by simply doing: if list_: (where list_ is your list)
you can verify any element by using list_[idx] (where idx is the index of the element). For example, list_[0] will get you the first element of the list, while list_[-1], the last one.
That said, you don't have to wait for all the elements to be added to the list if you need to process them on the go. You might look for something like this:
def push(list_):
count = 0
while True:
list_.append(count)
f()
count += 1
if count == 1000:
break
def f():
print('First element: {}'.format(list_[0]))
print('Last element: {}'.format(list_[-1]))
if __name__ == '__main__':
list_ = []
push(list_)

Boolean not working like it should?

imgfound=False
imgexists=0
img_ext=['.jpg','.jpeg','.png','.gif']
while True:
httpfind=html.find('http',imgexists)
if httpfind==-1:
break
imgexists=httpfind
imgexist=html.find('"',imgexists)
imgurl=html[imgexists:imgexist]
imgexists+=len(imgurl)
for extscan in img_ext:
if not imgurl.find(extscan)==-1:
imgfound=True
break
#print imgfound
if imgfound==False:
continue
print imgurl
I want to find links to images in a html document. But something is not working like it should. Like it prints all links regardless of whether they have a img_ext substring in them. I printed the value in imgfound, and for all the links it is True. Where have I gone wrong?
The expression
not imgurl.find(extscan) == -1
will evaluate to False for every integer, because of operators precedence.
How can you fix it?
Change it to
imgurl.find(extscan) != -1
Or, change it to
not(imgurl.find(extscan) == -1)
Christian's answer is correct, but it's worth noting that this is not good Python style. The preferred form is:
if extscan not in imgurl
Your version looks like a Java-ism.

psychopy keyboard answer breaks down

I am trying to write an Go_nogo Task in Psychopy. Even though I managed to write a script which is working, there are still a few things that make troubles. First, I present pictures of emotional stimuli (im_n, neural; im_a, emotional) and people should only answer by pressing "space" if neutral emotional pictures are presented. When I run the code below everything works well until I don't press any key or the wrong key. So my question is, how do I have to write the code that I don't get kicked out of the run while not answering...? Thanks everybody!
for im in imlist: # Loop for each Image in the List
picShown = bitmap.setImage(im)
bitmap.draw()
win.flip()
rt_clock.reset()
resp = False
while rt_clock.getTime() < timelimit: # timelimit is defined 2 s
if not resp:
resp = event.getKeys(keyList=['space'])
rt = rt_clock.getTime()
if im in im_n: # im_n is an extra list of one kind of images
correctResp = 'space'
if resp[0]==correctResp:
corrFb.draw() # is defined as a "green O"
else:
incorrFb.draw() # is defined as a "red X"
win.flip()
core.wait(ISI)
I get the error message:
if resp[0]==correctResp:
IndexError: list index out of range
My guess is that you get this error message at the if resp[0]==correctResp: line:
IndexError: list index out of range
Is that true? If yes, it is simply because event.getKeys() returns an empty list [] if no responses were collected. And doing [][0] will give you the above error because there's no first element (index zero) just like [1,2,3,4][1000] will give you the same error. Note that even if you press a lot of keys and none of them are in the keyList, getKeys will return an empty list because it ignores everything but the contents of the keyList (unless you set keyList=None, in which case it accepts all keys).
There's a few simple ways out of this. Firstly, you can simply check whether resp is empty and give a "fail" score if it is and only check for correctness if it is not. A more general solution, which would work with many response keys and scoring criteria, is to do if correctResp in resp and then score as a success if yes. This comparison will work with an empty list as well, in which case it always returns False as empty lists per definition can't contain anything.
But in your particular case, you only have one response option so it is even simpler! Since you've "filtered" responses sing the keyList, you KNOW that if resp is [], the subject answered "no-go" and conversely if resp is not [], he/she answered "go". So:
if im in im_n: # im_n is an extra list of one kind of images
if resp: # if subject answered 'go'
corrFb.draw() # is defined as a "green O"
else:
incorrFb.draw() # is defined as a "red X"
Actually, I suspect that you also want to give feedback in trials without neutral images. In that case, define correct as bool(resp) is (im in im_n):
if bool(resp) is (im in im_n): # if answer correspond to trial type
corrFb.draw() # is defined as a "green O"
else:
incorrFb.draw() # is defined as a "red X"

Categories

Resources