קורס פיתוח מתקדם בפייתון
פרק
>
רמה
מודולי סיריאליזציה
מודול מבנה
מטרה
קבע את הפירוט הסופי של הנתונים עבור החווה החדשה באמצעות מודול struct.
בסוף הדרך קיימת תחנת שירות המנהלת את החווה החדשה שכבר נבנתה ואת הגידולים שכבר נזרעו. כאן נבחן ונעבד את הנתונים עבור הגידולים שנטענו ואת התפוקה הצפויה של החווה. כמו ברמות אחרות בפרק זה, נעבוד עם סידור ושליפת נתונים (serialization and deserialization), כאשר נציג מודול נוסף בשם struct.
מודול struct מציג סדרה של פונקציות לסידור נתונים שמארזות נתונים בפורמט בינארי. בשונה משאר המודולים שעבדנו איתם, יש לך שליטה רבה יותר על איך ניתן למבנה את הנתונים גם בעת הסידור וגם בעת הביטול, מה שהופך אותו ליותר רב תכליתי ממודולים אחרים. השתמש בimport struct כדי לגשת לפונקציות הבאות בהן נשתמש לעיבוד הנתונים:
struct.calcsize(): קובע כמה בתים נדרשים לאריזת מחרוזת פורמט נתונה. הוא מקבל ארגומנט אחד – הפורמט שברצונך לאמת את גודלו בבתים. הפורמטים בהם נשתמש הם:- integer: מיוצג כ-
'i'והוא הפורמט עבור נתונים המיוצגים במספרים שלמים. - float: מיוצג כ-
'f'והוא הפורמט עבור נתונים המיוצגים במספרים עשרוניים. - double: מיוצג כ-
'd'והוא הפורמט עבור נתונים המיוצגים במספרים עשרוניים מורכבים יותר, כאשר פורמט ה- float אינו מספק.
- integer: מיוצג כ-
struct.pack(): מסדר נתונים לבינארי, כאשר הוא אורז אותם בפורמט שבחרת. הוא יכול לקבל שני ארגומנטים או יותר, כאשר הראשון הוא הפורמט שברצונך להשתמש בו, והארגומנטים הנוספים הם הערכים שברצונך לארוז. הפורמטים הם כפי שתוארו לעיל ויש להוסיף אותם בהתאמה למספר הארגומנטים.struct.unpack(): מבטל את סידור הנתונים הבינארי (deserializes) ומקבל שני ארגומנטים – הראשון הוא הפורמט שאמור להתאים לפורמט שבו נארזו הנתונים, והשני הוא הנתונים המאווזרים.struct.iter_unpack(): מבטל את סידור הנתונים הבינארי בצורה איטרטיבית, ופועל בדומה ל-struct.unpack()אך עובר בלולאה על כל בלוק נתונים בנפרד.struct.pack_into(): גרסה מתקדמת שלstruct.pack(), המקבלת ארבעה ארגומנטים: הפורמט שברצונך להשתמש בו, את חיץ הנתונים שאליו תרצה לארוז את הנתונים, את המיקום בחיץ שבו תרצה שהנתונים ימוקמו, ולבסוף את הנתונים אותם תרצה לארוז.struct.unpack_from(): גרסה מתקדמת שלstruct.unpack(), המקבלת שלושה ארגומנטים: את הפורמט שברצונך להשתמש בו, את חיץ הנתונים ממנו תרצה לבטל את הסידור, ולבסוף את המיקום בחיץ ממנו תרצה לפרק את הנתונים. פעולה זו מאפשרת לפרק חלקים ספציפיים מהנתונים.
צעד לסימון X האור בתחנת השירות ופנה לשולחן. צור שלושה משתנים בשם: integer, float ו-double. נשתמש בהם כדי לאמת את גודל הבתים של כל פורמט באמצעות הפונקציה struct.calcsize(). עבור המשתנה integer השתמש בפונקציה עם 'i' כארגומנט, עבור המשתנה float השתמש בפונקציה עם 'f' כארגומנט, ועבור המשתנה double השתמש בפונקציה עם 'd' כארגומנט. לדוגמה: integer = struct.calcsize('i'). הוסף את שלושת המשתנים לפונקציה המוגדרת מראש write().
צעד לסימון X זהב והשתמש בפונקציה read() כדי לאסוף נתונים על החווה החדשה. רשום את נקודות הנתונים והפורמט לעתיד, ובפרט: Resources, Size ו-Estimate. לאחר מכן, צעד לסימון X האור מעל השטיח הכחול ויצר משתנה בשם blue_data.
באמצעות המשתנה blue_data אחסן את הערך שמחזירה הפונקציה struct.pack(), כאשר כארגומנטים תעביר את הפורמט והערכים שרשמת קודם. בעת כתיבת הפורמט, עליך לשלב את סוגי הפורמטים ליחידה אחת. לדוגמה, הפורמט של integer מסומן כ-'i' כפי שתואר, ואם אתה מוסיף שלושה נתונים מסוג integer, תכתוב זאת כ-'iii'. באותה מידה, אם אתה מוסיף integer, float ו-double, הפורמט יהיה ifd. כאשר מוסיפים את הנתונים, יש להעבירם כערכים נפרדים לארגומנטים. להלן דוגמה כללית:
data_1 = 8 # is an integer data_2 = 2.25 # is a float data_3 = 900.702938103 # is a double blue_data = struct.pack('ifd', data_1, data_2, data_3)
הפונקציה struct.pack() מאפשרת גמישות רבה, בכך שהיא מאפשרת להגדיר איך לעצב את הנתונים ולארוז מספר נקודות נתונים בבת אחת, לפי שיקול דעתך. הוסף את הנתונים שנאספו קודם לפי הדוגמה שלעיל כבסיס. השתמש בפונקציה display() עם blue_data כארגומנט כדי להציג את הנתונים הארוזים.
צעד לסימון X כהה מעל השטיח הכחול ופנה למסך. צור משתנה בשם blue_unpack ואחסן בו את הערך שמחזירה הפונקציה struct.unpack(), כאשר תעביר כארגומנטים את אותו פורמט שבו נארזו הנתונים ואת המשתנה blue_data. הפורמט נכתב באותה צורה שבה נכתבה הפונקציה struct.pack(), כך שתוכל לבטל את אריזת הנתונים באותה צורה שבה נארזו אותם מלכתחילה. השתמש בפונקציה write() עם blue_unpack כארגומנט כדי לאמת את הנתונים שאורגנו קודם.
באותו מיקום, נשתמש גם בפונקציה struct.iter_unpack(). הפונקציה מקבלת את אותם ארגומנטים כמו struct.unpack(), אך היא מעוצבת כלולאה for, מה שמאפשר לעבור על הנתונים במקום להציגם כולה בבת אחת. קוד הפונקציה הוא:
for values in struct.iter_unpack(-insert value-, -insert value-): player.speak(values)
נשתמש בפונקציה speak() כדי להציג את הערכים. עבור הארגומנטים החסרים בפונקציה struct.iter_unpack(), הוסף את אותם הערכים שהשתמשת בהם ב-struct.unpack(), כיוון שאלו וריאציות של אותה הפונקציה מבחינת השימוש.
צעד לסימון X זהב מעל השטיח האדום ופנה לשולחן. השתמש בפונקציה read() כדי לעיין בכמויות הגידולים. רשום את כל הכמויות והפורמט עבור כל גידול. לאחר מכן, צעד לסימון X האור מעל השטיח האדום ויצר אובייקט בשם buffer, והגדר אותו כערך bytearray(16). זהו אוסף של בתים אותו ניתן לגשת אליו לפני האכלוס; לצורכי הפעולה, הוא פועל כאילו הוא בנק נתונים שבו ניתן לאחסן נתונים באופן ידני. המספר 16 מציין את מספר הבתים שניתן לאחסן באובייקט buffer.
השתמש בפונקציה struct.pack_into() כדי לאכלס את האובייקט buffer שיצרת. אין צורך לשמור את הערך המוחזר מהפונקציה במשתנה, כיוון שהפונקציה מוסיפה את הערכים ישירות ל-buffer. נשתמש בפונקציה זו עבור כל אחד מערכי הגידולים שנרשמו, כאשר נספק את הארגומנטים המתאימים.
לדוגמה, עבור הערך של הגידול הראשון, תתקבל לך המידע על הפורמט, מיקום הבתים והכמות. העבר כארגומנט הראשון את הפורמט, כארגומנט שני את האובייקט buffer, כארגומנט שלישי את המיקום ב-buffer שבו תרצה לאחסן את הערך, ולבסוף את הערך אותו תרצה לארוז ולהכניס ל-buffer.
struct.pack_into('i', buffer, 0, 82)
לאובייקט buffer יש 16 בתים כפי שצוין, ובקוד למעלה, הפורמט integer תופס 4 בתים ומוחדר החל מהמיקום 0. משמעות הדבר היא שלאחר הכנסת הנתונים, נותרו 12 בתים פנויים ב-buffer, כאשר המיקום 0-3 תפוסים מהערך שקיבלת, במקרה זה 82. יש לבצע פעולה זו עבור כל נקודות הנתונים של הגידולים שרשמת, בסך הכל שלושה (3) נתונים. השתמש בפונקציה display() והעבר לה את buffer כדי להציג את הנתונים המסודרים.
צעד לסימון X כהה מעל השטיח האדום ופנה למסך. כאן נבטל את אריזת הנתונים כדי לאמת את התוכן ולאשר שהאחסון בוצע כהלכה. צור שלושה משתנים בשם: lettuce, carrots ו-melons. נפרק את הנתונים של כל אחד מהנתונים בנפרד. עבור כל משתנה, אחסן את הערך המוחזר על ידי הפונקציה struct.unpack_from() והעבר כארגומנטים את הנתונים אותם רישמת בעת האריזה. כארגומנט ראשון העבר את הפורמט, כארגומנט שני את האובייקט buffer ממנו תבצע את הפירוק, ולבסוף את המיקום ב-buffer שממנו תרצה לפרק. לדוגמה:
lettuce = struct.unpack_from('i', buffer, 0)
נתונים אלה מתייחסים לדוגמה הקודמת, ויש לבצע את אותה פעולה עבור שני המשתנים הנוספים. לבסוף, הכנס את lettuce, carrots ו-melons לפונקציה המוגדרת מראש write() כדי להשלים את הרמה.