סדנת למידה מהירה — טכנולוגיה חדשה תחת לחץ זמן
סדנת למידה מהירה — ספרייה לא מוכרת תוך 30 דקות
אחד מהחלקים המפחידים בסדנת גאמא הוא הרגע שמקבלים ספרייה שמעולם לא ראו — ומבקשים לממש איתה משהו תוך שעה. זה לא מבחן על הספרייה — זה מבחן על יכולת הלמידה שלך.
- שיטת 5 שלבים — README→Example→API Scan→Implement→Debug, סה"כ 30 דקות
- ניווט ב-Documentation — מה לחפש ומה לדלג, dir() ו-help() ב-Python
- Error Messages — קרא מלמטה למעלה, כל שגיאה היא מידע
- תרגיל: requests (Python) — GET, JSON, timeout, error handling
- תרגיל: axios (JavaScript) — async/await, POST, error types
- תרגיל: C Header File — קריאת API ישירות מ-.h ללא Docs
- Mindset מקצועי — מה אומרים למלווה, מה לא, קוד עובד חלקי > קוד שלם שבור
שיטת 5 שלבים: ללמוד ספרייה ב-30 דקות
כל שלב מוגבל בזמן — ומיועד לתת מספיק כדי להתחיל לממש, לא להיות מומחה. זה כמו קבלת מפה לעיר חדשה — לא צריך לדעת כל רחוב, צריך לדעת לקרוא מפה ולמצוא יעד.
import json
raw = '{"name": "gamma", "score": 95, "tags": ["cyber", "ctf"]}'
data = json.loads(raw)
print(type(data))
print(data['tags'][1])
print(data.get('level', 'unknown'))מה הפלט?Error Messages — המורה הטוב ביותר
שגיאות הן לא כישלון — הן מידע. מקצוענים רואים Error ומפעילים Methodology. מתחילים רואים Error ונבהלים. ההבדל הוא גישה.
טבלת Error Types
| סוג שגיאה | מה זה אומר | איך לטפל |
|---|---|---|
| ModuleNotFoundError | הספרייה לא מותקנת | pip install X / npm install X |
| AttributeError | קראת לפונקציה שלא קיימת | dir(obj) לבדוק מה יש |
| TypeError | טיפוס שגוי בפרמטר | בדוק מה הפונקציה מצפה |
| KeyError / IndexError | גישה לKey/Index שלא קיים | בדוק שה-Key קיים קודם |
| ConnectionError | בעיה ברשת | בדוק URL, port, חיבור |
| ValueError | ערך לא תקין | בדוק פורמט הנתונים |
# ─── Anatomy: קרא Traceback מלמטה למעלה! ─────────────────
Traceback (most recent call last): ← התחל לקרוא מלמטה!
File 'my_code.py', line 15, in main
result = api.fetch_data(url, timeout)
File '/lib/api_client.py', line 42, in fetch_data
response = requests.get(url, timeout=timeout)
requests.exceptions.ConnectionError: ← 1. סוג השגיאה
Failed to establish a new connection: ← 2. תיאור
[Errno 111] Connection refused ← 3. הסיבה הספציפית
# ─── אבחון ─────────────────────────────────────────────────
# 1. שורה תחתונה: 'Connection refused' → השרת לא מקשיב
# 2. הקוד שלי: line 15 → בדוק ה-URL שאני שולח
# 3. פתרון: האם ה-URL נכון? האם השרת רץ? האם ה-Port נכון?
# ─── Pattern נפוץ בסדנה / CTF ─────────────────────────────
# שגיאה: AttributeError: 'NoneType' has no attribute 'text'
# → response מ-requests.get() החזיר None (שגיאת רשת?)
# פתרון: תמיד בדוק:
if response is not None and response.status_code == 200:
data = response.json()
else:
print(f"Error: {response.status_code if response else 'No response'}")! מלכודת — None לא זורק Exception ›
פונקציה שמחזירה None על כישלון (במקום לזרוק Exception) היא מלכודת נפוצה. הקוד ממשיך, ואחר כך קורסת בשורה אחרת עם AttributeError מבלבל.
# ─── דוגמה: None propagation ──────────────────────────────
def find_user(id):
# ... API call ...
# מחזיר None אם לא נמצא
user = find_user(999) # לא קיים → None
print(user['name']) # AttributeError: 'NoneType'!
# ─── תיקון: תמיד בדוק None ──────────────────────────────
user = find_user(999)
if user is None:
print("User not found")
else:
print(user['name'])TypeError: connect() missing 1 required positional argument: 'port'. מה עושים?File 'scanner.py', line 23, in run_scan
results = api.scan(target)
File '/lib/api.py', line 67, in scan
sock.connect((host, port))
ConnectionRefusedError: [Errno 111] Connection refusedמה הבעיה וכיצד לתקן?import requests
r = requests.get('https://api.example.com/data')
print(r.json()['result'])
# שגיאה: AttributeError: 'NoneType' object has no attribute 'json'מה הסיבה ומה התיקון?requests (Python) ו-axios (JS) — תרגול מעשי
שתי ספריות HTTP נפוצות שמופיעות בסדנה. requests לפייתון, axios לג'אווסקריפט. הלוגיקה זהה — HTTP request, קבל response, טפל ב-errors.
# ─── requests (Python) — API מרכזי ───────────────────────
import requests
# GET בסיסי:
r = requests.get('https://httpbin.org/get', timeout=10)
print(r.status_code) # 200
print(r.json()) # dict — הJSON המפוענח
print(r.text) # str — גוף כטקסט גולמי
print(r.headers) # dict — Response headers
# GET עם params:
r = requests.get('https://api.github.com/users/torvalds',
headers={'Accept': 'application/vnd.github.v3+json'},
timeout=10)
if r.status_code == 200:
data = r.json()
print(f"Name: {data['name']}, Repos: {data['public_repos']}")
# POST עם JSON:
r = requests.post('https://httpbin.org/post',
json={'key': 'value'},
timeout=10)
# Error Handling:
try:
r = requests.get('https://httpbin.org/delay/10', timeout=2)
except requests.exceptions.Timeout:
print("Timeout!")
except requests.exceptions.ConnectionError:
print("No connection!")
# ─── axios (JavaScript) — API מרכזי ─────────────────────
const axios = require('axios');
// GET בסיסי:
const response = await axios.get('https://api.example.com/data');
console.log(response.data); // ← הJSON (לא response.json()!)
console.log(response.status); // 200
// POST עם Error Handling:
try {
const res = await axios.post('/api/items', { name: 'test' });
console.log('Created:', res.data);
} catch (error) {
if (error.response) {
// שרת החזיר 4xx/5xx
console.error('Server error:', error.response.status);
} else if (error.request) {
// לא קיבלנו תגובה כלל
console.error('Network error');
} else {
// שגיאה בהגדרת הRequest
console.error('Setup error:', error.message);
}
}| תכונה | requests (Python) | axios (JavaScript) |
|---|---|---|
| JSON Response | r.json() | response.data |
| Status Code | r.status_code | response.status |
| Async | Synchronous (blocking) | Promise / async-await |
| Error 4xx/5xx | אין Exception — בדוק status_code | זורק Exception עם error.response |
| Timeout | timeout=10 (שניות) | { timeout: 10000 } (ms) |
error.response הוא undefined. מה זה אומר?import requests
r = requests.get('https://api.github.com/users/torvalds',
timeout=10)
data = r.json()
print(data.get('public_repos', 0))
print(type(data['login']))מה יודפס (בהנחה שהAPI עובד)?קריאת C Header + Mindset מקצועי בסדנה
בסדנה אפשר לקבל ספרייה ב-C עם Header File בלבד — אין Docs, אין README. הכישרון לקרוא .h ולהסיק API הוא מיומנות RE בסיסית.
// ─── mysterylib.h — ספרייה לא מוכרת ────────────────────
typedef struct {
int id;
char name[64];
float score;
} Record;
// Initialize the library. Call before any other function.
// Returns: 0 on success, -1 on error
int mystery_init(const char *config_path);
// Create a new record. name: max 63 chars. score: 0.0-100.0
// Returns: pointer to Record, or NULL on failure
Record* mystery_create(const char *name, float score);
// Fetch record by ID. Returns NULL if not found.
Record* mystery_get(int id);
// Save all records to disk.
// Returns: number of records saved, or -1 on error
int mystery_save(const char *filepath);
// Free all resources. Call at end.
void mystery_cleanup(void);
// ─── ניתוח ה-Header: מה מסיקים? ──────────────────────────
// 1. struct Record: id (auto), name (max 63!), score (0-100)
// 2. Flow חובה: init() → create()/get() → save() → cleanup()
// 3. Error: return -1 / NULL על כישלון — תמיד בדוק!
// 4. init() קודם לכל — בלי זה כולם ייכשלו
// 5. mystery_create: לא malloc עצמנו — הספרייה מנהלת זיכרון
// ─── שימוש נכון ───────────────────────────────────────────
if (mystery_init(NULL) != 0) { return 1; } // תמיד בדוק!
Record *r = mystery_create("Alice", 95.5f);
if (!r) { mystery_cleanup(); return 1; } // NULL check!
printf("id=%d name=%s score=%.1f\n", r->id, r->name, r->score);
int saved = mystery_save("output.dat");
mystery_cleanup(); // תמיד בסוף!Mindset מקצועי בסדנה
| מצב | תגובה שגויה ❌ | תגובה נכונה ✅ |
|---|---|---|
| לא יודע את הספרייה | 'אני לא יכול לעשות את זה' | 'אני מתחיל ב-README / dir()' |
| שגיאה לא מובנת | פאניקה, מחיקת כל הקוד | קרא Error בקפידה, חפש GitHub Issues |
| תקוע 5 דקות | שתיקה, ויתור | חזור ל-Example, שנה גישה, דבר למלווה |
| הזמן עומד לפוג | מנסה לגמור הכל ושובר | 80% עובד מוצג > 100% שבור |
"קיבלתי Error, זה אומר שהParameter מצפה לtype אחר"
"הגעתי עד לנקודה X, החלק Y לא הספקתי — הנה הפתרון החלקי"
"שאלתי Stack Overflow על השגיאה הזו ומצאתי ש..."
המשפטים שמכשילים: 'לא יודע', 'לא מבין', 'אי אפשר' — בלי הסבר!
int db_connect(const char *host, int port, int timeout_ms);. מה אפשר להסיק על Error Handling?void* net_open(const char *url); int net_read(void *conn, char *buf, int size); void net_close(void *conn);. מה ה-Flow הנכון לשימוש?אתגר מעשי — סדנה תחת לחץ — Security ו-Debug
פורמט מיון אמיתי: מתוזמן, רב-קטגורי, תחת לחץ. בונוס-זמן על פתרון מהיר. ההגשה נבדקת אוטומטית מול מקרי-קצה נסתרים.
def bsearch(a, t):
lo, hi = 0, len(a) - 1
while lo <= hi:
mid = (lo + hi) // 2
if a[mid] == t: return mid
elif a[mid] < t: lo = mid # באג כאן
else: hi = mid - 1
return -1סיכום + Dry Run גאמא
הנה סיכום השיטות הקריטיות ושאלות מסכמות בסגנון מיון גאמא.
- שיטת 5 שלבים: README(5) → Example(5) → API Scan(5) → Implement(15) → Debug(5) = 30 דק׳
- dir(lib) + help(func) ב-Python = Docs מובנים, עובד גם Offline
- Traceback: קרא מלמטה למעלה. שורה תחתונה = סוג השגיאה ← זה מה שלתקן
- requests: r.json(), r.status_code, timeout=10. לא זורק על 4xx/5xx — בדוק ידנית
- axios: response.data, response.status. זורק Exception על 4xx/5xx. error.response vs error.request
- C Header: struct = נתונים, Comments = Docs, return -1/NULL = error, init→use→cleanup
- Mindset: קוד עובד חלקי > קוד שלם שבור. "תקוע כאן, הנה מה שניסיתי" > שתיקה
- תקוע? → dir(), help(), GitHub Issues, חזור לExample, דבר למלווה
result = api.search("gamma")['hits'][0]['title'] וקורס עם KeyError: 'hits'. מה הבעיה?Record* mystery_create(const char *name, float score);. כתבת: Record *r = mystery_create("Alice", 95.5); ומשתמש ב-r->name. מה החסר הקריטי?שאלות תרגול ותשובות (15)
שאלה 1.1 — שיטת הלמידה · קיבלת ספרייה Python לא מוכרת בסדנה. מה הצעד הראשון?
- א. לקרוא את כל ה-Documentation הרשמי של הספרייה מההתחלה ועד הסוף
- ב. לפנות למלווה בסדנה ולבקש ממנו שיסביר בדיוק מה הספרייה עושה
- ג. import the_lib; print(dir(the_lib)) כדי לחשוף מיד את כל ה-API הזמין
- ד. להתחיל לכתוב קוד שמנחש את שמות הפונקציות וה-API של הספרייה
✓ תשובה: ג) — dir() הוא ה-API Scanner המובנה של Python. תוך שניות רואים רשימת כל הפונקציות והמחלקות. help() נותן documentation מהיר על כל פונקציה — Parameters, Returns, Raises. זה מהיר בהרבה מקריאת Docs חיצוניים, ועובד גם ב-Offline.
שאלה 1.2 — ניהול זמן · אתה תקוע 8 דקות על בעיה בסדנה. מה עושים?
- א. המשך לנסות עוד ועוד, מפני שקרוב לוודאי שהפתרון כבר ממש קרוב
- ב. מחק את כל הקוד שכתבת עד כה והתחל את המשימה כולה מחדש מאפס
- ג. דלג על הסעיף הזה באופן מלא ועבור ישר לסעיף הבא של המשימה
- ד. שנה גישה: חפש את השגיאה ב-GitHub Issues וחזור לבנות מ-Example בסיסי
✓ תשובה: ד) — שתיקה + ויתור = הכישלון הכי גרוע. חיפוש GitHub Issues עם הודעת השגיאה המדויקת נותן לרוב פתרון תוך דקות. חזרה ל-Basic Example ובנייה הדרגתית עליו — Strategy מוכחת. דיבור למלווה מראה יכולת תקשורת ומודעות עצמית, וקלות עוזרת.
שאלה 1.3 — Dry Run: json.loads · import json raw = '{"name": "gamma", "score": 95, "tags": ["cyber", "ctf"]}' data = json.loads(raw) print(type(data)) print(data['tags'][1]) print(data.get('level', 'unknown'))מה הפלט?
import json
raw = '{"name": "gamma", "score": 95, "tags": ["cyber", "ctf"]}'
data = json.loads(raw)
print(type(data))
print(data['tags'][1])
print(data.get('level', 'unknown'))- א. dict / cyber / unknown — tags[1] הוא הערך השני ברשימת ה-tags
- ב. dict / ctf / None — get() מחזיר None כאשר אין ברירת-מחדל מוגדרת
- ג. <class 'dict'> / ctf / unknown — get() מחזיר ברירת-מחדל למפתח חסר
- ד. str / ctf / None — json.loads מחזיר מחרוזת גולמית ולא מילון נתונים
✓ תשובה: ג) — json.loads() מחזיר Python dict. type(data) = <class 'dict'>. data['tags'] = ["cyber","ctf"]. tags[1] = "ctf" (אינדקס 1). data.get('level', 'unknown'): 'level' לא קיים ב-dict → מחזיר 'unknown'. שים לב: data['level'] היה זורק KeyError!
שאלה 2.1 — זיהוי Error · קיבלת: TypeError: connect() missing 1 required positional argument: 'port'. מה עושים?
TypeError: connect() missing 1 required positional argument: 'port'
- א. חפש את הטקסט 'TypeError Python' במנוע החיפוש וקווה לפתרון מהיר
- ב. הסר לחלוטין את השורה שקוראת ל-connect() כדי להיפטר מן השגיאה
- ג. הסר והתקן מחדש את הספרייה, שכן ייתכן שההתקנה הנוכחית פגומה
- ד. קרא help(connect) כדי לראות את הפרמטרים הנדרשים ואז תקן את הקריאה
✓ תשובה: ד) — ה-Error מספר בדיוק מה חסר: פרמטר 'port'. help(connect) מציג את כל הפרמטרים הנדרשים ואופציונליים. TypeError = טיפוס שגוי או פרמטר חסר — תמיד קרא מה הפונקציה מצפה. ה-Error הוא ה-Doc!
שאלה 2.2 — קריאת Traceback · File 'scanner.py', line 23, in run_scan results = api.scan(target) File '/lib/api.py', line 67, in scan sock.connect((host, port)) ConnectionRefusedError: [Errno 111] Connection refusedמה הבעיה וכיצד לתקן?
File 'scanner.py', line 23, in run_scan results = api.scan(target) File '/lib/api.py', line 67, in scan sock.connect((host, port)) ConnectionRefusedError: [Errno 111] Connection refused
- א. השירות שאליו מנסים להתחבר אינו פועל, או שה-host/port שגויים — בדוק
- ב. מדובר בשגיאת תחביר (Syntax) בשורה 23 של הקובץ scanner.py שכתבת
- ג. הספרייה api כלל אינה מותקנת במערכת, ולכן יש להריץ pip install api
- ד. חסר קובץ המקור lib/api.py שהספרייה מנסה לטעון בזמן הריצה שלה
✓ תשובה: א) — קוראים מלמטה למעלה: שורה תחתונה = ConnectionRefusedError: Connection refused. זה אומר שמנסים לפתוח TCP connection אבל השרת לא מקשיב. הקוד שלך ב-line 23. לבדוק: target נכון? Port פתוח? אם זה סדנה — האם השרת שלהם רץ? שאל את המלווה.
שאלה 2.3 — AttributeError על None · import requests r = requests.get('https://api.example.com/data') print(r.json()['result']) # שגיאה: AttributeError: 'NoneType' object has no attribute 'json'מה הסיבה ומה התיקון?
import requests
r = requests.get('https://api.example.com/data')
print(r.json()['result'])
# שגיאה: AttributeError: 'NoneType' object has no attribute 'json'- א. הספרייה requests אינה מותקנת כלל, ולכן יש להריץ pip install requests
- ב. ל-Response אין מתודת json(), ולכן צריך להשתמש במקום זאת ב-.text
- ג. r הוא None (שגיאת רשת או URL שגוי) — בדוק זאת לפני הגישה ל-.json()
- ד. ה-API החזיר את הקוד 404, ולכן יש לוודא ש-status_code שווה ל-200
✓ תשובה: ג) — requests.get() יכול להחזיר None אם יש שגיאת רשת, או לזרוק Exception. ה-AttributeError "NoneType has no attribute 'json'" = r היא None. תיקון: if r and r.status_code == 200: data = r.json(). תמיד בדוק None ו-status_code לפני שימוש ב-Response.
שאלה 3.1 — requests vs axios · ב-requests (Python) קיבלת Response עם status_code=404. האם נזרקה Exception?
- א. כן — הספרייה requests זורקת Exception על כל שגיאת HTTP שמתקבלת
- ב. לא — requests אינו זורק Exception על 4xx/5xx; יש לבדוק status_code ידנית
- ג. כן — הקוד 404 תמיד גורם לזריקת חריגה מסוג FileNotFoundError
- ד. זה תלוי לחלוטין בגרסה הספציפית של הספרייה requests המותקנת אצלך
✓ תשובה: ב) — ההבדל המרכזי בין requests לaxios: axios זורק Exception על 4xx/5xx (ל-catch ב-try-catch). requests לא — הוא מחזיר Response עם status_code=404 ומצפה שתבדוק. אפשר להפעיל r.raise_for_status() כדי שrequests יזרוק Exception על שגיאות HTTP.
שאלה 3.2 — axios error types · ב-axios קיבלת Exception בtry-catch. error.response הוא undefined. מה זה אומר?
error.response
- א. השרת קיבל את הבקשה והחזיר עליה שגיאת שרת פנימית מסוג 500
- ב. הבקשה עצמה כלל לא נשלחה מהדפדפן אל השרת בשל שגיאה מוקדמת
- ג. ה-JSON שהתקבל בגוף התגובה אינו תקין, ולכן הפענוח שלו נכשל
- ד. הבקשה נשלחה אך לא התקבלה תגובה — זו שגיאת רשת (Timeout או DNS)
✓ תשובה: ד) — axios מסווג שגיאות ל-3: (1) error.response מוגדר = שרת ענה עם 4xx/5xx. (2) error.request מוגדר, error.response = undefined = Request יצא אבל ללא תגובה (Timeout/Connection Refused). (3) שניהם undefined = שגיאה בהגדרת ה-Request עצמו.
שאלה 3.3 — Dry Run: requests · import requests r = requests.get('https://api.github.com/users/torvalds', timeout=10) data = r.json() print(data.get('public_repos', 0)) print(type(data['login']))מה יודפס (בהנחה שהAPI עובד)?
import requests
r = requests.get('https://api.github.com/users/torvalds',
timeout=10)
data = r.json()
print(data.get('public_repos', 0))
print(type(data['login']))- א. שגיאת KeyError, מכיוון שהמפתח 'public_repos' כלל אינו קיים ב-JSON
- ב. הערך 0 ולאחריו <class 'int'>, מכיוון ש-login מוחזר כמספר שלם
- ג. מספר כלשהו ואז <class 'str'> — public_repos הוא int ו-login מחרוזת
- ד. הערך None ולאחריו <class 'dict'>, מכיוון ש-data הוא מילון מקונן
✓ תשובה: ג) — r.json() מחזיר dict. data.get('public_repos', 0) = מחזיר את הערך (מספר repos) או 0 אם לא קיים. data['login'] = שם המשתמש כ-string. type(str) = <class 'str'>. שים לב: ב-JSON, numbers → Python int, strings → Python str.
שאלה 4.1 — קריאת C Header · ב-Header רואים: int db_connect(const char *host, int port, int timeout_ms);. מה אפשר להסיק על Error Handling?
int db_connect(const char *host, int port, int timeout_ms);
- א. לפי מוסכמת C: הערך 0 מציין הצלחה ו--1 מציין כישלון — תמיד לבדוק
- ב. הפונקציה תמיד מצליחה, וערך ה-int המוחזר הוא מזהה החיבור שנוצר
- ג. הפונקציה זורקת Exception במקרה של כישלון בהתחברות אל השרת
- ד. ערך ההחזרה מסוג const char* הוא מחרוזת המתארת את פרטי השגיאה
✓ תשובה: א) — C Convention סטנדרטי: int return value שלילי (-1) = כישלון, 0 = הצלחה (או ID חיובי). const char *host = input בלבד (const). timeout_ms = timeout במילישניות. תמיד בדוק return value ב-C — אין Exception mechanism אוטומטי. זה נלמד מקריאת Header בלבד!
שאלה 4.2 — Mindset · אתה בסדנה, נתנו לך ספרייה ב-C. כתבת קוד שעובד 80% — חלק אחד נשבר. נותרות 3 דקות. מה עושים?
- א. הצג את מה שעובד והסבר בבירור מה לא הספקת ומה ניסית לעשות בחלק X
- ב. מחק את כל מה שכתבת עד כה ונסה במהירות פתרון חלופי אחר לגמרי
- ג. שמור על שתיקה מוחלטת ואל תציג דבר עד שתסיים את כל המשימה
- ד. בקש מהבוחן הארכת זמן כדי שתוכל להשלים גם את החלק שנשבר לך
✓ תשובה: א) — 80% עובד + הסבר ברור > 100% שבור. הבוחן מעריך: (1) מה הצלחת לממש. (2) האם אתה מבין מה חסר. (3) האם יש לך תכנית לפתרון. מחיקה ב-3 דקות האחרונות = אסון. שתיקה = לא מראה מה ידעת. דיבור על מה עבד ומה לא = Professional.
שאלה 4.3 — גאמא סגנון: Flow מלא · בסדנה קיבלת Header: void* net_open(const char *url); int net_read(void *conn, char *buf, int size); void net_close(void *conn);. מה ה-Flow הנכון לשימוש?
void* net_open(const char *url); int net_read(void *conn, char *buf, int size); void net_close(void *conn);
- א. net_read → net_open → net_close: קריאה תחילה ורק אחריה הפתיחה
- ב. net_open → בדוק NULL → net_read בלולאה → net_close תמיד בסוף
- ג. net_open → net_read → net_open שוב → net_close בסיום התהליך
- ד. net_read → net_close → net_open: סגירה עוד לפני פתיחת החיבור
✓ תשובה: ב) — מה-Header מסיקים: net_open מחזיר void* (handle) → יכול להיות NULL על כישלון → חייב לבדוק. net_read מקבל conn → צריך אחרי open. net_close = cleanup שחייב תמיד לקרות. Pattern קלאסי: init → use → cleanup. אם net_read מחזיר int (bytes read) → לולאה עד 0/-1.
גאמא סגנון א׳ — שיטה בפעולה · בסדנה קיבלת ספרייה Python לא מוכרת ושאלה: 'שלח HTTP GET ל-API וקבל שדה "result"'. אין README. מה 3 הצעדים הראשונים?
- א. לחפש במנוע החיפוש, לשאול את המלווה, ואז לחכות בסבלנות לתשובה
- ב. לכתוב מיד requests.get() ולנחש את שם השדה ואת מבנה התגובה
- ג. לקרוא מההתחלה ועד הסוף את כל קוד המקור של הספרייה הלא-מוכרת
- ד. (1) print(dir(lib)) — מה קיים? (2) help(lib.get) — פרמטרים? (3) קוד
✓ תשובה: ד) — ה-3 צעדים: dir() → help() → כתוב. זה ה-API Scan השלב מהשיטה, אבל כשאין README מתחילים ישר בו. תוך 5 דקות יודעים: מה הפונקציות, מה הפרמטרים, מה ה-Return Value. אחר כך ממשים ב-15 דקות.
גאמא סגנון ב׳ — Error Diagnosis · קוד Python מריץ result = api.search("gamma")['hits'][0]['title'] וקורס עם KeyError: 'hits'. מה הבעיה?
result = api.search("gamma")['hits'][0]['title']- א. ה-dict שמחזירה api.search() אינו מכיל את המפתח 'hits' — בדוק את keys()
- ב. הספרייה כלל אינה מותקנת, ולכן הקריאה ל-api.search נכשלת באופן מיידי
- ג. מדובר ב-IndexError, מכיוון שאין איבר כלל במקום ה-0 של הרשימה
- ד. המתודה search() מחזירה את הערך None ולא מילון של תוצאות חיפוש
✓ תשובה: א) — KeyError: 'hits' = ה-dict שמוחזר לא מכיל את המפתח 'hits'. אולי ה-API משתמש ב-'results' / 'data' / 'items'. תמיד: print(api.search("gamma")) ולראות את מבנה ה-dict האמיתי. לא להניח על שמות מפתחות.
גאמא סגנון ג׳ — C Header: Error Pattern · ב-Header: Record* mystery_create(const char *name, float score);. כתבת: Record *r = mystery_create("Alice", 95.5); ומשתמש ב-r->name. מה החסר הקריטי?
Record* mystery_create(const char *name, float score);
- א. לא בדקת ש-r אינו NULL לפני הגישה אליו — הדבר עלול לגרום ל-Crash
- ב. הערך 95.5 חייב היה להיכתב כ-95.5f כדי להיות literal מסוג float
- ג. היה צורך לקרוא תחילה לפונקציית mystery_init() עוד לפני היצירה
- ד. היה צורך להקצות זיכרון עם malloc עוד לפני הקריאה ל-create
✓ תשובה: א) — Header אומר: "Returns: pointer to Record, or NULL on failure". גישה ל-r->name כשr=NULL = Segmentation Fault ← קריסה מיידית. כלל: כל פונקציה C שמחזירה pointer → תמיד בדוק NULL לפני גישה. (ג) גם נכון אבל לא הסיבה לקריסה כאן.)