Python Key error -when trying to use statements - python-3.x

Here is my code i am getting a key error on line 31, something to do with the word 'Reserved'
#Create a loan class that will allow members to borrow books
class Loan(Book, Member):
"""Class that allows members to reserve,cancel reservations, return and borrow books
Librarians can extract the data
pre-conditions: inherits from Book and member classes
if the above is not correct the data wont be
"""
#classmethod
#set up a class in order to borrow a book
def Borrow(cls, name, title):
"""
Parameters
----------
cls : TYPE
"""
#Find ID of book/member
BookID = Book.scan(title)[0]
MemberID = Member.scan(name)[0]
#check if the book is available
Status = books[BookID]['Available']
#if the book is available check then check the different reservations
if Status == "Yes":
#if the book is not reserves then issue the book and add a new entry
if books[BookID]["Reserved"] == "No": #THIS IS LINE 31
dateToday = datetime.datetime.now().strftime('%Y-%m-%d')
loans[len(loans)+1]={'BookID':BookID, 'MemberID':MemberID, 'Date of loan': dateToday, 'Date of return':'NaN', 'Length of borrow':'NaN'}
books[BookID]["Available"] = "No"
print("You have now borrowed", title)
#if the books is reserved and the member is first in the queue
#remove the member from the reservation list and record new record
elif books[BookID]["Reserved"] == "Yes" and books[BookID]["ReservedID"][0] == MemberID:
dateToday = datetime.datetime.now().strftime('%Y-%m-%d')
loans[len(loans)+1] = {'BookID':BookID, 'MemberID':MemberID, 'Date of loan': dateToday, 'Date of return':'NaN', 'Length of borrow':'NaN'}
books[BookID]["Available"] = "No"
Loan.RemoveReservation(name, title)
if len(books[BookID]["ReservedID"]) == 0:
books[BookID]["Reserved"] = "No"
print("You have now borrowed", title)
#if the member has reserved the book but there is someone else renting it
elif books[BookID]["Reserved"] == "Yes" and MemberID in books[BookID]["ReservedID"]:
print(title, "is not available at the moment. You can reserve this though")
#if the book isnt available and the member hasnt reserved it
else:
print(title, "is not available")
#
#
elif Status == "No":
if MemberID in books[BookID]["ReservedID"]:
print(title, "not ready")
else:
print(title, "not ready")
Loan.Borrow(name="Charlie Roberts", title ="God Created the Integers")
print(books[Book.scan("God Created the Integer")[0]])
print(loans[len(loans)])

A KeyError means that that key does not exist in the dictionary. If you want to check for existence of a key, either wrap it in a try/catch:
try:
doSomething(myDict['invalidKey'])
except KeyError:
#Process error
OR
Check if the key exists first:
d = {"a": 1, "b": 2}
if "a" in d.keys():
#The key was in the dictionary
else:
#The key wasn't in the dictionary
If you want to add the key to your dictionary, you'll have to set the key equal to a value first:
>>> d = {}
>>> d['a']
KeyError
>>> d['a'] = "foo"
>>> d['a']
foo

Related

list of lists to find an element from user input

right now, I'm trying to do a simple program, where user can add new, view, search, and delete. But as for now, I'm stuck at def findEmp(): below is my code and I'm really appreciate for you guys to help me with this problem.
When I key in the existing name 'mia' from global list, the result show 'Employee name not exist'.
from tabulate import tabulate
emps_global = [['mia','hr','admin']] # existing element
tablehead = ['Name', 'Department', 'Position']
def addnew():
emp_new = [] # empty local list
emp_new.append(input("Enter name: "))
emp_new.append(input("Enter department: "))
emp_new.append(input("Enter position: "))
emps_global.append(emp_new) # append local list to global list called emps_global
print(emps_global) # print out list of lists for emps_global
def findEmp():
emp = input("Enter employee name: ") # even existing name in the global list show 'not exist'
if emp in range(len(emps_global)): # i'm not sure this is correct or not
print("Yes employee exist")
elif emp not in range(len(emps_global)):
print("Employee name not exist")
def view():
print(tabulate(emps_global, headers=tablehead, tablefmt='psql'))
def deleteInfo():
pass
while True:
print("[1] to add")
print("[2] to search")
print("[3] to view")
print("[4] to delete")
inp = input(">> ")
if inp == '1':
addnew()
elif inp == '2':
findEmp()
elif inp == '3':
view()
elif inp == '4':
deleteInfo()
else:
print("Wrong input")
Edit you findEmp() as
def findEmp():
emp = input("Enter employee name: ") # even existing name in the global list show 'not exist'
for entry in emps_global:
if entry[0]==emp: # i'm sure this is correct or not
return entry
return "Name does not exist"
the range(len(emp_globs)) gives a list of numbers from 0 to len(emp_globs), so your condition compares the input name with a number, hence it doesn't work.

Why do I keep getting the AttributeError: 'str' object has no attribute 'Student' when running my program

I am trying to run a program that implements Object Oriented Programming to help a student register for a course. I keep running into an Attribute Error and can't seem to figure out where my code went wrong.
I initially thought it had something to do with the fact that I had not implemented the self parameter in all the method def statements. But after I fixed this, I still encountered the same error message.
ONE = 1
TWO = 2
THREE = 3
FOUR = 4
FIVE = 5
TRUE = True
FALSE = False
COURSES_INPUT = 'courses-sample.txt'
STUDENTS_INPUT= 'students-sample.txt'
import student
import course
def main():
process_students()
process_courses()
option = get_option()
while option != 5:
if option == 1:
course_num = input('please input course number of course you wish to add: ')
add_course = new_student.add_course(course_num)
while add_course == FALSE:
print('The course requested for add does not exist. Please Try Again.')
course_num = input('Please input course number of course you wish to add: ')
if new_course.space_available() == TRUE:
new_course.enroll_student()
else:
print('Class requested does not have any seats available.')
if option == 2:
course_num = input('please input course number of course you wish to drop: ')
drop_course = new_student.drop_course(course_num)
while drop_course == FALSE:
print('The enrolled course requested for drop does not exist. Please Try Again.')
course_num = input('Please input course number of course you wish to drop: ')
new_course.drop_student()
if option == 3:
print_student_info(student_dict)
if option == 4:
print_course_schedule(course_dict)
option = get_option()
write_updated('students-updated.txt',student_dict)
write_updated('courses-updated.txt',course_dict)
def print_menu():
print("1. Add course")
print("2. Drop course")
print("3. Print student's schedule")
print("4. Print course schedule")
print("5. Done")
print("")
def get_option():
print_menu()
choice = input("What would you like to do? ")
while choice not in range(1,6):
print_menu()
choice = input("Choice is invalid. What would you like to do? ")
return choice
def process_students():
student_dict = {}
student_info = open(STUDENTS_INPUT,"r")
for student in student_info:
info_list = student.split(":")
new_id = info_list[0]
first_name = info_list[1]
last_name = info_list[2]
course_list = info_list[3:]
new_student = student.Student(new_id, first_name, last_name, course_list)
print(new_student.line_for_file())
student_dict[new_eid] = new_student
student_info.close()
def process_courses():
course_dict = {}
course_info = open(COURSES_INPUT,"r")
for course in course_info:
info_list = course.split(";")
unique_num = info_list[0]
class_name = info_list[1]
prof = info_list[2]
seats = info_list[3]
capacity = info_list[4]
new_course = course.Course(unique_num, class_name, prof, seats, capacity)
course_dict[unique_num] = new_course
course_info.close()
def print_course_schedule(course_dict):
for value in course_dict:
print(value)
def print_student_info(student_dict):
for value in student_dict:
print(value)
def get_id():
eid = input("What is the UT EID? ")
while eid not in student_dict:
eid = input("Invalid UT EID. Please re-enter: ")
return eid
def get_unique():
unique = input("What is the course unique number? ")
while unique not in course_dict:
unique = input("Invalid unique number. Please re-enter: ")
return unique
def write_updated(filename,dictionary):
output_file = open(filename,'w')
for key in dictionary:
output_file.write(dictionary[key])
output_file.close()
main()
Error Message:
Traceback (most recent call last):
File "C:\Users\njung\Downloads\MIS 304 Final Project\untitled folder\Nguyen_Calvin_Jung_Nicholas-FP.py", line 132, in <module>
main()
File "C:\Users\njung\Downloads\MIS 304 Final Project\untitled folder\Nguyen_Calvin_Jung_Nicholas-FP.py", line 24, in main
process_students()
File "C:\Users\njung\Downloads\MIS 304 Final Project\untitled folder\Nguyen_Calvin_Jung_Nicholas-FP.py", line 83, in process_students
new_student = student.Student(new_id, first_name, last_name, course_list)
AttributeError: 'str' object has no attribute 'Student'
>>>
I also have the classes used stored in separate files (was required for the program) and have imported the modules containing these classes into main as you can see at the top.
Your error is AttributeError: 'str' object has no attribute 'Student'
Looking at the trace, it seems that it originates from this code:
student_info = open(STUDENTS_INPUT,"r")
for student in student_info:
info_list = student.split(":")
new_id = info_list[0]
first_name = info_list[1]
last_name = info_list[2]
course_list = info_list[3:]
new_student = student.Student(new_id, first_name, last_name, course_list)
Here you've opened a file. student_info is the file, and you iterate over the lines in the file. Each line student is a string.
You later call student.Student(new_id, first_name, last_name, course_list), but since student is just a string, it naturally does not contain a Student method.

TypeError: '>=' not supported between instances of '_Printer' and 'int'

Trying to program a vending machine
I'm trying to check if the entered money is enough. (products)
But it keeps giving me that error-message. (TypeError: '>=' not supported between instances of '_Printer' and 'int')
products = {
"A": [100, "cola"],
"B": [100, "drink0"]
}
def coinCounter():
print("Bitte Münzen einwerfen! / Betrag eingeben!")
credits = int(input("Betrag: "))
def product():
print("Bitte Produkt wählen!")
choosedProduct = input("Produkt: ").capitalize()
if choosedProduct in products and credits >= products[choosedProduct][0]:
output = True
elif choosedProduct not in products:
print("Das Produkt existiernt nicht.")
elif products[choosedProduct][0] >= credits:
print("Du hast nicht genug Geld eingeworfen")
def moneyBack(moneyBack):
moneyBack = credits - products[choosedProduct][0]
print("Zurück: ", moneyBack)
def output(output, choosedProduct):
if output == True:
print("Das Produkt", choosedProduct[1], "wird ausgegeben...")
output = False
output()
moneyBack()
def main():
coinCounter()
product()
main()
The problem is one of scope.
When you set credits in coinCounter, this assignment is local to the function and not visible to the outside world. Why does your script not crash with a NameError? Because there is a global builtin object called credits, which you can call (or print) to see a short copyright notice:
>>> credits
Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
for supporting Python development. See www.python.org for more information.
You try to compare this object to an integer, which fails.
Instead, have coinCounter return the amount of credits and call coinCounter either in product, or call it in main and give the value as an argument to product:
products = {
"A": [100, "cola"],
"B": [100, "drink0"]
}
def coinCounter():
print("Bitte Münzen einwerfen! / Betrag eingeben!")
return int(input("Betrag: "))
def product(credits):
print("Bitte Produkt wählen!")
choosedProduct = input("Produkt: ").capitalize()
if choosedProduct in products and credits >= products[choosedProduct][0]:
output = True
elif choosedProduct not in products:
print("Das Produkt existiernt nicht.")
elif products[choosedProduct][0] >= credits:
print("Du hast nicht genug Geld eingeworfen")
def moneyBack(moneyBack):
moneyBack = credits - products[choosedProduct][0]
print("Zurück: ", moneyBack)
def output(output, choosedProduct):
if output == True:
print("Das Produkt", choosedProduct[1], "wird ausgegeben...")
output = False
output()
moneyBack()
def main():
credits = coinCounter()
product(credits)
main()
input() returns a string: https://docs.python.org/3.0/library/functions.html#input
"TypeError exception is raised when an operation or function is applied to an object of inappropriate type. The associated value is a string giving details about the type mismatch": https://docs.python.org/3/library/exceptions.html#TypeError
You cannot compare a string to an int, therefore you have to convert the input value to int: int(input("Betrag: ")).
`

Need Help: TypeError: 'in <string>' requires string as left operand, not list

I am trying to get my code to give me information such as price of an item if I input the brand "Nike" or anything like that. However, I am getting the error code as the title. Please any help would be appreciated
clothing_brands = [
["544", "Jordan", "Shoes", 200],
["681", "Stussy", "Sweatshirt", 50],
["481", "Obey", "T-Shirt", 30],
["339", "North Face", "Jacket", 80],
["250", "Levis", "Jeans", 40],
["091", "Nike", "Socks", 10],
]
def findClothing(brand):
found = False
for brand in clothing_brands:
if clothing_brands in brand[1]:
found = True
break
if found:
return brand
else:
return None
def printBrand(brand):
print ("\n~~~~Thrift Shop Brands:~~~~")
print ("Item Number:", brand[0])
print ("Brand Name:", brand[1])
print ("Clothing Type:", brand[2])
print ("Price:", brand[3])
if __name__ == "__main__":
print ("\n~~~Welcome to Macklemore's clothing Thrift Shop~~~~")
print ("1) Add a brand you would like to see us carry")
print ("2) What is the brand's clothing type?")
print ("3) What is the price of a particular brand?")
print ("4) What is a brand's information?")
print ("5) Print everything we have in stock")
print ("0) Exit")
while True:
option = input ("Please Select a Menu item.")
if (option == "0"):
break
if (option == "1"):
Item_number = input ("What is the Item Number?")
Brand_name = input ("What is the name of the Brand?")
Clothing_type = input ("What type of clothing is the Brand?")
Price = input ("How much is the item?")
brand = [Item_number, Brand_name, Clothing_type, Price]
clothing_brands.append(brand)
print ("Thank you for your input, We will begin searching to add that item into our inventory")
print (Brand_name, Clothing_type, Price)
print ("Come back in a couple of days to see if we have added the item")
if (option == "2"):
brand = input ("What is the brand you are looking for information on?")
brand = findClothing(brand)
if (brand != None):
print ("The Clothing type of this brand is:", brand[2])
if (option == "3"):
brand = input ("What is the brand you are looking for information on?")
brand = findClothing(brand)
if (brand != None):
print ("The Price of the brand is:", brand[3])
if (option == "4"):
brand = input ("What is the brand you are looking for information on?")
brand = findClothing(brand)
if (brand != None):
printBrand (brand)
else:
print ("Sorry, we do not carry this brand. If you would like for us to search for this brand, Please try option 1!")
if (option == "5"):
for brand in clothing_brands:
print (brand)
Your findClothing method does not use its input parameter (it's overwritten by the loop variable) and is instead using if clothing_brands in brand[1]: which makes no sense since clothing_brands is not even a string.
Fixing that fixes your error;
def findClothing(input_brand):
found = False
for brand in clothing_brands:
if input_brand in brand[1]:
found = True
break
if found:
return brand
else:
return None

Global Name "msg" not defined

I'm currently writing a class called SMS_store(). In it, I have a method called delete.
Delete is simply supposed to make sure the user has given me a valid integer. If so, it's supposed to pop an item from the list.
class SMS_store():
def __init__(self):
self.__inbox = []
def delete(self, i):
if i >= len(self.__inbox):
return None
else:
self.__inbox.pop[i]
Whenever I run the code in my test program, I run into two errors at my delete stage:
1) if I type myInbox.delete(2) when there's only 2 items in the list, I get "list index out of range" and I though I was protected from that error. myInbox.delete(3) gives me None.
2) If I type myInbox.delete(1) when there's a valid index 1 in my list, it says global name 'msg' not defined. I don't get why I'm seeing that error.
Here's my full class code.
#SMS_store class
"""
Pre-condition: SMS_store class is instantiated in client code.
Post-condition: SMS_store class is instantiated.
"""
class SMS_store():
#Object instantiation
"""
Pre-conditon: SMS_store class is instantiated in client code.
Post-condition: Object creates an empty list.
"""
def __init__(self):
self.__inbox = []
#add_new_arrival method
"""
Pre-condition: Class method is handed a valid phone number of 11, 10, or 7
digits as a string with no hyphens or letters, a string containing a time,
and a string containing the text of a message.
Post-condition: Method will append a tuple containing False for an
undread message, the phone number, the time arrived and the text of the
message to the class created list.
"""
def add_new_arrival(self, from_number, time_arrived, text_of_SMS):
number = from_number
#Check for valid phone number and add hyphens based on number length
if len(number) == 11:
number = number[0] + "-" + number[1:4] + "-" + number[4:7] + "-"\
+ number[7:]
elif len(number) == 7:
number = number[:3] + "-" + number[3:]
elif len(number) == 10:
number = "1-" + number[:3] + "-" + number[3:6] + "-" + number[6:]
elif number.isalpha():
number = "Invalid number"
else:
number = "Invalid number"
time = time_arrived
text = text_of_SMS
message = (False, number, time, text)
self.__inbox.append(message)
#message_count method
"""
Post-condition: method returns the number of tuples in class created list.
Returns None if list is empty.
"""
def message_count(self):
count = len(self.__inbox)
if count == 0:
return None
else:
return count
#get_unread_indexes method
"""
Post-condition: method creates an empty list,checks for any tuples with
"False" at index 0. If "False" is found, it appends the index for the
tuple in the list. Method returns list of indexes.
"""
def get_unread_indexes(self):
unread = []
for message in self.__inbox:
if message[0] == False:
unread.append(self.__inbox.index(message))
return unread
#get_message method
"""
Pre-condition: Method is passed an integer.
Post-condition: Method checks for a valid index number. If valid, the
method will then check if indexed tuple contains "True" or "False" at index
0. If True, message is returned in new tuple containing items from indexes
1, 2, and 3. If False, a new tuple is created containing "True"
indicating the message is now read, plus indexes 1, 2, and 3 from the
original called tuple.
"""
def get_message(self, i):
#check for valid index number
if i >= len(self.__inbox):
return None
else:
msg = self.__inbox[i]
if msg[0] == True:
return (msg[1], msg[2], msg[3])
#create new tuple with True, and index 1-3 from original tuple
else:
self.__inbox.pop(i)
newMsg = (True, msg[1], msg[2], msg[3])
self.__inbox.insert(i, newMsg)
return newMsg[1:]
#delete method
"""
Pre-condition: Method is passed an integer.
Post-condition: Method checks that the integer is a valid index number. If
valid, method pops index from class created list.
"""
def delete(self, i):
if i >= len(self.__inbox):
return None
else:
self.__inbox.pop(i)
#Clear method
"""
Post-condition: method resets the inbox to an empty list.
"""
def clear(self):
self.__inbox = []
Here's how I am using the code in my test program:
#Test instantiation
naomisInbox = SMS_store()
martisInbox = SMS_store()
#Test add_new_arrival
naomisInbox.add_new_arrival("12345678912", "10:38PM", "Yay! Sorry, been")
martisInbox.add_new_arrival("23456789123", "10:37PM", "Hey I finally hit 90")
martisInbox.add_new_arrival("12345678912", "10:40PM", "Now I sleep :)")
naomisInbox.add_new_arrival("23456789123", "10:40PM", "Night")
#Test message_count
count = naomisInbox.message_count()
print("Naomi has", count, "messages in her inbox.")
count = martisInbox.message_count()
print("Marti has", count, "messages in his inbox.\n")
#Test get_unread_indexes
numUnread = naomisInbox.get_unread_indexes()
print("Naomi has unread messages at indexes: ", numUnread)
numUnread = martisInbox.get_unread_indexes()
print("Marti has unread messages at indexes: ", numUnread,"\n")
#Test get_message
msg = naomisInbox.get_message(9)
print("Getting message from Naomi's inbox at index [9]: ")
if msg == None:
print("No message at that index.")
else:
for item in msg:
print(item)
print("\n")
numUnread = naomisInbox.get_unread_indexes()
print("Naomi now has unread messages at indexes: ", numUnread, "\n")
msg = martisInbox.get_message(1)
print("Getting message from Marti's inbox at index [1]:")
for item in msg:
print(item)
print("\n")
numUnread = martisInbox.get_unread_indexes()
print("Marti now has unread messages at indexes: ", numUnread, "\n")
#Test delete
remove = naomisInbox.delete(0)
if remove == None:
print("Invalid index.")
count = naomisInbox.message_count()
numUnread = naomisInbox.get_unread_indexes()
print("Naomi now has", count, "messages with unread messages at index: ",\
numUnread)
#Test clear
print("\nAfter clearing: ")
naomisInbox.clear()
count = naomisInbox.message_count()
print("Naomi now has", count, "messages in her inbox.")
martisInbox.clear()
count = martisInbox.message_count()
print("Marti now has", count, "messages in his inbox.")
Error
Error:
Traceback (most recent call last):
File "/home/theriddler/Documents/CSIS153/Assignments/Nansen3/Nansen3.py", line 56, in <module>
remove = naomisInbox.delete(0)
File "/home/theriddler/Documents/CSIS153/Assignments/Nansen3/modSMS.py", line 125, in delete
NameError: global name 'msg' is not defined
Any help is appreciated. Sorry if it's a repeated question. Thanks, Blackwell.
for your first problem.
1)if there are only two items in the list then you cannot delete the 2nd item by passing 2 as index it should be 1.
2)your second problem tells that you are using same msg variable in SMS_store class within different functions without defining it as self variable for the class. However cant find any thing for now. You should probably check it again as it works well on my machine.
Now a little more light on your delete method:
def delete(self, i):
if i >= len(self.__inbox):
return None
else:
self.__inbox.pop(i)
Here if you want to delete the last message always then just use self.__ibox.pop() without passing any index but in case you want to delete an indexed message then u should do self.__ibox.pop(i-1)
because in case i is last element of the list then it will always be equal to length of the list and else will never be executed.
Also your delete method returns None only in if condition but if else runs then again None is returned by default so
remove = naomisInbox.delete(0)
if remove == None:
print("Invalid index.")
This will always print 'invalid index' as message even if the message gets deleted.

Resources