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

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

איך לא לייצר סיסמה אקראית

25/04/2023

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

import random

def generate_password(length, symbols):
    password = ''
    for i in range(length):
        password += random.choice(symbols)
    return password

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

import string
import random

def generate_password(length):
    chars = string.ascii_letters + string.digits + string.punctuation
    while True:
        password = ''.join(random.choice(chars) for _ in range(length))
        if (any(c.islower() for c in password)
            and any(c.isupper() for c in password)
            and any(c.isdigit() for c in password)
            and any(c in string.punctuation for c in password)):
            return password

אז נכון גם הרבה מתכנתים אנושיים שאני מכיר היו משתמשים ב random.choice במקום ב os.urandom בלי לשים לב, ואולי גם אתם כתבתם קוד כזה בעבר. בכל מקרה אלה כמה סיבות בגללן אני משתדל לא לכתוב כך, גם במערכות שאינן קריטיות לאבטחה של אף אחד:

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

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

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

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

שורה תחתונה ובשביל העתיד, זו גירסה של הפונקציה שלא קיבלתי מ Chat GPT שמשתמשת ב os.urandom כדי לבחור סמלים לסיסמה בסדר אקראי ממש:

import os

def make_random_password(length=12, symbols='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@$^_+&'):
    password = []
    for i in map(lambda x: int(len(symbols)*x/255.0), os.urandom(length)):
        password.append(symbols[i])
    return ''.join(password)

הטעות שכולם עושים

24/04/2023

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

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

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

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

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

וזו הטעות הגדולה שכולם עושים.

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

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

מתי לחתוך

23/04/2023

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

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

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

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

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

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

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

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

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

טיפ יוניקס: פיצול קלט בעזרת הפקודה split

22/04/2023

הפקודה ifconfig (או בגירסתה העדכנית יותר ip a) מציגה רשימה של כל כתובות ה ip על המכונה. זה חלק מהפלט לדוגמה:

utun6: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1380
        inet6 fe80::4b03:c5a9:d358:bb3a%utun6 prefixlen 64 scopeid 0x17
        nd6 options=201<PERFORMNUD,DAD>
vmenet0: flags=8b63<UP,BROADCAST,SMART,RUNNING,PROMISC,ALLMULTI,SIMPLEX,MULTICAST> mtu 1500
        ether be:50:b2:b2:bc:7b
        media: autoselect
        status: active
bridge100: flags=8a63<UP,BROADCAST,SMART,RUNNING,ALLMULTI,SIMPLEX,MULTICAST> mtu 1500
        options=3<RXCSUM,TXCSUM>
        ether 52:ed:3c:d3:64:64
        inet 192.168.64.1 netmask 0xffffff00 broadcast 192.168.64.255
        inet6 fe80::50ed:3cff:fed3:6464%bridge100 prefixlen 64 scopeid 0x10
        inet6 fd5e:dcce:7fd0:a7fb:10c8:64d2:15b:ca05 prefixlen 64 autoconf secured
        Configuration:
                id 0:0:0:0:0:0 priority 0 hellotime 0 fwddelay 0
                maxage 0 holdcnt 0 proto stp maxaddr 100 timeout 1200
                root id 0:0:0:0:0:0 priority 0 ifcost 0 port 0
                ipfilter disabled flags 0x0
        member: vmenet0 flags=3<LEARNING,DISCOVER>
                ifmaxaddr 0 port 15 priority 0 path cost 0
        nd6 options=201<PERFORMNUD,DAD>
        media: autoselect
        status: active

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

המשך קריאה

היום למדתי: טקסט לדיבור באפליקציות ווב

21/04/2023

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

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

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

  2. בשדה voice של אותו Utterance אנחנו כותבים את הקול שאנחנו רוצים שיגיד את המשפט. אפשר לקבל את רשימת כל הקולות מ speechSynthesis.getVoices(). יש עוד כמה שדות באוביקט זה שמאפשרים לנו לבקש ממנו לדבר יותר מהר או להתאים פרמטרים אחרים.

  3. אחרי שיש לנו Utterance מוכן נשלח אותו לפונקציה speak של window.speechSynthesis כדי לשמוע אותו.

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

וזה הקוד:

synth =  window.speechSynthesis;
voice = synth.getVoices().find(v => v.lang === "he-IL");

text = new SpeechSynthesisUtterance("היו שלום ותודה על הדגים");
text.voice = voice;

function say() {
  synth.speak(text);
}

btn.addEventListener('click', say);

האשבנג ב JavaScript? זה לא היה כבר?

19/04/2023

רשימת הפיצ'רים שייכנסו ל JavaScript ב 2023 כוללת את:

  1. האפשרות לחפש במערך מהסוף.

  2. תמיכה ב Hashbang.

  3. אפשרות להשתמש בסימבולים בתור מפתחות ב WeakMap.

  4. פונקציות לשינוי מערך (לדוגמה מיון) בהעתקה ולא בשינוי In Place.

בעוד שפיצ'רים 1, 3 ו-4 די צפויים, פיצ'ר מספר 2 הפתיע אותי. נזכיר ש HashBang הוא סימן ה #! שאומר ליוניקס איזה תוכנית צריך להפעיל כשלקובץ טקסט יש הרשאות הרצה ואנחנו "מפעילים" את הקובץ. מתכנתי Node.JS מאז ומעולם השתמשו בסימן הזה כדי לכתוב סקריפטים ב JavaScript והכל עבד, לדוגמה הסקריפט הזה:

#!/usr/bin/env node

console.log('hello world');

עובד גם ב Node וגם ב Deno ואפילו בדפדפנים, למרות שהסימן #! לא חוקי ב JavaScript. המנועים פשוט מתעלמים ממנו.

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

פירוט ההצעה כאן: https://tc39.es/proposal-hashbang/out.html

ופירוט על כל הפיצ'רים החדשים ב 2023 זמין כאן: https://pawelgrzybek.com/whats-new-in-ecmascript-2023/

מה עושים כשמצליחים את כל התרגילים?

18/04/2023

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

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

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

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

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

מה עושים אם המשחק קל מדי? עולים לשלב הבא.

צריך הארכה

17/04/2023

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

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

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

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

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

ציונים

16/04/2023

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

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

היום, לפחות בתעשיית ההייטק, התשתית הזאת כמעט לא קיימת.

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

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

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

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

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