מתכנתים העוסקים בקביעות במלאכתם, יזכו לעיתים תכופות להיתקל באתגרים בתחומים שונים.
דוגמה טובה לאתגר נפוץ שכזה היא יצירת מידע אקראי:
דוגמה טובה נוספת היא עבודה עם תאריכים:
פתירת האתגרים הללו עשויה להיות משימה מורכבת, ולטמון בחובה בעיות ומקרי קצה רבים.
תארו לעצמכם כמה זמן היה נחסך לו היה מישהו פותר את הבעיות הנפוצות הללו עבור כל המתכנתים!
כרעיון, מודול הוא פיסת תוכנה עצמאית המשרתת מטרה מוגדרת.
המטרה יכולה להיות, לדוגמה, טיפול בתאריכים, יצירת נתונים אקראיים או תקשורת עם אתרי אינטרנט.
בפייתון, מודול הוא קובץ המאגד הגדרות ופקודות, שיחדיו יוצרות אוסף כלים בתחום מסוים.
ניקח כדוגמה את המודול random, שמטרתו לעזור לנו ליצור מידע אקראי.
לפני שנוכל להשתמש ביכולותיו של המודול, נצטרך לבקש מפייתון לטעון אותו בעזרת מילת המפתח import:
In [ ]:
import random
פעולה זו טוענת את המודול ומאפשרת לנו להשתמש בו בהמשך הקוד. נהוג להגיד שייבאנו את המודול random.
עכשיו, כשהמודול יובא, אפשר להשתמש בו בקוד התוכנית שלנו באופן שיענה על הצורך ליצירת דברים אקראיים.
כדי להבין איך להשתמש במודול ומהן יכולותיו, נוכל לקרוא מידע נוסף על אודותיו במגוון דרכים:
python documentation randomבמנועי חיפוש.
dir(random).random. ונלחץ Tab ↹.
במשחק הפוקימון "פוקימון אדום" אפשר לבחור בתור הפוקימון ההתחלתי את בלבזאור, את סקווירטל או את צ'רמנדר.
על הפוקימון הטוב ביותר לבחירה ניטשים ויכוחים רבים עוד מאז שחרורו של המשחק ב־1996.
כדי לא להיקלע לעין הסערה, נבנה תוכנה שתבחר את הפוקימון עבורנו באופן אקראי.
התיעוד של המודול random, כולל פונקציה בשם choice, שבאמצעותה נוכל לבחור איבר אקראי מתוך iterable.
השימוש בתיעוד מומלץ במיוחד בהקשרי מודולים, שכן ההסברים שם בהירים, ופעמים רבות מובאות שם דוגמאות לשימוש בפונקציות של המודול.
נייבא את random ואז נשתמש ב־choice:
In [ ]:
import random
pokemons = ['Bulbasaur', 'Squirtle', 'Charmander']
starter_pokemon = random.choice(pokemons)
print(starter_pokemon)
לא היינו יכולים להשתמש ב־random.choice לולא היינו מייבאים את random.
מרגע שייבאנו את המודול – נוכל להשתמש בו לאורך כל הקוד.
השתמשו בפונקציה הנמצאת במודול random כדי לדמות הטלת קובייה בעלת 20 פאות (D20).
הגרילו מספר בין 1 ל־20, הפעם בעזרת פונקציה שהיא לא choice.
השתמשו במקורות המידע שצוינו כדי למצוא את הפונקציה המתאימה למשימה.
חשוב!
פתרו לפני שתמשיכו!
אלו, בין היתר, היתרונות של שימוש במודולים הקיימים בפייתון:
רוב התוכנות שבהן אתם משתמשים נעזרות במספר לא מועט של מודולים.
כרגע נתמקד בשימוש במודולים שמגיעים עם פייתון, אך בעתיד נשתמש במודולים שיצרו מתכנתים אחרים, ואף ניצור מודולים בעצמנו.
איש דג החרב מגדיר "מחולל סיסמאות חזקות" כך:
כתבו מחולל סיסמאות חזקות.
על אף שזהו תרגיל נחמד, לעולם לא נשתמש ב־random לצורכי אבטחת מידע.
להרחבה, קראו על יתרונותיו של המודול secrets.
עצרת של המספר $n$ (המסומנת כ־$n!$) היא מכפלת כל המספרים השלמים החיוביים עד $n$, כולל.
נחשב את העצרת של 6 באמצעות המודול math:
In [ ]:
import math
print(math.factorial(6)) # 1 * 2 * 3 * 4 * 5 * 6
במקרה שהצגנו, אין לנו באמת צורך בכל הפונקציות הנמצאות במודול math, אלא רק בפונקציה factorial.
תעלול נחמד שאפשר לעשות הוא לייבא רק את factorial באמצעות מילת המפתח from:
In [ ]:
from math import factorial
print(factorial(6))
כדאי לשים לב שלאחר שייבאנו בעזרת from נשתמש ישירות ב־factorial, מבלי להזכיר את השייכות שלה למודול math.
אפשר גם לייבא יותר משם אחד מאותו מודול, במכה אחת:
In [ ]:
from math import cos, pi
print(cos(pi))
באופן כללי, העדיפו לייבא את המודול כולו ולא חלקים מתוכו.
זה יעזור לכם להימנע מיצירת מקרים מבלבלים כמו זה:
In [ ]:
from math import e
# (דמיינו הרבה קוד כאן)
print(e) # ?לרוב הוא שם משתנה שתוכנו שגיאה, האם זה המקרה גם פה e ?מאיפה זה הגיע
אם ממשיכים בכיוון, פייתון מאפשרת לנו לעשות את הדבר המזעזע הבא:
In [ ]:
from math import *
יבוא בעזרת כוכבית יגרום לכך שכל מה שמוגדר במודול "יישפך" לתוך התוכנית שלנו.
זה יאפשר לנו להשתמש בכל התוכן של math בלי להזכיר את שם המודול:
In [ ]:
print(f"floor(5.5) --> {floor(5.5)}")
print(f"ceil(5.5) --> {ceil(5.5)}")
print(f"pow(9, 2) --> {pow(9, 2)}")
print(f"e --> {e}")
פרקטיקה זו נחשבת מאוד לא מנומסת, ואתם מתבקשים לא להשתמש בה, אלא אם כן אלו ההוראות הכתובות בתיעוד של המודול.
ישנן לא מעט סיבות הגיוניות מאחורי איסור זה:
המודול turtle הוא דרך פופולרית ללמד ילדים תכנות באמצעים גרפיים.
תכנות ב־turtle הוא מעין משחק: ישנו צב שהולך במרחב, ומשאיר צבע בכל מקום שאליו הוא מגיע.
אפשר להורות לצב בכמה מעלות להסתובב לכל כיוון, ולאיזה מרחק ללכת בכיוון שאליו הוא מופנה.
כך, בסוף מסלול הטיול של הצב, מתקבל ציור מלא חן.
הרעיון נוצר כחלק משפת התכנות Logo בשנת 1967.
נראה דוגמה לתוצר של ריצת תוכנית שכזו, שבה אנחנו משרטטים 100 ריבועים בהיסט של מעלה אחת בכל פעם.
אנחנו ממליצים לשחק עם המודול קצת (זה כיף!) ולראות אם אתם מצליחים לצייר כוכב, לדוגמה :)
In [ ]:
import turtle
turtle.speed(10)
for i in range(400):
turtle.forward(50 + i)
turtle.right(91)
turtle.done()
הרצת קוד של turtle תפתח לכם חלון חדש בו יצויר פלט התוכנית.
כדי להמשיך להריץ את התאים במחברת, סגרו את החלון.
כדי לשנות את השם שבו אנחנו מתייחסים למודול, ניעזר במילת המפתח as.
לדוגמה:
In [ ]:
import turtle as kipik
kipik.speed(100) # קיפיק מהיר הרבה יותר מצב רגיל
for i in range(400):
kipik.forward(50 + i)
kipik.right(91)
kipik.done()
כך אפשר לקצר את שם המודול שאנחנו מייבאים, ולהימנע מסרבול מיותר.
למרות זאת, יבוא מודול תחת שם אחר נחשב פרקטיקה לא מנומסת, שעלולה לבלבל קוראים שבקיאים בשמות המודולים הקיימים.
ישנם שני מקרים יוצאי דופן, שבהם השימוש ב־as נחשב רצוי:
as במסמכי התיעוד של המודול.
לשימוש במודולים יש כללי סגנון שמוסכמים על רוב המתכנתים.
הם מופיעים במסמך בשם PEP8, שמטרתו להגדיר איך נראה קוד פייתון המסוגנן כראוי.
הנה כמה כללים שראוי שתעקבו אחריהם:
from ליבוא של יותר משם אחד – השמות צריכים להיות מסודרים בסדר מילוני.מה התאריך היום?
In [ ]:
import datetime
print("What is the time now?")
print(datetime.datetime.now())
נשתמש במודול calendar כדי להדפיס את לוח השנה של החודש הנוכחי:
In [ ]:
from calendar import prmonth as print_calendar # לא מנומס, אבל דוגמה טובה
import datetime
current_date = datetime.datetime.now()
print_calendar(current_date.year, current_date.month)
import על כך שאנחנו הולכים להשתמש במודול מסוים בקוד שלנו.
בתרגילים הבאים השתמשו באינטרנט כדי למצוא מודולים ופונקציות שיסייעו לכם לפתור את התרגיל.
נסו להימנע מחיפוש ומקריאה של פתרונות לתרגיל המסוים המופיע במחברת (כמו חיפושים הכוללים "חפיסת קלפים").
כתבו פונקציה שמקבלת נתיב לתיקייה, ומחזירה את רשימת כל הקבצים שמתחילים ברצף האותיות "deep" באותה תיקייה.
בדקו שהפעלת הפונקציה על התיקייה images מחזירה שני קבצים.
בחפיסת קלפים רגילה, שבה 52 קלפים, יש לכל קלף שתי תכונות:
כל צירוף של ערך וצורה מופיע בחפיסה בדיוק פעם אחת.
כתבו פונקציה שמקבלת תאריך עתידי בתצורה YYYY-MM-DD, ומדפיסה את מספר הימים שנשארו עד שנגיע לתאריך המיוחל.
לדוגמה, אם התאריך היום הוא 2020-05-04 וקיבלנו כקלט 2020-05-25, הפונקציה תחזיר 21.
כתבו תוכנה שמקבלת כקלט מהמשתמש שני תאריכים בתצורה: YYYY-MM-DD.
התוכנה תגריל תאריך חדש שנמצא בין שני התאריכים שהמשתמש הזין כקלט.
לדוגמה, עבור הקלטים 1912-06-23 ו־1954-06-07, פלט אפשרי הוא 1939-09-03.
כיוון שאני הולך למכולת רק בימי שני ואני צרכן כבד של רוטב ויניגרט, אם התאריך נופל על יום שני, הדפיסו: "אין לי ויניגרט!"
רמז: קראו על EPOCH.