@יוסף1111 אמר בהתנהגות של לולאת FOR:
לולאה אמורה לרוץ כל הזמן. נכון?
לא בדיוק, קוד בפייתון (ובעצם בכל שפה) רץ כסדר, כלומר מבצע את הפקודות שורה שורה בסדר שנכתבו. יש לפעמים פקודות שאומרים לפייתון ללכת לישון לזמן מה, ואז הפייתון הולך לישון כמו ילד טוב לזמן המוגדר ואז הוא מתעורר וממשיך לפקודה הבאה.
לולאה רצה בדיוק כמו קוד רגיל, רק כשהוא מגיע לסוף הוא מתחיל שוב מהתחלה.
בוא ננתח מה קורה.
אני מדלג על החלק הראשון שלא כל כך מעניין,
בשורה 20 אתה כותב while 1:, הכוונה היא: "א. תבדוק אם התנאי (1) הוא חיובי (התנאי 1 תמיד יהיה חיובי), ב. במידה וכן, תריץ את הבלוק הבא, וכשתגיע לסוף תחזור שוב לשלב א."
בשפת בנ"א אתה מריץ את הבלוק בלולאה אינסופית.
בשורה הבאה אתה כותב: for cc in ser.read():, הכוונה היא: אתה מצהיר שהערך שמוחזר מ-ser.read() הוא iterable, הכוונה שהיא סוג אובייקט שיכולה לספק לך ערכים, ואפשר לשלוף את הערכים אחד אחד.
אתה מפקד על פייתון לקחת את ה-iterable הזה ולשלוף את הערכים אחד אחד, בכל שליפה של ערך הוא אמור לשים את הערך במשתנה cc ולהריץ את הבלוק.
איך פייתון שולפת את הערכים מהאובייקט הזה?
היא קוראת את הפונקציה__iter__כדי לקבל אובייקט מסוג iterator, על ה-iterator הזה אפשר לקרוא פונקציית__next__שבכל קריאה מחזירה את הערך הבאה.
מאיפה הערכים האלו שהאובייקט מחזירה?
הם מגיעים מהסריאל פורט.
ערכים אלו לא תמיד זמינים מיד, לפעמים צריך לחכות עד שהם יגיעו מאן שהם אמורים להגיע. ומה קורה אם הערכים עוד לא זמינים?
הפונקציה ששולפת את הערכים פשוט הולכת לישון
כי אין לה מה לעשות עד שהערכים יהיו זמינים, לפני שהיא ישנה היא מבקשת ממערכת ההפעלה להעיר אותה ברגע שמשהו זמין מהסיריאל פורט. ברגע שקלט מגיע, מערכת ההפעלה מעוררת את הפונקציה מהשינה העריבה והפונקציה מקבלת את הדאטה ומחזירה אותה לקורא של הפונקציה. בזמן הזה שהיא ישנה, התוכנה שלך מושבתת.
בשורה 22 (שרצה אחרי היקיצה מהשינה) אתה בודק אם הלחצן מולחץ, במידה וכן אתה מריץ (שורה 23) ser.close(). הפעולה הזו גורמת שבאיטרציה הבאה של הלולאה כאשר פייתון תנסה לשלוף את הערך הבא עבור הלולאה, היא תקבל תשובה "מצטער, נגמר". זה מפסיק את הלולאה, וגורם ללולאת ה-for להסתיים, הקוד ממשיך אחרי הלולאה. מכיון שלולאת ה-for מקוננת בתוך לולאת while הקוד תחזור שוב ללולאה החיצונית שזה יריץ שוב שורה 21. (האם התכוונת לזה? זה ייכשל כי לכאורה אי אפשר לקרוא ser.read() אחרי הסגירה של הפורט...)




תכונה לא ידועה בוורד - צבירת קטעים בלוח והדבקה של כולם ביחד