Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

how to build a street with more than 1 house ?

2 views
Skip to first unread message

Stef Mientki

unread,
Jun 6, 2008, 6:45:07 PM6/6/08
to pytho...@python.org
hello,

In the code below, I can build a large street like this:
large_street = house * 25
but not a small street. like this:
small_street = 5 * house

Why is this different ?
And more interesting, how do I get the right results ?

thanks,
Stef Mientki

class type_house ( object ) :
def __init__( self, front_doors = 1 ) :
self.front_doors = front_doors
def __mul__ ( self, b ) :
return type_house ( self.front_doors * b )

house = type_house ()
large_street = house * 25
print large_street.front_doors
small_street = 5 * house
print small_street.front_doors

Tommy Grav

unread,
Jun 6, 2008, 6:48:06 PM6/6/08
to pytho...@python.org

On Jun 6, 2008, at 6:45 PM, Stef Mientki wrote:

> hello,
>
> In the code below, I can build a large street like this:
> large_street = house * 25
> but not a small street. like this:
> small_street = 5 * house

This calls the int.__mul__() code i believe.

> Why is this different ?
> And more interesting, how do I get the right results ?

If memory serves me right look into __rmul__().

Cheers
Tommy

Message has been deleted

David C. Ullrich

unread,
Jun 7, 2008, 9:48:13 AM6/7/08
to
On Sat, 07 Jun 2008 00:45:07 +0200, Stef Mientki
<stef.m...@gmail.com> wrote:

>hello,
>
>In the code below, I can build a large street like this:
> large_street = house * 25
>but not a small street. like this:
> small_street = 5 * house
>
>Why is this different ?

Because you're multiplying on the left in one
case and on the right in the other.

You realize that house*5 should work, right?

>And more interesting, how do I get the right results ?
>
>thanks,
>Stef Mientki
>
>class type_house ( object ) :
> def __init__( self, front_doors = 1 ) :
> self.front_doors = front_doors
> def __mul__ ( self, b ) :
> return type_house ( self.front_doors * b )

The reason house*25 works is that the __mul__
method says what it should be. If you want
5*house to work you need a __rmul__.
Nothing in Python automatically makes
a*b the same as b*a; when it sees 5*house
first it checks 5 to see whether it knows
whether it knows what 5*house should be
(no, 5 never heard of this house thing), then
it checks house to see if it knows what
5*house should be (no, house has no
__rmul__).

The simplest thing is just to define __rmul__
to make multiplication commuttative:

def __rmul__(self, b):
"""Defines what b*self should return."""
return self*b

Now 5*house calls __rmul__, which
returns house*5. That in turn calls __mul__,
which returns what you want. And some day
when you modify __mul__ (in a subclass?)
you won't need to worry about making the
same change to __rmul__.

>house = type_house ()
>large_street = house * 25
>print large_street.front_doors
>small_street = 5 * house
>print small_street.front_doors

David C. Ullrich

Stef Mientki

unread,
Jun 7, 2008, 5:21:05 PM6/7/08
to python-list@python.org >> "python-list@python.org"
thanks guys,

David C. Ullrich wrote:
> On Sat, 07 Jun 2008 00:45:07 +0200, Stef Mientki
> <stef.m...@gmail.com> wrote:
>
>
>> hello,
>>
>> In the code below, I can build a large street like this:
>> large_street = house * 25
>> but not a small street. like this:
>> small_street = 5 * house
>>
>> Why is this different ?
>>
>
> Because you're multiplying on the left in one
> case and on the right in the other.
>
> You realize that house*5 should work, right?
>
>

yes.


>> And more interesting, how do I get the right results ?
>>
>> thanks,
>> Stef Mientki
>>
>> class type_house ( object ) :
>> def __init__( self, front_doors = 1 ) :
>> self.front_doors = front_doors
>> def __mul__ ( self, b ) :
>> return type_house ( self.front_doors * b )
>>
>
> The reason house*25 works is that the __mul__
> method says what it should be. If you want
> 5*house to work you need a __rmul__.
> Nothing in Python automatically makes
> a*b the same as b*a; when it sees 5*house
> first it checks 5 to see whether it knows
> whether it knows what 5*house should be
> (no, 5 never heard of this house thing), then
> it checks house to see if it knows what
> 5*house should be (no, house has no
> __rmul__).
>
> The simplest thing is just to define __rmul__
> to make multiplication commuttative:
>

Aha, now a bell begins to ring ...


> def __rmul__(self, b):
> """Defines what b*self should return."""
> return self*b
>

this works indeed ...


> Now 5*house calls __rmul__, which
> returns house*5. That in turn calls __mul__,
> which returns what you want. And some day
> when you modify __mul__ (in a subclass?)
> you won't need to worry about making the
> same change to __rmul__.
>
>

thanks for the clear explanation.

cheers,
Stef


>> house = type_house ()
>> large_street = house * 25
>> print large_street.front_doors
>> small_street = 5 * house
>> print small_street.front_doors
>>
>
> David C. Ullrich

> --
> http://mail.python.org/mailman/listinfo/python-list
>

0 new messages