المحتوى عن 'loop'.



مزيد من الخيارات

  • ابحث بالكلمات المفتاحية

    أضف وسومًا وافصل بينها بفواصل ","
  • ابحث باسم الكاتب

نوع المُحتوى


التصنيفات

  • التخطيط وسير العمل
  • التمويل
  • فريق العمل
  • دراسة حالات
  • نصائح وإرشادات
  • التعامل مع العملاء
  • التعهيد الخارجي
  • التجارة الإلكترونية
  • الإدارة والقيادة
  • مقالات ريادة أعمال عامة

التصنيفات

  • PHP
    • Laravel
    • ووردبريس
  • جافاسكريبت
    • Node.js
    • jQuery
    • AngularJS
    • Cordova
  • HTML
    • HTML5
  • CSS
  • SQL
  • سي شارب #C
    • منصة Xamarin
  • بايثون
    • Flask
    • Django
  • لغة روبي
    • Sass
    • إطار عمل Bootstrap
    • إطار العمل Ruby on Rails
  • لغة Go
  • لغة جافا
  • لغة Kotlin
  • برمجة أندرويد
  • لغة Swift
  • لغة R
  • لغة TypeScript
  • سير العمل
    • Git
  • صناعة الألعاب
    • Unity3D
  • مقالات برمجة عامة

التصنيفات

  • تجربة المستخدم
  • الرسوميات
    • إنكسكيب
    • أدوبي إليستريتور
    • كوريل درو
  • التصميم الجرافيكي
    • أدوبي فوتوشوب
    • أدوبي إن ديزاين
    • جيمب
  • التصميم ثلاثي الأبعاد
    • 3Ds Max
    • Blender
  • نصائح وإرشادات
  • مقالات تصميم عامة

التصنيفات

  • خواديم
    • الويب HTTP
    • قواعد البيانات
    • البريد الإلكتروني
    • DNS
    • Samba
  • الحوسبة السّحابية
    • Docker
  • إدارة الإعدادات والنّشر
    • Chef
    • Puppet
    • Ansible
  • لينكس
  • FreeBSD
  • حماية
    • الجدران النارية
    • VPN
    • SSH
  • مقالات DevOps عامة

التصنيفات

  • التسويق بالأداء
    • أدوات تحليل الزوار
  • تهيئة محركات البحث SEO
  • الشبكات الاجتماعية
  • التسويق بالبريد الالكتروني
  • التسويق الضمني
  • التسويق بالرسائل النصية القصيرة
  • استسراع النمو
  • المبيعات
  • تجارب ونصائح

التصنيفات

  • إدارة مالية
  • الإنتاجية
  • تجارب
  • مشاريع جانبية
  • التعامل مع العملاء
  • الحفاظ على الصحة
  • التسويق الذاتي
  • مقالات عمل حر عامة

التصنيفات

  • الإنتاجية وسير العمل
    • مايكروسوفت أوفيس
    • ليبر أوفيس
    • جوجل درايف
    • شيربوينت
    • Evernote
    • Trello
  • تطبيقات الويب
    • ووردبريس
    • ماجنتو
  • أندرويد
  • iOS
  • macOS
  • ويندوز

التصنيفات

  • شهادات سيسكو
    • CCNA
  • شهادات مايكروسوفت
  • شهادات Amazon Web Services
  • شهادات ريدهات
    • RHCSA
  • شهادات CompTIA
  • مقالات عامة

أسئلة وأجوبة

  • الأقسام
    • أسئلة ريادة الأعمال
    • أسئلة العمل الحر
    • أسئلة التسويق والمبيعات
    • أسئلة البرمجة
    • أسئلة التصميم
    • أسئلة DevOps
    • أسئلة البرامج والتطبيقات
    • أسئلة الشهادات المتخصصة

التصنيفات

  • ريادة الأعمال
  • العمل الحر
  • التسويق والمبيعات
  • البرمجة
  • التصميم
  • DevOps

تمّ العثور على 5 نتائج

  1. القدرة على تعديل حلقة التكرار الخاصة بالووردبريس تمنحك الكثير من التحكم بتصميم ومحتوى موقعك المبني على ووردبريس. دائمًا ما أقوم بإنشاء حلقات تكرار خاصة، أحيانًا عن طريق تعديل حلقة التكرار القياسية وأحيانًا أخرى باستخدام WP_Query لإنشاء حلقات تكرار جديدة بالكامل. ولكن أحيانًا في بعض الحالات أرغب بأخذ الأمور إلى المستوى التالي. أريد أن أقوم بعرض المقال الأول في حلقتي بطريقة مختلفة عن المقالات التي تليه. يمكنني القيّام بهذا لأنني قد أريد إضافة تنسيقات خاصة أو ربما لأنّني أريد عرض محتوًى مختلفًا. مثلًا قد أريد أن أعرض محتوى المقال الأول وفقط المقتطفات بالنسبة للمقالات التي تليه، أو ربما أريد عرض الصورة البارزة للمقال الأول بحجم مختلف عن بقية المقالات، أو مثلًا أريد أن أطبّق كلاسات CSS مختلفة على أوّل مقالٍ. القيام بهذا الأمر سيمكّنك من تسليط الضوء على أحدث مقالاتك، جلب انتباه زوّار موقعك لقراءتها وتشجيعهم للنقر عليها. كما يمكّنك هذا الأمر من تحسين نسق موقعك، عن طريق إنشاء تصميمٍ أكثر تنويعًا. خلال هذا الدرس سأقوم بتعليمك كيف تستخدم كلاس WP_Query للقيام بذلك. سأريك كيف تقوم بعمل استعلامٍ خاص لكل مقالاتك باستخدام WP_Query ثم بعد ذلك سأريك كيف تقوم بإنشاء استعلام خاص ثانٍ يتم تطبيقه فقط على مقالك الأوّل. خلال المثال الذي سنعمل عليه سأريك أولًا كيف يمكنك القيام بهذا الأمر على نموذج صفحة خاصة باستخدام WP_Query لجعل استعلامين مختلفين يعملان معًا. ثم بعد ذلك سأريك كيف تطبّق هذه التقنيّة على حلقة التكرار القياسية. أخيرًا سأريك كيف تقوم بتعديل نموذج صفحة الأرشيف القياسية واستخدام دالّة pre_get_posts لتغيير حلقة التكرار القياسية. ما الذي ستحتاجه: لكي تتمكن من المتابعة طيلة هذا المقال ستكون بحاجة إلى: سكريبت ووردبريس مخصص للتطوير (إيّاك ان تقوم بالتجريب على موقعك مباشرة ما لم تتأكد من أن الكود الذي قمت بكتابته يعمل بشكل جيد). محرر أكواد. لنبدأ: إنشاء الاستعلام موقعي الشخصي يحتوي على نموذج خاص من أجل صفحة “كتب”. هذه الصفحة تقوم بعرض المحتوى الذي قمت بإضافته إلى صفحة “كتب” ثم تقوم بتشغيل حلقة التكرار لإخراج جميع كتبي. كل هذا يتم عن طريق استخدام "إضافة مقال خاص". حلقة التكرار الخاصة بك قد تكون مختلفة جدًّا فأنت ربما قد ترغب بتطبيق التالي على مقالات عادية، أو على نموذج صفحة أرشيف، أو حتّى على مقالات مخصصة أو أي شيء قد تريد العمل عليه. إذًا أنت لست مجبرًا على العمل فقط على نموذج صفحة لاستخدام هذه التقنية. يجب عليك فقط التركيز على الطريقة التي تعمل بها حلقة التكرار ثم بعد ذلك يمكنك تطبيق هذه التقنية على موقعك. هذه صورة من صفحتي بحلقة تكرار واحدة تقوم بعرض كل كتبي في شبكة 2*2 لقد استخدمت بعضًا من البرمجة الكائنية CSS الموجودة بقالبي لإنشاء شبكة 2*2 لعرض جميع كتبي. داخل الحلقة يوجد : العنوان، المقتطفات والصورة البارزة. إليكم الكود الذي استخدمه <?php $args = array( 'post_type' => 'rmcc_blurb', ); $query = new WP_query ( $args ); if ( $query->have_posts() ) { ?> <section class="books list full-width"> <?php while ( $query->have_posts() ) : $query->the_post(); ?> <article id="post-<?php the_ID(); ?>" <?php post_class( array( 'book', 'left', 'half' ) ); ?>> <h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3> <?php if ( has_post_thumbnail() ) { ?> <a href="<?php the_permalink(); ?>"> <?php the_post_thumbnail( 'medium', array( 'class' => 'left', 'alt' => get_the_title() ) ); ?> </a> <?php }?> <?php the_excerpt(); ?> <div class="button"><a href="<?php the_permalink(); ?>">Explore the Book</a></div> </article> <?php endwhile; ?> <?php wp_reset_postdata(); ?> </section> <?php } ?> يمكنك ملاحظة حلقة التكرار خاصتي تحتوي على معامل واحد ألا وهو نوع المقال post type. إذًا فإن ما ستعرضه هذه الحلقة هو فقط المقالات من النوع المدخل. كما سيتم عرض المقالات حسب الأحدث. لكن ما نريد القيام به هو عرض المقال الأول بطريقة مختلفة، للقيام بذلك يلزمنا: القيام بإنشاء حلقة تكرار خاصة بأول مقال لعرض أوّل مقال بطريقة مختلفة سنحتاج لإنشاء حلقة تكرار منفردة تقوم بعرض ذلك المقال فقط. للقيام بذلك سنحتاج الى معاملين، واحد لنوع المقال والاخر لعدد المقالات الذي سيكون posts_per_page حيث سيتم جعل قيمته 1. ابدأ بعمل نسخة ثانية من حلقة التكرار لديك بحيث يكون لديك حلقتا تكرار داخل ملف نموذجك، كلا الحلقتين تستخدمان WP_Query. الان عدّل المعاملات للحلقة الأولى بحيث يصبح الكود لديك كما يلي: $args = array( 'post_type' => 'rmcc_blurb', 'posts_per_page' => 1 ); هذه الحلقة ستقوم بعرض فقط أحدث مقال، لا يوجد داعٍ للقيام بهذا إن لم تكن تريد تغيير شيء في طريقة عرض أول مقال. في حالتي هذه أريد عرض المقتطفات والمحتوى. كما أريد أيضًا إضافة بعض التنسيقات للنسق كي أجعل الصورة البارزة والمقتطفات يظهران المحتوى. إليكم النسخة الجديدة من الكود للحلقة التي ستعرض المقال الأول فقط: <article id="post-<?php the_ID(); ?>" <?php post_class( 'book' ); ?>> <div class="left one-third"> <?php if ( has_post_thumbnail() ) { ?> <a href="<?php the_permalink(); ?>"> <?php the_post_thumbnail( 'medium', array( 'class' => 'left', 'alt' => get_the_title() ) ); ?> </a> <?php }?> </div> <div class="right two-thirds book-excerpt"> <h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3> <?php the_excerpt(); ?> </div> <div class="clear"> <?php the_content(); ?> </div> </article> ستلاحظ أن هناك كودًا إضافيًّا للمحتوى، وأنّني قد أضفت أيضًا عنصر div لتنسيق النسق، طبعًا أذكّرك أنّني استخدم ملف التنسيق الموجود مسبقًا في قالبي. إليك كيف يظهر أول مقال في صفحتي الآن: كل شيء يبدو جيدًّا. لابدّ أنّك قد انتبهت أنّني قد قمت بنزع الزر الذي يأخذك لصفحة قراءة الكتاب، السبب في ذلك يعود إلى كون محتوى المقال ظاهر الآن ولكنّني قمت بتعويض ذلك إلى زر لشراء الكتاب الذي أخذناه من محتوى المقال. تعديل حلقة التكرار للمقالات اللاحقة: لكن هناك مشكلة. إليك صورة من أول مقال والمقالات التّي تليه: حاليًا أوّل مقال يتم تكراره مرّتين، يتم عرضه في الحلقة التي كانت موجودة في البداية كما يتم عرضه في الحلقة الجديدة التي قمنا بإنشائها. لإصلاح هذا المشكل سيتوجّب عليّ إضافة معامل جديد offset لحلقة التكرار الثانية. هذا المعامل يطلب من ووردبريس تجاهل عدد محدد من المواضيع لعدم عرضها. في حالتي هذه قمت بعرض أوّل مقال بطريقة مختلفة في حلقة التكرار الأولى، لذا سأقوم بتجاهل أول مقال في الحلقة الثانية. ملاحظة: عند استخدامك لهذه التقنية يجب أن تتساوى القيمة المحددة لمعامل posts_per_page في أوّل حلقة مع القيمة المحدّدة لمعامل offset في الحلقة الثانية. في الحلقة التكرارية الثانية سأقوم بتعديل الكود ليصبح بالشكل التالي: $args = array( 'post_type' => 'rmcc_blurb', 'offset' => 1 ); الآن عندما أقوم بتحديث الصفحة ستجد أنّ أوّل مقالٍ لم يعد يعرض مرّتين. ذلك جيّد! الآن وقد أكملت هذا الجزء، أكون قد أنشأت صفحة خاصة تحتوي على حلقتي تكرار إحداهما تقوم بعرض محتوى إضافي لأول مقال. تطبيق هذه التقنية على حلقة التكرار القياسية لكن ماذا لو كانت صفحتك تعمل باستخدام حلقة تكرار قياسية؟ إن كانت هذه هي حالتك، يمكنك تعديل ملف النموذج الذي تعمل عليه تلك الصفحة فقط بإضافة استعلام إضافي باستخدام WP_Query. لن تكون بحاجة لكتابة استعلامين جديدين. هناك خطوتان لهذه التقنية: إضافة استعلام إضافي لملف نموذجك باستخدام WP_Query. في ملف الدوال الخاص بقالبك (functions.php) استخدم pre_get_posts لتعديل حلقة التكرار القياسية لهذا النوع من الملفات لكي تقوم بتجاوز المقال الأول. إضافة الاستعلام الإضافي بداية قم بفتح ملف النموذج الذي ترغب بتعديله. يمكنه أن يكون أي نموذج أرشيف تريده. في حالتنا هذه إن كنت أستخدم النموذج القياسي لعرض المقالات المخصصة من نوع كتب، فإن الملف سيكون اسمه archive-rmcc_book.php. قبل حلقة التكرار الرئيسية أضف الحلقة الإضافية باستخدام WP_Query. ستقوم بهذا بطريقة مشابهة لما قمنا به سابقا عن طريق نسخ وتعديل محتوى الحلقة الرئيسية، ولكن بوضعها داخل استعلام منشئ بواسطة WP_Query. لا تنسى أنه سيتوجب عليك إضافة معامل post_type مع إعطائه قيمة نوع المقالات التي تريدها، حتى ولو كنت تستخدم نموذج لعرض هذا النوع من المقالات فقط. قم بحفظ ملفك وستلاحظ أنّ المقال الأول سيعرض مكرّرًا مثلما حدث معنا في المثال الذي عملنا عليه. تجاوز المقال الأول في الاستعلام الرئيسي: لا يمكنك التعديل مباشرة على معاملات الإستعلام الرئيسي في ملف الأرشيف. عوضًا عن ذلك سيتوجب عليك استخدام معلق “hook ” للقيام بهذا التعديل. افتح ملف functions.php (في حالة كان قالبك لا يحتوي على ذلك الملف فقم بإنشائه) ثم أضف الكود التالي: <?php $args = array( 'post_type' => 'rmcc_blurb', 'posts_per_page' => 1 ); $query = new WP_query ( $args ); if ( $query->have_posts() ) { ?> <section class="books first wide-box"> <?php while ( $query->have_posts() ) : $query->the_post(); ?> <article id="post-<?php the_ID(); ?>" <?php post_class( 'book' ); ?>> <div class="left one-third"> <?php if ( has_post_thumbnail() ) { ?> <a href="<?php the_permalink(); ?>"> <?php the_post_thumbnail( 'medium', array( 'class' => 'left', 'alt' => get_the_title() ) ); ?> </a> <?php }?> </div> <div class="right two-thirds book-excerpt"> <h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3> <?php the_excerpt(); ?> </div> <div class="clear"> <?php the_content(); ?> </div> </article> <?php endwhile; ?> <?php wp_reset_postdata(); ?> </section> <?php } ? ستلاحظ أن هناك ثلاثة وسوم شروط مستخدمة. واحد للتحقق أننا لسنا في شاشة المدير، الآخر للتحقق أن الاستعلام الرئيسي يعمل، أمّا الأخير فللتحقّق أنّنا في صفحة الأرشيف الخاصة بالمقالات المخصصة التي نريد التعديل عليها. وسمِّ الشرط الذي ستحتاجه من أجل مقالاتك الخاصة (أو تصنيفات أو أي شيء تريد العمل عليه) يمكنك أن تجده في دليل الووردبريس للمطوّرين WordPress Codex. قم بحفظ ملف الدّوال خاصتك وستلاحظ أنّ مقالتك الأولى تعرض باستخدام حلقة التكرار التي أضفتها أما باقي المقالات اللاحقة فتعرض باستخدام حلقة التكرار الرئيسية. WP_Query تسمح لك بلفت الانتباه الى أحدث مقالاتك باستخدام هذه التقنية، يمكنك استعمال كلاس WP_Query لعرض محتوًى إضافي لأحدث مقالاتك، أو تنسيقها بطريقة مختلفة. كما رأيت في مثالنا الذي عملنا عليه، لقد استخدمنا هذه التقنية لجعل كتابي الأخير يظهر بطريقة بارزة مقارنة بباقي الكتب. يمكنك تطبيق هذه التقنية على حلقة تكرار خاصة قمت بإنشائها باستخدام كلاس WP_Query على حلقة تكرار قياسية في ملفات نماذج قالبك (مهما كان القالب الذي تستخدمه). بمجرد القيّام بهذا فإنّ آخر مقال لك سيكون ظاهرًا ويلفت انتباه قرّائك لقراءته. ترجمة -وبتصرّف- للمقال How to Use the WordPress Loop to Style Your First Post Differently لصاحبه Rachel McCollin
  2. من الأمور التي تجعلني أفضّل استخدام صور GIF دائمة الحركة هو أنها طريقة بسيطة نسبيًا لاستعراض المهارات في التصميم والرسوم الإيضاحية. بالإضافة إلى أنها لا تتطلب وقتا طويلا في الإنتاج، العمل عليها ممتع، علاوة على أنها تختصر كثيرًا من عمليّة التحريك، وهو أمر ذو بال. زاد اهتمامي كثيرا، بوصفي متخصّصًا في الرسوم التوضيحية ومخرج رسوم متحركة، بإنشاء صور GIF دائمة الحركة، لكل من الاستخداميْن الشخصي والمهني خلال السنوات القليلة الماضية. وبما أنني أُسأل كثيرا عن عملي، فسأشارككم بما تعلمته عن صنع صور GIF دائم الحركة “الناجحة”. ابدأ بالقصة بالنسبة لي إنها الخطوة الأكثر تحديا. أحاول أن آتي بفكرة مضحكة وجذابة لكن سهلة الفهم. وبالطبع يجب أن تعمل في صورة GIF دائمة الحركة. دعوني أحدثكم عن مثال، ألا وهو مشروعي لصور GIF بعنوان Game Of Thrones. حيث صنعت صورة GIF لكل حلقة من الموسم السادس لمسلسل صراع العروش، وكان التحدي أخذ المشاهد – التي غالبا ما تكون عنيفة – وتحويلها إلى صور GIF جذابة تعمل كنسخة ملخصة من الحلقة. ستجد أدناه ثلاثة صور متحرّكة تمثل مشاهد قاسية. تخفّف هذه الرسومات الملونة الظريفة من هول المشاهد الأصلية التي يمكن نعتها بكلّ وصف إلا الطرافة. تجمع صورة GIF أدناه، والتي تدوم 15 ثانية، 3 إلى 4 حلقات صغيرة تخلق قصة ذات معنى. مدة الرسوم المتحركة “الصافية” تتراوح بين 5 و6 ثوان؛ لذا فإن سرد قصة ما عبر الحلقات يوفر عليّ بعض العمل. أبقها بسيطة يمنحك استخدام تصميم تقليلي Minimalist المزيد من الحرية في مرحلة التحريك. يمكنني القول من واقع خبرتي إنه كلما كان التصميم أبسط وأوضح كان التحريك أسهل، فالتصميم المعقد يحوي العديد من التفاصيل والظلال وغيرها وبالتالي يتوجب عليك أن تنتبه لها في كل إطار. لذا أبق الأمور بسيطة. أحب استخدام الأشكال الهندسية البسيطة وصيغ الألوان الباهتة. كما أتجنب التفاصيل غير الضرورية كأصابع اليديْن والقدميْن، وأستخدم تصاميم بسيطة لليدين والرجلين - فمن الأسهل أن ترسم ببساطة عوضا عن رسم ذراع مفصلة مع الظلال وسماكات مختلفة ودقة تشريحية. يسمح لك تصميم الأطراف بأشكال بسيطة بمدها وعصرها واللعب بها وكأنها معكرونة دون التأثير على سماكتها الأصلية. يمكنني أن أتلاعب ضمن هذه القيود بالتصاميم مع المبالغة ببعض الميزات لإضفاء الفكاهة والأسلوب المميز والاهتمام البصري: جسد ضخم بوجه صغير، ذراعان ثخينتان جدا أو ذراعان نحيلتان وطويلتان جدًّا وغير ذلك. كما أنني أجد رسم وتحريك الشخصيات البسيطة أكثر جمالا وتعبيرا. لأشرح ما أعنيه، إليك صورة للموهوب سيمون بايلز. تمعن بها وستجد أن الشخصية صممت بالعناصر الأساسية فقط: أشكال بسيطة للأطراف، شكل أثخن للجسم ودائرتان كاملتان للأطراف والشعر. هذا كل شيء. بإمكاني التلاعب في التصميم بسهولة أكبر بكثير مما لو رُسِم بطريقة واقعية أكثر تفصيلا. سيكون من الصعب تنفيذه كل تلك التقلبات المجنونة لو لم يكن التصميم سهلا. يجب أن تكون الحلقات كاملة بما أن صور GIF دائمة الحركة تعرض تلقائيًّا مرارا وتكرارا، فإنها يجب أن تكون كاملة – وإلا سيسهل اكتشاف العيوب، ناهيك عن تشتيت الانتباه. لذا أَوْلِ التفاصيل الكثير من الاهتمام. اهتم كثيرا بكل إطار من رسمتك المتحركة لتضمن ظهور الحلقات باستمرار. أطمح إلى تصميم رسوم متحركة سلسة، وأحيانا أستخدم الرسوم المتحركة الكلاسيكية لإجراء تعديلات بسيطة كرفرفة الشعر وحركة الأطراف (يكون التصميم البسيط بمتناول اليد هنا أيضا). وبما أن صور GIF دائمة الحركة تكون قصيرة في أغلب الحالات فهي تستحق العناء. أول شيء أفعله لجعل الرسوم المتحركة هو إنشاء الإطارين الأول والأخير حتى يُوَّحدا بسلاسة. ومن ثم أنتقل إلى إنشاء جسم الرسم المتحرك. حاول إضافة عناصر ممتعة لتفاجئ بها المشاهدين عند مشاهدة صور دائمة الحركة. إليك أفكارا قد تساعدك للاستلهام منها: استخدم التأثيرات الصغيرة. على سبيل المثال، أضف نجوما إلى العناصر اللامعة واندفاعات لحركة الأطراف السريعة جدا وغيوما صغيرة من الغبار عند ارتطام شيء ثقيل بالأرض. ضخّم الحركة. على سبيل المثال، افصل الرأس عن الجسد عندما تُلكم الشخصية. اختر لوحة الألوان الخاصة بك بحكمة، فصور GIF محدودة ب 256 لونا، لذا فإن البكسلات تظهر إن لم تكن التدرجات متناسقة. ترجمة - بتصرّف - للمقال Creating seamless looping GIFs لصاحبه Eran Mendel. حقوق الصورة البارزة محفوظة لـ Vecteezy
  3. بعد أن تعلمنا التعامل مع المعاملات الموضعية (Positional parameters) في الدرس السابق، حان الوقت الآن لشرح آخر بُنية من بُنى التحكم: for. وكما في البنيتين while و until، تُستعمَل for لإنشاء حلقات تكرار. الشكل العام لحلقة for: for variable in words; do commands done الخلاصة هي أنَّ for تُسنِد كلمةً من قائمة الكلمات إلى متغيّرٍ معيّن، ثم تُنفِّذ الأوامر الموجودة داخل الحلقة، ثم تكرر ذلك إلى أن تُستعمَل جميع الكلمات الموجودة في القائمة. هذا مثالٌ عنها: #!/bin/bash for i in word1 word2 word3; do echo $i done أُسنِدَت -في بادئ الأمر- القيمة word1 إلى المتغير i، ثم نُفِّذ الأمر echo $i، ثم أُسنِدَت القيمة word2 إلى المتغير i، ثم نُفِّذ الأمر echo $i، وهكذا، إلى أن تُسنَد جميع الكلمات إلى المتغير i. الشيء المثير للاهتمام في for هو تنوع الطرائق التي تستطيع فيها بناء قائمة الكلمات، حيث يمكن استخدام جميع أنواع التوسعات (expansions). سنولِّد قائمة الكلمات في المثال الآتي باستخدام تعويض الأوامر (command substitution): #!/bin/bash count=0 for i in $(cat ~/.bash_profile); do count=$((count + 1)) echo "Word $count ($i) contains $(echo -n $i | wc -c) characters" done قمنا في المثال السابق بإحصاء عدد الكلمات في ملف ‎.bash_profile، ثم أظهرنا عدد الحروف في كل كلمة. حسنًا، ما علاقة ذلك بالمعاملات الموضعية؟ حسنًا، يمكن استخدام المعاملات الموضعية كقائمة بالكلمات التي ستمرّ عليها الحلقة for: #!/bin/bash for i in "$@"; do echo $i done المتغير "@" هو متغيرٌ خاصٌ بالصَدَفة ويحتوي على قائمة بوسائط سطر الأوامر. تُستعمَل هذه التقنية عادةً لمعالجة قائمة ملفات عبر سطر الأوامر. هذا مثالٌ آخر: #!/bin/bash for filename in "$@"; do result= if [ -f "$filename" ]; then result="$filename is a regular file" else if [ -d "$filename" ]; then result="$filename is a directory" fi fi if [ -w "$filename" ]; then result="$result and it is writable" else result="$result and it is not writable" fi echo "$result" done جرِّب السكربت السابق، ومرِّر إليه قائمةً بعدِّة ملفات، أو استعمل محرفًا بديلًا مثل * وانظر إلى مخرجاته. هذا سكربتٌ آخر يُقارِن الملفات الموجودة في مجلدين، ويظهِر قائمة بالملفات الموجودة في المجلد الأول وغير الموجودة في المجلد الثاني: #!/bin/bash # cmp_dir - program to compare two directories # Check for required arguments if [ $# -ne 2 ]; then echo "usage: $0 directory_1 directory_2" 1>&2 exit 1 fi # Make sure both arguments are directories if [ ! -d $1 ]; then echo "$1 is not a directory!" 1>&2 exit 1 fi if [ ! -d $2 ]; then echo "$2 is not a directory!" 1>&2 exit 1 fi # Process each file in directory_1, comparing it to directory_2 missing=0 for filename in $1/*; do fn=$(basename "$filename") if [ -f "$filename" ]; then if [ ! -f "$2/$fn" ]; then echo "$fn is missing from $2" missing=$((missing + 1)) fi fi done echo "$missing files missing" لنوظِّف ما سبق في مثالٌ عملي. لنحاول تحسين الدالة home_space في السكربت الذي نبنيه لكي تُخرِج المزيد من المعلومات. كانت النسخة القديمة من الدالة تبدو كما يلي: home_space() { # Only the superuser can get this information if [ "$(id -u)" = "0" ]; then echo "<h2>Home directory space by user</h2>" echo "<pre>" echo "Bytes Directory" du -s /home/* | sort -nr echo "</pre>" fi } # end of home_space هذه هي النسخة الحديثة منها: home_space() { echo "<h2>Home directory space by user</h2>" echo "<pre>" format="%8s%10s%10s %-s\n" printf "$format" "Dirs" "Files" "Blocks" "Directory" printf "$format" "----" "-----" "------" "---------" if [ $(id -u) = "0" ]; then dir_list="/home/*" else dir_list=$HOME fi for home_dir in $dir_list; do total_dirs=$(find $home_dir -type d | wc -l) total_files=$(find $home_dir -type f | wc -l) total_blocks=$(du -s $home_dir) printf "$format" $total_dirs $total_files $total_blocks done echo "</pre>" } # end of home_space تتضمن هذه النسخة المُحسَّنة أمرًا جديدًا هو printf، الذي يُستخدم لتنسيق المُخرجات بناءً على محتويات "عبارة التنسيق" (format string). تنحدر أصول الأمر printf من لغة البرمجة C وهو موجودٌ أيضًا في لغاتٍ برمجيةٍ أخرى مثل C++‎ و Perl و awk و java و PHP وبالطبع bash. هنالك أمرٌ آخر جديد هو الأمر find، الذي يُستخدم للبحث عن ملفات أو مجلدات تُطابِق معيارًا أو مقياسًا محدَّدًا (criteria). استخدمنا الأمر find في الدالة home_space لعرض قائمة بالمجلدات والملفات العادية الموجودة في مجلد المنزل، ثم أحصينا عدد الملفات والمجلدات باستخدام الأمر wc (تذكَّر أنَّه اختصار للعبارة "Word Count"). النقطة المثيرة للاهتمام في دالة home_space المُعدَّلة هي كيفية تعاملنا مع مشكلة عدم السماح بالوصول إلى مجلدات المنزل من المستخدمين العاديين، يمكنك ملاحظة أنَّنا اختبرنا إن كان المستخدم هو الجذر بوساطة id ثم -اعتمادًا على ناتج الاختبار- أسندنا سلاسل نصية مختلفة إلى المتغير dir_list، الذي سيُمثِّل قائمة الكلمات لحلقة for التي تليه. وبهذه الطريقة، إذا شغَّل مستخدمُ عاديٌ السكربت، فستُعرض معلومات عن مجلد المنزل الخاص به فقط. موضوعٌ آخر يمكننا توظيف حلقة for فيه هو الدالة system_info التي لم نكملها بعد. يمكننا كتابتها كالآتي: system_info() { # Find any release files in /etc if ls /etc/*release 1>/dev/null 2>&1; then echo "<h2>System release info</h2>" echo "<pre>" for i in /etc/*release; do # Since we can't be sure of the # length of the file, only # display the first line. head -n 1 $i done uname -orp echo "</pre>" fi } # end of system_info حدَّدنا في بادئ الأمر إن كانت هنالك ملفات release لكي نعالجها. تحتوي ملفات release على اسم التوزيعة وإصدارها. وهي موجودة في مجلد ‎/etc. ولكي نكتشف وجودها، سنستعمل الأمر ls لكننا لسنا مهتمين بمخرجات الأمر، وإنما بحالة الخروج، التي ستكون مساوية للصفر (true) إن وُجِدَت أيّة ملفات. الخطوة الآتية هي طباعة شيفرة HTML لهذا القسم من الصفحة؛ ولمّا كنا نعلم أنَّ هنالك عدِّة ملفات release لكي نعالجها، فسنستخدم حلقة for للمرور على كلٍ واحدٍ منها. ثم سنستعمل الأمر head في داخل الحلقة للحصول على السطر الأول من كل ملف. في النهاية، استعملنا الأمر uname مع الخيارات o و r و p للحصول على بعض المعلومات الإضافية حول النظام. ترجمة -وبتصرّف- للمقال Flow Control - Part 3 لصاحبه William Shotts.
  4. تعرّفنا في الدّرس السّابق على المجالات وكيفيّة استخدامها مع العبارات الشرطيّة. سنتعرّف في هذا الدّرس على أنواع الحلقات Loops المختلفة والتي يمكن استخدامها في روبي. تُستخدم الحواسيب عادةً لتنفيذ أوامر متكرّرة آليًّا. تكرار تنفيذ مهام متشابهة دون خطأ هي عمليّة من السّهل على الحواسيب فعلها على أتمّ وجه، على عكس الإنسان الذي غالبًا ما يفشل في ذلك. ولأن التكرار أحد الأمور الشّائعة في البرمجة فإن روبي توفّر عدّة طرق لتنفيذه تسمّى بالحلقات. تقوم الحلقات بتكرار تنفيذ بعض الشيفرة البرمجيّة بناءً على شروط أو حالات معيّنة. حلقة while أوّل نوع من الحلقات سنتعرّف عليه هو حلقة while. تقوم حلقة while بتكرار تنفيذ الشيفرة البرمجيّة الموجودة بداخلها متى صحّ شرط معيّن. لفهم الحلقة أكثر دعونا نأخذ مثالاً عليها. سنطبّق ما تعلّمناه في الدروس السّابقة ولتحسين برنامج لعبة إلقاء النّرد التي تعرّفنا عليها سابقًا. أنشئ ملفّ روبي وسمّه while.rb أو أيّ اسم تريد مع كتابة rb. في نهاية اسم الملف. واكتب الشيفرة البرمجيّة التالية به: number = 0 attempts = 0 while number < 6 number = rand(1..6) puts "You rolled #{number}" attempts += 1 end puts "It took you #{attempts} attempts to roll number 6" بدأنا أوّلاً بتعريف متغيّر باسم number ومتغيّر باسم attempts. وأعطينا المتغيّرين قيمة مبدئيّة صفر. سنستخدم المتغيّرين لاحقًا في حلقة while لذلك فنحتاج إلى تهيئتهما أوّلاً في بداية البرنامج قبل تنفيذ حلقة while. إن لم نفعل ذلك فسوف نحصل على رسالة خطأ Error إذا تم استخدامهما قبل حصولهما على قيمة. جرّب بنفسك حذف المتغيّرين وتنفيذ البرنامج وحاول تحليل رسالة الخطأ التي ستظهر إليك. بعد ذلك لدينا الحلقة تبدأ باستخدام كلمة while المفتاحيّة في السّطر الرّابع وتنتهي بـ end في السّطر الثّامن (تعرّفنا على end سابقًا عندما استخدمناها مع العبارات الشرطيّة). وبين while وend لدينا الشيفرة البرمجيّة التي نريد تكرار تنفيذها متى تحقّق شرط الحلقة الموجود بعد كلمة while. لدينا الشرط في هذه الحالة هو أن تكون قيمة المتغيّر number أقلّ من 6. أعتقد أنّك قد خمّنت كل هذا بمجرّد رؤيتك للبرنامج وقبل قراءة الشرح فمن السّهولة قراءة حلقة while كما لو كانت إنجليزيّة عاديّة. ببساطة نخبر روبي أنّ تنفّذ مجموعة الشيفرة البرمجيّة متى (while) كان المتغيّر number أقلّ من 6. الآن وحيث أنّ قيمة المتغيّر number هي صفر في البداية فستقوم الحلقة بتنفيذ الشيفرة البرمجيّة مرّة واحدة على الأقل لأنّها ستبدأ وقيمة number أقلّ من 6. الآن بالنّظر إلى الشيفرة البرمجيّة بداخل while والتي ستُنفّذ على الأقلّ مرّة واحدة نجد أنّها تبدأ بتعيين قيمة جديدة للمتغيّر number وهي قيمة عشوائيّة من الأرقام الصحيحة بين 1 و6. تقابل هذه الشيفرة عمليّة إلقائك للنّرد. بعد ذلك نستخدم أمر puts لطباعة نصّ على الشّاشة يخبر المستخدم أنّ ناتج إلقائه للنّرد هو الرقم النّاتج عن الاختيار العشوائي بين 1 و6. تقابل هذه عمليّة سقوط النّرد وظهور الرّقم النّاتج. في آخر سطر من هذه الحلقة سيتمّ زيادة قيمة المتغيّر attempts بواحد. تذكّر أنّ رمز =+ هذا يعني إضافة القيمة الموجودة على الجانب الأيمن إلى قيمة attempts الأصليّة وحفظ القيمة الجديدة في المتغيّر attempts. إذًا في حالتنا هذه تضيف روبي 1 إلى attempts في كلّ مرّة تُنفّذ الشيفرات. الآن إذا كان الرقم العشوائي النّاتج لا زال أقلّ من 6 فسيتمّ تنفيذ هذه الشيفرات الموجودة داخل حلقة while مجدّدًا، ممّا يعني تعيين رقم عشوائي جديد إلى المتغيّر number، طباعة هذه القيمة الجديدة ثمّ زيادة قيمة المتغيّر attempts بواحد. ثمّ التحقّق هل قيمة number الجديدة أقلّ من 6 وهكذا دواليك إلى أن تصبح قيمة المتغيّر number هي 6. حينها سيتمّ إيقاف الحلقة وطباعة الرسالة الموجودة في السطر 10 والتي تخبر المستخدم عدد المرّات التي ألقى فيها النّرد (والمتمثّلة في المتغيّر attempts) قبل أن يصل إلى الرّقم 6. جرّب تنفيذ هذا البرنامج بفتح الطرفيّة والوصول إلى المجلّد الذي يحتوي على الملفّ وكتابة أمر: ruby [file name] حيث [file name] هو اسم الملفّ الخاصّ بك. while.rb في حالتي. جرّب البرنامج أكثر من مرّة ولاحظ كيف تختلف المُخرجات Outputs في كلّ مرّة. حلقة until حلقات until تشبه إلى حدٍّ كبير حلقات while. الفرق هو أن حلقة until ستواصل التكرار إلى أن يتحقّق شرط معيّن. على عكس while التي تواصل التكرار متى كان الشرط متحقّقًا وتتوقّف عند عدم تحقّقه. لتوضيح الفكرة أكثر سنستعرض مثال على ذلك. أنشئ ملفّ جديد باسم until.rb أو أيّ اسم آخر واكتب به الشيفرة البرمجيّة التّالية: puts "Hello! Type something" input = "" until input == "goodbye" puts input.upcase input = gets.chomp end puts "Bye! Let's play again soon" أوّلاً بدأنا بطباعة رسالة للمستخدم ترشده إلى ما عليه فعله ومن جديد قمنا بإنشاء وتهيئة متغيّر باسم input والذي سوف يستقبل مُدخلات المستخدم. عيّننا للمتغيّر سلسلة فارغة لأن روبي ستُرجع خطأ إذا ذُكر المتغيّر للمرّة الأولى في الحلقة دون ذكر سابق له. الآن وبالنّظر إلى حلقة until نجد أنّ لدينا الكلمة المفتاحيّة until لبداية الحلقة وend لإنهائها. لدينا أيضًا بعد until الشرط الذي فور حدوثه ستتوقّف الحلقة عن تنفيذ الشيفرات الموجودة بداخلها. هذه المرّة فإنّه الشيفرة البرمجيّة الموجودة في حلقة until سيتمّ تكرار تنفيذها إلى أن (until) تكون قيمة المتغيّر input تساوي السلسلة "goodbye". تذكّر كيف أنّ السلسلة الافتراضيّة المعيّنة للمتغيّر input هي سلسلة فارغة، إذًا فإنّ الحلقة ستعمل على الأقلّ مرّة واحدة. بالنّظر إلى داخل الحلقة، نرى أنّنا نستخدم أوّلاً أمر puts لطباعة المُدخلات ونستخدم دالّة upcase لطباعة تلك المُدخلات بأحرف كبيرة Capital Letters. هل يمكن أن تخمّن ما هي القيمة الأولى التي ستُطبع عند تنفيذ البرنامج وقبل كتابتك أيّة مدخلات؟ أعتقد أنّك توقّعتها، سلسلة فارغة. في السطر التالي نقوم باستبدال القيمة الموجودة في المتغيّر input بالقيمة الجديدة التي سيدخلها المستخدم. تذكّر استخدمنا دالّة chomp للتخلّص من رمز Enter المضاف إلى نهاية المُدخل. هذه الحلقة ستُكرّر ما يُدخله المستخدم ولكن بحروف كبيرة إلى أن يدخل المستخدم goodbye. وعند حدوث ذلك فستتوقّف الحلقة عن العمل ويطبع البرنامج الرسالة الأخيرة الموجودة في السطر 9 لإخبار المستخدم بانتهاء اللّعبة. جرّب تنفيذ البرنامج. هل لاحظت كيف لا يطبع البرنامج كلمة goodbye بأحرف كبيرة عندما تكتبها؟ هل يمكنك جعل الحلقة تطبع goodbye بأحرف كبيرة أوّلاً ثم تتوقّف عن التنفيذ؟ المكررات سنتعرّف الآن على بعض أنواع المكرّرات Iterators. وهي عبارة عن بعض الدوال الخاصّة بـالمصفوفات، جداول التقطيع و المجالات التي تحدّثنا عنها في الدروس السّابقة وعملها يشبه عمل الحلقات العاديّة. دالة each أوّل دالّة سنتعرّف عليها هي دالّة each والتي يمكنك رؤيتها في المثال التّالي: (1..10).each do |number| puts "#{number} squared is #{number**2}" end المجال الموجود هنا يمثّل الأعداد الصحيحة من 1 إلى 10 مع وجود 10 ضمنها. وبعدها استخدمنا دالّة each عن طريق كتابتها بعد المجال وبين الاثنين نقطة والتي تمثّل طريقة استدعاء الدوال على أيّ كائن في روبي. وتنتهي بالكلمة المفتاحيّة end مجدّدًا. ما تفعله هذه الدّالّة هو تنفيذ الشيفرة البرمجيّة الموجودة بداخلها على كلّ (each) عنصر موجود في المجال. لاحظ القيمة الموجودة في السّطر الأوّل number الموجودة بين رمزي الأنبوب Pipe Symbols. تمثّل هذه القيمة ما يشبه المتغيّر المؤقّت لتخزين قيمة عنصر المجال وقت حدوث كلّ عمليّة تكرار. إذًا فستبدأ الدّالّة بتعيين قيمة للمتغيّر تساوي 1 ثمّ تُدخل تلك القيمة إلى السلسلة التابعة لأمر puts. بمجرّد تنفيذ هذا الأمر سيتمّ زيادة قيمة المتغيّر لتصبح 2 وتُنفّذ الدّالّة أمر puts من جديد. وستتابع الدّالّة فعل ذلك (أعني زيادة قيمة المتغيّر وتنفيذ أمر puts) حتّى تصل إلى أن تكون قيمة المتغيّر number هي10. إذًا فهذا المتغيّر يعتبر نوعًا ما ماسك مكان Placeholder لكلّ رقم في كلّ تكرار يحدث في الدالّة. الآن لنلق نظرة على الشيفرة الموجودة داخل الدّالّة. ما يفعله البرنامج هنا هو استخدام دالّة puts لطباعة النصّ الذي نريد على الشّاشة وخاصيّة الاستيفاء Interpolation لطباعة الرقم ليمكننا رؤية كل رقم في المجال بدءًا من 1 ونهايةً بـ 10 ثم يخبرنا أنّ الرقم مربّعًا يساوي قيمة الاستيفاء الثّانية {number**2}#. تعرّفنا في درس التّعامل مع الأرقام أنّ رمز النّجمة يمثّل عمليّة الضرب. الآن أخبرك أن رمزي النّجمة معًا يمثّلان الأُسّ Power. إذًا فإنّ number**2 تعني number أسّ 2 أو قيمة number مربّعة. أو بشكل آخر number number. دالة map تشبه دالّة map دالّة each. ولكن بدلاً من مجرّد تنفيذ الشيفرة البرمجيّة بداخلها فإنّها تقوم أيضًا بإنشاء مصفوفة جديدة (أو جدول تقطيع) يحتوي نتائج تنفيذ الشيفرة الموجودة بداخلها على المصفوفة التي تم تنفيذها عليها. كما أنه بإمكانها باستبدال القيمة الأصليّة بداخل المصفوفة أو جدول التقطيع بالقيمة النّاتجة عن الشيفرة الموجودة داخل المكرّر أو الدّالّة map في حال ما إذا أضفنا علامة التّعجّب إلى اسم الدّالة لتصبح !map. لنستعرض المثال التّالي لتوضيح مبدأ عمل هذه الدّالّة: fruits = ["apples", "oranges"] fruits.map! { |fruit| "I like " + fruit } p fruits يمكننا أن نرى في المثال أنّ لدينا مصفوفة من سلسلتين معيّنة للمتغيّر fruits. الآن نريد أن نضيف I like قبل كلّ عنصر في هذه المصفوفة. كل ما علينا فعله هو استخدام الدّالّة map والتي سوف تكرّر تنفيذ الشيفرة البرمجيّة الموجودة بداخلها على كلّ عنصر في المصفوفة. لاحظ كيف استخدمنا الحاضنات Curly Braces هذه المرّة لوضع الشيفرة البرمجيّة بينها بدلاً من do وend. هذه الطريقة شائعة الاستخدام إذا كانت الشيفرة البرمجيّة مكوّنة من سطر واحد وذلك يوفّر عليك وضع end في سطر جديد. لاحظ لدينا من جديد المتغيّر المؤقّت واسمه هنا fruit والذي سيشير إلى كلّ عنصر موجود في المصفوفة. إذًا فلكلّ عنصر في المصفوفة سنقوم بإضافة السلسلة "I like" قبله. بعد ذلك استخدامنا دالّة + لإضافة السلسلة الجديدة إلى العنصر الذي تُنفّذ عليه الدّالّة. لن تطبع الدّالّة ذلك على الإطلاق فليس لدينا أمر puts أو أيّ شيء يؤدّي إلى تنفيذ عمليّة الطباعة. ستقوم الدّالّة فقط باستبدال العنصر الموجود في المصفوفة بالقيمة التي تُرجعها الشيفرة البرمجيّة الموجودة في الدّالّة. إذًا فنتوقّع تغيّر قيمة المصفوفة الأصليّة إلى التّالي: ["I like apples", "I like oranges"] ولاحظ كيف استخدمنا نسخة Bang للدّالّة map. وذلك بإضافة علامة تعجّب أو ما يسمّى برمز Ban إلى اسم الدّالّة. فعل هذا يعني أن المصفوفة سوف تُستبدل بالكامل. إذا لم نضع علامة Bang فكانت الدّالّة ستقوم بتنفيذ الشيفرات على عناصر المصفوفة وإنشاء/إرجاع مصفوفة مؤقّتة ولكن لم تكن لتستبدل المصفوفة الأصليّة الموجودة في المتغيّر fruits. في حالتنا وحيث أنّنا استخدمنا Bang فسيتمّ تغيير المصفوفة الأصليّة وحفظها في fruits. السّطر الأخير من الشيفرات يستخدم أمر p والذي يستخدم هنا لإظهار كيف أصبح المصفوفة بعد تغييرها. يستخدم أمر p غالبًا عند تنقيح الشيفرة البرمجيّة. حيث أنّه سيُظهر الكائن بدلاً من تحويله إلى سلسلة. هو مشابه جدًا لأمر puts. ولكن في حين أنّ puts يطبع دائمًا سلسلة على الشّاشة حيث أنّه اختصار لـ put string، فإنّ أمر p يُظهر الكائن تمامًا كما هو. إذًا فإنّه في المثال أعلاه بإمكاننا باستخدام p لرؤية المصفوفة fruits كمصفوفة. جرّب تنفيذ البرنامج وألق نظرة على المصفوفة الجديدة بعد التّعديل. خاتمة تعرّفنا في هذا الدّرس على مفهوم الحلقات وأنواعها ويمكنك التعرّف عليها أكثر عن طريق قراءة توثيق روبي عنها. تعرّفنا أيضًا على المكرّرات المستخدمة مع المصفوفات، جداول التقطيع والمجالات. أقترح عليك تحسين أحد البرامج المستخدمة في هذا الدّرس، مثلاً جرّب تعديل المثال المستخدم في حلقة until بحيث يستقبل كلمة goodbye على أيّ هيئة ويتحقّق الشرط وتتوقف الحلقة عن التنفيذ (أعني عند كتابة المستخدم Goodbye ،GOODBYE أو GoodBye أو غير ذلك من صور الكلمة يعتبر البرنامج أنّ الشرط قد تحقّق ويوقف اللّعبة). إذا كان لديك تساؤل أو تريد مشاركتنا ما طبّقت لا تتردّد في استخدام قسم التعليقات أدناه.
  5. python 101

    بعد أن تعلّمنا في الدّرس السّابق كيفيّة التّعامل مع التّعابير الشّرطية، وكيفيّة استعمال الجمل الشّرطية في برامجنا وكيفّية القيّام بإزاحة مناسبة عند التّعامل مع أجزاء متعدّدة من الشّيفرة في لغة بايثون، سنكمل مشوار تعلّم هذه اللغة الجميلة. سنتعلّم في هذا الدّرس كيفيّة التّعامل مع حلقات التّكرار مثل حلقة for وحلقة while. مع التذكير بأنّ جميع الشّيفرات التّي تبدأ بعلامة <<< يجب أن تنفّذ على مفسر بايثون. تُمكّنك الحلقات من تكرار شيفرة عددا من المرّات، يُمكنك أن تحدّد عدد مرّات التّكرار حسب إرادتك. حلقة While حلقة While تقوم بتكرار شيفرة ما عندما يكون الشّرط محقّقا ولا تتوقّف إلا عندما يكون الشّرط خاطئا، ولإنشاء حلقة while يجب تحديد عدد المرّات التّي تتكرّر فيها ووضعها كشرط ثم زيادة قيمة مُتغيّر بواحد، بحيث يزداد إلى أن يصل إلى العدد المُحدّد في الشّرط فيتوقّف. بإمكانك أيضًا تحديد شرط من نوع آخر بحيث لا ترتبط الحلقة بتنفيذ الشيفرة بعدد مُعيّن من المرّات وإنما بتحقق شرط مُعيّن (أن تصبح قيمة مُتغيّر مُخالفة لقيمة نقوم بتحديدها) لنقل بأنّنا نريد طباعة "Hello" مائة مرّة، بالطّبع قد تقول أكرّر الجملة التالية مائة مرة: print "Hello" هذه الطّريقة صحيحة لكنّها تُكلّف الكثير من الوقت، والمُبرمج دائما ما يُفكّر بطريقة أذكى (افعل أكثر عدد ممكن من المهام في أقل وقت ممكن). لذلك لا يُمكننا اعتماد هذه الطّريقة. وتُقدم لنا لغات البرمجة خاصية التكرار ببساطة وبأقل عدد من الأسطر. كمثال يُمكننا طباعة "Hello" عشر مرّات بالطّريقة التّاليّة، لاحظ بأنّ الجمل التّابعة للكلمة while مُزاحةٌ بأربع مسافات بيضاء: >>> i = 0 >>> while i < 10: ... print "Hello" ... i = i +1 Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello شرح المثال أعلاه: السّطر الأول: نقوم بوضع قيمة بدئية للمتغيّر i. السّطر الثّاني: نقوم بإضافة الشّرط وهو أن تكون قيمة المتغير أصغر من العدد عشرة فإن كان يُساوي 10 يتوقّف البرنامج. السّطر الثّالث: نقوم بطباعة الكلمة السّطر الرّابع: نقوم بزيّادة قيمة المتغير في المرّة الأولى سيقرأ المفسّر قيمة المُتغيّر فيجدها تُساوي العدد 0، ثمّ يتحقّق من أنّ شرط أن تكون القيمة أصغر من 10 صحيح، وبما أنّ الشّرط مُحقّق في المرّة الأولى (بالطّبع لأنّ 0 أصغر من 10) سيُتابع البرنامج العمل، وسيطبع جملة التّرحيب "Hello" بعد ذلك يزيد المُفسّر قيمة المتغيّر i بواحد (لتكون القيمة الجديدة هي 1) يتحقّق المُفسّر من صحّة الشّرط مُجدّدا وبما أنّه مُحقّق فقد طُبعت الجملة "Hello" مرّة ثانيّة، بعدها يزيد من قيمة المُتغيّر بواحد مجدّدا لتكون القيمة الجديدة للمُتغيّر i هي العدد 2 والذي بدوره أصغر من 10 فتُطبع الجملة مرّة ثالثة. وهكذا دواليك إلى أن تصل قيمة المُتغيّر إلى العدد 10 فيُصبح الشّرط خاطئا (لأنّ العدد 10 ليس أصغر من 10 بل مُساو له)، وبالتّالي يتوقّف التّكرار. لتستوضح الأمر بشكل أفضل، يُمكنك أن تطبع قيمة المُتغيّر i عند كلّ تكرار، انظر المثال: >>> i = 0 >>> while i < 10: ... print "Hello", i ... i = i +1 ... Hello 0 Hello 1 Hello 2 Hello 3 Hello 4 Hello 5 Hello 6 Hello 7 Hello 8 Hello 9 أمثلة تطبيقية لاستعمال حلقة While مثال 1: الوصول إلى عناصر قائمة، مجموعة أو صف هناك عدّة أمثلة تطبيقيّة لاستعمال حلقة While، وعلى سبيل المثال يُمكن أن تُستخدم حلقة التّكرار هذه للدّوران على قائمة وطباعة عناصرها، انظر المثال التّالي: >>> I = 0 >>> children = ['Omar','Khaled','Hassan','Zaid','Youssef'] >>> while i < len(children): ... print children[i] ... i = i + 1 ... Omar Khaled Hassan Zaid Youssef في المثال أعلاه، قُمنا بإنشاء قائمة باسم children تحتوي على خمسة عناصر، ثمّ قُمنا بطباعة كلّ عنصر عند كلّ تكرار، وقد وضعنا وجوب أن تكون قيمة المُتغيّر i أصغر من عدد عناصر القائمة والتّي حدّدناها بمُساعدة الدّالة len، وذلك ليتوقّف البرنامج عند وصول قيمة المتغير إلى العدد 5. مُلاحظة: هذا مجرّد مثال لكيفيّة استخدام حلقة While. وعادة ما تُستخدم الحلقة for لمثل هذه التّطبيقات (الدّوران على القوائم، المجموعات والصفوف…) وذلك لأنّها أكثر مرونة، وفي النّهاية يعود الاختيار لك (ويُمكنك استخدام الطّريقة التّي تُناسبك). مثال 2: عمل البرنامج إلى أن يجيب المستخدم بجواب معين لنقل بأنّك سألت المُستخدم سؤالا رياضيا (مثلا: "ما جمع 4 زائد 3" )، وتريد تهنأته عند إدخال الجواب الصحيح، الأمر بسيط، ولا يتعدى بضعة أسطر، افتح ملفّا وسمّه Answer.py، وضع فيه الأسطر التّالية: number = raw_input('Enter the Result of 3+4: ') if int(number) == 7: print 'Congratulation' نستخدم الدّالة int هنا لتحويل القيمة المُدخلة من طرف المُستخدم إلى قيمة من نوع integer أي عدد صحيح، وهذا مُفيد لأنّ القيمة التّي تُستقبل في الدّالة raw_input تكون عبارة عن سلسلة نصيّة. بعد أن قُمنا بجزء من المطلوب لنفترض بأنّ المُستخدم قد أدخل إجابة خاطئة، الأمر الذي قد يخطر في بالك الآن هو طباعة جملة تُفيد المُستخدم بأنّ إجابته خاطئة والخروج من البرنامج، الأمر جيّد ، ولكن ماذا لو أردنا أن نوفّر للمُستخدم حقّ المُحاولة من جديد، بحيث يطبع البرنامج جملة تفيد بأنّ الإجابة المُدخلة خاطئة ثمّ يطلب من المُستخدم أن يُحاول مجدّدا مع توفير إمكانيّة إدخال قيمة جديدة، يُمكن أن نقوم بذلك بالاستعانة بجملة else انظر المثال التّالي: number = raw_input('Enter the Result of 3+4: ') if int(number) == 7: print 'Congratulation!' else: print 'Sorry, Your Answer is not correct, please try again:' number = raw_input('Enter the Result of 3+4: ') if int(number) == 7: print 'Congratulation!' هذه الشّيفرة جيّدة لكنّها غير عمليّة بتاتا، إذ تستخدم الكثير من التّكرار الذي لا فائدة منه، كما أنّها لا توفّر للمُستخدم سوى محاولة واحدة أخرى. فماذا لو أردنا أن نوفّر للمُستخدم عددا أكبر من المُحاولات؟ قد تقول ننسخ الشّيفرة أعلاه ونكرّرها عددا من المرّات في برنامجنا، هذا الحلّ سيء جدّا وذلك لأنّه لا يلبّي رغبتنا في توفير عدد لا نهائي من المحاولات للمُستخدم (بحيث لا يتوقّف البرنامج إلا عندما يجد المُستخدم الإجابة الصّحيحة)، كما أنّ نسخ الشّيفرة وتكرارها عدّة مرّات سيجعل من البرنامج طويلا وصعب القراءة. لحلّ هذه المُسألة، يُمكننا ببساطة أن نكرّر الشّيفرة التّي تتحقّق من الإجابة كلّ مرّة تُخالف فيه الإجابة التّي أدخلها المُستخدم، يعني يُمكننا أن نُخبر البرنامج بالتّحقّق من الإجابة إذا كانت صحيحة فكل شيء جيّد ونطبع رسالة تهنئة، إذا كانت الإجابة خاطئة، فسنعيد الشّيفرة مُجدّدا، ونعيد السّؤال إلى أن يصل المُستخدم إلى الإجابة الصحيحة، والتّالي مثال على الشيفرة التي تؤدي الغرض: number = raw_input('Enter the Result of 3+4: ') while int(number) != 7: number = raw_input('Wrong answer please try again, enter the Result of 3+4: ') print 'Congratulation' السّطر الأول: يقوم البرنامج بطلب الإجابة من المُستخدم. السّطر الثاني: تتحقّق حلقة While من كون الإجابة خاطئة، إذا تحقّق الشّرط، ينتقل البرنامج إلى السّطر الثالث، إذا لم يتحقّق (أي قيمة المتغير تساوي 7)، ينتقل البرنامج إلى السّطر الرابع. السّطر الثالث: يقوم البرنامج بإخبار المُستخدم بأنّ الإجابة خاطئة ويطلب منه إعادة المُحاولة. السّطر الرابع: يطبع البرنامج جملة التهنئة. حلقة التكرار For حلقة For جملة برمجية أخرى تُمكّن من التكرار، وهي من الأساليب المُستعملة للدوران حول قيم القوائم كذلك، وتتميّز بتعريف مُتغيّر العدّ في بداية الحلقة، أي أنّك على خلاف حلقة While لا تحتاج إلى تعريف المُتغيّر قبل البدء بكتابة الحلقة، كما أنّ حلقة for لا تحتاج إلى شرط معيّن بل تُحدّد عدد مرّات التّكرار حسب عدد عناصر القائمة المُسندة. انظر المثال التّالي، لاحظ بأنّ الجمل التّابعة للسّطر (for counter in range(1, 11 مُزاحةٌ بأربع مسافات بيضاء (انظر درس الإزاحات والمساحات البيضاء). >>> for counter in range(1, 11): ... print counter, 'Hello World!' ... 1 Hello World! 2 Hello World! 3 Hello World! 4 Hello World! 5 Hello World! 6 Hello World! 7 Hello World! 8 Hello World! 9 Hello World! 10 Hello World! في المثال أعلاه أنشأنا حلقة تكرار تدور على قائمة أنشأناها باستخدام الدّالة range، وأسندنا قيم التّكرار إلى المتغيّر counter الاختلاف هنا عن حلقة while هو أنّ المُتغيّر counter يعتبر جزءا من قائمة وليس مُتغيّرا يحمل قيمة في كلّ تكرار. مُلاحظة: لدّالة range تقوم بإنشاء قائمة أعداد مرتّبة من الأصغر إلى الأكبر حسب عاملين الأول رقم البداية والثّاني يُمثّل النّهاية مع ملاحظة بأنّ الرّقم النّهائي في السّلسلة لا يحتسب (في المثال التّالي 1 هو العدد الأول والعدد النّهائي هو العدد 11 ). >>> range(1,11) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] يُمكن إنشاء قائمة معكوسة بتمرير معامل ثالث بقيمة 1- وقلب المعاملات: >>> range(10, 0, -1) [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] تُمكّنُ حلقة for من الدّوران على عناصر مجموعة ما (القوائم الصفوف، السّلاسل النّصيّة…) عن طريق تمرير اسم المُتغيّر بعد كلمة in في الشيفرة، لاحظ بأنّ الجمل التّابعة للسّطر for lettre in v مُزاحةٌ بأربع مسافات بيضاء (انظر الدّرس السّابق). >>> v = "Hello" >>> for lettre in v: ... print lettre ... H e l l o في المثال أعلاه، قمنا بتعيين القيمة "Hello" للمتغير v وبعدها استخدمنا حلقة for لكي نطبع كل حرف من هذه الكلمة والذي عيّناه للمتغير lettre. كما رأينا من قبل يُمكن كذلك استخدام for لتكرار شيفرة ما عددا من المرّات، كما فعلنا مع حلقة while بمُساعدة الدّالة range: for i in range(0,100): print i يُمكن كذلك أن نستعمل حلقة for لنقوم بالمرور على مفاتيح قاموس ما لنحصل على كل مفتاح على حدة، انظر المثال التالي: >>> a = {'x': 1, 'y': 2, 'z': 3} >>> for key in a: ... print key ... x y z وكما قلنا سابقا في الدّرس الرابع، يُمكنك الحصول على كل من مفاتيح وقيم وعناصر قاموس على شكل قائمة: >>> a = {'x': 1, 'y': 2, 'z': 3} >>> a.keys() ['x', 'y', 'z'] >>> a.values() [1, 2, 3] >>> a.items() [('x', 1), ('y', 2), ('z', 3)] ومما سبق نستنتج بأنّنا نستطيع الحصول على كل واحدة من قيم القاموس: >>> a = {'x': 1, 'y': 2, 'z': 3} >>> for value in a.values(): ... print value ... 1 2 3 وبالتّالي يُمكنك أن تستنتج بأنّنا نستطيع المرور على كل من مفاتيح القواميس وقيمها معا في نفس الوقت: >>> a = {'x': 1, 'y': 2, 'z': 3} >>> for key, value in a.items(): ... print key, value ... x 1 y 2 z 3 أمثلة تطبيقية لاستعمال حلقة For مثال 1: طباعة مفاتيح وقيم قاموس معين يُمكننا أن نستعمل حلقة for لطباعة كل مفتاح وقيمته في قاموس ما. لنقل مثلا بأنّنا نمتلك قاموسا يحتوي على أسماء الألوان وشيفرة كلّ لون بنظام hex (نظام يستخدمه مطورو الويب لإسناد لون مُعيّن لعنصر ما، فعوضا عن كتابة اسم اللون تُستخدم شيفرته)، ونُريد أن نطبع كل لون متبوعا بشيفرته، القاموس الذي نمتلكه هو كالتّالي: colors = { "red":"#f00", "green":"#0f0", "blue":"#00f", "cyan":"#0ff", "magenta":"#f0f", "yellow":"#ff0", "black":"#000" } ونريد أن نعرض هذه المفاتيح مع قيمها بشكل لطيف، هل يُمكنك أن تُفكّر في طريقة لإنجاز مرادنا؟ الحل يكون باستخدام حلقة for للمرور على كل مفتاح وقيمته ومن ثمَّ طباعتها، يُمكننا القيام بذلك بسطرين فقط من شيفرة بايثون، وذلك كالتّالي (ضعها في ملف بامتداد py ونفّذ الملف). colors = { "red":"#f00", "green":"#0f0", "blue":"#00f", "cyan":"#0ff", "magenta":"#f0f", "yellow":"#ff0", "black":"#000" } for color_name, hex_value in colors.items(): print color_name + ': ' + hex_value مُخرجات البرنامج ستكون كالتّالي: blue: #00f yellow: #ff0 green: #0f0 cyan: #0ff magenta: #f0f red: #f00 black: #000 هذا مُجرّد مثال بسيط على استخدام كل من حلقة for والقواميس على أرض الواقع، ولا يجب عليك أن تضع حدّا لإبداعك، إذ يُمكنك استخدام ما تعلّمته بطرق مُختلفة وبرمجة برمجيات تقوم بوظائف لا محدودة، لذا لا تربط علمك بهذه الأمثلة، بل فكّر في طريقة للاستفادة مما تعلّمته لإنتاج برامج أكثر تعقيدا وذات وظائف مُتعدّدة، وسيُسعدني إن شاركت برامجك معنا. إيقاف حلقة بجملة :break يُمكن أن توقف حلقة تكراريّة من نوع while عند نقطة معيّنة بالجملة break ويُمكن تحديد نقطة التوقف باستخدام جملة if الشّرطيّة، انظر المثال: >>> i = 0 >>> while i < 30: ... if i > 15: ... print "Stop the loop" ... break ... print i ... i = i + 1 ... 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Stop the loop في المثال أعلاه، كان من المُفترض أن تُكمل الحلقة التنفيذ إلى أن يصل المُتغيّر iإلى القيمة 30، ولكنّه توقّف بمُجرّد أن وصلت قيمة المُتغيّر إلى 15 وهذا لأنّنا وضعنا شرطا لإيقاف التكرار عندما تُصبح قيمة i أكبر من 15 وبما أنّ الشّرط أصبح صحيحا فقد توقّف البرنامج لأنّنا أمرناه بالجملة break. ويُمكن كذلك أن توقف حلقة تكراريّة من نوع for عند نقطة معيّنة بالجملة break ويُمكن تحديد نقطة التوقف باستخدام جملة if الشّرطيّة: >>> list = [1,5,10,15,20,25] >>> for i in list: ... if i > 15: ... print "Stop the loop" ... break ... print i ... 1 5 10 15 Stop the loop في المثال أعلاه، توقّف الدوران على القائمة list بعد أن وصل المتغيّر إلى القيمة 15، وهذا هو الشرط الذي وضعناه في جملة if. تجاهل تنفيذ الشيفرة في حلقة بجملة :continue يُمكن أن توقف حلقة تكراريّة من نوع for عند نقطة معيّنة ثمّ تُكمل التكرار في الخطوة التّاليّة، أي قفز خطوة عند التّكرار، وذلك بالاستعانة بالجملة continue ويُمكن تحديد نقطة التوقف باستخدام جملة if الشّرطيّة، يعني أنّك تستطيع إخبار البرنامج بالانتقال إلى التنفيذ التّالي إذا ما تحقّق هذا الشّرط، انظر المثال: >>> list = range(1, 31) >>> for i in list: ... if i == 15: ... print "Continue the loop" ... continue ... print i ... 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Continue the loop 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 في المثال أعلاه، كان من المُفترض أن تُكمل الحلقة التنفيذ إلى أن يصل المُتغيّر iإلى القيمة 30، ولكنّه توقّف بمُجرّد أن وصلت قيمة المُتغيّر إلى 15 وتابعت عندما وصلت القيمة إلى العدد 16 وهذا لأنّنا وضعنا شرطا لإيقاف التكرار عندما تُساوي قيمة i العدد 15 وبما أنّ الشّرط قد تحقّق فقد توقّف البرنامج عند تلك النّقطة وطبع جملة Continue the loop لأنّنا أمرناه بالجملة continue. تمارين صديقي القارئ، يجب أن تعرف بأنّ التّعلم لا يكتمل إلا بتطبيق المُكتسبات، لذلك فالتّفكير في حلول هذه التّمارين أمر فعال جدا ومُفيد لك، لذلك لا تكن كسولا، ولا تكتف بالقراءة فقط، بل عليك تطبيق ما تعلّمته وإنشاء برامجك الخاصّة، خاصّة وأنّك إلى الآن قد تعرّفت على جزء كبير من تقنيات البرمجة التي تسمح لك بإنشاء برامج مُبهرة، تُؤدي أغراضا عديدة. يُمكنك أن تنشر حلول التّمارين في صندوق التعليقات إذا كنت ترغب في ذلك، ومن المفضل أن تُحاول حل التّمارين بنفسك قبل أن تنظر إلى أجوبة زملائك. تمرين 1 اكتب برنامجين يقومان بطباعة جملة: Hello World! 1000 مرة. البرنامج الأول باستخدام حلقة While والثاني بحلقة For. تمرين 2 اكتب برنامجا يقوم بأخذ قيمة من المُستخدم ثمّ يطبعها 10 مرات. تمرين 3 ما مُخرجات البرنامج التّالي: number = 3 list = range(1, 31) for i in list: if i == number: continue if 15 < i < 21: continue print i تمرين 4 اكتب برنامجا يقوم بطباعة عناصر القائمة التّالية مع جملة ترحيب. list = ['Ahmed', 'Abdelhadi', 'Dyouri', 'Hossam', 'Mohammed', 'Khaled', 'Ibrahim', 'Othman'] يجب أن تكون مُخرجات البرنامج كالتّالي: Hello, Ahmed Hello, Abdelhadi Hello, Dyouri Hello, Hossam Hello, Mohammed Hello, Khaled Hello, Ibrahim Hello, Othman تمرين 5 عد إلى الدّرس السّابق وعدّل برنامج تسجيل الدخول لكي يقبل مُحاولة المُستخدم من جديد إذا كانت كلمة السّر خاطئة. ولا تنس أن تنشر برنامجك في قسم التّعليقات على هذا المقال إذا أردت ذلك. ترجمة -وبتصرف- من الكتاب Python Practice Book لصاحبه Anand Chitipothu.