How do I iterate through a list of objects - python

I'm trying to print a list(phonebook) of objects(record) but I'm new to python and it is not recognizing that record is a objects in the list. How would I call objects in this instance?
Ive tried looking at tutorials of python for loops but none reference how to call an object in a list.
class record:
def __init__(self,telephone,lastname,firstname):
self.telephone = telephone
self.lastname = lastname
self.firstname = firstname
class PhoneBook:
def __init__(self):
self.phonebook = []
def printphonebook(self):
for record in self.phonebook:
x = 0
print(self.phonebook[x])
x = x + 1
Expected output would be the list of objects including the telephone number, last name, and first name.

You want to print an instance of a class. So you should provide the special __str__ method to tell python how the object should be printed. __str__() must return a string: here the docs.
class record:
def __init__(self,telephone,lastname,firstname):
self.telephone = telephone
self.lastname = lastname
self.firstname = firstname
def __str__(self):
#returning a string with the content, you can edit the string to fit your needs.
#here I am using formatted string literals, works with python >= 3.6
return f"Last name: {self.lastname}, First Name: {self.firstname}, Telephone: {self.telephone}"
class PhoneBook:
def __init__(self):
self.phonebook = []
def printphonebook(self):
for entry in self.phonebook:
print(entry)
What happens here is that when you call print(record) the __str__() method is used to provide a string representing the content of the instance.
So if you do:
book = PhoneBook()
book.phonebook.append(record(800, "Wayne", "Bruce"))
book.phonebook.append(record(1234, "Kent", "Clark"))
book.phonebook.append(record(499, "Prince", "Diana"))
book.printphonebook()
This will print:
Last name: Wayne, First Name: Bruce, Telephone: 800
Last name: Kent, First Name: Clark, Telephone: 1234
Last name: Prince, First Name: Diana, Telephone: 499

You have no elements in your self.phonebook. Of course it prints nothing.
Every iteration you create x=0 so you always will print the first item:
class record:
def __init__(self,telephone,lastname,firstname):
self.telephone = telephone
self.lastname = lastname
self.firstname = firstname
class PhoneBook:
def __init__(self):
self.phonebook = [1,2,3,4,5]
def printphonebook(self):
for record in self.phonebook:
x = 0
print(self.phonebook[x])
x = x + 1
a = PhoneBook()
a.printphonebook()
1
1
1
1
1
Your x index is really pointless, you can just print record:
class record:
def __init__(self,telephone,lastname,firstname):
self.telephone = telephone
self.lastname = lastname
self.firstname = firstname
class PhoneBook:
def __init__(self):
self.phonebook = [1,2,3,4,5]
def printphonebook(self):
for record in self.phonebook:
print(record)
a = PhoneBook()
a.printphonebook()
1
2
3
4
5
So: 1. Fill your self.phonebook with ANY elements 2. Print record, without indices.

Related

Python Class Function not defined

I'm creating a class with function within,
but i keep getting error "name 'direct_report' is not defined"
Basically im tring to make an organization chart, creating a list using the direct_report function to add people under each position
class employee:
def __init__(self, name , title, salary):
self.name = name
self.title = title
self.salary = salary
self.direct_reports_list = direct_report()
def __str__(self):
#otheremp_list = []
print(self.title,'-', self.name)
print('Direct Reports:')
for emp in self.direct_reports_list:
print(emp.title,'-', emp.name)
# otheremp_list.append(emp.direct_reports_list)
#print('other employees:')
#for emp in otheremp_list:
# print(emp.title,'-', emp.name)
# otheremp_list.append(emp.direct_reports_list)
def direct_report(self,value):
print(value)
direct_reports_list = []
direct_reports_list.append(value)
print(direct_reports_list)
return direct_reports_list
ceo = employee("Elon Musk", "CEO",1000000)
devdir = employee("Jeff Bezos","Development Director",500000)
devassoc1 = employee("Beyonce Knowles","Development Associate", 50000)
devassoc2 = employee("Taylor Swift","Development Associate", 50000)
ceo.direct_report(devdir)
ceo.direct_report(devdir2)
devdir.direct_report(devassoc1)
devdir.direct_report(devassoc2)
print(ceo)
The # is my further plan to print the full organization chart, but currently im still stuck at the "direct report" parts
You need to add one indentation level for the classes methods like that:
class employee:
def __init__(self, name , title, salary):
self.name = name
self.title = title
self.salary = salary
self.direct_reports_list = direct_report()
def __str__(self):
#otheremp_list = []
print(self.title,'-', self.name)
print('Direct Reports:')
for emp in self.direct_reports_list:
print(emp.title,'-', emp.name)
# otheremp_list.append(emp.direct_reports_list)
#print('other employees:')
#for emp in otheremp_list:
# print(emp.title,'-', emp.name)
# otheremp_list.append(emp.direct_reports_list)
def direct_report(self,value):
print(value)
direct_reports_list = []
direct_reports_list.append(value)
print(direct_reports_list)
return direct_reports_list
ceo = employee("Elon Musk", "CEO",1000000)
devdir = employee("Jeff Bezos","Development Director",500000)
devassoc1 = employee("Beyonce Knowles","Development Associate", 50000)
devassoc2 = employee("Taylor Swift","Development Associate", 50000)
ceo.direct_report(devdir)
ceo.direct_report(devdir2)
devdir.direct_report(devassoc1)
devdir.direct_report(devassoc2)
print(ceo)
Call the function in this way.
class employee:
def __init__(self, name , title, salary):
self.name = name
self.title = title
self.salary = salary
self.direct_reports_list = self.direct_report()
try self.direct_report() instead as you are calling a method within the class
Try this code.
class employee:
def __init__(self, name , title, salary):
self.name = name
self.title = title
self.salary = salary
self.direct_reports_list = []
def __str__(self):
#otheremp_list = []
print(self.title,'-', self.name)
print('Direct Reports:')
for emp in self.direct_reports_list:
print(emp.title,'-', emp.name)
# otheremp_list.append(emp.direct_reports_list)
#print('other employees:')
#for emp in otheremp_list:
# print(emp.title,'-', emp.name)
# otheremp_list.append(emp.direct_reports_list)
return "Done"
def direct_report(self,value):
self.direct_reports_list.append(value)
ceo = employee("Elon Musk", "CEO",1000000)
devdir = employee("Jeff Bezos","Development Director",500000)
devassoc1 = employee("Beyonce Knowles","Development Associate", 50000)
devassoc2 = employee("Taylor Swift","Development Associate", 50000)
ceo.direct_report(devdir)
devdir.direct_report(devassoc1)
devdir.direct_report(devassoc2)
print(ceo)
print(devdir)
print(devassoc1)
print(devassoc2)

How to access function output of one class from a function of another

I have two classes Course and Student. Course has a function that grades a student and gives a score. I'm trying to build a function in Student that takes that grade and shows the total score for a particular student.
class courseClass(object):
def grade(self, student, grade):
self.grade = grade
if self.grade == 1:
print("Student passed mandatory assignment")
elif self.grade == 0:
print("Student failed mandatory assignment")
elif self.grade != 0 or 1:
raise Exception("score is out of pattern range")
course_instance = courseClass()
course_instance.grade(student1, 1)
class Student(object):
def grade_status(self, student):
return [i.grade for i in self.grade]
student1 = Student("Bob Bobson", 20, 58008)
x = Student.grade_status(student1)
print(x)
AttributeError: 'Student' object has no attribute 'grade'
I think it needs to something like this instead:
def grade_status(self, grade):
self.grade =
But I don't know how to make it equal to the grade that's being given at the grade function (and will it know which student it is assigned to?)
Here is just one design (feel free to change the grading system):
class Course:
"""
Models a course being taught, for example: geometry
"""
def __init__(self, course_name):
self._course_name = course_name
self._enrollment = {} # No students so far
#property
def course_name(self):
"""Get the course_name."""
return self._course_name
def enroll_student(self, student):
"""
enroll student in this course
"""
self._enrollment[student] = None # no grade so far
student.add_course(self) # show that student is taking this course
return self
def enrollment(self):
"""
generate students enrolled in course
"""
for student, grade in self._enrollment.items():
yield student, grade
def assign_grade(self, student, grade):
"""
assign grade to a student
"""
assert student in self._enrollment
self._enrollment[student] = grade
return self
def get_grade(self, student):
"""
return a student's grade
"""
return self._enrollment[student]
class Student:
"""
Models a student
"""
def __init__(self, name):
self._name = name
self._courses = []
#property
def name(self):
"""Get student name"""
return self._name
def add_course(self, course):
self._courses.append(course)
return self
def courses(self):
for course in self._courses:
yield course
geometry = Course('geometry')
history = Course('history')
john_doe = Student('john doe')
jane_doe = Student('jane_doe')
geometry.enroll_student(john_doe)
geometry.enroll_student(jane_doe)
history.enroll_student(jane_doe)
geometry.assign_grade(john_doe, 1)
geometry.assign_grade(jane_doe, 2)
history.assign_grade(jane_doe, 1)
# print all the geometry grades
for student, grade in geometry.enrollment():
print(student.name, grade)
# print all of john_doe's courses and grades:
for course in john_doe.courses():
print('john_doe:', course.course_name, course.get_grade(john_doe))
for course in jane_doe.courses():
print('jane_doe:', course.course_name, course.get_grade(jane_doe))
Prints:
john doe 1
jane_doe 2
john_doe: geometry 1
jane_doe: geometry 2
jane_doe: history 1
I dont know if this what are trying to do
class courseClass(object):
def __init__(self, student, grade):
self.student = student
self.grade = grade
def grade_status(self):
if self.grade == 1:
return "Student passed mandatory assignment"
elif self.grade == 0:
return "Student failed mandatory assignment"
elif self.grade != 0 or 1:
raise Exception("score is out of pattern range")
class Student(object):
def __init__(self, name, age, random_number):
self.name = name
self.age = age
self.random_number = random_number
student1 = Student("Bob Bobson", 20, 58008)
course_instance = courseClass(student1,0)
x = course_instance.grade_status()
print(x)

Get an object item from a python list

I have three classes defined as following:
# class that identify a single person
class Person(object):
def __init__(self, name, surname, email):
self.name = name
self.surname = surname
self.email = email
def __eq__(self, other):
if isinstance(other, str):
return self.email = other
elif isinstance(other, Person):
return self.email = other.email
#class that allow iteration of class People
class PeopleIterator(object):
def __init__(self, people_list):
self._iterable = people_list
self._index = 0
def __next__(self):
if self._index < (len(self._iterable.list)):
result = self._iterable.list[self._index]
self._index += 1
return result
raise StopIteration
#class that identify a list of person
class People(object):
def __init__(self):
self.list = []
def add(self, obj):
self.list.append(obj)
def __iter__(self):
return PeopleIterator(self)
def __len__(self):
return len(self.list)
Basically is a list of instances of class Person, that can be iterated.
With this code I'm able to write:
friends = People()
john = Person("John", "Smith", "john.smith#mail.com")
friends.add(john)
mark = Person("Mark", "Green", "mark.green#mail.com")
friends.add(mark)
for f in friends:
print(f.email)
Now, I would like to get an item from the collection, searching by email.
Something like:
if friends["john.smith#mail.com"] is not None:
print(friends["john.green#mail.com"].name)
david = friends["david.white#mail.com"]
if david is None:
print("David is not your friend")
I'm not sure if a dictionary was a better solution instead a list.
You should implement the __getitem__ method on the People class:
def __getitem__(self, item):
try:
return [x for x in self.list if x.email == item][0]
except IndexError:
return None
Edit 2021
This normally is not an issue, but consider doing a normal for loop to avoid looping through the entire list. For large applications where performance matters, this things need to be taken into account.
def __getitem__(self, item):
for i in self.list:
if i.email == item:
return i # Loop stops
return None
You can also use a database. Here MongoDB(download, tutorial). It is better for big data and more complex analyzes.
import pymongo
from pymongo import MongoClient
mongoclient = MongoClient("mongodb://localhost:27017/") #Connect to Mongodb
database = mongoclient["yourdatabase"] #Connects to the database
collection = database["youcollection"] #Connects to the collection
element1 = {"firstname": "John", "lastname": "Smiht", "email": "john.smith#mail.com"} #Element to insert
collection.insert_one(element1) #Insert in collection
element2 = {"firstname": "Mark", "lastname": "Green", "email": "mark.green#mail.com"} #Element to insert
collection.insert_one(element2) #Insert in collection
results = collection.find({"email": "john.smith#mail.com"}) #Write Element in collection
for result in results: #Results is a array of all elements which were found
print(result["firstname"]) #Print the firstname of the found element
print(result["lastname"]) #print the lastname of the found element

Printing sum of list items

What I need is to print the total a person has spent on products, I know the code is horrible but that's how I received the assignment. Never worked with Python so it's all a little mystery for me.
My result so far
The outcome should be 950 for Jeroen, 1175 for Martijn and 800 for Bart without printing them individually.
#start opdracht3 class
class opdracht3:
#start product class
class Product:
#constructor
def __init__(self, productname, price):
self.productname = productname
self.price = price
#end product class
#person class
class Person:
#constructor
def __init__(self, name, email, productlist):
self.name = name
self.email = email
self.productlist = productlist
#adding products to person's collection
def buyItem(self, item):
self.productlist.append(item)
#end person class
#collection of persons
persons = []
#defining person1 with the items he has bought
productlist1 = []
person1 = Person("Jeroen","jbm.mutsters#avans.nl", productlist1)
product1 = Product("Moto G7",150)
person1.buyItem(product1)
product3 = Product("iPhone",800)
person1.buyItem(product3)
#defining person2 with the items he has bought
productlist2 = []
person2 = Person("Martijn","m.dereus1#avans.nl", productlist2)
product2 = Product("iPhone",800)
person2.buyItem(product2)
product5 = Product("iPad",375)
person2.buyItem(product5)
#defining person2 with the items he has bought
productlist3 = []
person3 = Person("Bart","b.linsen#avans.nl", productlist3)
product4 = Product("iPhone",800)
person3.buyItem(product2)
#add person1 and person2 to the persons collection
persons.append(person1)
persons.append(person2)
persons.append(person3)
#generating output
for p in persons:
print(p.name)
for i in p.productlist:
print(i.productname)
print(i.price)
print("-----------------")
print("einde output")
print("***************")
#end generating output
#end opdracht3 class
Thanks in advance.
You can use the built-in sum to find the sum, and a list comprehension to get the prices from the items:
sum([x.price for x in p.productlist])
Same but in as a instance method:
class Person:
def __init__(self, name, email, productlist):
self.name = name
self.email = email
self.productlist = productlist
def buyItem(self, item):
self.productlist.append(item)
def get_sum_spend(self):
return sum([product.price for product in self.productlist])
Also, camel case methods naming typically is not used in Python. You can read more in pep8.
I added the method sum_product_prices to the person class which adds up the prices of the products in the persons productlist. Add the persons to the list persons and print out the return value of sum_product_prices. I removed the opdracht 3 class because it is not used.
#start product class
class Product:
#constructor
def __init__(self, productname, price):
self.productname = productname
self.price = price
#end product class
#person class
class Person:
#constructor
def __init__(self, name, email, productlist):
self.name = name
self.email = email
self.productlist = productlist
#adding products to person's collection
def buy_item(self, item):
self.productlist.append(item)
def sum_product_prices(self):
sum = 0
for product in self.productlist:
sum += product.price
return sum
#end person class
#collection of persons
persons = []
#defining person1 with the items he has bought
productlist1 = []
person1 = Person("Jeroen","jbm.mutsters#avans.nl", productlist1)
product1 = Product("Moto G7",150)
person1.buy_item(product1)
product3 = Product("iPhone",800)
person1.buy_item(product3)
persons.append(person1)
productlist2 = []
person2 = (Person("Martijn","x#y.com",productlist2))
person2.buy_item(product3)
product4 = Product("iPad",375)
person2.buy_item(product4)
persons.append(person2)
productlist3 = []
person3 = Person("Bart","a#b.com",productlist3)
person3.buy_item(product4)
persons.append(person3)
for person in persons:
print(person.name + " " + str(person.sum_product_prices()))

Creating a call function for multiple classes

So I got my code to work, but two lines are messing me up, and not quite sure what to put.
Code(the two lines are marked):
class Person(object):
numPerson = 0
def __init__(self,firstName,lastName):
self.firstName = firstName
self.lastName = lastName
def fullName(self):
print self.firstName +' '+self.lastName
class Employee(Person):
numEmployee = 0
def __init__(self,firstName,lastName,pay,employID):
Person.__init__(self, firstName, lastName)
self.pay = pay
self.employID = employID
Employee.numEmployee += 1
class Programmer(Employee):
def __init__(self,firstName,lastName,pay,employID,proLang):
self.proLang = proLang
Employee.__init__(self, firstName, lastName, pay, employID)
class Manager(Employee):
def __init__(self,firstName,lastName,pay,employID,progList):
self.progList = progList
Employee.__init__(self, firstName, lastName, pay, employID)
def addProgrammer(self):
self.progList.append(Programmer.fullName) <------------------- This line
def removeProgrammer(self):
if len(self.progList) == 0:
pass
else:
del self.progList[0]
def printList(self):
print self.progList
a = Manager('Alfred','Jones',20.00,0001,[])
b = Programmer('James','Smith', 11.75, 0002, 'Java')
a.addProgrammer() <--------------------------------------------- And This line
a.printList()
I'm trying to add the programmer's name to the progList using the .addProgramer method. I keep trying different combos and this is the closest I got.
Output:
[<unbound method Programmer.fullName>]
So, I'm not sure what needs to be in the addProgramer method in order to properly add the programmers name, or if I need an argument inside the a.addProgrammer at the very end.
Here:
self.progList.append(Programmer.fullName)
You're not adding an instance of a programmer, you are adding a method from the programmer class.
Also:
def fullName(self):
print self.firstName +' '+self.lastName
This doesn't actually return the name of the programmer, it only prints it to the console. To actually output and use the the fullname you need to return self.firstName + ' ' + self.lastName
Likewise in that function you also need to specify which programmer you are adding:
def addProgrammer(self, added_programmer):
self.progList.append(added_programmer.fullName()) # Call the function to get the fullname
And now to add a programmer:
Alfred = Manager('Alfred','Jones',20.00,0001,[]) #make a manager
James = Programmer('James','Smith', 11.75, 0002, 'Java') #make a programmer
Alfred.addProgrammer(James) #add the programmer
Alfred.printList()
Putting this all together:
class Person(object):
numPerson = 0
def __init__(self,firstName,lastName):
self.firstName = firstName
self.lastName = lastName
def fullName(self):
return self.firstName +' '+self.lastName
class Employee(Person):
numEmployee = 0
def __init__(self,firstName,lastName,pay,employID):
Person.__init__(self, firstName, lastName)
self.pay = pay
self.employID = employID
Employee.numEmployee += 1
class Programmer(Employee):
def __init__(self,firstName,lastName,pay,employID,proLang):
self.proLang = proLang
Employee.__init__(self, firstName, lastName, pay, employID)
class Manager(Employee):
def __init__(self,firstName,lastName,pay,employID,progList):
self.progList = progList
Employee.__init__(self, firstName, lastName, pay, employID)
def addProgrammer(self, added_programmer):
self.progList.append(added_programmer.fullName()) # Call the function to get the fullname
def removeProgrammer(self):
if len(self.progList) == 0:
pass
else:
del self.progList[0]
def printList(self):
print self.progList
Alfred = Manager('Alfred','Jones',20.00,1,[])
James = Programmer('James','Smith', 11.75, 2, 'Java')
Alfred.addProgrammer(James)
Alfred.printList()

Categories