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



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

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

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

نوع المُحتوى


التصنيفات

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

التصنيفات

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

التصنيفات

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

التصنيفات

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

التصنيفات

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

التصنيفات

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

التصنيفات

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

التصنيفات

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

أسئلة وأجوبة

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

التصنيفات

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

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

  1. فلنفترض أنك تريد تشغيل دالة اسمها bounceBall أربع مرات. كيف يمكنك ذلك؟ هل ستختار الطريقة التالية؟: function bounceBall() { // bounce the ball here } bounceBall() bounceBall() bounceBall() bounceBall() يمكن أن تكون الطريقة أعلاه مناسبة إذا كنت تريد تنفيذ الدالة بضع مرات. مالذي سيحدُث إن احتجت لتنفيذ الدالة bounceBall مئة مرة؟ الطريقة الأفضل في هذه الحالة هي استخدام تعليمة التكرار الحلقي for. تعليمة التكرار الحلقي for تنفّذ تعليمة التكرار الحلقي for كتلة من التعليمات البرمجية بعدد المرات التي تريد. في ما يلي مثال على تنفيذ الدالة bounceBall عشر مرات: for (let i = 0; i < 10; i++) { bounceBall() } تتكوّن التعليمة for من أربعة أجزاء: العبارة الابتدائية initialExpression الشرط condition عبارة الزيادة incrementalExpression والجملة statement for (initialExpression; condition; incrementExpression) { statement } ستحتاج عندما تريد تنفيذ تعليمة تكرار حلقي إلى جملة برمجية Statement. الجملة هي كتلة الشفرة البرمجية التي تريد تنفيذها مرات عدّة. يمكنك كتابة أي شفرة ترغب بها مهما كان عدد أسطرها، كما يمكنك استخدام دوال. تأخذ التعليمة for الصيغة التالية عند استخدام الدالة bounceBall في الجزء الخاصّ بالجملة: for (initialExpression; condition; incrementExpression) { bounceBall() } ستحتاج كذلك إلى تعريف عبارة ابتدائية Initial expression تبدأ بها تعليمة التكرار الحلقي. هذا هو الجزء الذي تعرّف فيه متغيرا. من المتعارف عليه تسمية المتغير الابتدائي في تعليمة for بالحرف i وإعطاؤه القيمة 0. هكذا تبدو صيغة for عند تحديد عبارتها الابتدائية: for (let i = 0; condition; incrementExpression) { bounceBall() } نزيد قيمة المتغيّر (i في مثالنا) - أو ننقُصه - بعد تنفيذ الحلقة التكرارية لأول مرة، وذلك عن طريق عبارة الزيادة Incremental expression. لزيادة قيمة المتغير i بواحد نعيد إسناده بحيث يُصبح يساوي i + 1 أي بالعبارة i = i + 1. تُختَصر العبارة i = i + 1على ++i والتي يكثُر استخدامها في حلقات التكرار. لنقص قيمة المتغير i بواحد نعيد إسناده بحيث يُصبح يساوي i - 1، أي بالعبارة i = i - 1. تُختَصر العبارة i = i - 1 على --i. بالعودة إلى المثال مع الدالة bounceBall فإننا زدنا المتغيّر i في كل مرة بواحد. تصبح صيغة التعليمة for على النحو التالي: for (let i = 0; condition; i++) { bounceBall() } لكن… هل يجدُر بي زيادة قيمة المتغيّر أم النقص منها؟ توجد الإجابة في الجزء الأخير من تعليمة التكرار الحلقي for وهو الشرط. في حالة تحقّق الشرط - أي أن قيمته تساوي true - فإن الجملة الموجودة في التعليمة for تُنفَّذ وإلا فلا. ينفّذ مفسر جافاسكريبت عبارة الزيادة incrementalExpression مباشرة بعد تنفيذ الجملة statement ثم يتحقّق مجدّدًا من أن قيمة الشرط تساوي true فإن كان الأمر كذلك نفّذ الجملة statement مرة أخرى. يعيد المفسّر الكرة إلى أن تصبح قيمة الشرط false. حينها يتجاوز الحلقة التكرارية وينفّذ الشفرة التي تليها. إن لم تكن تريد تنفيذ الحلقة فيمكنك جعل قيمة الشرط مساوية لـ false منذ البداية: // لن تُنفَّذ الحلقة التكرارية التالية نظرا لأن قيمة الشرط تساوي false for (let i = 0; i < 0; i++) { bounceBall() const timesBounced = i + 1 console.log('The ball has bounced ' + timesBounced + ' times') } // ستُنفّذ الشفرة التالية فقط console.log('next line of code') ستكون نتيجة تنفيذ الشفرة أعلاه على النحو التالي: next line of code عندما تريد تنفيذ الحلقة التكرارية مرتين فستحتاج إلى تغيير الشرط بحيث تكون قيمته false بعد تنفيذ عبارة الزيادة مرتين: // ستُنفّذ الحلقة التكرارية التالية مرتين for (let i = 0; i < 2; i++) { bounceBall() const timesBounced = i + 1 console.log('The ball has bounced ' + timesBounced + ' times')") } console.log('next line of code') النتيجة: The ball has bounced 1 times The ball has bounced 2 times next line of code أما إذا أردت تشغيل الحلقة عشر مرات فسيتوجّب عليك تغيير الشرط بحيث تصبح قيمته false بعد تنفيذ عبارة الزيادة عشر مرات. // ستُنفّذ الحلقة التكرارية التالية عشر مرات for (let i = 0; i < 10; i++) { bounceBall() const timesBounced = i + 1 console.log('The ball has bounced ' + timesBounced + ' times')") } console.log('next line of code') النتيجة: الحلقات غير المحدودة Infinite loops نجد أنفسنا أمام حلقات غير محدودة عندما تكون قيمة الشرط في الحلقة التكرارية for مساوية دائما لـtrue، ممّا يتسبّب في تجمّد التبويب أو المتصفّح ونحتاج بالتالي لإغلاقه وإعادة تشغيله. استخدام الحلقات التكرارية مع المصفوفات Arrays في الواقع لن تحتاج كثيرا لاستخدام الحلقات التكرارية لتنفيذ دالة عشر مرات كما فعلنا مع الدالة bounceBall السابقة. أغلب استخدامات الحلقات التكرارية هو مع المصفوفات أو الكائنات Objects. يتمثّل التكرار عبر المصفوفة في المرور مرة واحدة على كل عنصُر في المصفوفة. بالإمكان استخدام طول المصفوفة (التابع length) في الجزء الخاص بالشرط من تعليمة التكرار. const fruitBasket = ['موزة', 'تفاحة', 'إجاصة'] // fruitBasket.length is 3 for (let i = 0; i < fruitBasket.length; i++) { console.log("توجد " + fruitBasket[i] + " في السلة") } النتيجة: توجد موزة في السلة توجد تفاحة في السلة توجد إجاصة في السلة هناك طريقة بديلة وهي استخدام عبارة نقص بدلًا من عبارة الزيادة، وذلك بالبدء من نهاية المصفوفة في العبارة الابتدائية ضمن تعليمة التكرار: for (let i = fruitBasket.length - 1; i >= 0; i--) { console.log("توجد " + fruitBasket[i] + " في السلة") } النتيجة (لاحظ الفرق): توجد إجاصة في السلة توجد تفاحة في السلة توجد موزة في السلة المرور على المصفوفات بالحلقة for of هناك طريقة ثالثة - أفضل بكثير - للمرور عبر مصفوفة، وهي استخدام تعليمة التكرار الحلقي for...of وهي تعليمة جديدة من إضافات المعيار ES6. تُكتَب التعليمة بالصيغة التالية const fruitBasket = ['موزة', 'تفاحة', 'إجاصة'] for (let fruit of fruitBasket) { console.log("توجد " + fruit + " في السلة") } النتيجة: توجد موزة في السلة توجد تفاحة في السلة توجد إجاصة في السلة يُفضَّل استخدام التعليمة for ...of بدلا من الطريقة التقليدية لاستخدام تعليمة التكرار الحلقي for عند التعامل مع المصفوفات فهي تمرّ على المصفوفة لمرة واحدة فقط، كما لا تحتاج إلى طول المصفوفة؛ ممّا يجعل قراءة الشفرة وصيانتها أيسر بكثير. يمكن استخدام التعليمة for ...of مع أي كائن لديه الخاصيّة Symbol.iterator. إن طبعت مصفوفة فارغة باستخدام التعليمة console.log فسترى أن لديها خاصيّة باسم Synmbol.iterator (ضمن المفتاح _proto_). العمليات المنطقية في الحلقات التكرارية يمكنك استخدام if/else أو أي عمليات منطقية أخرى داخلة حلقة for التكرارية. فلنفترض مثلا أن لديك مصفوفة بمجموعة من الأعداد وتريد إنشاء مصفوفة ثانية تتضمّن أعداد المصفوفة الأولى التي تصغُر 20. حتى تصل إلى هدفك فيجب أن تمرّ أولا على عناصر المصفوفة الأولى بحلقة for: const numbers = [25, 22, 12, 56, 8, 18, 34]; for (let num of numbers) { // سنكمل التعليمات بعد قليل } ثم نتحقّق ما إذا كان العنصُر الذي نمرّ عليه يقل عن 20. تصبح الشفرة كالتالي: const numbers = [25, 22, 12, 56, 8, 18, 34]; for (let num of numbers) { if (num < 20) { // نكمل بعد قليل } } إذا كان العنصُر أصغر من 20 نضيفه إلى مصفوفة أخرى. نستعمل التابع push لهذا الغرض. تصبح الشفرة كالتالي (smallerThan20 هو اسم المصفوفة الثانية): const numbers = [25, 22, 12, 56, 8, 18, 34]; let smallerThan20 = [] for (let num of numbers) { if (num < 20) { smallerThan20.push(num) } } ترجمة - بتصرّف - للمقال Understanding for loops لصاحبه Zell Liew.
  2. يسمح لنا استخدام حلقات التكرار في برمجة الحاسوب بأتمتة وتكرار المهام المتشابهة مرّاتٍ عدِّة. وسنشرح في هذا الدرس كيفية استخدام حلقة for في بايثون. حلقة for تؤدي إلى تكرار تنفيذ جزء من الشيفرات بناءً على عدّاد أو على متغير، وهذا يعني أنَّ حلقات for تستعمل عندما يكون عدد مرات تنفيذ حلقة التكرار معلومًا قبل الدخول في الحلقة، وذلك على النقيض من حلقات while المبنية على شرط. حلقات for تُبنى حلقات for في بايثون كما يلي: for [iterating variable] in [sequence]: [do something] ستُنفَّذ الشيفرات الموجودة داخل حلقة التكرار عدِّة مرات إلى أن تنتهي الحلقة. لننظر إلى كيفية مرور الحلقة for على مجالٍ من القيم: for i in range(0,5): print(i) سيُخرِج البرنامج السابق عند تشغيله الناتج الآتي: 0 1 2 3 4 ضبطنا المتغير i في حلقة for ليحتوي على القيمة التي ستُنفَّذ عليها حلقة التكرار، وكان مجال القيم التي ستُسنَد إلى هذا المتغير من 0 إلى 5. ثم طبعًا قيمة المتغير في كل دوران لحلقة التكرار، لكن أبقِ في ذهنك أنَّنا نميل إلى بدء العد من الرقم 0 في البرمجة، وعلى الرغم من عرض خمسة أرقام، لكنها تبدأ بالرقم 0 وتنتهي بالرقم 4. من الشائع أن ترى استخدامًا لحلقة for عندما تحتاج إلى تكرار كتلة معيّنة من الشيفرات لعددٍ من المرات. استخدام حلقات التكرار مع الدالة range()‎ إحدى أنواع السلاسل غير القابلة للتعديل في بايثون هي تلك الناتجة من الدالة range()‎، وتستخدم الدالة range()‎ في حلقات التكرار للتحكم بعدد مرات تكرار الحلقة. عند التعامل مع الدالة range()‎ عليك أن تمرر معاملًا رقميًا أو معاملين أو ثلاثة معاملات: start يشير إلى القيم العددية الصيحية التي ستبدأ بها السلسلة، وإذا لم تُمرَّر قيمة لهذا المعامل فستبدأ السلسلة من 0 stop هذا المعامل مطلوب دومًا وهو القيمة العددية الصحيحة التي تمثل نهاية السلسلة العددية لكن دون تضمينها step هي مقدار الخطوة، أي عدد الأرقام التي يجب زيادتها (أو إنقاصها إن كنّا نتعامل مع أرقام سالبة) في الدورة القادمة، وقيمة المعامل step تساوي 1 في حال لم تُحدَّد له قيمة لننظر إلى بعض الأمثلة التي نُمرِّر فيها مختلف المعاملات إلى الدالة range()‎. لنبدأ بتمرير المعامل stop فقط، أي أنَّ السلسلة الآتية من الشكل range(stop): for i in range(6): print(i) كانت قيمة المعامل stop في المثال السابق مساويةً للرقم 6، لذا ستمر حلقة التكرار من بداية المجال 0 إلى نهايته 6 (باستثناء الرقم 6 كما ذكرنا أعلاه): 0 1 2 3 4 5 المثال الآتي من الشكل range(start ,stop) الذي تُمرَّر قيم بدء السلسلة ونهايتها: for i in range(20,25): print(i) المجال –في المثال السابق– يتراوح بين 20 (بما فيها الرقم 20) إلى 25 (باستثناء الرقم 25)، لذا سيبدو الناتج كما يلي: 20 21 22 23 24 الوسيط step الخاص بالدالة range()‎ شبيه بمعامل الخطوة الذي نستعمله عند تقسيم [السلاسل النصية](آلية فهرسة السلاسل النصية وطريقة تقسيمها في بايثون 3) لأنه يستعمل لتجاوز بعض القيم ضمن السلسلة. يأتي المعامل step في آخر قائمة المعاملات التي تقبلها الدالة range()‎ وذلك بالشكل الآتي range(start, stop, step). لنستعمل المعامل step مع قيمة موجبة: for i in range(0,15,3): print(i) سيؤدي المثال السابق إلى إنشاء سلسلة من الأرقام التي تبدأ من 0 وتنتهي عند 15 لكن قيمة المعامل step هي 3، لذا سيتم تخطي رقمين في كل دورة، أي سيكون الناتج كالآتي: 0 3 6 9 12 يمكننا أيضًا استخدام قيمة سالبة للمعامل step للدوران إلى الخلف، لكن علينا تعديل قيم start و stop بما يتوافق مع ذلك: for i in range(100,0,-10): print(i) قيمة المعامل start في المثال السابق هي 100، وكانت قيمة المعامل stop هي 0، والخطوة هي ‎-10، لذا ستبدأ السلسلة من الرقم 100 وستنتهي عند الرقم 0، وسيكون التناقص بمقدار 10 في كل دورة، ويمكننا ملاحظة ذلك في الناتج الآتي: 100 90 80 70 60 50 40 30 20 10 الخلاصة: عندما نبرمج باستخدام لغة بايثون، فسنجد أننا نستفيد كثيرًا من السلاسل الرقمية التي تنتجها الدالة range()‎. استخدام حلقة for مع أنواع البيانات المتسلسلة يمكن الاستفادة من القوائم (من النوع list) وغيرها من أنواع البيانات المتسلسلة واستعمالها كمعاملات لحلقات for، فبدلًا من الدوران باستخدام الدالة range()‎ فيمكننا تعريف قائمة ثم الدوران على عناصرها. سنُسنِد في المثال الآتي قائمةً إلى متغير، ثم سنستخدم حلقة for للدوران على عناصر القائمة: sharks = ['hammerhead', 'great white', 'dogfish', 'frilled', 'bullhead', 'requiem'] for shark in sharks: print(shark) في هذه الحالة، قمنا بطباعة كل عنصر موجود في القائمة؛ وصحيحٌ أننا استعملنا الكلمة shark كاسم للمتغير، لكن يمكنك استعمال أي اسم صحيح آخر ترغب به، وستحصل على نفس النتيجة: hammerhead great white dogfish frilled bullhead requiem الناتج السابق يُظهِر دوران الحلقة for على جميع عناصر القائمة مع طباعة كل عنصر في سطرٍ منفصل. يشيع استخدام القوائم والأنواع الأخرى من البيانات المتسلسلة مثل السلاسل النصية وبنى tuple مع حلقات التكرار لسهولة الدوران على عناصرها. يمكنك دمج هذه الأنواع من البيانات مع الدالة range()‎ لإضافة عناصر إلى قائمة، مثلًا: sharks = ['hammerhead', 'great white', 'dogfish', 'frilled', 'bullhead', 'requiem'] for item in range(len(sharks)): sharks.append('shark') print(sharks) الناتج: ['hammerhead', 'great white', 'dogfish', 'frilled', 'bullhead', 'requiem', 'shark', 'shark', 'shark', 'shark', 'shark', 'shark'] أضفنا هنا السلسلة النصية 'shark' خمس مرات (وهو نفس طول القائمة sharks الأصلي) إلى القائمة sharks. يمكننا استخدام حلقة for لبناء قائمة جديدة: integers = [] for i in range(10): integers.append(i) print(integers) هيّئنا في المثال السابق قائمةً فارغةً باسم integers لكن حلقة التكرار for ملأت القائمة لتصبح كما يلي: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] وبشكلٍ شبيهٍ بما سبق، يمكننا الدوران على السلاسل النصية: sammy = 'Sammy' for letter in sammy: print(letter) الناتج: S a m m y يمكن الدوران على بنى tuple كما هو الحال في القوائم والسلاسل النصية. عند المرور على عناصر نوع البيانات dictionary، فمن المهم أن تبقي بذهنك البنية الخاصة به (key:value) لكي تضمن أنَّك تستدعي العنصر الصحيح من المتغير. هذا مثالٌ بسيطٌ نعرض فيه المفتاح (key) والقيمة (value): sammy_shark = {'name': 'Sammy', 'animal': 'shark', 'color': 'blue', 'location': 'ocean'} for key in sammy_shark: print(key + ': ' + sammy_shark[key]) الناتج: name: Sammy animal: shark location: ocean color: blue عند استخدام متغيرات من النوع dictionary مع حلقات for فيكون المتغير المرتبط بحلقة التكرار متعلقًا بمفتاح القيم، وعلينا استخدام التعبير dictionary_variable[iterating_variable] للوصول إلى القيمة الموافقة للمفتاح. ففي المثال السابق كان المتغير المرتبط بحلقة التكرار باسم key وهو يُمثِّل المفاتيح، واستعملنا التعبير sammy_shark[key] للوصول إلى القيمة المرتبطة بذاك المفتاح. الخلاصة: تُستعمَل حلقات التكرار عادةً للدوران على عناصر البيانات المتسلسلة وتعديلها. حلقات for المتشعّبة يمكن تشعّب حلقات التكرار في بايثون، كما هو الحال في بقية لغات البرمجة. حلقة التكرار المتشعبة هي الحلقة الموجودة ضمن حلقة تكرار أخرى، وهي شبيهة بعبارات if المتشعّبة. تُبنى حلقات التكرار المتشعبة كما يلي: for [first iterating variable] in [outer loop]: # Outer loop [do something] # Optional for [second iterating variable] in [nested loop]: # Nested loop [do something] يبدأ البرنامج بتنفيذ حلقة التكرار الخارجية، ويُنفَّذ أوّل دوران فيها، وأوّل دوران سيؤدي إلى الدخول إلى حلقة التكرار الداخلية، مما يؤدي إلى تنفيذها إلى أن تنتهي تمامًا. ثم سيعود تنفيذ البرنامج إلى بداية حلقة التكرار الخارجية، ويبدأ بتنفيذ الدوران الثاني، ثم سيصل التنفيذ إلى حلقة التكرار الداخلية، وستُنفَّذ حلقة التكرار الداخلية بالكامل، ثم سيعود التنفيذ إلى بداية حلقة التكرار الخارجية، وهلّم جرًا إلى أن ينتهي تنفيذ حلقة التكرار الخارجية أو إيقاف حلقة التكرار عبر استخدام [التعبير break](كيفية استخدام تعابير break و continue و pass عند التعامل مع حلقات التكرار في بايثون 3) أو غيره من التعابير. لنُنشِئ مثالًا يستعمل حلقة forمتشعبة لكي نفهم كيف تعمل بدقة. حيث ستمر حلقة التكرار الخارجية في المثال الآتي على قائمة من الأرقام اسمها num_list، أما حلقة التكرار الداخلية فستمر على قائمة من السلاسل النصية اسمها alpha_list: num_list = [1, 2, 3] alpha_list = ['a', 'b', 'c'] for number in num_list: print(number) for letter in alpha_list: print(letter) سيظهر الناتج الآتي عند تشغيل البرنامج: 1 a b c 2 a b c 3 a b c يُظهِر الناتج السابق أنَّ البرنامج أكمل أوّل دوران على عناصر حلقة التكرار الخارجية بطباعة الرقم 1، ومن ثم بدأ تنفيذ حلقة التكرار الدخلية مما يطبع الأحرف a و b و c على التوالي. وبعد انتهاء تنفيذ حلقة التكرار الداخلية، فعاد البرنامج إلى بداية حلقة التكرار الخارجية طابعًا الرقم 2، ثم بدأ تنفيذ حلقة التكرار الداخلية (مما يؤدي إلى إظهار a و b و c مجددًا). وهكذا. يمكن الاستفادة من حلقات for المتشعبة عند المرور على عناصر قوائم تتألف من قوائم. فلو استعملنا حلقة تكرار وحيدة لعرض عناصر قائمة تتألف من عناصر تحتوي على قوائم، فستُعرَض قيم القوائم الداخلية: list_of_lists = [['hammerhead', 'great white', 'dogfish'],[0, 1, 2],[9.9, 8.8, 7.7]] for list in list_of_lists: print(list) الناتج: ['hammerhead', 'great white', 'dogfish'] [0, 1, 2] [9.9, 8.8, 7.7] وفي حال أردنا الوصول إلى العناصر الموجودة في القوائم الداخلية، فيمكننا استعمال حلقة for متشعبة: list_of_lists = [['hammerhead', 'great white', 'dogfish'],[0, 1, 2],[9.9, 8.8, 7.7]] for list in list_of_lists: for item in list: print(item) الناتج: hammerhead great white dogfish 0 1 2 9.9 8.8 7.7 الخلاصة: نستطيع الاستفادة من حلقات for المتشعبة عندما نريد الدوران على عناصر محتوى في قوائم. الخلاصة رأينا في هذا الدرس كيف تعمل حلقة التكرار for في لغة بايثون، وكيف نستطيع إنشاءها واستعمالها. حيث تستمر حلقة for بتنفيذ مجموعة من الشيفرات لعددٍ مُحدِّدٍ من المرات. ترجمة –وبتصرّف– للمقال How To Construct For Loops in Python 3لصاحبته Lisa Tagliaferri
  3. توجد طرق متعددة لصنع تطبيقات لنظام تشغيل أندرويد ويُفضل المطوَرون كتابة التطبيقات باستخدام اللغة الرسمية وهي جافا لقدرتها على استغلال كافة موارد الهاتف وكفاءتها عند العمل. وتُستخدم لغات البرمجة لإعطاء الأوامر للحاسوب لتنفيذها وتتشابه مع اللغات الحقيقية في أنها بدلًا من أن تتواصل مع البشر فهي تتواصل مع الحاسوب ووصف الطريقة التي أرغب أن يعمل بها. يعتمد نظام تشغيل أندرويد على أساسيات لغة جافا ومكتباتها القوية بالإضافة إلى مكتبات أندرويد الخاصة، ويتم وضع الشيفرة المكتوبة بلغة جافا بعد أن يتم ترجمتها إلى صيغتها التنفيذية في ملف بامتداد apk جنبًا إلى جنب مع باقي الموارد من صور وملف androidManifest. البرمجة كائنية التوجه تتميز لغة جافا بأنها لغة سهلة التعلم وتٌصنف من اللغات عالية المستوى والتي نستطيع فهم أوامرها بسهولة، وهي من لغات البرمجة التي تدعم مفهوم البرمجة كائنية التّوجّه. والبرمجة كائنية التّوجّه تتكون من مجموعة من المفاهيم. في عالمنا الحقيقي يمكن التعامل مع أي شيء على أنه كائن، ولكل كائن صفات تميزه ولديه وظائف يستطيع القيام بها، فمثلًا الكاميرا كائن لها صفات مثل اللون والأبعاد والشركة المصنعة لها، ولها وظائف يستطيع القيام بها مثل التصوير أو تخزين وعرض الصورة. ويوجد أنواع عديدة من الكاميرات لذا يتم وضع التصميم المشترك والتعريف الخاص بهذه الكائنات في البرمجة في صنفClass ومن هذا الصّنف يتم استخراج الكائنات. لذا يتم تصّنيف الأشياء إلى فئات تشترك في الصفات والوظائف ومنها يتم صنع الكائنات Objects. المتغيرات تتعامل لغة جافا مع كافة أنواع البيانات والقيام عليها بالعمليات المختلفة. لذا تستخدم المتغيرات كحاويات لتخزين هذه البيانات لحفظها بشكل مؤقت والقيام عليها بالعمليات المطلوبة ويمكن تغيير هذه القيم في أي وقت ويعتبر تعريف المتغيرات الطريقة لجعل الحاسوب يحتفظ بالمعلومات. عند تعريف متغير جديد يجب تحديد ما هو نوع البيانات التي يستطيع المتغير تخزينها بداخله، قد تكون البيانات اسمًا أو أرقامًا أو رابط لفيديو أو صورة لذا يجب تحديد نوع البيانات التي سيحتويها المتغير حتى يستطيع البرنامج التعامل معها بشكل صحيح. فإذا كان المتغير رقمًا فلا يمكن أن نخزن به نصًا. ولتعريف متغير جديد يتم على هذا النحو: DataType variableName; يتم كتابة نوع البيانات أولًا ثم اسم المتغير، واسم المتغير يمكن أن يكون أي شيء ولكن هناك بعض الأمور التي يجب مراعاتها وهي: يمكنك استخدام الحروف "A-Z" و "a-z" و "0-9". ألا يبدأ برقم. لا يسمح باستخدام أي حروف خاصة في الاسم مثل @، # وغيرهما عدا _ فقط. لا يسمح باستخدام المسافات في الاسم. ألا يكون الاسم من الكلمات المجوزة لدى اللغة وهي كلمات ذات معنى محدد لدى المترجم. أنواع البيانات هناك بعض الأنواع الأساسية لتعريف المتغيرات مثل: الأرقام الصحيحة: يتم تخزين الأرقام الصحيحة في متغير النوع int. int number=26; الأرقام الكسرية: لتخزين الأرقام الكسرية نستخدم متغير من النوع float أو double. double fraction=102.486; float fraction=842.014f; لاحظ أن عند تعريف متغير من النوع float يجب وضع الحرف f في نهاية الرقم. الحروف: لتخزين حرف واحد نستخدم متغير من النوع char. char c=’y’; char num=’8’; char s=’&’; يتم وضع الحرف بين علامتيّ اقتباس فردية. القيم المنطقية: لتخزين متغير يحمل إحدى القيمتين المنطقيين true أو false يتم تعريف متغير من النوع boolean، ويستخدم في المقارنات المنطقية. boolean flag=true; النصوص: لتخزين نص يتم استخدام متغير من النوع String. String str=”Hello,World!!”; يتم وضع النص بين علامتيّ اقتباس زوجية ولا يوجد حد لطول النص. والاختلاف بين النوعين char و String أن الأول لتخزين حرف واحد فقط والثاني لنص كامل، ولاحظ أن علامتيَ الاقتباس مختلفة فلا يمكن استخدام "R" لتخزينها في متغير من النوع char لأنها داخل علامتيّ الاقتباس الخاصة بالنص. كما يمكنك أن تقوم بتعريف المزيد من أنواع البيانات باستخدام الأصناف كما سنرى لاحقًا. في الأمثلة السابقة قمنا بتعريف المتغير وتخزين قيمة مبدئية بداخله، هناك طريقة أخرى يمكن استخدامها كما في المثال التالي. int x; x=100; في المثال السابق تم تعريف متغير اسمه x ثم قمنا لاحقًا بتخزين قيمة بداخله ويمكن تغيير القيمة بعد ذلك في أي وقت داخل البرنامج، وبالمثل يمكن تعريف باقيِ أنواع المتغيرات بهذه الطريقة. ملاحظات تنتهي الجمل في جافا بالفاصلة المنقوطة ";" للتعبير عن انتهاء الجملة، ويمكن اعتبارها مثل النقطة التي تنتهي بها الجملة عند الكتابة. العلامة "=" تسمى بـ "عامل الإسناد" (Assignment Operator) وتستخدم لتخزين القيم التي تقع يمين العامل في المتغير الذي يقع على يساره. int x; x=3; x=x+5; في هذا المثال سيتم تخزين 3 في المتغير x ثم بعد ذلك جمع عليه الرقم 5 وتخزينه مرة أخرى في x ليصبح الناتج النهائي المخزن داخل المتغير x يساوي 8. العمليات الحسابية والمنطقية العمليات الرياضية يمكننا القيام بالعمليات الرياضية المعتادة في لغة جافا فمثلًا: int x = 19; int y = 4; int result = x + y; وهنا يتم جمع قيم المتغيرين وتخزينهما في المتغير result ليصبح الناتج يساوي 23: int result = x – y; وإذا قمنا بتغيير السطر الثالث بهذا السطر فيصبح الناتج 15: int result = x * y; وناتج ضربهما يساوي 76: int result = x / y; وناتج القسمة يساوي 4 ويتم إهمال الكسر لأن في لغات البرمجة عندما نقوم بقسمة رقمين صحيحين فيكون الناتج رقمًا صحيحًا. int result = x % y; وتعني هذه العملية بباقي قسمة x على y وتساوي 5. وهناك العملية: x++; وهي تتشابه مع: x=x+1; فهي تقوم بزيادة واحد على قيمة المتغير، وبالمثل العملية --x تقوم بطرح واحد من قيمة المتغير. عمليات المقارنة وتقارن هذه العمليات بين المعاملات مثل: int a = 15; int b = 20; boolean result = a > b; وتقوم هذه العملية بالمقارنة بين قيمتيّ a و b وتخزين true أو false في المتغير result وفي المثال السابق سيتم تخزين false لأن b ذات قيمة أكبر من a. وباقي المقارنات هي > أصغر من، و =< أكبر من أو يساوي، => أصغر من أو يساوي، == يساوي، =! لا يساوي وكلهم يكون ناتجهم إما true أو false. العمليات المنطقية تستخدم العمليات المنطقية في ربط ناتج أكثر من عملية مقارنة سويًا. int a = 15; int b = 20; int c = 7; boolean result = a > b && a > c; وتستخدم && (كحرف العطف "و") للتعبير عن وجوب تحقق الشرطين معًا ليكون الناتج true ويكون false غير ذلك. boolean result = a > b || a > c; وتستخدم || (كحرف العطف "أو") للتعبير عن تحقق إحدى الشرطين أو تحققهما معًا ليكون الناتج true ويكون الناتج false عندما يكون الشرطين غير متحققين معًا. boolean result = !(a>b); وتعني ! عكس الناتج فإذا كان true يصبح false والعكس صحيح. التعليقات يحتاج المطوّر في بعض الأحيان لإضافة بعض التعليقات والملاحظات على البرنامج وذلك لتسهيل فهم ما كتبه من شيفرات عند قراءتها دون التأثير على الأوامر المكتوبة، حيث أن التعليقات لا يترجمها المترجم الخاص بجافا بل يهملها. تعليق السطر الواحد هذا النوع من التعليق يتم باستخدام علامتيّ //، ويجعل السطر المقابل لها تعليق لا يراه البرنامج. //This is a single-line comment int weekDays = 7; //Number of Days in a week كما ترى يقوم التعليق بتوضيح الأمور للمطوّر. تعليق الأسطر المتعددة يمكنك أن تكتب تعليق في عدة أسطر باستخدام /* */ لكتابة التعليق: /*This is a multi-line comment. That comment ends when it finds the closing marker. */ يتم حجز عدد من الأسطر بين */ و /* وتكون عبارة عن تعليق. ولن يتم تنفيذها في البرنامج، فوصول المترجم لـ */ تجعله يتجاهل كل ما يقابله حتى يصل لـ /* ثم يقوم بتنفيذ ما بعدها. لذا فالتعليقات في البرنامج تساهم في توضيحه وتجعل قراءته أسهل. فأي شيء يبدو واضحًا وبديهيًا عند كتابة البرنامج قد لا يبدو كذلك بعد مرور فترة طويلة. الجمل الشرطية وهي الجمل التي تنفذ عند تحقق شرط معين ولتنفيذها يتم استخدام if و if-else و switch، وإذا لم يتحقق هذا الشرط لا يتم تنفيذها. جملة if تعتبر جملة if من أبسط الجمل الشرطية فهي تحتوي على شرط عند تحققه يتم تنفيذ أوامر محددة ويتم تركيبها على الشكل التالي: if ( Condition ) { // Do Some Actions if it’s true } تُكتب كلمة if ويتم وضع الشرط بين الأقواس و عند تحقق الشرط يتم تنفيذ الأوامر المتواجدة بين القوسين { } وإذا لم يتحقق يتم تجاهل هذه الأوامر واستكمال الشفرة الخاصة بالبرنامج. مثال على ذلك: int x = 10; String result = “false”; if(x > 10){ result = “true”; } في المثال السابق يتم التحقق من قيمة المتغير x إذا كانت أكبر من الصفر أم لا، وفي هذه الحالة فالشرط سليم ويتم تخزين النص "true" داخل المتغير result، وإذا تم تغيير قيمة المتغير x إلى -5 مثلًا لن يتحقق الشرط وستظل قيمة النص "false". الجملة if-else وهي تقوم بنفس الوظيفة التي تقوم بها if عدا أنه إذا لم يتحقق الشرط الخاص بـ if تقوم بتنفيذ أوامر أخرى معرّفة لدى الجملة else، وبالتعديل على المثال السابق: int x = -6; String result ; if(x > 10){ result = “true”; }else{ result = “false”; } في المثال لا يتم تم وضع نص مبدئي في المتغير result ويتم التحقق بعد ذلك من الشرط الخاص بـ if إذا كان صحيحًا فسيتم وضع النص "true" داخل المتغير result أما إذا كان خاطئًا فسيتم وضع القيم "false" داخل المتغير result. ويمكن القيام بالتحقق بأكثر من شرط كما في المثال التالي: char grade = ‘B’; String result; if(grade==’A’){ result = “Excellent”; }else if(grade==’B’){ result = “Very good”; }else if(grade==’C’){ result = “good”; }else if(grade==’D’){ result = “passed”; }else{ result = “failed”; } في هذا المثال تم استخدام أكثر من شرط وجملة واحدة فقط التي تتحقق ويكون الشرط فيها صحيحًا وفي المثال فهي الجملة الثانية ويتم تخزين النص "very good". لاحظ أننا لا تستخدم == عند المقارنة بين النصوص من النوع String وتستخدم الدالة equals. جملة switch تستخدم هذه الجملة عندما نريد التحقق من قيمة متغير واحد فقط وتعتبر أكثر سهولة من if في هذه الحالة: switch(variable){ case 1: //Do something break; case 2: //Do something break; default: //Do something break; } وبتحويل المثال السابق الخاص بـ if باستخدام switch: char grade = ‘B’; String result; switch(grade){ case ‘A’: result = “Excellent”; break; case ‘B’: result = “Very good”; break; case ‘C’: result = “good”; break; case ‘D’: result = “passed”; break; default: result = “failed”; break; } ملاحظات يتم كتابة اسم المتغير فقط بين الأقواس الخاصة بـ switch ولا يتم تحديد شرط معين. تكتب كلمة case وتتبعها قيمة المتغير عند هذه الحالة حتى يتم تنفيذ الأوامر الخاصة بهذه الحالة إذا تساوت قيمة المتغير الخاص بـ switch مع القيمة الخاصة بـ case (في المثال السابق كان المتغير من النوع char لذا تم وضع القيم الخاصة بـ case بين علامتيّ التنصيص المفردة). في آخر كل حالة يتم وضع الأمر break وهو أمر للخروج من الجملة switch، وإذا لم يتم وضعه سيتم تنفيذ باقي الحالات المتواجدة داخل الجملة switch حتى نصل إلى الأمر break أو تنتهي الجملة switch. يتم تنفيذ الحالة default عندما يكون قيمة المتغير الخاص بـ switch لا يوجد لها حالة خاصة بها. جملة switch تتعامل مع المتغيرات من النوع int أو char أو String فقط. الجمل الشرطية التكرارية الجمل الشرطية التكرارية هي جمل تقوم بتنفيذ أوامر عدة مرات في حال كان الشرط صحيحًا، وتتشابه مع الجمل الشرطية في تركيبها وتختلف معها في عدد مرات تنفيذ الأمر. تمتلك لغة جافا عدة أنواع من الجمل التكرارية مثل while و do While و for. الجملة while وتتشابه تركيبة هذه الجملة مع الجملة if كالتالي: while (Condition){ //Do some Actions here } ويتم تنفيذ الأوامر داخل الجملة while طالما الشرط متحقق ويتم التوقف عندما يصبح الشرط خاطئًا، مثال على ذلك: int i = 0; int sum = 0; while( i < 5 ){ sum = sum + 1; i++; } في هذا المثال يكون الشرط صحيحًا فيتم تنفيذ الجمل داخل while ثم يتم التحقق من الشرط مرة أخرى ويكون صحيحًا وهكذا حتى يصبح الشرط خاطئًا ويُلاحظ أن الشرط لن يتحقق في حالة i تساوي 5 وعند الخروج من الجملة التكرارية تكون القيمة 5 مخزنة داخل المتغير sum. الجملة for وتختلف طريقة كتابة هذه الجملة عن الجملة while. for (initialization ; condition ; update){ // Do Some Actions here } داخل القوسين الخاصين بالجملة for يتم تقسيمها إلى ثلاث أقسام تفصلهم الفاصلة المنقوطة ";" وأول قسم يتم به تهيئة المتغير إعطائه قيمة ابتدائية، والقسم الثاني الشرط المعتاد، والقسم الأخير خاص بتحديث الشرط. فمثلًا لاستخدام for في المثال السابق الخاص بـ while: int sum =0; for(int i=0;i<5;i++){ sum = sum + 1; } ويقوم المثال السابق بنفس الوظيفة و ُلاحظ أنه تم دمج الجمل الثلاث التي كانت قبل جملة while والشرط الخاص بـ while والتحديث للشرط داخل جملة while في سطر واحد داخل الأقواس الخاصة بـ for. وتُستخدم الجمل التكرارية لتكرار تنفيذ أوامر محددة لحين غياب شرط معين يتم تحديده مسبقًا. سنواصل في الدرس القادم باقي أساسيات جافا التي تحتاج أن تعرفها قبل أن تشرع في برمجة تطبيقات أندرويد.
  4. بعد أن تعلمنا التعامل مع المعاملات الموضعية (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.
  5. تُعتبر الحلقات التكراريّة من البنى المهمّة في لغات البرمجة، حيث نستطيع من خلالها تنفيذ عبارة أو عدّة عبارات برمجيّة لعدد من المرّات. تدعم سي شارب مثل باقي لغات البرمجة نوعين من الحلقات التكراريّة من حيث عدد التكرار، فهناك الحلقات ذات العدد المحدّد من المرّات (حلقة for) والتي نعلم فيها عدد مرّات التكرار بشكل مسبق، والحلقات ذات العدد غير المحدّد من المرّات (حلقة do-while وحلقة while) التي يكون فيها عدد مرّات التكرار غير مُحدّدًا. حلقة for التكرارية يمكن من خلال هذه الحلقة تكرار تنفيذ عبارة برمجيّة أو أكثر عددًا محدّدًا من المرّات، ولهذه الحلقة الشكل العام التالي: for ([init_counter]; [loop_condition]; [counter_expression]) { statement1; statement2; ... } القسم [init_counter] هو قسم التهيئة الذي يتمّ من خلاله تهيئة متغيّر الحلقة بقيمة ابتدائيّة (وغالبًا ما يتمّ التصريح عنه في هذا القسم أيضًا)، يسمّى متغيّر الحلقة أيضًا بعدّاد الحلقة loop counter، أمّا القسم [loop_condition] فيمثّل شرط التكرار أو الاستمرار للحلقة، فهو تعبير مقارنة يعطي true أو false بحيث تستمرّ الحلقة بالتكرار طالما كان هذا الشرط محقّقًا (يعطي true). القسم الأخير [counter_expression] ويتمّ فيه عادةً إجراء عملية حسابية على متغيّر الحلقة وغالبًا ما تكون هذه العمليّة هي زيادة متغيّر الحلقة بمقدار واحد. انظر الشيفرة البسيطة التالية التي تعمل على تنفيذ العبارة التي تحوي التابع WriteLine ثلاث مرّات: for (int i = 0; i < 3; i++) { Console.WriteLine("i = {0}", i); } عند تنفيذ الشيفرة السابقة ستحصل على الخرج التالي: i = 0 i = 1 i = 2 لاحظ أنّنا صرّحنا عن المتغيّر i من النوع int وأسندنا إليها القيمة 0 في قسم التهيئة، وبالنسبة لشرط الاستمرار للحلقة i < 3 فمن الواضح أنّ الحلقة ستستمرّ بالتكرار طالما كانت قيمة i أصغر تمامًا من 3. أمّا بالنسبة للقسم الأخير فنعمل على زيادة قيمة متغيّر الحلقة i بمقدار 1 في كلّ دورة عن طريق عامل الزيادة اللاحق ++i. آلية عمل هذه الحلقة بسيطة: عندما يصل تنفيذ البرنامج إلى حلقة for يتمّ التصريح عن المتغيّر i وإسناد القيمة 0 إليه. يختبر البرنامج شرط استمرار الحلقة i < 3 فإذا كان true يبدأ بتنفيذ العبارات البرمجيّة الموجودة ضمن حاضنة for. وإلّا يخرج فورًا من الحلقة. بعد الانتهاء من تنفيذ العبارات ضمن حاضنة for، ينتقل البرنامج إلى التعبير ++i ليزيد قيمة i بمقدار 1. تتكرّر نفس الخطوتين 2 و 3. سيتكرّر في هذا المثال البسيط تنفيذ العبارة الموجودة في الحاضنة ثلاث مرّات لأنّ العدّ يبدأ من الصفر (قيمة i الابتدائيّة تساوي الصفر). لنتناول الآن برنامجًا عمليًّا وظيفته إيجاد مجموع سلسلة من الأعداد المتتالية. أنشئ برنامجًا جديدًا اسمه Lesson04_1 ثمّ استبدل محتويات الملف Program.cs بالشيفرة التالية: 1 using System; 2 3 namespace Lesson04_1 4 { 5 class Program 6 { 7 static void Main(string[] args) 8 { 9 int n, sum = 0; 10 string str_n; 11 12 Console.WriteLine("This Program calculates the series: sum = 1 + 2 + 3 + ... + n"); 13 Console.Write("Input 'n' please: "); 14 str_n = Console.ReadLine(); 15 16 n = int.Parse(str_n); 17 18 for (int i = 1; i <= n; i++) 19 { 20 sum += i; 21 } 22 23 Console.WriteLine("sum = {0}", sum); 24 } 25 } 26 } يعمل البرنامج السابق على جمع الأعداد من 1 حتى القيمة المدخلة n. أي سيحسب برنامجنا مجموع السلسلة: 1 + 2 + 3 + … + n. لاحظ القيمة الابتدائيّة للمتغيّر i (تساوي 1) وشرط استمرار الحلقة i <= n في السطر 18. تذكّر أنّ العبارة الموجودة في السطر 20 تُكافئ العبارة sum = sum + i. نفّذ البرنامج وجرّب إدخال قيم مختلفة للمتغيّر n لتحصل على المجاميع الموافقة. ملاحظة: المتغيّر i في البرنامج السابق مرئي فقط ضمن الحلقة التكراريّة ولا وجود له خارجها، يعرف هذا بمجال الرؤية للمتغيّر variable scope. ستؤدّي محاولة الوصول للمتغيّر i خارج الحلقة إلى خطأ أثناء بناء البرنامج. سنكتب الآن برنامجًا آخرًا لحساب مجموع السلسلة: 2 + 4 + 6 + 8 + … + n. لن يختلف البرنامج في هذا المثال عن البرنامج Lesson04_1 باستثناء أنّنا سنجمع الأعداد الزوجية فقط. إليك البرنامج كما سيبدو: 1 using System; 2 3 namespace Lesson04_2 4 { 5 class Program 6 { 7 static void Main(string[] args) 8 { 9 int n, sum = 0; 10 string str_n; 11 12 Console.WriteLine("This Program calculates the series: sum = 2 + 4 + 6 + ... + n"); 13 Console.Write("Input 'n' please: "); 14 str_n = Console.ReadLine(); 15 16 n = int.Parse(str_n); 17 18 for(int i = 0; i <= n; i += 2) 19 { 20 sum += i; 21 } 22 23 Console.WriteLine("sum = {0}", sum); 24 } 25 } 26 } لاحظ كيف نزيد قيمة المتغيّر i في كلّ تكرار للحلقة for بمقدار 2 باستخدام التعبير i += 2 (السطر 18)، وبالتالي نتفادى جمع الأعداد الفردية (لاحظ أنّ قيمة i بدأت من الصفر). فيما عدا ذلك يبدو هذا البرنامج مطابقًا لبنية البرنامج Lesson04_1. حلقة while التكرارية لهذه الحلقة التكراريّة الشكل العام التالي: while (loop_condition) { statement1; statement2; ... } ستتكرّر العبارات البرمجيّة الموجودة ضمن حاضنة while طالما كان الشرط loop_condition محقّقًا (أي true) وبمجرّد أن يصبح الشرط loop_condition غير محقّق تتوقّف الحلقة عن التكرار. سنعدّل البرنامج Lesson04_1 السابق لكي يسمح باستخدام الحلقة while. أنشئ مشروعًا جديدًا وسمّه Lesson04_3 ثم استبدل محتويات Program.cs بما يلي: 1 using System; 2 3 namespace Lesson04_3 4 { 5 class Program 6 { 7 static void Main(string[] args) 8 { 9 int n, sum = 0, i = 1; 10 string str_n; 11 12 Console.WriteLine("This Program calculates the series: sum = 1 + 2 + 3 + ... + n"); 13 Console.Write("Input 'n' please: "); 14 str_n = Console.ReadLine(); 15 16 n = int.Parse(str_n); 17 18 while (i <= n) 19 { 20 sum += i; 21 22 i++; 23 } 24 25 Console.WriteLine("sum = {0}", sum); 26 } 27 } 28 } صرّحنا عن المتغيّر i وأسندنا له القيمة 1 في السطر 9 والذي سيمثّل متغيّر حلقة while. استبدلنا حلقة for بحلقة while في السطر 18 مع ملاحظة أنّ شرط استمرار الحلقة i <= 5 بقي دون تعديل. لاحظ العبارة المهمّة في السطر 22 والتي تحوي التعبير ++i الذي سيزيد قيمة i بمقدار واحد في كلّ دورة. إنّ إغفال هذه العبارة سيؤدّي إلى الدخول في حلقة لا نهائيّة، لأنّ شرط الاستمرار في هذه الحالة لن يعطي false أبدًا لأنّ قيمة i لن تتغيّر. نفّذ البرنامج وأدخل قيم مختلفة للمتغيّر n لاختبار البرنامج. جرّب الآن إدخال القيمة 0 للمتغيّر n ستحصل في الخرج على المجموع sum = 0 وهذا منطقيّ. إذ أنّنا نخبر البرنامج بأنّنا لا نريد جمع أي عدد. سبب الحصول على هذا الخرج في الواقع هو أنّ البرنامج أثناء التنفيذ لن يدخل إلى حلقة while مطلقًا لأنّ شرط الاستمرار i <= n سيكون غير محقّقًا منذ البداية (تذكّر أنّ قيمة i الابتدائيّة هي 1). حلقة do-while التكرارية لهذه الحلقة الشكل العام التالي: do { statement1; statement2; ... } while (loop_condition) وهي تشبه الحلقة while باستثناء أنّ شرط استمرار الحلقة loop_condition يجري اختباره في نهايتها وليس في بدايتها كما هو الحال مع حلقة while. قد لا يبدو هذا الأمر مهمًّا في البداية ولكنّه في الحقيقة عكس ذلك تمامًا. لفهم الفرق أنشئ مشروعًا جديدًا وسمّه Lesson04_04 ثمّ استبدل الشيفرة الموجودة في Program.cs بالشيفرة التالية: 1 using System; 2 3 namespace Lesson04_4 4 { 5 class Program 6 { 7 static void Main(string[] args) 8 { 9 int n, sum = 0, i = 1; 10 string str_n; 11 12 Console.WriteLine("This Program calculates the series: sum = 1 + 2 + 3 + ... + n"); 13 Console.Write("Input 'n' please: "); 14 str_n = Console.ReadLine(); 15 16 n = int.Parse(str_n); 17 18 Do 19 { 20 sum += i; 21 22 i++; 23 } 24 while (i <= n); 25 26 Console.WriteLine("sum = {0}", sum); 27 } 28 } 29 } لا يختلف هذا البرنامج عن سابقيه في حساب مجموع السلسلة 1 + 2 + 3 + … + n، نفّذ البرنامج وأدخل القيمة 0 للمتغيّر n ستحصل في الخرج على المجموع sum = 1 وهذا خطأ بالطبع! السبب في ذلك أنّ اختبار شرط الاستمرار في حلقة do-while يجري بعد انتهاء الحلقة من تنفيذ أوّل دورة لها، حيث تؤدّي هذه الدورة إلى جعل قيمة المتغيّر sum تساوي 1 وقيمة i تساوي 2، وبعد ذلك يأتي اختبار الشرط i <= n والذي سيعطي false بالطبع وتتوقف الحلقة عن التكرار ولكن بعد فوات الأوان. في حلقة while (وحتى في حلقة for) لم نواجه هذه المشكلة لأنّ شرط استمرارها يجري اختباره في بداية الحلقة وقبل تنفيذ أي دورة تكراريّة. تمارين داعمة تمرين 1 اكتب برنامجًا يطبع الأعداد من 1 حتى 100 على الشاشة باستثناء الأعداد من مضاعفات العدد 5 أي على الشكل التالي: 1, 2, 3, 4, 6, 7, 8, 9, 11, … , 14, 16, … تلميح: ستحتاج في هذا التمرين إلى استخدام بنية if ضمن حلقة for واختبار قيمة التعبير المنطقي i % 5 == 0 على افتراض أنّ i هو عدّاد الحلقة. تمرين 2 اكتب برنامجًا يطلب من المستخدم إدخال عدد صحيح موجب ثمّ يوجد مضروب هذا عدد (قيمة العاملي له). فإذا أدخل عددًا سالبًا يجب على البرنامج أن ينبّه المستخدم على ذلك ويُنهي التنفيذ. تلميح: تذكّر أنّ مضروب عدد يُعبّر عن الجداءات للقيم المتناقصة لهذا العدد فمثلًا لإيجاد مضروب 5 (!5) نكتب: 5! = 5 * 4 * 3 * 2 * 1 تذكّر أيضًا أنّ !1 =1 و !0 = 1. الخلاصة تحدثنا في هذا الدرس عن الحلقات التكراريّة بأنواعها المختلفة. تدعم سي شارب عدة حلقات تكراريّة تُعتبر حلقة for من أهمّها. في الحقيقة توجد حلقة تكراريّة أخرى لم نتحدّث عنها في هذا الدرس، وهي حلقة foreach، وهي حلقة مفيدة جدًّا أجلّت الحديث عنها إلى أن نتعرّف على المجموعات Collections بأنواعها ونتعلّم التعامل معها.
  6. php 101

    سنتطرّق في هذا الدرس إلى مفهوم الحلقات في PHP، التي تسمح لك بتنفيذ تعليمات برمجية مرةً أو أكثر. فعلى سبيل المثال، لو أردت أن أطبع كلمة "hsoub" عشر مرات فعلي عندها أن أكتب الأمر echo مراتٍ عشر، لكن يمكنني عبر استعمال حلقة أن أكتب الأمر echo مرةً واحدةً لطباعة الجملة عشر مرات. هنالك أربعة أنواع من الحلقات في PHP هي: حلقة while حلقة do-while حلقة for حلقة foreach سنتعلم في هذا الدرس عن أول ثلاث حلقات لأن الرابعة متعلقة بالمصفوفات التي سنتعلمها لاحقًا، لذا سنؤجِّل شرح حلقة foreach إلى درسٍ قادم. حلقة while حلقة while هي من أبسط أشكال الحلقات في PHP، إذ تقوم هذه الحلقة بتنفيذ التعليمات البرمجية مرارًا وتكرارًا إلى أن يتحقق الشرط (أي تصبح قيمته FALSE)، ويتم التحقق من قيمة الشرط قبل كل تكرار، فلو تغيرت قيمته أثناء التنفيذ فسيستمر تنفيذ التعليمات الموجودة في الحلقة إلى نهايتها؛ وقد يتحقق شرط حلقة while من البداية (أي تكون قيمته من البداية FALSE)، وبهذا لن تُنفَّذ التعليمات الموجودة فيها أبدًا. الشكل العام للحلقة while هو: while (expr) { statments } خصائص هذا الشرط مماثلة لخصائص شرط عبارة if-else؛ فلطالما كانت قيمة الشرط true أو قيمةً ليست صفرية، فسيستمر تنفيذ الشيفرة مرارًا وتكرارًا. لنلقِ نظرةً على هذا المثال: <?php // نعطي قيمةً ابتدائية للمتغير $initial_value = 0; // أصغر من 10 هو الشرط الذي سينهي الحلقة while($initial_value < 10) { echo 'hsoub'.'<br>'; // سنزيد قيمة المتغير بمقدار 1 $initial_value++; } ?> تبدأ قيمة المتغير ‎$initial_value من القيمة 0 وسيستمر تنفيذ الحلقة لطالما كانت قيمة المتغير ‎initial_value$ أصغر من 10؛ تزداد قيمة ‎$initial_value بمقدار 1 في كل تكرار؛ وسيطبع المثال السابق الكلمة "hsoub" عشر مرات، ويُستعمَل الوسم <br> لإدراج سطرٍ جديد في مستندات HTML (لطباعة الكلمات في أسطرٍ مختلفة). تذكر أنَّ النقطة "." تجمع بين سلسلتين نصيتين. حلقة do-while هذه الحلقة مشابهة جدًا لحلقة while لكن الاختلاف بينها هو أنَّ هذه الحلقة تتحقق من قيمة الشرط بعد أن تنفِّذ الشيفرة الموجود ضمنها؛ أي أنها تتحقق من الشرط عند تكرار تنفيذ الشيفرة وليس عند تنفيذها لأول مرة. شكلها العام هو: do { statments } while (expr); مثالٌ عليها: <?php // نعطي قيمةً ابتدائية للمتغير $initial_value = 0; // أصغر من 10 هو الشرط الذي سينهي الحلقة do { echo 'hsoub'.'<br>'; // سنزيد قيمة المتغير بمقدار 1 $initial_value++; } while($initial_value < 10); ?> سيطبع هذا المثال الكلمة "hsoub" عشر مرات أيضًا، لكن الاختلاف يكمن فيما لو كانت القيمة الابتدائية للمتغير ‎$initial_value أكبر أو تساوي 10، ففي هذا الحالة لن تُنفَّذ حلقة while بينما ستُنفَّذ حلقة do-while. أي أنها ستنفَّذ مرةً واحدةً على الأقل. لاحظ وجود الفاصلة المنقوطة بعد while في حلقة do-while. حلقة for الشكل العام لحلقة for هو: for (initialize; condition; operation) { statments } لنأخذ مثالًا قبل أن نناقش آلية عمل هذه الحلقة: <?php // تهيئة المتغير داخل الحلقة for($initial = 0; $initial <10; $initial++) { echo 'hsoub'.'<br>'; } // تهيئة المتغير خارج الحلقة $initial_value = 0; for (; $initial_value < 10; $initial_value++) { echo 'hsoub'.'<br>'; } ?> شاهدنا -في أول نوعين من الحلقات- كيف أننا نهيّئ متغيرًا، ثم علينا التحقق من الشرط في الحلقة كي تُنفَّذ، ثم في النهاية علينا تعديل قيمة المتغير (زيادةً أو نقصانًا). لكننا نجري الخطوات الثلاث السابقة في مكانٍ وحيد في حلقة for. تأخذ الحلقة for ثلاثة وسائط (arguments): القيمة الابتدائية (initialize): وهي مماثلة لأول نوعين من الحلقات. يمكننا تهيئة المتغيرات في حلقة for بطريقتين، الأولى داخل الحلقة (بين الأقواس) والأخرى قبل الحلقة. لاحظ طريقة الكتابة في المثال السابق؛ حيث يُفصَل بين كل وسيط والآخر بفاصلة منقوطة؛ وإذا كنت تُهيّئ القيمة خارج الحلقة، فلا تنسَ أن تضع الفاصلة المنقوطة حتى ولو كانت القيمة فارغة. الشرط (condition): وهو يقارن بين قيمة المتغير الذي تمت تهيئته والقيمة المعطية. العملية (operation): وهي التي ستعدِّل في قيمة المتغير بعد نهاية تنفيذ كل تكرار للحلقة. أمثلة إضافية لا يكفي الشكل العام للأوامر والتعليمات لتعلم لغة البرمجة وفهمها فهمًا تامًا؛ لنحاول الآن استيعاب هذه الأمثلة: <?php // طباعة الأرقام من 10 إلى 0 for ($number=10; $number >= 0; $number--) { echo $number.'<br>'; } ?> <?php // زيادة الرقم بمقدار 2 في كل دورة for ($number=0; $number < 10; $number+=2) { echo $number.'<br>'; } ?> نجد -في المثال أعلاه- المعامل "‎+=‎" الذي يُضيف القيمة على الجانب الأيمن إلى قيمة المتغير على الجانب الأيسر؛ يمكنك أيضًا استعمال هذه المعاملات: "‎*=‎": الضرب، مثال ‎$number *= 2‎ "‎-=‎": الطرح "‎/=‎": القسمة "‎%=‎": باقي القسمة "‎^=‎": القوة (أو الأس) سنكتب الآن برنامجًا لطباعة مضاعفات الرقم 5 بين العددين 1 و 100؛ تذكَّر أن المعامل % يُعيد باقي القسمة. <?php for ($number=1; $number < 100; $number++) { if ($number % 5 == 0) { echo $number.'<br>'; } } ?> الشكل البديل لبنى التحكم تدعم PHP شكلًا بديلًا لأقواس بنى التحكم التي هي if، و while، و for، و foreach، و switch؛ وطريقة استعمال الشكل البديل هي وضع نقطتين رأسيتين (:) بدلًا من قوس البداية، واستبدال قوس النهاية بالكلمات "endif;‎"، أو "endwhile;‎"، أو "‎endfor;‎"، أو "endforeach;‎" (سنناقش تلك الحلقة في درسٍ لاحق)، أو "endswitch;‎" على التوالي وبالترتيب. <?php if ($a == 5): ?> A is equal to 5 <?php endif; ?> قسم HTML في المثال السابق (A is equal to 5) موجودٌ ضمن جملة if شرطية مكتوبة بالشكل البديل، لاحظ أن تمييز بداية ونهاية بنى التحكم أسهل عند دمج HTML مع PHP. ستظهر جملة "A is equal to 5" فقط إن كانت قيمة المتغير ‎$a مساوية للرقم 5. يمكن تطبيق الشكل البديل على عبارات else و elseif أيضًا. هذا مثالٌ عنها بالشكل البديل: <?php if ($a == 5): echo "a equals 5"; echo "..."; elseif ($a == 6): echo "a equals 6"; echo "!!!"; else: echo "a is neither 5 nor 6"; endif; ?> تمرين اكتب برنامجًا فيه حلقتين متداخلتين لطباعة جدول الضرب للأعداد من 1 إلى 9؛ حيث يكون ناتج خرجه هو: 1 2 3 4 5 6 7 8 9 2 4 6 8 10 12 14 16 18 3 6 9 12 15 18 21 24 27 4 8 12 16 20 24 28 32 36 5 10 15 20 25 30 35 40 45 6 12 18 24 30 36 42 48 54 7 14 21 28 35 42 49 56 63 8 16 24 32 40 48 56 64 72 9 18 27 36 45 54 63 72 81 حاول أن تشغل السكربت السابق من سطر الأوامر (استعمل ‎\t لإدراج مسافة جدولة [tab]، و ‎\n لإدراج سطر جديد). المصادر مقال Loops in PHP لصاحبه Harish Kumar. صفحات while، و do-while، و for، و Alternative syntax في دليل PHP وغيرها.
  7. 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.