Background Information

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.

Assignment Overview

You are required to design and implement two related programs:

 “admin.py”, a CLI program that allows the user to manage a list of quiz questions, and stores the data in a text file. Develop this program before “quizle.py”.

 “quizle.py”, a GUI program that uses the data in the text file to implement a quiz game for the user to play. 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 “quizle.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/or 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 are required in the admin.py program are 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 majority of the unit. The entirety of this program (without the Optional Additions and Enhancements) can be implemented in under 200 lines of code – If your program significantly exceeds this, ask your tutor for advice. Everything you need to know in order to develop this program is covered in the first seven modules of the unit. This program should be developed before “quizle.py”.

This program allows the user to manage a collection of quiz questions that are to be 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 content in JSON format:

JSON

[

{

“question”: “In which year was Halley’s Comet last visible

from Earth?”,

“answers”: [“1986”],

“difficulty”: 2

},

{

“question”: “Where were the 2016 Summer Olympics held?”,

“answers”: [“rio de janeiro”, “rio”, “brazil”],

“difficulty”: 1

}

]

This example file contains the details of two questions, stored in a list. Each of those questions is a dictionary consisting of three items that have keys of:

“question” (a string of the quiz question)

“answers” (a list of strings representing all of the answers that are considered correct)

o Since the user will be typing their answer in the GUI program, a list of strings allows the program to account for different variations of how a correct answer may be typed. It also allows for questions with multiple correct answers.

o They have been stored in lowercase to make it easier to match against the answer entered by the user.

“difficulty” (an integer between 1 and 5 representing how difficult the question is)

If this file was to be read into a Python variable named data, then “data[0]” would refer to the dictionary containing the question about Halley’s Comet and “data[0][‘difficulty’]” would refer to the integer of 2. “data[1][‘answers’]” would refer to the list of [“rio de janeiro”, “rio”, “brazil”].

Understanding the structure of this data and how you can use it is very important in many aspects of this assignment. Revise Module 3 and Module 7 if you are unsure about how to interact with lists and dictionaries. Semester 2, 2017 CSP1150/CSP5110 Assignment 2 Page 4

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.

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 (e.g. due to the file not existing, or it not containing valid JSON data), then simply set the data variable to be an empty list. This will occur the first time the program is run, since the data file will not exist yet.

This is the first and only time that the program should need to read anything from the file. After this point, the program uses the data list, which is written to the file whenever a change is made.

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

 This requirement has been completed for you in the starter file.

3. If the user enters “a” (add), prompt them to enter a question, then prompt them to enter as many answers as desired, and finally prompt them to enter the difficulty of the question, which must be an integer between 1 and 5. Place the details into a new dictionary with the structure shown on the previous page, and append the dictionary to the data list. Finally, write the entire data list to the text file in JSON format to save the data.

Use your “inputSomething()” function (detailed below) to prompt the user for the question and answers to ensure that the user is re-prompted until they enter something other than whitespace.

How you handle prompting the user to enter multiple answers is up to you, as long as you ensure that they enter at least one answer. You may want to store the answers in lowercase, to make it easier to match the user’s answer to them in the GUI program.

Use your “inputInt()” function (detailed below) to prompt the user for the question difficulty to ensure that the user is re-prompted until they enter an integer. Remember to make sure it is between 1 and 5 – keep on prompting the user until they enter a valid integer.

Once the new dictionary has been added to the data list, use your “saveChanges()” function (detailed below) to write the changes to the text file.

4. If the user enters “l” (list), display the text of all questions (just the question, not the answers or difficulty) in the data list preceded by their index number, or a “No questions saved” message if there is nothing in the list.

Use a “for” loop to iterate through the items in the data list.

You can use the “enumerate()” function to make sure you have a variable containing the index number of each question as you loop through them (see Lecture 3).

5. If the user enters “s” (search), prompt for a search term and then display the details of all questions which contain the search term in the question text. 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 questions – the loop body needs an “if” to only print questions that contain the search term (use the “in” operator – see Lecture 3).

Convert the search term and question text to lowercase to find matches regardless of case.

Use your “inputSomething()” function (detailed below) to prompt the user for a search term, to ensure that the user is re-prompted until they enter something other than whitespace.

6. If the user enters “v” (view), prompt them for an index number and then print details of the corresponding question in full. This should include the question text, answers, and difficulty.

Use your “inputInt()” function (detailed below) to prompt the user for the index number of the question, 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 doesn’t exist in the data list. Also consider showing a “No questions saved” message and not allowing the user to specify an index number if the data list is empty.

 Display the list of answers in a pleasing way, rather than simply printing the entire list. e.g.

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

Use your “inputInt()” function (detailed below) to prompt the user for the index number of the question, 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 doesn’t exist in the data list. Also consider showing a “No questions saved” message and not allowing the user to specify an index number if the data list is empty.

Once the question has been deleted from data list, use 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.

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

Use the “strip()” method on a string to remove whitespace from the start and end. If a string consists entirely of whitespace, it will have nothing left once you strip the whitespace away.

Note that exception handling is not needed 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 text file.

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

Additional “admin.py” Requirements for CSP5110 Students

If you are in CSP5110, the following additional requirements apply. If you are in CSP1150, you do not need to do implement these requirements (but you are encouraged to do so if you want). Ask your tutor if you do not understand any of the requirements or would like further information.

1. Add 1 to the index number of questions whenever the list or search results are shown, so that the list begins at 1 instead of 0. Remember to subtract 1 from the user’s input when viewing or deleting questions so that you reference the appropriate index of the data list.

2. As well as ensuring that the user enters an integer, the “inputInt()” function must also make sure that the integer is positive (i.e. a minimum of 1). Make sure that this requirement is mentioned in the error message that is displayed if an invalid value is entered.

3. Always check if the data list is empty whenever a user tries to list, search, view or delete, and only allow the action to proceed if there is at least one item in the list.

Related posts: