Re: [Tutor] How to handle exceptions raised inside a function?
Patty wrote: This is very interesting to me - the below excerpt is something I was trying to do for one of my programs and gave up on it: A fifth approach, common in some other languages, is to return some arbitrary value, and set an error flag. The caller then has to write code like this: result = function(arguments) if not last_result_error: # no error occurred print result is, result If you do this, I will *personally* track you down and beat you to death with a rather large fish. *wink* I think I was trying to do something like thius at the end of a function I wrote- return 2 or return my_special_integer_mvar That syntax won't work. However, the basic idea is (moderately) sound: your function has a special value that means something funny happened. Python very occasionally uses this: hello world.find(z) # not found -1 which you then use like this: result = string.find(target) if result == -1: # special value print(not found) else: print(found at position %d % result) In general, this idiom is mildly disparaged in Python circles, but not forbidden. Exceptions are usually considered better. However, what I'm talking about is quite different. Here's how I might write the string find method using this (horrible) implementation: # Global status flag. find_succeeded = 0 def find(string, target): global find_succeeded if target in string: find_succeeded = 1 return string.find(target) else: find_succeeded = 0 # I never know what number to return... return 42 # that'll do... (In low-level languages like C, the number returned on failure (where I choose 42) is often whatever value happens to be in some piece of memory -- essentially a random number.) result = find(hello world, z) if find_succeeded == 1: print(found at position %d % result) else: print(not found) This is even more inconvenient and difficult than earlier. Consider what happens if you want to do two or more searches. Because they all report their status via the one global variable, you must inspect the global after each call, before making the next call, or the status will be lost. In Python you can do this: results = [s.find(target) for s in list_of_strings] and then, later, inspect each individual result to see if it was -1 or not. But with the global status idiom, you can't do that, because the status flag is lost once you call find() again. -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to handle exceptions raised inside a function?
I think I understand, I will have to reread this a couple times! But I do consider myself a C programmer so that probably explains why I was trying to write code that way. And you are right 'you must inspect the global after each call, before making the next call'. I *was* setting up the function to check on and muck with this mvar before the end where I 'return' my own thing. So for Python programming you are advising us to use one of the other four approaches to error handling and not try to do something like: call custom function, something is returned to a mvar while processing each statement, which is then examined for content and if one of three 'bad' or 'good' things are in the mvar, trying to avoid return values of [0 1 -1 2 -2] because off-the-top-of-my-head these are meaningful in various languages, so come up with 3 way-out-there-numbers-of-my-own, such as your '42'example. Then try and 'return' this from the function back to the calling function, possibly main(). Then examine return value integer and have ' if statements' doing something depending... So does this mean I am thinking through this like a C programmer? And I don't think I would be checking a variable at all using the other four ways, I would just let an error happen and let the return value be whatever it is and let the exception come up (or my custom exception handler) and handle it, instead I was trying to get right in the middle of it and force things. Also I was trying to use the return value for purposes other than error. I think what I was trying to do would be like a Case Statement really if that were supported in Python. return my_special_integer_mvar So the above will not work? If you were to try this, do you have to return digits? You can't return an mvar (and hope it doesn't change on you while going back to calling program)? Thanks for confirming my understanding or confusion as the case may be!! Patty Patty wrote: This is very interesting to me - the below excerpt is something I was trying to do for one of my programs and gave up on it: A fifth approach, common in some other languages, is to return some arbitrary value, and set an error flag. The caller then has to write code like this: result = function(arguments) if not last_result_error: # no error occurred print result is, result If you do this, I will *personally* track you down and beat you to death with a rather large fish. *wink* I think I was trying to do something like thius at the end of a function I wrote- return 2 or return my_special_integer_mvar That syntax won't work. However, the basic idea is (moderately) sound: your function has a special value that means something funny happened. Python very occasionally uses this: hello world.find(z) # not found -1 which you then use like this: result = string.find(target) if result == -1: # special value print(not found) else: print(found at position %d % result) In general, this idiom is mildly disparaged in Python circles, but not forbidden. Exceptions are usually considered better. However, what I'm talking about is quite different. Here's how I might write the string find method using this (horrible) implementation: # Global status flag. find_succeeded = 0 def find(string, target): global find_succeeded if target in string: find_succeeded = 1 return string.find(target) else: find_succeeded = 0 # I never know what number to return... return 42 # that'll do... (In low-level languages like C, the number returned on failure (where I choose 42) is often whatever value happens to be in some piece of memory -- essentially a random number.) result = find(hello world, z) if find_succeeded == 1: print(found at position %d % result) else: print(not found) This is even more inconvenient and difficult than earlier. Consider what happens if you want to do two or more searches. Because they all report their status via the one global variable, you must inspect the global after each call, before making the next call, or the status will be lost. In Python you can do this: results = [s.find(target) for s in list_of_strings] and then, later, inspect each individual result to see if it was -1 or not. But with the global status idiom, you can't do that, because the status flag is lost once you call find() again. -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to handle exceptions raised inside a function?
On Tue, Nov 30, 2010 at 13:23, Steven D'Aprano st...@pearwood.info wrote: Richard D. Moores wrote: Please take a look at 2 functions I just wrote to calculate the harmonic and geometric means of lists of positive numbers: http://tutoree7.pastebin.com/VhUnZcma. Both Hlist and Glist must contain only positive numbers, so I really need to test for this inside each function. But is there a good way to do this? What should the functions return should a non-positive number be detected? Is there a conventional Pythonic way to do this? (2) If you don't trust that a sensible exception will be raised, then do your own error checking, and raise an exception. I'll go with this one because I do want both Hlist and Glist to contain only positive real numbers. So I'll go with Jerry Hill's suggestion for both H and G. See the two revised functions at http://tutoree7.pastebin.com/VfYLpFQq. For what it's worth, I have a module of statistics functions (shameless plug: http://pypi.python.org/pypi/stats and http://code.google.com/p/pycalcstats -- feedback and bug reports welcome) An impressive collection. Thanks for sharing! that includes the harmonic and geometric mean. My harmonic mean looks like this: def harmonic_mean(data): try: m = mean(1.0/x for x in data) except ZeroDivisionError: return 0.0 if m == 0.0: return math.copysign(float('inf'), m) return 1/m math.copysign! Didn't know about that one. But mean? It's not a built-in function.. Dick Notice that if the data includes one or more zeroes, the harmonic mean itself will be zero: limit as x-0 of 1/x - infinity, and 1/infinity - 0. If the sum of reciprocals itself cancels to zero, I return the infinity with the appropriate sign. The only exceptions that could occur are: * mean will raise ValueError if the data is empty; * if an argument is non-numeric, TypeError will occur when I take the reciprocal of it. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to handle exceptions raised inside a function?
Richard D. Moores wrote: [...] def harmonic_mean(data): try: m = mean(1.0/x for x in data) except ZeroDivisionError: return 0.0 if m == 0.0: return math.copysign(float('inf'), m) return 1/m math.copysign! Didn't know about that one. But mean? It's not a built-in function.. No, it's not, it's a function from my stats module. The naive version is simple: def mean(data): return sum(data)/len(data) My version is a bit more complicated than that, in order to minimize round-off error and support iterators. -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to handle exceptions raised inside a function?
On Tue, Nov 30, 2010 at 13:23, Steven D'Aprano st...@pearwood.info wrote: For what it's worth, I have a module of statistics functions (shameless plug: http://pypi.python.org/pypi/stats and http://code.google.com/p/pycalcstats -- feedback and bug reports welcome) Your readme says: Installation stats requires Python 3.1. To install, do the usual: python3 setup.py install I'm afraid I've never fully understood instructions like that. I have Python 3.1. I now have your stats-0.1.1a. where do I put it to do the above? It's now in 3.1's site-packages. Do I CD to stats-0.1.1a and run that command? Or? Could I have put stats-0.1.1a anywhere, CD-ed to that anywhere, and then run the command? I hesitate to experiment because I don't want your files sprayed all over my hard disk. Thanks, Dick ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to handle exceptions raised inside a function?
On Thu, Dec 2, 2010 at 10:27 AM, Richard D. Moores rdmoo...@gmail.com wrote: Could I have put stats-0.1.1a anywhere, CD-ed to that anywhere, and then run the command? Yes. python setup.py install essentially instructs distutils (or setuptools or distribute - whichever is being used) to install the package into your site-packages or $PYTHONPATH (if configured that way by means of configuration). NB: Copying the package's directory into site-packages hwoever has the same effect. The directory that contains the __init__.py cheers James -- -- James Mills -- -- Problems are solved by method ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to handle exceptions raised inside a function?
On Wed, Dec 1, 2010 at 16:41, James Mills prolo...@shortcircuit.net.au wrote: On Thu, Dec 2, 2010 at 10:27 AM, Richard D. Moores rdmoo...@gmail.com wrote: Could I have put stats-0.1.1a anywhere, CD-ed to that anywhere, and then run the command? Yes. Thanks, James. Did that. Thought I'd publicize Steven's stuff a bit. I pasted the help on module stats at http://tutoree7.pastebin.com/bhcjhRuV Dick ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to handle exceptions raised inside a function?
On Tue, Nov 30, 2010 at 3:00 PM, Richard D. Moores rdmoo...@gmail.com wrote: Both Hlist and Glist must contain only positive numbers, so I really need to test for this inside each function. But is there a good way to do this? What should the functions return should a non-positive number be detected? Is there a conventional Pythonic way to do this? If the value passed to the function is illegal, you should raise a ValueError exception. Something like this in your harmonic_mean function, maybe: if not all(x 0 for x in Hlist): raise ValueError(All items in Hlist must be positive numbers.) -- Jerry ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to handle exceptions raised inside a function?
Richard D. Moores wrote: Please take a look at 2 functions I just wrote to calculate the harmonic and geometric means of lists of positive numbers: http://tutoree7.pastebin.com/VhUnZcma. Both Hlist and Glist must contain only positive numbers, so I really need to test for this inside each function. But is there a good way to do this? What should the functions return should a non-positive number be detected? Is there a conventional Pythonic way to do this? There are two basic approaches to handling errors in Python: (1) Don't do any error checking at all. If the input is bad, an exception will (hopefully!) be raised. Provided you know that bad input *will* lead to an exception, and not just plausible-looking but incorrect result, this is often the simplest way. (2) If you don't trust that a sensible exception will be raised, then do your own error checking, and raise an exception. For numeric work, another approach is to return a floating point NAN (Not A Number). Unfortunately Python doesn't give any standard way to specify *which* NAN is returned, but you can return float(nan) to return one of them. A fourth approach, rare in Python, is to return some sort of magic value to indicate an exceptional case. Just about the only example of this I can think of is string.find(), which returns -1 to indicate not found. A fifth approach, common in some other languages, is to return some arbitrary value, and set an error flag. The caller then has to write code like this: result = function(arguments) if not last_result_error: # no error occurred print result is, result If you do this, I will *personally* track you down and beat you to death with a rather large fish. *wink* For what it's worth, I have a module of statistics functions (shameless plug: http://pypi.python.org/pypi/stats and http://code.google.com/p/pycalcstats -- feedback and bug reports welcome) that includes the harmonic and geometric mean. My harmonic mean looks like this: def harmonic_mean(data): try: m = mean(1.0/x for x in data) except ZeroDivisionError: return 0.0 if m == 0.0: return math.copysign(float('inf'), m) return 1/m Notice that if the data includes one or more zeroes, the harmonic mean itself will be zero: limit as x-0 of 1/x - infinity, and 1/infinity - 0. If the sum of reciprocals itself cancels to zero, I return the infinity with the appropriate sign. The only exceptions that could occur are: * mean will raise ValueError if the data is empty; * if an argument is non-numeric, TypeError will occur when I take the reciprocal of it. -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to handle exceptions raised inside a function?
This is very interesting to me - the below excerpt is something I was trying to do for one of my programs and gave up on it: A fifth approach, common in some other languages, is to return some arbitrary value, and set an error flag. The caller then has to write code like this: result = function(arguments) if not last_result_error: # no error occurred print result is, result If you do this, I will *personally* track you down and beat you to death with a rather large fish. *wink* I think I was trying to do something like thius at the end of a function I wrote- return 2 or return my_special_integer_mvar and then do something or other depending on this value once it passes back to calling function or main(). I think I used similar code as you have above. It didn't go well and also there seemed to be a problem related to where I was returning this value _to_ (where I actually placed this snippet of code like you wrote above) - a function or module I wrote or main(). So, could you expand on this for me? I would have to dig around to find the actual program I was working on. Thanks, Patty - Original Message - From: Steven D'Aprano st...@pearwood.info To: tutor@python.org Sent: Tuesday, November 30, 2010 1:23 PM Subject: Re: [Tutor] How to handle exceptions raised inside a function? Richard D. Moores wrote: Please take a look at 2 functions I just wrote to calculate the harmonic and geometric means of lists of positive numbers: http://tutoree7.pastebin.com/VhUnZcma. Both Hlist and Glist must contain only positive numbers, so I really need to test for this inside each function. But is there a good way to do this? What should the functions return should a non-positive number be detected? Is there a conventional Pythonic way to do this? There are two basic approaches to handling errors in Python: (1) Don't do any error checking at all. If the input is bad, an exception will (hopefully!) be raised. Provided you know that bad input *will* lead to an exception, and not just plausible-looking but incorrect result, this is often the simplest way. (2) If you don't trust that a sensible exception will be raised, then do your own error checking, and raise an exception. For numeric work, another approach is to return a floating point NAN (Not A Number). Unfortunately Python doesn't give any standard way to specify *which* NAN is returned, but you can return float(nan) to return one of them. A fourth approach, rare in Python, is to return some sort of magic value to indicate an exceptional case. Just about the only example of this I can think of is string.find(), which returns -1 to indicate not found. A fifth approach, common in some other languages, is to return some arbitrary value, and set an error flag. The caller then has to write code like this: result = function(arguments) if not last_result_error: # no error occurred print result is, result If you do this, I will *personally* track you down and beat you to death with a rather large fish. *wink* For what it's worth, I have a module of statistics functions (shameless plug: http://pypi.python.org/pypi/stats and http://code.google.com/p/pycalcstats -- feedback and bug reports welcome) that includes the harmonic and geometric mean. My harmonic mean looks like this: def harmonic_mean(data): try: m = mean(1.0/x for x in data) except ZeroDivisionError: return 0.0 if m == 0.0: return math.copysign(float('inf'), m) return 1/m Notice that if the data includes one or more zeroes, the harmonic mean itself will be zero: limit as x-0 of 1/x - infinity, and 1/infinity - 0. If the sum of reciprocals itself cancels to zero, I return the infinity with the appropriate sign. The only exceptions that could occur are: * mean will raise ValueError if the data is empty; * if an argument is non-numeric, TypeError will occur when I take the reciprocal of it. -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor