לדלג לתוכן

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, כך שאם הגבול ישתנה יהיה צריך לשנות רק במקום אחד.