المسارات
/
Python
Python
/
التمارين
/
القائمة المترابطة
القائمة المترابطة

القائمة المترابطة

متوسط

مقدمة

أنت تعمل على مشروع لتطوير نظام لجدولة القطارات في شبكة سكك حديدية مزدحمة.

طُلب منك تطوير نموذج أولي لمسارات القطارات في نظام الجدولة. يتكوّن كل مسار من تسلسل من محطات القطار التي يتوقف عندها قطار معيّن.

التعليمات

قرّر فريقك استخدام قائمة مترابطة مزدوجة لتمثيل كل مسار قطار في الجدول الزمني. كل محطة على طول مسار القطار ستُمثَّل بعقدة في القائمة المترابطة.

لا داعي للقلق بشأن أوقات الوصول والمغادرة في المحطات. كل محطة ستُمثَّل ببساطة بعدد.

يمكن تمديد المسارات بإضافة محطات إلى بداية المسار أو نهايته. ويمكن أيضًا تقصيرها بإزالة محطات من بداية المسار أو نهايته.

أحيانًا تُغلق إحدى المحطات، وفي هذه الحالة يجب إزالتها من المسار، حتى لو لم تكن في بداية المسار أو نهايته.

لا يُقاس حجم المسار بمدى سفر القطار، بل بعدد المحطات التي يتوقف عندها.

Note

القائمة المترابطة بنية بيانات أساسية في علم الحاسوب، وكثيرًا ما تُستخدم في تنفيذ بنى بيانات أخرى. وكما يوحي الاسم، فهي قائمة من العقد المترابطة معًا. إنها قائمة من "العقد"، حيث ترتبط كل عقدة بجارتها أو بجيرانها. في القائمة المترابطة الأحادية ترتبط كل عقدة بالعقدة التي تليها فقط. وفي القائمة المترابطة المزدوجة ترتبط كل عقدة بالعقدة التي تسبقها، وكذلك بالعقدة التي تليها.

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

كيف يتم بناء هذا التمرين في Python

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

في الملف الأولي، سترى بداية صنف Node، وكذلك صنف LinkedList. ينبغي أن يتتبّع صنف Node الخاص بك قيمة العقدة، وكذلك العُقد التي تسبقها أو تليها. وينبغي تنفيذ push وpop وshift وunshift، والطريقة الخاصة بـ len، داخل صنف LinkedList. وقد تجد أيضًا أنه من المفيد تنفيذ طريقة خاصة iter لأجل التكرار.

وخلافًا للتمرين الأساسي، سنختبر حالات الخطأ باستدعاء pop وshift على قوائم مترابطة فارغة، لذا ستحتاج إلى raise الأخطاء بالشكل المناسب.

وأخيرًا، نودّ أن تنفّذ delete بالإضافة إلى الطرق المشروحة أعلاه. تأخذ delete وسيطًا واحدًا، وهو القيمة المراد حذفها من القائمة المترابطة. وإذا ظهرت القيمة أكثر من مرة، فينبغي حذف أول ظهور لها فقط.


رسائل الاستثناء

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

يتطلّب هذا التمرين تحديدًا أن تستخدم عبارة الرفع لكي «تطلق» ValueError عندما لا توجد قيمة العقدة التي يجري حذفها بـ delete() في القائمة المترابطة. بالإضافة إلى ذلك، ينبغي إطلاق IndexError إذا لم تبقَ أي عُقد لكي تُستدعى عليها pop(). ولن تنجح الاختبارات إلا إذا قمت بـ raise لهذه exceptions وأضفت معها رسائل.

لكي ترفع ValueError مع رسالة، اكتب الرسالة كوسيط لنوع exception:

# When the value passed to `delete()` is not found.
if not found:
    raise ValueError("Value not found")

لكي ترفع IndexError مع رسالة، اكتب الرسالة كوسيط لنوع exception:

# When pop() is called and there are no nodes left in the linked list
if self.length == 0:
    raise IndexError("List is empty")

الطرق الخاصة في Python

ستستدعي اختبارات هذا التمرين أيضًا len() على صنف LinkedList الخاص بك. ولكي تعمل len()، ستحتاج إلى إنشاء طريقة خاصة __len__. وللتفاصيل حول تنفيذ الطرق الخاصة أو طرق «dunder» في Python، انظر توثيق Python: التخصيص الأساسي للكائنات وتوثيق Python: ‏LinkedLists.

نوصي أيضًا بإنشاء طريقة خاصة __iter__ تساعد في التكرار عبر قائمتك المترابطة.



المصدر

موضوع كلاسيكي في علوم الحاسوب
تعديل عبر GitHub يفتح الرابط في نافذة أو علامة تبويب جديدة
Python Exercism

مستعد لبدء القائمة المترابطة؟

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