מערך שיעור: Clean Code ו-Debugging
משך: יום לימוד מלא — 6 שעות אקדמיות (270 דקות).
מטרת השיעור: להעביר את הסטודנטים מ"קוד שעובד" ל"קוד שקל להבין, לשנות ולדבג", ולתת להם שיטה וכלים למציאת באגים במקום ניחוש.
בסוף השיעור הסטודנטים צריכים:
- לשפץ קוד לא נקי לפי Naming, SRP, DRY, KISS והפרדת אחריות, בלי לשנות את ההתנהגות.
- לקרוא Traceback מלמטה למעלה ולזהות סוג שגיאה, מיקום וסיבה סבירה.
- למצוא Logical Error בעזרת Breakpoints, Step Over/Into וחלון Variables, לפי חמשת שלבי הדיבאג.
דגש קריטי: הדגמת Debugging חיה. לא להסתפק בהסבר על הכפתורים: לפתור באג אמיתי מול הכיתה, בקול רם, כולל טעויות. זה הרגע שבו הסטודנטים מבינים שדיבאג הוא שיטה ולא כישרון.
מהלך השיעור
| חלק בשיעור | משך | הערות ודגשים |
|---|---|---|
| פתיחה + אבחון רמה | 10 דק' | 3 שאלות מהירות לפי הפערים שעלו במבחן ה-Python הבסיסי. |
| Clean Code א’: שמות, פונקציות קטנות, SRP | 35 דק' | להציג “לפני” ולשאול “מה הקוד עושה?”. למדוד כמה זמן לוקח להבין לעומת גרסת ה"אחרי". |
| הפסקה | 15 דק' | |
| Clean Code ב’: DRY, KISS, SoC, הערות, Refactoring | 40 דק' | Refactoring של הקבלה בצעדים, עם הרצה אחרי כל צעד. |
| Debugging א’: סוגי שגיאות + Traceback | 30 דק' | “בלש שגיאות” על הלוח. להדגים שאותה פונקציה יכולה ליפול בכל אחד משלושת הסוגים. |
| הפסקה | 15 דק' | |
| Debugging ב’: תהליך + Debugger + באג חי | 45 דק' | debug_intro.py להכרת הכלי, ואז drop_lowest.py מקצה לקצה. |
| תרגול + בדוק את עצמך | 30 דק' | תרגיל 4 (שני באגים) בזוגות: אחד “נהג” על המקלדת, השני “נווט”. |
דגשים להעברת השיעור
- Clean Code אינו טעם אישי. לחזור על הנימוק: “קוד נקרא פי 10 יותר משנכתב”. לא לומר “ככה יפה”, אלא “ככה זה יותר קל לשנות, הנה ההוכחה”.
- להראות את מחיר ה-Copy-Paste: לשנות דרישה (למשל הודעת OK ל-✓) בקוד הכפול מול הקוד ה-DRY, ולספור שינויים.
- לא להגזים בפירוק. להראות גם דוגמה של פירוק מוגזם, כדי שהסטודנטים לא יפרקו כל שורה לפונקציה.
- ה-Debugger: לוודא לפני השיעור שההרחבה Python מותקנת אצל כולם ו-
F5עובד. מי שלא מצליח: Run → Start Debugging. - לחשוב בקול בזמן הדיבאג: “אני מצפה ש-lowest יהיה 70. הוא 0. אז הבעיה לפני השורה הזו”. זו המיומנות שמלמדים.
- שלב Verify הוא המקום לחשוף את מקרה הקצה (
[70]→ ZeroDivisionError), וזה מכין את Exceptions של מחר.
מושגים
| מושג | הסבר קצר |
|---|---|
| Clean Code | קוד שקל לקרוא, להבין ולשנות. |
| PEP 8 / snake_case | מדריך הסגנון של Python / מוסכמת שמות במילים קטנות עם קו תחתון. |
| Magic Number | מספר בקוד בלי שם שמסביר אותו. |
| Single Responsibility | לכל פונקציה תפקיד אחד וסיבה אחת להשתנות. |
| DRY | כל ידע מופיע במקום אחד. |
| KISS | הפתרון הפשוט עדיף. |
| Separation of Concerns | הפרדה בין קלט, לוגיקה ופלט. |
| Docstring | תיאור פונקציה בשלוש מירכאות, מתחת ל-def. |
| Refactoring | שינוי מבנה בלי שינוי התנהגות. |
| Early Return | יציאה מוקדמת מפונקציה כשתנאי לא מתקיים. |
| Bug | פער בין התנהגות רצויה להתנהגות בפועל. |
| Syntax / Runtime / Logical Error | שגיאת תחביר / שגיאה בזמן ריצה / תוצאה שגויה בלי הודעה. |
| Traceback / Stack Trace | מסלול הקריאות עד השגיאה. קוראים מלמטה למעלה. |
| Breakpoint | נקודת עצירה לפני ביצוע שורה. |
| Step Over / Into / Out | בצע שורה / היכנס לפונקציה / צא מהפונקציה. |
| Call Stack | שרשרת הקריאות הנוכחית. |
תרגיל חשיבה
שאלת פתיחה (לפני חלק ה-Debugging): “יש לי פונקציה שמחזירה ממוצע מעל 100 עבור ציונים בין 0 ל-100. אין שום הודעת שגיאה. איך הייתם מחפשים את הבאג?”
מהלך:
- לאסוף שיטות מהכיתה. תשובות צפויות: “לקרוא את הקוד”, “להוסיף print”, “לשנות דברים עד שיעבוד”.
- לשאול על כל שיטה: “איך תדעו שתיקנתם? ואם יש 500 שורות?”
- להציג את חמשת השלבים כ"פרוטוקול רופא".
- להריץ את
drop_lowest.pyולבצע מול הכיתה את כל השלבים. בשלב Isolate, לבקש מהכיתה להחליט איפה לשים את ה-Breakpoint הראשון.
מה המרצה מראה בסוף: טבלת המעקב (סיבוב / grade / תנאי / lowest) שנבנתה מהחלון Variables, ומתחתיה המשפט: “הבאג לא היה בשורה שנתנה את התוצאה השגויה, אלא בהנחה שלנו שאפס הוא ערך התחלתי טוב.” ומיד אחר כך, שלב Verify עם [70] שחושף באג נוסף: “בדיקה טובה מוצאת את הבאג הבא לפני המשתמש.”