im trying to initialize a list object with various items found in a text file. However, whenever I call the argument, it says name "lib_list" is not defined, even though it is. I also tried calling catalog without the argument, but then it says a positional argument, "lib_list", required. I'm just not sure what to do and would greatly appreciate some insight
class InvalidItem(Exception):
#your code here
def __init__(self, error):
self.error
#defing InvalidOption Exception class
class InvalidOption(Exception):
def __init__(self, error):
self.error
#define a Catalog class and a serach method
class Catalog:
def __init__(self, lib_list: list):
self.lib_list = lib_list
def search(self, lib_type, lib_title):
for item in self.lib_list:
if type(item) == lib_type and item.Title == lib_title:
return item
return None
#define a LibraryItem class
class Library_Item:
def __init__(self, genre, author, stack_num):
self.genre = genre
self.author = author
self.stacknum = stack_num
#define a Book, Magazine class
class Book(Library_Item):
def __init__(self, title, genre, stack_num, isbn, author):
super().__init__(title, genre, stack_num)
self.isbn = isbn
self.author = author
def __str__(self):
listing = (f'{self.title}' \
f'{self.author}' \
f'{self.isbn}' \
f'{self.stack_num}')
return listing
class Magazine(Library_Item):
def __init__(self, title, genre, stack_num, volume_num, issue):
super().__init__(title, genre, stack_num)
self.volume_num = volume_num
self.issue = issue
def __str__(self):
listing = (f'{self.title}' \
f'{self.volume_num}' \
f'{self.issue}' \
f'{self.stack_num}')
return listing
#define a main function -----
def main():
file_name = 'D:\\Users\Owner\\Desktop\\library.txt'
lib_items = []
print("-----------------------")
print("Welcome to library menu")
print("-----------------------")
#read file information and create book/magazine object
with open(file_name, 'r') as f:
for line in f:
listings = line.strip().split(',')
item_type = listings[0]
title = listings[1]
genre = listings[2]
stack_num = listings[3]
#find the item type
if item_type == 'book':
#create a book object
isbn = listings[4]
author = listings[5]
book1 = Book(title,genre,stack_num,isbn,author)
listings.append(book1)
else:
volume_num = listings[4]
issue = listings[5]
mag1 = Magazine(title, genre, stack_num, isbn, issue)
listings.append(mag1)
LibCat = Catalog(lib_list)
print('Library Database loaded')
x = 1
while x ==1:
try:
choice = int(input("\n1. Search \n2. Exit \n Enter choice (1-2): "))
if choice != 1 and choice != 2:
raise InvalidOption("Invalid option. Returning to main menu")
except InvalidOption as invalid:
print(invalid.error)
continue
if choice == 1:
item_type = input("Please enter the item type (book/magazine): ")
item_title = input("Please enter the item title: ")
if item_type == "book":
item_type = Book
elif item_type == "magazine":
item_type = Magazine
else:
item_type = None
try:
search = LibCat.search(item_type, item_title)
if not search:
raise InvalidItem("Sorry, this itme is not valid")
else:
print("-----Item Information-----")
print(search)
except InvalidItem as item:
print(item.error)
continue
else:
print("Exiting database")
break
main()
You are trying to send lib_list in the class Catalog. The problem here is, in your main() function you have nowhere defined lib_list and lib_list is a parameter name for the Catalog __init__() it is not a pre-defined variable. To fix this error:
# Change line 82:
LibCat = Catalog(listings) # Assuming listings is your variable related with "lib_list"
You simply need to put the variable that you want the class to take as lib_list rather than putting lib_list itself.
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 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):
this is my product class
class Product(object):
def __init__(self,price,name,catalognum,starRating):
self.price = price
self.name = name
self.catalognum = catalognum
self.starRating = starRating
def __str__():
print "Catalognum:[0]\n\
Name: [1]\n\
Price: $[2]\n\
Rating: [3]".format(catalognum,name,price,num_starRating)
def num_starRating(self):
return "*"*int(self.rating)
class Book(object):
def __init__(self,price,name,catalognum,starRating,author,ISBN,publisher):
self.price = price
self.name = name
self.catalognum = catalognum
self.starRating = starRating
self.author = author
self.ISBN = ISBN
self.publisher = publisher
def __str__():
print "author:[0]\n\
Title:[1]\n\
Price:$[2]\n\
ISBN:[3]\n\
Publisher:[4]\n\
Rating[5]".format(author,Title,Price,ISBN,num_starRating)
class Movie(object):
def __init__(self,Director,Studio,Title,Price,Running_Time,starRating,name,catalognum):
self.Director = Director
self.Studio = Studio
self.Title = Title
self.Price = Price
self.Running_Time = Running_Time
self.starRating = starRating
self.name = name
self.catalognum = catalognum
def __str__():
print "Director:[0]\n\
Title:[1]\n\
Price:[2]\n\
Running_Time:[3]min\n\
Studio:[4]\n\
Rating[5]".format(Director,Title,Price,Running_Time,Studio,num_starRating)
This is my catalog class
class Catalog(object):
def __init__(self,product_file):
self.product_file = product_file
sortByColumn = 0
self.cataloglist = self.BuildCatalogList
def BuildCatalogList(self):
file = open(self.product_file,"r")
filelist = file.readlines()
product_list = []
for i in range(1,len(file_list)):
product = filelist[i].split(',')
item = product(float(product[2]),int(product[3]),product[1],product[0])
product_list.append(item)
return product_list
def setsortby(self,sortype):
self.sortbycolumn = sorttype
def printcatalogtable(self):
print “[0][1][2][3]”.format(“catalog #”,”name”,”price($)”,”rating”)
import os
directory = os.listdir(“.”)
for filename in directory:
if filename [:-3:] == “pyc”:
os.remove(filename)
catalog = catalog(“bookdata.txt)
for printcatalogtable
print”[0:20]][1:25][2:15][3]”.format(“catalog #”,”name”,”price($)”,”rating)
for product in cataloglist:
print “(0:20)(1:25)(2:15.2f) (3)”[3]”.format(product,catalognum,product,name,price,name,product,price,product.getstarrating())
Using two classes, I tried to print out my file i have saved in format that follows catalog class
but its not working out, any ideas?
It should work out like this:
Catalog Number (6 digits),Title,Price,Star Rating (1-5),Author First Name,Author Last Name,ISBN,Publisher
123456,Game of Thrones: A Song of Ice and Fire,11.99,5,George RR,Martin,9780553582017,Random House Publishing Group
654321,City of Bones,11.99,4,Cassandra,Clare,9781406331400,Margaret K McElderry Books
654613,How I Met My Husband,14.99,4,Alice,Munro,2354365435123,Book Bublishers Inc
524638,The Hunger Games,9.99,4,Susan,Collins,9780439023481,Scholastic Press
632356,Lives of the Saints,19.99,2,Ninno,Ricci,8883336666,Harol Hitch Hijackers Books
675031,1984,11.99,5,George,Orwell,1782127755,Secker and Warburg London
111111,Forbidden City,5.99,1,William,Bell,4435-13422453,Lamest Books Corp
315644,Harry Potter and the Prisoner of Azkaban,14.99,5,JK,Rowling,64569-7861-0537,Raincoast
478931,Fifty Shades of Grey,2.99,0,EL,James,783844-6512-982,BooksBooksBooks Inc.
101010,Breaking Dawn,0.99,1,Stephanie,Meyer,101010-1010-101,LOLOLOLOL Press
548573,The Great Gatsby,14.99,4,F Scott,Fitzgerald,9781597226769,Scribners
123827,Steve Jobs,39.99,4.5,Walter,Isaacson,9781451648539,Google Inc
453123,Twilight,0.1,1,Stephenie,Meyer,9781594133299,Simons Inc.
445234,A Midsummer Night's Dream,10.99,3,William,Shakespeare,123455-4322-144,Penguin Group
542324,Paper Town,12.99,2,John,Green,698773-3122-341,Penguin Group
991337,Shutter Island,19.99,4.5,Dennis,Lehane,1234567890154,Awesome Group
123431,The Magic School Bus at the Waterworks,50,5,Joanna ,Cole,0-590-40360-5,Scholastic Corporation
Your BuildCatalogList starts at 0 spaces this should be changed as below (and of course for all the other functions that belong to the class Catalog.
class Catalog(object):
def __init__(self,product_file):
self.product_file = product_file
sortByColumn = 0
self.cataloglist = self.BuildCatalogList
# Spaces added to this function.
def BuildCatalogList(self):
file = open(self.product_file,"r")
filelist = file.readlines()
product_list = []
for i in range(1,len(file_list)):
product = filelist[i].split(',')
item = product(float(product[2]),int(product[3]),product[1],product[0])
product_list.append(item)
return product_list
The indentation of __init__ and __str__ methods of Book and Movie classes are wrong. Indent it properly.