دورة تطوير بايثون المتقدمة
الفصل
>
المستوى
وحدات التسلسل
وحدة Struct
الهدف
إعداد التحليل النهائي للبيانات للأراضي الزراعية الجديدة باستخدام وحدة struct.
في نهاية الطريق توجد محطة خدمة تدير الأراضي الزراعية الجديدة التي تم بناؤها والمحاصيل المزروعة مسبقًا. هنا سنقوم بفحص ومعالجة بيانات المحاصيل المزروعة مسبقًا والإنتاج المتوقع للأراضي الزراعية. كما هو الحال مع المستويات الأخرى في هذا الفصل، سنعمل على تسلسل البيانات وإلغاء تسلسلها، مقدّمين وحدة أخيرة تُسمى struct.
تقدم وحدة struct سلسلة من دوال التسلسل التي تعبئ البيانات بتنسيق ثنائي، وعلى عكس الوحدات الأخرى التي عملنا بها، فإن لديك تحكمًا أكبر في كيفية هيكلة البيانات أثناء تسلسلها وعند إلغاء تسلسلها لاحقًا، مما يجعلها أكثر مرونة من الوحدات الأخرى. استخدم import struct للوصول إلى الدوال التالية التي سنستخدمها لمعالجة البيانات:
-
struct.calcsize(): يحدد عدد البايتات التي تعبئها سلسلة تنسيق معينة، يأخذ وسيطًا واحدًا وهو التنسيق الذي تريد التحقق من حجمه بالبايت. التنسيقات التي سنستخدمها هي:- integer: ممثل بـ
'i'وهو تنسيق للبيانات الممثلة بأعداد صحيحة. - float: ممثل بـ
'f'وهو تنسيق للبيانات الممثلة بأعداد عشرية. - double: ممثل بـ
'd'وهو تنسيق للأعداد العشرية الأكثر دقة حيث لا يكفي تنسيق float.
- integer: ممثل بـ
-
struct.pack(): ينسق البيانات في صورة ثنائية، حيث يمكنك اختيار التنسيق الذي تريد إنشاءه. يمكنه أخذ وسيطين أو أكثر، أولهما التنسيق الذي تريد استخدامه، والآخر القيم التي تريد تسلسلها. يجب إضافة التنسيقات المتوافقة مع عدد الوسائط التي تضيفها. -
struct.unpack(): يفك تسلسل البيانات الثنائية المعبّأة، يأخذ وسيطين، التنسيق الذي يجب أن تكون مشابهًا للتنسيق الذي تم تسلسل البيانات به، والبيانات التي تم تسلسلها. -
struct.iter_unpack(): يفك تسلسل البيانات الثنائية المعبّأة، يعمل بنفس طريقةstruct.unpack()ولكن يكرر عبر كل كتلة بيانات على حدة باستخدام حلقة. -
struct.pack_into(): إصدار متقدم منstruct.pack()، يأخذ أربعة وسائط: التنسيق الذي تريد استخدامه، المخزن المؤقت (buffer) الذي تريد وضع البيانات فيه، الموضع داخل المخزن المؤقت الذي تريد أن تحتله البيانات، وأخيرًا البيانات التي تعبئها. -
struct.unpack_from(): إصدار متقدم منstruct.unpack()، يأخذ ثلاث وسائط: التنسيق الذي تريد استخدامه، المخزن المؤقت الذي تريد فك التسلسل منه، وأخيرًا الموقع في المخزن المؤقت الذي تريد فك التسلسل منه. يتيح لك ذلك فك تسلسل أجزاء محددة من البيانات.
اذهب إلى علامة X المضيئة في محطة الخدمة وواجه المكتب، وأنشئ ثلاث متغيرات تسمى: integer وfloat وdouble. سنستخدمها للتحقق من الحجم بالبايت لكل تنسيق باستخدام الدالة struct.calcsize(). استخدم في متغير integer الدالة مع 'i' كوسيط، في متغير float استخدم الدالة مع 'f' كوسيط، وأخيرًا في متغير double استخدم الدالة مع 'd' كوسيط. على سبيل المثال: integer = struct.calcsize('i'). أضف المتغيرات الثلاثة إلى الدالة الجاهزة write().
اذهب إلى علامة X الذهبية واستخدم الدالة read() لجمع بيانات الأراضي الزراعية الجديدة، ودوّن نقاط البيانات والتنسيق للاستخدام المستقبلي، وهي: الموارد، الحجم والتقدير. بمجرد تدوين هذه المعلومات، اذهب إلى علامة X المضيئة فوق السجادة الزرقاء وأنشئ متغيرًا باسم blue_data.
في المتغير blue_data خزن قيمة الدالة struct.pack() مع تحديد التنسيق والقيم التي دونتها سابقًا كوسائط. عند كتابة التنسيق، يجب "تعبئة" أنواع التنسيقات في وحدة واحدة متكاملة. على سبيل المثال، يرمز للتنسيق الصحيح بـ 'i' كما ذُكر، إذا كنت تضيف ثلاثة بيانات عددية صحيحة، فستكتب 'iii'. وبالمثل، إذا كنت تضيف عددًا صحيحًا وعددًا عشريًا وعددًا عشريًا أكثر دقة، فستكتب 'ifd'. عند إضافة البيانات، ضعها كوسائط فردية. فيما يلي مثال عام:
data_1 = 8 # is an integer data_2 = 2.25 # is a float data_3 = 900.702938103 # is a double blue_data = struct.pack('ifd', data_1, data_2, data_3)
تتيح الدالة struct.pack() الكثير من المرونة، مما يسمح لك بتحديد الطريقة التي تريد بها تنسيق البيانات وتسلسل نقاط بيانات متعددة مرة واحدة، وفقًا لتقديرك. أضف البيانات التي قرأتها مسبقًا باستخدام المثال أعلاه كنموذج. استخدم الدالة display() مع blue_data كوسيط لمشاهدة البيانات المعبّأة.
اذهب إلى علامة X المظلمة فوق السجادة الزرقاء وواجه المحطة، وأنشئ متغيرًا باسم blue_unpack وخزّن فيه قيمة الدالة struct.unpack() مع إضافة نفس التنسيق المستخدم لتعبئة البيانات والمتغير blue_data كوسائط. يكتب التنسيق بنفس الطريقة كما في struct.pack()، حتى تتمكن من فك تسلسل البيانات بنفس الطريقة التي قمت بتسلسلها بها في البداية. استخدم الدالة write() مع blue_unpack كوسيط للتحقق من البيانات التي سطرتها سابقًا.
في نفس الموقع، سنستخدم أيضًا دالة struct.iter_unpack()، تأخذ نفس الوسائط التي تأخذها struct.unpack()، ولكن الآن تكون في حلقة for، مما يتيح لنا تكرار البيانات بدلًا من كتابتها دفعة واحدة. يتم ترميز الدالة على النحو التالي:
for values in struct.iter_unpack(-insert value-, -insert value-): player.speak(values)
سنستخدم دالة speak() لعرض القيم، للوسائط المفقودة في دالة struct.iter_unpack()، أضف نفس الوسائط التي استخدمتها سابقًا مع struct.unpack() لأنها مجرد متغيرات لنفس الدالة من حيث الاستخدام.
اذهب إلى علامة X الذهبية فوق السجادة الحمراء وواجه المكتب، واستخدم الدالة read() لمراجعة كميات المحاصيل. دوّن جميع الكميات وتنسيق كل محصول. اذهب إلى علامة X المضيئة فوق السجادة الحمراء وأنشئ كائنًا باسم buffer، وأضف القيمة bytearray(16). هذا عبارة عن مجموعة من البايتات التي يمكننا معالجتها قبل تعبئتها، ولأغراضنا تعمل كخزان بيانات حيث يمكنك تخزين البيانات يدويًا. الرقم 16 كوسيط هو طول البايتات التي يمكنك تخزينها في كائن buffer.
استخدم دالة struct.pack_into() لملء كائن buffer الذي أنشأته. لا تحتاج إلى إنشاء متغير لتخزين قيمة الدالة حيث إن الدالة نفسها ستدرج القيم مباشرة في كائن buffer. سنستخدم الدالة لكل قيمة من القيم التي دونتها مسبقًا ونملأ وسائطها بها.
على سبيل المثال، للقيمة الأولى للمحصول المقدمة، ستُقدم تنسيقها، وموقع بايتاتها، وكميتها. أضف التنسيق كوسيط أول، والموقع الذي تريد تسلسل البايتات إليه وهو في هذه الحالة buffer. كوسيط ثالث حدد الموضع الذي تريد إضافة القيمة داخله في buffer، يحدد التنسيق عدد البايتات المستخدمة فتأكد من تعبئة البيانات في أماكن غير مشغولة مسبقًا. وأخيرًا أضف القيمة التي تريد تسلسلها وتعبئتها في كائن buffer.
struct.pack_into('i', buffer, 0, 82)
يحتوي كائن buffer على 16 بايت كما ذُكر سابقًا، في الكود الموضح أعلاه، تنسيق integer يتطلب 4 بايتات ويُدرج في الموضع 0. هذا يعني أنه بمجرد إدراج البيانات في buffer، يتبقى داخل buffer 12 بايت غير مستخدمة، حيث تكون المواضع من 0-3 مشغولة بالقيمة المقدمة، في هذه الحالة 82. قم بهذا الإجراء لجميع نقاط بيانات المحاصيل الثلاث (3) التي قرأتها ودونتها مسبقًا. استخدم الدالة display() وأضف buffer لعرض البيانات المعبّأة.
اذهب إلى علامة X المظلمة فوق السجادة الحمراء وواجه المحطة، هنا سنقوم بإلغاء تسلسل البيانات للتحقق من محتواها وضمان التخزين الصحيح. أنشئ ثلاث متغيرات باسم: lettuce، carrots وmelons، سنفك تسلسل بيانات كل نقطة بيانات على حدة. لكل متغير، خزّن قيمة struct.unpack_from() واضبط الوسائط باستخدام نفس البيانات التي دونتها لتعبئة البيانات. للوسيط الأول ضع التنسيق، والثاني أضف كائن buffer وهو الموقع الذي تريد فك التسلسل منه، وأخيرًا أضف الموضع في buffer الذي تريد فك التسلسل منه. على سبيل المثال:
lettuce = struct.unpack_from('i', buffer, 0)
تتوافق هذه البيانات مع مثال التعبئة السابق الذي يتم فك تسلسله، قم بنفس الإجراء للمتغيرين الآخرين وأدخل lettuce وcarrots وmelons في الدالة الجاهزة write() لإتمام المستوى.