المشروع الختامي
نبني نظام درجات كاملًا يجمع كل ما تعلّمناه في المقرر. ⏱ نحو 40 دقيقة.
- تخطط لبرنامج كامل وتقسّمه إلى مراحل.
- تجمع الكلاسات والدوال والقوائم والاستثناءات في برنامج واحد.
- تختبر كل مرحلة قبل الانتقال إلى التالية.
- تطوّر البرنامج بإضافة ميزة جديدة.
١فكرة المشروع
نبني برنامجًا حقيقيًّا يستخدمه المعلم: يُدخل أسماء الطلاب ودرجاتهم، فيطبع البرنامج تقريرًا: حالة كل طالب، والمتوسط، وصاحب أعلى درجة، وعدد الناجحين.
| المرحلة | ما نبنيه | من أي وحدة؟ |
|---|---|---|
| 1 | كلاس الطالب | البرمجة الشيئية |
| 2 | قراءة درجة صحيحة دائمًا | الحلقات والاستثناءات |
| 3 | دوال الحساب: المتوسط والأعلى والعدّ | الدوال والقوائم |
| 4 | البرنامج الرئيس والتقرير | كل ما سبق |
لا نكتب البرنامج دفعة واحدة. نبني مرحلة، ونجرّبها، ثم ننتقل إلى التي بعدها. هكذا يعمل المبرمجون.
٢المرحلة 1: كلاس الطالب
لكل طالب اسم ودرجة، ودالة تخبرنا هل نجح، ودالة تعرض سطره في التقرير. نجرّب الكلاس بطالبين قبل أن نكمل:
class Student: def __init__(self, name, mark): self.name = name self.mark = mark def passed(self): return self.mark >= 60 def show(self): if self.passed(): state = "ناجح" else: state = "راسب" print(self.name, "-", self.mark, "-", state) a = Student("هند", 92)b = Student("سعد", 45)a.show()b.show()
٣المرحلة 2: قراءة درجة صحيحة
المعلم قد يخطئ في الكتابة. الدالة read_mark لا تُرجع إلا درجة صحيحة بين 0 و 100، وتكرر الطلب حتى يكتبها:
def read_mark(): while True: try: m = int(input("الدرجة: ")) if 0 <= m <= 100: return m print("الدرجة من 0 إلى 100") except ValueError: print("اكتب الدرجة بالأرقام") m = read_mark()print("تم:", m)
لاحظ أن return داخل الحلقة توقف الدالة والحلقة معًا، فلا نحتاج break.
٤المرحلة 3: دوال الحساب
ثلاث دوال، كل واحدة تؤدي مهمة واحدة، وتستقبل قائمة الطلاب. هذه الأنماط نفسها التي تعلّمتها: المجموع، والأكبر، والعدّ:
class Student: def __init__(self, name, mark): self.name = name self.mark = mark def passed(self): return self.mark >= 60 def show(self): if self.passed(): state = "ناجح" else: state = "راسب" print(self.name, "-", self.mark, "-", state) def average(students): total = 0 for s in students: total += s.mark return total / len(students) def top(students): best = students[0] for s in students: if s.mark > best.mark: best = s return best def count_passed(students): count = 0 for s in students: if s.passed(): count += 1 return count group = [Student("هند", 92), Student("سعد", 45), Student("ليلى", 78)]print(average(group))print(top(group).name)print(count_passed(group))
٥المرحلة 4: البرنامج كاملًا
نجمع المراحل، ونضيف البرنامج الرئيس الذي يقرأ البيانات ويطبع التقرير. جرّبه بنفسك، وأدخل قيمًا خطأ عمدًا لترى كيف يتعامل معها:
class Student: def __init__(self, name, mark): self.name = name self.mark = mark def passed(self): return self.mark >= 60 def show(self): if self.passed(): state = "ناجح" else: state = "راسب" print(self.name, "-", self.mark, "-", state) def read_mark(): while True: try: m = int(input("الدرجة: ")) if 0 <= m <= 100: return m print("الدرجة من 0 إلى 100") except ValueError: print("اكتب الدرجة بالأرقام") def average(students): total = 0 for s in students: total += s.mark return total / len(students) def top(students): best = students[0] for s in students: if s.mark > best.mark: best = s return best def count_passed(students): count = 0 for s in students: if s.passed(): count += 1 return count students = []n = int(input("عدد الطلاب: "))for i in range(n): name = input("الاسم: ") mark = read_mark() students.append(Student(name, mark)) print("----- التقرير -----")for s in students: s.show()print("المتوسط:", round(average(students), 1))print("الأعلى:", top(students).name)print("الناجحون:", count_passed(students), "من", len(students))
في المثال كتب المعلم «خمسون» ثم 150 لسعد، فرفضهما البرنامج حتى كتب 45. لم ينهَر البرنامج، والتقرير صحيح.
٦ماذا استخدمنا من المقرر؟
| المفهوم | أين في المشروع |
|---|---|
| المتغيّرات و input و print | قراءة الأسماء وطباعة التقرير |
| if و else | حالة الطالب والتحقق من الدرجة |
| while و for | تكرار الطلب، والمرور على الطلاب |
| الدوال و return | read_mark و average و top و count_passed |
| القوائم | قائمة students |
| الكلاس والكائن | Student |
| try و except | رفض الدرجة المكتوبة بالحروف |
📎 للاستزادة (اختياري): أفكار لتطوير المشروع
- أضف التقدير لكل طالب: ممتاز، جيد جدًّا، جيد، مقبول.
- رتّب التقرير من الأعلى درجة إلى الأقل.
- ابحث عن طالب باسمه واطبع درجته.
- احفظ التقرير في ملف نصي
(ستتعلّمه في مقرر لاحق).
توقّع وتحقّق
لماذا نبني المشروع على مراحل؟
ماذا تُرجع read_mark إذا كتب المعلم 150؟
أي دالة تستخدم نمط «الأكبر حتى الآن»؟
top تقارن كل طالب بالأفضل حتى الآن.الدالة top تُرجع:
top(students).nameالخلاصة
- قسّم البرنامج الكبير إلى مراحل صغيرة، وجرّب كل مرحلة.
- الكلاس يصف البيانات، والدوال تحسب، والبرنامج الرئيس يربط بينها.
read_markتحمي البرنامج من الإدخال الخطأ بـtryوexcept.- هذا المشروع يجمع كل ما تعلّمته في المقرر.
تحدٍّ برمجي: طوّر النظام: التقدير
متقدمأضف إلى كلاس Student دالة grade تُرجع التقدير: ممتاز (90 فأكثر)، جيد جدًّا (75 فأكثر)، ناجح (60 فأكثر)، راسب. ثم اطبع لكل طالب في القائمة اسمه وتقديره.
- أضف
def grade(self): داخل الكلاس. - استخدم if و elif و else مع return.
- مرّ على القائمة واطبع: الاسم ثم
grade().
ابدأ من هذا الكود، واضغط ▶ شغّل هنا لتكتب حلّك وتجرّبه مباشرة:
class Student: def __init__(self, name, mark): self.name = name self.mark = mark group = [Student("هند", 92), Student("فهد", 81), Student("ليلى", 64), Student("سعد", 45)]
💡 تلميح 1
self.mark >= 90💡 تلميح 2
for s in group: print(s.name, s.grade())حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.
class Student: def __init__(self, name, mark): self.name = name self.mark = mark def grade(self): if self.mark >= 90: return "ممتاز" elif self.mark >= 75: return "جيد جدًّا" elif self.mark >= 60: return "ناجح" return "راسب" group = [Student("هند", 92), Student("فهد", 81), Student("ليلى", 64), Student("سعد", 45)]for s in group: print(s.name, s.grade())