Tutorials Logic, IN info@tutorialslogic.com

Python Capstone Project: Build a Tested Learning Progress Reporter

Project Outcome

Build a command-line application that imports lesson activity from CSV, validates and stores it in SQLite, calculates progress summaries, exports JSON, and optionally synchronizes completed lesson identifiers with a remote API. The project remains useful without network access and has explicit boundaries for files, database work, and HTTP.

Completion means a fresh virtual environment can install the built wheel, run the command, pass automated tests, reject malformed or duplicate data safely, produce useful logs, and follow a documented deployment and rollback procedure.

Feature Contract

  • Import a UTF-8 CSV file with lesson, status, and completed_at columns.
  • Reject unknown status values and impossible dates with row numbers.
  • Store learners, lessons, and progress using SQLite constraints and transactions.
  • List incomplete lessons and summarize completion by topic.
  • Export a stable JSON report schema.
  • Synchronize completed identifiers through a timeout-bound API adapter.
  • Expose commands through a packaged progress-report entry point.

Project Structure

Suggested Package Layout

Suggested Package Layout
pyproject.toml
src/progress_report/
  cli.py
  domain.py
  import_csv.py
  repository.py
  sync_api.py
tests/
  unit/
  integration/

The src layout prevents tests from accidentally importing an uninstalled package from the repository root.

Domain Values

Represent status with an enum and parsed timestamps with datetime values. Keep CSV strings and SQLite rows at adapters so calculations operate on validated domain data.

Validated Progress Record

Validated Progress Record
from dataclasses import dataclass
from datetime import datetime
from enum import StrEnum

class Status(StrEnum):
    STARTED = "started"
    COMPLETED = "completed"

@dataclass(frozen=True)
class Progress:
    lesson: str
    status: Status
    completed_at: datetime | None = None

The importer decides whether a raw status and timestamp can construct this record.

Database Contract

Use parameterized queries, enable foreign keys for each SQLite connection, and import one file inside a transaction so a failed row does not leave an unexplained partial batch.

Table Essential Rule
learners Canonical email is unique
lessons External lesson identifier is unique
progress One learner and lesson pair is unique
sync_events Stable request key prevents duplicate remote work

Command Surface

CLI Commands

CLI Commands
progress-report import activity.csv --learner maya@example.com
progress-report summary --learner maya@example.com
progress-report export report.json --learner maya@example.com
progress-report sync --learner maya@example.com --dry-run

A dry run prints intended synchronization without sending data and must not mark events as delivered.

Test Evidence

  • Unit-test status parsing, date rules, summary calculations, and duplicate handling.
  • Integration-test CSV encoding and SQLite constraints with temporary paths.
  • Mock only the remote API transport; verify the adapter separately against a controlled HTTP contract.
  • Test interruption and retry so synchronization remains idempotent.
  • Build the wheel and run one command from a fresh environment.

Delivery Milestones

  • 1. Create pyproject.toml, src layout, entry point, and quality commands.
  • 2. Implement domain records and CSV validation.
  • 3. Add SQLite schema, repository, transaction, and integration tests.
  • 4. Add summary and JSON export commands.
  • 5. Add API adapter, timeout, retry classification, and dry run.
  • 6. Add security review, logging, profile evidence, artifact test, and deployment runbook.

Acceptance Evidence

  • Malformed rows report the source row and do not partially commit the batch.
  • Repeated import and sync operations do not duplicate progress or remote events.
  • No API token, learner data, or full payload appears in logs.
  • Static checks and automated tests pass from one project command.
  • The installed wheel works outside the source checkout.
  • The release identifies its Python requirement and can be rolled back without corrupting SQLite data.

Extension Choices

After the acceptance evidence passes, add a process pool for a measured CPU-heavy report, a small web API, or encrypted backup export. Each extension must preserve offline behavior and the existing data contract.

Review the Complete Application

0 of 2 checked

Q1. Why test the wheel in a fresh environment?

Q2. What protects a retried sync operation?

Try this next

Deliver the Capstone

0 of 2 completed

  1. Import one validated CSV row through domain conversion, transaction, repository, summary output, and tests before adding more commands. Keep parsing errors separate from persistence failures so each has a useful report.
  2. Import the same file twice with a stable idempotency key, then install the built wheel in a fresh virtual environment and run the reporting command. The second import must not duplicate progress records, and the command must not depend on the source tree.
Browse Free Tutorials

Explore 500+ free tutorials across 20+ languages and frameworks.