Skip to content

Commit 5847c76

Browse files
committed
Todo_App
1 parent ea5467d commit 5847c76

9 files changed

Lines changed: 252 additions & 1 deletion

File tree

advanced/dependency_injection.py

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,46 @@
1-
1+
# dependency_injection.py
2+
3+
class Logger:
4+
"""A simple Logger class to log messages."""
5+
6+
def log(self, message):
7+
print(f"[LOG]: {message}")
8+
9+
10+
class FileLogger(Logger):
11+
"""A logger that writes logs to a file."""
12+
13+
def __init__(self, filename="app.log"):
14+
self.filename = filename
15+
16+
def log(self, message):
17+
with open(self.filename, "a") as file:
18+
file.write(f"[LOG]: {message}\n")
19+
print(f"Logged to file: {message}")
20+
21+
22+
class Application:
23+
"""Application class demonstrating dependency injection."""
24+
25+
def __init__(self, logger: Logger):
26+
"""Inject a logger dependency via the constructor."""
27+
self.logger = logger
28+
29+
def run(self):
30+
"""Simulate running the application."""
31+
self.logger.log("Application has started.")
32+
self.logger.log("Performing some tasks...")
33+
self.logger.log("Application is shutting down.")
34+
35+
36+
# Example Usage
37+
if __name__ == "__main__":
38+
console_logger = Logger() # Injecting a Console Logger
39+
app1 = Application(console_logger)
40+
app1.run()
41+
42+
print("\nSwitching to FileLogger...\n")
43+
44+
file_logger = FileLogger() # Injecting a File Logger
45+
app2 = Application(file_logger)
46+
app2.run()

projects/todo_app/README.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# 📝 To-Do List App (OOP in Python)
2+
3+
This is a simple Object-Oriented **To-Do List App** in Python with **CRUD operations** and **persistent storage**.
4+
5+
## 🚀 Features
6+
✅ Object-Oriented Design (Encapsulation, Abstraction)
7+
✅ CRUD Operations (Add, Remove, Toggle, List Tasks)
8+
✅ Persistent Storage (JSON-based)
9+
✅ User-Friendly CLI
10+
11+
## 📂 Folder Structure
12+
todo_app/
13+
│── main.py # Entry point for the app
14+
│── models.py # Task class and related models
15+
│── todo_manager.py # Business logic for managing tasks
16+
│── cli.py # Command-line interface for the app
17+
│── storage.py # Handles data persistence (JSON-based storage)
18+
│── requirements.txt # List of dependencies (if needed)
19+
│── README.md # Documentation for the to-do app
20+
21+
22+
## 📌 How to Run?
23+
1️⃣ **Navigate to the folder**
24+
```sh
25+
cd projects/todo_app/
26+
27+
2️⃣ Run the CLI app
28+
29+
```
30+
python main.py
31+
```
32+
33+
## 🛠 Future Improvements
34+
35+
🔹 SQLite or PostgreSQL Storage
36+
🔹 GUI (Tkinter/PyQt)
37+
🔹 Web App (Flask/FastAPI)

projects/todo_app/cli.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# cli.py
2+
3+
from todo_manager import TodoManager
4+
5+
def main():
6+
manager = TodoManager()
7+
8+
while True:
9+
print("\n📌 To-Do List Manager")
10+
print("1. Add Task")
11+
print("2. List Tasks")
12+
print("3. Toggle Task Completion")
13+
print("4. Remove Task")
14+
print("5. Exit")
15+
16+
choice = input("Enter your choice: ")
17+
18+
if choice == "1":
19+
title = input("Enter task title: ")
20+
description = input("Enter task description: ")
21+
task = manager.add_task(title, description)
22+
print(f"✅ Task '{task.title}' added.")
23+
24+
elif choice == "2":
25+
tasks = manager.list_tasks()
26+
if not tasks:
27+
print("No tasks found.")
28+
for task in tasks:
29+
print(task)
30+
31+
elif choice == "3":
32+
task_id = input("Enter Task ID to toggle: ")
33+
task = manager.toggle_task(task_id)
34+
if task:
35+
print(f"🔄 Task '{task.title}' updated.")
36+
else:
37+
print("⚠️ Task not found.")
38+
39+
elif choice == "4":
40+
task_id = input("Enter Task ID to remove: ")
41+
manager.remove_task(task_id)
42+
print("🗑️ Task removed.")
43+
44+
elif choice == "5":
45+
print("👋 Goodbye!")
46+
break
47+
48+
else:
49+
print("⚠️ Invalid choice, try again.")
50+
51+
if __name__ == "__main__":
52+
main()

projects/todo_app/main.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# main.py
2+
3+
from cli import main
4+
5+
if __name__ == "__main__":
6+
main()

projects/todo_app/models.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# models.py
2+
3+
import uuid
4+
from datetime import datetime
5+
6+
class Task:
7+
"""Represents a single task in the to-do list."""
8+
9+
def __init__(self, title, description="", completed=False):
10+
self.id = str(uuid.uuid4()) # Unique identifier for each task
11+
self.title = title
12+
self.description = description
13+
self.completed = completed
14+
self.created_at = datetime.now()
15+
16+
def mark_complete(self):
17+
"""Mark the task as completed."""
18+
self.completed = True
19+
20+
def mark_incomplete(self):
21+
"""Mark the task as incomplete."""
22+
self.completed = False
23+
24+
def __str__(self):
25+
"""String representation of a task."""
26+
status = "✅" if self.completed else "❌"
27+
return f"[{status}] {self.title} - {self.description} (Created: {self.created_at.strftime('%Y-%m-%d %H:%M')})"

projects/todo_app/requirements.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# requirements.txt
2+
3+
# No external dependencies needed, but add if required

projects/todo_app/storage.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# storage.py
2+
3+
import json
4+
import os
5+
from models import Task
6+
7+
class Storage:
8+
"""Handles saving and loading tasks from a JSON file."""
9+
10+
def __init__(self, filename="tasks.json"):
11+
self.filename = filename
12+
13+
def save_tasks(self, tasks):
14+
"""Save tasks to a JSON file."""
15+
with open(self.filename, "w") as f:
16+
json.dump([task.__dict__ for task in tasks], f, indent=4)
17+
18+
def load_tasks(self):
19+
"""Load tasks from a JSON file."""
20+
if not os.path.exists(self.filename):
21+
return []
22+
with open(self.filename, "r") as f:
23+
data = json.load(f)
24+
return [Task(**task) for task in data]

projects/todo_app/todo_manager.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# todo_manager.py
2+
3+
import json
4+
import os
5+
from models import Task
6+
7+
class TodoManager:
8+
"""Manages the to-do list tasks (CRUD operations)."""
9+
10+
def __init__(self, storage_file="tasks.json"):
11+
self.storage_file = storage_file
12+
self.tasks = self.load_tasks()
13+
14+
def add_task(self, title, description=""):
15+
"""Add a new task."""
16+
task = Task(title, description)
17+
self.tasks.append(task)
18+
self.save_tasks()
19+
return task
20+
21+
def remove_task(self, task_id):
22+
"""Remove a task by ID."""
23+
self.tasks = [task for task in self.tasks if task.id != task_id]
24+
self.save_tasks()
25+
26+
def list_tasks(self):
27+
"""List all tasks."""
28+
return self.tasks
29+
30+
def toggle_task(self, task_id):
31+
"""Toggle task completion status."""
32+
for task in self.tasks:
33+
if task.id == task_id:
34+
task.mark_complete() if not task.completed else task.mark_incomplete()
35+
self.save_tasks()
36+
return task
37+
return None
38+
39+
def save_tasks(self):
40+
"""Save tasks to a JSON file."""
41+
with open(self.storage_file, "w") as f:
42+
json.dump([task.__dict__ for task in self.tasks], f, indent=4)
43+
44+
def load_tasks(self):
45+
"""Load tasks from a JSON file."""
46+
if not os.path.exists(self.storage_file):
47+
return []
48+
with open(self.storage_file, "r") as f:
49+
data = json.load(f)
50+
return [Task(**task) for task in data]

tasks.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[
2+
{
3+
"id": "103cc036-b83a-4960-b824-ac9c57e775be",
4+
"title": "Book Reading",
5+
"description": "I would read 5 pages daily.",
6+
"completed": false,
7+
"created_at":

0 commit comments

Comments
 (0)