<div dir="rtl" lang="he">

# תרגילים - שיעור 5.4: JSON - קריאה, כתיבה ומניפולציה של מידע מובנה

## מידע כללי
- **שיעור:** 5.4 - JSON
- **סוג השיעור:** מעשי (2 שעות)
- **הערה:** התרגילים בנויים בדרגת קושי עולה. חשוב לבצע אותם לפי הסדר כדי לבנות את ההבנה בצורה הדרגתית.

---

## תרגיל 1: קריאה מקובץ JSON בסיסי (קריאה - 15 דקות)
### הנחיות:
נתון לכם קובץ בשם `israeli_tech.json` המכיל רשימה של חברות הייטק ישראליות. עליכם לכתוב סקריפט פייתון שיקרא את תוכן הקובץ וידפיס למסך את שם החברה השנייה ברשימה ואת סך כל העובדים בחברה הראשונה.

**israeli_tech.json:**
```json
[
  {
    "name": "Wix",
    "founded": 2006,
    "employees": 6000
  },
  {
    "name": "Monday.com",
    "founded": 2012,
    "employees": 1500
  },
  {
    "name": "ironSource",
    "founded": 2010,
    "employees": 1000
  }
]
```

### קוד התחלתי:
```python
import json

def read_company_data(file_path):
    # Your code here
    # 1. פתחו את הקובץ לקריאה
    # 2. טענו את תוכן ה-JSON באמצעות json.load()
    # 3. הדפיסו את שם החברה השנייה (אינדקס 1)
    # 4. הדפיסו את מספר העובדים בחברה הראשונה (אינדקס 0)

# קריאה לפונקציה עם הנתיב לקובץ
read_company_data('israeli_tech.json')
```

---

## תרגיל 2: כתיבה לקובץ JSON עם עברית (כתיבה - 15 דקות)
### הנחיות:
כתבו סקריפט פייתון שיוצר מילון (dictionary) המייצג מוצר ישראלי. המילון צריך להכיל שם בעברית, מחיר (מסוג float) ותיאור בעברית. לאחר מכן, שמרו את המילון לקובץ בשם `product.json` תוך שימוש בקידוד UTF-8 המתאים לעברית.

### שאלות:
1.  צרו מילון פייתון עם המפתחות `product_name`, `price`, `description`. מלאו אותו בפרטים על מוצר ישראלי לבחירתכם (לדוגמה: "במבה", 2.90, "חטיף בוטנים קלאסי").
2.  השתמשו ב-`json.dump()` כדי לכתוב את המילון לקובץ `product.json`.
3.  ודאו שאתם משתמשים בפרמטרים `indent=4` כדי שהקובץ יהיה קריא, וחשוב מכל - `ensure_ascii=False` כדי שהעברית תוצג כראוי ולא כקודי Unicode.
4.  פתחו את הקובץ `product.json` וודאו שהתוכן נשמר נכון ובעברית.

### קוד התחלתי:
```python
import json

product_data = {
    # השלימו את פרטי המוצר כאן
}

file_path = 'product.json'

# Your code here
# השתמשו ב-with open(...) וב-json.dump() עם הפרמטרים הנכונים

print(f"המוצר נשמר בהצלחה בקובץ {file_path}")
```

---

## תרגיל 3: ניווט ופיענוח JSON מקונן (Nested JSON - 20 דקות)
### הנחיות:
קבלתם אובייקט JSON המייצג הזמנה מאתר קניות ישראלי. האובייקט מכיל פרטי לקוח, כתובת למשלוח ורשימת פריטים שהוזמנו. עליכם לכתוב פונקציה שמקבלת את ה-JSON כ-string, מפענחת אותו ומדפיסה סיכום הזמנה.

**נתוני ה-JSON (כ-string):**
```python
order_json_str = """
{
  "order_id": "SH-102-559",
  "customer": {
    "name": "ישראל ישראלי",
    "email": "israel@example.com"
  },
  "shipping_address": {
    "street": "הרצל 15",
    "city": "תל אביב",
    "zip_code": "6608811"
  },
  "items": [
    {
      "product_id": "milk-3",
      "name": "חלב תנובה 3%",
      "quantity": 2,
      "price_per_unit": 6.20
    },
    {
      "product_id": "cottage-5",
      "name": "קוטג' 5%",
      "quantity": 3,
      "price_per_unit": 5.80
    }
  ],
  "is_paid": true
}
"""
```

### שאלות:
1.  טענו את ה-string `order_json_str` למילון פייתון באמצעות `json.loads()`.
2.  כתבו קוד ששולף ומדפיס את המידע הבא:
    *   שם הלקוח.
    *   העיר למשלוח.
    *   שם המוצר השני ברשימת הפריטים.
3.  חשבו והדפיסו את המחיר הכולל של ההזמנה (סכום של `quantity * price_per_unit` עבור כל פריט).

---

## תרגיל 4: עיבוד Webhook תשלומים (אינטגרציה - 20 דקות)
### הנחיות:
אתם מפתחים מערכת e-commerce, וקיבלתם Webhook מספק שירותי התשלומים "ישראכרט" לאחר ניסיון חיוב. המידע מגיע בפורמט JSON. עליכם לכתוב פונקציה המעבדת את המידע הזה.

**נתוני ה-Webhook (כמילון פייתון):**
```python
webhook_payload = {
    "event_type": "transaction.succeeded",
    "timestamp": "2026-05-10T12:30:00Z",
    "data": {
        "transaction_id": "tr_a8b2c1d3",
        "amount": 249.90,
        "currency": "ILS",
        "customer_id": "cust_z9y8x7",
        "payment_details": {
            "card_type": "MasterCard",
            "last_4_digits": "1234"
        }
    }
}
```

### שאלות:
1.  כתבו פונקציה `process_payment_webhook` שמקבלת את המילון `webhook_payload`.
2.  בתוך הפונקציה, בדקו אם ערך המפתח `event_type` הוא `transaction.succeeded`.
3.  אם התנאי מתקיים, הדפיסו הודעה המפרטת את פרטי העסקה המוצלחת:
    *   "עסקה אושרה!"
    *   "מזהה עסקה: {transaction_id}"
    *   "סכום: {amount} {currency}"
    *   "4 ספרות אחרונות: {last_4_digits}"
4.  אם ה-`event_type` שונה, הדפיסו הודעת שגיאה.

---

## תרגיל 5: פיענוח תגובת JSON מ-LLM (אינטגרציית AI - 20 דקות)
### הנחיות:
שלחתם בקשה למודל שפה גדול (LLM) כדי לקבל המלצות על מסעדות בתל אביב. המודל החזיר תשובה בפורמט JSON, אך היא מגיעה כ-string גולמי. המשימה שלכם היא לפענח את ה-JSON ולהציג את המידע בצורה ידידותית למשתמש.

**תגובת ה-LLM (כ-string):**
```python
llm_response_str = """
{
  "query": "מסעדות מומלצות בתל אביב",
  "recommendations": [
    {
      "name": "האחים",
      "cuisine": "ישראלי",
      "rating": 4.5
    },
    {
      "name": "טאיזו",
      "cuisine": "אסייאתי",
      "rating": 4.8
    },
    {
      "name": "פורט סעיד",
      "cuisine": "ים תיכוני",
      "rating": 4.3
    }
  ]
}
"""
```

### שאלות:
1.  השתמשו ב-`json.loads()` כדי להמיר את `llm_response_str` לאובייקט פייתון.
2.  כתבו לולאה שעוברת על רשימת ההמלצות (`recommendations`).
3.  בכל איטרציה, הדפיסו את פרטי המסעדה בפורמט הבא:
    `שם: [שם המסעדה], סגנון: [סוג המטבח], דירוג: [הדירוג]`

---

## תרגיל 6: ולידציה של תגובת AI עם Pydantic (אינטגרציית AI - 20 דקות)
### הנחיות:
בהמשך לתרגיל הקודם, לפעמים ה-LLM מחזיר מידע לא עקבי (למשל, דירוג כמחרוזת במקום כמספר). נשתמש בספריית `Pydantic` כדי לוודא שהמידע תקין ולהמיר אותו לסוגי הנתונים הנכונים.

### קוד התחלתי:
```python
from pydantic import BaseModel, ValidationError
from typing import List
import json

# תגובת LLM עם סוג נתונים לא תקין בדירוג
llm_messy_response_str = """
{
  "recommendations": [
    { "name": "האחים", "cuisine": "ישראלי", "rating": 4.5 },
    { "name": "טאיזו", "cuisine": "אסייאתי", "rating": "4.8" }, 
    { "name": "פורט סעיד", "cuisine": "ים תיכוני", "rating": 4 }
  ]
}
"""

# 1. הגדירו את המודלים של Pydantic
class Restaurant(BaseModel):
    # Your code here: name (str), cuisine (str), rating (float)
    pass

class RecommendationsResponse(BaseModel):
    # Your code here: recommendations (List[Restaurant])
    pass

# 2. פענחו את ה-JSON וצרו אובייקט Pydantic
try:
    data = json.loads(llm_messy_response_str)
    # Your code here: צרו אובייקט RecommendationsResponse מה-data
    
    # 3. אם הוולידציה הצליחה, הדפיסו את המידע
    # ...
    
except ValidationError as e:
    print("שגיאת ולידציה:", e)

```
### שאלות:
1. השלימו את הגדרת המודלים `Restaurant` ו-`RecommendationsResponse` ב-Pydantic. שימו לב ש-`rating` צריך להיות `float`.
2. טענו את `llm_messy_response_str` ובצעו ולידציה מול המודל `RecommendationsResponse`.
3. הדפיסו את אחת ההמלצות מהאובייקט שיצרתם ובדקו מהו ה-type של שדה הדירוג שלה. האם `Pydantic` המיר את המחרוזת "4.8" למספר `float`?

---

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

**קובץ התחלתי `books.json`:**
```json
{
    "books": [
        {
            "id": "978-0321765723",
            "title": "התפסן בשדה השיפון",
            "author": "ג'.ד. סלינג'ר",
            "price": 65.50,
            "stock": 10
        },
        {
            "id": "978-0743273565",
            "title": "אלכימאי",
            "author": "פאולו קואלו",
            "price": 72.00,
            "stock": 5
        }
    ]
}
```

### משימות:
1.  **קריאה:** כתבו פונקציה `load_books(filepath)` שטוענת את נתוני הספרים מהקובץ.
2.  **הוספה:** כתבו פונקציה `add_book(books_data, new_book)` שמקבלת את רשימת הספרים הקיימת ואובייקט של ספר חדש, ומוסיפה אותו לרשימה.
3.  **עדכון:** כתבו פונקציה `update_stock(books_data, book_id, new_stock)` שמוצאת ספר לפי `id` ומעדכנת את המלאי (`stock`) שלו.
4.  **שמירה:** כתבו פונקציה `save_books(filepath, books_data)` ששומרת את המבנה המעודכן בחזרה לקובץ JSON, עם תמיכה בעברית.
5.  **איחוד:** כתבו סקריפט ראשי שמבצע את הצעדים הבאים:
    *   טוען את הנתונים מ-`books.json`.
    *   מוסיף ספר חדש לבחירתכם.
    *   מעדכן את המלאי של "אלכימאי" ל-8 יחידות.
    *   שומר את הנתונים המעודכנים בחזרה לקובץ `books.json`.

**הגישו את קובץ הפייתון (.py) ואת קובץ ה-JSON המעודכן עד השיעור הבא.**

---

## קריטריונים להערכה
| קריטריון | ציון |
|---|---|
| תרגיל 1: קריאה נכונה והדפסת הנתונים | 10% |
| תרגיל 2: כתיבה נכונה עם `ensure_ascii=False` | 10% |
| תרגיל 3: ניווט נכון במבנה מקונן וחישוב הסכום | 15% |
| תרגיל 4: לוגיקה נכונה לעיבוד Webhook | 15% |
| תרגיל 5: פיענוח והצגת תגובת LLM | 15% |
| תרגיל 6: שימוש נכון ב-Pydantic לוולידציה | 15% |
| תרגיל 7 (בית): פתרון מלא, קוד קריא ופונקציונלי | 20% |
| **סה"כ** | **100%** |

</div>