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

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

ושוב

18/08/2018

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

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

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

טיפ גיט: אפשר להוסיף הודעות ל Stash שלכם

16/08/2018
git

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

[1]
$ git checkout -b new-router
$ # ... work work work
$ # oh no - production error, must fix something in master

[2]
$ git stash
$ git checkout master
$ # fix and deploy

[3]
$ git checkout new-router
$ git stash pull

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

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

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

הפקודה:

$ git stash save 'started writing CSS for the new router but big production bug stopped me'

תשמור את השינויים בצד יחד עם ההודעה.

הפקודה:

$ git stash list

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

$ git stash list stash^{/big}

תציג את כל השינויים שההודעה שלהם כוללת את המילה big ולסיום הפקודה:

$ git stash apply stash^{/big}

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

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

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

https://www.tocode.co.il/workshops/43

סיווג אחר לתקלות תוכנה

15/08/2018

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

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

אפשר להתחיל מהסולם הבא:

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

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

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

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

  5. אני יכול לתקן את זה אבל זה ידרוש Down time של שרת הייצור לכמה שעות.

  6. אני יכול לתקן את זה בלי לאבד מידע, תוך שינוי ממוקד רק של הקוד הבעייתי.

  7. אני יכול לתקן את זה ויש לי בדיקות אוטומטיות לוודא שהתיקון לא שובר התנהגות ישנה.

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

איך נבדוק בפייתון שמשהו הוא מספר

14/08/2018

נתונה תוכנית פייתון קצרה המקבלת קלט ממשתמש וצריכה לוודא שהקלט הוא מספר. בואו בשביל המשחק נוסיף לו 7 ונדפיס את התוצאה:

x = input('please select a number: ')
print(float(x) + 7)

מה עושים אם המשתמשים שלכם לא כאלה נחמדים ומכניסים ערך שאינו מספר? הרצת התוכנית תיראה כך:

localhost:~ ynonperek$ python3 a.py
please select a number: yo
Traceback (most recent call last):
  File "a.py", line 2, in <module>
    print(float(x) + 7)
ValueError: could not convert string to float: 'yo'

ופייתון מתלונן בצדק שאי אפשר להמיר את yo למספר.

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

use strict;
use Scalar::Util qw/looks_like_number/;

print "please select a number: ";
my $x = <>;

if (looks_like_number($x)) {
  print($x + 7, "\n");
} else {
  print("Not a number\n");
}

לפייתון אין פונקציה looks_like_number וכל מיני ניסיונות למצוא דברים דומים יתנו לכם תוצאות לא נכונות. הנה למשל הפונקציה isnumeric שנראית ממש מתאימה:

>>> '1'.isnumeric()
True
>>> '15'.isnumeric()
True
>>> 'a'.isnumeric()
False

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

>>> '-5'.isnumeric()
False
>>> '1.2'.isnumeric()
False

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

try:
    x = input('please select a number: ')
    print(float(x) + 7)
except ValueError:
    # value is not a number
    print("sorry not a number")

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

מי צריך ללמוד גיט

13/08/2018
git

למתכנתים וותיקים שעבדו עם כלי ניהול גירסאות בעבר אמור לקחת בדיוק עשר דקות למצוא את שתי הפקודות החשובות בגיט: checkout ו commit. עוד כמה שעות של עבודה ואתם כבר שולטים גם ב add ו clone ואולי אפילו ב diff ויכולים להמשיך לעבוד כאילו אתם עדיין עם SVN. עד שמתחילות הצרות.

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

סיבה שניה היא פוטנציאל הרווח. כי אם אתם עובדים בגיט כמעט בטוח שאתם יכולים להפיק יותר מהכלי אם תדעו לעבוד נכון עם בראנצ'ים, לשלב ביניהם ולהזיז קוד בין הבראנצ'ים השונים. ואם תכירו טוב את ההבדל בין ה Staging Area, ל Local Repository ול Remote Repository תוכלו להשתמש בצורה חכמה יותר בכל אחד.

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

הרשמה בחינם בקישור:

https://www.tocode.co.il/workshops/43

פאזלים

12/08/2018

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

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

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

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

קודם כל כן

11/08/2018

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

https://hackernoon.com/the-trap-of-sales-driven-development-89e16c5e292f

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

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

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

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

לקום וללכת

10/08/2018

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

״הלקוח שלי לא נותן לי לכתוב בדיקות בפרויקט״

״הלקוחה שלי מתעקשת שהאתר יהיה כתוב בוורדפרס״

״נמאס לרדוף אחרי לקוחות שלא משלמים... מי המשוגע שהמציא את השוטף + 120 ?״

״איך אפשר לעבוד ככה עם כל הפגישות האלה?!״

אבל מסתבר שכשאנחנו מתעקשים על שלנו לקוחות טובים יותר באים והקריירה שלנו לוקחת כיוון הרבה יותר מוצלח לטווח הרחוק:

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

״אני לא בונה אתרי וורדפרס״

״מדיניות התשלום אצלנו היא נט + 30 ואני עובד רק עם לקוחות ששילמו מקדמה״

״כל פגישה עם הלקוח מחויבת בתשלום של שעת ייעוץ כולל פגישות היכרות עם לקוחות חדשים״.

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

כמעט נכון

09/08/2018

היתה לי היום בעיה עם CSS - רציתי לייצר אלמנט שנפתח באנימציה לגובה שמחושב באופן אוטומטי לפי הגובה של הילדים. הנה הניסיון הראשון:

.item {
    transition: all 0.5s;
}

.close {
    height: 0;
    overflow: hidden;
}

.open {
    height: auto;
}

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

הלכתי לחבר Stack Overflow לראות מה ההמלצות וכמובן שאני לא הראשון שניסיתי את זה. ההצעה שם היתה להשתמש בגובה מקסימלי כדי לייצר את האנימציה: כלומר תגדירו גובה מקסימלי 0 במצב סגור וגובה מקסימלי ממש גבוה למצב פתוח וכך נקבל אנימציה על ה max-height. הגובה האמיתי נקבע ל auto והכל (כמעט) יעבוד:

.item {
    transition: all 0.5s;
}

.close {
    max-height: 0;
    overflow: hidden;
}

.open {
    max-height: 1000px;
}

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

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

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

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