tags:

views:

153

answers:

4

I used python to write an assignment last week, here is a code snippet

def departTime():
    '''
    Calculate the time to depart a packet.
    '''
    if(random.random < 0.8):
        t = random.expovariate(1.0 / 2.5)
    else:
        t = random.expovariate(1.0 / 10.5)
    return t

Can you see the problem? I compare random.random with 0.8, which should be random.random().

Of course this because of my careless, but I don't get it. In my opinion, this kind of comparison should invoke a least a warning in any programming language.

So why does python just ignore it and return False?

+3  A: 

Because in Python that is a perfectly valid comparison. Python can't know if you really want to make that comparison or if you've just made a mistake. It's your job to supply Python with the right objects to compare.

Because of the dynamic nature of Python you can compare and sort almost everything with almost everything (this is a feature). You've compared a function to a float in this case.

An example:

list = ["b","a",0,1, random.random, random.random()]
print sorted(list)

This will give the following output:

[0, 0.89329568818188976, 1, <built-in method random of Random object at 0x8c6d66c>, 'a', 'b']
Daan Davidsz
You can't compare and sort *everything*. Try sorting complex numbers and you'll get `TypeError: no ordering relation is defined for complex numbers`.
Robert Rossney
+1  A: 

I think python allows this because the random.random object could be overriding the > operator by including a __gt__ method in the object which might be accepting or even expecting a number. So, python thinks you know what you are doing... and does not report it.

If you try check for it, you can see that __gt__ exists for random.random...

>>> random.random.__gt__
<method-wrapper '__gt__' of builtin_function_or_method object at 0xb765c06c>

But, that might not be something you want to do.

Shrikant Sharat
I don't think `__gt__` needs to be defined in order for Python to permit a greater-than comparison between different types
Ben James
That's true, it isn't necessary, but I wanted to show that it exists for random.random anyway.
Shrikant Sharat
+9  A: 

This isn't always a mistake

Firstly, just to make things clear, this isn't always a mistake.

In this particular case, it's pretty clear the comparison is an error.

However, because of the dynamic nature of Python, consider the following (perfectly valid, if terrible) code:

import random
random.random = 9 # Very weird but legal assignment.
random.random < 10 # True
random.random > 10 # False

What actually happens when comparing objects?

As for your actual case, comparing a function object to a number, have a look at Python documentation: Python Documentation: Expressions. Check out section 5.9, titled "Comparisons", which states:

The operators <, >, ==, >=, <=, and != compare the values of two objects. The objects need not have the same type. If both are numbers, they are converted to a common type. Otherwise, objects of different types always compare unequal, and are ordered consistently but arbitrarily. You can control comparison behavior of objects of non-built-in types by defining a cmp method or rich comparison methods like gt, described in section Special method names.

(This unusual definition of comparison was used to simplify the definition of operations like sorting and the in and not in operators. In the future, the comparison rules for objects of different types are likely to change.)

That should explain both what happens and the reasoning for it.

BTW, I'm not sure what happens in newer versions of Python.

Edit: If you're wondering, Debilski's answer gives info about Python 3.

Edan Maor
+6  A: 

This is ‘fixed’ in Python 3 http://docs.python.org/3.1/whatsnew/3.0.html#ordering-comparisons.

Debilski