قراءة البيانات المسلسلة

كثيرًا ما تأتي البيانات مسلسلة (Sequence) تتكرر بزمن ثابت؛ كأيام الأسبوع، وأسابيع الشهر، وأشهر السنة. ويتم رصدُ القيَم في الأنظمة بهذه المواقيت بحسبها؛ فربَّما يتمُّ جرْدُ السلع يوميًّا، وربمَّا تُرسَلُ الشحنات أسبوعيًّا، وربما تُصرف الرواتب شهريًّا.

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

إجراء الحساب على بعض القائمة

نعود إلى بيانات القراءة خلال أربعة أسابيع:

نريد المرور على بيانات القراءة ومعرفة موضع كل قيمة، ثم استخراج بيانات كل أسبوع لحساب مجموعها.

الشريحة من الموضع 0 إلى ما قبل 7 تستخرج الأسبوع الأول

تزودنا بايثون بدالة النطاق range(start, stop, step) وبالاستعمال تتضح:

وهذه معناها:

  • البداية هي 0
  • النهاية هي 10 (غير مشمولة)
  • الخطوة هي 2

وهذا يعني أننا نبدأ من 0 ونصل إلى 10 بخطوة مقدارها 2، فنحصل على الأعداد: 0, 2, 4, 6, 8.

النطاق يبدأ من 0 بخطوة 2 ويتوقف قبل 10

وإذا مررنا معطيين، فإنهما يفسرنا على أنهما البداية والنهاية، والقيمة الافتراضية للخطوة هي 1:

وإذا كان المعطى واحدًا؛ فإنه يفسَّر بأنه النهاية، والقيمة الافتراضية للبداية هي 0:

والآن نستعمل النطاق لتوليد الأرقام بحيث تكون النهاية هي عدد الأيام، فيحصل لنا هذا الكر:

الموضع والقيمة معًا

عندما نريد موضع كل عنصر وقيمته معًا، فإن الدالة enumerate(list) تعطينا الاثنين في كل كرة:

في for i, value نضع اسمين تفصل بينهما فاصلة: يأخذ i الموضع، ويأخذ value قيمة العنصر في ذلك الموضع.

يبدأ العد من 0، فتكون أول قيمة لـ i هي 0، وأول قيمة لـ value هي 10. وفي الكرة التالية نحصل على الموضع 1 والقيمة 15، وهكذا.
وبذلك نستعمل value مباشرةً بدل قراءة القيمة بـ days[i].

الشريحة

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

ولاحظ أن النهاية لا تشمل العنصر رقم 7 وإنما غايتها العنصر رقم 6.

وإذا كانت البداية من 0 فكتابتها وعدمه واحدة:

وكذلك الأسبوع الثاني والثالث والرابع:

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

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

الشريحة من i+5 إلى ما قبل i+7 تستخرج آخر يومين من كل أسبوع

مثال: توزيع نماذج الاختبار

تصور أن لدينا نموذجين من الاختبار، ونريد أن نوزعها بحيث يأخذ نصفهم النموذج الأول والنصف الثاني يأخذ النموذج الثاني، لكن نريد أن يكون التوزيع بحسب الصف الذي يجلس فيه الطلاب.

نفترض أن كل صف يجلس فيه ثلاثة طلاب، ونريد أن نجعل لكل صف نموذجًا.

نمر على قائمة الأسماء بخطوة مقدارها 3 (عدد الطلاب في كل صف):

شرائح الطلاب بخطوة 3 والمجموعة الأخيرة ذات الطالبين

إذا تجاوز حد توقف الشريحة طول القائمة، فإنها تضم العناصر المتاحة فقط. وإذا بدأت بعد نهاية القائمة، فإنها تعطي قائمة فارغة. قراءة الشريحة لا تغيّر القائمة الأصلية، وتختلف عن قراءة عنصر منفرد بمؤشر خارج الحدود.

قراءة البيانات المجدولة

افترض أن لديك قائمة بالمصروفات (expenses) والإيرادات (revenues) لكل رُبع من السنة، وتريد حساب صافي الربح (net) لكل ربع على حدة، ثم جمعها لتحصل على الربح الإجمالي للسنة.

الإيرادات والمصروفات تقترن بحسب الموضع لحساب صافي كل ربع

فإننا نستعمل نفس الرقم (i) للإشارة هنا وهنا أثناء الكر، حتى نجري الحساب على القيَم المتقابلة، ونضع ناتج ذلك في موضعٍ يقابلهما في سلسلة ثالثة (net)، وذلك على النحو التالي:

ولاحظ أن جملة التعيين net[i] = ... تحل محل الصفر في تلك المواضع.

الضم بـ zip

تعطي zip في كل دورة عنصرًا من كل قائمة بالترتيب نفسه، دون الحاجة إلى المؤشر i. ونستخدم list.append لإضافة الفرق إلى نهاية قائمة النتائج:

تتوقف zip عند أقصر القائمتين؛ فإذا كان لإحداهما عناصر إضافية فلن تقترن بعناصر من الأخرى. ويجب الحفاظ على العلاقة بين القيم: ترتيب قائمة وحدها قد يربط إيرادًا بتكلفة فترة أخرى.

خلاصة

  • range تولّد مواضع ببداية ونهاية وخطوة؛ النهاية غير مشمولة.
  • enumerate تعطي موضع العنصر وقيمته معًا.
  • الشريحة تختار جزءًا من القائمة، وحد توقفها غير مشمول.
  • الموضع نفسه يربط العناصر المتقابلة؛ تغيير ترتيب قائمة وحدها قد يفسد العلاقة.
  • zip تعطي العناصر المقترنة معًا وتتوقف عند أقصر قائمة.
  • list.append تضيف قيمة إلى نهاية قائمة النتائج.