לדלג לתוכן

1.2 DRY, KISS, YAGNI פתרון

תרגיל 1 - DRY - פתרון

הכפילות נמצאת בשלושה מקומות: כותרת הדוח, הפסיק, ובניית רשימת המשימות באיחור.

def _get_overdue_tasks(tasks: list) -> list:
    return [t for t in tasks if t["status"] != "done" and t["days_left"] < 0]


def _format_overdue_section(overdue: list) -> str:
    lines = [f"משימות באיחור: {len(overdue)}"]
    for task in overdue:
        lines.append(f"  - {task['title']}: {abs(task['days_left'])} ימים באיחור")
    return "\n".join(lines)


def _report_header() -> str:
    return "דוח משימות\n" + "=" * 30


def generate_task_report_for_manager(tasks: list) -> str:
    overdue = _get_overdue_tasks(tasks)
    return "\n".join([
        _report_header(),
        _format_overdue_section(overdue)
    ])


def generate_task_report_for_developer(tasks: list) -> str:
    overdue = _get_overdue_tasks(tasks)
    in_progress = [t for t in tasks if t["status"] == "in_progress"]
    return "\n".join([
        _report_header(),
        _format_overdue_section(overdue),
        f"\nמשימות בתהליך: {len(in_progress)}"
    ])


def generate_task_report_for_client(tasks: list) -> str:
    done = [t for t in tasks if t["status"] == "done"]
    overdue = _get_overdue_tasks(tasks)
    return "\n".join([
        _report_header(),
        f"משימות שהושלמו: {len(done)}",
        _format_overdue_section(overdue)
    ])

תרגיל 2 - KISS - פתרון

def calculate_task_completion_rate(tasks: list) -> float:
    if not tasks:
        return 0.0
    done_count = sum(1 for t in tasks if t.get("status") == "done")
    return done_count / len(tasks) * 100

שלושה שורות במקום שמונה-עשרה. קריא, ישיר, ועושה בדיוק אותו דבר.


תרגיל 3 - YAGNI - פתרון

הדברים שמפרים YAGNI:

  1. deleted_comments - סל מחזור שלא ביקשו
  2. comment_versions - היסטוריית עריכות שלא ביקשו
  3. שדה version בתגובה - לא נדרש
  4. שדה translations - תרגום שלא ביקשו
  5. שדה reactions - תגובות שלא ביקשו
  6. שדה thread_parent_id - threads שלא ביקשו
  7. soft_delete, translate_comment, add_reaction - מתודות עם TODO ריק

הקוד הנכון:

class CommentSystem:
    def __init__(self):
        self.comments = []

    def add_comment(self, task_id: int, user_id: int, content: str) -> dict:
        comment = {
            "id": len(self.comments) + 1,
            "task_id": task_id,
            "user_id": user_id,
            "content": content
        }
        self.comments.append(comment)
        return comment

    def get_comments(self, task_id: int) -> list:
        return [c for c in self.comments if c["task_id"] == task_id]

כשיבקשו עוד פיצ'רים - נוסיף אותם. לא לפני.


TaskFlow - פתרון

def validate_task_title(title: str):
    if not title or not title.strip():
        raise ValueError("כותרת המשימה לא יכולה להיות ריקה")
    if len(title) < 3:
        raise ValueError("כותרת המשימה חייבת להכיל לפחות 3 תווים")
    if len(title) > 200:
        raise ValueError("כותרת המשימה לא יכולה לעלות על 200 תווים")


@app.post("/tasks")
def create_task(title: str, description: str, user_id: int):
    validate_task_title(title)
    db = get_db()
    db.execute("INSERT INTO tasks VALUES (?, ?, ?)", (title, description, user_id))
    db.commit()
    return {"message": "משימה נוצרה"}


@app.put("/tasks/{task_id}")
def update_task(task_id: int, title: str, description: str):
    validate_task_title(title)
    db = get_db()
    db.execute(
        "UPDATE tasks SET title=?, description=? WHERE id=?",
        (title, description, task_id)
    )
    db.commit()
    return {"message": "משימה עודכנה"}