Different Random Numbers Between Already/Not Yet Compiled Code

Eric Eide eeide at cs.utah.edu
Fri Jan 25 11:11:49 EST 2002


"Tim" == Tim Peters <tim.one at home.com> writes:

	Tim> [...] but Python won't *let* you use instances as dict keys unless
	Tim> you define both or neither of
	Tim> 
	Tim> 1. __hash__
	Tim> 2. One of {__cmp__, __eq__}

Well, it let me, AFAIK.  See the code below, which uses instances of `Product'
as dictionary keys.

	Tim> Since Eric said he doesn't define __hash__, but is using these
	Tim> guys as dict keys, that implies he isn't defining __cmp__ (or
	Tim> __eq__) either.  So if he's using the default .sort(), he is
	Tim> sorting by memory address.  It's possible that he's using a custom
	Tim> sort function, though.

Yes, I give a lambda to `sort'.

	Tim> Eric, show us some code instead of trying to describe what you're
	Tim> doing.  It's Python code: it's easier to read than to describe
	Tim> <wink>.

All right, if you insist.  Boiling down the relevant bits of my program gives
the following:

-----
import random

class Product:
    def __init__(self, id):
        self.id_ = id

    def get_id(self):
        return self.id_

class Model:
    def __init__(self, product_id_list, seed=None):
        if seed is not None:
            random.seed(seed)
        self.products_ = map(Product, product_id_list)
        self.product_weights_ = self.make_base_product_weights()

    default_weight = 100

    def make_base_product_weights(self):
        weights = { }
        for p in self.products_:
            weights[p] = Model.default_weight
        return weights

    def make_customer_product_weights(self):
        weights = self.product_weights_.copy()
        stddev = 0.2
        pairs = weights.items()
        # Added following call to `sort'; see discussion below,
        pairs.sort(lambda a, b: a[0].get_id() - b[0].get_id())
        for pair in pairs:
            this_product = pair[0]
            this_weight = pair[1]
            new_weight = int(this_weight * random.gauss(1.0, stddev))
            weights[this_product] = new_weight
        return weights

# e.g.:
# m = Model([1,2,3,4,5],1)

-----

For sufficiently large models, I was getting unpredictable results from
`make_customer_product_weights', because I was iterating over the products in
an unpredictable order.  So I added the call to `sort', and now my simulation
produces predictable results.

Also, as a result of Tim's previous good advice, I subsequently added `__cmp__'
and `__hash__' methods to my Product class.

Thanks again for all the help!

Eric.

-- 
-------------------------------------------------------------------------------
Eric Eide <eeide at cs.utah.edu>  .         University of Utah School of Computing
http://www.cs.utah.edu/~eeide/ . +1 (801) 585-5512 voice, +1 (801) 581-5843 FAX



More information about the Python-list mailing list