Aiden's Project Guide

Project: Clash Royale Personality Quiz (pivoting to Web App) Category: Web Development (Flask) Last updated: April 18

Note: This guide reflects the latest state of your project repo + our Wednesday lab discussion. It may not match the most up-to-date version if you've worked since.

Where You Are

Two things happened this week:

  1. You have the hard part working. load_cards, map_personality_to_type, and find_best_card in data/main.py are solid. They're your quiz brain. We're keeping all of them.
  2. You decided to go Flask. End goal: someone visits your site, takes the quiz, sees a Clash Royale character card as their result.

This week you'll reshape the project for Flask, split your code into a handwritten business logic module and a Flask app, and move your questions into a data file.

Project Structure

Your project splits into two kinds of code:

  • Business logic — you handwrite this. The functions that make your project different from anyone else's. You must be able to explain every line out loud.
  • Library / view code — agent-assisted is fine. Flask routes, HTML templates, Bootstrap classes. The agent already knows these patterns — let it scaffold, then read what it produced and edit it until you understand it.

Target layout by Thursday:

final-project-pierai6-1/
├── app.py                  ← Flask routes — agent-assisted OK
├── quiz.py                 ← business logic — handwrite (yours to own)
├── pyproject.toml
├── data/
│   ├── cards.txt           ← data
│   └── questions.json      ← data (new)
└── templates/
    ├── home.html           ← HTML — agent-assisted OK
    ├── quiz.html           ← HTML — agent-assisted OK
    └── result.html         ← HTML — agent-assisted OK

Why the split? From Lecture 1: The MVP — your final demo is about what's yours. The Flask code looks the same for every Flask app; your scoring algorithm does not.

Phase 1: Initialize the Project for Flask

Agent-assisted is fine here. uv init, uv add flask, and the "hello world" Flask app are the same for every Flask project. You're not demonstrating anything new by typing them — you're setting up the scaffold.

Objective

Move from the CLI setup to a running Flask app. Your first browser "hello" is the goal.

Instructions

Sample Output

Visit http://127.0.0.1:5000. You should see:

hello

Hints

Minimal app.py:

from flask import Flask

app = Flask(__name__)

@app.route("/")
def home():
    return "hello"

Run the server:

uv run flask --app app run --debug

--debug makes Flask reload on save so you don't have to restart the server.

Optional — get help from your agent:

I'm pivoting from a CLI to Flask. Walk me through uv init, uv add
flask, and a minimal app.py. Don't touch data/main.py yet.

Phase 2: Move the Questions into a JSON File

Handwrite this yourself. The question set IS your quiz — what you ask and in what order. The file format is trivial; the content is yours.

Objective

Your 4 questions currently live inside main() in data/main.py. Data belongs in a data file. Move them to data/questions.json.

Instructions

Sample Structure

data/questions.json:

[
  {
    "id": "personality_type",
    "text": "What role do you naturally take in a group?",
    "options": {
      "a": "leader",
      "b": "supporter",
      "c": "strategist",
      "d": "lone wolf"
    }
  }
]

Add the other three (style, energy, trait) following the same shape. It's fine to ask your agent to do this for you!

Hints

Reading JSON in Python:

import json

def load_questions(filename):
    with open(filename, "r") as file:
        return json.load(file)

json.load() returns a Python list of dicts — the same shape you typed in the file. No parsing logic needed.

Testing it worked:

questions = load_questions("data/questions.json")
print(questions[0]["text"])  # should print your first question

Optional — get help from your agent:

Move my questions data/questions.json using the JSON structure described below:
<paste in the sample structure code above>

Phase 3: Build quiz.py (your Business Logic Module)

Handwrite this yourself. This IS your project — the scoring algorithm that picks a Clash Royale character from someone's answers. You will be asked to explain this code out loud on demo day.

Objective

Move your scoring logic out of data/main.py and into a new quiz.py at the project root. This will allow you to work on your core logic code separate from the UI code (CLI or web).

Instructions

Hints

New find_best_card signature:

def find_best_card(cards, answers):
    # answers = {"card_type": "troop", "style": "aggressive",
    #            "energy": "fast", "trait": "brave"}
    best_card = None
    best_score = -1
    for card in cards:
        score = 0
        if card["card_type"] == answers["card_type"]:
            score += 3
        # ... same pattern for style / energy / trait
    return best_card, best_score

Why the dict? The Flask form gives you back request.form, which already behaves like a dict. Cleaner to pass it through than unpack into 4 arguments.

Tip. Write quiz.py without any Flask imports. If it imports flask or render_template, you've leaked view code into the business logic. Keep them separate.

Optional — get help from your agent:

Walk me through refactoring find_best_card to take an `answers` dict.
Show old and new signatures side-by-side. Don't change anything
until I say so — I want to understand the refactor first.

Phase 4: Wire Up the Flask Routes

Agent-assisted is fine here. Read what the agent produces, edit it until you understand it, then move on. The business logic is in quiz.py.

Objective

Replace your "hello" route with three real routes that run the quiz.

Instructions

    • GET / → render home.html
    • GET /quiz → call load_questions(), pass to quiz.html
    • POST /result → read form answers, call find_best_card, render result.html

Hints

Full route skeleton:

from flask import Flask, render_template, request
from quiz import load_cards, load_questions, find_best_card, map_personality_to_type

app = Flask(__name__)

@app.route("/")
def home():
    return render_template("home.html")

@app.route("/quiz")
def quiz():
    questions = load_questions("data/questions.json")
    return render_template("quiz.html", questions=questions)

@app.route("/result", methods=["POST"])
def result():
    personality_type = request.form.get("personality_type")
    card_type = map_personality_to_type(personality_type)
    answers = {
        "card_type": card_type,
        "style": request.form.get("style"),
        "energy": request.form.get("energy"),
        "trait": request.form.get("trait"),
    }
    cards = load_cards("data/cards.txt")
    best_card, _ = find_best_card(cards, answers)
    return render_template("result.html", card=best_card)

Read, don't copy. After the agent writes this for you, read it line by line. Understand what request.form.get() returns. Understand why methods=["POST"] is there on /result but not /. Ask about anything unclear.

Optional — get help from your agent:

Help me plan three Flask routes for my quiz (/, /quiz, /result).
Show me the route stubs first. Then walk me through request.form
and how it reflects what's in my HTML form.

Phase 5: Templates + Styling

Agent-assisted is fine here. HTML markup and Bootstrap classes are UI code.

Objective

Three simple HTML pages so the quiz actually looks like a quiz.

Instructions

Sample Output

/quiz should show:

Question 1: What role do you naturally take in a group?
 ( ) leader
 ( ) supporter
 ( ) strategist
 ( ) lone wolf

Question 2: How do you usually approach things?
 ...

[ Submit ]

Hints

Looping over questions in quiz.html:

<form action="/result" method="post">
  {% for question in questions %}
    <fieldset>
      <legend>{{ question.text }}</legend>
      {% for key, value in question.options.items() %}
        <label>
          <input type="radio" name="{{ question.id }}" value="{{ value }}">
          {{ value }}
        </label><br>
      {% endfor %}
    </fieldset>
  {% endfor %}
  <button type="submit">Submit</button>
</form>

Bootstrap CDN (in <head>):

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">

Optional — get help from your agent:

Scaffold home.html, quiz.html, and result.html for my quiz. Use
Bootstrap via CDN. Keep the markup simple enough that I can edit
it. Don't change app.py or quiz.py.

Phase 6: Cleanup + Journal

Handwrite this yourself. The journal entry is your primary functionality and where you will need to explain your thinking for the demo.

Objective

Delete the CLI leftovers and write your Checkpoint 2 journal entry.

Instructions

    • What you pivoted (CLI → Flask)
    • What's in quiz.py (business logic) vs app.py (library code)
    • Which parts you wrote yourself vs which parts came from the agent
    • What's still rough

Hints

Commit message idea:

checkpoint 2: flask pivot + quiz.py business logic module

Checkpoint 2 Readiness

By Thursday April 23 at 3pm:

Helpful Resources