Past Lesson Note

This note is from 8 months ago. You're viewing content from a previous lesson.

Daily Note for October 1, 2025 Past Lesson

At the start of every class, please: 

  1. Make sure you are working from your programming folder
  2. Make sure your python virtual environment is activated
  3. Make sure you can access our test template at 127.0.0.1:5000

 

  1. Please the folder: 25-26-9th-Grade and then open 04-school-store.
  2. Please run app.py 
  3. Please add a few items and conduct a sale (I'll walk you through this part).

 

1) Identify — Add a health-check route

Where: anywhere above if __name__ == '__main__':
Edit:

@app.route('/ping')
def ping():
    return 'pong'

Done when: Visiting /ping shows pong.


2) Display — Show the current time on the dashboard

Where: in index() route
Edit (add import and pass a var):

from datetime import datetime  # already imported above
# ...
return render_template('index.html',
    total_products=total_products,
    low_stock_products=low_stock_products,
    recent_sales=recent_sales,
    low_stock_items=low_stock_items,
    now=datetime.now().strftime('%Y-%m-%d %H:%M'))

Template hint: put {{ now }} somewhere visible.
Done when: The home page shows a timestamp.


3) Annotate — Greet the user after login

Where: in /login POST, inside if user: block after setting session
Edit:

flash(f"Welcome, {user['username']}!", 'success')

Done when: After login, a green message says “Welcome, admin!”.


4) Validate — Warn if price is below cost when adding a product

Where: in /inventory/add POST, right after you convert numbers
Edit:

if price < cost:
    flash('Warning: price is below cost.', 'info')

(Still allows saving; it just warns.)
Done when: Adding a product with price < cost shows an info warning.


5) Filter — Add a very simple “low stock only” filter to inventory

Where: in /inventory route, after existing filters
Edit:

low = request.args.get('low', '')
if low == '1':
    query += " AND p.stock_quantity <= p.min_stock_level"

Usage: Visit /inventory?low=1.
Done when: Only low-stock products appear with ?low=1.


6) Construct — Make transaction IDs more unique

Where: in generate_transaction_id()
Edit:

import random
def generate_transaction_id():
    timestamp = datetime.now().strftime('%Y%m%d%H%M%S')
    return f"TXN{timestamp}{random.randint(100,999)}"

Done when: Two quick checkouts don’t collide; IDs end with 3 random digits.


7) Populate — Add one more default category

Where: in init_database() where default_categories is defined
Edit (add a tuple):

('Merch', 'Stickers, pins, mugs, and school swag'),

Done when: After deleting the DB (or running on a fresh DB), categories includes “Merch”.
(Existing INSERT OR IGNORE prevents duplicates.)

 

8) Define — Expose an app version

Where: near the top of the file (globals) and add a route
Edit:

APP_VERSION = "0.1.0"

@app.route('/version')
def version():
    return APP_VERSION

Done when: Visiting /version shows 0.1.0.


9) Identify — Add a “who am I?” endpoint

Where: add a route anywhere above if __name__ == '__main__':
Edit:

@app.route('/me')
def me():
    if not session.get('user_id'):
        return jsonify({"logged_in": False})
    return jsonify({
        "logged_in": True,
        "id": session['user_id'],
        "username": session['username'],
        "role": session['role']
    })

Done when: /me returns JSON with your username when logged in, and {"logged_in": false} when not.


10) Validate — Block negative prices or stock on add

Where: in /inventory/add POST, after converting to numbers
Edit:

if price < 0 or cost < 0 or stock_quantity < 0 or min_stock_level < 0:
    flash('Values cannot be negative.', 'error')
    return redirect(url_for('add_product'))

Done when: Submitting a negative value shows an error and does not save.


11) Handle — Show a friendly 404 page

Where: near other routes; add an error handler
Edit:

@app.errorhandler(404)
def not_found(e):
    return render_template('404.html'), 404

Template hint: create templates/404.html with one line like Page not found.
Done when: Visiting a bad URL shows your custom 404 page.


12) Summarize — Tiny JSON stats endpoint

Where: add a route that reuses your existing queries
Edit:

@app.route('/api/stats')
def api_stats():
    if not session.get('user_id'):
        return jsonify({"error": "login required"}), 401
    conn = get_db_connection()
    total_products = conn.execute("SELECT COUNT(*) FROM products").fetchone()[0]
    total_sales = conn.execute("SELECT COUNT(*) FROM sales").fetchone()[0]
    low_stock = conn.execute("SELECT COUNT(*) FROM products WHERE stock_quantity <= min_stock_level").fetchone()[0]
    conn.close()
    return jsonify({
        "total_products": total_products,
        "total_sales": total_sales,
        "low_stock": low_stock
    })

Done when: Visiting /api/stats while logged in returns a JSON object with those three counts.