Kodax

JSON و CSV: تبادل البيانات — هياكل البيانات

JSON و CSV: تبادل البيانات

الملف النصي العادي مناسب للملاحظات، لكن البيانات المنظمة تحتاج تنسيقاً متفقاً عليه حتى تقرأها برامج أخرى. أشهر تنسيقين: JSON للبيانات المتداخلة (تطبيقات الويب والإعدادات)، و CSV للجداول (Excel وجداول البيانات).

JSON

يشبه قواميس وقوائم Python:

{"name": "منى", "age": 21, "skills": ["Python", "SQL"], "active": true}

| Python | JSON |

|---|---|

| dict | object {} |

| list, tuple | array [] |

| str | string (بعلامات تنصيص مزدوجة فقط) |

| True / False / None | true / false / null |

أربع دوال فقط

| الدالة | الوظيفة |

|---|---|

| json.dumps(obj) | كائن Python ← نص JSON |

| json.loads(text) | نص JSON ← كائن Python |

| json.dump(obj, f) | كتابة إلى ملف |

| json.load(f) | قراءة من ملف |

حرف s في النهاية يعني string.

import json
user = {"name": "منى", "skills": ["Python"]}
with open("user.json", "w", encoding="utf-8") as f:
    json.dump(user, f, ensure_ascii=False, indent=2)

- ensure_ascii=False ليُحفظ النص العربي مقروءاً بدل منى.

- indent=2 لتنسيق مريح للقراءة.

مفاتيح JSON نصوص دائماً: القاموس {1: "a"} يعود بعد الحفظ والقراءة {"1": "a"}.

CSV

كل سطر صف، والقيم مفصولة بفواصل:

name,city,score
منى,البصرة,95

استخدم وحدة csv ولا تقسّم بـ split(",") يدوياً: القيمة قد تحتوي فاصلة داخل علامات تنصيص.

import csv
with open("students.csv", newline="", encoding="utf-8") as f:
    for row in csv.DictReader(f):     # كل صف قاموس بأسماء الأعمدة
        print(row["name"], int(row["score"]))

- كل القيم تُقرأ كنصوص؛ حوّل الأرقام بنفسك.

- newline="" مطلوبة عند فتح ملفات CSV حتى لا تظهر أسطر فارغة إضافية في Windows.

للكتابة: csv.DictWriter(f, fieldnames=[...]) ثم writeheader() و writerow(dict).

Excel والعربية

لكي يفتح Excel ملف CSV عربي بشكل صحيح، احفظه بترميز "utf-8-sig".

JSON أم CSV؟

| JSON | CSV |

|---|---|

| بيانات متداخلة (قوائم داخل كائنات) | جدول بسيط بأعمدة ثابتة |

| واجهات الويب (APIs) | التصدير إلى Excel |

تمرين

اقرأ ملف CSV للمنتجات (الاسم، الفئة، السعر)، واحسب متوسط السعر لكل فئة، واحفظ النتيجة في ملف JSON بنص عربي مقروء.

import csv
import json
from pathlib import Path

# ===== JSON =====
user = {"name": "منى", "age": 21, "skills": ["Python", "SQL"], "active": True, "manager": None}

text = json.dumps(user, ensure_ascii=False)
print(text)
back = json.loads(text)
print(back["skills"][0], back["active"])

Path("user.json").write_text(json.dumps(user, ensure_ascii=False, indent=2), encoding="utf-8")
with open("user.json", encoding="utf-8") as f:
    loaded = json.load(f)
print(loaded == user)                       # True

# مفاتيح JSON نصوص دائماً
print(json.loads(json.dumps({1: "a"})))     # {'1': 'a'}

# ===== CSV: كتابة =====
rows = [
    {"name": "منى", "city": "البصرة", "score": 95},
    {"name": "علي", "city": "بغداد", "score": 72},
    {"name": "زيد", "city": "بغداد", "score": 88},
]
with open("students.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=["name", "city", "score"])
    writer.writeheader()
    writer.writerows(rows)

# ===== CSV: قراءة (كل القيم نصوص) =====
by_city = {}
with open("students.csv", newline="", encoding="utf-8") as f:
    for row in csv.DictReader(f):
        score = int(row["score"])
        by_city.setdefault(row["city"], []).append(score)

averages = {city: sum(s) / len(s) for city, s in by_city.items()}
print(averages)

# تنظيف ملفات المثال
Path("user.json").unlink()
Path("students.csv").unlink()
اختبر فهمك