1.2 DRY, KISS, YAGNI תרגול
זיהוי הפרות¶
תרגיל 1 - DRY¶
הקוד הבא יוצר דוחות בשלושה פורמטים. מצאו את הכפילות ותקנו אותה.
def generate_task_report_for_manager(tasks: list) -> str:
report = "דוח משימות\n"
report += "=" * 30 + "\n"
overdue = [t for t in tasks if t["status"] != "done" and t["days_left"] < 0]
report += f"משימות באיחור: {len(overdue)}\n"
for task in overdue:
report += f" - {task['title']}: {abs(task['days_left'])} ימים באיחור\n"
return report
def generate_task_report_for_developer(tasks: list) -> str:
report = "דוח משימות\n"
report += "=" * 30 + "\n"
overdue = [t for t in tasks if t["status"] != "done" and t["days_left"] < 0]
report += f"משימות באיחור: {len(overdue)}\n"
for task in overdue:
report += f" - {task['title']}: {abs(task['days_left'])} ימים באיחור\n"
in_progress = [t for t in tasks if t["status"] == "in_progress"]
report += f"\nמשימות בתהליך: {len(in_progress)}\n"
return report
def generate_task_report_for_client(tasks: list) -> str:
report = "דוח משימות\n"
report += "=" * 30 + "\n"
done = [t for t in tasks if t["status"] == "done"]
report += f"משימות שהושלמו: {len(done)}\n"
overdue = [t for t in tasks if t["status"] != "done" and t["days_left"] < 0]
report += f"משימות באיחור: {len(overdue)}\n"
return report
תרגיל 2 - KISS¶
הקוד הבא מבצע חישוב פשוט אבל בצורה מסובכת מדי. פשטו אותו.
from functools import reduce
from typing import Callable
def calculate_task_completion_rate(tasks: list) -> float:
pipeline: list[Callable] = [
lambda t: filter(lambda x: x.get("status") is not None, t),
lambda t: list(t),
lambda t: (
reduce(lambda acc, x: acc + (1 if x["status"] == "done" else 0), t, 0),
len(t)
)
]
done_count, total = reduce(lambda data, fn: fn(data), pipeline, tasks)
return (done_count / total * 100) if total > 0 else 0.0
תרגיל 3 - YAGNI¶
הלקוח ביקש מערכת פשוטה לניהול תגובות למשימות. הפיתוח מוצג למטה. מה YAGNI כאן?
class CommentSystem:
def __init__(self):
self.comments = []
self.deleted_comments = [] # לסל מחזור עתידי
self.comment_versions = {} # לעריכות היסטוריות
def add_comment(self, task_id: int, user_id: int, content: str):
comment = {
"id": len(self.comments) + 1,
"task_id": task_id,
"user_id": user_id,
"content": content,
"version": 1,
"translations": {}, # לתרגום עתידי
"reactions": {}, # לlike/dislike עתידי
"thread_parent_id": None # לthreaded comments עתידי
}
self.comments.append(comment)
self.comment_versions[comment["id"]] = [comment.copy()]
return comment
def get_comments(self, task_id: int):
return [c for c in self.comments if c["task_id"] == task_id]
def soft_delete(self, comment_id: int):
# TODO: לממש בעתיד
pass
def translate_comment(self, comment_id: int, language: str):
# TODO: לממש בעתיד
pass
def add_reaction(self, comment_id: int, user_id: int, reaction: str):
# TODO: לממש בעתיד
pass
TaskFlow¶
חזרו לקוד הפרויקט. הוסיפו פונקציית וולידציה לכותרות המשימות בהתאם לעקרון DRY, כך שאם הגבול ישתנה יהיה צריך לשנות רק במקום אחד.