FAQ
I want to change the DEFAULT behavior of python
to print out all floating points in scientific format?
For instance,
x=0.01
print x
1.000000E-2 #Like print "%E"%x

How can I do it?

Daehyok Shin

Search Discussions

  • John Roth at Aug 8, 2003 at 11:21 pm
    "sdhyok" <sdhyok at yahoo.com> wrote in message
    news:420ced91.0308081115.7060e551 at posting.google.com...
    I want to change the DEFAULT behavior of python
    to print out all floating points in scientific format?
    For instance,
    x=0.01
    print x
    1.000000E-2 #Like print "%E"%x

    How can I do it?

    Daehyok Shin
    To the best of my knowledge, you can't. I believe the
    only way to actually control the format is with the '%'
    operator.

    Of course, if you want to get the source, make the
    change, and then have your own private copy of Python,
    you could manage it.

    John Roth
  • Ben Finney at Aug 9, 2003 at 12:36 am

    On 8 Aug 2003 12:15:53 -0700, sdhyok wrote:
    I want to change the DEFAULT behavior of python
    Then you can modify the Python source to do whatever you want. This is
    a bad idea for your current stated purpose, though.

    Changing the default behaviour of a native Python type will only be
    local to machines that have this altered Python; if you write code that
    depends on that, it will break unexpectedly on other machines.
    to print out all floating points in scientific format?
    For instance,
    x=0.01
    print x
    1.000000E-2 #Like print "%E"%x

    How can I do it?
    Since changing the way native flot object operate is a bad idea, two
    ways seem reasonable.

    One is to always use output formatting, since it will make your code
    clearer.
    x = 0.01
    print "%E" % x
    1.000000E-02

    The other way is to subclass the 'float' class to overload its __str__
    method. This gives you objects that default to what you want, without
    breaking Python.
    class SciFloat( float ):
    ... """ A floating-point number class
    ... that defaults to scientific representation
    ... """
    ... def __init__( self, *args, **kwargs ):
    ... float.__init__( self, args, kwargs )
    ... return
    ... def __str__( self ):
    ... return "%E" % self
    ...
    if( __name__ == '__main__' ):
    ... x = SciFloat( 0.01 )
    ... print x
    ...
    1.000000E-02
    >>>

    --
    \ "I filled my humidifier with wax. Now my room is all shiny." |
    `\ -- Steven Wright |
    _o__) |
    Ben Finney <http://bignose.squidly.org/>
  • Sdhyok at Aug 9, 2003 at 2:42 pm
    I am disappointed that there is no elegant solution for this problem
    in python.
    As you may notice, my primary usage of python is for scientific
    programming.
    For the purpose, it is critical for users to flexibly modify the
    printing format
    of floating points depending on their ranges and precisions.

    Think about this case.
    import Numeric as N
    x = N.arange(10.)
    print x
    [ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]
    print "%E"%x
    TypeError: float argument required

    Even the format string option in print command doesn't work for numpy
    array.
    This limitation can be a serious handicap in the application of python
    for scientific programming.
    I like to listen to all of you who are interested in this issue.

    Shin, Daehyok
  • Cousin Stanley at Aug 9, 2003 at 4:07 pm
    The conversion to e format in the print statement
    seems to work OK if I iterate over the items in the array ....
    import Numeric as N

    x = N.arange( 10. )

    print x
    [ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]
    for this_item in x :
    ... print '%e' % this_item
    ...
    0.000000e+000
    1.000000e+000
    2.000000e+000
    3.000000e+000
    4.000000e+000
    5.000000e+000
    6.000000e+000
    7.000000e+000
    8.000000e+000
    9.000000e+000
    >>>


    --
    Cousin Stanley
    Human Being
    Phoenix, Arizona
  • Sdhyok at Aug 10, 2003 at 7:21 pm
    Cousin, you are right.
    But, do you want to write for loops
    whenever you print arrays?
    Maybe not if you are a hard-core scientific programmer.

    "Cousin Stanley" <CousinStanley at hotmail.com> wrote in message news:<bh361p$u9lvt$1 at ID-130333.news.uni-berlin.de>...
    The conversion to e format in the print statement
    seems to work OK if I iterate over the items in the array ....
    import Numeric as N

    x = N.arange( 10. )

    print x
    [ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]
    for this_item in x :
    ... print '%e' % this_item
    ...
    0.000000e+000
    1.000000e+000
    2.000000e+000
    3.000000e+000
    4.000000e+000
    5.000000e+000
    6.000000e+000
    7.000000e+000
    8.000000e+000
    9.000000e+000
  • Cousin Stanley at Aug 10, 2003 at 8:32 pm

    Cousin, you are right.
    But, do you want to write for loops
    whenever you print arrays?

    Maybe not if you are a hard-core scientific programmer.
    Cousin sdhyok ....

    I believe that the nature of science and the numerical tools
    that it employs for problem solving is highly context dependent
    upon the particular problem at hand and that it might be difficult
    to find a one-size-fits-all solution for array printing since
    the nature of the arrays that are employed and their content
    can vary greatly from context to context ....

    The dimensonality, homogeniety, and population density
    of the arrays employed must be considered as design parameters
    in each problem space and treated accordingly ....

    However, one can define specialized array functions,
    print functions or otherwise, for specific problems
    and use those without having to code the loops each time ....

    I do have an extensive background in computational chemistry ....

    Some would call that discipline hard-core science ....

    Others would call it hand-waving in hopeless depths ....

    --
    Cousin Stanley
    Human Being
    Phoenix, Arizona
  • Andrew Dalke at Aug 9, 2003 at 6:59 pm

    sdhyok:
    As you may notice, my primary usage of python is for scientific
    programming.
    For the purpose, it is critical for users to flexibly modify the
    printing format
    of floating points depending on their ranges and precisions.
    Python gives complete control over you can represent numbers.
    It just doesn't change the default representation. Users *can*
    flexibly modify the printing format.

    I can't see why you would want to change it globally. That
    just sounds wrong. Eg, I want my app to print the resolution
    in Angstroms in the form "%3.2f" while I want the mass values
    in "%3.1f". A global setting is a very clumsy way to change that.
    This limitation can be a serious handicap in the application of python
    for scientific programming.
    I like to listen to all of you who are interested in this issue.
    I do scientific programming. The lack of specialized formatting
    hasn't bothered me at all.

    Andrew
    dalke at dalkescientific.com
  • Sdhyok at Aug 10, 2003 at 7:25 pm
    "Andrew Dalke" <adalke at mindspring.com> wrote in message news:<bh3g5c$f4m$1 at slb5.atl.mindspring.net>...
    Python gives complete control over you can represent numbers.
    It just doesn't change the default representation. Users *can*
    flexibly modify the printing format.

    I can't see why you would want to change it globally. That
    just sounds wrong. Eg, I want my app to print the resolution
    in Angstroms in the form "%3.2f" while I want the mass values
    in "%3.1f". A global setting is a very clumsy way to change that.
    Andrew, I take your advice.
    To change the format of floating point globally
    may be too aggressive.
    But, still I think we need more elegant way to print out floating point arrays
    in python.

    What is your best way for my example?
    (I hope it is not for loop.)

    Daehyok Shin
  • Andrew Dalke at Aug 11, 2003 at 12:00 am

    sdhyok:
    What is your best way for my example?
    (I hope it is not for loop.)
    It's a for loop. I disagree with your assessment that it's a problem,
    so I'll understand if you disagree with my solution.

    Andrew
    dalke at dalkescientific.com
  • Alex Martelli at Aug 9, 2003 at 4:58 pm

    sdhyok wrote:

    I want to change the DEFAULT behavior of python
    to print out all floating points in scientific format?
    For instance,
    x=0.01
    print x
    1.000000E-2 #Like print "%E"%x

    How can I do it?
    You need to download Python's sources, modify them, and build a modified
    Python interpreter and libraries that impose the behavior you want rather
    than what the normal Python interpreter and libraries do.

    Specifically, look at function format_float, line 233 of file
    Objects/floatobject.c in the current 2.3 maintenance branch for example.
    Currently it formats the float with "%.*g" [variable precision passed
    in as an argument to format_float]; if you want to use a different C level
    format string, that string is the one you need to change.

    Of course, that's likely to break some of the tests in Python's unit-tests
    suite, so you'll probably want to modify those, too. And then, you get to
    maintain your "slightly divergent" Python yourself forevermore. I do not
    think there is much likelihood that a patch in this regard would be
    accepted in the Python core, even if you made it flexible enough to keep
    the current behavior by default and change it only upon specific request
    (e.g., use a variable string for the format, and let the Python coder
    modify the letter in it, only, keeping "%.*g" as the default but letting
    the 'g' be changed) -- such "big global" settings, which would let one
    idiosyncratic library module modify Python behavior enough to break other
    innocent modules, are looked at with disfavour, for reasons that should
    be obvious (each and every such 'big global' _damages_ Python's suitability
    for writing very large, multi-authors applications -- that suitability is
    currently very high, and _extremely_ convincing arguments would need to
    be brought to bear in order to convince Guido to deliberately lower it).


    Alex
  • Sdhyok at Aug 10, 2003 at 7:27 pm
    As you recommend, I won't modify the default behavior of python.
    But, still I need a better treatment of python on arrays.

    Daehyok Shin

    Alex Martelli <aleax at aleax.it> wrote in message news:<aL9Za.34994$an6.1223329 at news1.tin.it>...
    sdhyok wrote:
    I want to change the DEFAULT behavior of python
    to print out all floating points in scientific format?
    For instance,
    x=0.01
    print x
    1.000000E-2 #Like print "%E"%x

    How can I do it?
    You need to download Python's sources, modify them, and build a modified
    Python interpreter and libraries that impose the behavior you want rather
    than what the normal Python interpreter and libraries do.

    Specifically, look at function format_float, line 233 of file
    Objects/floatobject.c in the current 2.3 maintenance branch for example.
    Currently it formats the float with "%.*g" [variable precision passed
    in as an argument to format_float]; if you want to use a different C level
    format string, that string is the one you need to change.

    Of course, that's likely to break some of the tests in Python's unit-tests
    suite, so you'll probably want to modify those, too. And then, you get to
    maintain your "slightly divergent" Python yourself forevermore. I do not
    think there is much likelihood that a patch in this regard would be
    accepted in the Python core, even if you made it flexible enough to keep
    the current behavior by default and change it only upon specific request
    (e.g., use a variable string for the format, and let the Python coder
    modify the letter in it, only, keeping "%.*g" as the default but letting
    the 'g' be changed) -- such "big global" settings, which would let one
    idiosyncratic library module modify Python behavior enough to break other
    innocent modules, are looked at with disfavour, for reasons that should
    be obvious (each and every such 'big global' _damages_ Python's suitability
    for writing very large, multi-authors applications -- that suitability is
    currently very high, and _extremely_ convincing arguments would need to
    be brought to bear in order to convince Guido to deliberately lower it).


    Alex
  • Carl Banks at Aug 10, 2003 at 8:17 pm

    sdhyok wrote:
    As you recommend, I won't modify the default behavior of python.
    But, still I need a better treatment of python on arrays.
    Continually repeating your question isn't going to make a better
    treatment magically appear.

    Just use the loop method someone suggested.

    If you don't like writing a for loop every time, put it in a function.


    --
    CARL BANKS
    "You don't run Microsoft Windows. Microsoft Windows runs you."
  • Alex Martelli at Aug 10, 2003 at 10:51 pm

    sdhyok wrote:

    As you recommend, I won't modify the default behavior of python.
    But, still I need a better treatment of python on arrays.
    Arrays are supplied by extension modules, most popularly Numeric.

    If you're doing scientific computations in Python and use arrays but
    not Numeric (or its slated-to-be-replacement numarray, of which I
    don't know much yet; or the many things layered atop of and onside
    of Numeric, such as scipy), switch. You'll be happy you did.

    I've never heard a scientific programmer complain too badly about
    how Numeric treats arrays, whether they were coming from Fortran
    (the typical case), other higher-level languages, or general purpose
    languages not really suited for scientific computation (such as C).

    You seem to be focused on readable display of arrays (quite an
    unusual focus for scientific programming). So, worst case, it's trivial
    to write a general purpose function that takes an array of ANY size
    and rank and emits it in the way you prefer -- easier than in any
    other language commonly used for scientific programming.

    So, you don't need anything from Python -- just write that blessed
    function and scientifically program to your heart's content.


    Alex
  • David M. Cooke at Aug 11, 2003 at 1:18 am

    At some point, Alex Martelli wrote:
    sdhyok wrote:
    As you recommend, I won't modify the default behavior of python.
    But, still I need a better treatment of python on arrays.
    You seem to be focused on readable display of arrays (quite an
    unusual focus for scientific programming). So, worst case, it's trivial
    to write a general purpose function that takes an array of ANY size
    and rank and emits it in the way you prefer -- easier than in any
    other language commonly used for scientific programming.
    With Numeric at least, you can set globally the functions used for
    str() and repr() on arrays, giving exactly this, without requiring a
    separate function for representations. Have a look at Numeric.py,
    multiarray.set_string_function(), and ArrayPrinter.py from the Numeric
    distribution.

    The simple way of controlling output with Numeric is to use the
    variables sys.output_line_width, sys.float_output_precision and
    sys.float_output_supress_small (if true, replace in the output numbers that
    are much smaller than the rest with zero, which is very nice when most of
    your numbers are 1.0, and you've got some annoying 1.8342e-17 that you want
    to ignore). These are added by Numeric to the sys module.

    With numarray, you could subclass the array object, write your own
    __str__ and __repr__ methods, and use that instead.

    --
    \/|<
    /--------------------------------------------------------------------------\
    David M. Cooke
    cookedm(at)physics(dot)mcmaster(dot)ca
  • Sdhyok at Aug 11, 2003 at 3:52 am
    Thanks, Alex.

    snip
    If you're doing scientific computations in Python and use arrays but
    not Numeric (or its slated-to-be-replacement numarray, of which I
    don't know much yet; or the many things layered atop of and onside
    of Numeric, such as scipy), switch. You'll be happy you did.
    I refer all sequences, but, as you say, particularly numpy arrays.
    I've never heard a scientific programmer complain too badly about
    how Numeric treats arrays, whether they were coming from Fortran
    (the typical case), other higher-level languages, or general purpose
    languages not really suited for scientific computation (such as C).
    Right, we can use scientific binary formats, like NetCDF, HDF.
    But, we often want to read the data in our naked eyes
    and exchange them with spreadsheet.
    You seem to be focused on readable display of arrays (quite an
    unusual focus for scientific programming). So, worst case, it's trivial
    to write a general purpose function that takes an array of ANY size
    and rank and emits it in the way you prefer -- easier than in any
    other language commonly used for scientific programming.

    So, you don't need anything from Python -- just write that blessed
    function and scientifically program to your heart's content.
    Trivial to create my own function.
    But, surprisingly no common function or command for the work.
    Maybe, one solution is

    import Numeric as N
    N.print(array, format="%.2E")


    Daehyok Shin
  • Alex Martelli at Aug 11, 2003 at 8:48 am
    sdhyok wrote:
    ...
    I've never heard a scientific programmer complain too badly about
    how Numeric treats arrays, whether they were coming from Fortran
    (the typical case), other higher-level languages, or general purpose
    languages not really suited for scientific computation (such as C).
    Right, we can use scientific binary formats, like NetCDF, HDF.
    But, we often want to read the data in our naked eyes
    and exchange them with spreadsheet.
    For "exchange with spreadsheets" see the csv module (new in 2.3), e.g.:
    import csv
    import sys
    csv.writer(sys.stdout).writerow([ 100.+i for i in range(3,8) ])
    103.0,104.0,105.0,106.0,107.0
    >>>

    It doesn't, of course, force scientific format (it uses the general
    format) -- spreadsheets don't need that. However, it does have the
    concept of a "Dialect" (here, I've let the dialect default to 'excel'),
    a bundle of formatting parameters that tweak the output into the best
    form for a given spreadsheet; that doesn't provide the specific bit
    of formatting control you want, but it gives what's clearly the right
    "hook" on which to hang any kind of formatting control. If you need
    to pursue "exchange with spreadsheet" and you have a use-case for
    needing scientific format in such a setting, then proposing a patch
    to module csv [having the dialect optionally record the preferred
    way to format floating point numbers] might stand a good chance.

    Right now, _csv.c [line 1126 in the sources) just transforms the
    fields it's emitting with PyObject_Str(field) -- equivalent to the
    Python call str(field), just as the print statement does. But just
    as it nows checks dialect->quoting before coming to that, it might
    well check some other field of the '*dialect* structure in order
    to influence output formatting selectively -- *IF* good use cases
    could be found and verified where a spreadsheet's behavior can be
    made better by special formatting of numbers fed to it.

    You seem to be focused on readable display of arrays (quite an
    unusual focus for scientific programming). So, worst case, it's trivial
    to write a general purpose function that takes an array of ANY size
    and rank and emits it in the way you prefer -- easier than in any
    other language commonly used for scientific programming.

    So, you don't need anything from Python -- just write that blessed
    function and scientifically program to your heart's content.
    Trivial to create my own function. We agree.
    But, surprisingly no common function or command for the work.
    Actually, Numeric.array2string IS exactly such a "common function
    or command". It's been written 7 years ago by Konrad Hinsen and
    happily used ever since by thousands of happy users of Numeric --
    how much more common than this can you get?

    However, among its very numerous formatting parameters, it does
    NOT have one to let you force exponential format as opposed to
    fixedpoint format -- it always decides that tidbit (i.e. whether
    an 'e' or 'f' is ultimately used in the format string) by itself.

    Clearly, no Numeric user has had substantial need for this kind
    of forced output formatting over these many years -- which I do
    not find at all surprising. Still, array2string is a Python
    coded function -- see its sources in Numeric/ArrayPrinter.py --
    so that experimenting with changes to it is trivial, and maybe
    the Numeric maintainers will look with favour upon a patch,
    should you decide to offer one. It might be as simple as adding
    yet one more optional parameter to the array2string function,
    say "forcedformat" defaulting to None, passing it on to the
    underlying internal _floatFormat function it calls to determine
    the format string, and having _floatFormat just use it, if not
    None, instead of determining the format itself. I would
    suggest you make a copy of ArrayPrinter.py, tweak it to your
    own satisfaction, then send the resulting patch to the Numeric
    maintainers proposing inclusion in Numeric's next release.
    Maybe, one solution is

    import Numeric as N
    N.print(array, format="%.2E")
    In my opinion, the solution I just sketched for you, i.e.:

    print N.array2string(array, precision=2, forcedformat="E")

    stands a much better chance than the addition of a new function
    that does direct printing (rather than the more useful and
    flexibile formatting-to-string) and merges precision and
    formatcharacter into one argument (note that array2string
    does already accept a precision argument) -- even without
    considering the fact that 'print' is a keyword and thus not
    usable as a function-name.


    Alex
  • Bengt Richter at Aug 10, 2003 at 9:14 pm

    On Sat, 09 Aug 2003 16:58:46 GMT, Alex Martelli wrote:
    sdhyok wrote:
    I want to change the DEFAULT behavior of python
    to print out all floating points in scientific format?
    For instance,
    x=0.01
    print x
    1.000000E-2 #Like print "%E"%x

    How can I do it?
    You need to download Python's sources, modify them, and build a modified
    Python interpreter and libraries that impose the behavior you want rather
    than what the normal Python interpreter and libraries do.

    Specifically, look at function format_float, line 233 of file
    Objects/floatobject.c in the current 2.3 maintenance branch for example.
    Currently it formats the float with "%.*g" [variable precision passed
    in as an argument to format_float]; if you want to use a different C level
    format string, that string is the one you need to change.

    Of course, that's likely to break some of the tests in Python's unit-tests
    suite, so you'll probably want to modify those, too. And then, you get to
    maintain your "slightly divergent" Python yourself forevermore. I do not
    think there is much likelihood that a patch in this regard would be
    accepted in the Python core, even if you made it flexible enough to keep
    the current behavior by default and change it only upon specific request
    (e.g., use a variable string for the format, and let the Python coder
    modify the letter in it, only, keeping "%.*g" as the default but letting
    the 'g' be changed) -- such "big global" settings, which would let one
    idiosyncratic library module modify Python behavior enough to break other
    innocent modules, are looked at with disfavour, for reasons that should
    be obvious (each and every such 'big global' _damages_ Python's suitability
    for writing very large, multi-authors applications -- that suitability is
    currently very high, and _extremely_ convincing arguments would need to
    be brought to bear in order to convince Guido to deliberately lower it).
    OTOH, why not a sys.printhook ? There is a kind of precedent in
    import sys
    def dh(obj):
    ... if isinstance(obj, (int, long, float)): return sys.__displayhook__('%e'%float(obj))
    ... else: return sys.__displayhook__(obj)
    ...
    sys.displayhook = dh
    1
    '1.000000e+000'
    _
    '1.000000e+000'
    2L
    '2.000000e+000'
    3.
    '3.000000e+000'
    1, 2L, 3.
    (1, 2L, 3.0)

    I didn't bother with recursive list and tuple mods. That would be up to the printhook user.
    ISTM a printhook would be easy to implement and not disruptive overall, whatever silliness
    it might inspire in particular individuals ;-)

    Actually, I think there could even be some good use for it, since you could do things with
    the object stream that you couldn't do by intercepting strings in sys.stdout.write.

    Regards,
    Bengt Richter
  • Bengt Richter at Aug 10, 2003 at 9:00 pm

    On 8 Aug 2003 12:15:53 -0700, sdhyok at yahoo.com (sdhyok) wrote:
    I want to change the DEFAULT behavior of python
    to print out all floating points in scientific format?
    For instance,
    x=0.01
    print x
    1.000000E-2 #Like print "%E"%x

    How can I do it?
    Do you have to use the print statement per se for output?
    I.e., why couldn't you write

    sciPrint( x, whatever, etc )

    instead of

    print x, whatever, etc

    Then you could customize sciPrint as you please.
    Or do you have to change the behaviour of existing modules without
    changing their source?

    Regards,
    Bengt Richter
  • Sdhyok at Aug 11, 2003 at 3:41 am
    Writing my own function is definitely one choice.
    But, my point is that if some of us are really serious
    about scientific/engineering programming,
    we must have a common function or command
    to print out whole array elements easily with any format we want.

    It can be in Numeric (or numarray) package like,

    import Numeric as N
    N.print(array, format="%.2E")


    Daehyok Shin

    bokr at oz.net (Bengt Richter) wrote in message news:<bh6bq6$p1u$0 at 216.39.172.122>...
    On 8 Aug 2003 12:15:53 -0700, sdhyok at yahoo.com (sdhyok) wrote:

    I want to change the DEFAULT behavior of python
    to print out all floating points in scientific format?
    For instance,
    x=0.01
    print x
    1.000000E-2 #Like print "%E"%x

    How can I do it?
    Do you have to use the print statement per se for output?
    I.e., why couldn't you write

    sciPrint( x, whatever, etc )

    instead of

    print x, whatever, etc

    Then you could customize sciPrint as you please.
    Or do you have to change the behaviour of existing modules without
    changing their source?

    Regards,
    Bengt Richter
  • Ben Finney at Aug 11, 2003 at 3:33 am

    On 10 Aug 2003 20:41:35 -0700, sdhyok wrote:
    Writing my own function is definitely one choice.
    But, my point is that if some of us are really serious about
    scientific/engineering programming, we must have a common function or
    command to print out whole array elements easily with any format we
    want.
    We eagerly await your patches for improving the Numeric code in whatever
    way you want.

    --
    \ "If I melt dry ice, can I swim without getting wet?" -- Steven |
    `\ Wright |
    _o__) |
    Ben Finney <http://bignose.squidly.org/>

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedAug 8, '03 at 7:15p
activeAug 11, '03 at 8:48a
posts21
users9
websitepython.org

People

Translate

site design / logo © 2022 Grokbase