# SOLID principles
## 1. Single Responsibility Principle (SRP)
### Definition
This principle is certainly the simplest to understand.
A function should do only one thing and have only one reason to change.
Each function should be organized to perform a single well-defined task.
### Example
Imagine we need to process user data from a csv file and save active users to a database.
```python
# DON'T
import csv
import sqlite3
def process_users(csv_file: str, db_file: str):
"""Reads users from a CSV file, filters active ones, and saves them to a database."""
conn = sqlite3.connect(db_file)
cursor = conn.cursor()
with open(csv_file, newline="") as file:
reader = csv.DictReader(file)
users = [row for row in reader]
active_users = [user for user in users if user["active"] == "1"]
for user in active_users:
cursor.execute("INSERT INTO users VALUES (?, ?, ?)", (user["id"], user["name"], user["active"]))
conn.commit()
conn.close()
```
```python
# DO
import csv
import sqlite3
from typing import List, Dict
def read_users_from_csv(csv_file: str) -> List[Dict[str, str]]:
"""Reads users from a CSV file and returns a list of dictionaries."""
with open(csv_file, newline="") as file:
return list(csv.DictReader(file))
def filter_active_users(users: List[Dict[str, str]]) -> List[Dict[str, str]]:
"""Filters and returns only active users."""
return [user for user in users if user["active"] == "1"]
def save_users_to_db(db_file: str, users: List[Dict[str, str]]):
"""Saves users to an SQLite database."""
conn = sqlite3.connect(db_file)
cursor = conn.cursor()
for user in users:
cursor.execute("INSERT INTO users VALUES (?, ?, ?)", (user["id"], user["name"], user["active"]))
conn.commit()
conn.close()
def process_users(csv_file: str, db_file: str):
"""Orchestrates the user processing pipeline."""
users = read_users_from_csv(csv_file)
active_users = filter_active_users(users)
save_users_to_db(db_file, active_users)
```
### Summary
Avoid function doing too much stuff, split responsibilities into focused functions.
Each function could be tested separately.
Easier to maintain: if we change a you change a behavior in the code, you change only one function, not the entire pipeline.
The SRP-compliant approach ensure s better maintainability, testability and keep the code easy to understand.
## 2. Open/Closed Principle (OCP)
---
Bibliography:
- [Title - website.com](need bibliography)