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

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

זה ייקח רק חמש דקות

16/05/2022

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

אבל אלה רק חלק קטן מהמצבים.

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

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

#!/bin/bash

count=0

ls | while IFS= read -r line;
do
  (( count++ ))
done

echo $count

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

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

שלושה טריקים של foreach שכבר לא כדאי לעשות

15/05/2022

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

המשך קריאה

בואו נמצא מספרים שמחים עם Elixir

14/05/2022

מספר שמח הוא מספר שסכום ריבועי הספרות שלו בסוף יוצא 1. מספר עצוב הוא מספר שסכום ריבועי הספרות שלו לא יוצא 1, לא משנה כמה פעמים מעלים בריבוע ומחברים. ככה יוצא ש 7 הוא מספר שמח, כי כשמעלים אותו בריבוע מקבלים 49, וכשמעלים בריבוע את שתי הספרות של 49 מקבלים 16 ו 81 שסכומם יוצא 97, ממשיכים עוד סיבוב ומקבלים את 49 ו 81 שסכומם הוא 130, ועכשיו אנחנו מתקרבים למשהו כי 3 בריבוע זה 9 ו 1 בריבוע נשאר 1, יחד הם נותנים 10, שסכום ריבועי הספרות שלו הוא פשוט 1 בריבוע ועוד אפס בריבוע כלומר המספר 1.

לעומתו 4 הוא מספר עצוב כי בריבוע הוא נותן 16, וכשמעלים בריבוע את 1 ו 6 מקבלים 1 ו 36, שזה יחד 37, הסכום הבא הוא 58, אחרי זה 89, ואז 145, 42, 20 ושוב 4.

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

המשך קריאה

כשהקוד שכתבת יוצא מסובך יותר ממה שרצית

13/05/2022

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

זה לא אומר שהקוד גרוע.

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

זה לא אומר שאתה לא מתכנת טוב.

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

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

שטח מת

12/05/2022

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

<div />
<div />
<div />
<div />

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

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

<div>
    <div>
        <div>
            <div></div>
        </div>
    </div>
</div>

טיפ טייפסקריפט: פיצול ממשקים

11/05/2022

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

function Counter(props: { initialValue: number, step: number }) {
}

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

interface ICounterProps {
  initialValue: number;
  step: number;
  buttonText?: string;
}

function Counter(props: ICounterProps) {
}

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

interface ICounterProps {
  initialValue: number;
  step: number;
  buttonText?: string;
  turboButtonText?: string;
  turboStep?: number;
}

function Counter(props: ICounterProps) {
}

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

interface ICounterProps {
  initialValue: number;
  step: number;
  buttonText?: string;
}

interface ICounterWithTurboProps extends ICounterProps {
  turboButtonText: string;
  turboStep: number;
}

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

function Counter(props: ICounterProps|ICounterWithTurboProps) {
  const {
    initialValue,
    step,
    buttonText = 'Increase',
    turboButtonText,
    turboStep,
  } = props as ICounterWithTurboProps;
}

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

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

קליל ומאושר

10/05/2022

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

המשך קריאה

זמן לימוד

09/05/2022

מתי עוצרים? מתי למדתם "מספיק להיום"? אולי...

  • בסיום השיעור (כשהשעון מראה 12, בעוד 20 דקות)

  • בסוף הפרק

  • אחרי שאסיים את כל התרגילים

  • אחרי שאפתור את הבאג, או כשהקוד יעבוד

  • עד שהאוכל יגיע

  • עד שתיכנס שיחת טלפון מעניינת

  • עד שתגיע הודעה חשובה בווטסאפ

  • עד שאירדם

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

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

הזמנה לוובינר: תקשורת בין סרביסים עם RabbitMQ

08/05/2022

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

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

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

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

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

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

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

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

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

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

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

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

לפרטים נוספים והרשמה שווה לבקר בדף הוובינר בקישור: https://www.tocode.co.il/workshops/115

צעדים ראשונים עם SQL Alchemy

07/05/2022

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

המשך קריאה