uk
Feedback
ToCode

ToCode

Відкрити в Telegram

טיפים קצרים למתכנתים מאת ינון פרק

Показати більше
1 419
Підписники
Немає даних24 години
Немає даних7 днів
-230 день
Архів дописів
ToCode
1 419
# 5. Find the first different element
# (still a no-op, until someone will request its next)
duplicates = itertools.dropwhile(lambda p: p[0] == p[1], pairs)

# 6. Print the first duplicate running everything
print(next(duplicates)[0])
וכן המטרה של הקוד הזה היא לשחק עם חיבורי Generators לא למצוא את הדרך היעילה או הקצרה ביותר לזהות איבר כפול ברשימה.

ToCode
1 419
# גנרטורים ב Python: זהירות רק לא לשבור אחד המנגנונים שאהבתי ב Python מהרגע הראשון היה מנגנון ה Generators או בעברית פונקציה יוצרת: אנחנו מגדירים לפייתון איך סידרת ערכים מסוימת נראית ופייתון כבר יבנה את הערכים מהסידרה על פי דרישה. לא תמיד קל לראות מהשניה הראשונה ש Generators עובדים ממש טוב יחד (לפחות כל עוד אנחנו לא שוברים את השרשרת). ## איך זה עובד במודול itertools אפשר למצוא לא מעט Generators אז בואו נתחיל עם כמה דוגמאות משם ואז נראה מה קורה כשאנחנו בונים Generators חדשים משלנו. הפונקציה itertools.cycle לדוגמה היא פונקציה שמייצרת סידרה אינסופית של ערכים מתוך מספר קטן של ערכי בסיס באמצעות חזרה אינסופית על הערכים. הנה דוגמה קטנה להמחשה - נניח שיש לנו שני שחקנים במשחק מבוסס תורות, אז נוכל להשתמש ב cycle כדי לעבור ביניהם:
>>> players = itertools.cycle(['Tom', 'Jane'])
>>> print(f"It's {next(players)}'s turn")
It's Tom's turn
>>> print(f"It's {next(players)}'s turn")
It's Jane's turn
>>> print(f"It's {next(players)}'s turn")
It's Tom's turn
>>> print(f"It's {next(players)}'s turn")
It's Jane's turn
>>> print(f"It's {next(players)}'s turn")
It's Tom's turn
>>> print(f"It's {next(players)}'s turn")
It's Jane's turn
הפונקציה itertools.islice חותכת רק "פרוסה" מתוך Generator. ומה שיפה שאני יכול לשלב אותה עם cycle:
>>> ''.join(list(itertools.islice(itertools.cycle('hello '), 50)))
'hello hello hello hello hello hello hello hello he'
עדיין מתוך אותו מודול הפונקציה accumulate מחזירה סידרה של תוצאות הפעלת פונקציה כל פעם על האלמנט הבא. אני ממשיך את ההמחשה ומוסיף אותה למשחק:
>>> list(itertools.islice(itertools.accumulate(itertools.cycle([10, 20, 30, 40]), operator.add), 10))
[10, 30, 60, 100, 110, 130, 160, 200, 210, 230]
## איך זה נשבר מאחר ו Generators עובדים כל כך טוב יחד חשוב לשים לב כשאנחנו כותבים Generator חדש לא לשבור את השרשרת. שימו לב לקוד הבא:
import itertools
from collections import OrderedDict

def nodups(collection):
    s = OrderedDict()

    for item in collection:
        s[item] = True

    for item in s:
        yield item
הפונקציה nodups היא Generator שאמור להחזיר את כל האלמנטים ללא כפילויות מהאוסף שקיבלה. יכולים כבר לראות את הבעיה בפונקציה? בגלל החלוקה לשני שלבים אי אפשר יהיה לחבר פונקציה זו לשרשרת Generators: אם היא תנסה להריץ את הלולאה הראשונה על collection אינסופי, הלולאה לעולם לא תסתיים ואף פעם לא יהיה שום yield. לדוגמה הקוד הבא ייכנס ללולאה אינסופית:
list(itertools.islice(nodups(itertools.cycle('aaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccc')), 10))
גישה טובה יותר תיראה כך:
def better_nodups(collection):
    s = set()
    for item in collection:
        if item not in s:
            yield item

        s.add(item)
אני עדיין משתמש בקבוצה כדי לדעת איזה אלמנטים ראיתי ולכן עדיין יש מגבלה שכל האלמנטים ב collection צריכים להיות כאלה שאוכל לשמור בתוך set, אבל הפעם אני יכול להרכיב את ה Generator הזה בשרשרת עם Generators אחרים. ## שילוב Generators בואו נשלב את כל ה Generators שראינו ונכתוב משהו מועיל - למשל קוד שמוצא ומדפיס את האלמנט הכפול הראשון ברשימה: 1. רשימת הערכים תהיה ה Collection הבסיסי שלי. אפעיל עליה iter כדי להפוך אותה ל Iterator. 2. את הרשימה אשלח ל itertools.tee שישכפל אותה לשני איטרטורים. 3. אחד מהם אשלח ל better_nodups כך שלא יכיל כפילויות. 4. עכשיו ארוץ על שני האיטרטורים ואחפש את האלמנט הראשון שלא שווה ביניהם. זה האלמנט הכפול הראשון בסידרה. הנה הקוד לאמיצים:
import itertools
from collections import OrderedDict

# 1. Create a base list
# (note 2 is the first duplicate item)
base = iter([1, 2, 3, 5, 4, 11, 12, 15, 2, 10, 20, 99])

def uniq(collection):
    s = set()
    for item in collection:
        if item not in s:
            yield item

        s.add(item)

# 2. Send the list to tee
[c1, c2] = itertools.tee(base)

# 3. Remove duplicates from c2
# (though this is still a noop until we start taking elements)
c2 = uniq(c2)

# 4. Create an iterator on the pairs
# (still a no-op)
pairs = zip(c1, c2)

ToCode
1 419
תודה לכל המשיבים נראה שיש כיוון ברור. אעדכן כאן כשדברים יתחילו להתבשל

ToCode
1 419
# איך אני אוהב ללמוד: מחשבות על הדרכה ולימוד בהובלת התלמיד אני זוכר בתור ילד בבית ספר שהיו קצת שיעורים שמדברים בהם אבל היו לא מעט שיעורים שבהם המורה מדברת ואתה יושב וכותב. אחרי זה באוניברסיטה שוב היו קצת שיעורים עם דיונים אבל ברובם המוחלט את המורה החליף פרופסור שעומד ליד הלוח ומדבר ואתה שוב יושב וכותב. אני לא זוכר הרבה מהתוכן של אותם שיעורים, לא בבית ספר ולא באוניברסיטה, אבל החוויה של לשבת ולכתוב כל מה שאומרים לך ובהמשך ללמוד את זה לקראת המבחן היא חוויה מעצבת. היא חוויה שמשדרת יחסי כוחות, תפקידים ותפיסה של המקום שלך בעולם. דווקא את החלק הזה של מערכת החינוך לקח לי הרבה יותר זמן לשכוח. ולכן כשאני מסתכל קדימה על לימוד ולוקח דוגמאות מהצלחות לימודיות שהיו לי אני מדמיין את העקרונות הבאים: 1. אני רוצה לקבוע כמה להתעמק בכל נושא לפי מידת העניין שלי בו. 2. אני רוצה לקבוע כמה זמן להשקיע בלימוד כל יום, לפי מה שמסתדר או מתחשק לי. 3. אני רוצה לבחור מה יהיה הנושא הבא שאלמד, מתוך מבחר של 2-3 כיווני התפתחות (קצת כמו במשחקי אסטרטגיה ישנים שאתה יכול לבחור איזה טכנולוגיה לחקור). 4. בין אם השקעתי בלימוד 15 דקות או 4 שעות, אני רוצה לקחת משהו שאוכל להשתמש בו בהמשך היום בסיטואציות אחרות: איזושהי הבנה, איזשהו טריק, איזושהי חשיבה אחרת שתעזור לי ביום יום. 5. אני רוצה לבחור את סוג הפעילות הלימודית שתתאים לי - לפתור חידה, לצפות בוידאו, לקרוא מאמר, לכתוב מאמר, להתקדם בפרויקט, לדבר עם חברים על מה שלמדתי, להסביר למישהו אחר, לגשת למבחן, לכתוב עבודה. 6. החיים מלאים הפתעות ותזמונים זה עסק מסובך. אני רוצה להיות מסוגל ללמוד על אש קטנה תקופה בזמן שאני עושה דברים אחרים, ובתקופה אחרת לחזור ולהשקיע יותר בלימודים, בלי שאצטרך להסביר למערכת מה עשיתי בזמן הזה. 7. אני רוצה לקבל פרס אמיתי וספציפי שמתאים למטרות שלי כשהגעתי לאבן דרך משמעותית בתהליך (ולא, ציון טוב בתעודה ממש לא ישמח אותי).

ToCode
1 419
הי חברים אני מתכנן לפתוח קורס ציבורי חדש בקרוב ומתלבט לגבי הנושא אז אשמח לשמוע את דעתכם. איזה מהנושאים הבאים מעניין אתכם ללמוד?
Anonymous voting

ToCode
1 419
# טיפ גיט: מעיכת קומיטים נתקעתם עם ענף שיש בו יותר מדי שינויים ואתם פשוט צריכים לקחת את כל הקוד משם בתור קומיט יחיד אליכם לעץ? ככה תוכלו להשתמש ב merge squash כדי לעשות בדיוק את זה. ## מה אנחנו מנסים לחבר הפרויקט שלנו התחיל טוב עם ענף main וענף dev אבל עם הזמן הענפים התפצלו: המתכנתים התחילו פיתוח על ענף dev, באמצע הפיתוח גילו באג קריטי ותיקנו אותו בענף main ועכשיו רוצים לחבר את כל הקוד שכתבנו ל dev, בתור קומיט יחיד, לענף main בלי לפגוע בתיקון הבאג הקריטי שכבר יש שם. הלוג מענף main נראה כך:
# [main] git log --oneline --graph
* cc5cec4 (HEAD -> main) FIXED readme
* 35e4d4d initial commit
והלוג מענף dev נראה כך:
# [dev] git log --oneline --graph
* 754149f (HEAD -> dev) add db/schema
* fe0c9e5 add stuff scaffold
* c3d8bcc FIXED readme
* 3d35a86 add activeadmin
* 35e4d4d initial commit
הקומיט המשותף האחרון ביניהם הוא 35e4d4d כלומר הקומיט הראשון במערכת ואחריו אנחנו רואים את הפיצול. ## מיזוג ומעיכה הגישה הפשוטה לחיבור ענף dev בתור קומיט יחיד נקראת Merge Squash Commits. הפעולה כאן בעצם לוקחת את כל הקוד מהקומיט האחרון בענף אחר ומעבירה אותו אליי לתיקיית העבודה, בלי כל ההיסטוריה של הענף. בצד שלי אם אני מרוצה מהתוצאה אוכל להפעיל commit אחרי ה merge ולקבל קומיט יחיד מכל השינויים בענף שאותו אני משלב. נשים לב שבדוגמה שלנו יש קונפליקט: גם ענף main וגם ענף dev שינו את הקובץ README.md ולכן אני צריך לבחור איזה שינוי אני רוצה לקחת. ברוב המקרים כשיש קונפליקט נרצה להסתכל ממש על תוכן הקבצים ולקחת את השורות המתאימות מכל קובץ - בשביל שמצד אחד לא נפספס תיקון באג קריטי שבוצע על ענף main, אבל מצד שני כן נוותר על תיקוני באגים שהקוד שלנו הפך למיותרים. בדוגמה שלנו אני יודע שהקונפליקט היחיד הוא בקובץ README.md ויודע שהקוד הנכון נמצא בענף main ולכן אפעיל את הפקודות הבאות:
$ git checkout main
$ git merge --squash dev

Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Squash commit -- not updating HEAD
Automatic merge failed; fix conflicts and then commit the result.
וזה הקונפליקט שידענו שיגיע. עכשיו אפשר לקחת את גירסת README.md מענף main ולהמשיך:
$ git checkout main -- README.md
$ git commit -m 'new feature from dev'
$ git log --oneline --graph

* 694f1cb (HEAD -> main) new feature from dev
* cc5cec4 FIXED readme
* 35e4d4d initial commit
קיבלתי קומיט יחיד עם כל השינויים מענף dev.

ToCode
1 419
# קפה על המקלדת כשעוד היה מותר לימדתי קורס Front End באיזו חברת הייטק. שולחן המחשב של המדריך שם היה יחסית צפוף ובלי לשים לב באחד ההסברים של אחרי-ארוחת-צהריים הזזתי את היד לא טוב וכוס קפה שלמה נפלה לי מהשולחן על הלפטופ. עכשיו המק שממש לא ראה את זה בא דווקא הגיב בנונשלנטיות מפתיעה. אחרי ניגוב קטן של המקשים הוא המשיך לעבוד, הריץ את כל התוכניות שכתבתי ואת השקפים ולא הראה שום סימן למעגלים החשמליים שנשרפים אצלו בבטן. אני, שידעתי עמוק בלב שעדיף לכבות מכשיר חשמלי שהתרטב ולתת לו להתייבש (אפילו לקחת למעבדה), לא העזתי לסיים את היום מוקדם רק בגלל כוס קפה, ובטח ובטח כשהמחשב עדיין מגיב. במעבדה למחרת כבר ידעו להגיד שהמחשב הוא טוטאל לוס, ושממש חבל שלא סגרתי אותו באותו רגע ובאתי אליהם מיד, כי אז עוד יכלו להציל אותו. וכמו באותו קורס גם היום אני רואה מערכות תוכנה הרבה יותר מורכבות אפילו מהמקבוק שהרסתי, סופגות ברוגע כוס קפה וירטואלית (מה שמכונה "שים קצת מסקנטייפ רק שיעבוד בדמו") וממשיכות לתפקד - לפעמים עד הדמו, לפעמים גם הרבה אחרי. כל אותו הזמן אנחנו יודעים שעדיף היה לעצור ל Refactoring, אבל רק לעתים נדירות מוצאים את האומץ לעצור לפני שנהיה מאוחר מדי.

ToCode
1 419
# שורת פתיחה טובה אנחנו יודעים שהרבה יותר קל ללמוד טכנולוגיה חדשה כשאנחנו עובדים על פרויקט אמיתי בטכנולוגיה זו. אבל אנחנו גם יודעים שברוב מקומות העבודה לא יתנו לכם להתחיל פרויקט בטכנולוגיה שאתם לא מכירים על חשבון שעות העבודה רק בשביל ללמוד אותה. אם בחברה שלכם עובדים היום ב Java ואתם רוצים לשכנע את הבוס לכתוב סרביס קטן ב Node.JS רק בשביל ללמוד Node זה הולך להיות שכנוע קשה. מצד שני עם כל העבודה מהבית והסגרים ברוב מקומות העבודה יש לכם היום יותר חופש פעולה ממה שאי פעם היה. אם תצליחו לקום שעה קודם לתכנת בנוסף לעבודה המופלאה שאתם עושים ביום יום, תוכלו לכתוב בשעה הזו כל מה שאתם רוצים. וכאן מתחיל הקסם- אם בשעה נוספת של עבודה למשך חודש אתם יכולים לבנות משהו שאנשים ישתמשו בו, אז החל מהחודש השני אתם כבר תהיו המתחזקים של פרויקט פנימי בחברה ותוכלו לקבל זמן עבודה אמיתי לשפר את הפרויקט שלכם. לאט לאט כשהפרויקט יגדל גם הבוס ירגיש יותר בנוח לתת לכם לבנות רכיבים נוספים בטכנולוגיה זו ובלי לשים לב אתם כבר בשליש משרה מתכנתי Node.JS. שורת פתיחה טובה זה לפעמים כל מה שצריך בשביל לעשות שינוי גדול. כמו אצל סיימון וגרפינקל, רק בקוד: <iframe width="560" height="315" src="https://www.youtube.com/embed/Eo2ZsAOlvEM" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

ToCode
1 419
# שלושה דברים שמעסיקים מחפשים בקורות החיים שלכם אם אתם שולחים קורות חיים ולא מקבלים זימונים לראיונות יכול להיות שהסיבה היא שהמעסיקים הפוטנציאליים שמקבלים את קורות החיים לא מוצאים בהם את תשובות מספקות ל-3 שאלות פשוטות שמעניינות אותם: 1. האם אתם מסוגלים לבנות מוצר עובד בטכנולוגיה שרלוונטית להם? 2. האם הקוד שלכם יסבך לאחרים את החיים? 3. האם אתם הולכים להשקיע בעבודה לאורך זמן? כל שאלה נפתחת להמון סימנים קטנים שאנחנו מחפשים בקורות חיים - לדוגמה אנשים שמחליפים עבודות לעתים תכופות או שגרים רחוק נתפסים בתור כאלה שלא יצליחו להשקיע במשרה לאורך זמן. אנשים שאין להם ניסיון בטכנולוגיה הרלוונטית או בטכנולוגיות דומות, או שאנחנו לא רואים עקומת למידה ברשימת המשרות שלהם, נתפסים בתור כאלה שלא יצליחו לבנות מוצר עובד בטכנולוגיה הרלוונטית. ואנשים שעושים טעויות מטופשות, לא מטפלים טוב במקרי קצה, משאירים קוד שיתמוטט כשיהיו יותר משתמשים, לא כותבים תיעוד כמו שצריך ולא בונים בדיקות אוטומטיות לקוד שלהם נתפסים בתור כאלה שהקוד שלהם הולך לסבך את האחרים. רוצים לשפר את הסיכויים שלכם לקבל ראיון? לפני שאתם שולחים קורות חיים למשרה הבאה נסו להסתכל על המסמך מנקודת מבט של המגייס ובידקו איזה תשובות אתם מצליחים לתת לשלושת השאלות מקריאת מסמך קורות החיים שאתם רוצים לשלוח. אם התשובות לא מספיק טובות, עדכנו את המסמך עד שתהיו מרוצים.

ToCode
1 419
# איך לזהות לחיצות מקלדת (ואירועים אחרים) ב tkinter מערכת האירועים של tk יכולה להיות קצת מבלבלת בעיקר בגלל סוגי האירועים המובנית והשימוש בטקסטים כדי לתאר אירועים (ובגלל שהתיעוד של tk לא הכי נוח לקריאה). אז לטובת אלה מכם שמסתבכים ובעקבות שאלה של תלמיד, הנה כמה דוגמאות קוד לעבודה עם לחיצות מקלדת בתוכנית tk. ## איך זה עובד כל Widget ב tk יכול לדווח לעולם על דברים שקורים, למשל אם שינו לו את הגודל, אם הוא קיבל פוקוס, או - וזה מה שאותנו מעניין - אם לחצו על כפתור מקלדת בשטח שלו. ה Widgets של tk ממוקמים אחד בתוך השני ולכן כשקורה אירוע כל Widget רלוונטי מקבל הזדמנות לטפל בו. אם יש לי תיבת טקסט שנמצאת בתוך פריים אז שניהם יהיו מודעים ללחיצת הכפתור ויקבלו הזדמנות לטפל באירוע. חיבור קוד לאירועים מבוצע עם הפונקציה bind. יש bind לכל Widget וגם הפונקציה נמצאת על אוביקט ה Tk הראשי כך שאפשר במקום אחד לטפל בכל האירועים מכל ה Widgets. ## דוגמת קוד קצרה התוכנית הבאה היא הדרך הכי קצרה שמצאתי ב tk להקשיב ללחיצות מקלדת:
from tkinter import *

root = Tk()

def on_key_press(event):
    print("Key Press: ", event.char)

root.bind('<KeyPress>', on_key_press)
root.mainloop()
הרצת התוכנית תציג חלון חדש ריק, וכאשר חלון זה יהיה בפוקוס אז כל לחיצת מקלדת בתוך החלון תוסיף הודעה במסוף עם הכפתור שנלחץ. ## דוגמת קוד קצת יותר ארוכה אפשר לראות שהרעיון עובד גם אם יש לנו מספר Widgets, ושבמצב כזה כל ה Event Handlers של כל ה Widgets יופעלו. נסו את הקוד הבא:
from tkinter import *

root = Tk()
a = Label(root, text="Hello World")
a.pack()

b = Text(root)
b.pack()

def on_key_press(event):
    print("Key Press: ", event.char)


def on_text_keypress(ev):
    print("A")

root.bind('<KeyPress>', on_key_press)
b.bind('<KeyPress>', on_text_keypress)
root.mainloop()
הקוד מציג Label ומתחתיה תיבת טקסט. כל לחיצת מקלדת בתוך החלון, ולא משנה איזה Widget נמצא עכשיו בפוקוס, תגרום להפעלת הפונקציה on_key_press. בנוסף כל לחיצת מקלדת בתוך הפוקוס של תיבת הטקסט תגרום להפעלת הפונקציה on_text_keypress.

ToCode
1 419
# הצד האפל של למידה עצמית הרבה מדברים בעידן הקורונה על הקסם בלמידה עצמית, על איך שלמידה מרחוק צריכה להיות יותר אסינכרונית, ובמיוחד בהקשר הבית ספרי על כמה זה נפלא כשתלמידים מסתדרים בקבוצות וחוקרים ומגלים יחד רעיונות חדשים. נדמה לפעמים שהאנשים האלה אף פעם לא היו תלמידים או שלא ראו תלמידים מקרוב. למידה עצמית אסינכרונית היא הדרך היחידה להקנות מיומנות בצורה שמאפשרת התפתחות. ההתמודדות האישית של כל תלמיד עם החסמים והאתגרים האישיים שלו בקבוצה עם תלמידים אחרים שתומכים בו ומורה שמקדם אותם ונותן פידבק על העשיה היא תהליך אותו תלמידים יצטרכו להטמיע לקראת היום בו יהיו אנשים בוגרים שצריכים להסתדר בשוק העבודה. אבל אל תטעו - בשביל לתת לתלמידים כלים טובים ללמידה צריך להיות מוכנים גם לחיות עם הצד האפל של הלמידה העצמית והאסינכרונית. הנה כמה דברים שתלמידים יעשו כשניתן להם יותר אחריות על הלמידה שלהם: ## הם ייכשלו למידה עצמית אסינכרונית אומרת שאנחנו נותנים לתלמיד משימה והוא צריך לעשות אותה בזמן שלו יחד עם החברים שלו. התלמיד יכול לשאול שאלות ואנחנו יכולים לשאול אותו איך הולך ולבקש לראות התקדמות, קצת כמו בעולם העבודה. וקצת כמו בעולם העבודה יכול להיות שקבוצה מסוימת תלך לאיבוד. הם לא ידעו מה לעשות, הם לא יבינו את ההוראות, הם לא יבינו את חומרי הלימוד שנתתם להם. רוב המורים לא מסוגלים לחיות עם תלמידים שלא מבינים או שלא מסתדרים. גם כאן באתר כל פעם מחדש קשה לי לענות לתלמיד שאין לנו תשובות בית ספר לתרגולים ושאני מוכן לעזור בשאלה נקודתית אבל שזה גם בסדר לא להצליח. ולי עוד יש אג'נדה חזקה בנושא. העניין שברוב העולם האמיתי זה בדיוק מה שקורה: אנחנו לא מסתדרים, צועקים, מתעצבנים עד שבסוף מצליחים (או שלא). בשביל שלמידה עצמית באמת תקנה מיומנויות למידה חשובות לעולם האמיתי אפשרות הכישלון חייבת להיות שם. כל עוד זה משחק שאפשר רק לנצח בו, אין התמודדות אמיתית ואין למידה. ## הם ילמדו טעויות רוב הלימוד האסינכרוני בבתי ספר מבוסס על הרעיון שהמורה נותן לתלמידים את כל חומר הלימוד והתלמיד פשוט מבצע את הלימוד או המשימה בזמן שלו בצורה אסינכרונית. זה לא משקף את העולם האמיתי וגם משעמם לתלמידים. הרבה יותר מעניין לראות תלמידים שמחפשים חומרים בעצמם, שואלים את החברים שלהם או ההורים שלהם (או את גוגל) ומכינים משהו שהמורה לא תכנן מראש שהם יבנו. וכן אם אתם הולכים בדרך הזאת אל תהיו מופתעים כשהדבר שהם בנו כולל טעויות קטנות או שקרים בוטים. ## הם יעבירו תקופות ארוכות בלי ללמוד כלום גם אנשים מבוגרים מתחבשנים בעבודה והדבר נכון פי כמה לתלמידים בבית ספר. תלמידים ילמדו מה שמעניין אותם ויחפפו את מה שלא מעניין אותם. חופש הפעולה שנתתם להם יהפוך לחרב פיפיות כשהנושא שעל הפרק הוא הכנה לבגרות באזרחות. אבל מה שיותר מזעזע הוא שמוטיבציה פנימית יכולה להיעלם מהר כמו שהיא הופיעה. (וכן המוטיבציה חייבת להיות פנימית כדי ליצור למידה אפקטיבית מחוץ למסגרת של מורה-מקריא-חומר-וכולם-כותבים). חלק מהעניין ביצירת מוטיבציה פנימית הוא שלפעמים היא לא שם, וזה בסדר. אם אתם לא מוכנים לחיות עם תקופות בלי למידה אז אתם בהכרח יוצרים מנגנוני מוטיבציה חיצוניים, ובמכה אחת הפסדתם הכל. ## הם יבואו לא מוכנים למבחן למידה עצמית אפקטיבית קורית כשתלמיד מבין את המטרה, מבין את המוטיבציה ומתקדם בקצב שלו לכיוון אותה מטרה. תלמידים שונים יתקדמו בקצב שונה ולכיוון מטרות שונות. אז איך בדיוק אתם הולכים למדוד התקדמות? ואיך המבחן שלכם הולך להשפיע על הבחירות של התלמידים ועל המוטיבציה הפנימית שלהם? למידה עצמית אפקטיבית היא אנטי-מבחן במובן זה שהמבחן הוא אישי לכל משתתף והמירוץ הוא נגד עצמך בלבד. ## ובכל זאת למידה עצמית אסינכרונית בהנחיית מורה ובשיתוף חברים לכיתה היא דרך הלימוד היחידה שתיתן לתלמידים שלנו את הכלים להסתדר בעתיד בעולם העבודה הטכנולוגי. הטכנולוגיה משתנה מהר ואנחנו צריכים אנשים עם סט מיומנויות מגוון בצוות. אין שום דרך שהדרכה אחידה לתלמידים ש"סופגים" את החומר יכולה לעבוד. הבעיה של כמעט כל מאמר שקראתי בהקשר של שילוב למידה אסינכרונית בכיתות בית הספר היא שהם מנסים להחזיק במקל משני קצותיו: גם לקבל למידה עתידנית, עצמית, עם תלמידים סקרנים שבונים דברים מופלאים בעצמם; וגם להצליח במבחן ולהתקבל לאוניברסיטה. השניים לא הולכים יחד ואין לי ספק על איזה מהשניים צריך לוותר.