$ cat /posts/project-to-do-list-application-with-file-storage.md
[tags]Python

Project: To-Do List Application with File Storage

drwxr-xr-x2026-01-185 min0 views
Project: To-Do List Application with File Storage

A to-do list application demonstrates fundamental programming concepts including data structures, file handling, CRUD operations, and user interface design while creating practical productivity tool. This project implements comprehensive task manager supporting adding new tasks with titles and descriptions, viewing all tasks with status indicators, updating existing tasks modifying content, deleting completed or unwanted tasks, marking tasks complete tracking progress, filtering by status showing pending or completed, and persistent storage saving tasks to JSON file ensuring data survives program restarts. Command-line to-do managers provide lightweight alternatives to web applications, integrate into developer workflows, and teach essential concepts applicable to larger database-driven applications.

This comprehensive project explores task data structure using dictionaries storing id, title, description, status, and creation date, file persistence with JSON module using json.dump() saving tasks and json.load() reading tasks, CRUD operations implementing create adding tasks with unique IDs, read displaying tasks in formatted lists, update modifying existing tasks, and delete removing tasks by ID, user interface creating menu-driven CLI with numbered options accepting user input validating choices, status management tracking pending and completed states toggling completion status, data validation ensuring non-empty titles checking valid IDs, and error handling catching file not found exceptions, JSON decode errors, and invalid input. This project teaches dictionary operations for structured data, list comprehension filtering tasks, file I/O reading and writing JSON, working with datetime for timestamps, string formatting for display, function organization structuring code logically, exception handling for robustness, and user experience design creating intuitive interfaces, providing foundation for web applications, mobile apps, and database-driven systems while creating immediately useful tool for personal task management.

Core Task Manager Implementation

The core implementation defines task structure using dictionaries and implements CRUD operations. Each task contains unique identifier, title, optional description, completion status, and creation timestamp. Functions handle task creation, retrieval, updating, and deletion maintaining data consistency.

pythontask_manager_core.py
# Core Task Manager Implementation

import json
import os
from datetime import datetime
import uuid

# === Task data structure ===

"""
Task Dictionary Structure:
{
    'id': 'unique-uuid',
    'title': 'Task title',
    'description': 'Optional description',
    'status': 'pending' or 'completed',
    'created_at': 'YYYY-MM-DD HH:MM:SS',
    'completed_at': 'YYYY-MM-DD HH:MM:SS' or None
}
"""

# Configuration
DATA_FILE = 'tasks.json'

# === File operations ===

def load_tasks():
    """
    Load tasks from JSON file.
    
    Returns:
        list: List of task dictionaries
    """
    if not os.path.exists(DATA_FILE):
        return []
    
    try:
        with open(DATA_FILE, 'r') as f:
            return json.load(f)
    except json.JSONDecodeError:
        print("Warning: Tasks file is corrupted. Starting fresh.")
        return []
    except Exception as e:
        print(f"Error loading tasks: {e}")
        return []

def save_tasks(tasks):
    """
    Save tasks to JSON file.
    
    Args:
        tasks (list): List of task dictionaries
    
    Returns:
        bool: True if successful, False otherwise
    """
    try:
        with open(DATA_FILE, 'w') as f:
            json.dump(tasks, f, indent=2)
        return True
    except Exception as e:
        print(f"Error saving tasks: {e}")
        return False

# === CRUD operations ===

def create_task(title, description=""):
    """
    Create a new task.
    
    Args:
        title (str): Task title
        description (str): Optional task description
    
    Returns:
        dict: Created task dictionary
    """
    if not title or not title.strip():
        raise ValueError("Task title cannot be empty")
    
    task = {
        'id': str(uuid.uuid4())[:8],  # Short UUID
        'title': title.strip(),
        'description': description.strip(),
        'status': 'pending',
        'created_at': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
        'completed_at': None
    }
    
    return task

def add_task(tasks, title, description=""):
    """
    Add new task to list and save.
    
    Args:
        tasks (list): Current task list
        title (str): Task title
        description (str): Task description
    
    Returns:
        dict: Created task
    """
    task = create_task(title, description)
    tasks.append(task)
    
    if save_tasks(tasks):
        print(f"\nβœ“ Task added successfully! (ID: {task['id']})")
        return task
    else:
        print("\nβœ— Failed to save task")
        return None

def get_task_by_id(tasks, task_id):
    """
    Find task by ID.
    
    Args:
        tasks (list): Task list
        task_id (str): Task ID to find
    
    Returns:
        dict or None: Task if found, None otherwise
    """
    for task in tasks:
        if task['id'] == task_id:
            return task
    return None

def update_task(tasks, task_id, title=None, description=None):
    """
    Update existing task.
    
    Args:
        tasks (list): Task list
        task_id (str): Task ID to update
        title (str): New title (optional)
        description (str): New description (optional)
    
    Returns:
        bool: True if updated, False otherwise
    """
    task = get_task_by_id(tasks, task_id)
    
    if not task:
        print(f"\nβœ— Task with ID '{task_id}' not found")
        return False
    
    if title:
        task['title'] = title.strip()
    if description is not None:  # Allow empty string
        task['description'] = description.strip()
    
    if save_tasks(tasks):
        print(f"\nβœ“ Task updated successfully!")
        return True
    else:
        print("\nβœ— Failed to save changes")
        return False

def delete_task(tasks, task_id):
    """
    Delete task by ID.
    
    Args:
        tasks (list): Task list
        task_id (str): Task ID to delete
    
    Returns:
        bool: True if deleted, False otherwise
    """
    task = get_task_by_id(tasks, task_id)
    
    if not task:
        print(f"\nβœ— Task with ID '{task_id}' not found")
        return False
    
    tasks.remove(task)
    
    if save_tasks(tasks):
        print(f"\nβœ“ Task deleted successfully!")
        return True
    else:
        print("\nβœ— Failed to delete task")
        return False

def mark_complete(tasks, task_id):
    """
    Mark task as completed.
    
    Args:
        tasks (list): Task list
        task_id (str): Task ID to mark complete
    
    Returns:
        bool: True if marked, False otherwise
    """
    task = get_task_by_id(tasks, task_id)
    
    if not task:
        print(f"\nβœ— Task with ID '{task_id}' not found")
        return False
    
    if task['status'] == 'completed':
        print("\n⚠ Task is already completed")
        return False
    
    task['status'] = 'completed'
    task['completed_at'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    
    if save_tasks(tasks):
        print(f"\nβœ“ Task marked as completed!")
        return True
    else:
        print("\nβœ— Failed to save changes")
        return False

def mark_pending(tasks, task_id):
    """
    Mark task as pending (undo completion).
    
    Args:
        tasks (list): Task list
        task_id (str): Task ID to mark pending
    
    Returns:
        bool: True if marked, False otherwise
    """
    task = get_task_by_id(tasks, task_id)
    
    if not task:
        print(f"\nβœ— Task with ID '{task_id}' not found")
        return False
    
    if task['status'] == 'pending':
        print("\n⚠ Task is already pending")
        return False
    
    task['status'] = 'pending'
    task['completed_at'] = None
    
    if save_tasks(tasks):
        print(f"\nβœ“ Task marked as pending!")
        return True
    else:
        print("\nβœ— Failed to save changes")
        return False

# === Task filtering ===

def get_pending_tasks(tasks):
    """
    Get all pending tasks.
    
    Args:
        tasks (list): Task list
    
    Returns:
        list: Pending tasks
    """
    return [task for task in tasks if task['status'] == 'pending']

def get_completed_tasks(tasks):
    """
    Get all completed tasks.
    
    Args:
        tasks (list): Task list
    
    Returns:
        list: Completed tasks
    """
    return [task for task in tasks if task['status'] == 'completed']

# === Display functions ===

def display_task(task, show_description=True):
    """
    Display single task.
    
    Args:
        task (dict): Task to display
        show_description (bool): Whether to show description
    """
    status_icon = 'βœ“' if task['status'] == 'completed' else 'β—‹'
    
    print(f"\n[{status_icon}] {task['title']}")
    print(f"    ID: {task['id']}")
    
    if show_description and task['description']:
        print(f"    Description: {task['description']}")
    
    print(f"    Created: {task['created_at']}")
    
    if task['completed_at']:
        print(f"    Completed: {task['completed_at']}")

def display_tasks(tasks, title="All Tasks"):
    """
    Display list of tasks.
    
    Args:
        tasks (list): Tasks to display
        title (str): Display title
    """
    print("\n" + "="*60)
    print(f"  {title}")
    print("="*60)
    
    if not tasks:
        print("\n  No tasks to display.")
        print()
        return
    
    for i, task in enumerate(tasks, 1):
        status_icon = 'βœ“' if task['status'] == 'completed' else 'β—‹'
        print(f"\n{i}. [{status_icon}] {task['title']}")
        print(f"   ID: {task['id']}")
        if task['description']:
            print(f"   {task['description']}")
    
    print()

def display_summary(tasks):
    """
    Display task statistics.
    
    Args:
        tasks (list): Task list
    """
    total = len(tasks)
    pending = len(get_pending_tasks(tasks))
    completed = len(get_completed_tasks(tasks))
    
    print("\n" + "="*60)
    print("  TASK SUMMARY")
    print("="*60)
    print(f"  Total Tasks: {total}")
    print(f"  Pending: {pending}")
    print(f"  Completed: {completed}")
    if total > 0:
        completion_rate = (completed / total) * 100
        print(f"  Completion Rate: {completion_rate:.1f}%")
    print()

print("Core task manager implementation completed!")
Use UUIDs for IDs: Generate unique IDs with uuid.uuid4(). More reliable than sequential numbers, prevents conflicts when merging task lists.

Interactive Command-Line Interface

The interactive interface provides menu-driven interaction with numbered options for common operations. It displays clear menus, accepts user input with validation, calls appropriate functions, and handles errors gracefully. The interface loop continues until user chooses to exit maintaining persistent session.

pythontodo_cli.py
# Interactive Command-Line Interface

import os
import sys

# Import core functions
from task_manager_core import (
    load_tasks, save_tasks, add_task, update_task,
    delete_task, mark_complete, mark_pending,
    get_pending_tasks, get_completed_tasks,
    display_tasks, display_task, display_summary,
    get_task_by_id
)

def clear_screen():
    """Clear terminal screen."""
    os.system('cls' if os.name == 'nt' else 'clear')

def display_menu():
    """Display main menu."""
    print("\n" + "="*60)
    print("           πŸ“ TO-DO LIST MANAGER πŸ“")
    print("="*60)
    print("\n1. βž• Add New Task")
    print("2. πŸ“‹ View All Tasks")
    print("3. ⏳ View Pending Tasks")
    print("4. βœ… View Completed Tasks")
    print("5. ✏️  Update Task")
    print("6. βœ“ Mark Task Complete")
    print("7. β—‹ Mark Task Pending")
    print("8. πŸ—‘οΈ  Delete Task")
    print("9. πŸ“Š View Summary")
    print("10. πŸ”„ Clear Screen")
    print("0. πŸšͺ Exit")
    print("="*60)

def get_input(prompt, required=True):
    """
    Get user input with validation.
    
    Args:
        prompt (str): Input prompt
        required (bool): Whether input is required
    
    Returns:
        str: User input
    """
    while True:
        value = input(prompt).strip()
        
        if not required or value:
            return value
        
        print("⚠ This field is required. Please enter a value.")

def handle_add_task(tasks):
    """Handle adding new task."""
    print("\n" + "="*60)
    print("  ADD NEW TASK")
    print("="*60)
    
    title = get_input("\nTask title: ", required=True)
    description = get_input("Description (optional): ", required=False)
    
    try:
        add_task(tasks, title, description)
    except ValueError as e:
        print(f"\nβœ— Error: {e}")
    
    input("\nPress Enter to continue...")

def handle_view_tasks(tasks, filter_type='all'):
    """Handle viewing tasks."""
    if filter_type == 'pending':
        filtered = get_pending_tasks(tasks)
        title = "Pending Tasks"
    elif filter_type == 'completed':
        filtered = get_completed_tasks(tasks)
        title = "Completed Tasks"
    else:
        filtered = tasks
        title = "All Tasks"
    
    display_tasks(filtered, title)
    input("Press Enter to continue...")

def handle_update_task(tasks):
    """Handle updating task."""
    print("\n" + "="*60)
    print("  UPDATE TASK")
    print("="*60)
    
    # Show current tasks
    display_tasks(tasks, "Select Task to Update")
    
    if not tasks:
        input("Press Enter to continue...")
        return
    
    task_id = get_input("\nEnter task ID: ", required=True)
    
    # Check if task exists
    task = get_task_by_id(tasks, task_id)
    if not task:
        print(f"\nβœ— Task with ID '{task_id}' not found")
        input("\nPress Enter to continue...")
        return
    
    # Display current task
    print("\nCurrent task:")
    display_task(task)
    
    # Get new values
    print("\nEnter new values (leave blank to keep current):")
    new_title = get_input(f"Title [{task['title']}]: ", required=False)
    new_description = get_input(f"Description [{task['description']}]: ", required=False)
    
    # Update
    update_task(
        tasks,
        task_id,
        title=new_title if new_title else None,
        description=new_description if new_description else None
    )
    
    input("\nPress Enter to continue...")

def handle_mark_complete(tasks):
    """Handle marking task as complete."""
    print("\n" + "="*60)
    print("  MARK TASK AS COMPLETE")
    print("="*60)
    
    # Show pending tasks
    pending = get_pending_tasks(tasks)
    display_tasks(pending, "Pending Tasks")
    
    if not pending:
        input("Press Enter to continue...")
        return
    
    task_id = get_input("\nEnter task ID to mark complete: ", required=True)
    mark_complete(tasks, task_id)
    
    input("\nPress Enter to continue...")

def handle_mark_pending(tasks):
    """Handle marking task as pending."""
    print("\n" + "="*60)
    print("  MARK TASK AS PENDING")
    print("="*60)
    
    # Show completed tasks
    completed = get_completed_tasks(tasks)
    display_tasks(completed, "Completed Tasks")
    
    if not completed:
        input("Press Enter to continue...")
        return
    
    task_id = get_input("\nEnter task ID to mark pending: ", required=True)
    mark_pending(tasks, task_id)
    
    input("\nPress Enter to continue...")

def handle_delete_task(tasks):
    """Handle deleting task."""
    print("\n" + "="*60)
    print("  DELETE TASK")
    print("="*60)
    
    # Show all tasks
    display_tasks(tasks, "Select Task to Delete")
    
    if not tasks:
        input("Press Enter to continue...")
        return
    
    task_id = get_input("\nEnter task ID to delete: ", required=True)
    
    # Confirm deletion
    task = get_task_by_id(tasks, task_id)
    if task:
        print("\nTask to delete:")
        display_task(task)
        confirm = get_input("\nAre you sure? (yes/no): ", required=True)
        
        if confirm.lower() in ['yes', 'y']:
            delete_task(tasks, task_id)
        else:
            print("\nβœ— Deletion cancelled")
    
    input("\nPress Enter to continue...")

def handle_summary(tasks):
    """Handle displaying summary."""
    display_summary(tasks)
    input("Press Enter to continue...")

def main():
    """Main application loop."""
    # Load tasks
    tasks = load_tasks()
    
    print("\nβœ“ Loaded {} tasks".format(len(tasks)))
    input("Press Enter to continue...")
    
    while True:
        clear_screen()
        display_menu()
        
        choice = get_input("\nEnter choice (0-10): ", required=True)
        
        if choice == '0':
            # Exit
            print("\n" + "="*60)
            print("  Thank you for using To-Do List Manager!")
            print("  Your tasks have been saved.")
            print("  Goodbye! πŸ‘‹")
            print("="*60 + "\n")
            break
        
        elif choice == '1':
            handle_add_task(tasks)
        
        elif choice == '2':
            handle_view_tasks(tasks, 'all')
        
        elif choice == '3':
            handle_view_tasks(tasks, 'pending')
        
        elif choice == '4':
            handle_view_tasks(tasks, 'completed')
        
        elif choice == '5':
            handle_update_task(tasks)
        
        elif choice == '6':
            handle_mark_complete(tasks)
        
        elif choice == '7':
            handle_mark_pending(tasks)
        
        elif choice == '8':
            handle_delete_task(tasks)
        
        elif choice == '9':
            handle_summary(tasks)
        
        elif choice == '10':
            clear_screen()
        
        else:
            print("\nβœ— Invalid choice! Please select 0-10.")
            input("\nPress Enter to continue...")

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        print("\n\nβœ— Application interrupted. Tasks saved.\n")
        sys.exit(0)
    except Exception as e:
        print(f"\nβœ— Unexpected error: {e}")
        sys.exit(1)
Handle Keyboard Interrupt: Catch KeyboardInterrupt (Ctrl+C) gracefully, save data, and display friendly exit message. Improves user experience.

Complete Application with Enhancements

The complete application adds advanced features including search functionality finding tasks by keyword, priority levels marking task importance, due dates with reminders, task categories for organization, and export capabilities generating reports. These enhancements demonstrate practical extensions building upon core functionality.

pythonenhanced_features.py
# Complete Application with Enhancements

import json
from datetime import datetime, timedelta

# === Enhanced task structure ===

"""
Enhanced Task Structure:
{
    'id': 'unique-uuid',
    'title': 'Task title',
    'description': 'Description',
    'status': 'pending' or 'completed',
    'priority': 'low', 'medium', or 'high',
    'category': 'work', 'personal', etc.,
    'due_date': 'YYYY-MM-DD' or None,
    'created_at': 'YYYY-MM-DD HH:MM:SS',
    'completed_at': 'YYYY-MM-DD HH:MM:SS' or None
}
"""

# === Search functionality ===

def search_tasks(tasks, keyword):
    """
    Search tasks by keyword.
    
    Args:
        tasks (list): Task list
        keyword (str): Search keyword
    
    Returns:
        list: Matching tasks
    """
    keyword = keyword.lower()
    results = []
    
    for task in tasks:
        if (keyword in task['title'].lower() or
            keyword in task.get('description', '').lower() or
            keyword in task.get('category', '').lower()):
            results.append(task)
    
    return results

# === Priority management ===

def get_priority_tasks(tasks, priority):
    """
    Get tasks by priority.
    
    Args:
        tasks (list): Task list
        priority (str): Priority level
    
    Returns:
        list: Tasks with specified priority
    """
    return [task for task in tasks 
            if task.get('priority', 'medium') == priority]

def sort_by_priority(tasks):
    """
    Sort tasks by priority (high, medium, low).
    
    Args:
        tasks (list): Task list
    
    Returns:
        list: Sorted tasks
    """
    priority_order = {'high': 0, 'medium': 1, 'low': 2}
    
    return sorted(tasks, 
                 key=lambda x: priority_order.get(x.get('priority', 'medium'), 1))

# === Due date management ===

def get_overdue_tasks(tasks):
    """
    Get overdue tasks.
    
    Args:
        tasks (list): Task list
    
    Returns:
        list: Overdue pending tasks
    """
    today = datetime.now().date()
    overdue = []
    
    for task in tasks:
        if task['status'] == 'pending' and task.get('due_date'):
            try:
                due_date = datetime.strptime(task['due_date'], '%Y-%m-%d').date()
                if due_date < today:
                    overdue.append(task)
            except ValueError:
                pass
    
    return overdue

def get_upcoming_tasks(tasks, days=7):
    """
    Get tasks due within specified days.
    
    Args:
        tasks (list): Task list
        days (int): Number of days to look ahead
    
    Returns:
        list: Upcoming tasks
    """
    today = datetime.now().date()
    future = today + timedelta(days=days)
    upcoming = []
    
    for task in tasks:
        if task['status'] == 'pending' and task.get('due_date'):
            try:
                due_date = datetime.strptime(task['due_date'], '%Y-%m-%d').date()
                if today <= due_date <= future:
                    upcoming.append(task)
            except ValueError:
                pass
    
    return upcoming

# === Category management ===

def get_categories(tasks):
    """
    Get unique categories from tasks.
    
    Args:
        tasks (list): Task list
    
    Returns:
        list: Unique categories
    """
    categories = set()
    for task in tasks:
        if task.get('category'):
            categories.add(task['category'])
    
    return sorted(list(categories))

def get_tasks_by_category(tasks, category):
    """
    Get tasks in specific category.
    
    Args:
        tasks (list): Task list
        category (str): Category name
    
    Returns:
        list: Tasks in category
    """
    return [task for task in tasks 
            if task.get('category', '').lower() == category.lower()]

# === Export functionality ===

def export_to_text(tasks, filename='tasks_export.txt'):
    """
    Export tasks to text file.
    
    Args:
        tasks (list): Task list
        filename (str): Export filename
    
    Returns:
        bool: True if successful
    """
    try:
        with open(filename, 'w', encoding='utf-8') as f:
            f.write("TO-DO LIST EXPORT\n")
            f.write("=" * 60 + "\n")
            f.write(f"Exported: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
            f.write(f"Total Tasks: {len(tasks)}\n")
            f.write("=" * 60 + "\n\n")
            
            for i, task in enumerate(tasks, 1):
                status = 'βœ“' if task['status'] == 'completed' else 'β—‹'
                f.write(f"{i}. [{status}] {task['title']}\n")
                f.write(f"   ID: {task['id']}\n")
                
                if task.get('priority'):
                    f.write(f"   Priority: {task['priority'].upper()}\n")
                
                if task.get('category'):
                    f.write(f"   Category: {task['category']}\n")
                
                if task.get('due_date'):
                    f.write(f"   Due: {task['due_date']}\n")
                
                if task.get('description'):
                    f.write(f"   Description: {task['description']}\n")
                
                f.write(f"   Created: {task['created_at']}\n")
                
                if task.get('completed_at'):
                    f.write(f"   Completed: {task['completed_at']}\n")
                
                f.write("\n")
        
        print(f"\nβœ“ Tasks exported to {filename}")
        return True
        
    except Exception as e:
        print(f"\nβœ— Export failed: {e}")
        return False

# === Statistics ===

def generate_statistics(tasks):
    """
    Generate detailed statistics.
    
    Args:
        tasks (list): Task list
    
    Returns:
        dict: Statistics dictionary
    """
    stats = {
        'total': len(tasks),
        'pending': len([t for t in tasks if t['status'] == 'pending']),
        'completed': len([t for t in tasks if t['status'] == 'completed']),
        'overdue': len(get_overdue_tasks(tasks)),
        'high_priority': len(get_priority_tasks(tasks, 'high')),
        'categories': len(get_categories(tasks))
    }
    
    if stats['total'] > 0:
        stats['completion_rate'] = (stats['completed'] / stats['total']) * 100
    else:
        stats['completion_rate'] = 0
    
    return stats

def display_statistics(tasks):
    """
    Display detailed statistics.
    
    Args:
        tasks (list): Task list
    """
    stats = generate_statistics(tasks)
    
    print("\n" + "="*60)
    print("  DETAILED STATISTICS")
    print("="*60)
    print(f"  Total Tasks: {stats['total']}")
    print(f"  Pending: {stats['pending']}")
    print(f"  Completed: {stats['completed']}")
    print(f"  Overdue: {stats['overdue']}")
    print(f"  High Priority: {stats['high_priority']}")
    print(f"  Categories: {stats['categories']}")
    print(f"  Completion Rate: {stats['completion_rate']:.1f}%")
    print()

print("Enhanced features implementation completed!")

Development Best Practices

  • Validate all user input: Check for empty strings, invalid IDs, and malformed data. Provide clear error messages guiding users to correct input
  • Handle file operations safely: Use try-except blocks catching FileNotFoundError and JSONDecodeError. Create backup before overwriting data
  • Separate concerns: Organize code into modules - data operations, file I/O, user interface. Improves maintainability and testing
  • Use consistent data structure: Define clear task dictionary schema. Document required and optional fields. Validate structure when loading
  • Implement proper ID system: Use UUIDs preventing ID conflicts. Never reuse IDs even after deletion. Makes data merging possible
  • Add timestamps: Record creation and modification times. Enables sorting by date, tracking task age, and audit trails
  • Provide user feedback: Show success/error messages with icons (βœ“, βœ—, ⚠). Use clear language describing what happened and why
  • Support undo operations: Implement marking completed tasks back to pending. Consider adding comprehensive undo/redo system
  • Format output clearly: Use consistent formatting, visual separators, and icons. Make interface scannable and intuitive
  • Write tests: Create unit tests for CRUD operations, edge cases, and error handling. Ensures reliability during enhancements
Backup Before Modifying: Create backup of tasks.json before implementing destructive operations. Prevents data loss during development.

Conclusion

Building to-do list application demonstrates essential programming concepts through practical project. The implementation includes task data structure using dictionaries with id generated by uuid, title and description for content, status tracking pending or completed, timestamps for created_at and completed_at, and optional fields for priority, category, and due_date, file persistence with JSON using json.dump() serializing tasks to file with indent for readability, json.load() deserializing from file, error handling for corrupted files and missing data, and atomic writes preventing partial corruption, CRUD operations with create_task() generating new tasks with validation, add_task() appending to list and saving, get_task_by_id() finding specific tasks, update_task() modifying existing content, delete_task() removing by ID, mark_complete() and mark_pending() toggling status, and filtering functions for status, priority, and categories, and interactive CLI with menu-driven interface displaying numbered options, input validation ensuring data quality, clear user feedback with success/error messages, screen clearing for better UX, and keyboard interrupt handling for graceful exit.

Key learning outcomes include data structures using dictionaries for task representation, lists storing collections with append() and remove(), list comprehension filtering with conditions, file operations opening files with context managers, reading and writing JSON, handling file exceptions, working with datetime using datetime.now() for timestamps, strftime() formatting dates, parsing date strings with strptime(), and calculating date differences, function organization creating focused single-purpose functions, separating data and presentation logic, using return values effectively, exception handling catching specific exceptions like ValueError and FileNotFoundError, providing helpful error messages, and preventing crashes, user interface design creating intuitive menus, validating input appropriately, providing visual feedback with icons and formatting. Enhanced features include search functionality finding tasks by keyword in title, description, or category, priority management with low, medium, high levels, sorting by priority importance, due date tracking identifying overdue tasks, showing upcoming deadlines, category organization grouping related tasks, filtering by category, export capabilities generating text reports, creating backups, and statistics calculating completion rates, tracking overdue counts, analyzing by priority and category. This project provides foundation for web applications building Flask or Django versions, mobile applications creating React Native or Flutter apps, desktop GUI using Tkinter or PyQt, database integration replacing JSON with SQLite or PostgreSQL, and cloud synchronization adding online storage, demonstrating how basic concepts combine into functional software while teaching practical development skills applicable across programming domains.

$ cat /comments/ (0)

new_comment.sh

// Email hidden from public

>_

$ cat /comments/

// No comments found. Be the first!

[session] guest@{codershandbook}[timestamp] 2026

Navigation

Categories

Connect

Subscribe

// 2026 {Coders Handbook}. EOF.