• בלוג
  • שיתוף קוד באמצעות גנרטורים

שיתוף קוד באמצעות גנרטורים

21/04/2019

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

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

def get_numeric_input(prompt):
    while True:
        try:
            return int(input(prompt))
        except ValueError as e:
            print("Sorry, only integers are allowed. Please try again")

עכשיו אני יכול להפעיל אותה בלולאה 5 פעמים ולהדפיס את המספר הגדול ביותר:

values = []
for i in range(5):
    values.append(get_numeric_input("Please select a number: "))
print(max(values))

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

res = get_numeric_input("Please select a number: ")
for i in range(4):
    res = max(get_numeric_input("Please select a number: "), res)

print(res)

יש כאן שם של משתנה שהייתי צריך להמציא (res), והקריאה לפונקצית ה input מופיעה פעמיים.

דרך אחרת להגיע לאותו פיתרון היא לעטוף את הפונקציה ב Generator:

def user_numeric_input(prompt):
    while True:
        yield get_numeric_input(prompt)

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

print(reduce(max, islice(user_numeric_input("Please select a number: "), 5)))

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