How to convert a string to list using python? - python

I am working with RC-522 RFID Reader for my project. I want to use it for paying transportation fee. I am using python and used the code in: https://github.com/mxgxw/MFRC522-python.git
On python script Read.py, Sector 8 was read with the use of this code:
# Check if authenticated
if status == MIFAREReader.MI_OK:
MIFAREReader.MFRC522_Read(8) <---- prints the sector 8
MIFAREReader.MFRC522_StopCrypto1()
else:
print "Authentication error"
The output of this was:
Sector 8 [100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
So that last part(Sector 8 [100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), I convert it to string. I want that to be a list but I can't. Tried to put it on a variable x and use x.split() but the output when I execute print(x) is "None".
x = str(MIFAREReader.MFRC22_READ(8))
x = x.split()
print x #PRINTS ['NONE']
I want it to be like this:
DATA = [100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
so that I can use the sum(DATA) to check for balance, and I can access it using indexes like DATA[0]
Thanks a lot!!

Follow these steps:
Open MFRC522.py >> header file for RFID Reader
vi MFRC522.py
look for function
def MFRC522_Read(self, blockAddr)
add this line return backData at the end of function.
Save it.
In read() program, call it like
DATA=(MIFAREReader.MFRC522_Read(8))
print 'DATA :',DATA
I hope this solves the problem.

You can use .split(",") to specify the delimiter ",".
Something like that:
input_string = "[100, 234, 0, 0, 567, 0, 0, 0, 3, 0, 235, 0, 0, 12, 0, 0]"
listed_string = input_string[1:-1].split(",")
sum = 0
for item in listed_string:
sum += int(item)
print(sum)
prints
1151

In line with Moutch answer, using list comprehension:
input='[100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]'
DATA = [int(item) for item in input[1:-1].split(',')]
print(sum(DATA))
If data string is entire output of Read.Py
input="""Card read UID: 67,149,225,43
Size: 8
Sector 8 [100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]"""
#find index position of 'Sector' text and select from this using slices.
inputn = input[input.index('Sector')+9:]
DATA = [int(item) for item in inputn[1:-1].split(',')]
print(DATA)
print(sum(DATA))

If you have some guarantee about the source and nature of the data in that list (and you know the format will always be the same), Python's eval would work. For example:
original_string = 'Sector 8 [100, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]'
data_start_index = original_string.index('[') # find '['
data_string = original_string[data_start_index:] # extract the list
data = eval(data_string)
print(type(data)) # <class 'list'>
print(sum(data)) # 101
If you don't have these guarantees, you'll have to use the split method as suggested by Moutch, due to the fragility and exploitability of eval - it blindly executes whatever (potentially malicious) code is passed to it.
Edit: Use ast.literal_eval instead of plain old eval for safety guarantees. This still requires that the formatting of the string be consistent (e.g., that it always have square brackets) in order to properly evaluate to a Python list.

Related

Python Binary Number Class: Numpy Array Manipulation Getting "TypeError: 'bool' object is not iterable"

I am trying to create a class called "Binary" and the main idea of it is to take a string representing a fixed width binary number that is 16 bits as it's only parameter and store it as a numpy integer array into it's one instance variable "bit_array".
If the given string is greater than 16 characters or contains anything other than 0's and 1's, it is to raise a RuntimeError. If "string" is less than 16 characters, it is to pad on the leftmost digit of given string onto the start of the numpy array until the resulting array contains exactly 16 digits. The given string defaults to '0' and accepts an empty string, treating an empty string as '0'. The code I have written for init is as follows (in "hw4.py" - the main file for this assignment):
import numpy as np
class Binary:
def __init__(self, string='0'):
if not string:
string = '0'
else:
if len(string) > 16:
raise RuntimeError
else:
for i in string:
if i != '1' and i != '0':
raise RuntimeError
if len(string) == 16:
int_arr = np.array(tuple(string))
self.bit_array = int_arr
else:
int_arr_inc = np.array(tuple(string))
if int_arr_inc[0] == 0:
pad = np.zeros((16 - len(int_arr_inc)), int)
else:
pad = np.ones((16 - len(int_arr_inc)), int)
self.bit_array = np.concatenate((pad, int_arr_inc))
There is also an eq overloaded method intended to compare the bit_array of another "Binary" object in this class (this passes the spec's test case so there shouldn't be any changes required here, just more for being transparent):
def __eq__(self, other):
if str(self.bit_array) == str(other.bit_array):
return True
else:
return False
The spec requires that there is no use of list() or any form of lists at all in the init method. The method is not to return anything and it's only purpose is to build a Binary object that has a bit_array that converts the string parameter into a numpy integer array. The test cases I have to test against calls the following test case (in a test file "hw4_test.py"):
from hw4 import Binary
import unittest, numpy as np
class TestBinary(unittest.TestCase):
def setUp(self):
self.bin_0 = Binary("")
self.bin_1 = Binary("01")
self.bin_2 = Binary("010")
def test_init(self):
self.assertTrue(all(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) == self.bin_0.bit_array))
self.assertTrue(all(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]) == self.bin_1.bit_array))
self.assertTrue(all(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]) == self.bin_2.bit_array))
However, the first test case here fails, giving me :
Traceback (most recent call last):
File "C:\Users\17606\Desktop\ISTA-350\hw4\hw4_test.py", line 30, in test_init
self.assertTrue(all(np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) == self.bin_0.bit_array))
TypeError: 'bool' object is not iterable
I've tried many ways of creating the numpy arrays, such as fromstring (which is deprecated anyways) and trying with a map of the parameter string, to no avail. As the test case code above shows, I am expecting
Binary("")
To result in a Binary object containing a bit_array of a numpy array like
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
But the TypeError above keeps occuring. Any ideas? I am having trouble understanding where I am even iterating over anything that could be a bool type. I am using Python 3.10 on Windows 10 with PyCharm as my IDE.
P.S
This is for a school course and I am not very concerned about conventions or efficiency for this. Just syntax and logic :)
Thanks!

How to use dateparser to detect dates in strings?

I want to use dateparser to detect which cell contains a date. I have a broad range of different date formats: Fr, 21.02.2020 // 20.02.2020 // 21.02 // 21-02-2020 // January, 21 2020 // 21-Jan-2020 // 21/02/20 and I am sure there will still come a couple more in the future. The library dateparser is able to detect all of them pretty well, though it also detects 'PO', 'to','06','16:00' as date or relative date, which I don't want. I tried to check the Documentation and turn the relative date off or to look how to change to only detect "real dates". In the settings they offer different PARSERS and the possibility to only use some of them. These are the default PARSERS and the program runs through all of them:
'timestamp': If the input string starts with 10 digits, optionally followed by additional digits or a period (.), those first 10 digits are interpreted as Unix time.
'relative-time': Parses dates and times expressed in relation to the current date and time (e.g. “1 day ago”, “in 2 weeks”).
'custom-formats': Parses dates that match one of the date formats in the list of the date_formats parameter of dateparser.parse() or DateDataParser.get_date_data.
'absolute-time': Parses dates and times expressed in absolute form (e.g. “May 4th”, “1991-05-17”). It takes into account settings such as DATE_ORDER or PREFER_LOCALE_DATE_ORDER.
'base-formats': Parses dates that match one of the following date formats
I tried to only use one of them with the part settings={'base-formats':True}) in my code, nonetheless it won't work. Furthermore they offer the following snippet to turn of individual PARSERS:
>>> from dateparser.settings import default_parsers
>>> parsers = [parser for parser in default_parsers if parser != 'relative-time']
>>> parse('today', settings={'PARSERS': parsers})
Here pops up the error:
ModuleNotFoundError: No module named 'dateparser.settings'
I tried pip install, won't work.
Link to docu: https://dateparser.readthedocs.io/en/latest/#settings
And here's my code:
import dateparser
inputlist = [[' ','Supplier:',' Company Y', ' ', 'Project:','Carasco', ' '],[' ','21-Jan-2020',' ','Consultant:','James Farewell', ' ', ' '],['PO', ' Service', ' Cost Center', ' Accounting Object', ' deliver at', ' Amount', ' Unit'],['0106776','XYZ', 'Countable',' ', '16:00','6,00','h',],['Fr, 21.02.2020', '20.03.2020', ' ', ' ', ' ', ' ','6/04/20']]
print(inputlist)
outerlist=[]
for row in inputlist:
innerlist = []
for cell in row:
parsecheck = dateparser.parse(cell, languages=['en', 'de'], settings={'base-formats':True})
if parsecheck == None:
innerlist.append(0)
else:
innerlist.append(1)
outerlist.append(innerlist)
print(outerlist)
I currently get:
[0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 1, 1, 1], [1, 1, 0, 0, 0, 0, 1]]
Desired Output:
[0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0,0, 0, 0], [1, 1, 0, 0, 0, 0, 1]]
This is the best I could do:
import dateparser
import locale
inputlist = [[' ','Supplier:',' Company Y', ' ', 'Project:','Carasco', ' '],[' ','21-Jan-2020',' ','Consultant:','James Farewell', ' ', ' '],['PO', ' Service', ' Cost Center', ' Accounting Object', ' deliver at', ' Amount', ' Unit'],['0106776','XYZ', 'Countable',' ', '16:00','6,00','h',],['Fr, 21.02.2020', '20.03.2020', ' ', ' ', ' ', ' ','6/04/20']]
print(inputlist)
customlist = ["%d.%m.%Y", "%d-%b-%Y", "%w/%m/%y", "%a, %d.%m.%Y"]
outerlist=[]
saved = locale.setlocale(locale.LC_ALL)
locale.setlocale(locale.LC_ALL, 'de_de')
for row in inputlist:
innerlist = []
for cell in row:
parsecheck = dateparser.parse(cell, languages=['en', 'de'], settings={'PARSERS':['custom-formats']}, date_formats=customlist)
if parsecheck == None:
innerlist.append(0)
else:
innerlist.append(1)
outerlist.append(innerlist)
locale.setlocale(locale.LC_ALL, saved)
print(outerlist)
The output is:
[[0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0, 1]]
For parsing Fr, 21.02.2020 I changed the locale to Germany and, near the end I go back to your initial locale.
The format was based on documentation of strftime() and strptime() Behavior
Agreed that changing the settings does not work as expected based on the docs. Looking at the code, it doesn't look like you can get date-only objects (though I'm not an expert and may have missed something). If I understand correctly, it should be settings = {'PARSER': 'base-formats'} instead of settings = {'base-formats':True}, but that doesn't solve your problem.
I can only suggest a work around making use of the fact that the hour and minute of the returned datetime object default to 0.
import dateparser
outerlist=[]
for row in inputlist:
innerlist = []
for cell in row:
parsecheck = None
if dateparser.parse(cell, settings={'STRICT_PARSING':True}) != None and dateparser.parse(cell).hour == 0:
parsecheck = dateparser.parse(cell, languages=['en', 'de'], settings={'PARSER':'date_formats'})
if parsecheck == None:
innerlist.append(0)
else:
innerlist.append(1)
outerlist.append(innerlist)
STRICT_PARSING:True means the returned value is None if any ofYEAR, DAY or MONTH are missing, which takes care of 'PO', 'h' and '6,00' returning valid datetime objects. Checking if the hour attribute is zero gets rid of the valid times.
Unfortunately
for cell in row:
parsecheck = dateparser.parse(cell, languages=['en','de'], settings={'STRICT_PARSING':True, 'PARSER':'date_formats'})
if parsecheck != None and parsecheck.hour == 0:
innerlist.append(1)
else:
innerlist.append(0)
doesn't seem to work since it interprets '16:00' as a date
edit - you don't need to import datetime

Lists inside dictionary. How to iterate to get a specific value?

I'm trying to extract a value from a list in a dictionary. Here's a snippet
of the list inside the dict:
u'anomalies_bar_chart': {u'sleepy_client': 0, u'high_wifi_retries': 0, u'high_wifi_latency': 0, u'sta_dns_timeout': 0, u'weak_signal': 0, u'sta_arp_timeout': 0, u'sta_ip_timeout': 0, u'high_tcp_packet_loss': 0, u'poor_stream_eff': 0, u'low_phy_rate': 0, u'high_tcp_latency': 0}, u'tx_tcp_stats': {u'stalls': 0, u'lat_max':
This is what I got so far, but I'm getting a Key Error
for ap in c.get_aps():
for sub in ap['anomalies_bar_chart']
print sub['sleepy_client']
Any help would be greatly appreciated!
Thanks in advance!

How to sort a json file with spark in python?

I have a json file as following and I would like to sort it using rdd. How would I do it?
I tried the following but it does not sort the words :(
rdd = self.sc.textFile(self.dic_path).sortByKey()
{
"biennials": 0,
"tripolitan": 0,
"oblocutor": 0,
"leucosyenite": 0,
"chilitis": 0,
"fabianist": 0,
"diazeutic": 0,
"alible": 0,
"woods": 4601,
"preadjournment": 0,
"spiders": 0,
"fabianism": 0,
}

How to retain values appended to a python list

Please I need help with this code.I want mylist to retain values appended to it next time the function 'no_repeat_rule' is called. I'm pretty new to python. My code is below:
def no_repeat_rule(play_board):
mylist = list()
if seeds_left(play_board) == 2 and sum(play_board[:6])== 1:
mylist.append(play_board)
return mylist
Output of this code (in part) is:
...
[[1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]]
Player 1 chose cup 0
[[0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]]
Player 2 chose cup 6
[[0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]]
...
what I want the function 'no_repeat_rule' to do is to grow mylist each time a player plays. I don't know if this is clear enough to get help?
The simplest thing to do would be to add another parameter in the function defintion, such that it looks like:
def no_repeat_rule(play_board, aList):
Before you call the function, declare a list outside of the function. Set this equal to the result of the function, and pass it as a parameter whenever you call the function. For instance:
x = list()
def no_repeat_rule(play_board, aList):
myList = aList
if seeds_left(play_board) == 2 and sum(play_board[:6])== 1:
myList.append(play_board)
return myList
x = no_repeat_rule(someBoardHere, x)
I believe this should work if I understand what you're asking. If not, please respond and I'll try something else.
what do you need is an object which is associated with the function. It calls attribute. It is very handy in python.
Your code may look like this:
def no_repeat_rule(play_board):
if not hasattr(no_repeat_rule,"mylist"):
no_repeat_rule.mylist = []
if seeds_left(play_board) == 2 and sum(play_board[:6])== 1:
no_repeat_rule.mylist.append(play_board)
return no_repeat_rule.mylist
I couldn't check this code, but it should work for local atributes. BTW it is for python 2.7

Categories