Set object attribute based on zipped attribute, value pairs - python

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)

Related

How to calculate total price with discount by the products in Python

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())

Calculations in class Student

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

python __repr__(self): does not return

I have a below code in which the magic method repr(self) does not return my instance parameters below is the code
i am trying to learn the oops concept
class Item:
pay_rate = 0.8 # The pay rate after 20% discount
all = []
def __init__(self, name: str, price: float, quantity=0):
# Run validations to the received arguments
assert price >= 0, f"Price {price} is not greater than or equal to zero!"
assert quantity >= 0, f"Quantity {quantity} is not greater or equal to zero!"
# Assign to self object
self.name = name
self.price = price
self.quantity = quantity
# Actions to execute
Item.all.append(self)
def calculate_total_price(self):
return self.price * self.quantity
def apply_discount(self):
self.price = self.price * self.pay_rate
def __repr__(self):
return "Item('{self.name}', {self.price}, {self.quantity})"
item1 = Item("Phone", 100, 1)
item2 = Item("Laptop", 1000, 3)
item3 = Item("Cable", 10, 5)
item4 = Item("Mouse", 50, 5)
item5 = Item("Keyboard", 75, 5)
You missed one f character
def __repr__(self):
return f"Item('{self.name}', {self.price}, {self.quantity})"

NameError line 50 for item in storeProducts , name 'storeProducts' is not defined

I'm having a problem with my python program where I'm trying to create a class that holds data about an item in a retail store. I don't know why it's giving me NameError. Also, would it be possible to convert the data in storeProducts list into a dictionary and still have it displayed as a table
class Products:
def __init__(self,productId,description,quantity,price):
self.productId = productId
self.description = description
self.quantity = quantity
self.price = price
def set_productId(self,productId):
self.__productId = productId
def set_description(self,description):
self.__description = description
def set_quantity(self,quantity):
self.__quantity = quantity
def set_price(self,price):
self.__price = price
def get_productId(self,productId):
return self.__productId
def get_description(self,description):
return self.__description
def get_quantity(self,quantity):
return self.__quantity
def get_price(self,price):
return self.__price
def __str__(self):
return'Products:'+ 'title:' + self.title+', description:' + self.description + \
' ,quantity' + self.quantity + ', price:' + self.price
def main():
storeProducts = [[1,'Jacket',1,59.95],
[2, 'Designer Jeans' , 40, 34.95],
[3, 'Shirt' , 20, 24.95],]
print=(': Product ID : Description : Quantity : Price : ')
for item in storeProducts:
print(':',item[0],''*(9-len(str(item[0]))), ':',
item[1],''*(11-len(item[1])),':',
item[2],''*(8-len(str(item[2]))),':',
item[3],''*(5-len(str(item[3]))))
main()
If you copy-pasted the code properly, there's a clear indentation problem in your main function.

Simple Class --> Class property updation

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

Categories