פתח דבר

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

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

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

כאמור העיון באוסף מניח היכרות עם כלי תכנות ומבני נתונים הנלמדים בדרך כלל בקורס תכנות בסיסי (לרשימה של חומרים אלה ראו כאן). הפתרונות שהוא מציע לבעיות הנדונות בו נסמכים אך ורק על חומרים אלה, ומטרה חשובה של האוסף היא לתרגל ככל האפשר את השימוש בהם. ככלל האוסף נמנע במכוון מהישענות על חומרים הנלמדים בקורסים מתקדמים, גם כשברור שמתכנתים ברמה בינונית או גבוהה יכתבו פתרונות שונים מאלה שהאוסף מציג. דוגמה אחת: בעיה 18 עוסקת בבניית אוסף המחזיק נתונים מתוך קובץ .csv מותר לשער כי מתכנתים ברמה בינונית יבנו את האוסף באמצעות הכלים המוצעים בספריות ייעודיות לטיפול בגליונות נתונים: למשל הם יוכלו להשתמש בספריה pandas ולשמור את הנתונים במבנה נתונים המוגדר בשפה זו, DataFrame. הפתרון לבעיה 18 מראה כיצד לשמור את הנתונים שיש בקובץ בתוך מילון, וזאת כדי לתרגל את הטיפול במבנה נתונים בסיסי וחשוב זה. מטעמים דומים האוסף משתמש בניסוחים הרווחים בקורסי תכנות בסיסי ומסייעים לתלמידים להבין את הרעיונות הנלמדים, הגם שאינם מדויקים לגמרי. דוגמות בולטות הם “הצבת ערך במשתנה”, “משתנה המכיל ערך”, וכיוצא באלה. האוסף אינו מניח היכרות לפרטי פרטים עם שמירת אובייקטים בזכרון וממילא גם לא עם הפשר המדויק יותר של “משתנה”, היינו בתור תווית (alias) לאובייקט בזכרון. 

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

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

שלמי תודה: הילה מושיוב ואסף רימון העירו הערות חשובות על ספר זה ואני מוקיר להם תודה על כך. 

עפר אליאור

ירושלים תשע”ו 

ofer.elior@gmail.com

 

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

age = input(‘Insert age; -1 to stop: ‘)

while age != ‘-1’:

    print(age)

    age = input(‘Insert age; -1 to stop: ‘)