How about adding rational fraction to Python?

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Thu Feb 28 02:05:27 EST 2008


On Wed, 27 Feb 2008 18:43:24 -0800, Paul Rubin wrote:

> Steven D'Aprano <steve at REMOVE-THIS-cybersource.com.au> writes:
>> def pmean(data):  # Paul Rubin's mean
>>     """Returns the arithmetic mean of data, unless data is all ints, in
>>     which case returns the mean rounded to the nearest integer less
>>     than the arithmetic mean."""
>>     s = sum(data)
>>     if isinstance(s, int): return s//len(data)
>>     else: return s/len(data)
> 
> Scheme and Common Lisp do automatic conversion and they thought out the
> semantics rather carefully, and I think both of them return exact
> rationals in this situation (int/int division).

Potentially better than returning a float, but equally objectionable to 
all those insisting that int <op> int should only return an int.


> I agree with you that
> using // as above is pretty weird and it may be preferable to raise
> TypeError on any use of int/int (require either an explicit conversion,
> or use of //).


Then you have completely misunderstood my objection.

It's not that // is weird, but that the semantics that you want by 
default:

"return the mean for arbitrary numeric data, except for all ints, in 
which case return the mean rounded to the next smaller integer"

is weird. Weird or not, if you want those semantics, Python gives you the 
tools to create it, as above. It's not even very much more work.

But the normal semantics:

"return the mean for arbitrary numeric data"

should be easier, and with Python it is:

def mean(data): return sum(data)/len(data)

That does the right thing for data, no matter of what it consists of: 
floats, ints, Decimals, rationals, complex numbers, or a mix of all of 
the above.

You want the pmean() case to be easy, and the mean() case to be hard, and 
that's what boggles my brain.



-- 
Steven



More information about the Python-list mailing list