واحد من أهم المفاهيم التي يجب عليك تعلمها واكتسابها جيداً في علم البرمجة هو مفهوم التحكم في تدفق البيانات Control flow والذي يمكن تبسيطه باختصار بآنه كتابة آكواد برمجية يمكنها ان تتخذ قرارات حول الاكواد البرمجية التي تليها اما بتنفيذها او تجاهلها حسب حالتها.

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

المثال السابق يصف احد اهم ادوات التحكم في تدفق البيانات، وهو القيام بعده عمليات من التحقق وتنفيذ الاكواد المناسبة حسب نتائج التحقق. هذه التحققات في البرمجة يطلق عليها اسم العبارات الشرطية وهي جزء من مفهوم التحكم في تدفق البيانات الواسع. العبارات الشرطية التي سيتم استعمالها في سويفت هي الموجودة في بقية لغات البرمجة والتي تتضمن if و if-else و switch. 

المعاملات المنطقية

كل عبارة شرطية if تستخدم معامل منطقي لكي يتحقق من حالة شيئ ما هل هو true او false. ونتيجة التحقق هذه ستكون Bool آيضاً (true او false) وهي التي ستحدد هل سيتم تشغيل كود برمجي اخر مرتبط بعبارة if أو سيتم تجاهلها بالكامل والنزول للكود الذي يليها في الترتيب. 

سنلتقي نظرة سريعة على اهم المعاملات المنطقية التي يمكنك استخدامها للتحقق:

  • ==   القيمتان تتساوى معاً
  • !=    القيمتان لا تساوي احداهما الاخرى
  • >     القيمة على اليسار تكون آكبر من التي على اليمين
  • >=   القيمة على اليسار تكون اكبر من او تساوي التي على اليمين
  • <     القيمة على اليسار تكون آصغر من التي على اليمين
  • <=   القيمة على اليسار تكون اصغر من او تساوي التي على اليمين
  • &&  العبارات علي اليمين (و) اليسار تكون جميعها true
  • ||     العبارات على اليمين (أو) اليسار تكون منها واحدة على الاقل true
  • !     عكس حالة العبارة الشرطية للحالة المقابلة. اذا كانت true تصبح false والعكس صحيح

عبارات if الشرطية

العبارة الشرطية الاكثر وضوحها ومباشرة هي if "اذا باللغة العربية" فحينما تستخدمها كأنك تقول للبرنامج (اذا كان هذا الشرط true فقم بتنفيذ الكود التالي، واذا كان false فتجاوز كامل الكود ولا تنفذه).

في معظم الحالات يتم استخدام عبارات if للتحقق من حالات بسيطة مع عدد محدود من  الاحتمالات التي يمكن اخراجها. شاهد المثال ستجد العبارة الشرطية موضحة بخط عريض:

let temperature = 100 if temperature >= 100{ print("The water is boiling.") }  // هذا الكود سيطبع النص The water is boiling.

في المثال السابق عبارة التحقق تشترط ان يكون قيمة المتغير تساوي او آكبر من 100، وقيمة المتغير بالفعل هي كذلك بالتالي اصبحت نتيجة الحالة الشرطية صحيحة true وتم تنفيذ الكود.

عبارات if-else الشرطية

كما تعلمنا مع if الشرطية٬ حينما لا تتحقق الحالة الشرطية وتكون النتيجة false فإن الكود الخاص بها لن يتم تنفيذه، وفي تلك الحالة سيتم تجاهل الكود تماماً الا اذا اضفت له عبارة تقوم بتنفيذ كود برمجي اخر في حال لم تتحقق الحالة الشرطية الاولى. كآنك تقول لسويفت اذا لم يمكن الكود الشرطي الاساسي true فقم بتنفيذ هذا الكود البديل او الافتراضي. يمكنك القيام بذلك من خلال استخدام عبارة else كما في المثال التالي:

let temperature = 90 if temperature >= 100{ print("The water is boiling.") } else { print("The water is not boiling.") }  // هذا الكود سيطبع العباره الثانية The water is not boiling.

في المثال السابق لم تتحقق الحالة الشرطية الاساسية if لان قيمت المتغير ليست اكبر من 100 بالتالي اعطتنا false وتم الانتقال للحالة الثانية البديلة التي طلبنا من سويفت طباعتها كحالة بديلة.

يمكنك ايضاً اضافة المزيد من الحالات الشرطية الاضافية بعدد غير محدود من خلال استعمال else-if على التوالي تحت العبارة الشرطية الاساسية if وسيتم التحقق من حالتها وتنفيذ واحدة منها فقط. عملية التحقق تبدأ من الاعلى الى الاسفل لكل حالات if و else-if وصولاً الى النهاية اذا كانت لديك حالة افتراضية else ليتم تنفيذها في حال لم تتحقق اي من عبارات if التي تسبقها:

var finishPosition = 2  if finishPosition == 1 {   print("Congratulations, you won the gold medal!") } else if finishPosition == 2 {   print("You came in second place, you won a silver medal!") } else {   print("You did not win a gold or silver medal.") }  // هذا الكود سيطبع العابرة الثانية else-if 

التحقق من حالات متعددة

تحدثنا في بداية هذا المقال عن المعاملات المنطقية في لغات البرمجة وذكرنا مجموعة من ابرزها في لغه سويفت وكان من ضمنها (&&) و (||) التي تسمح لك بالتحقق من اكثر من حالة بعدد غير محدود في عبارة if واحدة وسنشرح فيما يلي كل واحدة منها.

بوابات AND &&

في علم الحاسوب بوابات And تعني ان كل الحالات يجب ان تكون true حتى تتحقق العبارة الشرطية بالكامل، ولو كان لديك 4 حالات جميعها كانت true ماعدا واحدة false فإن كامل العبارة المنطقية ستعتبر false وسيتم تجاوزها للكود الذي اسفلها. المثال التي يوضح استخدام بوابات AND من خلال المعامل الخاص بها &&:

let temperature = 70  if temperature >= 65 && temperature <= 75 {   print("The temperature is just right.") } else if temperature < 65 {   print("It is too cold.") } else {   print("It is too hot.") }  // هذا الكود سيطبع The temperature is just right.

في المثال تحققت العبارة الشرطية المكونة من حالتين لآن كلا القيمتين تعطي نتيجة true وقد تم استخدام بوابة And && من اجل التحقق من اكثر من حاله واحدة كما شرحنا.

بوابات OR || 

في علم الحاسوب بوابات OR تعني ان واحدة من الحالات على الاقل يجب ان تكون true حتى يتم تتحقق العبارة الشرطية مهما كان عدد الحالات التي تتضمنها. بالتالي true واحد في عباره شرطية من 20 حالة false سيجعلها كلها true ويتم تنفيذ الكود. شاهد المثال علي استخدام بوابات OR من خلال المعامل ||:

var isPluggedIn = false var hasBatteryPower = true  if isPluggedIn || hasBatteryPower {   print("You can use your laptop.") } else {   print("Douh!") }  // هذا الكود سيطبع You can use your laptop.

في الكود السابق استخدمنا OR للتحقق من الحالتين التي لدينا وكآننا نقول لسويفت اننا نريد على الاقل حاله واحدة منها لتكون true حتى نطبع تلك العباره٬ بلغه ابسط كآننا نقول للمستخدم يجب ان يكون الابتوب متصل بالتيار الكهربائي او يملك بطاريه داخليه حتى يمكن استعماله والا فلن تستطيع. امر منطقي بسيط يقودنا للحديث عن القيم المنطقية في الجزء التالي من المقال. :)

القيم المنطقية

يمكنك استعمال نتيجة تحقق المعاملات المنطقية التي تستخدمها في الكود الخاص بك لانشاء متغيرات جديدة من نوع Bool بالتالي يتم تخزين تلك النتائج في المتغيرات الجديدة لاعادة استعمالها اكثر من مره في البرنامج. انت تتذكر ان نتائج المعاملات المنطقية لا تكون الا true او false بالتالي المتغير الجديد سيكون Bool فقط.

let number = 1000 let isSmallNumber = number < 10 

في المثال السابق بالسطر الثاني طلبنا من سويفت انشاء let جديد اسمه isSmallNumber وقيمته ستكون هي نتيجة التحقق من قيمة number هل هو اصغر من 10 ام لا. النتيجة ستكون false بالتي المتغير  isSmallNumber ستكون قيمته دوماً false حينما تستخدمه مره اخرى في البرنامج.

let speedLimit = 65 let currentSpeed = 72 let isSpeeding = currentSpeed > speedLimit // currentSpeed is greater than the speedLimit, so  isSpeeding is assigned a `true` value

في المثال السابق انشأنا 2 let بقيم محددة ثم انشأنا let ثالث اسمه isSpeeding وقيمته ستكون اما true او false وهي نتيجة مقارنه هل currentSpeed آكبر من speedLimit وهو بالفعل اكبر منه بالتالي قيمة isSpeeding ستكون true.

var isSnowing = false  if isSnowing { print("It is not snowing.") }  // هذا الكود لن يطبع شيئ بسبب عدم تحقق الحالة الشرطية

في المثال السابق يمكنك استخدام قيمة المتغير isSnowing في داخل عبارة شرطية مباشرة. كأنك تطلب من سويفت  ان ينفذ الكود اذا كانت نتيجة المتغير true  فقط.

ويمكنك ان تطلب منه العكس باستعمال معامل NOT الذي تمثله علامة التعجب (!) قبل المتغير في العبارة الشرطية بالتالي سويفت ستنفذ الكود في حالة كانت قيمتة المتغير false فقط كما في المثال التالي:

var isSnowing = false  if !isSnowing { print("It is not snowing.") }  // هذا الكود سيطبع It is not snowing.

عبارات switch الشرطية

تعلمنا فيما سبق انه يمكن استخدام if و else-if من اجل القيام بعمليات التحقق من عدة عبارات شرطية تمثل حالات مختلفة المطلوب التحقق منها جميعاً من الاعلى للاسفل من اجل تنفيذ حالة واحدة منها فقط. هذه الطريقة تميل الى الفوضى كثيراً في حال كنت تملك حالات كثير وستجعل قراءة الكود مهمة صعبه، بالتالي يكون الحل في استخدام خاصية switch التي تعتبر شكل مطور من if لانها تسمح لك بإدارة الاحتمالات المتعددة ولكن بشكل اكثر تنظيماً وسهولة.

استخدام switch يتم بآن تاخذ متغير ما تريد تقارنته مع مجموعة من الاحتمالات ليتم تنفيذ كود مختلف مخصص لكل حالة من الاحتمالات التي تزودها به. سويفت ستنفذ الكود الذي تتطابق حالته case مع قيمة المتغير الذي حددته مع switch ثم تتجاهل كل الحالات المتبقية لان ايجاد نتيجة واحدة متطابقه سيكفي لاعتبار عبارة switch متحققة. شاهد المثال التالي:

let numberOfWheels = 2 switch numberOfWheels { case 1:     print("Unicycle") case 2:     print("Bicycle") case 3:     print("Tricycle") case 4:     print("Quadcycle") default:      print("That's a lot of wheels!") }  // هذا الكود سيطبع Bicycle

كما شاهدت في المثال تم طباعه العبارة التي تملك case 2 لانها تساوي قيمة المتغير numberOfWheels. وبعد تنفيذ ذلك الكود اعتبرت سويفت كامل عبارة switch متحققة لانها وجدت القيمة المناسبة فلا داعي للتحقق من بقية الحالات. ايضاً كملاحظة مهمة انظر الى الكود ستجد انه يتضمن حالة تسمى default هي الحالة الافتراضية في حال كان المتغير numberOfWheels يمثل قيمة مختلفة عن كل الحالات التي تتضمنها عبارة switch. بعباره اخرى default تشابه تماماً الفكره والهدف من else مع عبارات if الشرطية. بالطبع كان يمكن كتابة كامل الكود السابق باستخدام if و else-if ولكن مع switch الكود اسهل واوضح بكثير وهذا اهم مايجب عليك ان تتعلمه وتمارسه كمبرمج ناجح لتكتب اكواد يقرأها غيرك بسهولة.

مع عبارات switch يمكنك ان تضيف عدة حالات في حالة او case واحد كما في المثال التالي للتحقق من احرف العلة في اللغة الانجليزية:

let character = "z"  switch character { case "a", "e", "i", "o", "u" :     print("This character is a vowel.") default:      print("This character is a consonant.") }  // هذا الكود سيطبع This character is a consonant.

اما بالنسبة للتحقق من الارقام المتعددة مع switch فيمكنك ان تضيف كل مجموعة من الارقام في مدى معين بين ثلاث نقاط (...) حتى تقلل عدد الحالات قدر الامكان وتجعل كودك اسهل واوضح كما في المثال التالي:

var distance = 50  switch distance { case 0...9: // يتحقق بين الارقام من 0 الى 9     print("Your destination is close.") case 10...99: // يتحقق بين الارقام من 10 الى 99     print("Your destination is a medium distance from here.") case 100...999: // يتحقق بين الارقام من 100 الى 999     print("Your destination is far from here.") default:      print("Are you sure you want to travel this far?") }  // هذا الكود سيطبع Your destination is a medium distance from here.

المعامل الثلاثي Ternary Operator

في سويفت والكثير من لغات البرمجة يوجد طريقة مختصرة وبديلة لكتابة if-else متعددة الاسطر. هي ليست ضرورية ولكنها مفيدة من باب الاختصار ولذلك سنشرحها هنا. 

الطريقة تكون باستخدام المعامل الثلاثي الذي يرمز له بالرمز (: ؟)  والذي يتكون من ثلاثه عناصر:

  • سؤال منطقي يوضع قبل (؟)اجابته true او false.
  • قيمة محددة بعد (:) اذا كانت اجابة السؤال السابق true.
  • قيمة محددة بعد (:) اذا كانت اجابة السؤال السابق false.

شاهد المثال التالي:

var largest: Int let a = 15 let b = 4  largest = a > b ?a:b

في المثال السابق قلنا لسويفت اذا كان a أكبر من b فقم بجعل a قيمة للمتغير largest. اذا لم يكن a أكبر من b فقم بجعل b كقيمة للمتغير largest.

ومن اجل الاسهاب في الشرح انظر للمثال السابق لو تمت كتابتة من خلال else-if:

var largest: Int let a = 15 let b = 4  if a > b {     largest = a } else {     largest = b }

كان هذا كل شيء هام عن تدفق البيانات في سويفت. اتمنى ان لا تتردد في مشاركتي بآي استفسار او تعليق على حسابي في تويتر كما اتطلع لانضمام المزيد من المتعلمين على قناة سلاك حتى نستمتع بالتعلم معاً.



-------------------------------

# تحديث1: أحاول في مجموعة سلاك اعداد تمارين تفاعلية من اعدادي واضيف عليها تمارين كتاب Apple التعليمي حتى ترسخ الفهم للمبتدئين تماماً وسأضع هنا التمارين الخاصة بهذا المقال. بإمكانك ارسال الحل لنا في مجموعة سلاك اطلب دعوة من حسابي في تويتر.


التمرين الأول  اطبع كود يتحقق من الساعة بتوقيتك حينما تكون تحل هذا التمرين بحيث يقوم الكود بعرض رسالة ترحيبية حسب الوقت بنظام 24 ساعة كالتالي: من الساعة 5 فجراً الى 12 صباحاً يطبع "Good morning" ومن الساعة 13 ظهراً الى الساعة 18 مساءً يطبع "Good afternoon" ومن الساعة 19 مساءً الى الساعة 4 فجراً يطبع "Good evening"   ----------------  التمرين الثاني   لنفرض ان هناك مسافر يحمل حقيبة وزنها 25 كيلو. قم بعمل كود يتحقق من وزن الحقيبة ثم يطبع له رسالة حسب الوزن كالتالي:  اذا كانت الحقيبة تزن أقل من 20 كيلو يطبع العبارة التالية (نتمنى لك رحلة سعيدة)  اذا كانت الحقيبة تزن اكثر من 20 كيلو يطبع له العبارة التالية (يوجد رسوم تبلغ 50 ريال بسبب تجاوز الوزن المسموح للحقائب)   -----------  التمرين الثالث   لنفرض ان هناك طالب يدعى أحمد حاز على درجة 78 في مادة الرياضيات في نتائج اختباراته الجامعية  استخدم ماتعلمته عن switch  لكتابة كود يتحقق من نتيجة أحمد ليظهر له تقديره في هذه المادة حسب الجدول التالي:  A+ = 95 - 100 A = من 90 الى اقل من 95 B+ = من 85 الى اقل من 90 B = من 80 الى اقل من 85 C+ = من 75 الى اقل من 80 C = من 70 الى اقل من 75 D+ = من 65 الى اقل من 70 D = من 60 الى اقل من 65 F = أقل من 60 راسب   -------------------   اسئلة اضافية  // أي من المعاملات التالية يستخدم للتحقق من قيمة المتغير  A. =  B. == C. != D. >=    // أي من المعاملات التالية يعني NOT لعكس قيمة المتغير  A. !=  B. ! C. || D. <  // اي من المعاملات التالية يعني "أكبر من"؟  A. < B. > C. <= D. >=  // اي من المعاملات التالية يعني "أكبر من او يساوي"؟  A. < B. > C. <= D. >=  // اي من المعاملات التالية يعني "و"؟ AND  A. ! B. || C. && D. !=  // اي من المعاملات التالية يعني "أو"؟ OR  A. ! B. || C. && D. !=