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

Reply via email to