This repository marks the transition from single-file scripts to structured, multi-file applications. Each project here is a complete, end-to-end tool that demonstrates the ability to architect and build softwareβa critical skill for any professional developer role.
This project is a robust command-line application for managing a to-do list. It saves tasks to a JSON file, allowing for persistent storage between sessions.
-
Project Architecture: Structuring code into logical, multi-file applications.
-
Object-Oriented Programming (OOP): Using classes to model real-world data (Task).
-
File I/O: Reading from and writing to JSON files for data persistence.
-
Command-Line Interface (CLI): Building professional user-facing tools with argparse.
-
Modularity: Separating application logic from the user interface.
cli-task-manager/
βββ tasks.json # The database file where tasks are stored
βββ task_manager.py # Contains the core logic for managing tasks
βββ main.py # The entry point of the application; handles user commandstask_manager.py
import json
import os
class TaskManager:
"""Manages all the core logic for the to-do list."""
def __init__(self, filename='tasks.json'):
"""Initializes the TaskManager, loading tasks from the file."""
self.filename = filename
self.tasks = self._load_tasks()
def _load_tasks(self):
"""Private method to load tasks from the JSON file."""
if not os.path.exists(self.filename):
return [] # Return an empty list if the file doesn't exist
try:
with open(self.filename, 'r') as f:
return json.load(f)
except json.JSONDecodeError:
return [] # Return empty list if file is empty or corrupted
def _save_tasks(self):
"""Private method to save the current list of tasks to the JSON file."""
with open(self.filename, 'w') as f:
json.dump(self.tasks, f, indent=4)
def add_task(self, description):
"""Adds a new task to the list."""
if not description:
print("Error: Task description cannot be empty.")
return
task = {
'id': len(self.tasks) + 1,
'description': description,
'status': 'pending'
}
self.tasks.append(task)
self._save_tasks()
print(f"β
Added task: '{description}'")
def list_tasks(self):
"""Lists all tasks with their status."""
if not self.tasks:
print("No tasks found. Your to-do list is empty!")
return
print("\n--- To-Do List ---")
for task in self.tasks:
status_icon = "β
" if task['status'] == 'done' else "β»οΈ"
print(f"{status_icon} [{task['id']}] {task['description']}")
print("------------------\n")
def complete_task(self, task_id):
"""Marks a specific task as complete."""
task_found = False
for task in self.tasks:
if task['id'] == task_id:
task['status'] = 'done'
self._save_tasks()
print(f"π Completed task: '{task['description']}'")
task_found = True
break
if not task_found:
print(f"Error: Task with ID {task_id} not found.")main.py
import argparse
from task_manager import TaskManager
def main():
"""Main function to handle command-line arguments and run the application."""
# Setup the argument parser to create a professional CLI
parser = argparse.ArgumentParser(description="A simple command-line task manager.")
# Create a subparsers object to handle different commands (like 'git add', 'git commit')
subparsers = parser.add_subparsers(dest='command', help='Available commands')
# Command: 'add'
add_parser = subparsers.add_parser('add', help='Add a new task to the list.')
add_parser.add_argument('description', type=str, help='The description of the task.')
# Command: 'list'
list_parser = subparsers.add_parser('list', help='List all tasks.')
# Command: 'done'
done_parser = subparsers.add_parser('done', help='Mark a task as complete.')
done_parser.add_argument('id', type=int, help='The ID of the task to complete.')
args = parser.parse_args()
# Initialize the core logic from our other file
manager = TaskManager()
# Execute the correct function based on the user's command
if args.command == 'add':
manager.add_task(args.description)
elif args.command == 'list':
manager.list_tasks()
elif args.command == 'done':
manager.complete_task(args.id)
else:
# If no command is given, print the help message
parser.print_help()
if __name__ == "__main__":
main()
# --- How to Run from Terminal ---
# To add a task: python main.py add "Buy groceries"
# To list all tasks: python main.py list
# To complete a task: python main.py done 1This project introduces web development. Flask is a lightweight and powerful framework for building web applications in Python. This is one of the most in-demand skills in the industry.
-
Web Development: Building a functional web application using the Flask framework.
-
Front-End & Back-End Separation: Understanding the roles of Python (back-end logic) and HTML (front-end presentation).
-
HTML Templating: Using Jinja2 templates to dynamically insert Python data into an HTML page.
-
Handling Web Requests: Creating routes to respond to user requests in a browser.
flask-quote-of-the-day/
βββ app.py # The main Flask application file (back-end logic)
βββ templates/
βββ index.html # The HTML file for the user interface (front-end)app.py
# You must install Flask first: pip install Flask
from flask import Flask, render_template
import random
# Initialize the Flask application
app = Flask(__name__)
# A simple list of quotes to serve as our "database"
quotes = [
"The only way to do great work is to love what you do. - Steve Jobs",
"Innovation distinguishes between a leader and a follower. - Steve Jobs",
"Strive not to be a success, but rather to be of value. - Albert Einstein",
"The future belongs to those who believe in the beauty of their dreams. - Eleanor Roosevelt",
"The best way to predict the future is to invent it. - Alan Kay"
]
# Define the main route for our website (e.g., "[http://127.0.0.1:5000/](http://127.0.0.1:5000/)")
@app.route('/')
def home():
"""This function runs when a user visits the main page."""
# Choose a random quote from our list
random_quote = random.choice(quotes)
# Render the HTML template and pass the quote data to it
return render_template('index.html', quote=random_quote)
# This allows you to run the app directly using "python app.py"
if __name__ == '__main__':
# 'debug=True' makes the server auto-reload when you save changes
app.run(debug=True)templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Quote of the Day</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #f0f2f5;
color: #333;
}
.container {
text-align: center;
padding: 40px;
background-color: white;
border-radius: 12px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
}
h1 {
color: #1a73e8;
margin-bottom: 20px;
}
blockquote {
font-size: 1.5em;
margin: 0;
padding: 20px;
border-left: 5px solid #1a73e8;
background-color: #e8f0fe;
border-radius: 8px;
}
p {
margin-top: 10px;
font-style: italic;
}
</style>
</head>
<body>
<div class="container">
<h1>Quote of the Day</h1>
<blockquote>
<!-- This is the Jinja2 template syntax. The 'quote' variable is passed from our Python app.py -->
<p>"{{ quote.split(' - ')[0] }}"</p>
<footer>β {{ quote.split(' - ')[1] }}</footer>
</blockquote>
</div>
</body>
</html>-
Architecting Applications: How to structure code into logical, maintainable, multi-file projects.
-
Building End-to-End Tools: Creating complete applications from the command line to the web browser.
-
Using Core Libraries: Gaining experience with essential libraries like argparse for CLIs and Flask for web development.
-
Data Persistence: Understanding how to save and load application data using standard formats like JSON.
Feel free to fork these project ideas, expand on them (e.g., add a 'delete task' feature), and submit a pull request.
If you found this progression helpful, please star β the repositories to support more projects like this.