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

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

ארבעה עקרונות של תכנות פונקציונאלי שתוכלו למצוא ב Python

23/03/2020

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

אגב- ביום חמישי הקרוב אני ודני נעביר וובינר על תכנות פונקציונאלי עם Clojure. אם בא לכם לשמוע יותר על תכנות פונקציונאלי ממש שווה לבוא. פרטים בקישור https://www.tocode.co.il/workshops/95.

המשך קריאה

נוסע על אדים

22/03/2020

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

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

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

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

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

איך לבדוק פרויקט Python אוטומטית עם Github Action

21/03/2020

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

מנגנון Github Actions יריץ בשבילכם קוד על מכונה וירטואלית בעזרת דוקר. הקוד הזה יכול לעשות כל מה שתרצו, אבל לרוב נשתמש בו כדי להריץ בצורה אוטומטית את הבדיקות שכתבנו, להריץ Linter על הקוד וכמובן לבנות את המערכת ולהעלות את התוצאה לשרת ה Production. בדוגמא כאן אנחנו ניקח פרויקט שמכיל תיקיית בדיקות עם ספריית pytest ונגרום לגיטהאב להריץ את הבדיקות כל פעם שאנחנו דוחפים קוד חדש. מערכת הבדיקות משתמשת ב Selenium ותריץ את הבדיקה על דפדפן פיירפוקס שרץ במצב Headless, כלומר ללא ממשק משתמש.

בשביל להתחיל להשתמש ב Github Actions אתם צריכים ליצור Workflow. זה בעצם קובץ yml שמסביר לגיטהאב מה יהיה בתוך הקונטיינר שהוא ירים. את ה Workflow אנחנו שומרים בתוך תיקיה בשם .github/workflows בתוך תיקית הפרויקט. אני קראתי לקובץ test.yml וכתבתי בו את התוכן הבא:

# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions

name: pytest-demo

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:
  build:

    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: [3.8]

    steps:
    - uses: actions/checkout@v2
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v1
      with:
        python-version: ${{ matrix.python-version }}
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install -r requirements.txt
    - name: Test with pytest
      run: |
        pip install pytest
        python -m pytest

הקובץ מתקין קונטיינר דוקר מתוך אימג' שנקרא ubuntu-latest. אימג' זה כולל גם התקנה של פיירפוקס לכן לא צריך להתקין אותו בנפרד. הוא יתקין את כל הספריות שרשומות בקובץ requirements.txt בפרויקט ולאחר מכן ימשיך להרצת pytest.

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

אתם יכולים לראות את התוצאה בפרויקט שיצרתי בקישור https://github.com/ynonp/pytest-action-demo.

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

גיטהאב עצמם אגב יצרו המון תבניות לקובץ ה Workflow עבור שפות תכנות וסביבות עבודה שונות. אם יש לכם פרויקט בשפה אחרת שווה להעיף מבט בקישור https://github.com/actions/starter-workflows/tree/master/ci ואני בטוח שתמצאו סטארטר טוב לשפה שלכם, וגם אם לא זה די פשוט לקחת אחד מהקיימים ולהתאים אותו.

מחשבים לא משקרים

20/03/2020

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

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

אז לא.

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

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

חלומות על CSS

19/03/2020

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

המשך קריאה

הכי טוב שהיה פה

18/03/2020

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

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

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

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

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

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

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

לכתוב הוראות לעצמך

17/03/2020

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

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

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

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

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

שאלות מראיונות עבודה: פונקציות ב JavaScript

16/03/2020

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

    add(2, 5); // 7
    add(2)(5); // 7

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

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

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

const add2 = add(2);
// now add2 is a new function

const result = add2(7);
// now result is 7

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

function add(x, y) {
  if (arguments.length === 2) {
      return x + y;
  } else if (arguments.length === 1) {
    return y => add(x, y);
  }
}

console.log(add(2, 5));
console.log(add(2)(5));

עוד צעד קדימה יכול להיות להוציא החוצה את החלק בקוד שמתעסק בהפעלה חלקית של הפונקציה לפונקציה נפרדת, למשל נוכל לקרוא לה partialify:

function partialify(f) {
  const requiredArgsCount = f.length;

  return function(...args) {
    if (args.length === requiredArgsCount) {
      return f(...args);
    } else {
      return f.bind(null, ...args);
    }
  }
}

const add = partialify(function add(x, y) {
  return x + y;
});

console.log(add(2, 5));
console.log(add(2)(5));

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

const add = partialify(function add(x, y, z) {
  return x + y + z;
});

console.log(add(2)(5)(7));

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

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

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

15/03/2020

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

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

$ curl 'https://lab.isaaclin.cn/nCoV/api/area?latest=1&provinceEng=Israel' 2>/dev/null | jq '.results[0].confirmedCount'

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

alias cocount="curl 'https://lab.isaaclin.cn/nCoV/api/area?latest=1&provinceEng=Israel' 2>/dev/null | jq '.results[0].confirmedCount'"

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

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

סקרנות

14/03/2020

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

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

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

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