Question
Classes: The most important learning outcome of this assignment is to be able to use classes to create reusable data types that simplify and modularise
Classes:
The most important learning outcome of this assignment is to be able to use classes to create reusable data types that simplify and modularise your programs. The fact that you can use these classes in both console and GUI programs highlights this modularity.
It is important that you create these classes first - before any code that requires them. This is good coding practice. You should and then test each method of each class - one at a time - committing as you go (e.g., you might commit each time you complete a method and its tests).
The starter code includes two files (test_book.py and test_bookcollection.py) with inco mplete code for testing your classes. Com plete these files with simple tests, that you write as you develop your Book and BookCollection classes.
Do not change the existing tests... wri te code that makes these tests pass.
You may use assert as shown in lectures [1], or just very simple tests that print the results of calling the methods you are testing with expected and actual results [2].
Once you have writ ten and tested your classes, you can then use the Book class in your console program.
We will assess your Git commit history to see (and mark) that you do these in an appropriate order, so make sure you wri te your classes, with tests, then the console program, before attempting any functionality for the GUI.
Complete the Book class in book.py. This should be a simple class with the required attributes for a book (title, author, number of pages, whether or not it is required) and the methods:
__init__
__str__
two methods to mark the book as required/completed
method to determine if a book is considered "long", which is defined as having 500+ pages.
Complete the BookCollection class in bookcollection.py. This class should contain a single attribute: a list of Book objects, and at least the following methods:
load books (from csv file into Book objects in the list)
save books (from book list into csv file)
add book - add a single Book object to the books attribute
get number of required pages
sort (by the key passed in, then by title) (see attrgetter from [3])
Do not store any additional attributes in this class. (E.g., you don't need to store the number of books because this information is easily derived from what you do store.)
Remember to test your classes before moving on to using them in the following programs.
Console Program:
After you have wr itten and tested your classes, rewrite your first assignment to make use of your new Book class. Optionally, you may also use the BookCollection class in your console program. Start by copying the code from your first assignment into the existing a1_classes.py file and committing. In the first assignment, each book was stored as a list. Modify your code so that each book is stored as an object of your new Book class.
You do not need to r ewr ite your first assignment in any other way, even if it had problems, but you are welcome to. We will only evaluate how you use the Book class in the program.
GUI Program:
Please be sure you have compl eted the classes and console program before you attempt the GUI. In the past, students have writ ten a working GUI program without any classes and missed the main point of the assignment.
(The display and functionality explained here is also shown in the screencast video demo.)
The GUI program should have the following features, as demonstrated in the accompanying screencast video. Comp lete the main program in a Kivy App subclass in main.py. [4, 5]
The data (model) for this program should be a single BookCollection object.
The program should load the CSV file of books using the method from BookCollection.
The books file must be saved when the program ends (there's a method for that!), updating any changes made with the app by the user (see on_stop method from [5]).
The left side of the screen contains a drop-down "spinner" for the user to choose the sorting (see spinner_demo from [4]), and text entry fields for inputting information for a new book. You might like to consider using a dictionary to help with mapping the GUI text to the attributes of the class to be sorted by.
The right side contains a button for each book, colour-coded based on whether the book is complet ed or not (the actual colour scheme is up to you).
The status bar at the top shows the number of pages to read.
The status bar at the bottom shows program messages.
If the program runs and the default 'books.csv' file does not exist, the program should display a warning status message and continue. It can still save the file at the end.
When the user clicks on a book button, the book changes between comp leted and required (see guitars_app.py from [4] for an example of using Kivy with custom objects associated with buttons).
The text to display when a book button is clicked is like (where "name" is the actual book name):
You need to read name.
You completed name.
You need to read name. Get started!
You completed name. Great job!
For long books, it should be like:
Adding Books (Error Checking):
The user can add a new book by entering text in the input fields and clicking "Add Book".
All book fields are required. If a field is left blank, the bottom status label should display "All fields must be comp leted" when "Add Book" is clicked.
The number of pages field must be a valid integer. If this is invalid (and no other fields are empty), the status bar should display "Please enter a valid number".
If number of pages is less than 1, the status label should display "Pages must be > 0".
Pressing the Tab key should move between the text fields. (popup_demo from [4])
When a book is successfully added, the entry text fields should be cleared and the new book button should appear in its sorted location. (dynamic_widgets from [4])
When the user clicks the "Clear" button, all text in the input fields and the bottom status label should be cleared.
General Coding Requirements:
At the very top of your main.py file, complete the comment containing your details.
Document all your classes and methods clearly with docstrings. Include inline/block comments as appropriate. You do not need comments in the kv file.
Make use of named constants where appropriate. E.g., colours could be constants.
Use functions/methods appropriately for each significant part of the program. Remember that functions should follow the Single Responsibility Principle.
Use exception handling where appropriate to deal with input errors. When error checking inside functions (e.g., a handler for clicking the Add Book button), you might like to consider the "Function with error checking" pattern from [6].
Comp lete your GUI design using the kv language in the app.kv file. Creating the book buttons should be done in main.py, not in the kv file, since this will be dynamic (dynamic_widgets from [4]).
a1_classes.py
"""(Incomplete) Tests for Book class.""" from book import Book
app.kv:
# Create your Kivy layout in the kv language here | |
BoxLayout: |
book.py
bookcollection.py
books.csv
books_backup.csv
main.py
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started