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

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

שורה אחת שעושה את הכל

20/03/2018

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

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

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

במחשבים אין קסמים. עדיף להכניס לקוד רק דברים שמבינים.

הכל או כלום

19/03/2018

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

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

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

השוואה בין הטמעת 4 ספקי סליקת אשראי לאתר שלכם

18/03/2018

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

המשך קריאה

כשגוגל טועה

17/03/2018

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

sum('123' - '0')

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

sum(int(x) for x in ['1', '2', '3'])

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

בדוגמא כאן חיפוש בגוגל עבור "python substract string from list" מוצא המון תוצאות לא רלוונטיות (בעיקר על הפונקציה remove), לעומת זאת החיפוש "python convert list to integers" מציג את הפיתרון כבר בתוצאה הראשונה. כשגוגל טועה זה כמעט תמיד בגלל ששאלנו את השאלה הלא נכונה.

ינון קונספט

16/03/2018

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

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

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

import fileinput
from functools import reduce
from itertools import chain

def longer(acc, val):
    if len(acc) > len(val):
        return acc
    else:
        return val

def flatten(listOfLists):
    return chain.from_iterable(listOfLists)


print(
    reduce(
        longer,
        flatten(
            map(
                lambda s: s.split(),
                fileinput.input()
            )
        )
    )
)

ואותה התוכנית בשפת Ruby:

class String
  def longer(other)
    length > other.length ? self : other
  end
end

puts ARGF.flat_map(&:split).reduce(&:longer)

ואותה התוכנית בשפת Elixir:

defmodule My do
  def longer(val, acc) do
    if String.length(acc) > String.length(val) do
      acc
    else
      val
    end
  end
end

IO.stream(:stdio, :line)
|> Enum.flat_map(&String.split/1)
|> Enum.reduce(&My.longer/2)
|> IO.puts

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

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

מרגיש כמו שיעורי בית

15/03/2018

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

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

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

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

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

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

יש לכם עוד רעיונות? ספרו בתגובות אשמח לשמוע.

דרישות קדם

14/03/2018

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

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

יש טכנולוגיות חדשות שפשוט מוסיפות יכולות ומפשטות מקרי קצה בעייתיים. אין בעיה לכתוב C++ בלי לדעת כלום על C++11, 14 או 17, אבל מי שכן יודע על הרחבות אלו יוכל לכתוב קוד הרבה יותר מדויק. אין בעיה לכתוב היום JavaScript ES5 אבל מי שיודע גם ES6/7/8 יוכל לכתוב את אותם הדברים בצורה יעילה יותר. ובכל מקרה במצבים כאלה לחדש אין קיום בלי הישן.

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

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

תרגילים טובים וטובים פחות

13/03/2018

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

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

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

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

פרשת רמיני

12/03/2018

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

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

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

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

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

בדיקות

11/03/2018

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

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

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

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

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

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