ניתוח שגיאות שכיחות של מתכנתים מתחילים

ג. ספורר ו- א. סולווי

J.G. Spohrer and E. Soloway (1986). Analyzing the high frequency bugs, In Empirical Studies of Programmers, E., Soloway, Y., Iyengar (ed.), Albex Publishing Corporation, Norwood, New Jersy, 230-251.

התקציר המצורף נערך ע"י ד"ר ברוריה הברמן

בתוך הברמן, ב., לוי, ד., לפידות, ת. (עורכות). סקר ספרות "קשיי למידה למתחילים בהוראת מדעי המחשב והוראת רקורסיה".

הוצאת "מחשבה" – מרכז המורים הארצי למדעי המחשב, 2001. עמודים 13-17

אודות המאמר

המאמר מתאר מחקר העוסק בניתוח שגיאות של מתכנתים מתחילים. המחברים מאששים את הטענה הרווחת כי קיים מספר מצומצם של שגיאות אופייניות המופיעות בשכיחות גבוהה אצל רוב המתחילים הלומדים תכנות. לעומת זאת, הם מפריכים טענה רווחת אחרת כי מרבית השגיאות נעוצות בהכרח בתפיסות מוטעות אודות משמעות של מבנים בשפת מחשב. המאמר דן בהשלכות הממצאים על הוראת תכנות.

 

רשימת מושגים

w בעיית המפרש האנושי – Human Interpreter Problem

w בעיית חוסר עקביות של טיפוסי נתונים – Data-Type Inconsistency Problem        

w בעיית סדר מקרי – Coincidental Ordering Problem

w בעיית ערך קצה –  Boundary Problem

w בעיית שפה טבעית –  Natural Language Problem

w בעיית תלות בין תת-משימות – Plan-Dependency Problem  

w מבנה בשפה – Language construct

w תבניות – Plans and goals

 

המחקר

מטרת המחקר הייתה לאשר או להפריך את הטענות הבאות, הרווחות לגבי שגיאות של תלמידים המתחילים ללמוד תכנות:

             ·   קיים מספר מצומצם של שגיאות אופייניות שכיחות אצל תלמידים מתחילים.

             ·   רוב השגיאות נובעות מתפיסות מוטעות שיש לתלמידים לגבי מבנה כלשהו בשפה.

מטרה נוספת הייתה לנסות להסביר מדוע שגיאות מסוימות מתרחשות.

השיטה

החוקרים פתחו שיטה לאיתור שגיאות שכיחות של מתחילים, הבוחנת האם קושי מסוים נובע מחוסר מיומנויות של פתרון בעיות, או בגלל שליטה בלתי מספיקה בשפת התכנות. במחקר השתתפו סטודנטים שלמדו באוניברסיטה קורס  "מבוא לתכנות בסביבת "Pascal, המיועד למסלול הומניסטי. התלמידים נתבקשו במהלך הקורס לכתוב תכניות מחשב לפתרון בעיות נתונות. נבדקו כ- 50 תכניות שנכתבו כפתרון לכל אחת משלוש בעיות שנבחרו על ידי החוקרים לצורך המחקר. הבעיה הראשונה הייתה משימה ברמה התחלתית בה התלמידים היו צריכים להשתמש לראשונה בתנאי מקונן. לפתרון השאלה השנייה היה עליהם להשתמש לראשונה בלולאה, ובבעיה השלישית – להשתמש לראשונה בפרוצדורות. בנוסף, בכל שאלה היה עליהם להשתמש באופן חדש במבנים קודמים המוכרים להם.

איסוף הנתונים נערך באמצעות הקלטת הגרסה הראשונה של תכנית נטולת שגיאות תחביריות שעברה קומפילציה. הנחת החוקרים הייתה, שכל עוד יש בתכנית שגיאות תחביריות, התלמיד עסוק בתיקון שגיאות אלו, ורק כשהתכנית נכונה תחבירית, מתחילה בדיקת ביצוע התכנית במונחי התנהגות קלט/פלט (האם התכנית נכונה לוגית). הם רצו לנתח גרסה ראשונית של תכנית שעברו קומפילציה, לפני שנערכו בהן שינויים עקב בדיקות לוגיות.

המחברים מסתמכים על מחקרים קודמים אשר תומכים בהשערה כי הידע בו משתמשים מתכנתים לפיתוח ולניתוח תכניות בנוי מאוסף תבניות. כל תבנית מורכבת ממטרה (goal) ומקוד-תכנית/אלגוריתם (plan) המשמש להשגת המטרה. המטרה מתארת את "מה צריך לבצע" כדי לפתור את הבעיה , ואילו קוד-תכנית/אלגוריתם מתאר "כיצד" תושג המטרה.

בהתאם, במחקר המתואר במאמר זה, ניתוח התכניות וזיהוי השגיאות נעשה על ידי שימוש בתבניות (plans and goals). השגיאות מתוארות במונחים של הבדלים בין תבנית המקובלת כנכונה להשגת המטרה, לבין תכנית נבדקת, שנכתבה להשגת אותה מטרה. תכניות שגויות הן אלו שלא תשגנה את המטרה.  

המחברים מבחינים בין טיפוסי שגיאות (bug types) ומופעי שגיאות (bug tokens). טיפוס שגיאות הוא שם כולל לקבוצת מופעי שגיאות הזהים במהותם.

במחקר התגלה שלא כל השגיאות נוצרות באופן שווה. קיימות שגיאות המופיעות שוב ושוב אצל מתחילים, בעוד שאחרות מופיעות לעתים רחוקות בלבד. ובמילים אחרות, יש טיפוסי שגיאות בעלי מספר מופעי שגיאות גדול במיוחד, בעוד שקיימים טיפוסי שגיאות שמספר מופעיהן קטן, ואפילו זניח.

מקור השגיאות (הסברים מתקבלים על הדעת)

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

בגלל הדגש על לימוד מבני השפה, יכול להיראות על פניו ששגיאות התלמידים נובעות מאי הבנת משמעות של מבנים מסוימים. סברה נוספת רווחת היא ששגיאות מתרחשות בשכיחות גבוהה במצבים חדשים, או כשנעשה שימוש במבנה או במשפט חדש בשפה.

מחברי המאמר טוענים שלמעשה אין בספרות המחקרית תמיכה ממשית להשערות אלו, כיוון שהמחקרים התומכים כביכול בהשערות אלו, נערכו במועדים קצרי טווח של הוראה, ולא במסגרת "טבעית" וממושכת במהלך של לימוד קורס מתחילתו ועד סופו. לעומת מחקרים אלו, המחקר המתואר במאמר זה נערך לאורך סמסטר שלם, במסגרת כמעט טבעית.

על מנת לבדוק את תקפות ההשערה הרווחת, נערך ניתוח יסודי של תכניות שפותחו על ידי תלמידים עבור שלושת הבעיות, וזוהו 11 טיפוסי שגיאות שכיחות. אחת בלבד אובחנה באופן ודאי כנובעת מאי הבנה של משמעות מבנה בשפה, ועוד שלוש שגיאות יתכן שנובעות מכך. לגבי שבע שגיאות אחרות לא נמצאו תימוכין להשערה, וניתנו הסברים אחרים.

הבעיות עליהן מעידות השגיאות שזוהו מפורטות להלן.

בעיות הקשורות לתפיסת המשמעות של מבנים/משפטים בשפת תכנות

(1) בעיית חוסר עקביות של טיפוסי נתונים (Data-Type Inconsistency Problem):

כאשר משמעות משפט בשפה תלויה בטיפוסי נתונים של משתנים המופיעים בו, עלולות להתעורר בעיות. לדוגמא, השימוש במשפט קלט readln שונה כאשר יש לקלוט סדרת מספרים, סדרת תווים, או סדרה משולבת של מספרים או תווים.

למשל, בהינתן סדרת קלט המכילה שילוב של מספרים ותווים המופרדים ביניהם בתווי רווח (spaces),

הרי שעבור דוגמת קלט: 23 a 10 45  +  משפט קלט נכון מתייחס לתו רווח המפריד בין מספר לתו:

readln(Id, Whitespace1, Prob_type, Num1, Num2, Whitespace2, Sign)            

בעוד שמשפט קלט שגוי מתעלם מתווי הרווח:      readln(Id, Prob_type, Num1, Num2, Sign)   

שגיאה זו מעידה על תפיסה מוטעית של משמעות משפט קלט המתייחס לקליטת תווים משולבת בסדרת נתונים מטיפוס אחר.      

(2) בעיית שפה טבעית (Natural Language Problem):

במקרים בהם משפטי השפה כוללים מילים שמורות הלקוחות מהשפה הטבעית, התלמידים עלולים להבין לא נכון את משמעותם. 

(3) בעיית המפרש האנושי (Human Interpreter Problem):

יש מקרים בהם תלמידים מצפים שמשפט שהם כתבו יתפרש בדרך מסוימת, ויתבצע בהתאם. הם מניחים שהמחשב יפרש את המשפט באופן זהה להם. למעשה הם משייכים למבנים/משפטים בשפה את המשמעות הרצויה בעיניהם.

בעיות שאינן קשורות לתפיסת המשמעות של מבנים/משפטים בשפת תכנות

(1) בעיית ערך קצה (Boundary Problem)

תלמידים אינם כוללים ערכים מסוימים בתחום הערכים החוקיים לייצוג נתונים, כדוגמת המספר אפס. שגיאה מסוג זה נקראת off-by-one bug. השגיאה באה לידי ביטוי בניסוח תנאי באמצעות אופרטור יחס (כגון <, =, <=). ההסבר שהשגיאה נובעת מאי הבנת אופן השימוש באופרטור אינו מתקבל על הדעת כאשר באותה תכנית נעשה בו שימוש נכון. במקרה זה, יש לשייך את השגיאה לגורם אחר, מהותי יותר.

מסתבר שלתלמידים יש קושי לזהות גבולות של תחום ערכים אותם יכול משתנה לקבל. קשה להם להבחין בין ערכים אפשריים, ערכים טריוויאליים, וערכים בלתי מתקבלים על הדעת. כמו כן קשה להם לקבוע האם הטיפול בערך קצה צריך להתבצע בנפרד, או בתחום/י הערכים עבורם הוא משמש כערך קצה.

תלמידים מבצעים לעתים  הקבלה בין קבועים שונים בתכנית המשמשים לזיהוי ערכי קצה, גם אם הדבר אינו נכון בהקשר הבעיה. למשל, התייחסות אחידה לשני קבועים למרות שאחד מהם שייך לתחום הערכים המותרים, ואילו השני מהווה גבול, אך אינו שייך לתחום.

(2) בעיית תלות בין תת-משימות (Plan-Dependency Problem):

תלמידים מתקשים בזיהוי תלויות בין תת-משימות, ובהתאם אינם מממשים קשרים אלו. לדוגמא, תלות בין משימת פלט למשימת חישוב המחשבת את הערך האמור להיות מוצג כפלט. יש בעיות בהן מחושב ומוצג כפלט רק ערך המחושב בהתקיים תנאי מסוים. במקרה והתנאי אינו מתקיים, החישוב אינו מתבצע, ובהתאם אין מה להציג כפלט. במילים אחרות, תת המשימה של פלט תוצאת החישוב תלויה בתת המשימה של חישוב ערך התוצאה. שגיאה אופיינית מתבטאת בכך שלמרות שקטע הקוד העוסק בחישוב ערך התוצאה נוסח כהלכה תוך שימוש במבנה בקרה מתאים, ערך המשתנה המייצג את תוצאת החישוב מודפס בכל מקרה, בין אם חושב, ובין אם לא חושב בגלל אי-קיום התנאי.

מקור אפשרי לשגיאה הוא אי הבנת משמעות מבנה הבקרה if-then-else (כל המשפטים המופיעים לאחר ה- else, שייכים לבלוק המשויך ל- else ומתבצעים בהתאם). אולם זה אינו ההסבר היחיד המתקבל על הדעת. לעתים מספיק להתבונן בקוד כדי להבחין שזה אינו גורם השגיאה. אופן ארגון הקוד מעיד על ראיית התלמיד את סדר ביצועו. למשל, שימוש בהזחה או תיחום קטעי קוד ב- begin-end.  כאשר תלמיד מארגן את הקוד באופן נכון, אפשר להניח שהשגיאה אינה נובעת מאי הבנת משמעות המבנה. דוגמה לכך ניתן לראות בקטעי הקוד הבאים:

קטע קוד נכון

    קלוט נתון

    אם הנתון מקיים תנאי אזי

בצע חישוב

              הצג את תוצאת החישוב

קטע קוד שגוי

    קלוט נתון

    אם הנתון מקיים תנאי אזי

בצע חישוב

    הצג את תוצאת החישוב

 

הסבר אפשרי לשגיאה שאינו קשור לאי הבנת משמעות מבנים בשפת התכנות הוא: תפיסה מוטעית של "קיטוע פלט" (output fragmentation) - הפלט חייב תמיד להתבצע, ללא תלות בחוקיות הפלט. מעבר לזה, יש לתלמידים תפיסה מוטעית אחרת: תבנית של ארגון הקוד - "הפלט תמיד צריך להיות בסוף". תלמידים אלו כותבים את קטע הקוד המטפל בפלט בסוף התכנית. הנה לדוגמה ציטוט מדברי תלמיד: "תחילה אני צריך לקבל את הקלט, אחר כך אני בודק אם הוא אינו חוקי אני מדפיס הודעה, אחרת אני מבצע את החישוב. בסוף, אחרי שהחישוב התבצע, הפלט מתבצע".

 (3) בעיית שלילה ושלמות (Negation and Whole-Part Problem):

תלמידים מתחילים סבורים ששלילת דבר טוב בשלמותו, יוצרת דבר רע בשלמותו, ולהפך.  בבדיקת תנאי תלמידים משתמשים בקשר OR במקום בקשר AND. לדוגמה, ניסוח שגוי של תנאי לבדיקה האם ערך משתנה X שונה מהמספרים 1,2,3 :      

                If ( (X<>1) OR (X<>2) OR (X<>3) ) then...

הסבר אפשרי לשגיאה זו: תלמידים סבורים שכדי לנסח תנאי מורכב, באמצעות מרכיבים שכל אחד מהם מייצג דבר טוב בשלמותו, או דבר רע בשלמותו, יש לחבר את המרכיבים באמצעות OR. בדוגמה זו, תלמידים ניסו להשתמש בשלילה כדי להגדיר דבר טוב בשלמותו על ידי שלילת דבר רע בחלקו: לשלול שוויון של X לערכים האסורים 1,2,3 על ידי שימוש ב- ‘<>’. למשל, שלילת הביטוי X=1  על ידי:  X<>1 . אולם כאשר ערך הביטוי X<>1 הוא אמת, אין זה מעיד על דבר טוב בשלמותו, שכן X יכול להיות שווה ל- 2, או ל- 3.

(4) בעיית ציפיות ופרשנות (Expectations and Interpretation Problem):

תלמידים עלולים להשתמש בנוסחאות לא נכונות לחישוב ערכים, שאינן בהתאם למוגדר בבעיה, כי יש להם ציפייה שונה, או פרשנות שונה לגבי האופן בו הערך אמור להיות מחושב (שגיאה זו אינה מהותית, אך בעלת שכיחות גבוהה לפי המחבר, ב.ה.).

(5) בעיית כפילות ספרה בסוף מספר (Duplicate Tail-Digit Problem):

תלמידים המשתמשים בקבועים מספריים בעלי הופעה של ספרות זהות בסוף המספר, משמיטים לעתים את הספרה "המיותרת" בסוף המספר. הגורם לכך יכול להיות טעות בחישוב ערכו של הקבוע, או בהקלדה שגויה.

(6) בעיית השפעת ידע דומה (Related Knowledge Inference Problem):

תלמידים מושפעים לעתים מאנלוגיה. למשל, מספר השניות בשעה הוא 3600, אך מספר המעלות במעגל הוא 360, והתלמיד בבואו לחשב את מספר השניות חושב על שעון, מבצע את ההשלכה הלא נכונה וכופל את מספר השעות ב- 360. אולם אין ספק שהגורם לשגיאה זו אינו אי הבנת משמעות של מבנה בשפת המחשב.

 (7) בעיית סדר מקרי (Coincidental Ordering Problem):

תלמידים עשויים לבנות ביטוי אריתמטי אשר סדר כתיבתו זהה לסדר החישוב המצופה של מרכיביו, ובתוך כך הם עלולים לא לזהות חלקים בביטוי שיש לתת להם סדר עדיפות שונה. הם אינם משלבים סוגריים לעקיפת סדר החישוב הרצוי כיוון שהם סבורים שהמחשב אכן יבצע את החישוב לפי סדר הכתיבה. לדוגמה, חישוב מס הכנסה לפי הכלל "על 10000 ש"ח הראשונים של הברוטו משלמים 30% מס, ואילו על יתר הסכום  משלמים  32%" תלמידים רשמו את הביטוי הבא:

              Tax := 10000*0.30+Income-10000*0.32

הביטוי משקף את סדר החישוב כפי שמבצע התלמיד בראשו: "תכפיל את 10000 ב- 0.32 ותוסיף לתוצאה את ההפרש בין ההכנסה הכוללת Income ל- 10000 מוכפל ב- 0.32%".  התלמיד לא רשם סוגריים לאלץ את החיסור Income-10000 להתבצע לפני פעולת הכפל, ומניח שהמחשב יבצע את החישוב כמצופה.

סיכום

שגיאות של מתחילים אינן מופיעות במידה דומה. יש שגיאות שהופעתן נדירה, ויש שגיאות ששכיחותן גבוהה במיוחד. ממצאי המחקר סותרים את הסברה שמקור מרבית השגיאות הוא בתפיסה מוטעית של משמעות במבנים/משפטים בשפת התכנות. המחברים גילו 10 בעיות אשר באות לידי ביטוי בשגיאות שכיחות של מתכנתים מתחילים, שרק שלוש מהן קשורות להבנת משמעות של מבנים או משפטים בשפת תכנות. יתר הבעיות נובעות מתפיסת מושגים וקשרים שאינם קשורים בהכרח ישירות לתכנות. המחברים מדגישים שלממצא זה יש השלכות להוראה: מורים המודעים לשגיאות שכיחות, יכולים לשפר באופן משמעותי את ההוראה ולטפל במיגורן. הבהרת המשמעות של המבנים/משפטי השפה אין די בה להפחתת השגיאות, שכן הממצאים מראים שמרבית השגיאות אינן קשורות בהכרח להבנה שגויה של משמעות זו. על המורים לגוון את ההוראה ולשלב בתהליך הלימוד דוגמאות של פתרונות בנויים היטב, במקביל לפתרונות שגויים. לדעת מחברי המאמר, הצגת שגיאות אפשריות בפני תלמידים עשויה לעזור להם לשים לב, ולהימנע מלעשותן.

חזרה לאתר