From: Stefan Krah on
Keith <keith.brafford(a)> wrote:
> Even though this uses the to_eng_string() function, and even though I
> am using the decimal.Context class:
> >>> c = decimal.Context(prec=5)
> >>> decimal.Decimal(1234567).to_eng_string(c)
> '1234567'
> That is not an engineering notation string.

To clarify further: The spec says that the printing functions are not
context sensitive, so to_eng_string does not *apply* the context.

The context is only passed in for the 'capitals' value, which determines
whether the exponent letter is printed in lower or upper case.

This is one of the unfortunate situations where passing a context can
create great confusion for the user. Another one is:

>>> c = Context(prec=5)
>>> Decimal(12345678, c)

Here the context is passed only for the 'flags' and 'traps' members:

>>> Decimal("wrong", c)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.2/", line 548, in __new__
"Invalid literal for Decimal: %r" % value)
File "/usr/lib/python3.2/", line 3836, in _raise_error
raise error(explanation)
decimal.InvalidOperation: Invalid literal for Decimal: 'wrong'

>>>c.traps[InvalidOperation] = False
>>> Decimal("wrong", c)

Stefan Krah

From: Grant Edwards on
On 2010-04-26, Keith <keith.brafford(a)> wrote:

> I am considering writing a PEP for the inclusion of an engineering
> format specifier, and would appreciate input from others.

I very regularly do something similar in various apps, though I often
want to specify the exponent (e.g. I always want to print a given
value in "mega" scaling even if that ends up as 0.090e3 or 1000.010e3.

So I would suggest adding an optional "exponent" value such that "%3n"
would always result in <whatever>e+03

Grant Edwards grant.b.edwards Yow! You were s'posed
at to laugh!
From: Mark Dickinson on
On Apr 26, 4:36 am, Keith <keith.braff...(a)> wrote:
> I am considering writing a PEP for the inclusion of an engineering
> format specifier, and would appreciate input from others.

> [...]

> I am thinking that if we simply added something like %n (for eNgineer)
> to the list of format specifiers that we could make life easier for
> engineers:
> ("%n" % 12345)  == "12.345e+03"
> ("%n" %  1234)  == "1.234e+03"
> ("%n" %   123)  == "123e+00"
> ("%n" % 1.2345e-5)  == "12.345e+06"

I don't think there's much chance of getting changes to old-style
string formatting accepted; you might be better off aiming at the new-
style string formatting. (And there, the 'n' modifier is already
taken for internationalization, so you'd have to find something
different. :)

From: Mark Dickinson on
On Apr 26, 6:47 am, Keith <keith.braff...(a)> wrote:
> From that document it appears that my decimal.Decimal(1234567) example
> shows that the module has a bug:
> Doc says:
> [0,123,3] ===>  "123E+3"
> But Python does:>>> import decimal
> >>> decimal.Decimal(123000).to_eng_string()
> '123000'

That's not a bug. The triple [0,123,3] is Decimal('123e3'), which is
not the same thing as Decimal('123000'). The former has an exponent
of 3 (in the language of the specification), while the latter has an
exponent of 0.

>>> decimal.Decimal('123e3').to_eng_string()

From: Keith on
>Apparently either you and the General Decimal Arithmetic spec differ
>on what constitutes engineering notation, there's a bug in the Python
>decimal library,

You've distilled it precisely, and as you've shown in a different
post, it's the former.

The Python decimal module seems to implement correctly Mike
Cowlishaw's spec, but what that spec refers to as "engineering
notation" isn't really what engineers actually use. That is, even
with decimal.Decimal.to_eng_string(), engineers still end up having to
write their own string formatting code.

I think it's worth making the print statement (or print function, as
the case may be) let us do engineering notation, just like it lets us
specify scientific notation.

--Keith Brafford