On 2014-04-20 17:22, Ian Kelly wrote:
On Apr 19, 2014 2:54 PM, "Chris Angelico" <ros...@gmail.com <mailto:ros...@gmail.com>> wrote: > > On Sun, Apr 20, 2014 at 6:38 AM, Ian Kelly <ian.g.ke...@gmail.com <mailto:ian.g.ke...@gmail.com>> wrote: > >> Or you just cast one of them to float. That way you're sure you're > >> working with floats. > > > > Which is inappropriate if the type passed in was a Decimal or a complex. > > In that case, you already have a special case in your code, so whether > that special case is handled by the language or by your code makes > little difference. Is your function so generic that it has to be able > to handle float, Decimal, or complex, and not care about the > difference, and yet has to ensure that int divided by int doesn't > yield int? Then say so; put in that special check. Personally, I've > yet to meet any non-toy example of a function that needs that exact > handling; most code doesn't ever think about complex numbers, and a > lot of things look for one specific type: When I'm writing a generic average function, I probably don't know whether it will ever be used to average complex numbers. That shouldn't matter, because I should be able to rely on this code working for whatever numeric type I pass in: def average(values): return sum(values) / len(values) This works for decimals, it works for fractions, it works for complex numbers, it works for numpy types, and in Python 3 it works for ints. > Maybe it's not your code that should be caring about what happens when > you divide two integers, but the calling code. If you're asking for > the average of a list of numbers, and they're all integers, and the > avg() function truncates to integer, then the solution is to use sum() > and explicitly cast to floating point before dividing. First, that's not equivalent. Try the following in Python 3: values = [int(sys.float_info.max / 10)] * 20 print(average(values)) Now try this: print(average(map(float, values))) I don't have an interpreter handy to test, but I expect the former to produce the correct result and the latter to raise OverflowError on the call to sum.
Python 3.4.0 (v3.4.0:04f714765c13, Mar 16 2014, 19:25:23) [MSC v.1600 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information. >>> import sys >>> def average(values): ... return sum(values) / len(values) ... >>> values = [int(sys.float_info.max / 10)] * 20 >>> print(average(values)) 1.7976931348623158e+307 >>> print(average(map(float, values))) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in average TypeError: object of type 'map' has no len() >>> print(average(list(map(float, values)))) inf >>> In fact, that's true back to Python 3.1
Second, why should the calling code have to worry about this implementation detail anyway? The point of a generic function is that it's generic.
-- https://mail.python.org/mailman/listinfo/python-list