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

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

הטעות הכי גדולה של מתכנתים שרוצים להשתפר

06/07/2020

מה הופך אותך למתכנת או מתכנתת טובים יותר?

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

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

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

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

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

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

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

קירות

05/07/2020

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

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

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

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

בואו נתרגם משפטים עם Python ו Google Translate

04/07/2020

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

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

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

from googletrans import Translator

translator = Translator()
texts = ['אני אוהב שוקולד', 'ועוגות גבינה', 'וארטיק וסוכריות', 'ותות גינה']

translations = translator.translate(texts)
for item in translations:
  print(item.text)

אפשר למצוא את התוכנית ולשחק איתה בשידור חי ברפליט שבקישור https://repl.it/@ynonp/python2#main.py.

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

python -m pip install --user googletrans

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

I love chocolate
And cheesecakes
And vinegar and candies
And garden strawberries

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

המשך קריאה

היום למדתי: אפשר לשרשר השוואות ב Python

02/07/2020

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

>>> 2 == 2 == 2

והוא ענה לי True.

אז הלכתי לכתוב לו שיר אהבה קצר מרוב אושר, ופייתון אפילו חייך אליי בחזרה:

x = 30
if 20 < x < 50:
    print("I \U00002764 Python")

פרילאנס, בוטסטרפ וסטארט-אפ

01/07/2020

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

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

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

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

למה כל כך קשה להחזיר חוב טכני

30/06/2020

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

Springboot -The AJP Connector is configured with secretRequired=“true” but the secret attribute is either null or ""

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

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

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

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

ההבדל בין סניור לג'וניור (או: מה שלא כותבים במודעות דרושים)

29/06/2020

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

At least 1-2 years of experience in web development (Front End). Experience with JS Frameworks such as Angular, React, Aurelia or Ember. Experience with developing Single Page Applications. Experience with Object Oriented JavaScript Experience in the design of software architecture Exceptional self-learning capabilities

והדרישות עבור מפתח סניור:

At least 4 years of experience in web development (Front End). Experience with JS Frameworks such as Angular, React, Aurelia or Ember. Experience with developing Single Page Applications. Experience with Object Oriented JavaScript. Experience in the design of software architecture. Exceptional self-learning capabilities.

חיפשתי. באמת שחיפשתי. אפילו diff הפעלתי בין שתי המודעות ותמיד אותה תשובה - שנתיים ניסיון. באמת?! שנתיים ניסיון? זה מה שעושה את ההבדל?

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

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

כשמישהו שואל ״אני כבר יודע לעבוד עם Redux ו MobX, מה עוד צריך בשביל להיות Senior?״ זאת לא השאלה הנכונה. בשביל להתקדם צריך את האומץ להגיד ״אני לא יודע״. המעבר מ Junior ל Senior זה לא מירוץ אלא דרך חיים.

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

בוטקמפ ריאקט

בוטקמפ פייתון

שאלת SQL: איך למצוא רק את השורות עבורן עמודה מסוימת היא הגדולה ביותר?

28/06/2020

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

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

בשביל לקבל תמונה של המידע בואו נתחיל עם שאילתה פשוטה:

select id, chapter_id, course_id, length from lessons where course_id = 2;

 id | chapter_id | course_id | duration
----+-------------------+-----------+--------
 17 |                 3 |         2 |     40
 18 |                 3 |         2 |     35
 20 |                 3 |         2 |     50
 22 |                 4 |         2 |     60
 21 |                 4 |         2 |     65
 19 |                 3 |         2 |     55
 23 |                 3 |         2 |     45
  9 |                 1 |         2 |      1
 24 |                 2 |         2 |     30
 13 |                 2 |         2 |     20
 70 |                 3 |         2 |     43
 71 |                 3 |         2 |     48
 11 |                 1 |         2 |     10
 10 |                 1 |         2 |      5
 12 |                 1 |         2 |     15
 14 |                 2 |         2 |     25
(16 rows)

ואנחנו רוצים לקבל רק את השורות:

 course_id | id | chapter_id | duration
-----------+----+-------------------+--------
         2 | 21 |                 4 |     65
         2 | 19 |                 3 |     55
         2 | 24 |                 2 |     30
         2 | 12 |                 1 |     15
(4 rows)

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

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

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

השליפה הראשונה לפי הפרק נראית כך:

select chapter_id, max(duration) as max_duration from lessons where course_id = 2 group by chapter_id;

 chapter_id | max_duration
------------+--------------
          1 |           15
          2 |           30
          3 |           55
          4 |           65

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

ERROR: column "lessons.id" must appear in the GROUP BY clause or be used in an aggregate function

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

select l.course_id, l.id, f.chapter_id, l.duration
from (
    select chapter_id, max(duration) as max_duration
    from lessons group by chapter_id
) as x
inner join
lessons as l on l.chapter_id = x.chapter_id and l.duration = x.max_duration where l.course_id = 2;

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

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

=> select distinct on(chapter_id) id, chapter_id, duration from lessons where course_id = 2 order by chapter_id, duration desc;

 id | chapter_id | duration
----+-------------------+--------
 12 |                 1 |     15
 24 |                 2 |     30
 19 |                 3 |     55
 21 |                 4 |     65
(4 rows)

אז למה הפסקת?

27/06/2020

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

״הקורס הולך מצוין - השיעורים ברורים, והטקסט ליד הוידאו מאוד עוזר להבנה״

״בינתיים הגעתי עד שיעור 12. בקצב הזה תוך שבועיים אני כבר יודעת Python״

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

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

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

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

פרטים נוספים על קורס Python: https://www.tocode.co.il/bootcamps/17

פרטים נוספים על קורס React: https://www.tocode.co.il/bootcamps/18