الفروع والحلقات في التطبيق العملي
الفروع والحلقات في التطبيق العملي
لقد تعلمنا الكثير من النظريات — الآن حان الوقت لبناء بعض المشاريع الحقيقية. هذا درس عملي. باستخدام جمل if وحلقات for و while و break و continue وغيرها من المفاهيم التي تعلمناها، سنبني أربعة برامج كاملة خطوة بخطوة.
لكل مشروع، سنحلل المتطلبات، ونكتب الكود، ونناقش التحسينات الممكنة.
المشروع 1: لعبة تخمين الأرقام (محسّنة)
في الدرس 08، كتبنا لعبة تخمين أرقام أساسية. الآن دعنا نُحسّنها بإضافة اختيار الصعوبة، حد المحاولات، وميزة "العب مرة أخرى."
المتطلبات
1. يختار اللاعب مستوى الصعوبة: سهل (1-50، غير محدود)، عادي (1-100، 10 محاولات)، صعب (1-200، 7 محاولات)
2. يولد النظام رقماً مستهدفاً عشوائياً
3. بعد كل تخمين، تلميح "أعلى" أو "أقل" وعرض المحاولات المتبقية
4. بعد التخمين الصحيح أو نفاد المحاولات، اسأل "العب مرة أخرى؟"
5. أدخل q للخروج
الكود الكامل (⭐⭐⭐)
مثال: لعبة تخمين الأرقام
import random
print("=" * 30)
print("Number Guessing Game (Enhanced)")
print("=" * 30)
while True: # الحلقة الخارجية: تتحكم في "العب مرة أخرى"
# اختيار الصعوبة
print("\nSelect difficulty:")
print("1. Easy (1~50, unlimited)")
print("2. Normal (1~100, 10 tries)")
print("3. Hard (1~200, 7 tries)")
choice = input("Enter 1/2/3: ")
if choice == "1":
max_num = 50
max_attempts = float("inf") # غير محدود
elif choice == "2":
max_num = 100
max_attempts = 10
elif choice == "3":
max_num = 200
max_attempts = 7
else:
print("Invalid choice, defaulting to Normal")
max_num = 100
max_attempts = 10
# توليد الرقم المستهدف
target = random.randint(1, max_num)
attempts = 0
print(f"\nNumber generated between 1~{max_num}. Start guessing!")
# الحلقة الداخلية: منطق اللعبة الرئيسي
while True:
if attempts >= max_attempts:
print(f"\nOut of attempts! The answer was {target}")
break
guess_str = input(f"{max_attempts - attempts} tries left, enter your guess: ")
if guess_str.lower() == "q":
print("Quitting game.")
max_attempts = -1 # علامة لإعلام الحلقة الخارجية
break
if not guess_str.isdigit():
print("Please enter a valid number!")
continue
guess = int(guess_str)
attempts += 1
if guess < target:
print("Too low, try higher!")
elif guess > target:
print("Too high, try lower!")
else:
print(f"\nCongratulations! The answer was {target}!")
print(f"You got it in {attempts} tries.")
break
if max_attempts == -1:
break
again = input("\nPlay again? (y/n): ")
if again.lower() != "y":
print("Thanks for playing, goodbye!")
break
تسليط الضوء على التصميم: الحلقة الخارجية تتحكم في "العب مرة أخرى"، الحلقة الداخلية تتحكم في "عملية التخمين." علامة
max_attempts = -1تحل مشكلة الخروج من كلتا الحلقتين عندما يدخل اللاعب q. نهج أكثر أناقة هو تغليف منطق اللعبة في دالة واستخدامreturnللخروج مرة واحدة.
المشروع 2: جدول الضرب (أنماط متعددة)
في الدرس 08، طبعنا جدول ضرب قياسي. المبرمج الجيد يجب أن يكون قادراً على التحكم بمرونة في هياكل الحلقات لإخراج أي نمط.
النمط 1: المثلث السفلي القياسي (⭐⭐)
مثال: المثلث السفلي القياسي
print("=== Standard Lower Triangle ===")
for i in range(1, 10):
for j in range(1, i + 1):
print(f"{j}x{i}={i*j}", end="\t")
print()
النمط 2: المستطيل الكامل (⭐⭐)
مثال: المستطيل الكامل
print("=== Full Rectangle ===")
for i in range(1, 10):
for j in range(1, 10):
print(f"{j}x{i}={i*j}", end="\t")
print()
النمط 3: المثلث العلوي (⭐⭐⭐)
مثال: المثلث العلوي
print("=== Upper Triangle ===")
for i in range(1, 10):
for k in range(1, i):
print(end="\t\t")
for j in range(i, 10):
print(f"{i}x{j}={i*j}", end="\t")
print()
الرؤية الرئيسية: تحدّي المثلث العلوي هو "محاذاة المسافات" — كل صف يحتاج
(i-1) * 2حرف تبويب من المسافة البادئة. يستخدم هذا حلقتين داخليتين: الأولى تطبع المسافات، والثانية تطبع الصيغ.
المشروع 3: آلة حاسبة بسيطة (محسّنة)
في تمارين الدرس 08، كتبنا آلة حاسبة أساسية. الآن دعنا نصنع نسخة محسّنة تدعم العمليات المستمرة مع التاريخ.
المتطلبات
1. ابدأ بالنتيجة الحالية = 0
2. يدخل المستخدم: العامل والرقم، مثل "+ 5"
3. العوامل المدعومة: + - * / ** // % clear exit
4. clear يعيد تعيين النتيجة إلى 0
5. exit ينهي البرنامج
6. بعد كل عملية، أظهر النتيجة الحالية والتاريخ
الكود الكامل (⭐⭐⭐)
print("=" * 40)
print("Enhanced Calculator")
print("Format: operator number, e.g., + 5")
print("Supported: + - * / ** // %")
print("Special commands: clear reset exit quit")
print("=" * 40)
result = 0.0
history = []
while True:
print(f"\nCurrent result: {result}")
cmd = input(">>> ").strip()
if cmd.lower() in ("exit", "quit"):
print("Thanks for using!")
break
if cmd.lower() == "clear":
result = 0.0
history.clear()
print("Reset to 0")
continue
parts = cmd.split()
if len(parts) != 2:
print("Invalid format! Enter: operator number")
continue
op, num_str = parts
if not num_str.replace(".", "").isdigit() or num_str.count(".") > 1:
print("Invalid number!")
continue
num = float(num_str)
old_result = result
if op == "+":
result += num
elif op == "-":
result -= num
elif op == "*":
result *= num
elif op == "/":
if num == 0:
print("Error: Cannot divide by zero!")
continue
result /= num
elif op == "**":
result **= num
elif op == "//":
if num == 0:
print("Error: Cannot divide by zero!")
continue
result //= num
elif op == "%":
if num == 0:
print("Error: Cannot divide by zero!")
continue
result %= num
else:
print(f"Invalid operator: {op}")
continue
history.append(f"{old_result} {op} {num} = {result}")
print(f"= {result}")
if len(history) >= 1:
print("--- Recent History ---")
for item in history[-3:]:
print(f" {item}")
عقلية البرمجة: هذا المثال يظهر التفاعل الكلاسيكي بين الحلقات والشروط —
while Trueيبقي البرنامج قيد التشغيل،if-elif-elseيعالج مختلف الإدخالات،continueيتخطى الإدخال غير الصالح، وbreakيخرج بشكل طبيعي.
المشروع 4: الباحث عن الأعداد الأولية
دع المستخدم يدخل نطاقاً، وأخرج جميع الأعداد الأولية ضمن ذلك النطاق، واحسبها.
المتطلبات
1. يدخل المستخدم قيم البداية والنهاية
2. يُخرج البرنامج جميع الأعداد الأولية في ذلك النطاق
3. اعرض 10 في كل سطر، بمحاذاة أنيقة
4. أظهر العدد الإجمالي للأعداد الأولية
الكود الكامل (⭐⭐⭐)
print("Prime Number Finder")
print("Enter a range, and I'll find all primes within it.")
start_str = input("Start value (>=2): ")
end_str = input("End value: ")
if not (start_str.isdigit() and end_str.isdigit()):
print("Please enter valid positive integers!")
else:
start = int(start_str)
end = int(end_str)
if start < 2:
start = 2
print("Start value adjusted to 2 (primes start from 2)")
if start > end:
print("Start value cannot be greater than end value!")
else:
primes = []
for num in range(start, end + 1):
is_prime = True
for i in range(2, int(num ** 0.5) + 1):
if num % i == 0:
is_prime = False
break
if is_prime:
primes.append(num)
print(f"\nFound {len(primes)} primes between {start} and {end}:")
for i, prime in enumerate(primes, 1):
print(f"{prime:5d}", end="")
if i % 10 == 0:
print()
print()
المشروع 5: مؤشر BMI الصحي + مدقق قوة كلمة المرور
هذا المشروع يربط العوامل الحسابية وعوامل المقارنة والعوامل المنطقية والجمل الشرطية وطرق السلاسل النصية لحل مشكلتين واقعيتين شائعتين.
الجزء 1: مؤشر BMI الصحي (⭐⭐)
BMI = weight(kg) / height(m)^2
مثال: حاسبة BMI
weight = 68
height = 1.75
bmi = weight / (height ** 2)
print("=== BMI Health Index ===")
print(f"Weight: {weight} kg")
print(f"Height: {height} m")
print(f"BMI: {bmi:.1f}")
if bmi < 18.5:
print("Category: Underweight")
elif 18.5 <= bmi < 24:
print("Category: Normal")
elif 24 <= bmi < 28:
print("Category: Overweight")
else:
print("Category: Obese")
الجزء 2: مدقق قوة كلمة المرور (⭐⭐⭐)
password = "Py3#thon"
length = len(password)
has_digit = any(c.isdigit() for c in password)
has_letter = any(c.isalpha() for c in password)
has_special = not password.isalnum()
print("=== Password Strength Checker ===")
print(f"Password: {password}")
print(f"Length: {length}")
print(f"Contains digit: {has_digit}")
print(f"Contains letter: {has_letter}")
print(f"Contains special char: {has_special}")
if length < 6:
strength = "Weak"
elif length >= 10 and has_digit and has_letter and has_special:
strength = "Strong"
elif length >= 8 and has_digit and has_letter:
strength = "Medium"
else:
strength = "Weak"
print(f"Password strength: {strength}")
أخطاء الفروع/الحلقات الشائعة
الخطأ 1: حلقة لا نهائية — نسيان تحديث متغير الشرط
# طريقة خاطئة
n = 1
while n <= 10:
print(n)
# نسيت n += 1 — لن تنتهي أبداً
# طريقة صحيحة
n = 1
while n <= 10:
print(n)
n += 1
الخطأ 2: الخلط بين = و ==
# طريقة خاطئة
if score = 100: # هذا إسناد، وليس مقارنة!
print("Perfect!")
# طريقة صحيحة
if score == 100:
print("Perfect!")
الخطأ 3: تعديل قائمة أثناء التكرار
# طريقة خاطئة — الحذف أثناء التكرار يسبب تخطياً
numbers = [1, 2, 3, 4, 5]
for num in numbers:
if num % 2 == 0:
numbers.remove(num)
print(numbers)
# طريقة صحيحة — أنشئ قائمة جديدة
numbers = [1, 2, 3, 4, 5]
odd_numbers = [num for num in numbers if num % 2 != 0]
print(odd_numbers)
الخطأ 4: سوء فهم قيمة نهاية range()
# خطأ: توقع أن يُخرج range(5) 1 2 3 4 5
for i in range(5):
print(i) # الإخراج الفعلي: 0 1 2 3 4
# طريقة صحيحة
for i in range(1, 6):
print(i) # الإخراج: 1 2 3 4 5
حالات الاستخدام الشائعة
| السيناريو | تقنية الحلقة/الفرع | الوصف |
|---|---|---|
| معالجة البيانات (تصفية، تنظيف) | for + continue |
تخطي البيانات غير الصالحة |
| قائمة تفاعل المستخدم | while True + break |
عرض القائمة مراراً حتى الخروج |
| تحميل الصفحات | while + شرط |
حتى لا توجد بيانات أخرى |
| بحث/استعلام | for + break + else |
توقف عند العثور؛ else إذا لم يُعثر |
| معالجة ملفات دفعة واحدة | for + منطق متداخل |
تكرار كل ملف في دليل |
| حلقة اللعبة الرئيسية | while True + معالجة الأحداث |
عرض مستمر واستجابة للإدخال |
❓ أسئلة شائعة
False يوماً ما؟ 2) هل يعدّل جسم الحلقة متغير الشرط؟ 3) هل while True لديه break مقابل؟ إضافة print() لإخراج قيم المتغيرات الرئيسية هي الطريقة الأكثر فعالية لتصحيح الحلقات اللانهائية.
س:أيهما أكثر كفاءة — range() أم التكرار على قائمة؟ ج:range() يُرجع تسلسلاً كسولاً دون إنشاء جميع الأرقام مرة واحدة. range(1000000) لا يستهلك ذاكرة تقريباً، بينما list(range(1000000)) يستهلك كثيراً. لأعداد التكرار الكبيرة، استخدم range() مباشرة لكفاءة أفضل في الذاكرة.
س:كود المشروع أطول بكثير من الأمثلة السابقة. كيف يجب أن أقرأه؟ ج:ثلاث خطوات: أولاً، افهم الهيكل العام (كم عدد الحلقات/الشروط). ثانياً، افهم التدفق الرئيسي (كيف تتغير المتغيرات). ثالثاً، ركز على الحالات الحدودية (التحقق من صحة الإدخال، القسمة على صفر، إلخ.). الكود الجيد يوثّق نفسه — أسماء متغيرات ذات معنى وتعليقات في النقاط الرئيسية.📖 ملخص
- لعبة التخمين المحسّنة: حلقة خارجية لـ "العب مرة أخرى"، حلقة داخلية لـ "التخمين"، استخدم
while True+breakلإدارة الخروج متعدد المستويات - أنماط جدول الضرب: تحكم في حدود
range()للحلقة الداخلية لإخراج مثلث سفلي، علوي، مستطيل، والمزيد - الآلة الحاسبة المحسّنة:
continueلتخطي الإدخال غير الصالح، قائمة لتخزين التاريخ،split()لتحليل إدخال المستخدم - الباحث عن الأعداد الأولية: حسّن بالفحص حتى
sqrt(num)للكفاءة؛enumerate(primes, 1)للإخراج المرقّم - نصائح التصحيح: ثلاثة عناصر لفحص الحلقات اللانهائية، ميِّز
=عن==، لا تعدّل القوائم أثناء التكرار
📝 تمارين
⭐: الأعداد النرجسية
العدد "النرجسي" هو عدد مكون من 3 أرقام حيث مجموع مكعبات أرقامه يساوي العدد نفسه. مثال: 153 = 1^3 + 5^3 + 3^3.
استخدم حلقة for للعثور على جميع الأعداد النرجسية (هناك 4).
⭐⭐: اطبع معيناً
اقبل عدداً فردياً n من المستخدم، ثم أخرج معيناً مصنوعاً من * في وحدة التحكم.
⭐⭐⭐: نظام إدارة درجات الطلاب
اكتب برنامجاً ينفذ الميزات التالية:
- أدخل درجات الطلاب (أدخل q للتوقف)
- احسب المجموع والمتوسط والأعلى والأدنى
- عد الطلاب في كل نطاق: 90-100 (ممتاز)، 80-89 (جيد)، 70-79 (متوسط)، 60-69 (مقبول)، <60 (راسب)
- أخرج الدرجات مرتبة من الأعلى إلى الأدنى



