Reputation: 8131
I'm working on my first object oriented bit of python and I have the following:
#!/usr/bin/python
import random
class triangle:
# Angle A To Angle C Connects Side F
# Angle C to Angle B Connects Side D
# Angle B to Angle A Connects Side E
def __init__(self, a, b, c, d, e, f):
self.a = a
self.b = b
self.c = c
self.d = d
self.e = e
self.f = f
#def solver:
#pass
#initialize Triangle
myTri = triangle(0,0,0,0,0,0)
#Pick Three Random Angles or Sides to Generate Values For
sample = random.sample([myTri.a, myTri.b, myTri.c, myTri.d, myTri.e, myTri.f], 3)
#Sets the three randomly picked variables to a Random Number
sample[0] = random.randint(1, 100)
sample[1] = random.randint(1, 100)
sample[2] = random.randint(1, 100)
How do I pass myTri.a, for example to random.randint. It is passing the value of '0' which it initialized. I want to be able to assign a random value to three of the .a-.f attributes of myTri. What am I missing?
Upvotes: 1
Views: 420
Reputation: 82934
Alternative to using setattr: do it when you create a Triangle instance.
args = [random.randint(1, 100) for i in xrange(3)] + [0, 0, 0]
random.shuffle(args)
my_tri = Triangle(*args)
Upvotes: 0
Reputation: 361710
When you say [myTri.a, myTri.b, ...]
you are not getting a list of the variables themselves, or references to them. Instead you are getting just their values. Since you know they were initialized to 0
, it is as if you had written [0, 0, 0, 0, 0, 0]
. There's no difference.
Then later when you try to assign to sample[0]
, you are actually just overwriting the 0 that is stored in that array with a random value. Python knows nothing at all about myTri
at that point; the connection is lost.
Here's what you can do to get the effect you're aiming for. First, pass a list of variable names we want to assign to later to random.sample
:
sample = random.sample(["a", "b", "c", "d", "e", "f"], 3)
That'll give us back 3 random variable names. Now we want to assign to the variables with those same names. We can do that by using the special setattr
function, which takes an object and a variable name and sets its value. For instance, setattr(myTri, "b", 72)
does the same thing as myTri.b = 72
. So rewritten we have:
setattr(myTri, sample[0], random.randint(1, 100))
setattr(myTri, sample[1], random.randint(1, 100))
setattr(myTri, sample[2], random.randint(1, 100))
The major concept here is that you're doing a bit of reflection, also known as introspection. You've got dynamic variable names--you don't know exactly who you're messing with--so you've got to consult with some more exotic, out of the way language constructs. Normally I'd actually caution against such tomfoolery, but this is a rare instance where introspection is a reasonable solution.
Upvotes: 5
Reputation:
To assign to a
, b
, and c
:
myTri.a = random.randint(1, 100)
myTri.b = random.randint(1, 100)
myTri.c = random.randint(1, 100)
To assign to one random attribute from a
-f
:
attrs = ['a', 'b', 'c', 'd', 'e', 'f']
setattr(myTri, random.choice(attrs), random.randint(1, 100))
To assign to three random attributes from a
-f
:
attrs = ['a', 'b', 'c', 'd', 'e', 'f']
for attr in random.sample(attrs, 3):
setattr(myTri, attr, random.randint(1, 100))
Upvotes: 2