أهلاً بك في هذا الدرس الجديد!
في الدرس السابق، قمنا ببناء أول "أداة" عملية لوكيلنا: دالة send_email. هذه الدالة تمثل "ذراع" الوكيل التي تمكنه من "التصرف" في العالم الرقمي عبر إرسال البريد الإلكتروني.
اليوم، سنقوم ببناء الأداة الثانية في صندوق أدوات وكيلنا. إذا كانت send_email هي "الذراع"، فإن أداة اليوم ستكون بمثابة "العين" التي يقرأ بها الوكيل البيانات. هدفنا هو بناء أداة لقراءة قائمة المستلمين من ملف. هذه الخطوة أساسية، فقبل أن يتمكن الوكيل من إرسال أي بريد، يجب أن يعرف إلى من سيرسل وما هي المعلومات المتوفرة عن كل شخص.
سنتعلم كيفية التعامل مع نوعين شائعين جدًا من ملفات البيانات: CSV و JSON، وسننشئ دالة بايثون قوية يمكنها قراءة كليهما.
1. فهم تنسيق CSV والتعامل معه
ملفات CSV (اختصار لـ Comma-Separated Values أو "القيم المفصولة بفواصل") هي واحدة من أبسط الطرق لتخزين البيانات الجدولية. تخيل جدول بيانات بسيط في Excel، ولكن محفوظ كملف نصي عادي، حيث يمثل كل سطر صفًا في الجدول، وتفصل الفواصل بين الخلايا.
على سبيل المثال، يمكن أن تبدو قائمة المستلمين لدينا في ملف recipients.csv بهذا الشكل:
name,email,city
أحمد,ahmad@example.com,الرياض
فاطمة,fatima@example.com,جدة
يوسف,youssef@example.com,دبي
لغة بايثون توفر مكتبة مدمجة اسمها csv تجعل قراءة هذه الملفات والتعامل معها أمرًا سهلاً وآمنًا، وتتجنب المشاكل التي قد تحدث عند محاولة تقسيم السطور يدويًا (على سبيل المثال، ماذا لو كان أحد الحقول يحتوي على فاصلة؟).
الفيديو التالي يقدم شرحًا ممتازًا لكيفية استخدام مكتبة csv في بايثون.
Python Tutorial: CSV Module - How to Read, Parse, and Write CSV Files
شاهد هذا المقطع من قناة Corey Schafer لتفهم أساسيات التعامل مع ملفات CSV. ركز على الفرق بين csv.reader الذي يعيد البيانات كقوائم، و csv.DictReader الذي يعيدها كقواميس وهو ما سنعتمد عليه.
شاهد أولاً الجزء من الدقيقة 1:57 إلى 4:53 لفهم طريقة القراءة الأساسية باستخدام csv.reader. ثم شاهد الجزء الأهم من الدقيقة 10:39 إلى 12:17 الذي يشرح csv.DictReader.
كما رأيت في الفيديو، استخدام csv.DictReader هو الطريقة المثلى لنا. لماذا؟ لأنه يقرأ كل سطر في الملف كقاموس (Dictionary)، ويستخدم الصف الأول (الترويسة أو Header) كمفاتيح للقاموس. هذا يجعل الكود أكثر وضوحًا وقابلية للصيانة، حيث يمكنك الوصول إلى البيانات باستخدام أسماء ذات معنى مثل row['email'] بدلاً من الفهارس الرقمية المبهمة مثل row[1].
للحصول على شرح نصي مفصل باللغة العربية، يمكنك مراجعة المقال التالي من أكاديمية حسوب.
العمل مع ملفات CSV وبيانات JSON باستخدام لغة بايثون
يقدم هذا المقال شرحًا نصيًا رائعًا للتعامل مع ملفات CSV. سيعزز فهمك للمفاهيم التي شاهدتها في الفيديو ويوفر لك مرجعًا مكتوبًا يمكنك العودة إليه.
اقرأ قسم "كائنات reader" لفهم الأساسيات. ثم انتقل إلى قسم "كائنات DictReader و DictWriter الخاصة بملفات CSV" وركز على DictReader لأنه يوضح الطريقة التي سنستخدمها.
2. فهم تنسيق JSON والتعامل معه
تنسيق JSON (اختصار لـ JavaScript Object Notation) هو تنسيق شائع آخر لتبادل البيانات، وهو مفضل بشكل خاص في واجهات برمجة التطبيقات (APIs). يعتمد على بنية "مفتاح-قيمة" (key-value) تشبه إلى حد كبير قواميس بايثون.
نفس قائمة المستلمين السابقة يمكن تمثيلها في ملف recipients.json بهذا الشكل:
[
{
"name": "أحمد",
"email": "ahmad@example.com",
"city": "الرياض"
},
{
"name": "فاطمة",
"email": "fatima@example.com",
"city": "جدة"
},
{
"name": "يوسف",
"email": "youssef@example.com",
"city": "دبي"
}
]
هل تلاحظ التشابه؟ هذا الهيكل هو عبارة عن قائمة (list) من القواميس (dictionaries)، وهو نفس الهيكل الذي نسعى للحصول عليه من ملفات CSV! هذه الميزة تجعل التعامل مع JSON في بايثون سهلاً للغاية باستخدام مكتبة json المدمجة.
شاهد هذا المقطع القصير لترى كيف يتم ذلك.
يشرح هذا الفيديو من قناة Tech With Tim ببساطة شديدة كيفية قراءة ملف JSON وتحويله مباشرة إلى قاموس أو قائمة في بايثون.
شاهد المقطع من الدقيقة 4:04 إلى 4:53. ركز على استخدام الدالة json.load() لتحميل محتوى الملف إلى متغير.
بسطرين فقط، يمكننا قراءة ملف JSON بأكمله وتحويله إلى بنية بيانات بايثون أصلية، جاهزة للاستخدام الفوري.
3. بناء أداة قراءة الملفات
الآن، دعنا نجمع ما تعلمناه لبناء دالة ذكية يمكنها قراءة قائمة المستلمين بغض النظر عما إذا كانت مخزنة في ملف CSV أو JSON. سنضيف هذه الدالة إلى ملف tools.py الذي أنشأناه في الدرس السابق.
ستقوم الدالة بالخطوات التالية:
- تستقبل مسار الملف كمدخل.
- تتحقق من امتداد الملف (
.csvأو.json). - تستخدم الطريقة المناسبة لقراءة الملف بناءً على امتداده.
- تعالج الأخطاء المحتملة، مثل عدم العثور على الملف.
- تعيد البيانات دائمًا بنفس التنسيق: قائمة من القواميس.
افتح ملف tools.py وأضف الكود التالي إليه:
# tools.py
# (الكود السابق الخاص بـ send_email موجود هنا)
# ...
import csv # استيراد مكتبة CSV
import json # استيراد مكتبة JSON
def read_recipients_from_file(file_path):
"""
تقرأ قائمة المستلمين من ملف CSV أو JSON.
:param file_path: مسار الملف (e.g., 'data/recipients.csv').
:return: قائمة من القواميس، حيث يمثل كل قاموس مستلمًا.
تعيد قائمة فارغة في حالة حدوث خطأ.
"""
recipients = []
try:
# التحقق من امتداد الملف لتحديد كيفية القراءة
if file_path.endswith('.csv'):
with open(file_path, mode='r', encoding='utf-8') as file:
reader = csv.DictReader(file)
for row in reader:
recipients.append(dict(row))
elif file_path.endswith('.json'):
with open(file_path, mode='r', encoding='utf-8') as file:
recipients = json.load(file)
else:
print(f"خطأ: تنسيق الملف غير مدعوم: {file_path}. يرجى استخدام .csv أو .json.")
return []
except FileNotFoundError:
print(f"خطأ: لم يتم العثور على الملف في المسار: {file_path}")
return []
except Exception as e:
print(f"حدث خطأ غير متوقع أثناء قراءة الملف: {e}")
return []
print(f"تم بنجاح قراءة {len(recipients)} مستلم من ملف {file_path}")
return recipients
# --- قسم الاختبار ---
# يمكنك استخدام هذا الجزء لاختبار الدالة الجديدة
if __name__ == "__main__":
# --- اختبار دالة إرسال البريد (من الدرس السابق) ---
# print("بدء اختبار إرسال البريد...")
# send_email("test@example.com", "Subject", "Body")
# --- اختبار دالة قراءة المستلمين (الجديدة) ---
print("\n--- بدء اختبار قراءة الملفات ---")
# أنشئ هذه الملفات للاختبار
recipients_csv = read_recipients_from_file('recipients.csv')
if recipients_csv:
print("البيانات من ملف CSV:")
print(recipients_csv)
print("-" * 20)
recipients_json = read_recipients_from_file('recipients.json')
if recipients_json:
print("البيانات من ملف JSON:")
print(recipients_json)
print("-" * 20)
# اختبار ملف غير موجود
read_recipients_from_file('non_existent_file.txt')
للتحضير للاختبار:
- في نفس المجلد الذي يوجد به ملف
tools.py، أنشئ ملفًا جديدًا باسمrecipients.csvوالصق المحتوى التالي فيه:name,email,city أحمد,ahmad@example.com,الرياض فاطمة,fatima@example.com,جدة - أنشئ ملفًا آخر باسم
recipients.jsonوالصق المحتوى التالي فيه:[ { "name": "يوسف", "email": "youssef@example.com", "city": "دبي" }, { "name": "نورة", "email": "noura@example.com", "city": "الدمام" } ] - الآن، قم بتشغيل ملف
tools.pyمن الطرفية:python tools.py
يجب أن ترى مخرجات تؤكد قراءة البيانات بنجاح من كلا الملفين، بالإضافة إلى رسالة خطأ عند محاولة قراءة ملف غير موجود، مما يثبت أن معالجة الأخطاء لدينا تعمل بشكل صحيح!
اختبر فهمك!
لنفترض أنك استلمت ملف contacts.txt يحتوي على بيانات مفصولة بمسافة tab (\t) بدلاً من الفاصلة. كيف يمكنك تعديل دالة read_recipients_from_file للتعامل مع هذا النوع من الملفات؟
Show answer
الحل يكمن في تعديل الجزء الخاص بقراءة ملفات CSV. عند إنشاء كائن DictReader، يمكنك تحديد الفاصل (delimiter) المستخدم في الملف.
يمكنك إضافة شرط جديد مثل elif file_path.endswith('.txt'): ثم داخله، تستخدم الكود التالي:
with open(file_path, mode='r', encoding='utf-8') as file:
# نحدد أن الفاصل هو tab
reader = csv.DictReader(file, delimiter='\t')
for row in reader:
recipients.append(dict(row))
هذا يوضح قوة مكتبة csv التي لا تقتصر على الفواصل فقط، بل يمكنها التعامل مع أي فاصل تحدده.
خلاصة الدرس
لقد قطعنا شوطًا مهمًا آخر في بناء مشروعنا. في هذا الدرس:
- تعلمنا أساسيات تنسيقي البيانات CSV و JSON.
- استكشفنا مكتبات بايثون المدمجة (
csvوjson) لقراءة هذه الملفات بكفاءة. - أعطينا الأولوية لقراءة البيانات في هيكل منظم (قائمة من القواميس) باستخدام
csv.DictReader. - قمنا ببناء أداة مرنة (
read_recipients_from_file) يمكنها التعامل مع كلا التنسيقين، معالجة الأخطاء، وإرجاع البيانات بشكل متسق.
الآن، يمتلك وكيلنا "ذراعًا" للتصرف (send_email) و"عينًا" للإدراك (read_recipients_from_file). لقد أصبح جاهزًا لتلقي التعليمات ومعالجة البيانات.
ماذا بعد؟
بعد أن جهزنا الأدوات، حان الوقت لتشغيل "العقل". في الدرس القادم، سنبدأ بالجزء الأكثر إثارة: "تطوير منطق الوكيل لاستخدام LLM في تخصيص محتوى البريد لكل مستلم". سنقوم بربط الأدوات التي بنيناها مع نموذج لغوي كبير (LLM)، وسنرى كيف يمكن للوكيل أن يقرأ قائمة المستلمين، ويفكر، ثم يكتب رسالة مخصصة لكل شخص قبل استخدام أداة إرسال البريد. استعد لترى وكيلك يبدأ في "التفكير" لأول مرة