Quiz admin program

Assignment

Assignment Overview
You are required to design and implement program:
·“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”.

Starter file for the programis provided along with this assignment brief, to help youget started and to facilitate an appropriate program structure. Please use the starter file.

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.

This program allows the user to manage a collection of quiz questions that are to be stored in a textfile named “data.txt”. Use the “json” module to write data to the text file in JSON format and toread the JSON data from the file back into Python.

This example file contains the details of two questions, stored in a list. Each of those questions is adictionary 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 toaccount for different variations of how a correct answer may be typed. It also allows for questions withmultiple correct answers.
oThey 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’]” wouldrefer to the integer of 2. “data[1][‘answers’]” would refer to the list of [“rio dejaneiro”, “rio”, “brazil”].

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

  • 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, whichmust be an integer between 1 and 5. Place the details into a new dictionary with the structureshown 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.
  • 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.
  • 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.
  • 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.
  • 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.
  • If the user enters “q” (quit), print “Goodbye!” and break out of the loop to end the program.
  • 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).

admin.py

# Name:

# Student Number:

# This file is provided to you as a starting point for the “admin.py”

#It aims to give you just enough code to help ensure

# that your program is well structured.  Please use this file as the basis for your assignment work.

# The “pass” command tells Python to “do nothing”.

# It is simply a placeholder to ensure that the starter files run smoothly.

# They are not needed in your completed program.

# Replace them with your own code as you complete the assignment.

# Import the json module to allow us to read and write data in JSON format.

importjson

# This function repeatedly prompts for input until an integer is entered.

definputInt(prompt):

pass

# This function repeatedly prompts for input until something other than whitespace is entered.

definputSomething(prompt):

pass

# This function opens “data.txt” in write mode and writes dataList to it in JSON format.

defsaveChanges(dataList):

pass

# Here is where you attempt to open data.txt and read the data into a “data” variable.

# If the file does not exist or does not contain JSON data, set “data” to an empty list instead.

# This is the only time that the program should need to read anything from the file.

# Print welcome message, then enter the endless loop which prompts the user for a choice.

print(‘Welcome to the Quizle Admin Program.’)

while True:

print(‘Choose [a]dd, [l]ist, [s]earch,

[v]

iew, [d]elete or [q]uit.’)

choice = input(‘> ‘)

if choice == ‘a’:

# Add a new question.

pass

elif choice == ‘l’:

# List the current questions.

pass

elif choice == ‘s’:

# Search the current questions.

pass

elif choice == ‘v’:

# View a question.

pass

elif choice == ‘d’:

# Delete a question.

pass

elif choice == ‘q’:

# Quit the program.

pass

else:

# Print “invalid choice” message.

pass

 Solution

 admin.py

 # Name:

# Student Number:

# This file is provided to you as a starting point for the “admin.py”

# It aims to give you just enough code to help ensure

# that your program is well structured.  Please use this file as the basis for your assignment work.

# The “pass” command tells Python to “do nothing”.

# It is simply a placeholder to ensure that the starter files run smoothly.

# They are not needed in your completed program.

# Replace them with your own code as you complete the assignment.

# Import the json module to allow us to read and write data in JSON format.

importjson

importtextwrap

# This function repeatedly prompts for input until an integer is entered.

definputInt(prompt):

haveInt = False

while not haveInt:

int_str = input(prompt)

try:

number = int(int_str)

if number < 1:

print(“Invalid value. The integer must be positive”)

else:

haveInt = True

exceptValueError:

print(“Invalid value. Must be an integer”)

return number

# This function repeatedly prompts for input until something other than whitespace is entered.

definputSomething(prompt):

haveSomething = False

while not haveSomething:

something = input(prompt)

something = something.strip()

if something != ”:

haveSomething = True

else:

print(“Invalid value. Please enter non-empty string”)

return something

# This function opens “data.txt” in write mode and writes dataList to it in JSON format.

defsaveChanges(dataList):

fp = open(‘data.txt’, ‘w’)

json.dump(dataList, fp, indent=2)

fp.close()

# Returns True if the question or any of answers contains term

defsearchTerm(term, d):

if term in d[“question”].lower():

return True

for answer in d[“answers”]:

if term in answer:

return True

return False

# Here is where you attempt to open data.txt and read the data into a “data” variable.

# If the file does not exist or does not contain JSON data, set “data” to an empty list instead.

# This is the only time that the program should need to read anything from the file.

try:

fp = open(‘data.txt’)

data = json.load(fp)

fp.close()

except (IOError, ValueError):

data = []

# Print welcome message, then enter the endless loop which prompts the user for a choice.

print(‘Welcome to the Quizle Admin Program.’)

while True:

print(‘Choose [a]dd, [l]ist, [s]earch,

[v]

iew, [d]elete or [q]uit.’)

choice = input(‘> ‘)

if choice == ‘a’:

# Add a new question.

question = inputSomething(‘Enter the question: ‘)

answers = []

while answers == []:

doneWithAnsweers = False

while not doneWithAnsweers:

answer = inputSomething(‘Enter a valid answer (enter “q” when done): ‘)

if answer == ‘q’:

doneWithAnsweers = True

else:   # convert to lowercase

answers.append(answer.lower())

haveDifficulty = False

while not haveDifficulty:

difficulty = inputInt(‘Enter question difficulty (1-5): ‘)

if difficulty < 1 or difficulty > 5:

print(‘Invalid value. Must be an integer between 1 and 5.’)

else:

haveDifficulty = True

data.append({“question”: question, “answers”: answers, “difficulty”: difficulty})

print(‘Question added!’)

saveChanges(data)

elif choice == ‘l’:

# List the current questions.

if data:

print(‘Current questions:’)

for i, d in enumerate(data):

short_question = textwrap.shorten(d[“question”], 50)

print(”  {}) {}”.format(i + 1, short_question))

else:

print(‘No questions saved’)

elif choice == ‘s’:

# Search the current questions.

if data:

term = inputSomething(‘Enter a search term: ‘).lower()

found = 0  # the number of question matching the term

print(‘Search results:’)

for i, d in enumerate(data):

ifsearchTerm(term, data[i]):

found = found + 1

short_question = textwrap.shorten(d[“question”], 50)

print(”  {}) {}”.format(i + 1, short_question))

if found == 0:

print(“No results found”)

else:

print(‘No questions saved’)

elif choice == ‘v’:

# View a question.

if data:

index = inputInt(‘Question number to view: ‘) – 1   # index is 1-based

if index <len(data):

print(“”)

print(“Question:”)

short_question = textwrap.shorten(data[index][“question”], 50)

print(”  ” + short_question)

print(“”)

print(“Valid answers: ” + “, “.join(data[index][“answers”]))

print(“Difficulty: ” + str(data[index][“difficulty”]))

else:

print(‘Invalid index number’)

else:

print(‘No questions saved’)

elif choice == ‘d’:

# Delete a question.

if data:

index = inputInt(‘Question number to delete: ‘) – 1   # index is 1-based

if index <len(data):

del data[index]

print(“Question deleted!”)

saveChanges(data)

else:

print(‘Invalid index number’)

else:

print(‘No questions saved’)

elif choice == ‘q’:

# Quit the program.

print(“Goodbye!”)

break

else:

# Print “invalid choice” message.

print(“Invalid choice”) 

pseudocode (1).txt 

try to open ‘data.txt’ and parse it as a JSON object

load the contents to the list “data”

on exception set “data” to an empty list

print the welcome message

run the infinite loop:

read the menu option from the user

if the option is ‘a’:

get the question from user with “inputSomething”

get a list of answers from user using a while loop with “inputSomething”

get question difficulty with “inputInt”, make sure it is in 1..5 range

construct the data dictionary and add it to data list

write changes to the file with “saveChanges”

if the option is ‘l’:

display a mesage and do nothing if “data” list is empty

for each item in data list

display the question

if the option is ‘s’:

display a mesage and do nothing if “data” list is empty

get the term from the user

for each item in data list

check if the question contains the term with “searchTerm” and print the question

display a mesage if no math is found

if the option is ‘v’:

display a mesage and do nothing if “data” list is empty

get the index from user

if index is valid dipslay the data item at given index

otherwise display error message

if the option is ‘d’:

display a mesage and do nothing if “data” list is empty

get the index from user

if index is valid remove the data item at that position

and write changes to the file with “saveChanges”

otherwise display error message

if the option is ‘q’:

print goodbye message

break the loop

else

print “Invalid choice” message

functioninputInt(prompt):

until user enters positive integer:

prompt for input

try to convert the input to integer

if the input is valid and positive

return the integer

otherwise print error message

functioninputSomething(prompt):

until user enters non-empty input do:

prompt for input

strip leading and training spaces

check if the input string is non-zero

return input string

functionsaveChanges(dataList):

open “data.txt” in write mode

writedataList to it in JSON format

close file

functionsearchTerm(term, d):

if “question” field contains term return True

else if any answer in “answers” list contain term return True

otherwise return False