הבלוג של ינון פרק

טיפים קצרים וחדשות למתכנתים

הגיע הזמן להפסיק להשתמש ב Debugger

02/01/2021

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

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

המשך קריאה

לא חשבתי שאפשר

01/01/2021

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

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

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

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

איך לברוח מלולאה כפולה ב Python

31/12/2020

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

for i in values:
    for j in values:
        for k in values:
            if i != j and j != k and i + j + k == 2020:
                print(f"Found! {i}, {j}, {k}")
                break

זה עובד, אבל... כך נראית התוצאה:

Found! 289, 480, 1251
Found! 289, 1251, 480
Found! 480, 289, 1251
Found! 480, 1251, 289
Found! 1251, 289, 480
Found! 1251, 480, 289

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

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

def triplets(values):
    for i in values:
        for j in values:
            for k in values:
                if i != j and j != k:
                    yield(i, j, k)


for i, j, k in triplets(values):
    if i + j + k == 2020:
        print(f"Found! {i}, {j}, {k}")
        break

פה הייתי צריך לקחת את הלולאה החוצה ולהגדיר אותה בפונקציה נפרדת בתור Generator שזה קצת מעצבן, אבל אחרי שעשיתי את זה אני יכול להמשיך להתייחס ללולאה בתור לולאה "רגילה" בה break עובד.

הפונקציה itertools.product היא דרך גנרית לבנות כזה מנגנון ובצורה מקוצרת כך שהקוד הבא עובד מעולה:

import itertools
for i, j, k in itertools.product(values, values, values):
    if i != j != k and i + j + k == 2020:
        print(f"Found! {i}, {j}, {k}")
        break

ובמקרה הספציפי שלנו שאנחנו רוצים 3 מספרים שונים נוכל לקצר תהליכים צעד אחד נוסף באמצעות הפונקציה itertools.combinations שכבר דואגת להחזיר לנו רק שלשות של מספרים שונים:

for i, j, k in itertools.combinations(values, 3):
    if i + j + k == 2020:
        print(f"Found! {i}, {j}, {k}")
        break

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

מילים ומשפטים

30/12/2020

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

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

מצד שני ברגע שלמדנו מבנה מסוים אנחנו יכולים להשתמש בו בשפות חדשות ככל שנלמד את המילים בהן. לכן תוכנית שמדפיסה את לוח הכפל תיראה מאוד דומה ב C, perl, ruby, python, JavaScript או כל שפה פרוצדורלית אחרת שתיקחו. ברגע שיש בשפה תמיכה בלולאות for עם משתנה רץ, יהיה לנו קל לבנות בה את לוח הכפל. וברגע שיש בשפה פונקציות אנחנו יכולים לבנות בה את הרקורסיה, גם אם התחביר של הגדרת פונקציה וקריאה לה יהיו שונים בין שפות.

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

אני יודע את זה

29/12/2020

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

"אני יודע את זה" הוא הרגע בו אפשר להפסיק לחפש ברשת כל מיני רעיונות יצירתיים איך להתמודד עם הבעיה ופשוט להתקדם עם הדבר שאנחנו יודעים עד שנגיע לפיתרון. אם מישהו יבקש ממני מחר למרכז div ב CSS, אני מתחיל עם "אני יודע את זה" ואז ממשיך ליצור את הפלקסבוקס ולמרכז את התוכן. גם אם חסר לי סינטקס, החיפוש ברשת כבר לא יהיה חיפוש כללי של "איך לכתוב תוכן באמצע העמוד באמצעות CSS" אלא משהו יותר ספציפי כמו "Flexbox reference" או אפילו "flexbox align items example".

ואני יודע את זה הוא המפתח להערכות זמנים חכמות, כי הוא מאפשר להבדיל בין אי הוודאות של התכנות (החלק בו אנחנו מחפשים כל מיני כיוונים ולא ממש יודעים מה אנחנו עושים), לבין העבודה המלוכלכת של כתיבת הקוד.

והחלק הקשה? זה יהיה לזהות מתי "אני יודע את זה" יהפוך ל "הייתי בטוח שאני יודע את זה ועכשיו אני מבין שטעיתי בגדול".

קונדה-מה?

28/12/2020

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

המשך קריאה

לא חדש

27/12/2020

רובי 3 יצא השבוע ואחד הפיצ'רים המלהיבים בו הוא התמיכה ב Type Hints. אבל כשנכנסים לפרטים מזהים ש:

  1. התמיכה ב Type Hints היא בסך הכל שילוב כברירת מחדל של ספריה שכבר קיימת תקופה ארוכה שנקראת rbs.

  2. התחביר של Type Hints מוכר כבר לכל מי שהיה בשיחה הזאת - והוא פשוט תחביר rbs.

  3. ה Type Checker (נקרא steep) לא נכלל כחלק מרובי, אבל גם הוא כבר נמצא בפיתוח תקופה ארוכה ומתמודד מול Type Checker בתחביר אחר שנקרא Sorbet.

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

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

הפי אנד

26/12/2020

הרבה פעמים כשאתה מסתכל על מערכת ומנסה להוסיף פיצ'ר מסוים אתה נתקע על שטויות-

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

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

"אולי עדיף לבנות Stored Procedure במקום לכתוב את השאילתה בקוד, כי במקרה דומה בו כתבתי את השאילתה בקוד הביצועים היו ממש גרועים"

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

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

טיפים לעבודה יעילה על מספר סביבות פייתון במקביל

25/12/2020

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

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

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

המשך קריאה

לחץ ולימודים

24/12/2020

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

ובאותו הזמן לחץ הוא גם האויב הכי גדול של הלימוד. השאלה "האם זה יהיה במבחן?" היא ההיפך מכל מה שאני מדמיין כשאני חושב על לימודים ועל גיוס מועמדים שמכירים לעומק את הנושא.

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