Day 29: Mini To-Do List

Objective

Create a mini to-do list application that allows the user to:

  1. Add tasks.
  2. View the list of tasks.
  3. Mark tasks as completed.
  4. Save tasks to a file so they persist between sessions.

For example:

Menu:

1. Add a task  
2. View tasks  
3. Mark a task as completed  
4. Exit  
  • The application will save and load tasks from a file called tasks.txt.

Why This Challenge Is Important

This task introduces you to:

  • Interactive menus for user interaction.
  • Reading and writing structured data to files.
  • Handling and managing dynamic lists.
  • Developing a program with state that persists beyond runtime.

Steps to Solve

1. Understand the Problem

You need to:

  1. Display a menu for the user.
  2. Let the user add, view, and update tasks.
  3. Save the task list to a file so the user can resume later.
  4. Reload tasks from the file when the program starts.

2. Plan Your Solution

  1. Create a menu for user input.
  2. Use a list or dictionary to store tasks and their status (e.g., completed or not).
  3. Save the list to a file when the program ends.
  4. Load the saved file when the program starts.

Code Examples

Python Example

import os

TASKS_FILE = "tasks.txt"

def load_tasks():
    """Load tasks from the file."""
    if not os.path.exists(TASKS_FILE):
        return []
    with open(TASKS_FILE, "r") as file:
        tasks = [line.strip() for line in file.readlines()]
    return tasks

def save_tasks(tasks):
    """Save tasks to the file."""
    with open(TASKS_FILE, "w") as file:
        file.writelines(f"{task}\n" for task in tasks)

def display_tasks(tasks):
    """Display the list of tasks."""
    if not tasks:
        print("Your to-do list is empty.")
    else:
        for i, task in enumerate(tasks, start=1):
            print(f"{i}. {task}")

def main():
    tasks = load_tasks()
    print("Welcome to the Mini To-Do List!")
    
    while True:
        print("\nMenu:")
        print("1. Add a task")
        print("2. View tasks")
        print("3. Mark a task as completed")
        print("4. Exit")
        choice = input("Enter your choice: ")

        if choice == "1":
            task = input("Enter the task: ")
            tasks.append(task)
            print("Task added!")
        elif choice == "2":
            print("\nYour To-Do List:")
            display_tasks(tasks)
        elif choice == "3":
            print("\nYour To-Do List:")
            display_tasks(tasks)
            task_num = input("Enter the number of the task to mark as completed: ")
            if task_num.isdigit() and 1 <= int(task_num) <= len(tasks):
                task_index = int(task_num) - 1
                tasks[task_index] += " (completed)"
                print("Task marked as completed!")
            else:
                print("Invalid task number!")
        elif choice == "4":
            save_tasks(tasks)
            print("Your tasks have been saved. Goodbye!")
            break
        else:
            print("Invalid choice. Please try again.")

main()

Java Example

import java.io.*;
import java.util.ArrayList;
import java.util.Scanner;

public class ToDoList {
    private static final String TASKS_FILE = "tasks.txt";
    private static ArrayList<String> tasks = new ArrayList<>();

    public static void main(String[] args) {
        loadTasks();
        Scanner scanner = new Scanner(System.in);

        System.out.println("Welcome to the Mini To-Do List!");

        while (true) {
            System.out.println("\nMenu:");
            System.out.println("1. Add a task");
            System.out.println("2. View tasks");
            System.out.println("3. Mark a task as completed");
            System.out.println("4. Exit");
            System.out.print("Enter your choice: ");
            String choice = scanner.nextLine();

            switch (choice) {
                case "1":
                    System.out.print("Enter the task: ");
                    String task = scanner.nextLine();
                    tasks.add(task);
                    System.out.println("Task added!");
                    break;
                case "2":
                    displayTasks();
                    break;
                case "3":
                    displayTasks();
                    System.out.print("Enter the number of the task to mark as completed: ");
                    try {
                        int taskNum = Integer.parseInt(scanner.nextLine());
                        if (taskNum > 0 && taskNum <= tasks.size()) {
                            tasks.set(taskNum - 1, tasks.get(taskNum - 1) + " (completed)");
                            System.out.println("Task marked as completed!");
                        } else {
                            System.out.println("Invalid task number!");
                        }
                    } catch (NumberFormatException e) {
                        System.out.println("Invalid input. Please enter a number.");
                    }
                    break;
                case "4":
                    saveTasks();
                    System.out.println("Your tasks have been saved. Goodbye!");
                    return;
                default:
                    System.out.println("Invalid choice. Please try again.");
            }
        }
    }

    private static void loadTasks() {
        try (BufferedReader reader = new BufferedReader(new FileReader(TASKS_FILE))) {
            String line;
            while ((line = reader.readLine()) != null) {
                tasks.add(line);
            }
        } catch (IOException e) {
            System.out.println("No saved tasks found. Starting fresh.");
        }
    }

    private static void saveTasks() {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(TASKS_FILE))) {
            for (String task : tasks) {
                writer.write(task);
                writer.newLine();
            }
        } catch (IOException e) {
            System.out.println("Error saving tasks.");
        }
    }

    private static void displayTasks() {
        if (tasks.isEmpty()) {
            System.out.println("Your to-do list is empty.");
        } else {
            for (int i = 0; i < tasks.size(); i++) {
                System.out.println((i + 1) + ". " + tasks.get(i));
            }
        }
    }
}

Features to Add for Fun

  1. Deadline Tracking: Let users specify due dates for tasks.
  2. Categories: Group tasks by categories (e.g., work, personal, errands).
  3. Search Functionality: Allow users to search for tasks by keywords.
  4. Remove Tasks: Add a feature to delete unwanted tasks.

What You’ve Learned

  • Managing user interaction through menus.
  • Working with file input/output to persist data.
  • Organizing tasks in lists for dynamic updates.

Next Steps

In Day 30: Final Project – Bringing It All Together, you’ll combine everything you’ve learned to create a more comprehensive and functional application. Stay tuned!