This assignment tests your understanding of and ability to apply the programming concepts we have covered throughout the unit. The concepts covered in the second half of the unit build upon the fundamentals covered in the first half of the unit.
You are required to design and implement two related programs:
The following pages describe the requirements of both programs in detail.
Starter files for both of these programs are provided along with this assignment brief, to help you get started and to facilitate an appropriate program structure. Please use the starter files.
As emphasised by the case study of Module 5, it is important to take the time to properly design a solution before starting to write code. Hence, this assignment requires you to write and submit pseudocode of your program design for "admin.py", but not fruit_test.py (pseudocode is not very well suited to illustrating the design of an event-driven GUI program). Furthermore, while your tutors are happy to provide help and feedback on your assignment work throughout the semester, they will expect you to be able to show your pseudocode and explain the design of your code.
You will gain a lot more benefit from pseudocode if you actually attempt it before trying to code your program - even if you just start with a rough draft to establish the overall program structure, and then revise and refine it as you work on the code. This back and forth cycle of designing and coding is completely normal and expected, particularly when you are new to programming. The requirements detailed on the following pages should give you a good idea of the structure of the program, allowing you to make a start on designing your solution in pseudocode.
See Reading 3.3 for further information and tips regarding writing good pseudocode.
Write a separate section of pseudocode for each function you define in your program so that the pseudocode for the main part of your program is not cluttered with function definitions. Ensure that the pseudocode for each of your functions clearly describes the parameters that the function receives and what the function returns back to the program.
It may help to think of the pseudocode of your program as the content of a book, and the pseudocode of functions as its appendices: It should be possible to read and understand a book without necessarily reading the appendices, however they are there for further reference if needed.
The functions required in the "admin.py" program are detailed later in the assignment brief.
The following pages describe the requirements of both programs in detail.
"admin.py" is a program with a Command-Line Interface (CLI) like that of the programs we have created throughout the first half of the unit. The entirety of this program can be implemented in under 200 lines of code - If your program exceeds this, ask your tutor for advice. Everything you need to know in order to develop this program is covered in the first 7 modules of the unit. This program should be developed before fruit_test.py.
This program allows the user to manage data regarding the nutritional information of fruit. The user can add a new fruit to the data by specifying its name and the following nutritional information per 100 grams: Calories, Dietary Fibre (in grams), Sugar (in grams) and Vitamin C (in milligrams). The program also allows the user to list, search, view and delete fruit in the data.
The data is stored in a text file named "data.txt". Use the json module to write data to the text file in JSON format and to read the JSON data from the file back into Python. See Reading 7.1 for details regarding this. To illustrate the structure of the data, below is an example of the file's content in JSON format (which is almost identical to Python):
[
{
"name": "Apple",
"calories": 52.0,
"fibre": 2.4,
"sugar": 10.0,
"vitamin_c": 4.6
},
{
"name": "Banana",
"calories": 89.0,
"fibre": 2.6,
"sugar": 12.0,
"vitamin_c": 8.7
}
]
This example file contains the details of fruit as items in a list. Each of those items is a dictionary consisting of 5 items which have keys of "name", calories, fibre, sugar and vitamin_c - a string and four floats.
If this file was to be read into a Python variable named data, then "data[0]" would refer to the dictionary containing the first fruit (Apple), and data[0]['fibre'] would refer to the float of 2.4.
Understanding the structure of this data and how you can use it is very important in many aspects of this assignment - in particular, you will need to understand how to loop through the items of a list and how to refer to items in a dictionary. Revise Module 3 and Module 7 if you are unsure about how to interact with lists and dictionaries, and see the Blackboard discussion board for further help.
To help you visualise the "admin.py" program, here is an annotated screenshot of it being used: see image.
In the following information, numbered points describe a requirement of the program, and bullet points (in italics) are additional details, notes and hints regarding the requirement. Ask your tutor if you do not understand the requirements or would like further information. The requirements are:
1. The first thing the program should do is try to open a file named "data.txt" in read mode, then load the data from the file into a variable named data and then close the file.
2. The program should then print a welcome message and enter an endless loop which starts by printing a list of options: "Choose [a]dd, [l]ist, [s]earch, [v]iew, [d]elete or [q]uit." and then prompts the user to enter their choice. Once a choice has been entered, use an if/elif to respond appropriately (detailed in the following requirements).
3. If the user enters "a" (add), prompt them to enter all 5 details of a fruit, beginning with the name. Place the details into a new dictionary with the structure shown on the previous page, and append the dictionary to the data list, then write the list to the text file in JSON format.
4. If the user enters "l" (list), display the names of all fruit in the data list preceded by their index number, or a No fruit saved error message if there is nothing in the list.
5. If the user enters "s" (search), prompt for a search term and then list the fruit whose name contains the search term. Remember to include the index number next to each result.
6. If the user enters "v" (view), prompt them for an index number and then print the corresponding fruit's name and all of its nutritional information.
7. If the user enters "d" (delete), prompt them for an index number and then remove the corresponding fruit from the data list, then display a Fruit deleted message.
8. If the user enters "q" (quit), print Goodbye! and break out of the loop to end the program.
9. If the user enters anything else, print an "Invalid choice" message (the user will then be re- prompted for a choice on the next iteration of the loop).
This concludes the core requirements of "admin.py". The following pages detail the functions mentioned above and optional additions and enhancements that can be added to the program. Remember that you are required to submit pseudocode for your design of admin.py.
The requirements above mentioned four functions - "inputInt()", inputFloat(), inputSomething(), and saveData(). As part of admin.py, you must define and use these functions.
1. The "inputInt()" function takes one parameter named prompt. The function should repeatedly re-prompt the user (using the prompt parameter) for input until they enter an integer. It should then return the value as an integer.
2. The "inputFloat()" function takes one parameter named prompt. The function should repeatedly re-prompt the user (using the prompt parameter) for input until they enter a float. It should then return the value as a float.
3. The "inputSomething()" function takes one parameter named prompt. The function should repeatedly re-prompt the user (using the prompt parameter) for input until they enter a value which consists of at least one non-whitespace character (i.e. the input cannot be nothing or consist entirely of spaces, tabs, etc.). It should then return the value as a string.
4. The "saveData()" function takes one parameter named dataList (this will be the data list). The function should open data.txt in write mode, then write the dataList parameter to the file in JSON format and close the file. This function does not return anything.
The definitions of these functions should be at the start of the program (as they are in the starter file provided), and it should be called where needed in the program. Revise Module 4 if you are uncertain about defining and using functions, and be sure to implement them so that they receive and return values exactly as described above. It is important to adhere to function specifications.
In particular, remember that the "prompt" parameter of the first three functions is for the text that you want to show as a prompt. Here is an example of the function being called and its output:
age = inputInt('Enter your age: ') -> Enter your age:
You are welcome to write additional functions if you feel they improve your program.
"fruit_test.py" is a program with a Graphical User Interface (GUI), as covered in Module 9. It should be coded in an Object Oriented style, as covered in Module 8. Everything you need to know in order to develop this program is covered in the first 9 modules of the unit. This program should be developed after admin.py. The entirety of this program can be implemented in under 125 lines of code - If your program exceeds this, ask your tutor for advice. To ensure compatibility and consistency, you must use the tkinter module to create the GUI. You will also need to use the tkinter.messagebox, random and json modules.
This program uses the data from the "data.txt" file. Similar to the admin program, this program should load the data from the file once only when the program begins. The program implements a simple quiz by randomly selecting two different fruit and one nutritional component (calories, fibre, sugar or Vitamin C) and using them to present the user with a True/False question to answer. see image.
When the user clicks one of the buttons, the program should determine whether their answer is correct and show an appropriate messagebox: see image.
A new question is then generated and displayed, and the program continues like this until the user closes it - selecting two random fruit and a random nutritional component each time.
The following pages detail how to implement the program.
The constructor (the "__init__" method) of your GUI class must implement the following:
1. Create the main window of the program and give it a title of "Fruit Test".
2. Try to open the "data.txt" file in read mode and load the JSON data from the file into an attribute named self.data, and then close the file.
3. Check if self.data contains fewer than two items, and if so show an error messagebox with a "Not enough fruit" message and destroy the main window.
4. Create an attribute named "self.components" and set it to a list containing strings of calories, fibre, sugar and vitamin_c.
5. The constructor should then use Label, Button and Frame widgets from the "tkinter" module to implement the GUI depicted on the previous page.
self.btnTrue = tkinter.Button(self.btnFrame, text='True', command=lambda: self.checkAnswer(True))
6. Lastly, the constructor should end by calling the "self.showQuestion" method to place the first question into the GUI, and then call tkinter.mainloop() to start the main loop.
That is all that the constructor requires. The following pages detail the methods mentioned above, and some optional additions and enhancements. You are not required to submit pseudocode for your design of "fruit_test.py", as pseudocode is not particularly well suited to illustrating the design of an event-driven GUI program.
Your GUI class requires two methods to implement the functionality of the program - "self.showQuestion" and self.checkAnswer. As part of the GUI class of fruit_test.py, you must define these methods. I have described the required functionality of the methods rather than giving step-by-step instructions: It is up to you to design and implement the necessary code.
1. The "self.showQuestion" method randomly selects two fruit from self.data and a nutritional component from self.components and uses them to show a True/False question in the GUI. The question should be in the following format (or similar):
100 grams of < name of fruit 1> contains more < name of component>
than 100 grams of < name of fruit 2>.
2. The "self.checkAnswer" method determines whether the user clicked the correct button and shows a Correct/Incorrect messagebox. The method should receive a parameter named answer, which will contain True or False (boolean) depending on which button was clicked. Your code must determine if the user's answer is correct, and show an appropriate messagebox, and then call the self.showQuestion method to select and show a new question.
These two methods are all that are required to implement the functionality of the program, but you may write/use additional methods if you feel they improve your program.