A-level Python · Lesson 9 of 9

A-level project: task manager

OCR H446 programming project skills / AQA 7517 NEA-style skills

Design and implement a modular, database-backed command-line task manager with testing.

← All A-level Python lessons

Planning a substantial project

A larger application should begin with a clear problem, data model and modular design. Develop and test separate features before connecting the user interface to persistent storage. Keep evidence of testing and evaluation as the project evolves.

Watch out: A working demonstration is only part of an A-level project. Design decisions, systematic testing and evaluation also matter.

1 · Learn and explore

Study this example, identify inputs and outputs, then trace the key variables. Run and adapt it in Python 3.

import sqlite3

def setup(connection):
    connection.execute('CREATE TABLE IF NOT EXISTS tasks (id INTEGER PRIMARY KEY, name TEXT NOT NULL, complete INTEGER NOT NULL DEFAULT 0)')

def add_task(connection, name):
    if not name.strip(): raise ValueError('name required')
    connection.execute('INSERT INTO tasks(name) VALUES (?)', (name.strip(),))
    connection.commit()

def list_tasks(connection):
    return connection.execute('SELECT id, name, complete FROM tasks ORDER BY id').fetchall()

def complete_task(connection, task_id):
    cursor = connection.execute('UPDATE tasks SET complete=1 WHERE id=?', (task_id,))
    connection.commit()
    return cursor.rowcount > 0

def main():
    with sqlite3.connect('tasks.db') as db:
        setup(db)
        while True:
            command=input('1 add / 2 list / 3 complete / 4 exit: ').strip()
            if command=='1':
                name=input('Task name: ').strip()
                try: add_task(db,name)
                except ValueError as error: print(error)
            elif command=='2':
                for task_id,name,done in list_tasks(db): print(task_id,'[x]' if done else '[ ]',name)
            elif command=='3':
                try: print('Updated' if complete_task(db,int(input('Task ID: '))) else 'Not found')
                except ValueError: print('Please enter a numeric ID')
            elif command=='4': break
            else: print('Choose 1 to 4')

2 · Independent programming challenge

Design and implement a modular, database-backed command-line task manager with testing. Download the starter, design your solution, and add tests before revealing the answer.

Download starter + solution ZIP ↓

Stretch task: investigate time/space complexity or data validation, then write an evaluation of your approach.

Show reference solution after attempting the task
import sqlite3

def setup(connection):
    connection.execute('CREATE TABLE IF NOT EXISTS tasks (id INTEGER PRIMARY KEY, name TEXT NOT NULL, complete INTEGER NOT NULL DEFAULT 0)')

def add_task(connection, name):
    if not name.strip(): raise ValueError('name required')
    connection.execute('INSERT INTO tasks(name) VALUES (?)', (name.strip(),))
    connection.commit()

def list_tasks(connection):
    return connection.execute('SELECT id, name, complete FROM tasks ORDER BY id').fetchall()

def complete_task(connection, task_id):
    cursor = connection.execute('UPDATE tasks SET complete=1 WHERE id=?', (task_id,))
    connection.commit()
    return cursor.rowcount > 0

def main():
    with sqlite3.connect('tasks.db') as db:
        setup(db)
        while True:
            command=input('1 add / 2 list / 3 complete / 4 exit: ').strip()
            if command=='1':
                name=input('Task name: ').strip()
                try: add_task(db,name)
                except ValueError as error: print(error)
            elif command=='2':
                for task_id,name,done in list_tasks(db): print(task_id,'[x]' if done else '[ ]',name)
            elif command=='3':
                try: print('Updated' if complete_task(db,int(input('Task ID: '))) else 'Not found')
                except ValueError: print('Please enter a numeric ID')
            elif command=='4': break
            else: print('Choose 1 to 4')

if __name__=='__main__': main()

3 · Debug and explain

Change one boundary condition in the starter or reference program. Predict which test fails, then repair it and document why.

Concept check: Why is a test plan essential for this project?

Reveal explanation

It records expected outcomes for normal, boundary and invalid inputs and shows whether requirements are met.

4 · Assess your learning

Describe the algorithm or design in your own words; include a normal test, a boundary test and an invalid input. Compare your answers with the reference solution and record one improvement.

Progress is stored only in this browser.

Want extra practice? Try interactive Python tracing and debugging questions →