بناء سجل درجات
Build a Gradebook
بناء سجل درجات — Build a Gradebook
في هذا الدرس ستبني سجل درجات صغيراً خطوة بخطوة. الهدف ليس حفظ الكود — الهدف هو أن ترى كيف تفكر في شكل البيانات قبل كتابة سطر واحد، وكيف تختار الهيكل المناسب لكل عملية.
سجل الدرجات يمثل بيانات حقيقية: لكل طالب اسم ودرجة، وتريد العمليات التالية: إضافة طالب، حساب المتوسط، إيجاد الأعلى، تصفية الناجحين، وطباعة تقرير. اختيار شكل البيانات يؤثر على شكل كل عملية بعده.
تصميم البيانات قبل الكود
قبل أن تكتب def أو dict، اسأل نفسك: ما هي المعلومات التي أحتاجها لكل طالب؟ اسم ودرجة. كيف سأبحث؟ غالباً بالاسم. كيف سأمر على الجميع؟ بالترتيب أو بلا ترتيب.
الجواب: قاموس {اسم: درجة} مناسب جداً هنا — البحث بالاسم فوري، والمرور على الجميع سهل بـ .items(). لو احتجنا معلومات أكثر لكل طالب، كنا ننتقل لقاموس من قواميس أو قاموس من dataclasses، لكن لهذا الدرس {اسم: درجة} يكفي.
الخطوة 1 — إنشاء السجل وإضافة الطلاب
لاحظ أن add_student تستخدم book[name] = score مباشرةً. في Python، هذا التعيين يضيف المفتاح إن لم يكن موجوداً أو يحدّث قيمته إن كان موجوداً — سلوك واحد يغطي الحالتين. لا نحتاج if name in book أولاً.
الخطوة 2 — حساب المتوسط
التحقق من if not book ضروري لأن قسمة على صفر تعطي ZeroDivisionError في Python. هذه الحالة الحدية ليست نادرة — كود المشاريع الحقيقية يمر باختبار بسجلات فارغة دائماً. هنا نرجع 0.0 لأن الدرس بسيط، لكن في تطبيق حقيقي قد تختار رفع استثناء أو إرجاع None.
الخطوة 3 — إيجاد الأعلى درجة
max(book, key=lambda k: book[k]) يمر على مفاتيح القاموس ويرجع المفتاح الذي تكون قيمته الأكبر. الـ key= في max() قوية جداً — تسمح لك بتحديد “ماذا تعني الأكبرية” بدلاً من مقارنة المفاتيح مباشرةً.
الخطوة 4 — تصفية الناجحين
الخطوة 5 — إنتاج تقرير منسّق
نظرة على الصورة الكاملة
الآن اجمع كل الدوال في برنامج واحد:
لماذا هذا التصميم يعمل؟
كل دالة لها مسؤولية واحدة: add_student لا تعرف شيئاً عن التقارير، وprint_report لا تعرف شيئاً عن كيفية حساب المتوسط. هذا يجعل كل دالة سهلة التغيير بشكل مستقل — إذا أردت تغيير حد النجاح من 75 إلى 60، تغيّر قيمة واحدة في passing_students.
لاحظ أيضاً كيف أن sorted(book.items(), key=lambda x: x[1], reverse=True) تُرجع قائمة من الأزواج (name, score) مرتبة. هذا نمط شائع جداً في Python — القاموس لا يُرتّب، لكن sorted() تعطيك نسخة مرتبة بأي معيار تختاره.
خلاصة
سجل الدرجات هذا استخدم dict للوصول السريع بالاسم، sorted() للترتيب، max() مع key= لإيجاد الأعلى، وDict Comprehension للتصفية. هذه أنماط ستراها في كل مشروع Python حقيقي — قواعد بيانات مؤقتة، نتائج API، معالجة ملفات. في المختبر التالي ستطبق نفس المبادئ لكن مع بيانات أكثر تعقيداً وأقل توجيه.