Evaluating if variable in list python - 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)

Related

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

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':...}

How Do I Start Pulling Apart This Block of JSON Data?

I'd like to make a program that makes offline copies of math questions from Khan Academy. I have a huge 21.6MB text file that contains data on all of their exercises, but I have no idea how to start analyzing it, much less start pulling the questions from it.
Here is a pastebin containing a sample of the JSON data. If you want to see all of it, you can find it here. Warning for long load time.
I've never used JSON before, but I wrote up a quick Python script to try to load up individual "sub-blocks" (or equivalent, correct term) of data.
import sys
import json
exercises = open("exercises.txt", "r+b")
byte = 0
frontbracket = 0
backbracket = 0
while byte < 1000: #while byte < character we want to read up to
#keep at 1000 for testing purposes
char = exercises.read(1)
sys.stdout.write(char)
#Here we decide what to do based on what char we have
if str(char) == "{":
frontbracket = byte
while True:
char = exercises.read(1)
if str(char)=="}":
backbracket=byte
break
exercises.seek(frontbracket)
block = exercises.read(backbracket-frontbracket)
print "Block is " + str(backbracket-frontbracket) + " bytes long"
jsonblock = json.loads(block)
sys.stdout.write(block)
print jsonblock["translated_display_name"]
print "\nENDBLOCK\n"
byte = byte + 1
Ok, the repeated pattern appears to be this: http://pastebin.com/4nSnLEFZ
To get an idea of the structure of the response, you can use JSONlint to copy/paste portions of your string and 'validate'. Even if the portion you copied is not valid, it will still format it into something you can actually read.
First I have used requests library to pull the JSON for you. It's a super-simple library when you're dealing with things like this. The API is slow to respond because it seems you're pulling everything, but it should work fine.
Once you get a response from the API, you can convert that directly to python objects using .json(). What you have is essentially a mixture of nested lists and dictionaries that you can iterate through and pull specific details. In my example below, my_list2 has to use a try/except structure because it would seem that some of the entries do not have two items in the list under translated_problem_types. In that case, it will just put 'None' instead. You might have to use trial and error for such things.
Finally, since you haven't used JSON before, it's also worth noting that it can behave like a dictionary itself; you are not guaranteed the order in which you receive details. However, in this case, it seems the outermost structure is a list, so in theory it's possible that there is a consistent order but don't rely on it - we don't know how the list is constructed.
import requests
api_call = requests.get('https://www.khanacademy.org/api/v1/exercises')
json_response = api_call.json()
# Assume we first want to list "author name" with "author key"
# This should loop through the repeated pattern in the pastebin
# access items as a dictionary
my_list1 = []
for item in json_response:
my_list1.append([item['author_name'], item['author_key']])
print my_list1[0:5]
# Now let's assume we want the 'sha' of the SECOND entry in translated_problem_types
# to also be listed with author name
my_list2 = []
for item in json_response:
try:
the_second_entry = item['translated_problem_types'][0]['items'][1]['sha']
except IndexError:
the_second_entry = 'None'
my_list2.append([item['author_name'], item['author_key'], the_second_entry])
print my_list2[0:5]

Why is find_withtag wont work in python

This is part of my code, the id of image wont print even I use the withtag function. I think the function canvas.delete won't work is also the same problem, it seem the tag is inserted as "123","456". However, the tag I expected to use and get is 123 instead of '123'. And I guess it's the main problem I can't get the id I want with the findtag function.
CurrentImage=Note[NoteIndexLocal]
Temp=canvas.create_image(XShow,YShow,image=CurrentImage,tag=123)
print canvas.find_withtag(123) #This Wont Work,printed()
canvas.delete(123) #This Wont Work
print canvas.gettags(Temp) #printed '123'
From: http://effbot.org/tkinterbook/canvas.htm
Tags are symbolic names attached to items. Tags are ordinary strings,
and they can contain anything except whitespace (as long as they don’t
look like item handles).
Use str(123) instead of 123
EDIT: correct answer is in text from doc "as long as they don’t look like item handles". Number 123 looks like item handle (print Temp to see how it looks like) so it doesn't work. Use text like "a123" and it will work.

Python: If dict keys in line

Found this great answer on how to check if a list of strings are within a line
How to check if a line has one of the strings in a list?
But trying to do a similar thing with keys in a dict does not seem to do the job for me:
import urllib2
url_info = urllib2.urlopen('http://rss.timegenie.com/forex.xml')
currencies = {"DKK": [], "SEK": []}
print currencies.keys()
testCounter = 0
for line in url_info:
if any(countryCode in line for countryCode in currencies.keys()):
testCounter += 1
if "DKK" in line or "SEK" in line:
print line
print "testCounter is %i and should be 2 - if not debug the code" % (testCounter)
The output:
['SEK', 'DKK']
<code>DKK</code>
<code>SEK</code>
testCounter is 377 and should be 2 - if not debug the code
Think that perhaps my problem is because that .keys() gives me an array rather than a list.. But haven't figured out how to convert it..
change:
any(countryCode in line for countryCode in currencies.keys())
to:
any([countryCode in line for countryCode in currencies.keys()])
Your original code uses a generator expression whereas (I think) your intention is a list comprehension.
see: Generator Expressions vs. List Comprehension
UPDATE:
I found that using an ipython interpreter with pylab imported I got the same results as you did (377 counts versus the anticipated 2). I realized the issue was that 'any' was from the numpy package which is meant to work on an array.
Next, I loaded an ipython interpreter without pylab such that 'any' was from builtin. In this case your original code works.
So if your using an ipython interpreter type:
help(any)
and make sure it is from the builtin module. If so your original code should work fine.
This is not a very good way to examine an xml file.
It's slow. You are making potentially N*M substring searches where N is the number of lines and M is the number of keys.
XML is not a line-oriented text format. Your substring searches could find attribute names or element names too, which is probably not what you want. And if the XML file happens to put all its elements on one line with no whitespace (common for machine-generated and -processed XML) you will get fewer matches than you expect.
If you have line-oriented text input, I suggest you construct a regex from your list of keys:
import re
linetester = re.compile('|'.join(re.escape(key) for key in currencies))
for match in linetester.finditer(entire_text):
print match.group(0)
#or if entire_text is too long and you want to consume iteratively:
for line in entire_text:
for match in linetester.find(line):
print match.group(0)
However, since you have XML, you should use an actual XML processor:
import xml.etree.cElementTree as ET
for elem in forex.findall('data/code'):
if elem.text in currencies:
print elem.text
If you are only interested in what codes are present and don't care about the particular entry you can use set intersection:
codes = frozenset(e.text for e in forex.findall('data/code'))
print codes & frozenset(currencies)

associative list python

i am parsing some html form with Beautiful soup. Basically i´ve around 60 input fields mostly radio buttons and checkboxes. So far this works with the following code:
from BeautifulSoup import BeautifulSoup
x = open('myfile.html','r').read()
out = open('outfile.csv','w')
soup = BeautifulSoup(x)
values = soup.findAll('input',checked="checked")
# echoes some output like ('name',1) and ('value',4)
for cell in values:
# the following line is my problem!
statement = cell.attrs[0][1] + ';' + cell.attrs[1][1] + ';\r'
out.write(statement)
out.close()
x.close()
As indicating in the code my problem ist where the attributes are selected, because the HTML template is ugly, mixing up the sequence of arguments that belong to a input field. I am interested in name="somenumber" value="someothernumber" . Unfortunately my attrs[1] approach does not work, since name and value do not occur in the same sequence in my html.
Is there any way to access the resulting BeautifulSoup list associatively?
Thx in advance for any suggestions!
My suggestion is to make values a dict. If soup.findAll returns a list of tuples as you seem to imply, then it's as simple as:
values = dict(soup.findAll('input',checked="checked"))
After that you can simply refer to the values by their attribute name, like what Peter said.
Of course, if soup.findAll doesn't return a list of tuples as you've implied, or if your problem is that the tuples themselves are being returned in some weird way (such that instead of ('name', 1) it would be (1, 'name')), then it could be a bit more complicated.
On the other hand, if soup.findAll returns one of a certain set of data types (dict or list of dicts, namedtuple or list of namedtuples), then you'll actually be better off because you won't have to do any conversion in the first place.
...Yeah, after checking the BeautifulSoup documentation, it seems that findAll returns an object that can be treated like a list of dicts, so you can just do as Peter says.
http://www.crummy.com/software/BeautifulSoup/documentation.html#The%20attributes%20of%20Tags
Oh yeah, if you want to enumerate through the attributes, just do something like this:
for cell in values:
for attribute in cell:
out.write(attribute + ';' + str(cell[attribute]) + ';\r')
I'm fairly sure you can use the attribute name like a key for a hash:
print cell['name']

Categories

Resources