Python script for a CLI To-Do List App

I asked Grok how it could help with creating software. After bragging about its capabilities (tl;dr), it spontaneously delivered code for a Python script for a CLI To-Do List App.

Example: Let’s Build Something Simple [Oh yeah, thank you.]

If you want a starting point, here’s a quick Python script for a CLI To-Do List App to demonstrate my ability to create software:

import sqlite3
import sys

def init_db():
    conn = sqlite3.connect("todo.db")
    cursor = conn.cursor()
    cursor.execute("""CREATE TABLE IF NOT EXISTS tasks (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        task TEXT NOT NULL,
        completed BOOLEAN DEFAULT 0
    )""")
    conn.commit()
    conn.close()

def add_task(task):
    conn = sqlite3.connect("todo.db")
    cursor = conn.cursor()
    cursor.execute("INSERT INTO tasks (task) VALUES (?)", (task,))
    conn.commit()
    conn.close()
    print(f"Added task: {task}")

def list_tasks():
    conn = sqlite3.connect("todo.db")
    cursor = conn.cursor()
    cursor.execute("SELECT id, task, completed FROM tasks")
    tasks = cursor.fetchall()
    conn.close()
    if not tasks:
        print("No tasks found.")
        return
    for task in tasks:
        status = "✓" if task[2] else " "
        print(f"[{task[0]}] {task[1]} [{status}]")

def complete_task(task_id):
    conn = sqlite3.connect("todo.db")
    cursor = conn.cursor()
    cursor.execute("UPDATE tasks SET completed = 1 WHERE id = ?", (task_id,))
    if cursor.rowcount == 0:
        print(f"Task {task_id} not found.")
    else:
        print(f"Completed task {task_id}.")
    conn.commit()
    conn.close()

def main():
    init_db()
    if len(sys.argv) < 2:
        print("Usage: todo.py [add|list|complete] [args]")
        return

    command = sys.argv[1].lower()
    if command == "add" and len(sys.argv) > 2:
        add_task(" ".join(sys.argv[2:]))
    elif command == "list":
        list_tasks()
    elif command == "complete" and len(sys.argv) == 3:
        try:
            complete_task(int(sys.argv[2]))
        except ValueError:
            print("Task ID must be a number.")
    else:
        print("Invalid command. Use: add <task>, list, or complete <id>")

if __name__ == "__main__":
    main()

How to use:
1. Save as todo.py.
2. Run python todo.py add “Buy groceries” to add a task.
3. Run python todo.py list to see tasks.
4. Run python todo.py complete 1 to mark task 1 as done.

This could be extended into a web app with Flask or a mobile app with Flutter.

[Me: Add a function to remove all tasks marked as completed.]

I’ll add a function to the todo.py script to remove all tasks marked as completed. The new function, clear_completed, will delete tasks where completed = 1 from the database. I’ll also update the main function to handle a new clear command.Here’s the modified script with the new functionality:

import sqlite3
import sys

def init_db():
    conn = sqlite3.connect("todo.db")
    cursor = conn.cursor()
    cursor.execute("""CREATE TABLE IF NOT EXISTS tasks (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        task TEXT NOT NULL,
        completed BOOLEAN DEFAULT 0
    )""")
    conn.commit()
    conn.close()

def add_task(task):
    conn = sqlite3.connect("todo.db")
    cursor = conn.cursor()
    cursor.execute("INSERT INTO tasks (task) VALUES (?)", (task,))
    conn.commit()
    conn.close()
    print(f"Added task: {task}")

def list_tasks():
    conn = sqlite3.connect("todo.db")
    cursor = conn.cursor()
    cursor.execute("SELECT id, task, completed FROM tasks")
    tasks = cursor.fetchall()
    conn.close()
    if not tasks:
        print("No tasks found.")
        return
    for task in tasks:
        status = "✓" if task[2] else " "
        print(f"[{task[0]}] {task[1]} [{status}]")

def complete_task(task_id):
    conn = sqlite3.connect("todo.db")
    cursor = conn.cursor()
    cursor.execute("UPDATE tasks SET completed = 1 WHERE id = ?", (task_id,))
    if cursor.rowcount == 0:
        print(f"Task {task_id} not found.")
    else:
        print(f"Completed task {task_id}.")
    conn.commit()
    conn.close()

def clear_completed():
    conn = sqlite3.connect("todo.db")
    cursor = conn.cursor()
    cursor.execute("DELETE FROM tasks WHERE completed = 1")
    deleted = cursor.rowcount
    conn.commit()
    conn.close()
    if deleted == 0:
        print("No completed tasks to clear.")
    else:
        print(f"Cleared {deleted} completed task(s).")

def main():
    init_db()
    if len(sys.argv) < 2:
        print("Usage: todo.py [add|list|complete|clear] [args]")
        return

    command = sys.argv[1].lower()
    if command == "add" and len(sys.argv) > 2:
        add_task(" ".join(sys.argv[2:]))
    elif command == "list":
        list_tasks()
    elif command == "complete" and len(sys.argv) == 3:
        try:
            complete_task(int(sys.argv[2]))
        except ValueError:
            print("Task ID must be a number.")
    elif command == "clear":
        clear_completed()
    else:
        print("Invalid command. Use: add <task>, list, complete <id>, or clear")

if __name__ == "__main__":
    main()

Changes Made

  1. New Function: clear_completed:
    • Connects to the todo.db database.
    • Executes a DELETE SQL query to remove all tasks where completed = 1.
    • Reports the number of tasks deleted or a message if none were found.
    • Commits changes and closes the connection.
  2. Updated main Function:
    • Added support for a clear command (runs clear_completed()).
    • Updated the usage message to include clear as a valid command.
  3. Error Handling:
    • The clear_completed function checks if any tasks were deleted (cursor.rowcount) to provide appropriate feedback.

How to Use the New Function

  • Save the updated script as todo.py.
  • Run python todo.py clear to delete all tasks marked as completed (those with ✓ in the list).
  • Example workflow:
python todo.py add "Buy groceries"
python todo.py add "Write report"
python todo.py complete 1
python todo.py list
python todo.py clear
python todo.py list
  • This will add two tasks, mark “Buy groceries” as completed, list tasks, clear completed tasks, and list again to show only “Write report” remains.

Notes

  • The database (todo.db) remains compatible with the original script; no schema changes were needed.
  • If you want to test without affecting existing data, back up todo.db or use a different database name.
  • Let me know if you need further modifications, like undoing deletions or adding a confirmation prompt before clearing!

First item on the to-do list, create a to-do list. Done.