יסודות התכנות בשפת Python · פרק 1 — מבוא⌂📚🏠
פרק 1

מבוא

10 שעות לימוד

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

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

1.1 הנדסת מחשבים ואתגרים חישוביים

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

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

התחוםהאתגרמה המחשב מחשב
רפואהמעקב אחר לב של מטופל לאורך היוםמנתח את האות דגימה אחר דגימה, ומתריע כשהדופק אינו סדיר
תחבורההדרך המהירה ביותר בעיר עמוסהמשווה בין מספר עצום של דרכים, ומחשב מחדש בכל שינוי בעומס
אנרגיהרשת חשמל שיש בה לוחות סולארייםמאזן רגע אחר רגע בין הייצור לצריכה
תעשייהבדיקה של כל פריט בקו ייצורמשווה את תמונת הפריט לדגם בתוך חלקיק שנייה
דוגמה 1.1
מכשיר א.ק.ג. לוקח 500 דגימות של האות בשנייה. כמה דגימות הוא אוסף ביממה שלמה? ולמה זה אתגר חישובי?
פתרון:
500 · 60 · 60 · 24 = 43200000

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

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

1.2 משימות חישוביות פשוטות

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

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

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

  1. נמיר את צבע הפס הראשון לספרה. זו ספרת העשרות.
  2. נמיר את צבע הפס השני לספרה. זו ספרת האחדות.
  3. נמיר את צבע הפס השלישי לספרה, ונקרא לה n.
  4. נכפיל את המספר שקיבלנו משני הפסים הראשונים ב-10n. התוצאה היא הערך באוהם.

חום פירושו 1, שחור פירושו 0, ולכן המספר הוא 10. אדום פירושו n = 2:

10 · 102 = 1000 Ω

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

דוגמה 1.3
בשרשרת קישוט יש 16 נורות המחוברות בטור. נורה אחת נשרפה, וכולן כבו. ננתק את השרשרת מן המקור, ויש לנו אוהמטר שמראה אם קטע ממנה מוליך או לא. איך נמצא את הנורה השרופה?
פתרון:

הנתון: 16 נורות, והקטע שבו נמצאת הנורה השרופה אינו מוליך. הדרוש: הנורה השרופה. נשווה בין שני אלגוריתמים:

האלגוריתםהצעדיםבדיקות במקרה הגרוע
אחת אחרי השנייהנבדוק את הנורה הראשונה, אחר כך את השנייה, וכן הלאה, עד שנמצא את זו שאינה מוליכה15: אם חמש-עשרה תקינות, האחרונה היא השרופה
חצייהנבדוק חצי מן השרשרת. אם הוא מוליך, השרופה בחצי האחר, ואם לא, היא בחצי הזה. אחר כך נחצה את מה שנשאר, עד שנשארת נורה אחת4: מ-16 ל-8, ל-4, ל-2, ל-1

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

טעות נפוצה: צעד כמו "נמדוד כמה פעמים וניקח ערך מתאים" אינו צעד באלגוריתם: כמה פעמים? ואיזה ערך הוא המתאים? שני אנשים שיבצעו אותו יגיעו לשתי תוצאות שונות. הניסוח הנכון: "נמדוד שלוש פעמים וניקח את הממוצע".
שאלה 1.2: סוללה של 9 V מחוברת לשני נגדים בטור, 100 Ω ו-200 Ω. אנחנו רוצים לדעת מה הזרם במעגל החשמלי. כתבו את הנתון, הדרוש והצעדים.

1.3 שפת תכנות

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

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

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

התוכנית שכתבנוהמפרשפקודות למעבד

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

השפהאיפה נפגוש אותההפקודה
Pythonהספר הזה, ניתוח נתונים, תקשורת עם התקניםprint("Power on")
C++לוח ארדואינוSerial.println("Power on");
C#יישומי מחשבConsole.WriteLine("Power on");
טעות נפוצה: שפת תכנות אינה סלחנית. אנחנו מבינים משפט שיש בו שגיאת כתיב, אבל המפרש לא: print ו-Print הן שתי מילים שונות, כי אותיות גדולות וקטנות נבדלות.
שאלה 1.3: איזו מן השורות האלה תקינה בפייתון?
(א) print("Ready")
(ב) Print("Ready")
(ג) print("Ready
(ד) print "Ready"

1.4 התוכנית: קריאה, כתיבה, הרצה, בדיקה ותיקון

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

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

כתיבההרצהבדיקהסיימנוקריאת השגיאה ותיקונהנכוןשגוי

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

print("Sensor test")
print("Reading:", 25)
# the next line runs last
print("Done")
פלט
Sensor test
Reading: 25
Done
print("Done")
print("Sensor test")
print("Reading:", 25)
פלט
Done
Sensor test
Reading: 25

כתיבה. כותבים פקודה אחת בכל שורה, ושומרים את התוכנית בקובץ שסיומת שמו .py.

טעות נפוצה: בפייתון יש משמעות לרווח שבתחילת השורה, כפי שנראה בפרק 3. בתוכניות שאנחנו כותבים עכשיו כל שורה מתחילה בעמודה הראשונה:
print("Start")
    print("End")
פלט
IndentationError: unexpected indent

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

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

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

print("Battery check")
print("Voltage: 9 V)
פלט
SyntaxError: unterminated string literal (detected at line 2)
print("Battery check")
Print("Voltage: 9 V")
פלט
Battery check
NameError: name 'Print' is not defined

הניסיון השלישי: אין הודעת שגיאה. אבל האם הפלט נכון? זרם של יותר מ-200 A מסוללה קטנה? בלתי אפשרי. המחשב חילק את 9 ב-100 תחילה ואז הוסיף 200, ואנחנו רוצים שיחבר את שתי ההתנגדויות לפני החילוק. נוסיף סוגריים, ונקבל את התוכנית השנייה:

print("Battery check")
print("Voltage: 9 V")
print("Current:", 9 / 100 + 200, "A")
פלט
Battery check
Voltage: 9 V
Current: 200.09 A
print("Battery check")
print("Voltage: 9 V")
print("Current:", 9 / (100 + 200), "A")
פלט
Battery check
Voltage: 9 V
Current: 0.03 A

עכשיו הפלט סביר, ומתאים למה שנחשב ביד: 9 חלקי 300. את האופרטורים החשבוניים נלמד בפירוט בפרק 2.

הערה: הניסיון השלישי הוא המסוכן ביותר: התוכנית רצה ואינה מתלוננת. לכן לא מספיק שהתוכנית רצה, ותמיד בודקים אותה על דוגמה שאנחנו יודעים את תוצאתה.
שאלה 1.4: מה מדפיסה התוכנית הבאה?
print("A")
print()
print("B", "C")
print(2 + 3)
print("2 + 3")

1.5 סביבת הפיתוח ותוכנית ראשונה

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

תכנית הלימודים ממליצה להכיר שתי סביבות: סביבה מקוונת, וסביבה שמתקינים על המחשב. כאן נכיר את Google Colab ואת IDLE. יש סביבות נוספות כמו Visual Studio Code ו-PyCharm, ואותה תוכנית רצה בכולן.

Google ColabIDLE
איפה היא רצהבדפדפן, והתוכנית רצה על שרת מרוחקעל המחשב שלנו
מה צריךחשבון Google וחיבור לאינטרנטהתקנת פייתון מהאתר python.org, ו-IDLE מגיעה איתה
איפה העבודה נשמרתמחברת ב-Google Driveקובץ .py במחשב
Turtleלא עובד, כי לשרת המרוחק אין מסךעובד, ונפתח לו חלון

ב-Google Colab:

  1. נכנסים אל colab.research.google.com ובוחרים מחברת חדשה.
  2. כותבים את התוכנית בריבוע שמופיע, שהוא התא.
  3. לוחצים על לחצן ההרצה שליד התא, או על Shift+Enter, והפלט מופיע מתחתיו.

ב-IDLE:

  1. פותחים את IDLE, ומופיע חלון Shell.
  2. בוחרים File > New File, וכותבים את התוכנית בחלון החדש.
  3. שומרים בעזרת File > Save בשם כמו first.py.
  4. לוחצים על F5, והפלט מופיע בחלון Shell.

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

print("Hello from the lab")
פלט
Hello from the lab
print("Measuring station")
print("Power on")
print()
print("Ready")
פלט
Measuring station
Power on

Ready

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

טעות נפוצה: אם מעתיקים קוד מ-Word או מאתר, המירכאות עלולות להגיע נטויות במקום ישרות. הן נראות לנו דומות, אבל בעיני המפרש הן תווים אחרים, כמו בתוכנית השנייה:
print("7 * 6")
print(7 * 6)
print("Seconds:", 24 * 60 * 60)
פלט
7 * 6
42
Seconds: 86400
print(“Power on”)
פלט
SyntaxError: invalid character '“' (U+201C)
שאלה 1.5: כתבו תוכנית שמדפיסה את חלקי תחנת המדידה, כל חלק בשורה: Solar panel , Battery , Gauge
▶ניסוי חי — מעבדת התוכנית הראשונהכותבים בעורך פקודות print ומריצים אותן, מנסים תקלות מוכנות וקוראים את הודעות השגיאה. אין במעבדה import, ולכן תוכניות Turtle מריצים ב-IDLE.
⚠
המעבדה אינה זמינה כרגע. החומר בפרק שלם גם בלעדיה: ממשיכים לקרוא, וחוזרים לניסוי מאוחר יותר או פותחים אותו ישירות מן הקישור שמתחת למסגרת.
https://fahed-lab.com/electronics/python_basics#intro
פותחים את המעבדה בדף נפרד ↗ fahed-lab.com/electronics/python_basics#intro

1.6 העצם כמופע של מחלקה

פותחים את ארון המעבדה ומוצאים שנים-עשר רבי-מודדים מאותו דגם. לכולם אותם לחצנים ואותן יכולות, כי הם יוצרו לפי תכנון אחד. אבל כל רב-מודד הוא דבר נפרד: זה בתחום 20 V וקורא 11.9, וההוא כבוי.

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

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

מחלקה: רב-מודדתכונות: תחום, קריאה, טעינהפעולות: הפעלה, בחירת תחום, מדידהעצם: רב-מודד 1תחום: ‎20 V‎קריאה: ‎11.9 V‎טעינה: ‎80%‎עצם: רב-מודד 2תחום: ‎2 A‎קריאה: ‎0.5 A‎טעינה: ‎35%‎עצם: רב-מודד 3תחום: ‎200 V‎קריאה: ‎0 V‎טעינה: ‎100%‎מופע
מחלקה אחת ושלושה עצמים: אותן פעולות, וערכי תכונות שונים
מחלקהשני עצמים ממנהתכונותפעולות
נוריתהאדומה שעל הלוח, והירוקה לידהצבע, דולקת או לאהדלקה, כיבוי
סוללהסוללת המכונית, וסוללת האזעקהמתח, קיבולתטעינה, פריקה
טלפוןהטלפון שלי, והטלפון של חברמספר, טעינהחיוג, שליחת הודעה
טעות נפוצה: לא מערבבים בין השניים: המחלקה אינה מודדת דבר, היא התכנון בלבד, ומי שמודד הוא רב-מודד מסוים. וכשמשנים את התחום של רב-מודד אחד, התחום של האחר אינו משתנה.
שאלה 1.6: בחרו את המחלקה "מאוורר". כתבו לה שתי תכונות ושתי פעולות, ותארו שני עצמים ממנה.

1.7 מחלקה קיימת: Turtle

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

חלון Turtle הוא מישור דו-ממדי עם שני צירים. הנקודה (0, 0) באמצע החלון, x גדל ימינה, ו-y גדל למעלה. כל נקודה נכתבת (x, y), ו-x תמיד ראשון. העצם נולד ב-(0, 0) וכיוונו ימינה. הפקודות forward ו-backward מזיזות אותו בכיוונו הנוכחי, והפקודות right ו-left מסובבות אותו במקומו, במעלות.

xy-150-100-5050100150-100-5050100(100, 50)(-100, 50)(-50, -100)(0, 0)
המישור: החץ במצב ההתחלה, ושלוש נקודות להמחשה
forwardbackwardleft(90)right(90)
ארבע הפקודות, ביחס לכיוון החץ

תוכנית Turtle ראשונה:

import turtle
pen = turtle.Turtle()
pen.forward(100)
print(pen.position())
turtle.done()
פלט
(100.00,0.00)
50100
מה שהחלון מציג אחרי ההרצה
הערה: הרשת והמספרים בציורי הספר נוספו כדי שיהיה קל לקרוא את הקואורדינטות. החלון האמיתי לבן, ויש בו רק הקווים והחץ.
טעות נפוצה: אל תקראו לקובץ התוכנית turtle.py: אז import turtle מוצאת את הקובץ שלנו במקום את המודול המוכן, והתוכנית נעצרת. קראו לו למשל draw1.py. ואל תנסו את Turtle ב-Google Colab, אלא השתמשו ב-IDLE או בסביבה אחרת על המחשב.

תנועה וסיבוב:

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

import turtle
pen = turtle.Turtle()
pen.forward(100)
pen.left(90)
pen.forward(50)
pen.backward(20)
print(pen.position())
turtle.done()
פלט
(100.00,30.00)
5010050
החץ עומד ב-(100, 30) וכיוונו למעלה
טעות נפוצה: הכיוונים right ו-left הם ביחס לחץ, לא ביחס לדף. אם החץ מכוון למטה, אז right(90) מסובבת אותו שמאלה בדף.
דוגמה 1.5
נצייר ריבוע שצלעו 100.
פתרון:

נתקדם ונסתובב, ארבע פעמים:

import turtle
pen = turtle.Turtle()
pen.forward(100)
pen.right(90)
pen.forward(100)
pen.right(90)
pen.forward(100)
pen.right(90)
pen.forward(100)
pen.right(90)
turtle.done()
50100-100-50

זה עובד, אבל כתבנו את אותו זוג פקודות ארבע פעמים. ומה אם נרצה צורה עם 20 צלעות? בפרק 4 נלמד את הלולאה, כלומר לומר למחשב "חזור על זה", ואז נכתוב את זוג הפקודות פעם אחת בלבד.

הרמת העט וצבע:

הפקודה penup מרימה את העט, והעצם זז אחריה בלי לצייר, והפקודה pendown מחזירה אותו לדף. יש להן שמות קצרים יותר: up ו-down. הפקודה color משנה את צבע העט, ושם הצבע הוא טקסט באנגלית בין מירכאות, והוא חל על כל מה שמצויר אחריה. נצייר בעזרתן סרגל בשני צבעים:

import turtle
pen = turtle.Turtle()
pen.color("green")
pen.forward(80)
pen.penup()
pen.forward(15)
pen.pendown()
pen.color("red")
pen.forward(40)
pen.up()
pen.forward(15)
pen.down()
pen.forward(40)
turtle.done()
50100150200
שני צבעים ושני רווחים

מעבר לנקודה:

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

import turtle
pen = turtle.Turtle()
pen.goto(50, 50)
pen.goto(100, 0)
pen.goto(150, 50)
pen.goto(200, 0)
print(pen.position())
turtle.done()
פלט
(200.00,0.00)
5010015020050
אות משולש, בלי שום זווית
טעות נפוצה: אם העט על הדף, goto מציירת קו בדרך. כדי לעבור למקום אחר בלי קו, מרימים את העט לפניה ומחזירים אותו אחריה.
שאלה 1.7: איפה עומד העצם בסוף התוכנית? ענו לפני ההרצה.
import turtle
pen = turtle.Turtle()
pen.forward(50)
pen.left(90)
pen.forward(30)
pen.backward(10)
print(pen.position())
turtle.done()

1.8 קריאת ממשק פשוט של מחלקה

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

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

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

הפעולההפרמטריםמה היא עושה
Turtle()כלוםיוצרת עצם חדש ב-(0, 0), שכיוונו ימינה
forward(d)מספר: מרחקמתקדם d בכיוונו הנוכחי
backward(d)מספר: מרחקנסוג d בלי להסתובב
right(a)מספר: זווית במעלותמסתובב במקומו לימינו
left(a)מספר: זווית במעלותמסתובב במקומו לשמאלו
penup() , up()כלוםמרים את העט
pendown() , down()כלוםמחזיר את העט לדף
color(name)טקסט: שם הצבעמשנה את צבע העט
goto(x, y)שני מספרים: קואורדינטותעובר לנקודה, ומצייר אם העט על הדף
position()כלוםמחזירה את המיקום הנוכחי ואינה מדפיסה אותו

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

טעות נפוצה: את הממשק קוראים כלשונו. בלי סוגריים הפעולה אינה מזומנת, והגרוע מכול הוא שהמפרש אינו מתלונן: התוכנית השנייה רצה, והעצם אינו זז.
import turtle
pen = turtle.Turtle()
pen.forward(80)
pen.position()
print(pen.position())
turtle.done()
פלט
(80.00,0.00)
import turtle
pen = turtle.Turtle()
pen.forward
print(pen.position())
turtle.done()
פלט
(0.00,0.00)

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

import turtle
pen = turtle.Turtle()
pen.Forward(100)
פלט
AttributeError: 'Turtle' object has no attribute 'Forward'. Did you mean: 'forward'?
import turtle
pen = turtle.Turtle()
pen.forward("100")
פלט
TypeError: can't multiply sequence by non-int of type 'float'

התועלת האמיתית בקריאת הממשק היא שאפשר להשתמש בפעולה שלא ראינו מעולם. הנה פעולות נוספות מאותו ממשק:

הפעולההפרמטריםמה היא עושה
circle(r)מספר: רדיוסמצייר מעגל, שמרכזו במרחק r משמאל לחץ, וחוזר לנקודת ההתחלה
dot(size, color)מספר וטקסטמצייר נקודה מלאה בקוטר ובצבע המבוקשים, גם כשהעט מורם
pensize(w)מספר: עובימשנה את עובי הקו
write(text)טקסטכותב את הטקסט במיקום הנוכחי
hideturtle()כלוםמסתיר את החץ, והציור נשאר
דוגמה 1.6
נצייר את סמל הנורה: מעגל ובתוכו שני קווים מצטלבים.
פתרון:

בממשק כתוב שהמרכז של circle(40) נמצא במרחק 40 משמאל לחץ. החץ מכוון ימינה, ולכן המרכז הוא (0, 40). את נקודות הקווים נחשב סביב המרכז הזה, ונרים את העט לפני כל מעבר:

import turtle
pen = turtle.Turtle()
pen.pensize(2)
pen.circle(40)
pen.up()
pen.goto(-28, 12)
pen.down()
pen.goto(28, 68)
pen.up()
pen.goto(-28, 68)
pen.down()
pen.goto(28, 12)
pen.up()
pen.goto(50, 30)
pen.write("Lamp")
pen.hideturtle()
turtle.done()
-505010050100Lamp
סמל הנורה, מן הממשק בלבד
הערה: הממשק המלא נמצא בתיעוד של פייתון, באתר docs.python.org, ויש בו פעולות רבות. אפשר גם לכתוב בחלון Shell את הפקודה help(turtle.Turtle.forward) אחרי import turtle, והממשק של הפעולה הזאת יופיע שם.
שאלה 1.8: למחלקה של נורית יש הממשק הזה: on() בלי פרמטרים, off() בלי פרמטרים, brightness(percent) עם פרמטר מספרי מ-0 עד 100, ו-is_on() שמחזירה True או False. יש לנו עצם בשם led. כתבו פקודות שמדליקות אותו בחצי עוצמה, ואז מדפיסות אם הוא דולק.

1.9 יצירת עצמים חדשים

בכל פעם שמזמנים את turtle.Turtle() נולד מופע חדש. לכל עצם המיקום, הכיוון והצבע שלו, ופקודה שניתנת לעצם אחד אינה משפיעה על אחרים. שם העצם שלפני הנקודה קובע מי מבצע:

import turtle
pen_a = turtle.Turtle()
pen_b = turtle.Turtle()
pen_a.color("red")
pen_b.color("blue")
pen_a.forward(100)
pen_b.left(90)
pen_b.forward(60)
print(pen_a.position())
print(pen_b.position())
turtle.done()
פלט
(100.00,0.00)
(0.00,60.00)
5010050
שני עצמים מאותה מחלקה
דוגמה 1.7
במסך של נתח לוגי רואים את אות השעון ואת אות הנתונים, זה מעל זה. נצייר אותם בשני עצמים, ולכל אות העט שלו.
פתרון:

ניצור את העצם clock, נרים את העט שלו, נכתוב את השם, ואז נצייר בעזרת goto. אחר כך ניצור את data ונעשה אותו דבר:

import turtle
clock = turtle.Turtle()
clock.color("blue")
clock.up()
clock.goto(4, 68)
clock.write("CLK")
clock.goto(0, 60)
clock.down()
clock.goto(0, 90)
clock.goto(40, 90)
clock.goto(40, 60)
clock.goto(80, 60)
clock.goto(80, 90)
clock.goto(120, 90)
clock.goto(120, 60)
clock.goto(160, 60)
clock.hideturtle()
data = turtle.Turtle()
data.color("red")
data.up()
data.goto(4, 6)
data.write("DATA")
data.goto(0, 0)
data.down()
data.goto(80, 0)
data.goto(80, 30)
data.goto(160, 30)
data.hideturtle()
turtle.done()
5010015050100CLKDATA
שני אותות בשני עצמים: כל עצם זוכר את מיקומו ואת צבעו
טעות נפוצה: השורה pen_b = pen_a אינה יוצרת עצם: אין כאן Turtle(), אלא שני שמות לעצם אחד. לכן בציור יש חץ אחד, ומה שעושים באחד השמות קורה לאותו עצם:
import turtle
pen_a = turtle.Turtle()
pen_b = pen_a
pen_a.forward(100)
pen_b.left(90)
pen_b.forward(50)
print(pen_a.position())
print(pen_b.position())
turtle.done()
פלט
(100.00,50.00)
(100.00,50.00)
5010050
שני שמות, עצם אחד, קו אחד
שאלה 1.9: מה מדפיסה התוכנית? שימו לב ש-goto אינה משנה את כיוון העצם.
import turtle
pen_a = turtle.Turtle()
pen_b = turtle.Turtle()
pen_a.goto(40, 40)
pen_b.backward(30)
pen_a.forward(10)
print(pen_a.position())
print(pen_b.position())
turtle.done()
פרויקט הספר: תחנת המדידה · שלב 1 — התחנה מצוירת

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

import turtle

panel = turtle.Turtle()
panel.color("blue")
panel.pensize(2)
panel.up()
panel.goto(-200, 125)
panel.write("PANEL")
panel.goto(-200, 60)
panel.down()
panel.goto(-100, 60)
panel.goto(-100, 120)
panel.goto(-200, 120)
panel.goto(-200, 60)
panel.up()
panel.goto(-150, 60)
panel.down()
panel.goto(-150, 120)
panel.hideturtle()

wire = turtle.Turtle()
wire.up()
wire.goto(-100, 90)
wire.down()
wire.goto(120, 90)
wire.up()
wire.goto(-150, 60)
wire.down()
wire.goto(-150, -30)
wire.goto(150, -30)
wire.goto(150, 60)
wire.up()
wire.goto(0, 90)
wire.dot(8)
wire.down()
wire.goto(0, 35)
wire.up()
wire.goto(0, -30)
wire.dot(8)
wire.down()
wire.goto(0, 25)
wire.hideturtle()

cell = turtle.Turtle()
cell.color("red")
cell.pensize(3)
cell.up()
cell.goto(-25, 35)
cell.down()
cell.goto(25, 35)
cell.up()
cell.goto(-12, 25)
cell.down()
cell.goto(12, 25)
cell.up()
cell.goto(32, 24)
cell.write("BATTERY")
cell.hideturtle()

gauge = turtle.Turtle()
gauge.color("green")
gauge.pensize(2)
gauge.up()
gauge.goto(150, 60)
gauge.down()
gauge.circle(30)
gauge.up()
gauge.goto(150, 90)
gauge.down()
gauge.goto(168, 110)
gauge.up()
gauge.goto(125, 126)
gauge.write("GAUGE")
gauge.hideturtle()

turtle.done()
-200-150-100-5050100150200-5050100150PANELBATTERYGAUGE
תרשים התחנה: ציירו אותו ארבעה עצמים מן המחלקה Turtle

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

עיקרי הפרק:

סיכום פקודות הפרק:

פקודהמה היא עושה
print("text", 2 + 3)הדפסה על המסך
# commentהערה שהמפרש מתעלם ממנה
import turtleהבאת המודול המוכן
pen = turtle.Turtle()יצירת עצם חדש בשם pen
pen.forward(d) pen.backward(d)תנועה בכיוון הנוכחי
pen.right(a) pen.left(a)סיבוב במקום
pen.penup() pen.pendown()הרמת העט והורדתו
pen.up() pen.down()שמות קצרים לשתי הפקודות הקודמות
pen.color("red")צבע העט
pen.goto(x, y)מעבר לנקודה
pen.position()המיקום הנוכחי, ערך שחוזר אלינו
turtle.done()השארת החלון פתוח

מילון מונחים:

עבריתEnglishערבית
הנדסת מחשביםComputer engineeringهندسة الحاسوب
אתגר חישוביComputational challengeتحدٍّ حسابي
אלגוריתםAlgorithmالخوارزمية
ניתוח המשימהTask analysisتحليل المهمة
שפת תכנותProgramming languageلغة البرمجة
תחבירSyntaxالنحو
מפרשInterpreterالمفسّر
תוכניתProgramالبرنامج
הערהCommentالتعليق
פלטOutputالمُخرَج
סביבת פיתוחDevelopment environment (IDE)بيئة التطوير
מחלקהClassالفئة
עצםObjectالكائن
מופעInstanceالنسخة
תכונהAttributeالصفة
פעולהMethodالعمليّة
פרמטרParameterالوسيط
ממשקInterfaceالواجهة
התשובות הסופיות לשאלות הפרק
1.1 בשעה יש 4 קריאות, ובשנה 35040 קריאות מכל מונה. כשיש בעיר מאות אלפי מונים אדם אינו יכול לקרוא אותן, ואילו התוכנית אוספת אותן ומגלה תקלות וצריכה חריגה.
1.2 הנתון: המתח ושני הנגדים. הדרוש: הזרם. הצעדים: מחברים את שתי ההתנגדויות, ואז מחלקים את המתח בסכום. נריץ את החישוב הזה בסעיף 1.4.
1.3 רק שורה (א). ב-(ב) יש אות גדולה, ב-(ג) חסרים המירכאות והסוגר, וב-(ד) חסרים הסוגריים.
1.4 A , שורה ריקה , B C , 5 , 2 + 3
1.5
print("Solar panel")
print("Battery")
print("Gauge")
1.6 למשל: התכונות: מהירות, מתח. הפעולות: הפעלה, שינוי מהירות. העצם הראשון: מאוורר הארגז, מהירותו נמוכה, 12 V. העצם השני: מאוורר המחשב, מהירותו גבוהה, 5 V.
1.7 (50.00,20.00)
1.8 led.on() , led.brightness(50) , print(led.is_on())
1.9 (50.00,40.00) , (-30.00,0.00)

שאלות לתרגול:

רמה ראשונה — בסיסי
1.
מה מדפיסה התוכנית?
print("9 * 9")
print(9 * 9)
print()
print("Done", 9 + 9)
תשובות: 9 * 9 , 81 , שורה ריקה , Done 18
2.
בתוכנית הבאה שלוש שגיאות. מצאו ותקנו אותן, וציינו: באיזה סדר המפרש מודיע עליהן?
Print("Lab 3")
print("Voltage: 5 V)
    print("End")
תשובות: תחילה הוא מודיע על המירכאות החסרות, אחר כך על הרווח שבתחילת השורה האחרונה, כי אלה שגיאות תחביר שנבדקות לפני ההרצה. ולבסוף על האות הגדולה ב-Print, כי זו מתגלה רק בזמן הביצוע.
print("Lab 3")
print("Voltage: 5 V")
print("End")
3.
מה מצויר? ואיפה עומד העצם בסוף? ציירו ביד לפני שתקראו את התשובה.
import turtle
pen = turtle.Turtle()
pen.forward(80)
pen.left(90)
pen.forward(40)
pen.right(90)
pen.forward(80)
pen.right(90)
pen.forward(40)
print(pen.position())
turtle.done()
תשובות: העצם עומד ב-(160.00,0.00).
5010015050
4.
כתבו תוכנית שמציירת מלבן שרוחבו 120 וגובהו 60, בעזרת forward ו-left בלבד.
תשובות:
import turtle
pen = turtle.Turtle()
pen.forward(120)
pen.left(90)
pen.forward(60)
pen.left(90)
pen.forward(120)
pen.left(90)
pen.forward(60)
turtle.done()
5010050
רמה שנייה — בינוני
5.
השתמשו באלגוריתם מסעיף 1.2 כדי למצוא את ערכו של נגד שפסיו: צהוב, סגול, כתום.
תשובות: צהוב פירושו 4, סגול פירושו 7, ולכן המספר 47. כתום פירושו n = 3. הערך: 47000 אוהם.
6.
כתבו תוכנית שמציירת קו מקווקו אנכי כלפי מעלה: שלושה קטעים שאורך כל אחד 30, וביניהם שני רווחים שאורך כל אחד 20. אחר כך הדפיסו את המיקום.
תשובות:
import turtle
pen = turtle.Turtle()
pen.left(90)
pen.forward(30)
pen.up()
pen.forward(20)
pen.down()
pen.forward(30)
pen.up()
pen.forward(20)
pen.down()
pen.forward(30)
print(pen.position())
turtle.done()
50100150
מדפיסה: (0.00,130.00)
7.
היעזרו בממשק מסעיף 1.8 וציירו שלוש נוריות חיווי, כל אחת נקודה בקוטר 30: אדומה, כתומה וירוקה, ובין כל שתיים מרחק 50, בלי שום קו ביניהן.
תשובות:
import turtle
pen = turtle.Turtle()
pen.up()
pen.dot(30, "red")
pen.forward(50)
pen.dot(30, "orange")
pen.forward(50)
pen.dot(30, "green")
pen.hideturtle()
turtle.done()
50100
רמה שלישית — אתגר
8.
הדקי סוללה מחוברים לנורה: התיל האדום plus מתחיל ב-(0, 40) ומגיע ל-(120, 25). התיל השחור minus מתחיל ב-(0, 0) ומגיע ל-(120, 15). ציירו את שני התילים בשני עצמים, בזוויות ישרות בלבד, והדפיסו את מיקום הסיום של כל אחד.
תשובות:
import turtle
plus = turtle.Turtle()
minus = turtle.Turtle()
plus.color("red")
minus.color("black")
plus.up()
plus.goto(0, 40)
plus.down()
plus.goto(120, 40)
plus.goto(120, 25)
minus.goto(120, 0)
minus.goto(120, 15)
print(plus.position())
print(minus.position())
turtle.done()
5010050
מדפיסה: (120.00,25.00) , (120.00,15.00)
9.
תצוגת שבעה מקטעים מציגה את הספרה 2 בחמישה מקטעים רצופים. ציירו אותה בקו עבה, ברוחב 50 ובגובה 100, בלי לצייר אף מקטע פעמיים, והסתירו את החץ.
תשובות:
import turtle
pen = turtle.Turtle()
pen.pensize(4)
pen.up()
pen.goto(0, 100)
pen.down()
pen.goto(50, 100)
pen.goto(50, 50)
pen.goto(0, 50)
pen.goto(0, 0)
pen.goto(50, 0)
pen.hideturtle()
turtle.done()
5050100
10.
ציירו משושה משוכלל שצלעו 60. זווית הסיבוב במצולע משוכלל בעל n צלעות היא 360 חלקי n. כמה פקודות צריך לצלעות ולסיבובים? וכמה היה צריך למצולע בעל 100 צלעות?
תשובות: הזווית היא 60 מעלות, וצריך 12 פקודות: שתיים לכל צלע. למצולע בעל 100 צלעות צריך 200 פקודות, ולכן נזדקק ללולאה בפרק 4.
import turtle
pen = turtle.Turtle()
pen.forward(60)
pen.left(60)
pen.forward(60)
pen.left(60)
pen.forward(60)
pen.left(60)
pen.forward(60)
pen.left(60)
pen.forward(60)
pen.left(60)
pen.forward(60)
pen.left(60)
turtle.done()
-505010050100