المسارات
/
Common Lisp
Common Lisp
/
التمارين
/
الالتحاق بالخدمة
الالتحاق بالخدمة

الالتحاق بالخدمة

تمرين تعلّمي

مقدمة

التنسيق - الأساسيات

في Common Lisp يوجد مفهوم يُسمى «الطابعة»، ويشمل كل الدوال التي تكتب تمثيلات نصية لبيانات Lisp. ومن هذه الدوال دالة format التي تتيح للمبرمج تنسيق البيانات كما يريد.

قدرات format والطابعة في Lisp عمومًا موضوع واسع؛ وهنا سنصف أساسيات استخدام format.

دالة FORMAT

تأخذ الدالة format وسيطين على الأقل: تيارًا تُطبع إليه، وسلسلة نصية للتحكم تحدد ما يُطبع وكيف.

التيارات مفهوم قائم بذاته وسنشرحه في موضع آخر. لكن كل ما تحتاج معرفته الآن أن الطباعة تجري إلى التيار، وأن لهذا الوسيط قيمتين خاصتين: t و nil. تعني t الطباعة إلى المخرَج القياسي (وهو التيار الذي يرتبط به المتغير *standard-output*). أما nil فتعني إنشاء سلسلة نصية وإرجاعها.

لاحظ أن format ستُقيَّم دائمًا إلى nil إلا في الحالة الأخيرة حيث تُحدَّد nil بوصفها التيار. وهذه طريقة شائعة لإقحام القيم في سلسلة نصية أو إنشائها.

(format nil "hello world") ; => "hello world"
(format t "hello world")   ; => NIL (but "hello world" is printed to standard output)

توجيهات التنسيق

يمكن أن تحتوي السلسلة النصية للتحكم على «توجيهات التنسيق» التي تعطي format تعليمات حول ما يُطبع وكيف تُفسَّر بقية المعاملات الممرَّرة إليها. وبمعنى ما، فإن سلسلة التحكم برنامج يقوم format بتفسيره وتشغيله. تبدأ جميع التوجيهات بالرمز ~ ويتبعها محرف (مثل ~A و ~D و ~&). ولا يهم كون المحرف كبيرًا أو صغيرًا.

معظم توجيهات التنسيق تُقحم ببساطة وسيطًا ممرَّرًا إلى format في المخرَج، ويقال إنها «تستهلك» هذا الوسيط. وبعض التوجيهات لا تستهلك وسائط، أو تستهلك أكثر من وسيط واحد. بل إن هناك توجيهًا يتيح لك التنقل في قائمة الوسائط أو تخطي بعضها.

التنسيق الأساسي

من توجيهات التنسيق العامة جدًا التوجيه ~A، وهو يطبع نسخة «مقروءة للبشر» من البيانات.

(format nil "Value = ~a" 10)                ; => "10"
(format nil "hello ~a" "world")             ; => "hello world"
(format nil "The list is: ~A" (list 1 2 3)) ; => "The list is: (1 2 3)"

وثمة توجيه مفيد آخر هو ~S، وهو يطبع نسخة «مقروءة للآلة» من البيانات. وقد يكون مفيدًا جدًا إذا أردت أن تكون قادرًا على تفسير المخرَج بوصفه بيانات Lisp. في كثير من الحالات سيبدو مثل ~A، لكن لاحظ أنه في السلاسل النصية على سبيل المثال سيتضمن المخرَج علامتَي الاقتباس (مُهرَّبتين عند تضمينهما في سلسلة نصية أخرى) بحيث يمكن إعادة قراءة القيمة بوصفها معاملًا من نوع سلسلة نصية.

(format nil "~s" 10)            ; => "10"
(format nil "~s" "hello world") ; => "\"hello world\""
(format nil "~s" (list 1 2 3))  ; => "(1 2 3)"

وثمة توجيهان مفيدان آخران هما ~% و ~&. الأول يُخرج محرف سطر جديد، أما الثاني فيُخرج «سطرًا جديدًا». والفرق أن ~% يُخرج دائمًا سطرًا جديدًا، بينما ~& يُخرجه فقط إن لم تكن عند بداية سطر. ولا يستهلك أيٌّ منهما وسيطًا.

(format nil "~%new~%lines") ; => "
                                  new
                                  lines"

(format nil "~&new~&lines"  ; => "new
                                  lines"

وأخيرًا، التوجيه ~~ توجيه بسيط يُخرج علامة ~ حرفيًا.

التعليمات

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

1. تنسيق القيم الربعية

أول ما تحتاجه Layla هو دالة: format-quarter-value تأخذ معاملين: الربع السنوي والقيمة، وتنسّقهما لإعداد تقرير. وينبغي أن تُقيّم إلى سلسلة نصية.

(format-quarter-value "last" 3.14) ; => "The value last quarter: 3.14"
(format-quarter-value "this" 0) ; => "The value this quarter: 0"

2. تقرير الربعين

تشكرك Layla على دالة format-quarter-value وتقول إنها ستكون مفيدة جدًا في الدالة التالية المطلوبة.

يحتاج التقرير التالي إلى عرض الربع والقيمة لكل من الربعين مطبوعين على سطرين.

كما يجب أن يذهب الإخراج إلى المجرى المقدَّم كوسيط أول.

على سبيل المثال: (format-two-quarters t "last" 3.14 "this" 0) سينتج ما يلي على الإخراج القياسي:


The value last quarter: 3.14
The value this quarter: 0

لاحظ الأسطر الفارغة حوله.

3. مقروء للبشر مقابل مقروء لكائنات Lisp الفضائية

نسيت Layla أن تخبرك أن كائنات Lisp الفضائية تحب رؤية القيم بطريقة يمكن قراءتها كبيانات Lisp. لذا تحتاج كائنات Lisp الفضائية إلى دالة جديدة يمكن قراءتها كبيانات Lisp (مرة أخرى إلى المجرى المحدد):

(format-two-quarters-for-reading nil "last" 3.14 "this" 0) ; =>

"(\"The value last quarter: 3.14\" \"The value this quarter: 0\")"
تعديل عبر GitHub يفتح الرابط في نافذة أو علامة تبويب جديدة
Common Lisp Exercism

مستعد لبدء الالتحاق بالخدمة؟

سجّل في Exercism لتتعلّم وتتقن Common Lisp عبر 27 مفهومًا92 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.