python __repr__(self): does not return - python

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})"

Related

Why am I getting the error 'class FidelityPromo(Promotion):IndentationError: expected an indented block'?

from abc import ABC, abstractmethod
from collections import namedtuple
Customer = namedtuple('Customer', 'name fidelity')
class LineItem:
def __init__(self, product, quantity, price):
self.product = product
self.quantity = quantity
self.price = price
def total(self):
return self.quantity * self.price
class Order:
def __init__(self, customer, cart, promotion=None):
self.customer = customer
self.cart = list(cart)
self.promotion = promotion
def total(self):
if not hasattr(self, '__total'):
self.__total = sum(item.total() for item in self.cart)
return self.__total
def due(self):
if self.promotion is None:
discount = 0
else:
discount = self.promotion.discount(self)
return self.total() - discount
def __repr__(self):
return '<Order total: {:0.2f} due: {:0.2f}>'.format(self.total(), self.due())
class Promotion(ABC):
#abstractmethod
def discount(self, order):
class FidelityPromo(Promotion):
def discount(self, order):
return order.total() * .05 if order.customer.fidelity >= 1000 else 0
class BulkItemPromo(Promotion):
def discount(self, order):
discount = 0
for item in order.cart:
if item.quantity >= 20:
discount += item.total() * .1
return discount
class LargeOrderPromo(Promotion):
def discount(self, order):
distinct_items = {item.product for item in order.cart}
if len(distinct_items) >= 10:
return order.total() * .07
return 0
joe = Customer('John Doe', 0)
ann = Customer('Ann Smith', 1100)
cart = [LineItem('banana', 4, .5), LineItem('apple', 10, 1.5), LineItem('watermellon', 5, 5.0)]
Order(joe, cart, FidelityPromo())
I expect this result:
<Order total: 42.00 due: 42.00>

Can I specify the datatype of a class parameter in python?

I'm confused because a video I'm watching says I can force the datatype by adding it after the parameter with a colon def __init__(self, name: str, price: float, quantity=0):. However, this throws invalid syntax.
class Item:
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
def calculate_total_price(self):
return self.price * self.quantity
item1 = Item("Phone", 100, 1)
item2 = Item("Laptop", 1000, 3)
print(item1.calculate_total_price())
print(item2.calculate_total_price())

How to combine attributes from 2 objects that are not received upon initialization

This is my code. I would like to know how to combine the "_transactions" attributes from 2+ objects.
Could you please help me out?
class Account:
def __init__(self, owner, amount=0):
self.owner = owner
self.amount = amount
self._transactions = []
def add_transaction(self, amount):
if type(amount) != int:
raise ValueError("please use int for amount")
self._transactions.append(amount)
def __add__(self, other):
name = f"{self.owner}&{other.owner}"
starting_amount = self.amount + other.amount
self._transactions += other._transactions
return Account(name, starting_amount)
acc = Account('bob', 10)
acc2 = Account('john')
acc.add_transaction(20)
acc.add_transaction(-20)
acc.add_transaction(30)
acc2.add_transaction(10)
acc2.add_transaction(60)
acc3 = acc + acc2
print(acc3._transactions)
The output should be:
[20, -20, 30, 10, 60]
But instead is:
[]
You should modify the __add__ function in order to sum the transactions; infact when you instatiate a new class, the self._transactions attribute is an empty list by default.
class Account:
def __init__(self, owner: str, amount: int = 0, transactions: list = None):
self.owner = owner
self.amount = amount
self._transactions = [] if transactions is None else transactions
def __add__(self, other):
name = f"{self.owner}&{other.owner}"
starting_amount = self.amount + other.amount
transactions = self._transactions + other._transactions
return Account(name, starting_amount, transactions)
def add_transaction(self, amount):
if type(amount) != int:
raise ValueError("please use int for amount")
self._transactions.append(amount)
acc = Account('bob', 10)
acc2 = Account('john')
acc.add_transaction(20)
acc.add_transaction(-20)
acc.add_transaction(30)
acc2.add_transaction(10)
acc2.add_transaction(60)
acc3 = acc + acc2
print(acc3._transactions)
>>> [20, -20, 30, 10, 60]

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.

Set object attribute based on zipped attribute, value pairs

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)

Categories