You are on page 1of 13

CSP1150/CSP5110 Programming Principles

Assignment 2: Individual programming project (Fast Food Quiz)


Assignment Marks: Marked out of 30, (30% of unit)
Due Date: 31 October 2016, 9:00AM

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 add, list, search, view and delete
nutritional information about fast food menu items, and stores the data in a text file.
Develop this program before foodquiz.py.
foodquiz.py, a GUI program that uses the data in the text file to quiz the user about the
nutritional information of the fast food menu items. 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.

Semester 2, 2016 CSP1150/CSP5110 Assignment 2 Page 1


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 foodquiz.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 are required in this assignment are detailed later in the assignment brief.
The following pages describe the requirements of both programs in detail.

Semester 2, 2016 CSP1150/CSP5110 Assignment 2 Page 2


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

This program allows the user to manage a collection of fast food menu item nutritional information
that is 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 files content in JSON format
(which is almost identical to Python):

[ JSON This example file contains the details of two fast


{ food menu items in a list. Each of those items is
"name": "Big Mac", a dictionary consisting of 7 items which have
"calories": 540,
"fat": 29, keys of name, calories, fat, cholesterol,
"protein": 25, sodium, carbohydrates and protein.
"carbohydrates": 45,
"sodium": 1040,
"cholesterol": 75 If this file was to be read into a Python variable
}, named data, then data[0] would refer to
{ the dictionary containing the first menu item
"name": "Whopper",
(Big Mac), and data[0]['fat'] would
"calories": 760,
"fat": 47, refer to the integer of 29.
"protein": 33,
"carbohydrates": 53, Understanding the structure of this data and
"sodium": 1410,
"cholesterol": 100 how you can interact with it is very important in
} many aspects of this assignment.
]

Remember: Items in a dictionary are unordered: They will probably not appear in the order shown
in your file, however this will have no impact upon either program or how you use the data.

Semester 2, 2016 CSP1150/CSP5110 Assignment 2 Page 3


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

3. If the user enters a (add), prompt them to enter all 7 details of a fast food menu item,
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. Finally, write the list to the text
file in JSON format to save the data.
Use your inputSomething() function (detailed below) to prompt the user for the name of the
menu item, to ensure that the user is re-prompted until they enter something.
Use your inputInt() function (detailed below) to prompt the user for the nutritional details of
the menu item, to ensure that the user is re-prompted until they enter an 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 names of all menu items in the data list preceded by
their index number, or a No menu items saved error 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 menu item as you loop through them (see Lecture 3).

Semester 2, 2016 CSP1150/CSP5110 Assignment 2 Page 4


5. If the user enters s (search), prompt for a search term and then list the items whose name
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 items the loop body needs an
if to only print items that contain the search term (use the in operator see Lecture 3).
Convert the search term and menu item name 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.

6. If the user enters v (view), prompt them for an index number and then print the
corresponding menu items name and all of its nutritional information.
Include the unit of measurement next to the nutritional information as needed: Fat, carbohydrates
and protein are measured in grams, while cholesterol and sodium are measures in milligrams.
Use your inputInt() function (detailed below) to prompt the user for the index number of the
menu item, 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 menu items 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 Menu item deleted message.
Use your inputInt() function (detailed below) to prompt the user for the index number of the
menu item, 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 menu items saved message and not allowing the user to
specify an index number if the data list is empty.
Once the menu item 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.

Semester 2, 2016 CSP1150/CSP5110 Assignment 2 Page 5


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 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 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 menu items whenever the list or search results are shown, so that
the list begins at 1 instead of 0. Remember to subtract 1 from the users input when viewing or
deleting menu items 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 0). Make sure that this requirement is
mentioned in the error message that is displayed if an invalid value is entered.

Semester 2, 2016 CSP1150/CSP5110 Assignment 2 Page 6


Optional Additions and Enhancements for admin.py
The following are suggestions for optional additions and enhancements that you can implement to
demonstrate deeper understanding of programming and deliver a product which is more polished.
They are not required, but you are encouraged to implement them (and others) if you can.

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.

When viewing a menu item, show the amount of kilojoules (rounded up to the nearest
whole number) in parentheses after the number of calories. 1 calorie is 4.184 kilojoules.

When searching for a menu item, show a No results found message if the search term is
not found in the name of any of the menu items in the list.

If you enter items from different fast food chains, it is likely that they will have the same
name, e.g. Cheeseburger. Modify the Add section of the program so that after the user
enters the name of an item, the code checks if there is already an item with that name in the
data list and only proceeds once the user enters a name that does not already exist.
o Alternatively, you could prompt the user to specify the name of the fast food chain
(e.g. McDonald's) after specifying the name of the item and include that in the
data that you store. Be sure to show the chain name when listing, searching and
viewing, and also include it when displaying item names in foodquiz.py.

Allow users to use the search, view and delete options more efficiently by allowing input of
s <search term>, v <index number> and d <index number>. For example, instead of
needing to type s and then big, the user could type s big, and instead of needing to
type v then 1, the user could type v 1.

Semester 2, 2016 CSP1150/CSP5110 Assignment 2 Page 7


Annotated Screenshot of admin.py
To help illustrate the admin.py program, here is an annotated screenshot of it being used:

The program welcomes the user, then shows


a list of options to choose from.
The user chooses l to list the current menu
items and is told that there are none saved.
They then choose a and add an item by
following the prompts that appear.
They then choose a again and add a
second item.

Now when the user chooses l, they are


shown the names of the two saved items.
The user chooses v to view a menu item,
entering the index number when prompted.
Details of the menu item are shown.

The user chooses s to search for an item,


entering a search term when prompted. The
program searches for matching item names.

The user chooses d to delete an item,


entering the index number when prompted.
Finally, the user chooses q to quit.

Semester 2, 2016 CSP1150/CSP5110 Assignment 2 Page 8


Requirements of foodquiz.py
foodquiz.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. 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 menu items from the data and one nutritional
component (calories, fat, protein, carbohydrates, sodium or cholesterol), then asking the user which
of the two menu items contains more of that nutritional component.

The names of the two randomly selected items are shown.

The question is asked using the randomly selected component.

The left and right buttons contain the currently selected


item names, and the middle button is always the same.

(Your program may look slightly different, depending on which operating system you use,
and you are also welcome to adjust the layout and formatting of the GUI as desired)

When the user clicks one of the buttons, the program should determine whether their answer is
correct and show an appropriate messagebox:

The program continues like this until the user closes it selecting two random menu items and a
random nutritional component each time.

The following pages detail how to implement the program.

Semester 2, 2016 CSP1150/CSP5110 Assignment 2 Page 9


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

3. Create an attribute named self.components and set it to a list containing strings of


calories, fat, cholesterol, sodium, carbohydrates and protein.
This list will be used in the showQuestion method to randomly select a nutritional component.
Make sure that you spell the words exactly the same as the keys of the dictionaries in your data list.

4. The constructor should then use Frame, Label and Button and 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.
Note that you do not need to set any text for labels or buttons containing the names of menu items or
the name of the nutritional item at this point these will be set by the showQuestion method.
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.
All of the Buttons should call the checkAnswer method when clicked. See the details of this
method on the next page for some important information regarding how to do this.

4. Finally, the constructor should end by calling the 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,
the additional requirements for CSP5110 students and optional additions and enhancements. You
are not required to submit pseudocode for your design of foodquiz.py, as pseudocode is not
particularly well suited to illustrating the design of an event-driven GUI program.

Semester 2, 2016 CSP1150/CSP5110 Assignment 2 Page 10


Methods in the GUI class of foodquiz.py
Your GUI class requires two methods to implement the functionality of the program -
showQuestion and checkAnswer. As part of the GUI class of foodquiz.py, you must
write 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 showQuestion method is responsible for randomly selecting two food items and a
nutritional component and showing them in the GUI. Simply select two random items from
self.data and one random nutritional component from self.components, then use them to set
the text for the labels/buttons in your GUI as needed.
This method is called at the end of the constructor (to select/show the first question) and by the
checkAnswer method (to select/show the next question).
Use random.sample() to ensure the two items you select from self.data are different.
Store the selected items and the selected nutritional component as attributes (i.e. include self.
at the start of the variable name) so that you can access them in the checkAnswer method.

2. The checkAnswer method is responsible for determining whether the user clicked the
correct button. The method should receive a parameter named clickedButton, which will
be used to identify which button was clicked it should contain either left, middle or right.
Including a parameter value for a method that is called by clicking a button can be tricky, so here
is an example of some code that shows you how it can be done:
self.btnLeft = tkinter.Button(self.btnFrame, command=lambda: self.checkAnswer('left')) Python

If clickedButton is left or right, then simply compare the selected nutritional


component of the selected food items to determine whether the user was correct.

If clickedButton is middle then it is only correct if the selected nutritional component of


the selected items are within 10% of each others value. For example:
If the two items had values of 100 and 110 then they are within 10% of each other, since 100 is within
10% of 110 (range of 99-121) and 110 is within 10% of 100 (range of 90-110).
However if the items had values of 99 and 110 then they are not within 10% of each other, since while
99 is within 10% of 110 (range of 99-121), 110 is not within 10% of 99 (range of 89.1-108.9)

Once you have determined whether the user answered correctly or not, show the appropriate
messagebox as per the screenshots above, and then call the 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 functions if you feel they improve your program.

Semester 2, 2016 CSP1150/CSP5110 Assignment 2 Page 11


Additional foodquiz.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. The look of your GUI will be assessed more critically. Ensure that it is well-presented: Use
padding, make sure that there is space between the buttons, make the labels containing item
names and the nutritional component stand out by using a different font, size or colour, etc.

Optional Additions and Enhancements for foodquiz.py


The following are suggestions for optional additions and enhancements that you can implement to
demonstrate deeper understanding of programming and deliver a product which is more polished.
They are not required, but you are encouraged to implement them (and others) if you can.

Use attributes to keep track of the number of questions that have been asked and how
many questions have been answered correctly, and use it to show the users score in the GUI.

Make the Correct/Incorrect messageboxes more informative by including the relevant


nutritional information of both items, e.g.:

Implement a countdown timer of 6 seconds that is shown on the GUI if the user does not
answer within 6 seconds, show a messagebox saying that they ran out of time and continue
to the next question by calling showQuestion. Timers are covered in Reading 9.2.

Submission of Deliverables
Once your assignment is complete, submit both the pseudocode for admin.py (PDF format) and the
source code for admin.py and foodquiz.py to the appropriate location in the Assessments area
of Blackboard. An assignment cover sheet is not required, but be sure to include your name and
student number at the top of all files.

Semester 2, 2016 CSP1150/CSP5110 Assignment 2 Page 12


Referencing, Plagiarism and Collusion
The entirety of your assignment must be your own work (unless otherwise referenced) and
produced for the current instance of the unit. Any use of unreferenced content you did not create
constitutes plagiarism, and is deemed an act of academic misconduct. All assignments will be
submitted to plagiarism checking software which includes previous copies of the assignment.

Remember that this is an individual assignment. Never give anyone any part of your assignment
even after the due date or after results have been released. Do not work together with other
students on individual assignments helping someone by explaining errors in their code/logic or
directing them to the relevant resources is appropriate, but doing it for them or showing them how
you did it is not. An unacceptable level of cooperation between students on an assignment is
collusion, and is deemed an act of academic misconduct. If you are uncertain about plagiarism,
collusion or referencing, simply email your tutor, lecturer or unit coordinator and ask.

Marking Key
Marks are allocated as follows for this assignment. The marks are divided between both programs.

Criteria Marks
Pseudocode
These marks are awarded for submitting pseudocode which suitably represents the design 5
of your source code. As there are no fixed standards for pseudocode, it will be assessed on
the basis of does it help in understanding/describing the structure of the program?
Functionality
These marks are awarded for submitting source code that implements the requirements 15
specified in this brief, in Python 3. Code which is not functional or contains syntax errors
will lose marks, as will failing to implement requirements as specified.
Code Quality
These marks are awarded for submitting well-written source code that is efficient, well- 10
formatted and demonstrates a solid understanding of the concepts involved. This includes
appropriate use of commenting and adhering to best practise.

Total: 30

Semester 2, 2016 CSP1150/CSP5110 Assignment 2 Page 13

You might also like