Personality Quiz

Summary of Deadlines

This assignment's practice questions on PrairieLearn are due by Tue, Sep 22 at 11:59pm.

Your solution to the project portion of this assignment is due to Gradescope by Mon, Sep 28 at 11:59 pm.

Presentations for this assignment will take place on Mon, Oct 5 and Tue, Oct 6.

Practice

This assignment features a number of practice questions available on PrairieLearn under the assignment called "HW2: Personality Quiz".

These questions will help you practice skills that are relevant to this assignment before you get started on the project. You must earn points on every question to receive full credit, although you are permitted to try each question as many times as you need. Some questions are static, meaning that they will not change when you retry them. Others have elements of random generation, meaning that you will get a new variant of the question on each attempt. As long as you earn points on one variant of a question, you get full credit for that question.

You are welcome to use whatever resources you want to complete these practice questions, but you should make sure you understand what you're doing. This is important for learning, and we'll also ask you to solve a variant of one of these questions as part of your Presentation in the final section of the project.

This assignment's practice questions on PrairieLearn are due by Tue, Sep 22 at 11:59pm.


Project

Navigate to HW2: Personality Quiz on Codio to get started.

Where: Complete on Codio, Submit on Gradescope

Summary of Deliverables

By the end of HW02, here's what you'll need to submit to Gradescope:

  • personality_quiz.py
  • readme_quiz.txt
  • my_quiz.quiz

0. Getting started

A. Goals

The goal of this assignment is to familiarize you with lists, iteration, strings, and reading data from a file. The specific goals are to:

  • Learn about file formats & structured data
  • Use nested loops
  • Parse information from strings
  • Use Python command-line arguments

At the end of this assignment, you will produce a program that delivers interactive Personality Quizzes to a user.

B. Background

Personality Quizzes are sets of questions designed to determine how the quiztaker fits into certain categories. Some of these quizzes purport to be serious and scientific, hoping to reveal something essential about a person's behavior as a result of their personality "types". Among these (pseudo)scientific groupings, you may have heard of the Myers-Briggs test or the Big Five test.[1]

Other quizzes are designed to be a bit more lighthearted while telling you about yourself: your Dungeons and Dragons moral alignment or your Hogwarts house are two such examples.[2] There are quizzes that are just plain entertaining,` helping you identify which beloved character you most resemble. And finally, there are quizzes that, well...

I really don't understand it either.

C. Your program

You are going to write a program that reads in a quiz from another file. This quiz file will contain information about the quiz, its questions, and then the rules for scoring the quiztaker's answers and showing them the outcome. The Python code that you write will allow you take any quiz file that matches the provided format and present it to the user in this interactive format. We've provided two examples of quizzes and you'll be writing your own, too.

D. First Steps

You should see personality_quiz.py, lila_or_lenu.quiz, and pet.quiz in your Codio filetree. Reach out to course staff if you don't see these!

If you need to download the original files again, you can find them here.

In order to complete this assignment, you will need to use the following Python skills:

  • Using input() to read input from the user during execution
  • Converting lines (strings) into lists with .split()
  • Converting strings to numeric values using int()
  • Reading command line arguments using sys.argv
  • Reading information from a file object using open() and readline()
  • Using values from one list as indices for positions in another list
  • Finding the position of the smallest value in a list

You can review these skills by referring to the linked resources.

E. Advice

  • Run and debug frequently! Make one small change at a time, ensuring that your program works as you expect it to after each change.
  • You can test your program easily by adding in temporary print() statements. For instance, if you read in a line of text, you can print its value to check that it contains the information that you expect! When you're done testing & debugging, you should remove these temporary print() statements.
    • If you are not getting the outputs you expect, print out the values of variables at different points in the program (i.e. before a loop, inside the body of a loop, after the loop)
  • Keep your code organized by using indentation and avoiding too many blank lines.
  • Comment frequently (this helps you and others understand the code) and use descriptive variable names.

1. Command Line Arguments

You can review the details of command line arguments in Python by reading these notes.

Your personality_quiz program will take just one command line argument: a string that is the name of the file containing the quiz information. The quiz instructions (questions, titles, scoring details, etc.) are stored in separate text files ending in .quiz so that we can use our program to load different quizzes. Make sure to read the command line argument as the first thing you do and store it in a variable called filename. Recall that command line arguments are stored inside of sys.argv, so your program must start by importing sys.

A. Check-in

Try running personality_quiz.py with a few different quiz file names. To make sure that you are reading and capturing the file names properly, print them out. Since you are passing in command line arguments, you must run the program from the terminal and cannot simply use the "Run" button that you may have used on previous assignments. Here are a couple of example executions that you should be able to match at this point, keeping in mind that lines starting with $ represent commands you have to type into the terminal.

$ python personality_quiz.py lila_or_lenu.quiz
lila_or_lenu.quiz
$ python personality_quiz.py my_made_up_quiz_name.quiz
my_made_up_quiz_name.quiz

Your program should not crash. Verify that your program behaves exactly in this way.

Make sure to keep this print statement in your program!

2. Printing the Title & Description

Your goal for this part will be to read the title and description from the quiz file and print them out (along with the file name which we printed in Part 1A).

A. Quiz File Format: Title & Description

The .quiz files all start in the same way: one line containing the title of the quiz, followed by three lines that contain the description that the quiz taker will see when starting the quiz. These lines will be read verbatim from the file and then printed directly to the user. You can assume that none of these first four lines will be empty.

Quiz Title
Description Line One
Description Line Two
Description Line Three

B. Setting up a File Reader

The Python standard library provides the function open() to allow you to access information from a file within your program.

In your personality_quiz.py program, you can declare a variable called quiz_file and have it store the reading connection to the quiz file like so:

# creates a variable quiz_file to be used to read from the file
quiz_file = open(filename, 'r') 

quiz_file is just a variable name. Technically, you could name this variable anything, but for consistency with the instructions, we recommend that you use this name. Keep in mind that you only need to declare and initialize quiz_file once!

C. Reading values from the file

Now that quiz_file is initialized, you can access/read information from it using quiz_file.readline(). The output of readline() will include the newline character at the end of the str that you receive. For example, if we are running the program on pet.quiz, then the first result of readline() is exactly the following:

"What Household Pet Would You Be?\n"

This newline character, '\n', signifies that this string is an entire line. But if we were to print out that string, Python would print out two new lines after the actual title: one for the '\n' present in the string, and one extra on the end because that's what print() normally does. We will want to remove this trailing newline character so that the text is printed without a bunch of extra space. The easiest way to do this is by calling .strip() on the lines as you read them.

Read the first four lines of the file and print them out so that the user sees the quiz title and description. Remember that reading starts from the top left of the file, and reads left-to-right and then onto the next line below.

D. Check-in

You should be able to run your program with these specified command line arguments and see the corresponding outputs.

$ python personality_quiz.py lila_or_lenu.quiz
lila_or_lenu.quiz
Are You a Lila or a Lenu?
Lila Cerullo and Lenu Greco are the main characters of Elena Ferrante's Neapolitan Novels.
While they form a remarkable bond of friendship, they are very different people! Take
this quiz to determine whether you're more like Lila or more like Lenu.
$ python personality_quiz.py pet.quiz
pet.quiz
What Household Pet Would You Be?
Maybe you're a cat!
Maybe you're a dog instead.
Maybe you're actually a fish. Let's find out.

3. Questions and Answers

Next, we'll print the questions and let the quiz taker respond to them. Our goal is to print a question, ask the user for their answer, and save this result. We'll repeat that process for each question in the file.

A. Quiz File Format: Questions & Answers

The next unread line in the quiz file contains two numbers: the total number of possible outcomes from the quiz and the number of questions in the quiz, respectively. For example, in lila_or_lenu.quiz, this line looks like:

2 3

You can verify that there are two possible outcomes (Lila or Lenu) and three questions. These numbers should always be positive, but there are otherwise no restrictions on them.

The next set of lines contain the questions and answers. There will always be the same number of outcomes as answers per question. For example, since we read on the previous line that there are three questions with two possible outcomes, then the next six lines would look like the following, keeping in mind that we start counting from 0.

Question 0. Question text here
Answer 0
Answer 1
Question 1. Question text here
Answer 0
Answer 1
Question 2. Question text here
Answer 0
Answer 1

Since there are three questions with two outcomes, we have nine question and answer lines to read.

B. Asking and Answering

You may want to save the number of outcomes and number of questions for use later. Both values will be represented as characters in a string, so it will be up to you to parse that information out of the string.

Tip: The function .split() transforms a string into a list of strings. The function int() transforms a string of a written integer into a numberic value.

Then, for each question:

  • read the line containing the question text from the quiz file & print it
  • and, for each line representing a possible choice:
    • read that possible choice for that question from the quiz file
    • print that possible choice with numbers, starting at 0, followed by a . character and a space (the character).
  • after all answers are read and printed, read the quiz taker's answer using input(), making sure to remember to parse it as an integer.

You can assume that the user will always give you a value in the valid range—don't worry about handling malformed answers.

You don't need to save the user's answers yet. What you want to make sure that you can do is print each of the question & answer groups one at a time, pausing between each group until the quiz taker answers the question.

C. Check-in

Run your program on pet.quiz and don't provide any input after the program starts running. Your output should match the output below, and make sure that the program doesn't stop running!

$ python personality_quiz.py pet.quiz
pet.quiz
What Household Pet Would You Be?
Maybe you're a cat!
Maybe you're a dog instead.
Maybe you're actually a fish. Let's find out.
Question 0. Do you like the outdoors?
0. Not at all.
1. Yes, I love being outside.
2. Yes, but only the beach or the pool.

Then, if you type 1 in the terminal and press enter/return, you should see the following output. (The 1 you see on line 9 is the one you typed, not anything that gets printed by the program.)

pet.quiz
What Household Pet Would You Be?
Maybe you're a cat!
Maybe you're a dog instead.
Maybe you're actually a fish. Let's find out.
Question 0. Do you like the outdoors?
0. Not at all.
1. Yes, I love being outside.
2. Yes, but only the beach or the pool.
1
Question 1. How do you feel about meeting new people?
0. Love it.
1. Hate it.
2. Totally indifferent.

Finally, type in 0 and press enter/return. Your program should stop executing.

D. Recording Answers

In order to figure out what the quiz taker's final result will be, we'll have to store all of the answers that they respond. You should initialize an empty list that will be used to store all of the given answers. In this guide, we'll call that list answers. You can use .append() to add the most recent answer to the end of the list. Consider what that means when the quiz taker gives an answer x to Question y. At what position y in the answers list will the value x be stored?

E. Checkpoint

While we'll eventually score all of the answers in order to decide what result the quiz taker gets, you should verify that you are correctly storing all of the answers first. Do this by printing out the contents of answers.

Try running python personality_quiz.py lila_or_lenu.quiz and giving answers 0, 1, and 0. What values you should expect to display when you print the content of answers? Make sure that this is what is printed. Try completeing the quiz with different answers to make sure you always print what you expect.

Make sure to delete the print statement for this checkpoint before submitting!

4. Scoring

Now that we have all the answers, we should tally up the results and give the quiz taker the answer they've been waiting for!

A. Quiz File Format: Scoring Guide

Next in the file, we find the scoring guide. There will be one line per question, and on each line there will be one number per outcome/answer. The first line in the scoring guide reflects how the answers for the first question will be scored, the second line corresponds to the second question, and so on.

The scoring in the quiz works by associating each answer with one of the possible outcomes. In lila_or_lenu.quiz, the scoring guide looks like so:

0 1
0 1
1 0

This indicates that picking the first answer to Question 0 would award a point to Outcome 0 and that picking the second answer in Question 0 would award a point to Outcome 1. The same pattern follows for Question 1 since the lines are identical. Notice that the third line is different, though: in Question 2, choosing the first answer would award a point to Outcome 1 and the second answer awards a point to Outcome 0.

After the scoring guide, we have the results messages. There will be one line per possible outcome in the quiz, and your job after scoring will be to print out only the line representing the outcome that has accumulated the highest score.

B. Scoring the Answers

At this point, you will need to score each answer provided by the quiz taker. Use the scoring guide to determine which outcome each answer the quiz taker provided was associated with. You will need to tally up the number of answers associated with each outcome.

Your code should work with any quiz in the correct format, regardless of the number of questions or outcomes.

We suggest you use a list that is the correct size to store one point tally per outcome, but how you score these questions is up to you, so long as the final outcome is correct. For the rest of the writeup we will assume the score list exists, and we will call it scores.

C. Printing the Final Result

Now it's time to check which outcome got the largest point total. (If multiple outcomes have the same maximum score, then just pick the first one in the list.)

Tip: Either try iterating through scores to find the index with the maximum value, or think about how some built-in functions like max() and .index() might be able to help you here.

The messages to print for each outcome are located as the last few lines of the file, right after the scoring guide. Once you have the winning outcome, use this to decide which of the final lines to print out. For example, in pet.quiz, if outcome 0 is the winner, then you'd print the first result line ("You're a cat!"). If outcome 2 is the winner, then you'd print out "You're a fish!".

D. Checkpoint

Try running python personality_quiz.py lila_or_lenu.quiz and give the answers 1, 0, 0. This should mean that outcome 1, or "Lenu", is the outcome that gets the highest number of points. Your final output should then look like this:

$ python personality_quiz.py lila_or_lenu.quiz
lila_or_lenu.quiz
Are You a Lila or a Lenu?
Lila Cerullo and Lenu Greco are the main characters of Elena Ferrante's Neapolitan Novels.
While they form a remarkable bond of friendship, they are very different people! Take
this quiz to determine whether you're more like Lila or more like Lenu.
Question 0. Are you more of an artist or a writer?
0. Artist
1. Writer
1
Question 1. Growing up, were you an only child? If not, were you close with your siblings?
0. Close
1. Not close or only child
0
Question 2. After college, where would you prefer to live?
0. Far away someplace new
1. Close to my hometown
0
You're a Lenu! You might be a bit shy, but you have a ton of talent! You're a person who won't let their past define them.

Then, try running python personality_quiz.py pet.quiz and give answers 2 and 2. This means "fish" wins, and you should see:

$ python personality_quiz.py pet.quiz
pet.quiz
What Household Pet Would You Be?
Maybe you're a cat!
Maybe you're a dog instead.
Maybe you're actually a fish. Let's find out.
Question 0. Do you like the outdoors?
0. Not at all.
1. Yes, I love being outside.
2. Yes, but only the beach or the pool.
2
Question 1. How do you feel about meeting new people?
0. Love it.
1. Hate it.
2. Totally indifferent.
2
You're a fish!

5. Write Your Own Quiz!

This is not just for fun—by writing your own my_quiz.quiz file, you'll verify your understanding of the file format and get another quiz example that you can use to test your code. When we grade your assignment, we'll test it on quiz files you haven't seen before to make sure that your code works on all kinds of examples in the format. You can verify that you're meeting all the specifications by coming up with a quiz of your own. Plus, it should be fun to write your own quiz.

Things to keep in mind:

  • Make sure to write at least three questions and have at least two possible outcomes. You can include as many questions as you want, but to keep grading simple, please limit the number of possible outcomes to four.
  • You'll need to include all pieces, in this order:
    • title
    • description
    • number of outcomes & number of questions that matches the rest of your quiz
    • one answer per outcome in each question you write
    • scoring guide, one line per question
    • all potential outcomes, one per line

Make sure that your quiz file can be run with your program since it will be worth points!

6. Readme and Submission

A. Readme

Complete readme_quiz.txt in the same way that you have done for previous assignments.

B. Submission

Submit personality_quiz.py, readme_quiz.txt, and my_quiz.quiz you choose to create on Gradescope.

Your code will be tested for runtime and checkstyle errors upon submission.

Please note that the autograder does not reflect your full grade for this assignment—there are manual points awarded for style as well. Additionally, there may be manual deductions in addition to the autograder's deductions.

Important: Remember to delete the print statements from Checkpoint 3E before submitting.

If you encounter any autograder-related issues, please make a private post on Ed.


Presentation

You will be required to meet with a TA for fifteen minutes outside of class to present your work on this assignment. Presentations for this assignment will take place on Mon, Oct 5 and Tue, Oct 6. Sign up for a presentation time slot TODO HERE TODO.

As a reminder, you'll start the presentation with ten minutes spent on reviewing and discussing your project submission.

You and your TA will go through the project code that you submitted. Your TA will mark your style score and other manually graded components of the assignment, and they will explain their marks to you as they go. There may be cases where they ask you to clarify or justify a choice you made, so make sure to run through your code briefly before your presentation.

Then, your TA will ask you one or two questions about the behavior of your code to judge your understanding.

Finally, you'll be given a variant of a question from the PrairieLearn Practice portion of this assignment and asked to solve it.

You will not have access to any resources during this part of the presentation.

Grading

The grading rubric required to achieve each criterion will be different for each question, but the way that we approximately convert answers to points is displayed in the following scheme. Note that answers need not be perfectly correct to receive a high score on this portion of the presentation.

Criterion Grade for Question
Fully correct answer with ability to justify A+
Partially correct answer with a reasonable approach and the ability to justify A
Mostly incorrect/incomplete answer with ability to reason aloud about the steps taken B
Mostly incorrect/incomplete answer with partial ability to reason aloud about the steps taken B-
Incorrect or incomplete answers with no reasonable justification Participation credit only

Assignment Concept provided by Bhrajit Thakur. This version was written by Harry Smith in 2024.


  1. I think I'm INFJ on the M-B test. The Big Five tells me that I'm quite open and agreeable (nice!) if not so conscientious (ouch). ↩︎

  2. Chaotic Good and Ravenclaw. ↩︎