Fixed digits after decimal with f-strings - python

Is there an easy way with Python f-strings to fix the number of digits after the decimal point? (Specifically f-strings, not other string formatting options like .format or %)
For example, let's say I want to display 2 digits after the decimal place.
How do I do that? Let's say that
a = 10.1234

Include the type specifier in your format expression:
>>> a = 10.1234
>>> f'{a:.2f}'
'10.12'

When it comes to float numbers, you can use format specifiers:
f'{value:{width}.{precision}}'
where:
value is any expression that evaluates to a number
width specifies the number of characters used in total to display, but if value needs more space than the width specifies then the additional space is used.
precision indicates the number of characters used after the decimal point
What you are missing is the type specifier for your decimal value. In this link, you an find the available presentation types for floating point and decimal.
Here you have some examples, using the f (Fixed point) presentation type:
# notice that it adds spaces to reach the number of characters specified by width
In [1]: f'{1 + 3 * 1.5:10.3f}'
Out[1]: ' 5.500'
# notice that it uses more characters than the ones specified in width
In [2]: f'{3000 + 3 ** (1 / 2):2.1f}'
Out[2]: '3001.7'
In [3]: f'{1.2345 + 4 ** (1 / 2):9.6f}'
Out[3]: ' 3.234500'
# omitting width but providing precision will use the required characters to display the number with the the specified decimal places
In [4]: f'{1.2345 + 3 * 2:.3f}'
Out[4]: '7.234'
# not specifying the format will display the number with as many digits as Python calculates
In [5]: f'{1.2345 + 3 * 0.5}'
Out[5]: '2.7344999999999997'

Adding to Robᵩ's answer: in case you want to print rather large numbers, using thousand separators can be a great help (note the comma).
>>> f'{a*1000:,.2f}'
'10,123.40'
And in case you want to pad/use a fixed width, the width goes before the comma:
>>> f'{a*1000:20,.2f}'
' 10,123.40'

Adding to Rob's answer, you can use format specifiers with f strings (more here).
You can control the number of decimals:
pi = 3.141592653589793238462643383279
print(f'The first 6 decimals of pi are {pi:.6f}.')
The first 6 decimals of pi are 3.141593.
You can convert to percentage:
grade = 29/45
print(f'My grade rounded to 3 decimals is {grade:.3%}.')
My grade rounded to 3 decimals is 64.444%.
You can do other things like print constant length:
from random import randint
for i in range(5):
print(f'My money is {randint(0, 150):>3}$')
My money is 126$
My money is 7$
My money is 136$
My money is 15$
My money is 88$
Or even print with a comma thousand separator:
print(f'I am worth {10000000000:,}$')
I am worth 10,000,000,000$

Consider:
>>> number1 = 10.1234
>>> f'{number1:.2f}'
'10.12'
Syntax:
"{" [field_name] ["!" conversion] [":" format_spec] "}"
Explanation:
# Let's break it down...
# [field_name] => number1
# ["!" conversion] => Not used
# [format_spec] => [.precision][type]
# => .[2][f] => .2f # where f means Fixed-point notation
Going further, Format strings have the below syntax. As you can see there is a lot more that can be done.
Syntax: "{" [field_name] ["!" conversion] [":" format_spec] "}"
# let's understand what each field means...
field_name ::= arg_name ("." attribute_name | "[" element_index "]")*
arg_name ::= [identifier | digit+]
attribute_name ::= identifier
element_index ::= digit+ | index_string
index_string ::= <any source character except "]"> +
conversion ::= "r" | "s" | "a"
format_spec ::= [[fill]align][sign][#][0][width][grouping_option][.precision][type]
# Looking at the underlying fields under format_spec...
fill ::= <any character>
align ::= "<" | ">" | "=" | "^"
sign ::= "+" | "-" | " "
width ::= digit+
grouping_option ::= "_" | ","
precision ::= digit+
type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"
Refer https://docs.python.org/3/library/string.html#format-string-syntax

It seems that no one use dynamic formatter. To use dynamic formatter, use:
WIDTH = 7
PRECISION = 3
TYPE = "f"
v = 3
print(f"val = {v:{WIDTH}.{PRECISION}{TYPE}}")
Other format see: https://docs.python.org/3.6/library/string.html#format-specification-mini-language
Reference: Others SO Answer

Simply
a = 10.1234
print(f"{a:.1f}")
Output: 10.1
a = 10.1234
print(f"{a:.2f}")
Output: 10.12
a = 10.1234
print(f"{a:.3f}")
Output: 10.123
a = 10.1234
print(f"{a:.4f}")
Output: 10.1234
Just change the value after the decimal point sign which represent how may decimal point you want to print.

a = 10.1234
print(f"{a:0.2f}")
in 0.2f:
0 is telling python to put no limit on the total number of digits to
display
.2 is saying that we want to take only 2 digits after decimal
(the result will be same as a round() function)
f is telling that it's a float number. If you forget f then it will just print 1 less digit after the decimal. In this case, it will be only 1 digit after the decimal.
A detailed video on f-string for numbers
https://youtu.be/RtKUsUTY6to?t=606

Related

Decimal point question how would I go about 9 decimal points [duplicate]

Is there an easy way with Python f-strings to fix the number of digits after the decimal point? (Specifically f-strings, not other string formatting options like .format or %)
For example, let's say I want to display 2 digits after the decimal place.
How do I do that? Let's say that
a = 10.1234
Include the type specifier in your format expression:
>>> a = 10.1234
>>> f'{a:.2f}'
'10.12'
When it comes to float numbers, you can use format specifiers:
f'{value:{width}.{precision}}'
where:
value is any expression that evaluates to a number
width specifies the number of characters used in total to display, but if value needs more space than the width specifies then the additional space is used.
precision indicates the number of characters used after the decimal point
What you are missing is the type specifier for your decimal value. In this link, you an find the available presentation types for floating point and decimal.
Here you have some examples, using the f (Fixed point) presentation type:
# notice that it adds spaces to reach the number of characters specified by width
In [1]: f'{1 + 3 * 1.5:10.3f}'
Out[1]: ' 5.500'
# notice that it uses more characters than the ones specified in width
In [2]: f'{3000 + 3 ** (1 / 2):2.1f}'
Out[2]: '3001.7'
In [3]: f'{1.2345 + 4 ** (1 / 2):9.6f}'
Out[3]: ' 3.234500'
# omitting width but providing precision will use the required characters to display the number with the the specified decimal places
In [4]: f'{1.2345 + 3 * 2:.3f}'
Out[4]: '7.234'
# not specifying the format will display the number with as many digits as Python calculates
In [5]: f'{1.2345 + 3 * 0.5}'
Out[5]: '2.7344999999999997'
Adding to Robᵩ's answer: in case you want to print rather large numbers, using thousand separators can be a great help (note the comma).
>>> f'{a*1000:,.2f}'
'10,123.40'
And in case you want to pad/use a fixed width, the width goes before the comma:
>>> f'{a*1000:20,.2f}'
' 10,123.40'
Adding to Rob's answer, you can use format specifiers with f strings (more here).
You can control the number of decimals:
pi = 3.141592653589793238462643383279
print(f'The first 6 decimals of pi are {pi:.6f}.')
The first 6 decimals of pi are 3.141593.
You can convert to percentage:
grade = 29/45
print(f'My grade rounded to 3 decimals is {grade:.3%}.')
My grade rounded to 3 decimals is 64.444%.
You can do other things like print constant length:
from random import randint
for i in range(5):
print(f'My money is {randint(0, 150):>3}$')
My money is 126$
My money is 7$
My money is 136$
My money is 15$
My money is 88$
Or even print with a comma thousand separator:
print(f'I am worth {10000000000:,}$')
I am worth 10,000,000,000$
Consider:
>>> number1 = 10.1234
>>> f'{number1:.2f}'
'10.12'
Syntax:
"{" [field_name] ["!" conversion] [":" format_spec] "}"
Explanation:
# Let's break it down...
# [field_name] => number1
# ["!" conversion] => Not used
# [format_spec] => [.precision][type]
# => .[2][f] => .2f # where f means Fixed-point notation
Going further, Format strings have the below syntax. As you can see there is a lot more that can be done.
Syntax: "{" [field_name] ["!" conversion] [":" format_spec] "}"
# let's understand what each field means...
field_name ::= arg_name ("." attribute_name | "[" element_index "]")*
arg_name ::= [identifier | digit+]
attribute_name ::= identifier
element_index ::= digit+ | index_string
index_string ::= <any source character except "]"> +
conversion ::= "r" | "s" | "a"
format_spec ::= [[fill]align][sign][#][0][width][grouping_option][.precision][type]
# Looking at the underlying fields under format_spec...
fill ::= <any character>
align ::= "<" | ">" | "=" | "^"
sign ::= "+" | "-" | " "
width ::= digit+
grouping_option ::= "_" | ","
precision ::= digit+
type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"
Refer https://docs.python.org/3/library/string.html#format-string-syntax
It seems that no one use dynamic formatter. To use dynamic formatter, use:
WIDTH = 7
PRECISION = 3
TYPE = "f"
v = 3
print(f"val = {v:{WIDTH}.{PRECISION}{TYPE}}")
Other format see: https://docs.python.org/3.6/library/string.html#format-specification-mini-language
Reference: Others SO Answer
Simply
a = 10.1234
print(f"{a:.1f}")
Output: 10.1
a = 10.1234
print(f"{a:.2f}")
Output: 10.12
a = 10.1234
print(f"{a:.3f}")
Output: 10.123
a = 10.1234
print(f"{a:.4f}")
Output: 10.1234
Just change the value after the decimal point sign which represent how may decimal point you want to print.
a = 10.1234
print(f"{a:0.2f}")
in 0.2f:
0 is telling python to put no limit on the total number of digits to
display
.2 is saying that we want to take only 2 digits after decimal
(the result will be same as a round() function)
f is telling that it's a float number. If you forget f then it will just print 1 less digit after the decimal. In this case, it will be only 1 digit after the decimal.
A detailed video on f-string for numbers
https://youtu.be/RtKUsUTY6to?t=606

different syntax for accessing method of literals [duplicate]

This question already has answers here:
Accessing attributes on literals work on all types, but not `int`; why? [duplicate]
(4 answers)
Closed 1 year ago.
Why we can directly access a method belonging to a string literal:
keyfunc="STR".__eq__
or a float constant:
keyfunc=1.0.__eq__
or even:
keyfunc=1..__eq__ # 1. is the same float as 1.0
but the same code for an integer throws a syntax error?
keyfunc=1.__eq__ # WRONG!
The last line should be written as:
keyfunc=(1).__eq__
Why and when are the parens required?
Reason for this to happen:
It's because 1. gets treated as a float:
>>> 1.
1.0
>>>
And obviously:
>>> 1.0__eq__
SyntaxError: invalid decimal literal
>>>
Would give an error.
It's because Python operates from left to right. So the dot would belong to 1 to make it a float.
Workaround for this other than parenthesis:
So the way to fix it would be to add a space between 1 and the dot ., like:
>>> 1 .__eq__
<method-wrapper '__eq__' of int object at 0x00007FFDF14B2730>
>>>
Reasoning for these workarounds to work:
The reason this works is because:
>>> 1 .
SyntaxError: invalid syntax
>>>
Gives an error, so it doesn't get treated as an integer.
It's the same case for (1).
As you can see:
>>> (1).
SyntaxError: invalid syntax
>>>
Documentation references:
As shown on this page of the documentation:
integer ::= decimalinteger | octinteger | hexinteger | bininteger
decimalinteger ::= nonzerodigit digit* | "0"+
nonzerodigit ::= "1"..."9"
digit ::= "0"..."9"
octinteger ::= "0" ("o" | "O") octdigit+
hexinteger ::= "0" ("x" | "X") hexdigit+
bininteger ::= "0" ("b" | "B") bindigit+
octdigit ::= "0"..."7"
hexdigit ::= digit | "a"..."f" | "A"..."F"
bindigit ::= "0" | "1"
The above is the integer literal definitions in Python.
It also has to do with the python compiler specification. But the main confusion is that we don't know who the period belongs to, i.e.
keyfunc=[1.]__eq__ or keyfunc=1[.__eq__]. Without specifying the (1) or (as mentioned) adding the space, we don't know whether it's the end of an expression or not.

Nesting / escaping a f-string "=" (equal sign) expression

Is it possible to escape a python f-string within a "=" expression? (new feature in Python 3.8)
For example I have the following expression:
def double(x):
return x * 2
some_int = 2
print(f'{double(some_int) = }')
Which prints:
double(some_int) = 4
Is it possible to escape the some_int parameter in a way so that it prints:
double(2) = 4
Or do I have to type the expression twice and concatenate the literal expression and result the old-fashioned way?
As said in the What's New In Python 3.8 document:
Added an = specifier to f-strings. An f-string such as f'{expr=}' will
expand to the text of the expression, an equal sign, then the
representation of the evaluated expression.
So no, you can't do it that way(one shot) because the left side of = will become a string. Use traditional f-string interpolation:
print(f'double({some_int}) = {double(some_int)}')
Output:
double(2) = 4
Your code did not run, however I assume you mean to do:
some_int = 2
print(f'double({some_int}) = {some_int*2}')
which prints:
double(2) = 4

Can someone explain me about these lines?

set_9 = {1,2,3,4,5}
for a in set_9:
print(f"{a:>6.2f}")
Output
1.00
2.00
3.00
4.00
5.00
Is :> an operator? If not, what type is it?
What is 6.2f mean?
The format used is called Formatted string literals or f-strings, which is f"{a:>6.2f}"
Anything inside the curly braces is replacement field, which is {a:>6.2f}
Here, a is the field_name and >6.2f is the format_spec.
replacement_field ::= "{" [field_name] ["!" conversion] [":"
format_spec] "}"
Expanding the format specification used in your example:
> - align - Right align the field
6 - width - Minimum width (by default space is used as
fill character)
.2 - precision - Number of digits after the decimal point
f - type - Floating point notation

How do you use multiple arguments in {} when using the .format() method in Python

I want a table in python to print like this:
Clearly, I want to use the .format() method, but I have long floats that look like this: 1464.1000000000001 I need the floats to be rounded, so that they look like this: 1464.10 (always two decimal places, even if both are zeros, so I can't use the round() function).
I can round the floats using "{0:.2f}".format("1464.1000000000001"), but then they do not print into nice tables.
I can put them into nice tables by doing "{0:>15}.format("1464.1000000000001"), but then they are not rounded.
Is there a way to do both? Something like "{0:>15,.2f}.format("1464.1000000000001")?
You were almost there, just remove the comma (and pass in a float number, not a string):
"{0:>15.2f}".format(1464.1000000000001)
See the Format Specification Mini-Language section:
format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]
fill ::= <any character>
align ::= "<" | ">" | "=" | "^"
sign ::= "+" | "-" | " "
width ::= integer
precision ::= integer
type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"
Breaking the above format down then:
fill: <empty>
align: < # left
sign: <not specified>
width: 15
precision: 2
type: `f`
Demo:
>>> "{0:>15.2f}".format(1464.1000000000001)
' 1464.10'
Note that for numbers, the default alignment is to the right, so the > could be omitted.
"{0:15.2f}".format(1464.1000000000001)
I always find this site useful for this stuff:
https://pyformat.info/

Categories