Reputation: 13
Text in italic can be skipped.
First of all: Forgive me if what I'm asking for is basic knowledge, easy to find answers too, or anything similar that may make my post annoying to anyone. I'm new to programming, and just started it to have an excuse not to read for exams. I'm trying to make a program that can kind of mimic evolution from a tribe of humans to..well, a more advanced tribe of humans. My goal is to some time in the future make a very simple Civilization-like game that focuses on people rather than buildings and units. Starting from scratch, knowing pretty much nothing about programming at the moment, i know this is a task I will probably never complete. Hopefully I'll learn something on the way though. Because my knowledge is so limited, my questions will be clumsy and badly formulated. I'm sorry, thanks for reading.
The current problem: I've made a class that makes objects that are supposed to represent people.
The class looks like this at the moment:
class Settler:
settlerCount = 0
iqlistfemale = []
iqlistmale = []
maleCount = 0
femaleCount = 0
surnameMale = []
surnameFemale = []
def __init__(self, sex):
if sex=="m" or sex=="f" or sex=="M" or sex=="F":
self.name = choice(surnames)
Settler.settlerCount += 1
self.iq=round(random.normalvariate(100,10))
if sex=="m" or sex=="M":
self.sex = "Male"
Settler.iqlistmale=Settler.iqlistmale+[self.iq]
Settler.surnameMale += [self.name]
Settler.maleCount += 1
else:
self.sex = "Female"
Settler.iqlistfemale=Settler.iqlistfemale+[self.iq]
Settler.surnameFemale += [self.name]
Settler.femaleCount += 1
It will contain way more attributes later, this is just a beginning.
I've also made a loop that will ask you for an amount of males to create, and then an amount of females to create.
The loop-thing looks like this:
x=int(input("Number of male Settlers to generate? (1-20) "))
if x >0 and x <21:
tellergenerator=0
while tellergenerator<x:
Settler("M")
tellergenerator=tellergenerator+1
else:
print("Wrong input!")
x=int(input("Number of female Settlers to generate? (1-20) "))
if x >0 and x <21:
tellergenerator=0
while tellergenerator<x:
Settler("F")
tellergenerator=tellergenerator+1
else:
print("Wrong input!")
Also, I've made a def thing that will allow you to call for information on the attributes of an object:
def displaySettler(self):
print("Name:", self.name, "Sex:", self.sex, "IQ:", self.iq)
Now, for the questions:
I've found a way to combine a number to a string, which might allow me to put into the loop a system that creates object names like settler1, settler2, settler3, but the way I do that is to do something like
x=settler
y=(some counter)
z=x+str(y)
Is that something I can use? The only way I know to create my objects with name is by writing something like
settler1=Settler("F")
or
w=Settler("F")
is it possible to use the contents of variable z to name something?
Is it possible to get those values directly from the objects, and go through all the objects directly and calculate the average from that?
Or to put it another way: If I have 200 objects, is there some way to get the IQs of all the objects added together?
Thanks for reading (if anyone got this far). All constructive feedback will be much appreciated.
Upvotes: 1
Views: 2728
Reputation: 214949
Two things:
1) it's better to have two distinct classes, Male and Female, both of them extend the base class Settler
. Thus you avoid the most of if sex = M then this else that
stuff
Example:
class Settler:
def __init__(self, name):
self.name = name
self.iq = round(random.normalvariate(100,10))
class Male(Settler):
def __str__(self):
return '{0.name}, male, iq {0.iq}'.format(self)
class Female(Settler):
def __str__(self):
return '{0.name}, female, iq {0.iq}'.format(self)
Note how both classes use __str__
to "represent" themselves in a string form.
2) keep all stuff concerning lists of objects outside of objects definitions. Good objects don't know what's happening outside them. For example, this is how to generate a list of people:
def generate(klass, how_many):
surnames = ['Doe', 'Smith', 'Mueller', 'Polly-Parrot']
return [klass(random.choice(surnames)) for _ in range(how_many)]
people = generate(Male, 10) + generate(Female, 20)
[stuff for _ in range(N)]
basically means "do stuff N times".
Finally, let's put it all together and print a list of people:
for person in people:
print(person)
The output will be something like:
Doe, male, iq 114.0 Doe, male, iq 110.0 Polly-Parrot, male, iq 89.0 Smith, male, iq 96.0 Polly-Parrot, male, iq 83.0 Mueller, female, iq 118.0 Mueller, female, iq 90.0 Smith, female, iq 90.0 Smith, female, iq 103.0 Mueller, female, iq 89.0 Smith, female, iq 87.0
Let us know if you have more questions.
Upvotes: 1
Reputation: 63
Edit: Sr2222 beat me to it. I think we are using the same idea.
Not sure if this is the best way, but:
You are able to store objects in a dict, using names generated from a loop.
As an example:
group_of_vars = {}
for name in range(5):
entry = 'object_'+str(name)
group_of_vars[name] = entry
print group_of_vars
print group_of_vars
{0: 'object_0', 1: 'object_1', 2: 'object_2', 3: 'object_3', 4: 'object_4
Therefore
>>> print group_of_vars[1]
object_1
So by using this knowledge, you could make a list of variable names (auto-generated or manually) and keep it in a list. Then reference the name of the list as your range in the for-loop, and refer to each variable in that list.
As for getting the sum of all IQ's of the objects added together, you could do (following my earlier example, assume that the entries in the dict are objects with iq property values)
sum = 0
for name in group_of_vars:
sum += group_of_vars[name].iq
>>> print sum
This should return the sum of the iq property of all objects in the dict group_of_vars.
Upvotes: 0
Reputation: 3981
in response to your second question, and let's say that you had a list of Settlers called people
(this is a list comprehension)...
iqs = [person.iq for person in people]
total_iq = sum(iqs)
Upvotes: 0
Reputation: 26150
You need to have your person generator record the generated people in a data structure, such as a list or dictionary, then access those people from that created structure. In place of your while
loop, try:
people = []
for i in range(x):
people.append(Settler('M')) # or 'F', for the other loop
Then you can use:
people[n].displaySettler() # where n is any integer from 0 to x-1
Upvotes: 3