I have created two classes: Person and Student in different modules. Here is my class Person:
import datetime
class Person:
def __init__(self, name, surname, patronymic, birthdate):
self.name = name
self.surname = surname
self.patronymic = patronymic
self.birthdate = birthdate
def age(self):#this function calculates age of person
today = datetime.date.today()
age = today.year - self.birthdate.year
if today < datetime.date(today.year, self.birthdate.month, self.birthdate.day):
age -= 1
return age
Here is my class Student:
from ClassPerson import Person
class Student(Person):
number_of_group = eval(input("\nInput number of group: "))
summa = 0
amount_of_students = 0
overall_age = 0
def __init__(self, name, surname, patronymic, birthdate, faculty, group, scholarship):
Person.__init__(self, name, surname, patronymic, birthdate)
self.faculty = faculty
self.group = group
self.scholarship = scholarship
if Student.number_of_group == self.group:
Student.summa += self.scholarship
Student.overall_age += Student.age(self)
Student.amount_of_students += 1
#property
def scholarship(self):
return self.__scholarship
#scholarship.setter
def scholarship(self, new_s):
if new_s < 1300:
self.__scholarship = 1300
elif new_s > 4000:
self.__scholarship = 4000
else:
self.__scholarship = new_s
I have one simple problem: I need to calculate for specific group overall sum of scholarships and middle age of students of this group. I do calculations in def __init__. But i also had property and setter to change the amount of scholarship due to conditions. So for example we have 3 students:
student1 = Student(
"Joe",
"Hapfy",
"Canes",
datetime.date(1992, 3, 12),
"Philosophy faculty",
441,
4300
)
student2 = Student(
"Jane",
"Mers",
"Rodrigo",
datetime.date(1998, 4, 29),
"Historical faculty",
441,
2700
)
student3 = Student(
"Pavlo",
"Hornov",
"Andriyovich",
datetime.date(1997, 7, 22),
"Mathematics faculty",
171,
1300
)
I want to change student1 scholarship. For example:
student1.scholarship = 1500
print(student1.scholarship)
But the changes are not saved, cause i do calculations in dev __init__. For example, I input number of group as 441.
result = Student.overall_age/Student.amount_of_students
print("Total sum of scholarships: %d" % Student.summa)
The sum of scholarships will be 4300+2700, but due to setter 4300 will be changed to 4000 and sum will be 6700. But now my student1 scholarship is 1500 and i want to receive result 1500+2700=4200. How can i do such calculations after changes of scholarship? Should I use method or something like that instead of calculations in dev __init__?
The property setter needs to update Student.summa when necessary.
Since the setter needs to read the old value, we can't use it before we initialize the internal __scholarship attribute. So the __init__() method needs to assign directly to the internal attribute, rather than using the setter with self.scholarship.
from ClassPerson import Person
class Student(Person):
number_of_group = eval(input("\nInput number of group: "))
summa = 0
amount_of_students = 0
overall_age = 0
def __init__(self, name, surname, patronymic, birthdate, faculty, group, scholarship):
Person.__init__(self, name, surname, patronymic, birthdate)
self.faculty = faculty
self.group = group
self.__scholarship = scholarship
if Student.number_of_group == self.group:
Student.summa += self.scholarship
Student.overall_age += Student.age(self)
Student.amount_of_students += 1
#property
def scholarship(self):
return self.__scholarship
#scholarship.setter
def scholarship(self, new_s):
old_s = self.__scholarship
if new_s < 1300:
self.__scholarship = 1300
elif new_s > 4000:
self.__scholarship = 4000
else:
self.__scholarship = new_s
# Adjust Student.summa by the change in scholarship
if self.group == Student.number_of_group:
Student.summa += self.__scholarship - old_s
Related
I created two classes. In class Cart i need to implement the method get_total_price that calculate total price with discount.
Discount depends on count product:
count discount
at least 5 5%
at least 7 10%
at least 10 20%
at least 20 30%
more than 20 50%
class Product:
def __init__(self, name, price, count):
self.name = name
self.price = price
self.count = count
class Cart:
def __init__(self, *products_list):
self.products_list = products_list
def get_total_price(self):
pass
products = (Product('p1',10,4),
Product('p2',100,5),
Product('p3',200,6),
Product('p4',300,7),
Product('p5',400,9),
Product('p6',500,10),
Product('p7',1000,20))
cart = Cart(products)
print(cart.get_total_price())
The result of running the program should be 24785.0
Can someone help, because I can not figure out how to get the attributes(price, count) to calculate the discount.
It seems cart.products_list returns a tuple containing the products list (so, a tuple in another tuple). If it's not intended, remove the '*'.
Here is a working solution for the current structure; if you remove '*', remove [0] in the get_total_price method.
def discount_mult(q):
if q > 20:
return .5
elif q >= 20:
return .7
elif q >= 10:
return .8
elif q >= 7:
return .9
elif q >= 5:
return .95
else:
return 1
class Product:
def __init__(self, name, price, count):
self.name = name
self.price = price
self.count = count
class Cart:
def __init__(self, *products_list):
self.products_list = products_list
def get_total_price(self):
return sum([i.price*i.count*discount_mult(i.count) for i in self.products_list[0]])
products = (Product('p1',10,4),Product('p2',100,5),Product('p3',200,6),Product('p4',300,7),
Product('p5',400,9),Product('p6',500,10),Product('p7',1000,20))
cart = Cart(products)
print(cart.get_total_price())
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)
How would you simplify calculate_commission() if the commission percentages for each attribute was defined by the zipped list and the length of the zipped list could potentially increase (ex. ...('price_201', 2.3),) ?
zipped_price_and_commission = [
('price_4', .04),
('price_3', .034),
('price_2', .029),
('price_1', .021),
]
class Price:
def __init__(self, **kwargs):
self.price = kwargs.get('price')
self.price_1 = 2
self.price_2 = 2.5
self.price_3 = 3
self.price_4 = 5
def calculate_commission(self):
if self.price >= self.price_4:
commission = .04
elif self.price >= self.price_3:
commission = .034
elif self.price >= self.price_2:
commission = .029
elif self.price >= self.price_1:
commission = .021
else:
commission = 0
setattr(self, 'commission', commission)
IN: price = Price(price=3.3)
IN: price.calculate_commission()
IN: print(price.commission)
OUT: 0.034
In the first place, you should define all attributes in the init function. For example, you would get an error if someone tried to access the commission attribute without checking it first. So, just to be sure, you should initialize it with something.
Assuming that there is no need to have the commission as a zipped list, you can just do it like this:
comission = [ 0.04, 0.034, 0.029, 0.021]
class Price:
def __init__(self, cost):
self.price = cost
self.prices = [5,3,2.5,2]
self.commission = 0
def calculate_commission(self):
for index, prc in enumerate(self.prices):
if self.price >= prc:
self.commission = comission[index]
break
price = Price()
price.calculate_commission()
print(price.commission)
However, if you do need a zipped list, you can change the self.comission line to
self.commission = zipped_price_and_commission[index][1]
Edit: after seeing your update: If the number of commissions increases, you just have to update the self.prices variable to reflect them. You should also pass the prices as an argument to the class, instead of setting it inside the class
You can use a dictionary:
commissions = {
'price_4': .04,
'price_3': .034,
'price_2': .029,
'price_1': .021}
Then, in calculate_commission():
def calculate_commission(self):
if self.price >= self.price_4:
commission = commissions['price_4']
elif self.price >= self.price_3:
commission = commissions['price_3']
elif self.price >= self.price_2:
commission = commissions['price_2']
elif self.price >= self.price_1:
commission = commissions['price_1']
else:
commission = 0
setattr(self, 'commission', commission)
zipped_price_and_commission = [
('price_4', .04),
('price_3', .034),
('price_2', .029),
('price_1', .021),
]
class Price:
def __init__(self, **kwargs):
self.price = kwargs.get('price')
self.price_1 = 2
self.price_2 = 2.5
self.price_3 = 3
self.price_4 = 5
self.priceData = { 'price_4': 5,'price_3': 3,'price_2': 2.5,'price_1': 2}
def calculate_commission(self):
commission = 0
for price , commision in zipped_price_and_commission:
if self.price >= self.priceData[price]:
commission = commision
break
setattr(self, 'commission', commission)
price = Price(price=3.3)
price.calculate_commission()
print(price.commission)
I have a simple class. This is the output I got:
>>> print(Customer.total_amount)
1300
but I expected the output to be:
>>> print(Customer.total_amount)
1000
What am I doing wrong?
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
Customer.total_amount += self.amount
cust1 = Customer("cust1", "8892398598", "ritheshb1#gmail.com")
cust2 = Customer("cust2", "8892498598", "ritheshb2#gmail.com")
cust1.add_amount(100)
cust2.add_amount(200)
cust1.add_amount(300)
cust2.add_amount(400)
print(cust1.amount)
print(cust2.amount)
print(Customer.total_amount)
Change :
Customer.total_amount += self.amount
to
Customer.total_amount += amount
I'm learning how to use Classes, so far I have achieved the following:
class customer:
def __init__ (self, name, ID, money):
self.name = name
self.ID = ID
self.money = money
def deposit(self, amount):
self.money = self.money+amount
def withdraw(self, amount):
self.money = self.money-amount
mike = customer('Mike', 1343, 1884883)
john = customer('John', 1343, 884839)
steve = customer('Steve', 1343, 99493)
adam = customer('Adam', 1343, 10000)
I would like to create a function that sorts the customers by the amount of money they have but am unsure about how to do so.
You can sort a list of objects in place by an attribute like this:
your_list.sort(key=lambda x: x.attribute_name, reverse=True)
If you set reverse=False, the list is ordered ascending, with reverse=True it is sorted from highest amount to lowest.
So in your case:
class customer:
def __init__ (self, name, ID, money):
self.name = name
self.ID = ID
self.money = money
def deposit(self, amount):
self.money = self.money+amount
def withdraw(self, amount):
self.money = self.money-amount
mike = customer('Mike', 1343, 1884883)
john = customer('John', 1343, 884839)
steve = customer('Steve', 1343, 99493)
adam = customer('Adam', 1343, 10000)
unsorted_list = [steve, adam, mike, john]
print [c.name for c in unsorted_list]
unsorted_list.sort(key=lambda c: c.money, reverse=True)
print [c.name for c in unsorted_list]
For more information check this question too
def sort_by_money(customer)
for index in range(1,len(customer)):
currentvalue = customer[index].money
position = index
while position>0 and customer[position-1].money > currentvalue:
alist[position]=alist[position-1]
position = position-1
customer[position]=customer
Simple insertion sort that takes in customer array and sorts it back based on money.
This code will be outside your customer class that will take customer array as input.
There can be many correct answer to this problem. Written insertion sort to explain properly.