Python Forum

Full Version: enter string into list according to a known rule
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
Hello,
I want to make the following :
today I'm reading canbus data in this form (the data is string type)
Data = d8 59 80 a2 c8 be f4 92
I want to make a function the take the data, put every 2 digits into 1 place in a list
so in the end I will have this :
Data_List = [d8, 59, 80, a2, c8, be, f4, 92]
then I will create a function that will print the data for place 0-7 according to input
Data_List[3] --> 'a2'

the reason in to make an easy list and not to think how to get to item 3 (places 9 and 10)
so insted of writing
Data[9:11] I will wirte Data_List[3]
hope the reason is clear

I mange to to this:
def CutData(FullData, StartByte, length=1):
    Byte_Data  = []
    print(f'full data is {FullData}')
    print(f'size is {len(FullData)}')
    i = 0
    test = ""
    for Char in FullData:
        print(str(i) + " : " + Char )
        if Char  != " ":
            test = test + Char 
            Byte_Data.insert(i, test)
            i += 1
        else:
            test = ""
    print(Byte_Data)
    Byte_Data = Byte_Data[1::2]
    print(Byte_Data)
which retunr this:

full data is d8 59 80 a2 c8 be f4 92
size is 23
0 : d
1 : 8
2 :
2 : 5
3 : 9
4 :
4 : 8
5 : 0
6 :
6 : a
7 : 2
8 :
8 : c
9 : 8
10 :
10 : b
11 : e
12 :
12 : f
13 : 4
14 :
14 : 9
15 : 2
['d', 'd8', '5', '59', '8', '80', 'a', 'a2', 'c', 'c8', 'b', 'be', 'f', 'f4', '9', '92']
['d8', '59', '80', 'a2', 'c8', 'be', 'f4', '92']
I guess this is OK - but is there more "normal" \ pretty way to do this?

Thanks ,
Split the string on space's
data = 'd8 59 80 a2 c8 be f4 92'
data_list = data.split(' ')
print(data_list)
Output:
['d8', '59', '80', 'a2', 'c8', 'be', 'f4', '92']
The provided example could not work because the quoting is missing.

import binascii


from_your_post = "d8 59 80 a2 c8 be f4 92".replace(" ","")

# unhexlify can not handle whitespaces, so I've replaced them with nothing
raw_bytes = binascii.unhexlify(from_your_post)

# iterating over bytes -> you get integers (0-255, one Byte) back
# accessing an index on raw bytes also return an int
# consuming raw_bytes with a list, tuple or other sequence types, will also make integers
# but accessing a range of bytes, will still return raw bytes
# the bytes type in Python is a hybrid.

for value in raw_bytes:
    print(value, type(value))
To keep the values, you can append them to a list or consume the raw_bytes with a list:
integers = list(raw_bytes)
print(integers)
Output:
[216, 89, 128, 162, 200, 190, 244, 146]
(Aug-11-2021, 01:58 PM)Yoriz Wrote: [ -> ]Split the string on space's
data = 'd8 59 80 a2 c8 be f4 92'
data_list = data.split(' ')
print(data_list)
Output:
['d8', '59', '80', 'a2', 'c8', 'be', 'f4', '92']


I guess I did it tha very long and hard way :-)

Thanks!
(Aug-11-2021, 02:06 PM)DeaD_EyE Wrote: [ -> ]The provided example could not work because the quoting is missing.

import binascii


from_your_post = "d8 59 80 a2 c8 be f4 92".replace(" ","")

# unhexlify can not handle whitespaces, so I've replaced them with nothing
raw_bytes = binascii.unhexlify(from_your_post)

# iterating over bytes -> you get integers (0-255, one Byte) back
# accessing an index on raw bytes also return an int
# consuming raw_bytes with a list, tuple or other sequence types, will also make integers
# but accessing a range of bytes, will still return raw bytes
# the bytes type in Python is a hybrid.

for value in raw_bytes:
    print(value, type(value))
To keep the values, you can append them to a list or consume the raw_bytes with a list:
integers = list(raw_bytes)
print(integers)
Output:
[216, 89, 128, 162, 200, 190, 244, 146]


I did somthing else , and now I have the wanted value were I want it
but when I try to convert it from Hex str to int I get error?
['ee', 'ad', 'd0', '76', 'dd', 'ff', '52', '00']
<class 'str'>
Traceback (most recent call last):
  File "Documents/GetVIN.py", line 61, in <module>
    x = int(TestValue, 16)
ValueError: invalid literal for int() with base 16: "['dd']"
"
this is what I have done:
def CutData(FullData, StartByte, length=1):
    StartByte = StartByte - 1
    EndByte = StartByte + length
    Data_Byte = FullData.split(' ')
    print(Data_Byte)  
    Wanted_Data = str(Data_Byte[StartByte:EndByte])
    print(type(Wanted_Data))
    return Wanted_Data

TestValue = (CutData(Data, 5, 1))
                x = int(TestValue, 16)
                print(x)
what is wrong?
I have str in hex and want to make it an int
is the command is wrong?
what am I missing?

Thanks,
from my example in the other thread
spam = bytearray(b'0P\x14}\x04\xf8\xff3')
data = [f"{byte:02x}" for byte in spam]
print(data)
data = [int(f"{byte:02x}", base=16) for byte in spam]
print(data)
data is list of string

Output:
['30', '50', '14', '7d', '04', 'f8', 'ff', '33'] [48, 80, 20, 125, 4, 248, 255, 51]
But if I want to converte only 1 item in list?
for example item on 4 place only?

def CutData(FullData, StartByte, length=1):
    StartByte = StartByte - 1
    EndByte = StartByte + length
    print(f'full data is {FullData}')
    Data_Byte = FullData.split(' ')
    print(f'Full Data_Byte is {Data_Byte}')
    Wanted_Data = str(Data_Byte[StartByte:EndByte])
    print(type(Wanted_Data))
    return Wanted_Data

if PID == "1E491DD0":
                Speed= (CutData(Data, 4, 1))
                print (str(type(Speed)) + "  " + Speed)
I get
full data is e5 a9 5c 7e b2 ff 02 00
Full Data_Byte is ['e5', 'a9', '5c', '7e', 'b2', 'ff', '02', '00']
<class 'str'>
<class 'str'>  ['b2']
when I do the same thing on console , it's working

>>> Test_List = ['12', '34', 'AA', 'F2']
>>> type(Test_List)
<class 'list'>
>>> type(Test_List[2])
<class 'str'>
>>> y = int(Test_List[2], 16)
>>> print(y)
170
also if I take your example - it's working (same class - both of them are strings)

>>> spam = bytearray(b'0P\x14}\x04\xf8\xff3')
>>> data = [f"{byte:02x}" for byte in spam]
>>> print(data)
['30', '50', '14', '7d', '04', 'f8', 'ff', '33']
>>> type(data[2])
<class 'str'>
>>> y = int(data[2], 16)
>>> print(y)
20
Thanks ,
I don't really understand what you want to do. We don't know what Data is in your example (str, bytearay, list. something else?)
spam = bytearray(b'0P\x14}\x04\xf8\xff3')
data = [f"{byte:02x}" for byte in spam]
print(f'Full Data: {data}')
start=0
length = 4
data = [f"{byte:02x}" for byte in spam[start:start + length]]
print(f'Partial data: {data}')
Output:
Full Data: ['30', '50', '14', '7d', '04', 'f8', 'ff', '33'] Partial data: ['30', '50', '14', '7d']
Will this help?
def CutData(FullData, StartByte, length=1):
    StartByte = StartByte - 1
    EndByte = StartByte + length
    print(f'full data is {FullData}' + str(type(FullData)))  
    Data_Byte = FullData.split(' ')
    print(f'Full Data_Byte is {Data_Byte}' + str(type(Data_Byte))
    Wanted_Data = str(Data_Byte[StartByte:EndByte])
    print(type(Wanted_Data))
    return Wanted_Data

 Test= (CutData(Data, 5, 1))
                print (str(type(Test)) + "  " + Test)
                y = str(Test)
                print(y)
full data is 74 a9 60 7e a9 ff 02 00<class 'str'>
Full Data_Byte is ['74', 'a9', '60', '7e', 'a9', 'ff', '02', '00']<class 'list'>
<class 'str'>
<class 'str'>  ['a9']
So, it's str why do you keep working with str, when you can work with original bytearay or list? The conversion to str was on your insistence in order to replicate the str representation of data in str representation of Message.
Looking further in your code, you convert this string to list
and you pass StartByte=5 and length=1. In your code you decrease StartByte by 1. So you want 1 element at index 4 and that is a9. What do you want/expect to get?
Pages: 1 2