Reputation: 12317
I am trying to talk to a device using python. I have been handed a tuple of bytes which contains the storage information. How can I convert the data into the correct values:
response = (0, 0, 117, 143, 6)
The first 4 values are a 32-bit int telling me how many bytes have been used and the last value is the percentage used.
I can access the tuple as response[0] but cannot see how I can get the first 4 values into the int I require.
Upvotes: 8
Views: 42852
Reputation:
Would,
num = (response[0] << 24) + (response[1] << 16) + (response[2] << 8) + response[3]
meet your needs?
aid
Upvotes: 13
Reputation: 608
This looks like a job for reduce!
What you basically need is to, bit-shift a byte at a time, and then add (addition) the next byte in the sequence.
a = (0, 0, 117, 143, 6)
reduce(lambda x, y: (x<<8) + y, a)
7704326
Upvotes: 2
Reputation:
How about using the map function:
a = (0, 0, 117, 143, 6)
b = []
map(b.append, a)
Also, I don't know if this is you are looking for:
response = (0, 0, 117, 143, 6)
response[0:4]
Upvotes: 0
Reputation: 42692
See Convert Bytes to Floating Point Numbers in Python
You probably want to use the struct module, e.g.
import struct
response = (0, 0, 117, 143, 6)
struct.unpack(">I", ''.join([chr(x) for x in response[:-1]]))
Assuming an unsigned int. There may be a better way to do the conversion to unpack, a list comprehension with join was just the first thing that I came up with.
EDIT: See also ΤΖΩΤΖΙΟΥ's comment on this answer regarding endianness as well.
EDIT #2: If you don't mind using the array module as well, here is an alternate method that obviates the need for a list comprehension. Thanks to @JimB for pointing out that unpack can operate on arrays as well.
import struct
from array import array
response = (0, 0, 117, 143, 6)
bytes = array('B', response[:-1])
struct.unpack('>I', bytes)
Upvotes: 12
Reputation: 109417
You could also make use of the array module
import struct
from array import array
response = (0, 0, 117, 143, 6)
a = array('B', response[:4])
struct.unpack('>I', a)
(30095L,)
Upvotes: 4
Reputation:
OK, You don't specify the endinanness or whether the integer is signed or and it (perhaps) is faster to with the struct module but:
b = (8, 1, 0, 0)
sum(b[i] << (i * 8) for i in range(4))
Upvotes: 4