Akiiino
Akiiino

Reputation: 1090

Python – random is not actually random

I use this code:

class Car:
    def __init__(self):
        self.start == [0, roads[0].index('#')]
        while roads[self.start[0]][self.start[1]] == '#':
            self.start[0] = randint(0, len(roads)-1)
            self.start[1] = randint(0, len(roads[0])-1)
        self.start = tuple(self.start)

        self.finish == [0, roads[0].index('#')]
        while roads[self.finish[0]][self.finish[1]] == '#':
            self.finish[0] = randint(0, len(roads)-1)
            self.finish[1] = randint(0, len(roads[0])-1)
        self.finish = tuple(self.finish)

        self.kind = randint(0, 1)

What it does is this: in a map represented like this:

#############1#########
#############1111######
#############1##1######
#######1111111111######
#############1#########
#############1#########

it finds two 1s and sets them as start and finish, then it randomly selects one more variable. Then i do this:

a = Car()
b = Car()

only to find out that they both have always the same start and finish, but sometimes different kinds. I don't understand – if there is an issue with random not working, it shouldn't work on self.kind as well!
How do I fix it?

Upvotes: 0

Views: 100

Answers (2)

Martijn Pieters
Martijn Pieters

Reputation: 1121226

You are using an equality test here:

self.start == [0, roads[0].index('#')]

That'll fail unless you have a start attribute at the class level; it is not assigning, it is testing for equality there. You'd get a NameError here!

So, you probably do have a Car.start class attribute, and it is a mutable type, like a list:

class Car:
    start = [0, 0]

but forgot to include that in your question.

You then assign to self.start indices, the class attribute:

self.start[0] = randint(0, len(roads)-1)
self.start[1] = randint(0, len(roads[0])-1)

This is shared data as this modifies the class attribute!

Finally, you set an instance attribute:

self.start = tuple(self.start)

containing shared data. The same applies to your self.finish attribute.

You can fix this by using assignment rather than an equality test:

self.start = [0, roads[0].index('#')]

and the same applies to self.finish:

self.finish == [0, roads[0].index('#')]

You could also just use a local name here and assign only to the instance attribute once you are done constructing the lists.

Upvotes: 4

pkacprzak
pkacprzak

Reputation: 5629

Probably you should change your assignments to this:

self.start = [0, roads[0].index('#')]

and this:

self.finish = [0, roads[0].index('#')]

Right now, you are using the comparison operator.

Upvotes: 2

Related Questions