0

I am creating a method in Python whereby it will take a number which will form a byte string that will then get sent to the Arduino. However whenever I try, the escape character is always included in the final byte string.

Here is the snippet of the code I am using:

num = 5
my_str = '\\x4' + str(num)
my_str.encode('utf-8')

Result:

b'\\x45'

I tried another method:

num2 = 5
byte1 = b'\\x4'
byte2 = bytes(str(num2), 'ISO-8859-1')
new_byte = byte1 + byte2
new_byte

Result:

b'\\x45'

Trying yet in a different way:

num = 5
u = chr(92) + 'x4' + str(num)
u.encode('ISO-8859-1')

Result:

b'\\x45'

I would like to get the byte string to be b'\x45' without the escape character but not really sure what I have missed. I will appreciate any pointers on how I can achieve this.

2
  • Will num always be a digit between 0 and 9? Could it also be a string representing a hex digit like "a" or "f"? Commented Aug 20, 2017 at 21:18
  • num2 = 5, b = chr(ord('\x40')+num2), hex(ord(b)) -> '0x45'. Commented Aug 20, 2017 at 23:29

2 Answers 2

4

Your problem is that you have already escaped the backslash. It is not recommended to construct a literal using an unknown variable, especially if there's a simpler way, which there is:

def make_into_bytes(n):
    return bytes([64 + n])

print(make_into_bytes(5))

This outputs

b'E'

Note that this isn't a bug, as this is simply the value of 0x45:

>>> b'\x45'
b'E'

The way this function works is basically just doing it by hand. Prepending '4' to a hex string (of length 1) is the same as adding 4 * 16 to it, which is 64. I then construct a bytes object out of this. Note that I assume n is an integer, as in your code. If n should be a digit like 'a', this would be the integer 10.

If you want it to work on hex digits, rather than on integer digits, you would need to change it to this:

def make_into_bytes(n):
    return bytes([64 + int(n, 16)])

print(make_into_bytes('5'))
print(make_into_bytes('a'))

with output

b'E'
b'J'

This quite simply converts the digit from base 16 first.

Sign up to request clarification or add additional context in comments.

3 Comments

Regarding "It is very difficult to construct a literal using an unknown variable" – that's not true. It's very easy, but not the recommended way of solving this problem.
For what it's worth, you can use codecs.decode("\\x45", "unicode_escape") to parse a string containing escapes.
Good point! Thanks, I'll edit my answer. Also, I'm sorry if I sounded blunt earlier. I didn't mean to.
1

You can use the built-in function chr() to convert an integer to the corresponding character:

>>> chr(0x40 + 5)
'E'

Alternatively, if you just one to get the n-th letter of the alphabet, it might be more readable to use str.ascii_uppercase

>>> string.ascii_uppercase[5 - 1]
'E'

Note that the results in this answer are strings in Python 3, not bytes objects. Simply calling .encode() on them will convert them to bytes.

2 Comments

This isn't a bytes object
@IzaakvanDongen I know it isn't, but it's trivial to convert into one. I answered the part of the question the OP struggled with, but I'll point it out explicitly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.