Jake: Week 4: Start Building Your Baseball App

You have a prototype of your baseball training app from v0. That prototype may look very polished -- v0 is built for fast UI. This week you start rebuilding the idea in Flask with Python you can read and change. Your first version will look simpler than v0 on purpose. We add structure first, then keep improving toward Demo Day (April 29th).

Design still matters: this guide uses Tailwind CSS (via CDN) so your pages look clean without huge custom CSS blocks. See Tailwind CSS.

Your v0 prototype: https://v0.dev/chat/baseball-mvp-app-f5tJhByUkhT
Use it as a reference for features and layout, not as something your Flask app must match on day one.

Check In: What Are You Working On?

Open TODO.md. Does it describe what you are actually doing today? If not, update it now -- even a rough line like "Start building the baseball app in Flask" is fine. You will refine this at the end.

Part 1: Essential Project Catch-up

These steps fix project files your instructors need to review and that unblock your build. Practice-only work is optional (see the bottom of this section).

Rename files that start with a space

Your repo still has v0-prompt.md and vibe-code-report.md -- notice the accidental space before the letter v. That breaks tools and links.

  1. In the file explorer, find each file that starts with a space
  2. Right-click -- Rename
  3. Delete the space at the very beginning so the names are exactly v0-prompt.md and vibe-code-report.md
  4. Save / commit after renaming (see below)

Finish vibe-code-report.md

Open vibe-code-report.md after renaming. Make sure it includes:

  • A clear prototype link (you already have one -- keep it)

  • Features list -- what your MVP includes

  • Reflection -- a few sentences for:

    • How you feel about how the prototype turned out
    • What you would change with more time
    • What you would keep the same
  • Known limitations -- what does not work yet (for example: pages that do not save data)

Commit your catch-up

  1. Save all files: Ctrl+S (Windows/Chromebook) or Cmd+S (Mac)
  2. Source Control -- message: rename v0 files, complete vibe code report
  3. Commit, then Sync Changes

Optional (not required): Your warmup.py can stay as extra practice. If you want, add a formula and a print line so it runs -- but that is not required for your baseball app or Demo Day path.

Part 2: Create Your Flask App

Flask connects URLs to Python functions. Each function returns HTML as a string. For now everything lives in app.py so you can see the full path from Python to browser.

Step 1: Create app.py

In the file explorer, create a new file named app.py (use the New File icon or right-click -- same idea in Codespaces and Cursor).

Paste:

from flask import Flask

app = Flask(__name__)


@app.route("/")
def home():
    return """
    <html>
    <head>
        <meta charset="utf-8">
        <title>Baseball Training App</title>
        <script src="https://cdn.tailwindcss.com"></script>
    </head>
    <body class="min-h-screen bg-slate-900 text-white">
        <div class="mx-auto max-w-2xl px-6 py-12">
            <h1 class="text-3xl font-bold text-rose-500">Baseball Training App</h1>
            <p class="mt-2 text-slate-400">By Jake F.</p>
            <p class="mt-6 text-slate-200">Welcome to your personal baseball training program. Pick a section below.</p>
            <div class="mt-8 flex flex-wrap gap-3">
                <a class="rounded-lg bg-rose-500 px-4 py-2 font-semibold text-slate-900 shadow hover:bg-rose-400" href="/drills">Drills &amp; Workouts</a>
                <a class="rounded-lg border-2 border-rose-500 px-4 py-2 font-semibold text-rose-400 hover:bg-rose-500/10" href="/nutrition">Nutrition</a>
            </div>
        </div>
    </body>
    </html>
    """


@app.route("/drills")
def drills():
    return """
    <html>
    <head>
        <meta charset="utf-8">
        <title>Drills &amp; Workouts</title>
        <script src="https://cdn.tailwindcss.com"></script>
    </head>
    <body class="min-h-screen bg-slate-900 text-white">
        <div class="mx-auto max-w-2xl px-6 py-12">
            <h1 class="text-2xl font-bold text-rose-500">Drills &amp; Workouts</h1>
            <h2 class="mt-8 text-lg font-semibold text-slate-200">Hitting</h2>
            <ul class="mt-3 list-inside list-disc space-y-2 text-slate-300">
                <li>Tee work -- 50 swings, contact point</li>
                <li>Soft toss -- 30 reps, hands inside</li>
                <li>Live BP -- 20 pitches</li>
            </ul>
            <h2 class="mt-8 text-lg font-semibold text-slate-200">Fielding</h2>
            <ul class="mt-3 list-inside list-disc space-y-2 text-slate-300">
                <li>Ground balls -- 25 each side</li>
                <li>Pop flies -- 15 reps</li>
                <li>Quick release -- 20 throws</li>
            </ul>
            <p class="mt-10"><a class="text-rose-400 underline hover:text-rose-300" href="/">&larr; Back to Home</a></p>
        </div>
    </body>
    </html>
    """


if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0", port=5000)

Notes:

  • @app.route("/") -- homepage

  • @app.route("/drills") -- drills page

  • Tailwind -- classes like bg-slate-900 and text-rose-500 style the page. The script in <head> must stay there.

  • The Nutrition link is on the homepage, but the /nutrition route is not in this paste yet -- you add it in Step 4.

Step 2: Install Flask

Open the terminal (Terminal > New Terminal in Codespaces, or View > Terminal in Cursor):

pip install flask

Use pip3 install flask if the first command fails.

Step 3: Run your app

  1. Open app.py, save it
  2. Click the play button (triangle) in the top-right
  3. When the terminal shows the server running on port 5000:
    • Codespaces: use the port forward popup or the Ports tab, open port 5000 in the browser
    • Local Cursor: open http://localhost:5000

You should see the dark homepage with Drills & Workouts and Nutrition. Drills should work. Nutrition will 404 until Step 4.

Stop the server: focus the terminal, Ctrl+C.

Step 4: Add the /nutrition page yourself

Copy the pattern from /drills:

  1. In app.py, find if __name__ == "__main__":
  2. Above that line, add @app.route("/nutrition") and def nutrition(): with return """ ... """ HTML
  3. List foods and drinks that help baseball players (5--8 items is enough)
  4. Use the same Tailwind look as the other pages (min-h-screen bg-slate-900, headings, a link back to /)

Step 5: Make it yours

Ideas:

  • Swap Tailwind colors (for example rose-500 to emerald-500)

  • Change drill bullets to what you actually do

  • Add another route when you are ready (schedule, compare, etc.)

Part 3: Save Everything to GitHub

  1. Save all files
  2. Source Control -- message: add flask baseball app with tailwind
  3. Commit, Sync Changes

Set Your Goal for Next Week

Now that you have built something, open TODO.md again and replace what is there with one specific thing you will work on before next class. You have a much better idea now than you did at the start. Examples:

  • "Add a weekly schedule page and link it from the home page."
  • "Add a /compare page with Ronald Acuna Jr. stats (even if numbers are placeholder at first)."
  • "Improve nutrition content and add one more training page."

Write one clear sentence -- not "work on my app."

Troubleshooting

"No module named flask"

Run pip install flask or pip3 install flask.

Play button missing or nothing runs

Save app.py, make sure its tab is active. In Codespaces you can run python app.py in the terminal if needed.

"Address already in use"

Ctrl+C in the terminal, then start again.

Page looks unstyled

Confirm <script src="https://cdn.tailwindcss.com"></script> is in the <head>. Save, restart Flask, refresh the browser.

"Not Found" for Nutrition

You need @app.route("/nutrition") above def nutrition():, and both must sit above if __name__ == "__main__":.

Source Control / sync issues

Save files first. If push fails, use the ... menu in Source Control to Push and set upstream if asked.

Get Help From Your AI Agent

Use this prompt when you are stuck. Fill in the brackets. Ask for steps, not a full rewrite.

I'm building my baseball training Flask app for Demo Day. This week I'm working on: [e.g. adding /nutrition / fixing an error / styling with Tailwind].

Here's my code:

[paste app.py or one route]

Problem: [describe it. Paste terminal errors here].

Please do not replace my whole project. Tell me what to check first, then small changes to try. Define new terms in one sentence.

You can also highlight a line and ask: "What does this part do?"