ATAR Year 11 Computer Science - Project 1 Part 1

ATAR Year 11 Computer Science - Project 1 Part 1

Investigation and Design

Name: Arafat Course: Computer Science - ATAR Year 11 Task: Task 1 - Unit 1


1. Problem Outline

The purpose of this project is to design and develop an interactive text-based adventure game using Python, themed around a psychological mystery set in a school environment. The player takes on the role of a student at AIC Kewdale who notices an empty desk in their classroom-someone is missing, but nobody else seems to remember them. The overall objective is to investigate the disappearance, make choices that affect the protagonist’s Memory and Sanity stats, complete classroom minigames, and ultimately reach one of three distinct endings depending on the player’s decisions and stat values.


2. Problem Description

2.1 Objective of the Game

The player must navigate a school day while investigating the mysterious disappearance of a classmate whom nobody else remembers. The core objective is to uncover the truth about the missing person while managing two competing stats: Memory (the ability to remember the truth) and Sanity (mental stability). The game ends with one of three endings determined by the player’s final choice and their stat values.

2.2 Setting and Main Story Scenario

The game is set at AIC Kewdale during a single school day that stretches into the evening. The story follows a student who notices an empty desk in class. When they ask their friend Abdullah about it, nobody remembers the missing person. The player progresses through:

  • Chapter 1: The Empty Desk - Classroom scene with minigames (English typing test and Maths quiz)
  • The Hallway - Exploration with locker investigation and eavesdropping
  • Chapter 2: Suburbia - Walking home with optional detour
  • The House - Visiting the missing person’s family home (optional path)
  • Night - Final confrontation via a mysterious text message
  • Ending - One of three endings based on choices and stats

2.3 Rules of the Game

  • The player makes choices by typing the number corresponding to their chosen option (e.g. typing 1, 2, or 3).
  • Invalid inputs are rejected with feedback messages that become more intense as Sanity drops.
  • Two stats are tracked throughout the game:
    • Memory (0-100): Higher Memory allows the player to remember the missing person’s identity. Lower Memory causes text distortion (letters replaced with dots) and name forgetting.
    • Sanity (0-100): Higher Sanity keeps the player safe but causes them to forget the missing person. Lower Sanity causes text distortion (word repetition, creepy insertions like “…stop…”) and increasingly hostile error messages.
  • Stat changes are displayed to the player with colour-coded HUD indicators (e.g. [+10 MEMORY], [-5 SANITY]).

2.4 How the Game Is Played (Interaction Model)

The game is played entirely through the terminal/command line. Text is displayed using a typewriter effect (character-by-character printing with variable speed). The player reads narrative text, then selects from numbered options when prompted. During minigame segments, the player types responses directly (sentences for English, numbers for Maths, 5-letter words for Wordle). The game uses ANSI colour codes for visual feedback (green for success, red for errors, yellow for warnings, cyan for stats, dim grey for atmospheric text).

2.5 Scoring and Tracking System

The game tracks two primary stats:

StatStarting ValueEffect When HighEffect When Low
Memory100Player remembers the truth; text displays the correct nameText becomes corrupted; letters are replaced with dots; names revert to defaults
Sanity100Player is “safe” but forgets the missing personWords repeat randomly; “…stop…” is inserted into text; error messages become hostile

Stats are modified by player choices (e.g. investigating costs Sanity but gains Memory) and minigame performance (e.g. high typing accuracy gains Memory; low scores lose Sanity). Both stats are clamped between 0 and 100.

2.6 How Different Endings Are Reached

There are three endings:

  1. “Ignorance is Bliss” - Triggered if the player answers NO to the final text message, or if Sanity > 60 and Memory < 40. The player forgets everything and goes to sleep.
  2. “The Keeper” - Triggered if the player answers YES and Sanity < 40. The player is institutionalised but retains their memories.
  3. “Equivalent Exchange” - Triggered if the player answers YES with moderate-to-high Sanity. The missing person returns but the player begins to fade from existence.

2.7 Advanced Play Techniques and Strategies

  • Name Entry: If the player correctly guesses the missing person’s default name (Husain for boys, Fatima for girls) during the classroom scene, they receive a Memory boost. Entering the name incorrectly still stores it and creates dynamic name-swapping throughout the game.
  • Curb Sitting: In Chapter 2, sitting on the curb provides a large Memory boost (+20) at the cost of significant Sanity (-20), but this option can only be used once.
  • Wordle Minigame: At the missing person’s house, the player can attempt to hack a phone using a Wordle-style puzzle. If Memory is above 90, the answer is revealed. Successfully completing it unlocks the knows_truth flag and forces the correct target name.
  • Easter Eggs: Entering specific names (e.g. “fastmode” enables instant text, entering “Husain” or “Fatima” as the player name triggers alternate character assignments, and the name “abdia” triggers a hidden base64-encoded message).
  • Text Distortion System: The game dynamically distorts displayed text based on current stat values, creating a unique reading experience on each playthrough.

3. Requirements

3.1 Functional Requirements

IDRequirementPriority
FR-01The game must display a title screen with ASCII art and a typewriter text effectMust
FR-02The game must allow the player to select their gender (Boy/Girl), which determines the default missing person’s nameMust
FR-03The game must allow the player to enter their character name with input validation (non-empty, not “Abdullah”)Must
FR-04The game must track Memory and Sanity stats (integers, clamped 0-100) throughout the entire gameMust
FR-05The game must display stat changes to the player using colour-coded text indicatorsMust
FR-06The game must present multiple-choice decisions using numbered options and validate the player’s inputMust
FR-07The game must include a typing accuracy minigame (English class) that displays a sentence, counts down, clears the screen, and scores the player’s attemptMust
FR-08The game must include a maths quiz minigame with progressive difficulty (3 rounds)Must
FR-09The game must include a Wordle-style minigame with colour-coded feedback (green/yellow/grey)Must
FR-10The game must have at least three distinct story paths based on player choices (safe route home, detour to the house, curb sitting)Must
FR-11The game must have three significantly different endings based on the final choice and stat valuesMust
FR-12The game must use arrays (lists) to store related data (sentences for typing, startup lines, word lists, error messages)Must
FR-13The game must use functions with parameters to structure code (e.g. type_text(text, speed, color), input_choice(options, state), apply_text_effects(text, state))Must
FR-14The game must dynamically distort displayed text based on Memory and Sanity valuesShould
FR-15The game must dynamically swap the missing person’s displayed name based on statsShould
FR-16The game must handle KeyboardInterrupt gracefully without crashingShould
FR-17The game must include a fast mode toggle (via name entry or command-line argument)Could

3.2 Non-Functional Requirements

IDRequirementPriority
NFR-01The game must run in any standard terminal that supports ANSI colour codesMust
NFR-02Code must use meaningful variable and function names following Python naming conventions (snake_case)Must
NFR-03Code must include comments explaining the purpose of each function and key logic sectionsMust
NFR-04Code must use consistent indentation (4 spaces) and appropriate whitespaceMust
NFR-05The typewriter text effect must create an engaging, readable pace (adjustable speed parameter)Should
NFR-06The game must be completable within 10-15 minutes per playthroughShould
NFR-07Input prompts must be clearly visible and distinguishable from narrative textShould
NFR-08The game should gracefully handle terminal width variations using shutil.get_terminal_size()Should

4. Development Schedule (Gantt Chart)

Note: Create this as a visual Gantt chart using software such as Excel, Google Sheets, or an online Gantt chart tool (e.g. TeamGantt, canva.com). The chart should include the following tasks and phases:

PhaseTaskWeek 1Week 2Week 3Week 4Week 5
InvestigateResearch text adventure game mechanics████
InvestigateWrite problem outline and description████
InvestigateDefine functional and non-functional requirements████
DesignCreate structure chart████
DesignCreate flowcharts████
DesignWrite pseudocode algorithm████
DesignComplete trace tables████
DevelopImplement core game engine (GameState, type_text, input_choice)████
DevelopImplement story scenes (Chapters 1-2, Hallway, House, Night)████████
DevelopImplement minigames (typing, math, wordle)████
DevelopImplement endings and text distortion effects████
TestCreate and execute test plan████
EvaluateConduct user acceptance testing████
EvaluateWrite developer retrospective████

Milestones:

  • End of Week 1: Investigation complete, requirements finalised
  • End of Week 2: All design artefacts complete (pseudocode, flowchart, structure chart)
  • End of Week 3: Core game engine and first playable prototype working
  • End of Week 4: All story scenes, minigames, and endings implemented
  • End of Week 5: Testing complete, evaluation written, project submitted

5. Structure Chart

Note: Create this as a visual diagram using software such as draw.io, Lucidchart, or PowerPoint. The hierarchy below describes the structure:

                            main()
                              |
            ┌─────────┬──────┴──────┬──────────┬──────────┐
            |         |             |          |          |
      run_tutorial  scene_intro  scene_walk  scene_     scene_    endings
           ()       _school()    _home()    parents_   night_      ()
                                            house()    text()
                        |
              ┌─────────┼──────────┐
              |         |          |
         minigame_  minigame_  minigame_
         typing()   math()     wordle()

    ┌──────────────── Shared Utility Functions ────────────────┐
    |                                                          |
    |  type_text()    input_choice()    apply_text_effects()   |
    |  clear_screen() flush_input()     banner()               |
    |  get_width()                                             |
    └──────────────────────────────────────────────────────────┘

    ┌──────────────── GameState Class ─────────────────────────┐
    |                                                          |
    |  __init__()                                              |
    |  set_target_name_by_gender()                             |
    |  mod_stats(mem, san)                                     |
    |  get_missing_name()                                      |
    └──────────────────────────────────────────────────────────┘

Module descriptions:

ModulePurposeCalls
main()Entry point; initialises GameState and runs scenes in sequence; handles exceptionsrun_tutorial(), scene_intro_school(), scene_walk_home(), scene_parents_house(), scene_night_text(), endings()
run_tutorial()Displays title screen, boot sequence, tutorial rules, and collects player name/gendertype_text(), input_choice(), clear_screen(), flush_input()
scene_intro_school()Chapter 1: classroom scene, friend interaction, name entry, hallway explorationtype_text(), input_choice(), apply_text_effects(), minigame_typing(), minigame_math()
scene_walk_home()Chapter 2: walking home with branching paths (safe, detour, curb)type_text(), input_choice(), apply_text_effects()
scene_parents_house()Optional scene at the missing person’s house with argue/hack/leave choicestype_text(), input_choice(), minigame_wordle()
scene_night_text()Final YES/NO choice scenetype_text(), input_choice(), apply_text_effects()
endings()Displays one of three endings based on stats and final choicetype_text()
minigame_typing()English typing accuracy test with timed sentence displaytype_text(), clear_screen(), banner(), flush_input()
minigame_math()Progressive difficulty maths quiz (3 rounds)type_text(), clear_screen(), banner(), flush_input()
minigame_wordle()Wordle-style 5-letter word guessing game with coloured feedbacktype_text(), clear_screen(), banner(), flush_input()
type_text()Typewriter text display with colour, speed, and tenseness parameters(none)
input_choice()Validates player menu input; displays options; returns valid choicetype_text(), flush_input(), get_width()
apply_text_effects()Distorts text based on Memory and Sanity stat valuesGameState.get_missing_name()
GameState.mod_stats()Updates Memory and Sanity values (clamped 0-100) and displays changestype_text()
GameState.get_missing_name()Returns the displayed name for the missing person based on stats(none)

6. Flowchart

Note: Create this as a visual flowchart using software such as draw.io, Lucidchart, or PowerPoint. Use standard flowchart symbols (oval for start/end, rectangle for process, diamond for decision, parallelogram for input/output). The logic below describes the main game loop:

Flowchart 1: Main Game Loop

[START]
   |
   v
[Initialise GameState: memory=100, sanity=100]
   |
   v
[run_tutorial(): Display title, get gender, get name]
   |
   v
[scene_intro_school(): Display Chapter 1]
   |
   v
<Player asked about empty desk>
  /          \
"The person    "Never mind"
who sits       |
there"         v
  |        [Set girl_name_input = target_name]
  v        [mod_stats(mem=-10, san=+5)]
[Get name input from player]        |
  |                                 |
  v                                 |
<Name matches target_name?>         |
  /          \                      |
YES          NO                     |
  |           |                     |
  v           v                     |
[mem+5,     [mem-5,                 |
 san-5]     san+5]                  |
  |           |                     |
  v           v                     v
[Run minigame_typing() -> score affects stats]
   |
   v
[Run minigame_math() -> score affects stats]
   |
   v
[Display Hallway scene]
   |
   v
<Hallway choice: Locker / Chatter / Leave>───┐
   |          |           |                   |
   v          v           v                   |
[Locker:   [Chatter:   [Leave:              |
 san-5,     san-5]      break]              |
 mem+5]       |           |                 |
   |          |           |                 |
   └──────────┘           |                 |
         |                v                 |
         └──── (loop back if not Leave) ────┘
                          |
                          v
[scene_walk_home(): Display Chapter 2]
   |
   v
<Walk choice: Home / Detour / Curb>
  /          |          \
Home       Detour      Curb
  |          |           |
  v          v           v
[mem-15,  [mem+10,    [mem+20,
 san+15]   san-15,     san-20]
           parents_      |
           house=True]   v
  |          |        (loop back)
  v          v
<parents_house_visited?>
  /          \
NO           YES
  |            |
  v            v
(skip)   [scene_parents_house()]
  |            |
  v            v
[scene_night_text(): Display final YES/NO prompt]
   |
   v
<final_choice == "YES"?>
  /                    \
NO (or san>60          YES
  & mem<40)              |
  |                      v
  v               <sanity < 40?>
[ENDING:            /        \
 Ignorance       YES         NO
 is Bliss]        |           |
                  v           v
              [ENDING:    [ENDING:
               The         Equivalent
               Keeper]     Exchange]
                  |           |
                  v           v
               [END]       [END]

Flowchart 2: input_choice() Validation Loop

[START: input_choice(options, state)]
   |
   v
[Display separator line]
   |
   v
[Display all options with keys]
   |
   v
[flush_input()]
   |
   v
[Read user input]
   |
   v
<Input in valid_keys?>
  /          \
YES          NO
  |            |
  v            v
[Return      <sanity < 40?>
 choice]      /          \
            YES          NO
              |            |
              v            v
           [Display     [Display
            hostile      normal
            error]       error]
              |            |
              v            v
           [Loop back to "Read user input"]

7. Pseudocode Algorithm

BEGIN main
    TRY
        state ← new GameState()
        state.memory ← 100
        state.sanity ← 100

        // Tutorial and setup
        CALL clear_screen()
        DISPLAY ASCII art title centred on screen
        INPUT "Press Enter to continue"

        DISPLAY startup boot sequence lines
        DISPLAY tutorial instructions

        // Gender and name selection
        gender ← CALL input_choice(["Boy", "Girl"], state)
        IF gender = "1" THEN
            state.player_gender ← "Boy"
            state.target_name ← "Husain"
        ELSE
            state.player_gender ← "Girl"
            state.target_name ← "Fatima"
        END IF

        REPEAT
            INPUT player_name
            IF player_name = "" THEN
                player_name ← "Player"
            END IF
            IF player_name = "Abdullah" THEN
                DISPLAY "Name reserved. Choose another."
            ELSE
                EXIT LOOP
            END IF
        UNTIL valid name entered
        state.player_name ← player_name

        // ---- CHAPTER 1: THE EMPTY DESK ----
        CALL clear_screen()
        DISPLAY "CHAPTER 1: THE EMPTY DESK"

        text ← "You sit in class. To your left, there is an empty desk."
        DISPLAY CALL apply_text_effects(text, state)

        choice ← CALL input_choice(["The person who sits there.", "Never mind."], state)

        IF choice = "1" THEN
            INPUT entered_name
            state.girl_name_input ← entered_name
            IF entered_name = state.target_name THEN
                CALL state.mod_stats(mem=+5, san=-5)
            ELSE
                CALL state.mod_stats(mem=-5, san=+5)
            END IF
        ELSE
            state.girl_name_input ← state.target_name
            CALL state.mod_stats(mem=-10, san=+5)
        END IF

        // Minigames
        CALL minigame_typing(state)
        CALL minigame_math(state)

        // Hallway exploration loop
        REPEAT
            choice ← CALL input_choice(["Check locker", "Listen to chatter", "Leave school"], state)
            IF choice = "1" THEN
                DISPLAY "You find a note in your locker."
                CALL state.mod_stats(san=-5, mem=+5)
            ELSE IF choice = "2" THEN
                DISPLAY "You overhear a conversation about someone forgotten."
                CALL state.mod_stats(san=-5)
            ELSE IF choice = "3" THEN
                EXIT LOOP
            END IF
        UNTIL choice = "3"

        // ---- CHAPTER 2: SUBURBIA ----
        sat_on_curb ← FALSE
        REPEAT
            DISPLAY "CHAPTER 2: SUBURBIA"
            text ← "The houses all look the same."
            DISPLAY CALL apply_text_effects(text, state)

            options ← ["Head home", "Detour to house"]
            IF NOT sat_on_curb THEN
                APPEND "Sit on the curb" TO options
            END IF

            choice ← CALL input_choice(options, state)

            IF choice = "1" THEN
                CALL state.mod_stats(mem=-15, san=+15)
                EXIT LOOP
            ELSE IF choice = "2" THEN
                CALL state.mod_stats(mem=+10, san=-15)
                state.parents_house_visited ← TRUE
                EXIT LOOP
            ELSE IF choice = "3" AND NOT sat_on_curb THEN
                CALL state.mod_stats(mem=+20, san=-20)
                sat_on_curb ← TRUE
            END IF
        UNTIL choice = "1" OR choice = "2"

        // ---- THE HOUSE (conditional) ----
        IF state.parents_house_visited THEN
            argued ← FALSE
            REPEAT
                DISPLAY "You knock on the door."

                IF NOT argued THEN
                    options ← {1: "Argue", 2: "Show phone (Hack)", 3: "Leave"}
                ELSE
                    options ← {2: "Show phone (Hack)", 3: "Leave"}
                END IF

                choice ← CALL input_choice(options, state)

                IF choice = "1" AND NOT argued THEN
                    CALL state.mod_stats(san=-20, mem=+5)
                    argued ← TRUE
                ELSE IF choice = "2" THEN
                    won ← CALL minigame_wordle(state)
                    IF won THEN
                        state.knows_truth ← TRUE
                        CALL state.mod_stats(mem=+20, san=-20)
                    END IF
                    EXIT LOOP
                ELSE IF choice = "3" THEN
                    CALL state.mod_stats(san=+5, mem=-5)
                    EXIT LOOP
                END IF
            UNTIL exited
        END IF

        // ---- NIGHT ----
        DISPLAY "NIGHT"
        text ← "You are lying in bed."
        DISPLAY CALL apply_text_effects(text, state)
        DISPLAY "UNKNOWN ID: Do you really want them back?"

        state.final_choice ← CALL input_choice(["YES", "NO"], state)

        // ---- ENDINGS ----
        IF state.final_choice = "2" OR (state.sanity > 60 AND state.memory < 40) THEN
            DISPLAY "ENDING: IGNORANCE IS BLISS"
        ELSE IF state.final_choice = "1" AND state.sanity < 40 THEN
            DISPLAY "ENDING: THE KEEPER"
        ELSE IF state.final_choice = "1" THEN
            DISPLAY "ENDING: EQUIVALENT EXCHANGE"
        END IF

    CATCH KeyboardInterrupt
        DISPLAY "[SIMULATION TERMINATED]"
    CATCH Exception
        DISPLAY error message
    END TRY
END main

Pseudocode: apply_text_effects(text, state)

BEGIN apply_text_effects(text, state)
    processed_text ← text

    // Sanity effects: word repetition and creepy insertions
    IF state.sanity < 80 THEN
        words ← SPLIT processed_text BY spaces
        new_words ← empty array
        FOR EACH word IN words
            APPEND word TO new_words
            IF random() < (0.6 - state.sanity / 100) THEN
                APPEND word TO new_words    // echo effect
            END IF
            IF state.sanity < 50 AND random() < 0.2 THEN
                APPEND "...stop..." TO new_words
            END IF
        END FOR
        processed_text ← JOIN new_words WITH spaces
    END IF

    // Memory effects: letter replacement with dots
    IF state.memory < 80 THEN
        chars ← CONVERT processed_text TO character array
        FOR i ← 0 TO LENGTH(chars) - 1
            IF chars[i] is alphabetic AND random() < (0.6 - state.memory / 100) THEN
                chars[i] ← "."
            END IF
        END FOR
        processed_text ← JOIN chars
    END IF

    // Name replacement based on stats
    current_name ← CALL state.get_missing_name()
    IF state.girl_name_input IN processed_text AND current_name ≠ state.girl_name_input THEN
        REPLACE state.girl_name_input WITH current_name IN processed_text
    END IF

    RETURN processed_text
END apply_text_effects

Pseudocode: minigame_typing(state)

BEGIN minigame_typing(state)
    sentences ← ["The quick brown fox jumps over the lazy dog.",
                  "Why does nobody else remember the empty desk.",
                  "Reality is leaking from the corners of this room.",
                  "Everyone has forgotten about " + state.target_name + " but me."]

    target ← random choice FROM sentences
    DISPLAY target

    // Countdown timer
    FOR i ← 5 DOWN TO 1
        DISPLAY "Time remaining: " + i
        WAIT 1 second
    END FOR

    CALL clear_screen()
    INPUT user_input

    // Calculate accuracy score
    IF user_input = target THEN
        score ← 100
    ELSE
        matches ← count matching characters at same positions
        total ← MAX(LENGTH(user_input), LENGTH(target))
        score ← INTEGER(matches / total * 100)
    END IF

    DISPLAY "Accuracy: " + score + "%"

    IF score > 80 THEN
        CALL state.mod_stats(mem=+10)
    ELSE IF score > 50 THEN
        CALL state.mod_stats(san=-5)
    ELSE
        CALL state.mod_stats(san=-15)
    END IF

    RETURN score
END minigame_typing

8. Trace Tables

Trace Table 1: Full Playthrough - “Equivalent Exchange” Ending

This trace follows a player who investigates thoroughly, takes the detour, wins Wordle, and says YES.

StepAction / Inputmemorysanitygirl_name_inputparents_house_visitedknows_truthfinal_choiceNotes
1GameState initialised100100""FalseFalse""Starting values
2Gender: “1” (Boy)100100""FalseFalse""target_name = “Husain”
3Name: “Arafat”100100""FalseFalse""player_name = “Arafat”
4Chapter 1: Choose “1” (The person who sits there)100100""FalseFalse""Player investigates
5Enter name: “Husain” (correct)105→10095”Husain”FalseFalse""mem clamped to 100; mem+5, san-5
6Typing minigame: score 85%10095”Husain”FalseFalse""mem+10 (clamped to 100)
7Math minigame: 3/3 correct10095”Husain”FalseFalse""mem+10 (clamped to 100)
8Hallway: “1” (Check locker)10090”Husain”FalseFalse""san-5, mem+5 (clamped)
9Hallway: “3” (Leave school)10090”Husain”FalseFalse""Exits loop
10Suburbia: “3” (Sit on curb)10070”Husain”FalseFalse""mem+20 (clamped), san-20
11Suburbia: “2” (Detour)10055”Husain”TrueFalse""mem+10 (clamped), san-15
12House: “2” (Show phone / Hack)10055”Husain”TrueFalse""Enters Wordle
13Wordle: Won10030”Husain”TrueTrue""mem+10 (clamped) + mem+20 (clamped), san-5, san-20. knows_truth=True
14Night: “1” (YES)10030”Husain”TrueTrue”1”final_choice = “1”
15Endings check: final_choice=“1”, sanity=30 (<40)10030”Husain”TrueTrue”1”ENDING: THE KEEPER

Note: With sanity at 30 (< 40), this actually triggers “The Keeper” ending. For “Equivalent Exchange”, sanity would need to be >= 40.

Trace Table 2: Safe Playthrough - “Ignorance is Bliss” Ending

This trace follows a player who avoids investigation and chooses safety.

StepAction / Inputmemorysanitygirl_name_inputparents_house_visitedfinal_choiceNotes
1GameState initialised100100""False""Starting values
2Gender: “2” (Girl)100100""False""target_name = “Fatima”
3Name: “Sarah”100100""False""player_name set
4Chapter 1: Choose “2” (Never mind)90100”Fatima”False""mem-10, san+5 (clamped). girl_name_input = target_name
5Typing minigame: score 40%9085”Fatima”False""san-15 (score < 50)
6Math minigame: 1/3 correct9065”Fatima”False""san-10 per wrong answer (x2)
7Hallway: “3” (Leave school)9065”Fatima”False""Exits immediately
8Suburbia: “1” (Head home)7580”Fatima”False""mem-15, san+15
9Parents house: skipped7580”Fatima”False""parents_house_visited = False
10Night: “2” (NO)7580”Fatima”False”2”final_choice = “2”
11Endings check: final_choice=“2”7580”Fatima”False”2”ENDING: IGNORANCE IS BLISS

Trace Table 3: input_choice() with Invalid Input

Stepuser_inputvalid_keysuser_in in valid_keys?sanityOutput
1”hello”[“1”, “2”, “3”]No85”That’s not an option.” (random from normal msgs)
2”5”[“1”, “2”, “3”]No85”Try again.” (random from normal msgs)
3""[“1”, “2”, “3”]No85”Focus.” (random from normal msgs)
4”2”[“1”, “2”, “3”]Yes85Returns “2”