פרויקט Matplotlib

דף זה מכיל את הפרטים של פרויקט כתיבה טכני שהתקבל בעונת Google Docs.

סיכום הפרויקט

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

תיאור הפרויקט

למה בחרנו לעשות זאת?

בעבר, ה-API של matplotlib הסתמך במידה רבה על מחרוזת כ-enum ""סוגים משתמעים". מלבד חיקוי ה-API של matlab, מחרוזות הפרמטרים האלה מאפשרות למשתמש להעביר ערכים עשירים מבחינה סמנטית כארגומנטים לפונקציות matplotlib, בלי לייבא באופן מפורש ערך enum בפועל או להוסיף לו תחילית מילולית רק כדי להעביר אפשרויות גרף בסיסיות (כלומר, קל יותר להקליד plt.plot(x, y, linestyle='solid') ופחות מיותר מערך כמו plt.plot(x, y, linestyle=mpl.LineStyle.solid)).

רבים מהסוגים המשתמעים האלה של מחרוזת כטיפוסים בני מנייה (enum) התפתחו מאז לתכונות מתוחכמות יותר. לדוגמה, linestyle יכול עכשיו להיות מחרוזת או שני צמדים של רצפים, ו-MarkStyle יכול עכשיו להיות מחרוזת או matplotlib.path.Path. זה נכון לגבי סוגים רבים של משתמע, אבל MarkStyle הוא היחיד (למיטב ידיעתי) שיש לו סטטוס של שדרוג למחלקה Python מתאימה.

מכיוון שהסוגים המשתמעים האלה הם לא מחלקות כשלעצמם, בעבר, Matplotlib היה צריך להשתמש בפתרונות משלו כדי לרכז את התיעוד והאימות של הסוגים המשתמעים האלה (למשל, דפוס האינטרפולציה של docstring של docstring.interpd.update ודפוס התיקוף של cbook._check_in_list, בהתאמה) במקום להשתמש בשרוכי הכלים הרגילים שסופקו על ידי סיווגים של Python (למשל, תיקוף, מחרוזות ומחרוזות __init__ בהתאמה).

הפתרונות האלה עבדו היטב עבורנו, אבל היעדר מיקום מפורש בתיעוד של כל סוג מרומז פירושו שלרוב קשה למצוא את התיעוד. טבלאות גדולות של ערכים מותרים חוזרות על עצמן לאורך כל התיעוד, ולעיתים קרובות חסרה הצהרה מפורשת לגבי ההיקף של סוג מרומז. ניקח לדוגמה את מסמכי plt.plot: ב-"Notes", תיאור של שיטת הסגנון דמוית ה-Matlab מציין את האפשרויות linestyle, color ו-markers. יש הרבה דרכים להעביר את שלושת הערכים האלה, אבל משתמשים רבים זה המקור היחיד להבנת הערכים האפשריים באפשרויות האלה, עד שהם נתקלים באחד מהמדריכים הרלוונטיים. טבלה של המאפיינים Line2D כלולה בניסיון להראות לקורא אילו אפשרויות יש לו לשליטה בעלילה. עם זאת, בעוד שהערך linestyle מבצע קישור תקין אל Line2D.set_linestyle (נדרשים שני קליקים), כאשר הקלט האפשרי מתואר, הערכים color וערכי markers לא כן. color פשוט מקשר אל Line2D.set_color, שלא מאפשר אינטואיציה כלשהי לגבי סוגי הקלט המותרים.

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

סיום היעד

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

אם נשתמש שוב בדוגמה של linestyle, מה שרצינו שיהיה במסמכים LineCollection הוא רק:

  1. קישור להשלמת מסמכים עם מקורות קלט מותרים (שילוב של המסמכים שמופיעים ב-Line2D.set_linestyle ובמדריך לסגנון שורות).
  2. תיאור פשוט של מה שהפרמטר נועד להשיג. למשתמשים מתקדמים של matplotlib זה ברור מהשם של הפרמטר, אבל זה לא חייב להיות המצב אצל משתמשים חדשים.

כך זה ייראה במסמכי LineCollection עצמם הוא רק python """""" linestyles: `LineStyle` or list thereof, default: :rc:`lines.linestyle` ('-') A description of whether the stroke used to draw each line in the collection is dashed, dotted or solid, or some combination thereof. """""" שבו ההתייחסות מסוג LineStyle תיקבע על ידי Sphinx כדי להפנות למערך התיעוד היחיד, המוסמך והמלא, לגבי האופן שבו Matplotlib מטפל בסגנון קו.

יתרונות

הגישה הזו כוללת כמה תכונות מועילות:

  1. הצגת ההיקף המלא של מה שכל פונקציה מסוגלת לברור בטקסט פשוט (ללא צורך בקליקים).
  2. הפיכת אפשרות ברירת המחדל לגלויה (ללא קליקים). הצגת אפשרות ברירת המחדל לעיתים קרובות מספיקה כדי להפעיל את הזיכרון של משתמשים חוזרים.
  3. תאר באופן מלא את האפשרויות 'הנפוצות ביותר' ו'הקלות ביותר' לפרמטר שיהיו זמינות בקלות במהלך הגלישה (בלחיצה אחת).
  4. אתם יכולים לפשט את התהליך של גילוי תכונות ושיטות קלט חזקות יותר כמו "גלילה למטה" כדי לראות אפשרויות מתקדמות יותר (עדיין בלחיצה אחת בלבד).
  5. לספק אסטרטגיה מרכזית לקישור מסמכי 'API' ברמה העליונה ל'מדריכים' הרלוונטיים.
  6. הימנעו מפיצוץ מסמכים ב-API, כאשר סריקה של האפשרויות הרבות האפשריות לכל פרמטר גורמת ליצירה של מחרוזות docstring בודדות.

יתרונות נוספים לגישה הזו על פני המסמכים הנוכחיים הם:

  1. בגלל הריכוז של המסמכים, יש פחות סיכוי שמסמכי Docs לא יהיו עדכניים.
  2. קנוניזציה של רבים מ"הסטנדרטים המשתמעים" של matplotlib (כמו "גבולות" לעומת "גבולות") שצריך ללמוד כיום על ידי קריאת הקוד.
  3. התהליך ידגיש בעיות בעקביות ה-API כך שקל יותר לעקוב אחרי הבעיות באמצעות הכלי למעקב אחר בעיות ב-GitHub, דבר שיעזור לנו לשפר את ה-API.
  4. זמני build מהירים יותר של מסמכים, בגלל ירידה משמעותית בכמות הטקסט שצריך לנתח.

הטמעה

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

אחרי השלמת התיעוד המרכזי לסוג משתמע נתון, מתחיל המאמץ השני הגדול: החלפת מסמכי ה-API הקיימים בקישורים למסמכי התיעוד החדשים, במטרה להפוך את חוויית השימוש בפועל במסמכי התיעוד החדשים לקלה ככל האפשר, גם לאלו שמשתמשים בכלי help() המובנה של Python וגם למשתמשים שמעיינים במסמכים שלנו באינטרנט.

למרות שהפורמט המדויק של המסמכים המוצעים כאן עשוי להשתנות עם התפתחות הפרויקט, פעלתי בשיתוף עם צוות הליבה של Matplotlib במהלך "שיחות הפיתוח" השבועיות שלהם כדי להגיע להסכמה לגבי האסטרטגיה המוצעת היא הגישה המומלצת, השימושית והמתקבלת מבחינה טכנית ביותר כדי להתחיל לתעד את "הקריאות המרומזות האלו" (הערות לגבי "הקריאות המרומזות" האלו זמינות). אני אשתמש בתשתית 'מדריכים' הקיימת בשלבים הראשונים של יצירת התיעוד המרכזי לכל סוג משתמע, כך שיהיה לי קל להפנות לדפים האלה באופן הבא, בלי שאצטרך ליצור כיתות ציבוריות חדשות (שוב, באמצעות המסמכים ב-LineCollection כדוגמה):

""""""
linestyles: LineStyle or list thereof, default: :rc:`lines.linestyle` ('-')
    A description of whether the stroke used to draw each line in the collection
    is dashed, dotted or solid, or some combination thereof. For a full
    description of possible LineStyle's, see :doc:`tutorials/types/linestyle`.
""""""

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

לבסוף, הרשימה הראשונית של הסוגים המשתמעים שאני מציע לתעד במהלך עונת Google Docs הנוכחית היא:

  1. capstyle
  2. joinstyle
  3. bounds
  4. extents
  5. linestyle
  6. colors/lists of colors
  7. colornorm/colormap
  8. tick formatters

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