AttributeError Python OOP - python

from typing import List
class Customer:
def __init__(self, name:str,age:int, phone_number: List['PhoneNumber']):
self.name = name
self.age = age
self.phone_number = phone_number
def check_ownership(self):
for number in self.phone_number:
if number.owner == self.name:
print(f"Number: {number} is owned by {self.name}")
else:
print(f"Number: {number} is not owned by {self.name}")
class PhoneNumber:
def __init__(self,credit: int,phone_number: int, owner:Customer):
self.credit = credit
self.phone_number = phone_number
self.owner: Customer = owner
def add_credit(self, amount):
self.credit += amount
customer1 = Customer("Jake",20,[4321,5374])
phonenum1 = PhoneNumber(12,4321,"Jake")
phonenum2 = PhoneNumber(12,5374,"John")
print(customer1.check_ownership())
Im trying to check if the customer "Jake" is really set as a owner for the phone numbers he owns but i keep getting AttributeError: 'int' object has no attribute 'owner'. What is the right way to check if the customer really owns those numbers.

Related

create a list from class user input

Create an employee class with the following members: name, age, id, salary
setData() - should allow employee data to be set via user input
getData()- should output employee data to the console
create a list of 5 employees. You can create a list of objects in the following way, appending the objects to the lists.
emp_object = []
for i in range(5):
emp_ object.append(ClassName())
I'm trying to do this exercise and this is what I got:
class employee:
def __init__(self, n = None, a = None, i = None, s = None):
self.name = n
self.age = a
self.id = i
self.salary = s
def setData(self):
self.n = input("Enter name: ")
self.a = int(input("Enter age: "))
self.i = int(input("Enter id: "))
self.s = int(input("Enter salary: "))
self.getData()
def getData(self):
print("Name:", self.name, self.age, self.id, self.salary)
e1 = employee()
e1.setData()
e2 = employee()
e2.setData()
e3 = employee()
e3.setData()
e4 = employee()
e4.setData()
e5 = employee()
e5.setData()
emp_object = []
for i in range(5):
emp_object.append(employee())
print(emp_object)
It prints the employee details as "None" and I need help to create a list
Expected Output:
Name id Age Salary
AAA 20 1 2000
BBB 22 2 2500
CCC 20 3 1500
DDD 22 4 3500
EEE 22 5 4000
Change the instance variable self.n ( in the setData method) to self.name to match the declaration your class init method ...and do the same for the self.a, self.i... variables .
I beleive the problem is that you are not setting the parameters to the ones you want in the setData function.
You need to do this:
class employee:
def __init__(self, n = None, a = None, i = None, s = None):
self.name = n
self.age = a
self.id = i
self.salary = s
def setData(self):
self.name = input("Enter name: ")
self.age = int(input("Enter age: "))
self.id = int(input("Enter id: "))
self.salary = int(input("Enter salary: "))
self.getData()
def getData(self):
print("Name:", self.name, self.age, self.id, self.salary)
The __init__ and setData are two separate functions.
First you want to separate some responsabilities for a better reading.
We will divide the problem in two parts :
Employee model
Input/output problem
Employee
Create a class who contains only employee data (we can use dataclasses but, I assume you're a beginner, so I'll keep simple)
class Employee:
def __init__(self, uid=None, name=None, age=None, salary=None):
self.name = name
self.age = age
self.id = uid
self.salary = salary
Output and Input
To display the employee's data in console, we can use __str__ function. It is used when you class need to be converted into a str (in print for isntance).
We then add an other method in charge to set employee's data.
Our Employee class become :
class Employee:
def __init__(self, uid=None, name=None, age=None, salary=None):
self.name = name
self.age = age
self.id = uid
self.salary = salary
def __str__(self):
return f"Name: {self.name}, {self.age}, {self.id}, {self.salary}"
def set_data(self):
self.name = input("Enter name: ")
self.age = int(input("Enter age: "))
self.id = int(input("Enter id: "))
self.salary = int(input("Enter salary: "))
Our class is complete. Now we will write the algorithm in charge to create 5 employees.
So under the Employee class :
if __name__ == '__main__':
# Empty list containing our employees
employees = []
# We loop 5 times.
for i in range(5):
# We create an employee
employee = Employee()
# We set the data
employee.set_data()
# We append our brand-new employee into the list
employees.append(employee)
# Now we display our data :
for employee in employees:
# We just need to print the object thanks to __str__ method
print(employee)
Tell me if I answered correctly to your problem !

How can I print each item in an unknown length list that is a class attribute as a string in python?

I have a class (Student) with different attributes, such as studentId, address, and courses. My str method for the class returns all the information that the user put in. However, for the attributes that are lists, such as courses, the location of the information is printed out instead of the actual information. Here is the code (sorry it's a little long, there's a bunch of classes):
class Person:
__name = None
__age = None
__address = None
def __init__(self, name, age=0, address=None):
self.set_name(name)
self.set_age(age)
self.set_address(address)
def __str__(self):
return 'Name: ' + self.__name + '\n' + \
'Age: ' + str(self.__age) + '\n' + \
'Address: ' + str(self.__address)
def set_name(self, name):
self.__name = name
def get_name(self):
return self.__name
def set_age(self, age):
self.__age = age
def get_age(self):
return self.__age
def set_address(self, address):
self.__address = address
def get_address(self):
return self.__address
class Student(Person):
def __init__(self, name, studentID= None, age= 0, address= None):
super(Student, self).__init__(name, age, address)
self.set_studentID(studentID)
self.__courses =[]
def __str__(self):
result = Person.__str__(self)
result += '\nStudent ID:' + self.get_studentID()
for item in self.__courses:
result += '\n ' + str(item)
return result
def set_studentID(self, studentID):
if isinstance(studentID, str) and len(studentID.strip()) > 0:
self.__studentID = studentID.strip()
else:
self.__studentID = 'NA'
def get_studentID(self):
return self.__studentID
def add_course(self, course):
print('in add_course')
self.__courses.append(course)
def get_courses(self):
for i in range(len(self.__courses)):
return self.__courses[i]
class Course:
__courseName = None
__dept = None
__credits = None
def __init__(self, courseName, dept= 'GE', credits= None):
self.set_courseName(courseName)
self.set_dept(dept)
self.set_credits(credits)
def __str__(self):
return self.get_courseName() + '/' + self.get_dept() + '/' + str(self.get_credits())
def set_courseName(self, courseName):
if isinstance(courseName, str) and len(courseName.strip()) > 0:
self.__courseName = courseName.strip()
else:
print('ERROR: Name must be a non-empty string')
raise TypeError('Name must be a non-empty string')
def get_courseName(self):
return self.__courseName
def set_dept(self, dept):
if isinstance(dept, str) and len(dept.strip()) > 0:
self.__dept = dept.strip()
else:
self.__dept = "GE"
def get_dept(self):
return self.__dept
def set_credits(self, credits):
if isinstance(credits, int) and credits > 0:
self.__credits = credits
else:
self.__credits = 3
def get_credits(self):
return self.__credits
students = []
def recordStudentEntry():
name = input('What is your name? ')
age = input('How old are you? ')
studentID= input('What is your student ID? ')
address = input('What is your address? ')
s1 = Student(name, studentID, int(age), address)
students.append(s1)
s1.add_course(recordCourseEntry())
print('\ndisplaying students...')
displayStudents()
print()
def recordCourseEntry():
courses = []
for i in range(2):
courseName = input('What is the name of one course you are taking? ')
dept = input('What department is your course in? ')
credits = input('How many credits is this course? ')
c1 = Course(courseName, dept, credits)
print(c1)
courses.append(c1)
displayCourses(courses)
return courses
def displayCourses(courses):
print('\ndisplaying courses of student... ')
for c in range(len(courses)):
print(courses[c])
def displayStudents():
for s in range(len(students)):
print()
print(students[s])
recordStudentEntry()
This is how the code above prints out the 'displaying students...' part:
displaying students...
Name: sam
Age: 33
Address: 123 st
Student ID:123abc
[<__main__.Course object at 0x000002BE36E0F7F0>, <__main__.Course object at
0x000002BE36E0F040>]
I know that it is printing out the location because I need to index into the list. However, the length of the list will be different every time. Normally if I wanted to index into a list, for example, to print a list of names, I would do:
listOfNames = ['sam', 'john', 'sara']
for i in range(len(listOfNames)):
print(listOfNames[i])
or
listOfNames = ['sam', 'john', 'sara']
for i in listOfNames:
print(i)
(not sure what if any difference there is between the 2 ways since they both print out the same way:)
sam
john
sara
How can I write something like the indexing into a list technique shown here in my str method for my class so that it prints the information and not the location?
It would be good to keep to the standard conventions for Python, such as naming
private attributes for objects with single underscores, not double underscores.
The latter are reserved for Python "internal" attributes and methods.
Also, it is convention to use object attributes for objects with get/set methods,
not class attributes. This will make it easier to inspect your objects, while
still maintaining data hiding. Example:
class Course:
def __init__(self, courseName, dept= 'GE', credits= None):
self._courseName = None
self._dept = None
self._credits = None
self.set_courseName(courseName)
...
Your question about why the courses don't print out the way you expected
is rooted in a programming error with the way you programmed the recording
of courses. In recordCourseEntry(), you record two courses and put them
in a list. However, you pass that to your Student object using a method
intended for one course at a time. My suggested fix would be:
...
# s1.add_course(recordCourseEntry())
courses = recordCourseEntry()
for course in courses:
s1.add_course(course)
...
This will probably be enough to get you going. An example output I got was:
Name: Virtual Scooter
Age: 33
Address: 101 University St.
Student ID:2021
ff/GE/3
gg/GE/3

Simple class Property Update

I have a class where I'm expecting this:
print(rithesh.amount) = 150.
How can I do this?
Here is my code:
class Customer:
total_amount = 0
def __init__(self, name, mob, email, amount=None):
self.name = name
self.mob = mob
self.eamil = email
def add_amount(self, amount):
self.amount = amount
rithesh = Customer("Rithesh", "8896398598", "ritheshb1#gmail.com")
rithesh.add_amount(100)
rithesh.add_amount(50)
print(rithesh.amount)
You can declare your amount variable in your __init__ method as 0. Then make a small change in your add_amount method.
class Customer:
total_amount = 0
def __init__(self, name, mob, email, amount=None):
self.name = name
self.mob = mob
self.eamil = email
self.amount = 0
def add_amount(self, amount):
self.amount += amount
rithesh = Customer("Rithesh", "8896398598", "ritheshb1#gmail.com")
rithesh.add_amount(100)
rithesh.add_amount(50)
print(rithesh.amount)
output
150
The actual way of having properties in python is by using #property decorator
for example, in your class:
class Customer:
total_amount = 0
def __init__(self, name, mob, email, amount=None):
self.name = name
self.mob = mob
self.eamil = email
#property
def add_amount(self):
return self.add_amount
#add_amount.setter
def add_amount(self, amount):
self.add_amount = amount
rithesh = Customer("Rithesh", "8896398598", "ritheshb1#gmail.com")
rithesh.add_amount = 150
print(rithesh.add_amount)
Got how to do it.
i have to declare the value self.amount = 0 during initialization.
class Customer:
total_amount = 0
def __init__(self, name, mob, email, amount=None):
self.name = name
self.mob = mob
self.eamil = email
self.amount = 0
def add_amount(self, amount):
self.amount += amount
rithesh = Customer("Ritehsh", "8892398598", "ritheshb1#gmail.com")
rithesh.add_amount(100)
rithesh.add_amount(50)
print(rithesh.amount)
hence getting output as print(rithesh.amount) = 150
What is happening is that when you call add_amount you are not adding the value to self.amount you are just setting it.
Just change the definition of add_amount from:
self.amount = amount
to:
self.amount += amount
And add to the __init__ method:
self.amount = 0

How to use for loop in class for user inputs?

I have created employee details using class by giving pre defined inputs. I'm not able to store the results into a dict. I need to write it as a csv. I would be thankful if you could help me, as I'm a novice in python
Here are my codes:
Is it correct way to use for loop in classes?
class Employee():
def main(self,name,idno,position,salary):
self.name=name
self.idno=idno
self.position=position
self.salary = salary
def input(self):
n=int(raw_input("Enter the number of employees:"))
for i in range(n):
self.name=raw_input("Name:")
self.idno=raw_input("Idno:")
self.position=raw_input("position:")
self.salary=raw_input("salary:")
print("Name:", self.name, "Idno:", self.idno, "position:", self.position,
"salary:", self.salary)
if __name__=='__main__':
result=Employee()
result.input()
First of all, I don't think you're class will be working like you intend it to. Since you're constantly overwriting the class variables, there is no point in entering more than one employee, as the class can currently only save information on one employee. I would consider saveing employees as dictionarys and have those dictionaries saved as a list in your Employee(s) class.
class Employees():
all_employees = [{...}, {...}]
dict_keys = ["name", "idno", "position",...]
def input(self):
counter = 0
n = input("Number of employees: ")
while counter < n:
new_employee = dict()
for key in dict_keys:
new_employee[key] = raw_input("{}: ".format(key))
all_employees.append(new_employee)
if __name__ == "__main__":
e = Employees()
e.input()
This illustrates what I was saying in my comment about using a for loop outside of the class:
class Employee(object):
def __init__(self, name, idno, position, salary):
self.name=name
self.idno=idno
self.position=position
self.salary = salary
def print_data(self):
print("Name:", self.name, "Idno:", self.idno, "position:", self.position,
"salary:", self.salary)
if __name__=='__main__':
def input_employee_data():
print('Enter data for an employee')
name = raw_input("Name:")
idno = raw_input("Idno:")
position = raw_input("position:")
salary = raw_input("salary:")
print('')
return name, idno, position, salary
employees = list()
n = int(raw_input("Enter the number of employees:"))
for i in range(n):
name, idno, position, salary = input_employee_data()
employee = Employee(name, idno, position, salary)
employees.append(employee)
print('List of employess')
for employee in employees:
employee.print_data()

TypeError: __init__() takes exactly 8 arguments (7 given) Python Homework

I can't figure out why I am getting the TypeError. Below is a class and two sub-classes. The first two work fine. The Final sub-class(OperatingSys) is where I am finding difficulty. I have put my Error input at the very bottom. Thanks in advance!
class InventoryItem(object):
def __init__(self, title, description, price, store_id):
self.title = title
self.description = description
self.price = price
self.store_id = store_id
def __str__(self):
return self.title
def __eq__(self, other):
if self.store_id == other.title:
return True
else:
return False
def change_description(self, description=""):
if not description:
description = raw_input("Please give me a description:")
self.description = description
def change_price(self, price = -1):
while price < 0:
price = raw_input("Please give me the new price [X.XX]: ")
try:
price = float(price)
break
except:
print "I'm sorry but {} isn't valid.".format(price)
self.price = price
def change_title(self, title=""):
if not title:
title = raw_input("Please give me a new title: ")
self.title = title
class Book(InventoryItem):
def __init__(self, title, description, price, format, author, store_id):
super(Book, self).__init__(title=title,
description = description,
price = price,
store_id=store_id)
self.format = format
self.author = author
def __str__(self):
book_line = "{title} by {author}".format(title = self.title, author = self.author)
return book_line
def __eq__(self, other):
if self.title == other.title and self.author == other.author:
return True
else:
return False
def change_format(self, format):
if not format:
format = raw_input("Please give me the new format: ")
self.format = format
def change_author(self, author):
if not author:
author = raw_input("Please give me the enw author: ")
class OperatingSys(InventoryItem):
def __init__(self, InventoryItem, title, price, description, opsys, rating, store_id):
super(OperatingSys, self).__init__(title=title, price=price, description=description, store_id=store_id)
self.opsys = opsys
self.rating = rating
def __str__(self):
opsys_line = "{title} for {OpSys}, price is {price}".format(title = self.title, OpSys=self.OpSys, price = self.price)
return opsys_line
def __eq__(self, other):
if self.title == other.title and self.author == other.author:
return True
else:
return False
def change_opsys(self, opsys):
if not opsys:
opsys = raw_input("Please give me a new Operating System: ")
self.opsys = opsys
def change_rating(self, rating):
if not rating:
rating = raw_input("Plese assign the appropriate rating: ")
self.rating = rating
TheDivision = OperatingSys(title="The Division",description="third person shooter", price=69.99, opsys="", rating="", store_id=3908657)
Traceback (most recent call last):
File "<pyshell#128>", line 1, in <module>
TheDivision = OperatingSys(title="The Division",description="third person shooter", price=69.99, opsys="", rating="", store_id=3908657)
TypeError: __init__() takes exactly 8 arguments (7 given)
When you try and create OperatingSys you are passing in 6 parameters — which together with self make 7:
OperatingSys(
title="The Division", # 1
description="third person shooter", # 2
price=69.99, # 3
opsys="", # 4
rating="", # 5
store_id=3908657 # 6
)
But your definition requires 7 (8 including self):
def __init__(self, InventoryItem, title, price, description, opsys, rating, store_id):
I suspect that the InventoryItem there is a mistake — you don't need to include the parent class as a parameter in the init definition.
def __init__(self, title, price, description, opsys, rating, store_id):

Categories

Resources