updating class object from main function Python - python

I have a book library program that it's class reads a file containing ID and name and assign them to self objects as id and card holder. then there is self object for borrowed books, so then I can identify which user borrowed which book.
The problem is in main function when a user return a book, I don't know how to update the self borrowed book object to delete that book from the object, so the self id will not have books borrowed to it.
Here is how the class looks:
#loan time length is 3 weeks by default
LOAN_TIME = 3
class Librarycard:
def __init__(self, card_id, card_holder):
self.__id = card_id
self.__holder = card_holder
#a dictionary that will contain the full book : loan time, updated in later function
self.__loan = {}
def return_book(self, book):
del self.__loan[book]
print('returned')
return
and this is my main function part which concern the book loaning:
def main():
command = input("Command: ")
#borrowed books main list to check if book borrowed or not
borrowed_books = []
if command == "R":
book = input("Book code: ")
if book not in borrowed_books:
print('This book has not been borrowed by anyone')
else:
del borrowed_books[book]
print('book returned')
# this is where I try to enter the function from the class to update the object
# dictionary
book.return_book(book)
if __name__ == "__main__":
main()

A couple of issues here.
First, the book that comes from the input is a string and not the actual book class. So, when calling book.return_book(book), the compiler is looking for a method return_book in the string class (which is obviously not there).
Second, borrowed_books is never being updated in the main class, so the user will never return any books.
Third, instead of using del in the Class, use self.__loan.pop(book). It is the inbuilt python function, and is a better way to remove the book.
Finally, there are a lot of camel case issues
Here is what the final code may look like.
class LibraryCard:
def __int__ (self, card_id, card_holder):
self.card_id=card_id
self.__card_holder=card_holder
self.checked_out={}
def return_book (self, book_id):
popped = self.checked_out.pop(book_id, "Book was already returned, or was never checked out")
if (popped != "Book was already returned, or was never checked out"):
print("Book returned: "+popped)
else:
print(popped)
def isCard(self, id, name):
return self.card_id==id and self.__card_holder==name
def main():
cards = {}
while (true):
command = input("To check out a book press \"C\", to return a book press \"R\" (without the quotes):\t")
print("Whether or not you have an account, please follow the instructions below")
card_id=input("Enter your card id:\t")
user_name=input("For security purposes, enter your name:\t")
if (user_id not in cards):
print("Welcome to Library Services")
cards[user_id] = LibraryCard(card_id, user_name)
if (not cards[user_id].isCard(user_id, user_name)):
print("Wrong user name or user id, please retry")
continue
if (command=="C"):
book=input("Enter the name of the book you would like to check out: ")
cards[user_id].checked_out[book]=3
print("Checked out successfully!")
else:
book=input("Enter the name of the book you would like to return: ")
cards[user_id].return_book(book)

class Librarycard:
def __init__(self, card_id, card_holder):
self.__id = card_id
self.__holder = card_holder
# a dictionary that will contain the full book : loan time, updated in later function
self.__loan = {'tttt': {},"uuuu":{}}
def return_book(self, book):
del self.__loan[book]
print('returned')
return
def main():
# command = input("Command: ")
command = "R"
# borrowed books main list to check if book borrowed or not
borrowed_books = ["tttt","aaaa"]
if command == "R":
# book = input("Book code: ")
book = "tttt"
if book not in borrowed_books:
print('This book has not been borrowed by anyone')
else:
borrowed_books.remove(book)
print('book returned')
library_book = Librarycard('card_id', 'you know holder')
print("before ",library_book._Librarycard__loan)
library_book.return_book(book)
print("after ",library_book._Librarycard__loan)
if __name__ == "__main__":
main()
C:\Users\sharp\AppData\Local\Programs\Python\Python39\python.exe C:/Users/sharp/Desktop/project/testid.py
book returned
before {'tttt': {}, 'uuuu': {}}
returned
after {'uuuu': {}}
Process finished with exit code 0

I have fixed it in a way that I added a new variable that connects the class in the main function, then did a loop that runs into all the cards inside the class keys of the class, and finally with that key I activated the return book function.
The main issue was that I didn't create an access for which ID I wanted to delete the book from. but once activated with the for loop I was able to reach all ID'S object and delete the book from the one that has it.
Here is how the code looks like in the specific parts concerning this problem:
def main():
#function that reads the text file and assign the card ids and card holders as a
#dictionary.
library = read_card_data("library.txt")
while True:
command = input("Command: ")
if command == "R":
book = input("Book code: ")
if book not in borrowed_books:
print('This book has not been borrowed by anyone')
else:
del borrowed_books[book]
for card in library.keys():
library[card].return_book(book)

Related

Problem adding and deleting objects from python class

Please can someone help me to fix the code, I want to create a school class and create an object. After that, I want to use the join function to add students ( if a student exists it will not add it and it will show a message, and if not exists it will add the student), same as the leave function (it will delete from the list only if exists). and finally, the show_all function will display all the values in the list. I think the structure of the code is wrong, so please can someone help me
class School:
def __init__(self):
print("A class has opened!")
def join(self, student):
self.student = student
if self.student not in my_school:
print(self.student +" is a new member of the school!")
else:
print("We already have "+ self.student +".")
def leave(self):
if self.student in my_school:
del self.student
else:
print("No such student")
def show_all(self):
print(my_school)
# create new object in class
my_school = School()
# add the student if not exists only
my_school.join('Sarah')
# delete if exists
my_school.leave("Noor")
# show all the list
my_school.show_all()
Your code has several errors:
When you call join (a bad method name, because it already exists) you reassign the student to single variable.
In leave you reference the instance witch is not possible because it doesn't jet exist.
Here is some code:
class School:
def __init__(self):
print("An instance of School was created!")
self.students = []
def join(self, student):
if student not in self.students:
self.students.append(student)
print(student + " is a new member of the school!")
else:
print("We already have "+ student +".")
def leave(self, student):
if student in self.students:
self.students.remove(student)
else:
print("No such student")
def show_all(self):
print(self.students)
# create new object in class
my_school = School()
# add the student if not in students
my_school.join("Sarah")
# delete the student if in the students list
my_school.leave("Noor")
# print the students
my_school.show_all()
This is by no means good code, but comes close to what you wanted to achieve.

Error while calling python function, TypeError: returnbook() missing 1 required positional argument: 'self'

I have created a python program where customers can return book and borrow book from Library, while executing I gets error * TypeError: borrow() missing 1 required positional argument: 'self' *
What changes I should make to execute the program successfully ?
I will call returnbook() function initially as the library have no books at present.
class Library:
def __init__(self):
self.availablebook = availablebook
def reducebook(self,book):
if book in self.availablebook:
self.availablebook.remove(book)
print('book is removed')
def addbook(self,book):
self.availablebook.append(book)
print('book added')
class Customer:
def borrow(self):
print('enter book')
book = input()
Library.reducebook(book)
def returnbook(self):
print('enter book')
book = input()
Library.addbook(book)
while True:
print('enter 1 for add book,2 for borrow book,3 to exit')
self.x = int(input())
if(x==1):
Customer.borrow()
elif(x==2):
Customer.returnbook()
else:
print('exiting')
quit()
Create an instance of the Customer class, do not use the class directly:
customer = Customer()
customer.borrow()
customer.returnbook()
availablebook should be a list in __init__ function.
self.availablebook = []
Also, Modify your while loop.
while True:
print('enter 1 for add book,2 for borrow book,3 to exit')
x = int(input())
if(x==1):
Customer().borrow()
elif(x==2):
Customer().returnbook()
else:
print('exiting')
quit()
There are some mistakes in your code :
self.x is not an attribute from a class. You can just write x.
You have to add the availablebook variable as an input of init function
You get a missing argument because you do not create your Library and Customer classes the good way. You can write Library([]).borrow() if you consider adding availablebook input, else just write Library().borrow().
I think the best is to create a library before you loop : my_lib = Library([])
Then add a library input in your Customer functions in order to edit the library you want and hence avoid creating a new library each time.
Here is the code I would suggest you :
class Library:
def __init__(self, availablebook):
self.availablebook = availablebook
def reducebook(self, book):
if book in self.availablebook:
self.availablebook.remove(book)
print('book is removed')
def addbook(self,book):
self.availablebook.append(book)
print('book added')
class Customer:
def borrow(self, library):
print('enter book')
book = input()
library.reducebook(book)
def returnbook(self, library):
print('enter book')
book = input()
library.addbook(book)
my_lib = Library([])
while True:
print('enter 1 for add book,2 for borrow book,3 to exit')
x = int(input())
if(x==1):
Customer().borrow(my_lib)
elif(x==2):
Customer().returnbook(my_lib)
else:
print('exiting')
quit()

How to make a function that calls aand prints each students name and courses

Here is what i have so far
from CSE_324_course import Course
from CSE_324_skeleton_student import Student
math = Course("Algebra I")
language = Course("Spanish I")
science = Course("Earth Science")
history = Course("U.S. History I")
phys_ed = Course("Physical Education I")
speaking = Course("Speech I")
art = Course("Art I")
test_student = Student("Jill", "Sample")
test_student.add_course(math)
test_student.add_course(language)
test_student.add_course(science)
test_student.add_course(history)
test_student2 = Student("Bill", "Sample")
test_student2.add_course(math)
test_student2.add_course(phys_ed)
test_student2.add_course(science)
test_student2.add_course(history)
test_student3 = Student("Kim", "Sample")
test_student3.add_course(language)
test_student3.add_course(speaking)
test_student3.add_course(science)
test_student3.add_course(art)
student_list=[test_student,test_student2,test_student3]
for (test_student,test_student2,test_student3 : get_course)
if (test_student().equals(search))
System.out.println(teststudnetgetCourse());
#Each iteration should:
#get,concatenate, and print the first and last name of the student
#print all courses for that student
#print a blank line between students
'''for this part you may need to review the other skeleton code to:
- see how to get items from a list
- see if there is code (like a function) in that file you can call in this file
- verify that running this file gets you the correct output with information from that file
Also, review syntax of pulling items from a list f
2 page of code
Course import Course
class Student:
student_id = 0
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
self.courses = []
self.student_id = Student.student_id
Student.student_id += 1
def __str__(self):
# TODO You will need to use a variable in the loop, so you must intialize it here,
# that variable will need to be initalized to get items listed in the first def _init_ section
# TODO add a loop that will go through the course list
# TODO Add code here to create a string representation of a student,
# including first and last name and all courses that student is taking
return "complete this return statement based on your in loop variable"
def get_first_name(self):
return self.first_name
def get_last_name(self):
return self.last_name
def get_student_id(self):
return self.student_id
def add_course(self, new_course):
# TODO add code to append new_course to self.courses
print "Course not yet added, implementation needed."
3rd page
class Course:
def __init__(self, course_name):
self.course_name = course_name
def __str__(self):
return self.course_name
I think you are looking to change
for (test_student,test_student2,test_student3 : get_course)
if (test_student().equals(search))
System.out.println(teststudnetgetCourse());
(which you have improperly indented) to:
for student in student_list:
print("{} {}".format(student.first_name, student.last_name))
for course in student.courses:
print(course) # This won't work because "2 page of code Course import Course" needs to be finished
print("\n") # blank line between students

How do I fix these errors for a short assignment in creating classes in Python?

I have a short assignment I need to complete that has to do with creating classes, and I'm not sure what the problem with my code is. Here are the instructions below and underneath that is my code. Please explain what my error(s) is/are and how to fix it/them:
Build 2 classes. The first class will be a "Book" class. The book class has 4 variables that are all private. The first is checkedOut which is a Boolean value initialized to false, title which is a string that is initalized by a input variable, author which is a string and is initialized by an input variable, pages that is an integer and is also initialized by an input variable. This class will also have 4 functions associated with is. The first will return the variable checkedOut. The second will change the value of checkedOut. If the value is set to true, then it will be changed to false and vice versa. The third function will return the number of pages and the final function will return the title. When a book object is printed it be in the format of "title author pages checkedOut".
The second class will be called a library. When the library is initialized it will create a empty dictionary called collection. The library class will have 2 functions. The first function will be called addBook and it will take in 3 input variables, title, author, and pages. In this function you will create a book object, then add it to the dictionary with the title as the key. The second function will take in the title of a book, find the book in the dictionary and call the books function that changes the checkedOut status. The finally, when a library object is printed out, it will print out each book in the library on a separate line.
Finally the library class will be implemented in a python program called main.py.
Here is my code:
class Book:
title = str(input("Enter the title of the book. "))
author = str(input("Enter the author of the book. "))
pages = int(input("Enter the number of pages in the book. "))
checkedOut = False
def checked_Out(self):
print(checkedOut)
return checkedOut
def change_value_of_checkedOut(self):
if checkedOut == False:
checkedOut = True
print("Switched from False to True.")
elif checkedOut == True:
checkedOut = False
print("Switched from True to False.")
def return_pages(self):
print(pages)
return pages
def return_title(self):
print(title)
return title
class Library(Book):
def __init__(self):
collection = {}
def addBook(self, title, author, pages):
new_book = Book()
collection[title] = author
def change_checked_out_status(self, title):
if title in collection:
new_book.change_value_of_checkedOut(self)
else:
print("This book is not in the collection.")
What is wrong with what I did here? I keep getting errors to the effect that a certain variable name is not defined when I try to create objects and run the code in IDLE.
(0) Next time, paste the errors.
class Book:
title = str(input("Enter the title of the book. "))
author = str(input("Enter the author of the book. "))
pages = int(input("Enter the number of pages in the book. "))
checkedOut = False
def checked_Out(self):
print(checkedOut)
return checkedOut
(1) Just this part.
checkedOut is not defined. Where do you see checkedOut? right above the function checked_Out. Okay. Short answer, add self..
Example:
def checked_Out(self):
print(self.checkedOut)
return self.checkedOut
And you really should not be doing the title, author stuff there. They become class variables, not instance variables. There's a difference.
(2) Avoid input if you are still using 2.x Python.
Use raw_input and get rid of str. That's safer. In the 3.x you can use input and it will always be string (raw_input will always return string). That's also causing problem.
(3) You have the tenadacy of captializing everything. I am usually pretty chill but it kinds of bad. Don't call it checked_Out that's really inconsistent plus Python programmers prefer checked_out. checkedOut can be named to checked_out and hey, you can conflict. Don't name your function and variables so similar.
Create the class separately, and get the input separately. Also, you want to mention that each variable is an instance variable, not in the local scope:
class Book:
def __init__(self, title, author, pages):
self.title = title
self.author = author
self.pages = pages
self.checkedOut = False
def checked_Out(self):
print(self.checkedOut) # it has to be the instance variable
return self.checkedOut
def change_value_of_checkedOut(self):
if self.checkedOut == False:
self.checkedOut = True
print("Switched from False to True.")
elif self.checkedOut == True:
self.checkedOut = False
print("Switched from True to False.")
def return_pages(self):
print(self.pages)
return self.pages
def return_title(self):
print(self.title)
return self.title
class Library:
def __init__(self):
collection = {}
def addExistingBook(self, book):
collection[book.title] = book.author
def addNewBook(self, title, author, pages): # create a book
new_book = Book(title, author, pages)
collection[title] = new_book.author # access the author
def change_checked_out_status(self, title):
if title in collection.keys():
title.change_value_of_checkedOut()
else:
print("This book is not in the collection.")
Then, add the rest in a main function:
def main():
# if you are using Python 2.x, change input() to raw_input()
title = str(input("Enter the title of the book. "))
author = str(input("Enter the author of the book. "))
pages = int(input("Enter the number of pages in the book. "))
myBook = Book(title, author, pages)
myLib = Library()
myLib.addExistingBook(myBook)

Class deletion in cmd but not in IDLE

When I run this code in the command prompt, the Person I create is automatically deleted, but when in IDLE the deletion does not occur. Why?
NOTE: This is a program that is supposed to create an address book (a list of dictionaries)
Here is my code:
list = []
class bookEntry(dict):
total = 0
def __init__(self):
bookEntry.total += 1
self.d = {}
def __del__(self):
bookEntry.total -= 1
list.remove(self)
class Person(bookEntry):
def __init__(self, n):
bookEntry.__init__(self)
self.n = n
print '%s has been created' % (self.n)
def __del__(self):
print '%s has been deleted' % (self.n)
def addnewperson(self, n, e = '', ph = '', note = ''):
self.d['name'] = n
self.d['email'] = e
self.d['phone'] = ph
self.d['note'] = note
list.append(self)
I run the code with a startup function:
def startup():
aor = raw_input('Hello! Would you like to add an entry or retrieve one?')
if aor == 'add':
info = raw_input('Would you like to add a person or a company?')
if info == 'person':
n = raw_input('Please enter this persons name:')
e = raw_input('Please enter this persons email address:')
ph = raw_input('Please enter this persons phone number:')
note = raw_input('Please add any notes if applicable:')
X = Person(n)
X.addnewperson(n, e, ph, note)
startup()
When the code is run in IDLE I receive the following prompts, and submit the following answers:
'''
Hello! Would you like to add an entry or retrieve one?add
Would you like to add a person or a company?person
Please enter this persons name:Pig
Please enter this persons email address:pig#brickhouse.com
Please enter this persons phone number:333-333-3333
Please add any notes if applicable:one of three
Pig has been created
'''
Here, Pig is created and is not deleted. But in cmd.....
'''
Hello! Would you like to add an entry or retrieve one?add
Would you like to add a person or a company?person
Please enter this persons name:Pig
Please enter this persons email address:pig#brickhouse.com
Please enter this persons phone number:333-333-3333
Please add any notes if applicable:one of three
Pig has been created
Pig has been deleted
'''
Why is Pig being deleted?? __del__ is never called...
While you run in IDLE, the python process is still running even after you execute this program unless you exit from IDLE. But in command line, the python process executes your program and exits itself. So, that is where __del__ comes into play. When the reference count of the object is zero, it is automatically called to destroy it. so your object is deleted. When your program is ended and python process is itself terminated, there is no need for it to exist as well.
Reference
When the program ends, all variables are automatically deleted (otherwise, there would be a memory leak). IDLE keeps the environment open so you can keep using the variables you've created.
Note: My original answer was mistaken- I missed the lines
list = []
and
list.append(self)

Categories

Resources