class BookReadList(App): def build(self): # Create the main widget for Kivy program self.booklist = BookList() self.booklist.load_books() self.title = "Reading List 2.0" # Kivy title self.root = Builder.load_file("app.kv") # load Kivy self.loading() # load the books return self.root def loading(self): count = 0 total = 0 self.root.ids.entriesBox.clear_widgets() # clear all the widgets self.root.ids.status_label.text = "Click books to mark them as completed" for item in self.booklist.requirelist: temp_button = Button(text=item.title, background_color=[ count - 0.5, 0, 1, 1 ]) # setting background colour temp_button.book = item temp_button.bind( on_release=self.handle_mark) # if click display the list self.root.ids.entriesBox.add_widget(temp_button) count += 1 total = self.booklist.getRequirePage() if count == 0: # Situation when no book there self.root.ids.top_label.text = "No required items" # Show the prompt at the top label self.root.ids.entriesBox.clear_widgets() # Clear the list widgets else: # Else print total price at the top label self.root.ids.top_label.text = "Total pages to read: {}".format( total) # Else show the total price of required items at top babel def handle_mark( self, book ): # Function when user click the button of the required item (Each required button) name = book.text self.booklist.complete_book( book.book ) # Using "c" instead of "r" in the list when user chooses the item self.root.ids.status_label.text = ( "{} marked as completed".format(name) ) # Show the marked item at the status label def completed(self): # Function for the completed item (Completed button) count = 0 total = 0 self.root.ids.entriesBox.clear_widgets() # Clear the list widgets for book in self.booklist.completelist: # using for loop to separate to sorted file temp_button = Button(text=book.title) # Setting the button text temp_button.book = book temp_button.bind(on_release=self.handle_completed ) # Setting when user click the button self.root.ids.entriesBox.add_widget( temp_button) # Add widgets for each completed item count += 1 total = self.booklist.getCompletePage() if count == 0: # If total count = 0, then means no completed item self.root.ids.top_label.text = "No completed items" # Show the prompt at the top label self.root.ids.entriesBox.clear_widgets() # Clear the list widgets else: self.root.ids.top_label.text = "Total pages completed: {}".format( total) # Else show the total price of completed items at top babel def handle_completed( self, book ): # Function when user click the button of the completed item (Each conpleted button) self.root.ids.status_label.text = "{},write by {}, pages:{}, (completed)".format( book.book.title, book.book.author, book.book.pages) # Show the detail of the completed item at the status label def handle_add(self): # Function for adding new item (Add item button) title = self.root.ids.input_name.text # Let user enter the item name author = self.root.ids.input_author.text # Let user enter the pages of item pages = self.root.ids.input_pages.text # Let user enter the priority of item if title == "" or pages == "" or author == "": # If any field is blank, show error prompt self.root.ids.status_label.text = "All fields must be completed" else: try: # Using exception let user enter valid number author = self.root.ids.input_author.text pages = int(self.root.ids.input_pages.text) except ValueError: self.root.ids.status_label.text = "Please enter a valid number" else: if pages <= 0: self.root.ids.status_label.text = "pages must be >= 0" else: book = Book(title, author, pages, flag='r') self.booklist.add_book(book) self.root.ids.status_label.text = "book \'{}\' wrote by {} in {} pages has been add to book list".format( title, author, pages) # show the added item at the status label self.root.ids.input_name.text = "" self.root.ids.input_author.text = "" self.root.ids.input_pages.text = "" # Clear whole input box after the new item add to the list # Error check def handle_clear( self): # Function for clear whole input box (Clear button) self.root.ids.input_name.text = "" self.root.ids.input_author.text = "" self.root.ids.input_pages.text = "" def save_item( self ): # Function for saving completed item to the file (Save item button) file_writer = open("books.csv", "w") # Open the file with the correct format count = 0 writer = csv.writer(file_writer) for book in self.booklist.requirelist: writer.writerow([book.title, book.author, book.pages, book.flag]) count += 1 for book in self.booklist.completelist: writer.writerow([book.title, book.author, book.pages, book.flag]) count += 1 self.root.ids.status_label.text = "{} items saved to items.csv".format( count) # Display how many items which add to the file at the status label file_writer.close()
""" (incomplete) Tests for BookList class """ from booklist import BookList from book import Book books = BookList() # test empty BookList print(books) assert len(books.book_list) == 0 # test loading books books.load_books() print(books) assert len(books.book_list) > 0 # assuming CSV file is not empty # test adding a new Book books.add_book('In Search of Lost Time', 'Marcel Proust', 365) print(books) assert len(books.book_list) >= 0 # test saving books (check CSV file manually to see results) books.save_books() assert len(books.book_list) > 0 # test get book by title function book = books.get_book_title('The Practice of Computing Using Python') print(book) # test total number of pages for required
from booklist import BookList from book import Book # test empty BookList book_list = BookList() print(book_list) assert len(book_list.books) == 0 # test loading books book_list.load_books('books.csv') print(book_list) assert len(book_list.books) > 0 # assuming CSV file is not empty # test sorting books # test adding a new Book # test saving books (check CSV file manually to see results)
class ReadingListApp(App): BOOK_FILE = "books.csv" # file of books LONG_COLOUR = (0, 1, 1, 1) # colour for books 500 pages or over SHORT_COLOUR = (1, 1, 0, 1) # colour for books under 500 pages def __init__(self): super(ReadingListApp, self).__init__() self.book_list = BookList() self.top_status_bar = Label(id="top_status_bar", text="total pages", size_hint_y=None, height=50) self.bottom_status_bar = Label(id="bottom_status_bar", text="click books to mark them as complete", size_hint_y=None, height=50) def build(self): self.title = "Reading List 2.0" self.root = Builder.load_file("app.kv") self.book_list.load_books(self.BOOK_FILE) self.create_buttons("r") # creates buttons for required books return self.root def create_buttons(self, book_type): self.get_list_type(book_type) # changes what menu widget is highlighted and what the status bars say depending on the type of book chosen self.clear_buttons() self.book_list.sort_books() self.root.ids.books.add_widget(self.top_status_bar) if self.book_list.is_empty(book_type) == 0: empty_label = Label() self.root.ids.books.add_widget(empty_label) # creates a filler label if there aren't any books that match the chosen type self.create_book_buttons(book_type) self.root.ids.books.add_widget(self.bottom_status_bar) def add_book(self, title, author, pages): valid = 0 while valid == 0: if self.root.ids.title_input.text == "" or self.root.ids.author_input.text == "" \ or self.root.ids.pages_input.text == "": self.bottom_status_bar.text = "All fields must be complete" break try: book = Book(title, author, int(pages)) except ValueError: self.bottom_status_bar.text = "Please enter a valid number" break if book.pages < 0: self.bottom_status_bar.text = "Pages must be >= 0" break else: self.bottom_status_bar.text = "{} {}".format(str(book), "was added") self.book_list.add_book(Book(self.root.ids.title_input.text, self.root.ids.author_input.text, self.root.ids.pages_input.text)) valid = 1 self.clear_buttons() self.create_buttons("r") self.clear_text() def clear_buttons(self): self.root.ids.books.clear_widgets() def clear_text(self): self.root.ids.title_input.text = "" self.root.ids.author_input.text = "" self.root.ids.pages_input.text = "" def completed_button_information(self, instance): book = self.book_list.get_book_from_title(instance.text) self.bottom_status_bar.text = "{} {}".format(book, "(completed)") def create_book_buttons(self, book_type): for book in self.book_list.books: if book.book_type == book_type: # splits up required and completed books temp_button = Button(text=str(book.title)) if book.book_type == "r": temp_button.bind(on_release=self.mark_completed) if book.is_long(): temp_button.background_color = self.LONG_COLOUR else: temp_button.background_color = self.SHORT_COLOUR # buttons for required books else: temp_button.bind(on_release=self.completed_button_information) self.root.ids.books.add_widget(temp_button) # buttons for completed books def get_list_type(self, book_type): if book_type == "r": self.top_status_bar.text = "{}{}".format("Total pages to read: ", self.book_list.get_required_pages()) self.bottom_status_bar.text = "Click books to mark them as completed" self.root.ids.list_required.state = "down" self.root.ids.list_complete.state = "normal" else: self.top_status_bar.text = "{}{}".format("Total pages completed: ", self.book_list.get_completed_pages()) self.bottom_status_bar.text = "Click books to view details" self.root.ids.list_complete.state = "down" self.root.ids.list_required.state = "normal" def mark_completed(self, button): book = self.book_list.get_book_from_title(button.text) Book.mark_complete(book) self.create_buttons("r") self.bottom_status_bar.text = "{}{}".format("Completed: ", str(book)) def on_stop(self): self.book_list.save_books(self.BOOK_FILE)