[Tutor] the binary math wall
I'm running headlong into the dilemma of binary math representation, with game-ending consequences, e.g.: 0.15 0.14999 Obviously, any attempts to manipulate this value, under the misguided assumption that it is truly 0.15 are ill-advised, with inevitable bad results. the particular problem I'm attempting to corral is thus: math.modf(18.15) (0.14858, 18.0) with some intermediate scrunching, the above snippet morphs to: (math.modf(math.modf(18.15)[0]*100)[0])/.6 1.4298 The last line should be zero, and needs to be for me to continue this algorithm. Any of Python's help-aids that I apply to sort things out, such as formatting (%), or modules like decimal do nothing more than powder up the display for visual consumption (turning it into a string). The underlying float value remains corrupted, and any attempt to continue with the math adapts and re-incorporates the corruption. What I'm shooting for, by the way, is an algorithm that converts a deg/min/sec formatted number to decimal degrees. It [mostly] worked, until I stumbled upon the peculiar cases of 15 minutes and/or 45 minutes, which exposed the flaw. What to do? I dunno. I'm throwing up my hands, and appealing to the Council. (As an [unconnected] aside, I have submitted this query as best I know how, using plain text and the tu...@... address. There is something that either I, or my yahoo.com mailer *or both* doesn't quite get about these mailings. But, I simply do my best, following advice I've been offered via this forum. Hope this --mostly-- works.) From the virtual desk of Lowell Tackett ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] the binary math wall
On Tue, Apr 20, 2010 at 11:58 AM, Lowell Tackett lowelltack...@yahoo.com wrote: I'm running headlong into the dilemma of binary math representation, with game-ending consequences, e.g.: 0.15 0.14999 Obviously, any attempts to manipulate this value, under the misguided assumption that it is truly 0.15 are ill-advised, with inevitable bad results. Yes, floats are slightly inaccurate. No, this usually doesn't cause problems. You can use the decimal module if you want. But I think your problem is that your math is wrong. You are assuming that your float values are precise and they are not. You must check ranges when dealing with float values, not for specific values. I.E. you should never depend on a value being 1 in a float calculation, instead your equations need to be robust enough to deal with values very close to 1 as well. If your equations cannot handle this, then coerce the value to 1. if .999 i 1.1: i = 1 And before you say but that is just a hack, no, that is the nature of floating-point values. No one ever claimed that they were precise or that you should depend on their values being precise. If you really care so much, use the decimal module. But you really just need to adapt your formulas from the ideal to the reality, in which the values are not necessarily complete. May I suggest another approach though? Why even process these values as floats? Consider this: a = 18.15 a 18.149 a = '18.15' degree, min = map(int, a.split('.')) degree 18 min 15 Supposing you get your input as a string. Basically the second you let your value end up stored as a float, there's no turning back. You need to get ahold of this value before it becomes a float and deal with it in a different way. The most straightforward is to deal with the parts individually as integers. Eventually you will develop a distrust for floats and you will intrinsically know where and when you should / shouldn't use them ;) Hope that helps, -Luke ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] the binary math wall
On Tue, Apr 20, 2010 at 12:58 PM, Lowell Tackett lowelltack...@yahoo.com wrote: Any of Python's help-aids that I apply to sort things out, such as formatting (%), or modules like decimal do nothing more than powder up the display for visual consumption (turning it into a string). The underlying float value remains corrupted, and any attempt to continue with the math adapts and re-incorporates the corruption. Using the decimal module does not convert anything to strings. The decimal module gives you floating point arithmetic with base 10 rather than base 2. You examples seem to work okay for me using decimals: IDLE 2.6.4 import decimal n = decimal.Decimal(18.15) n Decimal('18.15') print n 18.15 divmod(n, 1) (Decimal('18'), Decimal('0.15')) divmod(divmod(n, 1)[1]*100, 1)[1]/decimal.Decimal(0.6) Decimal('0.0') If you need to avoid floating point calculations entirely, you might try the fractions module (new in python 2.6): import fractions n = fractions.Fraction(18.15) n Fraction(363, 20) print n 363/20 divmod(divmod(n, 1)[1]*100, 1)[1]/fractions.Fraction(0.6) Fraction(0, 1) print divmod(divmod(n, 1)[1]*100, 1)[1]/fractions.Fraction(0.6) 0 and if you need to convert to float at the end: float(divmod(divmod(n, 1)[1]*100, 1)[1]/fractions.Fraction(0.6)) 0.0 -- Jerry ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] the binary math wall
On Tue, Apr 20, 2010 at 11:58 AM, Lowell Tackett lowelltack...@yahoo.comwrote: I'm running headlong into the dilemma of binary math representation, with game-ending consequences, e.g.: 0.15 0.14999 Obviously, any attempts to manipulate this value, under the misguided assumption that it is truly 0.15 are ill-advised, with inevitable bad results. the particular problem I'm attempting to corral is thus: math.modf(18.15) (0.14858, 18.0) with some intermediate scrunching, the above snippet morphs to: (math.modf(math.modf(18.15)[0]*100)[0])/.6 1.4298 The last line should be zero, and needs to be for me to continue this algorithm. Any of Python's help-aids that I apply to sort things out, such as formatting (%), or modules like decimal do nothing more than powder up the display for visual consumption (turning it into a string). The underlying float value remains corrupted, and any attempt to continue with the math adapts and re-incorporates the corruption. That is not precisely correct - modf first converts decimal to a float and then applies the calculation. Try this instead: def modf(mydecimal): num = decimal.Decimal('1.0') return (mydecimal%num, mydecimal//num) On my machine this returns (with In [18]: modf(d) Out[18]: (Decimal('0.15'), Decimal('18')) Which are easily converted. In [30]: (modf(modf(d)[0]*100)[0])/decimal.Decimal('.6') Out[30]: Decimal('0.0') So your problem with decimal isn't that it lacks the precision you're seeking - you're simply converting it to a float /before/ performing the calculations, which makes turning it into a decimal in the first place pretty much useless. HTH, Wayne ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] the binary math wall
On Tue, 20 Apr 2010 09:58:06 -0700 (PDT) Lowell Tackett lowelltack...@yahoo.com wrote: I'm running headlong into the dilemma of binary math representation, with game-ending consequences, e.g.: 0.15 0.14999 [...] The last line should be zero, and needs to be for me to continue this algorithm. Any of Python's help-aids that I apply to sort things out, such as formatting (%), or modules like decimal do nothing more than powder up the display for visual consumption (turning it into a string). The underlying float value remains corrupted, You are wrong: from decimal import Decimal s = 0.15 Decimal(s) == float(s) This shows, maybe weirdly, that the decimal version != 0.14999 --since it is actually equal to 0.15. Decimals are *not* internally represented as binary values, but instead with groups of bits each coding a *decimal* digit; this is precisely the point. Else why do you think developpers would cope with such a problem? Denis vit esse estrany ☣ spir.wikidot.com ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] the binary math wall
On 04/21/10 02:58, Lowell Tackett wrote: I'm running headlong into the dilemma of binary math representation, with game-ending consequences, e.g.: Never use float for representing numbers, use float to represent a magnitude, do not rely on the exact representation of the number itself. If you need to control the representation of your number, either keep the number as integers or string or use fixed-point arithmetic (Decimal), depending on your use case. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] the binary math wall
From the virtual desk of Lowell Tackett --- On Tue, 4/20/10, Luke Paireepinart rabidpoob...@gmail.com wrote: From: Luke Paireepinart rabidpoob...@gmail.com Subject: Re: [Tutor] the binary math wall To: Lowell Tackett lowelltack...@yahoo.com Cc: tutor Tutor@python.org Date: Tuesday, April 20, 2010, 1:20 PM On Tue, Apr 20, 2010 at 11:58 AM, Lowell Tackett lowelltack...@yahoo.com wrote: I'm running headlong into the dilemma of binary math representation, with game-ending consequences, e.g.: 0.15 0.14999 Yes, floats are slightly inaccurate. But I think your problem is that your math is wrong. You are assuming... If your equations cannot handle this, then coerce the value to 1. if .999 i 1.1: i = 1 And before you say but that is just a hack, no, that is the nature... But you really just need to adapt... May I suggest another approach though? Consider this: a = 18.15 a 18.149 a = '18.15' degree, min = map(int, a.split('.')) degree 18 min 15 Supposing you get your input as a string. Basically the second you let your value end up stored as a float, there's no turning back... Eventually you will develop a distrust for floats... Hope that helps, -Luke I was gonna go out jogging - and in a coupla hours check to see if anyone had tried to take this on; going out the door I decided to take a quick look. Ahem... These responses just blow me away on a couple of levels. I'm choosing Luke's offering as representative. Within minutes some great folks had read, parsed, and re-structured my query. My narrow focus yells out my inexperience...I was trying as hard as I could, with limited tools, to solve the issue. That's fine. But...the breadth and depth of the responses represent nothing short of a paradigm shift in my window into this world of hacking. Ya'll have insights of a scale unimagined in the confines of my thinking box. (Now, I gotta go out and jog just to clear my head!) Then come back...and pull the blinds closed...and absorb; and come up for air in maybe a week or so. And only then, be able to offer my thanks with an objective sense of how much I've been helped today...Wow! ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] the binary math wall
Lowell Tackett wrote: I'm running headlong into the dilemma of binary math representation, with game-ending consequences, e.g.: 0.15 0.14999 Obviously, any attempts to manipulate this value, under the misguided assumption that it is truly 0.15 are ill-advised, with inevitable bad results. the particular problem I'm attempting to corral is thus: math.modf(18.15) (0.14858, 18.0) with some intermediate scrunching, the above snippet morphs to: (math.modf(math.modf(18.15)[0]*100)[0])/.6 1.4298 The last line should be zero, and needs to be for me to continue this algorithm. Any of Python's help-aids that I apply to sort things out, such as formatting (%), or modules like decimal do nothing more than powder up the display for visual consumption (turning it into a string). The underlying float value remains corrupted, and any attempt to continue with the math adapts and re-incorporates the corruption. What I'm shooting for, by the way, is an algorithm that converts a deg/min/sec formatted number to decimal degrees. It [mostly] worked, until I stumbled upon the peculiar cases of 15 minutes and/or 45 minutes, which exposed the flaw. What to do? I dunno. I'm throwing up my hands, and appealing to the Council. (As an [unconnected] aside, I have submitted this query as best I know how, using plain text and the tu...@... address. There is something that either I, or my yahoo.com mailer *or both* doesn't quite get about these mailings. But, I simply do my best, following advice I've been offered via this forum. Hope this --mostly-- works.) From the virtual desk of Lowell Tackett One of the cases you mention is 1.666The decimal package won't help that at all. What the decimal package does for you is two-fold: 1) it means that what displays is exactly what's there 2) it means that errors happen in the same places where someone doing it by hand will encounter. But if you literally have to support arbitrary rational values (denominators other than 2 or 5), you would need to do fractions, either by explicitly keeping sets of ints, or by using a fractions library. And if you have to support arbitrary arithmetic, there's no answer other than hard analysis. This is not a Python-specific problem. Floating point has had such issues in every language I've dealt with since 1967, when I first learned Fortran. If you compare two values, the simplest mechanism is abs(a-b) delta where you have to be clever about what small value to use for delta. If all values are made up of degrees/minutes/seconds, and seconds is a whole number, then store values as num-seconds, and do all arithmetic on those values. Only convert them back to deg/min/sec upon output. DaveA ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] the binary math wall
On Tue, 20 Apr 2010 14:45:50 -0400 Dave Angel da...@ieee.org wrote: If all values are made up of degrees/minutes/seconds, and seconds is a whole number, then store values as num-seconds, and do all arithmetic on those values. Only convert them back to deg/min/sec upon output. This seems the most direct answer of the issue. If performance is not critical, I would even write a small Angle type with ° ' '' int attributes to get rid of (read: abstract away) all complexity once and for all. Denis vit esse estrany ☣ spir.wikidot.com ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Python Examples of processing MS Outlook
-Original Message- From: tutor-bounces+mike.hansen=atmel@python.org [mailto:tutor-bounces+mike.hansen=atmel@python.org] On Behalf Of Peter Meagher Sent: Friday, April 16, 2010 3:13 AM To: tutor@python.org Subject: [Tutor] Python Examples of processing MS Outlook Greetings, I'm doing a lot of email processing at the moment. I put together some basic code from within Outlook to open my default inbox, filter email records based on text in the Subject field, then parse the body, finally send the output to a text file. This is simple stuff but very useful. I need to do more, however as a newbie with Python, I figured I could both learn and produce at the same time. Does anyone have references to simple MS Outlook 2007 processing code that I could vulture for my purposes? (The code that I adapted was from an old Office 2000 vba text, so the version 2007 may not be that essential to my purposes) After much searching, I found a reference to PyWebmail, however it communicates directly to the webmail accounts, is much more than I really need and I want to stay in the Outlook environment for a number of reasons, particularly its interface to Access. Thank you. Peter Meagher You probably need to look at Python COM. Another problem with Outlook is that it has some security that prevents other programs from controlling it in response to various virus attacks. I think there's a way around it. Mike ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] the binary math wall
On Wed, 21 Apr 2010 02:58:06 am Lowell Tackett wrote: I'm running headlong into the dilemma of binary math representation, with game-ending consequences, e.g.: 0.15 0.14999 Obviously, any attempts to manipulate this value, under the misguided assumption that it is truly 0.15 are ill-advised, with inevitable bad results. That really depends on what sort of manipulation you are doing. x = 0.15 x 0.14999 x*100 == 15 True Seems pretty accurate to me. However: 18.15*100 == 1815 False The simplest, roughest way to fix these sorts of problems (at the risk of creating *other* problems!) is to hit them with a hammer: round(18.15*100) == 1815 True [...] What I'm shooting for, by the way, is an algorithm that converts a deg/min/sec formatted number to decimal degrees. It [mostly] worked, until I stumbled upon the peculiar cases of 15 minutes and/or 45 minutes, which exposed the flaw. I'm afraid that due to the nature of floating point, this is a hard problem. Even the professionals at Hewlett-Packard's scientific calculator division don't always get it right, and they are *extremely* careful: http://www.hpmuseum.org/cgi-sys/cgiwrap/hpmuseum/archv018.cgi?read=132690 The best result I can suggest is, change the problem! Don't pass degrees-minutes-seconds around using a floating point value, but as a tuple with distinct (DEG, MIN, SEC) integer values. Or create a custom class. But if you really need D.MMSS floats, then something like this should be a good start.: def dms2deg(f): Convert a floating point number formatted as D.MMSS into degrees. mmss, d = math.modf(f) assert d == int(f) if mmss = 0.60: raise ValueError( 'bad fractional part, expected .60 but got %f' % mmss) mmss *= 100 m = round(mmss) if m = 60: raise ValueError('bad minutes, expected 60 but got %d' % m) s = round((mmss - m)*100, 8) if not 0 = s 60.0: raise ValueError('bad seconds, expected 60.0 but got %f' % s) return d + m/60.0 + s/3600.0 dms2deg(18.15) 18.25 dms2deg(18.1515) 18.2541666 which compares well to my HP-48GX: 18.15 HMS- gives 18.25, and: 18.1515 HMS- gives 18.254167. Note though that this still fails with some valid input. I will leave fixing it as an exercise (or I might work on it later, time permitting). -- Steven D'Aprano ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] the binary math wall
From the virtual desk of Lowell Tackett --- On Tue, 4/20/10, Steven D'Aprano st...@pearwood.info wrote: From: Steven D'Aprano st...@pearwood.info Subject: Re: [Tutor] the binary math wall To: tutor@python.org Date: Tuesday, April 20, 2010, 7:39 PM On Wed, 21 Apr 2010 02:58:06 am Lowell Tackett wrote: I'm running headlong into the dilemma of binary math representation, with game-ending consequences, e.g.: 0.15 0.14999 Obviously, any attempts to manipulate this value, under the misguided assumption that it is truly 0.15 are ill-advised, with inevitable bad results. That really depends on what sort of manipulation you are doing. x = 0.15 x 0.14999 x*100 == 15 True Seems pretty accurate to me. However: 18.15*100 == 1815 False The simplest, roughest way to fix these sorts of problems (at the risk of creating *other* problems!) is to hit them with a hammer: round(18.15*100) == 1815 True Interestingly, this is the [above] result when I tried entered the same snippet: Python 2.5.1 (r251:54863, Oct 14 2007, 12:51:35) [GCC 3.4.1 (Mandrakelinux 10.1 3.4.1-4mdk)] on linux2 Type help, copyright, credits or license for more information. round(18.15)*100 == 1815 False But...I'm just offering that for its' curiosity value, not to contradict your comments or the case you are making. [...] What I'm shooting...is an algorithm that converts a deg/min/sec formatted number to decimal degrees. It [mostly] worked...which exposed the flaw. I'm afraid that due to the nature of floating point, this is a hard problem. Even the professionals at Hewlett-Packard's scientific calculator division don't always get it right, and they are *extremely* careful: http://www.hpmuseum.org/cgi-sys/cgiwrap/hpmuseum/archv018.cgi?read=132690 Interesting that you raise the *hallowed* 48GX as a standard. I have one (of the two I own) sitting next to me here, and have been using it as the bar against which to compare my computer. Using the HMS+/-/- etc. functions, I get pretty darned accurate results. (Wish I'd known in time that HP was gonna throw the 48's down the drain-I would own a lot more than two of them!) The best result I can suggest is, change the problem! Don't pass degrees-minutes-seconds around using a floating point value, but as a tuple with distinct (DEG, MIN, SEC) integer values. Or create a custom class. But if you really need D.MMSS floats, then something like this should be a good start.: def dms2deg(f): Convert a floating point number formatted as D.MMSS into degrees. mmss, d = math.modf(f) assert d == int(f) if mmss = 0.60: raise ValueError( 'bad fractional part, expected .60 but got %f' % mmss) mmss *= 100 m = round(mmss) if m = 60: raise ValueError('bad minutes, expected 60 but got %d' % m) s = round((mmss - m)*100, 8) if not 0 = s 60.0: raise ValueError('bad seconds, expected 60.0 but got %f' % s) return d + m/60.0 + s/3600.0 dms2deg(18.15) 18.25 dms2deg(18.1515) 18.2541666 which compares well to my HP-48GX: 18.15 HMS- gives 18.25, and: 18.1515 HMS- gives 18.254167. Note though that this still fails with some valid input. I will leave fixing it as an exercise (or I might work on it later, time permitting). -- Steven D'Aprano ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor What you've provided with your comments is more of what I've received wholesale in this entire discourse--an incredible wealth of new insight and ways of looking at the problem. Don't think you grasp how new I am at this, and how even what little I've tried to pull off-on my own-is way out at the edge of the box for me. Someone wondered if performance was an issue that could effect my choices. Well, no. Basically, I want to manipulate [land] survey data - you know, coordinates and stuff - so the goal here is coding those things that will yield accurate number results. I've been handed, in response, comments about the challenges going all the way back to the early days of Fortran, stuff I had no concept of. This is all fantastic, and it's gonna take a long time for me to assimilate and absorb what has been offered. Even your comment concerning creating a class--my reaction is Oh, oh--classes? What'da I do NOW?! But, I've been given a great deal to chew on, and the implications go way beyond the scope of my original query. Did I get what I asked for when I posed my question? I'd say so...about 10X! Now I gotta go to work and gain some good knowledge out of this mountain of advice that's been piled on my desk! Thanks, all... ___ Tutor
Re: [Tutor] Need some info
On Tue, Apr 20, 2010 at 9:37 PM, Marco Rompré marcodrom...@gmail.comwrote: Hi! in my programming course at university, I need to create a python model with 2 concepts in a one towards many relation each of them having 2-3 properties. Also, I need to create an application with screens to add, modify, and delete the data of the model. Can someone know where I can find the information that would help me to successfully complete my assignment Check with 1) Your professor/course materials 2) Documentation at python.org And if all else fails, you can ask here if you post 1) Where you are so far 2) What you're doing that you think should work 3) What python tells you is the problem, and any other sundry details. Obviously we don't do homework here, but we're more than happy to help those who get stuck on a problem. HTH, Wayne ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor