مقدمة في علوم الحاسوب والبرمجة باستخدام Python › المحاضرة 4: التكرارات على النصوص، والتخمين والتحقّق، والأعداد الثنائية 6 / 30 السابق التالي

المحاضرة 4: شرائح التكرار على السلاسل والتخمين والبحث وشروح الثنائية كاملة

المحاضرة 4: التكرار على السلاسل النصية والتخمين والاختبار والبحث الثنائي (Loops Over Strings, Guess-and-Check, Binary)

المصادر والنسبة والترخيص

المادة الأصلية: آنا بيل (Ana Bell)، MIT OpenCourseWare (MIT OCW)، معهد ماساتشوستس للتكنولوجيا، مقرر 6.100L: مقدمة في علوم الحاسوب والبرمجة باستخدام Python، خريف 2022 (Fall 2022).

هذه ترجمة وتكييف عربي غير رسمي وفق رخصة CC BY-NC-SA 4.0: النسبة–غير التجاري–المشاركة بالمثل، ولا تعني اعتمادًا أو تأييدًا من MIT أو MIT OCW. شروط الاستخدام والاستشهاد.

منهج الترجمة: لكل صفحة في ملف الشرائح عنوان مستقل ورقم مطابق. نُقلت الأشكال المتكرّرة إلى جداول تحافظ على تسلسلها. الشيفرة محفوظة بالإنجليزية. لم تُضمَّن صور أو صفحات PDF. الصورة في الشريحة 8 مستثناة صراحةً من رخصة المصدر (مصدرها غير معروف) فحُذفت مع الإشارة إلى موضعها.

الشريحة 1: التكرار على السلاسل النصية، والتخمين والاختبار، والثنائية

(LOOPS OVER STRINGS, GUESS-and-CHECK, BINARY)

(نزّل الشرائح وملفات .py لمتابعة الشرح).

6.100L، المحاضرة 4 — آنا بيل (Ana Bell).

الشريحة 2: في المرة الماضية

  • آليات التكرار (Looping Mechanisms):
    • حلقات while وحلقات for.
  • حلقات while:
    • تكرّر ما دام الشرط صحيحًا.
    • يجب التأكد من عدم الدخول في حلقة لانهائية (Infinite Loop).
  • حلقات for:
    • يأخذ متغيّر الحلقة (Loop Variable) القيم في تسلسل واحدًا تلو الآخر.
    • يمكنها المرور على نطاقات من الأعداد (Ranges of Numbers).
    • ولسوف نرى قريبًا أشياء أخرى كثيرة يسهل المرور عليها بالتكرار.

الشريحة 3: الأمر break

  • يخرج فورًا من أي حلقة هو فيها.
  • يتخطّى بقية التعابير في كتلة الشيفرة.
  • يخرج من الحلقة الداخلية فقط (Innermost Loop)!
while <condition_1>:
    while <condition_2>:
        <expression_a>
        break
        <expression_b>
    <expression_c>

الشريحة 4: الأمر break

mysum = 0
for i in range(5, 11, 2):
    mysum += i
    if mysum == 5:
        break
    mysum += 1
print(mysum)
  • ماذا يحدث في هذا البرنامج؟
  • رابط Python Tutor.

الشريحة 5: جرّب بنفسك!

  • اكتب شيفرة تمرّر حلقة for على نطاق ما وتطبع كم عددًا زوجيًّا يوجد في ذلك النطاق. جرّب مع:
    • range(5)
    • range(10)
    • range(2,9,3)
    • range(-4,6,2)
    • range(5,6)

الشريحة 6: السلاسل النصية والتكرار

  • شيفرة للتحقق من وجود الحرف i أو u في سلسلة نصية.
  • الطرق الثلاث تفعل الشيء نفسه:
s = "demo loops - fruit loops"
for index in range(len(s)):
    if s[index] == 'i' or s[index] == 'u':
        print("There is an i or u")
for char in s:
    if char == 'i' or char == 'u':
        print("There is an i or u")
for char in s:
    if char in 'iu':
        print("There is an i or u")

الشريحة 7: الفكرة الكبرى

تسلسل القيم في حلقة for ليس محدودًا بالأعداد.

الشريحة 8: cheerleaders الروبوتات

(ROBOT CHEERLEADERS)

ملاحظة المترجم: محتوى هذه الشريحة صورة مصدرها غير معروف وجميع الحقوق محفوظة، وهي مستثناة من رخصة CC الخاصة بالمصدر؛ لذلك حُذفت الصورة ولم تُستعَض عنها.

الشريحة 9: جرّب بنفسك!

  • افترض أنك أُعطيت سلسلة نصية من حروف صغيرة في المتغيّر s. عدّ كم حرفًا فريدًا (Unique) يوجد في السلسلة. مثال: إذا كانت s = "abca" فتطبع شيفرتك 3.
  • تلميح:
    • مرّ على كل محرف في s.
    • تتبَّع المحارف التي رأيتها في متغيّر سلسلة نصية.
    • أضف محارف من s إلى متغيّر seen إذا لم تكن موجودة بالفعل في ذلك المتغيّر.

الشريحة 10: ملخص ما مرّ حتى الآن

  • الكائنات لها أنواع.
  • التعابير تُقيَّم إلى قيمة واحدة، وتُربط باسم متغيّر.
  • التفريع (Branching): if وelse وelif.
    • ينفّذ البرنامج مجموعة شيفرة أو مجموعة أخرى.
  • آليات التكرار (Looping Mechanisms): حلقات while وحلقات for.
    • تُنفَّذ الشيفرة تكرارًا ما دام شرط ما صحيحًا.
    • تُنفَّذ الشيفرة تكرارًا لكل القيم في تسلسل.

الشريحة 11: هذا كل ما تحتاجه لتنفيذ الخوارزميات

(THAT IS ALL YOU NEED TO IMPLEMENT ALGORITHMS)

الشريحة 12: التخمين والاختبار (GUESS-and-CHECK)

(GUESS-and-CHECK)

الشريحة 13: التخمين والاختبار

  • تُسمَّى العملية بالتعداد الشامل (Exhaustive Enumeration).
  • ينطبق على مسألة يكون فيها:
    • بإمكانك تخمين قيمة للحل.
    • بإمكانك التحقق مما إذا كان الحل صحيحًا.
    • ويمكنك المواصلة في التخمين حتى:
      • تجد الحل، أو
      • تكون قد جرّبت كل القيم.

مخطّط الانسياب (Flowchart):

        Initial guess
             ↓
    Is your guess correct?
        yes → done
        no  ↓
Choose the next guess  (Be systematic)
             ↓
      (back to guess)

الشريحة 14: التخمين والاختبار — الجذر التربيعي (Square Root)

  • الفكرة الأساسية:
    • معطى عدد صحيح، لنسمّه xx، نريد أن نعرف إن كان هناك عدد صحيح آخر هو جذره التربيعي.
    • ابدأ بتخمين وتحقق إن كان الجواب الصحيح.
  • القيم المفحوصة في المخطط: 0، 1، 2، 3، 4، 5، 6، 7، 8، 9، 10.

الشريحة 15: التخمين والاختبار — الجذر التربيعي

  • الفكرة الأساسية نفسها:
    • ابدأ بتخمين وتحقق إن كان الجواب الصحيح.
    • لكي تكون منهجيًّا (Be systematic)، ابدأ بـ guess = 0، ثم 1، ثم 2، وهكذا.

الشريحة 16: التخمين والاختبار — الجذر التربيعي

  • الفكرة الأساسية نفسها.

  • إذا كان xx مربعًا كاملًا (Perfect Square)، فسنجد جذره في النهاية ويمكننا التوقف (انظر مربع التخمين).

  • مثال في المخطط: x=16x = 16، والتخمينات من 0 إلى 10.

الشريحة 17: التخمين والاختبار — الجذر التربيعي

  • الفكرة الأساسية نفسها.

  • ولكن ماذا لو لم يكن xx مربعًا كاملًا؟

    • نحتاج إلى معرفة متى نتوقف.
    • استخدم الجبر (Algebra): إذا كان مربع التخمين أكبر من xx، فيمكننا التوقف.
  • مثال في المخطط: x=517x = 517، والتخمينات من 0 إلى 10.

الشريحة 18: التخمين والاختبار — الجذر التربيعي بحلقة while

guess = 0
x = int(input("Enter an integer: "))
while guess**2 < x:
    guess = guess + 1
if guess**2 == x:
    print("Square root of", x, "is", guess)
else:
    print(x, "is not a perfect square")

الشريحة 19: التخمين والاختبار — الجذر التربيعي

  • هل يعمل هذا مع أي قيمة عددية صحيحة لـ xx؟

  • ماذا لو كان xx سالبًا؟

    • تنتهي حلقة while فورًا.
    • يمكن التحقق من وجود مدخل سالب ومعالجته بطريقة مختلفة.
  • مثال في المخطط: x=−2x = -2، والتخمينات من -1 إلى 8.

الشريحة 20: التخمين والاختبار — الجذر التربيعي بحلقة while

guess = 0
neg_flag = False
x = int(input("Enter a positive integer: "))
if x < 0:
    neg_flag = True
while guess**2 < x:
    guess = guess + 1
if guess**2 == x:
    print("Square root of", x, "is", guess)
else:
    print(x, "is not a perfect square")
if neg_flag:
    print("Just checking... did you mean", -x, "?")

الشريحة 21: الفكرة الكبرى

التخمين والاختبار لا يستطيع اختبار عدد لا نهائي من القيم. عليك التوقف عند نقطة ما!

الشريحة 22: مقارنة التخمين والاختبار

الخطوة while loop for loop
التخمين الأوّلي Initial guess — لا شيء هنا
هل تخمينك صحيح؟ Is your guess correct? Check if the guess is correct
اختر التخمين التالي (كن منهجيًّا) Choose next guess (Be systematic) Sequentially go through all possible guesses
— لا نعم
— كسر الحلقة، انتهيت (Break the loop, you’re done) مررت على كل القيم في التسلسل (Went through all vals in sequence)
— — لا يوجد حل (Did not find a solution)
— — ما زالت هناك قيم (Still more vals in sequence)

الشريحة 23: جرّب بنفسك!

  • ضع عددًا كعدد سريّ (Secret Number).
  • اكتب برنامجًا يمرّ على كل الأعداد من 1 إلى 10 ويطبع القيمة السريّة إذا كانت في هذا النطاق. إن لم يُعثر عليها فلا يطبع شيئًا.
  • كيف يبدو البرنامج إن غيّرت الشرط إلى: إن لم يُعثر عليها، اطبع أنه لم يعثر عليها.

الشريحة 24: جرّب بنفسك!

  • قارن بين الشيفرتين اللتين:
    • تضعان عددًا كعدد سريّ.
    • تمرّان على كل الأعداد من 1 إلى 10 وتطبعان القيمة السريّة إذا كانت في هذا النطاق.
  • الأولى: إن لم يُعثر عليها لا يطبع شيئًا.
  • الثانية: إن لم يُعثر عليها، يطبع أنه لم يعثر عليها.
  • الجواب:
secret = 7
found = False
for i in range(1,11):
    if i == secret:
        print("yes, it's", i)
    found = True
if not found:
    print("not found")
secret = 7
for i in range(1,11):
    if i == secret:
        print("yes, it's", i)

الشريحة 25: الفكرة الكبرى

يمكن استخدام القيم البوليانية كإشارات (Signals) إلى أن شيئًا قد حدث. ونسمّيها أعلامًا بوليانية (Boolean Flags).

الشريحة 26: while loop أم for loop؟

  • رأينا أن الشيفرة تبدو أنظف عند المرور على تسلسلات من القيم (أي باستخدام حلقة for).
    • لا تضبط العنصر المُكرَّر (Iterant) بنفسك كما في حلقة while.
    • احتمال إدخال أخطاء أقل.
  • خذ مثالًا يستخدم حلقة for مع نطاق صريح من القيم.

الشريحة 27: التخمين والاختبار — الجذر التكعيبي: مكعّبات موجبة

cube = int(input("Enter an integer: "))
for guess in range(cube+1):
    if guess**3 == cube:
        print("Cube root of", cube, "is", guess)

الشريحة 28: التخمين والاختبار — الجذر التكعيبي: مكعّبات موجبة وسالبة

cube = int(input("Enter an integer: "))
for guess in range(abs(cube)+1):
    if guess**3 == abs(cube):
        if cube < 0:
            guess = -guess
        print("Cube root of "+str(cube)+" is "+str(guess))

الشريحة 29: التخمين والاختبار — الجذر التكعيبي: أسرع قليلًا

cube = int(input("Enter an integer: "))
for guess in range(abs(cube)+1):
    if guess**3 >= abs(cube):
        break
if guess**3 != abs(cube):
    print(cube, "is not a perfect cube")
else:
    if cube < 0:
        guess = -guess
    print("Cube root of "+str(cube)+" is "+str(guess))

الشريحة 30: مثال آخر

  • تذكّر مسائل الكلمات (Word Problems) من طفولتك؟
  • مثال:
    • أليزا وبن وسيندي يبيعون تذاكر لجمع تبرّعات.
    • بن يبيع عددًا أقل بـ 2 من أليزا.
    • سيندي تبيع ضعف ما تبيعه أليزا.
    • بيع الثلاثة 10 تذاكر في المجموع.
    • كم باعت أليزا؟
  • يمكن حلّها جبريًّا، لكن يمكننا أيضًا استخدام التخمين والاختبار.

الشريحة 31: التخمين والاختبار مع مسائل الكلمات

for alyssa in range(11):
    for ben in range(11):
        for cindy in range(11):
            total = (alyssa + ben + cindy == 10)
            two_less = (ben == alyssa-2)
            twice = (cindy == 2*alyssa)
            if total and two_less and twice:
                print(f"Alyssa sold {alyssa} tickets")
                print(f"Ben sold {ben} tickets")
                print(f"Cindy sold {cindy} tickets")

الشريحة 32: مثال بأعداد أكبر

  • مع أعداد أكبر، يصبح تداخل الحلقات بطيئًا!
  • مثال:
    • أليزا وبن وسيندي يبيعون تذاكر لجمع تبرّعات.
    • بن يبيع عددًا أقل بـ 20 من أليزا.
    • سيندي تبيع ضعف ما تبيعه أليزا.
    • بيع الثلاثة 1000 تذكرة في المجموع.
    • كم باعت أليزا؟
  • الشيفرة السابقة لن تنتهي في وقت معقول.
  • بدلًا من ذلك، مرّ على متغيّر واحد وكتّب المعادلات مباشرة.

الشريحة 33: حل أكثر كفاءة

for alyssa in range(1001):
    ben = max(alyssa - 20, 0)
    cindy = alyssa * 2
    if ben + cindy + alyssa == 1000:
        print("Alyssa sold " + str(alyssa) + " tickets")
        print("Ben sold " + str(ben) + " tickets")
        print("Cindy sold " + str(cindy) + " tickets")

الشريحة 34: الفكرة الكبرى

يمكنك تطبيق الحوسبة (Computation) على مسائل كثيرة!

الشريحة 35: الأعداد الثنائية (Binary Numbers)

(BINARY NUMBERS)

الشريحة 36: الأعداد في بايثون

  • int: أعداد صحيحة، مثل التي تعلّمتها في المدرسة الابتدائية.
  • float: أعداد حقيقية، مثل التي تعلّمتها في المرحلة الإعدادية.

الشريحة 37: دافعنا — احتفظ بهذا في ذهنك للشرائح القليلة التالية

x = 0
for i in range(10):
    x += 0.1
print(x == 1)
print(x, '==', 10*0.1)

الشريحة 38: الفكرة الكبرى

العمليات على بعض الأعداد العشرية (floats) تُدخل خطأً صغيرًا جدًّا. والخطأ الصغير قد يكون له أثر كبير إذا أُجريت العمليات مرات عديدة!

الشريحة 39: نظرة أقرب على الأعداد العشرية

  • بايثون (وكل لغة برمجة أخرى) تستخدم «الفاصلة العائمة» (Floating Point) لتقريب الأعداد الحقيقية.
  • مصطلح «الفاصلة العائمة» يشير إلى الطريقة التي تُخزَّن بها هذه الأعداد في الحاسوب.
  • التقريب (Approximation) لا يهم عادةً…
  • لكنه يهمّنا نحن!
  • لنرَ لماذا…

الشريحة 40: تمثيل الفاصلة العائمة

  • يعتمد على عتاد الحاسوب، لا على تنفيذ لغة البرمجة.
  • أشياء أساسية يجب فهمها:
    • الأعداد (وكل شيء آخر) تُمثَّل كتسلسل من البتات (Bits) — أي 0 أو 1.
    • حين نكتب الأعداد، تستخدم الرموز أساس 10.
    • و0.1 يمثّل العدد الكسري 1/101/10.
  • هذا يسبّب تنافرًا معرفيًّا (Cognitive Dissonance) — وسيؤثّر في كيفية كتابة شيفرتنا.

الشريحة 41: لماذا الثنائية؟ — التنفيذ العتادي

  • سهلة التنفيذ في العتاد: ابنِ مكوّنات يمكن أن تكون في حالة واحدة من حالتين.
  • عتاد الحاسوب مبنيّ حول طرق تستطيع تخزين المعلومات بكفاءة كـ 0 أو 1 وإجراء عمليات حسابية بهذا التمثيل.
    • الجهد (Voltage) «عالٍ» أو «منخفض».
    • الدوران المغناطيسي (Magnetic Spin) «لأعلى» أو «لأسفل».
  • مناسبة للعمليات الحسابية على الأعداد الصحيحة، لكن ماذا عن الأعداد ذات الأجزاء الكسرية (floats)؟

الشريحة 42: الأعداد الثنائية

  • التمثيل في الأساس 10 لعدد صحيح:
    • مجموع لقوى 10، مضروبة في أعداد صحيحة من 0 إلى 9.
1507=1×103+5×102+0×101+7×100=1000+500+71507 = 1\times10^3 + 5\times10^2 + 0\times10^1 + 7\times10^0 = 1000 + 500 + 7
  • التمثيل الثنائي هو الفكرة نفسها في الأساس 2:
    • مجموع لقوى 2، مضروبة في أعداد صحيحة من 0 إلى 1.
150710=1×210+1×28+1×27+1×26+1×25+1×21+1×201507_{10} = 1\times2^{10} + 1\times2^8 + 1\times2^7 + 1\times2^6 + 1\times2^5 + 1\times2^1 + 1\times2^0 =1024+256+128+64+32+2+1= 1024 + 256 + 128 + 64 + 32 + 2 + 1 =101111000112= 10111100011_2

الشريحة 43: تحويل عدد صحيح عشري إلى ثنائي

  • ندخل الأعداد بالنظام العشري، والحاسوب يحتاج إلى تحويلها إلى النظام الثنائي.
  • خذ مثال x=1910=1×24+0×23+0×22+1×21+1×20=100112x = 19_{10} = 1\times2^4 + 0\times2^3 + 0\times2^2 + 1\times2^1 + 1\times2^0 = 10011_2.
  • إذا أخذنا باقي قسمة xx على 2، أي x%2، حصلت على آخر بت ثنائي.
  • وإذا قسمنا xx قسمة صحيحة على 2، أي x//2، تحوّلت كل البتات إلى اليمين (Shifted Right) واحدًا.
    • x//2 = 1001_2.
  • واصل القسومات المتتالية؛ الآن يعطي الباقي البت التالي، وهكذا.
  • لنحوّل إلى الصورة الثنائية.

الشريحة 44: تنفيذ ذلك في بايثون للأعداد الموجبة

result = ''
if num == 0:
    result = '0'
while num > 0:
    result = str(num%2) + result
    num = num//2
  • رابط Python Tutor.

الشريحة 45: تنفيذ ذلك في بايثون مع معالجة الأعداد السالبة

if num < 0:
    is_neg = True
    num = abs(num)
else:
    is_neg = False

result = ''
if num == 0:
    result = '0'

while num > 0:
    result = str(num%2) + result
    num = num//2

if is_neg:
    result = '-' + result

الشريحة 46: ملخص

  • الحلقات يمكنها المرور على أي تسلسل من القيم:
    • range للأعداد.
    • سلسلة نصية (String).
  • التخمين والاختبار يوفّر خوارزمية بسيطة لحل المسائل:
    • عندما تكون مجموعة الحلول المحتملة قابلة للتعداد، فإن التعداد الشامل مضمون أن ينجح (في النهاية).
  • الأعداد الثنائية تساعدنا على فهم كيف تعمل الآلة:
    • التحويل إلى الثنائي سيساعدنا على فهم كيف تُخزَّن الأعداد العشرية.
    • وهذا مهم للخوارزمية التالية التي سنراها.

الشريحة 47: بيانات MIT OpenCourseWare

MIT OpenCourseWare — https://ocw.mit.edu

6.100L: مقدمة في علوم الحاسوب والبرمجة باستخدام Python.

خريف 2022.

للحصول على معلومات عن الاستشهاد بهذه المواد أو شروط استخدامها، تفضّل بزيارة https://ocw.mit.edu/terms.