The first class contains the car details and in the second Service class using the get_car_by_year() method. I need to return car based on the date of manufacturing using get_* function of the first class, but I am getting None no matter which year I enter.
Code:
class Car:
def __init__(self,model,year,registration_number):
self.__model=model
self.__year=year
self.__registration_number=registration_number
def get_model(self):
return self.__model
def get_year(self):
return self.__year
def get_registration_number(self):
return self.__registration_number
def __str__(self):
return(self.__model+" "+self.__registration_number+" "+(str)(self.__year))
class Service:
def __init__(self,car_list):
self.__car_list = car_list
def get_car_by_year(self,year):
result_list = []
for car in self.__car_list:
if(car.get_year() == year):
result_list.append(car.get_model())
if(len(result_list) == 0):
return None
return result_list
car1=Car("WagonR",2010,"KA09 3056")
car2=Car("Beat", 2011, "MH10 6776")
car3=Car("Ritz", 2013,"KA12 9098")
car4=Car("Polo",2013,"GJ01 7854")
car5=Car("Amaze",2014,"KL07 4332")
car_list=[car1, car2, car3, car4,car5]
a1 = Service(car_list)
print(a1.get_car_by_year(2013))
Your return statements are inside loop which will always return null, because the first car in your car list is WagonR which is 2010. If you would call your current function get_car_by_year with a 2010 year you will get your desired output.
Placing both return statements outside for loop will do the trick
def get_car_by_year(self,year):
result_list = []
for car in self.__car_list:
if(car.get_year() == year):
result_list.append(car.get_model())
if (len(result_list) == 0):
return None
return result_list
Related
This is the exercise:
Write the special method __str__() for CarRecord.
Sample output with input: 2009 'ABC321'
Year: 2009, VIN: ABC321
The following code is what I have came up with, but I'm receiving an error:
TYPEERROR: __str__ returned non-string
I can't figure out where I went wrong.
class CarRecord:
def __init__(self):
self.year_made = 0
self.car_vin = ''
def __str__(self):
return "Year:", (my_car.year_made), "VIN:", (my_car.car_vin)
my_car = CarRecord()
my_car.year_made = int(input())
my_car.car_vin = input()
print(my_car)
You're returning a tuple using all those commas. You should also be using self, rather than my_car, while inside the class. Try like this:
def __str__(self):
return f"Year: {self.year_made}, VIN: {self.car_vin}"
The f before the string tells Python to replace any code in braces inside the string with the result of that code.
class Car:
def __init__(self):
self.model_year = 0
self.purchase_price = 0
self.current_value = 0
def print_info():
print('Car Info') # It specifies a print_info class method but doesnt actually need to print anything useful.
def calc_current_value(self, current_year):
depreciation_rate = 0.15
car_age = current_year - self.model_year
self.current_value = round(self.purchase_price * (1 - depreciation_rate) ** car_age)
def print_info(self):
print("Car's information:")
print(" Model year:", self.model_year)
print(" Purchase price:", self.purchase_price)
print(" Current value:", self.current_value)
if __name__ == "__main__":
year = int(input())
price = int(input())
current_year = int(input())
my_car = Car()
my_car.model_year = year
my_car.purchase_price = price
my_car.calc_current_value(current_year)
my_car.print_info()
def __str__(self):
return "Year: {}, VIN: {}".format(self.year_made, self.car_vin)
The trick here is that you pull values from the top of the class as they are set later in the code.
This answer works for grading
def __str__(self):
return f"Year: {}, VIN: {}".format(self.year_made, self.car_vin)`
This is easier to understand
def __str__(self):
f"Year: {self.year_made}, VIN: {self.car_vin}")
I have two classes (Student and Course). I'm trying to write a method for the Course class that will remove a given student from a course. However, there's a problem when I run
self.students.remove(student) in the method. The error tells me that student is not in the students list. Printing the students list I don't actually see the values, but instead I see a reference to it:
print(self.students)
> [<data.Student object at 0x7fc9980334f0>, <data.Student object at 0x7fc998033580>, <data.Student object at 0x7fc9980428b0>, <data.Student object at 0x7fc998042a00>]
However, if I select a specific student at an index then I'm able to see the actual data.
print(self.students[0])
> 2020411:King,Maha
Why is this happening when trying to print the students attribute?
Code if needed:
from copy import deepcopy
class Student:
def __init__(self, sid, last, first):
self.sid = sid
self.last = last
self.first = first
def __str__(self):
return '{}:{},{}'.format(self.sid, self.last, self.first)
def __repr__(self):
return '{}:{},{}'.format(self.sid, self.last, self.first)
class Course:
def __init__(self, crn, students):
self.crn = crn
self.students = deepcopy(students)
def key(self):
return self.crn
def is_empty(self):
return len(self.students) == 0
def get_student(self, student_key):
for student in self.students:
if student.key() == student_key:
return deepcopy(student)
return None
def __contains__(self, student):
for i in self.students:
if student.key() == i.key():
return True
break
return False
def register(self, student):
if student not in self:
self.students.append(deepcopy(student))
return
def drop(self, student):
s = None
if student in self:
s = deepcopy(student)
self.students.remove(student)
return s
student1 = Student(2020411, 'King', 'Maha')
student2 = Student(2019399, 'Hess', 'Alvin')
student3 = Student(2020301, 'Chin', 'Yu')
student4 = Student(2019111, 'Hay', 'Ria')
student_list = [student1, student2, student3]
course1 = Course('CP104', student_list)
removed_student = course1.drop(student2)
The issue with deepcopy() is that it creates an entirely new object that has the same attributes as the original one, yet they are not equal. For list.remove(), this compares the reference to check if the actual object exists. In your case, you are trying to remove an object that is not in the list.
Instead of removing it, if you want to return the student, use list.pop().
def drop(self, student):
for i, s in enumerate(self.students):
if s.sid == student.sid :
return self.students.pop(i)
As a side note, it will be easier to do operations if Course.students is a dictionary such that:
self.students = {
`sid1`: student1,
`sid2`: student2,
# etc
}
EDIT: Alternatively, implement __eq__() in Student so that list.remove() will work.
def __eq__(self, other):
return self.sid == other.sid and self.first == other.first and self.last == other.last
The Product class seems to work fine but I'm trying to figure out how to get the Inventory class to separate each product into there specific categories. I feel like I'm close but whenever I try and print out the inventory it just shows where it's stored in memory and doesn't actually print anything out. The output i receive when running is at the bottom. I want it to print out the actual products and data, not the instance of it stored in memory.
class Product:
def __init__(self, pid, price, quantity):
self.pid = pid
self.price = price
self.quantity = quantity
def __str__(self):
#Return the strinf representing the product
return "Product ID: {}\t Price: {}\t Quantity: {}\n".format(self.pid, self.price, self.quantity)
def get_id(self):
#returns id
return self.pid
def get_price(self):
#returns price
return self.price
def get_quantity(self):
#returns quantity
return self.quantity
def increase_quantity(self):
self.quantity += 1
def decrease_quantity(self):
self.quantity -= 1
def get_value(self):
value = self.quantity * self.price
return 'value is {}'.format(value)
product_1 = Product('fishing', 20, 10)
product_2 = Product('apparel', 35, 20)
class Inventory:
def __init__(self, products):
self.products = products
self.fishing_list = []
self.apparel_list = []
self.value = 0
def __repr__(self):
return "Inventory(products: {}, fishing_list: {}, apparel_list: {}, value: {})".format(self.products, self.fishing_list, self.apparel_list, self.value)
def add_fishing(self):
for product in self.products:
if product.get_id() == 'fishing':
self.fishing_list.append(product)
return '{} is in the fishing section'.format(self.fishing_list)
def add_apparel(self):
for product in self.products:
if product.get_id() == 'apparel':
self.apparel_list.append(product)
return '{} is in the apparel section'.format(self.apparel_list)
inventory_1 = Inventory([product_1, product_2])
inventory_1.add_fishing()
print(inventory_1)
OUTPUT = Inventory(products: [<main.Product instance at 0x10dbc8248>, <main.Product instance at 0x10dbc8290>], fishing_list: [<main.Product instance at 0x10dbc8248>], apparel_list: [], value: 0)
You need to specify how an object of the class Inventory should be printed.
To do this you need to implement at least one of the following functions in your class.
__repr__
__str__
This answer helps, which of both you should use: https://stackoverflow.com/a/2626364/8411228
An implementation could look something like this:
class Inventory:
# your code ...
def __repr__(self):
return str(self.products) + str(self.fishing_list) + str(self.apparel_list) + str(self.value)
# or even better with formatting
def __repr__(self):
return f"Inventory(products: {self.products}, fishing_list: {self.fishing_list}, apparel_list: {self.apparel_list}, value: {self.value})
Note that I used in the second example f strings, to format the output string.
Im trying to write a simple vending machine.
I have Container class that contains items and class Items contains information like the prize and the amount.
The ID indentifies the item. Every calling add item will increment ID by one, so that every item is unique.
I would like to get the prize of given ID.
So for example: I add item, it has ID=30, I give ID and it returns the prize of it.
I tried something like this, but it does not work:
from Item import Item
class Container:
id = 30
def __init__(self, objects=None):
if objects is None:
objects = {}
self.objects = objects
def add_object(self, obj: Item):
self.objects.update({id: obj})
Container.id = container.id + 1
def get_length(self):
return len(self.objects)
def find_price_of_given_id(self, id):
# return self.objects.get(id).get_price()
pass
Cola = Item(20)
print(Cola.get_amount())
container = Container()
container.add_object(Cola)
print(container.objects.items())
Item class:
class Item:
def __init__(self, price,amount=5):
self.amount = amount
self.price = price
def get_price(self):
return self.price
def get_amount(self):
return self.amount
I dont know why also print(container.objects.items()) returns dict_items([(<built-in function id>, <Item.Item object at 0x00000000022C8358>)]), why not ID = 30 + Item object
id is the name of a builtin method. Don't use it as a variable name - leads to name confusion.
You're assigning the id inside the container class but never giving it back, so that people can look up the item using the id.
In python3, dict.items returns a dict_items iterator, so you need to iterate over it to get to the items within.
class Item:
def __init__(self, price, amount=5):
self.amount = amount
self.price = price
def get_price(self):
return self.price
def get_amount(self):
return self.amount
def __str__(self):
return f"{self.amount} # {self.price}"
class Container:
item_id = 30
def __init__(self, objects=None):
if objects is None:
objects = {}
self.objects = objects
def add_object(self, obj: Item):
id_to_assign = Container.item_id
self.objects.update({id_to_assign: obj})
Container.item_id = Container.item_id + 1
return id_to_assign
def get_length(self):
return len(self.objects)
def find_price_of_given_id(self, item_id):
return self.objects.get(item_id).get_price()
Cola = Item(20)
print(Cola.get_amount())
container = Container()
cola_id = container.add_object(Cola)
print(container.objects.items())
print(container.find_price_of_given_id(cola_id))
Output:
5
dict_items([(30, <__main__.Item object at 0x104444b00>)])
20
I am using eval to run a generated string to append the newly created EggOrder instance to the list of the correct instance of the DailyOrders class. The day provided by EggOrder is used to used to append to the correct instance. This relies on eval and the variable name of the DailyOrders instance and so it would be great to get this removed. I know there must be a better way.
class DailyOrders:
PRICE_PER_DOZEN = 6.5
def __init__(self, day):
self.orders = []
self.day = day
def total_eggs(self):
total_eggs = 0
for order in self.orders:
total_eggs += order.eggs
return total_eggs
def show_report(self):
if self.total_eggs() < 0:
print("No Orders")
else:
print(f"Summary:\nTotal Eggs Ordered: {self.total_eggs()}")
print(f"Average Eggs Per Customer: {self.total_eggs() / len(self.orders):.0f}\n*********")
class EggOrder():
def __init__(self, eggs=0, name="", day=""):
if not name:
self.new_order()
else:
self.name = name
self.eggs = eggs
self.day = day
eval(f"{self.day.lower()}.orders.append(self)")
def new_order(self):
self.name = string_checker("Name: ")
self.eggs = num_checker("Number of Eggs: ")
self.day = string_checker("Date: ")
def get_dozens(self):
if self.eggs % 12 != 0:
dozens = int(math.ceil(self.eggs / 12))
else:
dozens = self.eggs / 12
return dozens
def show_order(self):
print(f"{self.name} ordered {self.eggs} eggs. The price is ${self.get_dozens() * DailyOrders.PRICE_PER_DOZEN}.")
if __name__ == "__main__":
friday = DailyOrders("Friday")
friday_order = EggOrder(12, "Someone", "Friday")
friday_order.show_order()
friday.show_report()
saturday = DailyOrders("Saturday")
saturday_order = EggOrder(19, "Something", "Saturday")
saturday_order = EggOrder(27, "Alex Stiles", "Saturday")
saturday.show_report()
DailyOrders isn't actually a superclass (it was in a earlier version), it acts like one and I suspect the answer might have some inheritance.