المسارات
/
Python
Python
/
التمارين
/
تحقيق النجاح
تحقيق النجاح

تحقيق النجاح

تمرين تعلّمي

مقدمة

توفّر Python بنيتين للتكرار. حلقات while للتكرار غير المحدد (غير المعدود)، وحلقات for للتكرار المحدد (المعدود). تساعد الكلمات المفتاحية break و continue و else على تخصيص سلوك الحلقة. وتساعد range() و enumerate() في عدّ الحلقات والفهرسة.

حلقة while

تستمر حلقات while في التنفيذ ما دام loop expression أو «الاختبار» يُقيَّم إلى True في boolean context، وتتوقف عندما يُقيَّم إلى False:


# Lists are considered "truthy" in a boolean context if they
# contain one or more values, and "falsy" if they are empty.

>>> placeholders = ["spam", "ham", "eggs", "green_spam", "green_ham", "green_eggs"]

>>> while placeholders:
...     print(placeholders.pop(0))
...
'spam'
'ham'
'eggs'
'green_spam'
'green_ham'
'green_eggs'

حلقة for

الحلقة for الأساسية في Python يوصفها وصفًا أدق بأنها for each تمرّ على قيم أي كائن قابل للتكرار، وتتوقف عندما لا تُرجع أي قيم عند استدعاء next():


>>> word_list = ["bird", "chicken", "barrel", "bongo"]

>>> for word in word_list:
...    if word.startswith("b"):
...        print(f"{word.title()} starts with a B.")
...    else:
...        print(f"{word.title()} doesn't start with a B.")
...
'Bird starts with a B.'
'Chicken doesn\'t start with a B.'
'Barrel starts with a B.'
'Bongo starts with a B.'

كائن المتتالية range()

عندما لا يكون هناك iterable محدد، تُستخدم المتتالية الخاصة range() كعدّاد للحلقة. تتطلب range() قيمة من النوع int تحدّد عندها stop توقف المتتالية، ويمكنها اختياريًا أن تأخذ المعاملين start و step. إذا لم تُقدَّم قيمة start، تبدأ المتتالية من 0. كائنات range() كسولة (تُولَّد القيم عند الطلب)، وتدعم جميع عمليات المتتالية الشائعة، وتشغل مقدارًا ثابتًا من الذاكرة، مهما كان طول المتتالية المحددة.

# Here we use range to produce some numbers, rather than creating a list of them in memory.
# The values will start with 1 and stop *before* 7

>>> for number in range(1, 7):
...    if number % 2 == 0:
...       print(f"{number} is even.")
...    else:
...       print(f"{number} is odd.")
'1 is odd.'
'2 is even.'
'3 is odd.'
'4 is even.'
'5 is odd.'
'6 is even.'

# range() can also take a *step* parameter.
# Here we use range to produce only the "odd" numbers, starting with 3 and stopping *before* 15.

>>> for number in range(3, 15, 2):
...    if number % 2 == 0:
...       print(f"{number} is even.")
...    else:
...       print(f"{number} is odd.")
...
'3 is odd.'
'5 is odd.'
'7 is odd.'
'9 is odd.'
'11 is odd.'
'13 is odd.'

القيم والفهارس مع enumerate()

إذا احتجت إلى القيم وفهارسها معًا، فإن الدالة المدمجة enumerate(<iterable>) ستُرجع أزواجًا من (index, value):


>>> word_list = ["bird", "chicken", "barrel", "apple"]

# *index* and *word* are the loop variables.
# Loop variables can be any valid python name.

>>> for index, word in enumerate(word_list):
...    if word.startswith("b"):
...        print(f"{word.title()} (at index {index}) starts with a B.")
...    else:
...        print(f"{word.title()} (at index {index}) doesn't start with a B.")
...
'Bird (at index 0) starts with a B.'
'Chicken (at index 1) doesn\'t start with a B.'
'Barrel (at index 2) starts with a B.'
'Apple (at index 3) doesn\'t start with a B.'


# The same method can be used as a "lookup" for pairing items between two lists.
# Of course, if the lengths or indexes don't line up, this doesn't work.

>>> word_list = ["cat", "chicken", "barrel", "apple", "spinach"]
>>> category_list = ["mammal", "bird", "thing", "fruit", "vegetable"]

>>> for index, word in enumerate(word_list):
...    print(f"{word.title()} is in category: {category_list[index]}.")
...
'Cat is in category: mammal.'
'Chicken is in category: bird.'
'Barrel is in category: thing.'
'Apple is in category: fruit.'
'Spinach is in category: vegetable.'

تغيير سلوك الحلقة

يمكن استخدام الكلمة المفتاحية continue للانتقال مباشرة إلى دورة التكرار التالية:

word_list = ["bird", "chicken", "barrel", "bongo", "sliver", "apple", "bear"]

# This will skip *bird*, at index 0
for index, word in enumerate(word_list):
    if index == 0:
        continue
    if word.startswith("b"):
        print(f"{word.title()} (at index {index}) starts with a b.")

'Barrel (at index 2) starts with a b.'
'Bongo (at index 3) starts with a b.'
'Bear (at index 6) starts with a b.'

يمكن استخدام الكلمة المفتاحية break (كما في كثير من اللغات المشتقة من C) لإيقاف التكرار و«الخروج» من أقرب loop محيطة:

>>>  word_list = ["bird", "chicken", "barrel", "bongo", "sliver", "apple"]

>>> for index, word in enumerate(word_list):
...    if word.startswith("b"):
...        print(f"{word.title()} (at index {index}) starts with a B.")
...    elif word == "sliver":
...       break
...    else:
...       print(f"{word.title()} doesn't start with a B.")
... print("loop broken.")
...
'Bird (at index 0) starts with a B.'
'Chicken doesn\'t start with a B.'
'Barrel (at index 2) starts with a B.'
'Bongo (at index 3) starts with a B.'
'loop broken.'

التعليمات

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

1. تقريب الدرجات

يمكنك منح "درجات جزئية" على أسئلة الامتحان، لكن درجات الامتحان الإجمالية يجب أن تكون من نوع int. لذا قبل أن تفعل أي شيء آخر بدرجات الفصل، عليك المرور على الدرجات وتحويل أي درجة من نوع float إلى int. ولحسن حظك، يوفّر Python الدالة المدمجة round() التي يمكنك استخدامها.

أنشئ الدالة round_scores(student_scores) التي تأخذ list باسم student_scores. ينبغي لهذه الدالة أن تستهلك list المُدخلة وreturn قائمة جديدة تكون فيها كل الدرجات محوّلة إلى int. ترتيب الدرجات في list الناتجة غير مهم.

>>> student_scores = [90.33, 40.5, 55.44, 70.05, 30.55, 25.45, 80.45, 95.3, 38.7, 40.3]
>>> round_scores(student_scores)
...
[40, 39, 95, 80, 25, 31, 70, 55, 40, 90]

2. الطلاب غير الناجحين

بينما كنت تصحّح الامتحان، لاحظت أن بعض الطلاب لم يؤدّوا بالشكل الذي كنت تأمله. لكنك تشتّت انتباهك، ونسيت تدوين عدد الطلاب بالضبط.

أنشئ الدالة count_failed_students(student_scores) التي تأخذ list باسم student_scores. ينبغي لهذه الدالة أن تُحصي عدد الطلاب الذين لم يحصلوا على درجات ناجحة وتُرجع ذلك العدد كعدد صحيح. يحتاج الطالب إلى درجة أكبر من 40 لينجح في الامتحان.

>>> count_failed_students(student_scores=[90,40,55,70,30,25,80,95,38,40])
5

3. "الأفضل"

يريد المعلم الذي تساعده أن يجد مجموعة الطلاب الذين أدّوا "الأفضل" في هذا الامتحان. وما يُعدّ "الأفضل" يتغيّر، لذا عليك إيجاد درجات الطلاب التي تكون أكبر من أو تساوي العتبة الحالية.

أنشئ الدالة above_threshold(student_scores, threshold) التي تأخذ student_scores (وهي list من الدرجات) وthreshold (عتبة "أعلى درجة") كمعاملات. ينبغي لهذه الدالة أن تُرجع list بكل الدرجات التي تكون >= للعتبة threshold.

>>> above_threshold(student_scores=[90,40,55,70,30,68,70,75,83,96], threshold=75)
[90,75,83,96]

4. حساب الدرجات الحرفية

يحب المعلم الذي تساعده أن يمنح درجات حرفية إلى جانب الدرجات الرقمية. ولأن الطلاب نادرًا ما يحصلون على 100 في الامتحان، تُحسب العتبات الدنيا لـ "الدرجة الحرفية" بناءً على أعلى درجة تم تحقيقها، وتتزايد بالتساوي بين أعلى درجة وعتبة الرسوب <= 40.

أنشئ الدالة letter_grades(highest) التي تأخذ أعلى درجة في الامتحان كوسيط، وتُرجع list بالعتبات الدنيا للدرجات لكل فترة من فترات "الطريقة الأمريكية": ["D", "C", "B", "A"].

"""Where the highest score is 100, and failing is <= 40.
       "F" <= 40
 41 <= "D" <= 55
 56 <= "C" <= 70
 71 <= "B" <= 85
 86 <= "A" <= 100
"""

>>> letter_grades(highest=100)
[41, 56, 71, 86]


"""Where the highest score is 88, and failing is <= 40.
       "F" <= 40
 41 <= "D" <= 52
 53 <= "C" <= 64
 65 <= "B" <= 76
 77 <= "A" <= 88
"""

>>> letter_grades(highest=88)
[41, 53, 65, 77]

5. مطابقة الأسماء بالدرجات

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

أنشئ الدالة student_ranking(student_scores, student_names) بمعاملَي student_scores وstudent_names. طابق كل اسم طالب في list الخاصة بـ student_names مع درجته من list الخاصة بـ student_scores. يمكنك افتراض أن كل list من الوسائط ستكون مرتّبة من الأعلى درجة إلى الأدنى درجة. ينبغي للدالة أن تُرجع list من السلاسل النصية بالتنسيق <rank>. <student name>: <student score>.

>>> student_scores = [100, 99, 90, 84, 66, 53, 47]
>>> student_names =  ['Joci', 'Sara','Kora','Jan','John','Bern', 'Fred']
>>> student_ranking(student_scores, student_names)
...
['1. Joci: 100', '2. Sara: 99', '3. Kora: 90', '4. Jan: 84', '5. John: 66', '6. Bern: 53', '7. Fred: 47']

6. درجة "مثالية"

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

أنشئ الدالة perfect_score(student_info) بالمعامل student_info. student_info هو list من المصفوفات تحتوي كل واحدة على اسم الطالب ودرجته: [["Charles", 90], ["Tony", 80]]. ينبغي للدالة أن return أول زوج [<name>, <score>] للطالب الذي حصل على 100 في الامتحان.

إذا لم يُعثر على أي درجة 100 في student_info، فيجب إرجاع مصفوفة فارغة [].

>>> perfect_score(student_info=[["Charles", 90], ["Tony", 80], ["Alex", 100]])
["Alex", 100]

>>> perfect_score(student_info=[["Charles", 90], ["Tony", 80]])
[]
تعديل عبر GitHub يفتح الرابط في نافذة أو علامة تبويب جديدة
Python Exercism

مستعد لبدء تحقيق النجاح؟

سجّل في Exercism لتتعلّم وتتقن Python عبر 17 مفهومًا146 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.