ניתוח נתוני ספרייה בפייתון

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

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

שם הספרכמות עותקיםעלות
Harry Potter340
Da-VInci Code560
Diary of a Wimpy Kid250
Ali Baba425

המידע על הספרים נשמר במשתנה books מטיפוס מחרוזת (string). פרטי הספרים מופרדים באמצעות 'n\', כדוגמת משפט
ההשמה הבא:

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

  1. את מספר הספרים בספרייה.
  2. את השווי של מלאי הספרים בספרייה. בחישוב זה יש לסכוֹם את מכפלת עלות רכישת הספר במספר העותקים
    שלו בספרייה.
  3. רשימה ובה שמות כל הספרים שמספר העותקים שלהם קטן מ–10.

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

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

הכנת הנתונים

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

אז עכשיו הנתונים שלנו נראים ככה:

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

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

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

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

1. מספר הספרים בספרייה

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

2. שווי מלאי הספרים בספרייה

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

3. רשימה ובה שמות כל הספרים שמספר העותקים שלהם קטן מ–10

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

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