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
Related
Based on this answer (among others) it seems like f-strings is [one of] the preferred ways to convert to hexadecimal representation.
While one can specify an explicit target length, up to which to pad with leading zeroes, given a goal of an output with an even number of digits, and inputs with an arbitrary # of bits, I can imagine:
pre-processing to determine the number of bits of the input, to feed an input-specific value in to the fstring, or
post-processing a-la out = "0"+f"{val:x}" if len(f"{val:x}") % 2 else f"{val:02x}" (or even using .zfill())
The latter seems like it might be more efficient than the former - is there a built-in way to do this with fstrings, or a better alternative?
Examples of input + expected output:
[0x]1 -> [0x]01
[0x]22 -> [0x]22
[0x]333 -> [0x]0333
[0x]4444 -> [0x]4444
and so on.
Here's a postprocessing alternative that uses assignment expressions (Python 3.8+):
print((len(hx:=f"{val:x}") % 2) * '0' + hx)
If you still want a one-liner without assignment expressions you have to evaluate your f-string twice:
print((len(f"{val:x}") % 2) * '0' + f"{val:x}")
As a two-liner
hx = f"{val:x}"
print((len(hx) % 2) * '0' + hx)
And one more version:
print(f"{'0'[:len(hex(val))%2]}{val:x}")
I don't think there's anything built in to f-string formatting that will do this. You probably have to figure out what the "natural" width would be then round that up to the next even number.
Something like this:
def hf(n):
width = len(hex(n)) - 2 # account for leading 0x
width += width % 2 # round up
return f'{n:0{width}x}'
print(hf(1))
print(hf(15))
print(hf(16))
print(hf(255))
print(hf(256))
Output:
01
0f
10
ff
0100
You can use a variable in the pad-length part of the f-string. For example:
n = 4
val = 257
print(f"{val:0{n}x}") # 0101
Now, to figure out how many hex characters are in an integer, you just need to find how many bits are in the integer:
hex_count, rem = divmod(max(1, val.bit_length()), 4)
hex_count += (rem > 0)
(max(1, val.bit_length()) handles the case where val == 0, which has a bit length of 0)
So let's get the next even number after hex_count:
pad_length = hex_count + (hex_count % 2)
print(f"{val:0{pad_length}x}") # 0101
I'm not sure if this is any better than simply converting it to a hex string and then figuring out how much padding is needed, but I can't think of a readable way to do this all in an f-string. An unreadable way would be by combining all of the above into a single line, but IMO readable code is better than unreadable one-liners. I don't think there's a way to specify what you want as a simple f-string.
Note that negative numbers are formatted to an even number of digits, plus the - sign.
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'
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
see the list below:
2456905.204109
2456905.204132
2456905.204144
2456905.204155
2456905.204167
2456905.204178
2456905.20419
2456905.204201
2456905.204213
2456905.204225
The list goes on. I want to have the list all lined up so I want a 0 to the left of 2456905.204109.
I am just using x = round(num,6), but is there a way to always have 6 decimals? I haven't found anything other than other ways to round, which result in the same thing.
Use string formatting
>>> '%0.6f' % 2456905.20410897654321
'2456905.204109'
>>> '%0.6f' % 2456905.20419
'2456905.204190'
The number itself will not contain any insignificant digits as mentioned above, but you can alter the formatting when you print it. For instance you could write:
>>> x = round(2456905.20419, 6)
>>> '%0.6f' % x
Which will display as:
'2456905.204190'
Contrast this to just printing x without formatting, which will display as you are seeing right now:
2456905.20419
I need to format a float to the format +-00.00, tried the basic string formatting but can't get the leading + or - sign or two leading 0s if the value is fractional, any pointers?
'%+06.2f' % 1.1123344
+ means always use sign
0 means zero fill to full width.
6 is the total field width including sign and decimal point
.2 means 2 decimals.
f is float
Use '%+06.2f' to set the width and precision appropriately. The equivalent using new-style format strings is '{:+06.2f}'.format(n) (or '{0:+06.2f}' if your version of Python requires the positional component).
Using this should do it
x = 50.4796
a = -50.1246
print " %+2.2f" % (x)
print " %+2.2f" % (a)
The following should print
+50.48
-50.12