Задачи по Python: рекурсия, структуры данных, SDLC

Photo
Homi

المهمة الثالثة

السؤال: اذكر وظائف ثلاث وحدات برمجية بايثون لعمل محاكاة لإدارة سجل التصفح (Browser History) بحيث:
1. تعمل الوحدة المستدعية على:
أ. تعريف السجل من خلال قائمة فارغة.
ب. استدعاء وحدات الإضافة والحذف ومعرفة الصفحة الحالية والحجم والتحقق فيما إذا كان السجل فارغاً أم لا.

  1. إنشاء:
    أ. وحدة باسم push تستخدم عند زيارة صفحة جديدة.
    ب. وحدة تسمى pop لعرض الصفحة السابقة.
    ج. وحدة تسمى peek لعرض الصفحة الحالية.
    د. معرفة عدد الصفحات من وحدة تسمى size.
    هـ. التحقق هل السجل فارغ أم لا باستخدام وحدة تسمى is_empty.

الحل:

هذه المهمة تتطلب وصف وظائف وحدات برمجية في بايثون لمحاكاة سجل المتصفح. سنقوم بتعريف الوحدات المطلوبة وشرح وظيفة كل منها.

1. تعريف الوحدات ووظائفها:

  • الوحدة المستدعية (Main Module/Class):

    • __init__(self): تقوم بتهيئة السجل كقائمة فارغة عند إنشاء كائن من هذه الوحدة.
      python self.history = []
    • add_page(self, page): تضيف صفحة جديدة إلى نهاية السجل (تعمل كـ push).
    • remove_page(self): تزيل الصفحة الأخيرة من السجل وتعيدها (تعمل كـ pop).
    • get_current_page(self): تعرض الصفحة الحالية (الأخيرة في السجل) دون إزالتها (تعمل كـ peek).
    • get_size(self): تعيد عدد الصفحات الموجودة في السجل.
    • is_empty(self): تتحقق مما إذا كان السجل فارغاً وتعيد True أو False.
  • الوحدة push:

    • الوظيفة: تستخدم لإضافة صفحة جديدة إلى سجل التصفح. عند زيارة صفحة جديدة، يتم استدعاء هذه الوحدة لإضافتها إلى نهاية قائمة السجل.
  • الوحدة pop:

    • الوظيفة: تستخدم للانتقال إلى الصفحة السابقة. عند استدعائها، تزيل الصفحة الحالية من السجل وتعيدها، مما يجعل الصفحة التي قبلها هي الصفحة الحالية.
  • الوحدة peek:

    • الوظيفة: تستخدم لعرض الصفحة الحالية دون تغيير السجل. عند استدعائها، تعرض الصفحة الأخيرة في قائمة السجل.
  • الوحدة size:

    • الوظيفة: تستخدم لمعرفة عدد الصفحات الموجودة حالياً في سجل التصفح. تعيد طول القائمة التي تمثل السجل.
  • الوحدة is_empty:

    • الوظيفة: تستخدم للتحقق مما إذا كان سجل التصفح فارغاً. تعيد True إذا كانت القائمة فارغة، و False إذا كانت تحتوي على صفحات.

مثال توضيحي لكيفية عمل الوحدات (باستخدام كلاس بسيط):

PYTHON
class BrowserHistory:
    def __init__(self):
        self.history = []

    # تعمل كـ push
    def push(self, page):
        self.history.append(page)
        print(f"Added: {page}")

    # تعمل كـ pop
    def pop(self):
        if not self.is_empty():
            return self.history.pop()
        return None

    # تعمل كـ peek
    def peek(self):
        if not self.is_empty():
            return self.history[-1]
        return None

    # تعمل كـ size
    def size(self):
        return len(self.history)

    # تعمل كـ is_empty
    def is_empty(self):
        return len(self.history) == 0

# --- الاستخدام ---
history_manager = BrowserHistory()
print(f"Is empty? {history_manager.is_empty()}") # True

history_manager.push("google.com")
history_manager.push("facebook.com")
print(f"Current page: {history_manager.peek()}") # facebook.com
print(f"History size: {history_manager.size()}") # 2

previous_page = history_manager.pop()
print(f"Went back to: {previous_page}") # facebook.com
print(f"Current page: {history_manager.peek()}") # google.com
print(f"History size: {history_manager.size()}") # 1
print(f"Is empty? {history_manager.is_empty()}") # False

المهمة الرابعة

السؤال: في إطار دورة حياة تطوير البرمجيات (SDLC)، ما هو النموذج المناسب، وما هو أثر ذلك على تحقيق الشركة لتنفيذها؟

الحل:

السؤال يتحدث عن اختيار نموذج مناسب لدورة حياة تطوير البرمجيات (SDLC) وتأثير هذا الاختيار على تحقيق أهداف الشركة.

النموذج المناسب:

يعتمد اختيار النموذج المناسب لدورة حياة تطوير البرمجيات (SDLC) على عدة عوامل، منها:

  • طبيعة المشروع: هل هو مشروع كبير أم صغير؟ هل المتطلبات واضحة وثابتة أم متغيرة؟
  • حجم الفريق: هل الفريق كبير أم صغير؟
  • الجدول الزمني والميزانية: ما هي القيود المفروضة على الوقت والتكلفة؟
  • مستوى المخاطرة: ما هي درجة المخاطرة المتوقعة في المشروع؟

بشكل عام، هناك نماذج متعددة مثل:

  1. النموذج الشلالي (Waterfall Model): مناسب للمشاريع ذات المتطلبات الواضحة والثابتة، حيث يتم الانتقال من مرحلة إلى أخرى بشكل تسلسلي.
  2. النماذج التكرارية والمتزايدة (Iterative and Incremental Models): مثل نموذج "التطوير السريع للتطبيقات" (RAD) أو "التطوير الرشيق" (Agile). هذه النماذج مناسبة للمشاريع التي تتغير فيها المتطلبات أو عندما يكون من المهم تقديم منتج قابل للاستخدام بسرعة.
  3. النموذج الحلزوني (Spiral Model): يجمع بين عناصر النماذج التكرارية والتحكم في المخاطر، وهو مناسب للمشاريع الكبيرة والمعقدة وعالية المخاطر.

أثر اختيار النموذج على تحقيق الشركة لتنفيذها:

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

  • زيادة الكفاءة: النموذج المناسب يساعد على تنظيم العمل وتحديد المهام بوضوح، مما يزيد من كفاءة الفريق ويقلل من إهدار الوقت والموارد.
  • تحسين الجودة: بعض النماذج (مثل Agile) تشجع على الاختبار المستمر والتغذية الراجعة، مما يؤدي إلى منتج نهائي عالي الجودة يلبي احتياجات العملاء.
  • تقليل المخاطر: النماذج التي تركز على إدارة المخاطر (مثل الحلزوني) تساعد الشركة على تحديد ومعالجة المشاكل المحتملة مبكراً، مما يقلل من احتمالية فشل المشروع.
  • المرونة والاستجابة للتغيير: النماذج الرشيقة تتيح للشركة الاستجابة بسرعة للتغيرات في متطلبات السوق أو العملاء، مما يضمن بقاء منتجاتها تنافسية.
  • رضا العملاء: عندما يتم اختيار النموذج الذي يتناسب مع طبيعة المشروع ويسمح بإشراك العميل بشكل فعال، فإن ذلك يؤدي إلى منتج يلبي توقعاته ويزيد من رضاه.

الخلاصة:

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


المهمة الخامسة

السؤال: ارسم مخططاً مُبسطاً لعمليات الحساب للآلية الآتية: حساب الراتب الإجمالي لمندوب مبيعات، راتبه الأساسي (300) دينار، والعمولة الإضافية التي يأخذها على النحو الآتي:
1. إذا كانت مبيعاته أقل من أو تساوي (1000) دينار، فإن نسبة عمولته تبلغ 6%.
2. إذا كانت مبيعاته أكثر من (1000) دينار، وأقل من أو تساوي (3000) دينار، فإن نسبة عمولته تبلغ 7.5%.
3. إذا كانت مبيعاته أكثر من (3000) دينار، وأقل من أو تساوي (5000) دينار، فإن نسبة عمولته تبلغ 9%.
4. إذا كانت مبيعاته أكثر من (5000) دينار، فإن نسبة عمولته تبلغ 10%.

الحل:

سنقوم برسم مخطط تدفق (Flowchart) يوضح خطوات حساب الراتب الإجمالي للمندوب بناءً على قيمة مبيعاته.

المكونات الأساسية للمخطط:

  • البداية/النهاية (Terminal): شكل بيضاوي.
  • العمليات (Process): شكل مستطيل (مثل حساب العمولة أو الراتب).
  • المدخلات/المخرجات (Input/Output): شكل متوازي الأضلاع (مثل إدخال المبيعات أو عرض الراتب الإجمالي).
  • القرارات (Decision): شكل معين (للتحقق من شروط المبيعات).
  • الأسهم (Flowlines): لربط المكونات وتوضيح اتجاه التدفق.

مخطط التدفق:

MERMAID
graph TD
    A[البداية] --> B{إدخال قيمة المبيعات};
    B --> C{هل المبيعات <= 1000؟};
    C -- نعم --> D[العمولة = المبيعات * 0.06];
    C -- لا --> E{هل المبيعات <= 3000؟};
    E -- نعم --> F[العمولة = المبيعات * 0.075];
    E -- لا --> G{هل المبيعات <= 5000؟};
    G -- نعم --> H[العمولة = المبيعات * 0.09];
    G -- لا --> I[العمولة = المبيعات * 0.10];
    D --> J[الراتب الإجمالي = 300 + العمولة];
    F --> J;
    H --> J;
    I --> J;
    J --> K[عرض الراتب الإجمالي];
    K --> L[النهاية];

شرح المخطط:

  1. البداية: تبدأ العملية.
  2. إدخال قيمة المبيعات: يتم إدخال قيمة المبيعات التي حققها المندوب.
  3. هل المبيعات <= 1000؟: يتم التحقق من الشرط الأول.
    • نعم: إذا كانت المبيعات أقل من أو تساوي 1000، يتم حساب العمولة بنسبة 6%.
    • لا: إذا لم يتحقق الشرط الأول، ننتقل للتحقق من الشرط التالي.
  4. هل المبيعات <= 3000؟: يتم التحقق من الشرط الثاني.
    • نعم: إذا كانت المبيعات أكبر من 1000 وأقل من أو تساوي 3000، يتم حساب العمولة بنسبة 7.5%.
    • لا: ننتقل للشرط التالي.
  5. هل المبيعات <= 5000؟: يتم التحقق من الشرط الثالث.
    • نعم: إذا كانت المبيعات أكبر من 3000 وأقل من أو تساوي 5000، يتم حساب العمولة بنسبة 9%.
    • لا: ننتقل للشرط الأخير.
  6. العمولة = المبيعات * 0.10: إذا لم يتحقق أي من الشروط السابقة، فهذا يعني أن المبيعات أكبر من 5000، ويتم حساب العمولة بنسبة 10%.
  7. الراتب الإجمالي = 300 + العمولة: بعد حساب قيمة العمولة، يتم إضافتها إلى الراتب الأساسي (300 دينار) للحصول على الراتب الإجمالي.
  8. عرض الراتب الإجمالي: يتم عرض قيمة الراتب الإجمالي المحسوبة.
  9. النهاية: تنتهي العملية.

المهمة السادسة

السؤال: ما هو ناتج تنفيذ كل مقطع برمجي مما يأتي:

أ- المقطع الأول:

PYTHON
def repeat_string(s, n):
    if n == 0:
        return ""
    else:
        return s + repeat_string(s, n - 1)

print(repeat_string("Hello", 3))

الحل:

هذا المقطع البرمجي يستخدم الاستدعاء الذاتي (Recursion) لتكرار سلسلة نصية.

  • الدالة repeat_string(s, n):
    • تأخذ سلسلتين نصيتين s (النص المراد تكراره) و n (عدد مرات التكرار).
    • الحالة الأساسية (Base Case): إذا كانت n تساوي 0، تعيد سلسلة نصية فارغة "". هذا يوقف الاستدعاء الذاتي.
    • الحالة العودية (Recursive Case): إذا كانت n أكبر من 0، تعيد السلسلة s مضافاً إليها نتيجة استدعاء الدالة نفسها مع n-1.

تتبع التنفيذ:

  1. repeat_string("Hello", 3)
    • n ليست 0، لذا تعيد "Hello" + repeat_string("Hello", 2)
  2. repeat_string("Hello", 2)
    • n ليست 0، لذا تعيد "Hello" + repeat_string("Hello", 1)
  3. repeat_string("Hello", 1)
    • n ليست 0، لذا تعيد "Hello" + repeat_string("Hello", 0)
  4. repeat_string("Hello", 0)
    • n تساوي 0، لذا تعيد ""

النتيجة النهائية:

سيتم تجميع النتائج من الأسفل إلى الأعلى:
"Hello" + ("Hello" + ("Hello" + ""))
= "Hello" + ("Hello" + "Hello")
= "Hello" + "HelloHello"
= "HelloHelloHello"

الناتج:

Код
HelloHelloHello

ب- المقطع الثاني:

PYTHON
def draw_triangle(n):
    if n == 0:
        return
    else:
        draw_triangle(n - 1)
        print("*" * n)

draw_triangle(5)

الحل:

هذا المقطع البرمجي يستخدم أيضاً الاستدعاء الذاتي (Recursion) لرسم مثلث من النجوم.

  • الدالة draw_triangle(n):
    • تأخذ عدداً صحيحاً n يمثل عدد الصفوف أو حجم المثلث.
    • الحالة الأساسية (Base Case): إذا كانت n تساوي 0، فإن الدالة لا تفعل شيئاً وتعود (توقف الاستدعاء).
    • الحالة العودية (Recursive Case): إذا كانت n أكبر من 0:
      1. تستدعي الدالة نفسها مع n-1 (هذا يعني أنها ستبني المثلث من الأعلى إلى الأسفل).
      2. بعد انتهاء الاستدعاء السابق (أي بعد طباعة الصفوف العليا)، تقوم بطباعة n من النجوم *.

تتبع التنفيذ:

  1. draw_triangle(5):
    • تستدعي draw_triangle(4)
  2. draw_triangle(4):
    • تستدعي draw_triangle(3)
  3. draw_triangle(3):
    • تستدعي draw_triangle(2)
  4. draw_triangle(2):
    • تستدعي draw_triangle(1)
  5. draw_triangle(1):
    • تستدعي draw_triangle(0)
  6. draw_triangle(0):
    • تتوقف (الحالة الأساسية).
  7. العودة إلى draw_triangle(1):
    • تطبع * * 1 (أي *)
  8. العودة إلى draw_triangle(2):
    • تطبع * * 2 (أي **)
  9. العودة إلى draw_triangle(3):
    • تطبع * * 3 (أي ***)
  10. العودة إلى draw_triangle(4):
    • تطبع * * 4 (أي ****)
  11. العودة إلى draw_triangle(5):
    • تطبع * * 5 (أي *****)

الناتج:

Код
*
**
***
****
*****
السؤال الثالث اعطيني حل نهائي مختصر و السؤال السادس عادي ترسمو مع الخطوات
Homi

بالتأكيد! سأقوم بتقديم حل مختصر للسؤال الثالث، وحل مفصل للسؤال السادس مع الخطوات.

المهمة الثالثة

السؤال: اذكر وظائف ثلاث وحدات برمجية بايثون لعمل محاكاة لإدارة سجل التصفح (Browser History) بحيث:
1. تعمل الوحدة المستدعية على:
أ. تعريف السجل من خلال قائمة فارغة.
ب. استدعاء وحدات الإضافة والحذف ومعرفة الصفحة الحالية والحجم والتحقق فيما إذا كان السجل فارغاً أم لا.

  1. إنشاء:
    أ. وحدة باسم push تستخدم عند زيارة صفحة جديدة.
    ب. وحدة تسمى pop لعرض الصفحة السابقة.
    ج. وحدة تسمى peek لعرض الصفحة الحالية.
    د. معرفة عدد الصفحات من وحدة تسمى size.
    هـ. التحقق هل السجل فارغ أم لا باستخدام وحدة تسمى is_empty.

الحل المختصر:

  • push(page): تضيف صفحة جديدة إلى نهاية السجل.
  • pop(): تزيل وتعيد الصفحة الأخيرة من السجل (الصفحة السابقة).
  • peek(): تعرض الصفحة الأخيرة في السجل دون إزالتها (الصفحة الحالية).
  • size(): تعيد عدد الصفحات في السجل.
  • is_empty(): تعيد True إذا كان السجل فارغاً، و False إذا كان يحتوي على صفحات.

المهمة السادسة

السؤال: ما هو ناتج تنفيذ كل مقطع برمجي مما يأتي:

أ- المقطع الأول:

PYTHON
def repeat_string(s, n):
    if n == 0:
        return ""
    else:
        return s + repeat_string(s, n - 1)

print(repeat_string("Hello", 3))

الحل:

هذا المقطع يستخدم الاستدعاء الذاتي (Recursion) لتكرار سلسلة نصية.

  • الوظيفة: repeat_string(s, n) تأخذ سلسلة نصية s وعدد مرات التكرار n.
  • آلية العمل:
    1. إذا كانت n تساوي 0، تعيد سلسلة فارغة (هذه هي الحالة الأساسية التي توقف الاستدعاء).
    2. إذا كانت n أكبر من 0، تعيد السلسلة s مضافاً إليها نتيجة استدعاء الدالة نفسها مع n-1. هذه هي الحالة العودية.

خطوات التنفيذ (تتبع الاستدعاء):

  1. repeat_string("Hello", 3) تستدعي repeat_string("Hello", 2) وتعيد "Hello" + نتيجة الاستدعاء.
  2. repeat_string("Hello", 2) تستدعي repeat_string("Hello", 1) وتعيد "Hello" + نتيجة الاستدعاء.
  3. repeat_string("Hello", 1) تستدعي repeat_string("Hello", 0) وتعيد "Hello" + نتيجة الاستدعاء.
  4. repeat_string("Hello", 0) تعيد "" (الحالة الأساسية).

تجميع النتائج (من الداخل للخارج):

  • الاستدعاء الرابع يعيد "".
  • الاستدعاء الثالث يعيد "Hello" + "" = "Hello".
  • الاستدعاء الثاني يعيد "Hello" + "Hello" = "HelloHello".
  • الاستدعاء الأول يعيد "Hello" + "HelloHello" = "HelloHelloHello".

الناتج النهائي:

Код
HelloHelloHello

ب- المقطع الثاني:

PYTHON
def draw_triangle(n):
    if n == 0:
        return
    else:
        draw_triangle(n - 1)
        print("*" * n)

draw_triangle(5)

الحل:

هذا المقطع يستخدم أيضاً الاستدعاء الذاتي (Recursion) لطباعة مثلث من النجوم.

  • الوظيفة: draw_triangle(n) تأخذ عدداً صحيحاً n يمثل حجم المثلث (أو عدد الصفوف).
  • آلية العمل:
    1. إذا كانت n تساوي 0، تتوقف الدالة (الحالة الأساسية).
    2. إذا كانت n أكبر من 0:
      • أولاً، تستدعي الدالة نفسها مع n-1. هذا يعني أنها ستكمل بناء الأجزاء العلوية من المثلث أولاً.
      • بعد اكتمال الاستدعاء الداخلي (أي بعد طباعة الصفوف العلوية)، تقوم بطباعة n من النجوم *.

خطوات التنفيذ (تتبع الاستدعاء والطباعة):

  1. draw_triangle(5) تستدعي draw_triangle(4).
  2. draw_triangle(4) تستدعي draw_triangle(3).
  3. draw_triangle(3) تستدعي draw_triangle(2).
  4. draw_triangle(2) تستدعي draw_triangle(1).
  5. draw_triangle(1) تستدعي draw_triangle(0).
  6. draw_triangle(0) تتوقف.
  7. تعود draw_triangle(1) لتنفذ print("*" * 1) فتطبع *.
  8. تعود draw_triangle(2) لتنفذ print("*" * 2) فتطبع **.
  9. تعود draw_triangle(3) لتنفذ print("*" * 3) فتطبع ***.
  10. تعود draw_triangle(4) لتنفذ print("*" * 4) فتطبع ****.
  11. تعود draw_triangle(5) لتنفذ print("*" * 5) فتطبع *****.

الناتج النهائي (تسلسل ما تم طباعته):

Код
*
**
***
****
*****
Homi
Текст скопирован
Готово
Ошибка