طَبِّقْهاتعلّم المبدأ، وطبّقه بيدكمقرر 111 · أساسيات برمجة الحاسب
الدرس 28 · الوحدة 6: الأخطاء والمشروع الختامي

المشروع الختامي

نبني نظام درجات كاملًا يجمع كل ما تعلّمناه في المقرر. ⏱ نحو 40 دقيقة.

تقرير الدرجاتهندفهدسعدليلى
بعد هذا الدرس ستستطيع أن:
  • تخطط لبرنامج كامل وتقسّمه إلى مراحل.
  • تجمع الكلاسات والدوال والقوائم والاستثناءات في برنامج واحد.
  • تختبر كل مرحلة قبل الانتقال إلى التالية.
  • تطوّر البرنامج بإضافة ميزة جديدة.

١فكرة المشروع

نبني برنامجًا حقيقيًّا يستخدمه المعلم: يُدخل أسماء الطلاب ودرجاتهم، فيطبع البرنامج تقريرًا: حالة كل طالب، والمتوسط، وصاحب أعلى درجة، وعدد الناجحين.

المرحلةما نبنيهمن أي وحدة؟
1كلاس الطالبالبرمجة الشيئية
2قراءة درجة صحيحة دائمًاالحلقات والاستثناءات
3دوال الحساب: المتوسط والأعلى والعدّالدوال والقوائم
4البرنامج الرئيس والتقريركل ما سبق

لا نكتب البرنامج دفعة واحدة. نبني مرحلة، ونجرّبها، ثم ننتقل إلى التي بعدها. هكذا يعمل المبرمجون.

٢المرحلة 1: كلاس الطالب

لكل طالب اسم ودرجة، ودالة تخبرنا هل نجح، ودالة تعرض سطره في التقرير. نجرّب الكلاس بطالبين قبل أن نكمل:

main.py
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()
Shell×
>>> %Run main.py
هند - 92 - ناجح
سعد - 45 - راسب
>>>

٣المرحلة 2: قراءة درجة صحيحة

المعلم قد يخطئ في الكتابة. الدالة read_mark لا تُرجع إلا درجة صحيحة بين 0 و 100، وتكرر الطلب حتى يكتبها:

main.py
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)
Shell×
>>> %Run main.py
الدرجة: ثمانون
اكتب الدرجة بالأرقام
الدرجة: 120
الدرجة من 0 إلى 100
الدرجة: 80
تم: 80
>>>

لاحظ أن return داخل الحلقة توقف الدالة والحلقة معًا، فلا نحتاج break.

٤المرحلة 3: دوال الحساب

ثلاث دوال، كل واحدة تؤدي مهمة واحدة، وتستقبل قائمة الطلاب. هذه الأنماط نفسها التي تعلّمتها: المجموع، والأكبر، والعدّ:

main.py
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))
Shell×
>>> %Run main.py
71.66666666666667
هند
2
>>>

٥المرحلة 4: البرنامج كاملًا

نجمع المراحل، ونضيف البرنامج الرئيس الذي يقرأ البيانات ويطبع التقرير. جرّبه بنفسك، وأدخل قيمًا خطأ عمدًا لترى كيف يتعامل معها:

main.py
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))
Shell×
>>> %Run main.py
عدد الطلاب: 3
الاسم: هند
الدرجة: 92
الاسم: سعد
الدرجة: خمسون
اكتب الدرجة بالأرقام
الدرجة: 150
الدرجة من 0 إلى 100
الدرجة: 45
الاسم: ليلى
الدرجة: 78
----- التقرير -----
هند - 92 - ناجح
سعد - 45 - راسب
ليلى - 78 - ناجح
المتوسط: 71.7
الأعلى: هند
الناجحون: 2 من 3
>>>

في المثال كتب المعلم «خمسون» ثم 150 لسعد، فرفضهما البرنامج حتى كتب 45. لم ينهَر البرنامج، والتقرير صحيح.

٦ماذا استخدمنا من المقرر؟

المفهومأين في المشروع
المتغيّرات و input و printقراءة الأسماء وطباعة التقرير
if و elseحالة الطالب والتحقق من الدرجة
while و forتكرار الطلب، والمرور على الطلاب
الدوال و returnread_mark و average و top و count_passed
القوائمقائمة students
الكلاس والكائنStudent
try و exceptرفض الدرجة المكتوبة بالحروف
📎 للاستزادة (اختياري): أفكار لتطوير المشروع

توقّع وتحقّق

لماذا نبني المشروع على مراحل؟

كل مرحلة مجرّبة قبل التي بعدها.

ماذا تُرجع read_mark إذا كتب المعلم 150؟

لا تقبل إلا 0 إلى 100.

أي دالة تستخدم نمط «الأكبر حتى الآن»؟

top تقارن كل طالب بالأفضل حتى الآن.

الدالة top تُرجع:

لذلك كتبنا top(students).name

الخلاصة

تحدٍّ برمجي: طوّر النظام: التقدير

متقدم

أضف إلى كلاس Student دالة grade تُرجع التقدير: ممتاز (90 فأكثر)، جيد جدًّا (75 فأكثر)، ناجح (60 فأكثر)، راسب. ثم اطبع لكل طالب في القائمة اسمه وتقديره.

المطلوب:
  • أضف def grade(self): داخل الكلاس.
  • استخدم if و elif و else مع return.
  • مرّ على القائمة واطبع: الاسم ثم grade().

ابدأ من هذا الكود، واضغط ▶ شغّل هنا لتكتب حلّك وتجرّبه مباشرة:

main.py
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())

حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.

main.py
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())
انتقل إلى تقييم الدرساختيار من متعدد، وصح وخطأ، وأكمل الفراغ، وتتبّع الناتج.ابدأ التقييم ←