| msg212478 - (view) |
Author: (aubmoon) |
Date: 2014-02-28 21:53 |
| "{:+10.8}".format(0.12345678) returns '+0.12345678' (11 chars) should return '+.12345678' (10 chars) |
|
|
| msg212480 - (view) |
Author: Ned Deily (ned.deily) *  |
Date: 2014-02-28 22:32 |
| I think you are misunderstanding the meaning of the width component (e.g. the 10 in your example) of a format specification. As described in the documentation, width is a decimal integer defining the *minimum* field width, not the *maximum* field width. As necessary, the generated field will be as long as necessary to represent the item as requested by the format spec, but it will be at least "width" characters long. http://docs.python.org/3.3/library/string.html#format-specification-mini-language |
|
|
| msg212483 - (view) |
Author: (aubmoon) |
Date: 2014-03-01 00:48 |
| Admittedly maximum is not correct; however, minimum is not right either. The 10 is the desired (or target) width. Fixed width prints are commonly used with very legacy systems that die a painful death when fixed width strings are parsed by index and a field has spilled over a column. The point is that the format returns a string that is longer than the desired length when a perfectly valid version meets both the format and desired length (making it more correct). The desired length should only be exceeded when no solutions can be found. Note the below statement parses without error. For this reason I feel this is a valid but minor issue. By using a regular expression or slicing the desired result can be achieved, but with extra code. Thanks for the quick response! -Mark >>> float('+.12345678') On Friday, February 28, 2014, Ned Deily <report@bugs.python.org> wrote: > > Ned Deily added the comment: > > I think you are misunderstanding the meaning of the width component (e.g. > the 10 in your example) of a format specification. As described in the > documentation, width is a decimal integer defining the *minimum* field > width, not the *maximum* field width. As necessary, the generated field > will be as long as necessary to represent the item as requested by the > format spec, but it will be at least "width" characters long. > > > http://docs.python.org/3.3/library/string.html#format-specification-mini-language > > ---------- > nosy: +ned.deily > resolution: -> invalid > stage: -> committed/rejected > status: open -> closed > > _______________________________________ > Python tracker <report@bugs.python.org javascript:;> > <http://bugs.python.org/issue20811> > _______________________________________ > |
|
|
| msg212484 - (view) |
Author: Ned Deily (ned.deily) *  |
Date: 2014-03-01 02:48 |
| OK, so the issue is that Python float literals in the range 0.0 < x < 1.0 can be spelled without a "0" before the decimal point but the built-in format method for floats appears to always output the leading "0" even in cases where doing so cause the string to unnecessarily exceed the requested field width. It does seem to be a bit of an edge case. But I don't see anything in the current documentation or in PEP 3101 that addresses this case one way or another. Eric, what's your take on this? |
|
|
| msg212494 - (view) |
Author: Eric V. Smith (eric.smith) *  |
Date: 2014-03-01 10:39 |
| I think you always want the leading zero. Mark (Dickinson), what do yo think? And I also think changing it at this point would be problematic. |
|
|
| msg212495 - (view) |
Author: Eric V. Smith (eric.smith) *  |
Date: 2014-03-01 10:43 |
| Oops, not sure how the nosy list got changed. Sorry about that. |
|
|
| msg212502 - (view) |
Author: Mark Lawrence (BreamoreBoy) * |
Date: 2014-03-01 14:40 |
| '0.12345678' or '+0.1234567' could both be considered equally valid. Who can say which is really The One True Way? :) |
|
|
| msg212519 - (view) |
Author: (aubmoon) |
Date: 2014-03-01 18:49 |
| Neither of those strictly meets the stated format. '0.12345678' is missing the + which is explicit in the format and '+0.1234567' does not have 8 decimal places. Only '+.12345678' has a length of 10, 8 decimal places, and the required sign. I realize this definitely an edge case, but it was encountered in real life. Thanks again for the careful consideration of this issue. -Mark On Saturday, March 1, 2014, Mark Lawrence <report@bugs.python.org> wrote: > > Mark Lawrence added the comment: > > '0.12345678' or '+0.1234567' could both be considered equally valid. Who > can say which is really The One True Way? :) > > ---------- > nosy: +BreamoreBoy > > _______________________________________ > Python tracker <report@bugs.python.org javascript:;> > <http://bugs.python.org/issue20811> > _______________________________________ > |
|
|
| msg212521 - (view) |
Author: Stefan Krah (skrah) *  |
Date: 2014-03-01 21:57 |
| aubmoon: Would it be a possibility just to use 'f' instead? >>> "{:+10.7f}".format(1.12345678) '+1.1234568' >>> "{:+10.7f}".format(0.12345678) '+0.1234568' |
|
|
| msg212526 - (view) |
Author: (aubmoon) |
Date: 2014-03-01 23:04 |
| That is exactly what I tried first. It turns out in the particular case I have been working the 8th digit is needed for correct answers. The job is a port of a punch card FORTRAN system into something more modern. The catch is the system is a scientific application that protects life, limb, and treasure. The new system must inter-operate with the legacy system until the entire system can be replaced with VV&A software under configuration control. In my particular case the sign must be printed, the decimal must be printed, and all eight digits. The number is always strictly -1 < x < 1 and has eight significant digits. The number is the included in a larger string of data. What I have done to address the issue is format the x string separately from the rest of the data and then slice and join out the undesired leading 0. Then include the value as a %s format in the larger context. On Saturday, March 1, 2014, Stefan Krah <report@bugs.python.org> wrote: > > Stefan Krah added the comment: > > aubmoon: Would it be a possibility just to use 'f' instead? > > >>> "{:+10.7f}".format(1.12345678) > '+1.1234568' > >>> "{:+10.7f}".format(0.12345678) > '+0.1234568' > > ---------- > nosy: +skrah > > _______________________________________ > Python tracker <report@bugs.python.org javascript:;> > <http://bugs.python.org/issue20811> > _______________________________________ > |
|
|
| msg212527 - (view) |
Author: Eric V. Smith (eric.smith) *  |
Date: 2014-03-01 23:17 |
| I still think this is a special case that we won't "fix". And even if we did, you'd have to wait until 3.5. But instead of your solution, it might be easier to wrap your floats in a class that implements your version of format, based on float's format with some post-processing: class MyFloat(float): def __format__(self, fmt): s = float.__format__(self, fmt) if s[1] == '0': return s[0] + s[2:] return s print(format(MyFloat(0.12345678), '+8.8')) print(format(MyFloat(1.12345678), '+8.8')) gives: +.12345678 +1.1234568 I've grossly simplified __format__, of course. And I'm using built-in format() instead of ''.format() (because it's less typing), but they use the same mechanisms. So: print('{}:"{:+10.8}"'.format('answer', MyFloat(0.12345678))) gives: answer:"+.12345678" |
|
|
| msg212639 - (view) |
Author: (aubmoon) |
Date: 2014-03-03 14:40 |
| We will add extending the float class as another possible work around or part of a work around. Our developers now have a few options to choose from. I am not sure which approach will be preferred. thanks for all of the quick replies. this was just an odd case that was encountered, so I wanted the community to be aware of it. if and when to address it is above my level. On Saturday, March 1, 2014, Eric V. Smith <report@bugs.python.org> wrote: > > Eric V. Smith added the comment: > > I still think this is a special case that we won't "fix". And even if we > did, you'd have to wait until 3.5. > > But instead of your solution, it might be easier to wrap your floats in a > class that implements your version of format, based on float's format with > some post-processing: > > class MyFloat(float): > def __format__(self, fmt): > s = float.__format__(self, fmt) > if s[1] == '0': > return s[0] + s[2:] > return s > > print(format(MyFloat(0.12345678), '+8.8')) > print(format(MyFloat(1.12345678), '+8.8')) > > gives: > +.12345678 > +1.1234568 > > I've grossly simplified __format__, of course. And I'm using built-in > format() instead of ''.format() (because it's less typing), but they use > the same mechanisms. So: > > print('{}:"{:+10.8}"'.format('answer', MyFloat(0.12345678))) > > gives: > answer:"+.12345678" > > ---------- > > _______________________________________ > Python tracker <report@bugs.python.org javascript:;> > <http://bugs.python.org/issue20811> > _______________________________________ > |
|
|
| msg212770 - (view) |
Author: Mark Dickinson (mark.dickinson) *  |
Date: 2014-03-05 21:08 |
| > I think you always want the leading zero. Mark (Dickinson), what do yo think? Agreed that we want to keep the leading zero for normal uses. I wouldn't object to some way to opt out of the leading zero, but I'm not sure what that way (w/c)ould be. |
|
|
| msg221084 - (view) |
Author: Mark Lawrence (BreamoreBoy) * |
Date: 2014-06-20 12:46 |
| I cannot see a fix that would keep everybody happy. Also allow for potential backward compatibility issues. Given that there are at least two if not more suggested workarounds I'm inclined to close as "wont fix". Opinions please. |
|
|