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

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

אנטי-תבניות שלמדתי בבית ספר

10/03/2019

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

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

המשך קריאה

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

09/03/2019

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

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

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

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

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

בוא נחכה עם זה

08/03/2019

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

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

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

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

התאמה אישית של פרויקט Bootstrap4

07/03/2019

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

המשך קריאה

ומה אם היו לך שנתיים?

06/03/2019

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

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

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

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

קצב

04/03/2019

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

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

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

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

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

למה צריך כפתור מיוחד כדי לעבוד עם קבצים בינאריים?

03/03/2019

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

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

import binascii

def write_stuff_to_file(fname):
    with open(fname, 'w') as f:
        f.write('\x10')

def read_stuff_from_file(fname):
    with open(fname, 'r') as f:
        stuff = f.read()
        print(binascii.hexlify(stuff.encode('utf-8')))

write_stuff_to_file('demo.txt')
read_stuff_from_file('demo.txt')

התוכנית כותבת את הביטים של המספר 10 לקובץ בשם demo.txt ואז קוראת מהקובץ את אותם ביטים ומדפיסה אותם על המסך. התוצאה:

b'10'

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

import binascii

def write_stuff_to_file(fname):
    with open(fname, 'w') as f:
        f.write('\x0d')

def read_stuff_from_file(fname):
    with open(fname, 'r') as f:
        stuff = f.read()
        print(binascii.hexlify(stuff.encode('utf-8')))

write_stuff_to_file('demo.txt')
read_stuff_from_file('demo.txt')

ועכשיו התוצאה:

b'0a'

מה קרה כאן? כתבתי לקובץ את המספר 13 וקיבלתי בחזרה את המספר 10. נלך לראות מה כתוב בקובץ:

$ xxd demo.txt 
00000000: 0d

לפחות הכתיבה עבדה כמו שצריך. בקובץ באמת כתוב המספר 13 (שמודפס בתור d בכתיב הקסדצימלי), אבל כשאנחנו קוראים את זה מתוך תוכנית פייתון אנחנו מקבלים את המספר 10. מסתבר שכשאתם קוראים קובץ בתור קובץ טקסט פייתון ינסה לתקן לכם את תווי ירידת השורה שבקובץ. התו שמיוצג על ידי המספר 13 נקרא CR ומשתמשים בו כשיורדים שורה על מכונות Windows. על מק תו ירידת השורה נקרא LF ומיוצג על ידי המספר 10, ולכן כשקוראים מקובץ טקסט את המספר 13 על מכונת מק פייתון מניח שאנחנו קוראים קובץ טקסט שמישהו כתב על Windows ולכן מחליף את תו ירידת השורה כדי שיסתדר עם מה שמתאים למק.

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

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

בחזרה לתוכנית הקודמת - שינוי הפקודה open לעבודה עם מידע בינארי יבטל את המרת תווי ירידת השורה ויגרום לתוכנית לעבוד ולקרוא מהקובץ בדיוק את אותו מידע שכתבנו:

import binascii

def write_stuff_to_file(fname):
    with open(fname, 'wb') as f:
        f.write(b'\x0d')

def read_stuff_from_file(fname):
    with open(fname, 'rb') as f:
        stuff = f.read()
        print(binascii.hexlify(stuff))

write_stuff_to_file('demo.txt')
read_stuff_from_file('demo.txt')

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

fname = 'demo.txt'
with open(fname, 'r', encoding='utf-8') as f:
    pass

לא חשבתי שזה יעבוד

02/03/2019

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

וכשזה באמת לא הצליח אז עזבתי והלכתי לעשות משהו שאני טוב בו.

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

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

(וההזמדנות בסיפור הזה? מסתבר שאפשר לחסוך הרבה כסף אם אתם מצליחים להפוך לאנשים שיודעים שהם יכולים).

שאלות לא הוגנות

01/03/2019

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

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

function foo() {
    var a = b = 5;
    console.log(typeof(a));
    console.log(typeof(b));
}

foo();
console.log(typeof(a));
console.log(typeof(b));

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

function foo() {
    var a = 5;
    b = 5;

    console.log(typeof(a));
    console.log(typeof(b));
}

foo();
console.log(typeof(a));
console.log(typeof(b));

עכשיו הכל ברור. השאלה בודקת אם את יודעת את ההבדל בין הגדרת משתנה עם var להגדרה בלעדיו, ואנחנו יכולים לדבר על זה (ועל הדרך לדבר גם על let ו const ו window ו this ומתי נגדיר משתנים גלובליים, ואיזה עוד משתנים גלובליים יש בתוכנית הזאת).

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