Project 3: CLI-based To-do App0%

Project 3: CLI-based To-do App

Beginner12 min readUpdated: Jul 11, 2026
Study Materials

Project 3: CLI-Based To-Do App in Python

In this project, we apply our cumulative understanding of Object-Oriented Architecture, SQLite Database Management, Datetime Arithmetic, and Defensive Error Handling to engineer a high-productivity Command-Line Task & To-Do Management Engine.


1. System Architecture & Capabilities

Our To-Do application manages task lifecycles stored in an embedded tasks.db SQLite database:

Visual Architecture Blueprint
+-----------------------------------------------------------------------------+
|                                tasks.db                                     |
|                                                                             |
|  id (PK) | title | priority (HIGH/MED/LOW) | status | due_date | created_at |
+-----------------------------------------------------------------------------+

Key Capabilities:

  1. 1
    Full CRUD Lifecycle: Add, list, search, update status, and delete tasks.
  2. 2
    Priority Hierarchy: Prioritizes tasks by HIGH, MEDIUM, and LOW.
  3. 3
    Deadline Awareness: Compares task deadlines against current system time via the datetime module to flag OVERDUE tasks with visual alert tags.
  4. 4
    Resilient CLI: Parameterized SQL queries safeguard against SQL injection, while comprehensive error trapping handles invalid date formats.

2. Complete Project Implementation

Visual Architecture & Process Flow

How data and code flow step-by-step

Flowchart
Step 1
def _get_connection
self
Step 2
sqlite3.Connection:

3. Sample Execution Simulation

Output
===== TERMINAL TASK & TO-DO MANAGER =====
1. View All Active Tasks
2. Add New Task
3. Mark Task Status (Pending / In-Progress / Completed)
4. View Completed Archive
5. Delete Task
6. Exit
Select an option (1-6): 2
 
Enter task description: Prepare slide deck for board meeting
Priority (HIGH / MEDIUM / LOW) [Default: MEDIUM]: HIGH
Due Date (YYYY-MM-DD) or press Enter to skip: 2026-09-14
Task #1 ('Prepare slide deck for board meeting') added successfully.
 
===== TERMINAL TASK & TO-DO MANAGER =====
Select an option (1-6): 1
 
===========================================================================
ID | STATUS | PRIORITY | DUE DATE | TITLE
---------------------------------------------------------------------------
1 | [PENDING] | HIGH | 2026-09-14 | Prepare slide deck for board meeting
===========================================================================

Multiple Choice Questions

1. How does the SQLite table schema prevent arbitrary invalid values from being stored in the status column?

A. With an external Python cron job B. Using a SQL CHECK(status IN ('PENDING', 'IN_PROGRESS', 'COMPLETED')) constraint C. By making the column a Primary Key D. Status cannot be constrained in SQLite Answer: B Explanation: The SQL CHECK constraint validates that inserted or updated strings match one of the enumerated allowable states.


2. How does the application detect that a task is OVERDUE?

A. By pinging an external atomic clock API B. By comparing the task's due_date string against date.today().strftime("%Y-%m-%d") for incomplete tasks C. By catching a TimeoutError D. Tasks cannot be overdue in SQLite Answer: B Explanation: ISO formatted dates (YYYY-MM-DD) are lexicographically sortable; comparing due_date < today_str identifies dates in the past.


3. Which SQL clause allows custom hierarchical sorting (e.g. HIGH before MEDIUM before LOW)?

A. ORDER BY priority DESC B. ORDER BY CASE priority WHEN 'HIGH' THEN 1 WHEN 'MEDIUM' THEN 2 WHEN 'LOW' THEN 3 END C. GROUP BY priority D. PARTITION BY priority Answer: B Explanation: A SQL CASE statement inside an ORDER BY clause assigns custom integer weights to categorical strings for custom sorting.


4. What does cursor.lastrowid return after executing INSERT INTO tasks ...?

A. The number of rows in the table B. The newly generated auto-incrementing integer ID of the created task C. A list of all task names D. None Answer: B Explanation: cursor.lastrowid stores the generated primary key rowid of the most recently inserted record.


5. Why is parameterized SQL syntax (VALUES (?, ?, ?)) used when adding new tasks?

A. To prevent SQL Injection attacks from malicious task title strings B. To compress task titles in memory C. Parameterized queries run only on Saturdays D. It is mandatory for Python functions Answer: A Explanation: Parameterized placeholders treat values strictly as literal data rather than executable SQL code, preventing SQL injection vulnerabilities.


Next Lesson

Library Management System

Continue learning with hands-on practice, examples, and exercises in the upcoming topic.

Related Lessons

Practice Quiz

Test your understanding of this lesson with 5 questions. Each question has one correct answer.

PrevNext