Numeric type conversions

J

John Dann

I'm new to Python and can't readily find the appropriate function for
the following situation:

I'm reading in a byte stream from a serial port (which I've got
working OK with pyserial) and which contains numeric data in a packed
binary format. Much of the data content occurs as integers encoded as
2 consecutive bytes, ie a 2-byte integer.

I'm guess that there should be a function available whereby I can say
something like:

My2ByteInt = ConvertToInt(ByteStream[12:13])

to take a random example of the 2 bytes occurring at positions 12 and
13 in the byte stream.

Can anyone point me in the right direction towards a suitable function
please?

NB I don't know without further checking exactly how the bytes are
encoded, but I'm just transcribing some code across from a Windows
VB.Net program and these same bytes could be read straight into a
standard 2-byte signed short int, so I can be confident that it's a
fairly standard Windows-compatible encoding.
 
D

Diez B. Roggisch

John said:
I'm new to Python and can't readily find the appropriate function for
the following situation:

I'm reading in a byte stream from a serial port (which I've got
working OK with pyserial) and which contains numeric data in a packed
binary format. Much of the data content occurs as integers encoded as
2 consecutive bytes, ie a 2-byte integer.

I'm guess that there should be a function available whereby I can say
something like:

My2ByteInt = ConvertToInt(ByteStream[12:13])

to take a random example of the 2 bytes occurring at positions 12 and
13 in the byte stream.

Can anyone point me in the right direction towards a suitable function
please?

see the module struct in the standard-lib.

Diez
 
G

Gerhard Häring

John said:
I'm new to Python and can't readily find the appropriate function for
the following situation:

I'm reading in a byte stream from a serial port (which I've got
working OK with pyserial) and which contains numeric data in a packed
binary format. Much of the data content occurs as integers encoded as
2 consecutive bytes, ie a 2-byte integer. [...]

Use the unpack() function from the struct module.

-- Gerhard
 
J

John Machin

I'm new to Python and can't readily find the appropriate function for
the following situation:

I'm reading in a byte stream from a serial port (which I've got
working OK with pyserial) and which contains numeric data in a packed
binary format. Much of the data content occurs as integers encoded as
2 consecutive bytes, ie a 2-byte integer.

I'm guess that there should be a function available whereby I can say
something like:

My2ByteInt = ConvertToInt(ByteStream[12:13])

to take a random example of the 2 bytes occurring at positions 12 and
13 in the byte stream.

Can anyone point me in the right direction towards a suitable function
please?

NB I don't know without further checking exactly how the bytes are
encoded, but I'm just transcribing some code across from a Windows
VB.Net program and these same bytes could be read straight into a
standard 2-byte signed short int, so I can be confident that it's a
fairly standard Windows-compatible encoding.

You need the unpack function of the struct module. Supposing you have
a four-byte string containing two such short ints, first + 1 then -1
then this will work:

In the format string, '<' means little-endian (almost universal on PCs
running Windows), and 'h' means a signed 'half-word'. See the struct
manual section for more options.

You can write a function called convert_to_int (take a hint on naming
conventions) and use it a slice at a time, or you can use
struct.unpack to grab a whole record at once. Here's a real live
example of that:

(
f.height, option_flags, f.colour_index, f.weight,
f.escapement_type, f.underline_type, f.family,
f.character_set,
) = unpack('<HHHHHBBB', data[0:13])

HTH,
John
 
M

MRAB

I'm new to Python and can't readily find the appropriate function for
the following situation:

I'm reading in a byte stream from a serial port (which I've got
working OK with pyserial) and which contains numeric data in a packed
binary format. Much of the data content occurs as integers encoded as
2 consecutive bytes, ie a 2-byte integer.

I'm guess that there should be a function available whereby I can say
something like:

My2ByteInt = ConvertToInt(ByteStream[12:13])

to take a random example of the 2 bytes occurring at positions 12 and
13 in the byte stream.
[snip]
Please note that in slicing the start position is included and the end
position is excluded, so that should be ByteStream[12:14].
 
J

John Dann

[snip]
Please note that in slicing the start position is included and the end
position is excluded, so that should be ByteStream[12:14].

Yes, I just tripped over that, in fact, hence the error in my original
post. I suppose there must be some logic in including the start
position but excluding the end position, though it does escape me for
now. I can understand making a range inclusive or exclusive but not a
mixture of the two. Suppose it's just something you have to get used
to with Python and, no doubt, much commented on in the past.

JGD
 
P

Peter Otten

John said:
[snip]
Please note that in slicing the start position is included and the end
position is excluded, so that should be ByteStream[12:14].

Yes, I just tripped over that, in fact, hence the error in my original
post. I suppose there must be some logic in including the start
position but excluding the end position, though it does escape me for
now. I can understand making a range inclusive or exclusive but not a
mixture of the two.

http://www.cs.utexas.edu/users/EWD/ewd08xx/EWD831.PDF

Peter
 
L

Lie

[snip]
Please note that in slicing the start position is included and the end
position is excluded, so that should be ByteStream[12:14].

Yes, I just tripped over that, in fact, hence the error in my original
post. I suppose there must be some logic in including the start
position but excluding the end position, though it does escape me for
now. I can understand making a range inclusive or exclusive but not a
mixture of the two. Suppose it's just something you have to get used
to with Python and, no doubt, much commented on in the past.

JGD

There is actually a logic to that. It's explained in the help/tutorial
file, that you should think about the index as a cursor, the index
itself doesn't point to the item itself, but to the interval between
the item.

(read this on a monospace font, or it'll look screwed up)
0 1 2 3 4 5
+-------------------+
| A | B | C | D | E |
+-------------------+
-5 -4 -3 -2 -1 0

So to get BCD, you say [1:4]
 
H

Hrvoje Niksic

John Dann said:
I suppose there must be some logic in including the start position
but excluding the end position, though it does escape me for now. I
can understand making a range inclusive or exclusive but not a
mixture of the two. Suppose it's just something you have to get used
to with Python and, no doubt, much commented on in the past.

Half-open ranges are not specific to Python: for example, they're used
in Java (String.substring), Lisp (start and stop arguments to sequence
functions), and C++ (STL algorithms accept begin and end iterators
that generalize from pointers to the beginning and one-past-the-end of
an array).

Ranges so expressed have several nice properties. The size of the
range is expressed simply as b-a, you don't need to remember to add 1.
Empty range is easily expressed as [a, a>, rather than the much less
intuitive [a, a-1] for all-inclusive ranges. Consecutive ranges are
easily concatenated without missing or duplicating an element, so
[a, b> + [b, c> is exactly equivalent to [a, c>.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,677
Members
48,796
Latest member
Greg L.

Latest Threads

Top