How to get range of bits from byte in python? [duplicate] - python

I'm trying to convert an integer to binary using the bin() function in Python. However, it always removes the leading zeros, which I actually need, such that the result is always 8-bit:
Example:
bin(1) -> 0b1
# What I would like:
bin(1) -> 0b00000001
Is there a way of doing this?

Use the format() function:
>>> format(14, '#010b')
'0b00001110'
The format() function simply formats the input following the Format Specification mini language. The # makes the format include the 0b prefix, and the 010 size formats the output to fit in 10 characters width, with 0 padding; 2 characters for the 0b prefix, the other 8 for the binary digits.
This is the most compact and direct option.
If you are putting the result in a larger string, use an formatted string literal (3.6+) or use str.format() and put the second argument for the format() function after the colon of the placeholder {:..}:
>>> value = 14
>>> f'The produced output, in binary, is: {value:#010b}'
'The produced output, in binary, is: 0b00001110'
>>> 'The produced output, in binary, is: {:#010b}'.format(value)
'The produced output, in binary, is: 0b00001110'
As it happens, even for just formatting a single value (so without putting the result in a larger string), using a formatted string literal is faster than using format():
>>> import timeit
>>> timeit.timeit("f_(v, '#010b')", "v = 14; f_ = format") # use a local for performance
0.40298633499332936
>>> timeit.timeit("f'{v:#010b}'", "v = 14")
0.2850222919951193
But I'd use that only if performance in a tight loop matters, as format(...) communicates the intent better.
If you did not want the 0b prefix, simply drop the # and adjust the length of the field:
>>> format(14, '08b')
'00001110'

>>> '{:08b}'.format(1)
'00000001'
See: Format Specification Mini-Language
Note for Python 2.6 or older, you cannot omit the positional argument identifier before :, so use
>>> '{0:08b}'.format(1)
'00000001'

I am using
bin(1)[2:].zfill(8)
will print
'00000001'

When using Python >= 3.6, you can use f-strings with string formatting:
>>> var = 23
>>> f"{var:#010b}"
'0b00010111'
Explanation:
var the variable to format
: everything after this is the format specifier
# use the alternative form (adds the 0b prefix)
0 pad with zeros
10 pad to a total length off 10 (this includes the 2 chars for 0b)
b use binary representation for the number

You can use the string formatting mini language (Thanks to #Martijn Pieters for the suggestion) idea:
def binary(num, length=8):
return format(num, '#0{}b'.format(length + 2))
Demo:
print(binary(1))
Output:
'0b00000001'

I like python f-string formatting for a little more complex things like using a parameter in format:
>>> x = 5
>>> n = 8
>>> print(f"{x:0{n}b}")
00000101
Here I print variable x with following formatting: I want it to be left-filled with 0 to have length = n, in b (binary) format. See Format Specification Mini-Language from previous answers for more.

Sometimes you just want a simple one liner:
binary = ''.join(['{0:08b}'.format(ord(x)) for x in input])
Python 3

You can use something like this
("{:0%db}"%length).format(num)

You can use zfill:
print str(1).zfill(2)
print str(10).zfill(2)
print str(100).zfill(2)
prints:
01
10
100
I like this solution, as it helps not only when outputting the number, but when you need to assign it to a variable...
e.g. -
x = str(datetime.date.today().month).zfill(2) will return x as '02' for the month of feb.

You can use string.rjust method:
string.rjust(length, fillchar)
fillchar is optional
and for your Question you can write like this
'0b'+ '1'.rjust(8,'0)
so it will be '0b00000001'

Related

Formatting a float number without trailing zeros

When I do a simple division in Python 3, such as 123000/1000, I get 123.0, or 4/2 I get 2.0. How do I get rid of the trailing zero in Python 3's division?
EDIT:
I don't want just simple integer division. For ex, 1234/1000 should give 1.234.
To be clear, this question is about formatting the output, not internal representation.
Thanks all for your help! The answer came from #vaultah:
>>> f'{2.1:g}'
'2.1'
>>> f'{2.0:g}'
'2'
So just use regular division such as 4/2 and then format the string.
From the docs for 'g': https://docs.python.org/2/library/string.html#format-specification-mini-language
"insignificant trailing zeros are removed from the significand, and the decimal point is also removed if there are no remaining digits following it."
You could use something like this:
def remove_trailing_zeros(x):
return str(x).rstrip('0').rstrip('.')
remove_trailing_zeros(1.23) # '1.23'
remove_trailing_zeros(4.0) # '4
Normally, you would use standard string formatting options like '%2.1f' % number or any of the other many ways to format a string. However, you would then have to specify the amount of digits you want to display but in this case the number of trailing zeros to return is variable. The '%g' format specifier does not have this problem, but uses scientific notation and I don't know if that is what the OP wants.
The above solution converts the number to a "nicely printable string representation" (str(x)), and then removes trailing zeros (.rstrip('0')) and if necessary the remaining trailing period (.rstrip('.')) (to avoid "1." as a result) using standard string methods.
It's "correct" behaviour to have "floats" as a result, and .0 part simply indicates this fact. I think that what matter to you is "representation" of the result in the string. So you should not change actual result and only change the way it's "displayed". Use formatting mini language:
>>> for val in (123000/1000, 4/2, 1234/1000): print(f"{val:g}") # Use "General format" to represent floats
...
123
2
1.234
Mod is an O(1) operation which should add almost no overhead to your actual program. You could make it into a one liner also
x = a//b if not a % b else a/b
If you need to do this kind of thing a lot, make it into a function
def func(a, b):
return a//b if not a % b else a/b
func(10, 2) # out = 5
func(10, 3) # out = 3.333333333
func(1200, 100) # out = 12
func(1234, 1000) # out = 1.234
This works well for me. No scientific notation format for big numbers.
def no_trailing_zero(value: float) -> Union[float, int]:
return int(value) if value % 1 == 0 else float(str(value))
>>> no_trailing_zero(50)
50
>>> no_trailing_zero(50.11)
50.11
>>> no_trailing_zero(50.1100)
50.11
>>> no_trailing_zero(50.0)
50
>>> no_trailing_zero(500000000.010)
500000000.01
>>>
If you can guarantee that you get just a trailing zero, casting to int gets rid of it:
>>> 4/2
2.0
>>> int(4/2)
2
# // => used for integer output
# / => used for double output
x = 100/35 # => 2.857142857142857
y = 100//35 # => 2
z = 100.//35 # => 2.0 # floating-point result if divisor or dividend real

How to display last 2 digits from a number in Python

I am trying to take air pressure readings and plot them with their last 2 digits showing. However, when I use modulo:
--> x = 1004
--> x % 100
--> 4
This just generates 4.
How can I display this to show 04 instead of 4?
Thanks!
Try the following:
str(x%100).zfill(2)
If you need it as an int or a float, I don't think this is possible. If it's only for display purposes, convert it to a string and take the last 2 characters:
x = 1004
>>> str(x)[-2:]
'04'
If you just print out a number, it prints it out in its default format. For the number 2, that's obviously going to be 2, not 02.
If you want to specify a custom format, you need to use some form of string formatting. Python has a few ways to do it.
Format Strings
The same Format String Syntax is used by the format function, the str.format method, Formatter subclasses, and (with slight differences that aren't relevant here) f-string literals.
You can specify a width of 2, plus an align of = (meaning numeric alignment—padding is placed after any + or -) and a fill of 0. But there's also a special shortcut, where placing a 0 right before the width means numeric-aligned zero-fill. So:
>>> f"{x % 100:02}"
'02'
>>> format(x % 100, '02')
'02'
>>> '{:02}'.format(x % 100)
'02'
printf-style String Formatting
Python has an older, but still sometimes useful, way to do formatting,1 which more closely matches that of C and similar languages, calling printf-style or %-formatting.
You specify a width of 2, and a flag of 0, which indicates numeric zero-padding, together with a type of d to specify that you want to format the number as a signed integer decimal:
>>> "%02d" % (x % 100,)
'02'
While %-formatting isn't as flexible and powerful as format strings, it can sometimes be simpler to understand (especially if you're used to C or another language), is often faster, and works with bytes as well as str.
Manual string operations
Finally, you can always convert the number to a string and then use string methods on it. For example, you can use the zfill method to zero-fill a string:
>>> str(x % 100).zfill(2)
'02'
… or you can use the rjust method to right-justify it with '0' as a fill character:
>>> str(x % 100).rjust(2, '0')
'02'
In fact, instead of calculating the remainder, you could just convert the whole thing to a string, truncate it, then zero-fill:
>>> str(x)[-2:].zfill(2)
… although this probably won't be what you want is x is, say, -123 (you'll get 23 instead of 77).
1. In fact, it provides two older solutions, the other being template strings, but these aren't useful as often.
The shortest way to do this is '%02d' % (x % 100)
x = 1004
x = x % 100
str(x)
y = len(x)
if y == 0:
end
elif y == 2:
print (x)
elif y == 1:
print ('0'x)
else:
x = str(x)[-2:]
print (x)
In this, I've converted it into a string & calculated the length of the value as 'y'. Using a basic [if elif else] structure I have returned the values in your format, but as strings.
It is unclear what you wanted to use these values for because if you want them to represent figures you will probably need to edit the settings of whatever output application you are using. An alternative solution would be to use the value for 'x' as being different to the string so that the number value can still be used regardless of the way it is displayed when printing. wink, wink.
You could use string formatting too.
ans = 1004 % 100
format(ans, '03d')
More information about String formatting can be found here: https://pyformat.info/
No modulo, no zfill.
"{:02d}".format(12345)[-2:]
#> 45
"{:02d}".format(0)[-2:]
#> 00
"{:02d}".format(-9876)[-2:]
#> 76
"{:02d}".format(-1)[-2:]
#> -1
Your first step to use the modulus operator to find the two-least significant digits is correct.
Then you'll want to use a format string to pad your result when printing it. See: Python format Integer into fixed length strings

xor with leading zero issue in python

I want to xor two hex-format strings in python, like '45' and '4e'. But how do I keep the leading zero if the result is in [0x00, 0x0f]?
hex(int('45', 16) ^ int('4e', 16))
gives '0xb', while I'm expecting '0x0b'.
Thanks in advance.
The easiest method is to use str.format():
>>> '0x{:02x}'.format(0xb)
'0x0b'
For a relatively small number of values (like 0x00-0xff), one practical as well as very efficient method to convert the result into hexadecimal string the way you wish is to build and use a look-up table. The '0x%02x' % vexpression employed in building the table would also be a simple and fairly concise way of converting a single value just once.
>>> HEXDEC = ['0x%02x' % v for v in (x+y for x in range(16) for y in range(16))]
>>> HEXDEC[int('45', 16) ^ int('4e', 16)]
'0x0b'
>>>
The problem here is your expectations from the function hex.
hex() only produces a string presentation for output.
Proof:
>>> hex(2)+hex(15)
'0x20xf'
Which is utter nonsense of course since the string value of hex(2) and the string value of hex(15) are just being appended together.
The solution is to do your arithmetic clear though to the end THEN select how you wish to present the result.
The result of your calculation is 11:
>>> int('45', 16) ^ int('4e', 16)
11
Then format it.
Old way:
>>> '0x%0.2x' % 11
'0x0b'
Newer way:
>>> '0x'+format(11,'02x')
'0x0b'
Or:
>>> '0x{:02x}'.format(11)
'0x0b'

Add zeros to a float after the decimal point in Python

I am reading in data from a file, modify it and write it to another file. The new file will be read by another program and therefore it is crucial to carry over the exact formatting
for example, one of the numbers on my input file is:
1.000000
my script applies some math to the columns and should return
2.000000
But what is currently returned is
2.0
How would I write a float for example my_float = 2.0, as my_float = 2.00000 to a file?
Format it to 6 decimal places:
format(value, '.6f')
Demo:
>>> format(2.0, '.6f')
'2.000000'
The format() function turns values to strings following the formatting instructions given.
From Python 3.6 it's also possible to do f-string formatting. This looks like:
f"{value:.6f}"
Example:
> print(f"{2.0:.6f}")
'2.000000'
I've tried n ways but nothing worked that way I was wanting in, at last, this worked for me.
foo = 56
print (format(foo, '.1f'))
print (format(foo, '.2f'))
print (format(foo, '.3f'))
print (format(foo, '.5f'))
output:
56.0
56.00
56.000
56.00000
Meaning that the 2nd argument of format takes the decimal places you'd have to go up to. Keep in mind that format returns string.
I've had problems with using variables in f strings. When all else fails, read the manual :)
"A consequence of sharing the same syntax as regular string literals is that characters in the replacement fields must not conflict with the quoting used in the outer formatted string literal."
https://docs.python.org/3/reference/lexical_analysis.html#f-strings
Case in point:
my_number = 90000
zeros = '.2f'
my_string = f"{my_number:,{zeros}}"
print (my_string)
90,000.00
my_string = f'{my_number:,{zeros}}'
will not work, because of the single quotes.
Quotes containing the f string and the string
variable used in the f string should be
different.
If using single quotes for the string variable,
use double quotes for the f module and vice versa.
An answer using the format() command is above, but you may want to look into the Decimal standard library object if you're working with floats that need to represent an exact value. You can set the precision and rounding in its context class, but by default it will retain the number of zeros you place into it:
>>> import decimal
>>> x = decimal.Decimal('2.0000')
>>> x
Decimal('2.0000')
>>> print x
2.0000
>>> print "{0} is a great number.".format(x)
2.0000 is a great number.

How do I convert a string of bits to a hex string in Python?

I have a bit-string of 32 characters that I need to represent as hexadecimal in Python. For example, the string "10000011101000011010100010010111" needs to also be output as "83A1A897".
Any suggestions on how to best go about this in Python?
To format to hexadecimal you can use the hex function:
>>> hex(int('10000011101000011010100010010111', 2))
0x83a1a897
Or to get it in exactly the format you requested:
>>> '%08X' % int('10000011101000011010100010010111', 2)
83A1A897
>>> binary = '10010111'
>>> int(binary,2)
151
>>> hex(int(binary,2))
'0x97'
I hope this helps!
You can do this very easy with build in functions.
The first thing you want to do is convert your binary to an integer:
>> int("1010",2)
10
The second step then would be to represent this as hex:
>> "%04X" % int("1010",2)
'000A'
in case you don't want any predefined length of the hex string then just use:
>> "%X" % int("1010",2)
'A'
>> "0x%X" % int("1010",2)
'0xA'
To read in a number in any base use the builtin int function with the optional second parameter specifying the base (in this case 2).
To convert a number to a string of its hexadecimal form just use the hex function.
>>> number=int("10000011101000011010100010010111",2)
>>> print hex(number)
0x83a1a897L
Well we could string format just like Mark Byers said.Or in other way we could string format in another method like given below:
>>> print('{0:x}'.format(0b10000011101000011010100010010111))
83a1a897
To make the alphabets between the hex in upper case try this:
>>> print('{0:X}'.format(0b10000011101000011010100010010111))
83A1A897
Hope this is helpful.

Categories