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

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

פחד מכישלון

17/07/2022

זה גדול עליי

אין מצב שאני אצליח להבין את כל החומר

יותר מדי דברים לקרוא

יותר מדי נושאים

בחיים לא אמצא זמן לזה

בחיים לא אהיה מספיק טוב כדי למצוא עבודה

עזוב אני לא בגיל ללמוד עכשיו תחום חדש


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

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

כמה זמן ייקח לך לכתוב טטריס?

16/07/2022

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

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

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

כל ההבדל בינך היום לבין הבן אדם שכותב טטריס בשעה הוא לשבת לכתוב טטריס עשר פעמים. אפשר להתחיל כאן: https://data-flair.training/blogs/python-tetris-game-pygame/

היום למדתי: התקנת הפצה נוספת מאותו סוג ב WSL

15/07/2022

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

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

C:\ wsl --install

ואחרי זה אפשר לכתוב:

C:\ wsl

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

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

C:\ wsl --list --online

ואז אם רוצים להתקין למשל את kali אפשר להפעיל:

C:\ wsl --install -d kali-linux

פנטסטי. אבל- מה אם רוצים להתקין עוד מכונה של kali אחרי שהתקנתי אחת? או עוד מכונה של אובונטו אחרי שהתקנתי את ברירת המחדל? אז פה הסיפור מסתבך. ל wsl יש תמיכה מלאה בהתקנה כמה מכונות, אבל אין אופציה בהתקנה לתת שם למכונה. במקום זה מה שצריך לעשות זה להוריד קובץ tag.gz של המכונה שאתם רוצים ולעשות לו import.

הלינק לגירסה העדכנית של אובונטו הוא: https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-amd64-wsl.rootfs.tar.gz

ואם הורדתם אותו לתיקיית Downloads תצטרכו להפעיל את הפקודה הבאה בשביל להתקין:

C:\ wsl --import ubuntu2 C:\Users\ynonp\Documents\ubuntu2 C:\Users\ynonp\Downloads\ubuntu-22.04-server-cloudimg-amd64-wsl.rootfs.tar.gz

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

אחרי ה import אפשר להיכנס למכונה החדשה עם:

C:\ wsl -d ubuntu2

ושימו לב שמשתמש ברירת המחדל שם הוא root אז תצטרכו ליצור לעצמכם משתמש חדש.

פוטנציאל גנרי

14/07/2022

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

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

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

import urllib.request
import json


zen = urllib.request.urlopen("https://api.github.com/zen").read()
print(zen)

repos = json.loads(urllib.request.urlopen("https://api.github.com/users/ynonp/repos").read())

for repo in repos:
    data = json.loads(urllib.request.urlopen(f"https://api.github.com/repos/ynonp/{repo['name']}").read())
    print(f"Repo {data['name']} has size {data['size']}")

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

import urllib.request
import json

base_url = "https://api.github.com"

def read_string(endpoint):
    return str(urllib.request.urlopen(f"{base_url}/{endpoint}").read())

def read_dict(endpoint):
    return json.loads(urllib.request.urlopen(f"{base_url}/{endpoint}").read())


zen = read_string('zen')
print(zen)

repos = read_dict('users/ynonp/repos')

for repo in repos:
    data = read_dict(f"repos/ynonp/{repo['name']}")
    print(f"Repo {data['name']} has size {data['size']}")

וכאן עוצרים. בנינו קוד עם פוטנציאל גנרי.

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

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

תזרים

13/07/2022

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

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

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

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

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

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

  3. אני יכול להעלות את הקוד למערכת כמו Heroku כדי להגיע לאוויר כמה שיותר מהר, ולדחות את כתיבת קוד ה Deployment המסובך לאחרי שהמוצר באוויר.

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

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

כמה זמן לוקח לכתוב דיאלוג ב CSS?

12/07/2022

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

  • כמה זמן לוקח לכתוב דיאלוג מודאלי בדפדפן? שניה וחצי, רק שורה ב jQuery UI

  • כמה זמן לוקח לכתוב דיאלוג מודאלי בדפדפן? שניה וחצי, רק שורה ב Bootstrap

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

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

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

רק העתקתי

11/07/2022

"אני בסך הכל העתקתי את הקוד ממקום אחר במערכת"

"הבאג הזה היה שם גם קודם"

"זה באג בפריימוורק לא קשור אלינו"

"אף אחד לא ישים לב וצריך להתקדם עם הגירסה"

"מישהו אי פעם התלונן על זה?"

"זה בכלל פיצ'ר"

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

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

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

פרויקט צד

10/07/2022

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

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

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

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

איזה סוג של אבוד

09/07/2022

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

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

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

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

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

געגועים ל Higher Order Components

08/07/2022

לפני Hooks היינו משתמשים בריאקט בתבנית קצת מסורבלת שנקראה Higher Order Components כדי לשתף Stateful Logic בין כמה קומפוננטות, מה שהיום אנחנו עושים בקלות עם Custom Hooks. אבל הרעיון מאחורי Higher Order Components יכול לעזור גם בכתיבת קומפוננטות מודרניות ולאפשר שיתוף קוד טוב ופשוט באפליקציה. ככה זה עובד.

המשך קריאה