Related
I'm working on a school project which has to store the names of people and their respective score on a test in a list so that I can manipulate it to find averages as well as printing out each persons score with their name. Relatively new to Python so any help is appreciated :)
I would recommend using a dictionary. This pairs keys (the name of students) to values (the score on a test). Here is an example below that gets you the output that you would want.
import math
student_scores = {}
student_scores['Rick'] = 89
student_scores['Pat'] = 79
student_scores['Larry'] = 82
score_list = []
for name, score in student_scores.items():
score_list.append(score)
print(name.title() + "'s score was: " + str(score) + '%')
sum_scores = sum(score_list)
division_scores = len(score_list)
average_score = sum_scores / division_scores
print('The average score was {0:.2f}%'.format(average_score))
I created an empty dictionary that you will use to add student names and scores to a list. So in the dictionary (student_scores) The student name 'Rick' will be a key, and the score 89 will the value. I do this for 2 additional students, pairing their name up with the score that they received.
I create an empty list called score_list. You'll use this list later to add he sum of all scores, and divide by the number of total scores to get an average score for your test.
We start a for loop that iterates over each key and value in your dictionary. For each score, we append it to the empty score list. For each name and score, we print a message showing what the student got on the test.
Now that we have appended the scores to the dictionary we can use the sum method to get the sum of all scores in your score list. We put it in a variable called sum_scores. We also get the number of scores in your list by finding the length of the list (which will be 3 in this case since I put 3 scores in it). We will store that in a variable called division_scores (since I am dividing the sum of all scores by the number of scores recorded). We create a variable called average_score which is the result of the sum of scores divided by the total number of observations.
We then print what the average score was using the .format() method. We just format the average score so that you get it to extend two decimal places {0:.2f}%.
Your output is as follows:
Rick's score was: 89%
Pat's score was: 79%
Larry's score was: 82%
The average score was 83.33%
The above answer is a great data structure for pairing strings. It'll set you on the right track for enumerating scores, averages, etc in simple cases.
Another way to store relationships is with classes (or tuples, at the bottom!) There's a rough sketch of an OOP approach below.
The most important parts are
The properties of the ExamAttempt class store the information (names, scores)
In the Exam.record_attempt method, a new ExamAttempt object is created from the ExamAttempt class and added to the list of attempts on the Exam object.
From here, you could easily add other features. You'd probably want to model a Question and Answer, and maybe a Student object too, if you're going all out. If you store questions and answers, as well as which answer each student selected, you can start doing things like throwing out questions, grading on a curve, discovering questions to throw out, etc. The OOP approach makes it easier to extend functionality like plotting all kinds of fancy graphs, export to CSV or Excel, and so on.
Not all of the code below is necessary.. it can definitely be simplified a little, or reimagined entirely, but hopefully this should give you enough to start looking down that path. Even if it seems complicated now, it's not that bad, and it's what you'll want to be doing eventually (with Python, anyway!)
class ExamAttempt:
def __init__(self, id, name, correct, total):
self.id = id
self.name = name
self.correct = correct
self.total = total
self.score = (self.correct / float(self.total))
def __repr__(self):
return "<ExamAttempt: Id={}, Student={}, Score={}>".format(self.id, self.name, self.score)
class Exam:
def __init__(self, name, questions):
self.name = name
self.attempts = []
self.questions = questions
self.num_questions = len(questions)
def __str__(self):
return "<Exam ({})>".format(self.name)
def load(self, filename):
pass
def saveAttemptsToFile(self, filename):
pass
def record_attempt(self, student_name, num_correct):
id = len(self.attempts) + 1
self.attempts.append(
ExamAttempt(id, student_name, num_correct, self.num_questions))
def get_student_attempt(self, student_name):
for att in self.attempts:
if student_name == att.name:
return att
def get_average_score(self):
return "homework"
def get_results_by_score(self):
return sorted(self.attempts, key=lambda x: x.score, reverse=True)
def get_attempts_by_name(self):
return sorted(self.attempts, key=lambda x: x.name)
if __name__ == '__main__':
questions = ['Question?' for i in range(100)] # Generate 100 "questions" = 100%
exam = Exam('Programming 101', questions)
data = [('Rick', 89), ('Pat', 79), ('Larry', 82)]
for name, correct in data:
exam.record_attempt(name, correct)
for attempt in exam.get_results_by_score():
print("{} scored {}".format(attempt.name, attempt.score))
So this is what my GUI looks like:
GUI
,and where i need help with is if i type a subject code it must show all the students with the that particular subject. Here is my code for the search function and add function:
def add_student():
Sname = Student_name.get()
Ssurnname = Student_surname.get()
Sdetail = Student_detail.get()
Snumber = Student_number.get()
i = Students(Sname,Ssurnname,Sdetail,Snumber)
Sinfo.append(i)
iName = Student_subject.get()
iCode = Student_code.get()
iMark1 = Student_Mark1.get()
iMark2 = Student_Mark2.get()
iMark3 = Student_Mark3.get()
iProject = Student_project.get()
j = Subjects(iName,iCode,iMark1,iMark2,iMark3,iProject)
SSubject.append(j)
kCourse = Degree_course.get()
kCode = Degree_code.get()
kYear = Degree_year.get()
v = Degrees(kCourse,kCode,kYear)
SDegree.append(v)
popup_add()
student_list.append(Sinfo)
student_list.append(SSubject)
student_list.append(SDegree)
def filter_data():
top3 = Toplevel()
top3.geometry('300x300')
top3.title("Search")
Searchlabel = Label(top3, text = "Please enter the Subject code: ")
Searchlabel.grid(column=1, row=1, sticky = (W,E))
searchValue = StringVar()
top3.searchBox = ttk.Entry(top3, textvariable=searchValue).grid(column=1, row=2, sticky = (W,E))
def searchdata(*args):
print("*")
resultList.delete(0,END)
searchkey = searchValue.get()
for student in student_list:
if searchkey == student[0]:
resultList.insert(END,str(student))
elif searchkey == student[1]:
resultList.insert(END,str(student))
top3.button_1 = Button(top3, text = "Search", command = searchdata)
top3.button_1.grid(column=3, row=2, sticky = (W,E))
Observations
In the code you posted, it appears that student_list is a list with exactly three elements: a list of Students objects, a list of Subjects objects, and a list of Degrees objects. I make that observation based on these lines of code:
...
Sinfo.append(i)
...
SSubject.append(j)
...
SDegree.append(v)
...
student_list.append(Sinfo)
student_list.append(SSubject)
student_list.append(SDegree)
I have no way of knowing if that's your intent, or if that's the first bug. I also have no way of knowing if it will always have exactly three or more than three (but always a multiple of three).
Assuming that it's intentional that student_list will always have exactly three elements, this loop is incorrect:
for student in student_list:
if searchkey == student[0]:
resultList.insert(END,str(student))
The first time through the loop, student will itself be a list of Students. The second time through the loop, student will be a list of Subjects), and the third time through it will be a list of Degrees.
Suggestions
Assuming that your data structures are intentional and that your ultimate goal is to be able to generate a list of students based on a given subject code, you will need to iterate over the list of subjects, not students.
Given the current code structure, you would need to do something like this (using a temporary variable subjects for clarity):
subjects = student_list[1]
for subject in subjects:
...
However, given that the students are in one list but the subjects are in another, you need to keep track of the index in the list of the subjects so that you can use the same index to reference the related student.
Note: This would be much easier if the subjects were an attribute of the student, so you might want to consider making the subjects and degrees attributes of a student.
We can keep track of the index within the list of subjects by using python's enumerate function:
for index, subject in enumerate(subjects):
...
Within the loop, you need to compare what the user entered with the subject code, and if you find it, you need to insert the corresponding student in the window.
Without knowing for certain, I'm going to assume that the Subjects class provides the subject code as the attribute code. I have no way of knowing if that's a correct assumption.
students = student_list[0]
subjects = student_list[1]
for index, subject in enumerate(subjects):
if searchkey == subject.code:
this_student = students[index]
resultList.insert(END, str(thisstudent))
Solving the problem through better data structures
The real solution to your problem might be to rethink some of your design choices. Instead of keeping student info, student subjects, and student grades in three separate lists, you might want to consider creating a Student class that has the info, subjects and lists as attributes. With that, all of the data for a student is in one place.
For example:
class Student(object):
def __init__(self, info, subjects, grades):
self.info = info
self.subjects = subjects
self.grades = grades
You would then create student_list like this:
student_list.append(Student(Sinfo, SSubject, SDegree))
With that you can loop over these students in a slightly more easy and understandable way:
for student in student_list:
for subject in student.subjects:
if subject.code == searchkey:
resultList.insert(END, str(student.info))
You can make this even easier by creating a method that can do the test for you:
class Student(object):
def has_subject(code):
for subject in self.subjects:
if subject.code == code:
return True
return False
Then, your loop becomes even clearer:
for student in student_list:
if student.has_code(searchkey):
resultList.insert(END, str(student.info))
Final thoughts
My answer could be wrong, because your question lacks a considerable amount of information. This is why we ask for a Minimal, Complete, and Verifiable Example that actually runs. Without it, we have to make many guesses and assumptions about your code. If the assumptions are bad, I will have wasted half an hour addressing the wrong problem, and you will have wasted time reading an answer that isn't relevant.
Finally, it would be easier for you to get help if you were to write code that conforms to PEP8 naming standards. Your code is difficult to read because of your unconventional use of uppercase characters. People tend to not want to provide answers to code that is difficult to read.
I have two instances in my program: agents and firms.
I want a new class to work so that I can control the assignment of agents to firms.
The class I created has two dictionaries. I add posts and candidates to each dictionary. Each dictionary is keyed by the firm or agent ID. I had it work in other modules of my program.
I call the method to assign_post that would match candidates to posts. But it does not seem to work.
The whole class is:
class Posting(object):
def __init__(self):
self.available_postings = {}
self.candidates = {}
def add_post(self, firm):
self.available_postings[firm.get_firm_id()] = firm
def add_candidate(self, agent):
self.candidates[agent.get_id()] = agent
def assign_post(self):
# Rank positions by wage and rank employees by qualifications
# Make a match
while len(self.candidates) > 0 and len(self.available_postings) > 0:
# Best qualification
dummy_best = self.candidates.popitem()
for key in self.candidates.keys():
if dummy_best.get_qual() > self.candidates[key].get_qual():
dummy_best = self.candidates[key]
# Higher wage
dummy_higher = self.available_postings.popitem()
for key in self.available_postings.keys():
if dummy_higher.set_wage_base() > self.available_postings[key].set_wage_base():
dummy_higher = self.available_postings[key]
# Assignment. Firm has method add_employee
dummy_higher.add_employee(dummy_best)
# Remove agent and firm from list
del self.available_postings[dummy_higher.get_firm_id()]
del self.candidates[dummy_best.get_id()]
The mistake in your code is that you lose the item that received frompopitem(), in the case where it is not the best/higher. Try to receive element without removing it from dict, do assignment and after that remove it.
I'm currently studying Computer Science at GCSE level, and am nearing my first controlled assessment. Last week we moved onto learning about lists, but for the purpose of this weeks assignment, we need to create an improved version of our address book task using a 2D array. The purpose of the task is to allow the user to enter as many people as they require into an address book, and ask them for four pieces of information. This information is to be then printed onto the screen underneath.
Be that as it may, I'm encountering an error when entering more than one person into the address book, with the error list index out of range. I've read some posts on here already about the aforementioned error, but still don't seem to quite understand it fully. Any aid would be highly appreciated.
Here is my code thus far:
addressbook = ([])
number = int(input("How many people would you like in your address book:"))
for loop in range (0,number,1):
addressbook.append([(str(input("\nPlease enter your full name:")))])
addressbook.append([(str(input("Please enter your home address:")))])
addressbook.append([(str(input("Please enter your hometown:")))])
addressbook.append([(str(input("Please enter your mobile number:")))])
print("\nName:",addressbook[0][loop],"\nHomeaddress:",addressbook[1][loop],"\nHometown:",addressbook[2][loop],"\nMobile number:",addressbook[3][loop])
With the following error appearing:
Traceback (most recent call last):
File "C:\Users\Owner\Documents\Computer Science\Python\Address%20book.py", line 23, in <module>
print("\nName:",addressbook[0][loop],"\nHomeaddress:",addressbook[1][loop],"\nHometown:",addressbook[2][loop],"\nMobile number:",addressbook[3][loop])
IndexError: list index out of range
Rather than think of addressbook as a two-dimensional array of information about people, think of each dimension separately. An addressbook is a one-dimensional array of persons. Each person is, in turn, a one-dimensional array of information.
Bringing that thinking to our code can make the purpose much clearer:
# An address boook is an arary of persons
addressbook = []
number = int(input("How many people would you like in your address book:"))
# Create several persons, adding each to addressbook as we go:
for _ in range(number):
# Create one person:
person = []
person.append(str(input("\nPlease enter your full name:")))
person.append(str(input("Please enter your home address:")))
person.append(str(input("Please enter your hometown:")))
person.append(str(input("Please enter your mobile number:")))
# Add one person to addressbook
addressbook.append(person)
# Now addressbook has several persons
# Display addressbook, thinking of it as two-dim array
for loop in range(number):
print("\nName:",addressbook[loop][0],"\nHomeaddress:",addressbook[loop][1],"\nHometown:",addressbook[loop][2],"\nMobile number:",addressbook[loop][3])
# Display addressbook, thinking of it as array of persons:
for person in addressbook:
print("\nName:",person[0],"\nHomeaddress:",person[1],"\nHometown:",person[2],"\nMobile number:",person[3])
Other notes:
The statement addressbook = ([]) is identical to addressbook = []. Parentheses in that context do absolutely nothing.
Multi-dimensional arrays list the row number first, the column second. That is to say, the first number gets you to a row, and the 2nd number gets you to an element of that row. More simply, say addressbook[loop][0], not addressbook[0][loop].
The expression range(0, number,1) is identical to range(number), and the latter is easier to read.
In Python, if you need to assign a value but don't care about it further, use _, like so: for _ in range(number):.
The expression str(input(...)) is identical to the expression input(...), since input returns an object of type str. I left those alone because I suppose that verbose style is required by your instructor.
When the time comes, learn about breaking long expressions into multiple lines. Many people find that a line longer than about 80 characters is difficult to read.
You prompt the user "Please enter your full name" (emphasis added) each time. Presumably their name hasn't changed since the previous iteration of the loop. You are actually asking for some third party's full name. Try "Please enter their full name" or "Please enter this person's full name" or some such.
Finally, realize that computer programs will be read more often than they are written. This is true for professionally-maintained programs with hundreds of contributing programmers and also of one-off programs written by you for your own benefit. Use any means necessary to communicate effectively with the reader(s) of your program--comments, clear variable names, whitespace, whatever it takes.
First, Rob's explanation above is perfect for your assignment.
Now, I wanted to show you a few techniques, you can use, to make your life easier, without entering in OOP concepts and keeping the code as simple as possible, without error catching or whatsoever.
from collections import namedtuple
Person = namedtuple(
'Person',
('full_name', 'home_address', 'home_town', 'mobile_number')
)
person_print_template = '''
Full Name: {full_name}
Home Address: {home_address}
Home Town: {home_town}
Mobile Number: {mobile_number}'''
persons = []
number = int(input('How many people would you like in your address book: '))
for iteration in range(number):
full_name = input('\nFull name: ')
home_address = input('Home address: ')
home_town = input('Home town: ')
mobile_number = input('Mobile number: ')
person = Person(full_name, home_address, home_town, mobile_number)
persons.append(person)
for person in persons:
print(person_print_template.format(**person._asdict()))
collections.namedtuple is a way of defining really simple reusable objects and offers an _asdict() method which return a dictionary.
In python, putting ** in front of a dictionary allows you to unpack each of its dictionary keys and values which can be then passed, for example here, to a template, and str.format() will replace the "{key_name}" by its value.
Again this is a powerful way of formatting string output, especially when multi-line.=, either for the web or for command line output, like here.
Rob's answer, as Apero stated, is perfect. However as Apero addressed your format with functional programming, I'll address it in OOP (mostly because I love abstracting functional code! :D)
from collections import OrderedDict
# this is only necessary if you need your fields to always be in the
# same order when they're printed. Otherwise ignore and have Person
# inherit from dict
FIELDS = ["full name", "address", "hometown", "mobile number"]
class Person(OrderedDict): # see note above
def __init__(self, keys=None):
super().__init__() # this is magic that makes the OrderedDict work
if isinstance(keys, dict):
self.update(keys)
# this allows you to pass in a normal dict like you can for any
# other dict or ordered dict, and only prompt otherwise
else:
for key in keys:
self[key] = input("Please enter your %s: " % key)
def __str__(self):
"""The __str__ function describes how str(self) looks. I'm defining
it here to mimic the way Apero used his person_print_template string"""
output_strings = []
for key,value in self.items():
output_strings.append("{}: {}".format(key, value))
return "\n".join(output_strings)
# this is equivalently:
## return "\n".join(["{}: {}".format(key,value) for key,value in self.items()])
class AddressBook(list):
def __init__(self, size=None):
if size is None:
size = int(input("How many entries are in this address book? "))
for entry in range(size):
global FIELDS
self.append(Person(FIELDS))
def __str__(self):
return "\n\n".join([entry for entry in self])
# double spaced for readability
if __name__ == "__main__":
book = AddressBook()
print()
print(book)
# OUTPUT:
How many entries are in this address book? 2
Please enter your full name: Adam Smith
Please enter your address: 123 Some St.
Please enter your hometown: Eugene, OR
Please enter your mobile number: 555-867-5309
Please enter your full name: John Smith
Please enter your address: 987 Hello World, Ave.
Please enter your hometown: Camelot (tis a silly place)
Please enter your mobile number: 555-789-1234
full name: Adam Smith
address: 123 Some St.
hometown: Eugene, OR
mobile number: 555-867-5309
full name: John Smith
address: 987 Hello World, Ave.
hometown: Camelot (tis a silly place)
mobile number: 555-789-1234
You can certainly make changes in format to suit. I'd point you at the str.format method so you can do things like justify your strings beautifully
# # inside Person.__str__
for key,value in self.items():
global SCREENWIDTH # perhaps 50?
output_strings.append("{0}: {1:>{2}}".format(key,value, SCREENWIDTH - len(str(key)) - 1))
full name: Adam
address: blah
hometown: doohickey
mobile number: 1234
Possibly a flag on AddressBook.init that works as an alternate constructor given an existing list of Person objects.
class AddressBook(list):
def __init__(self, argument=None, _prompted=True):
if _prompted:
size = argument # just for clarity
self.from_prompt(size)
else:
lst = argument # just for clarity
self.from_list(lst)
def from_prompt(self, size):
# exactly as __init__ is above
def from_list(self, lst):
self.extend(lst)
Lots of fun stuff to be done with OOP. Personally I like them just because of Python's duck typing only becomes stronger when I can control both what kind of quack to listen to and what kind of quack to MAKE! :)
Use this instead
for loop in range (0,number,1):
addressbook.append([])
addressbook[-1].append([(str(input("\nPlease enter your full name:")))])
addressbook[-1].append([(str(input("Please enter your home address:")))])
addressbook[-1].append([(str(input("Please enter your hometown:")))])
addressbook[-1].append([(str(input("Please enter your mobile number:")))])
print("\nName:",addressbook[-1][0],"\nHomeaddress:",addressbook[-1][1],"\nHometown:",addressbook[-1][2],"\nMobile number:",addressbook[-1][3])
The problem with your code was you were using single dimension list. For every loop you are adding the items into addressbook so after 2 iterations of the loop it will look smthing like this
["name1","addr1","hmtown1","mob1","name2","addr2","hmtown2","mob2"]
So instead solution would be add an empty list for every iteration in loop and to that empty list we add the details so the structure would look like this
[["name1","addr1","hmtown1","mob1"],["name2","addr2","hmtown2","mob2"]]
In every iteration we access the last list by addressbook[-1] and then append the items to that last list, similarly accessing the items by using addressbook[-1][0].
Hope this helped you understand the problem.
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:
Main question: My loop-thing works fine, meaning it creates the number of objects of the right sex that I want to create. My problem is that it creates objects without names, as far as I know. This means I can't do the displaySettler() call, because it requires me to do nameofobject.displaySettler(). How can I, using some sort of loop function to create a bunch of objects, make those objects with names.
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?
I'd also like to ask the following: As you might see from my class, I'm doing a bunch of lists. I'm thinking I have to make a list for every attribute for every sex, containing the particular attributes of all objects. I want those lists to be able to calculate the populations average value of each attribute, and things like that.
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.
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
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.
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)
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.