Assignment Overview

You are required to design and implement two related programs:

  • admin.py, a CLI program that allows the user to manage a collection of simple setup and punchline jokes which are stored in a text file. Develop this program before jokebot.py.
  • jokebot.py, a GUI program that uses the data in the text file to display the jokes and allow the user to rate them. Develop this program after admin.py.

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.

Pseudocode

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 jokebot.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.

Three functions are required in this assignment (detailed later in the assignment brief). The following pages describe the requirements of both programs in detail.

Requirements of admin.py

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 175 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 jokebot.py.

This program allows the user to manage the details of a collection of jokes which are 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. This is an example of the files content in JSON format (which is almost identical to Python):

[
{
"setup": "What do you call a group of 8 hobbits?",
"sumOfRatings": 0,
"punchline": "A hobbyte.",
"numOfRatings": 0
},
{
"setup": "I once drank some food colouring...",
"sumOfRatings": 0,
"punchline": "It made me feel like I had dyed a little inside.",
"numOfRatings": 0
}
]

This example file contains two items in a list. Each of those items is a dictionary consisting of 4 items which have keys of setup, punchline, numOfRatings and sumOfRatings. If this file was to be read into a Python variable named data, then data[0] would refer to the dictionary containing the first joke (about hobbits), and data[0]['numOfRatings'] would refer to 0 (integer).

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 data.txt in read mode, then load the data from the file into a variable named data and then close the file.

  • The data in the file should be in JSON format, so you will need to use the load() function from the json module to read the data into your program. See the previous page for details of the data.
  • If any exceptions occur (due to the file not existing, or it not containing valid JSON data), then simply set the data variable to be an empty list.

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 below).

3. If the user enters a (add), prompt them to enter the setup and punchline of a joke, and use them to create a new dictionary with the structure shown on the previous page. Append the dictionary to the data list, then write the list to the text file in JSON format to save the joke.

  • Use your inputSomething() function (detailed below) when prompting for the setup and punchline, to ensure that the user is re-prompted until they enter something.
  • The dictionary for the new joke should contain 4 keys setup and punchline should contain what the user entered, and numOfRatings and sumOfRatings should be given values of 0.
  • Once the joke has been added to the data list, call your saveChanges() function (detailed below) to write the changes to the text file.

4. If the user enters l (list), display a list of the jokes (just the setup) preceded by their index number in the data list, or a No jokes saved error message if there is nothing in the list.

  • Use a for loop to iterate through the jokes in the data list.
  • You can use the enumerate() function to make sure you have a variable containing the index number of each joke as you loop through them (see Lecture 3).

5. If the user enters s (search), prompt for a search term and then list the jokes whose setup or punchline contains the search term. Remember to include the index number next to each result.

  • This is a good opportunity to reuse and tweak the code used to list all jokes the loop body needs an if to only print jokes that contain the search term (use the in operator see Lecture 3).
  • Convert the search term, joke setup and punchline to lowercase to find matches regardless of case.
  • Use your inputSomething() function (detailed below) when prompting for the search term, to ensure that the user is re-prompted until they enter something.

6. If the user enters v (view), prompt them for an index number and then print the corresponding jokes setup and punchline, including details of the jokes rating.

  • If the jokes numOfRatings key contains a 0, show a Joke has not been rated message. Otherwise, show how many times the joke has been rated and the average rating of the joke (rounded to 1 decimal place), e.g. Rated 3 time(s). Average rating is 3.3/5.
  • Use your inputInt() function (detailed below) when prompting for an index number, to ensure that the user is re-prompted until they enter an integer.
  • Display an Invalid index number message if the user enters an index number that doesnt exist in the data list. Also consider showing a No jokes saved message and not allowing the user to specify an index number if the data list is empty.

7. If the user enters d (delete), prompt them for an index number and then remove the corresponding item from the data list, then display a Joke deleted message.

  • Use your inputInt() function (detailed below) when prompting for an index number, to ensure that the user is re-prompted until they enter an integer.
  • Display an Invalid index number message if the user enters an index number that doesnt exist in the data list. Also consider showing a No jokes saved message and not allowing the user to specify an index number if the data list is empty.
  • Once the joke has been deleted from data list, call your saveChanges() function (detailed below) to write the changes to the text file.

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, the additional requirements for CSP5110 students, optional additions and enhancements, and an annotated screenshot of the program.

Since jokes are rated in the GUI program (jokebot.py) the ratings aspect of the assignment will make more sense once you have read the rest of the assignment brief.

Remember that you are required to submit pseudocode for your design of admin.py.

Functions in admin.py

The requirements above mentioned three functions - inputInt(), inputSomething(), and saveChanges(). You must define and use these functions as part of admin.py.

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.

  • See Workshop 4 for instructions regarding a similar function.

2. The inputSomething() function takes one parameter named prompt. The function repeatedly re-prompt the user (using the prompt parameter) for input until they enter a value which consists of at least one character once all whitespace has been stripped from the start and end of it. It should then return the value as a string.

  • Use the strip() method on a string to remove whitespace from the start and end.
  • Note that exception handling is of no use in this function.

3. The saveChanges() 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.

  • This is the only part of the program that should be writing to the file, and it always simply overwrites the entire content of the file with the entirety of the current data.
  • See Reading 7.1 for an example of using the json module. You can specify an additional indent parameter in the dump() function to format the JSON data nicely in the file.

You may write/use additional functions if you feel they improve your program.

Requirements of jokebot.py

jokebot.py is a program with a Graphical User Interface (GUI), as covered in Module 9. 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 150 lines of code If your program exceeds this, ask your tutor for advice.

This program uses the data from the data.txt file to show one joke at a time, allowing the user to rate the joke before showing the next one. Once all of the jokes have been shown, the program ends. To ensure compatibility and consistency, you are required to use the tkinter module for the GUI of jokebot.py. You will also need to use the tkinter.messagebox module and the json module.

To help illustrate the jokebox.py program, here are some annotated screenshots of it being used: (Your program may look slightly different, depending on which version of which operating system you use) see image.

See the content of Module 9 for examples of creating a class for your programs GUI. A starter file has been provided to assist you. For conciseness, I have referred to attribute names without the self. prefix in the following details.

Implement all of the following requirements, and ask your tutor if you do not understand any of the requirements or would like further information. The requirements of the program are:

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 Joke Bot.

  • You may also wish to set other settings such as the minimum size of the window.

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. Also create an attribute named self.currentJoke and set it to 0.

  • If any exceptions occur (due to the file not existing, or it not containing valid JSON data), show an error messagebox with a Missing/Invalid file message and use the destroy() method on the main window to end the program. Include a return statement in the exception handler after destroying the main window to halt the constructor so that the program ends cleanly.
  • self.currentJoke will keep track of which joke in self.data the program is up to.

3. The constructor should then use Label, Entry, Button and Frame widgets from the tkinter module to implement the GUI depicted on the previous page.

  • You will save time if you take time to design the GUI and determine exactly which widgets you will need and how to lay them out before you start writing the code.
  • You are welcome change the layout of the GUI, as long as the functionality is implemented.
  • See Reading 9.1 for information regarding various settings that can be applied to widgets to make them appear with the desired padding, colour, size, etc.
  • The Button that allows users to submit the rating should call the rateJoke method (detailed below) when clicked.

4. Finally, the constructor should end by calling the showJoke method to place the first joke 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, the additional requirements for CSP5110 students and optional additions and enhancements.

You are not required to submit pseudocode for your design of jokebot.py, as pseudocode is not particularly well suited to illustrating the design of an event-driven GUI program.

Methods in the GUI class of jokebot.py

Your GUI class requires two methods to implement the functionality of the program - showJoke and rateJoke. Neither of them require any parameters other than self, which is passed to all methods in a class. As part of the GUI class of jokebot.py, you must write these methods.

1. The showJoke method is responsible for displaying a joke in the GUI. The method must first select a joke from self.data using the self.currentJoke attribute, and then configure the labels for the setup, punchline and rating information to display the setup, punchline and rating information of the selected joke.

  • If the jokes numOfRatings key contains a 0, show a Joke has not been rated message. Otherwise, show how many times the joke has been rated and the average rating of the joke (rounded to 1 decimal place), e.g. Rated 3 time(s). Average rating is 3.3/5.
  • Once youve configured the labels to display the joke, set the focus to the rating Entry widget to make it convenient for the user Use the focus_set() method of the Entry widget to do this.

2. The rateJoke method is responsible for validating and recording the rating that a user gives a joke. The method must first ensure that an integer between 1 and 5 has been entered into the rating Entry widget If not, show an error messagebox and return to end the method.

If a valid rating has been entered, add one to the jokes numOfRatings value, and add the rating to the jokes sumOfRatings value in the self.data attribute. Then, open the data.txt file in write mode, write self.data to it in JSON format and close the file.

Finally, check the current joke is the last one (using self.currentJoke and self.data) and show the appropriate messagebox as per the screenshots above. If it is the final joke, end the program. Otherwise, add 1 to the self.currentJoke attribute, delete the content of the rating entry widget, and then call the showJoke method to display the next joke.

These two methods are all that are required to implement the functionality of the program, but you may write/use additional functions if you feel they improve your program.

Academic Honesty!
It is not our intention to break the school's academic policy. Posted solutions are meant to be used as a reference and should not be submitted as is. We are not held liable for any misuse of the solutions. Please see the frequently asked questions page for further questions and inquiries.
Kindly complete the form. Please provide a valid email address and we will get back to you within 24 hours. Payment is through PayPal, Buy me a Coffee or Cryptocurrency. We are a nonprofit organization however we need funds to keep this organization operating and to be able to complete our research and development projects.