You are on page 1of 418

‫البرمجة بلغة بايثون‬

‫تعلم البرمجة وكتابة البرامج وتنقيحها بلغة بايثون‬

‫تأليف‬

‫ليزا تاغليفيري‬

‫ترجمة‬

‫محمد بغات‬
‫عبد اللطيف ايمش‬

‫تحرير‬

‫جميل بيلوني‬

‫تصميم الغالف‬

‫فرج الشامي‬
‫أكاديمية حسوب © النسخة األولى ‪2020‬‬

‫صنف ‪ -‬غير‬
‫الم َّ‬
‫مرخص بموجب رخصة المشاع اإلبداعي‪ :‬نَ سب ُ‬
‫َّ‬ ‫هذا العمل‬

‫تجاري ‪ -‬الترخيص بالمثل ‪ 4.0‬دولي‬


‫عن الناشر‬
‫ُأ‬
‫نتج هذا الكتاب برعاية شركة حسوب وأكاديمية حسوب‪.‬‬

‫أكاديمية حسوب‬
‫تهدف أكاديمي ة حس وب إلى توف ير مق االت ودروس‬

‫ة وبلغة‬ ‫االت مُ ختلف‬ ‫ول مج‬ ‫ودة ح‬ ‫ة الج‬ ‫عالي‬

‫عربية فصيحة‪.‬‬

‫تق دم أكاديمي ة حس وب دورات ش املة بج ودة عالي ة‬

‫عن تعلم البرمج ة بأح دث تقنياته ا تعتم د على التط بيق‬

‫العملي‪ ،‬مما يؤهل الطالب لدخول سوق العمل بثقة‪.‬‬

‫تتكامل األكاديمية م ع موس وعة حس وب‪ ،‬ال تي ت وفر‬

‫عربيا شاماًل مدعمً ا باألمثلة للغات البرمجة‪.‬‬


‫ً‬ ‫ً‬
‫توثيقا‬

‫ب اب المُ س اهمة في األكاديمي ة مفت وح لك ل من ي رى‬

‫في نفس ه الق درة على توف ير مق االت أو كتب أو مس ارات‬

‫عالية الجودة‪.‬‬

‫‪Academy.hsoub.com‬‬
‫شركة حسوب‬

‫ته دف حس وب لتط وير ال ويب الع ربي وخ دمات اإلن ترنت‬

‫عن طري ق توف ير حل ول عملي ة وس هلة االس تخدام لتح ديات‬

‫مختلفة تواجه المستخدمين في العالم العربي‪.‬‬

‫تش جع حس وب الش باب الع ربي لل دخول إلى س وق العم ل‬

‫عن بع د بتوفيره ا منص ات عربي ة للعم ل عن بع د‪ ،‬مس تقل‬

‫ً‬
‫افة إلى موق ع بعي د‪ ،‬وكم ا أنه ا ت وفر خ دمات‬ ‫وخمس ات؛ إض‬

‫للنقاش ات الهادف ة في حس وب ‪ I/O‬وخدم ة رف ع الص ور ع بر‬

‫موقع صور‪.‬‬

‫يعمل في حسوب فريق شاب وش غوف من مختل ف ال دول‬

‫العربي ة‪ .‬ويمكن معرف ة المزي د عن ش ركة حس وب والخ دمات‬

‫التي تقدمها بزيارة موقعها‪.‬‬

‫‪Hsoub.com‬‬
‫▲‬

‫جدول المحتويات‬
‫تقديم ‪15..............................................‬‬
‫‪ .1‬كيفية استخدام هذا الكتاب‪17..................................‬‬

‫‪ .2‬ماذا بعد هذا الكتاب‪18...........................................‬‬

‫مدخل تعريفي إلى لغة بايثون‪20...............‬‬


‫‪ .1‬تاريخ بايثون‪22....................................................‬‬

‫‪ .2‬مميزات لغة بايثون‪22............................................‬‬

‫‪ .3‬أين ُتستخ َدم بايثون؟‪23.........................................‬‬

‫‪ .4‬لماذا بايثون وليس غيرها؟‪24...................................‬‬

‫‪ .5‬خالصة الفصل‪27..................................................‬‬

‫تثبيت بايثون وإعداد بيئة العمل‪28..............‬‬


‫‪ .1‬ويندوز ‪30...........................................................‬‬

‫‪ .2‬أوبنتو‪41.............................................................‬‬

‫‪ .3‬دبيان ‪47.............................................................‬‬

‫‪54..........................................................CentOS .4‬‬

‫‪60...........................................................macOS .5‬‬

‫سطر أوامر بايثون التفاعلي‪70...................‬‬


‫‪ .1‬فتح سطر األوامر التفاعلي‪71...................................‬‬
‫‪ .2‬العمل في سطر أوامر بايثون التفاعلي‪73.....................‬‬

‫‪ .3‬تع ُّدد األسطر ‪74....................................................‬‬

‫‪ .4‬استيراد الوحدات‪75..............................................‬‬

‫‪ .5‬الخروج من سطر أوامر بايثون التفاعلي‪77 ..................‬‬

‫‪ .6‬االطالع على التاريخ ‪78..........................................‬‬

‫‪ .7‬خالصة الفصل‪79..................................................‬‬

‫التعليقات واستخداماتها ‪80......................‬‬


‫‪ .1‬صياغة التعليقات‪81...............................................‬‬

‫‪ .2‬التعليقات الكتلية‪83...............................................‬‬

‫‪ .3‬التعليقات السطرية‪84............................................‬‬

‫‪ .4‬تعليق جزء من الشيفرة بدواعي االختبار والتنقيح‪85 .....‬‬

‫‪ .5‬خالصة الفصل‪87..................................................‬‬

‫المتغيرات واستخداماتها‪88.......................‬‬
‫‪ .1‬فهم المتغيرات‪89..................................................‬‬

‫‪ .2‬قواعد تسمية المتغيرات‪93......................................‬‬

‫‪ .3‬تغيير قيم المتغيرات‪95..........................................‬‬

‫‪ .4‬اإلسناد المتعدد (‪96..................)Multiple Assignment‬‬

‫‪ .5‬المتغيرات العامة والمحلية‪97...................................‬‬

‫‪ .6‬خالصة الفصل‪102................................................‬‬

‫أنواع البيانات والتحويل بينها‪103................‬‬


‫‪ .1‬خلفية عامة‪104....................................................‬‬

‫‪ .2‬األعداد‪105..........................................................‬‬

‫‪ .3‬القيم المنطقية‪107................................................‬‬
‫‪ .4‬السالسل النصية‪109..............................................‬‬

‫‪ .5‬القوائم (‪110................................................)Lists‬‬

‫‪ .6‬الصفوف (‪111...........................................)Tuples‬‬

‫‪ .7‬القواميس ( ‪112..................................)Dictionaries‬‬

‫‪ .8‬التحويل بين أنواع البيانات‪113................................‬‬

‫‪ .9‬خالصة الفصل‪125................................................‬‬

‫السالسل النصية والتعامل معها‪127...........‬‬


‫‪ .1‬إنشاء وطباعة السالسل النصية‪128...........................‬‬

‫‪ .2‬آلية فهرسة السالسل النصية‪129...............................‬‬

‫‪ .3‬تقسيم السالسل النصية‪131.....................................‬‬

‫‪ .4‬جمع السالسل النصية‪135........................................‬‬

‫‪ .5‬تكرار السالسل النصية‪136......................................‬‬

‫‪ .6‬تخزين السالسل النصية في متغيرات‪136 ...................‬‬

‫‪ .7‬دوال السالسل النصية‪137.......................................‬‬

‫‪ .8‬دوال اإلحصاء ‪143................................................‬‬

‫‪ .9‬خالصة الفصل‪146................................................‬‬

‫مدخل إلى تنسيق النصوص‪147.................‬‬


‫‪ .1‬الصياغة المختزلة‪148............................................‬‬

‫‪ .2‬عالمات االقتباس‪148.............................................‬‬

‫‪ .3‬كتابة النص على أكثر من سطر‪149............................‬‬

‫‪ .4‬تهريب المحارف‪150..............................................‬‬

‫‪ .5‬السالسل النصية الخام‪152......................................‬‬

‫نسقات ‪153..........................................‬‬
‫‪ .6‬استخدام المُ ِّ‬

‫‪ .7‬تحديد نوع القيمة‪161............................................‬‬


‫‪ .8‬إضافة حواشي‪163................................................‬‬

‫‪ .9‬استخدام المتغيرات‪165..........................................‬‬

‫‪ .10‬خالصة الفصل‪166...............................................‬‬

‫العمليات الحسابية ‪167.............................‬‬


‫‪ .1‬العامالت‪168........................................................‬‬

‫‪ .2‬الجمع والطرح‪170.................................................‬‬

‫‪ .3‬العمليات الحسابية األحادية‪171................................‬‬

‫‪ .4‬الضرب والقسمة ‪172..............................................‬‬

‫‪ .5‬عامل باقي القسمة (‪174.............................)Modulo‬‬

‫‪ .6‬القوة (‪174................................................)Power‬‬

‫‪ .7‬أسبقية العمليات الحسابية‪175.................................‬‬

‫‪ .8‬عامل اإلسناد (‪176 ................)Assignment Operators‬‬

‫‪ .9‬إجراء العمليات الرياضية عبر الدوال‪178.....................‬‬

‫‪ .10‬خالصة الفصل‪186...............................................‬‬

‫العمليات المنطقية (البوليانية)‪187.............‬‬


‫‪ .1‬عامل الموازنة‪188.................................................‬‬

‫‪ .2‬العامالت المنطقية‪191............................................‬‬

‫‪ .3‬جداول الحقيقة (‪194..........................)Truth Tables‬‬

‫‪ .4‬استعمال المنطق للتحكم في مسار البرنامج‪196 ............‬‬

‫‪ .5‬خالصة الفصل‪197................................................‬‬

‫النوع ‪ :List‬مدخل إلى القوائم‪198...............‬‬


‫‪ .1‬فهرسة القوائم ( ‪200..........................)Indexing Lists‬‬

‫‪ .2‬تعديل عناصر القائمة‪202........................................‬‬


‫‪ .3‬تقطيع القوائم (‪202..............................)Slicing Lists‬‬

‫‪ .4‬تعديل القوائم بالعوامل‪205.....................................‬‬

‫‪ .5‬إزالة عنصر من قائمة‪207........................................‬‬

‫‪ .6‬بناء قوائم من قوائم أخرى موجودة‪208 .....................‬‬

‫‪ .7‬استخدام توابع القوائم‪209......................................‬‬

‫‪ .8‬فهم كيفية استعمال ‪217............List Comprehensions‬‬

‫‪ .9‬خالصة الفصل‪223................................................‬‬

‫النوع ‪ :Tuple‬فهم الصفوف‪225..................‬‬


‫‪ .1‬فهرسة الصفوف‪227..............................................‬‬

‫‪ .2‬تقطيع قيم صف‪229..............................................‬‬

‫‪ .3‬إضافة بنى صف إلى بعضها‪231................................‬‬

‫‪ .4‬دوال التعامل مع الصفوف‪233..................................‬‬

‫‪ .5‬كيف تختلف بنى الصفوف عن القوائم‪235...................‬‬

‫‪ .6‬خالصة الفصل‪236................................................‬‬

‫النوع ‪ :Dictionary‬فهم القواميس‪237..........‬‬


‫‪ .1‬الوصول إلى عناصر قاموس‪239...............................‬‬

‫‪ .2‬تعديل القواميس‪243.............................................‬‬

‫‪ .3‬حذف عناصر من القاموس‪247.................................‬‬

‫‪ .4‬خالصة الفصل‪249................................................‬‬

‫التعليمات الشرطية ‪250............................‬‬


‫‪ .1‬التعليمة ‪251......................................................if‬‬

‫‪ .2‬التعليمة ‪253..................................................else‬‬

‫‪ .3‬التعليمة ‪254................................................else if‬‬


‫‪ .4‬تعليمات ‪ if‬المتشعبة‪257.........................................‬‬

‫‪ .5‬خالصة الفصل‪262................................................‬‬

‫المهام التكرارية‪ :‬مدخل إلى الحلقات‪263.....‬‬


‫‪ .1‬حلقة التكرار ‪264...........................................while‬‬

‫‪ .2‬حلقة التكرار ‪272..............................................for‬‬

‫‪ .3‬التحكم بحلقات التكرار‪282......................................‬‬

‫‪ .4‬خالصة الفصل‪287................................................‬‬

‫الدوال‪ :‬تعريفها واستعمالها‪288...............‬‬


‫‪ .1‬تعريف دالة ‪289....................................................‬‬

‫‪ .2‬المعامالت‪ :‬تمرير بيانات للدوال‪291...........................‬‬

‫‪ .3‬الوسائط المسمَّ اة ‪293.............................................‬‬

‫‪ .4‬القيم االفتراضية للوسائط‪295..................................‬‬

‫‪ .5‬إعادة قيمة‪296.....................................................‬‬

‫رئيسية‪299.............................‬‬
‫ً‬ ‫ً‬
‫دالة‬ ‫‪ .6‬استخدام )(‪main‬‬

‫‪ .7‬استخدام ‪ *args‬و ‪305...............................**kwargs‬‬

‫‪ .8‬ترتيب الوسائط‪310...............................................‬‬

‫‪ .9‬استخدام ‪ *args‬و ‪311...............................**kwargs‬‬

‫‪ .10‬خالصة الفصل‪313...............................................‬‬

‫الوحدات‪ :‬استيرادها وإنشاؤها‪314..............‬‬


‫‪ .1‬تثبيت الوحدات‪316..............................................‬‬

‫‪ .2‬استيراد الوحدات‪317.............................................‬‬

‫‪ .3‬استيراد عناصر مح َّددة‪320......................................‬‬

‫‪ .4‬األسماء المستعارة في الوحدات‪321 ..........................‬‬


‫مخصصة واستيرادها‪322......................‬‬
‫َّ‬ ‫‪ .5‬كتابة وحدات‬

‫‪ .6‬الوصول إلى الوحدات من مجلد آخر‪326.....................‬‬

‫‪ .7‬خالصة الفصل‪329................................................‬‬

‫بناء األصناف واستنساخ الكائنات‪330...........‬‬


‫‪ .1‬األصناف‪331........................................................‬‬

‫‪ .2‬الكائنات‪332........................................................‬‬

‫‪ .3‬الباني (‪334........................................)Constructor‬‬

‫‪ .4‬العمل مع عدة كائنات‪337........................................‬‬

‫‪ .5‬فهم متغيرات األصناف والنسخ‪338 ...........................‬‬

‫‪ .6‬العمل مع متغيرات الصنف والنسخة معً ا‪343.................‬‬

‫‪ .7‬خالصة الفصل‪344................................................‬‬

‫مفهوم الوراثة في البرمجة‪346.................‬‬


‫‪ .1‬ما هي الوراثة؟‪347................................................‬‬

‫‪ .2‬األصناف األساسية‪348...........................................‬‬

‫‪ .3‬األصناف الفرعية ‪350.............................................‬‬

‫‪ .4‬إعادة تعريف توابع الصنف األساسي‪353 .....................‬‬

‫‪ .5‬الدالة )(‪ super‬وفائدتها في الوراثة‪355.......................‬‬

‫تعددة (‪358...............)Multiple Inheritance‬‬


‫ِّ‬ ‫‪ .6‬الوراثة المُ‬

‫‪ .7‬خالصة الفصل‪360................................................‬‬

‫التعددية الشكلية وتطبيقاتها‪361.............‬‬


‫‪ .1‬ما هي التعددية الشكلية (‪)Polymorphism‬؟‪362 ...........‬‬

‫‪ .2‬إنشاء أصناف متعددة األشكال‪363............................‬‬

‫‪ .3‬التعددية الشكلية في توابع األصناف‪365.....................‬‬


‫‪ .4‬التعددية الشكلية في الدوال‪366...............................‬‬

‫‪ .5‬خالصة الفصل‪368................................................‬‬

‫منقح بايثون‪369 ..‬‬


‫ِّ‬ ‫تنقيح الشيفرات‪ :‬استخدام‬
‫تفاعليا‪370...............................‬‬
‫ً‬ ‫‪ .1‬تشغيل منقح بايثون‬

‫‪ .2‬استخدام المنقح للتنقل ضمن البرنامج‪372 ..................‬‬

‫‪ .3‬نقاط التوقف‪376..................................................‬‬

‫‪ .4‬دمج ‪ pdb‬مع البرامج‪379........................................‬‬

‫‪ .5‬تعديل تسلسل تنفيذ البرنامج ‪380.............................‬‬

‫‪ .6‬جدول بأوامر ‪ pdb‬الشائعة‪384.................................‬‬

‫‪ .7‬الوحدة ‪ :code‬تنقيح الشيفرات من سطر األوامر ‪385 .....‬‬

‫‪ .8‬الوحدة ‪ :Logging‬التنقيح بالتسجيل وتتبع األحداث‪390 .‬‬

‫‪ .9‬خالصة الفصل‪403................................................‬‬

‫إصدارات بايثون‪ :‬اإلصدار ‪ 3‬مقابل ‪404........2‬‬


‫‪ .1‬بايثون ‪405........................................................2‬‬

‫‪ .2‬بايثون ‪405........................................................3‬‬

‫‪ .3‬بايثون ‪406.....................................................2.7‬‬

‫‪ .4‬االختالفات األساسية بين اإلصدارات‪407....................‬‬

‫‪ .5‬نقاط أخرى يجب أخذها بالحسبان‪410 .......................‬‬

‫‪ .6‬ترحيل شيفرة بايثون ‪ 2‬إلى بايثون ‪411....................3‬‬

‫‪ .7‬تعرف على االختالفات بين بايثون ‪ 2‬و بايثون ‪413 ......3‬‬

‫‪ .8‬تحديث الشيفرة‪417..............................................‬‬

‫‪ .9‬التكامل المستمر (‪418...........)Continuous Integration‬‬

‫‪ .10‬خالصة الفصل‪419...............................................‬‬
‫تقديم‬
‫ت‬

‫▲‬ ‫|‬ ‫‪14‬‬


‫البرمجة بلغة بايثون‬ ‫تقديم‬

‫س طع نجم لغ ة البرمج ة ب ايثون في اآلون ة األخ يرة ح تى ب دأت ت زاحم أق وى لغ ات البرمج ة‬

‫في الص دارة وذاك لمزاي ا ه ذه اللغ ة ال تي ال تنحص ر أوله ا س هولة كتاب ة وق راءة ش يفراتها ح تى‬

‫أضحت الخيار األول بين يدي المؤسسات األكاديمية والتدريبية لتدريسها للطالب الجدد الراغ بين‬

‫في الدخول إلى مجال علوم الحاسوب والبرمجة‪ .‬أضف إلى ذلك أن بايثون ً‬
‫لغة متع َّددة األغ راض‬

‫واالس تخدامات‪ ،‬ل ذا فهي دومً ا الخي ار األول في ش تى مج االت عل وم الحاس وب الص اعدة مث ل‬

‫ال ذكاء الص نعي وتعلم اآلل ة وعل وم البيان ات وغيره ا‪ ،‬كم ا َّ‬
‫أنه ا مطلوب ة بش دة في س وق العم ل‬

‫وتعتمدها كبرى الشركات التقنية‪.‬‬

‫جاء هذا الكتاب المترجم عن كتاب «‪ »How to code in Python‬لصاحبته ل يزا ت اغليفيري‬

‫(‪ )Lisa Tagliaferri‬ليش رح المف اهيم البرمجي ة األساس ية بلغ ة ب ايثون‪ ،‬ونأم ل أن يك ون إض ً‬
‫افة‬

‫ً‬
‫منطلق ا لل دخول إلى ع الم البرمج ة من‬ ‫العربية وأن يفيد القارئ العربي في أن يك ون‬
‫َّ‬ ‫ً‬
‫نافعة للمكتبة‬

‫أوسع أبوابه‪.‬‬

‫هذا الكتاب مرخص بموجب رخصة المش اع اإلب داعي ‪« Creative Commons‬نس ب المُ ص نَّف ‪-‬‬

‫غير تجاري ‪ -‬الترخيص بالمثل ‪»4.0‬‬

‫( ‪)Attribution-NonCommercial-ShareAlike 4.0 - CC BY-NC-SA 4.0‬‬

‫مفتوحا‪.‬‬
‫ً‬ ‫تعليميا‬
‫ًّ‬ ‫وهو متاح الستخدامه مصدرًا‬

‫نظ رًا لكون ه مت وفرُ ا على هيئ ة كت اب إلك تروني‪ ،‬فبإمكان ك اس تخدام كت اب «البرمج ة بلغ ة‬

‫واء في‬
‫ً‬ ‫ً‬
‫مفتوح ا‪ ،‬وبالت الي يمكن اس تخدامه في أي فص ل دراس ي س‬ ‫تعليمي ا‬
‫ً‬ ‫ب ايثون» مرجعً ا‬

‫المدرسة أو الجامعة‪ ،‬كما يمكن توفير هذا الكتاب اإللكتروني للعامة في المكتبات‪.‬‬

‫▲‬ ‫|‬ ‫‪15‬‬


‫البرمجة بلغة بايثون‬ ‫تقديم‬

‫كيفية‬
‫َّ‬ ‫يمكن استخدام هذا الكتاب اإللكتروني بع دة طرائ ق‪ ،‬وس وف نوض ح في ه ذا التق ديم‬

‫التعام ل م ع الكت اب‪ ،‬وكي ف يمكن للمعلمين والطالب اس تخدام الكت اب في فص ولهم الدراس ية‪،‬‬

‫وكي ف يمكن ألمن اء المكتب ات العام ة والجامعي ة توف ير ه ذا الكت اب اإللك تروني ليك ون مرجعً ا‬

‫ً‬
‫الحق ا‪،‬‬ ‫ً‬
‫توجيه ا ح ول م ا يجب أن يتعلم ه‬ ‫تعليميا‪ .‬أخ يرًا‪ ،‬بالنس بة للق ارئ ال ذي أنهى الكت اب ويري د‬
‫ًّ‬

‫فقد أضفنا بعض المراجع اإلضافية في آخر هذا القسم‪.‬‬

‫‪ .1‬كيفية استخدام هذا الكتاب‬


‫ترتيب ا يناس ب المط ور المبت دئ‪،‬‬
‫ً‬ ‫ومنطقية‪ .‬ورغم َّ‬
‫أنه ُم رتب‬ ‫َّ‬ ‫ِّ‬
‫صمم هذا الكت اب بطريق ة سلس ة‬

‫إال َّ‬
‫أنه ليس علي ك التقي د ب الترتيب‪ :‬اب دأ حيث ش ئت‪ ،‬وأق رأه ب الترتيب ال ذي يناس ب احتياجات ك‪.‬‬

‫بعد إنهاء الكتاب‪ ،‬يمكنك استخدامه مرجعً ا‪.‬‬

‫إذا ق رأت الكت اب ب الترتيب‪ ،‬فس تبدأ رحلت ك في ب ايثون من مقدم ة عام ة ح ول اللغ ة لمن ال‬

‫يعرفه ا‪ ،‬بع د ذل ك‪ ،‬س تتعلم إع داد بيئ ة برمج ة على الجه از المحلي أو على الخ ادم‪ ،‬وس تبدأ تعلم‬

‫البني ة العام ة لش يفرة ب ايثون‪ ،‬وص ياغتها‪ ،‬وأن واع البيان ات فيه ا‪ .‬في ثنِيِّ ات الطري ق‪ ،‬س تتعلم‬

‫أساس يات المنط ق الحس ابي في ب ايثون‪ ،‬وهي مه ارات مفي دة ح تى في لغ ات البرمج ة األخ رى‪.‬‬

‫سنركز في بداية الكتاب على كتاب ة الس كربتات في ب ايثون‪ ،‬ثم س ِّ‬
‫نقدم بالت دريج مف اهيم البرمج ة‬

‫الكائني ة لمس اعدتك على كتاب ة ش يفرات أك ثر مرون ة وتعقي ًدا‪ ،‬م ع تجنب التك رار‪ .‬وفي نهاي ة‬

‫الكت اب‪ ،‬س تتعلم كيفي ة تنقيح ش يفرة ب ايثون‪ ،‬وس نختم بفص ل عن االختالف ات الرئيس ية بين‬

‫بايثون ‪ 3‬واإلصدارات السابقة وكيفية ترحيل شيفرة بايثون من اإلصدار بايثون ‪ 2‬إلى بايثون ‪.3‬‬

‫ا‪ .‬استخدام الكتاب في الفصل الدراسي‬

‫طالب ا‪ ،‬فيمكن ك إطالع معلم ك أو أس تاذك أو قس م الحوس بة على ه ذا الكت اب‬


‫ً‬ ‫إذا كنت‬

‫▲‬ ‫|‬ ‫‪16‬‬


‫البرمجة بلغة بايثون‬ ‫تقديم‬

‫اإللك تروني المج اني‪ .‬ق د يوج د في مدرس تك أو جامعت ك مس تودعً ا أو مكتب ًة مفتوح ًة للمراج ع‬

‫ً‬
‫أيض ا مش اركة ه ذا‬ ‫التعليمي ة وال تي يمكن ك فيه ا إتاح ة ه ذا الكت اب للطالب أو المعلمين‪ .‬يمكن ك‬

‫الكت اب اإللك تروني م ع األندي ة والمجموع ات ال تي تنتمي إليه ا وال تي ق د تك ون مهتم ة بتعلم‬

‫البرمج ة بلغ ة ب ايثون‪ .‬وإض افة إلى األندي ة وال برامج الخاص ة بعل وم الحاس وب‪ ،‬يمكن أن يس تفيد‬

‫ً‬
‫أيض ا من هذا الكتاب األشخاص الذين يدرسون علم البيانات واإلحصاء والعلوم اإلنسانية الرقمية‪.‬‬

‫ُدرس أو تش رف على ورش ات برمجي ة ِّ‬


‫تعلم فيه ا ب ايثون‪ ،‬فيمكن ك اس تخدام‬ ‫إذا كنت معلمً ا ت ِّ‬

‫ً‬
‫مجان ا م ع طالب ك‪ .‬يمكن ك اتب اع ت رتيب فص ول الكت اب‪ ،‬أو يمكن ك‬ ‫ه ذا الكت اب التعليمي المفت وح‬

‫ً‬
‫أيض ا تكمي ل‬ ‫انتقاء الفصول التي تناس ب المُ ق رَّ ر ال ذي ُت ِّ‬
‫درس ه وف ق ال ترتيب المناس ب ل ك‪ .‬يمكن ك‬

‫ً‬
‫أيض ا‬ ‫هذا الكتاب الرقمي ب الكثير من ال دروس والمق االت من أكاديمي ة حس وب أو غيره ا‪ ،‬ويمكن ك‬

‫استخدام موسوعة حسوب مرجعً ا للغة بايثون (وغيرها من اللغات)‪.‬‬

‫ب‪ .‬إضافة الكتاب إلى مكتبتك‬

‫إذا كنت أمين مكتب ة‪ ،‬فيمكن ك إض افة كت اب «البرمج ة بلغ ة ب ايثون» إلى فه رس مكتبت ك‪.‬‬

‫أن تعلم بعض مب ادئ البرمج ة يمكن أن يك ون‬


‫أن ليس ك ل الن اس مهتمين بالبرمج ة‪ ،‬إال َّ‬
‫ص حيح َّ‬

‫الرقمية‪.‬‬
‫َّ‬ ‫األمية‬
‫َّ‬ ‫مفي ًدا في الحياة المهنية‪ ،‬ويساعد على تخفيض‬

‫‪ .2‬ماذا بعد هذا الكتاب‬


‫عند االنتهاء من هذا الكتاب‪ ،‬يمكن ك االطالع على العدي د من المق االت العملي ة في أكاديمي ة‬

‫حسوب‪ .‬أثناء ذلك‪ ،‬يمكنك التنقل بين توثيق بايثون في موسوعة حسوب وفصول هذا الكتاب‪.‬‬

‫ألي شخص ملم بالبرمجة أن يس اهم في المش اريع مفتوح ة المص در‪ .‬ال برامج مفتوح ة‬
‫يمكن ِّ‬

‫المصدر هي برامج متاحة لالس تخدام وإع ادة التوزي ع والتع ديل دون قي ود‪ .‬تس اعد المس اهمة في‬

‫▲‬ ‫|‬ ‫‪17‬‬


‫البرمجة بلغة بايثون‬ ‫تقديم‬

‫المش اريع مفتوح ة المص در على تحس ين ال برامج‪ ،‬ع بر ض مان تمثيله ا لقاع دة عريض ة من‬

‫المس تخدمين‪ .‬عن دما يس اهم المس تخدمون في المش اريع مفتوح ة المص در‪ ،‬س واء ع بر كتاب ة‬

‫الش يفرة‪ ،‬أو التوثي ق‪ ،‬أو ص يانة المجل دات‪ ،‬ف إنهم ي وفرون قيم ة مض افة للمش روع‪ ،‬ومجتم ع‬

‫المطورين على العموم‪.‬‬

‫للحص ول على مراج ع إض افية عن ب ايثون‪ ،‬أو للمش اركة في نقاش ات م ع اآلخ رين‪ ،‬يمكن ك‬

‫االطالع على المقاالت واألسئلة والدروس عن بايثون في األكاديمية‪.‬‬

‫إذا كنت مهتمً ا بتعلم تطوير تطبيقات الويب أو تطبيقات الجوال‪ ،‬أو تعلم لغ ات مح َّددة مث ل‬

‫روبي وجافاس كربت‪ ،‬ف اطلع على قس م ال دورات في األكاديمي ة‪ ،‬كم ا يمكن ك تص فح موس وعة‬

‫حسوب ألجل قراءة توثيقات عدد كبير من لغات البرمجة باللغة العربية‪.‬‬

‫جميل بيلوني‬

‫‪ - 01‬يوليو ‪2020 -‬‬

‫▲‬ ‫|‬ ‫‪18‬‬


‫‪1‬‬
‫مدخل تعريفي إلى‬
‫لغة بايثون‬

‫▲‬ ‫|‬ ‫‪19‬‬


‫البرمجة بلغة بايثون‬ ‫مدخل تعريفي إلى لغة بايثون‬

‫ب ايثون لغ ٌة س هلة الق راءة للغاي ة ومتنوع ة ومتع ددة االس تخدامات‪ ،‬واس مها مس توحى من‬

‫مجموع ة كوميدي ة بريطاني ة باس م « ‪ ،»Monty Python‬وك ان أح د األه داف األساس ية لفري ق‬

‫يط‪ ،‬وطريق ة كتابته ا مباش رة‬ ‫ً‬


‫مرحة وسهلة االستخدام‪ ،‬وإع دادها بس ٌ‬ ‫تطوير بايثون هو جعل اللغة‬

‫وتعطي ك تقري رًا مباش رًا عن د ح دوث أخط اء‪ ،‬وهي خي ارٌ ممت ٌ‬
‫از للمبت دئين والواف دين الج دد على‬

‫البرمج ة‪ .‬لغ ة ب ايثون هي لغ ة متع ِّددة االس تعماالت‪ ،‬وت دعم مختل ف أنم اط البرمج ة مث ل كتاب ة‬

‫كائنية التوج ه (‪ ،)object-oriented‬وهي مناس ٌ‬


‫بة لألغ راض العام ة‪،‬‬ ‫َّ‬ ‫الس كربتات والبرمج ة‬

‫واستعمالها يتزايد في سوق العمل إذ تعتم دها منظم ٌ‬


‫ات مث ل « ‪( »United Space Alliance‬ش ركة‬

‫في مجال إرسال مركبات فضائية وتتعاقد معها ناسا) و « ‪( »Industrial Light & Magic‬أستوديو‬

‫درات كث يرةٍ لمن يري د تعلم لغ ة‬


‫ٍ‬ ‫للت أثيرات الس ينمائية وللرس وم المتحرك ة)‪ ،‬وت ِّ‬
‫وفر ب ايثون ق‬

‫برمجة جديدة‪.‬‬

‫ون ِشرَ ت أوّ ل مرة في ع ام ‪ُ ،1991‬‬


‫ط ِّورَ ت‬ ‫طورَ ت اللغة في نهاية الثمانينات من القرن الماضي‪ُ ،‬‬
‫ِّ‬

‫أنها‬ ‫ٌ‬
‫نشط للغاية في المجتمع‪ .‬وتع ُّد بايثون على َّ‬ ‫بايثون من قِ بل ‪ ،Guido van Rossum‬وهو عضوٌ‬

‫تثناءات‬ ‫ل م ع االس‬ ‫ة ‪ ،ABC‬وأوّ ل إص دار منه ا ك ان يتض من التعام‬ ‫ٌ‬


‫ديل عن لغ‬ ‫ب‬

‫(‪ )exception handling‬وال دوال واألص ناف (‪ )classes‬م ع إمكاني ة الوراث ة فيه ا‪ .‬وع دما ُأ ِ‬
‫نش ئ‬

‫منت دى محادث ة في ‪ Usenet‬باس م ‪ comp.lang.python‬في ‪ ،1994‬فب دأت قاع دة مس تخدمي‬

‫وخصوصا لتطوير‬
‫ً‬ ‫بايثون بالنمو‪ ،‬مما ّ‬
‫مهد الطريق لها لتصبح واحدة من أكثر لغات البرمجة شيوعً ا‬

‫البرمجيات مفتوحة المصدر‪.‬‬

‫▲‬ ‫|‬ ‫‪20‬‬


‫البرمجة بلغة بايثون‬ ‫مدخل تعريفي إلى لغة بايثون‬

‫‪ .1‬تاريخ بايثون‬
‫ظهرت لغة بايثون في أواخر الثمانينيات على يد غيدو فان روسوم (‪،)Guido van Rossum‬‬

‫وق د عُ َّدت خليف ًة للغ ة ‪ .ABC‬كم ا اس تفادت ب ايثون من الكث ير من اللغ ات الس ابقة له ا‪ ،‬مث ل‬

‫‪ Modula-3‬و ‪ C‬و ‪ C++‬و ‪ Algol-68‬و ‪ ،SmallTalk‬وغيرها من اللغات‪.‬‬

‫ُن ِش ر اإلص دار ‪ 2.0‬من لغ ة ب ايثون ع ام ‪ ،2000‬وق د ق َّدم العدي د من الم يزات الجدي دة‪ ،‬مث ل‬

‫الفهمية (‪ ،)List Comprehensions‬ونظ ام كنس المُ همالت (‪ .)garbage collection‬وظه ر‬


‫َّ‬ ‫القوائم‬

‫ً‬
‫متوافق ا تمامً ا م ع‬ ‫بي د َّ‬
‫أنه لم يكن‬ ‫رة في اللغ ة‪ْ ،‬‬ ‫في عام ‪ 2008‬اإلصدار بايثون ‪ ،3.0‬والذي َّ‬
‫شكل طف ً‬

‫اإلص دارات الس ابقة‪ ،‬ل ذلك ق رر فري ق التط وير االس تمرار في دعم إص دار أخ ير من سلس لة ب ايثون‬

‫‪ ،2.x‬وهو بايثون ‪ 2.7‬حتى عام ‪.2020‬‬

‫‪ .2‬مميزات لغة بايثون‬


‫تتميز بايثون بعدة أمور عن غيرها من لغات البرمجة‪ ،‬منها‪:‬‬

‫المفتاحية‪،‬‬
‫َّ‬ ‫ُّ‬
‫التعلم‪ :‬يس هل تعلم لغ ة ب ايثون‪ ،‬إذ تت ألف من ع دد قلي ل من الكلم ات‬ ‫س))هولة‬ ‫•‬
‫وتتميز بصياغة بسيطة وواضحة‪.‬‬

‫المقروئية‪ :‬شيفرة لغة بايثون واضحة ومنظمة وسهلة القراءة‪.‬‬ ‫•‬

‫سهلة الصيانة‪ :‬شيفرة بايثون سهلة الصيانة إلى حد بعيد‪.‬‬ ‫•‬

‫مكتب ))ة قياس ))ية واس)))عة‪ :‬تحت وي مكتب ة ب ايثون القياس ية على ع دد كب ير من الح زم‬ ‫•‬
‫المحمولة التي تتوافق مع أنظمة يونكس وويندوز وماك‪.‬‬

‫إمكانية تنفي ذ الش يفرات‬


‫َّ‬ ‫الوض))ع التف))اعلي‪ :‬ت دعم ب ايثون الوض ع التف اعلي‪ ،‬مم ا ي تيح‬ ‫•‬
‫ً‬
‫مباشرة على سطر األوامر وتنقيحها‪.‬‬

‫▲‬ ‫|‬ ‫‪21‬‬


‫البرمجة بلغة بايثون‬ ‫مدخل تعريفي إلى لغة بايثون‬

‫متع) ِّ‬
‫)ددة المنص))ات‪ :‬يمكن تش غيل لغ ة ب ايثون على طي ف واس ع من المنص ات واألجه زة‪،‬‬ ‫•‬
‫مع االحتفاظ بنفس الواجهة على جميع تلك المنصات‪.‬‬

‫التوس) )عية‪ :‬من أهم مم يزات ب ايثون‪ ،‬ه و توفره ا على ع دد هائ ل من الوح دات‪ ،‬ال تي‬
‫ُّ‬ ‫•‬
‫يمكنها توسيع قدرات اللغ ة في ك ل مج االت التط وير‪ ،‬مث ل تحلي ل البيان ات والرس وميات‬
‫ثنائي ة وثالثي ة األبع اد‪ ،‬وتط وير األلع اب‪ ،‬واألنظم ة المدمج ة‪ ،‬والبحث العلمي‪ ،‬وتط وير‬
‫المواقع وغيرها من المجاالت‪.‬‬

‫ِّ‬
‫توفر بايثون واجهات لجميع قواعد البيانات األساسية‪.‬‬ ‫قواعد البيانات‪:‬‬ ‫•‬

‫الرسومية‪.‬‬
‫َّ‬ ‫الرسوميات‪ :‬تدعم بايثون التطبيقات‬ ‫•‬

‫َّ‬
‫والمعقدة‪.‬‬ ‫دعم البرامج الكبيرة‪ :‬بايثون مناسبة للبرامج الكبيرة‬ ‫•‬

‫ستخدم بايثون؟‬
‫َ‬ ‫‪ .3‬أين ُت‬
‫ُتس تخ َدم لغ ة ب ايثون في ك ل المج االت‪ ،‬فهي لغ ة برمج ة متع ِّددة األغ راض‪ ،‬ومن مج االت‬

‫اس تخدامها‪ :‬تحلي ل البيان ات‪ ،‬والروبوت ات‪ ،‬وتعلم اآلل ة‪ ،‬وتطبيق ات ‪ ،REST‬وتط وير المواق ع‬

‫واأللع اب‪ ،‬والرس وم ثالثي ة األبع اد‪ ،‬واألتمت ة وبرمج ة األنظم ة المدمج ة‪ ،‬والكث ير من المج االت‬

‫األخرى التي ال يسعنا حصرها هنا‪.‬‬

‫تس تخدم الكث ير من المواق ع والش ركات العمالق ة لغ ة ب ايثون‪ ،‬ومنه ا ‪ Spotify‬و ‪Google‬‬

‫و‪ ،Amazon‬إض افة إلى ‪ Facebook‬ال تي تس تخدم ب ايثون لمعالج ة الص ور‪ .‬وفي ك ل ي وم تتح ول‬

‫ش ركات جدي دة إلى اس تخدام ب ايثون‪ ،‬مث ل ‪ Instagram‬ال تي ق ررت م ؤخ ًرا اس تخدامها وفض لتها‬

‫والبحثية‪ ،‬مث ل وكال ة الفض اء‬


‫َّ‬ ‫العلمية‬
‫َّ‬ ‫ً‬
‫أيض ا من قب ل بعض الجه ات‬ ‫على ‪ُ .PHP‬تس تخ َدم ب ايثون‬

‫األمريكية ناسا‪ ،‬والتي لها مستودع خاص بالمشاريع المُ طورة ببايثون‪.‬‬

‫▲‬ ‫|‬ ‫‪22‬‬


‫البرمجة بلغة بايثون‬ ‫مدخل تعريفي إلى لغة بايثون‬

‫‪ .4‬لماذا بايثون وليس غيرها؟‬


‫تحدي د أفض ل لغ ة برمج ة للتعلم ق د يك ون مهم ًة ص ً‬
‫عبة‪ .‬ل و س ألت ع َّدة أش خاص عن لغ ة‬

‫البرمج ة ال تي يجب تعلمه ا‪ ،‬فستحص ل على ع دة إجاب ات‪ ،‬ويكفي أن ت دخل على جوج ل وتكتب‬

‫مختلفة‪ ،‬وجدااًل ال ينتهي حول هذا الموضوع‪.‬‬


‫ً‬ ‫آراء‬
‫ً‬ ‫أفضل لغة برمجة‪ ،‬وستجد‬

‫ال أريد أن أبدأ حرب لغات البرمجة هنا‪ ،‬ولكني سأحاول تقديم بعض الحجج لتبرير لماذا أرى‬

‫وأن تعلم لغ ة ب ايثون مث الي للمبت دئين ال ذين يري دون دخ ول ع الم‬
‫َّ‬ ‫أن ب ايثون هي لغ ة المس تقبل‪،‬‬
‫َّ‬

‫البرمجة وعلوم الحاسوب‪.‬‬

‫ا‪ .‬الشعبية‬

‫بحس ب اس تطالع موق ع ‪ ،stackoverflow‬ب ايثون هي لغ ة البرمج ة العامَّ ة األس رع نم وً ا‪ ،‬كم ا‬

‫تمكنت سنة ‪ 2019‬من التفوق على جاف ا ِبع ِّدها أك ثر لغ ة برمج ة متع ددة األغ راض اس تخدامً ا‪ ،‬كم ا‬

‫أنه ا راب ع أك ثر لغ ة تكنولوجي ا برمج ة اس تخدامً ا وراء ‪ JavaScript‬و ‪ CSS/HTML‬و ‪ ،SQL‬كم ا َّ‬
‫أنه ا‬ ‫َّ‬

‫ثاني أكثر لغة برمجة محبوبة من قبل المبرمجين‪.‬‬

‫ب ايثون ليس ت لغ ة قويَّ ة وفعال ة وحس ب‪ ،‬كم ا ي دل على ذل ك حقيق ة َّ‬


‫أنه ا أك ثر لغ ة برمج ة‬

‫متع ِّددة األغ راض اس تخدامً ا‪ ،‬ب ل هي ف وق ذل ك محبوب ة من قب ل الم برمجين‪ ،‬وه ذا مؤش ر على‬

‫ألنها األسرع نموً ا‪ ،‬فهل ال ي زال ل ديك‬ ‫ً‬


‫مشرقا‪َّ ،‬‬ ‫فإن مستقبلها يبدو‬
‫َّ‬ ‫سهولتها‪ ،‬ثم فوق كل ذلك جميعً ا‪،‬‬

‫شك في أن تعلم لغة بايثون هو خيار مثالي لك؟!‬

‫المخططان البيانيان التاليان يوضحان شعبية لغة بايثون لدى المبرمجين‪:‬‬

‫▲‬ ‫|‬ ‫‪23‬‬


‫البرمجة بلغة بايثون‬ ‫مدخل تعريفي إلى لغة بايثون‬

‫أكثر لغات البرمجة شعبية (المصدر‪)https://insights.stackoverflow.com/survey/2019 :‬‬ ‫•‬

‫در‪:‬‬ ‫برمجين (المص‬ ‫دى الم‬ ‫ةل‬ ‫ة المحبوب‬ ‫ات البرمج‬ ‫ثر لغ‬ ‫أك‬ ‫•‬

‫‪)https://insights.stackoverflow.com/survey/2019‬‬

‫▲‬ ‫|‬ ‫‪24‬‬


‫البرمجة بلغة بايثون‬ ‫مدخل تعريفي إلى لغة بايثون‬

‫ب‪ .‬طلب سوق العمل‬

‫يس تخدم ب ايثون بعض أك بر الش ركات في مج ال التكنولوجي ا‪ ،‬مث ل ‪ Uber‬و ‪PayPal‬‬

‫ذا‪،‬‬ ‫ً‬
‫افة إلى ه‬ ‫و ‪ Google‬و ‪ Facebook‬و ‪ Instagram‬و ‪ Netflix‬و ‪ Dropbox‬و ‪ .Reddit‬إض‬

‫ُتس تخ َدم ب ايثون بكثاف ة في مج ال ال ذكاء االص طناعي والتعلم اآللي وتحلي ل البيان ات وأنظم ة‬

‫المراقبة وغير ذلك‪.‬‬

‫يق در موق ع ‪ ،stackoverflow‬ال دخل الس نوي لمط وري ب ايثون المح ترفين بح والي ‪ 63‬أل ف‬

‫طلبا كبيرًا على لغة بايثون في سوق العمل‪.‬‬


‫ً‬ ‫أن هناك‬
‫دوالر‪ ،‬وهو مبلغ كبير‪ ،‬ويدل على َّ‬

‫ج‪ .‬الدعم‬

‫تقريب ا‪ .‬و ِبع ِّدها اللغ ة‬


‫ً‬ ‫نظ ًرا لشعبيتها الكبيرة‪ ،‬تتمتع بايثون بدعم جيد على جميع المس تويات‬

‫المفض لة للمبت دئين‪ ،‬فهن اك قن اطير من المراج ع والم واد وال دورات التعليمي ة ال تي تش رح مف اهيم‬

‫األساسية‪ ،‬إضافة إلى صياغة اللغة وتطبيقاتها‪.‬‬


‫َّ‬ ‫البرمجة‬

‫س واء كنت هاويً ا‪ ،‬وتحب تعلم البرمج ة هواي ًة‪ ،‬أو ألج ل اس تخدامها في مج ال عمل ك‪ ،‬مث ل‬

‫الطبيعية وغ ير ذل ك‪ ،‬أو كنت تري د أن تعم ل عماًل مس تقاًل ‪ ،‬أو‬


‫َّ‬ ‫تحلي ل البيان ات ومعالج ة اللغ ات‬

‫تدخل سوق العمل وتحق ق دخاًل من البرمج ة‪ ،‬ففي جمي ع ه ذه الح االت‪ ،‬س يكون تعلم لغ ة ب ايثون‬

‫مثاليا لك‪.‬‬
‫ً‬ ‫خيا ًرا‬

‫▲‬ ‫|‬ ‫‪25‬‬


‫البرمجة بلغة بايثون‬ ‫مدخل تعريفي إلى لغة بايثون‬

‫‪ .5‬خالصة الفصل‬
‫وكائنية‪ ،‬وواح دة‬
‫َّ‬ ‫بايثون هي لغة برمجة عالية المستوى‪ ،‬ومُ ترجمَ ة (‪ )interpreted‬وتفاعلية‬

‫دءا من ألع اب‬


‫من أشهر لغات البرمجة وأكثره ا اس تخدامً ا‪ ،‬ويمكن اس تخدامها في ك ل المج االت‪ ،‬ب ً‬

‫ُّ‬
‫والتعلم اآللي‪.‬‬ ‫الفيديو ومعالجة اللغات‪ ،‬وحتى تحليل البيانات‬

‫أضف إلى ذلك أنها تتمتع بمقروئي ة عالي ة‪ ،‬إذ تس تخدم كلم ات إنجليزي ة بس يطة‪ ،‬على خالف‬

‫ياغية‬
‫َّ‬ ‫اإلمالئية والص‬
‫َّ‬ ‫أن قواع دها‬
‫اللغ ات األخ رى ال تي تس تخدم الرم وز والكلم ات المختص رة‪ ،‬كم ا َّ‬

‫ً‬
‫موازنة مع لغ ات برمجي ة أخ رى‪ .‬وه ذا ه و الس بب الرئيس ي العتم اد‬ ‫بسيطة‪ ،‬ما يجعل تعلمها سهاًل‬

‫الجامعات ومختلف دورات البرمج ة التدريبي ة تدريس ها في البداي ة لمن يري د ال دخول إلى مج ال‬

‫خصوصا‪.‬‬
‫ً‬ ‫علوم الحاسوب عمومً ا والبرمجة‬

‫▲‬ ‫|‬ ‫‪26‬‬


‫‪2‬‬
‫تثبيت بايثون‬
‫وإعداد بيئة العمل‬

‫▲‬ ‫|‬ ‫‪27‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫بع د أن أخ ذت فك رة عام ة عن لغ ة البرمج ة ب ايثون وتع رفت على تاريخه ا وإص داراتها ‪ -‬في‬

‫الفصل السابق ‪ -‬سيرشدك هذا الفصل إلى كيفي ة تث بيت ب ايثون على نظ ام تش غيلك وإع داد البيئ ة‬

‫البرمجية الالزمة لكتابة البرامج وتنفيذها خالل رحلتك التعليمية هذه‪.‬‬

‫األم ور ال تي سنس لط الض وء عليه ا هي‪ :‬تث بيت ب ايثون ‪ 3‬ثم إع داد بيئته ا البرمجي ة ال تي‬

‫ِّ‬
‫تمكن ك من إنش اء مس احة معزول ة في حاس وبك مخصص ة لمش اريع‬ ‫وهمية‬ ‫َّ‬
‫تتمثل بإع داد بيئ ة‬
‫َّ‬

‫أن ك ل مش روع تعم ل علي ه يمل ك مجموع ة من االعتمادي ات (‪)dependencies‬‬


‫ب ايثون‪ ،‬مم ا يع ني َّ‬
‫ؤثر على غيره ا من المش اريع‪ .‬ي ِّ‬
‫وفر لن ا ذل ك تحكمً ا أك بر بمش اريع ب ايثون وإمكاني ة‬ ‫وال تي لن ت ِّ‬

‫دارات مختلف ةٍ من حزمه ا وه ذا مهمٌ عن دما تتعام ل م ع الح زم الخارجي ة‪ .‬سننش ئ‬


‫ٍ‬ ‫التعامل م ع إص‬

‫بسيطا يعرض العبارة "!‪( "Hello World‬أهاًل بالعالم!) الشهيرة‪ ،‬وبهذا س نتحقق من‬
‫ً‬ ‫ً‬
‫برنامجا‬ ‫بعدئذٍ‬

‫ً‬
‫مألوفة لديك مم ا‬ ‫ً‬
‫صحيحا‪ ،‬وستصبح آنذاك طريقة إنشاء برامج بايثون وتنفيذها‬ ‫عمل البيئة عماًل‬

‫ِّ‬
‫يمهد الطريق لكتابة وتنفيذ مشاريع بايثون الالحقة‪.‬‬

‫اخ تر مم ا يلي القس م الخ اص بنظ ام تش غيل حاس وبك (حاولن ا ش مل أش هر أنظم ة التش غيل‪،‬‬

‫لينكس وويندوز وماك) وانتقل إليه التباع الخطوات الالزمة لتنفيذ ما سبق‪.‬‬

‫ويندوز‬ ‫•‬

‫لينكس‬ ‫•‬

‫أوبنتو‬ ‫◦‬

‫دبيان‬ ‫◦‬

‫سينتوس‬ ‫◦‬

‫ماك‬ ‫•‬

‫▲‬ ‫|‬ ‫‪28‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫‪ .1‬ويندوز‬
‫خطوة بخطوة إلى كيفية تثبيت بايثون ‪ 3‬في ويندوز ‪ ،10‬وتثبيت بيئة‬
‫ً‬ ‫رش ُدك هذا القسم‬
‫سي ِ‬
‫ُ‬

‫برمجة خاصة بها عبر سطر األوامر‪.‬‬

‫ا‪ .‬المتطلبات المسبقة‬

‫ازا علي ه نظ ام وين دوز ‪ 10‬متص ل بالش بكة م ع ص الحيات م دير‬


‫يجب أن تمل ك جه ً‬

‫(‪.)administrative access‬‬

‫ب‪ .‬فتح وإعداد ‪PowerShell‬‬

‫سنجري معظم أطوار التثبيت واإلعدادات عبر سطر األوامر‪ ،‬والذي ه و طريق ٌة غ يرُ رس وميةٍ‬

‫للتعام ل م ع الحاس وب‪ ،‬فب داًل من الض غط على األزرار‪ ،‬س تكتب ًّ‬
‫نص ا وتعطي ه للحاس وب لينف ذه‪،‬‬

‫ً‬
‫أيضا‪ .‬يمكن أن يساعدك سطر األوامر على تعديل أو أتمتة مختلف المه ام‬ ‫نصيا‬
‫ً‬ ‫ً‬
‫ناتجا‬ ‫ظهر لك‬
‫وسي ِ‬
‫ُ‬

‫ٌ‬
‫أساسية لمطوري البرمجيات‪.‬‬ ‫ٌ‬
‫أداة‬ ‫يوميا‪ ،‬وهو‬
‫ً‬ ‫التي تنجزها على الحاسوب‬

‫‪ PowerShell‬هي برن امج من ميكروس وفت ي وفر واجه ة س طر األوام ر‪ .‬يمكن إج راء المه ام‬

‫اإلدارية عبر تنفي ذ األص ناف ‪ ،cmdlets‬وال تي ُت َ‬


‫نط ق "‪ ،"command-lets‬وهي أص ناف متخصص ة‬

‫من اإلط ار ‪ .NET‬يمكنه ا تنفي ذ العملي ات‪ُ .‬جعِ لت ‪ PowerShell‬مفتوح ة المص در من ذ أغس طس‬

‫‪ ،2016‬وصارت متوفرة اآلن عبر ويندوز وأنظمة يونكس (بما في ذلك ماك ولينكس)‪.‬‬

‫س تعثر على ‪ PowerShell‬ب النقر األيمن على أيقون ة ‪ Start‬في ال ركن األيس ر الس فلي من‬

‫الشاش ة‪ .‬عن دما تنبث ق القائم ة‪ ،‬انق ر على " ‪ ،"Search‬ثم اكتب "‪ "PowerShell‬في ش ريط البحث‪.‬‬

‫عند تقديم خيارات لك‪ ،‬انقر بالزر األيمن على تطبيق سطح المكتب "‪."Windows PowerShell‬‬

‫▲‬ ‫|‬ ‫‪29‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫اختر "‪ ."Run as Administrator‬عندما يظهر مربع حوار يسألك‪:‬‬

‫?‪Do you want to allow this app to make changes to your PC‬‬

‫انقر على "‪ ."Yes‬بمجرد إتمام ذلك‪ ،‬سترى واجهة نصية تبدو كما يلي‪:‬‬

‫يمكننا تبديل مجلد النظام عن طريق كتابة األمر التالي‪:‬‬

‫~ ‪cd‬‬

‫بعد ذلك سننتقل إلى المجلد ‪.PS C:\Users\Sammy‬‬

‫لمتابع ة عملي ة التث بيت‪ ،‬س نع ّد بعض األذون ات من خالل ‪ .PowerShell‬تم إع داد‬

‫ً‬
‫أمانا بشكل افتراضي‪.‬‬ ‫‪ PowerShell‬لتعمل في الوضع األكثر‬

‫▲‬ ‫|‬ ‫‪30‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫هناك عدة مستويات لألذونات‪ ،‬والتي يمكنك إعدادها بوصفك مدي ًرا (‪:)administrator‬‬

‫‪ :Restricted‬يمث ل سياس ة التنفي ذ االفتراض ية‪ ،‬وبم وجب ه ذا الوض ع‪ ،‬لن تتمكن من‬ ‫•‬
‫ًة (أي‬ ‫ً‬
‫دفة تفاعلي‬ ‫فها ص‬ ‫تعمل ‪ PowerShell‬بوص‬ ‫كربتات‪ ،‬وس‬ ‫ذ الس‬ ‫تنفي‬
‫‪ )interactive shell‬وحسب‪.‬‬

‫وقع ة من قب ل جه ة‬ ‫ِّ‬
‫سيمكنك من تنفيذ جميع السكربتات وملفات اإلعداد المُ َّ‬ ‫‪:AllSigned‬‬ ‫•‬
‫موثوق ة‪ ،‬مم ا يع ني أن ه من المحتم ل أن ُتع ِّرض جه ازك لخط ر تنفي ذ س كربتات ض ارة إن‬
‫َّ‬
‫موقعة من جهة غير موثوقة‪.‬‬ ‫كانت‬

‫نزل ة من الش بكة‪،‬‬ ‫ِّ‬


‫تمكنك من تنفي ذ الس كربتات وملف ات اإلع داد المُ َّ‬ ‫‪ :RemoteSigned‬س‬ ‫•‬
‫والمُ َّ‬
‫وقعة من جه ة موثوق ة‪ ،‬مم ا يع ني احتم ال أن تع ِّرض جه ازك لخط ر تنفي ذ س كربتات‬
‫ضارة إن كانت تلك السكربتات الموثوقة ضارة‪.‬‬

‫‪ :Unrestricted‬تس مح بتنفي ذ جمي ع الس كربتات وملف ات اإلع داد المُ َّ‬
‫نزل ة من الش بكة‬ ‫•‬
‫نز ٌ‬
‫ل من الش بكة‪ .‬في ه ذه الحال ة‪ ،‬التوقيع ات الرقمي ة‬ ‫أن المل ف ُم َّ‬ ‫بمجرد تأكي د َّ‬
‫أنك ت درك ّ‬
‫غير الزمة‪ ،‬مما يعني أ َن ه من المحتمل تعريض جهازك لخطر تنفيذ سكربتات غير موثوق ة‬
‫منزلة من الشبكة قد تكون ضارة‪.‬‬

‫سنس تخدم سياس ة التنفي ذ ‪ RemoteSigned‬لتع يين اإلذن للمس تخدم الح الي‪ ،‬وهك ذا‬

‫سنسمح لبرنامج ‪ PowerShell‬بقب ول الس كربتات المُ َّ‬


‫نزل ة ال تي نث ق به ا‪ ،‬ودون خفض ك ل دفاعاتن ا‬

‫وجعل األذونات َّ‬


‫هشة كما هو الحال مع سياسة التنفيذ ‪ .Unrestricted‬سنكتب في ‪:PowerShell‬‬

‫‪Set-ExecutionPolicy -Scope CurrentUser‬‬

‫س تطالبك ‪ PowerShell‬بتحدي د سياس ة التنفي ذ‪ ،‬وبم ا َّ‬


‫أنن ا نري د اس تخدام‬

‫‪ ،RemoteSigned‬فسنكتب‪:‬‬

‫‪RemoteSigned‬‬

‫▲‬ ‫|‬ ‫‪31‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫بمجرد الضغط على ال زر اإلدخ ال (‪ُ ،)enter‬‬


‫ستس أل عم ا إن كنت نري د تغي ير سياس ة التنفي ذ‪.‬‬

‫اكتب الح رف ‪ y‬الختي ار "نعم"‪ ،‬واعتم اد التغي يرات‪ .‬يمكنن ا التحق ق من نج اح العملي ة عن طري ق‬

‫طلب األذونات الحالية في الجهاز عبر كتابة‪:‬‬

‫‪Get-ExecutionPolicy -List‬‬

‫ستحصل على مخرجات مشابهة لما يلي‪:‬‬

‫‪Scope ExecutionPolicy‬‬
‫‪----- ---------------‬‬
‫‪MachinePolicy‬‬ ‫‪Undefined‬‬
‫‪UserPolicy‬‬ ‫‪Undefined‬‬
‫‪Process‬‬ ‫‪Undefined‬‬
‫‪CurrentUser‬‬ ‫‪RemoteSigned‬‬
‫‪LocalMachine‬‬ ‫‪Undefined‬‬

‫أن المس تخدم الح الي يمكن ه تنفي ذ الس كربتات الموثوق ة ال تي ِّ‬
‫نُزلت من الش بكة‪.‬‬ ‫ه ذا يؤك د َّ‬

‫يمكننا اآلن تنزيل الملفات التي سنحتاج إليها إلعداد بيئة برمجة بايثون‪.‬‬

‫ج‪ .‬تثبيت ‪Chocolatey‬‬

‫م دير الح زم (‪ )package manager‬ه و مجموع ة من أدوات البرمجي ات ال تي تعم ل على‬

‫أتمت ة عملي ات التث بيت‪ ،‬بم ا في ذل ك التث بيت األولي لل برامج‪ ،‬وترقيته ا‪ ،‬وإع دادها‪ ،‬وإزالته ا‬

‫عند الحاجة‪.‬‬

‫تحف ظ ه ذه األدوات التثبيت ات في موق ع مرك زي‪ ،‬ويمكنه ا ص يانة جمي ع ح زم ال برامج على‬

‫النظام وفق تنسيقات (‪ )formats‬معروفة‪.‬‬

‫يع د ‪ Chocolatey‬م دير ح زم مفت وح المص در يعم ل من س طر األوام ر‪ ،‬ص ِّمم لنظ ام وين دوز‪،‬‬

‫▲‬ ‫|‬ ‫‪32‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

.‫ ويمكنه مس اعدتك على تث بيت التطبيق ات واألدوات بس رعة‬،‫ الخاص بلينكس‬apt-get ‫وتحاكي‬

.‫سنستخدمه لتنزيل ما نحتاج إليه لبيئتنا التطويرية‬

.‫أن التغييرات التي سيجريها على الجهاز مقبولة‬


َّ ‫ دعنا نقرؤه للتأكد من‬،‫قبل تثبيت السكربت‬

‫ سننش ئ‬.‫ في ناف ذة الطرفي ة‬Chocolatey ‫ لتنزي ل وع رض الس كربت‬.NET ‫سنستخدم إط ار العم ل‬

‫ في‬$ ‫ (يمكن ك تس ميته كم ا تري د طالم ا ستس تخدم المح رف‬$script ‫ يُ س مى‬WebClient ‫كائ ًن ا‬

:Internet Explorer ‫ والذي يشارك إعدادات االتصال بالشبكة مع المتصفح‬،)‫البداية‬

$script = New-Object Net.WebClient

‫دعن ا نلقي نظ رة على الخي ارات المتاح ة لن ا من خالل توص يل الك ائن إلى الص نف‬

:WebClient ‫ إلعادة جميع األعضاء (الخاصيات والتوابع) الخاصة بكائن‬Get-Member

$script | Get-Member

:‫سنحصل على المخرجات التالية‬

. . .
DownloadFileAsync Method void DownloadFileAsync(uri
address, string fileName), void DownloadFileAsync(ur...
DownloadFileTaskAsync Method System.Threading.Tasks.Task
DownloadFileTaskAsync(string address, string fileNa...
DownloadString Method string DownloadString(string
address), string DownloadString(uri address) # ‫هذا التابع‬
DownloadStringAsync Method void DownloadStringAsync(uri
address), void DownloadStringAsync(uri address, Sy...
DownloadStringTaskAsync Method
System.Threading.Tasks.Task[string]
DownloadStringTaskAsync(string address), Sy…
. . .

▲ | 33
‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫عن د النظ ر إلى المخرج ات‪ ،‬يمكنن ا تحدي د الت ابع ‪ DownloadString‬ال ذي يمكنن ا اس تخدامه‬

‫لعرض محتوى السكربت والتوقيع في نافذة ‪ PowerShell‬كما يلي‪:‬‬

‫)"‪$script.DownloadString("https://chocolatey.org/install.ps1‬‬

‫بعد مطالعة السكربت‪ ،‬يمكننا تثبيت ‪ Chocolatey‬عن طريق كتابة ما يلي في ‪:PowerShell‬‬

‫‪iwr https://chocolatey.org/install.ps1 -UseBasicParsing | iex‬‬

‫تس مح لن ا ‪ iwr‬أو ‪ Invoke-WebRequest‬ال تي تخص ‪ cmdlet‬باس تخراج البيان ات من‬

‫الش بكة‪ .‬س يؤدي ه ذا إلى تمري ر الس كربت إلى ‪ iex‬أو ‪ ،Invoke-Expression‬وال ذي س ينفذ‬

‫محتويات السكربت‪ ،‬وتنفيذ سكربت التثبيت لمدير الحزم ‪.Chocolatey‬‬

‫اسمح لبرنامج ‪ PowerShell‬بتث بيت ‪ .Chocolatey‬بمج رد تثبيت ه بالكام ل‪ ،‬يمكنن ا الب دء في‬

‫تثبيت أدوات إضافية باستخدام األمر ‪.choco‬‬

‫إن احتجت إلى ترقية ‪ Chocolatey‬مستقباًل ‪ ،‬يمكنك تنفيذ األمر التالي‪:‬‬

‫‪choco upgrade chocolatey‬‬

‫بعد تثبيت مدير الحزم‪ ،‬يمكننا متابعة تثبيت ما نحتاجه لبيئة البرمجة خاصتنا‪.‬‬

‫د‪ .‬تثبيت محرر النصوص ‪( nano‬اختياري)‬

‫س نثبِّت اآلن ‪ ،nano‬وه و مح ِّرر نص وص يس تخدم واجه ة س طر األوام ر‪ ،‬وال ذي يمكنن ا‬

‫استخدامه لكتابة البرامج مباشرة داخل ‪ .PowerShell‬ه ذه ليس ت خط وة إلزامي ة‪ ،‬إذ يمكن ك ب دال‬

‫من ذلك استخدام محرر نص وص بواجه ة مس تخدم رس ومية مث ل ‪ ،Notepad‬لكن م يزة ‪ nano‬أنه‬

‫س ُي ِّ‬
‫عودك على اس تخدام ‪ .PowerShell‬دعن ا نس تخدم ‪ Chocolatey‬لتث بيت ‪ nano‬وذل ك بتنفي ذ‬

‫األمر التالي‪:‬‬

‫▲‬ ‫|‬ ‫‪34‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫‪choco install -y nano‬‬

‫تلقائي ا دون الحاج ة إلى تأكي د‪ .‬بع د تث بيت‬


‫ً‬ ‫الخيار ‪ -y‬يعني َّ‬
‫أنك توافق على تنفي ذ الس كربت‬

‫‪ ،nano‬سنكون قادرين على استخدام األمر ‪ nano‬إلنشاء ملف ات نص ية جدي دة‪ ،‬وسنس تخدمه بع د‬

‫حين لكتابة أول برامجنا في بايثون‪.‬‬

‫ه‪ .‬تثبيت بايثون ‪3‬‬

‫مثلما فعلنا مع ‪ nano‬أعاله‪ ،‬سنستخدم ‪ Chocolatey‬لتثبيت بايثون ‪:3‬‬

‫‪choco install -y python3‬‬

‫س تثبِّت ‪ PowerShell‬اآلن ب ايثون ‪ ،3‬م ع ع رض بعض المخرج ات أثن اء العملي ة‪ .‬بع د اكتم ال‬

‫العملية‪ ،‬سترى المخرجات التالية‪:‬‬

‫‪Environment Vars (like PATH) have changed. Close/reopen your‬‬


‫‪shell to‬‬
‫‪See the changes (or in powershell/cmd.exe just type‬‬
‫‪'refreshenv').‬‬
‫‪The install of python3 was successful.‬‬

‫‪Software installed as 'EXE', install location is‬‬ ‫‪likely‬‬


‫‪default.‬‬

‫‪Chocolatey installed 1/1 packages. 0 packages failed.‬‬


‫\‪See the log for details (C:\ProgramData\chocolatey\logs‬‬
‫‪chocolatey.log).‬‬

‫بعد االنتهاء من التث بيت‪ ،‬س تحتاج إلى التحق ق من تث بيت ب ايثون وجهوزيته ا للعم ل‪ .‬لرؤي ة‬

‫التغي يرات‪ ،‬اس تخدم األم ر ‪ refreshenv‬أو أغل ق ‪ PowerShell‬ثم أع د فتحه ا بص الحيات م دير‬

‫▲‬ ‫|‬ ‫‪35‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫النظام‪ ،‬ثم تحقق من إصدار بايثون على جهازك‪:‬‬

‫‪python -V‬‬

‫المثبت‪.‬‬
‫َّ‬ ‫ستحصل على مخرجات في نافذة الطرفية والتي ستريك إصدار بايثون‬

‫‪Python 3.7.0‬‬

‫ٌ‬
‫أداة تعم ل م ع لغ ة ب ايثون ُت َثبِّ ت وت دير الح زم‬ ‫س نثبِّ ت األداة ‪ ،pip‬إلى ج انب ب ايثون‪ ،‬وهي‬

‫البرمجي ة ال تي ق د نحت اج إلى اس تخدامها في تط وير مش اريعنا (س نتعلم المزي د عن الوح دات‬

‫المخصص للوحدات)‪.‬‬
‫َّ‬ ‫والحزم التي يمكنك تثبيتها باألداة ‪ pip‬في الفصل‬

‫ِّ‬
‫سنحدث ‪ pip‬عبر األمر التالي‪:‬‬

‫‪python -m pip install --upgrade pip‬‬

‫يمكنن ا اس تدعاء ب ايثون من ‪ Chocolatey‬ع بر األم ر ‪ .python‬سنس تخدم الراي ة ‪ -m‬لتنفي ذ‬

‫الوحدة كأنها سكربت‪ ،‬وإنهاء قائمة الخيارات‪ ،‬ومن ثمَّ نستخدم ‪ pip‬لتثبيت اإلصدار األحدث‪.‬‬

‫بع د تث بيت ب ايثون وتح ديث ‪ ،pip‬فنحن ج اهزون إلع داد بيئ ة افتراض ية لمش اريع‬

‫التطوير خاصتنا‪.‬‬

‫و‪ .‬إعداد بيئة افتراضية‬

‫اآلن بع د تث بيت ‪ Chocolatey‬و ‪ nano‬وب ايثون‪ ،‬يمكنن ا المض ي ق دمً ا إلنش اء بيئ ة البرمج ة‬

‫خاصتنا عبر الوحدة ‪.venv‬‬

‫ُت ِّ‬
‫مكن ك البيئ ات االفتراض ية من إنش اء مس احة معزول ة في حاس وبك مخصص ة لمش اريع‬

‫أن كل مشروع تعمل عليه ستكون له اعتماديَّ ات ه (‪ )dependencies‬الخاص ة ب ه‪،‬‬


‫بايثون‪ ،‬مما يعني َّ‬
‫ِّ‬
‫تؤثر على غيره من المشاريع‪.‬‬ ‫والتي لن‬

‫▲‬ ‫|‬ ‫‪36‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫دارات‬
‫ٍ‬ ‫ي ِّ‬
‫وفر لن ا ض بط بيئ ةٍ برمجي ةٍ تحكمً ا أك بر بمش اريع ب ايثون‪ ،‬وإمكاني ة التعام ل م ع إص‬

‫مختلفةٍ من حزم بايثون‪ .‬وهذا مهمٌ كثيرًا عندما تتعامل مع الحزم الخارجية‪.‬‬

‫أي ع ددٍ تش اء من البيئ ات االفتراض َّية‪ ،‬وك ل بيئ ة س تكون ممثل ة بمجل د في‬
‫يمكن ك ض بط ِّ‬

‫حاسوبك يحتوي على عدد من السكربتات‪.‬‬

‫اختر المجلد الذي تريد أن تضع فيه بيئات ب ايثون‪ ،‬أو يمكن ك إنش اء مجل د جدي د باس تخدام‬

‫األمر ‪ mkdir‬كما يلي‪:‬‬

‫‪mkdir environments‬‬
‫‪cd environments‬‬

‫َ‬
‫انتقلت إلى المجلد الذي تريد احت واء البيئ ات في ه‪ ،‬تس تطيع اآلن إنش اء بيئ ة جدي دة‬ ‫بعد أن‬

‫بتنفيذ األمر التالي‪:‬‬

‫‪python -m venv my_env‬‬

‫س ِّ‬
‫ننفذ باس تخدام األم ر ‪ python‬الوح دة ‪ venv‬إلنش اء البيئ ة االفتراض ية ال تي أطلقن ا عليه ا‬

‫في هذه الحالة ‪.my_env‬‬

‫ستنش ئ ‪ venv‬مجل ًدا جدي ًدا يحت وي على بعض العناص ر ال تي يمكن عرض ها باس تخدام‬

‫األمر ‪:ls‬‬

‫‪ls my_env‬‬

‫سنحصل على المخرجات التالية‪:‬‬

‫‪Mode‬‬ ‫‪LastWriteTime‬‬ ‫‪Length Name‬‬


‫‪----‬‬ ‫‪-------------‬‬ ‫‪------ ----‬‬
‫‪d-----‬‬ ‫‪8/22/2016‬‬ ‫‪2:20 PM‬‬ ‫‪Include‬‬

‫▲‬ ‫|‬ ‫‪37‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫‪d-----‬‬ ‫‪8/22/2016‬‬ ‫‪2:20 PM‬‬ ‫‪Lib‬‬


‫‪d-----‬‬ ‫‪8/22/2016‬‬ ‫‪2:20 PM‬‬ ‫‪Scripts‬‬
‫‪-a----‬‬ ‫‪8/22/2016‬‬ ‫‪2:20 PM‬‬ ‫‪107 pyvenv.cfg‬‬

‫تعم ل ه ذه الملف ات م ع بعض ها لض مان أن تك ون مش اريعك معزول ٌة عن س ياق اآلل ة المحلي ة‪،‬‬

‫لكي ال تختلط ملفات النظ ام م ع ملف ات المش اريع‪ .‬وه ذا أم رٌ حس ٌن إلدارة اإلص دارات ولض مان َّ‬
‫أن‬

‫الحزم التي يحتاجها‪.‬‬


‫ٍ‬ ‫كل مشروع يملك وصواًل إلى‬

‫عليك تفعيل البيئة الستخدامها‪ ،‬وذلك بكتاب ة األم ر الت الي ال ذي س ُي ِّ‬
‫نفذ س كربت التفعي ل في‬

‫المجلد ‪:Scripts‬‬

‫‪my_env\Scripts\activate‬‬

‫ٌ‬
‫ابقة (‪ )prefix‬في المِ َحث (‪ )prompt‬وال تي هي اس م البيئ ة‬ ‫يجب أن تظه ر اآلن س‬

‫المستخدمة‪ ،‬وفي حالتنا هذه يكون اسمها ‪.my_env‬‬

‫>‪(my_env) PS C:\Users\Sammy\Environments‬‬

‫حاليا‪ ،‬وهذا يع ني َّ‬


‫أنن ا لن سنس تخدم إال‬ ‫ً‬ ‫أن البيئة ‪ my_env‬مفعَّ لة‬
‫تتيح لنا هذه البادئة معرفة َّ‬

‫إعدادات وحزم هذه البيئة عند إنشاء مشاريع جديدة‪.‬‬

‫ز‪ .‬إنشاء برنامج بسيط‬

‫ِ‬
‫لننش ئ برنامج ا بس يطا يع رض العب ارة «مرحب ا‬ ‫بع د أن أكملن ا ض بط بيئتن ا االفتراض ية‪،‬‬

‫أن البيئ ة تعم ل بالش كل الص حيح‪ ،‬ولكي تتع وَّ د على إنش اء ب رامج‬
‫بالع الم!»‪ ،‬وبه ذا س نتحقق من َّ‬

‫كنت واف ًدا جدي ًدا على اللغة‪.‬‬


‫َ‬ ‫بايثون إن‬

‫علينا أواًل تشغيل المحرر ‪ nano‬وإنشاء ملف جديد‪:‬‬

‫▲‬ ‫|‬ ‫‪38‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫‪(my_env) PS C:\Users\Sammy> nano hello.py‬‬

‫بعد فتح الملف في نافذة الطرفية‪ ،‬سنكتب البرنامج الخاص بنا‪:‬‬

‫)"!‪print("Hello, World‬‬

‫أغلق محرر ‪ nano‬بالضغط على ‪ Ctrl+x‬ثم اضغط على ‪ y‬عندما يسألك عن حفظ الملف‪.‬‬

‫بعد أن يُ َ‬
‫غلق المُ ِّ‬
‫حرر ‪ nano‬وتعود إلى سطر األوامر‪ ،‬حاول تنفيذ البرنامج‪:‬‬

‫‪(my_env) PS C:\Users\Sammy> python hello.py‬‬

‫َ‬
‫أنشأته إلى طباعة الناتج التالي في الطرفية‪:‬‬ ‫سيؤدي برنامج ‪ hello.py‬الذي‬

‫!‪Hello, World‬‬

‫للخروج من البيئة‪ ،‬اكتب األمر ‪ deactivate‬وستعود إلى مجلدك األص لي‪ .‬ح ان اآلن ال وقت‬

‫للتعم ق بلغ ة ب ايثون وإنش اء ب رامج رائع ة! انتق ل إلى الفص ل الت الي‪ ،‬اس تخدام س طر أوام ر‬

‫بايثون التفاعلي‪.‬‬

‫▲‬ ‫|‬ ‫‪39‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫‪ .2‬أوبنتو‬
‫وة بخط وة إلى كيفي ة تث بيت ب ايثون ‪ 3‬على خ ادم أوبنت و ‪،20.04‬‬
‫رش ُدك ه ذا القس م خط ً‬
‫سي ِ‬
‫ُ‬

‫البرمجة على الخوادم لها العديد من الميزات‪ ،‬كما تدعم المشاريع التعاونية‪.‬‬

‫أن ه ذا القس م يش رح عملي ة التث بيت على خ ادم أوبنت و ‪ ،20.04‬إال َّ‬
‫أن المف اهيم‬ ‫حيح َّ‬
‫ٌ‬ ‫ص‬

‫األساسية فيه تنطبق على جميع توزيعات دبيان لينكس (‪.)Debian Linux‬‬

‫ا‪ .‬المتطلبات المسبقة‬

‫يجب أن تملك ص الحيات مس تخدم غ ير ج ذري (‪ ) non-root user‬م ع امتي ازات ‪ sudo‬على‬

‫خ ادم أوبنت و ‪ .20.04‬إذا لم تكن ل ك خ برة في التعام ل م ع بيئ ة الناف ذة الطرفي ة‪ ،‬فيمكن ك مطالع ة‬

‫طرفيِة لينكس ‪.»Linux Terminal‬‬


‫ّ‬ ‫المقال «مدخل إلى‬

‫ب‪ .‬إعداد بايثون ‪3‬‬

‫مثبت ة مس ً‬
‫بقا‪.‬‬ ‫َّ‬ ‫في أوبنتو ‪ 20.04‬واإلصدارات األخ رى من دبي ان لينكس‪ ،‬س تجد أن ب ايثون ‪3‬‬

‫تخدام‬ ‫ه باس‬ ‫َّ‬


‫ونرقي‬ ‫ام‬ ‫ِّ‬
‫نحدث النظ‬ ‫ة‪ ،‬س‬ ‫ايثون حديث‬ ‫دارات ب‬ ‫أن إص‬
‫د من َّ‬ ‫للتأك‬

‫األمر ‪ apt‬للعمل مع أداة التحزيم المتقدمة من أوبنتو ( ‪:)Ubuntu’s Advanced Packaging Tool‬‬

‫‪sudo apt update‬‬


‫‪sudo apt -y upgrade‬‬

‫الخي ار ‪ -y‬يع ني َّ‬


‫أنك تواف ق على تث بيت جمي ع الح زم القابل ة للتح ديث‪ ،‬لكن ق د تحت اج إلى‬

‫تأكي د ذل ك عن د تح ديث النظ ام وذل ك اعتم ا ًدا على الح زم ال تي س ُتح َّدث‪ ،‬ونس خة نظام ك‪ .‬بع د‬

‫إكمال العملية‪ ،‬يمكن التحقق من إصدار بايثون ‪ 3‬المُ َّ‬


‫ثبت في النظام بكتابة‪:‬‬

‫▲‬ ‫|‬ ‫‪40‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫‪python3 -V‬‬

‫المثبت‪ .‬قد يختلف‬


‫َّ‬ ‫ستحصل على مخرجات في نافذة الطرفية والتي ستريك إصدار بايثون‬

‫ً‬
‫شبيها بما يلي‪:‬‬ ‫بناء على النسخة المثبتة في توزيعتك‪ ،‬لكن يجب أن يكون‬
‫ً‬ ‫الرقم‬

‫‪Python 3.8.2‬‬

‫ٌ‬
‫أداة تعم ل م ع لغ ة ب ايثون ُت َثبِّت‬ ‫إلدارة الحزم البرمجي ة الخاص ة بب ايثون‪ ،‬س نثبِّ ت ‪ ،pip‬وهي‬

‫وتدير الح زم البرمجي ة ال تي ق د نحت اج إلى اس تخدامها في تط وير مش اريعنا (س نتعلم المزي د عن‬

‫المخصص للوحدات)‪:‬‬
‫َّ‬ ‫الوحدات والحزم التي يمكنك تثبيتها باألداة ‪ pip‬في الفصل‬

‫‪sudo apt install -y python3-pip‬‬

‫يمكن تثبيت حزم بايثون بكتابة ما يلي مع تبديل ‪ package_name‬باسم الحزمة‪:‬‬

‫‪pip3 install package_name‬‬

‫علي ك وض ع اس م الحزم ة أو المكتب ة التابع ة لب ايثون مك ان ‪ package_name‬مث ل ‪Django‬‬

‫لتط وير ال ويب‪ ،‬أو ‪ NumPy‬لتثبيته ا؛ ل ذا‪ ،‬إن ش َ‬


‫ئت تث بيت ‪ NumPy‬فيمكن ك تنفي ذ األم ر‬

‫‪.pip3 install numpy‬‬

‫أن بيئة البرمجة جاهزة‪:‬‬


‫هناك عدة حزم وأدوات تطوير أخرى يجب تثبيتها للتأكد من ّ‬

‫‪sudo apt install -y build-essential libssl-dev libffi-dev‬‬


‫‪python3-dev‬‬

‫بع د أن انتهين ا من ض بط ب ايثون وتث بيت ‪ ،pip‬يمكنن ا اآلن إنش اء «بيئ ة افتراض ية»‬

‫(‪ )virtual environment‬لمشاريعنا‪.‬‬

‫▲‬ ‫|‬ ‫‪41‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫ج‪ .‬إعداد بيئة افتراضية‬

‫ُت ِّ‬
‫مك نك البيئات االفتراضية من إنشاء مساحة معزولة في خادمك مخصصة لمشاريع ب ايثون‪،‬‬

‫أن كل مش روع تعم ل علي ه س تكون ل ه اعتماديَّ ات ه (‪ )dependencies‬الخاص ة ب ه‪ ،‬وال تي‬


‫مما يعني َّ‬
‫ِّ‬
‫تؤثر على غيره من المشاريع‪.‬‬ ‫لن‬

‫دارات‬
‫ٍ‬ ‫ي ِّ‬
‫وفر لن ا ض بط بيئ ةٍ برمجي ةٍ تحكمً ا أك بر بمش اريع ب ايثون‪ ،‬وإمكاني ة التعام ل م ع إص‬

‫مختلفةٍ من حزم بايثون‪ .‬وهذا مهمٌ كثيرًا عندما تتعامل مع الحزم الخارجية‪.‬‬

‫أي ع ددٍ تش اء من البيئ ات االفتراض ية‪ ،‬وك ل بيئ ة س تكون ممثل ة بمجل د في‬
‫يمكن ك ض بط ُّ‬

‫خادمك يحتوي على عدد من السكربتات‪.‬‬

‫هناك عدة طرق إلعداد بيئة برمجية في بايثون‪ ،‬لكننا سنس تخدم وح دة (‪ )module‬برمجي ة‬

‫زء من مكتب ة ب ايثون ‪ 3‬القياس ية‪ .‬س نثبِّت ‪ venv‬على نظامن ا بتنفي ذ‬
‫باس م ‪ ،venv‬وهي ج ٌ‬

‫األمر التالي‪:‬‬

‫‪sudo apt-get install -y python3-venv‬‬

‫بعد إتمام التثبيت‪ ،‬فنحن جاهزون إلنشاء البيئ ات االفتراض ية‪ ،‬يمكنن ا اآلن إمَّ ا اختي ار مجل د‬

‫نضع فيه بيئات بايثون‪ ،‬أو إنشاء مجلد جديد باستخدام األمر ‪ mkdir‬كما يلي‪:‬‬

‫‪mkdir environments‬‬
‫‪cd environments‬‬

‫َ‬
‫انتقلت إلى المجلد الذي تريد احت واء البيئ ات في ه‪ ،‬تس تطيع اآلن إنش اء بيئ ة جدي دة‬ ‫بعد أن‬

‫بتنفيذ األمر اآلتي‪:‬‬

‫‪python3.6 -m venv my_env‬‬

‫▲‬ ‫|‬ ‫‪42‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫نش ئ األم ر ‪ pyvenv‬مجل ًدا جدي ًدا في ه بعض الملف ات ال تي يمكن عرض ها باس تخدام‬
‫سي ِ‬
‫ُ‬

‫األمر ‪:ls‬‬

‫‪ls my_env‬‬

‫ستظهر لك مخرجات شبيهة بالمخرجات التالية‪:‬‬

‫‪bin include lib lib64 pyvenv.cfg share‬‬

‫أن تك ون مش اريعك معزول ٌة عن س ياق اآلل ة المحلي ة‪،‬‬


‫تعم ل ه ذه الملف ات م ع بعض ها لض مان َ‬

‫لكي ال تختلط ملفات النظ ام م ع ملف ات المش اريع‪ .‬وه ذا أم رٌ حس ٌن إلدارة اإلص دارات ولض مان َّ‬
‫أن‬

‫ً‬
‫أيض ا ‪ ،Python Wheels‬وال تي هي‬ ‫الحزم ال تي يحت اج إليه ا‪ .‬تت وافر‬
‫ٍ‬ ‫كل مشروع يملك وصواًل إلى‬

‫زم مبني ة (‪ )built-package format‬لب ايثون‪ ،‬وال تي يمكن أن ُتس ِّرع من تط وير ال برامج‬
‫ص يغة ح ٍ‬

‫ٌ‬
‫ودة في‬ ‫بتقلي ل ع دد الم رات ال تي تحت اج فيه ا إلى تص ريف (‪ )compile‬المش روع‪ ،‬وهي موج‬

‫المجلد ‪ share‬في توزيعة أوبنتو ‪.20.04‬‬

‫سي ِّ‬
‫نفذ سكربت التفعيل‪:‬‬ ‫عليك تفعيل البيئة الستخدامها‪ ،‬وذلك بكتابة األمر التالي الذي ُ‬

‫‪source my_env/bin/activate‬‬

‫ٌ‬
‫ابقة (‪ )prefix‬في المِ حث (‪ )prompt‬وال تي هي اس م البيئ ة‬ ‫يجب أن تظه ر اآلن س‬

‫ً‬
‫مختلف ا في توزيع ة‬ ‫المستخدمة‪ ،‬وفي حالتنا هذه يكون اس مها ‪ ،my_env‬وق د يك ون مظه ر المِ َحث‬

‫دبي ان‪ ،‬وذل ك اعتم ا ًدا على اإلص دار المس تخدم؛ لكن يجب أن تش اهد اس م البيئ ة بين قوس ين في‬

‫بداية السطر‪:‬‬

‫‪(my_env) sammy@ubuntu:~/environments$‬‬

‫▲‬ ‫|‬ ‫‪43‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫أن البيئ ة ‪ my_env‬مفعَّ ل ة حالي ا‪ ،‬وه ذا يع ني َّ‬


‫أنن ا سنس تخدم‬ ‫ستس مح ل ك الس ابقة بمعرف ة َّ‬

‫إعدادات وحزم هذه البيئة عند إنشاء مشاريع جديدة‪.‬‬

‫ً‬
‫جاهزة لالستخدام بعد اتباعك للخطوات السابقة‪.‬‬ ‫يجب أن تكون بيئتك االفتراضية‬

‫مالحظة‪ :‬يمكنك داخل البيئة االفتراضية أن تستخدم األمر ‪ python‬بداًل من ‪ python3‬واألمر ‪ pip‬ب داًل من‬

‫كنت تس تخدم ب ايثون‪ 3‬خ ارج البيئ ة االفتراض َّية‪ ،‬فيجب علي ك حينه ا اس تخدام‬
‫َ‬ ‫إن ش َ‪.‬‬
‫ئت أم ا إذا‬ ‫‪pip3‬‬
‫‪ python3‬و ‪ pip3‬حصرًا‪.‬‬

‫د‪ .‬إنشاء برنامج بسيط‬

‫ِ‬
‫لننش ئ برنامج ا بس يطا يع رض العب ارة‬ ‫بع د أن أكملن ا ض بط بيئتن ا االفتراض ية‪،‬‬

‫أن البيئ ة تعم ل بالش كل الص حيح‪ ،‬ولكي تتع وَّ د على إنش اء‬ ‫َّ‬
‫َتحقق من َّ‬
‫«!‪ ،»Hello World‬وبهذا س ن‬

‫كنت واف ًدا جدي ًدا على اللغة‪.‬‬


‫َ‬ ‫برامج بايثون إن‬

‫علينا أواًل تشغيل محرر ملفات نصية إلنشاء ملف جديد‪ ،‬وليكن المُ ِّ‬
‫حرر ‪ nano‬الذي يعمل من‬

‫سطر األوامر‪:‬‬

‫‪(my_env) sammy@ubuntu:~/environments$ nano hello.py‬‬

‫بعد فتح الملف في نافذة الطرفية‪ ،‬سنكتب البرنامج الخاص بنا‪:‬‬

‫)"!‪print("Hello World‬‬

‫أغلق محرر ‪ nano‬بالضغط على ‪ Ctrl+x‬ثم اضغط على ‪ y‬عندما يسألك عن حفظ المل ف‪ .‬بع د‬

‫أن يُ َ‬
‫غلق المحرر ‪ nano‬وتعود إلى سطر األوامر‪ ،‬حاول تنفيذ البرنامج‪:‬‬

‫‪(my_env) sammy@ubuntu:~/environments$ python hello.py‬‬

‫▲‬ ‫|‬ ‫‪44‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫َ‬
‫أنشأته إلى طباعة الناتج اآلتي في الطرفية‪:‬‬ ‫سيؤدي برنامج ‪ hello.py‬الذي‬

‫!‪Hello World‬‬

‫للخروج من البيئة‪ ،‬اكتب األمر ‪ deactivate‬وستعود إلى مجلدك األصلي‪.‬‬

‫ضبطت اآلن بيئة تطوير للغة بايثون ‪ 3‬على خادم أوبنتو‪ ،‬وح ان ال وقت للتعم ق‬
‫َ‬ ‫تهانينا! لقد‬

‫بلغة بايثون وإنشاء برامج رائعة! انتقل إلى الفصل التالي‪ ،‬استخدام سطر أوامر بايثون التفاعلي‪.‬‬

‫▲‬ ‫|‬ ‫‪45‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫‪ .3‬دبيان‬
‫وة بخط وة إلى كيفي ة تث بيت ب ايثون ‪ 3‬على لينكس‪ ،‬وتث بيت بيئ ة‬
‫رش ُدك ه ذا القس م خط ً‬
‫سي ِ‬
‫ُ‬

‫أن ه ذا القس م يش رح عملي ة التث بيت في دبي ان ‪ ،10‬إال َّ‬


‫أن‬ ‫حيح َّ‬
‫ٌ‬ ‫برمج ة ع بر س طر األوام ر‪ .‬ص‬

‫المفاهيم األساسية فيه تنطبق على جميع توزيعات دبيان لينكس (‪.)Debian Linux‬‬

‫ا‪ .‬المتطلبات المسبقة‬

‫يجب أن تمل ك ص الحيات مس تخدم غ ير ج ذري ( ‪ )non-root user‬م ع امتي ازات ‪ sudo‬على‬

‫توزيعة دبيان ‪ ،10‬أو توزيعة أخرى من دبيان لينكس (‪.)Debian Linux‬‬

‫إذا لم تكن ل ك خ برة في التعام ل م ع بيئ ة الناف ذة الطرفي ة‪ ،‬فيمكن ك مطالع ة المق ال‬

‫طرفية لينكس ‪.»Linux Terminal‬‬


‫ّ‬ ‫«مدخل إلى‬

‫ب‪ .‬إعداد بايثون ‪3‬‬

‫س ُنثبِّ ت ونض بط ب ايثون ع بر س طر األوام ر‪ ،‬وال ذي ه و طريق ٌة غ يرُ رس وميةٍ للتعام ل م ع‬

‫ظهر ل ك‬ ‫ِّ‬ ‫الحاس وب‪ ،‬فب داًل من الض غط على األزرار‪ ،‬س تكتب ًّ‬
‫نص ا وتعطي ه للحاس وب لينفذه‪ ،‬وس ُي ِ‬

‫ً‬
‫أيضا‪ .‬يمكن أن يساعدك سطر األوامر على تعديل أو أتمتة مختلف المهام التي تنجزه ا‬ ‫نصيا‬
‫ً‬ ‫ً‬
‫ناتجا‬

‫أداة أساس ٌ‬
‫ية لمط وري البرمجي ات‪ ،‬وهنال ك الكث ير من األوام ر ال تي‬ ‫ٌ‬ ‫على الحاس وب يومي ا‪ ،‬وه و‬

‫علي ك تعلمه ا لكي تتمكن من االس تفادة من ه‪ .‬هنال ك مق االت في أكاديمي ة حس وب (مث ل مق ال‬

‫م دخل إلى طرفي ة لينكس ‪ )Linux Terminal‬س تعلمك أساس يات س طر األوام ر‪ ،‬وهنال ك كت اب‬

‫«سطر أوامر لينكس» الذي يُ ع ُّد مرجعً ا لطريقة التعامل مع سطر األوامر‪.‬‬

‫▲‬ ‫|‬ ‫‪46‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫ستجد تط بيق ‪( Terminal‬البرن امج ال ذي تس تعمله للوص ول إلى س طر األوام ر) بفتح القائم ة‬

‫في الزاوية السفلى اليسرى من الشاشة ثم كتاب ة «‪ »terminal‬في ش ريط البحث‪ ،‬ثم الض غط على‬

‫أيقون ة التط بيق ال تي س تظهر بعدئ ذٍ‪ .‬أو يمكن ك أن تض غط على ‪ Ctrl+Alt+T‬في لوح ة المف اتيح‬

‫بنفس الوقت لتشغيل تطبيق ‪.Terminal‬‬

‫في دبيان ‪ 10‬واإلصدارات األخرى من دبيان لينكس‪ ،‬ستجد ب ايثون َّ‬


‫مثبت ة مس ً‬
‫بقا‪ .‬للتأك د من‬

‫تخدام‬ ‫ه باس‬ ‫ِّ‬


‫ونرقي‬ ‫ام‬ ‫ِّ‬
‫نحدث النظ‬ ‫ة‪ ،‬س‬ ‫ايثون حديث‬ ‫دارات ب‬ ‫أن إص‬
‫َّ‬

‫األمر ‪:apt‬‬

‫‪sudo apt update‬‬


‫‪sudo apt -y upgrade‬‬

‫▲‬ ‫|‬ ‫‪47‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫الخي ار ‪ -y‬يع ني َّ‬


‫أنك تواف ق على تث بيت جمي ع الح زم القابل ة للتح ديث‪ ،‬لكن ق د تحت اج إلى‬

‫تأكيد ذلك عند تحديث النظام وذلك اعتما ًدا على الحزم التي ُ‬
‫ستح َّدث‪ ،‬ونسخة لينكس‪.‬‬

‫العملية‪ ،‬يمكننا التحقق من إصدار بايثون ‪ 3‬المُ َّ‬


‫ثبت في النظام بكتابة‪:‬‬ ‫َّ‬ ‫بعد إكمال‬

‫‪python3 -V‬‬

‫المثبت‪ .‬قد يختلف‬


‫َّ‬ ‫ستحصل على مخرجات في نافذة الطرفية والتي ستريك إصدار بايثون‬

‫ً‬
‫شبيها بما يلي‪:‬‬ ‫المثبتة في توزيعتك‪ ،‬لكن يجب أن يكون‬
‫َّ‬ ‫بناء على النسخة‬
‫ً‬ ‫الرقم‬

‫‪Python 3.7.3‬‬

‫ٌ‬
‫أداة تعم ل م ع لغ ة ب ايثون ُت َثبِّت‬ ‫إلدارة الحزم البرمجي ة الخاص ة بب ايثون‪ ،‬س نثبِّ ت ‪ ،pip‬وهي‬

‫وتدير الحزم البرمجية ال تي ق د نحت اج إلى اس تخدامها في تط وير مش اريعنا (س نتعلم المزي د عن‬

‫المخصص للوحدات)‪:‬‬
‫َّ‬ ‫الوحدات والحزم التي يمكنك تثبيتها باألداة ‪ pip‬في الفصل‬

‫‪sudo apt install -y python3-pip‬‬

‫يمكن تثبيت حزم بايثون بكتابة ما يلي مع تبديل ‪ package_name‬باسم الحزمة‪:‬‬

‫‪pip3 install package_name‬‬

‫علي ك وض ع اس م الحزم ة أو المكتب ة التابع ة لب ايثون مك ان ‪ package_name‬مث ل ‪Django‬‬

‫َ‬
‫شئت تنزي ل ‪ NumPy‬فيمكن ك تنفي ذ‬ ‫لتطوير الويب‪ ،‬أو ‪ NumPy‬إلجراء الحسابات العلمية؛ لذا‪ ،‬إن‬

‫األمر ‪.pip3 install numpy‬‬

‫أن بيئة البرمجة جاهزة‪:‬‬


‫هناك عدة حزم وأدوات تطوير أخرى يجب تثبيتها للتأكد من ّ‬

‫‪sudo apt install build-essential libssl-dev libffi-dev python3-‬‬


‫‪dev‬‬

‫▲‬ ‫|‬ ‫‪48‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫بع د أن انتهين ا من ض بط ب ايثون وتث بيت ‪ ،pip‬يمكنن ا اآلن إنش اء «بيئ ة افتراض ية»‬

‫(‪ )virtual environment‬لمشاريعنا‪.‬‬

‫ج‪ .‬إعداد بيئة افتراضية‬

‫ُت ِّ‬
‫مكن ك البيئ ات االفتراض ية من إنش اء مس احة معزول ة في حاس وبك مخصص ة لمش اريع‬

‫أن كل مشروع تعمل عليه ستكون له اعتماديَّ ات ه (‪ )dependencies‬الخاص ة ب ه‪،‬‬


‫بايثون‪ ،‬مما يعني َّ‬
‫ِّ‬
‫تؤثر على غيره من المشاريع‪.‬‬ ‫والتي لن‬

‫دارات‬
‫ٍ‬ ‫وإمكانية التعام ل م ع إص‬ ‫ي ِّ‬
‫وفر لن ا ض بط بيئ ةٍ برمجي ةٍ تحكم ا أك بر بمش اريع ب ايثون‪،‬‬
‫َّ‬

‫مختلفةٍ من حزم بايثون‪ .‬وهذا مهمٌ كثيرًا عندما تتعامل مع الحزم الخارجية‪.‬‬

‫أي ع ددٍ تش اء من البيئ ات االفتراض ية‪ ،‬وك ل بيئ ة س تكون ممثل ة بمجل د في‬
‫يمكن ك ض بط ُّ‬

‫حاسوبك يحتوي على عدد من السكربتات‪.‬‬

‫هناك عدة طرق إلعداد بيئة برمجية في بايثون‪ ،‬لكننا سنس تخدم وح دة (‪ )module‬برمجي ة‬

‫جزء من مكتبة بايثون ‪ 3‬القياسية‪ .‬سنثبِّ ت ‪ venv‬على نظامنا بكتابة‪:‬‬


‫ٌ‬ ‫باسم ‪ ،venv‬وهي‬

‫‪sudo apt install -y python3-venv‬‬

‫بعد إتمام التثبيت‪ ،‬فنحن جاهزون إلنشاء البيئ ات االفتراض ية‪ ،‬يمكنن ا اآلن إمَّ ا اختي ار مجل د‬

‫نضع فيه بيئات بايثون‪ ،‬أو إنشاء مجلد جديد باستخدام األمر ‪ mkdir‬كما يلي‪:‬‬

‫‪mkdir environments‬‬
‫‪cd environments‬‬

‫َ‬
‫انتقلت إلى المجلد الذي تريد احت واء البيئ ات في ه‪ ،‬تس تطيع اآلن إنش اء بيئ ة جدي دة‬ ‫بعد أن‬

‫بتنفيذ األمر اآلتي‪:‬‬

‫▲‬ ‫|‬ ‫‪49‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫‪python3.7 -m venv my_env‬‬

‫نش ئ األم ر ‪ pyvenv‬مجل ًدا جدي ًدا في ه بعض الملف ات ال تي يمكن عرض ها باس تخدام‬
‫سي ِ‬
‫ُ‬

‫األمر ‪:ls‬‬

‫‪ls my_env‬‬

‫ستظهر لك مخرجات شبيهة بالمخرجات التالية‪:‬‬

‫‪bin include lib lib64 pyvenv.cfg share‬‬

‫أن تك ون مش اريعك معزول ٌة عن س ياق اآلل ة المحلي ة‪،‬‬


‫تعم ل ه ذه الملف ات م ع بعض ها لض مان َ‬

‫لكي ال تختلط ملفات النظ ام م ع ملف ات المش اريع‪ .‬وه ذا أم رٌ حس ٌن إلدارة اإلص دارات ولض مان َّ‬
‫أن‬

‫ً‬
‫أيض ا ‪ ،Python Wheels‬وال تي هي‬ ‫الحزم ال تي يحت اج إليه ا‪ .‬تت وافر‬
‫ٍ‬ ‫كل مشروع يملك وصواًل إلى‬

‫زم (مث ل ‪ )built-package format‬لب ايثون‪ ،‬وال تي يمكن أن ُتس ِّرع من تط وير‬
‫ص يغة بن اء ح ٍ‬

‫ٌ‬
‫ودة‬ ‫ال برامج بتقلي ل ع دد الم رات ال تي تحت اج فيه ا إلى تص ريف (‪ )compile‬المش روع‪ ،‬وهي موج‬

‫في كل المجلدات المُ سمّ اة ‪.lib‬‬

‫سي ِّ‬
‫نفذ سكربت التفعيل‪:‬‬ ‫عليك تفعيل البيئة الستخدامها‪ ،‬وذلك بكتابة األمر التالي الذي ُ‬

‫‪source my_env/bin/activate‬‬

‫ٌ‬
‫ابقة (‪ )prefix‬في المِ حث (‪ )prompt‬وال تي هي اس م البيئ ة‬ ‫يجب أن تظه ر اآلن س‬

‫ً‬
‫مختلف ا في توزيع ة‬ ‫المستخدمة‪ ،‬وفي حالتنا هذه يكون اس مها ‪ ،my_env‬وق د يك ون مظه ر المِ َحث‬

‫دبي ان‪ ،‬وذل ك اعتم ا ًدا على اإلص دار المس تخدم؛ لكن يجب أن تش اهد اس م البيئ ة بين قوس ين في‬

‫بداية السطر‪:‬‬

‫‪(my_env) sammy@sammy:~/environments$‬‬

‫▲‬ ‫|‬ ‫‪50‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫أن البيئ ة ‪ my_env‬مفعل ة حالي ا‪ ،‬وه ذا يع ني أنن ا سنس تخدم‬


‫ستس مح ل ك الس ابقة بمعرف ة َّ‬

‫إعدادات وحزم هذه البيئة عند إنشاء مشاريع جديدة‪.‬‬

‫ً‬
‫جاهزة لالستخدام بعد اتباعك للخطوات السابقة‪.‬‬ ‫يجب أن تكون بيئتك االفتراضية‬

‫مالحظة‪ :‬يمكنك داخل البيئة االفتراضية أن تستخدم األمر ‪ python‬بداًل من ‪ python3‬واألمر ‪ pip‬ب داًل من‬

‫كنت تس تخدم ب ايثون‪ 3‬خ ارج البيئ ة االفتراض ية‪ ،‬فيجب علي ك حينه ا اس تخدام‬
‫َ‬ ‫إن ش َ‪.‬‬
‫ئت أم ا إذا‬ ‫‪pip3‬‬
‫‪ python3‬و ‪ pip3‬حصرًا‪.‬‬

‫د‪ .‬إنشاء برنامج بسيط‬

‫برنامجا بس ً‬
‫يطا يع رض العب ارة «مرحب ا بالع الم!»‪،‬‬ ‫ً‬ ‫ِ‬
‫لننشئ‬ ‫االفتراضية‪،‬‬
‫َّ‬ ‫بعد إكمال ضبط بيئتنا‬

‫أن البيئ ة تعم ل بالش كل الص حيح‪ ،‬ولكي تتع وّ د على إنش اء ب رامج ب ايثون إن‬
‫وبه ذا س نتحقق من َّ‬

‫كنت واف ًدا جدي ًدا على اللغة‪.‬‬


‫َ‬

‫علينا أواًل تشغيل محرر ملفات نصية إلنشاء ملف جديد‪ ،‬وليكن المحرر ‪ nano‬الذي يعمل من‬

‫سطر األوامر‪:‬‬

‫‪(my_env) sammy@sammy:~/environments$ nano hello.py‬‬

‫بعد فتح الملف في نافذة الطرفية‪ ،‬سنكتب البرنامج الخاص بنا‪:‬‬

‫)"!‪print("Hello, World‬‬

‫أغلق محرر ‪ nano‬بالضغط على ‪ Ctrl+x‬ثم اضغط على ‪ y‬عندما يسألك عن حفظ الملف‪.‬‬

‫بعد أن يُ َ‬
‫غلق المحرر ‪ nano‬وتعود إلى سطر األوامر‪ ،‬حاول تنفيذ البرنامج‪:‬‬

‫‪(my_env) sammy@sammy:~/environments$ python hello.py‬‬

‫▲‬ ‫|‬ ‫‪51‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫َ‬
‫أنشأته إلى طباعة الناتج التالي في الطرفية‪:‬‬ ‫سيؤدي برنامج ‪ hello.py‬الذي‬

‫!‪Hello, World‬‬

‫للخروج من البيئة‪ ،‬اكتب األمر ‪ deactivate‬وستعود إلى مجلدك األصلي‪.‬‬

‫تطوير للغة بايثون ‪ 3‬في نظام لينكس دبيان‪ ،‬ح ان اآلن ال وقت‬
‫ٍ‬ ‫َ‬
‫ضبطت اآلن بيئة‬ ‫تهانينا! لقد‬

‫للتعم ق بلغ ة ب ايثون وإنش اء ب رامج رائع ة! انتق ل إلى الفص ل الت الي‪ ،‬اس تخدام س طر أوام ر‬

‫بايثون التفاعلي‪.‬‬

‫▲‬ ‫|‬ ‫‪52‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫‪CentOS .4‬‬
‫وة بخط وة إلى كيفي ة تث بيت ب ايثون ‪ 3‬على ‪ ،CentOS 8‬وتث بيت‬
‫رش ُدك ه ذا القس م خط ً‬
‫سي ِ‬
‫ُ‬

‫بيئة برمجة عبر سطر األوامر‪.‬‬

‫ا‪ .‬المتطلبات المسبقة‬

‫يجب أن تملك صالحيات مس تخدم أساس ي غ ير ج ذري (‪ )non-root superuser‬على نظ ام‬

‫‪ CentOS 8‬متصل بالشبكة‪.‬‬

‫إذا لم تكن ل ك خ برة في التعام ل م ع بيئ ة الناف ذة الطرفي ة‪ ،‬فيمكن ك مطالع ة المق ال‬

‫طرفية لينكس ‪.»Linux Terminal‬‬


‫ّ‬ ‫«مدخل إلى‬

‫ب‪ .‬تحضير النظام‬

‫س ُنثبِّ ت ونض بط ب ايثون ع بر س طر األوام ر‪ ،‬إن ك ان نظ ام ‪ CentOS 8‬يب دأ بس طح مكتب ذي‬

‫واجهة مس تخدم رس ومية (‪ ،)GUI‬فيمكن ك ال دخول إلى س طر األوام ر بفتح القائم ة‪ ،‬وال دخول إلى‬

‫‪ Applications‬ثم ‪ Utilities‬ثم النق ر على ‪ .Terminal‬هنال ك مق االت في أكاديمي ة حس وب‬

‫طرفية لينكس ‪ )Linux Terminal‬ستعلمك أساسيات سطر األوامر‪ ،‬وهنالك‬


‫ّ‬ ‫(مثل مقال مدخل إلى‬

‫كتاب «سطر أوامر لينكس» الذي يُ ع ُّد مرجعً ا لطريقة التعامل مع سطر األوامر‪.‬‬

‫ارة‬ ‫ار للعب‬ ‫در ‪( DNF‬اختص‬ ‫ة المص‬ ‫زم مفتوح‬ ‫تخدم أداة إدارة الح‬ ‫سنس‬

‫‪ Dandified YUM‬وه و الجي ل الث اني من م دير الح زم ‪ Yellowdog Updater, Modified‬المع روف‬

‫باالختصار ‪ .)YUM‬هذه أداة شائعة االستخدام إلدارة الحزم على أنظمة لينكس المس تندة إلى ‪Red‬‬

‫‪ ،Hat‬مثل ‪ ،CentOS‬إذ تتيح لك تثبيت الحزم وتحديثها بسهولة‪ ،‬وكذلك إزالة الحزم من الجهاز‪.‬‬

‫▲‬ ‫|‬ ‫‪53‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫أن لدينا أحدث إصدار من ‪ yum‬عبر تنفيذ األمر التالي‪:‬‬


‫قبل أن نبدأ التثبيت‪ ،‬دعنا نتأكد من َّ‬

‫‪sudo dnf update -y‬‬

‫الطرفية من طلب تأكي د قب ل‬


‫َّ‬ ‫أنك ت درك َّ‬
‫أنك تح دث تغي يرات‪ ،‬وذل ك لمن ع‬ ‫الخي ار ‪ -y‬يع ني َّ‬

‫تنفيذ األمر‪.‬‬

‫بمجرَّ د تثبيت وتحديث كل شيء‪ ،‬فنحن جاهزون لتثبيت بايثون ‪.3‬‬

‫ج‪ .‬تثبيت وإعداد بايثون ‪3‬‬

‫نظ ام ‪ CentOS‬مش تق من ‪( RHEL‬اختص ار للجمل ة ‪ ، )Red Hat Enterprise Linux‬وال ذي‬

‫يرك ز على الثب ات واالس تقرار‪ .‬أي لن تج د في ه ذا النظ ام إال اإلص دارات المس تقرة والمُ خت برة من‬

‫ستجد أحدث إص دار من‬ ‫التطبيقات والحزم القابلة للتنزيل‪ ،‬لذلك وباستعمال مدير حزم ‪CentOS‬‬

‫بايثون دومً ا‪:‬‬

‫‪sudo dnf install python3 -y‬‬

‫بعد إكمال العملية‪ ،‬يمكننا التحقق من نجاح عملية التثبيت بطلب إصدار بايثون بكتابة‪:‬‬

‫‪python3 -V‬‬

‫المثبت‪ .‬قد يختلف‬


‫َّ‬ ‫ستحصل على مخرجات في نافذة الطرفية والتي ستريك إصدار بايثون‬

‫ً‬
‫شبيها بما يلي‪:‬‬ ‫بناء على النسخة المثبتة في توزيعتك‪ ،‬لكن يجب أن يكون‬
‫ً‬ ‫الرقم‬

‫‪Python 3.6.8‬‬

‫ً‬
‫انطالق ا من‬ ‫سنثبِّ ت ً‬
‫تاليا أدوات تطوير ‪ CentOS‬ال تي تس مح ل ك ببن اء التطبيق ات وتص ريفها‬

‫شيفرتها المصدرية‪:‬‬

‫▲‬ ‫|‬ ‫‪54‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫‪sudo dnf -y groupinstall development‬‬

‫ننتق ل بع د اكتم ال التث بيت للخط وة التالي ة وهي ض بط وإع داد بيئ ة تطويري ة لكتاب ة ب رامج‬

‫بايثون وتنفيذها‪.‬‬

‫د‪ .‬إعداد بيئة افتراضية‬

‫ثبتن ا ب ايثون وأع ددنا النظ ام‪ ،‬يمكنن ا المض ي ق دمً ا إلنش اء بيئ ة البرمج ة ال تي‬
‫اآلن بع د أن َّ‬

‫سنعمل فيها باستخدام ‪.venv‬‬

‫مخصص ة لمش اريع‬


‫َّ‬ ‫ُت ِّ‬
‫مكن ك البيئ ات االفتراض ية من إنش اء مس احة معزول ة في حاس وبك‬

‫أن كل مشروع تعمل عليه ستكون له اعتماديَّ ات ه (‪ )dependencies‬الخاص ة ب ه‪،‬‬


‫بايثون‪ ،‬مما يعني َّ‬
‫ِّ‬
‫تؤثر على غيره من المشاريع‪.‬‬ ‫والتي لن‬

‫دارات‬
‫ٍ‬ ‫وإمكانية التعام ل م ع إص‬ ‫ي ِّ‬
‫وفر لن ا ض بط بيئ ةٍ برمجي ةٍ تحكمً ا أك بر بمش اريع ب ايثون‪،‬‬
‫َّ‬

‫مختلفةٍ من حزم بايثون‪ .‬وهذا مهمٌ كثيرًا عندما تتعامل مع الحزم الخارجية‪.‬‬

‫أي ع ددٍ تش اء من البيئ ات االفتراض َّية‪ ،‬وك ل بيئ ة س تكون ممثل ة بمجل د في‬
‫يمكن ك ض بط ِّ‬

‫حاسوبك يحتوي على عدد من السكربتات‪.‬‬

‫بعد إتمام التثبيت‪ ،‬فنحن جاهزون إلنشاء البيئات االفتراض ية‪ ،‬يمكنن ا اآلن إم ا اختي ار مجل د‬

‫نضع فيه بيئات بايثون‪ ،‬أو إنشاء مجلد جديد باستخدام األمر ‪ mkdir‬كما يلي‪:‬‬

‫‪mkdir environments‬‬
‫‪cd environments‬‬

‫َ‬
‫انتقلت إلى المجلد الذي تريد احت واء البيئ ات في ه‪ ،‬تس تطيع اآلن إنش اء بيئ ة جدي دة‬ ‫بعد أن‬

‫بتنفيذ األمر اآلتي‪:‬‬

‫▲‬ ‫|‬ ‫‪55‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫‪python3 -m venv my_env‬‬

‫مً ا ذا معنًى‬ ‫ار اس‬ ‫ة ولكن يجب أن تخت‬ ‫ً‬


‫ازا للبيئ‬ ‫م ‪ my_env‬مج‬ ‫تعمل االس‬ ‫سنس‬

‫يناسب المشروع‪.‬‬

‫نش ئ األم ر ‪ pyvenv‬مجل ًدا جدي ًدا في ه بعض الملف ات ال تي يمكن عرض ها باس تخدام‬
‫سي ِ‬
‫ُ‬

‫األمر ‪:ls‬‬

‫‪ls my_env‬‬

‫ستظهر لك مخرجات شبيهة بالمخرجات التالية‪:‬‬

‫‪bin include lib lib64 pyvenv.cfg‬‬

‫أن تك ون مش اريعك معزول ٌة عن س ياق اآلل ة المحلي ة‪،‬‬


‫تعم ل ه ذه الملف ات م ع بعض ها لض مان َ‬

‫لكي ال تختلط ملفات النظ ام م ع ملف ات المش اريع‪ .‬وه ذا أم رٌ حس ٌن إلدارة اإلص دارات ولض مان َّ‬
‫أن‬

‫الحزم التي يحتاج إليها‪.‬‬


‫ٍ‬ ‫كل مشروع يملك وصواًل إلى‬

‫سي ِّ‬
‫نفذ سكربت التفعيل‪:‬‬ ‫عليك تفعيل البيئة الستخدامها‪ ،‬وذلك بكتابة األمر التالي الذي ُ‬

‫‪source my_env/bin/activate‬‬

‫ٌ‬
‫ابقة (‪ )prefix‬في المِ حث (‪ )prompt‬وال تي هي اس م البيئ ة‬ ‫يجب أن تظه ر اآلن س‬

‫المستخدمة‪ ،‬وفي حالتنا هذه يكون اسمها ‪:my_env‬‬

‫‪(my_env) [sammy@centosserver environments]$‬‬

‫حالي ا‪ ،‬وه ذا يع ني َّ‬


‫أنن ا سنس تخدم‬ ‫ً‬ ‫أن البيئ ة ‪ my_env‬مفعل ة‬
‫ستس مح ل ك الس ابقة بمعرف ة َّ‬

‫إعدادات وحزم هذه البيئة عند إنشاء مشاريع جديدة‪.‬‬

‫الح ظ أن م دير ح زم ب ايثون ‪ pip‬ق د ُثبِّت مس ً‬


‫بقا وال ذي سنس تعمله لتث بيت الح زم البرمجي ة‬

‫▲‬ ‫|‬ ‫‪56‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫وإدارتها في بيئتنا البرمجية السابقة‪ ،‬فيمكننا تثبيت أي حزمة بتنفيذ األمر التالي‪:‬‬

‫‪(my_env) [sammy@centosserver environments]$ sudo pip install‬‬


‫‪package_name‬‬

‫يش ير ‪ package_name‬هن ا إلى أي حزم ة أو مكتب ة من ب ايثون مث ل ‪ Django‬الحزم ة‬

‫المخصص ة لتط وير ال ويب أو ‪ NumPy‬الحزم ة المخصص ة إلج راء الحس ابات الرياض ية المتقدم ة‪،‬‬

‫فإذا أردت تثبيت الحزمة األخيرة‪ ،‬يمكنك ببساطة تنفيذ األمر ‪.pip install numpy‬‬

‫ً‬
‫جاهزة لالستخدام بعد اتباعك للخطوات السابقة‪.‬‬ ‫يجب أن تكون بيئتك االفتراضية‬

‫مالحظة‪ :‬يمكنك داخل البيئة االفتراضية أن تستخدم األمر ‪ python‬ب داًل من ‪ python3.6‬واألم ر ‪ pip‬ب داًل‬

‫كنت تس تخدم ب ايثون‪ 3‬خ ارج البيئ ة االفتراض ية‪ ،‬فيجب علي ك حينه ا اس تخدام‬
‫َ‬ ‫إن ش َ‪.‬‬
‫ئت أم ا إذا‬ ‫من ‪pip3.6‬‬
‫‪ python3.6‬و ‪ pip3.6‬حصرًا‪.‬‬

‫ه‪ .‬إنشاء برنامج بسيط‬

‫ً‬
‫يطا يع رض العب ارة‬ ‫ً‬
‫برنامج ا بس‬ ‫ِ‬
‫لننش ئ‬ ‫بع د أن أكملن ا ض بط بيئتن ا االفتراض ية‪،‬‬

‫أن البيئ ة تعم ل بالش كل الص حيح‪ ،‬ولكي تتع وَّ د على إنش اء‬ ‫َّ‬
‫نتحقق من َّ‬ ‫«مرحبا بالع الم!»‪ ،‬وبه ذا س‬

‫كنت واف ًدا جدي ًدا على اللغة‪.‬‬


‫َ‬ ‫برامج بايثون إن‬

‫علينا أواًل تشغيل محرر ملفات نصية إلنشاء ملف جديد‪ ،‬وليكن المحرر ‪:vi‬‬

‫‪(my_env) [sammy@centosserver environments]$ vi hello.py‬‬

‫بع د فتح المل ف في ناف ذة الطرفي ة‪ ،‬اكتب الح رف ‪ i‬لل دخول إلى وض ع اإلدراج‬

‫(‪ ،)insert mode‬بعدها يمكننا كتابة البرنامج‪:‬‬

‫▲‬ ‫|‬ ‫‪57‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫)"!‪print("Hello, World‬‬

‫اآلن اض غط على ال زر ‪ ESC‬للخ روج من وض ع اإلدراج‪ .‬بع د ذل ك ‪ ،‬اكتب ‪ :x‬ثم ‪ ENTER‬لحف ظ‬

‫الملف وإغالقه‪.‬‬

‫نحن جاهزون اآلن لتنفيذ البرنامج‪:‬‬

‫‪(my_env) [sammy@centosserver environments]$ python hello.py‬‬

‫َ‬
‫أنشأته إلى طباعة الناتج التالي في الطرفية‪:‬‬ ‫سيؤدي برنامج ‪ hello.py‬الذي‬

‫!‪Hello, World‬‬

‫للخروج من البيئة‪ ،‬اكتب األمر ‪ deactivate‬وستعود إلى مجلدك األصلي‪.‬‬

‫تطوير للغة بايثون ‪ 3‬في ‪ ،CentOS 8‬ح ان اآلن ال وقت للتعم ق‬


‫ٍ‬ ‫َ‬
‫ضبطت اآلن بيئة‬ ‫تهانينا! لقد‬

‫بلغة بايثون وإنشاء برامج رائعة! انتقل إلى الفصل التالي‪ ،‬استخدام سطر أوامر بايثون التفاعلي‪.‬‬

‫▲‬ ‫|‬ ‫‪58‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫‪macOS .5‬‬
‫وة بخط وة إلى كيفي ة تث بيت ب ايثون ‪ 3‬في ‪ ،macOS‬وتث بيت بيئ ة‬
‫رش ُدك ه ذا القس م خط ً‬
‫سي ِ‬
‫ُ‬

‫برمجة عبر سطر األوامر‪.‬‬

‫ا‪ .‬المتطلبات المسبقة‬

‫يجب أن تمل ك جه ً‬
‫ازا علي ه نظ ام ‪ macOS‬متص ل بالش بكة م ع ص الحيات م دير‬

‫(‪.)administrative access‬‬

‫إذا لم تكن ل ك خ برة في التعام ل م ع بيئ ة الناف ذة الطرفي ة‪ ،‬فيمكن ك مطالع ة المق ال‬

‫طرفية لينكس ‪.»Linux Terminal‬‬


‫ّ‬ ‫«مدخل إلى‬

‫ب‪ .‬فتح نافذة الطرفية‬

‫سنجري معظم أطوار التثبيت واإلعدادات عبر سطر األوامر‪ ،‬والذي ه و طريق ٌة غ يرُ رس وميةٍ‬

‫للتعام ل م ع الحاس وب‪ ،‬فب داًل من الض غط على األزرار‪ ،‬س تكتب ًّ‬
‫نص ا وتعطي ه للحاس وب لينف ذه‪،‬‬

‫ً‬
‫أيضا‪ .‬يمكن أن يساعدك سطر األوامر على تعديل أو أتمتة مختلف المه ام‬ ‫نصيا‬
‫ً‬ ‫ً‬
‫ناتجا‬ ‫ظهر لك‬
‫وسي ِ‬
‫ُ‬

‫ٌ‬
‫أساسية لمطوري البرمجيات‪.‬‬ ‫ٌ‬
‫أداة‬ ‫يوميا‪ ،‬وهو‬
‫ً‬ ‫التي تنجزها على الحاسوب‬

‫طرفي ة م اك ( ‪ )macOS Terminal‬هي تط بيق يمكن ك اس تخدامه لل دخول إلى واجه ة س طر‬

‫األوام ر‪ .‬مث ل التطبيق ات األخ رى‪ ،‬س تجد تط بيق الطرفي ة بال ذهاب إلى ‪ ،Finder‬وفتح المجل د‬

‫‪ ،Applications‬ثم ال ذهاب إلى المجل د ‪ ،Utilities‬ثم النق ر الم زدوج على ‪ Terminal‬لفتح ه‪ .‬أو‬

‫يمكن ك اس تخدام ‪ Spotlight‬ع بر الض غط على ال زرّ ين ‪ command‬و ‪ spacebar‬للعث ور على‬

‫‪ Terminal‬بكتابته في المربع الذي سيظهر‪.‬‬

‫▲‬ ‫|‬ ‫‪59‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫هنالك الكثير من األوامر التي عليك تعلمها لكي تتمكن من االستفادة منه‪ .‬هنال ك مق االت في‬

‫طرفي ة لينكس ‪ )Linux Terminal‬س تعلمك أساس يات‬


‫ّ‬ ‫أكاديمي ة حس وب (مث ل مق ال م دخل إلى‬

‫س طر األوام ر‪ ،‬وهنال ك كت اب «س طر أوام ر لينكس» ال ذي يُ ع َت بر مرجع ا لطريق ة التعام ل م ع س طر‬

‫األوامر في لينكس‪ ،‬والذي يشبه نظيره في ماك‪.‬‬

‫ج‪ .‬تثبيت ‪Xcode‬‬

‫‪ Xcode‬هي بيئ ة تط وير متكامل ة (‪ )IDE‬تت ألف من أدوات تط وير ال برامج لنظ ام التش غيل‬

‫ً‬
‫سلفا‪ .‬للتحقق من ذلك‪ ،‬اكتب في نافذة الطرفية ما يلي‪:‬‬ ‫‪ .MacOS‬قد يكون ‪ Xcode‬مثب ًتا عندك‬

‫‪xcode-select -p‬‬

‫▲‬ ‫|‬ ‫‪60‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫أن مثبت ‪:Xcode‬‬


‫إن حصلت على المخرجات التالية‪ ،‬فهذا يعني ّ‬

‫‪/Library/Developer/CommandLineTools‬‬

‫االفتراضية‪.‬‬
‫َّ‬ ‫إن تلقيت خطأ‪ ،‬فثبِّ ت ‪ Xcode‬من المتجر ‪ App Store‬واعتمد الخيارات‬

‫الطرفية‪ .‬ثم ثبِّ ت التطبيق ‪ Command Line Tools‬عن‬


‫َّ‬ ‫بعد تثبيت ‪ ،Xcode‬ارجع إلى النافذة‬

‫طريق كتابة‪:‬‬

‫‪xcode-select --install‬‬

‫عن د ه ذه المرحل ة‪ ،‬يك ون ق د ثبِّ ت ‪ ،Xcode‬والتط بيق ‪ Command Line Tools‬الخ اص ب ه‪،‬‬

‫ونحن اآلن مستعدون لتثبيت مدير الحزم ‪.Homebrew‬‬

‫د‪ .‬تثبيت وإعداد ‪Homebrew‬‬

‫أن طرفي ة ‪ macOS‬تتمت ع ب الكثير من وظ ائف طرفي ة لينكس وأنظم ة ي ونكس‬


‫في حين َّ‬

‫األخ رى‪ ،‬إال أنه ا ال ت أتي بم دير ح زم جي د‪ .‬م دير الح زم (‪ )package manager‬ه و مجموع ة من‬

‫أدوات البرمجي ات ال تي تعم ل على أتمت ة عملي ات التث بيت‪ ،‬بم ا في ذل ك التث بيت األولي لل برامج‪،‬‬

‫وترقيته ا‪ ،‬وإع دادها‪ ،‬وإزالته ا عن د الحاج ة‪ .‬تحف ظ ه ذه األدوات التثبيت ات في موق ع مرك زي‪،‬‬

‫ويمكنه ا ص يانة جمي ع ح زم ال برامج على النظ ام وف ق تنس يقات (‪ )formats‬معروف ة‪ .‬ت وفر‬

‫‪ Homebrew‬لنظ ام التش غيل ‪ macOS‬نظ ام إدارة ح زم مج اني ومفت وح المص در يبس ط عملي ة‬

‫تثبيت البرنامج‪ .‬لتثبيت ‪ِّ ،Homebrew‬‬


‫نفذ في الطرفية األمر التالي‪:‬‬

‫‪/usr/bin/ruby -e "$(curl -fsSL‬‬


‫‪https://raw.githubusercontent.com/Homebrew/install/master/insta‬‬
‫")‪ll‬‬

‫▲‬ ‫|‬ ‫‪61‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫ِّ‬
‫يعدل مس ار روبي على جه ازك‪ .‬يس حب األم ر ‪curl‬‬ ‫ط ِّور ‪ Homebrew‬ع بر روبي‪ ،‬ل ذلك س‬
‫ُ‬

‫الس كربت من عن وان ‪ URL‬المح دد‪ .‬سيوض ح ذل ك الس كربت م ا س يفعله‪ ،‬ثم يوق ف العملي ة ليطلب‬

‫منك التأكيد‪ .‬يوفر لك هذا الكثير من المالحظات حول ما سيفعله الس كربت في نظام ك‪ ،‬ويمنح ك‬

‫الفرصة للتحقق من العملية‪.‬‬

‫الح ظ َّ‬
‫أنك عن د إدخ ال كلم ة الم رور‪ ،‬فلن تع رض الطرفي ة المح ارف ال تي تكتبه ا‪ ،‬ولكنَّه ا‬

‫سجل‪ ،‬بعد إدخال كلمة المرور اضغط على الزر ‪ .return‬واض غط على الح رف ‪ y‬إن ُطلِب من ك‬
‫ست ِّ‬
‫ُ‬

‫تأكيد التثبيت‪.‬‬

‫لنلق نظرة على الرايات (‪ )flags‬المرتبطة باألمر ‪:curl‬‬

‫تخ بر الرايت ان ‪ -f‬أو ‪ --fail‬الطرفي ة بع دم إعط اء مخرج ات على هيئ ة مس تند ‪HTML‬‬ ‫•‬
‫عند حدوث أخطاء في الخادم‪.‬‬

‫ُتص مِ ت الرايت ان ‪ -s‬أو ‪ --silent‬األم ر ‪ ،curl‬بمع نى أن ه لن يع رض معلوم ات التق دم‪،‬‬ ‫•‬


‫وعن د جمعه ا م ع الراي تين ‪ -S‬أو ‪ ،--show-error‬س تجعل ‪ُ curl‬تظه ر رس الة خط أ في‬
‫حال الفشل‪.‬‬

‫تطلب الرايتان ‪ -L‬أو ‪ --location‬من ‪ curl‬إع ادة الطلبي ة (‪ )request‬إلى مك ان جدي د‬ ‫•‬
‫بأن الصفحة المطلوبة قد ُنقِ لت إلى موقع أخر‪.‬‬
‫إذا أبلغ الخادم َّ‬

‫بمج رد اكتم ال عملي ة التث بيت‪ ،‬سنض ع مجل د ‪ Homebrew‬في أعلى متغ ير البيئ ة ‪.PATH‬‬

‫سيض من ذل ك أن يتم اس تدعاء عملي ات تث بيت ‪ Homebrew‬ع بر األدوات ال تي ق د يختاره ا نظ ام‬

‫تلقائي ا‪ ،‬والتي قد تتعارض مع بيئة التطوير التي تنشئها‪.‬‬


‫ً‬ ‫التشغيل ‪Mac OS X‬‬

‫▲‬ ‫|‬ ‫‪62‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫يجب علي ك إنش اء أو فتح المل ف ‪ ~/.bash_profile‬باس تخدام مح رر نص وص س طر‬

‫األوامر ‪ nano‬باستخدام األمر ‪:nano‬‬

‫‪nano ~/.bash_profile‬‬

‫بعد فتح الملف في نافذة الطرفية‪ ،‬اكتب ما يلي‪:‬‬

‫‪export PATH=/usr/local/bin:$PATH‬‬

‫لحف ظ التغي يرات‪ ،‬اض غط على المفت اح ‪ control‬والح رف ‪ o‬ب التزامن‪ ،‬وعن د مطالبت ك‬

‫بالتأكي د‪ ،‬اض غط على المفت اح ‪ .return‬يمكن ك اآلن الخ روج من ‪ nano‬عن طري ق الض غط على‬

‫المفتاح ‪ control‬والحرف ‪ x‬بالتزامن‪.‬‬

‫لتفعيل هذه التغييرات‪ ،‬اكتب في نافذة الطرفية‪:‬‬

‫‪source ~/.bash_profile‬‬

‫أن‬
‫ستص ير اآلن التغي يرات ال تي أجريته ا على متغ ير البيئ ة ‪ PATH‬فعال ة‪ .‬يمكنن ا التحق ق من َّ‬

‫‪ Homebrew‬قد ُثبِّ ت بنجاح عن طريق كتابة‪:‬‬

‫‪brew doctor‬‬

‫إذا لم تكن هناك حاجة إلى أي تحديثات في هذا الوقت‪ ،‬فستطبع الطرفية ما يلي‪:‬‬

‫‪Your system is ready to brew.‬‬

‫خالف ذلك‪ ،‬قد تحصل على تنبيه يدعوك إلى تنفيذ أمر آخ ر مث ل ‪ brew update‬للتأك د من‬

‫أن ‪ Homebrew‬مح َّدث‪ .‬بمجرد أن تصبح ‪ Homebrew‬جاهزة‪ ،‬يمكنك تثبيت بايثون ‪.3‬‬
‫َّ‬

‫▲‬ ‫|‬ ‫‪63‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫ه‪ .‬تثبيت بايثون ‪3‬‬

‫يمكن ك اس تخدام ‪ Homebrew‬للبحث عن ال برامج ال تي يمكن ك تثبيته ا ع بر‬

‫األم ر ‪ ،brew search‬ويمكن ك الحص ول على قائم ة الح زم والوح دات ذات العالق ة بب ايثون فق ط‬

‫عبر تنفيذ األمر التالي‪:‬‬

‫‪brew search python‬‬

‫نافذة الطرفية ستخرج قائمة من الحزم والوحدات التي يمكنك تثبيتها على النحو التالي‪:‬‬

‫‪app-engine-python‬‬ ‫‪micropython‬‬ ‫‪python3‬‬


‫‪boost-python‬‬ ‫‪python‬‬ ‫‪wxpython‬‬
‫‪gst-python‬‬ ‫‪python-markdown‬‬ ‫‪zpython‬‬
‫‪homebrew/apache/mod_python‬‬ ‫‪homebrew/versions/gst-‬‬
‫‪python010‬‬
‫‪homebrew/python/python-dbus‬‬ ‫‪Caskroom/cask/kk7ds-‬‬
‫‪python-runtime‬‬
‫‪homebrew/python/vpython‬‬ ‫‪Caskroom/cask/mysql-‬‬
‫‪connector-python‬‬

‫سيكون بايثون ‪ 3‬من بين العناصر المدرجة في القائمة‪ .‬لذلك دعنا نثبِّتها‪:‬‬

‫‪brew install python3‬‬

‫الطرفية مالحظات بشأن عملية تثبيت بايثون ‪ ،3‬وقد يستغرق األمر بضع‬
‫َّ‬ ‫ستعرض لك نافذة‬

‫دقائق قبل اكتمال التثبيت‪.‬‬

‫إلى ج انب ب ايثون ‪ ،3‬س تثبِّ ت ‪ Homebrew‬و ‪ pip‬و ‪ setuptools‬و ‪ .wheel‬سنس تخدم ‪،pip‬‬

‫ٌ‬
‫أداة تعم ل م ع ب ايثون ُت َثبِّ ت وت دير الح زم البرمجي ة ال تي ق د نحت اج إلى اس تخدامها في‬ ‫وهي‬

‫المخصص للوحدات)‪.‬‬
‫َّ‬ ‫تطوير مشاريعنا (سنتعلم المزيد عن الوحدات والحزم في الفصل الالحق‬

‫▲‬ ‫|‬ ‫‪64‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫يمكن تثبيت حزم بايثون بكتابة ما يلي مع تبديل ‪ package_name‬باسم الوحدة‪:‬‬

‫‪pip3 install package_name‬‬

‫علي ك وض ع اس م الحزم ة أو المكتب ة التابع ة لب ايثون مك ان ‪ package_name‬مث ل ‪Django‬‬

‫َ‬
‫شئت تنزيل ‪ NumPy‬فيمكن ك تنفي ذ‬ ‫لتطوير الويب‪ ،‬أو ‪ NumPy‬إلجراء الحسابات العلمية‪ .‬لذا‪ ،‬إن‬

‫األمر ‪.pip3 install numpy‬‬

‫تس ّهل األداة ‪ setuptools‬تح زيم مش اريع ب ايثون‪ ،‬أم ا ‪ wheel‬فهي تنس يق ح زم‬

‫(‪ )built-package format‬لب ايثون يمكن ه تس ريع إنتاجي ة ال برامج عن طري ق تقلي ل ع دد الم رات‬

‫التي تحتاج فيها إلى التصريف‪.‬‬

‫بعد إكمال العملية‪ ،‬يمكننا التحقق من إصدار بايثون ‪ 3‬المُ َّ‬


‫ثبت في النظام بكتابة‪:‬‬

‫‪python3 --version‬‬

‫المثبت‪ .‬وال ذي‬


‫َّ‬ ‫ستحص ل على مخرج ات في ناف ذة الطرفي ة وال تي س تريك إص دار ب ايثون‬

‫افتراضيا أحدث إصدار مستقر ومتاح من بايثون ‪.3‬‬


‫ً‬ ‫سيكون‬

‫لتحديث إصدار بايثون ‪ ،3‬يمكنك أوالً تحديث ‪ ،Homebrew‬ثمَّ تحديث بايثون‪:‬‬

‫‪brew update‬‬
‫‪brew upgrade python3‬‬

‫من الممارسات الجيدة تحديث إصدار بايثون الذي تعمل به من حين آلخر‪.‬‬

‫و‪ .‬إعداد بيئة افتراضية‬

‫اآلن بع د تث بيت ‪ Xcode‬و ‪ Homebrew‬وب ايثون‪ ،‬يمكنن ا المض ي ق دمً ا إلنش اء بيئ ة‬

‫البرمجة خاصتنا‪.‬‬

‫▲‬ ‫|‬ ‫‪65‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫ُت ِّ‬
‫مكن ك البيئ ات االفتراض ية من إنش اء مس احة معزول ة في حاس وبك مخصص ة لمش اريع‬

‫أن كل مشروع تعمل عليه ستكون له اعتماديَّ ات ه (‪ )dependencies‬الخاص ة ب ه‪،‬‬


‫بايثون‪ ،‬مما يعني َّ‬
‫ِّ‬
‫تؤثر على غيره من المشاريع‪.‬‬ ‫والتي لن‬

‫دارات‬
‫ٍ‬ ‫ي ِّ‬
‫وفر لن ا ض بط بيئ ةٍ برمجي ةٍ تحكمً ا أك بر بمش اريع ب ايثون‪ ،‬وإمكاني ة التعام ل م ع إص‬

‫مختلفةٍ من حزم بايثون‪ .‬وهذا مهمٌ كثيرًا عندما تتعامل مع الحزم الخارجية‪.‬‬

‫أي ع ددٍ تش اء من البيئ ات االفتراض ية‪ ،‬وك ل بيئ ة س تكون ممثل ة بمجل د في‬
‫يمكن ك ض بط ِّ‬

‫حاسوبك يحتوي على عدد من السكربتات‪.‬‬

‫اختر المجلد الذي تريد أن تضع فيه بيئات ب ايثون‪ ،‬أو يمكن ك إنش اء مجل د جدي د باس تخدام‬

‫األمر ‪ mkdir‬كما يلي‪:‬‬

‫‪mkdir environments‬‬
‫‪cd environments‬‬

‫َ‬
‫انتقلت إلى المجلد الذي تريد احت واء البيئ ات في ه‪ ،‬تس تطيع اآلن إنش اء بيئ ة جدي دة‬ ‫بعد أن‬

‫بتنفيذ األمر التالي‪:‬‬

‫‪python3.6 -m venv my_env‬‬

‫نشئ هذا األمر مجل ًدا جدي ًدا (في هذه الحالة يُ سمى ‪ )my_env‬فيه بعض الملفات‪:‬‬
‫سي ِ‬
‫ُ‬

‫يشير الملف ‪ pyvenv.cfg‬إلى توزيعة بايثون التي استخدمتها لتنفيذ األمر‪.‬‬ ‫•‬

‫يحت وي المجل د الف رعي ‪ lib‬نس خة من إص دار ب ايثون‪ ،‬ويحت وي على مجل د يس مى‬ ‫•‬
‫سيس تخدم لتخ زين وح دات‬ ‫ً‬
‫فارغ ا في البداي ة‪ ،‬ولكن ه ُ‬ ‫‪ ،site-packages‬والذي س يكون‬
‫الطرف الثالث التي ستثبِّتها‪.‬‬

‫المجلد الفرعي ‪ include‬يُ ِّ‬


‫صرف (‪ )packages‬الحزم‪.‬‬ ‫•‬

‫▲‬ ‫|‬ ‫‪66‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫يحت وي المجل د الف رعي ‪ bin‬نس خة من رُ قام ة ب ايثون ( ‪ )Python binary‬جنب ا إلى جنب‬ ‫•‬
‫سيستخدم‪.‬‬
‫مع سكربت التفعيل (‪ )activate shell script‬الذي ُ‬

‫أن تك ون مش اريعك معزول ٌة عن س ياق اآلل ة المحلي ة‪،‬‬


‫تعم ل ه ذه الملف ات م ع بعض ها لض مان َ‬

‫لكي ال تختلط ملفات النظ ام م ع ملف ات المش اريع‪ .‬وه ذا أم رٌ حس ٌن إلدارة اإلص دارات ولض مان َّ‬
‫أن‬

‫الحزم التي يحتاج إليها‪.‬‬


‫ٍ‬ ‫كل مشروع يملك وصواًل إلى‬

‫سي ِّ‬
‫نفذ سكربت التفعيل‪:‬‬ ‫عليك تفعيل البيئة الستخدامها‪ ،‬وذلك بكتابة األمر التالي الذي ُ‬

‫‪source my_env/bin/activate‬‬

‫ٌ‬
‫ابقة (‪ )prefix‬في المِ حث (‪ )prompt‬وال تي هي اس م البيئ ة‬ ‫يجب أن تظه ر اآلن س‬

‫المس تخدمة‪ ،‬وفي حالتن ا ه ذه يك ون اس مها ‪ ،my_env‬وه ذا يع ني أنن ا لن سنس تخدم إال إع دادات‬

‫وحزم هذه البيئة عند إنشاء مشاريع جديدة‪.‬‬

‫ً‬
‫جاهزة لالستخدام بعد اتباعك للخطوات السابقة‪.‬‬ ‫يجب أن تكون بيئتك االفتراضية‬

‫مالحظة‪ :‬يمكنك داخل البيئة االفتراضية أن تستخدم األمر ‪ python‬بداًل من ‪ python3‬واألمر ‪ pip‬ب داًل من‬

‫كنت تس تخدم ب ايثون‪ 3‬خ ارج البيئ ة االفتراض ية‪ ،‬فيجب علي ك حينه ا اس تخدام‬
‫َ‬ ‫إن ش َ‪.‬‬
‫ئت أم ا إذا‬ ‫‪pip3‬‬
‫ألن ‪ python‬و‪ pip‬ستستدعيان إصدارًا قديمً ا من بايثون‬
‫‪ python3‬و ‪ pip3‬حصرًا‪َّ .‬‬

‫ز‪ .‬إنشاء برنامج بسيط‬

‫ً‬
‫يطا يع رض العب ارة‬ ‫ً‬
‫برنامج ا بس‬ ‫ِ‬
‫لننش ئ‬ ‫بع د أن أكملن ا ض بط بيئتن ا االفتراض ية‪،‬‬

‫أن البيئ ة تعم ل بالش كل الص حيح‪ ،‬ولكي تتع وَّ د على إنش اء‬
‫«مرحبا بالع الم!»‪ ،‬وبه ذا س نتحقق من َّ‬

‫كنت واف ًدا جدي ًدا على اللغة‪.‬‬


‫َ‬ ‫برامج بايثون إن‬

‫▲‬ ‫|‬ ‫‪67‬‬


‫البرمجة بلغة بايثون‬ ‫تثبيت بايثون وإعداد بيئة العمل‬

‫علينا أواًل تشغيل محرر ملفات نصية إلنشاء ملف جديد‪ ،‬وليكن المحرر ‪ nano‬الذي يعمل من‬

‫سطر األوامر‪:‬‬

‫‪(my_env) sammys-MBP:~ sammy$ nano hello.py‬‬

‫بعد فتح الملف في نافذة الطرفية‪ ،‬سنكتب البرنامج الخاص بنا‪:‬‬

‫)"!‪print("Hello, World‬‬

‫أغلق محرر ‪ nano‬بالضغط على ‪ Ctrl+x‬ثم اضغط على ‪ y‬عندما يسألك عن حفظ الملف‪.‬‬

‫بعد أن يُ َ‬
‫غلق المحرر ‪ nano‬وتعود إلى سطر األوامر‪ ،‬حاول تنفيذ البرنامج‪:‬‬

‫‪(my_env) sammys-MBP:~ sammy$‬‬ ‫‪python hello.py‬‬

‫َ‬
‫أنشأته إلى طباعة الناتج التالي في الطرفية‪:‬‬ ‫سيؤدي برنامج ‪ hello.py‬الذي‬

‫!‪Hello, World‬‬

‫للخروج من البيئة‪ ،‬اكتب األمر ‪ deactivate‬وستعود إلى مجلدك األصلي‪.‬‬

‫وير للغ ة ب ايثون ‪ 3‬في نظ ام ‪ ،Mac OS X‬ح ان اآلن ال وقت‬ ‫َ‬


‫بطت اآلن بيئ ة تط ٍ‬ ‫تهانين ا! لق د ض‬

‫للتعمق بلغة بايثون وإنشاء برامج رائعة!‬

‫▲‬ ‫|‬ ‫‪68‬‬


‫‪3‬‬
‫سطر أوامر بايثون‬
‫التفاعلي‬

‫▲‬ ‫|‬ ‫‪69‬‬


‫البرمجة بلغة بايثون‬ ‫سطر أوامر بايثون التفاعلي‬

‫ً‬
‫أيض ا م ترجم‬ ‫ي وفر س طر أوام ر ب ايثون التف اعلي (‪ ،)Python interactive console‬ويس مى‬

‫ب ايثون (‪ )Python interpreter‬للم برمجين طريق ة س ريعة لتنفي ذ األوام ر‪ ،‬وتجرب ة أو اختب ار‬

‫التعليمات البرمجية دون الحاجة إلى إنشاء وكتابة أي شيفرة برمجية‪.‬‬

‫يمكن الوص ول من خالل س طر األوام ر التف اعلي إلى جمي ع دوال ب ايثون المُ ض مّ نة‪ ،‬وجمي ع‬

‫الوح دات المُ َّ‬


‫ثبت ة‪ ،‬وت اريخ األوام ر‪ ،‬واإلكم ال التلق ائي‪ .‬وي وفر س طر األوام ر التف اعلي الفرص ة‬

‫الستكشاف وتجربة ش يفرات تعليم ات ب ايثون‪ ،‬والق درة على نس خ الش يفرة البرمجي ة ولص قها في‬

‫ملف الشيفرة المصدرية عندما تصبح جاهزة أي بعد تجريبها والتأكد من عملها‪.‬‬

‫س يتناول ه ذا الفص ل كيفي ة العم ل بس طر األوام ر التف اعلي لب ايثون‪ ،‬وكيفي ة االس تفادة من ه‬

‫أثناء كتابة الشيفرة‪.‬‬

‫‪ .1‬فتح سطر األوامر التفاعلي‬


‫مثبت في ه ب ايثون‪.‬‬
‫أي حاسوب محلي أو خادم َّ‬
‫يمكن الوصول إلى سطر األوامر التفاعلي من ّ‬

‫التعليم ة ال تي ستس تخدمها عمومً ا لل دخول إلى س طر األوام ر التف اعلي في اإلص دار االفتراض ي‬

‫لبايثون هي‪:‬‬

‫‪python‬‬

‫إذا أع د َّدت البيئ ة البرمجي ة وجهزته ا وف ق إرش ادات الفص ل الس ابق‪ ،‬فيمكن ك إنش اء بيئ ة‬

‫ثبت ة فيه ا عن طري ق ال دخول أواًل إلى تل ك البيئ ة (إن لم‬


‫واس تعمال إص دار ب ايثون والوح دات المُ َّ‬

‫ِّ‬
‫وجهز البيئة الوهمية قبل تنفيذ األوامر التالية)‪:‬‬ ‫ُتهيِّ ئ البيئة الوهمية بعد‪ ،‬فعد إلى الفصل السابق‬

‫‪cd environments‬‬
‫‪. my_env/bin/activate‬‬

‫▲‬ ‫|‬ ‫‪70‬‬


‫البرمجة بلغة بايثون‬ ‫سطر أوامر بايثون التفاعلي‬

‫ثم اكتب األمر ‪:python‬‬

‫‪(my_env) sammy@ubuntu:~/environments$ python‬‬

‫في مثالن ا الح الي‪ ،‬اإلص دار االفتراض ي ه و ‪ ،Python 3.7.7‬وال ذي يُ ع رَ ض في المخرج ات‬

‫بمجرد إدخال األمر‪ ،‬إلى جانب إشعار حقوق الملكية‪ ،‬وبعض األوامر التي يمكن ك كتابته ا للحص ول‬

‫على معلومات إضافية‪:‬‬

‫‪Python 3.7.7 (default, Jun‬‬ ‫)‪4 2020, 15:43:14‬‬


‫‪[GCC 9.3.1 20200408 (Red Hat 9.3.1-2)] on linux‬‬
‫‪Type "help", "copyright", "credits" or "license" for more‬‬
‫‪information.‬‬
‫>>>‬

‫في بداية كل سطر ستجد ثالث عالمات "أكبر من" (<<<)‪:‬‬

‫>>>‬

‫يمكنك استهداف إصدارات محددة من بايثون عن طريق إلح اق رقم اإلص دار ب األمر‪ ،‬وب دون‬

‫مسافات مثل تنفيذ األمر ‪:python2.7‬‬

‫)‪Python 2.7.18 (default, Apr 20 2020, 00:00:00‬‬


‫‪[GCC 9.3.1 20200408 (Red Hat 9.3.1-2)] on linux2‬‬
‫‪Type "help", "copyright", "credits" or "license" for more‬‬
‫‪information.‬‬
‫>>>‬

‫ت بيِّ ن المخرج ات لن ا َّ‬


‫أنن ا نس تخدم اإلص دار ‪ .Python 2.7.17‬إذا ك ان ه ذا ه و اإلص دار‬

‫ً‬
‫أيض ا ال دخول إلى س طر األوام ر التف اعلي باس تخدام‬ ‫االفتراض ي لب ايثون ‪ ،2‬فيمكنن ا‬

‫األمر ‪.python2‬‬

‫▲‬ ‫|‬ ‫‪71‬‬


‫البرمجة بلغة بايثون‬ ‫سطر أوامر بايثون التفاعلي‬

‫بالمقاب ل‪ ،‬يمكنن ا اس تدعاء إص دار ب ايثون ‪ 3‬االفتراض ي باس تخدام األم ر ‪ python3‬فنحص ل‬

‫على المخرجات التالية‪:‬‬

‫‪Python 3.7.7 (default, Jun‬‬ ‫)‪4 2020, 15:43:14‬‬


‫‪[GCC 9.3.1 20200408 (Red Hat 9.3.1-2)] on linux‬‬
‫‪Type "help", "copyright", "credits" or "license" for more‬‬
‫‪information.‬‬
‫>>>‬

‫ً‬
‫أيضا أن نفتح سطر األوام ر التف اعلي أعاله باس تخدام األم ر ‪ .python3.7‬بع د تش غيل‬ ‫يمكن‬

‫سطر األوامر التفاعلي لبايثون‪ ،‬يمكننا المضي قدمً ا والبدء في العمل‪.‬‬

‫‪ .2‬العمل في سطر أوامر بايثون التفاعلي‬


‫يقبل مترجم بايثون التفاعلي (‪ )Python interactive interpreter‬قواعد لغة بايثون‪ ،‬والتي‬

‫تضعها بعد البادئة <<<‪.‬‬

‫يمكننا‪ ،‬على سبيل المثال‪ ،‬إنشاء متغيِّ ر وإسناد قيمة له بالشكل التالي‪:‬‬

‫‪>>> birth_year = 1868‬‬

‫بمج رد تع يين قيم ة الع دد الص حيح ‪ 1868‬إلى المتغيِّ ر ‪ ،birth_year‬سنض غط على زر‬

‫اإلدخال ونحصل على سطر جديد يبدأ بثالث عالمات "أكبر من" (<<<)‪:‬‬

‫‪>>> birth_year = 1868‬‬


‫>>>‬

‫يمكننا االستمرار في تعيين المتغيِّ رات‪ ،‬وإجراء الحسابات الرياضياتية‪:‬‬

‫▲‬ ‫|‬ ‫‪72‬‬


‫البرمجة بلغة بايثون‬ ‫سطر أوامر بايثون التفاعلي‬

‫‪>>> birth_year = 1868‬‬


‫‪>>> death_year = 1921‬‬
‫‪>>> age_at_death = death_year - birth_year‬‬
‫)‪>>> print(age_at_death‬‬
‫‪53‬‬
‫>>>‬

‫كم ا نفع ل في ملف ات ال برامج النص ية (الس كربتات)‪ ،‬أنش أنا متغ يرات جدي دة أخ رى وأس ندنا‬

‫قيم ًة له ا تناس ب اس مها‪ ،‬ثم طرحن ا قيم ة متغيِّ ٍر من آخ ر‪ ،‬وطلبن ا من س طر األوام ر طباع ة المتغ ير‬

‫الذي ِّ‬
‫يمثل الفرق عبر الدالة )(‪.print‬‬

‫ً‬
‫أيضا استخدام سطر األوامر التفاعلي كآلة حاسبة‪:‬‬ ‫يمكنك‬

‫‪>>> 203 / 20‬‬


‫‪10.15‬‬
‫>>>‬

‫هنا‪ ،‬قسمنا العدد الصحيح ‪ 203‬على ‪ ،20‬لنحصل على الناتج ‪.10.15‬‬

‫تعدد األسطر‬
‫ُّ‬ ‫‪.3‬‬
‫عن دما نكتب ش يفرة متع ددة األس طر‪ ،‬سيس تخدم الم ترجم أس طر االس تمرارية‪ ،‬وهي أس طر‬

‫مس بوقة بثالث نق اط ‪ ...‬وللخ روج من ه ذا الوض ع‪ ،‬س تحتاج إلى الض غط على ال زر‬

‫‪ ENTER‬مرتين‪.‬‬

‫رطية لتحدي د م ا‬
‫َّ‬ ‫تعين الش يفرة التالي ة قيم تي متغيِّ رين‪ ،‬ثم تس تخدم تعليم ة ش‬
‫َّ‬

‫يجب طباعته‪:‬‬

‫▲‬ ‫|‬ ‫‪73‬‬


‫البرمجة بلغة بايثون‬ ‫سطر أوامر بايثون التفاعلي‬

‫'‪>>> sammy = 'Sammy‬‬


‫'‪>>> shark = 'Shark‬‬
‫‪>>> if len(sammy) > len(shark):‬‬
‫‪...‬‬ ‫)'‪print('Sammy codes in Java.‬‬
‫‪... else:‬‬
‫‪...‬‬ ‫)'‪print('Sammy codes in Python.‬‬
‫‪...‬‬
‫‪Sammy codes in Python.‬‬
‫>>>‬

‫في هذه الحالة‪ ،‬يتساوى طوال السلسلتين النصيتين‪ ،‬لذلك يتم تنفيذ التعليمة ‪.else‬‬

‫الحظ َّ‬
‫أنك ستحتاج إلى الحفاظ على مسافة بادئة بايثون (‪ )Python indenting‬المؤلفة من‬

‫ٌأ‬ ‫سي َ‬
‫طلق خط ‪:‬‬ ‫أربعة مسافات بيضاء‪ ،‬وإال ُ‬

‫‪>>> if len(sammy) > len(shark):‬‬


‫)'‪... print('Sammy codes in Java.‬‬
‫‪File "<stdin>", line 2‬‬
‫)'‪print('Sammy codes in Java.‬‬
‫^‬
‫‪IndentationError: expected an indented block‬‬
‫>>>‬

‫ً‬
‫أيض ا‬ ‫إض افة إلى تجرب ة التعليم ات البرمجي ة متع ددة األس طر في س طر األوام ر‪ ،‬يمكن ك‬

‫استيراد الوحدات‪.‬‬

‫‪ .4‬استيراد الوحدات‬
‫ِّ‬
‫متوفرة في بيئ ة‬ ‫معينة‬ ‫ً‬
‫سريعة للتحقق مما إذا كانت وحدات‬ ‫ً‬
‫طريقة‬ ‫يوفر لك مترجم بايثون‬
‫َّ‬

‫الحالية‪ .‬يمكنك ذلك باستخدام التعليمة ‪:import‬‬


‫َّ‬ ‫البرمجة‬

‫▲‬ ‫|‬ ‫‪74‬‬


‫البرمجة بلغة بايثون‬ ‫سطر أوامر بايثون التفاعلي‬

>>> import matplotlib


Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named 'matplotlib'

‫ لتث بيت‬.‫ متاح ة في بيئ ة البرمج ة الحالي ة‬matplotlib ‫ لم تكن الوح دة‬،‫في الحال ة أعاله‬

pip ‫ وتثبيته ا باس تخدام أداة إدارة الح زم‬،‫ س تحتاج إلى ت رك الم ترجم التف اعلي‬،‫تل ك الوح دة‬

:‫مثل العادة‬

(my_env) sammy@ubuntu:~/environments$ pip install matplotlib


Collecting matplotlib
Downloading matplotlib-2.0.2-cp35-cp35m-manylinux1_x86_64.whl
(14.6MB)
...
Installing collected packages: pyparsing, cycler, python-
dateutil, numpy, pytz, matplotlib
Successfully installed cycler-0.10.0 matplotlib-2.0.2 numpy-
1.13.0 pyparsing-2.2.0 python-dateutil-2.6.0 pytz-2017.2

‫ يمكن ك الع ودة إلى‬،‫ هي وجمي ع تبعياته ا بنج اح‬matplotlib ‫بمج رد تث بيت الوح دة‬

:‫المترجم التفاعلي‬

(my_env) sammy@ubuntu:~/environments$ python

‫ ويمكن ك اس تخدام الوح دة‬،‫أي رسالة خطأ إن استوردت الوح دة‬


َّ ‫ لن تتلقى‬،‫في هذه المرحلة‬

.‫ أو داخل ملف‬،‫المثبتة إما داخل سطر األوامر‬

▲ | 75
‫البرمجة بلغة بايثون‬ ‫سطر أوامر بايثون التفاعلي‬

‫‪ .5‬الخروج من سطر أوامر بايثون التفاعلي‬


‫هن اك طريقت ان رئيس يتان للخ روج من س طر األوام ر التف اعلي‪ :‬إم ا اس تخدام اختص ار لوح ة‬

‫المفاتيح‪ ،‬أو استخدام دالة من دوال بايثون‪.‬‬

‫اختص ار لوح ة المف اتيح ه و ‪ CTRL+D‬في أنظم ة *نيكس (أي لينكس وي ونكس)‪ ،‬أو ‪CTRL+Z‬‬

‫األصلية‪:‬‬
‫َّ‬ ‫الطرفية‬
‫َّ‬ ‫ثم ‪ CTRL‬في أنظمة ويندوز‪ ،‬وبذلك ستخرج من سطر األوامر‪ ،‬وتعود إلى البيئة‬

‫‪...‬‬
‫‪>>> age_at_death = death_year - birth_year‬‬
‫)‪>>> print(age_at_death‬‬
‫‪53‬‬
‫>>>‬
‫‪sammy@ubuntu:~/environments$‬‬

‫ب داًل من ذل ك‪ ،‬س تنهي الدال ة )(‪ quit‬س طر األوام ر التف اعلي‪ ،‬وتعي دك إلى بيئ ة المحط ة‬

‫ً‬
‫سابقا‪:‬‬ ‫الطرفية األصلية التي كنت فيها‬

‫'‪>>> octopus = 'Ollie‬‬


‫)(‪>>> quit‬‬
‫‪sammy@PythonUbuntu:~/environments$‬‬

‫في ح ال اس تخدام الدال ة )(‪ ،quit‬فس ُتؤرَّ خ في مل ف الت اريخ (‪ ،)history file‬بالمقاب ل لن‬

‫يُ َّ‬
‫سجل اختصار لوحة المفاتيح ‪ CTRL+D‬ذلك‪:‬‬

‫▲‬ ‫|‬ ‫‪76‬‬


‫البرمجة بلغة بايثون‬ ‫سطر أوامر بايثون التفاعلي‬

‫الملف ‪# /home/sammy/.python_history‬‬
‫‪...‬‬
‫‪age_at_death = death_year - birth_year‬‬
‫)‪print(age_at_death‬‬
‫'‪octopus = 'Ollie‬‬
‫)(‪quit‬‬

‫يمكن إنهاء مترجم بايثون بكال الطريقتين‪ ،‬فاختر ما يناسبك‪.‬‬

‫‪ .6‬االطالع على التاريخ‬


‫أن جمي ع أوام رك ت ؤرَّ خ في المل ف ‪ .python_history‬في‬
‫من فوائ د س طر األوام ر التف اعلي ّ‬

‫أي محرر نصي‪ ،‬مثل ‪:nano‬‬


‫أنظمة *ينكس‪ ،‬بحيث يمكنك االطالع عليها في ّ‬

‫‪nano ~/.python_history‬‬

‫بمج رد فتح ه باس تخدام مح رر نص وص‪ ،‬س يبدو مل ف ت أريخ ب ايثون الخ اص ب ك على‬

‫هذا النحو‪:‬‬

‫الملف ‪# /home/sammy/.python_history‬‬
‫‪import pygame‬‬
‫)(‪quit‬‬
‫‪if 10 > 5:‬‬
‫)"‪print("hello, world‬‬
‫‪else:‬‬
‫)"‪print("nope‬‬
‫'‪sammy = 'Sammy‬‬
‫'‪shark = 'Shark‬‬
‫‪...‬‬

‫بمجرد االنتهاء من ملفك‪ ،‬يمكنك الضغط على ‪ CTRL+X‬للخروج‪.‬‬

‫▲‬ ‫|‬ ‫‪77‬‬


‫البرمجة بلغة بايثون‬ ‫سطر أوامر بايثون التفاعلي‬

‫من خالل تتبع األحداث المُ ؤرَّخة في بايثون‪ ،‬يمكنك الرجوع إلى األوام ر والتج ارب الس ابقة‪،‬‬

‫ونسخ ولصق أو تعديل الشيفرة الستخدامها في الملفات البرمجية أو في ‪.Jupyter Notebook‬‬

‫‪ .7‬خالصة الفصل‬
‫سطر األوامر التفاعلي ه و فض ٌ‬
‫اء لتجرب ة ش يفرة ب ايثون‪ ،‬إذ يمكن ك اس تخدامه أداة لالختب ار‬

‫والتجريب وغير ذلك‪.‬‬

‫لتنقيح (‪ )Debug‬ملف ات البرمج ة في ب ايثون‪ ،‬يمكن ك اس تخدام الوح دة ‪ code‬لفتح م ترجم‬

‫تف اعلي داخ ل مل ف‪ ،‬وس نتحدث عن ذل ك بالتفص يل في الفص ل الالح ق‪ :‬كيفي ة تنقيح ب ايثون‬

‫باستخدام سطر األوامر التفاعلي‪.‬‬

‫▲‬ ‫|‬ ‫‪78‬‬


‫‪4‬‬
‫التعليقات‬
‫واستخداماتها‬

‫▲‬ ‫|‬ ‫‪79‬‬


‫البرمجة بلغة بايثون‬ ‫التعليقات واستخداماتها‬

‫زءا منه ا‪ ،‬إذ تتجاهله ا‬


‫التعليق ات هي عب ارات دخيل ة على الش يفرات البرمجي ة وليس ت ج ً‬

‫المُ ص ِّرفات (‪ )compilers‬والمترجم ات (‪ .)interpreters‬يُ س ِّهل تض مين التعليق ات في الش يفرات‬

‫من قراءتها وفهمها ومعرفة وظيفة كل جزء من أجزائها‪َّ ،‬‬


‫ألنها توفر معلومات وش روحات ح ول م ا‬

‫يفعله كل جزء من البرنامج‪.‬‬

‫اء على الغ رض من البرن امج‪ ،‬يمكن أن تك ون التعليق ات بمثاب ة مُ َّ‬


‫ذكرات ل ك‪ ،‬أو يمكن ك‬ ‫بن ً‬

‫كتابتها لمساعدة المبرمجين اآلخرين على فهم الشيفرة‪.‬‬

‫ستحسن كتابة التعليقات أثناء كتابة البرامج أو تح ديثها‪َّ ،‬‬


‫ألنك ق د تنس ى الس ياق وتسلس ل‬ ‫َ‬ ‫يُ‬

‫الحقا‪ ،‬والتعليقات القديمة قد تصبح عديمة الفائدة ومضللة إن لم ُتح َّدث‪.‬‬


‫ً‬ ‫األفكار‬

‫‪ .1‬صياغة التعليقات‬
‫تبدأ التعليقات السطرية في بايثون بالعالمة ‪ #‬ومسافة بيض اء‪ ،‬وتس تمر ح تى نهاي ة الس طر‪.‬‬

‫بشكل عام‪ ،‬ستبدو التعليقات على النحو التالي‪:‬‬

‫هذا تعليق ‪#‬‬

‫ألن التعليق ات ال ُت َّ‬


‫نفذ‪ ،‬فعن د تش غيل البرن امج‪ ،‬لن ت رى أي إش ارة للتعليق ات‪ ،‬فالتعليق ات‬ ‫نظرًا َّ‬

‫توض ع في الش يفرة المص درية ليقرأه ا الن اس‪ ،‬وليس للتنفي ذ‪ .‬في برن امج " !‪ "Hello, World‬ق د‬

‫يبدو التعليق كما يلي‪:‬‬

‫طبع "!‪ "Hello, World‬في سطر األوامر ‪#‬‬


‫)"!‪print("Hello, World‬‬

‫▲‬ ‫|‬ ‫‪80‬‬


‫البرمجة بلغة بايثون‬ ‫التعليقات واستخداماتها‬

‫في الحلقة ‪ ،for‬قد تبدو التعليقات كما يلي‪:‬‬

‫تعريف المتغير ‪ sharks‬كمصفوفة من السالسل النصية ‪#‬‬


‫‪sharks = ['hammerhead', 'great white', 'dogfish', 'frilled',‬‬
‫]'‪'bullhead', 'requiem‬‬

‫حلقة ‪ For‬تمر على المصفوفة ‪# sharks‬‬


‫‪for shark in sharks:‬‬
‫)‪print(shark‬‬

‫يجب أن ُتح اذى التعليق ات على نفس المس افة البادئ ة (‪ )indent‬للش يفرة ال تي َّ‬
‫تعلق عليه ا‪.‬‬

‫ً‬
‫أيض ا ب دون مس افة بادئ ة‪،‬‬ ‫أن التعليق ات على دال ة ليس له ا مس افة بادئ ة س تكون هي‬
‫بمع نى َّ‬

‫وسيكون لكل مستوى من المسافات البادئة التالي ة تعليق ات تتواف ق م ع الش يفرات البرمجي ة ال تي‬

‫ِّ‬
‫تعلق عليها‪.‬‬

‫على س بيل المث ال‪ ،‬الش يفرة التالي ة تع رّ ف الدال ة )(‪ again‬ال تي تس أل المس تخدم إن ك ان‬

‫يريد استخدام الحاسبة مج َّد ًدا‪ ،‬مع بعض التعليقات‪:‬‬

‫‪...‬‬
‫تعريف الدالة )(‪ again‬لسؤال المستخدم ‪#‬‬
‫إن كان يريد استخدام الحاسبة مجددا ‪#‬‬

‫‪def again():‬‬

‫أخذ المدخالت من المستخدم ‪#‬‬


‫'''(‪calc_again = input‬‬
‫?‪Do you want to calculate again‬‬
‫‪Please type Y for YES or N for NO.‬‬
‫)'''‬

‫ُنّ‬
‫فذ الدالة )(‪# calculate‬‬ ‫إن أدخل المستخدم ‪ Y‬فست‬

‫▲‬ ‫|‬ ‫‪81‬‬


‫البرمجة بلغة بايثون‬ ‫التعليقات واستخداماتها‬

‫‪if calc_again == 'Y':‬‬


‫)(‪calculate‬‬

‫إن كتب المستخدم ‪ N‬فقل وداعا للمستخدم وأنه البرنامج ‪#‬‬

‫‪elif calc_again == 'N':‬‬


‫)'‪print('See you later.‬‬

‫ًا آخر‪ ،‬فأعد تنفيذ الدالة ‪#‬‬


‫إن أدخل المستخدم حرف‬
‫‪else:‬‬
‫)(‪again‬‬

‫أي ش خص آخ ر يس تخدم مش روعه أو‬


‫الهدف من التعليقات هو مساعدة المبرمج األص لي‪ ،‬أو َّ‬

‫ً‬
‫حيحا‪ ،‬وب التوازي م ع‬ ‫يتع اون مع ه‪ ،‬على فهم ه‪ .‬وإذا تع ّذر ص يانة التعليق ات وتح ديثها تح دي ًثا ص‬

‫فإن عدم تضمين التعليقات قد يكون أفضل من كتابة تعليق يتناقض مع الشيفرة‪.‬‬
‫َّ‬ ‫الشيفرة‪،‬‬

‫يجب أن تجيب التعليق ات عن س ؤال "لم اذا" ب داًل من "م اذا" أو "كي ف"‪َّ .‬‬
‫ألنه م ا لم تكن‬

‫اف لفهم م ا ال ذي تفعل ه الش يفرة‪ ،‬أو‬ ‫َّ‬


‫ومعقدة‪ ،‬ف إن النظ ر إلى الش يفرة عمومً ا ك ٍ‬ ‫الش يفرة ص عبة‬

‫كيف تفعله‪.‬‬

‫‪ .2‬التعليقات الكتلية‬
‫يمكن اس تخدام التعليق ات الكتلي ة (‪ )Block Comments‬لتوض يح الش يفرات البرمجي ة‬

‫َّ‬
‫المعقدة ال تي ال تتوق ع أن يك ون الق ارئ على دراي ة به ا‪ .‬تنطب ق ه ذه التعليق ات الطويل ة على ج زء‬

‫من الشيفرة أو جميعها‪ ،‬كما توضع في نفس مستوى المسافة البادئة للشيفرة‪.‬‬

‫في التعليقات الكتلية‪ ،‬يبدأ كل سطر بالعالمة ‪ #‬تليها بمسافة بيضاء واحدة‪ .‬إذا كنت بحاجة‬

‫إلى استخدام أكثر من فقرة واحدة‪ ،‬فيجب فصلها بسطر يحتوي على عالمة ‪ #‬واحدة‪.‬‬

‫▲‬ ‫|‬ ‫‪82‬‬


‫البرمجة بلغة بايثون‬ ‫التعليقات واستخداماتها‬

‫فيما يلي مثال على كتلة تعليقات تشرح ما يحدث في الدالة )(‪ main‬المعرفة أدناه‪:‬‬

‫سوف تحلل الدالة ‪ main‬الوسائط عبر المتغير ‪# parser‬‬


‫ّ‬
‫َد بواسطة المستخدم على سطر األوامر‪ .‬هذا سيمرر ‪#‬‬
‫ُحد‬
‫الوسائط ست‬
‫الوسيط ‪ word‬الذي يريد المستخدم تحليله مع اسم الملف ‪#‬‬
‫ُدخل ‪#‬‬
‫المراد استخدامه‪ ،‬وكذلك تقديم نص مساعد إذا لم ي‬
‫المستخدم الوسيط بشكل صحيح ‪#‬‬
‫‪def main():‬‬
‫)(‪parser = argparse.ArgumentParser‬‬
‫(‪parser.add_argument‬‬
‫‪"word",‬‬
‫"‪help="the word to be searched for in the text file.‬‬
‫)‬
‫(‪parser.add_argument‬‬
‫‪"filename",‬‬
‫"‪help="the path to the text file to be searched through‬‬
‫)‬
‫‪...‬‬

‫ً‬
‫عادة عندما تك ون الش يفرة غ ير واض حة‪ ،‬وتتطلب ش ً‬
‫رحا ش امال‪.‬‬ ‫ُتستخ َدم التعليقات الكتلية‬

‫يجب أن تتجنب اإلفراط في التعليق على الشيفرة‪ ،‬ويجب أن تث ق في ق درة الم برمجين اآلخ رين‬

‫على فهم الشيفرة‪ ،‬إال إذا كنت تكتب لجمهور معين‪.‬‬

‫‪ .3‬التعليقات السطرية‬
‫توضع التعليقات السطرية (‪ )Inline comments‬على نفس الس طر ال ذي توج د في ه التعليم ة‬

‫البرمجية‪ .‬ومثل التعليقات األخرى‪َّ ،‬‬


‫فإنها تبدأ بالعالمة ‪ #‬ومسافة بيضاء واحدة‪.‬‬

‫بشكل عام‪ ،‬تبدو التعليقات السطرية كما يلي‪:‬‬

‫]‪[code‬‬ ‫تعليق مضمن حول الشيفرة ‪#‬‬

‫▲‬ ‫|‬ ‫‪83‬‬


‫البرمجة بلغة بايثون‬ ‫التعليقات واستخداماتها‬

‫ال ينبغي اإلكثار من استخدام التعليقات السطرية‪ ،‬ولكن عند اس تخدامها في محله ا يمكن أن‬

‫أيض ا إن ظننت َّ‬


‫أنك ق د ال تت ذكر‬ ‫ً‬ ‫تكون فعالة لشرح األجزاء الصعبة من الشيفرة‪ .‬وقد تكون مفيدة‬

‫س ط ًرا من الش يفرة في المس تقبل‪ ،‬أو إذا كنت تتع اون م ع ش خص ق د ال يك ون على دراي ة بجمي ع‬

‫جوانب الشيفرة‪.‬‬

‫أن‬
‫على سبيل المث ال‪ ،‬إذا لم يكن هن اك توض يح مس بق‪ ،‬فق د ال تعلم أنت أو المتع اونون مع ك َّ‬

‫الشيفرة التالية تنشئ عد ًدا عِ قديًّ ا‪ ،‬لذلك قد ترغب في إضافة تعليق مضمَّ ن‪:‬‬

‫‪z = 2.5 + 3j‬‬ ‫إنشاء عدد عقدي ‪#‬‬

‫ً‬
‫أيض ا اس تخدام التعليق ات الس طريَّ ة لش رح الس بب وراء فع ل ش يء م ا‪ ،‬أو بعض‬ ‫يمكن‬

‫المعلومات اإلضافية‪ ،‬كما في المثال التالي‪:‬‬

‫‪x = 8‬‬ ‫ابتداء ‪ x‬بقيمة عشوائية ‪#‬‬

‫يجب اس تخدام التعليق ات الس طرية عن د الض رورة وحس ب‪ ،‬كم ا ينبغي أن ت ِّ‬
‫وفر إرش ادات‬

‫مفيدة للشخص الذي يقرأ البرنامج‪.‬‬

‫‪ .4‬تعليق جزء من الشيفرة بدواعي االختبار والتنقيح‬


‫ً‬
‫أيض ا اس تخدام العالم ة ‪#‬‬ ‫باإلض افة إلى اس تخدام التعليق ات وس ً‬
‫يلة لتوثي ق الش يفرة‪ ،‬يمكن‬

‫لتعلي ق ج زء من الش يفرة وتعطيل ه أثن اء اختب ار أو تنقيح البرن امج ال ذي تعم ل علي ه‪ .‬أي عن دما‬

‫تواج ه أخط اء بع د إض افة أس طر جدي دة إلى الش يفرة‪ ،‬فق د ت رغب في تعلي ق بعض ها لمعرف ة‬

‫موض ع الخل ل‪ .‬يمكن أن ي تيح ل ك اس تخدام العالم ة ‪ #‬تجرب ة ب دائل أخ رى أثن اء إع داد الش يفرة‪.‬‬

‫على س بيل المث ال‪ ،‬ق د تفاض ل بين اس تخدام الحلق ة ‪ while‬أو حلق ة ‪ for‬أثن اء برمج ة لعب ة‪،‬‬

‫ويمكنك تعليق إحداهما بينما تختبر أيّ هما أفضل‪:‬‬

‫▲‬ ‫|‬ ‫‪84‬‬


‫البرمجة بلغة بايثون‬ ‫التعليقات واستخداماتها‬

import random

number = random.randint(1, 25)

# number_of_guesses = 0

for i in range(5):
# while number_of_guesses < 5:
print('Guess a number between 1 and 25:')
guess = input()
guess = int(guess)

# number_of_guesses = number_of_guesses + 1

if guess < number:


print('Your guess is too low')

if guess > number:


print('Your guess is too high')

if guess == number:
break

if guess == number:
print('You guessed the number!')

else:
print('You did not guess the number. The number was ' +
str(number))

▲ | 85
‫البرمجة بلغة بايثون‬ ‫التعليقات واستخداماتها‬

‫برمجية‪ ،‬باإلض افة إلى‬


‫َّ‬ ‫ي تيح ل ك تعلي ق الش يفرة البرمجي ة تجرب ة ع َّدة طرائ ق ومقارب ات‬

‫مساعدتك على العثور على مكمن الخطأ من خالل التعليق المنهجي لبعض أجزاء البرنامج‪.‬‬

‫‪ .5‬خالصة الفصل‬
‫واء‬
‫سيس اعدك اس تخدام التعليق ات في ب رامج ب ايثون على جع ل برامج ك أك ثر مقروئي ة‪ ،‬س ً‬

‫ِّ‬
‫ستسهل تع اون اآلخ رين مع ك في مش اريع‬ ‫لك أو لغيرك‪ .‬التعليقات المناسبة وذات الصلة والمفيدة‬

‫البرمجة وتجعل شيفرتك أكثر قيمة‪.‬‬

‫▲‬ ‫|‬ ‫‪86‬‬


‫‪5‬‬
‫المتغيرات‬
‫واستخداماتها‬

‫▲‬ ‫|‬ ‫‪87‬‬


‫البرمجة بلغة بايثون‬ ‫المتغيرات واستخداماتها‬

‫المتغ يرات (‪ )variables‬هي مفه وم ب رمجي مهم‪َّ .‬‬


‫إنه ا رم وز ت دل على البيان ات ال تي‬

‫تستخدمها في برنامجك‪ ،‬أي تعد حاويات للبيانات التي ستتعامل معها في برنامج‪.‬‬

‫ً‬
‫حيحا في‬ ‫سيغطي هذا الفصل بعض أساسيات المتغ يرات‪ ،‬وكيفي ة اس تخدامها اس تخدامً ا ص‬

‫برامج بايثون ‪.3‬‬

‫‪ .1‬فهم المتغيرات‬
‫من الناحية الفنية‪ ،‬يُ َّ‬
‫خصص للمتغير مساحة تخزيني ة في ال ذاكرة توض ع القيم ة المرتبط ة ب ه‬

‫فيها‪ .‬يُ ستخدم اسم المتغير لإلشارة إلى تلك القيمة المُ َّ‬
‫خزنة في ذاكرة البرنامج التي هي جزء من‬

‫ذاكرة الحاسوب‪ .‬المُ تغيِّ ر أشبه بعنوان ُتلصقه على قيمة مُ َّ‬
‫عينة‪:‬‬

‫حيحا يس اوي ‪ ،103204934813‬ونري د تخزين ه في متغيِّ ر ب داًل‬


‫ً‬ ‫أن ل دينا ع د ًدا ص‬
‫لنف ترض ّ‬

‫من إع ادة كتاب ة ه ذا الع دد الطوي ل ك ل م رة‪ ،‬ل ذلك سنس تخدم ش يًئ ا يُ س ِّهل ت ُّ‬
‫ذكره‪ ،‬مثل‬

‫المتغير ‪:my_int‬‬

‫‪my_int = 103204934813‬‬

‫عنوان مرتبط بقيمة‪ ،‬فسيبدو على النحو التالي‪:‬‬


‫ٌ‬ ‫إذا نظرنا إليه على َّ‬
‫أنه‬

‫▲‬ ‫|‬ ‫‪88‬‬


‫البرمجة بلغة بايثون‬ ‫المتغيرات واستخداماتها‬

‫عن وان القيم ة ه و ‪ my_int‬المكت وب عليه ا‪ ،‬والقيم ة هي ‪( 103204934813‬نوعه ا ع دد‬

‫صحيح‪ ،‬سنتطرق إلى أنواع البيانات في الفصل التالي)‪.‬‬

‫‪ my_int‬هي تعليم ة إس ناد ( ‪،)assignment statement‬‬ ‫التعليم ة ‪= 103204934813‬‬

‫وتتألف من األجزاء التالية‪:‬‬

‫اسم المتغير (‪)my_int‬‬ ‫•‬

‫ً‬
‫أيضا باسم "عالمة المساواة" (=)‬ ‫معامل اإلسناد‪ ،‬المعروف‬ ‫•‬

‫ُأ‬
‫القيمة التي س ِن َدت إلى اسم المتغير (‪)103204934813‬‬ ‫•‬

‫تش كل ه ذه األج زاء الثالث ة معً ا التعليم ة ال تي ُتس نِد على المتغ ير ‪ my_int‬القيم ة العددي ة‬

‫الصحيحة ‪. 103204934813‬‬

‫بمج رد تع يين قيم ة متغيِّ ر م ا‪ ،‬نك ون ق د َّ‬


‫هيئن ا أو أنش أنا ذل ك المتغ ير‪ .‬وبع د ذل ك‪ ،‬يمكنن ا‬

‫اس تخدام ذل ك المتغ ير ب داًل من القيم ة‪ .‬في ب ايثون‪ ،‬ال يل زم التص ريح عن المتغيِّ رات قب ل‬

‫اس تخدامها كم ا ه و الح ال في بعض لغ ات البرمج ة األخ رى‪ ،‬إذ يمكن ك الب دء في اس تخدام‬

‫ً‬
‫مباشرة‪.‬‬ ‫المتغير‬

‫بمج رد إس ناد القيم ة القيم ة ‪ 103204934813‬إلى المتغ ير ‪ ،my_int‬يمكنن ا اس تخدام ‪my_int‬‬

‫مكان العدد الصحيح‪ ،‬كما في المثال التالي‪:‬‬

‫▲‬ ‫|‬ ‫‪89‬‬


‫البرمجة بلغة بايثون‬ ‫المتغيرات واستخداماتها‬

‫)‪print(my_int‬‬

‫والمخرجات هي‪:‬‬

‫‪103204934813‬‬

‫اس تخدام المتغ يرات يس هل علين ا إج راء العملي ات الحس ابية‪ .‬في المث ال الت الي‪ ،‬سنس تخدم‬

‫التعليمة السابقة‪ ، my_int = 1040 ،‬ثم سنطرح من المتغير ‪ my_int‬القيمة ‪: 813‬‬

‫)‪print(my_int - 813‬‬

‫وسينتج لنا‪:‬‬

‫‪103204934000‬‬

‫في هذا المثال‪ ،‬يج ري ب ايثون العملي ة الحس ابية‪ ،‬ويط رح ‪ 813‬من المتغ ير ‪ ، my_int‬ويعي د‬

‫القيمة ‪.103204934000‬‬

‫يمكن ضبط المتغيرات وجعلها تساوي ناتج عملية حس ابية‪ .‬دعن ا نجم ع ع ددين معً ا‪ ،‬ونخ ِّزن‬

‫قيمة المجموع في المتغير ‪:x‬‬

‫‪x = 76 + 145‬‬

‫يشبه المثال أعاله إحدى المعادالت التي تراها في كتب الجبر‪ .‬في الج بر‪ُ ،‬تس تخ َدم الح روف‬

‫والرم وز لتمثي ل األع داد والكمي ات داخ ل الص يغ والمع ادالت‪ ،‬وبش كل مماث ل‪ ،‬المتغ يرات أس ماء‬

‫ايثون‪،‬أن َعلي ك التأك د دائمً ا من وض ع‬


‫ّ‬ ‫معين‪ .‬الف رق في لغ ة ب‬
‫َّ‬ ‫رمزي ة تمث ل قيم ة من ن وع بيان ات‬

‫المتغير على الجانب األيسر من المعادلة‪.‬‬

‫▲‬ ‫|‬ ‫‪90‬‬


‫البرمجة بلغة بايثون‬ ‫المتغيرات واستخداماتها‬

‫لنطبع ‪:x‬‬

‫)‪print(x‬‬

‫والمخرجات‪:‬‬

‫‪221‬‬

‫َّ ُأ‬
‫ألنه سنِد إلى المتغير ‪ x‬مجموع ‪ 76‬و ‪.145‬‬ ‫أعادت بايثون القيمة ‪221‬‬

‫يمكن أن تحوي المتغيِّ رات أي نوع من أنواع البيانات‪ ،‬وليس األعداد الصحيحة فقط‪:‬‬

‫'!‪my_string = 'Hello, World‬‬


‫‪my_flt = 45.06‬‬
‫القيم المنطقية ستعيد إما ‪ False‬أو ‪my_bool = 5 > 9 # True‬‬
‫]'‪my_list = ['item_1', 'item_2', 'item_3', 'item_4‬‬
‫)'‪my_tuple = ('one', 'two', 'three‬‬
‫}'&' ‪my_dict = {'letter': 'g', 'number': 'seven', 'symbol':‬‬

‫إذا طبعت أيًّ ا من المتغيِّ رات الم ذكورة أعاله‪ ،‬فس تعيد ب ايثون قيم ة المتغيِّ ر‪ .‬على س بيل‬

‫المثال‪ ،‬في الشيفرة التالية سنطبع متغيرًا يحتوي قائمة‪:‬‬

‫]'‪my_list = ['item_1', 'item_2', 'item_3', 'item_4‬‬


‫)‪print(my_list‬‬

‫وسينتج لنا‪:‬‬

‫]'‪['item_1', 'item_2', 'item_3', 'item_4‬‬

‫لق د مرَّ رن ا القيم ة ['‪ 'item_1‬و '‪ 'item_2‬و '‪ 'item_3‬و '‪ ]'item_4‬إلى‬

‫المتغير ‪ ،my_list‬ثم استخدمنا الدالة )(‪ print‬لطباعة تلك القيمة باستدعاء ‪.my_list‬‬

‫▲‬ ‫|‬ ‫‪91‬‬


‫البرمجة بلغة بايثون‬ ‫المتغيرات واستخداماتها‬

‫وض ع بع د ذل ك في‬ ‫ً‬


‫غيرة من ذاك رة الحاس وب‪ ،‬وتقب ل قيمً ا ُت َ‬ ‫ً‬
‫احة ص‬ ‫ُت ِّ‬
‫خص ص المتغيِّ رات مس‬

‫تلك المساحة‪.‬‬

‫‪ .2‬قواعد تسمية المتغيرات‬


‫تتس م تس مية المتغ يرات بمرون ة عالي ة‪ ،‬ولكن هن اك بعض القواع د ال تي علي ك أخ ذها‬

‫في الحسبان‪:‬‬

‫يجب أن تكون أسماء المتغيرات من كلمة واحدة فقط (بدون مسافات)‬ ‫•‬

‫يجب أن تتكوَّ ن أسماء المتغيرات من األحرف واألرقام والشرطة السفلية (_) فقط‬ ‫•‬

‫ال ينبغي أن تبدأ أسماء المتغيرات برقم‬ ‫•‬

‫باتباع القواعد المذكورة أعاله‪ ،‬دعنا نلقي نظرة على بعض األمثلة‪:‬‬

‫لماذا غير صالح؟‬ ‫اسم صحيح‬ ‫اسم غير صحيح‬

‫غير مسموح بالشرطات‬ ‫‪my_int‬‬ ‫‪my-int‬‬

‫ال يمكن البدء برقم‬ ‫‪int4‬‬ ‫‪4int‬‬

‫أي رمز غير‬


‫ال يمكن استخدام ّ‬
‫‪MY_INT‬‬ ‫‪$MY_INT‬‬
‫الشرطة السفلية‬

‫ال ينبغي أن يتكون االسم من أكثر‬


‫‪another_int‬‬ ‫‪another int‬‬
‫من كلمة واحدة‬

‫من األم ور ال تي يجب أخ ذها في الحس بان عن د تس مية المتغ يرات‪ ،‬ه و َّ‬
‫أنه ا حساس ة لحال ة‬

‫أن ‪ my_int‬و ‪ MY_INT‬و ‪ My_Int‬و ‪ mY_iNt‬كله ا مختلف ة‪ .‬ينبغي أن تتجنب‬


‫األحرف‪ ،‬وهذا يعني َّ‬

‫▲‬ ‫|‬ ‫‪92‬‬


‫البرمجة بلغة بايثون‬ ‫المتغيرات واستخداماتها‬

‫اس تخدام أس ماء متغيِّ رات متماثل ة لض مان أال يح دث خل ط عن دك أو عن د المتع اونين مع ك‪ ،‬س واء‬

‫الحاليين والمستقبليِّ ين‪.‬‬

‫أخ يرًا‪ ،‬ه ذه بعض المالحظ ات ح ول أس لوب التس مية‪ .‬من المتع ارف علي ه عن د تس مية‬

‫المتغيرات أن تبدأ اسم المتغير بحرف ص غير‪ ،‬وأن تس تخدم الش رطة الس فلية عن د فص ل الكلم ات‪.‬‬

‫ِّ‬
‫يفض ل بعض األش خاص اس تعمال تنس يق س نام الجم ل‬ ‫ً‬
‫أيض ا‪ ،‬وق د‬ ‫الب دء بح رف كب ير مقب ول‬

‫ولكن ه ذه الخي ارات‬


‫َّ‬ ‫(‪ ،camelCase‬الخلط بين األحرف الكب يرة والص غيرة) عن د كتاب ة المتغ يرات‪،‬‬

‫أقل شهرة‪.‬‬

‫لماذا غير متعارف عليه‬ ‫تنسيق شائع‬ ‫تنسيق غير شائع‬

‫أسلوب سنام الجمل‬


‫‪my_int‬‬ ‫‪myInt‬‬
‫(‪ )camelCase‬غير شائع‬

‫الحرف األول كبير‬ ‫‪int4‬‬ ‫‪Int4‬‬

‫أسلوب سنام الجمل‬


‫‪my_first_string‬‬ ‫‪myFirstString‬‬
‫(‪ )camelCase‬غير شائع‬

‫الخي ار األهم ال ذي علي ك التمس ك ب ه ه و االتس اق‪ .‬إذا ب دأت العم ل في مش روع يس تخدم‬

‫تنسيق سنام الجمل في تسمية المتغيرات‪ ،‬فمن األفضل االستمرار في استخدام ذلك التنسيق‪.‬‬

‫يمكنك مراجعة توثيق تنس يق الش يفرات البرمجي ة في ب ايثون في موس وعة حس وب للمزي د‬

‫من التفاصيل‪.‬‬

‫▲‬ ‫|‬ ‫‪93‬‬


‫البرمجة بلغة بايثون‬ ‫المتغيرات واستخداماتها‬

‫‪ .3‬تغيير قيم المتغيرات‬


‫كما تشير إلى ذلك كلمة "متغيِّ ر"‪ ،‬يمكن تغيير قيم المتغيرات في ب ايثون بس هولة‪ .‬ه ذا يع ني‬

‫ً‬ ‫ُأ‬ ‫َّ‬


‫مسبقا بسهولة بالغة‪.‬‬ ‫أنه يمكنك تعيين قيمة مختلفة إلى متغير س ِن َدت له قيمة‬

‫القدرة على إع ادة إس ناد القيم مفي دة للغاي ة‪ ،‬إذ ق د تحت اج خالل أط وار برنامج ك إلى قب ول‬

‫قيم ينشئها المستخدم ُ‬


‫وتحيلها على متغير‪.‬‬

‫ً‬
‫أيض ا في ال برامج الكب يرة ال تي ق د تحت اج خالله ا إلى‬ ‫سهولة إع ادة إس ناد المتغ يرات مفي دة‬

‫تغيير القيم باستمرار‪.‬‬

‫ً‬
‫صحيحا‪ ،‬ثم نعيد إسناد سلسلة نصية إليه‪:‬‬ ‫س ُنسند إلى المتغير ‪ x‬أواًل عد ًدا‬

‫تعيين ‪ x‬إلى قيمة عددية ‪#‬‬


‫‪x = 76‬‬
‫)‪print(x‬‬

‫إعادة تعيين ‪ x‬إلى سلسلة نصية ‪#‬‬


‫"‪x = "Sammy‬‬
‫)‪print(x‬‬

‫وسينتج لنا‪:‬‬

‫‪76‬‬
‫‪Sammy‬‬

‫يوضح المث ال أعاله أن ه يمكنن ا أواًل إس ناد قيم ة عددي ة إلى المتغ ير ‪ ،x‬ثم إع ادة إس ناد قيم ة‬

‫نصية إليه‪.‬‬

‫إذا أعدنا كتابة البرنامج بالشكل التالي‪:‬‬

‫▲‬ ‫|‬ ‫‪94‬‬


‫البرمجة بلغة بايثون‬ ‫المتغيرات واستخداماتها‬

‫‪x = 76‬‬
‫"‪x = "Sammy‬‬
‫)‪print(x‬‬

‫ألن تلك القيمة هي األحدث‪:‬‬


‫لن نتلقى سوى القيمة المسندة الثانية في المخرجات‪َّ ،‬‬

‫‪Sammy‬‬

‫ق د تك ون إع ادة إس ناد القيم إلى المتغ يرات مفي دة في بعض الح االت‪ ،‬لكن علي ك أن تبقي‬

‫ً‬
‫واضحا قدر اإلمكان‪.‬‬ ‫عينك على مقروئية الشيفرة‪ ،‬وأن تحرص على جعل البرنامج‬

‫‪ .4‬اإلسناد المتعدد (‪)Multiple Assignment‬‬


‫في ب ايثون‪ ،‬يمكن ك إس ناد قيم ة واح دة إلى ع دة متغ يرات في ال وقت نفس ه‪ .‬ي تيح ل ك ه ذا‬

‫ً‬
‫الحق ا‪ ،‬أو من خالل‬ ‫ً‬
‫دة‪ ،‬وال تي يمكن ك إع ادة إس نادها‬ ‫تهيئ ة ع َّدة متغ يرات دفع ًة واح‬

‫مدخالت المستخدم‪.‬‬

‫يمكن ك من خالل اإلس نادات المتع ددة إس ناد قيم ة واح دة إلى ع َّدة متغ يرات (مث ل المتغ ير‬

‫‪ x‬و‪ y‬و ‪ )z‬في سطر واحد‪:‬‬

‫‪x = y = z = 0‬‬
‫)‪print(x‬‬
‫)‪print(y‬‬
‫)‪print(z‬‬

‫الناتج سيكون‪:‬‬

‫‪0‬‬
‫‪0‬‬
‫‪0‬‬

‫▲‬ ‫|‬ ‫‪95‬‬


‫البرمجة بلغة بايثون‬ ‫المتغيرات واستخداماتها‬

‫عرفنا في هذا المثال ثالثة متغيرات (‪ x‬و ‪ y‬و ‪ ،)z‬وأسندنا إليها القيمة ‪.0‬‬

‫ً‬
‫أيضا بإسناد ع َّدة قيم لع َّدة متغيِّ رات ض من الس طر نفس ه‪ .‬ه ذه القيم يمكن‬ ‫تسمح لك بايثون‬

‫أن تكون من أنواع بيانات مختلفة‪:‬‬

‫‪j, k, l = "shark", 2.05, 15‬‬


‫)‪print(j‬‬
‫)‪print(k‬‬
‫)‪print(l‬‬

‫وهذه هي المخرجات‪:‬‬

‫‪shark‬‬
‫‪2.05‬‬
‫‪15‬‬

‫في المث ال أعاله‪ُ ،‬أ س ن َدت السلس لة النص ية "‪ "shark‬إلى المتغ ير ‪ ،j‬والع دد العش ري ‪2.05‬‬

‫إلى المتغير ‪ ،k‬والعدد الصحيح ‪ 15‬إلى المتغير ‪.l‬‬

‫إس ناد ع دة متغ يرات بع دة قيم في س طر واح د يمكن أن يختص ر الش يفرة ويقل ل من ع دد‬

‫أن ذلك ليس على حساب المقروئية‪.‬‬


‫أسطرها‪ ،‬ولكن تأكد من َّ‬

‫‪ .5‬المتغيرات العامة والمحلية‬


‫عن د اس تخدام المتغ يرات داخ ل البرن امج‪ ،‬من المهم أن تض ع نط اق (‪ )scope‬المتغ ير في‬

‫حساباتك‪ .‬يشير نطاق المتغ ير إلى المواض ع ال تي يمكن الوص ول منه ا إلى المتغيِّ ر داخ ل الش يفرة‪،‬‬

‫َّ‬
‫ألنه ال يمكن الوص ول إلى جمي ع المتغ يرات من جمي ع أج زاء البرن امج‪ ،‬فبعض المتغ يرات عامة‬

‫دئيا‪ُ ،‬تع رَّ ف المتغ يرات العام ة خ ارج ال دوال؛ أمَّ ا المتغ يرات‬
‫(‪ ،)global‬وبعض ها محلي (‪ .)local‬مب ًّ‬

‫المحلية‪ ،‬فتعرَّ ف داخل الدوال‪.‬‬

‫▲‬ ‫|‬ ‫‪96‬‬


‫البرمجة بلغة بايثون‬ ‫المتغيرات واستخداماتها‬

‫المثال التالي يعطي فكرة عن المتغيرات العامة والمحلية‪:‬‬

‫إنشاء متغير عام‪ ،‬خارج الدالة ‪#‬‬


‫"‪glb_var = "global‬‬

‫‪def var_function():‬‬
‫إنشاء متغير محلي داخل دالة ‪#‬‬
‫"‪lcl_var = "local‬‬
‫)‪print(lcl_var‬‬

‫استدعاء دالة لطباعة المتغير المحلي ‪#‬‬


‫)(‪var_function‬‬

‫طباعة متغير عام خارج دالة ‪#‬‬


‫)‪print(glb_var‬‬

‫المخرجات الناتجة‪:‬‬

‫‪local‬‬
‫‪global‬‬

‫يُ س نِد البرن امج أعاله سلس لة نص ية إلى المتغ ير العم ومي ‪ glb_var‬خ ارج الدال ة‪ ،‬ثم يع ِّرف‬

‫محليا باس م ‪ ،lcl_var‬ثم يطبع ه‬


‫ًّ‬ ‫نش ئ داخ ل تل ك الدال ة متغيِّ ًرا‬
‫وسي ِ‬
‫ُ‬ ‫الدال ة )(‪.var_function‬‬

‫قيمته‪ .‬ينتهي البرنامج باستدعاء الدالة )(‪ ،var_function‬وطباعة قيمة المتغير ‪.glb_var‬‬

‫لمَّ ا ك ان ‪ glb_var‬متغ يرًا عامًّ ا‪ ،‬فيمكنن ا الوص ول إلي ه داخ ل الدال ة )(‪.var_function‬‬

‫المثال التالي يبيِّ ن ذلك‪:‬‬

‫"‪glb_var = "global‬‬

‫‪def var_function():‬‬
‫"‪lcl_var = "local‬‬

‫▲‬ ‫|‬ ‫‪97‬‬


‫البرمجة بلغة بايثون‬ ‫المتغيرات واستخداماتها‬

‫)‪print(lcl_var‬‬
‫طباعة ‪ glb_var‬داخل الدالة ‪print(glb_var) #‬‬

‫)(‪var_function‬‬
‫)‪print(glb_var‬‬

‫المخرجات‪:‬‬

‫‪local‬‬
‫‪global‬‬
‫‪global‬‬

‫لقد طبعنا المتغير العام ‪ glb_var‬مرتين‪ ،‬إذ ُطبع داخل الدالة وخارجها‪.‬‬

‫ماذا لو حاولنا استدعاء المتغير المحلي خارج الدالة؟‬

‫"‪glb_var = "global‬‬

‫‪def var_function():‬‬
‫"‪lcl_var = "local‬‬
‫)‪print(lcl_var‬‬

‫)‪print(lcl_var‬‬

‫ص ِّرح عن ه فيه ا‪ .‬إذا حاولن ا القي ام ب ذلك‪،‬‬


‫ال يمكنن ا اس تخدام متغ ير محلي خ ارج الدال ة ال تي ُ‬

‫فسيطلق الخطأ ‪.NameError‬‬


‫ُ‬

‫‪NameError: name 'lcl_var' is not defined‬‬

‫دعنا ننظر إلى مثال آخر‪ ،‬حيث سنستخدم االسم نفسه لمتغير عام وآخر محلي‪:‬‬

‫▲‬ ‫|‬ ‫‪98‬‬


‫البرمجة بلغة بايثون‬ ‫المتغيرات واستخداماتها‬

‫متغير عام ‪num1 = 5 #‬‬

‫‪def my_function():‬‬
‫استخدام نفس اسم المتغير ‪num1 = 10 # num1‬‬
‫‪num2 = 7‬‬ ‫تعيين متغير محلي ‪#‬‬

‫طباعة المتغير المحلي ‪print(num1) # num1‬‬


‫طباعة المتغير المحلي ‪print(num2) # num2‬‬

‫استدعاء )(‪# my_function‬‬


‫)(‪my_function‬‬

‫طباعة المتغير العام ‪# num1‬‬


‫)‪print(num1‬‬

‫الناتج‪:‬‬

‫‪10‬‬
‫‪7‬‬
‫‪5‬‬

‫أن ‪num1‬‬
‫محلي ا داخ ل إح دى ال دوال‪ ،‬فس نرى َّ‬
‫ً‬ ‫ص ِّرح عن ه‬
‫ألن المتغ ير المحلي ‪ُ num1‬‬
‫نظ ًرا َّ‬

‫يس اوي القيم ة المحلي ة ‪ 10‬عن د اس تدعاء الدال ة‪ .‬عن دما نطب ع القيم ة العام ة للمتغ ير ‪ num1‬بع د‬

‫أن المتغير العام ‪ num1‬ال يزال مساويً ا للقيمة ‪.5‬‬


‫استدعاء الدالة )(‪ ،my_function‬سنرى َّ‬

‫من الممكن الوص ول إلى المتغ يرات العام ة واس تعمالها داخ ل دال ة باس تخدام الكلم ة‬

‫المفتاحية ‪:global‬‬

‫▲‬ ‫|‬ ‫‪99‬‬


‫البرمجة بلغة بايثون‬ ‫المتغيرات واستخداماتها‬

‫‪def new_shark():‬‬
‫جعل المتغير عاما ‪#‬‬
‫‪global shark‬‬
‫"‪shark = "Sammy‬‬

‫استدعاء الدالة )(‪# new_shark‬‬


‫)(‪new_shark‬‬

‫طباعة المتغير العام ‪# shark‬‬


‫)‪print(shark‬‬

‫أن المتغ ير المحلي ‪ shark‬عُ يِّ ن داخ ل الدال ة )(‪ ،new_shark‬إال َّ‬
‫أنه يمكن الوص ول إلي ه‬ ‫رغم َّ‬

‫من خارج الدالة بسبب الكلمة المفتاحية ‪ global‬المستخدمة قبل اسم المتغير داخل الدالة‪.‬‬

‫َ‬
‫بسبب استخدام ‪ ،global‬فلن يُ طلق ُّ‬
‫أي خطأ عندما نستدعي )‪ print(shark‬خ ارج الدال ة‪.‬‬

‫أن ذل ك يُ ع ُّد من الع ادات غ ير المس تحبة في‬ ‫رغم َّ‬


‫أنه يمكن ك اس تعمال متغ ير ع ام داخ ل دال ة‪ ،‬إال َّ‬

‫البرمج ة‪َّ ،‬‬


‫ألنه ا ق د ت ؤثر على مقروئي ة الش يفرة ع دا عن الس ماح لج زء من الش يفرة بتع ديل قيم ة‬

‫متغير قد يستعمله جزء آخر‪.‬‬

‫هناك شيء آخر يجب تذكره‪ ،‬وهو َّ‬


‫أنك إذا أشرت إلى متغير داخل دال ة‪ ،‬دون إس ناد قيم ة ل ه‪،‬‬

‫محليا‪ ،‬يجب عليك إسناد قيمة له داخل متن الدالة‪.‬‬


‫ًّ‬ ‫متغير‬
‫ٍ‬ ‫ضمنيا‪ .‬لجعل‬
‫ًّ‬ ‫فسيعَ ّد هذا المتغير عامً ا‬
‫ُ‬

‫عن د التعام ل م ع المتغ يرات‪ ،‬يك ون ل ك الخي ار بين اس تخدام المتغ يرات العام ة أو المحلي ة‪.‬‬

‫يُ َّ‬
‫فض ل في العادة استخدام المتغيرات المحلية‪ ،‬ولكن إن وجدت نفسك تس تخدم نفس المتغ ير في‬

‫عدة دوال‪ ،‬فقد ترغب في جعله عامً ا‪ .‬أمَّ ا إن كنت تحتاج المتغير داخل دالة أو ص نف واح د فق ط‪،‬‬

‫فقد يكون األولى استخدام متغير محلي‪.‬‬

‫▲‬ ‫|‬ ‫‪100‬‬


‫البرمجة بلغة بايثون‬ ‫المتغيرات واستخداماتها‬

‫‪ .6‬خالصة الفصل‬
‫لق د مررن ا في ه ذا الفص ل على بعض ح االت االس تخدام الش ائعة للمتغ يرات في ب ايثون ‪.3‬‬

‫مثل حاض ً‬
‫نة لمختل ف أن واع البيان ات في ب ايثون وال تي‬ ‫المتغيرات هي لبنة مهمة في البرمجة‪ ،‬إذ ُت ِّ‬

‫سنسلط عليها الضوء في الفصل التالي‪.‬‬

‫▲‬ ‫|‬ ‫‪101‬‬


‫‪6‬‬
‫أنواع البيانات‬
‫والتحويل بينها‬

‫▲‬ ‫|‬ ‫‪102‬‬


‫البرمجة بلغة بايثون‬ ‫أنواع البيانات والتحويل بينها‬

‫ُت ِّ‬
‫صنف بايثون البيانات (‪ )data‬إلى أن واع‪ ،‬كم ا ه و الح ال في جمي ع لغ ات البرمج ة‪ .‬ه ذا مهم‬

‫ألن نوع البيانات الذي تستخدمه سيقيِّ د القيم التي يمكن تعيينها لها‪ ،‬وما الذي يمكن فعله بها (بم ا‬
‫َّ‬

‫في ذلك العمليات التي يمكن تنفيذها عليها)‪.‬‬

‫اء‬
‫لية لب ايثون‪ .‬ه ذا ليس استقص ً‬
‫س نتعرَّ ف في ه ذا الفص ل على أهم أن واع البيان ات األص َّ‬

‫شاماًل ألنواع البيانات‪ ،‬ولكنَّه سيساعدك على التعرف على الخيارات المتاحة لك في بايثون‪.‬‬

‫‪ .1‬خلفية عامة‬
‫أن واع البيان ات في ب ايثون مش ابهة إلى ح د م ا ألن واع البيان ات ال تي نس تخدمها في الع الم‬

‫الحقيقي‪ .‬من أمثلة أنواع البيانات في العالم الحقيقي األعداد‪ ،‬مث ل‪ :‬األع داد الص حيحة الطبيعي ة‬

‫(‪ ،)... ،2 ،1 ،0‬واألعداد الصحيحة النسبية (‪ ،)... ،1 ،0 ،1- ،...‬واألعداد غير النسبية (‪.)π‬‬

‫يمكننا عادة في الرياضيات جمع أعداد من أنواع مختلفة مثل إضافة ‪ 5‬إلى ‪:π‬‬

‫‪5 + π‬‬

‫يمكنن ا إمَّ ا االحتف اظ بالمعادل ة ِبع ِّدها إجاب ة‪ ،‬وس تكون النتيج ة ع د ًدا غ ير نس بي (‪irrational‬‬

‫‪ ،)number‬أو يمكنن ا تق ريب (‪ )round‬الع دد ‪ π‬إلى ع دد ذي من ازل عش رية مح ددة‪ ،‬ثم‬

‫نجمع العددين‪:‬‬

‫‪5 + π = 5 + 3.14 = 8.14‬‬

‫ولكن‪ ،‬إذا حاولن ا إض افة ع دد إلى ن وع بيان ات آخ ر‪ ،‬مث ل الكلم ات‪ ،‬فستص بح األم ور مربك ة‬

‫وغير ذات معنى‪ .‬فكيف ستحل المعادلة التالية مثاًل ؟‬

‫‪hsoub + 8‬‬

‫▲‬ ‫|‬ ‫‪103‬‬


‫البرمجة بلغة بايثون‬ ‫أنواع البيانات والتحويل بينها‬

‫ً‬
‫مختلف ا تمامً ا‪ ،‬مث ل الكلم ات‬ ‫بالنسبة إلى الكلمة ‪ ،hsoub‬يمكن ع ُّد كل نوع من أنواع البيان ات‬

‫وكيفية التعام ل معه ا‬


‫َّ‬ ‫كيفية اس تخدامها‪،‬‬
‫َّ‬ ‫يتعين علين ا ت وخي الح ذر بش أن‬
‫َّ‬ ‫واألع داد‪ ،‬ل ذلك‬

‫في العمليات‪.‬‬

‫‪ .2‬األعداد‬
‫ً‬
‫راحة عن ن وع‬ ‫فسر كل عدد ُتدخله إلى بايثون على َّ‬
‫أنه عدد؛ ليس مطلوبًا من ك اإلعالن ص‬ ‫سي َّ‬
‫ُ‬

‫ألن ب ايثون َتع ُّد ّ‬


‫أي ع دد مكت وب ب دون فواص ل عش رية بمثاب ة ع دد ص حيح‬ ‫البيانات الذي تدخل ه َّ‬

‫وأي ع دد مكت وب بفواص ل لعش رية بمثاب ة ع دد عش ري (‪ ،float‬كما‬


‫ُّ‬ ‫(‪ ،integer‬كما ه و ح ال ‪،)138‬‬

‫هو حال ‪.)138.0‬‬

‫ا‪ .‬األعداد الصحيحة (‪)integer‬‬

‫كم ا ه و الح ال في الرياض يات‪ ،‬األع داد الص حيحة (‪ )integer‬في البرمج ة هي أع داد كامل ة‪،‬‬

‫ً‬
‫أيضا باسم ‪.int‬‬ ‫يمكن أن تكون موجبة أو سالبة أو معدومة (‪ .)... ،1،0،1- ،...‬ويُ عرف هذا النوع‬

‫كما هو الحال مع لغات البرمجة األخرى‪ ،‬يجب أال تستخدم الفواصل في األع داد المؤلف ة من أربع ة‬

‫أرقام أو أكثر‪ ،‬لذلك ال تكتب ‪ 1,000‬في برنامجك‪ ،‬واكتب ‪.1000‬‬

‫يمكننا طباعة عدد صحيح على النحو التالي‪:‬‬

‫)‪print(-25‬‬

‫وسينتج‪:‬‬

‫‪-25‬‬

‫▲‬ ‫|‬ ‫‪104‬‬


‫البرمجة بلغة بايثون‬ ‫أنواع البيانات والتحويل بينها‬

‫أو يمكننا اإلعالن عن متغير‪ ،‬والذي هو في هذه الحال ة رم ٌز للع دد ال ذي نس تخدمه أو نتعام ل‬

‫معه‪ ،‬مثال‪:‬‬

‫‪my_int = -25‬‬
‫)‪print(my_int‬‬

‫وسينتج لنا‪:‬‬

‫‪-25‬‬

‫ً‬
‫مباشرة مثل‪:‬‬ ‫يمكننا أن نجري العمليات الحسابية على األعداد الصحيحة في بايثون‬

‫‪int_ans = 116 - 68‬‬


‫)‪print(int_ans‬‬

‫المخرجات‪:‬‬

‫‪48‬‬

‫يمكن استخدام األع داد الص حيحة بع دة طرائ ق في ب رامج ب ايثون‪ ،‬وم ع اس تمرارك في تعلم‬

‫المزي د عن ه ذه اللغ ة‪ ،‬س تتاح ل ك الكث ير من الف رص الس تخدام األع داد الص حيحة والتعام ل معه ا‬

‫وفهم المزيد عن هذا النوع من البيانات‪.‬‬

‫ب‪ .‬األعداد العشرية (‪)Floating-Point Numbers‬‬

‫األع داد العش رية هي أع داد حقيقي ة‪ ،‬مم ا يع ني أن ه يمكن أن تك ون أع دا ًدا جذري ة أو غ ير‬

‫نسبية‪ .‬لهذا الس بب‪ ،‬يمكن أن تحت وي األع داد العش رية على ج زء كس ري‪ ،‬مث ل ‪ 9.0‬أو ‪.-116.42‬‬

‫وببساطة‪ ،‬فاألعداد العشرية هي أعداد تحتوي الفاصلة العشرية‪.‬‬

‫كما فعلنا مع األعداد الصحيحة‪ ،‬يمكننا طباعة األعداد العشرية هكذا‪:‬‬

‫▲‬ ‫|‬ ‫‪105‬‬


‫البرمجة بلغة بايثون‬ ‫أنواع البيانات والتحويل بينها‬

‫)‪print(17.3‬‬

‫وسينتج لنا‪:‬‬

‫‪17.3‬‬

‫ِّ‬
‫متغير يحوى عد ًدا عشريًا‪ ،‬مثال‪:‬‬ ‫ً‬
‫أيضا أن نعلن عن‬ ‫يمكننا‬

‫‪my_flt = 17.3‬‬
‫)‪print(my_flt‬‬

‫الناتج‪:‬‬

‫‪17.3‬‬

‫وكم ا ه و الح ال م ع األع داد الص حيحة‪ ،‬يمكنن ا أن نج رى العملي ات الحس ابية على‬

‫األعداد العشرية‪:‬‬

‫‪flt_ans = 564.0 + 365.24‬‬


‫)‪print(flt_ans‬‬

‫الناتج‪:‬‬

‫‪929.24‬‬

‫ألن ‪ 3‬عدد‬
‫أن ‪َّ ،3.0 ≠ 3‬‬
‫تختلف األعداد الصحيحة واألعداد العشرية عن بعضها عمومً ا‪ ،‬إذ َّ‬

‫صحيح‪ ،‬بينما ‪ 3.0‬عدد عشري‪.‬‬

‫‪ .3‬القيم المنطقية‬
‫هناك قيمتان فقط لنوع البيانات المنطقية (‪ ،)Boolean‬وهما ‪ True‬و ‪ُ .False‬تستخدم القيم‬

‫المنطقية لتمثيل قيم الحقيقة الموافقة للمنطق الرياضياتي (صح أو خطأ)‪.‬‬

‫▲‬ ‫|‬ ‫‪106‬‬


‫البرمجة بلغة بايثون‬ ‫أنواع البيانات والتحويل بينها‬

‫ع ادة م ا يب دأ اس م البيان ات المنطقي ة ب الحرف ‪ ،B‬إش ارة إلى اس م ع الم الرياض يات ‪George‬‬

‫‪ .Boole‬القيمتان ‪ True‬و ‪ُ False‬تكتبان دائمً ا بحرفين كبيرين ‪ T‬و ‪َّ ،F‬‬


‫ألنها قيم خاصة في بايثون‪.‬‬

‫منطقيا‪ ،‬إما ‪ True‬أو ‪:False‬‬


‫ً‬ ‫الكثير من العمليات الحسابية في الرياضيات ُتنتج قيمً ا‬

‫أكبر من‬ ‫•‬

‫‪bool_val = 500 > 100 # True‬‬


‫‪bool_val = 1 > 5‬‬ ‫‪# False‬‬

‫أصغر من‬ ‫•‬

‫‪bool_val = 200 < 400 # True‬‬


‫‪bool_val = 4 < 2‬‬ ‫‪# False‬‬

‫التساوي‬ ‫•‬

‫‪bool_val = 5 = 5‬‬ ‫‪# True‬‬


‫‪bool_val = 500 = 400 # False‬‬

‫كما هو الحال مع األعداد‪ ،‬يمكننا تخزين القيم المنطقية في المتغيرات‪:‬‬

‫‪my_bool = 5 > 8‬‬

‫يمكننا بعد ذلك طباعة القيمة المنطقية باستدعاء الدالة )(‪:print‬‬

‫)‪print(my_bool‬‬

‫أن العدد ‪ 5‬ليس أكبر من ‪ ،8‬فسوف نحصل على المخرجات التالية‪:‬‬


‫بما َّ‬

‫‪False‬‬

‫▲‬ ‫|‬ ‫‪107‬‬


‫البرمجة بلغة بايثون‬ ‫أنواع البيانات والتحويل بينها‬

‫المنطقية‪ ،‬وكي ف يمكن لل دوال والعملي ات‬


‫َّ‬ ‫كيفية اس تخدام القيم‬
‫َّ‬ ‫َّ‬
‫تتعلم م ع م رور ال وقت‬ ‫س‬

‫المنطقية أن تغيِّ ر مسار البرنامج‪.‬‬


‫َّ‬

‫‪ .4‬السالسل النصية‬
‫السلسلة النص ية (‪ )string‬هي عب ارة عن تسلس ل من مح رف واح د أو أك ثر (مح ارف وأع داد‬

‫ورم وز)‪ ،‬ويمكن أن تك ون ثابت ة أو متغ يرة‪ .‬تح اط السالس ل النص ية إم ا بعالم ات االقتب اس‬

‫المفردة ' أو عالمات االقتباس المزدوجة "‪ ،‬ل ذلك إلنش اء سلس لة نص ية‪ ،‬ض ع سلس لة من األح رف‬

‫بين عالمتي اقتباس‪:‬‬

‫'‪'This is a string in single quotes.‬‬


‫"‪"This is a string in double quotes.‬‬

‫يمكنك استخدام عالمات االقتب اس المف ردة أو عالم ات االقتب اس المزدوج ة‪ ،‬المهم أن تك ون‬

‫ً‬
‫متسقا في برنامجك‪.‬‬

‫البرن امج البس يط "!‪ "Hello, World‬يوض ح كي ف يمكن اس تخدام السالس ل النص ية في‬

‫أن حروف عبارة !‪ Hello, World‬تمثل سلسلة نصية‪.‬‬


‫البرمجة‪ ،‬إذ َّ‬

‫)"!‪print("Hello, World‬‬

‫كما هو الحال مع أنواع البيانات األخرى‪ ،‬يمكننا تخزين السالسل النصية في المتغيرات‪:‬‬

‫"!‪hw = "Hello, World‬‬

‫وطباعة السلسلة عن طريق استدعاء المتغيِّ ر‪:‬‬

‫)‪print(hw‬‬ ‫!‪# Hello, World‬‬

‫▲‬ ‫|‬ ‫‪108‬‬


‫البرمجة بلغة بايثون‬ ‫أنواع البيانات والتحويل بينها‬

‫مث ل األع داد‪ ،‬هن اك العدي د من العملي ات ال تي يمكن إجراؤه ا على السالس ل النص ية من أج ل‬

‫تحقي ق النت ائج ال تي نس عى إليه ا‪ .‬السالس ل النص ية مهم ة لتوص يل المعلوم ات إلى المس تخدم‪،‬‬

‫وكذلك لتمكين المستخدم من تمرير المعلومات إلى البرنامج‪.‬‬

‫‪ .5‬القوائم (‪)Lists‬‬
‫رتب قاب ل للتغي ير ( ‪ .)mutable‬وكم ا ُتع رَّ ف السالس ل‬
‫القائمة (‪ )list‬عب ارة عن تسلس ل م َّ‬

‫النصية باستخدام عالمات االقتباس‪ ،‬يتم تعريف القوائم باستخدام األقواس المعقوفة []‪.‬‬
‫َّ‬

‫ً‬
‫صحيحة‪:‬‬ ‫مثاًل ‪ ،‬هذه قائمة تحوي أعدا ًدا‬

‫]‪[-3, -2, -1, 0, 1, 2, 3‬‬

‫وهذه قائمة من األعداد العشرية‪:‬‬

‫]‪[3.14, 9.23, 111.11, 312.12, 1.05‬‬

‫وهذه قائمة من السالسل النصية‪:‬‬

‫]'‪['shark', 'cuttlefish', 'squid', 'mantis shrimp‬‬

‫ِّ‬
‫سنسمي قائمة السالسل النصية خاصتنا باالسم ‪:sea_creatures‬‬ ‫في المثال التالي‪،‬‬

‫‪sea_creatures = ['shark', 'cuttlefish', 'squid', 'mantis‬‬


‫]'‪shrimp‬‬

‫يمكننا طباعتها عن طريق استدعاء المتغير‪:‬‬

‫)‪print(sea_creatures‬‬

‫أن المخرجات تشبه تمامً ا القائمة التي أنشأناها‪:‬‬


‫وسترى َّ‬

‫]'‪['shark', 'cuttlefish', 'squid', 'mantis shrimp‬‬

‫▲‬ ‫|‬ ‫‪109‬‬


‫البرمجة بلغة بايثون‬ ‫أنواع البيانات والتحويل بينها‬

‫الق وائم هي ن وع بيان ات م رن للغاي ة‪ ،‬ألنه ا قابل ة للتغي ير‪ ،‬حيث يمكن إض افة قيم إليه ا‪ ،‬أو‬

‫بي د َّ‬
‫أنه غ ير قاب ل للتغي ير‪ ،‬ويُ س مى‬ ‫إزالت ه‪ ،‬أو تغييره ا‪ .‬هن اك ن وع بيان ات آخ ر مش ابه لق وائم‪ْ ،‬‬

‫الصف (‪.)tuple‬‬

‫‪ .6‬الصفوف (‪)Tuples‬‬
‫يُ ستخدم الصف (‪ )tuple‬لتجميع البيانات‪ ،‬وهو تسلسل ثابت من العناصر وغير قابل للتغيير‪.‬‬

‫الصفوف تشبه القوائم إلى حد كبير‪ ،‬لكنها تس تخدم األق واس () ب داًل من األق واس المعقوف ة []‪،‬‬

‫َّ‬
‫وألنها غير قابلة للتغيير‪ ،‬فال يمكن تغيير أو تعديل قيمها‪.‬‬

‫تبدو الصفوف كالتالي‪:‬‬

‫)'‪('blue coral', 'staghorn coral', 'pillar coral‬‬

‫يمكننا تخزين الصفوف في المتغيِّ رات وطباعتها‪:‬‬

‫)'‪coral = ('blue coral', 'staghorn coral', 'pillar coral‬‬


‫)‪print(coral‬‬

‫والمخرجات هي‪:‬‬

‫)'‪('blue coral', 'staghorn coral', 'pillar coral‬‬

‫كما هو الحال في أنواع البيان ات األخ رى‪ ،‬تطب ع ب ايثون الص فوف تمامً ا كم ا كتبناه ا‪ ،‬إذ تطب ع‬

‫سلسلة من القيم بين قوسين‪.‬‬

‫▲‬ ‫|‬ ‫‪110‬‬


‫البرمجة بلغة بايثون‬ ‫أنواع البيانات والتحويل بينها‬

‫‪ .7‬القواميس (‪)Dictionaries‬‬
‫اتيح ب القيم المقابل ة له ا في‬
‫ُ‬ ‫القاموس (‪ )dictionary‬هو ن وع مُ ض مّ ن في ب ايثون‪ ،‬إذ ُترب ط مف‬

‫ش كل أزواج‪ ،‬ه ذه األزواج مفي دة لتخ زين البيان ات في ب ايثون‪ .‬يتم إنش اء الق واميس باس تخدام‬

‫األقواس المعقوصة {}‪.‬‬

‫ُتس تخدم الق واميس ع ً‬


‫ادة لحف ظ البيان ات المترابط ة‪ ،‬مث ل المعلوم ات المقابل ة ل رقم تعري ف‪.‬‬

‫يبدو القاموس كما يلي‪:‬‬

‫‪{'name': 'Sammy', 'animal': 'shark', 'color': 'blue',‬‬


‫}'‪'location': 'ocean‬‬

‫س تالحظ أن ه باإلض افة إلى األق واس المعقوص ة‪ ،‬توج د عالم ات النقط تين الرأس يتين‬

‫(‪ )colons‬داخ ل الق اموس‪ .‬الكلم ات الموج ودة على يس ار النقط تين الرأس يتين هي المف اتيح‪.‬‬

‫أي نوع بيانات غير قابل للتغيير‪ .‬المفاتيح في القاموس أعاله هي‪:‬‬
‫المفاتيح قد تكون َّ‬

‫'‪'name', 'animal', 'color', 'location‬‬

‫الكلم ات الموج ودة على يمين النقط تين هي القيم‪ .‬يمكن أن تت ألف القيم من أي ن وع من‬

‫البيانات‪ .‬القيم في القاموس أعاله هي‪:‬‬

‫'‪'Sammy', 'shark', 'blue', 'ocean‬‬

‫مثل أنواع البيانات األخرى‪ ،‬يمكننا تخزين القواميس في متغيرات‪ ،‬وطباعتها‪:‬‬

‫‪sammy = {'name': 'Sammy', 'animal': 'shark', 'color': 'blue',‬‬


‫}'‪'location': 'ocean‬‬
‫)‪print(sammy‬‬

‫▲‬ ‫|‬ ‫‪111‬‬


‫البرمجة بلغة بايثون‬ ‫أنواع البيانات والتحويل بينها‬

‫والمخرجات هي‪:‬‬

‫‪{'color': 'blue', 'animal': 'shark', 'name': 'Sammy',‬‬


‫}'‪'location': 'ocean‬‬

‫إذا أردت الحص ول على الل ون (‪ )color‬الخ اص بـ ‪ ،Sammy‬فيمكن ك القي ام ب ذلك عن طري ق‬

‫استدعاء ]'‪ .sammy ['color‬هذا مثال على ذلك‪:‬‬

‫‪print(sammy['color']) # blue‬‬

‫القواميس من أنواع البيانات المهمَّ ة في برامج بايثون‪.‬‬

‫‪ .8‬التحويل بين أنواع البيانات‬


‫ِّ‬
‫يحدد نوع البيانات ‪-‬كما ذكرنا‪ -‬القيم ال تي يمكن اس تعمالها‪ ،‬والعملي ات ال تي يمكن ك إجراؤه ا‬

‫وع إلى آخ ر ألج ل معالجته ا بطريق ة مختلف ة‪.‬‬


‫عليه ا‪ .‬هن اك أوق ات نحت اج إلى تحوي ل القيم من ن ٍ‬

‫على سبيل المثال‪ ،‬قد نحتاج إلى ضم (‪ )concatenate‬القيم العددية إلى سالسل نصية‪.‬‬

‫سيرشدك هذا القسم إلى كيفية التحويل بين األعداد والسالسل النصية والص فوف والق وائم‪،‬‬

‫باإلضافة إلى تقديم بعض األمثلة التوضيحية‪.‬‬

‫ا‪ .‬تحويل األنواع العددية‬

‫هن اك نوع ان من البيان ات العددي ة في ب ايثون كم ا رأين ا ً‬


‫آنف ا‪ :‬األع داد الص حيحة واألع داد‬

‫العش رية‪ .‬س تعمل في بعض األحي ان على ش يفرة برمجي ة كتبه ا ش خص آخ ر‪ ،‬وق د تحت اج إلى‬

‫ً‬
‫حيحا في‬ ‫تحوي ل ع دد ص حيح إلى ع دد عش ري‪ ،‬أو العكس‪ ،‬أو ق د تج د َّ‬
‫أنك تس تخدم ع د ًدا ص‬

‫ال وقت ال ذي تحت اج إلى أع داد عش رية‪ .‬يت وفر في ب ايثون تواب ع مض مّ نة ُتس ِّهل علي ك تحوي ل‬

‫األعداد الصحيحة إلى أعداد عشريَّ ة‪ ،‬أو العكس‪.‬‬

‫▲‬ ‫|‬ ‫‪112‬‬


‫البرمجة بلغة بايثون‬ ‫أنواع البيانات والتحويل بينها‬

‫تحويل األعداد الصحيحة إلى أعداد عشرية‬

‫يح وّ ل الت ابع )(‪ float‬األع داد الص حيحة إلى أع داد عش رية‪ .‬الس تخدام ه ذه الدال ة‪ ،‬ض ع‬

‫ً‬
‫صحيحا بين القوسين‪:‬‬ ‫عد ًدا‬

‫)‪float(57‬‬

‫في هذه الحالة‪ ،‬سيحوَّ ل العدد الصحيح ‪ 57‬إلى العدد العشري ‪.57.0‬‬

‫ً‬
‫أيض ا اس تخدام ه ذه الدال ة م ع المتغ يرات‪ .‬ل ُنس نِد القيم ة ‪ 57‬إلى المتغيِّ ر ‪ ،f‬ثم نطب ع‬ ‫يمكن ك‬

‫العدد العشري الجديد‪:‬‬

‫‪f = 57‬‬

‫))‪print(float(f‬‬

‫الناتج سيكون‪:‬‬

‫‪57.0‬‬

‫يمكننا باستخدام الدالة )(‪ float‬تحويل األعداد الصحيحة إلى أعداد عشرية‪.‬‬

‫تحويل األعداد العشرية إلى أعداد صحيحة‬

‫تملك بايثون دالة أخرى مضمَّ نة لتحويل األعداد عشرية إلى أعداد صحيحة‪ :‬وهي )(‪.int‬‬

‫تعمل الدالة )(‪ int‬بشكل مشابه للدالة )(‪ :float‬يمكنك إضافة عدد عشري داخل القوسين‬

‫لتحويله إلى عدد صحيح‪:‬‬

‫)‪int(390.8‬‬

‫سيحوَّ ل العدد العشري ‪ 390.8‬إلى العدد الصحيح ‪.390‬‬


‫في هذه الحالة‪ُ ،‬‬

‫▲‬ ‫|‬ ‫‪113‬‬


‫البرمجة بلغة بايثون‬ ‫أنواع البيانات والتحويل بينها‬

‫وأن ‪c‬‬
‫َّ‬ ‫أن ‪ b‬يس اوي ‪،125.0‬‬ ‫ً‬
‫أيض ا اس تخدام ه ذه الدال ة م ع المتغ يرات‪ .‬لنص ِّرح َّ‬ ‫يمكن ك‬

‫يساوي ‪ ،390.8‬ثم نطبع العددين العشريين الجديدين‪:‬‬

‫‪b = 125.0‬‬

‫‪c = 390.8‬‬

‫))‪print(int(b‬‬

‫))‪print(int(c‬‬

‫والمخرجات ستكون‪:‬‬

‫‪125‬‬
‫‪390‬‬

‫عن د تحوي ل األع داد العش رية إلى أع داد ص حيحة بواس طة الدال ة )(‪ ،int‬تقتط ع ب ايثون‬

‫وتبقي القيمة الص حيحة؛ ل ذلك‪ ،‬لن ُتح ِّول الدال ة )(‪ int‬الع دد ‪390.8‬‬
‫األجزاء العشرية من العدد ُ‬

‫إلى ‪.391‬‬

‫تحويل األعداد عبر القسمة‬

‫في بايثون ‪ ،3‬عند تقسيم ع دد ص حيح على آخ ر‪ ،‬س ينتج ع دد عش ري على خالف ب ايثون ‪.2‬‬

‫أنه عن د قس مة ‪ 5‬على ‪ 2‬في ب ايثون ‪ ،3‬ستحص ل على ع دد عش ري (مث ل ‪ 2.5‬عن د‬


‫بمع نى َّ‬

‫قسمة ‪ 5‬على ‪:)2‬‬

‫▲‬ ‫|‬ ‫‪114‬‬


‫البرمجة بلغة بايثون‬ ‫أنواع البيانات والتحويل بينها‬

‫‪a = 5 / 2‬‬

‫)‪print(a‬‬

‫وسينتج لنا‪:‬‬

‫‪2.5‬‬

‫بينما في بايثون ‪ ،2‬ستحصل على ناتج صحيح‪ ،‬أي ‪ .2 = 5/2‬يمكن ك الحص ول على ع دد‬

‫صحيح ناتج عن عملية القسمة باستعمال المعامل ‪ //‬الجديد في بايثون ‪:3‬‬

‫‪a = 5 // 2‬‬

‫)‪print(a‬‬

‫وسينتج لنا‪:‬‬

‫‪2‬‬

‫ارج ع إلى فص ل «إص دارات ب ايثون‪ :‬ب ايثون ‪ 2‬مقاب ل ب ايثون ‪ »3‬لالطالع على المزي د من‬

‫الفروقات بين بايثون ‪ 2‬وبايثون ‪.3‬‬

‫ب‪ .‬التحويل مع السالسل النصية‬

‫السالسل النصية عبارة عن سلسلة مؤلفة من محرف واحد أو أك ثر (المح رف يمكن أن يك ون‬

‫ً‬
‫حرف ا‪ ،‬أو ع د ًدا‪ ،‬أو رم ًزا)‪ .‬السالس ل النص ية هي إح دى األش كال الش ائعة من البيان ات في ع الم‬

‫البرمجة‪ ،‬وقد نحتاج إلى تحويل السالسل النصية إلى أعداد أو أعداد إلى سالسل نص ية في كث ير‬

‫ً‬
‫خاصة عندما نعمل على البيانات التي ينشئها المستخدمون‪.‬‬ ‫من األحيان‪،‬‬

‫▲‬ ‫|‬ ‫‪115‬‬


‫البرمجة بلغة بايثون‬ ‫أنواع البيانات والتحويل بينها‬

‫تحويل األعداد إلى سالسل نصية‬

‫يمكنن ا تحوي ل األع داد إلى سالس ل نص ية ع بر الت ابع )(‪ .str‬يمكنن ا أن نم ِّرر إمَّ ا ع د ًدا أو‬

‫متغيرًا بين قوسي التابع‪ ،‬وبعد ذلك ُ‬


‫ستحوَّ ل تلك القيمة العددية إلى قيمة نصية‪.‬‬

‫دعنا ننظر أواًل في تحويل األعداد الصحيحة‪ .‬لتحويل العدد الصحيح ‪ 12‬إلى سلسلة نص ية‪،‬‬

‫يمكنك تمرير ‪ 12‬إلى التابع )(‪:str‬‬

‫)‪str(12‬‬

‫عند تنفيذ )‪ str(12‬في سطر أوام ر ب ايثون التف اعلي م ع األم ر ‪ python‬في ناف ذة الطرفي ة‪،‬‬

‫ستحصل على المخرجات التالية‪:‬‬

‫'‪'12‬‬

‫ً‬
‫حيحا‪ ،‬ولكنَّه أص بح اآلن‬ ‫تشير عالمات االقتباس المحيطة بالعدد ‪ 12‬إلى أنه لم يع د ع د ًدا ص‬

‫سلسلة نصية‪.‬‬

‫سيص بح باس تخدام المتغ يرات تحوي ل األع داد الص حيحة إلى سالس ل نص ية أك ثر فائ دة‪.‬‬

‫يوميا مث ل أن ن دخل ع دد أس طر‬


‫ًّ‬ ‫لنف ترض َّ‬
‫أنن ا نري د متابع ة تق ُّدم مس تخدم في مج ال البرمج ة‬

‫الشيفرة البرمجية التي كتبها‪ .‬نود أن نعرض ذلك على المستخدم‪ ،‬وذلك بطباع ة السالس ل النص ية‬

‫واألعداد في الوقت نفسه‪:‬‬

‫"‪user = "Sammy‬‬

‫‪lines = 50‬‬

‫‪print("Congratulations, " + user + "! You just wrote " + lines‬‬


‫)"‪+ " lines of code.‬‬

‫▲‬ ‫|‬ ‫‪116‬‬


‫البرمجة بلغة بايثون‬ ‫أنواع البيانات والتحويل بينها‬

‫سي َ‬
‫طلق الخطأ التالي‪:‬‬ ‫عند تنفيذ الشيفرة أعاله‪ُ ،‬‬

‫‪TypeError: Can't convert 'int' object to str implicitly‬‬

‫يتع ذر علين ا ض مُّ (‪ )concatenate‬األع داد إلى السالس ل النص ية في ب ايثون‪ ،‬ل ذلك يجب‬

‫تحويل المتغير ‪ lines‬إلى سلسلة نصية‪:‬‬

‫"‪user = "Sammy‬‬
‫‪lines = 50‬‬

‫‪print("Congratulations, " + user + "! You just wrote " +‬‬


‫)"‪str(lines) + " lines of code.‬‬

‫البرمجية‪ ،‬سنحص ل على المخرج ات التالي ة‪ ،‬وفيه ا تهنئ ة‬


‫َّ‬ ‫اآلن‪ ،‬عن دما ُن ِّ‬
‫نفذ الش يفرة‬

‫للمستخدم على تق ُّدمه‪:‬‬

‫‪Congratulations, Sammy! You just wrote 50 lines of code.‬‬

‫إذا أردن ا تحوي ل ع دد عش ري إلى سلس لة نص ية ب داًل من تحوي ل ع دد ص حيح إلى سلس لة‬

‫نصية‪ ،‬فعلينا تتبع نفس الخطوات والص ياغة الس ابقة‪ .‬عن دما نم ِّرر ع د ًدا عش ريً ا إلى الت ابع )(‪،str‬‬

‫ُ‬
‫ستعاد سلسلة نصية‪ .‬يمكننا استخدام قيمة العدد العشري نفسها‪ ،‬أو يمكننا استخدام متغيِّ ر‪:‬‬

‫))‪print(str(421.034‬‬

‫‪f = 5524.53‬‬
‫))‪print(str(f‬‬

‫وسينتج لنا‪:‬‬

‫‪421.034‬‬
‫‪5524.53‬‬

‫▲‬ ‫|‬ ‫‪117‬‬


‫البرمجة بلغة بايثون‬ ‫أنواع البيانات والتحويل بينها‬

‫يمكننا اختبار صحة التحويل عن طريق ضم الناتج إلى سلسلة نصية‪:‬‬

‫‪f = 5524.53‬‬

‫)"‪print("Sammy has " + str(f) + " points.‬‬

‫وهذا هو الناتج‪:‬‬

‫‪Sammy has 5524.53 points.‬‬

‫ح ِّول بنج اح إلى سلس لة نص ية‪َّ ،‬‬


‫ألن عملي ة الض م ق د‬ ‫أن ع ددنا العش ري ق د ُ‬
‫اآلن تأك دنا من َّ‬

‫ُن ِّفذت دون خطأ‪.‬‬

‫تحويل السالسل النصية إلى أعداد‬

‫يمكن تحوي ل السالس ل النص ية إلى أع داد باس تخدام الت ابعين )(‪ float‬و )(‪ .int‬إذا لم‬

‫يكن في السلس لة النص ية من ازل عش رية‪ ،‬فاألفض ل أن تحوله ا إلى ع دد ص حيح باس تخدام‬

‫التابع )(‪.int‬‬

‫دعنا نستخدم مثال تتبع عدد أس طر الش يفرة ال ذي أوردن اه أعاله‪ .‬ق د ت رغب في التعام ل م ع‬

‫ولكن ه ذه القيم‬
‫َّ‬ ‫ه ذه القيم باس تخدام الحس ابات الرياض ياتية لتق ديم نت ائج أدق للمس تخدم‪،‬‬

‫حاليا في سالسل نصية‪:‬‬


‫ًّ‬ ‫َّ‬
‫مخزنة‬

‫"‪lines_yesterday = "50‬‬

‫"‪lines_today = "108‬‬

‫‪lines_more = lines_today - lines_yesterday‬‬

‫)‪print(lines_more‬‬

‫▲‬ ‫|‬ ‫‪118‬‬


‫البرمجة بلغة بايثون‬ ‫أنواع البيانات والتحويل بينها‬

‫الناتج هو‪:‬‬

‫'‪TypeError: unsupported operand type(s) for -: 'str' and 'str‬‬

‫أن معام ل‬ ‫ًأ‬ ‫َّ‬


‫مخزنتان في سالسل نصية‪ ،‬تلقين ا خط ‪ .‬س بب ذل ك َّ‬ ‫ألن القيمتين العدديتين‬
‫نظرًا َّ‬

‫الطرح ‪ -‬ال يصلح للسالسل النصية‪.‬‬

‫دعن ا نع ِّدل الش يفرة لتض مين الت ابع )(‪ int‬ال ذي س يحول السالس ل النص ية إلى أع داد‬

‫ص حيحة‪ ،‬ويس مح لن ا بالقي ام بالعملي ات الرياض ياتية على القيم ال تي ك انت سالس ل نص ية‬

‫في األصل‪.‬‬

‫"‪lines_yesterday = "50‬‬

‫"‪lines_today = "108‬‬

‫)‪lines_more = int(lines_today) - int(lines_yesterday‬‬

‫)‪print(lines_more‬‬

‫وهذه هي المخرجات‪:‬‬

‫‪58‬‬

‫تلقائيا‪ ،‬ويساوي القيمة العددية ‪ 58‬في هذا المثال‪.‬‬


‫ًّ‬ ‫المتغير ‪ line_more‬هو عدد صحيح‬

‫أيضا تحويل األعداد في المثال أعاله إلى قيم عشرية باستخدام التابع )(‪ float‬بداًل‬
‫ً‬ ‫يمكننا‬

‫من الت ابع )(‪ .int‬وب دالً من الحص ول على الن اتج ‪ ،58‬سنحص ل على الن اتج ‪ ،58.0‬وه و‬

‫عدد عشري‪.‬‬

‫▲‬ ‫|‬ ‫‪119‬‬


‫البرمجة بلغة بايثون‬ ‫أنواع البيانات والتحويل بينها‬

‫ً‬
‫نقاطا على شكل قيم عشرية‪:‬‬ ‫سيكسب المستخدم ‪Sammy‬‬

‫"‪total_points = "5524.53‬‬

‫"‪new_points = "45.30‬‬

‫‪new_total_points = total_points + new_points‬‬

‫)‪print(new_total_points‬‬

‫الناتج‪:‬‬

‫‪5524.5345.30‬‬

‫ً‬
‫الحة‪ ،‬لكن ه سيض م‬ ‫في هذه الحالة‪ ،‬يع ُّد استخدام المعامل ‪ +‬م ع سلس لتين نص يتين عملي ًة ص‬

‫النص يتين ب داًل من جم ع القيم تين الع دديتين؛ ل ذلك‪ ،‬س يبدو الن اتج غ ير م ألوف‪َّ ،‬‬
‫ألنه‬ ‫ّ‬ ‫السلس لتين‬

‫ً‬
‫بعضا‪.‬‬ ‫نتيجة لصق القيمتين إلى جانب بعضهما‬

‫سنحتاج إلى تحويل هذه السالسل النص ية إلى أع داد عش رية قب ل إج راء أي عملي ات عليه ا‪،‬‬

‫وذلك باستخدام التابع )(‪:float‬‬

‫"‪total_points = "5524.53‬‬

‫"‪new_points = "45.30‬‬

‫)‪new_total_points = float(total_points) + float(new_points‬‬

‫)‪print(new_total_points‬‬

‫وسينتج عن ذلك‪:‬‬

‫‪5569.83‬‬

‫▲‬ ‫|‬ ‫‪120‬‬


‫البرمجة بلغة بايثون‬ ‫أنواع البيانات والتحويل بينها‬

‫اآلن‪ ،‬وبع د أن حوَّ لن ا السلس لتين النص يتين إلى ع ددين عش ريين‪ ،‬سنحص ل على النتيج ة‬

‫المتوقعة‪ ،‬والتي هي جمع ‪ 45.30‬و ‪.5524.53‬‬

‫إذا حاولنا تحويل سلسلة نصية ذات منازل عشرية إلى عدد صحيح‪ ،‬فسنحصل على خطأ‪:‬‬

‫"‪f = "54.23‬‬

‫))‪print(int(f‬‬

‫المخرجات‪:‬‬

‫'‪ValueError: invalid literal for int() with base 10: '54.23‬‬

‫إذا مرّ رنا عد ًدا عشريً ا موضوعً ا في سلسلة نص ية إلى الت ابع )(‪ ،int‬فسنحص ل على خط أ‪ ،‬إذ‬

‫لن ُتحوَّ ل إلى عدد صحيح‪.‬‬

‫ي تيح لن ا تحوي ل السالس ل النص ية إلى أع داد تع ديل ن وع البيان ات ال ذي نعم ل علي ه بس رعة‬

‫حتى نتمكن من إجراء عمليات على قيم عددية مكتوبة على شكل سالسل نصية‪.‬‬

‫ج‪ .‬التحويل إلى صفوف وقوائم‬

‫يمكن ك اس تخدام الت ابعين )(‪ list‬و )(‪ tuple‬لتحوي ل القيم المُ م رَّ رة إليهم ا إلى قائمة أو‬

‫صف على التوالي‪ .‬في بايثون‪:‬‬

‫القائم ة هي تسلس ل م َّ‬


‫رتب قاب ل للتغي ير من العناص ر الموض وعة داخ ل قوس ين‬ ‫•‬
‫معقوفين []‪.‬‬

‫الص ف عب ارة عن تسلس ل م رتب ث ابت (غ ير قاب ل للتغي ير) من العناص ر الموض وعة بين‬ ‫•‬
‫الهالليين ()‪.‬‬
‫َّ‬ ‫القوسين‬

‫▲‬ ‫|‬ ‫‪121‬‬


‫البرمجة بلغة بايثون‬ ‫أنواع البيانات والتحويل بينها‬

‫التحويل إلى صفوف‬

‫ِّ‬
‫يحس ن تحوي ل قائم ة إلى ص ف أداء‬ ‫نظ ًرا لك ون الص فوف غ ير قابل ة للتغي ير‪ ،‬فيمكن أن‬

‫ال برامج تحس ينًا كب يرًا‪ .‬عن دما نس تخدم الت ابع )(‪ ،tuple‬فس وف يُ عي د القيم ة المُ م رَّ رة إلي ه على‬

‫هيئة صف‪.‬‬

‫‪print(tuple(['pull request', 'open source', 'repository',‬‬


‫))]'‪'branch‬‬

‫المخرجات‪:‬‬

‫)'‪('pull request', 'open source', 'repository', 'branch‬‬

‫أن العناص ر موض وعة اآلن بين قوس ين‪ ،‬ب داًل من‬
‫أن الص ف ق د ُطب ع في المخرج ات‪ ،‬إذ َّ‬
‫ن رى َّ‬

‫القوسين المربعين‪.‬‬

‫دعنا نستخدم )(‪ tuple‬مع متغير يحتوي قائمة‪:‬‬

‫‪sea_creatures = ['shark', 'cuttlefish', 'squid', 'mantis‬‬


‫]'‪shrimp‬‬

‫))‪print(tuple(sea_creatures‬‬

‫سينتج‪:‬‬

‫)'‪('shark', 'cuttlefish', 'squid', 'mantis shrimp‬‬

‫ح ِّولت إلى ص ف‪ ،‬كم ا يش ير إلى ذل ك القوس ان‪ .‬يمكنن ا تحوي ل أي‬


‫أن القائم ة ُ‬
‫مرة أخرى‪ ،‬ن رى َّ‬

‫نوع قابل للتكرار (‪ )iterable‬إلى صف‪ ،‬بما في ذلك السالسل النصية‪:‬‬

‫))'‪print(tuple('Sammy‬‬

‫▲‬ ‫|‬ ‫‪122‬‬


‫البرمجة بلغة بايثون‬ ‫أنواع البيانات والتحويل بينها‬

‫المخرجات‪:‬‬

‫)'‪('S', 'a', 'm', 'm', 'y‬‬

‫لمَّ ا ك ان باإلمك ان الم رور (‪ )iterate‬على مح ارف السالس ل النص ية‪ ،‬فيمكنن ا تحويله ا إلى‬

‫صفوف باستخدام التابع )(‪ .tuple‬أمَّ ا أنواع البيانات غير القابلة للتك رار‪ ،‬مث ل األع داد الص حيحة‬

‫فستطلِق عملية تحويلها خطًأ‪:‬‬


‫ُ‬ ‫واألعداد العشرية‪،‬‬

‫))‪print(tuple(5000‬‬

‫والناتج سيكون‪:‬‬

‫‪TypeError: 'int' object is not iterable‬‬

‫في حين أن ه من الممكن تحوي ل ع دد ص حيح إلى سلس لة نص َّية‪ ،‬ومن ثم تحوي ل السلس لة‬

‫النص ية إلى ص ف‪ ،‬كم ا في ))‪ ،tuple(str(5000‬فمن األفض ل تجنب مث ل ه ذه التعليم ات‬

‫َّ‬
‫المعقدة‪.‬‬ ‫البرمجية‬

‫التحويل إلى قوائم‬

‫يمكن أن يك ون تحوي ل القيم‪ ،‬وخاص ة الص فوف‪ ،‬إلى ق وائم مفي ًدا عن دما تحت اج إلى نس خة‬

‫قابلة للتغيير من تلك القيم‪.‬‬

‫ألن ص ياغة الق وائم‬


‫سنس تخدم الت ابع )(‪ list‬لتحوي ل الص ف الت الي إلى قائم ة‪ .‬ونظ رً ا َّ‬

‫تس تخدم األق واس‪ ،‬تأك د من تض مين أق واس الت ابع )(‪ ،list‬وك ذلك األق واس الخاص ة‬

‫بالدالة )(‪:print‬‬

‫)))'‪print(list(('blue coral', 'staghorn coral', 'pillar coral‬‬

‫▲‬ ‫|‬ ‫‪123‬‬


‫البرمجة بلغة بايثون‬ ‫أنواع البيانات والتحويل بينها‬

‫المخرجات هي‪:‬‬

‫]'‪['blue coral', 'staghorn coral', 'pillar coral‬‬

‫ُأ‬ ‫تش ير األق واس المعقوف ة [] إلى َّ‬


‫أنه ق د رجعَ ت قائم ة من الص ف األص لي ال ذي مُ ِّرر ع بر‬

‫الدالة )(‪.list‬‬

‫لجعل الشيفرة سهلة القراءة‪ ،‬يمكننا إزالة أحد أزواج األقواس باستخدام متغيِّ ر‪:‬‬

‫)'‪coral = ('blue coral', 'staghorn coral', 'pillar coral‬‬

‫)‪list(coral‬‬

‫إن طبعنا )‪ ،list(coral‬فسنتلقى المخرجات نفسها الموجودة أعاله‪.‬‬

‫تمامً ا مثل الصفوف‪ ،‬يمكن تحويل السالسل النصية إلى قوائم‪:‬‬

‫))'‪print(list('shark‬‬

‫الناتج‪:‬‬

‫]'‪['s', 'h', 'a', 'r', 'k‬‬

‫ِّ‬
‫يوفر لنا نسخة قابلة للتغيير من القيمة األصلية‪.‬‬ ‫ُح ِّو َلت هنا السلسلة ‪ shark‬إلى قائمة‪ ،‬وهذا‬

‫‪ .9‬خالصة الفصل‬
‫في هذه المرحلة‪ ،‬يُ ف ترض أن يك ون ل ديك فهم جي د لبعض أن واع البيان ات الرئيس ية المتاح ة‬

‫طبيعيا من حياتك كمبرمج للغة بايثون‪.‬‬


‫ً‬ ‫جزءا‬
‫ً‬ ‫في بايثون‪ .‬أنواع البيانات هذه ستصبح‬

‫كيفية تحويل العديد من أنواع البيانات األص لية المهمَّ ة إلى‬


‫َّ‬ ‫ً‬
‫أيضا في هذا الفصل‬ ‫لقد وضحنا‬

‫أنواع بيانات أخرى‪ ،‬وذلك باستخدام التوابع المُ ضمّ نة‪ .‬يوفر تحويل أنواع البيان ات في ب ايثون ل ك‬

‫▲‬ ‫|‬ ‫‪124‬‬


‫البرمجة بلغة بايثون‬ ‫أنواع البيانات والتحويل بينها‬

‫ً‬
‫إضافية في مشاريعك البرمجية‪ .‬يمكنك التعرف على المزيد من التفاص يل عن ه ذه األن واع‬ ‫ً‬
‫مرونة‬

‫وطرائق التحويل بينها في موسوعة حسوب‪.‬‬

‫▲‬ ‫|‬ ‫‪125‬‬


‫‪7‬‬
‫السالسل النصية‬
‫والتعامل معها‬

‫▲‬ ‫|‬ ‫‪126‬‬


‫البرمجة بلغة بايثون‬ ‫السالسل النصية والتعامل معها‬

‫«السلسلة النصية» (‪ )string‬هي مجموعة من المحارف (أي األحرف واألرقام والرم وز) ال تي‬

‫إمَّ ا أن تك ون قيم ة ثابت ة أو قيم ة لمتغ ير‪ .‬وه ذه السالس ل النص ية مُ ش َّكلة من مح ارف يونيك ود‬

‫وألن النص ه و ش ٌ‬
‫كل ش ائعٌ من أش كال البيان ات ال ذي‬ ‫َّ‬ ‫(‪ )Unicode‬وال تي ال يمكن تغي ير م دلولها‪.‬‬

‫ً‬
‫أساسية في البرمج ة‪ .‬سيس تعرض‬ ‫مثل ُل ً‬
‫بنة‬ ‫وت ِّ‬
‫فإن السالسل النصية مهمة ج ًدا ُ‬
‫َّ‬ ‫يوميا‪ ،‬لذا‬
‫ً‬ ‫نستعمله‬

‫كيفية إنش اء وطباع ة السالس ة النص ية‪ ،‬وكيفي ة جمعه ا م ع بعض ها وتكراره ا‪ ،‬وآلي ة‬
‫َّ‬ ‫ه ذا الفص ل‬

‫تخزين السالسل النصية في متغيرات‪.‬‬

‫‪ .1‬إنشاء وطباعة السالسل النصية‬


‫تتواجد السالسل النصية إمَّ ا داخل عالمات اقتباس فردية ' أو عالمات اقتباس مزدوجة "‪،‬‬

‫ل ذا إلنش اء سلس لة نص ية‪ ،‬ك ل م ا علين ا فعل ه ه و وض ع مجموع ة من المح ارف بين أح د ن وعَ ي‬

‫َ‬
‫السابقين‪:‬‬ ‫عالمات االقتباس‬

‫'‪.‬هذه سلسلة نصية ضمن عالمتي اقتباس مفردتين'‬


‫"هذه سلسلة نصية ضمن عالمتي اقتباس مزدوجتين"‬

‫يمكن ك االختي ار بين الن وعَ ين الس َ‬


‫ابقين‪ ،‬لكن أيًّ ا ك ان اختي ارك‪ ،‬فعلي ك أن تحاف ظ على‬

‫استخدامك له في كام ل برنامج ك‪ .‬يمكن ك طباع ة السالس ل النص ية إلى الشاش ة باس تدعاء الدال ة‬

‫)(‪ print‬بكل بساطة‪:‬‬

‫)"‪print("Let's print out this string.‬‬


‫‪Let's print out this string.‬‬

‫كيفية التعام ل‬
‫َّ‬ ‫فهمت كيفي ة تهيئ ة السالس ل النص ية في ب ايثون‪ ،‬لنل ق نظ ً‬
‫رة اآلن إلى‬ ‫َ‬ ‫بعد أن‬
‫ِ‬

‫مع السالسل النصية في برامجك وتعديلها‪.‬‬

‫▲‬ ‫|‬ ‫‪127‬‬


‫البرمجة بلغة بايثون‬ ‫السالسل النصية والتعامل معها‬

‫‪ .2‬آلية فهرسة السالسل النصية‬


‫إن ك ل مح رف في السلس لة‬
‫وكما في نوع البيانات ‪ list‬ال ذي في ه عناص ر مرتبط ة بأرق ام‪ ،‬ف َّ‬

‫دءا من الفه رس ‪ .0‬فللسلس لة النص ية !‪ Sammy Shark‬س تكون‬


‫معين‪ ،‬ب ً‬
‫ّ‬ ‫النص ية يرتب ط بفه رس‬

‫الفهارس والمحارف المرتبطة بها كاآلتي‪:‬‬

‫‪s‬‬ ‫‪a‬‬ ‫‪m‬‬ ‫‪m‬‬ ‫‪y‬‬ ‫‪s‬‬ ‫‪h‬‬ ‫‪a‬‬ ‫‪r‬‬ ‫‪k‬‬ ‫!‬

‫‪0‬‬ ‫‪1‬‬ ‫‪2‬‬ ‫‪3‬‬ ‫‪4‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪7‬‬ ‫‪8‬‬ ‫‪9‬‬ ‫‪10‬‬ ‫‪11‬‬

‫وكم ا الحظت‪ ،‬س يرتبط المح رف ‪ S‬ب الفهرس ‪ ،0‬وس تنتهي السلس لة النص ية ب الفهرس ‪ 11‬م ع‬

‫رس خ ٌ‬
‫اص ب ه‪ ،‬وفي مثالن ا‬ ‫أن الف راغ بين كلمتَي ‪ Sammy‬و ‪ Shark‬ل ه فه ٌ‬ ‫ً‬
‫أيض ا َّ‬ ‫الرم ز !‪ .‬الح ظ‬

‫ً‬
‫أيض ا‪ ،‬وأيَّ ة رم وز أو عالم ات ت رقيم‬ ‫رس خ ٌ‬
‫اص به ا‬ ‫سيكون له الفهرس ‪ .5‬عالم ة التعجب ! له ا فه ٌ‬

‫أن المح ارف في ب ايثون له ا فه رس‬


‫بفهرس مخص ص له ا‪ .‬حقيق ة َّ‬
‫ٍ‬ ‫أخرى مثل *‪ ?;.&$#‬سترتبط‬

‫أن بإمكاننا الوصول إلى السالسل النص ية وتع ديلها كم ا نفع ل م ع أن واع البيان ات‬
‫خاص بها ستعني َّ‬

‫المتسلسلة األخرى‪.‬‬

‫ا‪ .‬الوصول إلى المحارف بفهارس موجبة‬

‫يمكنن ا الحص ول على مح رف من سلس لة نص ية باإلش ارة إلي ه ع بر فهرس ه‪ .‬يمكنن ا فع ل ذل ك‬

‫لة نص ً‬
‫ية ونطب ع‬ ‫عرف في المث ال اآلتي سلس ً‬
‫بوض ع رقم الفه رس بين قوس ين معق وفين []‪ .‬س ُن ِّ‬

‫المحرف المرتبط بالفهرس المذكور بين قوسين‪:‬‬

‫"!‪ss = "Sammy Shark‬‬


‫)]‪print(ss[4‬‬

‫▲‬ ‫|‬ ‫‪128‬‬


‫البرمجة بلغة بايثون‬ ‫السالسل النصية والتعامل معها‬

‫الناتج‪:‬‬

‫‪y‬‬

‫معي ٍن في سلس لةٍ نص يةٍ ‪ ،‬فس ُتعيد ب ايثون المح رف الموج ود في ذاك‬
‫ّ‬ ‫عندما ُنشير إلى فه ٍ‬
‫رس‬

‫ية‬ ‫لة النص‬ ‫ع في السلس‬ ‫رس الراب‬ ‫و ًدا في الفه‬ ‫رف ‪ y‬موج‬ ‫ان المح‬ ‫ع‪ ،‬ولمَّ ا ك‬ ‫الموض‬

‫"!‪ "Sammy Shark‬فعندما طبعنا ]‪ ss[4‬فظهر الحرف ‪.y‬‬

‫معين ة ض من‬
‫ّ‬ ‫خالص ة م ا س بق‪ ،‬أرق ام الفه ارس ستس مح لن ا بالوص ول إلى مح ارف‬

‫سلسلة نصية‪.‬‬

‫ب‪ .‬الوصول إلى المحارف بفهارس سالبة‬

‫ً‬
‫انطالق ا من نهايته ا‪ ،‬فعندئ ذٍ‬ ‫لة طويل ٌة وأردن ا تحدي د أح د محارفه ا لكن‬
‫إذا ك انت ل ديك سلس ٌ‬

‫دءا من الفه رس ‪ .-1‬ل و أردن ا أن نس تخدم الفه ارس‬


‫نستطيع اس تخدام األرق ام الس البة للفه ارس‪ ،‬ب ً‬

‫السالبة مع السلسلة النصية !‪ ،Sammy Shark‬فستبدو كما يلي‪:‬‬

‫‪s‬‬ ‫‪a‬‬ ‫‪m‬‬ ‫‪m‬‬ ‫‪y‬‬ ‫‪s‬‬ ‫‪h‬‬ ‫‪a‬‬ ‫‪r‬‬ ‫‪k‬‬ ‫!‬

‫‪-12‬‬ ‫‪-11‬‬ ‫‪-10‬‬ ‫‪-9‬‬ ‫‪-8‬‬ ‫‪-7‬‬ ‫‪-6‬‬ ‫‪-5‬‬ ‫‪-4‬‬ ‫‪-3‬‬ ‫‪-2‬‬ ‫‪-1‬‬

‫يمكنن ا أن نطب ع المح رف ‪ r‬في السلس لة الس ابقة في ح ال اس تخدمنا الفه ارس الس البة‬

‫باإلشارة إلى المحرف الموجود في الفهرس ‪ -3‬كما يلي‪:‬‬

‫)]‪print(ss[-3‬‬

‫وج دنا َّ‬


‫أنه يمكنن ا االس تفادة من الفه ارس الس البة ل و أردن ا الوص ول إلى مح رف في آخ ر‬

‫سلسلة نصية طويلة‪.‬‬

‫▲‬ ‫|‬ ‫‪129‬‬


‫البرمجة بلغة بايثون‬ ‫السالسل النصية والتعامل معها‬

‫‪ .3‬تقسيم السالسل النصية‬


‫يمكنن ا أن نحص ل على مج ال من المح ارف من سلس لة نص ية‪ ،‬فلنق ل مثاًل أنن ا نري د أن نطب ع‬

‫الكلمة ‪ Shark‬فقط‪ ،‬يمكننا فعل ذلك بإنشائنا «لقس م» من السلس لة النص ية‪ ،‬وال ذي ه و سلس ٌ‬
‫لة من‬

‫المحارف الموجودة ضمن السلسلة األصلية‪ .‬فاألقسام تسمح لن ا بالوص ول إلى ع ِّدة مح ارف دفع ًة‬

‫واحدة باستعمال مجال من أرقام الفهارس مفصولة فيما بينها بنقطتين رأسيتين [‪:]x:y‬‬

‫)]‪print(ss[6:11‬‬

‫الناتج‪:‬‬

‫‪Shark‬‬

‫عن د إنش ائنا لقس م مث ل [‪ ]6:11‬فس ُي ِّ‬


‫مثل أوَّ ل رقم مك ان ب دء القس م (متض منًا المح رف‬

‫الموج ود عن د ذاك الفه رس)‪ ،‬وال رقم الث اني ه و مك ان نهاي ة القس م (دون تض مين ذاك المح رف)‪،‬‬

‫وهذا هو السبب وراء استخدمنا لرقم فهرس يقع بعد نهاي ة القس م ال ذي نري د اقتطاع ه في المث ال‬

‫ية فرعي ًة» (‪ )substring‬عن دما ُن ِّ‬


‫قس م السالس ل النص ية‪ ،‬وال تي‬ ‫لة نص ً‬
‫نش ئ « سلس ً‬
‫الس ابق‪ .‬نحن ُن ِ‬

‫ٌ‬
‫ودة ض من سلس لةٍ أخ رى‪ .‬وعن دما نس تخدم التعب ير ]‪ ss[6:11‬فنحن نس تدعي‬ ‫هي سلس ٌ‬
‫لة موج‬

‫السلس لة النص ية ‪ Shark‬ال تي تتواج د ض من السلس لة النص ية !‪ .Sammy Shark‬إذا أردن ا تض مين‬

‫نش ئه‪ ،‬فيمكن أاّل نض ع أح د أرق ام الفه ارس في‬ ‫نهاي ة السلس لة (أو ب دايتها) في القس م ال ذي ُ‬
‫ست ِ‬

‫]‪ .string[n:n‬فمثاًل ‪ ،‬نس تطيع أن نطب ع أوَّ ل كلم ة من السلس لة ‪ – ss‬أي ‪ – Sammy‬بكتاب ة‬

‫ما يلي‪:‬‬

‫)]‪print(ss[:5‬‬

‫▲‬ ‫|‬ ‫‪130‬‬


‫البرمجة بلغة بايثون‬ ‫السالسل النصية والتعامل معها‬

‫فعلنا ذلك بحذف رقم الفه رس قب ل النقط تين الرأس يتين‪ ،‬ووض عنا رقم فه رس النهاي ة فق ط‪،‬‬

‫الفرعية‪ .‬لطباع ة منتص ف السلس لة النص ية‬


‫َّ‬ ‫ال ذي يُ ش ير إلى مك ان إيق اف اقتط اع السلس لة النص ية‬

‫إلى آخرها‪ ،‬فسنضع فهرس البداية فقط قبل النقطتين الرأسيتين‪ ،‬كما يلي‪:‬‬

‫)]‪print(ss[7:‬‬

‫الناتج‪:‬‬

‫!‪hark‬‬

‫إن‬
‫بكتاب ة فه رس البداي ة فق ط قب ل النقط تين الرأس يتين وت رك تحدي د الفه رس الث اني‪ ،‬ف َّ‬

‫ً‬
‫أيض ا اس تخدام‬ ‫السلسلة الفرعية ستبدأ من الفهرس األول إلى نهاية السلسلة النص ية كله ا‪ .‬يمكن ك‬

‫ً‬
‫سابقا‪ ،‬تبدأ أرقام الفهارس السلبية من الرقم‬ ‫الفهارس السالبة في تقسيم سلسلة نصية‪ ،‬فكما ذكرنا‬

‫‪ ،-1‬ويستمر العد إلى أن نصل إلى بداية السلسلة النصية‪ .‬وعند استخدام الفه ارس الس البة فس نبدأ‬

‫ألنه يقع أواًل في السلسلة‪ .‬لنستخدم فهرس ين ذوي رقمين س البين القتط اع ج زء‬
‫من الرقم األصغر َّ‬

‫من السلسلة النصية ‪:ss‬‬

‫)]‪print(ss[-4:-1‬‬

‫الناتج‪:‬‬

‫‪ark‬‬

‫ألن الحرف ‪ a‬يق ع‬


‫السلسلة النصية "‪ "ark‬مأخوذة من السلسلة النصية "!‪َّ "Sammy Shark‬‬

‫ً‬
‫مباشرة‪.‬‬ ‫في الموضع ‪ -4‬والحرف ‪ k‬يقع قبل الفهرس ‪-1‬‬

‫يمكن تحدي د الخط وة عن د تقس يم السالس ل النص ية وذل ك بتمري ر معام ل ث الث إض ً‬
‫افة إلى‬

‫فهرس ي البداي ة والنهاي ة‪ ،‬وه و الخط وة‪ ،‬ال تي ُتش ير إلى ع دد المح ارف ال تي يجب تجاوزه ا بع د‬
‫َ‬

‫▲‬ ‫|‬ ‫‪131‬‬


‫البرمجة بلغة بايثون‬ ‫السالسل النصية والتعامل معها‬

‫الحص ول على المح رف من السلس لة النص ية‪ .‬لم ُنح ِّدد إلى اآلن الخط وة في أمثلتن ا‪ ،‬إال َّ‬
‫أن قيمت ه‬

‫االفتراضية هي ‪ ،1‬لذا سنحص ل على ك ل مح رف يق ع بين الفهرس ين‪ .‬لننظ ر م ً‬


‫رة أخ رى إلى المث ال‬

‫السابق الذي يطبع السلسلة النصية الفرعية "‪:"Shark‬‬

‫)]‪print(ss[6:11‬‬ ‫‪# Shark‬‬

‫سنحصل على نفس النتائج بتضمين معامل ثالث هو الخطوة وقيمته ‪:1‬‬

‫)]‪print(ss[6:11:1‬‬ ‫‪# Shark‬‬

‫ستض ِّمن جمي ع المح ارف بين فهرس ين‪ ،‬وإذا‬ ‫إذا‪ ،‬إذا ك انت الخط وة ‪ 1‬فه ذا يع ني َّ‬
‫أن ب ايثون ُ‬ ‫ً‬

‫أن بعض‬ ‫ً‬


‫اوية للواح د‪ .‬أم ا ل و زدن ا الخط وة‪ ،‬فس نرى َّ‬ ‫ذفت الخط وة فس تع ُّدها ب ايثون مس‬
‫َ‬ ‫ح‬

‫المحارف ستهمل‪:‬‬

‫)]‪print(ss[0:12:2‬‬ ‫‪# SmySak‬‬

‫تحديد الخطوة بقيمة ‪ 2‬كما في ]‪ ss[0:12:2‬سيؤدي إلى تجاوز حرف بين كل حرفين‪ِ ،‬‬
‫ألق‬

‫ً‬
‫نظرة على المحارف المكتوبة بخط عريض‪:‬‬

‫!‪Sammy Shark‬‬

‫أيض ا عن دما ك انت الخط وة ‪ .2‬إذا وض عنا‬ ‫أن الف راغ الموج ود في الفه رس ‪ 5‬ق د همِ ل‬
‫ً‬ ‫ُأ‬
‫الح ظ َّ‬

‫ً‬
‫قيمة أكبر للخطوة‪ ،‬فسنحصل على سلسلةٍ نصيةٍ فرعيةٍ أصغر بكثير‪:‬‬

‫)]‪print(ss[0:12:4‬‬ ‫‪# Sya‬‬

‫حذف الفهرسين وترك النقط تين الرأس يتين س يؤدي إلى إبق اء كام ل السلس لة ض من المج ال‪،‬‬

‫ً‬
‫إضافة إلى ذل ك‪،‬‬ ‫سي ِّ‬
‫حدد عدد المحارف التي سيتم تخطيها‪.‬‬ ‫لكن إضافة معامل ثالث وهو الخطوة ُ‬

‫ترتيب معك وس إذا‬ ‫ِّ‬


‫يمكن ك من كتاب ة السلس لة النص ية ب‬ ‫يمكن ك تحدي د رقم س الب كخط وة‪ ،‬مم ا‬
‫ٍ‬

‫▲‬ ‫|‬ ‫‪132‬‬


‫البرمجة بلغة بايثون‬ ‫السالسل النصية والتعامل معها‬

‫َ‬
‫استعملت القيمة ‪:-1‬‬

‫)]‪print(ss[::-1‬‬

‫الناتج‪:‬‬

‫‪!krahS ymmaS‬‬

‫ً‬
‫مرة أخرى لكن إذا كانت الخطوة ‪:-2‬‬ ‫ِّ‬
‫لنجرب ذلك‬

‫)]‪print(ss[::-2‬‬

‫الناتج‪:‬‬

‫‪!rh ma‬‬

‫في المث ال الس ابق (]‪ ،)ss[::-2‬س نتعامل م ع كام ل السلس لة النص ية لع دم وج ود أرق ام‬

‫لفهارس البداية والنهاية‪ ،‬وسيتم قلب اتجاه السلسلة النصية الستخدامنا لخطوةٍ س البة‪ .‬باإلض افة‬

‫بترتيب معكوس‪:‬‬
‫ٍ‬ ‫أن الخطوة ‪ -2‬ستؤدي إلى تخطي حرف بين كل حرفين‬
‫إلى َّ‬

‫‪!krahS[whitespace]ymmaS‬‬

‫طبع الفراغ في المثال السابق‪.‬‬


‫سي َ‬
‫ُ‬

‫أن تحدي د المعام ل الث الث عن د تقس يم السالس ل النص ية س يؤدي إلى تحدي د‬
‫م ا رأين اه ه و َّ‬

‫الخط وة ال تي ُت ِّ‬
‫مثل ع دد المح ارف ال تي س يتم تخطيه ا عن د الحص ول على السلس لة الفرعي ة من‬

‫السلسلة األصلية‪.‬‬

‫▲‬ ‫|‬ ‫‪133‬‬


‫البرمجة بلغة بايثون‬ ‫السالسل النصية والتعامل معها‬

‫‪ .4‬جمع السالسل النصية‬


‫ً‬
‫بعض ا إلنش اء‬ ‫عملي ة الجم ع (‪ )concatenation‬تع ني إض افة سلس لتين نص يتين إلى بعض هما‬

‫أن العام ل ‪+‬‬


‫سلس لة نص ية جدي دة‪ .‬نس تخدم المعام ل ‪ +‬لجم ع السالس ل النص ية؛ أب ِق في ذهن ك َّ‬

‫يع ني عملي ة الجم ع عن د التعام ل م ع األع داد‪ ،‬أم ا عن دما نس تخدمه م ع السالس ل النص ية فيع ني‬

‫إض افتها إلى بعض ها‪ .‬لنجم ع السلس تين النص يتين "‪ "Sammy‬و "‪ "Shark‬م ع بعض ها ثم نطبعهم ا‬

‫باستخدام الدالة )(‪:print‬‬

‫)"‪print("Sammy" + "Shark‬‬
‫‪# SammyShark‬‬

‫َ‬
‫أردت وض ع ف راغ بين السلس لتين النص يتين‪ ،‬فيمكن ك بك ل بس اطة وض عه عن د نهاي ة‬ ‫إذا‬

‫السلسلة النصية األولى‪ ،‬أي بعد الكلمة "‪:"Sammy‬‬

‫)"‪print("Sammy " + "Shark‬‬


‫‪# Sammy Shark‬‬

‫َ‬
‫مختلفين من البيان ات‪ ،‬فلن نتمكن من‬ ‫لكن اح رص على ع دم اس تعمال العام ل ‪ +‬بين ن وعَ ين‬

‫جمع السالسل النصية واألرقام مع بعضها‪ ،‬فلو حاولنا مثاًل أن نكتب‪:‬‬

‫)‪print("Sammy" + 27‬‬

‫فسنحصل على رسالة الخطأ اآلتية‪:‬‬

‫‪TypeError: Can't convert 'int' object to str implicitly‬‬

‫أمَّ ا إذا أردن ا أن ُن ِ‬


‫نش ئ السلس لة النص ية "‪ "Sammy27‬فعلين ا حينه ا وض ع ال رقم ‪ 27‬بين‬

‫ً‬
‫حيحا‪ .‬سنس تفيد من تحوي ل‬ ‫لة نص ً‬
‫ية وليس ت ع د ًدا ص‬ ‫عالم َتي اقتباس ("‪ )"27‬مما يجعل ه سلس ً‬

‫األعداد إلى سالسل نصية عندما نتعامل مع أرق ام الهوات ف على س بيل المث ال‪َّ ،‬‬
‫ألنن ا لن نحت اج إلى‬

‫▲‬ ‫|‬ ‫‪134‬‬


‫البرمجة بلغة بايثون‬ ‫السالسل النصية والتعامل معها‬

‫إجراء عملية حسابية على رمز الدولة ورمز المنطق ة في أرق ام الهوات ف‪ ،‬إال َّ‬
‫أنن ا نري دهما أن يظه را‬

‫لة نص ً‬
‫ية جدي ً‬
‫دة ال تي يمكنن ا‬ ‫نش ئ سلس ً‬
‫متتابعَ ين‪ .‬عندما نجمع سلسلتين نص يتين أو أك ثر فنحن ُن ِ‬

‫استخدامها في برنامجنا‪.‬‬

‫‪ .5‬تكرار السالسل النصية‬


‫هنال ك أوق ٌ‬
‫ات نحت اج فيه ا إلى اس تخدام ب ايثون ألتمت ة المه ام‪ ،‬وإح دى األم ور ال تي يمكنن ا‬

‫أتمتتها هي تكرار سلسلة نصية ِّ‬


‫لعدة مرات‪ .‬إذ نستطيع فعل ذلك عبر العامل *‪ ،‬وكم ا ه و األم ر م ع‬

‫فإن العام ل * ل ه اس تخدامٌ مختل ف عن دما نتعام ل م ع أرق ام‪ ،‬حيث يُ ِّ‬
‫مثل عملي ة الض رب‪.‬‬ ‫َّ‬ ‫العامل ‪+‬‬

‫فإن العامل * هو معامل التكرار‪ ،‬فوظيفت ه هي تك رار‬


‫َّ‬ ‫ورقم‬
‫ٍ‬ ‫أمَّ ا عندما نستخدمه بين سلسلةٍ نصيةٍ‬

‫سلس لة نص ية ألي ع دد م رات تش اء‪ .‬لنح اول طباع ة السلس لة النص ية "‪ "Sammy‬تس ع م رات دون‬

‫تكرارها يدويً ا‪ ،‬وذلك عبر العامل *‪:‬‬

‫)‪print("Sammy" * 9‬‬

‫المخرجات‪:‬‬

‫‪SammySammySammySammySammySammySammySammySammy‬‬

‫ألي عددٍ نشاء من المرات‪.‬‬


‫يمكننا بهذه الطريقة تكرار السلسلة النصية ِّ‬

‫‪ .6‬تخزين السالسل النصية في متغيرات‬


‫أن المتغيِّ رات هي «رموز» يمكننا استعمالها لتخزين البيان ات في‬
‫وجدنا من فصل المتغيِّ رات َّ‬

‫ٌ‬
‫ارغ يمكن ك مل ؤه بالبيان ات أو القيم‪.‬‬ ‫ٌ‬
‫ندوق ف‬ ‫برن امج‪ .‬أي يمكن ك تخي ل المتغيِّ رات على َّ‬
‫أنه ا ص‬

‫ٌ‬
‫نوع من أنواع البيان ات‪ ،‬ل ذا يمكنن ا اس تعمالها لملء المتغ يرات‪ .‬التص ريح عن‬ ‫السالسل النصية هي‬

‫▲‬ ‫|‬ ‫‪135‬‬


‫البرمجة بلغة بايثون‬ ‫السالسل النصية والتعامل معها‬

‫سيس ِّهل علين ا التعام ل معه ا في برامجن ا‪ .‬لتخ زين سلس لة نص ية‬
‫متغ يرات تح وي سالس ل نص ية ُ‬

‫داخل متغير‪ ،‬فكل ما علينا فعله هو إسنادها إليه‪ .‬س ُن ِّ‬


‫صرح في المثال اآلتي عن المتغير ‪:my_str‬‬

‫"‪my_str = "Sammy likes declaring strings.‬‬

‫أص بح المتغ ير ‪ my_str‬اآلن مُ ش يرًا إلى سلس لةٍ نص يةٍ ‪ ،‬وال تي أمس ى بمق دورنا طباعته ا‬

‫كما يلي‪:‬‬

‫)‪print(my_str‬‬

‫وسنحصل على الناتج اآلتي‪:‬‬

‫‪Sammy likes declaring strings.‬‬

‫استخدام المتغيرات الحتواء قيم السالسل النصية سيساعدنا في االستغناء عن إعادة كتابة‬

‫السلسلة النصية في كل مرة نحتاج استخدامها‪ ،‬مما يُ ِّ‬


‫بس ط تعاملن ا معه ا وإجراءن ا للعملي ات عليه ا‬

‫في برامجنا‪.‬‬

‫‪ .7‬دوال السالسل النصية‬


‫ل دى ب ايثون ع َّدة دوال مبني ة فيه ا للتعام ل م ع السالس ل النص ية‪ .‬تس مح ه ذه ال دوال لن ا‬

‫بتع ديل وإج راء عملي ات على السالس ل النص ية بس هولة‪ .‬يمكن ك أن تتخي ل ال دوال على َّ‬
‫أنه ا‬

‫«أفع ال» يمكنن ا تنفي ذها على عناص ر موج ودة في الش يفرة‪ .‬ال دوال المبني ة في اللغ ة هي ال دوال‬

‫المُ عرَّ ف ة داخ ل لغ ة ب ايثون وهي ج اهزة مباش ً‬


‫رة لالس تخدام‪ .‬سنش رح في ه ذا القس م مختل ف‬

‫الدوال التي نستطيع استخدامها للتعامل مع السالسل النصية في بايثون ‪.3‬‬

‫▲‬ ‫|‬ ‫‪136‬‬


‫البرمجة بلغة بايثون‬ ‫السالسل النصية والتعامل معها‬

‫ا‪ .‬جعل السالسل النصية بأحرف كبيرة أو صغيرة‬

‫الدالتان )(‪ str.upper‬و )(‪ُ str.lower‬‬


‫ستعيدان السلسلة النصية بعد تحويل حال ة جمي ع‬

‫لية إلى األح رف الكب يرة أو الص غيرة (على الت والي وب الترتيب)‪ .‬ولع دم ق درتنا على‬
‫أحرفه ا األص َّ‬

‫لة نص ٌ‬
‫ية جدي ٌ‬
‫دة‪ .‬لن ُتع َّدل أيَّ ة مح ارف غ ير‬ ‫تع ديل السلس لة النص ية بع د إنش ائها‪ ،‬فس ُتعاد سلس ٌ‬

‫التينية في السلسلة النصية األصلية وستبقى على حالها‪ .‬لنح ِّول السلس لة النص ية ‪Sammy Shark‬‬

‫أحرف كبيرةٍ‪:‬‬
‫ٍ‬ ‫إلى‬

‫"‪ss = "Sammy Shark‬‬


‫))(‪print(ss.upper‬‬

‫الناتج‪:‬‬

‫‪SAMMY SHARK‬‬

‫أحرف صغيرة‪:‬‬
‫ٍ‬ ‫ِّ‬
‫لنحولها اآلن إلى‬

‫))(‪print(ss.lower‬‬

‫وسينتج‪:‬‬

‫‪sammy shark‬‬

‫ُّ‬
‫التحقق من مس اواة سلس لتين‬ ‫ستس ِّهل ال دالتان )(‪ str.upper‬و )(‪ str.lower‬عملي ة‬
‫ُ‬

‫نصيتين لبعضهما أو لموازنتهما وذلك عبر توحيد حالة األحرف‪ .‬فلو كتب المستخدم اسمه ب أحرف‬

‫سجاًل في قاعدة البيانات بموازنته بعد تحويل حالة أحرفه‪.‬‬


‫صغيرة فسنستطيع أن نتأكد إن كان مُ َّ‬

‫ب‪ .‬الدوال المنطقية‬

‫عدة دوال تتحقق من القيم المنطقية (‪ .)Boolean‬هذه الدوال مفي ٌ‬


‫دة عن د‬ ‫تتوفر في بايثون ِّ‬

‫▲‬ ‫|‬ ‫‪137‬‬


‫البرمجة بلغة بايثون‬ ‫السالسل النصية والتعامل معها‬

‫إنشائنا للنماذج التي يجب على المستخدمين مألها؛ فمثاًل ‪ ،‬إذا س ألنا المس تخدم عن الرم ز البري دي‬

‫وأردن ا أن نقب ل السالس ل النص ية ال تي تحت وي أرقامً ا فق ط‪ ،‬أو عن دما نس أله عن اس مه فس نقبل‬

‫ً‬
‫منطقية‪:‬‬ ‫ً‬
‫حروفا فقط‪ .‬هنالك عد ٌد من الدوال التي ُتعيد قيمً ا‬ ‫ً‬
‫نصية تحوي‬ ‫ً‬
‫سلسلة‬

‫َّ‬
‫تتحقق إذا احت وت السلس لة النص ية على أرق ام وأح رف فق ط (دون‬ ‫)(‪:str.isalnum‬‬ ‫•‬
‫َّ‬
‫تحقق ذلك‪.‬‬ ‫رموز)‪ ،‬أي تعيد ‪ true‬إن‬

‫َّ‬
‫تتحقق إذا احت وت السلس لة النص ية على أح رف فق ط (دون أرق ام‬ ‫)(‪:str.isalpha‬‬ ‫•‬
‫أو رموز)‪.‬‬

‫َّ‬
‫تتحقق إذا كانت جميع أحرف السلسلة النصية صغيرة‪.‬‬ ‫)(‪:str.islower‬‬ ‫•‬

‫َّ‬
‫تتحقق إذا احتوت السلسلة النصية على أرقام فقط‪.‬‬ ‫)(‪:str.isnumeric‬‬ ‫•‬

‫َّ‬
‫تتحقق إذا لم تحتوي السلسلة النصية إال على الفراغات‪.‬‬ ‫)(‪:str.isspace‬‬ ‫•‬

‫أنه ا عن وان‬ ‫َّ‬


‫تتحقق إذا ك انت حال ة أح رف السلس لة النص ية كم ا ل و َّ‬ ‫)(‪:str.istitle‬‬ ‫•‬
‫أن أوّ ل حرف من كل كلمة كبير‪ ،‬والبقية صغيرة)‪.‬‬
‫باللغة اإلنجليزية (أي َّ‬

‫َّ‬
‫تتحقق إذا كانت جميع أحرف السلسلة النصية كبيرة‪.‬‬ ‫)(‪:str.isupper‬‬ ‫•‬

‫عمليا‪:‬‬
‫ً‬ ‫لنجرب استعمال بعضها‬

‫"‪number = "5‬‬
‫"‪letters = "abcdef‬‬

‫))(‪print(number.isnumeric‬‬
‫))(‪print(letters.isnumeric‬‬

‫الناتج‪:‬‬

‫▲‬ ‫|‬ ‫‪138‬‬


‫البرمجة بلغة بايثون‬ ‫السالسل النصية والتعامل معها‬

‫‪True‬‬
‫‪False‬‬

‫اس تخدام الدال ة )(‪ str.isnumeric‬على السلس لة النص ية ‪ 5‬س ُيعيد القيم ة ‪ ،True‬بينم ا‬

‫وبشكل مماث ل‪ ،‬يمكنن ا معرف ة‬


‫ٍ‬ ‫سيعيد ‪.False‬‬
‫استخدام نفس الدالة على السلسلة النصية ‪ُ abcdef‬‬

‫إن كانت حالة األحرف في سلسلةٍ نصيةٍ كما ل و َّ‬


‫أنه ا عن وان‪ ،‬أو أنه ا كب يرة أو ص غيرة (ه ذه العملي ة‬

‫ً‬
‫بداية بعض السالسل النصية‪:‬‬ ‫تنطبق على اللغات المكتوبة باألحرف الالتينية)‪ .‬ل ُن ِ‬
‫نشئ‬

‫"‪movie = "2001: A SAMMY ODYSSEY‬‬


‫"‪book = "A Thousand Splendid Sharks‬‬
‫"‪poem = "sammy lived in a pretty how town‬‬

‫المنطقية لمعرفة الناتج (سنعرض كل دالتين وناتجهما تحتهما)‪:‬‬


‫َّ‬ ‫ِّ‬
‫لنجرب الدوال‬

‫))(‪print(movie.islower‬‬
‫))(‪print(movie.isupper‬‬

‫‪# False‬‬
‫‪# True‬‬

‫))(‪print(book.istitle‬‬
‫))(‪print(book.isupper‬‬

‫‪# True‬‬
‫‪# False‬‬

‫))(‪print(poem.istitle‬‬
‫))(‪print(poem.islower‬‬

‫‪# False‬‬
‫‪# True‬‬

‫▲‬ ‫|‬ ‫‪139‬‬


‫البرمجة بلغة بايثون‬ ‫السالسل النصية والتعامل معها‬

‫ستساعدنا معرفة إن كانت أحرف السلسلة النصية بحالة صغيرة أو كبيرة أو َّ‬
‫كأنها عنوان في‬

‫نيفا س ليمً ا‪ ،‬وت ِّ‬


‫وفر لن ا الفرص ة لتوحي د طريق ة تخ زين البيان ات ب التحقق من‬ ‫تص نيف البيان ات تص ً‬

‫ً‬
‫أيضا‬ ‫ٌ‬
‫مفيدة‬ ‫ً‬
‫وفقا لذلك‪ .‬الدوال المنطقية التي تعمل على السالسل النصية‬ ‫حالة أحرفها ثم تعديلها‬

‫معينة‪.‬‬
‫َّ‬ ‫ً‬
‫شروطا‬ ‫التحقق إن َّ‬
‫حق َقت مدخالت المستخدم‬ ‫ُّ‬ ‫عندما نريد‬

‫ج‪ .‬الدوال )(‪ join‬و )(‪ split‬و )(‪replace‬‬

‫ً‬
‫افية لتع ديل‬ ‫إمكانيات إض‬
‫ٍ‬ ‫ِّ‬
‫توفر الدوال )(‪ str.join‬و )(‪ str.split‬و )(‪str.replace‬‬

‫السالس ل النص ية في ب ايثون‪ .‬الدال ة )(‪ str.join‬تجم ع سلس لتين نص يتين م ع بعض هما‪ ،‬لكنَّه ا‬

‫ً‬
‫نصية‪:‬‬ ‫ً‬
‫سلسلة‬ ‫تفعل ذلك بتمرير إحداها إلى األخرى‪ .‬ل ُن ِ‬
‫نشئ‬

‫"‪balloon = "Sammy has a balloon.‬‬

‫لنستخدم اآلن الدالة )(‪ str.join‬إلضافة فراغات إلى تلك السلسلة النصية كاآلتي‪:‬‬

‫)‪" ".join(balloon‬‬

‫إذا طبعنا الناتج‪:‬‬

‫))‪print(" ".join(balloon‬‬

‫أن السلسلة النصية الجديدة هي السلسلة األولى لكن بين كل حرفين فراغ‪:‬‬
‫فسنجد َّ‬

‫‪S a m m y‬‬ ‫‪h a s‬‬ ‫‪a‬‬ ‫‪b a l l o o n .‬‬

‫ً‬
‫أيضا استخدام الدالة )(‪ str.join‬إلنشاء مقلوب سلسلة نصية‪:‬‬ ‫يمكننا‬

‫)))‪print("".join(reversed(balloon‬‬
‫‪.noollab a sah ymmaS‬‬

‫لم ن رغب في إض افة أيَّ ة سلس لة نص ية إلى أخ رى‪ ،‬ل ذا أبقين ا على السلس لة النص ية فارغ ًة دون‬

‫▲‬ ‫|‬ ‫‪140‬‬


‫البرمجة بلغة بايثون‬ ‫السالسل النصية والتعامل معها‬

‫ً‬
‫أيض ا لجم ع قائم ة (‪ )list‬من السالس ل النص ية‬ ‫محت وى داخله ا‪ .‬الدال ة )(‪ str.join‬مفي ٌ‬
‫دة‬

‫وإخراجها إلى سلسلةٍ وحيدة‪ .‬ل ُن ِ‬


‫نشئ سلسلة نصية يُ َ‬
‫فصل بين كلماتها بفاصلة من القائمة اآلتية‪:‬‬

‫))]"‪print(",".join(["sharks", "crustaceans", "plankton‬‬


‫‪sharks,crustaceans,plankton‬‬

‫أردت وضع فاصلة ثم فراغ بين القيم في المثال السابق‪ ،‬فيمكنك أن ُتعيد كتاب ة التعليم ة‬
‫َ‬ ‫إذا‬

‫البرمجية السابقة إلضافة فراغ بعد الفاصلة كما يلي‪:‬‬

‫)]"‪", ".join(["sharks", "crustaceans", "plankton‬‬

‫ً‬
‫أيض ا تجزئته ا‪ ،‬وذل ك ع بر‬ ‫ً‬
‫بعض ا‪ ،‬نس تطيع‬ ‫وكم ا نس تطيع جم ع السالس ل النص ية م ع بعض ها‬

‫الدالة )(‪:str.split‬‬

‫))(‪print(balloon.split‬‬
‫]'‪['Sammy', 'has', 'a', 'balloon.‬‬

‫ً‬
‫مفصولة بالفراغ ات في‬ ‫ُ‬
‫ستعيد الدالة )(‪ str.split‬قائمة (‪ )list‬تحوي سالسل نصية كانت‬

‫ً‬
‫أيض ا اس تخدام الدال ة‬ ‫ٌ‬
‫معامل لتحديد مح رف الفص ل‪ .‬يمكن ك‬ ‫السلسلة النصية األصلية إذا لم يُ مرَّ ر‬

‫معينة من السلسلة النصية األصلية‪ ،‬فلنحاول مثاًل حذف الحرف ‪:a‬‬


‫َّ‬ ‫)(‪ str.split‬لحذف أجزاء‬

‫))"‪print(balloon.split("a‬‬
‫]'‪['S', 'mmy h', 's ', ' b', 'lloon.‬‬

‫ح ذِ َف الح رف ‪ a‬من السلس لة النص ية وأص بح الن اتج مقس ومً ا عن د ك ل ورود للح رف ‪ a‬م ع‬
‫ُ‬

‫نسخة مح َّدث ًة منه ا بع د‬


‫ً‬ ‫ً‬
‫نصية ُ‬
‫وتعيد‬ ‫ً‬
‫سلسلة‬ ‫اإلبقاء على الفراغات‪ .‬تأخذ الدالة )(‪str.replace‬‬

‫أن الب الون ال ذي يملك ه س امي ق د ض اع‪ ،‬ولع دم‬


‫إج راء بعض عملي ات االس تبدال عليه ا‪ .‬لنف ترض َّ‬

‫امتالك سامي للبالون في الوقت الراهن‪ ،‬فس ُن ِّ‬


‫بدل الكلمة "‪ "has‬إلى "‪:"had‬‬

‫▲‬ ‫|‬ ‫‪141‬‬


‫البرمجة بلغة بايثون‬ ‫السالسل النصية والتعامل معها‬

‫))"‪print(balloon.replace("has","had‬‬

‫أوَّ ل سلس لة نص ية داخ ل أق واس الدال ة )(‪ replace‬هي السلس لة النص ية ال تي نري د‬

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

‫السطر السابق هو‪:‬‬

‫‪Sammy had a balloon.‬‬

‫ل )(‪ str.join‬و )(‪str.split‬‬ ‫ية مث‬ ‫ل النص‬ ‫ديل السالس‬ ‫تخدام دوال تع‬ ‫اس‬

‫و ‪ str.replace‬سيمنحك تحكمً ا كبيرًا بمعالجة السالسل النصية في بايثون‪.‬‬

‫‪ .8‬دوال اإلحصاء‬
‫بع د أن تعرفن ا على آلي ة فهرس ة المح ارف في السالس ل النص ية‪ ،‬ح ان ال وقت لمعاين ة بعض‬

‫الدوال التي ُتحصي السالسل النصية أو تعيد أرقام الفه ارس‪ .‬يمكنن ا أن نس تفيد من ذل ك بتحدي د‬

‫عدد المحارف التي نريد استقبالها من مدخالت المستخدم‪ ،‬أو لموازنة السالسل النصية‪.‬‬

‫عدة دوال ُتستخدم لإلحصاء‪ .‬لننظ ر أواًل‬


‫لدى السالسل النصية –كغيرها من أنواع البيانات– ِّ‬

‫إلى الدال ة )(‪ len‬ال تي ُتعي د ط ول َّ‬


‫أي ن وع متسلس ل من البيان ات‪ ،‬بم ا في ذل ك األن واع ‪string‬‬

‫و ‪ list‬و ‪ tuple‬و ‪ .dictionary‬لنطبع طول السلسلة النصية ‪:ss‬‬

‫))‪print(len(ss‬‬
‫‪# 12‬‬

‫ً‬
‫محرف ا‪ ،‬بم ا في ذل ك الف راغ وعالم ة‬ ‫ط ول السلس لة النص ية "!‪ "Sammy Shark‬ه و ‪12‬‬

‫ً‬
‫مباشرة تمرير سلسلة نصية إلى الدالة )(‪:len‬‬ ‫التعجب‪ .‬بداًل من استخدام متغيِّ ر‪ ،‬فلنحاول‬

‫▲‬ ‫|‬ ‫‪142‬‬


‫البرمجة بلغة بايثون‬ ‫السالسل النصية والتعامل معها‬

‫))"‪print(len("Let's print the length of this string.‬‬


‫‪# 38‬‬

‫الدالة )(‪ُ len‬تحصي الع دد اإلجم الي من المح ارف في سلس لة نص ية‪ .‬إذا أردن ا إحص اء ع دد‬

‫م رات تك رار مح رف أو مجموع ة من المح ارف في سلس لة نص ية‪ ،‬فيمكنن ا اس تخدام الدال ة‬

‫)(‪ ،str.count‬لنحاول إحصاء الحرف ‪ a‬في السلسلة النصية ‪:ss‬‬

‫))"‪print(ss.count("a‬‬
‫‪# 2‬‬

‫محرف آخر‪:‬‬
‫ٍ‬ ‫يمكننا البحث عن‬

‫))"‪print(ss.count("s‬‬
‫‪# 0‬‬

‫أن‬ ‫أن الح رف ‪ S‬ق د ورد في السلس لة النص ية‪ ،‬إال َّ‬
‫أنه من الض روري أن تبقي ب ذهنك َّ‬ ‫حيح َّ‬
‫ٌ‬ ‫ص‬

‫معين ة بغض النظ ر عن حالته ا‪ ،‬فعلين ا‬


‫َّ‬ ‫روف‬
‫ٍ‬ ‫ٌ‬
‫حساسة لحالة األحرف‪ ،‬فل و أردن ا البحث عن ح‬ ‫بايثون‬

‫حروف صغيرة‪.‬‬
‫ٍ‬ ‫حينها استخدام الدالة )(‪ str.lower‬لتحويل حروف السلسلة النصية إلى‬

‫لنحاول استخدام الدالة )(‪ str.count‬مع سلسلة من المحارف‪:‬‬

‫‪likes = "Sammy likes to swim in the ocean, likes to spin up‬‬


‫"‪servers, and likes to smile.‬‬
‫))"‪print(likes.count("likes‬‬

‫الن اتج ه و ‪ ،3‬إذ تتواج د مجموع ة المح ارف "‪ "likes‬ثالث م رات في السلس لة النص ية‬

‫ً‬
‫أيض ا معرف ة موق ع الح رف أو مجموع ة الح روف في السلس لة النص ية‪ ،‬وذل ك ع بر‬ ‫األصلية‪ .‬يمكنن ا‬

‫اء على رقم فهرس ه‪ .‬يمكنن ا أن نع رف م تى يق ع‬


‫الدال ة )(‪ ،str.find‬وس ُيعاد موض ع المح رف بن ً‬

‫أوَّ ل حرف ‪ m‬في السلسلة النصية ‪ ss‬كاآلتي‪:‬‬

‫▲‬ ‫|‬ ‫‪143‬‬


‫البرمجة بلغة بايثون‬ ‫السالسل النصية والتعامل معها‬

‫))"‪print(ss.find("m‬‬
‫‪# 2‬‬

‫أوّ ل م رة يق ع فيه ا الح رف ‪ m‬في الفه رس ‪ 2‬من السلس لة "!‪ ،"Sammy Shark‬يمكن ك أن‬

‫تراجع بداية هذا الدرس لرؤية جدول يبيِّ ن ارتباطات المحارف م ع فهارس ها في السلس لة الس ابقة‪.‬‬

‫لنرى اآلن مكان أوَّ ل ظهور لمجموعة المحارف ‪ likes‬في السلسلة "‪:"likes‬‬

‫))"‪print(likes.find("likes‬‬
‫‪# 6‬‬

‫أوَّ ل م رة تظه ر فيه ا السلس لة "‪ "likes‬هي في الفه رس ‪ ،6‬أي مك ان وج ود الح رف ‪l‬‬

‫من ‪ .likes‬م اذا ل و أردن ا أن نع رف موض ع ث اني تك رار للكلم ة ‪likes‬؟ نس تطيع فع ل ذل ك بتمري ر‬

‫ان إلى الدال ة )(‪ str.find‬ال ذي س يجعلها تب دأ بحثه ا من ذاك الفه رس‪ ،‬فب داًل من البحث‬
‫معامل ث ٍ‬
‫ٍ‬

‫انطالقا من الفهرس ‪:9‬‬


‫ً‬ ‫من أوَّ ل السلسلة النصية سنبحث‬

‫))‪print(likes.find("likes", 9‬‬
‫‪# 34‬‬

‫بدأ البحث في هذا المثال من الفهرس ‪ ،9‬وكانت أوَّ ل مطابقة للسلسلة النصية "‪ "likes‬عند‬

‫ً‬
‫إضافة إلى ذلك‪ ،‬يمكننا تحديد نهاية إلى مجال البحث بتمرير معامل ثالث‪ .‬وكم ا عن د‬ ‫الفهرس ‪.34‬‬

‫عكسيا‪:‬‬
‫ً‬ ‫تقسيم السالسل النصية‪ ،‬يمكننا استخدام أرقام الفهارس السالبة للعد‬

‫))‪print(likes.find("likes", 40, -6‬‬


‫‪# 64‬‬

‫يبحث آخ ر مث ال عن موض ع السلس لة النص ية "‪ "likes‬بين الفه رس ‪ 40‬و ‪ ،-6‬ولمَّ ا ك ان‬

‫المعامل األخير هو رقم سالب‪ ،‬فسيبدأ العد من نهاية السلسلة األصلية‪.‬‬

‫▲‬ ‫|‬ ‫‪144‬‬


‫البرمجة بلغة بايثون‬ ‫السالسل النصية والتعامل معها‬

‫دوال اإلحص اء مث ل )(‪ len‬و )(‪ str.count‬و )(‪ str.find‬مفي ٌ‬


‫دة في تحدي د ط ول‬

‫معينة فيها‪.‬‬
‫َّ‬ ‫السلسلة النصية وعدد حروفها وفهارس ورود محارف‬

‫‪ .9‬خالصة الفصل‬
‫لقد تعلمنا في هذا الفصل أساس يات التعام ل م ع السالس ل النص ية في لغ ة ب ايثون ‪ .3‬بم ا في‬

‫ً‬
‫إضافة إلى تخزينها في متغيرات‪ ،‬وهذه هي المعلوم ات‬ ‫ذلك إنشاءها وطباعتها وجمعها وتكرارها‪،‬‬

‫األساسية التي عليك فهمها لالنطالق في تعاملك مع السالسل النصية في برامج بايثون ‪.3‬‬

‫▲‬ ‫|‬ ‫‪145‬‬


‫‪8‬‬
‫مدخل إلى تنسيق‬
‫النصوص‬

‫▲‬ ‫|‬ ‫‪146‬‬


‫البرمجة بلغة بايثون‬ ‫مدخل إلى تنسيق النصوص‬

‫تحكم‬
‫ٍ‬ ‫عدة حاالت نحت اج فيه ا إلى‬ ‫ً‬
‫عادة من النص المكتوب‪ ،‬وهنالك ِّ‬ ‫تتألف السالسل النصية‬

‫ً‬
‫قراءة للبشر عبر وضع عالم ات ال ترقيم والس طور الجدي دة‬ ‫بكيفية إظهار النص وجعلها أسهل‬
‫َّ‬ ‫أكبر‬

‫كيفية التعام ل م ع السالس ل النص ية في ب ايثون لكي يظه ر‬


‫َّ‬ ‫والمح اذاة‪ .‬سنش رح في ه ذا الفص ل‬

‫النص الناتج بتنسيق صحيح‪.‬‬

‫‪ .1‬الصياغة المختزلة‬
‫لنف ِّرق أواًل بين الص ياغة المختزل ة للسالس ل النص ية ( ‪ )string literal‬والسالس ل النص ية‬

‫المجرَّ دة نفسها (‪ ،)string value‬فاألولى هي ما نراه في الشيفرة المصدرية للبرن امج‪ ،‬بم ا في ذل ك‬

‫عالمتَي االقتباس‪ .‬أمَّ ا السلسلة النصية نفس ها فهي م ا نراه ا عن دما نس تدعي الدال ة )(‪ print‬عن د‬

‫تش غيل البرن امج‪ .‬ففي برن امج !‪ Hello, World‬التقلي دي‪ ،‬تك ون الص ياغة المختزل ة هي‬

‫‪ Hello,‬دون عالمتَي‬ ‫‪ "Hello,‬بينم ا السلس لة النص ية المج رَّ دة هي !‪World‬‬ ‫"!‪World‬‬

‫أن السلسلة النصية هي ما نراه في نافذة الطرفية عندما ُنش ِّغل برن امج ب ايثون‪ .‬لكن‬
‫االقتباس‪ .‬أي َّ‬

‫وألن القيم‬
‫َّ‬ ‫بعض السالس ل النص ية ق د تحت وي على عالم ات اقتب اس‪ ،‬مث ل اقتباس نا لمقول ةٍ م ا‪.‬‬

‫المُ صنَّفة على َّ‬


‫أنها سالسل نصية بالصياغة المختزلة والقيم الفعلية المجرَّ دة للسالس ل النص ية غ ير‬

‫متساوية‪ ،‬فمن الضروري في أغلب الح االت إض افة تنس يق إلى ص ياغة السلس لة النص ية المختزل ة‬

‫لعرضها كما ينبغي‪.‬‬

‫‪ .2‬عالمات االقتباس‬
‫بس بب إمكانيتن ا اس تخدام عالم ات االقتب اس المف ردة أو المزدوج ة في ب ايثون‪ ،‬فمن الس هل‬

‫تض مين االقتباس ات بوض عها بين عالمتَي اقتب اس مزدوج تين في سلس لةٍ نص يةٍ محاط ةٍ بعالمتَي‬

‫اقتباس مفردتين كما في السلسلة اآلتية‪:‬‬

‫▲‬ ‫|‬ ‫‪147‬‬


‫البرمجة بلغة بايثون‬ ‫مدخل إلى تنسيق النصوص‬

‫'"!‪'Sammy says, "Hello‬‬

‫أو يمكنن ا اس تخدام عالم ة اقتب اس فردي ة (أو كم ا يس مونها «فاص لة علي ا» [ ‪)]apostrophe‬‬

‫في سلسلةٍ نصيةٍ محاطةٍ بعالمتَي اقتباس مزدوجتين‪:‬‬

‫"‪"Sammy's balloon is red.‬‬

‫ً‬
‫إذا‪ ،‬يمكنن ا التحكم بطريق ة ع رض عالم ات االقتب اس والفواص ل العلي ا في سالس لنا النص ية‬

‫عبر استخدام النوع الصحيح من عالمات االقتباس إلحاطة كامل السلسلة النصية‪.‬‬

‫‪ .3‬كتابة النص على أكثر من سطر‬


‫طباعة السالسل النص ية على أك ثر من س طر س تجعل منه ا واض ً‬
‫حة وس هلة الق راءة‪ .‬إذ يمكن‬

‫ِّ‬
‫بعدة أسطر لزيادة وضوحها‪ ،‬أو لتنسيقها كرس الة‪ ،‬أو للحف اظ على تع ُّدد‬ ‫تجميع النصوص المكتوبة‬

‫األس طر في األش عار‪ .‬نس تخدم ثالث عالم ات اقتب اس فردي ة ''' أو ثالث عالم ات اقتب اس‬

‫مزدوجة """ لإلحاطة بالسلسلة النصية التي تمتد على أكثر من سطر‪:‬‬

‫'''‬
‫‪This string is on‬‬
‫‪multiple lines‬‬
‫‪within three single‬‬
‫‪quotes on either side.‬‬
‫'''‬
‫"""‬
‫‪This string is on‬‬
‫‪multiple lines‬‬
‫‪within three double‬‬
‫‪quotes on either side.‬‬
‫"""‬

‫▲‬ ‫|‬ ‫‪148‬‬


‫البرمجة بلغة بايثون‬ ‫مدخل إلى تنسيق النصوص‬

‫خصوص ا‬
‫ً‬ ‫يمكنك اآلن طباعة السالسل النصية في ِّ‬
‫عدة أسطر لجعل النصوص سهلة القراءة –‬

‫الطويلة منها– وذلك عبر استخدام ثالث عالمات اقتباس متتالية‪.‬‬

‫‪ .4‬تهريب المحارف‬
‫طريق ة أخ رى لتنس يق السالس ل النص ية هي اس تخدام «مح رف الته ريب»‬

‫(‪ .)escape character‬فجميع عملي ات ته ريب المح ارف تب دأ بالخ ط المائ ل الخلفي (‪،backslash‬‬

‫أي \) متبوعً ا بمح ٍ‬


‫رف آخ ر ال ذي ل ه مع نى خ اص يفي د في تنس يق السلس لة النص ية‪ .‬ه ذه قائم ة‬

‫بأكثر محارف التهريب شيوعً ا‪:‬‬

‫\‪ :‬سطرٌ جدي ٌد في سلسلةٍ نصيةٍ متألفةٍ من ِّ‬


‫عدة أسطر‪.‬‬ ‫•‬

‫\\‪ :‬طباعة رمز الخط المائل الخلفي‪.‬‬ ‫•‬

‫'\‪ :‬طباعة عالمة اقتباس فردية‪.‬‬ ‫•‬

‫"\‪ :‬طباعة عالمة اقتباس مزدوجة‪.‬‬ ‫•‬

‫سطر جديد‪.‬‬
‫ٍ‬ ‫‪ :\n‬طباعة محرف االنتقال إلى‬ ‫•‬

‫‪ :\t‬طباعة محرف الجدولة (‪.)Tab‬‬ ‫•‬

‫لنستخدم محرف التهريب إلضافة عالمات االقتباس إلى سلس لتنا النص ية الس ابقة‪ ،‬لكن ه ذه‬

‫المرة س ُنحيط السلسلة النصية بعالمتَي اقتباس مزدوجتين‪:‬‬

‫)""\!‪print("Sammy says, \"Hello‬‬


‫"!‪# Sammy says, "Hello‬‬

‫▲‬ ‫|‬ ‫‪149‬‬


‫البرمجة بلغة بايثون‬ ‫مدخل إلى تنسيق النصوص‬

‫تمكننا عبر محرف التهريب "\ من استخدام عالمات االقتباس المزدوجة لإلحاط ة بالسلس لة‬

‫ً‬
‫أيض ا‬ ‫اط بعالمتَي اقتب اس مزدوج تين‪ .‬نس تطيع‬
‫مقتبس ومح ٍ‬
‫ٍ‬ ‫نص‬
‫النص ية ال تي تحت وي على ٍ‬

‫اس تخدام مح رف الته ريب '\ إلض افة عالم ة اقتب اس مف ردة ض من السلس لة النص ية المحاط ة‬

‫بعالمتَي اقتباس مفردتين‪:‬‬

‫)'‪print('Sammy\'s balloon is red.‬‬


‫‪# Sammy's balloon is red.‬‬

‫وألنن ا نس تخدم اآلن مح رف الته ريب فنس تطيع وض ع عالم ات االقتب اس المف ردة ح تى ل و‬

‫ك انت السلس لة النص ية كله ا موج ودة بين عالمتَي اقتب اس مف ردتين‪ .‬عن دما نس تخدم عالم ات‬

‫ً‬
‫فراغ ا في أعلى وأس فل النص عن د طباعت ه‪ .‬نس تطيع‬ ‫االقتباس الثالثية –كما فعلن ا أعاله– فس نجد‬

‫حذف تلك الفراغات عبر استخدام محرف التهريب \ في بداية ونهاية السلسلة النصية مع اإلبقاء‬

‫مقروءا بسهولة في الشيفرة‪.‬‬


‫ً‬ ‫على النص‬

‫\"""‬
‫‪This multi-line string‬‬
‫‪has no space at the‬‬
‫‪top or the bottom‬‬
‫\‪when it prints.‬‬
‫"""‬

‫كل ش بيهٍ بم ا س بق‪ ،‬يمكنن ا اس تخدام مح رف الته ريب ‪ \n‬لوض ع أس طر جدي دة دون‬
‫وبش ٍ‬

‫الحاجة إلى الضغط على زر ‪ Enter‬أو ‪:Return‬‬

‫▲‬ ‫|‬ ‫‪150‬‬


‫البرمجة بلغة بايثون‬ ‫مدخل إلى تنسيق النصوص‬

‫)"‪print("This string\nspans multiple\nlines.‬‬


‫‪# This string‬‬
‫‪# spans multiple‬‬
‫‪# lines.‬‬

‫لة نص ً‬
‫ية على أك ثر من‬ ‫يمكننا ال دمج بين مح ارف الته ريب‪ ،‬إذ س نطبع في المث ال اآلتي سلس ً‬

‫سطر‪ ،‬ونستعمل فيها مسافة جدولة (‪ )tab‬بين الترقيم ومحتوى السطر‪:‬‬

‫)"‪print("1.\tShark\n2.\tShrimp\n10.\tSquid‬‬
‫‪# 1.‬‬ ‫‪Shark‬‬
‫‪# 2.‬‬ ‫‪Shrimp‬‬
‫‪# 10.‬‬ ‫‪Squid‬‬

‫عالمة الجدولة األفقية ال تي وض عناها ع بر مح رف الته ريب ‪ \t‬س تحاذي الكتاب ة في العم ود‬

‫أن مح رف الته ريب ‪\n‬‬


‫حيح َّ‬
‫ٌ‬ ‫النص ي الث اني في المث ال أعاله‪ ،‬مم ا يجع ل قراءته ا س ً‬
‫هلة ج ًدا‪ .‬وص‬

‫ً‬
‫روءة‬ ‫يعم ل عماًل جي ًدا في النص وص القص ير‪ ،‬لكن ال ُنغفِ ل أهمي ة أن تك ون الش يفرة المص درية مق‬

‫أيضا‪ .‬فلو كان النص طوياًل ‪ ،‬فأرى َّ‬


‫أن من األفضل استخدام عالمات االقتباس الثالثية‪.‬‬ ‫ً‬ ‫بسهولةٍ‬

‫أن مح ارف الته ريب ُتس تعمَ ل إلض افة تنس يق إلى السالس ل ال تي ك ان من الص عب (أو‬
‫رأين ا َّ‬

‫عرض ا س ليمً ا دونه ا‪ .‬فه ل تس تطيع مثاًل أن تطب ع السلس لة النص ية اآلتي ة‬
‫ً‬ ‫حتى المستحيل) عرضها‬

‫دون استخدام محارف التهريب؟‬

‫"‪Sammy says, "The balloon's color is red.‬‬

‫‪ .5‬السالسل النصية الخام‬


‫ماذا لو أردنا تجاهل كل محارف التنسيق الخاص ة في سالس لنا النص ية؟ فلربم ا أردن ا موازن ة‬

‫ُّ‬
‫التحقق من صحة بعض الشيفرات الحاسوبية التي تستخدم الخ ط المائ ل الخلفي‪ ،‬وال نري د من‬ ‫أو‬

‫▲‬ ‫|‬ ‫‪151‬‬


‫البرمجة بلغة بايثون‬ ‫مدخل إلى تنسيق النصوص‬

‫بايثون تفسيره على َّ‬


‫أنه محرف تهريب‪ .‬أتت «السالسل النصية الخام» ( ‪ )raw strings‬في بايثون‬

‫لتح ل ه ذه المش كلة‪ ،‬وتتجاه ل جمي ع مح ارف التنس يق داخ ل سلس لة نص ية‪ ،‬بم ا في ذلك‬

‫محارف التهريب‪.‬‬

‫يمكنن ا إنش اء سلس لة نص ية خ ام بوض ع الح رف ‪ r‬في بداي ة السلس لة النص ية‪ ،‬قب ل عالم ة‬

‫ً‬
‫مباشرة‪:‬‬ ‫االقتباس األولى‬

‫)""\‪print(r"Sammy says,\"The balloon\'s color is red.‬‬


‫"\‪# Sammy says,\"The balloon\'s color is red.‬‬

‫سنستطيع اإلبقاء على محارف التهريب كما هي في السالسل النصية إن أسبقناها بالحرف ‪r‬‬

‫لتحويلها إلى سالسل نصية خام‪.‬‬

‫نسقات‬ ‫‪ .6‬استخدام ُ‬
‫الم ِّ‬
‫الدالة )(‪ str.format‬المتوافرة للسالسل النص ية تس مح ل ك باس تبدال المتغ يرات وتنس يق‬

‫القيم‪ .‬مما يمنحك القدرة على تجميع العناصر مع بعض ها ع بر إدخاله ا في مواض ع معين ة‪ .‬سيش رح‬

‫ل ك ه ذا القس م أش هر االس تخدامات آللي ة تنس يق السالس ل النص ية في ب ايثون‪ ،‬وال تي ستس اعدك‬

‫ً‬
‫قراءة واستخدامً ا‪.‬‬ ‫في جعل شيفرتك وبرنامجك أسهل‬

‫نس قات (‪ )formatters‬بوض ع حق ول قابل ة لالس تبدال ُتع رَّ ف ع بر وض ع قوس ين‬
‫تعم ل المُ ِّ‬

‫معق وفين {} في السلس لة النص ية ثم اس تدعاء الدال ة )(‪ ،str.format‬إذ س ُتمرَّ ر القيم ة ال تي‬

‫تري د وض عها ض من السلس لة النص ية إلى الدال ة )(‪ format‬وستوض ع ه ذه القيم ة في نفس مك ان‬

‫الحق ل القاب ل لالس تبدال الموج ود في السلس لة األص لية عن دما ُتش ِّغل برنامج ك‪ .‬لنطب ع سلس ً‬
‫لة‬

‫منس ًقا» (‪:)formatter‬‬ ‫ً‬


‫نصية تستخدم « ِّ‬

‫▲‬ ‫|‬ ‫‪152‬‬


‫البرمجة بلغة بايثون‬ ‫مدخل إلى تنسيق النصوص‬

‫))‪print("Sammy has {} balloons.".format(5‬‬

‫الناتج‪:‬‬

‫‪Sammy has 5 balloons.‬‬

‫ً‬
‫نصية تحتوي على قوسين معقوصين {}‪:‬‬ ‫ً‬
‫سلسلة‬ ‫أنشأنا في المثال السابق‬

‫"‪"Sammy has {} balloons.‬‬

‫أن القيم ة ‪5‬‬


‫ثم أض فنا الدال ة )(‪ str.format‬ومرَّ رن ا إليه ا القيم ة الرقمي ة ‪ 5‬وه ذا يع ني َّ‬

‫ستوضع مكان القوسين المعقوصين‪:‬‬

‫‪Sammy has 5 balloons.‬‬

‫نس ًقا إلى متغير‪:‬‬ ‫ً‬


‫أيضا إسناد السلسلة النصية األصلية التي تحوي مُ ِّ‬ ‫يمكننا‬

‫"‪open_string = "Sammy loves {}.‬‬


‫))"‪print(open_string.format("open source‬‬

‫الناتج‪:‬‬

‫‪Sammy loves open source.‬‬

‫أض فنا في المث ال الس ابق السلس لة النص ية "‪ "open source‬إلى سلس لةٍ نص يةٍ أك بر‬

‫باستبدالها للقوسين المعقوفين الموجو َدين في السلسلة األصلية‪ .‬تسمح ل ك المُ ِّ‬
‫نس قات في ب ايثون‬

‫باس تخدام األق واس المعقوف ة لحج ز أم اكن للقيم ال تي س تمررها مس تقباًل ع بر‬

‫الدالة )(‪.str.format‬‬

‫ا‪ .‬استخدام المُ ِّ‬


‫نسقات لحجز أكثر من مكان‬

‫يمكنك استخدام أكثر من زوج من األقواس المعقوصة عن د اس تعمال المُ ِّ‬


‫نس قات؛ فيمكن ك أن‬

‫▲‬ ‫|‬ ‫‪153‬‬


‫البرمجة بلغة بايثون‬ ‫مدخل إلى تنسيق النصوص‬

‫لة نص ً‬
‫ية أخ رى إلى المث ال الس ابق وذل ك بإض افة زوج آخ ر من األق واس المعقوص ة‬ ‫تض يف سلس ً‬

‫وتمرير قيمة ثانية إلى الدالة كما يلي‪:‬‬

‫مكانين محجوزين عبر }{ ‪#‬‬


‫"‪new_open_string = "Sammy loves {} {}.‬‬
‫ٌ‬
‫مفصول بينهما بفاصلة ‪#‬‬ ‫تمرير قيمتين إلى الدالة‬
‫))"‪print(new_open_string.format("open-source", "software‬‬

‫الناتج‪:‬‬

‫‪Sammy loves open-source software.‬‬

‫ً‬
‫زوجا آخر من األقواس المعقوصة إلى السلس لة النص ية للس ماح بوض ع قيم ة ثاني ة‪ ،‬ثم‬ ‫أضفنا‬

‫مررن ا سلس لتين نص يتين إلى الدال ة )(‪ str.format‬مفص ٌ‬


‫ول بينهم ا بفاص لة‪ .‬سنض يف عملي ات‬

‫استبدال أخرى عبر اتباع نفس اآللية التي شرحناها أعاله‪:‬‬

‫"‪sammy_string = "Sammy loves {} {}, and has {} {}.‬‬


‫‪print(sammy_string.format("open-source", "software", 5,‬‬
‫))"‪"balloons‬‬

‫الناتج‪:‬‬

‫‪Sammy loves open-source software, and has 5 balloons.‬‬

‫ب‪ .‬إعادة ترتيب المنسقات عبر المعامالت الموضعية‬

‫عندما نترك األقواس المعقوص ة دون مع امالت (‪ )parameters‬مم ررة إليه ا‪ ،‬فستض ع ب ايثون‬

‫القيم المُ مرَّ رة إلى الدالة )(‪ str.format‬بالترتيب‪ .‬هذا تعبيرٌ فيه زوجين من األقواس المعقوصة‬

‫ً‬
‫سابقا في هذا الفصل‪:‬‬ ‫ٌ‬
‫شبيه بما رأيناه‬ ‫يوضع مكانهما سلسلتان نصيتان‬

‫▲‬ ‫|‬ ‫‪154‬‬


‫البرمجة بلغة بايثون‬ ‫مدخل إلى تنسيق النصوص‬

‫‪print("Sammy the {} has a pet {}!".format("shark", "pilot‬‬


‫))"‪fish‬‬

‫الناتج‪:‬‬

‫!‪Sammy the shark has a pet pilot fish‬‬

‫زوج من األقواس المعقوصة ووضعت مكانه القيمة "‪ ،"shark‬ووضعت القيمة‬


‫ٍ‬ ‫ُاستبدِ ل أوَّ ل‬

‫"‪ "pilot fish‬مكان الزوج الثاني من األقواس‪ .‬القيم التي مرَّ رناها إلى الدال ة )(‪str.format‬‬

‫كانت بهذا الترتيب‪:‬‬

‫)"‪("shark", "pilot fish‬‬

‫أن القيم ة الس ابقة هي من الن وع ‪( tuple‬ص ف)‪ ،‬ويمكن الوص ول إلى ك ل قيم ة‬
‫الح ظ َّ‬

‫ابع له ا‪ ،‬وال ذي يب دأ من الفه رس ‪ .0‬يمكنن ا تمري ر أرق ام الفه ارس‬


‫رقمي ت ٍ‬ ‫رس‬
‫موجودة فيه ا ع بر فه ٍ‬
‫ٍ‬

‫إلى داخل القوسين المعقوفين‪:‬‬

‫‪print("Sammy the {0} has a pet {1}!".format("shark", "pilot‬‬


‫))"‪fish‬‬

‫سنحص ل بع د تنفي ذ المث ال الس ابق على نفس الن اتج ال تي ظه ر دون تحدي د أرق ام الفه ارس‬

‫يدويًّ ا‪ ،‬وذلك َّ‬


‫ألننا استدعينا القيم بالترتيب‪:‬‬

‫!‪Sammy the shark has a pet pilot fish‬‬

‫لكن إن عكس نا أرق ام الفه ارس في مع امالت األق واس المعقوف ة فس نتمكن من عكس ت رتيب‬

‫القيم المُ مرَّ رة إلى السلسلة النصية األصلية‪:‬‬

‫‪print("Sammy the {1} has a pet {0}!".format("shark", "pilot‬‬


‫))"‪fish‬‬

‫▲‬ ‫|‬ ‫‪155‬‬


‫البرمجة بلغة بايثون‬ ‫مدخل إلى تنسيق النصوص‬

‫الناتج‪:‬‬

‫!‪Sammy the pilot fish has a pet shark‬‬

‫لكن إن ح اولت اس تخدام الفه رس ذي ال رقم ‪ 2‬ولم تكن ل ديك إال قيم تين موج ودتين في‬

‫ً‬
‫قيمة خارج المجال المسموح‪ ،‬ولهذا السبب ستظهر رسالة خطأ‪:‬‬ ‫الفهرسين ‪ 0‬و ‪ ،1‬فأنت تستدعي‬

‫‪print("Sammy the {2} has a pet {1}!".format("shark", "pilot‬‬


‫))"‪fish‬‬

‫الناتج‪:‬‬

‫‪IndexError: tuple index out of range‬‬

‫ُتش ِير رسالة الخطأ إلى وجود قيمتين فقط ومكانهما هو ‪ 0‬و‪ ،1‬لذا كان الفهرس ‪ 2‬غير مرتب ٍ‬
‫ط‬

‫بقيمةٍ وك ان خ ارج المج ال المس موح‪ .‬لنض ف اآلن مك انين محج وزين إلى السلس لة النص ية ولنم ِّرر‬

‫بض ع قيم إلى الدال ة )(‪ str.format‬لكي نفهم آلي ة إع ادة ال ترتيب فهمً ا تامً ا‪ .‬ه ذه هي السلس لة‬

‫النصية الجديدة التي فيها أربعة أزواج من األقواس المعقوصة‪:‬‬

‫‪print("Sammy is a {}, {}, and {} {}!".format("happy",‬‬


‫))"‪"smiling", "blue", "shark‬‬

‫الناتج‪:‬‬

‫!‪Sammy is a happy, smiling and blue shark‬‬

‫ستوض ع القيم المُ م رَّ رة إلى الدال ة )(‪ str.format‬بنفس ت رتيب وروده ا في ح ال لم‬

‫نس تعمل المع امالت داخ ل األق واس المعقوص ة‪ .‬تمل ك السالس ل النص ية المُ م رَّ رة إلى الدالة‬

‫)(‪ str.format‬الفهارس اآلتية المرتبطة بها؛ لنستخدم اآلن أرقام الفه ارس لتغي ير ت رتيب ظه ور‬

‫القيم المرتبطة بها في السلسلة النصية‪:‬‬

‫▲‬ ‫|‬ ‫‪156‬‬


‫البرمجة بلغة بايثون‬ ‫مدخل إلى تنسيق النصوص‬

‫‪print("Sammy is a {3}, {2}, and {1} {0}!".format("happy",‬‬


‫))"‪"smiling", "blue", "shark‬‬

‫الناتج‪:‬‬

‫!‪Sammy is a shark, blue, and smiling happy‬‬

‫ولمّ ا ك ّن ا ق د ب دأنا ب الفهرس ذي ال رقم ‪ ،3‬فس تظهر القيم ة "‪ "shark‬أواًل‪ .‬أي َّ‬
‫أن وض ع رقم‬

‫الفهرس بين القوسين كمعامل سيؤدي إلى تغيير ترتيب ظهور القيم في السلسلة النصية األص لية‪.‬‬

‫نس تطيع ‪-‬باإلض افة إلى المع امالت الموض عية الرقمي ة‪ -‬أن نرب ط بين القيم وبين كلم ات محج وزة‬

‫مخصصة ومن ثم نستدعيها عبر وضع الكلمة المحجوزة بين القوسين المعقوصين كما يلي‪:‬‬

‫= ‪print("Sammy the {0} {1} a {pr}.".format("shark", "made", pr‬‬


‫))"‪"pull request‬‬

‫الناتج‪:‬‬

‫‪Sammy the shark made a pull request.‬‬

‫عية‪،‬‬ ‫أظه ر المث ال الس ابق اس تخدام كلم ة محج وزة وس ً‬


‫يطا باإلض افة إلى المع امالت الموض َّ‬

‫ً‬
‫أيض ا‬ ‫يمكن ك اس تخدام الكلم ة المحج وزة ‪ pr‬كوس يط باإلض افة إلى أرق ام الفه ارس‪ ،‬وتس تطيع‬

‫إعادة ترتيب تلك الوسائط كيفما شئت‪:‬‬

‫= ‪print("Sammy the {pr} {1} a {0}.".format("shark", "made", pr‬‬


‫))"‪"pull request‬‬

‫الناتج‪:‬‬

‫‪Sammy the pull request made a shark.‬‬

‫▲‬ ‫|‬ ‫‪157‬‬


‫البرمجة بلغة بايثون‬ ‫مدخل إلى تنسيق النصوص‬

‫بكيفية معالج ة‬
‫َّ‬ ‫عية والكلم ات المحج وزة س يمنحنا تحكمً ا أك بر‬
‫اس تخدام المع امالت الموض َّ‬

‫السلسلة النصية األصلية عبر إعادة ترتيب القيم المُ مرَّ رة إليها‪.‬‬

‫ج‪ .‬استخدام المُ ِّ‬


‫نسقات لتنظيم البيانات‬

‫يس طع نجم آلي ة التنس يق ال تي نش رحها في ه ذا الفص ل عن دما ُتس تخ َدم لتنظيم البيان ات‬

‫بصريً ا‪ ،‬فلو أردنا إظهار نتائج قاعدة البيانات إلى المستخدمين‪ ،‬فيمكننا استعمال المُ ِّ‬
‫نسقات لزي ادة‬

‫ً‬
‫راءة‪ .‬لننظ ر إلى حلق ة تك رار تقليدي ة في‬ ‫حجم الحق ل وتع ديل المح اذاة لجع ل الن اتج أس هل ق‬

‫لمجال من األعداد من ‪ 3‬إلى ‪:13‬‬


‫ٍ‬ ‫بايثون التي تطبع ‪ i‬و ‪ i*i‬و ‪i*i*i‬‬

‫‪for i in range(3,13):‬‬
‫)‪print(i, i*i, i*i*i‬‬

‫الناتج‪:‬‬

‫‪3 9 27‬‬
‫‪4 16 64‬‬
‫‪5 25 125‬‬
‫‪6 36 216‬‬
‫‪7 49 343‬‬
‫‪8 64 512‬‬
‫‪9 81 729‬‬
‫‪10 100 1000‬‬
‫‪11 121 1331‬‬
‫‪12 144 1728‬‬

‫نظمٌ قلياًل ‪ ،‬إال َّ‬


‫أن األع داد تت داخل م ع بعض ها بص ريً ا مم ا يُ ص ِّعب ق راءة‬ ‫أن الن اتج مُ َّ‬
‫حيح َّ‬
‫ٌ‬ ‫ص‬

‫َ‬
‫كنت تتعام ل م ع مجموع ة أك بر من البيان ات ال تي يتواج د فيه ا‬ ‫األس طر األخ يرة من الن اتج‪ ،‬وإذا‬

‫أعداد أكبر (أو أصغر) مما عرضناه في مثالن ا‪ ،‬فق د تب دو ل ك المش كلة جلي ًة حينه ا‪ .‬لنح اول تنس يق‬

‫▲‬ ‫|‬ ‫‪158‬‬


‫البرمجة بلغة بايثون‬ ‫مدخل إلى تنسيق النصوص‬

‫الناتج السابق إلعطاء مساحة أكبر إلظهار األعداد عبر المثال التالي‪:‬‬

‫‪for i in range(3,13):‬‬
‫))‪print("{:3d} {:4d} {:5d}".format(i, i*i, i*i*i‬‬

‫مباشرة بكتابة النقط تين الرأس يتين متبوع ًة‬


‫ً‬ ‫لم ُن ِّ‬
‫حدد في المثال السابق ترتيب الحقل وبدأنا‬

‫بحجم الحقل ورمز التحويل ‪َّ ( d‬‬


‫ألننا نتعامل مع أعداد صحيحة)‪ .‬أعطينا في المث ال الس ابق حجمً ا‬

‫افا إلي ه ‪ ،2‬ل ذا س يبدو‬


‫للحقل مساويً ا لعدد أرق ام الع دد ال ذي نتوق ع طباعت ه في الحق ل المع ني مض ً‬

‫الناتج كاآلتي‪:‬‬

‫‪3‬‬ ‫‪9‬‬ ‫‪27‬‬


‫‪4‬‬ ‫‪16‬‬ ‫‪64‬‬
‫‪5‬‬ ‫‪25‬‬ ‫‪125‬‬
‫‪6‬‬ ‫‪36‬‬ ‫‪216‬‬
‫‪7‬‬ ‫‪49‬‬ ‫‪343‬‬
‫‪8‬‬ ‫‪64‬‬ ‫‪512‬‬
‫‪9‬‬ ‫‪81‬‬ ‫‪729‬‬
‫‪10‬‬ ‫‪100‬‬ ‫‪1000‬‬
‫‪11‬‬ ‫‪121‬‬ ‫‪1331‬‬
‫‪12‬‬ ‫‪144‬‬ ‫‪1728‬‬

‫ً‬
‫أيض ا تحدي د حجم ث ابت للحق ل لنحص ل على أعم دة متس اوية الع رض‪ ،‬مم ا يض من‬ ‫يمكنن ا‬

‫إظهار األعداد الكبيرة بصورة صحيحة‪:‬‬

‫‪for i in range(3,13):‬‬
‫))‪print("{:6d} {:6d} {:6d}".format(i, i*i, i*i*i‬‬

‫الناتج‪:‬‬

‫‪3‬‬ ‫‪9‬‬ ‫‪27‬‬


‫‪4‬‬ ‫‪16‬‬ ‫‪64‬‬

‫▲‬ ‫|‬ ‫‪159‬‬


‫البرمجة بلغة بايثون‬ ‫مدخل إلى تنسيق النصوص‬

‫‪5‬‬ ‫‪25‬‬ ‫‪125‬‬


‫‪6‬‬ ‫‪36‬‬ ‫‪216‬‬
‫‪7‬‬ ‫‪49‬‬ ‫‪343‬‬
‫‪8‬‬ ‫‪64‬‬ ‫‪512‬‬
‫‪9‬‬ ‫‪81‬‬ ‫‪729‬‬
‫‪10‬‬ ‫‪100‬‬ ‫‪1000‬‬
‫‪11‬‬ ‫‪121‬‬ ‫‪1331‬‬
‫‪12‬‬ ‫‪144‬‬ ‫‪1728‬‬

‫ً‬
‫أيضا تعديل محاذاة النص الموجود في األعمدة باستخدام الرموز > و ^ و <‪ ،‬وتبديل‬ ‫يمكننا‬

‫‪ d‬إلى ‪ f‬إلظه ار من ازل عش رية‪ ،‬وغ ير ذل ك مم ا تعلمن اه في ه ذا ال درس إلظه ار البيان ات الناتج ة‬

‫كما نرغب‪.‬‬

‫‪ .7‬تحديد نوع القيمة‬


‫يمكن ك وض ع مع امالت أخ رى ض من القوس ين المعقوص ين‪ ،‬سنس تخدم الص يغة اآلتي ة‬

‫{‪ }field_name:conversion‬إذ ‪ field_name‬ه و الفه رس ال رقمي للوس يط المُ م رَّ ر إلى‬

‫يليا في القس م الس ابق‪ ،‬و ‪ conversion‬ه و الرم ز‬


‫الدال ة )(‪ str.format‬وال ذي ش رحناه تفص ً‬

‫المس تعمل للتحوي ل إلى ن وع البيان ات ال ذي تري ده‪« .‬رم ز التحوي ل» يع ني رم ًزا من ح ٍ‬
‫رف وحي د‬

‫الذي تستخدمه بايثون لمعرفة نوع القيمة المُ راد «تنسيقها»‪ .‬الرموز التي سنستخدمها في أمثلتنا‬

‫هي ‪ s‬للسالس ل النص ية و ‪ d‬إلظه ار األرق ام بنظ ام الع د العش ري (ذي األس اس ‪ )10‬و ‪ f‬إلظه ار‬

‫األعداد ذات الفاصلة‪.‬‬

‫يمكنك قراءة المزيد من التفاصيل عن رموز التنسيق في بايثون ‪( 3‬وغير ذل ك من المواض يع‬

‫ً‬
‫حيحا ع بر‬ ‫ال ُنم ِّرر في ه رقمً ا ص‬
‫المرتبط ة به ذا المج ال) في التوثي ق الرس مي‪ .‬لننظ ر إلى مث ٍ‬

‫الدالة )(‪ format‬لكننا نريد إظهاره كعددٍ ذي فاصلة عبر رمز التحويل ‪:f‬‬

‫▲‬ ‫|‬ ‫‪160‬‬


‫البرمجة بلغة بايثون‬ ‫مدخل إلى تنسيق النصوص‬

‫))"‪print("Sammy ate {0:f} percent of a {1}!".format(75, "pizza‬‬

‫الناتج‪:‬‬

‫!‪Sammy ate 75.000000 percent of a pizza‬‬

‫وضعت القيمة ‪-‬مك ان أوَّ ل ورود للص يغة {‪ -}field_name:conversion‬كع ددٍ ذي فاص لة‪،‬‬

‫أمَّ ا ث اني ورود للقوس ين المعقوص ين فك ان بالص يغة {‪ .}field_name‬الح ظ في المث ال الس ابق‬

‫وجود ع دد كب ير من األرق ام الظ اهرة بع د الفاص لة العش رية‪ ،‬لكن ك تس تطيع تقلي ل ع ددها‪ .‬فعن دما‬

‫ً‬
‫أيض ا تحدي د دق ة القيم ة الناتج ة بتض مين رم ز‬ ‫نس تخدم الرم ز ‪ f‬للقيم ذات الفاص لة نس تطيع‬

‫النقطة ‪ .‬متبوعً ا بعدد األرقام بعد الفاصلة التي نود عرضها‪ .‬حتى لو أكل سامي ‪ %75.765367‬من‬

‫قطع ة البي تزا فلن نحت اج إلى ه ذا الق در الكب ير من الدق ة‪ ،‬إذ يمكنن ا مثاًل أن نجع ل ع دد المن ازل‬

‫العشرية ثالث منازل بعد الفاصلة بوضعنا ‪ .3‬قبل رمز التحويل ‪:f‬‬

‫‪print("Sammy ate {0:.3f} percent of a‬‬


‫))‪pizza!".format(75.765367‬‬

‫الناتج‪:‬‬

‫!‪Sammy ate 75.765 percent of a pizza‬‬

‫أما إذا أردنا عرض منزلة عشرية وحيدة‪ ،‬فيمكننا إعادة كتابة السلسلة السابقة كاآلتي‪:‬‬

‫‪print("Sammy ate {0:.1f} percent of a‬‬


‫))‪pizza!".format(75.765367‬‬

‫الناتج‪:‬‬

‫!‪Sammy ate 75.8 percent of a pizza‬‬

‫▲‬ ‫|‬ ‫‪161‬‬


‫البرمجة بلغة بايثون‬ ‫مدخل إلى تنسيق النصوص‬

‫الح ظ كي ف أدى تع ديل دق ة األرق ام العش رية إلى تق ريب ال رقم (وف ق قواع د التق ريب‬

‫حيح أنن ا عرض نا رقمً ا دون من ازل عش رية كع ددٍ ذي فاص لة‪ ،‬إال أنن ا إذا حاولن ا‬
‫ٌ‬ ‫االعتيادي ة)‪ .‬وص‬

‫تحويل عدد عشري إلى عدد صحيح باستخدام رمز التحويل ‪ d‬فسنحصل على خطأ‪:‬‬

‫))‪print("Sammy ate {0:.d} percent of a pizza!".format(75.765367‬‬

‫الناتج‪:‬‬

‫'‪ValueError: Unknown format code 'd' for object of type 'float‬‬

‫إذا لم ترغب بعرض أيَّ ة منازل عشرية‪ ،‬فيمكنك كتابة تعبير كاآلتي‪:‬‬

‫‪print("Sammy ate {0:.0f} percent of a‬‬


‫))‪pizza!".format(75.765367‬‬

‫الناتج‪:‬‬

‫!‪Sammy ate 76 percent of a pizza‬‬

‫وإنم ا س يؤدي إلى تقلي ل ع دد‬ ‫ِّ‬


‫يؤدي ما سبق إلى تحوي ل الع دد العش ري إلى ع ددٍ ص حيح‪َّ ،‬‬ ‫لن‬

‫المنازل العشرية الظاهرة بعد الفاصلة‪.‬‬

‫‪ .8‬إضافة حواشي‬
‫لمَّ ا ك انت األم اكن المحج وزة ع بر القوس ين المعقوص ين {} هي حق ول قابل ة لالس تبدال (أي‬

‫ً‬
‫فعلية) فيمكنك إضافة حاش ية (‪ )padding‬أو إض افة ف راغ ح ول العنص ر بزي ادة حجم‬ ‫ليست قيمً ا‬

‫الحقل عبر معامالت إضافية‪ ،‬ق د تس تفيد من ه ذا األم ر عن دما تحت اج إلى تنظيم البيان ات بص ريً ا‪.‬‬

‫معين (مُ ً‬
‫قاس ا بع دد المح ارف) بتحدي د ذاك الحجم بع د النقط تين‬ ‫َّ‬ ‫بحجم‬
‫ٍ‬ ‫يمكنن ا إض افة حق ٍل‬

‫الرأسيتين ‪ :‬كما في المثال اآلتي‪:‬‬

‫▲‬ ‫|‬ ‫‪162‬‬


‫البرمجة بلغة بايثون‬ ‫مدخل إلى تنسيق النصوص‬

‫))"‪print("Sammy has {0:4} red {1:16}!".format(5, "balloons‬‬

‫الناتج‪:‬‬

‫‪Sammy has‬‬ ‫‪5 red balloons‬‬ ‫!‬

‫ً‬
‫محرف ا‬ ‫أعطين ا في المث ال الس ابق حقاًل بحجم ‪ 4‬مح ارف للع دد ‪ ،5‬وأعطين ا حقاًل بحجم ‪16‬‬

‫بيا)‪ .‬وكم ا رأين ا من ن اتج المث ال الس ابق‪ ،‬يتم‬


‫للسلسلة النصية ‪( balloons‬ألنه ا سلس لة طويل ة نس ً‬

‫افتراضيا إلى اليسار واألعداد إلى اليمين‪ ،‬يمكن ك أن ُتغيِّ ر من ه ذا بوض ع‬


‫ً‬ ‫محاذاة السالسل النصية‬

‫رم ز خ اص للمح اذاة بع د النقط تين الرأس يتين مباش ً‬


‫رة‪ .‬إذ س يؤدي الرم ز > إلى مح اذاة النص إلى‬

‫ِّ‬
‫فسيوس ط النص في الحق ل‪ ،‬والرم ز < س يؤدي إلى محاذات ه إلى اليمين‪.‬‬ ‫يس ار الحق ل‪ ،‬أم ا الرم ز ^‬

‫ِّ‬
‫ونوسط السلسلة النصية‪:‬‬ ‫لنجعل محاذاة العدد إلى اليسار‬

‫))"‪print("Sammy has {0:<4} red {1:^16}!".format(5, "balloons‬‬

‫الناتج‪:‬‬

‫‪Sammy has 5‬‬ ‫‪red‬‬ ‫‪balloons‬‬ ‫!‬

‫أن مح اذاة الع دد ‪ 5‬إلى اليس ار‪ ،‬مم ا يعطي مس احة فارغ ًة في الحق ل قب ل‬
‫نالح ظ اآلن َّ‬

‫الكلمة ‪ ،red‬وستظهر السلس لة النص ية ‪ balloons‬في منتص ف الحق ل وتوج د مس افة فارغ ة على‬

‫يمينه ا ويس ارها‪ .‬عن دما ُن ِّ‬


‫نس ق الحق ل لنجعل ه أك بر من حجم ه الط بيعي فس تمأل ب ايثون الحق ل‬

‫رف آخ ر بوض عه مباش ً‬


‫رة بع د‬ ‫افتراض ًيا بالفراغ ات‪ ،‬إال َّ‬
‫أنن ا نس تطيع تغي ير مح رف الملء إلى مح ٍ‬

‫النقطتين الرأسيتين‪:‬‬

‫))"‪print("{:*^20s}".format("Sammy‬‬

‫الناتج‪:‬‬

‫▲‬ ‫|‬ ‫‪163‬‬


‫البرمجة بلغة بايثون‬ ‫مدخل إلى تنسيق النصوص‬

‫********‪*******Sammy‬‬

‫ستض ع ب ايثون السلس لة النص ية المُ م رَّ رة إلى الدال ة )(‪ str.format‬ذات الفه رس ‪ 0‬مك ان‬

‫القوس ين المعقوص ين َّ‬


‫ألنن ا لم نطلب منه ا عكس ذل ك‪ ،‬ومن ثم سنض ع النقط تين الرأس يتين ثم‬

‫ِّ‬
‫سنوسط السلسلة النصية عبر‬ ‫حدد أننا سنستعمل المحرف * بداًل من الفراغات لملء الحقل‪ ،‬ثم‬
‫س ُن ِّ‬

‫أن حجم الحق ل ه و ‪ 20‬مح رف‪ ،‬ومُ ش يرين في نفس ال وقت إلى َّ‬
‫أن‬ ‫اس تعمال الرم ز ^ مُ ح ِّددين َّ‬

‫ي ع بر وض ع الرم ز ‪ .s‬يمكنن ا اس تخدام ه ذه المع امالت م ع المع امالت ال تي‬ ‫ٌ‬


‫الحق ل ه و حق ل نص ٌ‬

‫استخدمناها وشرحناها في األقسام السابقة‪:‬‬

‫‪print("Sammy ate {0:5.0f} percent of a‬‬


‫))‪pizza!".format(75.765367‬‬

‫الناتج‪:‬‬

‫‪Sammy ate‬‬ ‫!‪76 percent of a pizza‬‬

‫ِّ‬
‫حد دنا داخل القوسين المعقوصين رقم فهرس القيمة العددية ثم وضعنا النقطتين الرأسيتين‬

‫ثم اخترن ا حجم الحق ل ثم وض عنا نقط ًة‪ .‬لنض بط ع دد المن ازل العش رية الظ اهرة‪ ،‬ثم نخت ار ن وع‬

‫الحقل عبر رمز التحويل ‪.f‬‬

‫‪ .9‬استخدام المتغيرات‬
‫مرَّ رنا منذ بداية هذا الفصل وإلى اآلن األعداد والسالسل النص ية إلى الدال ة )(‪str.format‬‬

‫ً‬
‫أيضا‪ ،‬وذلك بنفس اآللية المعتادة‪:‬‬ ‫ً‬
‫مباشرة‪ ،‬لكنَّنا نستطيع تمرير المتغيرات‬

‫‪nBalloons = 8‬‬
‫))‪print("Sammy has {} balloons today!".format(nBalloons‬‬

‫▲‬ ‫|‬ ‫‪164‬‬


‫البرمجة بلغة بايثون‬ ‫مدخل إلى تنسيق النصوص‬

‫الناتج‪:‬‬

‫!‪Sammy has 8 balloons today‬‬

‫ً‬
‫أيضا استخدام المتغيِّ رات لتخ زين السلس لة النص ية األص لية باإلض افة إلى القيم ال تي‬ ‫يمكننا‬

‫ُ‬
‫ستمرَّ ر إلى الدالة‪:‬‬

‫"!‪sammy = "Sammy has {} balloons today‬‬


‫‪nBalloons = 8‬‬
‫))‪print(sammy.format(nBalloons‬‬

‫الناتج‪:‬‬

‫!‪Sammy has 8 balloons today‬‬

‫ستس ِّهل المتغ يرات من التعام ل م ع تعب يرات التنس يق ُ‬


‫وت ِّ‬
‫بس ط عملي ة إس ناد م دخالت‬ ‫ُ‬

‫نس ً‬
‫قة في السلسلة النصية النهائية‪.‬‬ ‫المستخدم وإظهارها مُ َّ‬

‫‪ .10‬خالصة الفصل‬
‫ش رحنا في ه ذا الفص ل ع ِّدة طرائ ق لتنس يق النص وص والسالس ل النص ية في ب ايثون ‪3‬؛‬

‫وعرفن ا كي ف ُن ِ‬
‫ظه ر السالس ل النص ية كم ا نري د ع بر اس تخدامنا لمح ارف الته ريب أو السالس ل‬

‫النصية الخام والمُ ِّ‬


‫نسقات‪ ،‬لكي يستفيد المستخدم من النص الناتج ويقرأه بسهولة‪.‬‬

‫▲‬ ‫|‬ ‫‪165‬‬


‫العمليات الحسابية‬
‫‪9‬‬

‫▲‬ ‫|‬ ‫‪166‬‬


‫البرمجة بلغة بايثون‬ ‫العمليات الحسابية‬

‫ٌ‬
‫شائعة ج ًدا في البرمجة‪ ،‬إذ ُتستخدم لتمثيل مختلف القيم‪ ،‬مثل أبعاد حجم الشاش ة‪،‬‬ ‫األعداد‬

‫والمواقع الجغرافية‪ ،‬والمبالغ المالية‪ ،‬ومقدار الوقت الذي مر منذ بداية فيديو‪ ،‬واأللوان وغير ذلك‪.‬‬

‫تع د الق درة على تنفي ذ العملي ات الرياض ية بفعالي ة في البرمج ة مه ارة مهم ة‪َّ ،‬‬
‫ألنك األع داد‬

‫س تكون في متن اول األي دي دومً ا‪ .‬الفهم الجي د للرياض يات يمكن أن يس اعدك على أن تص بح‬

‫أنه ليس ش ً‬
‫رطا أساس ًيا‪ .‬فالرياض يات أداة لتحقي ق م ا ت رغب في تحقيق ه‪،‬‬ ‫مبرمج ا أفض ل‪ ،‬إال َّ‬
‫ً‬

‫وطريقة لتحسين آلية التنفيذ‪.‬‬

‫س نعمل م ع أك ثر ن وعي البيان ات اس تخدامً ا في ب ايثون‪ ،‬وهم ا األع داد الص حيحة‬

‫واألعداد العشرية‪:‬‬

‫األعداد الصحيحة هي أعداد كاملة يمكن أن تكون موجبة أو سالبة أو معدومة مثل‬ ‫•‬
‫(‪.)... ،1 ، 0 ، 1- ،...‬‬

‫األع داد العش رية هي أع داد حقيقي ة تحت وي على فاص لة عش رية (كم ا في ‪9.0‬‬ ‫•‬
‫أو ‪.)-2.25‬‬

‫س نلقي في ه ذا الفص ل نظ ً‬
‫رة على العوام ل (‪ )operators‬ال تي يمكن اس تخدامها م ع أن واع‬

‫البيانات العددية في بايثون‪.‬‬

‫‪ .1‬العامالت‬
‫عملية حس ابية‪ ،‬إذ ج اءت تس مية عام ل من عملي ة‪،‬‬
‫َّ‬ ‫العامل (‪ )operator‬هو رمز أو دالة تمث ل‬

‫عملية‪ .‬على س بيل المث ال‪ ،‬في الرياض يات‪ ،‬عالم ة الجم ع أو ‪ +‬هي العام ل‬
‫َّ‬ ‫أي العام ل ال ذي يج ري‬

‫الذي يجري عملية الجمع‪.‬‬

‫▲‬ ‫|‬ ‫‪167‬‬


‫البرمجة بلغة بايثون‬ ‫العمليات الحسابية‬

‫في ب ايثون‪ ،‬س نرى بعض الع امالت المألوف ة‪ ،‬وال تي اس ُتعيرَ ت من الرياض يات‪ ،‬لكن هن اك‬

‫عامالت أخرى خاصة بمجال البرمجة‪.‬‬

‫الجدول التالي مرجعٌ سريعٌ للعامالت الحسابية في بايثون‪ .‬سنغطي جميع هذه العملي ات في‬

‫هذا الفصل‪.‬‬

‫الناتج‬ ‫العملية‬

‫مجموع ‪ x‬و ‪y‬‬ ‫‪x + y‬‬

‫طرح‪ x‬من ‪y‬‬ ‫‪x - y‬‬

‫عكس إشارة ‪x‬‬ ‫‪-x‬‬

‫نفس قيمة ‪x‬‬ ‫‪+x‬‬

‫ضرب‪ x‬بـ ‪y‬‬ ‫‪x * y‬‬

‫قسمة ‪ x‬على ‪y‬‬ ‫‪x / y‬‬

‫حاصل القسمة التحتية لـ ‪ x‬على ‪y‬‬ ‫‪x // y‬‬

‫باقي قسمة ‪ x‬على ‪y‬‬ ‫‪x % y‬‬

‫‪ x‬أس ‪y‬‬ ‫‪x ** y‬‬

‫ً‬
‫أيض ا عن ع امالت اإلس ناد المركب ة (‪ ،)compound assignment operators‬بم ا‬ ‫س نتحدث‬

‫حسابيا مع العامل =‪.‬‬


‫ً‬ ‫في ذلك =‪ +‬و =*‪ ،‬التي تجمع عاماًل‬

‫▲‬ ‫|‬ ‫‪168‬‬


‫البرمجة بلغة بايثون‬ ‫العمليات الحسابية‬

‫‪ .2‬الجمع والطرح‬
‫في ب ايثون‪ ،‬يعم ل مع امال الجم ع والط رح مث ل م ا ه و مع روف في الرياض يات‪ .‬في الواق ع‪،‬‬

‫ً‬
‫حاسبة‪.‬‬ ‫يمكنك استخدام لغة بايثون ً‬
‫آلة‬

‫بدءا من األعداد الصحيحة‪:‬‬


‫ً‬ ‫لنلق نظرة على بعض األمثلة‪،‬‬
‫ِ‬

‫)‪print(1 + 5‬‬

‫والناتج‪:‬‬

‫‪6‬‬

‫ب داًل من تمري ر أع داد ص حيحة مباش رة إلى الدال ة ‪ ،print‬يمكنن ا تهيئ ة المتغ يرات‬

‫بأعداد صحيحة‪:‬‬

‫‪a = 88‬‬
‫‪b = 103‬‬

‫)‪print(a + b‬‬

‫وسينتج لنا‪:‬‬

‫‪191‬‬

‫ً‬
‫أيض ا)‪ ،‬ل ذلك يمكنن ا إض افة‬ ‫األع داد الص حيحة يمكن أن تك ون موجب ة أو س البة (أو معدوم ة‬

‫عدد سالب إلى عدد موجب‪:‬‬

‫‪c = -36‬‬
‫‪d = 25‬‬

‫)‪print(c + d‬‬ ‫‪#‬‬ ‫‪-11‬‬

‫▲‬ ‫|‬ ‫‪169‬‬


‫البرمجة بلغة بايثون‬ ‫العمليات الحسابية‬

‫ً‬
‫مشابها مع األعداد العشرية‪:‬‬ ‫الجمع سيكون‬

‫‪e = 5.5‬‬
‫‪f = 2.5‬‬

‫)‪print(e + f‬‬ ‫‪#‬‬ ‫‪8.0‬‬

‫إذا جمعنا عددين عشريين معً ا‪ ،‬ستعيد بايثون عد ًدا عشريًّ ا‪.‬‬

‫ص ياغة الط رح تش به ص ياغة الجم ع‪ ،‬م ا ع دا أن ك ستس تبدل بعام ل الط رح (‪)-‬‬

‫عامل الجمع (‪:)+‬‬

‫‪g = 75.67‬‬
‫‪h = 32‬‬

‫)‪print(g - h‬‬ ‫‪#‬‬ ‫‪43.67‬‬

‫صحيحا من عدد عش ري‪ .‬س تعيد ب ايثون ع د ًدا عش ريًّ ا إذا ك ان أح د األع داد‬
‫ً‬ ‫هنا‪ ،‬طرحنا عد ًدا‬

‫المتضمنة في المعادلة عشريًّ ا‪.‬‬

‫‪ .3‬العمليات الحسابية األحادية‬


‫يتكون التعبير الرياضي األحادي ( ‪ )unary mathematical expression‬من مك ِّون أو عنص ر‬

‫واح د فق ط‪ ،‬ويمكن في ب ايثون اس تخدام العالم تين ‪ +‬و ‪ -‬بمفردهم ا ع بر قرنهم ا بقيم ة إلع ادة‬

‫القيمة نفسها (عبر العامل ‪ ،)+‬أو تغيير إشارة القيمة (عبر العامل ‪. )-‬‬

‫أنها ال ُتستخدم كثيرًا ‪ -‬إلى هوية القيمة ( ‪،)identity of the value‬‬


‫تشير عالمة الجمع ‪ -‬رغم َّ‬

‫أي تعيد القيمة نفسها‪ .‬يمكننا استخدام عالمة الجمع مع القيم الموجبة‪:‬‬

‫‪i = 3.3‬‬
‫)‪print(+i‬‬ ‫‪#‬‬ ‫‪3.3‬‬

‫▲‬ ‫|‬ ‫‪170‬‬


‫البرمجة بلغة بايثون‬ ‫العمليات الحسابية‬

‫ُ‬
‫فستعاد القيمة نفسها‪ ،‬وفي هذه الحالة ستكون‬ ‫عندما نستخدم عالمة الجمع مع قيمة سالبة‪،‬‬

‫ً‬
‫أيضا‪:‬‬ ‫قيمة سالبة‬

‫‪j = -19‬‬
‫)‪print(+j‬‬ ‫‪#‬‬ ‫‪-19‬‬

‫عالم ة الط رح‪ ،‬على خالف عالم ة الجم ع‪ ،‬تغيِّ ر إش ارة القيم ة‪ .‬ل ذلك‪ ،‬عن دما نض عها م ع قيم ة‬

‫موجبة‪ُ ،‬‬
‫ستعاد القيمة السالبة منها‪:‬‬

‫‪i = 3.3‬‬
‫)‪print(-i‬‬ ‫‪#‬‬ ‫‪-3.3‬‬

‫بالمقاب ل‪ ،‬عن دما نس تخدم عام ل الط رح األح ادي ( ‪ )minus sign unary operator‬م ع قيم ة‬

‫ُ‬
‫فستعاد القيمة الموجبة منها‪:‬‬ ‫سالبة‪،‬‬

‫‪j = -19‬‬
‫)‪print(-j‬‬ ‫‪# 19‬‬

‫ُ‬
‫ستع ِيد العمليتان الحسابيتان األحاديتان ‪ +‬و ‪ -‬إمَّ ا هوية القيمة المعطاة‪ ،‬أو القيمة المعاكس ة‬

‫في اإلشارة للقيمة المعطاة على التوالي‪.‬‬

‫‪ .4‬الضرب والقسمة‬
‫مث ل الجم ع والط رح‪ ،‬الض رب والقس مة في ب ايثون مش ابهان لم ا ه و مع روف في الرياض يات‪.‬‬

‫عالمة الضرب في بايثون هي *‪ ،‬وعالمة القسمة هي ‪./‬‬

‫فيما يلي مثال على ضرب عددين عشريين في بايثون‪:‬‬

‫‪k = 100.1‬‬

‫▲‬ ‫|‬ ‫‪171‬‬


‫البرمجة بلغة بايثون‬ ‫العمليات الحسابية‬

‫‪l = 10.1‬‬

‫)‪print(k * l‬‬ ‫‪#‬‬ ‫‪1011.0099999999999‬‬

‫عن دما ُتج رَ ى عملي ة القس مة في ب ايثون ‪ ،3‬فس يكون الع دد المُ ع اد دائمً ا عش ريًّ ا‪ ،‬ح تى ل و‬

‫استخدمت عددين صحيحين‪:‬‬

‫‪m = 80‬‬
‫‪n = 5‬‬

‫)‪print(m / n‬‬ ‫‪#‬‬ ‫‪16.0‬‬

‫هذا أحد االختالفات الرئيسية بين بايثون ‪ 2‬و بايثون ‪ .3‬اإلجابة في بايثون ‪ 3‬تك ون كس رية‪،‬‬

‫فستعاد القيمة ‪ .5.5‬أمَّ ا في بايثون ‪ ،2‬فحاصل التعبير‬


‫ُ‬ ‫فعند استخدام ‪ /‬لتقسيم ‪ 11‬على ‪ 2‬مثاًل ‪،‬‬

‫‪ 11/2‬هو ‪.5‬‬

‫يُ ج ِري العامل ‪ /‬في بايثون ‪ 2‬قسمة عملية القسمة مع تقريب الن اتج إلى أص غر ع دد ص حيح‬

‫له (ه ذه العملي ة ت دعى القس مة التقريبي ة [‪ ،)]floor division‬إذ َّ‬


‫أنه إن ك ان حاص ل القس مة‬

‫يساوي ‪ ،x‬فسيكون ناتج عملية القس مة في ب ايثون ‪ 2‬أك بر ع دد من األع داد الص حيحة األص غر من‬

‫نفذت المث ال )‪ print(80 / 5‬أعاله في ب ايثون ‪ 2‬ب داًل من ب ايثون ‪ ،3‬فس يكون‬
‫أو تس اوي ‪ .x‬إذا َّ‬

‫الناتج هو ‪ ،16‬دون الجزء العشري‪.‬‬

‫في ب ايثون ‪ ،3‬يمكن ك اس تخدام العام ل ‪ //‬إلج راء القس مة التقريبي ة‪ .‬التعب ير ‪100 // 40‬‬

‫س يعيد القيم ة ‪ .2‬القس مة التحتي ة مفي دة في ح ال كنت تري د أن يك ون حاص ل القس مة‬

‫ً‬
‫صحيحا‪.‬‬ ‫عد ًدا‬

‫▲‬ ‫|‬ ‫‪172‬‬


‫البرمجة بلغة بايثون‬ ‫العمليات الحسابية‬

‫‪ .5‬عامل باقي القسمة (‪)Modulo‬‬


‫العام ل ‪ %‬ه و ب اقي القس مة (‪ ،)modulo‬وال ذي يُ رج ع ب اقي عملي ة القس مة‪ .‬ه ذا مفي د للعث ور‬

‫على األعداد التي هي مضاعفات لنفس العدد‪ .‬المثال التالي يوضح كيفية استخدام عامل الباقي‪:‬‬

‫‪o = 85‬‬
‫‪p = 15‬‬

‫)‪print(o % p‬‬ ‫‪#‬‬ ‫‪10‬‬

‫حاص ل قس مة ‪ 85‬على ‪ 15‬ه و ‪ ،5‬والب اقي ‪ .10‬القيم ة ‪ 10‬هي ال تي س ُتعاد هن ا َّ‬


‫ألن عام ل‬

‫الباقي يعيد باقي عملية القسمة‪.‬‬

‫فسيعاد عدد عشري‪:‬‬


‫ُ‬ ‫إذا استخدمنا عددين عشريين مع عامل الباقي‪،‬‬

‫‪q = 36.0‬‬
‫‪r = 6.0‬‬

‫)‪print(o % p‬‬ ‫‪#‬‬ ‫‪0.0‬‬

‫باق‪ ،‬لذلك تعاد القيمة ‪.0.0‬‬


‫في حال قسمة ‪ 36.0‬على ‪ ،6.0‬فلن يكون هناك ٍ‬

‫‪ .6‬القوة (‪)Power‬‬
‫ً‬
‫أحيانا «األس») في بايثون لرفع الع دد األيس ر لق وة األس‬ ‫يُ ستخدم عامل القوة ** (يقال له‬

‫للع دد األيمن‪ .‬وه ذا يع ني أن ه في التعب ير ‪ ،5 ** 3‬الع دد ‪ 5‬س ُي َ‬


‫رفع إلى الق وة ‪ .3‬في الرياض يات‪،‬‬

‫غالبا ما نرى ه ذا التعب ير يُ كتب على الش كل ‪ ،5³‬إذ يُ ض رب الع دد ‪ 5‬في نفس ه ‪ 3‬م رات‪ .‬في ب ايثون‪،‬‬
‫ً‬

‫التعبيران ‪ 5 ** 3‬و ‪ 5 * 5 * 5‬سيعطيان النتيجة نفسها‪.‬‬

‫سنستخدم في المثال التالي المتغيرات‪:‬‬

‫▲‬ ‫|‬ ‫‪173‬‬


‫البرمجة بلغة بايثون‬ ‫العمليات الحسابية‬

‫‪s = 52.25‬‬
‫‪t = 7‬‬

‫)‪print(s ** t‬‬ ‫‪#‬‬ ‫‪1063173305051.292‬‬

‫األس ** سينتج عنه عدد عشري كبير‪.‬‬


‫ّ‬ ‫رفع العدد العشري ‪ 52.25‬إلى القوة ‪ 7‬عبر عامل‬

‫‪ .7‬أسبقية العمليات الحسابية‬


‫أن المع امالت س ُت َّ‬
‫قيم‬ ‫في بايثون‪ ،‬كما هو الح ال في الرياض يات‪ ،‬علين ا أن نض ع في حس اباتنا َّ‬

‫ً‬
‫وفقا لنظام األسبقية‪ ،‬وليس من اليسار إلى اليمين‪ ،‬أو من اليمين إلى اليسار‪.‬‬

‫إذا نظرنا إلى التعبير التالي‪:‬‬

‫‪u = 10 + 10 * 5‬‬

‫أن عملي ة الض رب س ُتجرَ ى أواًل ‪ ،‬ل ذا إن اس تدعينا‬ ‫قد نقرأه من اليس ار إلى اليمين‪ ،‬ولكن ت َّ‬
‫ذكر َّ‬

‫)‪ ،print(u‬فسنحصل على القيمة التالية‪:‬‬

‫‪60‬‬

‫قيم أواًل ‪ ،‬وس ينتج عنه ا الع دد ‪ ،50‬ثم يض اف إليه ا الع دد ‪ 10‬لنحص ل‬
‫ألن ‪ 5 * 10‬س ُت َّ‬
‫ه ذا َّ‬

‫على ‪ 60‬في النهاية‪.‬‬

‫إذا أردنا بداًل من ذلك إضافة القيمة ‪ 10‬إلى ‪ ،10‬ثم ضرب المجموع في ‪ ،5‬فيمكننا استخدام‬

‫األقواس كما نفعل في الرياضيات تمامً ا‪:‬‬

‫‪u = (10 + 10) * 5‬‬


‫)‪print(u‬‬ ‫‪#‬‬ ‫‪100‬‬

‫▲‬ ‫|‬ ‫‪174‬‬


‫البرمجة بلغة بايثون‬ ‫العمليات الحسابية‬

‫إحدى الطرق البسيطة لتذكر األسبقيات هي حفظ البيتين التاليين لتذكر أوائل كلماتهما‪:‬‬

‫ً‬
‫طريقا‬ ‫ً‬
‫ضيقا ‪ ...‬قم جد‬ ‫قم أبعد‬

‫الحرف‬ ‫العملية‬ ‫األسبقية‬

‫قم‬ ‫القوس‬ ‫‪1‬‬

‫أبعد‬ ‫األس‬ ‫‪2‬‬

‫ً‬
‫ضيقا‬ ‫الضرب‬ ‫‪3‬‬

‫قم‬ ‫القسمة‬ ‫‪4‬‬

‫جد‬ ‫الجمع‬ ‫‪5‬‬

‫ً‬
‫طريقا‬ ‫الطرح‬ ‫‪6‬‬

‫‪ .8‬عامل اإلسناد (‪)Assignment Operators‬‬


‫أكثر عامل اإلسناد استخدامً ا هو إشارة التساوي =‪ .‬يُ سنِد عامل اإلسناد (أو عامل التعيين) =‬

‫القيم ة الموج ودة على يمين ه إلى المتغ ير الموض وع على يس اره‪ .‬على س بيل المث ال‪ُ ،‬تس نِد‬

‫التعليمة ‪ v = 23‬العدد الصحيح ‪ 23‬للمتغير ‪.v‬‬

‫من الشائع استخدام عامالت اإلس ناد المركب ة ال تي تج ري عملي ة رياض ية على قيم ة المتغ ير‪،‬‬

‫ثم ُتسنِد القيمة الجديدة الناتجة إلى ذلك المتغير‪ .‬تجمع عوامل اإلسناد المركبة بين عامل رياضي‬

‫والعام ل =؛ ففي ح ال الجم ع‪ ،‬نس تخدم ‪ +‬م ع = للحص ول على عام ل اإلس ناد الم ركب =‪ .+‬لنطبِّ ق‬

‫ذلك في مثال عملي‪:‬‬

‫▲‬ ‫|‬ ‫‪175‬‬


‫البرمجة بلغة بايثون‬ ‫العمليات الحسابية‬

‫‪w = 5‬‬
‫‪w += 1‬‬
‫)‪print(w‬‬ ‫‪#‬‬ ‫‪6‬‬

‫أوالً‪ُ ،‬نس نِد القيم ة ‪ 5‬إلى المتغ ير ‪ ،w‬ثم نس تخدم معام ل اإلس ناد الم ركب =‪ +‬إلض افة الع دد‬

‫الصحيح إلى قيمة المتغير األيسر‪ ،‬ثم ُنسنِد النتيجة إلى المتغير ‪.w‬‬

‫ُتس تخدم مع امالت اإلس ناد المركب ة اس تخدامً ا متك ررًا م ع حلق ات ‪ for‬التكرارية‪ ،‬وال تي‬

‫ستستخدمها عندما تريد تكرار عمليةٍ عدة مرات‪:‬‬

‫‪for x in range (0, 7):‬‬


‫‪x *= 2‬‬
‫)‪print(x‬‬

‫والناتج سيكون‪:‬‬

‫‪0‬‬
‫‪2‬‬
‫‪4‬‬
‫‪6‬‬
‫‪8‬‬
‫‪10‬‬
‫‪12‬‬

‫تمكن ا باس تخدام الحلق ة ‪ for‬من أتمت ة العملي ة =* ال تي تض رب قيم ة المتغ ير ‪ w‬بالع دد ‪ ،2‬ثم‬

‫ُتسنِد النتيجة إلى المتغير ‪ w‬ألجل استخدامها في التكرار التالي من الحلقة‪.‬‬

‫ل دى ب ايثون معام ل إس ناد م ركب مقاب ل لك ل من المع امالت الحس ابية ال تي تطرقن ا ً‬
‫آنف ا‬

‫إليها وهي‪:‬‬

‫▲‬ ‫|‬ ‫‪176‬‬


‫البرمجة بلغة بايثون‬ ‫العمليات الحسابية‬

‫‪y += 1‬‬ ‫إضافة القيمة ثم إسنادها ‪#‬‬


‫‪y -= 1‬‬ ‫طرح القيمة ثم إسنادها ‪#‬‬
‫‪y *= 2‬‬ ‫ضرب القيمة ثم إسنادها ‪#‬‬
‫‪y /= 3‬‬ ‫تقسيم القيمة ثم إسنادها ‪#‬‬
‫‪y // = 5‬‬ ‫تقسيم سفلي القيمة ثم إسنادها ‪#‬‬
‫‪y **= 2‬‬ ‫تنفيذ عامل األس على القيمة ثم إسنادها ‪#‬‬
‫‪y %= 3‬‬ ‫إعادة باقي قسمة القيمة ثم إسناده ‪#‬‬

‫يمكن أن يكون عامل اإلسناد المركب مفي ًدا عندما تحتاج إلى الزيادة أو اإلنق اص الت دريجي‪،‬‬

‫أو عندما تحتاج إلى أتمتة عمليات معينة في برنامجك‪.‬‬

‫‪ .9‬إجراء العمليات الرياضية عبر الدوال‬


‫بع د أن تعرفن ا كيفي ة إج راء العملي ات الرياض ية ع بر العوام ل (‪ ،)opreators‬سنس تعرض في‬

‫هذا القسم بعض الدوال الرياضية المُ ضمَّ نة ال تي يمكن اس تخدامها م ع أن واع البيان ات العددي ة في‬

‫ب ايثون ‪ .3‬فتتض مّ ن ب ايثون ‪ 3‬العدي د من ال دوال ال تي يمكن ك اس تخدامها بس هولة في أي برن امج‪.‬‬

‫ت تيح ل ك بعض تل ك ال دوال تحوي ل أن واع البيان ات‪ ،‬والبعض اآلخ ر خ اص بن وع معين‪ ،‬مث ل‬

‫السالسل النصية‪.‬‬

‫سنلقي نظرة على الدوال التالية‪:‬‬

‫)(‪ :abs‬للحصول على القيمة المطلقة‬ ‫•‬

‫)(‪ :divmod‬للحصول على الحاصل والباقي في وقت واحد‬ ‫•‬

‫)(‪ :pow‬لرفع عدد لقوة معينة‬ ‫•‬

‫)(‪ :round‬لتقريب عدد بمنازل عشرية محددة‬ ‫•‬

‫قابل للتكرار (‪)iterable‬‬


‫ٍ‬ ‫)(‪ :sum‬لحساب مجموع العناصر في كائن‬ ‫•‬

‫▲‬ ‫|‬ ‫‪177‬‬


‫البرمجة بلغة بايثون‬ ‫العمليات الحسابية‬

‫فهم ه ذه ال دوال س يمنحك مرون ة أك بر في التعام ل م ع البيان ات العددي ة‪ ،‬ويس اعدك على‬

‫اتخاذ قرارات مدروسة عند تحديد العوامل والدوال التي عليك استخدامها‪.‬‬

‫ا‪ .‬القيمة المطلقة‬

‫تعي د الدال ة المض مّ نة )(‪ abs‬القيم ة المطلق ة للع دد ال ذي يُ م رر إليه ا‪ .‬في الرياض يات‪ ،‬تش ير‬

‫القيمة المطلقة إلى العدد نفسه إن كانت القيمة موجبة‪ ،‬أو القيمة المعاكسة إن كانت القيمة سالبة‪.‬‬

‫مثاًل ‪ ،‬القيمة المطلقة للعدد ‪ 15‬هي ‪ ،15‬والقيمة المطلقة للعدد ‪ -74‬هي ‪ ،74‬والقيمة المطلق ة‬

‫للعدد ‪ 0‬هي ‪.0‬‬

‫القيم ة المطلق ة مفه وم مهم في الحس اب والتحلي ل‪ ،‬كم ا َّ‬


‫أنه ا مفي دة ك ذلك في المواق ف‬

‫اليومي ة‪ ،‬مث ل حس اب المس افة المقطوع ة‪ .‬على س بيل المث ال‪ ،‬إذا كنت تح اول الوص ول إلى مك ان‬

‫يبعد ‪ 58‬مياًل ‪ ،‬ولكنَّك تجاوزت ذلك المك ان‪ ،‬وس افرت ‪ 93‬فرس ًخا‪ .‬ف َّ‬
‫إن حس بت ع دد الفراس خ ال تي‬

‫ينبغي أن تقطعها اآلن للوصول إلى الوجهة المقصودة‪ ،‬فسوف ينتهي بك المطاف بعدد سالب‪ ،‬لكن‬

‫سالبا من الفراسخ!‬
‫ً‬ ‫ال يمكنك السفر عد ًدا‬

‫سنستخدم الدالة )(‪ abs‬لحل هذه المشكلة‪:‬‬

‫عدد الفراسخ التي تفصلنا عن الوجهة انطالقًا من الُ‬


‫منطلق ‪#‬‬
‫‪miles_from_origin = 58‬‬

‫ُنطَلق إلى الوجهة ‪#‬‬


‫الفراسخ المقطوعة من الم‬
‫‪miles_travelled = 93‬‬

‫حساب عدد الفراسخ من الموقع الحالي ‪#‬‬


‫‪miles_to_go = miles_from_origin - miles_travelled‬‬

‫طباعة عدد الفراسخ المتبقية بعدد سالب ‪#‬‬

‫▲‬ ‫|‬ ‫‪178‬‬


‫البرمجة بلغة بايثون‬ ‫العمليات الحسابية‬

‫)‪print(miles_to_go‬‬
‫حساب القيمة المطلقة للعدد السالب ‪#‬‬
‫))‪print(abs(miles_to_go‬‬

‫المخرجات ستكون‪:‬‬

‫‪-35‬‬
‫‪35‬‬

‫أن ‪miles_travelled‬‬
‫لوال استخدام الدالة )(‪ ،abs‬لحصلنا على ع دد س الب‪ ،‬أي ‪ .-35‬ورغم َّ‬

‫فإن الدالة )(‪ abs‬تحل إشكالية العدد السالب‪.‬‬


‫َّ‬ ‫أصغر من ‪،miles_from_origin‬‬

‫ألن القيم ة المطلق ة دائمً ا تعي د‬


‫موجب ا‪َّ ،‬‬
‫ً‬ ‫سالبا‪ ،‬ستعيد الدالة )(‪ abs‬ع د ًدا‬
‫ً‬ ‫عندما ِّ‬
‫نمرر لها عد ًدا‬

‫أعدا ًدا موجبة أو معدومة‪.‬‬

‫موجبا‪ ،‬وكذلك الصفر‪:‬‬


‫ً‬ ‫في المثال التالي‪ ،‬سنمرر للدالة )(‪ abs‬عد ًدا‬

‫))‪print(abs(89.9‬‬ ‫‪#‬‬ ‫‪89.9‬‬


‫))‪print(abs(0‬‬ ‫‪# 0‬‬

‫ب‪ .‬العثور على الحاصل والباقي بدالة واحدة‬

‫القس مة التقريبي ة (‪ ،floor division‬ال تي ُتعي د حاص ل القس مة [‪ ]quotient‬م ع تقريب ه)‪،‬‬

‫ً‬
‫ارتباط ا‬ ‫وقس مة الب اقي (‪ ،modulo division‬ال تي تعي د ب اقي القس مة [‪ ،)]remainder‬مرتبط ان‬

‫ً‬
‫وثيقا‪ ،‬وقد يكون من المفيد استخدام دالة تجمع بين العمليتين معً ا‪.‬‬

‫تجم ع الدال ة المض مَّ نة )(‪ divmod‬بين العملي تين‪ ،‬إذ تعي د أواًل حاص ل عملي ة القس مة‬

‫التقريبية‪ ،‬ثم الباقي‪ .‬ينبغي تمرير عددين إلى الدالة )(‪ ،divmod‬على النحو التالي‪:‬‬

‫)‪divmod(a,b‬‬

‫▲‬ ‫|‬ ‫‪179‬‬


‫البرمجة بلغة بايثون‬ ‫العمليات الحسابية‬

‫تكافئ هذه الدالة العمليتين التاليتين‪:‬‬

‫‪a // b‬‬
‫‪a & b‬‬

‫أننا كتبنا كتابًا يحتوي ‪ 80‬ألف كلمة‪ .‬يري د الناش ر أن تحت وي ك ل ص فحة من الكت اب‬
‫لنفترض َّ‬

‫ما بين ‪ 300‬و ‪ 250‬كلمة‪ ،‬ونود أن نعرف ع دد الص فحات ال تي ستش كل الكت اب بحس ب ع دد كلم ات‬

‫الص فحة ال ذي اخترن اه‪ .‬باس تخدام الدال ة )(‪ ،divmod‬يمكنن ا أن نع رف على الف ور ع دد الص فحات‬

‫في الكتاب‪ ،‬وعدد الكلمات المتبقية التي ُ‬


‫ستنقل إلى صفحة إضافية‪.‬‬

‫كم عدد الكلمات في كتابنا ‪#‬‬


‫‪words = 80000‬‬

‫الخيار ‪ :A‬عدد كلمات الصفحة هو ‪# 300‬‬


‫‪per_page_A = 300‬‬

‫الخيار ‪ :B‬عدد كلمات الصفحة هو ‪# 250‬‬


‫‪per_page_B = 250‬‬

‫حساب الخيار ‪print(divmod(words,per_page_A)) # A‬‬


‫حساب الخيار ‪print(divmod(words,per_page_B)) # B‬‬

‫وسينتج عن هذه الشيفرة‪:‬‬

‫)‪(266, 200‬‬
‫)‪(320, 0‬‬

‫في الخيار ‪ ،A‬سنحص ل على ‪ 266‬ص فحة مليئ ة بالكلم ات‪ ،‬و ‪ 200‬كلم ة متبقي ة (ثلث ا ص فحة)‪،‬‬

‫والمجموع هو ‪ 267‬صفحة‪ ،‬وفي الخيار ‪ ،B‬سنحص ل على كت اب من ‪ 320‬ص فحة‪ .‬إن أردن ا الحف اظ‬

‫▲‬ ‫|‬ ‫‪180‬‬


‫البرمجة بلغة بايثون‬ ‫العمليات الحسابية‬

‫على البيئة‪ ،‬فالخيار ‪ A‬قد يكون أفضل‪ ،‬ولكن إذا أردن ا تص ميمً ا ج ذابًا‪ ،‬أو الكتاب ة بحجم خ ط كب ير‪،‬‬

‫فقد نختار الخيار "‪."B‬‬

‫تقبل الدالة )(‪ divmod‬األع داد الص حيحة واألع داد العش رية‪ ،‬في المث ال الت الي س ُن ِّ‬
‫مرر ع د ًدا‬

‫عشريًّ ا إلى الدالة )(‪:divmod‬‬

‫‪a = 985.5‬‬
‫‪b = 115.25‬‬

‫))‪print(divmod(a,b‬‬ ‫‪#‬‬ ‫)‪(8.0, 63.5‬‬

‫في هذا المثال‪ ،‬العدد ‪ 8.0‬ه و حاص ل القس مة التحتي ة للع دد ‪ 985.5‬مقس ومً ا على ‪،115.25‬‬

‫و ‪ 63.5‬هو الباقي‪.‬‬

‫ُّ‬
‫للتحقق من نتيجة )(‪:divmod‬‬ ‫يمكنك استخدام عامل القسمة التحتية ‪ //‬و عامل الباقي ‪%‬‬

‫)‪print(a//b‬‬ ‫‪#‬‬ ‫‪8.0‬‬


‫)‪print(a%b‬‬ ‫‪# 63.5‬‬

‫ج‪ .‬القوة (‪)Power‬‬

‫في بايثون‪ ،‬يمكنك استخدام عامل القوة ** (أو األس) لرفع عدد إلى ق وة معين ة‪ ،‬أو يمكن ك‬

‫استخدام الدالة )(‪ pow‬المضمَّ نة التي تأخذ عددين وتجري العملية نفسها‪.‬‬

‫ً‬
‫أبحاثا على البكتيريا‪ ،‬ونريد أن نق َّدر ع دد‬ ‫كيفية عمل الدالة )(‪ ،pow‬لنقل َّ‬
‫أننا نجري‬ ‫َّ‬ ‫لتوضيح‬

‫البكتيريا التي سنحصل عليها في نهاية اليوم إذا بدأنا ببكتيريا واحدة‪.‬‬

‫أن البكتيريا التي نعمل عليها تتضاعف في كل ساعة‪ ،‬لذلك النتيجة النهائية ستكون‬
‫لنفترض َّ‬

‫‪ 2‬قوة العدد الكلي لعدد الساعات التي مرت (‪ 24‬في حالتنا)‪.‬‬

‫▲‬ ‫|‬ ‫‪181‬‬


‫البرمجة بلغة بايثون‬ ‫العمليات الحسابية‬

‫‪hours = 24‬‬
‫)‪total_bacteria = pow(2,hours‬‬

‫)‪print(total_bacteria‬‬ ‫‪# 16777216‬‬

‫لق د مرَّ رن ا ع ددين ص حيحين للدال ة )(‪ ،pow‬والنتيج ة ال تي حص لنا عليه ا‪ ،‬وال تي ِّ‬
‫تمثل ع دد‬

‫البكتيريا بحلول نهاية اليوم‪ ،‬هي أكثر من ‪ 16‬مليون بكتيريا‪.‬‬

‫أس ‪ "3‬بش كل ع ام على بالش كل ‪ 3³‬وال تي تك افئ ‪،3 × 3 × 3‬‬


‫في الرياض يات‪ ،‬نكتب "‪ّ 3‬‬

‫أي ‪ .27‬ولحس اب ‪ 3³‬في ب ايثون‪ ،‬نكتب )‪ ،pow(3,3‬إذ تقب ل الدال ة )(‪ pow‬األع داد الص حيحة‬

‫ِّ‬
‫وتوفر بدياًل لعامل األس **‪.‬‬ ‫واألعداد العشرية‪،‬‬

‫د‪ .‬تقريب األعداد‬

‫تقريب األعداد ( ‪ )Rounding Numbers‬ضروري عند العمل مع األعداد العشرية التي تحتوي‬

‫على الكث ير من المن ازل (األج زاء) العش رية‪ .‬تقب ل الدال ة المض منة )(‪ round‬ع ددين‪ :‬أح دها ِّ‬
‫يمثل‬

‫ِّ‬
‫يحدد عدد المنازل العشرية المراد اإلبقاء عليها (أي قيمة التقريب)‪.‬‬ ‫العدد المراد تقريبه واآلخر‬

‫سنستخدم هذه الدالة لتقريب عدد عشري له أكثر من ‪ 10‬منازل عشرية والحص ول على ع دد‬

‫بأربعة منازل عشرية فقط‪:‬‬

‫‪i = 17.34989436516001‬‬
‫))‪print(round(i,4‬‬ ‫‪# 17.3499‬‬

‫في المث ال أعاله‪ ،‬تم تق ريب الع دد ‪ 17.34989436516001‬إلى ‪َّ 17.3499‬‬


‫ألنن ا ح َّددنا‬

‫عدد المنازل العشرية التي ينبغي االقتصار عليها بأربعة‪.‬‬

‫▲‬ ‫|‬ ‫‪182‬‬


‫البرمجة بلغة بايثون‬ ‫العمليات الحسابية‬

‫أن الدال ة )(‪ round‬تق ِّرب األع داد إلى األعلى‪ ،‬ل ذا ب داًل من إع ادة ‪،17.3498‬‬ ‫ً‬
‫أيض ا َّ‬ ‫الح ظ‬

‫ألن ال رقم ال ذي يلي الم نزل العش ري ‪ 8‬ه و ال رقم ‪ .9‬وس يقرَّ ب أي ع دد‬
‫فق د أع ادت ‪َّ ،17.3499‬‬

‫متبوع بالعدد ‪ 5‬أو أكبر إلى العدد الصحيح التالي‪.‬‬

‫المالية؛ فال يمكنن ا‬


‫َّ‬ ‫في الحياة اليومي ة‪ُ ،‬نق ِّرب األع داد ألس باب كث يرة‪ ،‬وخاص ة في التع امالت‬

‫تقسيم فلس واحد بالتساوي بين عدة أصدقاء مثال‪.‬‬

‫ِّ‬
‫نحدد في ه قيم‬ ‫س نكتب في المث ال الت الي برنامج ا بس يطا يمكن ه حس اب البقش يش‪ ،‬إذ س‬

‫المتغ يرات‪ ،‬ولكن يمكن ك إع ادة كتاب ة البرن امج لجع ل المس تخدمين ي دخلون القيم بأنفس هم‪ .‬في‬

‫ه ذا المث ال‪ ،‬ذهب ‪ 3‬أص دقاء إلى مطعم‪ ،‬وأرادوا تقس يم الف اتورة‪ ،‬وال تي تبل غ ‪ 87.93‬دوال ًرا‬

‫بالتساوي‪ ،‬باإلضافة إلى إكرامية (بقشيش) بنسبة ‪:٪20‬‬

‫‪bill = 87.93‬‬ ‫إجمالي الفاتورة ‪#‬‬


‫‪tip = 0.2‬‬ ‫بقشيش ‪# ٪ 20‬‬
‫‪split = 3‬‬ ‫عدد الناس الذين سيتشاركون الفاتورة ‪#‬‬

‫حساب الفاتورة اإلجمالية ‪#‬‬


‫)‪total = bill + (bill * tip‬‬
‫حساب ما ينبغي أن يدفعه كل شخص ‪#‬‬
‫‪each_pay = total / split‬‬
‫ما ينبغي أن يدفعه كل شخص قبل التقريب ‪#‬‬
‫)‪print(each_pay‬‬
‫تقريب العدد فال يمكننا تقسيم الفلسات ‪#‬‬
‫))‪print(round(each_pay,2‬‬

‫والمخرجات ستكون‪:‬‬

‫‪35.172000000000004‬‬
‫‪35.17‬‬

‫▲‬ ‫|‬ ‫‪183‬‬


‫البرمجة بلغة بايثون‬ ‫العمليات الحسابية‬

‫في هذا البرنامج‪ ،‬نطلب أواًل إخراج العدد بعد حساب إجمالي الف اتورة واإلكرامي ات مقس ومً ا‬

‫على ‪ ،3‬النتيجة ستكون عد ًدا يتض مَّ ن الكث ير من المن ازل العش رية‪.35.172000000000004 :‬‬

‫واقعيا‪َّ ،‬‬
‫فإنن ا نس تخدم الدال ة )(‪ ،round‬ونق ِّرب المن ازل‬ ‫ًّ‬ ‫مالي ا‬
‫ً‬ ‫ً‬
‫مبلغ ا‬ ‫ألن ه ذا الع دد ال ِّ‬
‫يمثل‬ ‫نظ رًا َّ‬

‫َّ‬
‫نتمكن من توفير ناتج يمكن لألصدقاء الثالثة أن يدفعوه‪.35.17 :‬‬ ‫العشرية على ‪ ،2‬حتى‬

‫إذا كنت تفض ل التق ريب إلى ع دد بال من ازل عش رية‪ ،‬يمكن ك تمري ر ‪ 0‬كمعام ل ث ان إلى‬

‫الدالة )(‪:round‬‬

‫)‪round(345.9874590348545304636,0‬‬

‫القيمة الناتجة ستكون ‪.346.0‬‬

‫ً‬
‫أيضا تمرير األعداد الصحيحة إلى )(‪ round‬دون الخ وف من تلقي خط أ‪ ،‬وه ذا مفي د‬ ‫يمكنك‬

‫حيحا ب داًل من ع دد عش ري‪ .‬وفي ه ذه الحال ة‪ ،‬س ُيعاد‬


‫ً‬ ‫في ح ال تلقيت من المس تخدم ع د ًدا ص‬

‫عدد صحيح‪.‬‬

‫ه‪ .‬حساب المجموع‬

‫ة‬ ‫َّ‬
‫المركب‬ ‫ات العدديَّ ة‬ ‫واع البيان‬ ‫اميع أن‬ ‫اب مج‬ ‫ة )(‪ sum‬لحس‬ ‫تخ َدم الدال‬ ‫ُتس‬

‫(‪ ،)numeric compound data types‬بما في ذلك القوائم‪ ،‬والصفوف‪ ،‬والقواميس‪.‬‬

‫يمكننا تمرير قائمة إلى الدالة )(‪ sum‬لجمع كل عناصرها بالترتيب من اليسار إلى اليمين‪:‬‬

‫]‪some_floats = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9‬‬
‫))‪print(sum(some_floats‬‬ ‫‪#‬‬ ‫‪49.5‬‬

‫▲‬ ‫|‬ ‫‪184‬‬


‫البرمجة بلغة بايثون‬ ‫العمليات الحسابية‬

‫نفس النتيجة سنحصل عليها إن استخدمنا الصفوف والقواميس‪:‬‬

‫حساب مجموع األعداد في الصف ‪#‬‬


‫)))‪print(sum((8,16,64,512‬‬
‫حساب مجموع األعداد في القاموس ‪#‬‬
‫))}'‪print(sum({-10: 'x', -20: 'y', -30: 'z‬‬

‫المخرجات‪:‬‬

‫‪60‬‬
‫‪-60‬‬

‫سيضاف إلى المجموع الناتج‪:‬‬


‫يمكن أن تأخذ الدالة )(‪ sum‬وسيطين‪ ،‬الوسيط الثاني ُ‬

‫]‪some_floats = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9‬‬

‫))‪print(sum(some_floats, 0.5‬‬ ‫‪# 50.0‬‬


‫))‪print(sum({-10: 'x', -20: 'y', -30: 'z'},60‬‬ ‫‪# 0‬‬

‫القيمة االفتراضية للوسيط الثاني هي ‪.0‬‬

‫‪ .10‬خالصة الفصل‬
‫َّ‬
‫غطينا في هذا الفصل العديد من العوام ل وال دوال ال تي ستس تخدمها م ع األع داد الص حيحة‬

‫والعش رية إلج راء أهم العملي ات الرياض ية وال زال هنال ك الكث ير منه ا‪ ،‬فننص حك بزي ارة توثي ق‬

‫العملي ات العددي ة في ب ايثون وتوثي ق األن واع العددي ة في ب ايثون في موس وعة حس وب لمزي د‬

‫من التفاصيل‪.‬‬

‫▲‬ ‫|‬ ‫‪185‬‬


‫‪10‬‬
‫العمليات المنطقية‬
‫(البوليانية)‬

‫▲‬ ‫|‬ ‫‪186‬‬


‫البرمجة بلغة بايثون‬ ‫العمليات المنطقية (البوليانية)‬

‫هن اك قيمت ان فق ط لن وع البيان ات المنطقية‪ ،‬وهم ا ‪ True‬و ‪ُ .False‬تس تخ َدم الحس ابات‬

‫المنطقية في البرمجة إلجراء الموازنات‪ ،‬والتحكم في مسار البرنامج‪.‬‬

‫ِّ‬
‫تمثل القيم المنطقي ة قيم الحقيق ة ( ‪ )truth values‬في علم المنط ق في الرياض يات‪ٌ ،‬‬
‫وتكتَب‬

‫القيمت ان ‪ True‬و ‪ False‬دائمً ا ب الحرفين الكب يرين ‪ T‬و ‪ F‬على الت والي‪ ،‬أل َّنهم ا قيمت ان خاص تان‬

‫المنطقية في ب ايثون‪ ،‬بم ا في ذل ك الموازن ة‬


‫َّ‬ ‫في ب ايثون‪ .‬س نتعرف في ه ذا الفص ل على العملي ات‬

‫المنطقية‪ ،‬وجداول الحقيقة‪.‬‬


‫َّ‬ ‫المنطقية‪ ،‬والعوامل‬
‫َّ‬

‫‪ .1‬عامل الموازنة‬
‫في البرمج ة‪ُ ،‬تس تخ َدم ع امالت الموازن ة ( ‪ )comparison operators‬للموازن ة بين القيم‪،‬‬

‫وتعي د إح دى القيم تين المنطق تين ‪ True‬و ‪ .False‬يوض ح الج دول أدن اه ع امالت‬

‫الموازنة المنطقية‪:‬‬

‫الشرح‬ ‫العامل‬

‫يساوي‬ ‫==‬

‫يخالف‬ ‫!=‬

‫أصغر من‬ ‫<‬

‫أكبر من‬ ‫>‬

‫أصغر من أو يساوي‬ ‫<=‬

‫أكبر من أو يساوي‬ ‫>=‬

‫▲‬ ‫|‬ ‫‪187‬‬


‫البرمجة بلغة بايثون‬ ‫العمليات المنطقية (البوليانية)‬

‫لفهم كيفية عمل هذه العامالت‪ ،‬سنستخدم المتغيرين التاليين‪:‬‬

‫‪x = 5‬‬
‫‪y = 8‬‬

‫في هذا المثال‪ ،‬لمَّ ا كان ‪ x‬يساوي ‪ ،5‬فهو أصغر من ‪ y‬ذي القيمة ‪.8‬‬

‫ِّ‬
‫سنجرب أحد الع امالت من الج دول أعاله‪.‬‬ ‫باستخدام هذين المتغيرين والقيم المرتبطة بهما‪،‬‬

‫س نطلب من ب ايثون أن تطب ع ن اتج عملي ة الموازن ة‪ ،‬إمَّ ا ‪ True‬أو ‪ .False‬لتوض يح المث ال أك ثر‪،‬‬

‫سنطبع سلسلة نصية لتوضيح ما جرى تقييمه‪.‬‬

‫‪x = 5‬‬
‫‪y = 8‬‬

‫)‪print("x == y:", x == y‬‬


‫)‪print("x != y:", x != y‬‬
‫)‪print("x < y:", x < y‬‬
‫)‪print("x > y:", x > y‬‬
‫)‪print("x <= y:", x <= y‬‬
‫)‪print("x >= y:", x >= y‬‬

‫والمخرجات هي‪:‬‬

‫‪x == y: False‬‬
‫‪x != y: True‬‬
‫‪x < y: True‬‬
‫‪x > y: False‬‬
‫‪x <= y: True‬‬
‫‪x >= y: False‬‬

‫باتباع المنطق الرياضي‪ ،‬في كل من التعبيرات المذكورة أعاله‪ ،‬هذه نتيجة الموازنات‪:‬‬

‫‪( 5‬قيمة ‪ )x‬تساوي ‪( 8‬قيمة ‪)y‬؟ ‪ ،False‬خطأ‬ ‫•‬

‫▲‬ ‫|‬ ‫‪188‬‬


‫البرمجة بلغة بايثون‬ ‫العمليات المنطقية (البوليانية)‬

‫‪ 5‬تخالف ‪8‬؟ ‪ ،True‬صحيح‬ ‫•‬

‫‪ 5‬أصغر من ‪8‬؟ ‪ ،True‬صحيح‬ ‫•‬

‫‪ 5‬أكبر من ‪8‬؟ ‪ ،False‬خطأ‬ ‫•‬

‫‪ 5‬أصغر من أو يساوي ‪8‬؟ ‪ ،True‬صحيح‬ ‫•‬

‫‪ 5‬ليس أصغر من أو يساوي ‪8‬؟ ‪ ،False‬خطأ‬ ‫•‬

‫رغم استخدامنا لألعداد الصحيحة هنا‪ ،‬إال َّ‬


‫أن ه بإمكاننا استبدال األعداد العشرية بها‪.‬‬

‫ً‬
‫أيضا استخدام السالسل النصية مع المعامالت المنطقية‪ .‬وهي حساسة لحالة األحرف‪،‬‬ ‫يمكن‬

‫افيا للسالس ل النص ية‪ ،‬ويوض ح المث ال الت الي كيفي ة موازن ة‬
‫ً‬ ‫م ا لم تس تخدم تابعً ا إض‬

‫السالسل النصية‪:‬‬

‫"‪Sammy = "Sammy‬‬
‫"‪sammy = "sammy‬‬

‫)‪print("Sammy == sammy: ", Sammy == sammy‬‬ ‫‪# Sammy == sammy:‬‬


‫‪False‬‬

‫السلس لة "‪ "Sammy‬أعاله ال تس اوي السلس لة النص ية "‪َّ ،"sammy‬‬


‫ألنهم ا ليس تا متم اثلتين‬

‫تمامً ا؛ فإح داهما تب دأ بح رف كب ير ‪ ،S‬واألخ رى بح رف ص غير ‪ .s‬ولكن ل و أض فنا متغ يرًا آخ ر‬

‫قيمته "‪ ،"Sammy‬فستكونان متساويتين‪:‬‬

‫"‪Sammy = "Sammy‬‬
‫"‪sammy = "sammy‬‬
‫"‪also_Sammy = "Sammy‬‬

‫▲‬ ‫|‬ ‫‪189‬‬


‫البرمجة بلغة بايثون‬ ‫العمليات المنطقية (البوليانية)‬

‫)‪print("Sammy == sammy: ", Sammy == sammy‬‬


‫‪# Sammy == sammy:‬‬ ‫‪False‬‬
‫)‪print("Sammy == also_Sammy", Sammy == also_Sammy‬‬
‫‪# Sammy == also_Sammy:‬‬ ‫‪True‬‬

‫ً‬
‫أيض ا اس تخدام ع امالت الموازن ة األخ رى‪ ،‬بم ا في ذل ك > و < لموازن ة سلس لتين‬ ‫يمكن ك‬

‫نص يتين‪ .‬س توازن ب ايثون ه ذه السالس ل النص ية بحس ب ال ترتيب المعجمي في نظ ام‬

‫ً‬
‫أيضا تقييم القيم المنطقية باستخدام عامالت الموازنة‪:‬‬ ‫محارف ‪ .ASCII‬ويمكنك‬

‫‪t = True‬‬
‫‪f = False‬‬

‫)‪print("t != f: ", t != f‬‬ ‫‪#‬‬ ‫‪t != f:‬‬ ‫‪True‬‬

‫تبيِّ ن الشيفرة البرمجية أعاله َّ‬


‫أن ‪ True‬ال تساوي ‪.False‬‬

‫الحظ الفرق بين العاملين = و ==‪.‬‬

‫‪x = y‬‬ ‫إسناد قيمة ‪ y‬إلى ‪# x‬‬


‫‪x == y‬‬ ‫و ‪ x‬متساويين ‪#‬‬ ‫تتحقق مما إذا كان ‪y‬‬

‫ِّ‬
‫يحدد قيم ة أح د المتغ يرين‪،‬‬ ‫األول =‪ ،‬هو عام ل اإلس ناد (‪ ،)assignment operator‬وال ذي س‬

‫ِّ‬
‫يحدد م ا إذا ك انت‬ ‫ويجعله ا مس اوية لقيم ة اآلخ ر‪ .‬الث اني ==‪ ،‬وه و عام ل الموازن ة ال ذي س‬

‫القيمتان متساويتين‪.‬‬

‫‪ .2‬العامالت المنطقية‬
‫هن اك ثالث ة ع امالت منطقي ة (‪ُ )Boolean operators‬تس تخدم لموازن ة القيم‪ .‬وتعي د إمَّ ا‬

‫‪ True‬أو ‪ .False‬ه ذه الع امالت هي‪( and ،‬و)‪ ،‬و ‪( or‬أو)‪ ،‬و ‪( not‬النفي)‪ ،‬وق د عرَّ فناه ا في‬

‫الجدول أدناه‪.‬‬

‫▲‬ ‫|‬ ‫‪190‬‬


‫البرمجة بلغة بايثون‬ ‫العمليات المنطقية (البوليانية)‬

‫الصياغة‬ ‫الشرح‬ ‫العامل‬

‫إن كان كال التعبيرين صحيحين‬


‫‪x and y‬‬ ‫‪and‬‬
‫‪True‬‬

‫إن كان أحد التعبيرين على األقل‬


‫‪x or y‬‬ ‫‪or‬‬
‫ً‬
‫صحيحا ‪True‬‬

‫‪not x‬‬ ‫إن كان التعبير خطأ ‪True‬‬ ‫‪not‬‬

‫ع ً‬
‫ادة م ا ُتس تخ َدم الع امالت المنطقي ة لتق ييم م ا إذا ك ان تعب يران منطقي ان ص حيحين أم ال‪.‬‬

‫على سبيل المثال‪ ،‬يمكن استخدامها لتحديد ما إذا كان الط الب ق د نجح‪َّ ،‬‬
‫وأنه مُ س جل في الفص ل‪،‬‬

‫فسي َ‬
‫ضاف الطالب إلى سجل النظام‪ .‬مثال آخ ر ه و تحدي د م ا‬ ‫ُ‬ ‫وإذا كانت كلتا الحالتان صحيحتين‪،‬‬

‫ً‬
‫نشطا لمتجر إلكتروني استنا ًدا إلى ما إذا ك ان لدي ه رص يد في المتج ر‪ ،‬أو‬ ‫إذا كان المستخدم عمياًل‬

‫َّ‬
‫أنه اشترى خالل األشهر الستة الماضية‪.‬‬

‫كيفية عمل العامالت المنطقية‪ ،‬دعنا نقيِّ م التعابير الثالث التالية‪:‬‬


‫َّ‬ ‫لفهم‬

‫))‪print((9 > 7) and (2 < 4‬‬ ‫كال التعبيرين صحيحان ‪#‬‬


‫))‪print((8 == 8) or (6 != 6‬‬ ‫أحد التعبيرين صحيح ‪#‬‬
‫))‪print(not(3 <= 1‬‬ ‫التعبير األصلي خطأ ‪#‬‬

‫والمخرجات هي‪:‬‬

‫‪True‬‬
‫‪True‬‬
‫‪True‬‬

‫▲‬ ‫|‬ ‫‪191‬‬


‫البرمجة بلغة بايثون‬ ‫العمليات المنطقية (البوليانية)‬

‫في الحال ة األولى‪ ،print((9 > 7) and (2 < 4)) ،‬ينبغي أن يك ون كال التعب يرين‬

‫ألن المعامل ‪ and‬مُ ستخ َدم‪.‬‬


‫‪ 9 > 7‬و ‪ 2 < 4‬صحيحين لتكون النتيجة ‪َّ True‬‬

‫أن قيم ة ‪ُ 8 == 8‬قيِّ مت‬


‫في الحال ة الثاني ة‪ ،print((8 == 8) or (6 != 6)) ،‬بم ا َّ‬

‫يقيم إليه التعب ير ‪ .6 != 6‬لكن ل و اس تخدمنا العام ل ‪ٌ ،and‬‬


‫لقيِّ م التعب ير إلى‬ ‫إلى ‪ ،True‬فال يهم ما َّ‬

‫القيمة ‪.False‬‬

‫في الحال ة الثالث ة‪ ،print(not(3 <= 1)) ،‬ينفي العام ل ‪ not‬القيم ة ‪ False‬ال تي تعي دها‬

‫ناتج العملية المنطقية ‪.1 =< 3‬‬

‫في المثال التالي‪ ،‬سنستبدل باألعداد العشرية أعدا ًدا صحيحة‪:‬‬

‫))‪print((-0.2 > 1.4) and (0.8 < 3.1‬‬ ‫أحد التعبيرين خطأ ‪#‬‬
‫))‪print((7.5 == 8.9) or (9.2 != 9.2‬‬ ‫كال التعبيرين خطأ ‪#‬‬
‫))‪print(not(-5.7 <= 0.3‬‬ ‫التعبير األصلي صحيح ‪#‬‬

‫في المثال أعاله‪:‬‬

‫‪ :and‬يجب أن يكون واحد على األقل من التعبيرين خطأ ليعيد القيمة ‪،False‬‬ ‫•‬

‫‪ :or‬يجب أن يكون كال التعبيرين خطأ لتعيد القيمة ‪،False‬‬ ‫•‬

‫ً‬
‫صحيحا حتى يعيد القيمة ‪.False‬‬ ‫‪ :not‬يجب أن يكون التعبير المرافق له‬ ‫•‬

‫إذا لم تكن النت ائج أعاله واض حة‪ ،‬فس نعرض بعض ج داول الحقيق ة أدن اه لتفهم األم ر‬

‫فهمً ا أفضل‪.‬‬

‫أيضا كتابة عبارات مُ َّ‬


‫ركبة باستخدام ‪ ،and‬و ‪ ،or‬و ‪:not‬‬ ‫ً‬ ‫يمكنك‬

‫)))‪not((-0.2 > 1.4) and ((0.8 < 3.1) or (0.1 == 0.1‬‬

‫▲‬ ‫|‬ ‫‪192‬‬


‫البرمجة بلغة بايثون‬ ‫العمليات المنطقية (البوليانية)‬

‫ألن كال‬
‫التعب ير ال داخلي‪ )0.1 == 0.1( or )3.1 < 0.8( :‬يعي د القيم ة ‪َّ ،True‬‬

‫َّ‬
‫محققان‪ ،‬أي يعيدان ‪.True‬‬ ‫التعبيرين الرياضيين‬

‫اآلن‪ ،‬نأخذ القيمة المُ عادة ‪ True‬ونجمعها مع التعبير المنطقي التالي‪:‬‬

‫)‪(-0.2> 1.4) and (True‬‬

‫يقيم إلى القيم ة ‪،False‬‬


‫‪َّ -0.2‬‬ ‫>‬ ‫ألن التعب ير ‪1.4‬‬
‫ه ذا المث ال يعي د ‪َّ ،False‬‬

‫و )‪ (False) and (True‬ينتج عنه القيمة ‪.False‬‬

‫أخيرًا‪ ،‬يعيد التعبير الخارجي‪ not (False) :‬القيمة ‪ ،True‬وبالتالي ستكون القيمة النهائي ة‬

‫المعادة هي‪:‬‬

‫‪True‬‬

‫‪ .3‬جداول الحقيقة (‪)Truth Tables‬‬


‫المنطق مجال واسع‪ ،‬وسنكتفي في هذا الفصل ببعض األفك ار المهمَّ ة ال تي يمكن أن تس اعدك‬

‫على تحسين طريقة تفكيرك وخوارزمياتك‪.‬‬

‫فيما يلي جداول الحقيقة لمعامل الموازنة ==‪ ،‬والمع امالت المنطقي ة ‪ ,and‬و ‪ ,or‬و ‪ .not‬من‬

‫كيفية عمله ا‪ ،‬ف ذلك س يجعلك أس رع في اتخ اذ الق رارات أثن اء كتاب ة‬
‫َّ‬ ‫المفي د أن تحف ظ‬

‫الشيفرات البرمجية‪.‬‬

‫▲‬ ‫|‬ ‫‪193‬‬


‫البرمجة بلغة بايثون‬ )‫العمليات المنطقية (البوليانية‬

== ‫ جدول الحقيقة الخاص بالعامل‬.‫ا‬

‫القيمة المُ عادة‬ y == x

True True == True

False False == True

False True == False

True False == False

AND ‫ جدول الحقيقة الخاص بالعامل‬.‫ب‬

‫القيمة المُ عادة‬ y and x

True True and True


False False and True
False True and False
False False and False

OR ‫ جدول الحقيقة الخاص بالعامل‬.‫ج‬

‫القيمة المُ عادة‬ y or x

True True or True


True False or True
True True or False
False False or False

▲ | 194
‫البرمجة بلغة بايثون‬ ‫العمليات المنطقية (البوليانية)‬

‫د‪ .‬جدول الحقيقة الخاص بالعامل ‪NOT‬‬

‫القيمة المُ عادة‬ ‫‪not‬‬ ‫‪x‬‬

‫‪False‬‬ ‫‪not‬‬ ‫‪True‬‬


‫‪True‬‬ ‫‪not‬‬ ‫‪False‬‬

‫ُتس تخ َدم ج داول الحقيق ة في المنط ق الرياض ياتي كث يرًا‪ ،‬وهي مفي دة‪ ،‬ويجب حفظه ا‬

‫ووضعها في الحسبان عند إنشاء الخوارزميات البرمجية‪.‬‬

‫‪ .4‬استعمال المنطق للتحكم في مسار البرنامج‬


‫رطية (‪،)flow control statements‬‬
‫َّ‬ ‫للتحكم في مس ار ونت ائج البرن امج ع بر التعليم ات الش‬

‫يمكننا استخدام «شرط» (‪ )condition‬متبوعً ا «بعبارة برمجية» (‪.)clause‬‬

‫قيم الش رط بإح دى القيم تين ‪ True‬أو ‪ ،False‬و ُتس تخ َدم تل ك القيم ة في اتخ اذ ق رار في‬
‫يُ َّ‬

‫البرن امج‪ .‬أمَّ ا العب ارة (‪ )clause‬فهي الكتل ة البرمجي ة ال تي تعقب الش رط وتح ِّدد نتيج ة البرن امج‬

‫وما ينبغي فعله في حال تحقق الشرط أو عدمه‪.‬‬

‫ُتظه ر الش يفرة أدن اه مث ااًل على مع امالت الموازن ة ال تي تعم ل م ع العب ارات الش رطية للتحكم‬

‫في مسار البرنامج‪:‬‬

‫‪if grade >= 65:‬‬ ‫شرط ‪#‬‬


‫)"‪print("Passing grade‬‬ ‫بند ‪#‬‬

‫‪else:‬‬
‫)"‪print("Failing grade‬‬

‫▲‬ ‫|‬ ‫‪195‬‬


‫البرمجة بلغة بايثون‬ ‫العمليات المنطقية (البوليانية)‬

‫ِّ‬
‫يحدد ه ذا البرن امج م ا إذا ك ان الط الب س ينجح أم يرس ب‪ .‬في ح ال ك انت الدرج ة ال تي‬ ‫س‬

‫حص ل عليه ا الط الب تس اوي ‪ 83‬مثاًل ‪ ،‬تق ييم العب ارة األولى س يكون ‪ ،True‬وس ُي َ‬
‫طبع النص‬

‫"‪ ."Passing grade‬أمَّ ا إن كانت درجة الطالب هي ‪ ،59‬فتق ييم العب ارة األولى س يكون ‪،False‬‬

‫الفرع ‪ ،else‬أي‬ ‫ةب‬ ‫ة المرتبط‬ ‫ذ التعليم‬ ‫امج لتنفي‬ ‫ينتقل البرن‬ ‫الي س‬ ‫وبالت‬

‫سيطبع "‪."Failing grade‬‬

‫يمكن تقييم كل كائنات بايثون بإحدى القيمتين ‪ True‬أو ‪ ،False‬لذلك يوصي الدليل ‪PEP 8‬‬

‫ألن ذلك قد يؤدي إلى إعادة قيم منطقية غير‬


‫بعدم موازنة كائن بإحدى القيمتين ‪ True‬أو ‪ّ ،False‬‬

‫َّ‬
‫متوقع ة‪ .‬على س بيل المث ال‪ ،‬علي ك تجنب اس تخدام مث ل ه ذا التعب ير ‪sammy == True‬‬

‫في برامجك‪.‬‬

‫المنطقية على ص ياغة ش روط يمكن اس تخدامها لتحدي د النتيج ة النهائي ة‬


‫َّ‬ ‫تس اعد الع امالت‬

‫للبرنامج من خالل التحكم في مسار التنفيذ‪.‬‬

‫‪ .5‬خالصة الفصل‬
‫ألقين ا في ه ذا الفص ل نظ رة على الموازن ات والع امالت المنطقي ة‪ ،‬باإلض افة إلى ج داول‬

‫الحقيقة‪ ،‬وكيفية استخدام القيم المنطقية للتحكم في مسار البرنامج‪.‬‬

‫▲‬ ‫|‬ ‫‪196‬‬


‫‪11‬‬
‫النوع ‪ :List‬مدخل‬
‫إلى القوائم‬

‫▲‬ ‫|‬ ‫‪197‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :List‬مدخل إلى القوائم‬

‫الن وع ‪( list‬القائمة) هي بني ة بيان ات في ب ايثون‪ ،‬وهي عب ارة عن تسلس ل مُ َّ‬


‫رتب قاب ل‬

‫وكيفية استخدامها‪.‬‬
‫َّ‬ ‫للتغيير من تجميعة عناصر‪ .‬سنتعرف في هذا الفصل على القوائم وتوابعها‬

‫ِّ‬
‫تمكنك من تجمي ع البيان ات المتش ابهة‪ ،‬أو ال تي‬ ‫القوائم مناسبة لتجميع العناصر المترابطة‪ ،‬إذ‬

‫معين ا معً ا‪ ،‬وت رتيب الش يفرة البرمجي ة‪ ،‬وتنفي ذ التواب ع والعملي ات على ع دة قيم في‬
‫َّ‬ ‫ً‬
‫غرض ا‬ ‫تخدم‬

‫وقت واحد‪.‬‬

‫تساعد القوائم في بايثون وغيره ا من هياك ل البيان ات المركب ة على تمثي ل التجميع ات‪ ،‬مث ل‬

‫تجميع ة ملف ات في مجل د على حاس وبك‪ ،‬أو ق وائم التش غيل‪ ،‬أو رس ائل البري د اإللك تروني‬

‫وغير ذلك‪.‬‬

‫ً‬
‫قائمة تحتوي على عناصر من نوع السالسل النصية‪:‬‬ ‫في المثال التالي‪ ،‬سننشئ‬

‫‪sea_creatures = ['shark', 'cuttlefish', 'squid', 'mantis‬‬


‫]'‪shrimp', 'anemone‬‬

‫عندما نطبع القائمة‪ ،‬فستشبه المخرجات القائمة التي أنشأناها‪:‬‬

‫)‪print(sea_creatures‬‬

‫الناتج‪:‬‬

‫]'‪['shark', 'cuttlefish', 'squid', 'mantis shrimp', 'anemone‬‬

‫أي عنص ر من القائم ة ع بر الفهرس ة‪.‬‬


‫مرتب ا من العناص ر‪ ،‬يمكن اس تدعاء ِّ‬
‫ً‬ ‫بوص فها تسلس اًل‬

‫َّ‬
‫مركب ة تت ألف من أج زاء أص غر‪ ،‬وتتم يز بالمرون ة‪ ،‬إذ يمكن إض افة عناص ر إليه ا‪،‬‬ ‫القوائم هي بيانات‬

‫وإزالته ا‪ ،‬وتغييره ا‪ .‬عن دما تحت اج إلى تخ زين الكث ير من القيم‪ ،‬أو التك رار ( ‪ )iterate‬عليه ا‪ ،‬وتري د‬

‫أن تملك القدرة على تعديل تلك القيم بسهولة‪ ،‬فالقوائم هي خيارك األفضل‪.‬‬

‫▲‬ ‫|‬ ‫‪198‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :List‬مدخل إلى القوائم‬

‫‪ .1‬فهرسة القوائم (‪)Indexing Lists‬‬


‫رس ذل ك العنص ر‪ ،‬وال ذي ه و ع دد ص حيح‪ ،‬فه رس‬
‫كل عنصر في القائمة يقابل ه رقم يمث ل فه َ‬

‫العنصر األول في القائمة هو ‪.0‬‬

‫إليك تمثيل لفهارس القائمة ‪:sea_creatures‬‬

‫‪shark‬‬ ‫‪shark‬‬ ‫‪squid‬‬ ‫‪shrimp‬‬ ‫‪anemone‬‬

‫‪0‬‬ ‫‪1‬‬ ‫‪2‬‬ ‫‪3‬‬ ‫‪4‬‬

‫يب دأ العنص ر األول‪ ،‬أي السلس لة النص ية ‪ ،shark‬عن د الفه رس ‪ ،0‬وتنتهي القائم ة عن د‬

‫الفهرس ‪ 4‬الذي يقابل العنصر ‪.anemone‬‬

‫ألن كل عنصر في قوائم بايثون يقابل ه رقم فه رس‪ ،‬يمكنن ا الوص ول إلى عناص ر الق وائم‬
‫نظرًا َّ‬

‫ومعالجتها كما نفعل مع أنواع البيانات المتسلسلة األخرى‪.‬‬

‫يمكننا اآلن استدعاء عنصر من القائمة من خالل رقم فهرسه‪:‬‬

‫)]‪print(sea_creatures[1‬‬ ‫‪#‬‬ ‫‪cuttlefish‬‬

‫َّ‬
‫موضح في الجدول أعاله‪ .‬المث ال‬ ‫تتراوح أرقام الفهارس في هذه القائمة بين ‪ 0‬و ‪ ،4‬كما هو‬

‫ِّ‬
‫يوضح ذلك‪:‬‬ ‫التالي‬

‫'‪sea_creatures[0] = 'shark‬‬
‫'‪sea_creatures[1] = 'cuttlefish‬‬
‫'‪sea_creatures[2] = 'squid‬‬
‫'‪sea_creatures[3] = 'mantis shrimp‬‬
‫'‪sea_creatures[4] = 'anemone‬‬

‫▲‬ ‫|‬ ‫‪199‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :List‬مدخل إلى القوائم‬

‫إذا اس تدعينا القائم ة ‪ sea_creatures‬ب رقم فه رس أك بر من ‪ ،4‬فس يكون الفه رس خ ارج‬

‫وسي َ‬
‫طلق الخطأ ‪:IndexError‬‬ ‫ُ‬ ‫النطاق‪،‬‬

‫)]‪print(sea_creatures[18‬‬

‫والمخرجات ستكون‪:‬‬

‫‪IndexError: list index out of range‬‬

‫أيض ا الوص ول إلى عناص ر القائم ة بفه ارس س البة‪ ،‬وال تي ُت َ‬


‫حس ب من نهاي ة القائم ة‪،‬‬ ‫ً‬ ‫يمكنن ا‬

‫بدءا من ‪ .-1‬هذا مفيد في حال كانت لدينا قائمة طويلة‪ ،‬وأردنا تحديد عنصر في نهايته‪.‬‬
‫ً‬

‫بالنسبة للقائمة ‪ ،sea_creatures‬تبدو الفهارس السالبة كما يلي‪:‬‬

‫‪anemone‬‬ ‫‪shrimp‬‬ ‫‪squid‬‬ ‫‪cuttlefish‬‬ ‫‪shark‬‬

‫‪-1‬‬ ‫‪-2‬‬ ‫‪-3‬‬ ‫‪-4‬‬ ‫‪-5‬‬

‫في المثال التالي‪ ،‬سنطبع العنصر ‪ squid‬باستخدام فهرس سالب‪:‬‬

‫)]‪print(sea_creatures[-3‬‬ ‫‪#‬‬ ‫‪squid‬‬

‫يمكننا ضم (‪ )concatenate‬سلسلة نصية مع سلسلة نصية أخرى باستخدام العامل ‪:+‬‬

‫)]‪print('Sammy is a ' + sea_creatures[0‬‬ ‫‪# Sammy is a shark‬‬

‫ً‬
‫أيض ا اس تخدام‬ ‫لقد ضممنا السلسلة النصية ‪ Sammy is a‬مع العنص ر ذي الفه رس ‪ .0‬يمكنن ا‬

‫ِّ‬
‫لضم قائمتين أو أكثر معً ا (انظر الفقرة أدناه)‪.‬‬ ‫المعامل ‪+‬‬

‫أي عنصر من عناصر القائمة والعمل عليه‪.‬‬


‫تساعدنا الفهارس على الوصول إلى ِّ‬

‫▲‬ ‫|‬ ‫‪200‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :List‬مدخل إلى القوائم‬

‫‪ .2‬تعديل عناصر القائمة‬


‫يمكنن ا اس تخدام الفهرس ة لتغي ير عناص ر القائم ة‪ ،‬عن طري ق إس ناد قيم ة إلى عُ نص ر مُ فه رس‬

‫ّ‬
‫ويسهل تعديل وتحديث عناصرها‪.‬‬ ‫من القائمة‪ .‬هذا يجعل القوائم أكثر مرونة‪،‬‬

‫إذا أردن ا تغي ير قيم ة السلس لة النص ية للعنص ر الموج ود عن د الفه رس ‪ ،1‬من القيم ة‬

‫‪ cuttlefish‬إلى ‪ ،octopus‬فيمكننا القيام بذلك على النحو التالي‪:‬‬

‫'‪sea_creatures[1] = 'octopus‬‬

‫اآلن‪ ،‬عندما نطبع ‪ ،sea_creatures‬ستكون النتيجة‪:‬‬

‫)‪print(sea_creatures‬‬ ‫‪# ['shark', 'octopus', 'squid', 'mantis‬‬


‫]'‪shrimp', 'anemone‬‬

‫ً‬
‫أيضا تغيير قيمة عنصر باستخدام فهرس سالب‪:‬‬ ‫يمكننا‬

‫'‪sea_creatures[-3] = 'blobfish‬‬
‫)‪print(sea_creatures‬‬ ‫‪#‬‬ ‫‪['shark', 'octopus', 'blobfish',‬‬
‫]'‪'mantis shrimp', 'anemone‬‬

‫اآلن اس تبدلنا بالسلس لة ‪ squid‬السلس لة النص ية ‪ blobfish‬الموج ودة عن د الفه رس‬

‫السالب ‪( -3‬والذي يقابل الفهرس الموجب ‪.)2‬‬

‫‪ .3‬تقطيع القوائم (‪)Slicing Lists‬‬


‫يمكنن ا أيض ا اس تدعاء ع دة عناص ر من القائم ة‪ .‬لنف ترض َّ‬
‫أنن ا ن رغب في طباع ة العناص ر‬

‫الموج ودة في وس ط القائم ة ‪ ،sea_creatures‬يمكنن ا القي ام ب ذلك عن طري ق اقتط اع ش ريحة‬

‫(جزء) من القائمة‪.‬‬

‫▲‬ ‫|‬ ‫‪201‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :List‬مدخل إلى القوائم‬

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

‫بنقطتين [‪:]x: y‬‬

‫)]‪print(sea_creatures[1:4‬‬ ‫‪# ['octopus', 'blobfish', 'mantis‬‬


‫]'‪shrimp‬‬

‫عند إنشاء شريحة‪ ،‬كما في [‪ ،]1: 4‬يبدأ االقتطاع من العنصر ذي الفهرس األول (مشموال)‪،‬‬

‫وينتهي عن د العنص ر ذي الفه رس الث اني (غ ير مش مول)‪ ،‬له ذا ُطبعَ ت في مثالن ا أعاله العناص ر‬

‫الموجودة في المواضع‪ ،1 ،‬و ‪ ،2‬و ‪.3‬‬

‫الفهرسين في التعبير [‪ .]x: y‬على‬


‫َ‬ ‫إذا أردنا تضمين أحد طرفي القائمة‪ ،‬فيمكننا حذف أحد‬

‫س بيل المث ال‪ ،‬إذا أردن ا طباع ة العناص ر الثالث ة األولى من القائم ة ‪ ،sea_creatures‬يمكنن ا فع ل‬

‫ذلك عن طريق كتابة‪:‬‬

‫)]‪print(sea_creatures[:3‬‬ ‫‪#‬‬ ‫‪['shark', 'octopus',‬‬


‫]'‪'blobfish‬‬

‫لق د ُطبعَ ت العناص ر من بداي ة القائم ة ّ‬


‫حتى العنص ر ذي الفه رس ‪ .3‬لتض مين جمي ع العناص ر‬

‫الموجودة في نهاية القائمة‪ ،‬سنعكس الصياغة‪:‬‬

‫)]‪print(sea_creatures[2:‬‬ ‫‪#‬‬ ‫‪['blobfish', 'mantis shrimp',‬‬


‫]'‪'anemone‬‬

‫ً‬
‫أيض ا اس تخدام الفه ارس الس البة عن د اقتط اع الق وائم‪ ،‬تمامً ا كم ا ه و الح ال م ع‬ ‫يمكنن ا‬

‫الفهارس الموجبة‪:‬‬

‫)]‪print(sea_creatures[-4:-2‬‬ ‫‪#‬‬ ‫]'‪['octopus', 'blobfish‬‬


‫)]‪print(sea_creatures[-3:‬‬ ‫‪#‬‬ ‫‪['blobfish', 'mantis‬‬
‫]'‪shrimp', 'anemone‬‬

‫▲‬ ‫|‬ ‫‪202‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :List‬مدخل إلى القوائم‬

‫هن اك معام ل آخ ر يمكنن ا اس تخدامه في االقتط اع‪ ،‬ويش ير إلى ع دد العناص ر ال تي يجب أن‬

‫تخطيها (الخطوة) بعد استرداد العنصر األول من القائم ة‪ .‬ح تى اآلن‪ ،‬لق د أغفلن ا المعام ل ‪،stride‬‬

‫وس تعطيه ب ايثون القيم ة االفتراض ية ‪ ،1‬م ا يع ني َّ‬


‫أنه س يتم اس ترداد ك ل العناص ر الموج ودة بين‬

‫الفهرسين المحددين‪.‬‬
‫َ‬

‫س تكون الص ياغة على الش كل الت الي [‪ ،]x: y: z‬إذ يش ير ‪ z‬إلى الخط وة (‪ .)stride‬في‬

‫المثال التالي‪ ،‬سننشئ قائمة كبيرة‪ ،‬ثم نقتطعها‪ ،‬مع خطوة اقتطاع تساوي ‪:2‬‬

‫]‪numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12‬‬

‫)]‪print(numbers[1:11:2‬‬ ‫‪#‬‬ ‫]‪[1, 3, 5, 7, 9‬‬

‫س يطبع التعب ير ]‪ numbers[1: 11: 2‬القيم ذات الفه ارس المحص ورة بين ‪( 1‬مش مولة)‬

‫و ‪( 11‬غير مشمولة)‪ ،‬وسيقفز البرنامج بخطوتين كل مرة‪ ،‬ويطبع العناصر المقابلة‪.‬‬

‫يمكنن ا ح ذف المُ ع املين األوَّ ل يين‪ ،‬واس تخدام الخط وة وح دها بع ِّدها مع اماًل وف ق الص ياغة‬

‫التالية‪:]::z[ :‬‬

‫)]‪print(numbers[::3‬‬ ‫‪#‬‬ ‫]‪[0, 3, 6, 9, 12‬‬

‫عن د طباع ة القائم ة ‪ numbers‬م ع تع يين الخط وة عن د القيم ة ‪ ،3‬فلن ُت َ‬


‫طب ع إال العناص ر ال تي‬

‫فهارس ها من مض اعفات ‪ .3‬يجع ل اس تخدام الفه ارس الموجب ة والس البة ومعام ل الخط وة في‬

‫اقتطاع القوائم التحكم في القوائم ومعالجتها أسهل وأكثر مرونة‪.‬‬

‫▲‬ ‫|‬ ‫‪203‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :List‬مدخل إلى القوائم‬

‫‪ .4‬تعديل القوائم بالعوامل‬


‫يمكن استخدام العوامل إلجراء تعديالت على القوائم‪ .‬س ننظر في اس تخدام الع املين ‪ +‬و *‬

‫ومقابليهما المركبين =‪ +‬و=*‪.‬‬

‫ِّ‬
‫لضم (‪ )concatenate‬قائمتين أو أكثر معً ا‪:‬‬ ‫يمكن استخدام العامل ‪+‬‬

‫‪sea_creatures = ['shark', 'octopus', 'blobfish', 'mantis‬‬


‫]'‪shrimp', 'anemone‬‬
‫‪oceans = ['Pacific', 'Atlantic', 'Indian', 'Southern',‬‬
‫]'‪'Arctic‬‬

‫)‪print(sea_creatures + oceans‬‬

‫والمخرجات هي‪:‬‬

‫‪['shark', 'octopus', 'blobfish', 'mantis shrimp', 'anemone',‬‬


‫]'‪'Pacific', 'Atlantic', 'Indian', 'Southern', 'Arctic‬‬

‫يمكن اس تخدام العام ل ‪ +‬إلض افة عنص ر (أو ع دة عناص ر) إلى نهاي ة القائم ة‪ ،‬لكن ت ذكر أن‬

‫تضع العنصر بين قوسين مربعين‪:‬‬

‫]'‪sea_creatures = sea_creatures + ['yeti crab‬‬


‫)‪print (sea_creatures‬‬ ‫‪#‬‬ ‫‪['shark', 'octopus', 'blobfish',‬‬
‫]'‪'mantis shrimp', 'anemone', 'yeti crab‬‬

‫ُ‬
‫يمكن اس تخدام العام ل * لمض اعفة الق وائم (‪ .)multiply lists‬ربم ا تحت اج إلى عم ل ن ِس ٍ‬
‫خ‬

‫لجميع الملفات الموجودة في مجلد على خادم‪ ،‬أو مشاركة قائمة أفالم مع األصدقاء؛ ستحتاج في‬

‫هذه الحاالت إلى مضاعفة مجموعات البيانات‪.‬‬

‫سنضاعف القائمة ‪ sea_creatures‬مرتين‪ ،‬والقائمة ‪ oceans‬ثالث مرات‪:‬‬

‫▲‬ ‫|‬ ‫‪204‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :List‬مدخل إلى القوائم‬

‫)‪print(sea_creatures * 2‬‬
‫)‪print(oceans * 3‬‬

‫والنتيجة ستكون‪:‬‬

‫‪['shark', 'octopus', 'blobfish', 'mantis shrimp', 'anemone',‬‬


‫‪'yeti crab', 'shark', 'octopus', 'blobfish', 'mantis shrimp',‬‬
‫]'‪'anemone', 'yeti crab‬‬
‫‪['Pacific', 'Atlantic', 'Indian', 'Southern', 'Arctic',‬‬
‫‪'Pacific', 'Atlantic', 'Indian', 'Southern', 'Arctic',‬‬
‫]'‪'Pacific', 'Atlantic', 'Indian', 'Southern', 'Arctic‬‬

‫يمكننا باستخدام العامل * نسخ القوائم عدة مرات‪.‬‬

‫ً‬
‫أيضا استخدام الشكلين المركبين للعاملين ‪ +‬و * مع عامل اإلسناد =‪ .‬يمكن اس تخدام‬ ‫يمكننا‬

‫الع املين المرك بين =‪ +‬و =* لملء الق وائم بطريق ة س ريعة ومُ ؤتمت ة‪ .‬يمكن ك اس تخدام ه ذين‬

‫الع املين لملء الق وائم بعناص ر نائب ة (‪ )placeholders‬يمكن ك تع ديلها في وقت الح ق بالم دخالت‬

‫المقدمة من المستخدم على سبيل المثال‪.‬‬

‫في المثال الت الي‪ ،‬سنض يف عنص رًا إلى القائم ة ‪ .sea_creatures‬س يعمل ه ذا العنص ر مث ل‬

‫عمل العنصر النائب‪ ،‬ونود إضافة هذا العنصر النائب ع دة م رات‪ .‬لفع ل ذل ك‪ ،‬سنس تخدم العام ل =‪+‬‬

‫مع الحلقة ‪.for‬‬

‫‪for x in range(1,4):‬‬
‫]'‪sea_creatures += ['fish‬‬
‫)‪print(sea_creatures‬‬

‫والمخرجات ستكون‪:‬‬

‫▲‬ ‫|‬ ‫‪205‬‬


‫البرمجة بلغة بايثون‬ ‫ مدخل إلى القوائم‬:List ‫النوع‬

['shark', 'octopus', 'blobfish', 'mantis shrimp', 'anemone',


'yeti crab', 'fish']
['shark', 'octopus', 'blobfish', 'mantis shrimp', 'anemone',
'yeti crab', 'fish', 'fish']
['shark', 'octopus', 'blobfish', 'mantis shrimp', 'anemone',
'yeti crab', 'fish', 'fish', 'fish']

.sea_creatures ‫ إلى القائمة‬fish ‫ عنصر‬for ‫سيضاف لكل تكرار في الحلقة‬


ُ

:‫يتصرف العامل =* بطريقة مماثلة‬

sharks = ['shark']

for x in range(1,4):
sharks *= 2
print(sharks)

:‫الناتج سيكون‬

['shark', 'shark']
['shark', 'shark', 'shark', 'shark']
['shark', 'shark', 'shark', 'shark', 'shark', 'shark', 'shark',
'shark']

‫ إزالة عنصر من قائمة‬.5


‫ سيؤدي ذلك إلى حذف العنصر الموجود عن د‬.del ‫يمكن إزالة العناصر من القوائم باستخدام‬

.‫الفهرس المحدد‬

.1 ‫ هذا العنصر موجود عن د الفه رس‬.octopus ‫ العنصر‬sea_creatures ‫سنزيل من القائمة‬

:‫ ثم نستدعي متغير القائمة وفهرس ذلك العنصر‬del ‫ سنستخدم‬،‫إلزالة هذا العنصر‬

▲ | 206
‫البرمجة بلغة بايثون‬ ‫النوع ‪ :List‬مدخل إلى القوائم‬

‫‪sea_creatures =['shark', 'octopus', 'blobfish', 'mantis‬‬


‫]'‪shrimp', 'anemone', 'yeti crab‬‬

‫]‪del sea_creatures[1‬‬
‫)‪print(sea_creatures‬‬ ‫‪#‬‬ ‫‪['shark', 'blobfish', 'mantis‬‬
‫]'‪shrimp', 'anemone', 'yeti crab‬‬

‫اآلن‪ ،‬العنصر ذو الفهرس ‪ ،1‬أي السلسلة النصية ‪ ،octopus‬لم يعد موجو ًدا في قائمتنا‪.‬‬

‫أيض ا تحدي د مج ال م ع العب ارة ‪ .del‬لنق ل َّ‬


‫أنن ا نري د إزال ة العناص ر ‪،octopus‬‬ ‫ً‬ ‫يمكنن ا‬

‫و ‪ blobfish‬و ‪ mantis shrimp‬معً ا‪ .‬يمكننا فعل ذلك على النحو التالي‪:‬‬

‫‪sea_creatures =['shark', 'octopus', 'blobfish', 'mantis‬‬


‫]'‪shrimp', 'anemone', 'yeti crab‬‬

‫]‪del sea_creatures[1:4‬‬
‫)‪print(sea_creatures‬‬ ‫‪#‬‬ ‫]'‪['shark', 'anemone', 'yeti crab‬‬

‫الفهرس ين ‪( 1‬مش مول) و ‪4‬‬


‫َ‬ ‫َّ‬
‫تمكنا من إزالة العناص ر الموج ودة بين‬ ‫باستخدام مجال مع ‪،del‬‬

‫(غير مشمول)‪ ،‬والقائمة أضحت مكوَّ نة من ‪ 3‬عناصر فقط بعد إزالة ‪ 3‬عناصر منها‪.‬‬

‫‪ .6‬بناء قوائم من قوائم أخرى موجودة‬


‫يمكن أن تتض مَّ ن عناص ر الق وائم ق وائم أخ رى‪ ،‬م ع إدراج ك ل قائم ة بين قوس ين معق وفين‬

‫داخل األقواس المعقوفة الخارجية التابعة لقائمة األصلية‪:‬‬

‫‪sea_names = [['shark', 'octopus', 'squid', 'mantis shrimp'],‬‬


‫]]'‪['Sammy', 'Jesse', 'Drew', 'Jamie‬‬

‫تسمى القوائم المُ تضمّ نة داخل قوائم أخرى بالقوائم المتشعبة (‪.)nested lists‬‬

‫يتعين علين ا اس تخدام فه ارس متع ددة تقاب ل‬


‫َّ‬ ‫للوص ول إلى عنص ر ض من ه ذه القائم ة‪ ،‬س‬

‫▲‬ ‫|‬ ‫‪207‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :List‬مدخل إلى القوائم‬

‫مستوى التشعُّ ب‪:‬‬

‫)]‪print(sea_names[1][0‬‬ ‫‪#‬‬ ‫‪Sammy‬‬


‫)]‪print(sea_names[0][0‬‬ ‫‪#‬‬ ‫‪shark‬‬

‫فهرسها ‪ .1‬ضمن كل قائمة متش ِّعبة داخلي ة‪،‬‬


‫ُ‬ ‫فهرس القائمة األولى يساوي ‪ ،0‬والقائمة الثانية‬

‫سيكون هناك فهارس منفصلة‪ ،‬والتي سنسميها فهارس ثانوية‪:‬‬

‫'‪sea_names[0][0] = 'shark‬‬
‫'‪sea_names[0][1] = 'octopus‬‬
‫'‪sea_names[0][2] = 'squid‬‬
‫'‪sea_names[0][3] = 'mantis shrimp‬‬

‫'‪sea_names[1][0] = 'Sammy‬‬
‫'‪sea_names[1][1] = 'Jesse‬‬
‫'‪sea_names[1][2] = 'Drew‬‬
‫'‪sea_names[1][3] = 'Jamie‬‬

‫أنك ستحتاج إلى اس تخدام أك ثر من‬ ‫َّ‬


‫مؤلفة من قوائم‪ ،‬من المهم أن تعي َّ‬ ‫عند العمل مع قوائم‬

‫فهرس واحد للوصول إلى عناصر القوائم المتشعبة‪.‬‬

‫‪ .7‬استخدام توابع القوائم‬


‫كيفية إض افة‬
‫َّ‬ ‫َّ‬
‫ونتعلم‬ ‫سنَتعرَّ ف اآلن على التوابع المُ ضمَّ نة التي يمكن استخدامها م ع الق وائم‪.‬‬

‫وكيفية إزالتها‪ ،‬وتوسيع القوائم وترتيبها‪ ،‬وغير ذلك‪.‬‬


‫َّ‬ ‫عناصر إلى القائمة‬

‫واع قابل ٌة للتغي ير (‪ )mutable‬على عكس السالس ل النص ية ال تي ال يمكن تغييره ا‪،‬‬
‫القوائم أن ٌ‬

‫فعندما تستخدم تابعً ا على قائمة ما‪ ،‬ستؤثر في القائمة نفسها‪ ،‬وليس في نسخة منها‪.‬‬

‫س نعمل في ه ذا القس م على قائم ة ِّ‬


‫تمثل ح وض س مك‪ ،‬إذ س تحوي القائم ة أس ماء أن واع‬

‫ً‬
‫أسماكا أو أزلناها من الحوض‪.‬‬ ‫األسماك الموجودة في الحوض‪ ،‬وسنعدلها كلمَّ ا أضفنا‬

‫▲‬ ‫|‬ ‫‪208‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :List‬مدخل إلى القوائم‬

‫ا‪ .‬التابع )(‪list.append‬‬

‫َر ) إلى نهاية القائمة ‪.list‬‬


‫يضيف التابع )‪ list.append(x‬عنصرًا (العنصر ‪ x‬الممر‬
‫ّ‬
‫ً‬
‫قائمة تمثل األسماك الموجودة في حوض السمك‪.‬‬ ‫يُ ِّ‬
‫عرف المثال التالي‬

‫]'‪fish = ['barracuda','cod','devil ray','eel‬‬

‫تتألف هذه القائمة من ‪ 4‬سالسل نصية‪ ،‬وتتراوح فهارسها من ‪ 0‬إلى ‪.3‬‬

‫سنض يف س مكة جدي دة إلى الح وض‪ ،‬ون ود بالمقاب ل أن نض يف تل ك الس مكة إلى قائمتن ا‪.‬‬

‫سنمرر السلسلة النصية ‪ flounder‬التي ِّ‬


‫تمثل نوع الس مكة الجدي دة إلى الت ابع )(‪،list.append‬‬ ‫ِّ‬

‫ثم نطبع قائمتنا المعدلة لتأكيد إضافة العنصر‪:‬‬

‫)'‪fish.append('flounder‬‬
‫)‪print(fish‬‬
‫‪#‬‬ ‫]'‪['barracuda', 'cod', 'devil ray', 'eel', 'flounder‬‬

‫اآلن‪ ،‬ص ارت ل دينا قائم ة من ‪ 5‬عناص ر‪ ،‬تنتهي بالعنص ر ال ذي أض فناه للت و ع بر‬

‫التابع )(‪.append‬‬

‫ب‪ .‬التابع )(‪list.insert‬‬

‫يأخذ التابع )‪ list.insert (i,x‬وسيطين‪ :‬األول ‪ِّ i‬‬


‫يمثل الفهرس الذي ترغب في إضافة‬

‫العنصر عنده‪ ،‬و ‪ x‬يمثل العنصر نفسه‪.‬‬

‫أن قائم ة‬
‫لق د أض فنا إلى ح وض الس مك س مكة جدي دة من ن وع ‪ .anchovy‬ربم ا الحظت َّ‬

‫ترتيبا أبج ديًا ح تى اآلن‪ ،‬له ذا الس بب ال نري د إفس اد ال ترتيب‪ ،‬ولن نض يف السلس لة‬
‫ً‬ ‫األسماك مرتبة‬

‫النصية ‪ anchovy‬إلى نهاية القائمة باستخدام الدالة )(‪list.append‬؛ بداًل من ذلك‪ ،‬سنس تخدم‬

‫التابع )(‪ list.insert‬إلضافة ‪ anchovy‬إلى بداية القائمة‪ ،‬أي عند الفهرس ‪:0‬‬

‫▲‬ ‫|‬ ‫‪209‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :List‬مدخل إلى القوائم‬

‫)'‪fish.insert(0,'anchovy‬‬
‫)‪print(fish‬‬
‫‪#‬‬ ‫‪['anchovy', 'barracuda', 'cod', 'devil ray', 'eel',‬‬
‫]'‪'flounder‬‬

‫في هذه الحالة‪ ،‬أضفنا العنصر إلى بداية القائمة‪.‬‬

‫وة واح ً‬
‫دة إلى األم ام‪ .‬ل ذلك‪ ،‬سيص بح العنص ر‬ ‫س تتقدم فه ارس العناص ر التالي ة خط ً‬

‫‪ barracuda‬عن د الفه رس ‪ ،1‬والعنص ر ‪ cod‬عن د الفه رس ‪ ،2‬والعنص ر ‪ - flounder‬األخ ير ‪ -‬عن د‬

‫الفهرس ‪.5‬‬

‫سنحض ر اآلن س مكة من ن وع ‪ damselfish‬إلى الح وض‪ ،‬ون رغب في الحف اظ على ال ترتيب‬

‫رس ‪:3‬‬ ‫د الفه‬ ‫ر عن‬ ‫ذا العنص‬ ‫عه‬ ‫ذلك سنض‬ ‫ة أعاله‪ ،‬ل‬ ‫ر القائم‬ ‫دي لعناص‬ ‫األبج‬

‫)'‪.fish.insert(3,'damselfish‬‬

‫ج‪ .‬التابع )(‪list.extend‬‬

‫ِّ‬
‫توسع قائمة بعناصر قائم ة أخ رى‪ ،‬فيمكن ك اس تخدام الت ابع )‪،list.extend(L‬‬ ‫إذا أردت أن‬

‫والذي يأخذ قائمة (المعامل ‪ )L‬ويضيف عناصرها إلى القائمة ‪.list‬‬

‫سنض ع في الح وض أربع ة أس ماك جدي دة‪ .‬أن واع ه ذه األس ماك مجموع ة معً ا في‬

‫القائمة ‪:more_fish‬‬

‫]'‪more_fish = ['goby','herring','ide','kissing gourami‬‬

‫أن‬
‫سنض يف اآلن عناص ر القائم ة ‪ more_fish‬إلى قائم ة األس ماك‪ ،‬ونطب ع القائم ة لنتأك د من َّ‬

‫عناصر القائمة الثانية قد أضيفت إليها‪:‬‬

‫)‪fish.extend(more_fish‬‬

‫▲‬ ‫|‬ ‫‪210‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :List‬مدخل إلى القوائم‬

‫)‪print(fish‬‬

‫ستطبع بايثون القائمة التالية‪:‬‬

‫‪['anchovy', 'barracuda', 'cod', 'devil ray', 'eel', 'flounder',‬‬


‫]'‪'goby', 'herring', 'ide', 'kissing gourami‬‬

‫في هذه المرحلة‪ ،‬صارت القائمة ‪ fish‬تتألف من ‪ 10‬عناصر‪.‬‬

‫د‪ .‬التابع )(‪list.remove‬‬

‫إلزال ة عنص ر من قائم ة‪ ،‬اس تخدم الت ابع )‪ ،list.remove(x‬وال ذي يزي ل أول عنص ر من‬

‫القائمة له القيمة المُ مرَّ رة ‪.x‬‬

‫ً‬
‫أبحاث ا عن‬ ‫ج اءت مجموع ة من العلم اء المحل يين لزي ارة الح وض‪ ،‬وس يجرون‬

‫النوع ‪ ،kissing gourami‬وطلبوا استعارة السمكة ‪ ،kissing gourami‬لذلك نود إزالة العنص ر‬

‫‪ kissing gourami‬من القائمة لنعكس هذا التغيير‪:‬‬

‫)'‪fish.remove('kissing gourami‬‬
‫)‪print(fish‬‬

‫والمخرجات ستكون‪:‬‬

‫‪['anchovy', 'barracuda', 'cod', 'devil ray', 'eel', 'flounder',‬‬


‫]'‪'goby', 'herring', 'ide‬‬

‫بع د اس تخدام الت ابع )(‪ ،list.remove‬لم يع د العنص ر ‪ kissing gourami‬موج و ًدا‬

‫في القائمة‪.‬‬

‫في ح ال اخ ترت عنص رًا ‪ x‬غ ير موج ود في القائم ة ومرَّ رت ه إلى الت ابع )(‪،list.remove‬‬

‫فسيطلق الخطأ التالي‪:‬‬


‫ُ‬

‫▲‬ ‫|‬ ‫‪211‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :List‬مدخل إلى القوائم‬

‫‪ValueError: list.remove(x): x not in list‬‬

‫لن يزي ل الت ابع )(‪ list.remove‬إال أوَّ ل عنص ر تس اوي قيمت ه قيم ة العنص ر المُ م رَّ ر إلى‬

‫التابع‪ ،‬لذلك إن ك انت ل دينا س مكتان من الن وع ‪ kissing gourami‬في الح وض‪ ،‬وأعرن ا إح داهما‬

‫إن التعب ير )'‪ fish.remove('kissing gourami‬لن يمح و إال العنص ر األول‬


‫فق ط للعلم اء‪ ،‬ف َّ‬

‫المطابق فقط‪.‬‬

‫ه‪ .‬التابع )(‪list.pop‬‬

‫يعي د الت ابع )]‪ list.pop ([i‬العنص ر الموج ود عن د الفه رس المح دد من القائم ة‪ ،‬ثم يزي ل‬

‫فهرس ا‬
‫ً‬ ‫أن هذا المعامل اختي اري‪ ،‬ل ذا‪ ،‬إذا لم تح دد‬
‫ذلك العنصر‪ .‬تشير األقواس المربعة حول ‪ i‬إلى َّ‬

‫فسيعاد العنصر األخير ثم يُ زال‪.‬‬


‫ُ‬ ‫(كما في )(‪،)fish.pop‬‬

‫لقد أصبح حجم السمكة ‪ devil ray‬كبي ًرا ج ًدا‪ ،‬ولم يعد الحوض يس عها‪ ،‬ولحس ن الح ظ َّ‬
‫أن‬

‫هناك حوض سمك في بلدة مجاورة يمكنه استيعابها‪ .‬سنستخدم التابع )(‪ ،.pop‬ونمرر إلي ه الع دد‬

‫‪ ،3‬الذي يساوي فهرس العنص ر ‪ ،devil ray‬بقص د إزالت ه من القائم ة‪ .‬بع د إع ادة العنص ر‪ ،‬س نتأكد‬

‫من أننا أزلنا العنصر الصحيح‪.‬‬

‫‪print(fish.pop(3)) # devil ray‬‬


‫)‪print(fish‬‬
‫‪# ['anchovy', 'barracuda', 'cod', 'eel', 'flounder', 'goby',‬‬
‫]'‪'herring', 'ide‬‬

‫مرر‬ ‫َّ‬
‫تمكنا من إزالة السمكة ‪ ray devil‬من قائمة األسماك‪ .‬إذا لم ُن ِّ‬ ‫باستخدام التابع )(‪.pop‬‬

‫أي معام ل إلى ه ذا الت ابع‪َّ ،‬‬


‫ونفذنا االس تدعاء )(‪ ،fish.pop‬فس ُيعاد العنص ر األخ ير ‪ ide‬ثم يُ َزال‬ ‫َّ‬

‫من القائمة‪.‬‬

‫▲‬ ‫|‬ ‫‪212‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :List‬مدخل إلى القوائم‬

‫و‪ .‬التابع )(‪list.index‬‬

‫يص عب في الق وائم الكب يرة تحدي د فه ارس العناص ر ال تي تحم ل قيم ة معين ة‪ .‬ألج ل ذل ك‪،‬‬

‫يمكنن ا اس تخدام الت ابع )‪ ،list.index(x‬إذ يمث ل الوس يط‪ x‬قيم ة العنص ر المبح وث عن ه‪ ،‬وال ذي‬

‫نري د معرف ة فهرس ه‪ .‬إذا ك ان هن اك أك ثر من عنص ر واح د يحم ل القيم ة ‪ ،x‬فس ُيعَ اد فه رس‬

‫العنصر األول‪.‬‬

‫)‪print(fish‬‬ ‫‪# ['anchovy', 'barracuda', 'cod', 'eel',‬‬


‫]'‪'flounder', 'goby', 'herring', 'ide‬‬

‫))'‪print(fish.index('herring‬‬ ‫‪# 6‬‬

‫سوف يُ َ‬
‫طل ق خطأ في حال مرَّ رنا قيمة غير موجودة في القائمة إلى التابع )(‪..index‬‬

‫ز‪ .‬التابع )(‪list.copy‬‬

‫ُ‬
‫أحيان ا نرغب في تعديل عناصر قائمةٍ والتجريب عليها‪ ،‬مع الحفاظ على القائمة األصلية دون‬

‫تغيير؛ يمكننا في هذه الحالة استخدام التابع )(‪ list.copy‬إلنشاء نسخة من القائمة األصلية‪.‬‬

‫في المث ال الت الي‪ ،‬س ِّ‬


‫نمرر القيم ة المع ادة من )(‪ fish.copy‬إلى المتغ ير ‪ ،fish_2‬ثم نطب ع‬

‫قيمة ‪ fish_2‬للتأكد من َّ‬


‫أنها تحتوي على نفس عناصر القائمة ‪.fish‬‬

‫)(‪fish_2 = fish.copy‬‬
‫)‪print(fish_2‬‬
‫‪#‬‬ ‫‪['anchovy', 'barracuda', 'cod', 'eel', 'flounder', 'goby',‬‬
‫]'‪'herring', 'ide‬‬

‫في هذه المرحلة‪ ،‬القائمتان ‪ fish‬و ‪ fish_2‬متساويتان‪.‬‬

‫▲‬ ‫|‬ ‫‪213‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :List‬مدخل إلى القوائم‬

‫ح‪ .‬التابع )(‪list.reverse‬‬

‫يمكنن ا عكس ت رتيب عناص ر قائم ة باس تخدام الت ابع )(‪ .list.reverse‬في المث ال الت الي‬

‫سنستخدم التابع )(‪ .reverse‬مع القائمة ‪ fish‬لعكس ترتيب عناصرها‪.‬‬

‫)(‪fish.reverse‬‬
‫)‪print(fish‬‬ ‫‪#‬‬ ‫‪['ide', 'herring', 'goby', 'flounder', 'eel',‬‬
‫]'‪'cod', 'barracuda', 'anchovy‬‬

‫بع د اس تخدام الت ابع )(‪ ،.reverse‬ص ارت القائم ة تب دأ بالعنص ر ‪ ،ide‬وال ذي ك ان في نهاي ة‬

‫القائمة من قبل‪ ،‬كما ستنتهي القائمة بالعنصر ‪ ،anchovy‬والذي كان في بداية القائمة من قبل‪.‬‬

‫ط‪ .‬التابع )(‪list.count‬‬

‫يعي د الت ابع )‪ list.count(x‬ع دد م رات ظه ور القيم ة ‪ x‬في القائم ة‪ .‬ه ذا الت ابع مفي د في‬

‫حال كنا نعمل على قائمة طويلة بها الكثير من القيم المتطابقة‪.‬‬

‫إذا ك ان ح وض الس مك كب يرًا‪ ،‬على س بيل المث ال‪ ،‬وك انت عن دنا ع دة أس ماك من الن وع‬

‫‪ ،neon tetra‬فيمكننا استخدام التابع )(‪ .count‬لتحديد العدد اإلجمالي ألسماك هذا النوع‪.‬‬

‫في المثال التالي‪ ،‬سنحسب عدد مرات ظهور العنصر ‪:goby‬‬

‫))'‪print(fish.count('goby‬‬ ‫‪#‬‬ ‫‪1‬‬

‫رة واح ً‬
‫دة فق ط في القائم ة‪ ،‬ل ذا س ُيعيد الت ابع )(‪.count‬‬ ‫تظه ر السلس لة النص ية ‪ goby‬م ً‬

‫ً‬
‫أيض ا م ع قائم ة مكوَّ ن ة من أع داد ص حيحة‪ ،‬ويوض ح المث ال‬ ‫الع دد ‪ .1‬يمكنن ا اس تخدام ه ذا الت ابع‬

‫التالي ذلك‪.‬‬

‫أن وجباته ا الغذائي ة‬


‫يتتبع المشرفون على الح وض أعم ار األس ماك الموج ودة في ه للتأك د من َّ‬

‫مناس بة ألعماره ا‪ .‬ه ذه القائم ة الثاني ة المُ س ماة ‪ fish_ages‬تتواف ق م ع أن واع الس مك في‬

‫▲‬ ‫|‬ ‫‪214‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :List‬مدخل إلى القوائم‬

‫ألن األسماك ال تي ال يتج اوز عمره ا عامً ا واح ًدا له ا احتياج ات غذائي ة خاص ة‪،‬‬
‫القائمة ‪ .fish‬نظ ًرا ّ‬

‫فسنحسب عدد األسماك التي عمرها عامً ا واح ًدا‪:‬‬

‫]‪fish_ages = [1,2,4,3,2,1,1,2‬‬
‫))‪print(fish_ages.count(1‬‬ ‫‪#‬‬ ‫‪3‬‬

‫يظه ر الع دد الص حيح ‪ 1‬في القائم ة ‪ fish_ages‬ثالث م رات‪ ،‬ل ذلك يعي د الت ابع )(‪.count‬‬

‫العدد ‪.3‬‬

‫ي‪ .‬التابع )(‪list.sort‬‬

‫ُ‬
‫استدعِ ي معها‪ .‬سنستخدم قائم ة‬ ‫يُ ستخدم التابع )(‪ list.sort‬لترتيب عناصر القائمة التي‬

‫األعداد الصحيحة ‪ fish_ages‬لتجريب التابع )(‪:.sort‬‬

‫)(‪fish_ages.sort‬‬
‫)‪print(fish_ages‬‬ ‫‪#‬‬ ‫]‪[1, 1, 1, 2, 2, 2, 3, 4‬‬

‫مرت ً‬
‫بة‪.‬‬ ‫َّ‬ ‫ُ‬
‫فستعاد تلك القائمة‬ ‫باستدعاء التابع )(‪ .sort‬مع القائمة ‪، fish_ages‬‬

‫ك‪ .‬التابع )(‪list.clear‬‬

‫بعد االنتهاء من العمل على قائمة م ا‪ ،‬يمكن ك إزال ة جمي ع العناص ر الموج ودة فيه ا باس تخدام‬

‫التابع )(‪.list.clear‬‬

‫ق ررت الحكوم ة المحلي ة االس تيالء على ح وض الس مك الخ اص بن ا‪ ،‬وجعل ه مس احة عامة‬

‫يس تمتع به ا س كان م دينتنا‪ .‬نظ رً ا ألنن ا لم نع د نعم ل على الح وض‪ ،‬فلم نع د بحاج ة إلى االحتف اظ‬

‫بقائمة األسماك‪ ،‬لذلك سنزيل عناصر القائمة ‪:fish‬‬

‫▲‬ ‫|‬ ‫‪215‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :List‬مدخل إلى القوائم‬

‫)(‪fish.clear‬‬
‫)‪print(fish‬‬ ‫‪#‬‬ ‫][‬

‫أقواس ا معقوف ة نتيج ة اس تدعاء الت ابع )(‪ .clear‬على القائم ة ‪،fish‬‬
‫ً‬ ‫ن رى في المخرج ات‬

‫وهذا تأكيد على َّّ‬


‫أن القائمة أصبحت خالية من جميع العناصر‪.‬‬

‫‪ .8‬فهم كيفية استعمال ‪List Comprehensions‬‬


‫اء على ق وائم موج ودة‬ ‫ت وفر ‪ List Comprehensions‬طريق ًة مختص ً‬
‫رة إلنش اء الق وائم بن ً‬

‫أي ن وع من البيان ات‬ ‫ً‬


‫مسبقا‪ .‬فيمكن عند استخدام ‪ list comprehensions‬بناء الق وائم باس تخدام ِّ‬

‫المتسلس لة ال تي يمكن ال دوران على عناص رها ع بر حلق ات التك رار‪ ،‬بم ا في ذل ك السالس ل النص ية‬

‫والص فوف‪ .‬من ناحي ة ال تركيب اللغ وي‪ ،‬تحت وي ‪ list comprehensions‬على عنص ر يمكن الم رور‬

‫وع بحلق ة ‪ .for‬ويمكن أن يُ َ‬


‫تب ع م ا س بق بتع ابير ‪ for‬أو ‪ if‬إض افية‪ ،‬ل ذا‬ ‫ير متب ٍ‬
‫علي ه ض من تعب ٍ‬

‫سيساعدك الفهم العميق لحلقات ‪ for‬والعبارات الشرطية في التعامل مع ‪.list comprehensions‬‬

‫ت ِّ‬
‫وفر ‪ list comprehensions‬طريق ًة مختلف ًة إلنش اء الق وائم وغيره ا من أن واع البيان ات‬

‫المتسلسلة‪ .‬وعلى الرغم من إمكانية استخدام الطرائق األخرى لل دوران‪ ،‬مث ل حلق ات ‪ ،for‬إلنش اء‬

‫المفض ل اس تعمال ‪ list comprehensions‬ألنه ا ِّ‬


‫تقلل ع دد األس طر الموج ودة‬ ‫َّ‬ ‫الق وائم‪ ،‬لكن من‬

‫في برنامجك‪.‬‬

‫يمكن بناء ‪ list comprehensions‬في بايثون كاآلتي‪:‬‬

‫]‪list_variable = [x for x in iterable‬‬

‫ُ‬
‫ستس نَد القائم ة‪ ،‬أو أي ن وع من البيان ات يمكن الم رور على عناص ره‪ ،‬إلى متغ ير‪ .‬المتغ يرات‬

‫اإلض افية –ال تي ُتش ير إلى عناص ر موج ودة ض من ن وع البيان ات ال ذي يمكن الم رور على عناص ره–‬

‫▲‬ ‫|‬ ‫‪216‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :List‬مدخل إلى القوائم‬

‫ُتب نى ح ول عب ارة ‪ .for‬والكلم ة المحج وزة ‪ in‬تس تعمل بنفس اس تعمالها في حلق ات ‪ for‬وذل ك‬

‫ً‬
‫مبنية على سلسلةٍ نصية‪:‬‬ ‫ً‬
‫قائمة‬ ‫مثال يُ ِ‬
‫نشئ‬ ‫لمرور على عناصر ‪ .iterable‬لننظر إلى‬
‫ٍ‬

‫]'‪shark_letters = [letter for letter in 'shark‬‬


‫)‪print(shark_letters‬‬

‫ً‬
‫دة إلى المتغ ير ‪ ،shark_letters‬واس تعملنا‬ ‫أس ندنا في المث ال الس ابق قائم ًة جدي‬

‫المتغ ير ‪ letter‬لإلش ارة إلى العناص ر الموج ودة ض من السلس لة النص ية '‪ .'shark‬اس تعملنا بع د‬

‫ذل ك الدال ة )(‪ print‬لكي نتأك د من القائم ة الناتج ة والمُ س نَدة إلى المتغ ير ‪،shark_letters‬‬

‫وحصلنا على الناتج اآلتي‪:‬‬

‫]'‪['s', 'h', 'a', 'r', 'k‬‬

‫تت ألف القائم ة ال تي أنش أناها باس تخدام ‪ list comprehensions‬من العناص ر ال تي تك ِّون‬

‫السلس لة النص ية '‪ ،'shark‬وهي ك ل ح رف في الكلم ة ‪ .shark‬يمكن إع ادة كتاب ة‬

‫تع ابير ‪ list comprehensions‬بش كل حلق ات ‪ ،for‬لكن الح ظ َّ‬


‫أنك ال تس تطيع إع ادة كتاب ة ك ل‬

‫حلق ة ‪ for‬بص يغة ‪ .list comprehensions‬لنع د كتاب ة المث ال الس ابق ال ذي أنش أنا في ه القائم ة‬

‫ف‬ ‫اعدنا في فهم كي‬ ‫ذا سيس‬ ‫ة ‪ ،for‬وه‬ ‫تخدام حلق‬ ‫‪ shark_letters‬باس‬

‫تعمل ‪ list comprehensions‬عملها‪:‬‬

‫][ = ‪shark_letters‬‬

‫‪for letter in 'shark':‬‬


‫)‪shark_letters.append(letter‬‬

‫)‪print(shark_letters‬‬

‫عن د إنش ائنا للقائم ة ع بر اس تخدام الحلق ة ‪ ،for‬فيجب تهيئ ة المتغ ير ال ذي س ُنس نِد العناص ر‬

‫▲‬ ‫|‬ ‫‪217‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :List‬مدخل إلى القوائم‬

‫إلي ه كقائم ة فارغ ة‪ ،‬وه ذا م ا فعلن اه في أوّ ل س طر من الش يفرة الس ابقة‪ .‬ثم ب دأت حلق ة ‪for‬‬

‫ً‬
‫تعملة المتغ ير ‪ letter‬لإلش ارة إلى قيم ة‬ ‫بال دوران على عناص ر السلس لة النص ية '‪ 'shark‬مس‬

‫العنصر الح الي‪ ،‬ومن ثم أض فنا ك ل عنص ر في السلس لة النص ية إلى القائم ة ض من حلق ة ‪ for‬وذل ك‬

‫ل‬ ‫ابقة يماث‬ ‫ة ‪ for‬الس‬ ‫اتج من حلق‬ ‫ة )‪ .list.append(x‬الن‬ ‫تخدام الدال‬ ‫باس‬

‫ناتج ‪ list comprehension‬في المثال أعاله‪:‬‬

‫]'‪['s', 'h', 'a', 'r', 'k‬‬

‫يمكن إعادة كتابة ‪ List comprehensions‬كحلقات ‪ ،for‬لكن بعض حلقات ‪ for‬يمكن إع ادة‬

‫كتابتها لتصبح ‪ List comprehensions‬لتقليل كمية الشيفرات المكتوبة‪.‬‬

‫ا‪ .‬استخدام التعابير الشرطية مع ‪List Comprehensions‬‬

‫يمكن اس تخدام التع ابير الش رطية في ‪ list comprehension‬لتع ديل الق وائم أو أن واع‬

‫ال عن اس تخدام العب ارة‬


‫البيان ات المتسلس لة األخ رى عن د إنش اء ق وائم جدي دة‪ .‬لننظ ر إلى مث ٍ‬

‫الشرطية ‪ if‬في تعبير ‪:list comprehension‬‬

‫)'‪fish_tuple = ('blowfish', 'clownfish', 'catfish', 'octopus‬‬

‫]'‪fish_list = [fish for fish in fish_tuple if fish != 'octopus‬‬


‫)‪print(fish_list‬‬

‫أساس ا للقائم ة الجدي دة ال تي‬


‫ً‬ ‫اس تعملنا المتغ ير ‪ fish_tuple‬ال ذي من ن وع البيان ات ‪tuple‬‬

‫س ُن ِ‬
‫نش ئها ال تي تس مى ‪ .fish_list‬اس تعملنا ‪ for‬و ‪ in‬كم ا في القس م الس ابق‪ ،‬لكنن ا أض فنا هن ا‬

‫التعليم ة الش رطية ‪ .if‬س تؤدي التعليم ة الش رطية ‪ if‬إلى إض افة العناص ر غ ير المس اوية للسلس لة‬

‫النص ية '‪ ،'octopus‬ل ذا س تحتوي القائم ة الجدي دة على العناص ر الموج ودة في بني ة ص ف‬

‫▲‬ ‫|‬ ‫‪218‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :List‬مدخل إلى القوائم‬

‫(‪ )tuple‬وال تي ال ُتط ا ِبق الكلم ة '‪ .'octopus‬عن د تش غيل البرن امج الس ابق فس نالحظ َّ‬
‫أن القائم ة‬

‫‪ fish_list‬تحت وي على نفس العناص ر ال تي ك انت موج ودة في ‪ fish_tuple‬لكن م ع ح ذف‬

‫العنصر '‪:'octopus‬‬

‫]'‪['blowfish', 'clownfish', 'catfish‬‬

‫أي أصبحت القائمة الجديدة تحتوي على بنية صف أصلية لكن ما عدا السلس لة النص ية ال تي‬

‫نش ئ مث ااًل آخ ر يس تعمل المع امالت الرياض ية واألرق ام‬


‫اس تثنيناها ع بر التعب ير الش رطي‪ .‬س ُن ِ‬

‫الصحيحة والدالة )(‪:range‬‬

‫]‪number_list = [x ** 2 for x in range(10) if x % 2 == 0‬‬


‫)‪print(number_list‬‬

‫ست َ‬
‫نش أ باس م ‪ number_list‬س تحتوي على مرب ع جمي ع القيم الموج ودة من‬ ‫القائم ة ال تي ُ‬

‫المجال ‪ 0‬إلى ‪ 9‬لكن إذا كان الرقم قاباًل للقسمة على ‪ .2‬وستبدو المخرجات اآلتية‪:‬‬

‫]‪[0, 4, 16, 36, 64‬‬

‫ِّ‬
‫نفكر بال ذي س يظهر إذا‬ ‫دعنا ُن ِّ‬
‫فصل ما الذي يفعله تعبير ‪ list comprehension‬السابق‪ ،‬ودعنا‬

‫استعملنا التعبير )‪ x for x in range(10‬فقط‪ .‬يجب أن يبدو برنامجنا الصغير كاآلتي‪:‬‬

‫])‪number_list = [x for x in range(10‬‬


‫)‪print(number_list‬‬

‫الناتج‪:‬‬

‫]‪[0, 1, 2, 3, 4, 5, 6, 7, 8, 9‬‬

‫لنضف العبارة الشرطية اآلن‪:‬‬

‫▲‬ ‫|‬ ‫‪219‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :List‬مدخل إلى القوائم‬

‫]‪number_list = [x for x in range(10) if x % 2 == 0‬‬


‫)‪print(number_list‬‬

‫الناتج‪:‬‬

‫]‪[0, 2, 4, 6, 8‬‬

‫أ َّدت التعليم ة الش رطية ‪ if‬إلى قب ول العناص ر القابل ة للقس مة على ‪ 2‬فق ط وإض افتها إلى‬

‫القائم ة‪ ،‬مم ا ي ؤدي إلى ح ذف جمي ع األرق ام الفردي ة‪ .‬يمكنن ا اآلن اس تخدام معام ل رياض ي ل تربيع‬

‫قيمة المتغير ‪:x‬‬

‫]‪number_list = [x ** 2 for x in range(10) if x % 2 == 0‬‬


‫)‪print(number_list‬‬

‫وسيخرَ ج الناتج اآلتي‪:‬‬


‫ُ‬ ‫أي ُ‬
‫ستربَّع قيم القائمة السابقة ]‪[0, 2, 4, 6, 8‬‬

‫]‪[0, 4, 16, 36, 64‬‬

‫ً‬
‫أيضا استعمال ما يشبه عبارات ‪ if‬المتشعبة في تعابير ‪:list comprehension‬‬ ‫يمكننا‬

‫== ‪number_list = [x for x in range(100) if x % 3 == 0 if x % 5‬‬


‫]‪0‬‬
‫)‪print(number_list‬‬

‫أن المتغ ير ‪ x‬قاب ل للقس مة على ال رقم ‪ ،3‬ثم س نتحقق إن ك ان المتغ ير ‪x‬‬
‫التحقق أواًل َّ‬
‫ُّ‬ ‫س يتم‬

‫فسيض اف إلى القائم ة‪،‬‬


‫ُ‬ ‫قاب ل للقس مة على ال رقم ‪ ،5‬وإذا َّ‬
‫حقق المتغ ير ‪ x‬الش رطين الس ابقين‬

‫وسي َ‬
‫ظهر في الناتج‪:‬‬ ‫ُ‬

‫]‪[0, 15, 30, 45, 60, 75, 90‬‬

‫▲‬ ‫|‬ ‫‪220‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :List‬مدخل إلى القوائم‬

‫يمكن اس تخدام تعليم ة ‪ if‬الش رطية لتحدي د م ا هي العناص ر ال تي نري د إض افتها إلى‬

‫القائمة الجديدة‪.‬‬

‫ب‪ .‬حلقات التكرار المتشعبة في تعابير ‪List Comprehension‬‬

‫يمكن اس تعمال حلق ات التك رار المتش عبة إلج راء ع ِّدة عملي ات دوران متداخل ة في برامجن ا‪.‬‬

‫ير‬ ‫ا إلى تعب‬ ‫نحاول تحويله‬ ‫عبة وس‬ ‫ة ‪ for‬متش‬ ‫م إلى حلق‬ ‫ذا القس‬ ‫ننظر في ه‬ ‫س‬

‫نش ئ ه ذه الش يفرة قائم ًة جدي ً‬


‫دة بال دوران على ق ائمتين وب إجراء‬ ‫‪ُ .list comprehension‬‬
‫ست ِ‬

‫عمليات رياضية عليها‪:‬‬

‫][ = ‪my_list‬‬

‫‪for x in [20, 40, 60]:‬‬


‫‪for y in [2, 4, 6]:‬‬
‫)‪my_list.append(x * y‬‬

‫)‪print(my_list‬‬

‫سنحصل على الناتج اآلتي عند تشغيل البرنامج‪:‬‬

‫]‪[40, 80, 120, 80, 160, 240, 120, 240, 360‬‬

‫تضرب الشيفرة السابقة العناصر الموجودة في أوَّ ل قائمة بالعناصر الموجودة في ثاني قائمة‬

‫في ك ل دورة‪ .‬لتحوي ل م ا س بق إلى تعب ير ‪ ،list comprehension‬وذل ك باختص ار الس طرين‬

‫طر وحي دٍ ‪ ،‬ال ذي يب دأ ب إجراء العملي ة ‪ ،x*y‬ثم‬


‫الموج ودين في الش يفرة الس ابقة وتحويلهم ا إلى س ٍ‬

‫ستلي هذه العملية حلقة ‪ for‬الخارجية‪ ،‬ثم يليه ا حلق ة ‪ for‬الداخلي ة؛ وسنض يف تعب ير )(‪print‬‬

‫أن ناتج القائمة الجديدة يُ طا ِبق ناتج البرنامج الذي فيه حلقتين متداخلتين‪:‬‬
‫للتأكد َّ‬

‫▲‬ ‫|‬ ‫‪221‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :List‬مدخل إلى القوائم‬

‫]]‪my_list = [x * y for x in [20, 40, 60] for y in [2, 4, 6‬‬


‫)‪print(my_list‬‬

‫الناتج‪:‬‬

‫]‪[40, 80, 120, 80, 160, 240, 120, 240, 360‬‬

‫أدى اس تعمال تعب ير ‪ list comprehension‬في المث ال الس ابق إلى تبس يط حلقتَي ‪for‬‬
‫ستس نَد إلى المتغ ير ‪ .my_list‬ت ِّ‬
‫وفر لن ا‬ ‫لتصبحا سط ًرا وحي ًدا‪ ،‬لكن م ع إنش اء نفس القائم ة وال تي ُ‬

‫ً‬
‫يطة إلنش اء الق وائم‪ ،‬مم ا يس مح لن ا باختص ار ع ِّدة أس طر‬ ‫تع ابير ‪ list comprehension‬طريق ًة بس‬

‫أن سهولة قراءة الشيفرة لها األولوية دومً ا‪ ،‬ل ذا‬


‫سطر وحيد‪ .‬لكن من المهم أن تبقي في ذهنك َّ‬
‫ٍ‬ ‫إلى‬

‫َّ‬
‫ومعقدة‪ ،‬فمن األفض ل حينه ا تحويله ا إلى‬ ‫بحت تع ابير ‪ list comprehension‬طويل ًة ج ًدا‬
‫َ‬ ‫إذا أص‬

‫حلقات تكرار عادية‪.‬‬

‫‪ .9‬خالصة الفصل‬
‫الق وائم هي ن وع بيان ات م رن يمكن تعديل ه بس هولة خالل أط وار البرن امج‪ .‬غطين ا في ه ذا‬

‫َّ‬
‫والض م‪.‬‬ ‫الفصل الميزات والخصائص األساس ية لق وائم‪ ،‬بم ا في ذل ك الفهرس ة واالقتط اع والتع ديل‬

‫ُ‬
‫هياكل بيانات مرنة ومفيدة للغاية‪ .‬كما‬ ‫لمَّ ا كانت القوائم تسلسالت قابلة للتغيير (‪َّ ،)mutable‬‬
‫فإنها‬

‫تتيح لنا توابع القوائم إجراء العديد من العمليات على القوائم بسهولة‪ ،‬إذ يمكنن ا اس تخدام التواب ع‬

‫لتعديل القوائم وترتيبها ومعالجتها بفعالية‪.‬‬

‫تسمح تعابير ‪ list comprehension‬لنا بتحويل قائمة أو أي نوع من البيانات المتسلسلة إلى‬

‫بسيط يُ ِّ‬
‫قلل عدد األسطر التي نكتبها‪ .‬تتبع تعابير ‪list comprehension‬‬ ‫ٌ‬ ‫ٌ‬
‫شكل‬ ‫سلسلةٍ جديدة‪ ،‬ولها‬

‫أن‬
‫حيح َّ‬
‫ٌ‬ ‫معي ًن ا‪ ،‬ل ذا ق د يج دها الم برمجون أول و الخلفي ة الرياض ية س هلة الفهم‪ .‬وص‬
‫ّ‬ ‫ش كاًل رياض ًيا‬

‫▲‬ ‫|‬ ‫‪222‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :List‬مدخل إلى القوائم‬

‫تع ابير ‪ list comprehension‬تختص ر الشيفرةـ لكن من المهم جع ل س هولة ق راءة الش يفرة من‬

‫أولوياتنا‪ ،‬وحاول تجنُّب األسطر الطويلة لتسهيل قراءة الشيفرة‪.‬‬

‫▲‬ ‫|‬ ‫‪223‬‬


‫‪12‬‬
‫النوع ‪ :Tuple‬فهم‬
‫الصفوف‬

‫▲‬ ‫|‬ ‫‪224‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :Tuple‬فهم الصفوف‬

‫يبدو نوع البيانات ‪( tuple‬صف) في بايثون كما يلي‪:‬‬

‫‪coral = ('blue coral', 'staghorn coral', 'pillar coral',‬‬


‫)'‪'elkhorn coral‬‬

‫وتجمَ ع إلى ص فوف) هي بني ة بيان ات ُت ِّ‬


‫مثل سلس لة مرتب ة من العناص ر‬ ‫الن وع ‪( tuple‬ص ف ُ‬

‫غير القابلة للتب ديل‪ ،‬وبالت الي ال يمكن تع ديل القيم الموج ودة فيه ا‪ .‬يس تعمل ن وع البيان ات ‪tuple‬‬

‫جزءا منه‪ .‬توضع القيم داخل الص ف بين‬


‫ً‬ ‫لتجميع البيانات‪ ،‬فكل عنصر أو قيمة داخل الصف ُت ِّ‬
‫شكل‬

‫قوسين ( ) ويُ َ‬
‫فصل بينه ا بفاص لة أجنبي ة ‪ ,‬وتب دو القيم الفارغ ة كم ا يلي )( = ‪ ،coral‬لكن إذا‬

‫احت وى الص ف على قيم –ح تى ل و ك انت قيم ًة واح ً‬


‫دة فق ط– فيجب وض ع فاص لة في ه‬

‫‪ .coral‬إذا اس تخدمنا الدال ة )(‪ print‬على الن وع ‪،tuple‬‬ ‫مث ل )‪= ('blue coral',‬‬

‫أن القيمة الناتجة ستوضع بين قوسين‪:‬‬ ‫فسنحصل على الناتج اآلتي الذي يُ ّ‬
‫بين َّ‬

‫)‪print(coral‬‬
‫‪('blue coral', 'staghorn coral', 'pillar coral', 'elkhorn‬‬
‫)'‪coral‬‬

‫عن د التفك ير ب النوع ‪ tuple‬وغ يره من ب نى البيان ات ال تي ُتع ُّد من أن واع «التجميع ات»‬

‫(‪ ،)collections‬فمن المفي د أن تض ع ببال ك مختل ف التجميع ات الموج ودة في حاس وبك‪ :‬تش كيلة‬

‫الملف ات الموج ودة عن دك‪ ،‬وق وائم التش غيل للموس يقى‪ ،‬والمفض لة الموج ودة في متص فحك‪،‬‬

‫ورس ائل بري دك اإللك تروني‪ ،‬ومجموع ة مق اطع الفي ديو ال تي تس تطيع الوص ول إليه ا من التلف از‪،‬‬

‫والكثير‪ .‬نوع ‪( tuple‬صف) شبيه بالنوع ‪( list‬قائمة)‪ ،‬لكن القيم الموجودة فيه ال يمكن تعديلها‪،‬‬

‫وبس بب ذل ك‪ ،‬ف أنت تخ بر اآلخ رين َّ‬


‫أنك ال تري د إج راء أيَّ ة تع ديالت على ه ذه السلس لة من القيم‬

‫عن دما تس تعمل الن وع ‪ tuple‬في ش يفرتك‪ .‬إض ً‬


‫افة إلى م ا س بق‪ ،‬ولع دم الق درة على تع ديل القيم‪،‬‬

‫▲‬ ‫|‬ ‫‪225‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :Tuple‬فهم الصفوف‬

‫تعملت الص فوف ب داًل من‬


‫َ‬ ‫ست َّ‬
‫نفذ الشيفرة بشكل أسرع إذا اس‬ ‫فسيكون أداء برنامجك أفضل‪ ،‬حيث ُ‬

‫القوائم (‪.)lists‬‬

‫‪ .1‬فهرسة الصفوف‬
‫يمكن الوصول إلى كل عنصر من عناصر الصف بمفرده َّ‬
‫ألنه سلسلة مرتب ة من العناص ر‪ ،‬وذل ك‬

‫عبر الفهرسة‪ .‬وكل عنص ر يرتب ط ب رقم فه رس‪ ،‬ال ذي ه و ع دد ص حيح يب دأ من الفه رس ‪ .0‬س تبدو‬

‫الفهارس من مثال ‪ coral‬السابق والقيم المرتبطة بها كاآلتي‪:‬‬

‫‪elkhorn coral‬‬ ‫‪pillar coral‬‬ ‫‪staghorn coral‬‬ ‫‪blue coral‬‬

‫‪3‬‬ ‫‪2‬‬ ‫‪1‬‬ ‫‪0‬‬

‫العنص ر األول ال ذي يُ ِّ‬


‫مثل السلس لة النص ية '‪ 'blue coral‬فهرس ه ‪ ،0‬وتنتهي القائم ة‬

‫وألن ك ل عنص ر من عناص ر الص ف ل ه رقم‬


‫َّ‬ ‫بالفهرس رقم ‪ 3‬المرتبط بالقيم ة '‪.'elkhorn coral‬‬

‫فه رس مرتب ط ب ه‪ ،‬فس نتمكن من الوص ول إلى عناص ره ف رادى‪ .‬يمكنن ا اآلن الوص ول إلى عنص ر‬

‫معين في الصف عبر استخدام رقم الفهرس المرتبط به‪.‬‬


‫ّ‬

‫)]‪print(coral[2‬‬
‫‪pillar coral‬‬

‫تتراوح قيم الفهارس في المتغير ‪ coral‬من ‪ 0‬إلى ‪ 3‬كما ه و ظ اهر في الج دول الس ابق‪ ،‬ل ذا‬

‫يمكننا استدعاء العناصر الموجودة فيه فرادى كما يلي‪:‬‬

‫]‪coral[0‬‬
‫]‪coral[1‬‬
‫]‪coral[2‬‬

‫▲‬ ‫|‬ ‫‪226‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :Tuple‬فهم الصفوف‬

‫]‪coral[3‬‬

‫إذا حاولن ا اس تدعاء المتغ ير ‪ coral‬م ع رقم فه رس أك بر من ‪ ،3‬فس تظهر رس الة خط أ تش ير‬

‫أن الفهرس خارج المجال‪:‬‬


‫إلى َّ‬

‫)]‪print(coral[22‬‬
‫‪# IndexError: tuple index out of range‬‬

‫ً‬
‫أيض ا الوص ول إلى الفه ارس باس تخدام رقم‬ ‫إض ً‬
‫افة إلى أرق ام الفه ارس الموجب ة‪ ،‬يمكنن ا‬

‫بدءا من نهاي ة قائم ة العناص ر وس يرتبط آخ ر عنص ر ب الفهرس ‪ ،-1‬وه ذا‬


‫ً‬ ‫فهرس سالب‪ ،‬وذلك بالعد‬

‫َ‬
‫وأردت الوص ول إلى‬ ‫مفي ٌد ج ًدا إذا كان لديك متغ ير من الن وع ‪ tuple‬وك ان يحت وي عناص ر كث يرة‬

‫ً‬
‫انطالق ا من النهاي ة‪ .‬ففي مثالن ا الس ابق عن ‪ ،coral‬إذا أردن ا اس تخدام الفه ارس‬ ‫أح د عناص ره‬

‫السالبة فالناتج كاآلتي‪:‬‬

‫‪elkhorn coral‬‬ ‫‪pillar coral‬‬ ‫‪staghorn coral‬‬ ‫‪blue coral‬‬


‫‪-1‬‬ ‫‪-2‬‬ ‫‪-3‬‬ ‫‪-4‬‬

‫إذا أردن ا طباع ة العنص ر '‪ 'blue coral‬باس تخدام الفه ارس الس البة‪ ،‬فس تبدو التعليم ة‬

‫كما يلي‪:‬‬

‫)]‪print(coral[-4‬‬
‫‪blue coral‬‬

‫يمكننا إضافة العناصر النصية الموجودة في الص ف إلى السالس ل النص ية األخ رى باس تخدام‬

‫العامل ‪:+‬‬

‫▲‬ ‫|‬ ‫‪227‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :Tuple‬فهم الصفوف‬

‫)]‪print('This reef is made up of ' + coral[1‬‬


‫‪# This reef is made up of staghorn coral‬‬

‫اس تطعنا في المث ال الس ابق إض افة عنص ر موج ود في الفه رس ‪ 1‬م ع السلس لة النص ية‬

‫ً‬
‫أيضا استخدام العامل ‪ +‬إلضافة بنيتَي صف معً ا‪.‬‬ ‫' ‪ ،'This reef is made up of‬ويمكننا‬

‫‪ .2‬تقطيع قيم صف‬


‫يمكنن ا اس تخدام الفه ارس للوص ول إلى ع ِّدة عناص ر من ص ف‪ ،‬أم ا التقطي ع فيس مح لن ا‬

‫بالوصول إلى ِّ‬


‫عدة قيم عبر إنشاء مجال من أرقام الفهارس المفص ولة بنقط تين رأس يتين [‪.]x:y‬‬

‫لنق ل َّ‬
‫أنن ا نري د ع رض العناص ر الموج ودة في وس ط المتغ ير ‪ ،coral‬يمكنن ا فع ل ذل ك بإنش اء‬

‫قطعة جديدة‪:‬‬

‫)]‪print(coral[1:3‬‬
‫)'‪('staghorn coral', 'pillar coral‬‬

‫ِّ‬
‫فيمثل أوَّ ل رقم مك ان ب دأ القطع ة‬ ‫عن د إنش اء قطع ة جدي دة –كم ا في المث ال الس ابق–‬

‫ً‬
‫متضمنة هذا الفه رس)‪ ،‬ورقم الفه رس الث اني ه و مك ان نهاي ة القطع ة (دون تض مين ه ذا الفه رس‬ ‫(‬

‫بالقطع ة)‪ ،‬وه ذا ه و الس بب وراء ع رض المث ال الس ابق للقيم المرتبط ة بالعناص ر الموج ودة في‬

‫َ‬
‫أردت تضمين إحدى نه ايتَي القائم ة‪ ،‬فيمكن ك ح ذف أح د األرق ام في التعب ير‬ ‫الفهرسين ‪ 1‬و ‪ .2‬إذا‬

‫]‪ ،tuple[x:y‬فمثاًل ‪ ،‬لنق ل أنن ا نري د ع رض أوَّ ل ثالث ة عناص ر من ‪ ،coral‬وال تي هي‬

‫'‪ 'blue coral‬و '‪ 'staghorn coral‬و '‪ ،'pillar coral‬فيمكننا فعل ذلك كاآلتي‪:‬‬

‫)]‪print(coral[:3‬‬
‫)'‪('blue coral', 'staghorn coral', 'pillar coral‬‬

‫المثال السابق عرض العناصر من بداية القائم ة وتوق ف قب ل العنص ر ذي الفه رس ‪ .3‬لتض مين‬

‫▲‬ ‫|‬ ‫‪228‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :Tuple‬فهم الصفوف‬

‫كل العناصر الموجودة في نهاية الصف‪ ،‬فيمكننا عكس التعبير السابق‪:‬‬

‫)]‪print(coral[1:‬‬
‫)'‪# ('staghorn coral', 'pillar coral', 'elkhorn coral‬‬

‫ً‬
‫أيضا عند التقطيع‪ ،‬كما فعلنا مع أرقام الفهارس الموجبة‪:‬‬ ‫يمكننا استخدام الفهارس السالبة‬

‫)]‪print(coral[-3:-1‬‬
‫)]‪print(coral[-2:‬‬
‫)'‪# ('staghorn coral', 'pillar coral‬‬
‫)'‪# ('pillar coral', 'elkhorn coral‬‬

‫افي يمكنن ا اس تعماله ويس مى «الخط وة»‪ ،‬ويُ ش ير إلى ع دد العناص ر ال تي‬ ‫هنال ك معام ٌ‬
‫ل إض‬
‫ٌ‬

‫يجب تجاوزها بعد الحصول على أوّ ل عنصر من القائم ة‪ .‬ح ذفنا في جمي ع أمثلتن ا الس ابقة معام ل‬

‫الخط وة‪ ،‬إذ القيم ة االفتراض ية ل ه في ب ايثون هي ‪ ،1‬ل ذا سنحص ل على جمي ع العناص ر الموج ودة‬

‫الفهرس ين الم ذكورين‪ .‬ش كل ه ذا التعب ير الع ام ه و ]‪ ،tuple[x:y:z‬إذ يُ ش ير المعام ل ‪ z‬إلى‬


‫َ‬ ‫بين‬

‫ً‬
‫قائمة أكبر‪ ،‬ثم ِّ‬
‫نقسمها‪ ،‬ونعطيها القيمة ‪ 2‬للخطوة‪:‬‬ ‫الخطوة‪ .‬ل ُن ِ‬
‫نشئ‬

‫)‪numbers = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12‬‬


‫)]‪print(numbers[1:11:2‬‬
‫)‪# (1, 3, 5, 7, 9‬‬

‫س تطبع التعليمة]‪ numbers[1:11:2‬القيم الموج ودة بين رقمين الفهرس ين ‪( 1‬بم ا في ذل ك‬

‫العنص ر المرتب ط ب الفهرس ‪ )1‬و ‪( 11‬دون تض مين ذل ك العنص ر)‪ ،‬ومن ثم س تخبر قيم ُة الخط وة ‪2‬‬

‫أن يتخطى عنص رً ا بين ك ل عنص رين‪ .‬يمكنن ا ح ذف أوَّ ل مع املين واس تخدام معام ل‬
‫امج َّ‬
‫َ‬ ‫البرن‬

‫برمجي من الشكل ]‪:tuple[::z‬‬ ‫بتعبير‬


‫ٍ‬ ‫الخطوة بمفرده‬
‫ٍ‬

‫▲‬ ‫|‬ ‫‪229‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :Tuple‬فهم الصفوف‬

‫)]‪print(numbers[::3‬‬
‫)‪# (0, 3, 6, 9, 12‬‬

‫طبعن ا في المث ال الس ابق عناص ر ‪ numbers‬بع د ض بط قيم ة الخط وة إلى ‪ ،3‬وبالت الي س يتم‬

‫تخطي عنصرين‪.‬‬

‫‪0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12‬‬

‫تقطي ع الص فوف باس تخدام أرق ام الفه ارس الموجب ة والس البة واس تعمال معام ل الخط وة‬

‫يسمح لنا بالتحكم بالناتج الذي نريد عرضه‪.‬‬

‫‪ .3‬إضافة بنى صف إلى بعضها‬


‫يمكن أن ُنض يف ب نى ص ف إلى بعض ها أو أن «نض ربها» ( ‪ ،)multiply‬تتم عملي ة اإلض افة‬

‫باس تخدام المعام ل ‪ ،+‬أم ا عملي ة الض رب فباس تخدام المعام ل *‪ .‬يمكن أن يُ س تخ َدم المعام ل ‪+‬‬

‫ً‬
‫بعض ا‪ .‬يمكنن ا إس ناد القيم الموج ودة في ب نيتَي ص ف إلى‬ ‫إلض افة ب نيتَي ص ف أو أك ثر إلى بعض ها‬

‫بنية جديدة‪:‬‬

‫‪coral = ('blue coral', 'staghorn coral', 'pillar coral',‬‬


‫)'‪'elkhorn coral‬‬
‫)'‪kelp = ('wakame', 'alaria', 'deep-sea tangle', 'macrocystis‬‬

‫)‪coral_kelp = (coral + kelp‬‬

‫)‪print(coral_kelp‬‬

‫الناتج‪:‬‬

‫‪('blue coral', 'staghorn coral', 'pillar coral', 'elkhorn‬‬


‫)'‪coral', 'wakame', 'alaria', 'deep-sea tangle', 'macrocystis‬‬

‫▲‬ ‫|‬ ‫‪230‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :Tuple‬فهم الصفوف‬

‫أن المعام ل ‪ +‬يمكن ه إض افة ب نى ص ف إلى بعض ها‪ ،‬لكن يمكن أن يس تعمل إلنش اء‬
‫حيح َّ‬
‫ٌ‬ ‫وص‬

‫بنية صف جديدة ناتجة عن جمع ب نى أخ رى‪ ،‬لكن ال يمكن ه تع ديل بني ة ص ف موج ودة مس ً‬
‫بقا‪ .‬أم ا‬

‫العام ل * فيمكن اس تخدامه لض رب ب نى ص ف‪ ،‬فربم ا تري د إنش اء نس خ من الملف ات الموج ودة في‬

‫أحد المجلدات إلى الخ ادوم أو مش اركة قائم ة بالمقطوع ات الموس يقية ال تي تحبه ا م ع أص دقائك‪،‬‬

‫ففي هذه الحاالت سترغب بمضاعفة مجموعات من البيانات (أو «ضربها»)‪ .‬لنضرب البنية ‪coral‬‬

‫بالرقم ‪ 2‬والبنية ‪ kelp‬بالرقم ‪ ،3‬ثم نسندها إلى بنى صف جديدة‪:‬‬

‫‪multiplied_coral = coral * 2‬‬


‫‪multiplied_kelp = kelp * 3‬‬

‫)‪print(multiplied_coral‬‬
‫)‪print(multiplied_kelp‬‬

‫الناتج‪:‬‬

‫‪('blue coral', 'staghorn coral', 'pillar coral', 'elkhorn‬‬


‫‪coral', 'blue coral', 'staghorn coral', 'pillar coral',‬‬
‫)'‪'elkhorn coral‬‬
‫‪('wakame', 'alaria', 'deep-sea tangle', 'macrocystis',‬‬
‫‪'wakame', 'alaria', 'deep-sea tangle', 'macrocystis', 'wakame',‬‬
‫)'‪'alaria', 'deep-sea tangle', 'macrocystis‬‬

‫يمكنن ا باس تخدام العام ل * أن ُنك ِّرر (أو ُنض اعِ ف) ب نى ص ف ب أي ع دد من الم رات نش اء‪ ،‬مم ا‬

‫سي ُن ِشئ بنى صف جديدة اعتما ًدا على محتوى البنى األصلية‪ .‬خالصة ما س بق هي َّ‬
‫أن ب نى الص ف‬

‫َ‬
‫العاملين ‪ +‬و *‪.‬‬ ‫يمكن إضافتها إلى بعضها أو ضربها لتشكيل بنى صف جديدة عبر استخدام‬

‫▲‬ ‫|‬ ‫‪231‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :Tuple‬فهم الصفوف‬

‫‪ .4‬دوال التعامل مع الصفوف‬


‫هنالك دوال مُ ضمَّ نة في لغة بايثون للتعامل مع بنى النوع ‪ ،tuple‬لننظر إلى بعضها‪.‬‬

‫ا‪len() .‬‬

‫وكم ا في السالس ل النص ية والق وائم‪ ،‬يمكنن ا حس اب ط ول (أو ع دد عناص ر) بني ة ص ف‬

‫باستخدام الدالة )(‪ len‬إذ ُن ِّ‬


‫مرر إليها بنية صف (معامل)‪ ،‬كما يلي‪:‬‬

‫)‪len(coral‬‬

‫معين‪ ،‬فمثاًل يمكننا االستفادة‬


‫َّ‬ ‫هذه الدالة مفيدة إذا أردنا أن َنضمَ ن َّ‬
‫أن لبنية صف عدد عناصر‬

‫من ذل ك بموازن ة بني تين م ع بعض هما‪ .‬إذا أردن ا طباع ة ع دد عناص ر ‪ kelp‬و ‪ ،numbers‬فس يظهر‬

‫الناتج اآلتي‪:‬‬

‫))‪print(len(kelp‬‬
‫))‪print(len(numbers‬‬

‫الناتج‪:‬‬

‫‪4‬‬
‫‪13‬‬

‫أن للبنية ‪ kelp‬أربعة عناصر‪:‬‬


‫يشير الناتج أعاله إلى َّ‬

‫)'‪kelp = ('wakame', 'alaria', 'deep-sea tangle', 'macrocystis‬‬

‫أمَّ ا البنية ‪ numbers‬فتملك ثالثة عشر عنصرًا‪:‬‬

‫)‪numbers = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12‬‬

‫▲‬ ‫|‬ ‫‪232‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :Tuple‬فهم الصفوف‬

‫أن الدالة )(‪ len‬تس تطيع أن تخبرن ا بع دد‬


‫نسبيا‪ ،‬إال َّ‬
‫ً‬ ‫أن هذه األمثلة عناصرها قليلة‬
‫وصحيح َّ‬
‫ٌ‬

‫عناصر بنى ‪ tuple‬الكبيرة‪.‬‬

‫ب‪ .‬الدالتان )(‪ max‬و )(‪min‬‬

‫عن دما نتعام ل م ع ب نى ص ف مكوَّ ن ة من عناص ر رقمي ة (بم ا فيه ا األع داد الص حيحة واألرق ام‬

‫ذات الفاصلة العشرية)‪ ،‬فيمكننا استخدام الدالتين )(‪ max‬و )(‪ min‬للعثور على أك بر وأص غر قيم ة‬

‫معين ة‪ .‬تس مح لن ا هات ان ال دالتان باس تخراج معلوم ات تخص البيان ات‬
‫َّ‬ ‫موج ودة في بني ة ص ف‬

‫القابلة لإلحصاء‪ ،‬مثل نت ائج االمتحان ات أو درج ات الح رارة أو أس عار المنتج ات …إلخ‪ .‬لننظ ر إلى‬

‫بنية صف مكونة من أعداد عشرية‪:‬‬

‫‪more_numbers = (11.13, 34.87, 95.59, 82.49, 42.73, 11.12,‬‬


‫)‪95.57‬‬

‫للحصول على القيمة العظمى من بين القيم اآلتي ة فعلين ا تمري ر بني ة ص ف إلى الدال ة )(‪max‬‬

‫كما في )‪ ،max(more_numbers‬وسنستخدم الدالة )(‪ print‬لعرض الناتج‪:‬‬

‫))‪print(max(more_numbers‬‬
‫‪# 95.59‬‬

‫كل ش بيهٍ بم ا س بق نس تخدم‬


‫أعادت الدالة )(‪ max‬أعلى قيمة في بنية ‪ .more_numbers‬وبش ٍ‬

‫الدالة )(‪:min‬‬

‫))‪print(min(more_numbers‬‬
‫‪# 11.12‬‬

‫ُأ عي َد هن ا أص غر رقم عش ري موج ودة في البني ة‪ .‬يمكن االس تفادة من ال دالتين )(‪max‬‬

‫و )(‪ min‬كثيرً ا للتعامل مع بنى ‪ tuple‬التي تحتوي الكثير من القيم‪.‬‬

‫▲‬ ‫|‬ ‫‪233‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :Tuple‬فهم الصفوف‬

‫‪ .5‬كيف تختلف بنى الصفوف عن القوائم‬


‫الف رق الرئيس ي بين الن وع ‪ tuple‬والن وع ‪ list‬ه و ع دم الق درة على تع ديل العناص ر‪ ،‬وه ذا‬

‫يعني َّ‬
‫أنن ا ال نس تطيع إض افة أو ح ذف أو اس تبدال العناص ر داخ ل بني ة ‪ .tuple‬لكن يمكنن ا إض افة‬

‫ً‬
‫بعض ا لتش كيل بني ة جدي دة كم ا رأين ا في أح د األقس ام الس ابقة‪.‬‬ ‫ب نيتَي ‪ tuple‬أو أك ثر إلى بعض ها‬

‫لتكن لدينا البنية ‪ coral‬اآلتية‪:‬‬

‫‪coral = ('blue coral', 'staghorn coral', 'pillar coral',‬‬


‫)'‪'elkhorn coral‬‬

‫لنقل أننا نريد استبدال العنصر '‪ 'blue coral‬ووضع العنصر '‪ 'black coral‬بداًل منه‪.‬‬

‫فلو حاولنا تغيير بنية صف بنفس الطريقة التي ُن ِّ‬


‫عدل فيها القوائم بكتابة‪:‬‬

‫'‪coral[0] = 'black coral‬‬

‫فستظهر رسالة خطأ كاآلتية‪:‬‬

‫‪TypeError: 'tuple' object does not support item assignment‬‬

‫أن ما نحتاج له‬


‫وذلك بسبب عدم إمكانية تعديل بنى الصفوف‪ .‬إذا أنشأنا بنية صف ثم قررنا َّ‬

‫هو بنية قائمة‪ ،‬فيمكننا تحويلها إلى قائمة ‪ ،list‬وذلك بالدالة )(‪:list‬‬

‫)‪list(coral‬‬

‫ً‬
‫قائمة اآلن‪:‬‬ ‫أصبحت بنية ‪coral‬‬

‫]'‪coral = ['blue coral', 'staghorn coral', 'pillar coral‬‬

‫ألن األق واس المحيط ة‬ ‫أن بني ة الص ف ‪ tuple‬تح وَّ َ‬


‫لت إلى قائم ة ‪َّ list‬‬ ‫يمكنن ا أن نالح ظ َّ‬

‫بالقيم أصبحت مربعة الشكل‪.‬‬

‫▲‬ ‫|‬ ‫‪234‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :Tuple‬فهم الصفوف‬

‫كل ش بيهٍ بم ا س بق‪ ،‬نس تطيع تحوي ل الق وائم من الن وع ‪ list‬إلى ‪ tuple‬باس تخدام‬
‫وبش ٍ‬

‫الدالة )(‪.tuple‬‬

‫‪ .6‬خالصة الفصل‬
‫نوع البيانات ‪( tuple‬الصفوف) ه و مجموع ٌة من البيان ات المتسلس لة ال تي ال يمكن تع ديلها‪،‬‬

‫وي ِّ‬
‫وفر تحس ينًا في أداء برامج ك ألن ه أس رع معالج ًة من الق وائم في ب ايثون‪ .‬وعن دما يراج ع‬

‫اآلخرون شيفرتك فس يعلمون من اس تخدامك لب نى ‪ tuple‬أن ك ال تري د تع ديل ه ذه القيم‪ .‬ش رحنا‬

‫في هذا الفصل الميزات األساسية لبنى ‪ tuple‬بما في ذلك الفهارس وتقطيعها وتجميعها‪ ،‬وعرضنا‬

‫بعض الدوال المُ ضمَّ نة المتوافرة لهذا النوع من البيانات‪.‬‬

‫▲‬ ‫|‬ ‫‪235‬‬


‫‪13‬‬
‫النوع ‪:Dictionary‬‬
‫فهم القواميس‬

‫▲‬ ‫|‬ ‫‪236‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :Dictionary‬فهم القواميس‬

‫الن وع ‪( dictionary‬الق اموس) ه و ن وع مُ ض مَّ ن في ب ايثون‪ .‬ترب ط الق واميس مف اتيح بقيم‬

‫على هيئة أزواج‪ ،‬وهذه األزواج مفيدة لتخزين البيانات في بايثون‪.‬‬

‫ً‬
‫عادة لتخزين البيانات المترابطة‪ ،‬مثل المعلومات المرتبطة برقم تعريف‪،‬‬ ‫تستخدم القواميس‬

‫أو ملفات تعريف المستخدم‪ُ ،‬‬


‫وتنشأ باستخدام األقواس المعقوصة {}‪.‬‬

‫تبدو القواميس على الشكل التالي‪:‬‬

‫‪sammy = {'username': 'sammy-shark', 'online': True,‬‬


‫}‪'followers': 987‬‬

‫باإلض افة إلى القوس ين المعقوص ين‪ ،‬الح ظ وج ود النقط تين الرأس يتين (‪ ):‬في الق اموس‪.‬‬

‫أي ن وع‬
‫الكلم ات الموج ودة على يس ار النقط تين الرأس يتين هي المف اتيح (‪ )keys‬ال تي ق د تك ون َّ‬

‫بيانات غير قابل للتغيير‪ .‬المفاتيح في القاموس أعاله هي‪:‬‬

‫‪username‬‬ ‫•‬

‫‪online‬‬ ‫•‬

‫‪followers‬‬ ‫•‬

‫المفاتيح في المثال أعاله عبارة عن سالسل نصية‪.‬‬

‫ِّ‬
‫تمثل الكلم ات الموج ودة على يمين النقط تين «القيم» (‪ .)values‬يمكن أن تت ألف القيم من‬

‫أي نوع من البيانات‪ .‬القيم في القاموس أعاله هي‪:‬‬

‫‪sammy-shark‬‬ ‫•‬

‫‪True‬‬ ‫•‬

‫‪87‬‬ ‫•‬

‫▲‬ ‫|‬ ‫‪237‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :Dictionary‬فهم القواميس‬

‫قيم الق اموس أعاله هي إمَّ ا سالس ل نص ية أو قيم منطقي ة أو أع داد ص حيحة‪ .‬س نطبع اآلن‬

‫القاموس ‪:sammy‬‬

‫)‪print(sammy‬‬

‫الناتج‪:‬‬

‫}‪{'username': 'sammy-shark', 'followers': 987, 'online': True‬‬

‫نالح ظ ب النظر إلى المخرج ات تغ ير ت رتيب األزواج قيم ة‪-‬مفت اح (‪ .)key-value‬في اإلص دار‬

‫داء من ب ايثون ‪ ،3.6‬ص ارت الق واميس‬


‫ب ايثون ‪ 3.5‬وم ا قبل ه‪ ،‬ك انت الق واميس غ ير مرتب ة‪ .‬لكن ابت ً‬

‫مرتب ا أم ال‪ ،‬س تظل األزواج قيم ة‪-‬مفت اح كم ا هي‪ ،‬وه ذا‬
‫ً‬ ‫مرتب ًة‪ .‬بغض النظ ر عم ا إذا ك ان الق اموس‬

‫ِّ‬
‫سيمكنك من الوصول إلى البيانات بناء على ترابطاتها‪.‬‬

‫‪ .1‬الوصول إلى عناصر قاموس‬


‫يمكنن ا الوص ول إلى قيم مح َّددة في الق اموس ب الرجوع إلى المف اتيح المرتبط ة به ا ويمكن‬

‫ً‬
‫أيضا االستعانة ببعض التوابع الجاهزة للوصول إلى القيم أو المفاتيح أو كليهما‪.‬‬

‫ا‪ .‬الوصول إلى عناصر القاموس باستخدام المفاتيح‬

‫إذا أردن ا الحص ول على اس م المس تخدم في ‪ ،Sammy‬فيمكنن ا ذل ك عن طري ق‬

‫استدعاء ]'‪ .sammy['username‬هذا مثال على ذلك‪:‬‬

‫)]'‪print(sammy['username‬‬ ‫‪#‬‬ ‫‪sammy-shark‬‬

‫▲‬ ‫|‬ ‫‪238‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :Dictionary‬فهم القواميس‬

‫تتصرف القواميس مثل قواعد البيان ات‪ ،‬فهي ب داًل من فهرس ة العناص ر بأع داد ص حيحة‪ ،‬كما‬

‫ه و الح ال في الق وائم‪ِّ ،‬‬


‫فإنه ا ُتفه رس العناص ر (أو قيم الق اموس) بمف اتيح‪ ،‬ويمكن ك ع بر تل ك‬

‫المفاتيح الحصول على القيم المقابلة لها‪.‬‬

‫باس تدعاء المفت اح ‪ ،username‬سنحص ل على القيم ة المرتبط ة ب ه‪ ،‬وهي ‪.sammy-shark‬‬

‫وبالمِ ثل‪ ،‬يمكن استدعاء القيم األخرى في القاموس ‪ sammy‬باستخدام نفس الصياغة‪:‬‬

‫]'‪sammy['followers‬‬ ‫‪# 987‬‬

‫]'‪sammy['online‬‬ ‫‪# True‬‬

‫ب‪ .‬استخدام التوابع للوصول إلى العناصر‬

‫ً‬
‫أيض ا اس تخدام بعض التواب ع‬ ‫باإلض افة إلى اس تخدام المف اتيح للوص ول إلى القيم‪ ،‬يمكنن ا‬

‫المُ ضمّ نة‪ ،‬مثل‪:‬‬

‫)(‪ :dict.keys‬الحصول على المفاتيح‬ ‫•‬

‫)(‪ :dict.values‬الحصول على القيم‬ ‫•‬

‫)(‪ :dict.items‬الحصول على العناصر على هيئة قائمة من أزواج (‪)key, value‬‬ ‫•‬

‫إلعادة المفاتيح‪ ،‬نستخدم التابع )(‪ ،dict.keys‬كما يوضح المثال التالي‪:‬‬

‫))(‪print(sammy.keys‬‬
‫‪#‬‬ ‫)]'‪dict_keys(['followers', 'username', 'online‬‬

‫كائن ع رض تك راري (‪ )iterable view object‬من الص نف ‪dict_keys‬‬


‫َ‬ ‫تلقينا في المخرجات‬

‫يحوي المفاتيح ثم ُط ِبعت المفاتيح على هيئة قائمة‪.‬‬

‫▲‬ ‫|‬ ‫‪239‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :Dictionary‬فهم القواميس‬

‫يمكن اس تخدام ه ذا الت ابع لالس تعالم من الق واميس‪ .‬على س بيل المث ال‪ ،‬يمكنن ا البحث عن‬

‫المفاتيح المشتركة بين قاموسين‪:‬‬

‫‪sammy = {'username': 'sammy-shark', 'online': True,‬‬


‫}‪'followers': 987‬‬
‫‪jesse = {'username': 'JOctopus', 'online': False, 'points':‬‬
‫}‪723‬‬

‫‪for common_key in sammy.keys() & jesse.keys():‬‬


‫)]‪print(sammy[common_key], jesse[common_key‬‬

‫أن لهم ا مف اتيح‬


‫يح وي القاموس ان ‪ sammy‬و ‪ jesse‬معلوم ات تعري ف المس تخدم‪ .‬كم ا َّ‬

‫ً‬
‫مفتاح ا ‪ followers‬يمث ل المت ابعين على‬ ‫ألن ل دى ‪ Sammy‬مل ف تعري ف اجتم اعي يض م‬
‫مختلف ة‪َّ ،‬‬

‫ً‬
‫مفتاح ا ‪ points‬يمث ل النق اط‪ .‬كال‬ ‫الشبكة االجتماعية‪ ،‬أما ‪ Jesse‬فلها مل ف تعري ف لأللع اب يض م‬

‫القاموس ين يش تركان في المفت احين ‪ username‬و ‪ ،online‬ويمكن العث ور عليهم ا عن د تنفي ذ‬

‫البريمج‪:‬‬
‫هذا ُ‬

‫‪sammy-shark JOctopus‬‬
‫‪True False‬‬

‫ولكن الغ رض هن ا ه و توض يح‬


‫َّ‬ ‫يمكنن ا بالتأكي د تحس ين البرن امج لتس هيل ق راءة المخرج ات‪،‬‬

‫إمكانية اس تخدام )(‪ dict.keys‬لرص د المف اتيح المش تركة بين ع َّدة ق واميس‪ .‬ه ذا مفي د بش كل‬

‫خاص عند العمل على القواميس الكبيرة‪.‬‬

‫وبالمث ل‪ ،‬يمكنن ا اس تخدام الت ابع )(‪ dict.values‬لالس تعالم عن القيم الموج ودة في‬

‫القاموس ‪ sammy‬على النحو التالي‪:‬‬

‫▲‬ ‫|‬ ‫‪240‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :Dictionary‬فهم القواميس‬

‫‪sammy = {'username': 'sammy-shark', 'online': True,‬‬


‫}‪'followers': 987‬‬

‫))(‪print(sammy.values‬‬ ‫‪#‬‬ ‫‪dict_values([True, 'sammy-shark',‬‬


‫)]‪987‬‬

‫يُ عي د كال الت ابعين )(‪ values‬و )(‪ keys‬ق وائم غ ير مرتب ة تض م مف اتيح وقيم الق اموس‬

‫عرض من الصنف ‪ dict_values‬و ‪ dict_keys‬على التوالي‪.‬‬


‫ٍ‬ ‫‪ sammy‬على هيئة كاِئني‬

‫إن أردت الحصول على األزواج الموجودة في القاموس‪ ،‬فاستخدم التابع )(‪:items‬‬

‫))(‪print(sammy.items‬‬

‫المخرجات ستكون‪:‬‬

‫‪dict_items([('online', True), ('username', 'sammy-shark'),‬‬


‫)])‪('followers', 987‬‬

‫‪ )key,‬من‬ ‫س تكون النتيج ة المع ادة على هيئ ة قائم ة مكون ة من أزواج (‪value‬‬

‫الصنف ‪.dict_items‬‬

‫يمكنن ا التك رار (‪ )iterate‬على القائم ة المُ ع ادة باس تخدام الحلق ة ‪ .for‬على س بيل المث ال‪،‬‬

‫يمكنن ا طباع ة جمي ع مف اتيح وقيم الق اموس المح دد‪ ،‬ثم جعله ا أك ثر مقروئي ة ع بر إض افة سلس لة‬

‫نصية توضيحية‪:‬‬

‫‪for key, value in sammy.items():‬‬


‫)‪print(key, 'is the key for the value', value‬‬

‫وسينتج لنا‪:‬‬

‫▲‬ ‫|‬ ‫‪241‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :Dictionary‬فهم القواميس‬

‫‪online is the key for the value True‬‬


‫‪followers is the key for the value 987‬‬
‫‪username is the key for the value sammy-shark‬‬

‫ك رَّ رت الحلق ة ‪ for‬على العناص ر الموج ودة في الق اموس ‪ ،sammy‬وطبعت المف اتيح والقيم‬

‫سط ًرا سطرًا‪ ،‬مع إضافة معلومات توضيحية‪.‬‬

‫‪ .2‬تعديل القواميس‬
‫الق واميس هي هياك ل بيان ات قابل ة للتغي ير (‪ ،)mutable‬أي يمكن تع ديلها‪ .‬في ه ذا القس م‪،‬‬

‫سنتعلم كيفية إضافة عناصر إلى قاموس‪ ،‬وكيفية حذفها‪.‬‬

‫ا‪ .‬إضافة وتغيير عناصر القاموس‬

‫يمكن ك إض افة أزواج قيم ة‪-‬مفت اح إلى ق اموس دون اس تخدام تواب ع أو دوال باس تخدام‬

‫الصياغة التالية‪:‬‬

‫‪dict[key] = value‬‬

‫زوجا مفتاح‪-‬قيمة إلى قاموس يُ سمى ‪:usernames‬‬


‫ً‬ ‫في المثال التالي‪ ،‬سنضيف‬

‫}'‪usernames = {'Sammy': 'sammy-shark', 'Jamie': 'mantisshrimp54‬‬

‫'‪usernames['Drew'] = 'squidly‬‬

‫)‪print(usernames‬‬ ‫‪#‬‬ ‫‪{'Drew': 'squidly', 'Sammy': 'sammy-‬‬


‫}'‪shark', 'Jamie': 'mantisshrimp54‬‬

‫أن القاموس قد تم تحديثه بالزوج '‪.'Drew': 'squidly‬‬


‫الحظ َّ‬

‫▲‬ ‫|‬ ‫‪242‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :Dictionary‬فهم القواميس‬

‫ألن الق واميس غ ير مرتب ة‪ ،‬فيمكن أن يظه ر ال زوج المُ ض اف في ِّ‬


‫أي مك ان في مخرج ات‬ ‫نظ رًا َّ‬

‫ً‬
‫الحقا‪ ،‬فسيظهر فيه الزوج المضاف حدي ًثا‪.‬‬ ‫القاموس‪ .‬إذا استخدمنا القاموس ‪usernames‬‬

‫معين‪ .‬في هذه الحالة‪ ،‬سنش ير‬


‫َّ‬ ‫يمكن استخدام هذه الصياغة لتعديل القيمة المرتبطة بمفتاح‬

‫ِّ‬
‫ونمرر قيمة مختلفة إليه‪.‬‬ ‫ً‬
‫سلفا‪،‬‬ ‫إلى مفتاح موجود‬

‫قاموس ا باس م ‪ِّ drew‬‬


‫يمثل البيان ات الخاص ة بأح د المس تخدمين‬ ‫ً‬ ‫س ِّ‬
‫نعرف في المث ال الت الي‬

‫على بعض الشبكات االجتماعية‪ .‬حص ل ه ذا المس تخدم على ع دد من المت ابعين اإلض افيين الي وم‪،‬‬

‫لذلك سنح ّدث القيمة المرتبطة بالمفتاح ‪ followers‬ثم نس تخدم الت ابع )(‪ print‬للتحق ق من ّ‬
‫أن‬

‫القاموس قد عُ ِّدل‪.‬‬

‫‪drew = {'username': 'squidly', 'online': True, 'followers':‬‬


‫}‪305‬‬

‫‪drew['followers'] = 342‬‬

‫)‪print(drew‬‬
‫‪#‬‬ ‫}‪{'username': 'squidly', 'followers': 342, 'online': True‬‬

‫أن عدد المتابعين قد قفز من ‪ 305‬إلى ‪.342‬‬


‫في المخرجات نرى ّ‬

‫يمكنن ا اس تخدام ه ذه الطريق ة إلض افة أزواج قيم ة‪-‬مفت اح إلى الق واميس ع بر م دخالت‬

‫بريمج ا س ريعً ا‪ ،usernames.py ،‬يعم ل من س طر األوام ر ويس مح للمس تخدم‬


‫ً‬ ‫المستخدم‪ .‬س نكتب‬

‫بإضافة األسماء وأسماء المستخدمين المرتبطة بها‪:‬‬

‫▲‬ ‫|‬ ‫‪243‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :Dictionary‬فهم القواميس‬

‫تعريف القاموس األصلي ‪#‬‬


‫}'‪usernames = {'Sammy': 'sammy-shark', 'Jamie': 'mantisshrimp54‬‬
‫إعداد الحلقة التكرارية ‪# while‬‬
‫‪while True:‬‬
‫اطلب من المستخدم إدخال اسم ‪#‬‬
‫)'‪print('Enter a name:‬‬

‫تعيين المدخالت إلى المتغير ‪# name‬‬


‫)(‪name = input‬‬

‫ًا في القاموس ثم اطبع الرد ‪#‬‬


‫تحقق مما إذا كان االسم موجود‬
‫‪if name in usernames:‬‬
‫)‪print(usernames[name] + ' is the username of ' + name‬‬

‫إذا لم يكن االسم في القاموس ‪#‬‬


‫‪else:‬‬

‫اطبع الرد ‪#‬‬


‫‪print('I don\'t have ' + name + '\'s username, what is‬‬
‫)'?‪it‬‬

‫خذ اسم مستخدم جديد لربطه بذلك االسم ‪#‬‬


‫)(‪username = input‬‬

‫عين قيمة اسم المستخدم إلى المفتاح ‪# name‬‬


‫‪usernames[name] = username‬‬

‫ّ البيانات قد حُد‬
‫ّثت ‪#‬‬ ‫ّن أن‬
‫ًا يبي‬
‫اطبع رد‬
‫)'‪print('Data updated.‬‬

‫ِّ‬
‫سننفذ البرنامج من سطر األوامر‪:‬‬

‫‪python usernames.py‬‬

‫▲‬ ‫|‬ ‫‪244‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :Dictionary‬فهم القواميس‬

‫عندما ِّ‬
‫ننفذ البرنامج‪ ،‬سنحصل على مخرجات مشابهة لما يلي‪:‬‬

‫‪Enter a name:‬‬
‫‪Sammy‬‬
‫‪sammy-shark is the username of Sammy‬‬
‫‪Enter a name:‬‬
‫‪Jesse‬‬
‫?‪I don't have Jesse's username, what is it‬‬
‫‪JOctopus‬‬
‫‪Data updated.‬‬
‫‪Enter a name:‬‬

‫عن د االنته اء من اختب ار البرن امج‪ ،‬اض غط على ‪ CTRL + C‬للخ روج من البرن امج‪ .‬يمكن ك‬

‫تخص يص ح رف إلنه اء البرن امج (مث ل الح رف ‪ ،)q‬وجع ل البرن امج يُ نص ت ل ه ع بر‬

‫التعليمات الشرطية‪.‬‬

‫يوضح ه ذا المث ال كي ف يمكن ك تع ديل الق واميس بش كل تف اعلي‪ .‬في ه ذا البرن امج‪ ،‬بمج رد‬

‫خروجك باستخدام ‪ ،CTRL + C‬ستفقد جميع بياناتك‪ ،‬إال إن ّ‬


‫خزنَت البيانات في ملف‪.‬‬

‫ً‬
‫أيضا إضافة عناصر إلى القواميس وتعديلها باس تخدام الت ابع )(‪ .dict.update‬ه ذا‬ ‫يمكننا‬

‫التابع مختلف عن التابع )(‪ append‬الذي يُ ستخدم مع القوائم‪.‬‬

‫سنض يف المفت اح ‪ followers‬في الق اموس ‪ jesse‬أدن اه‪ ،‬و َنمنح ه قيم ة عددي ة ص حيحة‬

‫بواسطة التابع )(‪ .jesse.update‬بعد ذلك‪ ،‬سنطبع القاموس المُ ح َّدث‪.‬‬

‫‪jesse = {'username': 'JOctopus', 'online': False, 'points':‬‬


‫}‪723‬‬

‫)}‪jesse.update({'followers': 481‬‬

‫)‪print(jesse‬‬ ‫‪#‬‬ ‫‪{'followers': 481, 'username': 'JOctopus',‬‬

‫▲‬ ‫|‬ ‫‪245‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :Dictionary‬فهم القواميس‬

‫}‪'points': 723, 'online': False‬‬

‫نتبين من المخرجات َّ‬


‫أننا نجحنا في إضافة الزوج ‪ followers: 481‬إلى القاموس ‪.jesse‬‬ ‫َّ‬

‫أيض ا اس تخدام الت ابع )(‪ dict.update‬لتع ديل زوج قيم ة‪-‬مفت اح موج ود س ً‬
‫لفا عن‬ ‫ً‬ ‫يمكنن ا‬

‫معين‪.‬‬
‫َّ‬ ‫طريق استبدال قيمة مفتاح‬

‫سنغيِّ ر القيمة المرتبطة بالمفتاح ‪ online‬في القاموس ‪ Sammy‬من ‪ True‬إلى ‪:False‬‬

‫‪sammy = {'username': 'sammy-shark', 'online': True,‬‬


‫}‪'followers': 987‬‬

‫)}‪sammy.update({'online': False‬‬

‫)‪print(sammy‬‬ ‫‪#‬‬ ‫‪{'username': 'sammy-shark', 'followers': 987,‬‬


‫}‪'online': False‬‬

‫‪ sammy.update({'online':‬القيم ة المرتبط ة بالمفت اح‬ ‫يغي ر الس طر )}‪False‬‬


‫ّ‬

‫'‪ 'online‬من ‪ True‬إلى ‪ .False‬عن د اس تدعاء الت ابع )(‪ print‬على الق اموس‪ ،‬يمكن ك أن ت رى‬

‫أن التحديث قد تمّ‪.‬‬


‫في المخرجات َّ‬

‫ا اس تخدام الص ياغة‬ ‫إلض افة عناص ر إلى الق واميس أو تع ديل القيم‪ ،‬يمكن إمّ‬

‫‪ ،dict[key] = value‬أو التابع )(‪.dict.update‬‬

‫‪ .3‬حذف عناصر من القاموس‬


‫ً‬
‫أيض ا ح ذف‬ ‫كم ا يمكن ك إض افة أزواج قيم ة‪-‬مفت اح إلى الق اموس‪ ،‬أو تغي ير قيم ه‪ ،‬يمكن ك‬

‫العناصر الموجودة في القاموس‪.‬‬

‫لتزيل زوج قيمة‪-‬مفتاح من القاموس‪ ،‬استخدم الصياغة التالية‪:‬‬

‫▲‬ ‫|‬ ‫‪246‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :Dictionary‬فهم القواميس‬

‫]‪del dict[key‬‬

‫أن ‪ jesse‬لم تع د تس تخدم‬


‫لنأخذ القاموس ‪ jesse‬الذي يمثل أحد المس تخدمين‪ ،‬ولنف ترض َّ‬

‫المنصة ألجل ممارسة األلع اب‪ ،‬ل ذلك س نزيل العنص ر المرتب ط بالمفت اح ‪ .points‬بع د ذل ك‪ ،‬س نطبع‬

‫القاموس لتأكيد حذف العنصر‪:‬‬

‫‪jesse = {'username': 'JOctopus', 'online': False, 'points':‬‬


‫}‪723, 'followers': 481‬‬

‫]'‪del jesse['points‬‬

‫)‪print(jesse‬‬
‫‪#‬‬ ‫}‪{'online': False, 'username': 'JOctopus', 'followers': 481‬‬

‫يزيل السطر ]'‪ del jesse ['points‬الزوج '‪ points': 723‬من القاموس ‪.jesse‬‬

‫إذا أردت مح و جمي ع عناص ر الق اموس‪ ،‬فيمكن ك ذل ك باس تخدام الت ابع )(‪.dict.clear‬‬

‫ً‬
‫الحق ا في البرن امج‪،‬‬ ‫سي بقى هذا القاموس في الذاكرة‪ ،‬وهذا مفيد في حال احتجنا إلى استخدامه‬
‫َ‬

‫سي ِّ‬
‫فرغ جميع العناصر من القاموس‪.‬‬ ‫بيد أنه ُ‬
‫ْ‬

‫دعنا نزيل كل عناصر القاموس ‪:jesse‬‬

‫‪jesse = {'username': 'JOctopus', 'online': False, 'points':‬‬


‫}‪723, 'followers': 481‬‬

‫)(‪jesse.clear‬‬

‫)‪print(jesse‬‬ ‫‪#‬‬ ‫}{‬

‫ً‬
‫فارغا اآلن‪.‬‬ ‫أن القاموس صار‬ ‫ُت ِ‬
‫ظهر المخرجات َّ‬

‫إذا لم تعد بحاجة إلى القاموس‪ ،‬فاستخدم ‪ del‬للتخلص منه بالكامل‪:‬‬

‫▲‬ ‫|‬ ‫‪247‬‬


‫البرمجة بلغة بايثون‬ ‫النوع ‪ :Dictionary‬فهم القواميس‬

‫‪del jesse‬‬

‫)‪print(jesse‬‬

‫إذا ّ‬
‫نفذت األمر )(‪ print‬بعد حذف القاموس ‪ ،jesse‬سوف تتلقى الخطأ التالي‪:‬‬

‫‪NameError: name 'jesse' is not defined‬‬

‫‪ .4‬خالصة الفصل‬
‫ألقين ا في ه ذا الفص ل نظ رة على الن وع ‪( dictionary‬الق واميس) في ب ايثون‪ .‬تت ألف‬

‫الق واميس (‪ )dictionaries‬من أزواج قيم ة‪-‬مفت اح‪ ،‬وت وفر حاًّل ممت ً‬
‫ازا لتخ زين البيان ات دون‬

‫اء على معانيه ا وعالقته ا ب أنواع‬


‫الحاج ة إلى فهرس تها‪ .‬ي تيح لن ا ذل ك اس ترداد القيم بن ً‬

‫البيانات األخرى‪.‬‬

‫إن لم تطلع على فصل فهم أنواع البيانات‪ ،‬فيمكنك الرجوع إلي ه للتع رف على أن واع البيان ات‬

‫األخرى الموجودة في بايثون‪.‬‬

‫▲‬ ‫|‬ ‫‪248‬‬


‫التعليمات الشرطية‬
‫‪14‬‬

‫▲‬ ‫|‬ ‫‪249‬‬


‫البرمجة بلغة بايثون‬ ‫التعليمات الشرطية‬

‫اء على‬ ‫ال تخلو لغة برمج ة من التعليم ات الش رطية (‪ )conditional statement‬ال تي ُت َّ‬
‫نفذ بن ً‬

‫تحقق شرط معين‪ ،‬وهي تعليمات برمجية يمكنها التحكم في تنفيذ شيفرات معينة بحسب تحق ق‬

‫شرط ما من عدمه في وقت التنفيذ‪.‬‬

‫ُت َّ‬
‫نفذ تعليم ات ب رامج ب ايثون من األعلى إلى األس فل‪ ،‬م ع تنفي ذ ك ل س طر بحس ب ترتيب ه‪.‬‬

‫باستخدام التعليم ات الش رطية‪ ،‬يمكن لل برامج التحق ق من اس تيفاء ش روط معين ة‪ ،‬ومن ثم تنفي ذ‬

‫الشيفرة المقابلة‪.‬‬

‫هذه بعض األمثلة التي سنستخدم فيها التعليمات الشرطية‪:‬‬

‫إن حص لت طالب ة على أك ثر من ‪ ٪65‬في االمتح ان‪ ،‬ف أعلن عن نجاحه ا؛ وإال‪ ،‬ف أعلن‬ ‫•‬
‫عن رسوبها‬

‫إذا كان لديه مال في حسابه‪ ،‬فاحسب الفائدة‪ .‬وإال‪ ،‬فاحسب غرامة‬ ‫•‬

‫إن اشتروا ‪ 10‬برتقاالت أو أكثر‪ ،‬فاحسب خصمً ا بمقدار ‪٪5‬؛ وإال فال تفعل‬ ‫•‬

‫اء على م ا إذا تحققت تل ك الش روط أم ال‪.‬‬ ‫ً‬


‫يفرة بن ً‬ ‫شروطا‪ ،‬ثم ُت ِّ‬
‫نفذ ش‬ ‫ً‬ ‫تقيِّ م الشيفرة الشرطية‬

‫كيفية كتابة التعليمات الشرطية في بايثون‪.‬‬


‫َّ‬ ‫ستتعلم في هذا الفصل‬

‫‪ .1‬التعليمة ‪if‬‬
‫سنبدأ بالتعليمة ‪ ،if‬والتي تتحقق مما إذا تحقق شرط مح َّدد أم ال‪ ،‬وفي حال تحق ق الش رط‪،‬‬

‫َّ‬
‫فستنفذ الشيفرة المقابلة له‪ .‬لنبدأ بأمثلة عملية توضح ذلك‪ .‬افتح ً‬
‫ملفا‪ ،‬واكتب الشيفرة التالية‪:‬‬

‫‪grade = 70‬‬
‫‪if grade >= 65:‬‬
‫)"درجة النجاح"(‪print‬‬

‫▲‬ ‫|‬ ‫‪250‬‬


‫البرمجة بلغة بايثون‬ ‫التعليمات الشرطية‬

‫أعطين ا للمتغ ير ‪ grade‬القيم ة ‪ .70‬ثمَّ اس تخدمنا التعليم ة ‪ if‬لتق ييم م ا إذا ك ان المتغ ير‬

‫‪ grade‬أك بر من (=>) أو يس اوي ‪ .65‬وفي تل ك الحال ة‪ ،‬س يطبع البرن امج السلس لة النص ية التالي ة‪:‬‬

‫"درجة النجاح"‪.‬‬

‫احف ظ البرن امج باالس م ‪ ،grade.py‬ثم ِّ‬


‫نفذه في بيئ ة البرمج ة المحلي ة من ناف ذة الطرفي ة‬

‫ألنه ا أك بر من ‪،65‬‬
‫باستخدام األمر ‪ .python grade.py‬في هذه الحالة‪ ،‬الدرجة ‪ 70‬تل بي الش رط‪ّ ،‬‬

‫لذلك ستحصل على المخرجات التالية عند تنفيذ البرنامج‪:‬‬

‫درجة النجاح‬

‫لنغير اآلن نتيجة هذا البرنامج عبر تغيير قيمة المتغير ‪ grade‬إلى ‪:60‬‬
‫ّ‬

‫‪grade = 60‬‬

‫‪if grade >= 65:‬‬


‫)"درجة النجاح"(‪print‬‬

‫ألن الش رط لم يتحق ق‪ ،‬ولم ن أمر‬


‫بع د حف ظ وتنفي ذ الش يفرة‪ ،‬لن نحص ل على أي مخرج ات‪ّ ،‬‬

‫البرنامج بتنفيذ تعليمة أخرى‪.‬‬

‫نتحقق مم ا إذا ك ان رص يد الحس اب المص رفي أق ل من ‪ .0‬لننش ئ ملف ا باس م‬


‫َّ‬ ‫مثال آخر‪ ،‬دعن ا‬

‫‪ ،account.py‬ونكتب البرنامج التالي‪:‬‬

‫‪balance = -5‬‬

‫‪if balance < 0:‬‬


‫)"‪.‬الحساب فارغ‪ ،‬أضف مبلغا اآلن‪ ،‬أو ستحصل على غرامة"(‪print‬‬

‫▲‬ ‫|‬ ‫‪251‬‬


‫البرمجة بلغة بايثون‬ ‫التعليمات الشرطية‬

‫عند تنفيذ البرنامج باستخدام ‪ ،python account.py‬سنحصل على المخرجات التالية‪:‬‬

‫‪.‬الحساب فارغ‪ ،‬أضف مبلً‬


‫غا اآلن‪ ،‬أو ستحصل على غرامة‬

‫أعطينا للمتغ ير ‪ balance‬القيم ة ‪ ،-5‬وهي أق ل من ‪ 0‬في البرن امج الس ابق‪ .‬ولمَّ ا ك ان الرص يد‬

‫توفيا لش رط التعليم ة ‪( if‬أي ‪ ،)balance < 0‬فسنحص ل على سلس لة نص ية في المخرج ات‬
‫ً‬ ‫مس‬

‫بمجرد حفظ الشيفرة وتنفيذها‪ .‬مرة أخرى‪ ،‬لو غيرنا الرصيد إلى القيمة ‪ 0‬أو إلى عدد م وجب‪ ،‬فلن‬

‫أي مخرجات‪.‬‬
‫نحصل على ّ‬

‫‪ .2‬التعليمة ‪else‬‬
‫ق د تري د من البرن امج أن يفع ل ش يًئا م ا في ح ال ع دم تحق ق ش رط التعليم ة ‪ .if‬في المث ال‬

‫أعاله‪ ،‬نريد طباعة مخرجات في حال النجاح والرسوب‪ .‬ولفع ل ذل ك‪ ،‬سنض يف التعليم ة ‪ else‬إلى‬

‫شرط الدرجة أعاله وفق الصياغة التالية‪:‬‬

‫‪grade = 60‬‬

‫‪if grade >= 65:‬‬


‫)"درجة النجاح"(‪print‬‬

‫‪else:‬‬
‫)"درجة الرسوب"(‪print‬‬

‫إن‬
‫قيم ة المتغ ير ‪ grade‬تس اوي ‪ ،60‬ل ذلك فش رط التعليم ة ‪ if‬غ ير متحق ق‪ ،‬وبالت الي ف َّ‬

‫أن عليه طباع ة السلس لة‬


‫البرنامج َّ‬
‫َ‬ ‫البرنامج لن يطبع السلسلة "درجة النجاح"‪ .‬تخبر التعليمة ‪else‬‬

‫ِّ‬
‫وننفذه‪ ،‬سنحصل على المخرجات التالية‪:‬‬ ‫النصية "درجة الرسوب"‪ .‬عندما نحفظ البرنامج‬

‫درجة الرسوب‬

‫▲‬ ‫|‬ ‫‪252‬‬


‫البرمجة بلغة بايثون‬ ‫التعليمات الشرطية‬

‫إذا ع ّدلنا البرن امج وأعطين ا المتغ يرَ ‪ grade‬القيم ة ‪ 65‬أو أعلى منه ا‪ ،‬فسنحص ل ب داًل من ذل ك‬

‫على الناتج "درجة النجاح"‪.‬‬

‫إلضافة التعليمة ‪ else‬إلى مثال الحساب المصرفي‪ ،‬سنعيد كتابة الشيفرة كما يلي‪:‬‬

‫‪balance = 522‬‬

‫‪if balance < 0:‬‬


‫)"‪.‬الحساب فارغ‪ ،‬أضف مبلغا اآلن‪ ،‬أو ستحصل على غرامة"(‪print‬‬

‫‪else:‬‬
‫)"‪.‬رصيدك أكبر من ‪print("0‬‬

‫سنحصل على المخرجات التالية‪:‬‬

‫‪.‬رصيدك أكبر من ‪0‬‬

‫غيرن ا قيم ة المتغ ير ‪ balance‬إلى ع دد م وجب لكي ُت َّ‬


‫نفذ الش يفرة المقابل ة‬ ‫هن ا‪َّ ،‬‬

‫للتعليمة ‪ .else‬إن أردت تنفيذ الشيفرة المقابلة للتعليمة ‪ ،if‬غيِّ ر القيمة إلى عدد سالب‪.‬‬

‫من خالل دمج العب ارتين ‪ if‬و ‪ ،else‬ف أنت تنش ئ تعليم ة ش رطية مزدوج ة‪ ،‬وال تي س تجعل‬

‫الحاسوب ينفذ شيفرة برمجية معينة سواء تم استيفاء شرط ‪ if‬أم ال‪.‬‬

‫‪ .3‬التعليمة ‪else if‬‬


‫ح تى اآلن‪ ،‬عملن ا على تعليم ات ش رطية ثنائي ة‪ ،‬أي إن تحق ق الش رط‪ ،‬فنف ذ ش يفرة م ا‪ ،‬وإال‪،‬‬

‫ً‬
‫برنامجا يتحقق من عدة حاالت شرطية‪.‬‬ ‫ِّ‬
‫فنفذ شيفرة أخرى فقط‪ .‬لكن في بعض الحاالت‪ ،‬قد تريد‬

‫وألج ل ه ذا‪ ،‬س وف نس تخدم التعليمة ‪ ،else if‬وال تي ُتكتب في ب ايثون هك ذا ‪ .elif‬تش به‬

‫التعليمة ‪ - elif‬أو ‪ - else if‬التعليمة ‪ ،if‬ومهمتها التحقق من شرط إضافي آخر‪.‬‬

‫▲‬ ‫|‬ ‫‪253‬‬


‫البرمجة بلغة بايثون‬ ‫التعليمات الشرطية‬

‫في برنامج الحساب المصرفي‪ ،‬قد ن رغب في الحص ول على ثالث ة مخرج ات مختلف ة مقابل ة‬

‫لثالث حاالت مختلفة‪:‬‬

‫الرصيد أقل من ‪0‬‬ ‫•‬

‫الرصيد يساوي ‪0‬‬ ‫•‬

‫الرصيد أعلى من ‪0‬‬ ‫•‬

‫ستوضع التعليمة ‪ elif‬بين التعليمة ‪ if‬والتعليمة ‪ else‬كما يلي‪:‬‬

‫‪. . .‬‬
‫‪if balance < 0:‬‬
‫)"‪.‬الحساب فارغ‪ ،‬أضف مبلغا اآلن‪ ،‬أو ستحصل على غرامة"(‪print‬‬

‫‪elif balance == 0:‬‬


‫ًا"(‪print‬‬ ‫)"‪.‬الرصيد يساوي ‪ ،0‬أضف مبلً‬
‫غا قريب‬

‫‪else:‬‬
‫)"‪.‬رصيدك أكبر من ‪print("0‬‬

‫اآلن‪ ،‬هناك ثالثة مخرجات محتملة يمكن أن ُتطبع عند تنفيذ البرنامج‪:‬‬

‫إن ك ان المتغ ير ‪ balance‬يس اوي ‪ ،0‬فسنحص ل على المخرج ات من التعليم ة ‪( elif‬أي‬ ‫•‬
‫قريبا‪.)".‬‬
‫ً‬ ‫ً‬
‫مبلغا‬ ‫السلسلة "الرصيد يساوي ‪ ،0‬أضف‬

‫إذا ُ‬
‫ض ِبط المتغ ير ‪ balance‬عن د ع دد م وجب‪ ،‬فس وف نحص ل على المخرج ات من‬ ‫•‬
‫التعليمة ‪( else‬أي طباعة السلسلة "رصيدك أكبر من ‪.)".0‬‬

‫إذا ُ‬
‫ض ِبط المتغير ‪ balance‬عن د ع دد س الب‪ ،‬فسنحص ل على المخرج ات من التعليم ة ‪if‬‬ ‫•‬
‫(أي السلسلة "الحساب فارغ‪ ،‬أضف مبلغا اآلن‪ ،‬أو ستحصل على غرامة")‪.‬‬

‫▲‬ ‫|‬ ‫‪254‬‬


‫البرمجة بلغة بايثون‬ ‫التعليمات الشرطية‬

‫ماذا لو أردنا أن نأخذ بالحس بان أك ثر من ثالث ة احتم االت؟ يمكنن ا كتاب ة ع دة تعليم ات ‪elif‬‬

‫في الشيفرة البرمجية‪.‬‬

‫ل ُنعِ د كتابة البرنامج ‪ grade.py‬بحيث يقابل كل نطاق من الدرجات عالمة محددة‪:‬‬

‫‪ 90‬أو أعلى تكافئ الدرجة ‪A‬‬ ‫•‬

‫‪ 80-89‬تعادل الدرجة ‪B+‬‬ ‫•‬

‫‪ 70-79‬تعادل الدرجة ‪B‬‬ ‫•‬

‫‪ 65-69‬تعادل الدرجة ‪B-‬‬ ‫•‬

‫‪ 64‬أو أقل تكافئ الدرجة ‪F‬‬ ‫•‬

‫س نحتاج لتنفي ذ ه ذه الش يفرة إلى تعليم ة ‪ if‬واح د‪ ،‬وثالث تعليم ات ‪ ،elif‬وتعليم ة ‪else‬‬

‫تعالج جميع الحاالت األخرى‪.‬‬

‫دعن ا نعي د كتاب ة الش يفرة من المث ال أعاله لطباع ة سلس لة نص ية مقابل ة لك ل عالم ة‪ .‬يمكنن ا‬

‫اإلبقاء على التعليمة ‪ else‬كما هي‪.‬‬

‫‪. . .‬‬
‫‪if grade >= 90:‬‬
‫)"‪print("A‬‬

‫‪elif grade >=80:‬‬


‫)"‪print("B+‬‬

‫‪elif grade >=70:‬‬


‫)"‪print("B‬‬

‫▲‬ ‫|‬ ‫‪255‬‬


‫البرمجة بلغة بايثون‬ ‫التعليمات الشرطية‬

‫‪elif grade >= 65:‬‬


‫)"‪print("B-‬‬

‫‪else:‬‬
‫)"‪print("F‬‬

‫ُت ّ‬
‫نفذ التعليمات ‪ elif‬بالترتيب‪ .‬هذا البرنامج سيكمل الخطوات التالية‪:‬‬

‫البرنامج ‪ ،A‬وإذا كانت الدرجة أق ل من ‪ ،90‬فس يمرّ‬


‫ُ‬ ‫إذا كانت الدرجة أكبر من ‪ ،90‬فسيطبع‬ ‫•‬
‫البرنامج إلى التعليمة التالية ‪...‬‬

‫إذا كانت الدرج ة أك بر من أو تس اوي ‪ ،80‬فس يطبع البرن ُ‬


‫امج ‪ ،B+‬إذا ك انت الدرج ة تس اوي‬ ‫•‬
‫‪ 79‬أو أقل‪ ،‬فسيمرّ البرنامج إلى التعليمة التالية ‪...‬‬

‫البرنامج ‪ ،B‬إذا كانت الدرجة تس اوي ‪69‬‬


‫ُ‬ ‫إذا كانت الدرجة أكبر من أو تساوي ‪ ،70‬فسيطبعُ‬ ‫•‬
‫أو أقل‪ ،‬فسيمرّ البرنامج إلى التعليمة التالية ‪...‬‬

‫البرنامج ‪ ،B-‬وإذا ك انت الدرج ة تس اوي‬


‫ُ‬ ‫إذا كانت الدرجة أكبر من أو تساوي ‪ ،65‬فسيطبع‬ ‫•‬
‫‪ 64‬أو أقل‪ ،‬فسيمرّ البرنامج إلى التعليمة التالية ‪...‬‬

‫أي من الشروط المذكورة أعاله‪.‬‬


‫سيطبع البرنامج ‪ ،F‬ألنه لم يتم استيفاء ِّ‬ ‫•‬

‫‪ .4‬تعليمات ‪ if‬المتشعبة‬
‫بع د أن تتع ود على التعليم ات ‪ if‬و ‪ elif‬و ‪ ،else‬يمكن ك االنتق ال إلى التعليم ات الش رطية‬

‫المتشعبة (‪.)nested conditional statements‬‬

‫ِّ‬
‫المتشعبة في الحاالت التي نري د فيه ا التحق ق من ش رط ث انوي‬ ‫يمكننا استخدام تعليمات ‪if‬‬

‫ُّ‬
‫التأكد من تحقق الشرط الرئيسي‪ .‬لهذا‪ ،‬يمكننا حشر تعليمة ‪ if-else‬داخل تعليم ة ‪if-else‬‬ ‫بعد‬

‫لنلق نظرة على صياغة ‪ if‬المتشعبة‪:‬‬


‫ِ‬ ‫أخرى‪.‬‬

‫▲‬ ‫|‬ ‫‪256‬‬


‫البرمجة بلغة بايثون‬ ‫التعليمات الشرطية‬

‫‪if statement1:‬‬ ‫تعليمة ‪ if‬الخارجية ‪#‬‬


‫)"‪print("true‬‬

‫‪if nested_statement:‬‬ ‫تعليمة ‪ if‬المتشعبة ‪#‬‬


‫)"‪print("yes‬‬

‫‪else:‬‬ ‫تعليمة ‪ else‬المتشعبة ‪#‬‬


‫)"‪print("no‬‬

‫‪else:‬‬ ‫تعليمة ‪ else‬الخارجية ‪#‬‬


‫)"‪print("false‬‬

‫هناك عدة مخرجات محتملة لهذه الشيفرة‪:‬‬

‫انت‬ ‫ا إذا ك‬ ‫امج مم‬ ‫يتحقق البرن‬ ‫حيحة‪ ،‬فس‬ ‫انت ‪ statement1‬ص‬ ‫إذا ك‬ ‫•‬

‫ً‬
‫أيض ا‪ .‬إذا ك انت كلت ا الح التين ص حيحتان‪ ،‬فسنحص ل‬ ‫‪ nested_statement‬ص حيحة‬

‫على المخرجات التالية‪:‬‬

‫‪true‬‬
‫‪yes‬‬

‫ولكن إن ك انت ‪ statement1‬ص حيحة‪ ،‬و ‪ nested_statement‬خط أ‪ ،‬فسنحص ل على‬ ‫•‬

‫المخرجات التالية‪:‬‬

‫‪true‬‬
‫‪no‬‬

‫أي ح ال‪ ،‬ل ذلك‬ ‫وإذا كانت ‪ statement1‬خطأ‪ ،‬فلن ُت ّ‬


‫نف ذ تعليم ة ‪ if-else‬المتش ِّعبة على ِّ‬ ‫•‬

‫ست ّ‬
‫نفذ التعليمة ‪ else‬وحدها‪ ،‬والمخرجات ستكون‪:‬‬ ‫ُ‬

‫▲‬ ‫|‬ ‫‪257‬‬


‫البرمجة بلغة بايثون‬ ‫التعليمات الشرطية‬

‫‪false‬‬

‫ً‬
‫أيضا استخدام عدة تعليمات ‪ if‬متشعبة في الشيفرة‪:‬‬ ‫يمكن‬

‫‪if statement1:‬‬ ‫‪ if‬الخارجية ‪#‬‬


‫)"‪print("hello world‬‬

‫‪if nested_statement1:‬‬ ‫‪ if‬المتشعبة األولى ‪#‬‬


‫)"‪print("yes‬‬

‫‪elif nested_statement2:‬‬ ‫‪ elif‬المتشعبة األولى ‪#‬‬


‫)"‪print("maybe‬‬

‫‪else:‬‬ ‫‪ else‬المتشعبة األولى ‪#‬‬


‫)"‪print("no‬‬

‫‪elif statement2:‬‬ ‫‪ elif‬الخارجية ‪#‬‬


‫)"‪print("hello galaxy‬‬

‫‪if nested_statement3:‬‬ ‫‪ if‬المتشعبة الثانية ‪#‬‬


‫)"‪print("yes‬‬

‫‪elif nested_statement4:‬‬ ‫‪ elif‬المتشعبة الثانية ‪#‬‬


‫)"‪print("maybe‬‬

‫‪else:‬‬ ‫‪ else‬المتشعبة الثانية ‪#‬‬


‫)"‪print("no‬‬

‫‪else:‬‬ ‫‪ else‬الخارجية ‪#‬‬


‫)"‪statement("Hello‬‬

‫في الشيفرة البرمجية أعاله‪ ،‬هناك تعليمات ‪ if‬و ‪ elif‬متش ِّعبة داخ ل ك ل تعليم ات ‪ .if‬ه ذا‬

‫سيفسح المجال لمزيد من الخيارات في كل حالة‪.‬‬

‫▲‬ ‫|‬ ‫‪258‬‬


‫البرمجة بلغة بايثون‬ ‫التعليمات الشرطية‬

‫دعن ا نلقي نظ رة على مث ال لتعليم ات ‪ if‬متش عبة في البرن امج ‪ .grade.py‬يمكنن ا التحق ق‬

‫حقق الط الب درج ة النج اح (أك بر من أو تس اوي ‪ ،)٪65‬ثم نح ِّدد العالم ة المقابل ة‬
‫أواًل مم ا إذا َّ‬

‫ِّ‬
‫يحقق الط الب درج ة النج اح‪ ،‬فال داعي للبحث عن العالم ة المقابل ة للدرج ة‪ ،‬وب داًل‬ ‫للدرج ة‪ .‬إذا لم‬

‫من ذلك‪ ،‬يمكن أن نجعل البرنامج يطبع سلسلة نصية فيها إعالن عن رسوب الطالب‪.‬‬

‫ستبدو الشيفرة المعدلة عن المثال السابق كما يلي‪:‬‬

‫‪. . .‬‬
‫‪if grade >= 65:‬‬
‫)"‪:‬درجة النجاح"(‪print‬‬

‫‪if grade >= 90:‬‬


‫)"‪print("A‬‬

‫‪elif grade >=80:‬‬


‫)"‪print("B+‬‬

‫‪elif grade >=70:‬‬


‫)"‪print("B‬‬

‫‪elif grade >= 65:‬‬


‫)"‪print("B-‬‬

‫‪else:‬‬
‫)"‪print("F‬‬

‫امج "درج ة‬
‫فسيس توفى الش رط األول‪ ،‬وس َيطبع البرن ُ‬
‫ُ‬ ‫إذا أعطين ا للمتغ ير ‪ grade‬القيم ة ‪،92‬‬

‫يتحقق مم ا إذا ك انت الدرج ة أك بر من أو تس اوي ‪ ،90‬وبم ا َّ‬


‫أن ه ذا الش رط‬ ‫َّ‬ ‫النج اح‪ .":‬بع د ذل ك‪ ،‬س‬

‫ُ‬
‫فستطبع ‪.A‬‬ ‫ً‬
‫أيضا‪،‬‬ ‫متحقق‬

‫▲‬ ‫|‬ ‫‪259‬‬


‫البرمجة بلغة بايثون‬ ‫التعليمات الشرطية‬

‫َ‬
‫توفى الش رط األول‪ ،‬ل ذلك س يتخطى‬ ‫أمَّ ا إذا أعطين ا للمتغ ير ‪ grade‬القيم ة ‪ ،60‬فلن يُ س‬

‫ِّ‬
‫المتشعبة‪ ،‬وينتقل إلى التعليمة ‪ ،else‬ويطبع ‪.F‬‬ ‫البرنامج تعليمات ‪if‬‬

‫يمكننا بالطبع إضافة المزيد من الخيارات‪ ،‬واستخدام طبقة ثانية من تعليم ات ‪ if‬المتش ِّعبة‪.‬‬

‫ربما نود إض افة ال درجات التفص يلية ‪ A+‬و ‪ A‬و ‪ .A-‬يمكنن ا القي ام ب ذلك عن طري ق التحق ق أواًل من‬

‫التحقق مم ا إذا ك انت الدرج ة تس اوي ‪ 90‬أو أعلى‪ ،‬ثم التحق ق مم ا إذا‬
‫ُّ‬ ‫اجتي از درج ة النج اح‪ ،‬ثم‬

‫كانت الدرجة تتجاوز ‪ ،96‬وفي تلك الحالة ستقابل العالمة ‪ .A+‬اطلع على المثال التالي‪:‬‬

‫‪. . .‬‬
‫‪if grade >= 65:‬‬
‫)"‪:‬درجة النجاح"(‪print‬‬

‫‪if grade >= 90:‬‬


‫‪if grade > 96:‬‬
‫)"‪print("A+‬‬

‫‪elif grade > 93 and grade <= 96:‬‬

‫)"‪print("A‬‬

‫‪elif grade >= 90:‬‬


‫)"‪print("A-‬‬
‫‪. . .‬‬

‫في الشيفرة أعاله‪ ،‬في حال تعيين المتغير ‪ grade‬عند القيمة ‪ ،96‬سيقوم البرنامج بما يلي‪:‬‬

‫التحقق مما إذا كانت الدرجة أكبر من أو تساوي ‪( 65‬صحيح)‬ ‫•‬

‫طباعة السلسلة "درجة النجاح‪" :‬‬ ‫•‬

‫التحقق مما إذا كانت الدرجة أكبر من أو تساوي ‪( 90‬صحيح)‬ ‫•‬

‫▲‬ ‫|‬ ‫‪260‬‬


‫البرمجة بلغة بايثون‬ ‫التعليمات الشرطية‬

‫التحقق مما إذا كانت الدرجة أكبر من ‪( 96‬خطأ)‬ ‫•‬

‫التحقق مما إذا كانت الدرجة أكبر من ‪ ،93‬وأقل من أو تساوي ‪( 96‬صحيح)‬ ‫•‬

‫طباعة ‪A‬‬ ‫•‬

‫تجاوز التعليمات الشرطية المتشعبة وتنفيذ باقي الشيفرة‬ ‫•‬

‫ستكون مخرجات البرنامج في حال كانت الدرجة تساوي ‪ 96‬كالتالي‪:‬‬

‫‪:‬درجة النجاح‬
‫‪A‬‬

‫تساعد تعليمات ‪ if‬المتشعبة على إضافة عدة مستويات من الشروط الفرعية إلى الشيفرة‪.‬‬

‫‪ .5‬خالصة الفصل‬
‫س تتحكم باس تخدام التعليم ات الش رطية‪ ،‬مث ل التعليم ة ‪ ،if‬في مس ار البرن امج أي ت دفق‬

‫معين من‬
‫َّ‬ ‫ُّ‬
‫التحقق من اس تيفاء ش رط‬ ‫تنفي ذ الش يفرة‪ .‬تطلب التعليم ات الش رطية من البرن امج‬

‫فست َّ‬
‫نفذ شيفرة معينة‪ ،‬وإال فسيس تمر تنفي ذ البرن امج وينتق ل إلى‬ ‫ُ‬ ‫عدمه‪ .‬وإذا تم استيفاء الشرط‪،‬‬

‫األسطر التالية‪.‬‬

‫يمكنك الدمج بين التعليمات الشرطية والمعامالت المنطقي ة‪ ،‬بم ا فيه ا ‪ and‬و ‪ ،or‬واس تخدام‬

‫التعليمات الشرطية مع الحلقات التكرارية‪.‬‬

‫▲‬ ‫|‬ ‫‪261‬‬


‫‪15‬‬
‫المهام التكرارية‪:‬‬
‫مدخل إلى الحلقات‬

‫▲‬ ‫|‬ ‫‪262‬‬


‫البرمجة بلغة بايثون‬ ‫المهام التكرارية‪ :‬مدخل إلى الحلقات‬

‫نستفيد من البرامج الحاسوبية خير استفادة في أتمتة المهام وإجراء المه ام التكراري ة لكيال‬

‫نحتاج إلى القيام بها يدويً ا‪ ،‬وإحدى طرائ ق تك رار المه ام المتش ابهة هي اس تخدام حلق ات التك رار‬

‫(‪ ،)loops‬وسنشرح في ه ذا الفص ل حلق تي التك رار الش هيرتين في ب ايثون ‪-‬وس ائر لغ ات البرمج ة‪-‬‬

‫‪ while‬و ‪ ،for‬وكيفية استعمالهما‪.‬‬

‫‪ .1‬حلقة التكرار ‪while‬‬


‫اء على متغ ير منطقي‬
‫حلق ة التك رار ‪ while‬ت ؤدي إلى تك رار تنفي ذ قس م من الش يفرة بن ً‬

‫(‪ ،)boolean‬وسيس تمر تنفي ذ ه ذه الش يفرة لطالم ا ك انت نتيج ة التعب ير المس تعمل معه ا‬

‫َّ‬
‫محق ًقا‪.‬‬ ‫ٌ‬
‫شرط ما‬ ‫تساوي ‪ true‬أي طالما كان‬

‫أن حلق ة ‪ while‬هي عب ارة ش ريطة تكراري ة؛ فبع د انته اء تنفي ذ التعليم ة‬
‫يمكن ك أن تتخي ل َّ‬

‫الش رطية ‪ ،if‬يُ س َتكمَ ل تنفي ذ بقي ة البرن امج‪ ،‬لكن م ع حلق ة ‪ while‬فس يعود تنفي ذ البرن امج إلى‬

‫بداي ة الحلق ة بع د انته اء تنفي ذها إلى أن يص بح الش رط مس اويًا للقيم ة ‪ false‬أي لم يع د‬

‫َّ‬
‫محق ًقا‪.‬‬ ‫الشرط‬

‫معي ًن ا من الم رات‪ ،‬فسيس تمر تنفي ذ‬


‫َّ‬ ‫وعلى النقيض من حلق ات ‪ for‬ال تي ُت َّ‬
‫نفذ ع د ًدا‬

‫معين‪ ،‬لذا لن تحتاج إلى عدد مرات تنفيذ الحلقة قبل إنشائها‪.‬‬
‫َّ‬ ‫شرط‬
‫ٍ‬ ‫حلقات ‪ while‬اعتما ًدا على‬

‫الشكل العام لحلقات ‪ while‬في لغة بايثون كاآلتي‪:‬‬

‫‪while [a condition is True]:‬‬


‫]‪[do something‬‬

‫سيس تمر تنفي ذ التعليم ات البرمجي ة الموج ودة داخ ل الحلق ة إلى أن يُ َّ‬
‫قيم الش رط ال ذي يلي‬

‫‪ while‬إلى القيمة ‪.false‬‬

‫▲‬ ‫|‬ ‫‪263‬‬


‫البرمجة بلغة بايثون‬ ‫المهام التكرارية‪ :‬مدخل إلى الحلقات‬

‫ً‬
‫برنامجا صغيرًا في ه حلق ة ‪ ،while‬ففي ه ذه البرن امج س نطلب من المس تخدم إدخ ال‬ ‫ل ُن ِ‬
‫نشئ‬

‫كلمة مرور‪ .‬وهنالك خياران أمام حلقة التكرار‪:‬‬

‫إمَّ ا أن تكون كلمة المرور صحيحة‪ ،‬فعندها سينتهي تنفيذ حلقة ‪.while‬‬ ‫•‬

‫أو أن تكون كلمة المرور غير صحيحة‪ ،‬فعندها سيستمر تنفيذ حلقة التكرار‪.‬‬ ‫•‬

‫َّ‬
‫المفض ل‪ ،‬ولنب دأ بتهيئ ة‬ ‫ِّ‬
‫محررن ا النص ي‬ ‫نش ئ ً‬
‫ملف ا باس م ‪ password.py‬في‬ ‫ل ُن ِ‬

‫المتغير ‪ paasword‬بإسناد سلسلة نصية فارغة إليه‪:‬‬

‫'' = ‪password‬‬

‫نس تخدم المتغ ير الس ابق للحص ول على م دخالت المس تخدم داخ ل حلق ة التك رار ‪.while‬‬

‫علينا بعد ذلك إنشاء حلقة ‪ while‬مع تحديد ما هو الشرط الذي يجب تحقيقه‪:‬‬

‫'' = ‪password‬‬

‫‪while password != 'password':‬‬

‫أتبعن ا –في المث ال الس ابق– الكلم ة المحج وزة ‪ while‬ب المتغير ‪ ،password‬ثمَّ س نتحقق إذا‬
‫َ‬

‫أن قيم ة المتغ ير‬


‫تنس َّ‬
‫ك انت قيم ة المتغ ير ‪ password‬تس اوي السلس لة النص ية '‪( 'password‬ال َ‬

‫سنحص ل عليه ا من م دخالت المس تخدم)‪ ،‬يمكن ك أن تخت ار أي سلس لة نص ية تش اء لموازن ة‬

‫مدخالت المستخدم بها‪ .‬هذا يعني َّ‬


‫أنه لو أدخل المستخدم السلسلة النصية ‪ password‬فس تتوقف‬

‫حلق ة التك رار وس ُيكمَ ل تنفي ذ البرن امج وس ُت َّ‬


‫نفذ أيّ ة ش يفرات خ ارج الحلق ة‪ ،‬لكن إذا أدخ ل‬

‫المستخدم أيّ ة سلس لة نص ية ال تس اوي ‪ password‬فس ُيكمَ ل تنفي ذ الحلق ة‪ .‬علين ا بع د ذل ك إض افة‬

‫الشيفرة المسؤولة عمّ ا يحدث داخل حلقة ‪:while‬‬

‫▲‬ ‫|‬ ‫‪264‬‬


‫البرمجة بلغة بايثون‬ ‫المهام التكرارية‪ :‬مدخل إلى الحلقات‬

‫'' = ‪password‬‬

‫‪while password != 'password':‬‬


‫)'?‪print('What is the password‬‬
‫)(‪password = input‬‬

‫َّ‬
‫نفذ البرنامج عب ارة ‪ print‬داخ ل حلق ة ‪ while‬وال تي تس أل المس تخدم عن كلم ة م روره‪ ،‬ثم‬

‫أس ندنا قيم ة م دخالت المس تخدم (ال تي حص لنا عليه ا ع بر الدال ة )(‪ )input‬إلى المتغ ير‬

‫َّ‬
‫يتحقق البرن امج إذا ك انت قيم ة المتغ ير ‪ password‬تس اوي السلس لة النص ية‬ ‫‪ .password‬س‬

‫َّ‬
‫تحقق ذل ك فس ينتهي تنفي ذ حلق ة ‪ .while‬لنض ف س طرًا آخ ر إلى البرن امج‬ ‫'‪ ،'password‬وإذا‬

‫ً‬
‫مساوية إلى ‪:false‬‬ ‫لنعرف ماذا يحدث إن أصبحت قيمة الشرط‬

‫'' = ‪password‬‬

‫‪while password != 'password':‬‬


‫)'?‪print('What is the password‬‬
‫)(‪password = input‬‬

‫)'‪print('Yes, the password is ' + password + '. You may enter.‬‬

‫أن آخ ر عب ارة )(‪ print‬موج ودة خ ارج حلق ة ‪ ،while‬ل ذا عن دما يُ دخِ ل المس تخدم‬
‫الح ظ َّ‬

‫طبع آخر جملة وال تي تق ع خ ارج حلق ة التك رار‪.‬‬ ‫ُ‬


‫فست َ‬ ‫الكلمة ‪ password‬عند سؤاله عن كلمة مروره‪،‬‬

‫لكن ماذا يحدث لو لم يدخل المس تخدم الكلم ة ‪ password‬ق ط؟ إذ لن يس تمر تنفي ذ البرن امج ولن‬

‫ي روا آخ ر عب ارة )(‪ print‬وسيس تمر تنفي ذ حلق ة التك رار إلى م ا ال نهاي ة! يس تمر تنفي ذ حلق ة‬

‫التك رار إلى م ا ال نهاي ة إذا بقي تنفي ذ البرن امج داخ ل حلق ة تك رار دون الخ روج منه ا‪ .‬وإذا أردت‬

‫الخروج من حلقة تكرار نهائية‪ ،‬فاضغط ‪ Ctrl+C‬في سطر األوامر‪ .‬احفظ البرنامج ثم ِّ‬
‫شغله‪:‬‬

‫▲‬ ‫|‬ ‫‪265‬‬


‫البرمجة بلغة بايثون‬ ‫المهام التكرارية‪ :‬مدخل إلى الحلقات‬

‫‪python password.py‬‬

‫س ُي َ‬
‫طلب من ك إدخ ال كلم ة الم رور‪ ،‬ويمكن ك تجرب ة م ا تش اء من الكلم ات‪ .‬ه ذا مث ٌ‬
‫ال عن‬

‫ناتج البرنامج‪:‬‬

‫?‪What is the password‬‬


‫‪hello‬‬
‫?‪What is the password‬‬
‫‪sammy‬‬
‫?‪What is the password‬‬
‫‪PASSWORD‬‬
‫?‪What is the password‬‬
‫‪password‬‬
‫‪Yes, the password is password. You may enter.‬‬

‫تعملت دال ًة من دوال‬


‫َ‬ ‫أن السالس ل النص ية حساس ة لحال ة األح رف إال إذا اس‬
‫أب ِق في ذهن ك َّ‬

‫النص وص لتحوي ل السلس لة النص ية إلى حال ة األح رف الص غيرة (على س بيل المث ال) قب ل‬

‫ُّ‬
‫التحقق منها‪.‬‬

‫ا‪ .‬تطبيق عملي‬

‫بع د أن تعلمن ا المب دأ األساس ي لحلق ة تك رار ‪ ،while‬فل ُن ِ‬


‫نش ئ لعب ة تعم ل على س طر األوام ر‬

‫ً‬
‫وائية لكي‬ ‫لتخمين األرقام والتي تستعمل الحلقة ‪ . while‬نريد من الحاسوب أن يُ ِ‬
‫نشئ أرقامً ا عش‬

‫يحاول المستخدمون تخمينها‪ ،‬لذا علينا استيراد الوحدة ‪ random‬عبر اس تخدام التعليم ة ‪import‬‬

‫ً‬
‫الحقُا إلى كيفي ة اس تيراد الوح دات في فص ل الوح دات)‪ ،‬وإذا لم تكن ه ذه الحزم ة‬ ‫(س نطرق‬

‫ً‬
‫مألوفة ل ك فيمكن ك ق راءة المزي د من المعلوم ات عن تولي د األرق ام العش وائية في توثي ق ب ايثون‪.‬‬

‫َّ‬
‫المفضل‪:‬‬ ‫ملفا باسم ‪ guess.py‬في محررك النصي‬ ‫ً‬
‫بداية ً‬ ‫ل ُن ِ‬
‫نشئ‬

‫▲‬ ‫|‬ ‫‪266‬‬


‫البرمجة بلغة بايثون‬ ‫المهام التكرارية‪ :‬مدخل إلى الحلقات‬

‫‪import random‬‬

‫علين ا اآلن إس ناد ع دد ص حيح عش وائي إلى المتغ ير ‪ ،number‬ولنجع ل مجال ه من ‪ 1‬إلى ‪25‬‬

‫(بما فيها تلك األرقام) كيال نجعل اللعبة صعبة ج ًدا‪.‬‬

‫‪import random‬‬

‫)‪number = random.randint(1, 25‬‬

‫يمكننا اآلن إنشاء حلقة ‪ ،while‬وذلك بتهيئة متغير ثم كتابة الحلقة‪:‬‬

‫‪import random‬‬

‫)‪number = random.randint(1, 25‬‬

‫‪number_of_guesses = 0‬‬

‫‪while number_of_guesses < 5:‬‬


‫)'‪print('Guess a number between 1 and 25:‬‬

‫)(‪guess = input‬‬
‫)‪guess = int(guess‬‬

‫‪number_of_guesses = number_of_guesses + 1‬‬

‫‪if guess == number:‬‬


‫‪break‬‬

‫هيأن ا متغ يرًا اس مه ‪ number_of_guesses‬قيمت ه ‪ ،0‬وس وف نزي د قيمت ه عن د ك ل تك رار‬

‫للحلقة لكي ال تصبح حلقتنا ال نهائية ثم سنضيف حلقة ‪ while‬التي تشترط أاّل تزيد قيمة المتغ ير‬

‫‪ number_of_guesses‬عن خمس تكرارات‪.‬‬

‫▲‬ ‫|‬ ‫‪267‬‬


‫البرمجة بلغة بايثون‬ ‫المهام التكرارية‪ :‬مدخل إلى الحلقات‬

‫وبع د المحاول ة الخامس ة س ُيعاد المس تخدم إلى س طر األوام ر‪ ،‬وإذا ح اول المس تخدم إدخ ال‬

‫أي شيء غير رقمي فسيحصل على رسالة خطأ‪.‬‬


‫ّ‬

‫أض فنا داخ ل حلق ة ‪ while‬عب ارة )(‪ print‬لطلب إدخ ال رقم من المس تخدم‪ ،‬ثم س نأخذ‬

‫ِّ‬
‫سنحول المتغير ‪guess‬‬ ‫مدخالت المستخدم عبر الدالة )(‪ُ input‬‬
‫ونس ِن َدها إلى المتغير ‪ ،guess‬ثم‬

‫من سلس لة نص ية إلى ع دد ص حيح‪ .‬وقب ل انته اء حلق ة التك رار‪ ،‬فعلين ا زي ادة قيم ة المتغ ير‬

‫نفذ حلقة التكرار أكثر من ‪ 5‬مرات‪.‬‬


‫‪ number_of_guesses‬بمقدار ‪ ،1‬لكيال ُت َّ‬

‫وفي النهاية‪ ،‬كتبنا التعليم ة ‪ if‬ش رطية ل نرى إذا ك ان المتغ ير ‪ guess‬ال ذي أدخل ه المس تخدم‬

‫مس او لل رقم الموج ود في المتغ ير ‪ number‬ال ذي َّ‬


‫ولده الحاس وب‪ ،‬وإذا تحق ق الش رط فسنس تخدم‬ ‫ٍ‬

‫ً‬
‫جاهزا لالستخدام‪ ،‬ويمكننا تشغيله عبر تنفي ذ‬ ‫التعليمة ‪ break‬للخروج من الحلقة‪ .‬أصبح البرنامج‬

‫األمر التالي‪:‬‬

‫‪python guess.py‬‬

‫ً‬
‫حيحا‬ ‫أن البرن امج يعم ل عماًل س ليمً ا‪ ،‬لكن المس تخدم لن يعلم إذا ك ان تخمين ه ص‬
‫حيح َّ‬
‫ٌ‬ ‫ص‬

‫ِّ‬
‫يخمن الرقم خمس م رات دون أن يعلم إذا ك انت إح دى محاوالت ه ص حيحة‪ .‬ه ذا مث ال‬ ‫ويمكنه أن‬

‫عن مخرجات البرنامج‪:‬‬

‫‪Guess a number between 1 and 25:‬‬


‫‪11‬‬
‫‪Guess a number between 1 and 25:‬‬
‫‪19‬‬
‫‪Guess a number between 1 and 25:‬‬
‫‪22‬‬
‫‪Guess a number between 1 and 25:‬‬
‫‪3‬‬

‫▲‬ ‫|‬ ‫‪268‬‬


‫البرمجة بلغة بايثون‬ ‫ مدخل إلى الحلقات‬:‫المهام التكرارية‬

Guess a number between 1 and 25:


8

‫لنضف بعض التعليمات الشرطية خ ارج حلق ة التك رار لكي يحص ل المس تخدم على معلوم ات‬

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

import random

number = random.randint(1, 25)

number_of_guesses = 0

while number_of_guesses < 5:


print('Guess a number between 1 and 25:')
guess = input()
guess = int(guess)

number_of_guesses = number_of_guesses + 1

if guess == number:
break

if guess == number:
print('You guessed the number in ' + str(number_of_guesses)
+ ' tries!')

else:
print('You did not guess the number. The number was ' +
str(number))

‫ لكن ذل ك لن‬،‫امج في ه ذه المرحل ة المس تخدمَ إذا اس تطاعوا تخمين ال رقم‬


ُ ‫س ُيخ ِبر البرن‬

‫ ولمس اعد‬.‫يح دث إال بع د انته اء حلق ة التك رار وبع د انته اء ع دد م رات التخمين المس موحة‬

▲ | 269
‫البرمجة بلغة بايثون‬ ‫ مدخل إلى الحلقات‬:‫المهام التكرارية‬

‫ وس تخبر تل ك التعليم ات‬while ‫ فلنض ف بعض التعليم ات الش رطية داخ ل حلق ة‬، ‫المس تخدم قلياًل‬

،‫ لكي يس تطيعوا تخمين ال رقم بنج اح‬،‫المس تخدم إذا ك ان تخمين ه أعلى من ال رقم أو أص غر من ه‬

:if guess == number ‫وسنضيف تلك التعليمات الشرطية قبل السطر الذي يحتوي على‬

import random

number = random.randint(1, 25)


number_of_guesses = 0

while number_of_guesses < 5:


print('Guess a number between 1 and 25:')
guess = input()
guess = int(guess)

number_of_guesses = number_of_guesses + 1

if guess < number:


print('Your guess is too low')

if guess > number:


print('Your guess is too high')

if guess == number:
break

if guess == number:
print('You guessed the number in ' + str(number_of_guesses)
+ ' tries!')

else:
print('You did not guess the number. The number was ' +
str(number))

▲ | 270
‫البرمجة بلغة بايثون‬ ‫المهام التكرارية‪ :‬مدخل إلى الحلقات‬

‫أن‬ ‫وعن دما ُنش ِّغل البرن امج م ً‬


‫رة أخ رى بتنفي ذ ‪ ،python guess.py‬فيمكنن ا مالحظ ة َّ‬

‫وائيا ه و ‪ 12‬وك ان تخمين‬


‫ً‬ ‫َّ‬
‫المولد عش‬ ‫المس تخدم سيحص ل على بعض المس اعدة‪ ،‬فل و ك ان ال رقم‬

‫أن ال رقم ال ذي خمن ه أك بر من ال رقم العش وائي‪ ،‬وذل ك لكي‬


‫المس تخدم ‪ ،18‬فس ُيخبره البرن امج َّ‬

‫ً‬
‫وفق ا ل ذلك‪ .‬هنال ك الكث ير من التحس ينات ال تي يمكن إجراؤه ا على‬ ‫يس تطيع تع ديل تخمني ه‬

‫الشيفرة السابقة‪ ،‬مثل تضمين آلية لمعالجة األخطاء التي تحدث عن دما ال يُ دخِ ل المس تخدم ع د ًدا‬

‫ً‬
‫صحيحا‪ ،‬لكن كان غرضنا هو رؤي ة كيفي ة اس تخدام حلق ة ‪ while‬في برن امج قص ير ومفي د يعم ل‬

‫من سطر األوامر‪.‬‬

‫‪ .2‬حلقة التكرار ‪for‬‬


‫اء على ع َّداد أو على متغيِّ ر‪ ،‬وه ذا‬
‫حلق ة ‪ for‬ت ؤدي إلى تك رار تنفي ذ ج زء من الش يفرات بن ً‬

‫أن حلقات ‪ for‬تستعمل عندما يكون عدد مرات تنفيذ حلقة التكرار معلومً ا قبل ال دخول في‬
‫يعني َّ‬

‫الحلقة‪ ،‬وذلك على النقيض من حلقات ‪ while‬المبنية على شرط‪.‬‬

‫ُتبنى حلقات ‪ for‬في بايثون كما يلي‪:‬‬

‫‪for [iterating variable] in [sequence]:‬‬


‫]‪[do something‬‬

‫ست َّ‬
‫نفذ الشيفرات الموجودة داخل حلق ة التك رار ع ِّدة م رات إلى أن تنتهي الحلق ة‪ .‬لننظ ر إلى‬ ‫ُ‬

‫مجال من القيم‪:‬‬
‫ٍ‬ ‫كيفية مرور الحلقة ‪ for‬على‬

‫‪for i in range(0,5):‬‬
‫)‪print(i‬‬

‫سيخ ِرج البرنامج السابق عند تشغيله الناتج اآلتي‪:‬‬


‫ُ‬

‫▲‬ ‫|‬ ‫‪271‬‬


‫البرمجة بلغة بايثون‬ ‫المهام التكرارية‪ :‬مدخل إلى الحلقات‬

‫‪0‬‬
‫‪1‬‬
‫‪2‬‬
‫‪3‬‬
‫‪4‬‬

‫ضبطنا المتغير ‪ i‬في حلقة ‪ for‬ليحت وي على القيم ة ال تي س ُت َّ‬


‫نفذ عليه ا حلق ة التك رار‪ ،‬وك ان‬

‫ستسنَد إلى هذا المتغير من ‪ 0‬إلى ‪ .5‬ثم طبعً ا قيمة المتغير في ك ل دوران لحلق ة‬
‫مجال القيم التي ُ‬

‫أننا نميل إلى بدء العد من الرقم ‪ 0‬في البرمجة‪ ،‬وعلى الرغم من ع رض‬
‫التكرار‪ ،‬لكن أبق في ذهنك َّ‬
‫ِ‬

‫خمسة أرقام‪ ،‬لكنها تبدأ بالرقم ‪ 0‬وتنتهي بالرقم ‪ .4‬من الشائع أن ترى استخدامً ا لحلق ة ‪ for‬عن دما‬

‫معينة من الشيفرات لعددٍ من المرات‪.‬‬


‫َّ‬ ‫تحتاج إلى تكرار كتلة‬

‫ا‪ .‬استخدام حلقة التكرار ‪ for‬مع الدالة )(‪range‬‬

‫إحدى أنواع السالسل غير القابلة للتع ديل في ب ايثون هي تل ك الناتج ة من الدال ة )(‪،range‬‬

‫وتستخدم الدالة )(‪ range‬في حلقات التكرار للتحكم بع دد م رات تك رار الحلق ة‪ .‬عن د التعام ل م ع‬

‫رقميا أو معاملين أو ثالثة معامالت‪:‬‬


‫ً‬ ‫الدالة )(‪ range‬عليك أن تمرر معاماًل‬

‫‪ :start‬يش ير إلى القيم العددي ة الص يحية ال تي س تبدأ به ا السلس لة‪ ،‬وإذا لم ُتم رَّ ر قيم ة‬ ‫•‬

‫لهذا المعامل فستبدأ السلسلة من ‪.0‬‬

‫‪ :stop‬ه ذا المعام ل مطل وب دومً ا وه و القيم ة العددي ة الص حيحة ال تي تمث ل نهاي ة‬ ‫•‬

‫السلسلة العددية لكن دون تضمينها‪.‬‬

‫‪ :step‬هي مقدار الخطوة‪ ،‬أي عدد األرقام التي يجب زيادتها (أو إنقاصها إن كنَّا نتعام ل‬ ‫•‬

‫مع أرقام سالبة) في الدورة القادمة‪ ،‬وقيمة المعامل ‪ step‬تساوي ‪ 1‬إن لم ُتح َّدد له قيمة‪.‬‬

‫▲‬ ‫|‬ ‫‪272‬‬


‫البرمجة بلغة بايثون‬ ‫المهام التكرارية‪ :‬مدخل إلى الحلقات‬

‫لننظر إلى بعض األمثلة التي ُن ِّ‬


‫مرر فيها مختلف المع امالت إلى الدال ة )(‪ .range‬لنب دأ بتمري ر‬

‫أن السلسلة اآلتية من الشكل )‪:range(stop‬‬


‫المعامل ‪ stop‬فقط‪ ،‬أي َّ‬

‫‪for i in range(6):‬‬
‫)‪print(i‬‬

‫اوية لل رقم ‪ ،6‬ل ذا س تمر حلق ة التك رار من‬


‫ً‬ ‫ك انت قيم ة المعام ل ‪ stop‬في المث ال الس ابق مس‬

‫بداية المجال ‪ 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‬ش بيه بمعام ل الخط وة ال ذي نس تعمله عن د تقس يم‬

‫السالس ل النص ية ألن ه يس تعمل لتج اوز بعض القيم ض من السلس لة‪ .‬ي أتي المعام ل ‪ step‬في آخ ر‬

‫▲‬ ‫|‬ ‫‪273‬‬


‫البرمجة بلغة بايثون‬ ‫المهام التكرارية‪ :‬مدخل إلى الحلقات‬

‫قائم ة المع امالت ال تي تقبله ا الدال ة )(‪ 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‬‬

‫▲‬ ‫|‬ ‫‪274‬‬


‫البرمجة بلغة بايثون‬ ‫المهام التكرارية‪ :‬مدخل إلى الحلقات‬

‫‪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‬‬

‫▲‬ ‫|‬ ‫‪275‬‬


‫البرمجة بلغة بايثون‬ ‫المهام التكرارية‪ :‬مدخل إلى الحلقات‬

‫‪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‬‬

‫▲‬ ‫|‬ ‫‪276‬‬


‫البرمجة بلغة بايثون‬ ‫المهام التكرارية‪ :‬مدخل إلى الحلقات‬

‫‪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‬‬

‫▲‬ ‫|‬ ‫‪277‬‬


‫البرمجة بلغة بايثون‬ ‫المهام التكرارية‪ :‬مدخل إلى الحلقات‬

‫‪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]:‬‬
‫]‪[do something‬‬ ‫اختياري ‪#‬‬

‫▲‬ ‫|‬ ‫‪278‬‬


‫البرمجة بلغة بايثون‬ ‫المهام التكرارية‪ :‬مدخل إلى الحلقات‬

‫الحلقة الداخلية الفرعية ‪#‬‬


‫‪for [second iterating variable] in [nested loop]:‬‬
‫]‪[do something‬‬

‫يب دأ البرن امج بتنفي ذ حلق ة التك رار الخارجي ة‪ ،‬ويُ َّ‬
‫نفذ أوّ ل دوران فيه ا‪ ،‬وأوَّ ل دوران س يؤدي‬

‫إلى ال دخول إلى حلق ة التك رار الداخلي ة‪ ،‬مم ا ي ؤدي إلى تنفي ذها إلى أن تنتهي تمامً ا‪ .‬ثم س يعود‬

‫تنفيذ البرنامج إلى بداية حلقة التكرار الخارجية‪ ،‬ويبدأ بتنفيذ ال دوران الث اني‪ ،‬ثم سيص ل التنفي ذ‬

‫إلى حلقة التكرار الداخلي ة‪ ،‬وس ُت َّ‬


‫نفذ حلق ة التك رار الداخلي ة بالكام ل‪ ،‬ثم س يعود التنفي ذ إلى بداي ة‬

‫حلق ة التك رار الخارجي ة‪ ،‬وهلم ج رًا إلى أن ينتهي تنفي ذ حلق ة التك رار الخارجي ة أو إيق اف حلق ة‬

‫نش ئ مث ااًل يس تعمل حلق ة ‪ for‬متش عبة لكي‬


‫التك رار ع بر اس تخدام التعليم ة ‪ break‬أو غيره ا‪ .‬ل ُن ِ‬

‫نفهم كي ف تعم ل بدق ة‪ ،‬إذ س تمر حلق ة التك رار الخارجي ة في المث ال اآلتي على قائم ة من األرق ام‬

‫اس مها ‪ ،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‬‬

‫▲‬ ‫|‬ ‫‪279‬‬


‫البرمجة بلغة بايثون‬ ‫المهام التكرارية‪ :‬مدخل إلى الحلقات‬

‫‪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‬‬

‫▲‬ ‫|‬ ‫‪280‬‬


‫البرمجة بلغة بايثون‬ ‫المهام التكرارية‪ :‬مدخل إلى الحلقات‬

‫]‪[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‬المتش عبة عن دما نري د ال دوران على عناص ر محت وى‬

‫في قوائم‪.‬‬

‫‪ .3‬التحكم بحلقات التكرار‬


‫أن اس تخدام حلق ات ‪ for‬أو ‪ while‬تس مح بأتمت ة وتك رار المه ام بطريق ة فعّ ال ة‪ .‬لكن‬
‫وج دنا َّ‬

‫في بعض األحي ان‪ ،‬ق د يت دخل عام ل خ ارجي في طريق ة تش غيل برنامج ك‪ ،‬وعن دما يح دث ذل ك‪،‬‬

‫▲‬ ‫|‬ ‫‪281‬‬


‫البرمجة بلغة بايثون‬ ‫المهام التكرارية‪ :‬مدخل إلى الحلقات‬

‫فربم ا تري د من برنامج ك الخ روج تمامً ا من حلق ة التك رار‪ ،‬أو تج اوز ج زء من الحلق ة قب ل إكم ال‬

‫تنفي ذها‪ ،‬أو تجاه ل ه ذا العام ل الخ ارجي تمامً ا‪ .‬ل ذا يمكن ك فع ل م ا س بق باس تخدام‬

‫التعليمات ‪ break‬و ‪ continue‬و ‪.pass‬‬

‫ا‪ .‬التعليمة ‪break‬‬

‫ِّ‬
‫توفر لك التعليم ة ‪ break‬الق درة على الخ روج من حلق ة التك رار عن د ح دوث عام ل خ ارجي‪.‬‬

‫نفذ في ك ل تك رار للحلق ة‪ ،‬وتوض ع ع ً‬


‫ادة ض من‬ ‫فعليك وضع التعليم ة ‪ break‬في الش يفرة ال تي س ُت َّ‬

‫تعليم ة ش رطية مث ل ‪ .if‬أل ق نظ ً‬


‫رة إلى أح د األمثل ة ال ذي يس تعمل التعليم ة ‪ break‬داخ ل‬ ‫ِ‬

‫حلقة ‪:for‬‬

‫‪number = 0‬‬

‫‪for number in range(10):‬‬


‫)*( ‪number = number + 1‬‬

‫‪if number == 5:‬‬


‫‪break‬‬ ‫توقف هنا ‪#‬‬

‫))‪print('Number is ' + str(number‬‬

‫)'‪print('Out of loop‬‬

‫امج ص غيرٌ ‪ّ ،‬‬


‫هيأن ا في بدايت ه المتغ ير ‪ number‬بجعل ه يس اوي الص فر‪ ،‬ثم بنين ا حلق ة‬ ‫ه ذا برن ٌ‬

‫تك رار ‪ for‬ال تي تعم ل لطالم ا ك انت قيم ة المتغ ير ‪ number‬أص غر من ‪ .10‬ثم قمن ا بزي ادة قيم ة‬

‫المتغ ير ‪ number‬داخ ل حلق ة ‪ for‬بمق دار ‪ 1‬في ك ل تك رار‪ ،‬وذل ك في الس طر (*) ثم ك ان هنال ك‬

‫مساو للرقم ‪ ،5‬وعند حدوث ذلك فس ُت َّ‬


‫نفذ التعليم ة‬ ‫ٍ‬ ‫الشرط ‪ if‬الذي يختبر إن كان المتغير ‪number‬‬

‫▲‬ ‫|‬ ‫‪282‬‬


‫البرمجة بلغة بايثون‬ ‫المهام التكرارية‪ :‬مدخل إلى الحلقات‬

‫‪ break‬للخ روج من الحلق ة‪ ،‬وتوج د داخ ل حلق ة التك رار الدال ة )(‪ print‬ال تي ُت َّ‬
‫نفذ في ك ل تك رار‬

‫إلى أن نخرج من الحلقة عبر التعليمة ‪ ،break‬إذ هي موجودة بعد التعليمة ‪ .break‬لكي نتأكد أنن ا‬

‫خرجنا من الحلقة‪ ،‬وضعنا عبارة )(‪ print‬أخيرة موجودة خارجها‪ .‬سنرى الناتج اآلتي عند‬

‫تنفيذ البرنامج‪:‬‬

‫‪Number is 1‬‬
‫‪Number is 2‬‬
‫‪Number is 3‬‬
‫‪Number is 4‬‬
‫‪Out of loop‬‬

‫أنه بمجرد أن أصبح العدد الص حيح ‪ number‬مس اويً ا لل رقم ‪ ،5‬فس ينتهي‬
‫ظهر الناتج السابق َّ‬
‫يُ ِ‬

‫تنفيذ حلقة التكرار عبر ‪.break‬‬

‫ب‪ .‬التعليمة ‪continue‬‬

‫تس مح لن ا التعليم ة ‪ continue‬بتخطي ج زء من حلق ة التك رار عن د ح دوث عام ل خ ارجي‪،‬‬

‫وعدم إكمال بقية الحلقة إلى نهايتها‪ .‬بعبارةٍ أخرى‪ ،‬سينتقل تنفي ذ البرن امج إلى أوّ ل حلق ة التك رار‬

‫عند تنفيذ التعليمة ‪ .continue‬يجب وضع التعليم ة ‪ continue‬في الش يفرة ال تي س ُت َّ‬
‫نفذ في ك ل‬

‫ً‬
‫عادة ضمن الشرط ‪.if‬‬ ‫تكرار للحلقة‪ ،‬ويوضع‬

‫سنس تخدم نفس البرن امج ال ذي اس تعملناها لش رح التعليم ة ‪ break‬أعاله‪ ،‬لكنن ا سنس تخدم‬

‫التعليمة ‪ continue‬بداًل من ‪:break‬‬

‫‪number = 0‬‬

‫‪for number in range(10):‬‬


‫‪number = number + 1‬‬

‫▲‬ ‫|‬ ‫‪283‬‬


‫البرمجة بلغة بايثون‬ ‫المهام التكرارية‪ :‬مدخل إلى الحلقات‬

‫‪if number == 5:‬‬


‫‪continue‬‬ ‫‪# continue here‬‬

‫))‪print('Number is ' + str(number‬‬

‫)'‪print('Out of loop‬‬

‫الف رق بين اس تخدام التعليم ة ‪ continue‬ب داًل من ‪ break‬ه و إكم ال تنفي ذ الش يفرة بغض‬

‫اوية إلى ال رقم ‪ .5‬لننظ ر‬


‫ً‬ ‫النظ ر عن التوق ف ال ذي ح دث عن دما ك انت قيم ة المتغ ير ‪ number‬مس‬

‫إلى الناتج‪:‬‬

‫‪Number is 1‬‬
‫‪Number is 2‬‬
‫‪Number is 3‬‬
‫‪Number is 4‬‬
‫‪Number is 6‬‬
‫‪Number is 7‬‬
‫‪Number is 8‬‬
‫‪Number is 9‬‬
‫‪Number is 10‬‬
‫‪Out of loop‬‬

‫أن السطر ال ذي يجب أن يحت وي على ‪ Number is 5‬ليس موج و ًدا في المخرج ات‪،‬‬
‫نالحظ َّ‬

‫لكن س ُيكمَ ل تنفي ذ حلق ة التك رار بع د ه ذه المرحل ة مم ا يطب ع األرق ام من ‪ 6‬إلى ‪ 10‬قب ل إنه اء‬

‫تنفيذ الحلقة‪.‬‬

‫َّ‬
‫معقدة ومتش ِّعبة‪،‬‬ ‫يمكن ك اس تخدام التعليم ة ‪ continue‬لتف ادي اس تخدام تعليم ات ش رطية‬

‫ست َ‬
‫رفض نتائجها‪.‬‬ ‫أو لتحسين أداء البرنامج عن طريق تجاهل الحاالت التي ُ‬

‫▲‬ ‫|‬ ‫‪284‬‬


‫البرمجة بلغة بايثون‬ ‫المهام التكرارية‪ :‬مدخل إلى الحلقات‬

‫ج‪ .‬التعليمة ‪pass‬‬

‫تسمح لنا التعليمة ‪ pass‬بالتعامل مع أحد الشروط دون إيقاف عمل حلق ة التك رار ب أي ش كل‪،‬‬

‫أي س ُت َّ‬
‫نفذ جمي ع التعليم ات البرمجي ة الموج ودة في حلق ة التك رار م ا لم تس تعمل تعليم ات تحكم‬

‫مثل ‪ break‬أو ‪ continue‬فيها‪ .‬وكما هو الحال مع التعليمات السابقة‪ ،‬يجب وض ع التعليم ة ‪pass‬‬

‫نفذ في ك ل تك رار للحلق ة‪ ،‬ويوض ع ع ً‬


‫ادة ض من الش رط ‪ .if‬سنس تخدم نفس‬ ‫في الش يفرة ال تي س ُت َّ‬

‫البرن امج ال ذي اس تعملناها لش رح التعليم ة ‪ break‬أو ‪ continue‬أعاله‪ ،‬لكنن ا سنس تخدم‬

‫التعليمة ‪ pass‬هذه المرة‪:‬‬

‫‪number = 0‬‬

‫‪for number in range(10):‬‬


‫‪number = number + 1‬‬

‫‪if number == 5:‬‬


‫‪pass‬‬ ‫تخطى وأكمل ‪#‬‬

‫))‪print('Number is ' + str(number‬‬

‫)'‪print('Out of loop‬‬

‫أن علي ه إكم ال تنفي ذ الحلق ة وتجاه ل‬


‫تخبر التعليمة ‪ pass‬التي تقع بعد الشرط ‪ if‬البرنامج َّ‬

‫ِّ‬
‫لنشغل البرنامج ولننظر إلى الناتج‪:‬‬ ‫مساواة المتغير ‪ number‬للرقم ‪.5‬‬

‫‪Number is 1‬‬
‫‪Number is 2‬‬
‫‪Number is 3‬‬
‫‪Number is 4‬‬

‫▲‬ ‫|‬ ‫‪285‬‬


‫البرمجة بلغة بايثون‬ ‫المهام التكرارية‪ :‬مدخل إلى الحلقات‬

‫‪Number is 5‬‬
‫‪Number is 6‬‬
‫‪Number is 7‬‬
‫‪Number is 8‬‬
‫‪Number is 9‬‬
‫‪Number is 10‬‬
‫‪Out of loop‬‬

‫أن البرنامج يعمل كما لو أننا لم نض ع‬


‫الحظنا عند استخدامنا للتعليمة ‪ pass‬في هذا البرنامج َّ‬

‫أن‬
‫تعليم ة ش رطية داخ ل حلق ة التك رار؛ إذ تخ بر التعليم ة ‪ pass‬البرن امج أن يكم ل التنفي ذ كم ا ل و َّ‬

‫الش رط لم يتحق ق‪ .‬يمكن أن تس تفيد من التعليم ة ‪ pass‬عن دما تكتب برنامج ك ألوّ ل م رة أثن اء‬

‫ّ‬
‫بحل مشكلة ما عبر خوارزمية‪ ،‬لكن قبل أن تضع التفاصيل التقنية له‪.‬‬ ‫تفكيرك‬

‫‪ .4‬خالصة الفصل‬
‫شرحنا في هذا الفصل كيف تعمل حلقتي التكرار ‪ ، while‬و ‪ for‬في بايثون وكيفية إنشائها‪،‬‬

‫إذ تس تمر األولى بتنفي ذ مجموع ة من األس طر البرمجي ة لطالم ا ك ان الش رط مس اويً ا للقيم ة ‪true‬‬

‫بينم ا تس تمر الثاني ة بتنفي ذ مجموع ة من الش يفرات لع ددٍ مُ ح ِّددٍ من الم رات‪ .‬انتقلن ا أخ يرًا إلى‬

‫التعليم ات ‪ break‬و ‪ continue‬و ‪ pass‬ال تي تس مح ب التحكم أك ثر بحلق ات ‪ for‬و ‪while‬‬

‫ِّ‬
‫تكررة‪.‬‬ ‫والتعامل مع األحداث المفاجئة التي تحدث أثناء تنفيذ مهمة مُ‬

‫▲‬ ‫|‬ ‫‪286‬‬


‫‪16‬‬
‫الدوال‪ :‬تعريفها‬
‫واستعمالها‬

‫▲‬ ‫|‬ ‫‪287‬‬


‫البرمجة بلغة بايثون‬ ‫الدوال‪ :‬تعريفها واستعمالها‬

‫راء م ا‪ ،‬ويمكن‪ ،‬بع د تعريفه ا‪ ،‬إع ادة‬ ‫الدال ة (‪ )function‬هي كتل ة من التعليم ات ال تي ِّ‬
‫تنفذ إج ً‬

‫اس تخدامها في أك ثر من موض ع‪ .‬تجع ل ال دوال الش يفرة تركيبي ة ( ‪ ،)modular‬مم ا يس مح‬

‫باستخدام نفس الشفرة مرارًا وتكرارًا‪.‬‬

‫تضم بايثون عد ًدا من الدوال المُ ضمّ نة الشائعة‪ ،‬مثل‪:‬‬

‫)(‪ print‬والتي تطبع كائنًا في الطرفية‪،‬‬ ‫•‬

‫ِّ‬
‫تحول أنواع البيانات النصية أو العددية إلى أعداد صحيحة‪،‬‬ ‫)(‪ int‬والتي‬ ‫•‬

‫)(‪ len‬التي تعيد طول كائن‪ ،‬وغيرها من الدوال‪.‬‬ ‫•‬

‫وكيفية استخدامها في البرامج‪.‬‬


‫َّ‬ ‫كيفية تعريف الدوال‪،‬‬
‫َّ‬ ‫َّ‬
‫سنتعلم في هذا الفصل‬

‫‪ .1‬تعريف دالة‬
‫مرحبا بالعالم!" إلى دالة‪.‬‬
‫ً‬ ‫لنبدأ بتحويل البرنامج الذي يطبع عبارة "‬

‫أنش ئ ً‬
‫ملف ا نص ًيا جدي ًدا‪ ،‬وافتح ه في مح رر النص وص المفض ل عن دك‪ ،‬ثم اس تدع البرن امج‬

‫‪ُ .hello.py‬تع رَّ ف الدال ة باس تخدام الكلم ة المفتاحي ة ‪ ،def‬متبوع ة باس م من اختي ارك‪ ،‬متبوعً ا‬

‫بقوسين يمكن أن يَحتويا المعامالت التي ستأخذها الدال ة‪ ،‬ثم ينتهي التعري ف بنقط تين‪ .‬في ه ذه‬

‫ِّ‬
‫سنعرف دالة باسم )(‪:hello‬‬ ‫الحالة‪،‬‬

‫‪def hello():‬‬

‫في الشفرة أعاله‪ ،‬أعددنا السطر األول من تعريف الدالة‪.‬‬

‫ثاني ا مُ ً‬
‫زاح ا ب أربع مس افات بيض اء‪ ،‬وفي ه س نكتب التعليم ات ال تي‬ ‫ً‬ ‫بع د ه ذا‪ ،‬سنض يف س ط ًرا‬

‫مرحبا بالعالم!" في سطر األوامر‪:‬‬


‫ً‬ ‫ِّ‬
‫ستنفذها الدالة‪ .‬في هذه الحالة‪ ،‬سنطبع العبارة "‬

‫▲‬ ‫|‬ ‫‪288‬‬


‫البرمجة بلغة بايثون‬ ‫الدوال‪ :‬تعريفها واستعمالها‬

‫‪def hello():‬‬
‫)"مرحبا بالعالم"(‪print‬‬

‫لق د أتممن ا تعري ف دالتن ا‪ ،‬غ ير أنن ا إن َن َّفذنا البرن امج اآلن‪ ،‬فلن يح دث ُّ‬
‫أي ش يء‪ ،‬ألنن ا لم‬

‫نستدع الدالة؛ لذلك‪ ،‬سنستدعي الدالة بالشكل )(‪ hello‬خارج كتلة تعريف الدالة‪:‬‬

‫‪def hello():‬‬
‫)"!مرحبا بالعالم"(‪print‬‬

‫)(‪hello‬‬

‫ِّ‬
‫لننفذ البرنامج‪:‬‬ ‫اآلن‪،‬‬

‫‪python hello.py‬‬

‫يجب أن تحصل على المخرجات التالية‪:‬‬

‫!مرحبا بالعالم‬

‫بعض الدوال أكثر تعقي ًدا بكث ير من الدال ة )(‪ hello‬ال تي عرَّ فناه ا أعاله‪ .‬على س بيل المث ال‪،‬‬

‫يمكننا استخدام الحلقة ‪ for‬والتعليمات الشرطية‪ ،‬وغيرها داخل كتلة الدالة‪.‬‬

‫ُّ‬
‫للتحقق مم ا إذا ك انت‬ ‫على س بيل المث ال‪ ،‬تس تخدم الدال ة المُ عرَّ ف ة أدن اه تعليم ة ش رطية‬

‫الم دخالت المم رَّ رة إلى المتغ ير ‪ name‬تحت وي على ح رف عل ة (‪ ،)vowel‬ثم تس تخدم الحلق ة ‪for‬‬

‫للمرور (‪ )iterate‬على الحروف الموجودة في السلسلة النصية ‪.name‬‬

‫تعريف الدالة )(‪# names‬‬


‫‪def names():‬‬
‫إعداد المتغير ‪ name‬وإحالة المدخالت عليه ‪#‬‬
‫))'‪:‬أدخل اسمك باللغة اإلنجليزية'(‪name = str(input‬‬

‫▲‬ ‫|‬ ‫‪289‬‬


‫البرمجة بلغة بايثون‬ ‫الدوال‪ :‬تعريفها واستعمالها‬

‫التحقق من أن ‪ name‬يحتوي حرف علة ‪#‬‬


‫‪if set('aeiou').intersection(name.lower()):‬‬
‫)'اسمك يحوي حرف علة'(‪print‬‬
‫‪else:‬‬
‫)'اسمك ال يحوي حرف علة'(‪print‬‬

‫المرور على حروف ‪# name‬‬


‫‪for letter in name:‬‬
‫)‪print(letter‬‬

‫استدعاء الدالة ‪#‬‬


‫)(‪names‬‬

‫تس تخدم الدال ة )(‪ names‬ال تي عرَّ فناه ا أعاله تعليم ة ش رطية‪ ،‬وحلق ة ‪ ،for‬وه ذا توض يح‬

‫ً‬
‫أيض ا جع ل التعليم ة الش رطية‬ ‫لكيفي ة تنظيم الش فرة البرمجي ة ض من تعري ف الدال ة‪ .‬يمكنن ا‬

‫والحلقة ‪ for‬دالتين منفصلتين‪.‬‬

‫تعري ف ال دوال داخ ل ال برامج يجع ل الش فرة البرمجي ة تركيبي ة (‪ ،)modular‬وقابل ة إلع ادة‬

‫االستخدام‪ ،‬وذلك سيتيح لنا استدعاء نفس الدالة دون إعادة كتابة شيفرتها كل مرة‪.‬‬

‫‪ .2‬المعامالت‪ :‬تمرير بيانات للدوال‬


‫أي وس ائط (‪ ،)arguments‬س نتعلم في‬
‫ح تى اآلن‪ ،‬عرَّ فن ا دال ة ذات قوس ين ف ارغين ال تأخ ذ َّ‬

‫هذا القسم كيفية تعريف المعامالت (‪ )parameters‬وتمرير البيانات إلى الدوال‪.‬‬

‫المعام ل (‪ )parameter‬ه و كي ان مُ س مًّ ى يوض ع في تعري ف الدال ة‪ ،‬ويع ِّرف وس ً‬


‫يطا‬

‫(‪ )arguments‬يمكن أن تقبله الدالة عند استدعائها‪.‬‬

‫ً‬
‫برنامج ا ص غي ًرا يأخ ذ ثالث ة مع امالت ‪ x‬و ‪ y‬و ‪ .z‬سننش ئ دال ة تجم ع تل ك‬ ‫دعن ا ننش ئ‬

‫ثم تطبع حاصل جمعها‪.‬‬


‫المعامالت وفق عدة مجموعات َّ‬

‫▲‬ ‫|‬ ‫‪290‬‬


‫البرمجة بلغة بايثون‬ ‫الدوال‪ :‬تعريفها واستعمالها‬

‫‪def add_numbers(x, y, z):‬‬


‫‪a = x + y‬‬
‫‪b = x + z‬‬
‫‪c = y + z‬‬
‫)‪print(a, b, c‬‬

‫)‪add_numbers(1, 2, 3‬‬

‫مرّ رن ا الع دد ‪ 1‬إلى المعام ل ‪ ،x‬و ‪ 2‬إلى المعام ل ‪ ،y‬و ‪ 3‬إلى المعام ل ‪ .z‬تتواف ق ه ذه القيم م ع‬

‫المعامالت المقابلة لها في ترتيب الظهور‪.‬‬

‫يُ ج ِري البرنامج العمليات الحسابية على المعامالت على النحو التالي‪:‬‬

‫‪a = 1 + 2‬‬
‫‪b = 1 + 3‬‬
‫‪c = 2 + 3‬‬

‫إن قيم ة ‪ a‬ستس اوي‬


‫اء على العملي ات الحس ابية أعاله‪ ،‬ف َّ‬ ‫ً‬
‫أيض ا ‪ a‬و ‪ b‬و ‪ ،c‬وبن ً‬ ‫تطب ع الدال ة‬

‫العدد ‪ ،3‬و ‪ b‬ستساوي ‪ ،4‬و ‪ c‬ستساوي العدد ‪.5‬‬

‫ِّ‬
‫لننفذ البرنامج‪:‬‬

‫‪python add_numbers.py‬‬

‫سنحصل على المخرجات التالية‪:‬‬

‫‪3 4 5‬‬

‫المع امالت هي متغ يرات ُتع رَّ ف ض من جس م الدال ة‪ .‬يمكن تع يين قيم إليه ا عن د تنفي ذ الت ابع‬

‫تلقائيا آنذاك‪.‬‬
‫ً‬ ‫بتمرير وسائط إلى الدالة‪ ،‬إذ ُتسنَد الوسائط إليها‬

‫▲‬ ‫|‬ ‫‪291‬‬


‫البرمجة بلغة بايثون‬ ‫الدوال‪ :‬تعريفها واستعمالها‬

‫المسماة‬
‫َّ‬ ‫‪ .3‬الوسائط‬
‫ُتس تدعى المع امالت بحس ب ت رتيب ظهوره ا في تعري ف الدال ة‪ ،‬أم ا الوس ائط المس ماة‬

‫(‪ُ )Keyword Arguments‬‬


‫فتستخ َدم بأسمائها في استدعاء الدالة‪.‬‬

‫ألن م ترجم‬
‫أي ت رتيب تري د‪َّ ،‬‬
‫عند اس تخدام الوس ائط المس مّ اة‪ ،‬يمكن ك اس تخدام المع امالت ب ِّ‬

‫بايثون سيستخدم الكلمات المفتاحية لمطابقة القيم مع المعامالت‪.‬‬

‫ِّ‬
‫ونمرر إليه ا المُ ع امِ لين ‪username‬‬ ‫سننشئ دالة تعرض معلومات الملف الشخصي للمستخدم‪،‬‬

‫(سلسلة نصية)‪ ،‬و ‪( followers‬عدد صحيح)‪.‬‬

‫تعريف دالة ذات معامالت ‪#‬‬


‫‪def profile_info(username, followers):‬‬
‫)‪print("Username: " + username‬‬
‫))‪print("Followers: " + str(followers‬‬

‫ة‬ ‫ي الدال‬ ‫عنا ‪ username‬و ‪ followers‬بين قوس‬ ‫ة‪ ،‬وض‬ ‫ف الدال‬ ‫ل تعري‬ ‫داخ‬

‫الخاص ة بالمس تخدم على هيئ ة‬


‫َّ‬ ‫)(‪ profile_info‬أثن اء تعريفه ا‪ .‬تطب ع ش فرة الدال ة المعلوم ات‬

‫سلسلة نصية باستخدام المعاملين المُ مرّ رين‪.‬‬

‫اآلن‪ ،‬يمكننا استدعاء الدالة وتعيين المعامالت‪:‬‬

‫‪def profile_info(username, followers):‬‬


‫)‪print("Username: " + username‬‬
‫))‪print("Followers: " + str(followers‬‬

‫استدعاء الدالة مع تعيين المعامالت ‪#‬‬


‫)‪profile_info("sammyshark", 945‬‬

‫استدعاء الدالة مع تمرير الوسائط المسماة إليها ‪#‬‬


‫)‪profile_info(username="AlexAnglerfish", followers=342‬‬

‫▲‬ ‫|‬ ‫‪292‬‬


‫البرمجة بلغة بايثون‬ ‫الدوال‪ :‬تعريفها واستعمالها‬

‫في االس تدعاء األول للدال ة‪ ،‬مرَّ رن ا اس م المس تخدم ‪ ،sammyshark‬وع دد المت ابعين ‪945‬‬

‫ب الترتيب ال وارد في تعري ف الدال ة‪ .‬أمَّ ا في االس تدعاء الث اني للدال ة‪ ،‬فق د اس تخدمنا الوس ائط‬

‫وعينا قيمً ا للوسائط ويمكن عكس الترتيب إن شئنا‪ .‬لننفذ البرنامج‪:‬‬


‫َّ‬ ‫المسمَّ اة‪،‬‬

‫‪python profile.py‬‬

‫سنحصل على المخرجات التالية‪:‬‬

‫‪Username: sammyshark‬‬
‫‪Followers: 945‬‬
‫‪Username: AlexAnglerfish‬‬
‫‪Followers: 342‬‬

‫سنحص ل في المخرج ات على أس ماء المس تخدمين‪ ،‬وأع داد المت ابعين لكال المس تخدمين‪.‬‬

‫يمكننا تغيير ترتيب المعامالت‪ ،‬كما في المثال التالي‪:‬‬

‫‪def profile_info(username, followers):‬‬


‫)‪print("Username: " + username‬‬
‫))‪print("Followers: " + str(followers‬‬

‫تغيير ترتيب المعامالت ‪#‬‬


‫)"‪profile_info(followers=820, username="cameron-catfish‬‬

‫عند تنفيذ البرنامج أعاله‪ ،‬سنحصل على المخرجات التالية‪:‬‬

‫‪Username: cameron-catfish‬‬
‫‪Followers: 820‬‬

‫يحاف ظ تعري ف الدال ة على نفس ت رتيب التعليم ات في )(‪ ،print‬ل ذلك يمكنن ا اس تخدام‬

‫بأي ترتيب نشاء‪.‬‬


‫الوسائط المسمّ اة ِّ‬

‫▲‬ ‫|‬ ‫‪293‬‬


‫البرمجة بلغة بايثون‬ ‫الدوال‪ :‬تعريفها واستعمالها‬

‫‪ .4‬القيم االفتراضية للوسائط‬


‫يمكنن ا إعط اء قيم افتراض ية لواح د أو أك ثر من المع امالت‪ .‬في المث ال أدن اه‪ ،‬س نعطي‬

‫للمعام ل ‪ followers‬القيم ة االفتراض ية ‪ 1‬الس تعمالها إن لم ُتم رَّ ر ه ذه القيم ة للدال ة‬

‫عند استدعائها‪:‬‬

‫‪def profile_info(username, followers=1):‬‬


‫)‪print("Username: " + username‬‬
‫))‪print("Followers: " + str(followers‬‬

‫تلقائي ا‬
‫ً‬ ‫عين ع دد المت ابعين‬
‫اآلن‪ ،‬يمكننا استدعاء الدالة مع تعيين اسم المستخدم فق ط‪ ،‬وس ُي َّ‬

‫ويأخذ القيمة ‪ .1‬لكن يمكننا تغيير عدد المتابعين إن شئنا‪.‬‬

‫‪def profile_info(username, followers=1):‬‬


‫)‪print("Username: " + username‬‬
‫))‪print("Followers: " + str(followers‬‬

‫)"‪profile_info(username="JOctopus‬‬
‫)‪profile_info(username="sammyshark", followers=945‬‬

‫عندما ِّ‬
‫ننفذ البرنامج باستخدام األمر ‪ ،python profile.py‬ستظهر المخرجات التالية‪:‬‬

‫‪Username: JOctopus‬‬
‫‪Followers: 1‬‬
‫‪Username: sammyshark‬‬
‫‪Followers: 945‬‬

‫تمري ر قيم إلى المع امالت االفتراض ية س يتخطى القيم ة االفتراض ية المعط اة في‬

‫تعريف الدالة‪.‬‬

‫▲‬ ‫|‬ ‫‪294‬‬


‫البرمجة بلغة بايثون‬ ‫الدوال‪ :‬تعريفها واستعمالها‬

‫‪ .5‬إعادة قيمة‬
‫كم ا يمكن تمري ر قيم إلى الدال ة‪ ،‬فيمكن ك ذلك أن تنتج الدال ة قيم ة وتعي دها لمن اس تدعاها‪.‬‬

‫ويكون ذلك عبر استخدام التعليم ة ‪return‬؛ ه ذه التعليم ة اختياري ة‪،‬‬


‫ُ‬ ‫يمكن أن تنتج الدالة قيمة‪،‬‬

‫وتم رَّ ر قيم ة التعب ير ال ذي‬ ‫نهي الدال ة مباش ً‬


‫رة عمله ا وتوق ف تنفي ذها‪ُ ،‬‬ ‫وفي ح ال اس تخدامها‪ ،‬فس ُت ِ‬

‫ُتعيد الدالة‬ ‫يء‪ ،‬فس‬ ‫ة ‪ return‬أي ش‬ ‫تدعي (‪ .)caller‬إذا لم يلي التعليم‬ ‫ا إلى المُ س‬ ‫ُ‬
‫يعقبه‬

‫َ‬
‫القيمة ‪.None‬‬

‫ح تى اآلن‪ ،‬اس تخدمنا الدال ة )(‪ print‬ب دالً من ‪ return‬في دوالن ا لطباع ة ش يء ب داًل من‬

‫برنامجا يعيد متغيرً ا بداًل من طباعته اآلن‪.‬‬


‫ً‬ ‫إعادته‪ .‬لننشئ‬

‫برنامجا في ملف نصي جديد يسمى ‪ square.py‬يحسب مربع المعام ل ‪ ،x‬ويُ حي ل‬


‫ً‬ ‫سننشئ‬

‫الن اتج إلى المتغ ير ‪ ،y‬ثم يعي ده‪ .‬س نطبع المتغ ير ‪ ،result‬وال ذي يس اوي ن اتج تنفي ذ‬

‫الدالة )‪.square(3‬‬

‫‪def square(x):‬‬
‫‪y = x ** 2‬‬
‫‪return y‬‬

‫)‪result = square(3‬‬
‫)‪print(result‬‬

‫ّ‬
‫لننفذ البرنامج‪:‬‬

‫‪python square.py‬‬

‫سنحصل على المخرجات التالية‪:‬‬

‫‪9‬‬

‫▲‬ ‫|‬ ‫‪295‬‬


‫البرمجة بلغة بايثون‬ ‫الدوال‪ :‬تعريفها واستعمالها‬

‫مخرج ات البرن امج هي الع دد الص حيح ‪ 9‬ال ذي أعادت ه الدال ة وه و م ا نتوقع ه ل و طلبن ا من‬

‫بايثون حساب مربع العدد ‪.3‬‬

‫لفهم كيفية عمل التعليمة ‪ ،return‬يمكننا تعليق التعليمة ‪:return‬‬

‫‪def square(x):‬‬
‫‪y = x ** 2‬‬
‫‪# return y‬‬

‫)‪result = square(3‬‬
‫)‪print(result‬‬

‫ّ‬
‫لننفذ البرنامج مرة أخرى‪:‬‬ ‫اآلن‪،‬‬

‫‪python square.py‬‬

‫سنحصل على الناتج التالي‪:‬‬

‫‪None‬‬

‫أي قيم ة‪ ،‬ل ذلك ُتع اد القيم ة‬


‫ب دون اس تخدام التعليم ة ‪ ،return‬ال يمكن للبرن امج إع ادة ِّ‬

‫االفتراضية ‪.None‬‬

‫إلي ك مث ال آخ ر‪ ،‬في برن امج ‪ add_numbers.py‬أعاله‪ ،‬سنس تبدل بالتعليم ة ‪return‬‬

‫الدالة )(‪:print‬‬

‫‪def add_numbers(x, y, z):‬‬


‫‪a = x + y‬‬
‫‪b = x + z‬‬
‫‪c = y + z‬‬
‫‪return a, b, c‬‬

‫▲‬ ‫|‬ ‫‪296‬‬


‫البرمجة بلغة بايثون‬ ‫الدوال‪ :‬تعريفها واستعمالها‬

‫)‪sums = add_numbers(1, 2, 3‬‬


‫)‪print(sums‬‬

‫خ ارج الدال ة‪ ،‬أحلن ا إلى المتغ ير ‪ sums‬نتيج ة اس تدعاء الدال ة بالوس ائط ‪ 1‬و ‪ 2‬و ‪ 3‬كم ا فعلن ا‬

‫أعاله ثم طبعنا قيمته‪.‬‬

‫ِّ‬
‫فلننفذ البرنامج مرة أخرى‪:‬‬

‫‪python add_numbers.py‬‬

‫والناتج سيكون‪:‬‬

‫)‪(3, 4, 5‬‬

‫لق د حص لنا على األع داد ‪ 3‬و ‪ 4‬و ‪ 5‬وهي نفس المخرج ات ال تي تلقيناه ا س ً‬
‫ابقا عن دما‬

‫ألن التعب ير المراف ق‬


‫استخدمنا الدالة )(‪ print‬في الدالة‪ .‬هذه المرة تمت إعادتها على هيئة ص ف َّ‬

‫للتعليمة ‪ return‬يحتوي على فاصلة واحدة على األقل‪.‬‬

‫ُت َ‬
‫وقف الدوال فورًا عندما تصل إلى التعليمة ‪ ،return‬سواء أعادت قيمة‪ ،‬أم لم ُتعِ د‪.‬‬

‫‪def loop_five():‬‬
‫‪for x in range(0, 25):‬‬
‫)‪print(x‬‬
‫‪if x == 5:‬‬
‫إيقاف الدالة عند ‪# x == 5‬‬
‫‪return‬‬
‫)"‪print("This line will not execute.‬‬

‫)(‪loop_five‬‬

‫▲‬ ‫|‬ ‫‪297‬‬


‫البرمجة بلغة بايثون‬ ‫الدوال‪ :‬تعريفها واستعمالها‬

‫ي ؤدي اس تخدام التعليم ة ‪ return‬داخ ل الحلق ة ‪ for‬إلى إنه اء الدال ة‪ ،‬وبالت الي لن يُ َّ‬
‫نفذ‬

‫السطر الموجود خارج الحلقة‪.‬‬

‫فسي َّ‬
‫نفذ الس طر )(‪ print‬األخ ير من المث ال الس ابق‪ .‬نعي د‬ ‫ُ‬ ‫لو استخدمنا بداًل من ذلك ‪،break‬‬

‫أن التعليمة ‪ return‬تنهي عمل الدالة‪ ،‬وقد تعيد قيمة إذا أعقبها تعبير‪.‬‬
‫التذكير َّ‬

‫ً‬
‫رئيسية‬ ‫ً‬
‫دالة‬ ‫‪ .6‬استخدام )(‪main‬‬
‫رغم َّ‬
‫أنه يمكن ك في ب ايثون اس تدعاء الدال ة في أس فل البرن امج وتنفي ذها (كم ا فعلن ا في‬

‫إن العدي د من لغ ات البرمج ة (مث ل ‪ C++‬و ‪ )Java‬تتطلب وج ود دال ة رئيس ية‬


‫األمثل ة أعاله)‪ ،‬ف َّ‬

‫إلزاميا‪ ،‬يمكن أن يهيكل برامج ب ايثون بطريق ة‬


‫ً‬ ‫إن تضمين دالة )(‪ ،main‬وإن لم يكن‬
‫تدعى ‪َّ .main‬‬

‫منطقية‪ ،‬فتضع أهم مكونات البرنامج في دالة واحدة‪ .‬كما يمكن أن يجعل البرن امج أك ثر مقروئي ة‬

‫للمبرمجين غير البايثونيِّ ين‪.‬‬

‫س نبدأ بإض افة دال ة )(‪ main‬إلى برن امج ‪ hello.py‬أعاله‪ .‬س نحتفظ بالدال ة )(‪ ،hello‬ثم‬

‫ِّ‬
‫نعرف الدالة )(‪:main‬‬

‫‪def hello():‬‬
‫)"مرحبا بالعالم"(‪print‬‬

‫‪def main():‬‬

‫ً‬
‫أيض ا‬ ‫ضمن الدالة )(‪ ،main‬سندرج الدالة )(‪ ،print‬والتي ستعُ لِمنا َّ‬
‫بأننا في الدال ة )(‪.main‬‬

‫سنستدعي الدالة )(‪ hello‬داخل )(‪:main‬‬

‫▲‬ ‫|‬ ‫‪298‬‬


‫البرمجة بلغة بايثون‬ ‫الدوال‪ :‬تعريفها واستعمالها‬

‫‪def hello():‬‬
‫)"مرحبا بالعالم"(‪print‬‬

‫‪def main():‬‬
‫)"هذه هي الدالة الرئيسية"(‪print‬‬
‫)(‪hello‬‬

‫أخي ًرا‪ ،‬في أسفل البرنامج‪ ،‬سنستدعي الدالة )(‪:main‬‬

‫‪def hello():‬‬
‫)"!مرحبا بالعالم"(‪print‬‬

‫‪def main():‬‬
‫)"‪.‬هذه هي الدالة الرئيسية"(‪print‬‬
‫)(‪hello‬‬

‫)(‪main‬‬

‫اآلن يمكننا تنفيذ برنامجنا‪:‬‬

‫‪python hello.py‬‬

‫وسنحصل على المخرجات التالية‪:‬‬

‫‪.‬هذه هي الدالة الرئيسية‬


‫!مرحبا بالعالم‬

‫نفذنا الدال ة )(‪ main‬وح دها‪ ،‬فق د ُطب ع‬


‫لمَّ ا اس تدعينا الدال ة )(‪ hello‬داخ ل )(‪ ،main‬ثم َّ‬

‫النص "مرحبا بالعالم!" مرة واحدة فقط‪ ،‬وذلك عقب السلسلة النصية التي أخبرتن ا بأنن ا في الدال ة‬

‫الرئيسية‪( .‬سنعمل اآلن م ع دوال مُ تع ِّددة‪ ،‬ل ذلك من المستحس ن أن تراج ع نطاق ات المتغ يرات في‬

‫فصل المتغيرات إن كنت قد نسيتها‪).‬‬

‫▲‬ ‫|‬ ‫‪299‬‬


‫البرمجة بلغة بايثون‬ ‫الدوال‪ :‬تعريفها واستعمالها‬

‫إذا عرَّ فت متغي ًرا داخل دال ة‪ ،‬فال يمكن ك أن تس تخدم ذل ك المتغ ير إال ض من تل ك الدال ة‪ .‬ل ذا‪،‬‬

‫إن أردت اس تخدام متغ ير م ا في ع دة دوال‪ ،‬فق د يك ون من األفض ل اإلعالن عن ه متغ ي ًرا‬

‫عامً ا (‪.)global variable‬‬

‫في ب ايثون‪ ،‬يع ُّد '__‪ '__main‬اس م النط اق ال ذي س ُت َّ‬


‫نفذ في ه الش يفرة العليا‬

‫(‪ .)top-level code‬عند تنفيذ برنامج من الدخل القياسي (‪ ،)standard input‬أو من س كربت‪ ،‬أو‬

‫من سطر األوامر‪ ،‬سيتم ضبط __‪ __name‬عند القيمة '__‪.'__main‬‬

‫لهذا السبب‪ ،‬اصطلح مطورو بايثون على استخدام الصياغة التالية‪:‬‬

‫‪if __name__ == '__main__':‬‬


‫ُنّ‬
‫فذ لو كان هذا هو البرنامج الرئيسي ‪#‬‬ ‫الشفرة التي ست‬

‫هذه الصياغة تتيح استخدام ملفات بايثون إما‪:‬‬

‫برامج رئيسية‪ ،‬مع تنفيذ ما يلي التعليمة ‪ ،if‬أو‬ ‫•‬

‫وحدات عادية‪ ،‬مع عدم تنفيذ ما يتبع التعليمة ‪.if‬‬ ‫•‬

‫ست َّ‬
‫نفذ الش فرة غ ير المُ تض ِّمنة في العب ارة ‪ if __name__ == '__main__':‬عن د التنفي ذ‪.‬‬ ‫ُ‬

‫ً‬
‫أيض ا الش يفرة البرمجي ة غ ير المُ تض ِّمنة في ه ذه‬ ‫إذا كنت تس تخدم مل ف ب ايثون كوح دة‪ ،‬فس ُت َّ‬
‫نفذ‬

‫العبارة عند استيراد ذلك الملف‪.‬‬

‫نوسع البرنامج ‪ names.py‬أعاله‪ ،‬لننش ئ ملف ا جدي ًدا يس مى ‪ .more_names.py‬س نعلن‬


‫ِّ‬ ‫دعنا‬

‫ِّ‬
‫نقس م في ه التعليم ات إلى‬ ‫لية بش كل‬ ‫ِّ‬
‫ونعدل الدالة )(‪ names‬األص َّ‬ ‫في هذا البرنامج عن متغير عام‪،‬‬

‫دالتين منفصلتين‪.‬‬

‫▲‬ ‫|‬ ‫‪300‬‬


‫البرمجة بلغة بايثون‬ ‫الدوال‪ :‬تعريفها واستعمالها‬

‫َّ‬
‫تتحقق الدال ة األولى )(‪ has_vowel‬مم ا إذا ك انت السلس لة النص ية ‪ name‬تحت وي على‬ ‫س‬

‫ح رف عل ة (‪ .)vowel‬وتطب ع الدال ة الثاني ة )(‪ print_letters‬ك ل ح رف من السلس لة‬

‫النصية ‪.name‬‬

‫اإلعالن عن متغير عام الستخدامه في جميع الدوال ‪#‬‬


‫))'‪:‬أدخل اسمك باللغة اإلنجليزية'(‪name = str(input‬‬

‫تعريف دالة للتحقق من أن ‪ name‬يحتوي حرف علة ‪#‬‬


‫‪def has_vowel():‬‬
‫‪if set('aeiou').intersection(name.lower()):‬‬
‫)'اسمك يحتوي حرف علة'(‪print‬‬
‫‪else:‬‬
‫)'اسمك ال يحتوي حرف علة'(‪print‬‬

‫المرور على حروف ‪# name‬‬


‫‪def print_letters():‬‬
‫‪for letter in name:‬‬
‫)‪print(letter‬‬

‫بع د ذل ك‪ ،‬دعن ا نع ِّرف الدال ة )(‪ main‬ال تي َستس تدعي كال من الدال ة )(‪has_vowel‬‬

‫والدالة )(‪.print_letters‬‬

‫اإلعالن عن متغير عام الستخدامه في جميع الدوال ‪#‬‬


‫))'‪:‬أدخل اسمك باللغة اإلنجليزية'(‪name = str(input‬‬

‫ّ ‪ name‬يحتوي حرف علة ‪#‬‬


‫تعريف دالة للتحقق من أن‬
‫‪def has_vowel():‬‬
‫‪if set('aeiou').intersection(name.lower()):‬‬

‫▲‬ ‫|‬ ‫‪301‬‬


‫البرمجة بلغة بايثون‬ ‫الدوال‪ :‬تعريفها واستعمالها‬

‫)'اسمك يحتوي حرف علة'(‪print‬‬


‫‪else:‬‬
‫)'اسمك ال يحتوي حرف علة'(‪print‬‬

‫المرور على حروف ‪# name‬‬


‫‪def print_letters():‬‬
‫‪for letter in name:‬‬
‫)‪print(letter‬‬

‫تعريف الدالة ‪ main‬التي ستستدعي بقية الدوال ‪#‬‬


‫‪def main():‬‬
‫)(‪has_vowel‬‬
‫)(‪print_letters‬‬

‫أخ ي ًرا‪ ،‬سنض يف العب ارة ‪ if __name__ == '__main__':‬في أس فل المل ف‪ .‬لق د وض عنا‬

‫جميع الدوال التي نو ُّد تنفيذها في الدالة )(‪ ،main‬لذا سنستدعي الدالة )(‪ main‬بعد الشرط ‪.if‬‬

‫اإلعالن عن متغير عام الستخدامه في جميع الدوال ‪#‬‬


‫))'‪:‬أدخل اسمك'(‪name = str(input‬‬

‫تعريف دالة للتحقق من أن ‪ name‬يحتوي حرف علة ‪#‬‬


‫‪def has_vowel():‬‬
‫‪if set('aeiou').intersection(name.lower()):‬‬
‫)'اسمك يحتوي حرف علة'(‪print‬‬
‫‪else:‬‬
‫)'اسمك ال يحتوي حرف علة'(‪print‬‬

‫المرور على حروف ‪# name‬‬

‫▲‬ ‫|‬ ‫‪302‬‬


‫البرمجة بلغة بايثون‬ ‫الدوال‪ :‬تعريفها واستعمالها‬

‫‪def print_letters():‬‬
‫‪for letter in name:‬‬
‫)‪print(letter‬‬

‫تعريف الدالة ‪ main‬التي ستستدعي بقية الدوال ‪#‬‬

‫‪def main():‬‬
‫)(‪has_vowel‬‬
‫)(‪print_letters‬‬

‫تنفيذ الدالة )(‪# main‬‬


‫‪if __name__ == '__main__':‬‬
‫)(‪main‬‬

‫يمكننا اآلن تنفيذ البرنامج‪:‬‬

‫‪python more_names.py‬‬

‫أن الشفرة هن ا‬
‫بيد َّ‬
‫سيعرض هذا البرنامج نفس المخرجات التي عرضها البرنامج ‪ْ ،names.py‬‬

‫أكثر تنظيمً ا‪ ،‬ويمكن استخدامها بطريقة تركيبية (‪.)modular‬‬

‫إذا لم ترغب في اإلعالن عن الدالة )(‪ ،main‬يمكنك بداًل من ذلك إنهاء البرنامج كما يلي‪:‬‬

‫‪...‬‬
‫‪if __name__ == '__main__':‬‬
‫)(‪has_vowel‬‬
‫)(‪print_letters‬‬

‫ارة‬ ‫تخدام العب‬ ‫ل )(‪ ،main‬واس‬ ‫ية مث‬ ‫ة رئيس‬ ‫تخدام دال‬ ‫ؤدي اس‬ ‫ي‬

‫‪ if __name__ == '__main__':‬إلى تنظيم الشيفرة البرمجية بطريقة منطقية‪ ،‬وجعلها أك ثر‬

‫مقروئية وتراكبية‪.‬‬

‫▲‬ ‫|‬ ‫‪303‬‬


‫البرمجة بلغة بايثون‬ ‫الدوال‪ :‬تعريفها واستعمالها‬

‫‪ .7‬استخدام ‪ *args‬و ‪**kwargs‬‬


‫تع ُّد المعامالت في تعاريف الدوال كيانات مسماة ُتح ِّدد وس ً‬
‫يطا (‪ )argument‬يمكن أن يُ م رَّ ر‬

‫إلى الدالة المُ عرَّ فة‪.‬‬

‫أثن اء البرمج ة‪ ،‬ق د ال ت درك جمي ع ح االت االس تخدام الممكن ة للش يفرة‪ ،‬ل ذا ق د ت رغب في‬

‫توسيع خيارات المبرمجين المستقبليين الذين سيستخدمون الوحدة التي طورتها‪.‬‬

‫كيفية تمري ر ع دد متغ ير من الوس ائط إلى دال ة م ا باس تخدام‬


‫َّ‬ ‫س نتعلم في ه ذا القس م‬

‫الصياغتين ‪ *args‬و ‪.**kwargs‬‬

‫ا‪*args .‬‬

‫في بايثون‪ ،‬يمكن اس تخدام الش كل أح ادي النجم ة ‪ *args‬مع اماًل لتمري ر قائم ة غ ير مح َّددة‬

‫الطول من الوسائط غ ير المس ماة (‪ )non-keyworded argument‬إلى ال دوال‪ .‬تج در اإلش ارة إلى‬

‫أن الكلم ة ‪ args‬متع ارف عليه ا بين الم برمجين‪ ،‬إال َّ‬
‫أنه ا‬ ‫أن النجمة (*) عنص ر ض روري هن ا‪ ،‬إذ رغم َّ‬
‫َّ‬

‫غير رسمية‪.‬‬

‫لنلق نظرة على مثال لدالة تستخدم وسيطين‪:‬‬


‫ِ‬

‫‪def multiply(x, y):‬‬


‫)‪print (x * y‬‬

‫عرَّ فنا في الشيفرة أعاله دالة تقبل وسيطين ‪ x‬و ‪ ،y‬عندما نستدعي هذه الدالة‪ ،‬س نحتاج إلى‬

‫تمرير ع ددين م وافقين للوس يطين ‪ x‬و ‪ .y‬في ه ذا المث ال‪ ،‬س ِّ‬
‫نمرر الع دد الص حيح ‪ 5‬إلى ‪ ،x‬والع دد‬

‫الصحيح ‪ 4‬إلى ‪:y‬‬

‫▲‬ ‫|‬ ‫‪304‬‬


‫البرمجة بلغة بايثون‬ ‫الدوال‪ :‬تعريفها واستعمالها‬

‫‪def multiply(x, y):‬‬


‫)‪print (x * y‬‬

‫)‪multiply(5, 4‬‬

‫عند تنفيذ الشفرة أعاله‪:‬‬

‫‪python lets_multiply.py‬‬

‫سنحصل على المخرجات التالية‪:‬‬

‫‪20‬‬

‫الحقا حساب ناتج ض رب ثالث ة أع داد ب داًل من ع ددين فق ط؟ إذا ح اولت تمري ر‬
‫ً‬ ‫ماذا لو قرَّ رنا‬

‫عدد إضافي إلى الدالة‪ ،‬كما هو موضح أدناه‪:‬‬

‫‪def multiply(x, y):‬‬


‫)‪print (x * y‬‬

‫)‪multiply(5, 4, 3‬‬

‫فسي َ‬
‫طلق الخطأ التالي‪:‬‬ ‫ُ‬

‫‪TypeError: multiply() takes 2 positional arguments but 3 were‬‬


‫‪given‬‬

‫ً‬
‫الحق ا‪ ،‬فالح ل ه و‬ ‫إذا ش ككت َّ‬
‫أنك س تحتاج إلى اس تخدام المزي د من الوس ائط‬

‫اس تخدام ‪ *args‬مع امال‪ .‬س نزيل المُ ع املين ‪ x‬و ‪ y‬من الش يفرة في المث ال األول‪ ،‬ونض ع‬

‫مكانهما ‪:*args‬‬

‫▲‬ ‫|‬ ‫‪305‬‬


‫البرمجة بلغة بايثون‬ ‫الدوال‪ :‬تعريفها واستعمالها‬

‫‪def multiply(*args):‬‬
‫‪z = 1‬‬
‫‪for num in args:‬‬
‫‪z *= num‬‬
‫)‪print(z‬‬

‫)‪multiply(4, 5‬‬
‫)‪multiply(10, 9‬‬
‫)‪multiply(2, 3, 4‬‬
‫)‪multiply(3, 5, 10, 6‬‬

‫عندما ِّ‬
‫ننفذ هذه الشيفرة‪ ،‬سنحصل على ناتج استدعاءات الدالة أعاله‪:‬‬

‫‪20‬‬
‫‪90‬‬
‫‪24‬‬
‫‪900‬‬

‫يمكنن ا باس تخدام الوس يط ‪ *args‬تمري ر أي ع دد نحب من الوس ائط عن د اس تدعاء الدال ة‬

‫باإلض افة إلى كتاب ة ش يفرة أك ثر مرون ة‪ ،‬وإنش اء دوال تقب ل ع د ًدا غ ير مح دد مس ً‬
‫بقا من الوس ائط‬

‫غير المسماة‪.‬‬

‫ب‪**kwargs .‬‬

‫متغير الطول من الوسائط المس ماة‬


‫َّ‬ ‫يُ ستخ َدم الشكل ذو النجمتين ‪ **kwargs‬لتمرير قاموس‬

‫أن اس تخدام الكلم ة ‪kwargs‬‬


‫إلى الدال ة المعرَّ ف ة‪ .‬م رة أخ رى‪ ،‬النجمت ان (**) ض روريتان‪ ،‬فم ع َّ‬

‫متعارف عليه لدى المبرمجين‪ ،‬إال َّ‬


‫أنها غير رسمية‪.‬‬

‫أي ع دد من الوس ائط ال تي ت رغب في‬


‫يمكن أن تأخ ذ ‪ ،**kwargs‬كم ا ه و ش أن ‪َّ ،*args‬‬

‫▲‬ ‫|‬ ‫‪306‬‬


‫البرمجة بلغة بايثون‬ ‫الدوال‪ :‬تعريفها واستعمالها‬

‫أن ‪ **kwargs‬تختل ف عن ‪ *args‬في َّ‬


‫أنه ا تس توجب تع يين أس ماء‬ ‫بي د ّ‬
‫تمريره ا إلى الدال ة ْ‬

‫المعامالت (‪.)keywords‬‬

‫في المثال التالي‪ ،‬ستطبع الدالة الوسيط ‪ **kwargs‬الممرر إليها‪:‬‬

‫‪def print_kwargs(**kwargs):‬‬
‫)‪print(kwargs‬‬

‫ِّ‬
‫ونمرر إليها بعض الوسائط المسماة‪:‬‬ ‫سنستدعي اآلن الدالة‬

‫‪def print_kwargs(**kwargs):‬‬
‫)‪print(kwargs‬‬

‫)‪print_kwargs(kwargs_1="Shark", kwargs_2=4.5, kwargs_3=True‬‬

‫ِّ‬
‫لننفذ البرنامج أعاله‪:‬‬

‫‪python print_kwargs.py‬‬

‫سنحصل على المخرجات التالية‪:‬‬

‫}'‪{'kwargs_3': True, 'kwargs_2': 4.5, 'kwargs_1': 'Shark‬‬

‫مرتب ا‪ .‬في ب ايثون ‪3.6‬‬


‫ً‬ ‫اعتما ًدا على إصدار بايثون ‪ 3‬الذي تس تخدمه‪ ،‬فق د ال يك ون الق اموس‬

‫وم ا بع ده‪ ،‬ستحص ل على أزواج قيم ة‪-‬مفت اح (‪ )key-value‬مرتب ة‪ ،‬ولكن في اإلص دارات الس ابقة‪،‬‬

‫عشوائيا‪.‬‬
‫ً‬ ‫سيكون ترتيب األزواج‬

‫سي َ‬
‫نش أ ق اموس يس مى ‪ ،kwargs‬وال ذي يمكنن ا التعام ل مع ه مث ل أي ق اموس ع ادي‬ ‫ُ‬

‫داخل الدالة‪.‬‬

‫▲‬ ‫|‬ ‫‪307‬‬


‫البرمجة بلغة بايثون‬ ‫ تعريفها واستعمالها‬:‫الدوال‬

‫قاموس ا من‬
ً ‫ سننش ئ دال ة تطب ع‬.**kwargs ‫كيفية اس تخدام‬
َّ ً
‫برنامج ا آخ ر إلظه ار‬ ‫لننش ئ‬

:‫ سنبدأ بقاموس يحوي اسمين‬،ً‫ أوال‬.‫األسماء‬

def print_values(**kwargs):
for key, value in kwargs.items():
print("The value of {} is {}".format(key, value))

print_values(my_name="Sammy", your_name="Casey")

:‫بعد تنفيذ البرنامج عبر األمر التالي‬

python print_values.py

:‫سنحصل على ما يلي‬

The value of your_name is Casey


The value of my_name is Sammy

.‫ثانيا‬
ً ‫ وقد يظهر‬، ‫ أواًل‬Casey ‫ لذلك قد يظهر االسم‬،‫مرتبة‬
َّ ‫قد ال تكون القواميس‬

‫أي ع دد‬
َّ **kwargs ‫افية إلى الدال ة ل نرى كي ف يمكن أن تقب ل‬ ِّ ‫س ُن‬
َّ ‫مرر اآلن وس ائط إض‬

:‫من الوسائط‬

def print_values(**kwargs):
for key, value in kwargs.items():
print("The value of {} is {}".format(key, value))

print_values(
name_1="Alex",
name_2="Gray",
name_3="Harper",
name_4="Phoenix",
name_5="Remy",

▲ | 308
‫البرمجة بلغة بايثون‬ ‫الدوال‪ :‬تعريفها واستعمالها‬

‫"‪name_6="Val‬‬
‫)‬

‫إذا َّ‬
‫نف ذنا البرنامج اآلن‪ ،‬فسنحصل على المخرجات التالية‪ ،‬والتي قد تكون غير مرتبة‪:‬‬

‫‪The value of name_2 is Gray‬‬


‫‪The value of name_6 is Val‬‬
‫‪The value of name_4 is Phoenix‬‬
‫‪The value of name_5 is Remy‬‬
‫‪The value of name_3 is Harper‬‬
‫‪The value of name_1 is Alex‬‬

‫ً‬
‫يرة في اس تخدام الوس ائط المس ماة‪ .‬فعن د‬ ‫ي تيح ل ك اس تخدام ‪ **kwargs‬مرون ًة كب‬

‫استخدامها‪ ،‬لن نحتاج إلى معرفة مسبقة بعدد الوسائط التي ستمرر إلى الدالة‪.‬‬

‫‪ .8‬ترتيب الوسائط‬
‫عند الخلط بين عدة أن واع من الوس ائط داخ ل دال ة‪ ،‬أو داخ ل اس تدعاء دال ة‪ ،‬يجب أن تظه ر‬

‫الوسائط وفق الترتيب التالي‪:‬‬

‫الوسائط العادية‬ ‫•‬

‫‪*args‬‬ ‫•‬

‫الوسائط المسمّ اة‬ ‫•‬

‫‪**kwargs‬‬ ‫•‬

‫عملي ا‪ ،‬عن د الجم ع بين المع امالت العادي ة‪ ،‬والوس يطين ‪ *args‬و ‪ ،**kwargs‬فينبغي أن‬
‫ً‬

‫تكون وفق الترتيب التالي‪:‬‬

‫▲‬ ‫|‬ ‫‪309‬‬


‫البرمجة بلغة بايثون‬ ‫الدوال‪ :‬تعريفها واستعمالها‬

‫‪def example(arg_1, arg_2, *args, **kwargs):‬‬


‫‪...‬‬

‫وعن د الجم ع بين المع امالت العادي ة والمع امالت المس ماة و ‪ *args‬و ‪ ،**kwargs‬ينبغي أن‬

‫تكون وفق الترتيب التالي‪:‬‬

‫‪def example2(arg_1, arg_2, *args, kw_1="shark",‬‬


‫‪kw_2="blobfish", **kwargs):‬‬
‫‪...‬‬

‫من المهم أن تأخ ذ في الحس بان ت رتيب الوس ائط عن د إنش اء ال دوال ح تى ال تتس بب في‬

‫متعلق بالصياغة‪.‬‬
‫ٍ‬ ‫إطالق خطٍأ‬

‫‪ .9‬استخدام ‪ *args‬و ‪ **kwargs‬في استدعاءات الدوال‬


‫أيضا استخدام ‪ *args‬و ‪ **kwargs‬لتمرير الوس ائط إلى ال دوال‪ .‬أواًل ‪ ،‬دعن ا ننظ ر إلى‬
‫ً‬ ‫يمكننا‬

‫مثال يستخدم ‪:*args‬‬

‫‪def some_args(arg_1, arg_2, arg_3):‬‬


‫)‪print("arg_1:", arg_1‬‬
‫)‪print("arg_2:", arg_2‬‬
‫)‪print("arg_3:", arg_3‬‬

‫)"‪args = ("Sammy", "Casey", "Alex‬‬


‫)‪some_args(*args‬‬

‫في الدالة أعاله‪ ،‬هناك ثالثة معامالت‪ ،‬وهي ‪ arg_1‬و _‪ arg‬و ‪ .arg_3‬ستطبع الدالة كل هذه‬

‫الوس ائط‪ .‬بع د ذل ك أنش أنا متغ ي ًرا‪ ،‬وَأ حلن ا علي ه عنص رًا تكراريً ا (في ه ذه الحال ة‪ ،‬ص ف)‪ ،‬ثم مرَّ رن ا‬

‫ذلك المتغير إلى الدالة باستخدام الصياغة النجمية (‪.)asterisk syntax‬‬

‫▲‬ ‫|‬ ‫‪310‬‬


‫البرمجة بلغة بايثون‬ ‫الدوال‪ :‬تعريفها واستعمالها‬

‫‪ ،python‬سنحص ل على‬ ‫عن دما ِّ‬


‫ننفذ البرن امج باس تخدام األم ر ‪some_args.py‬‬

‫المخرجات التالية‪:‬‬

‫‪arg_1: Sammy‬‬
‫‪arg_2: Casey‬‬
‫‪arg_3: Alex‬‬

‫ً‬
‫أيض ا ‪ *args‬م ع‬ ‫ً‬
‫أيض ا تع ديل البرن امج أعاله‪ ،‬واس تخدام قائم ة‪ .‬س ندمج‬ ‫يمكنن ا‬

‫وسيط مسمى‪:‬‬

‫‪def some_args(arg_1, arg_2, arg_3):‬‬


‫)‪print("arg_1:", arg_1‬‬
‫)‪print("arg_2:", arg_2‬‬
‫)‪print("arg_3:", arg_3‬‬

‫]‪my_list = [2, 3‬‬


‫)‪some_args(1, *my_list‬‬

‫إذا َّ‬
‫نفذنا البرنامج أعاله‪ ،‬فسنحصل على المخرجات التالية‪:‬‬

‫‪arg_1: 1‬‬
‫‪arg_2: 2‬‬
‫‪arg_3: 3‬‬

‫وبالمثل‪ ،‬يمكن استخدام الوسائط المسماة ‪ **kwargs‬الستدعاء دالة‪.‬‬

‫قاموس ا من ‪ 3‬أزواج مفت اح‪-‬قيم ة (سنس تخدم ‪ kwargs‬هن ا‪،‬‬


‫ً‬ ‫سننش ئ متغ يرًا‪ ،‬ونس ند إلي ه‬

‫مرره إلى دالة ذات ‪ 3‬وسائط‪:‬‬


‫ولكن يمكنك تسميته ما تشاء)‪ ،‬ثم ُن ِّ‬

‫▲‬ ‫|‬ ‫‪311‬‬


‫البرمجة بلغة بايثون‬ ‫الدوال‪ :‬تعريفها واستعمالها‬

‫‪def some_kwargs(kwarg_1, kwarg_2, kwarg_3):‬‬


‫)‪print("kwarg_1:", kwarg_1‬‬
‫)‪print("kwarg_2:", kwarg_2‬‬
‫)‪print("kwarg_3:", kwarg_3‬‬

‫‪kwargs = {"kwarg_1": "Val", "kwarg_2": "Harper", "kwarg_3":‬‬


‫}"‪"Remy‬‬
‫)‪some_kwargs(**kwargs‬‬

‫عن د تنفي ذ البرن امج أعاله باس تخدام األم ر ‪ ،python some_kwargs.py‬سنحص ل على‬

‫المخرجات التالية‪:‬‬

‫‪kwarg_1: Val‬‬
‫‪kwarg_2: Harper‬‬
‫‪kwarg_3: Remy‬‬

‫‪ .10‬خالصة الفصل‬
‫معين ة داخ ل البرن امج‪ ،‬كم ا‬
‫َّ‬ ‫ال دوال هي كت ل من التعليم ات البرمجي ة ال تي ُت ِّ‬
‫نفذ إج راءات‬

‫تس اعد على جع ل الش يفرة تركيبي ة‪ ،‬وقابل ة إلع ادة االس تخدام باإلض افة إلى تنظيمه ا وتس هيل‬

‫قراءتها‪( .‬لمعرفة المزيد حول كيفية جعل الشفرة تركيبية‪ ،‬يمكنك الرجوع إلى فصل الوحدات‪).‬‬

‫يمكنك اس تخدام الص ياغتين ‪ *args‬و ‪ **kwargs‬الخاص تين ض من َتع اريف وس ائط ال دوال‬

‫أي عدد تشاء من الوسائط إليها‪ ،‬إذ يُ ستحس ن اس تخدام ‪ *args‬و ‪ **kwargs‬في المواق ف‬
‫لتمرير ِّ‬

‫بيا‪ .‬وض ع في ذهن ك أن‬


‫ال تي تتوق ع أن يظ ل فيه ا ع دد الم دخالت في قائم ة الوس ائط ص غي ًرا نس ً‬

‫يحس ن مقروئي ة الش يفرة‪ ،‬ويس ِّهل على الم برمجين‪ ،‬ولكن ينبغي‬
‫ِّ‬ ‫اس تخدام ‪ *args‬و ‪**kwargs‬‬

‫استخدامهما بحذر‪.‬‬

‫▲‬ ‫|‬ ‫‪312‬‬


‫‪17‬‬
‫الوحدات‪ :‬استيرادها‬
‫وإنشاؤها‬

‫▲‬ ‫|‬ ‫‪313‬‬


‫البرمجة بلغة بايثون‬ ‫الوحدات‪ :‬استيرادها وإنشاؤها‬

‫توفر لغة بايثون مجموعة متنوعة من الدوال المضمَّ نة مثل‪:‬‬

‫)(‪ :print‬تطبع التعابير المُ مرَّ رة إليها في مجرى الخرج‬ ‫•‬

‫)(‪ُ :abs‬تعيد القيمة المطلقة للعدد‬ ‫•‬

‫ِّ‬
‫تحول القيمة المُ مرَّ رة إليها إلى عدد صحيح‬ ‫)(‪:int‬‬ ‫•‬

‫)(‪ُ :len‬تعيد طول تسلسل أو مجموعة‬ ‫•‬

‫هذه الدوال المضمَّ نة مفيدة‪ ،‬لكنها محدودة‪ ،‬له ذا يس تخدم المط ورون الوح دات (‪)modules‬‬

‫لتط وير ب رامج أك ثر تعقي ًدا‪ .‬الوح دات (‪ )Modules‬هي ملف ات ب ايثون ذات امت داد ‪ ،.py‬وال تي‬

‫أي ملف بايثون على أنه وحدة‪ .‬مثاًل ‪ ،‬إن ك ان هن اك مل ف‬


‫تحوي شيفرات بايثون‪ .‬يمكن التعامل مع ِّ‬

‫ب ايثون يس مى ‪ ،hello.py‬فس يكون اس م الوح دة المقابل ة ل ه ‪ ،hello‬وال ذي يمكن اس تيراده في‬

‫ملفات بايثون األخرى‪ ،‬أو استخدامه في مترجم (‪ )interpreter‬سطر أوامر بايثون‪.‬‬

‫يمكن للوح دات أن تع ِّرف دوااًل وأص ً‬


‫نافا ومتغ يرات يمكن الرج وع إليه ا من ملف ات ب ايثون‬

‫األخرى‪ ،‬أو من مترجم سطر أوامر بايثون‪.‬‬

‫في ب ايثون‪ ،‬يمكن ك الوص ول إلى الوح دات باس تخدام التعليم ة ‪ .import‬عن د فع ل ذل ك‪،‬‬

‫س ُت َّ‬
‫نفذ ش يفرة الوح دة‪ ،‬م ع االحتف اظ بنطاق ات ( ‪ )scopes‬التعريف ات ح تى تك ون متاح ة في‬

‫ملفك الحالي‪ .‬فعندما تس تورد ب ايثون وح ً‬


‫دة باس م ‪ hello‬على س بيل المث ال‪ ،‬فس يبحث الم ترجم‬

‫أواًل عن وحدة مضمَّ نة باسم ‪ .hello‬فإن لم يجد‪ ،‬فسيبحث عن ملف يسمى ‪ hello.py‬في قائمة‬

‫من المجلدات يحددها المتغير ‪.sys.path‬‬

‫سيرشدك هذا الفصل إلى كيفية البحث عن الوحدات وتثبيتها‪ ،‬واستيرادها‪ ،‬وإع ادة تس ميتها‬

‫(‪ ،)aliasing‬ثم سيعلمك كيفية إنشاء وحدة كاملة واستعمالها في شيفرة أخرى‪.‬‬

‫▲‬ ‫|‬ ‫‪314‬‬


‫البرمجة بلغة بايثون‬ ‫الوحدات‪ :‬استيرادها وإنشاؤها‬

‫‪ .1‬تثبيت الوحدات‬
‫هن اك ع دد من الوح دات المض مَّ نة في مكتب ة ب ايثون القياس ية ال تي تحت وي على العدي د من‬

‫الوح دات ال تي ت وفر الكث ير من وظ ائف النظ ام‪ ،‬أو ت وفر حل واًل قياس ية‪ .‬مكتب ة ب ايثون القياس ية‬

‫تأتي مع كل توزيعات بايثون‪.‬‬

‫أن وح دات ب ايثون ج اهزة للعم ل‪ ،‬ادخ ل إلى بيئ ة برمج ة ب ايثون ‪ 3‬المحلي ة‪ ،‬أو‬
‫للتحق ق من َّ‬

‫ِّ‬
‫وشغل مترجم بايثون في سطر األوامر على النحو التالي‪:‬‬ ‫بيئة البرمجة المستندة إلى الخادم‪،‬‬

‫‪(my_env) sammy@ubuntu:~/environment$ python‬‬

‫من داخل المترجم‪ ،‬يمكنك تنفيذ التعليمة ‪ import‬مع اسم الوحدة للتأكد من َّ‬
‫أنها جاهزة‪:‬‬

‫‪import math‬‬

‫لمَّ ا ك انت ‪ math‬وح دة مض مَّ نة‪ ،‬فينبغي أن يُ كم ل الم ترجم المهم ة دون أي مش اكل‪ ،‬ثم يع ود‬

‫أي ش يء للب دء في اس تخدام‬ ‫إلى المحث (‪ .)prompt‬ه ذا يع ني َّ‬


‫أنك لس ت بحاج ة إلى فع ل ِّ‬

‫الوحدة ‪.math‬‬

‫ِّ‬
‫لننفذ اآلن التعليم ة ‪ import‬م ع وح دة ق د ال تك ون مُ َّ‬
‫ثبت ة عن دك‪ ،‬مث ل ‪ ،matplotlib‬وهي‬

‫مكتبة للرسم ثنائي األبعاد‪:‬‬

‫‪import matplotlib‬‬

‫ٌأ‬
‫إذا لم تكن ‪ matplotlib‬مُ َّ‬
‫ثبتة‪ ،‬فسيظهر خط مثل الخطأ التالي‪:‬‬

‫'‪ImportError: No module named 'matplotlib‬‬

‫يمكنك إيقاف مترجم بايثون بالضغط على ‪ ،CTRL + D‬ثم تثبيت الوحدة ‪ matplotlib‬عبر‬

‫▲‬ ‫|‬ ‫‪315‬‬


‫البرمجة بلغة بايثون‬ ‫الوحدات‪ :‬استيرادها وإنشاؤها‬

‫‪ pip‬بتنفيذ األمر التالي‪:‬‬

‫‪(my_env) sammy@ubuntu:~/environment$ pip install matplotlib‬‬

‫بمج رد تثبيته ا‪ ،‬يمكن ك اس تيراد ‪ matplotlib‬من م ترجم ب ايثون باس تخدام‬

‫‪ ،import matplotlib‬ولن يحدث أي خطأ‪.‬‬

‫‪ .2‬استيراد الوحدات‬
‫لالس تفادة من ال دوال الموج ودة في الوح دة‪ ،‬س تحتاج إلى اس تيراد الوح دة ع بر التعليم ة‬

‫‪ ،import‬إذ تتألف من الكلمة المفتاحية ‪ import‬معقوبة باسم الوحدة كما في المثال اآلتي‪.‬‬

‫يُ ص رَّ ح عن عملي ة اس تيراد الوح دات في أعلى ملف ات ب ايثون‪ ،‬قب ل األس طر التوجيهي ة‬

‫(‪ shebang lines‬أي األس طر ال تي تب دأ بـ !‪ ،)#‬أو التعليق ات العام ة‪ .‬ل ذلك‪ ،‬سنس تورد في مل ف‬

‫برنامج بايثون ‪ my_rand_int.py‬الوحدة ‪ random‬لتوليد أعداد عشوائية على النحو التالي‪:‬‬

‫‪import random‬‬

‫عن دما نس تورد وح دة‪ ،‬نجعله ا ب ذلك متاح ة في برنامجن ا الح الي بوص فها فض اء اس م‬

‫يتعين علين ا الوص ول إلى الدال ة باس تخدام الص ياغة النقطي ة‬
‫َّ‬ ‫(‪ )namespace‬منفص ل‪ .‬أي س‬

‫(‪ )dot notation‬على النحو التالي ]‪.[module].[function‬‬

‫عمليا‪ ،‬ستبدو الشيفرة باستخدام مثال الوحدة ‪ random‬كما يلي‪:‬‬


‫ً‬

‫)(‪ :random.randint‬تستدعي الدالة إلعادة عدد صحيح عشوائي‪ ،‬أو‬ ‫•‬

‫)(‪ :random.randrange‬تستدعي الدالة إلعادة عنصر عشوائي من نطاق محدد‪.‬‬ ‫•‬

‫دعن ا ننش ئ حلق ة ‪ for‬لتوض يح كيفي ة اس تدعاء دال ة من الوح دة ‪ random‬ض من‬

‫▲‬ ‫|‬ ‫‪316‬‬


‫البرمجة بلغة بايثون‬ ‫الوحدات‪ :‬استيرادها وإنشاؤها‬

‫البرنامج ‪:my_rand_int.py‬‬

‫‪import random‬‬

‫‪for i in range(10):‬‬
‫))‪print(random.randint(1, 25‬‬

‫يس تورد ه ذا البرن امج الص غير الوح دة ‪ random‬في الس طر األول‪ ،‬ثم ينتق ل إلى الحلق ة ‪for‬‬

‫وائيا من المج ال ‪1‬‬


‫ً‬ ‫ً‬
‫حيحا عش‬ ‫التي ستمر على ‪ 10‬عناص ر‪ .‬داخ ل الحلق ة‪ ،‬س يطبع البرن امج ع د ًدا ص‬

‫امالت‬ ‫فهما مع‬ ‫حيحان ‪ 1‬و ‪ 25‬بوص‬ ‫ددان الص‬ ‫رّّ ر الع‬ ‫مول)‪ .‬يُ م‬ ‫إلى ‪( 25‬مش‬

‫إلى )(‪.random.randint‬‬

‫عن د تنفي ذ البرن امج باس تخدام األم ر ‪ ،python my_rand_int.py‬س تظهر ‪ 10‬أع داد‬

‫ألن ه ذه العناص ر عش وائية‪ ،‬فستحص ل على األرجح على‬


‫صحيحة عشوائية في المخرج ات‪ .‬نظ رًا َّ‬

‫أعداد مختلفة ( كلها محصورة بين ‪ 1‬و ‪ )25‬في كل مرة ِّ‬


‫تنفذ فيه ا البرن امج‪ ،‬لكنَّه ا عمومً ا س تبدو‬

‫كما يلي‪:‬‬

‫‪6‬‬
‫‪9‬‬
‫‪1‬‬
‫‪14‬‬
‫‪3‬‬
‫‪22‬‬
‫‪10‬‬
‫‪1‬‬
‫‪15‬‬
‫‪9‬‬

‫▲‬ ‫|‬ ‫‪317‬‬


‫البرمجة بلغة بايثون‬ ‫الوحدات‪ :‬استيرادها وإنشاؤها‬

‫إذا رغبت في اس تخدام دوال من أك ثر من وح دة‪ ،‬يمكن ك ذل ك عن طري ق إض افة ع دة‬

‫تعليمات استيراد‪:‬‬

‫‪import random‬‬
‫‪import math‬‬

‫قد تصادف شيفرات تستورد عدة وحدات مفصولة بفواصل مثل ‪import random, math‬‬

‫ولكن هذا ال يتوافق مع دليل التنسيق ‪.PEP 8‬‬


‫َّ‬

‫افية‪ ،‬يمكنن ا إض افة الث ابت ‪ pi‬من الوح دة ‪ math‬إلى برنامجن ا‪،‬‬
‫لالس تفادة من الوح دة اإلض َّ‬

‫وتقليل عدد األعداد الصحيحة العشوائية المطبوعة‪:‬‬

‫‪import random‬‬
‫‪import math‬‬

‫‪for i in range(5):‬‬
‫))‪print(random.randint(1, 25‬‬

‫)‪print(math.pi‬‬

‫اآلن‪ ،‬عن د تنفي ذ البرن امج‪ ،‬سنحص ل على مخرج ات على الش كل الت الي‪ ،‬م ع تق ريب للع دد ‪pi‬‬

‫في السطر األخير‪:‬‬

‫‪18‬‬
‫‪10‬‬
‫‪7‬‬
‫‪13‬‬
‫‪10‬‬
‫‪3.141592653589793‬‬

‫▲‬ ‫|‬ ‫‪318‬‬


‫البرمجة بلغة بايثون‬ ‫الوحدات‪ :‬استيرادها وإنشاؤها‬

‫ِّ‬
‫يمكن ك من‬ ‫ت تيح ل ك التعليم ة ‪ import‬اس تيراد وح دة واح دة أو أك ثر إلى برامج ك‪ ،‬وه ذا‬

‫االستفادة مما تحويها تلك الوحدات‪.‬‬

‫محددة‬
‫َّ‬ ‫‪ .3‬استيراد عناصر‬
‫لإلش ارة إلى عناص ر من وح دة مس توردة ض من فض اء األس ماء‪ ،‬يمكن ك اس تخدام التعليم ة‬

‫‪ .from ... import‬عن دما تس تورد الوح دات به ذه الطريق ة‪ ،‬س يكون بمق دورك الرج وع إلى‬

‫ال دوال بأس مائها فق ط‪ ،‬ب داًل من اس تخدام الص ياغة النقطي ة‪ .‬في ه ذه الص ياغة‪ ،‬يمكن ك تحدي د‬

‫التعريفات التي تود اإلشارة إليها مباشرة‪.‬‬

‫في بعض ال برامج‪ ،‬ق د ت رى العب ارة * ‪ ،from ... import‬إذ تش ير العالم ة * إلى جمي ع‬

‫ولكن هذه الصياغة غير معتمدة في ‪.PEP 8‬‬


‫ّ‬ ‫العناصر الموجودة في الوحدة‪،‬‬

‫سنحاول في البداية استيراد دالة واحدة من الوحدة ‪ ،random‬وهي )(‪:randint‬‬

‫‪from random import randint‬‬

‫هنا‪ ،‬نستدعي أواًل الكلمة المفتاحية ‪ ،from‬ثم ‪ .random‬بعد ذلك‪ ،‬نس تخدم الكلم ة المفتاحي ة‬

‫‪ ،import‬ونستدعي الدالة المحددة التي نو ُّد استخدامها‪.‬‬

‫اآلن‪ ،‬عندما نرغب في اس تخدام ه ذه الدال ة في برنامجن ا‪ ،‬لن نس تدعي الدال ة وف ق الص ياغة‬

‫ً‬
‫مباشرة‪ ،‬أي )(‪:randint‬‬ ‫النقطية‪ ،random.randint() ،‬ولكن سنستدعيها باسمها‬

‫‪from random import randint‬‬

‫‪for i in range(10):‬‬
‫))‪print(randint(1, 25‬‬

‫▲‬ ‫|‬ ‫‪319‬‬


‫البرمجة بلغة بايثون‬ ‫الوحدات‪ :‬استيرادها وإنشاؤها‬

‫ً‬
‫مسبقا‪.‬‬ ‫عند تنفيذ البرنامج‪ ،‬ستتلقى مخرجات مشابهة لما تلقيته‬

‫يتيح لنا استخدام ‪ from ... import‬الرجوع إلى العناصر المعرَّ فة في الوح دة من فض اء‬

‫األسماء الخاص ببرنامجنا‪ ،‬مما يتيح لنا تجنب استخدام الصياغة النقطية الطويلة‪.‬‬

‫‪ .4‬األسماء المستعارة في الوحدات‬


‫يمكن إعط اء أس ماء مس تعارة للوح دات ودواله ا داخ ل ب ايثون باس تخدام الكلم ة‬

‫المفتاحية ‪.as‬‬

‫أنه مس تخدم في وح دة‬ ‫ألنك تس تخدمه س ً‬


‫لفا في برنامج ك‪ ،‬أو َّ‬ ‫قد ترغب في تغي ير اس م م ا َّ‬

‫أخ رى مس توردة‪ ،‬أو ق د ت رغب في اختص ار اس م طوي ل تس تخدمه كث يرًا‪ .‬يمكن ك ذل ك ع بر‬

‫الصياغة التالية‪:‬‬

‫]‪import [module] as [another_name‬‬

‫نغير اس م الوح دة ‪ math‬إلى ‪m‬‬ ‫ِّ‬


‫لنعدل اسم الوحدة ‪ math‬في ملف البرن امج ‪ .my_math.py‬س ّ‬

‫من أجل اختصاره‪ .‬سيبدو برنامجنا المعدل كالتالي‪:‬‬

‫‪import math as m‬‬

‫)‪print(m.pi‬‬
‫)‪print(m.e‬‬

‫سنشير داخل البرنامج إلى الثابت ‪ pi‬بالتعبير ‪ ،m.pi‬بداًل من ‪.math.pi‬‬

‫يشيع في بعض الوحدات استخدام أسماء مستعارة ( ‪ )aliases‬مح َّددة‪ .‬فمثاًل ‪ ،‬يدعو التوثيق‬

‫الرسمي للوحدة ‪ matplotlib.pyplot‬إلى استخدام االسم المستعار ‪:plt‬‬

‫▲‬ ‫|‬ ‫‪320‬‬


‫البرمجة بلغة بايثون‬ ‫الوحدات‪ :‬استيرادها وإنشاؤها‬

‫‪import matplotlib.pyplot as plt‬‬

‫يس مح ه ذا للم برمجين بإلح اق الكلم ة القص يرة ‪ plt‬ب أي دال ة متاح ة داخ ل الوح دة‪ ،‬كم ا ه و‬

‫الحال في )(‪.plt.show‬‬

‫مخصصة واستيرادها‬
‫َّ‬ ‫‪ .5‬كتابة وحدات‬
‫س نتعلم اآلن كتاب ة وح دات ب ايثون ‪ -‬بع د تعلم كيفي ة اس تيرادها ‪ -‬الس تخدامها في ملف ات‬

‫البرمجة األخرى‪.‬‬

‫كتابة الوحدات مشابه لكتابة أي ملف بايثون آخ ر‪ .‬يمكن أن تحت وي الوح دات على تعريف ات‬

‫الدوال واألصناف والمتغيِّ رات التي يمكن استخدامها بعد ذلك في برامج بايثون األخرى‪.‬‬

‫سننشئ من بيئة البرمج ة الحالي ة الخاص ة بب ايثون ‪ 3‬أو بيئ ة البرمج ة المس تندة إلى الخ ادم‬

‫ً‬
‫الحقا من ملف آخر‪.‬‬ ‫ًّ‬
‫ملفا باسم ‪ ،hello.py‬والذي سنستورده‬

‫في البدء‪ ،‬سننشئ دالة تطبع العبارة "!‪:"Hello, world‬‬

‫تعريف دالة ‪#‬‬


‫‪def world():‬‬
‫)"!‪print("Hello, world‬‬

‫إذا َّ‬
‫نفذنا البرنامج في سطر األوامر باستخدام ‪ ،python hello.py‬فلن يح دث ش يء‪َّ ،‬‬
‫ألنن ا‬

‫لم نطلب من البرنامج فعل أي شيء‪.‬‬

‫ثاني ا في نفس المجلد (أي بج انب المل ف الس ابق) باس م ‪main_program.py‬‬
‫ً‬ ‫لننش ئ ً‬
‫ملف ا‬

‫حتى نتمكن من استيراد الوحدة التي أنشأناها للت و‪ ،‬ومن ثم اس تدعاء الدال ة‪ .‬يجب أن يك ون ه ذا‬

‫المل ف في نفس المجل د ح تى تع رف ب ايثون موض ع الوح دة‪َّ ،‬‬


‫ألنه ا ليس ت وح دة مُ ض مَّ نة ض من‬

‫مكتبة بايثون‪.‬‬

‫▲‬ ‫|‬ ‫‪321‬‬


‫البرمجة بلغة بايثون‬ ‫الوحدات‪ :‬استيرادها وإنشاؤها‬

‫استيراد الوحدة ‪# hello‬‬


‫‪import hello‬‬

‫استدعاء الدالة ‪#‬‬


‫)(‪hello.world‬‬

‫نظرً ا ألننا اس توردنا الوح دة‪ ،‬نحت اج إلى اس تدعاء الدال ة من خالل اإلش ارة إلى اس م الوح دة‬

‫بالص ياغة النقطي ة (‪ .)dot notation‬يمكنن ا ب داًل من ذل ك اس تيراد دال ة مح َّددة من الوح دة‬

‫بالتعليمة ‪ ،from hello import world‬واستدعاء تلك الدالة بالشكل )(‪ world‬كما تعلمنا ذلك‬

‫من الفصل السابق‪ .‬اآلن‪ ،‬يمكننا تنفيذ البرنامج من سطر األوامر‪:‬‬

‫‪python main_program.py‬‬

‫سنحصل على المخرجات التالية‪:‬‬

‫!‪Hello, world‬‬

‫ً‬
‫تعريف ا لمتغيِّ ر في‬ ‫ل نرى كي ف يمكنن ا اس تخدام المتغ يرات في الوح دات‪ ،‬دعن ا نض يف‬

‫الملف ‪:hello.py‬‬

‫تعريف دالة ‪#‬‬


‫‪def world():‬‬
‫)"!‪print("Hello, world‬‬

‫تعريف المتغير ‪#‬‬


‫"‪shark = "Sammy‬‬

‫بعد ذلك‪ ،‬سنستدعي المتغير داخل الدالة )(‪ print‬في الملف ‪:main_program.py‬‬

‫▲‬ ‫|‬ ‫‪322‬‬


‫البرمجة بلغة بايثون‬ ‫ استيرادها وإنشاؤها‬:‫الوحدات‬

# hello ‫استيراد الوحدة‬


import hello

# ‫استدعاء الدالة‬
hello.world()

# ‫طباعة المتغير‬
print(hello.shark)

:‫ سنحصل على المخرجات التالية‬،‫بمجرد تنفيذ البرنامج‬

Hello, world!
Sammy

ً ‫ دعن ا نع ِّرف ص‬،‫أخ ي ًرا‬


‫ وال ذي يحت وي‬،Octopus ‫ سننش ئ الص نف‬.hello.py ‫نفا في المل ف‬

:‫ إضافة إلى دالة تطبع الخاصيات عند استدعائها‬،color ‫ و‬name ‫على الخاصيتين‬

# ‫تعريف الدالة‬
def world():
print("Hello, world!")

# ‫تعريف المتغير‬
shark = "Sammy"
# ‫تعريف الصنف‬
class Octopus:
def __init__(self, name, color):
self.color = color
self.name = name

def tell_me_about_the_octopus(self):
print("This octopus is " + self.color + ".")
print(self.name + " is the octopus's name.")

▲ | 323
‫البرمجة بلغة بايثون‬ ‫الوحدات‪ :‬استيرادها وإنشاؤها‬

‫َ‬
‫الصنف إلى نهاية الملف ‪:main_program.py‬‬ ‫سنضيف اآلن‬

‫استيراد الوحدة ‪# hello‬‬


‫‪import hello‬‬

‫استدعاء الدالة ‪#‬‬


‫)(‪hello.world‬‬

‫طباعة المتغير ‪#‬‬


‫)‪print(hello.shark‬‬

‫استدعاء الصنف ‪#‬‬


‫)"‪jesse = hello.Octopus("Jesse", "orange‬‬
‫)(‪jesse.tell_me_about_the_octopus‬‬

‫بمج رد اس تدعاء الص نف ‪ Octopus‬باس تخدام )(‪ ،hello.Octopus‬يمكنن ا الوص ول إلى‬

‫دوال وخاص يات الص نف من فض اء األس ماء الخ اص ب الملف ‪ .main_program.py‬ي تيح لن ا ه ذا‬

‫كتاب ة )(‪ jesse.tell_me_about_the_octopus‬في الس طر األخ ير دون اس تدعاء ‪.hello‬‬

‫ً‬
‫أيض ا‪ ،‬على س بيل المث ال‪ ،‬اس تدعاء إح دى خاص يات الص نف‪ ،‬مث ل ‪ ،jesse.color‬دون‬ ‫يمكنن ا‬

‫الرجوع إلى اسم الوحدة ‪.hello‬‬

‫سنحصل عند تنفيذ البرنامج التالي على المخرجات التالية‪:‬‬

‫!‪Hello, world‬‬
‫‪Sammy‬‬
‫‪This octopus is orange.‬‬
‫‪Jesse is the octopus's name.‬‬

‫ً‬
‫أيض ا أن‬ ‫من المهم أن تضع في الحسبان أن الوح دات ال تض م تعريف ات دوال فق ط‪ ،‬ب ل يمكن‬

‫▲‬ ‫|‬ ‫‪324‬‬


‫البرمجة بلغة بايثون‬ ‫الوحدات‪ :‬استيرادها وإنشاؤها‬

‫ِّ‬
‫وتنفذها‪ .‬لتوض يح ه ذا‪ ،‬دعن ا نعي د كتاب ة المل ف ‪ hello.py‬لنجعل ه يق دم‬ ‫تق دم ش يفرات برمجي ة‬

‫ً‬
‫أيضا‪:‬‬ ‫الدالة )(‪ world‬وينفذها‬

‫تعريف دالة ‪#‬‬


‫‪def world():‬‬
‫)"!‪print("Hello, world‬‬

‫استدعاء الدالة داخل الوحدة ‪#‬‬


‫)(‪world‬‬

‫ً‬
‫أيض ا التعريف ات األخ رى في المل ف‪ .‬اآلن‪ ،‬في المل ف ‪،main_program.py‬‬ ‫لق د ح ذفنا‬

‫سنحذف كل األسطر باستثناء عبارة االستيراد‪:‬‬

‫استيراد الوحدة ‪# hello‬‬


‫‪import hello‬‬

‫عند تنفيذ ‪ ،main_program.py‬سنحصل على المخرجات التالية‪:‬‬

‫!‪Hello, world‬‬

‫ألن الوح دة ‪ hello‬ق دمت الدال ة )(‪ ،world‬وال تي مُ ِّررت بع د ذل ك إلى‬


‫ه ذا َّ‬

‫لت َّ‬
‫نفذ مع السكربت ‪.main_program.py‬‬ ‫‪ُ main_program.py‬‬

‫الوح دة هي مل ف ب ايثون مؤل ف من تعريف ات و ش يفرات برمجي ة يمكن االس تفادة منه ا في‬

‫ملفات بايثون األخرى‪.‬‬

‫‪ .6‬الوصول إلى الوحدات من مجلد آخر‬


‫ق د تك ون الوح دات مفي دة ألك ثر من مش روع واح د‪ ،‬وفي ه ذه الحال ة‪ ،‬لن يك ون من الحكم ة‬

‫االحتفاظ بالوحدة في مجلد مرتبط بمشروع خاص‪.‬‬

‫▲‬ ‫|‬ ‫‪325‬‬


‫البرمجة بلغة بايثون‬ ‫الوحدات‪ :‬استيرادها وإنشاؤها‬

‫إذا أردت استخدام وحدة من مجلد آخر غير المجلد الذي يح وي البرن امج الرئيس ي‪ ،‬فأمام ك‬

‫ع َّدة خيارات سنسردها فيما يلي‪.‬‬

‫تلقائيا على مسار الوحدة‬


‫ً‬ ‫ا‪ .‬التعرف‬

‫أحد الخيارات هو استدعاء مسار الوحدة من الملفات البرمجية ال تي تس تخدم تل ك الوح دة‪.‬‬

‫يُ ع د ه ذا حاًّل مؤق ًت ا يمكن اس تخدامه أثن اء عملي ة التط وير‪َّ ،‬‬
‫ألنه ال يجع ل الوح دة متاح ة على‬

‫مستوى النظام بأكمله‪ .‬إللح اق مس ار وح دة بمل ف ب رمجي آخ ر‪ ،‬س تبدأ باس تيراد الوح دة ‪ ،sys‬إلى‬

‫جانب الوحدات األخرى التي ترغب في استخدامها في ملف البرنامج الرئيسي‪.‬‬

‫زءا من مكتب ة ب ايثون القياس ية‪ ،‬وت وفر مع امالت ودوال نظامي ة يمكن ك‬
‫تعد الوح دة ‪ sys‬ج ً‬

‫استخدامها في برنامجك لتع يين مس ار الوح دة ال تي ت رغب في تق ديمها‪ .‬على س بيل المث ال‪ ،‬لنق ل‬

‫َّ‬
‫أنن ا نقلن ا المل ف ‪ hello.py‬إلى المس ار ‪ ،/usr/sammy/‬بينم ا يوج د المل ف ‪main_program.py‬‬

‫في مجل د آخ ر‪ .‬في المل ف ‪ ،main_program.py‬م ا ي زال بإمكانن ا اس تيراد الوح دة ‪ hello‬عن‬

‫طري ق اس تيراد الوح دة ‪ ،sys‬ثم إض افة المس ار ‪ /usr/sammy/‬إلى المس ارات ال تي يبحث ب ايثون‬

‫فيها عن الملفات‪.‬‬

‫‪import sys‬‬
‫)'‪sys.path.append('/usr/sammy/‬‬
‫‪import hello‬‬
‫‪...‬‬

‫عينت مس ار المل ف ‪ hello.py‬كم ا يجب‪ ،‬فس يكون بمق دورك تنفي ذ المل ف‬
‫إن َّ‬

‫أي أخط اء‪ ،‬وستحص ل على نفس المخرج ات ال تي حص لنا عليه ا أعاله‬
‫‪ main_program.py‬دون ِّ‬

‫عندما كان الملف ‪ hello.py‬في نفس المجلد‪.‬‬

‫▲‬ ‫|‬ ‫‪326‬‬


‫البرمجة بلغة بايثون‬ ‫الوحدات‪ :‬استيرادها وإنشاؤها‬

‫ب‪ .‬إضافة الوحدة إلى مسار بايثون‬

‫الخيار الث اني ه و إض افة الوح دة إلى المس ار ال ذي يبحث في ه ب ايثون عن الوح دات والح زم‪،‬‬

‫ً‬
‫متاحة على نطاق البيئة‪ ،‬أو على مستوى النظام‪.‬‬ ‫وهذا حل أفضل وأدوم‪ ،‬إذ يجعل الوحدة‬

‫لمعرف ة المس ار ال ذي يبحث في ه ب ايثون‪ ،‬ش ِّغل م ترجم (‪ )interpreter‬ب ايثون من بيئ ة‬

‫البرمجة خاصتك‪:‬‬

‫‪python‬‬

‫بعد ذلك‪ ،‬استورد الوحدة ‪:sys‬‬

‫‪import sys‬‬

‫ثم اطلب من بايثون طباعة مسار النظام‪:‬‬

‫)‪print(sys.path‬‬

‫ستحص ل على بعض المخرج ات‪ ،‬وس ُيطبع مس ار نظ ام واح د على األق ل‪ .‬إذا كنت تعم ل في‬

‫بيئة برمجة‪ ،‬فقد تتلقى العديد منها‪ .‬سيكون عليك البحث عن المسارات الموجودة في البيئة التي‬

‫ً‬
‫أيض ا في إض افة الوح دة إلى مس ار النظ ام الرئيس ي لب ايثون‪.‬‬ ‫حالي ا‪ ،‬ولكن ق د ت رغب‬
‫ً‬ ‫تس تخدمها‬

‫النتيجة ستكون مشابهة لما يلي‪:‬‬

‫'‪'/usr/sammy/my_env/lib/python3.5/site-packages‬‬

‫يمكنك اآلن نقل الملف ‪ hello.py‬إلى هذا المجلد‪ .‬بعد ذلك‪ ،‬يمكنك استيراد الوح دة ‪hello‬‬

‫مثل المعتاد‪:‬‬

‫‪import hello‬‬
‫‪...‬‬

‫▲‬ ‫|‬ ‫‪327‬‬


‫البرمجة بلغة بايثون‬ ‫الوحدات‪ :‬استيرادها وإنشاؤها‬

‫عن د تنفي ذ البرن امج الس ابق‪ ،‬يُ ف ترض أال يح دث ّ‬


‫أي خط أ‪ .‬يض من ل ك تع ديل مس ار الوح دة‬

‫إمكانية الوصول إليها مهم ا ك ان المجل د ال ذي تعم ل في ه‪ ،‬إذ ه ذا مفي د خاص ة في ح ال كنت تعم ل‬

‫على عدة مشاريع تشير إلى الوحدة نفسها‪.‬‬

‫‪ .7‬خالصة الفصل‬
‫يس مح مفه وم الوح دات باس تدعاء دوال غ ير مض مَّ نة في ب ايثون‪ .‬فبعض الوح دات مُ َّ‬
‫ثبت ة‬

‫نثبتها ع بر ‪ ،pip‬وي تيح لن ا اس تخدام الوح دات توس يع برامجن ا‬


‫كج زء من ب ايثون‪ ،‬وبعض ها س ّ‬

‫وت دعيمها‪ ،‬إذ تض ع تحت تص رُّ فنا ش فرات ج اهزة لالس تخدام‪ ،‬فيمكنن ا إنش اء وح دات خاص ة بن ا‪،‬‬

‫لنستخدمها نحن‪ ،‬أو المبرمجون اآلخرون‪.‬‬

‫▲‬ ‫|‬ ‫‪328‬‬


‫‪18‬‬
‫بناء األصناف‬
‫واستنساخ الكائنات‬

‫▲‬ ‫|‬ ‫‪329‬‬


‫البرمجة بلغة بايثون‬ ‫بناء األصناف واستنساخ الكائنات‬

‫ب ايثون لغ ٌة برمج ة كائني ة ( ‪ .)object-oriented programming language‬ف ِّ‬


‫تركز البرمج ة‬

‫الكائني ة (‪ )OOP‬على كتاب ة ش يفرات قابل ة إلع ادة االس تخدام‪ ،‬على عكس البرمج ة اإلجرائي ة‬

‫(‪ )procedural programming‬التي تركز على كتابة تعليمات صريحة ومتسلسلة‪.‬‬

‫تتيح البرمجة الكائنية لمبرمجي بايثون كتابة ش يفرات س هلة الق راءة والص يانة‪ ،‬وه ذا مفي د‬

‫للغاية عند تطوير البرامج المُ َّ‬


‫عقدة‪.‬‬

‫التمي يز بين األص ناف والكائن ات أح ُد المف اهيم األساس ية في البرمج ة الكائني ة‪ ،‬ويوض ح‬

‫التعريفان التاليان الفرق بين المفهومين‪:‬‬

‫فيع ِّرف الص نف‬ ‫الصنف (‪ :)class‬نموذج ع ام ُتنس ج على منوال ه كائن ات يُ ِ‬
‫نش ئها الم برمج‪ُ .‬‬ ‫•‬
‫ستنسخ (‪ )instantiated‬منه‪.‬‬
‫َ‬ ‫ً‬
‫مجموعة من الخاصيات التي تميز أي كائن يُ‬

‫الك ائن (‪ :)object‬نس ٌ‬


‫خة (‪ُ )instance‬تش تق من ص نف‪ ،‬فه و تجس يد عملي للص نف داخ ل‬ ‫•‬
‫البرنامج‪.‬‬

‫ُتستخ َدم األصناف إلنشاء أنماط‪ ،‬ثم ُتستعمل تلك األنماط إلنشاء الكائنات‪.‬‬

‫ابع‬
‫كيفية إنشاء األصناف والكائنات‪ ،‬وتهيئ ة الخاص يات باس تخدام ت ٍ‬
‫َّ‬ ‫ستتعلم في هذا الفصل‬

‫بان (‪ ،)constructor method‬والعمل على أكثر من كائن من نفس الصنف‪.‬‬


‫ٍ‬

‫‪ .1‬األصناف‬
‫آنف ا‪ُ .‬ت َ‬
‫نش أ األص ناف‬ ‫األص ناف هي نم اذج عام ة ُتس تخدم إلنش اء كائن ات‪ ،‬وس بق أن عرَّ فناه ا ً‬

‫باس تخدام الكلم ة المفتاحي ة ‪ ،class‬بش كل مش ابه لتعري ف ال دوال ال ذي يك ون باس تخدام الكلم ة‬

‫المفتاحية ‪.def‬‬

‫ً‬
‫صنفا يسمى ‪ ،Shark‬وننشئ له تابعين مرتبطين به‪ swim ،‬و ‪:be_awesome‬‬ ‫دعنا ِّ‬
‫نعرف‬

‫▲‬ ‫|‬ ‫‪330‬‬


‫البرمجة بلغة بايثون‬ ‫بناء األصناف واستنساخ الكائنات‬

‫‪class Shark:‬‬
‫‪def swim(self):‬‬
‫)"‪print("The shark is swimming.‬‬

‫‪def be_awesome(self):‬‬
‫)"‪print("The shark is being awesome.‬‬

‫ُتس مَّ ى مث ل ه ذه ال دوال «ت ابع» (‪َّ )method‬‬


‫ألنهم ا معرفت ان داخ ل الص نف ‪Shark‬؛ أي َّ‬
‫أنهم ا‬

‫دالتان تابعتان للصنف ‪.Shark‬‬

‫الوس يط األول له َ‬
‫اتين ال دالتين ه و ‪ ،self‬وه و مرج ع إلى الكائن ات ال تي س ُتبنَى من ه ذا‬

‫الص نف‪ .‬لإلش ارة إلى ُنس خ (أو كائن ات) من الص نف‪ ،‬يوض ع ‪ self‬دائمً ا في البداي ة‪ ،‬لكن يمكن أن‬

‫تكون معه وسائط أخرى‪.‬‬

‫ال ي ؤدي تعري ف الص نف ‪ Shark‬إلى إنش اء كائن ات من ه‪ ،‬وإنم ا يع ِّرف فق ط النم ط الع ام لتل ك‬

‫الحقا‪ .‬لذا‪ ،‬إذا ّ‬


‫نفذت البرنامج أعاله اآلن‪ ،‬فلن يُ عاد أي شيء‪.‬‬ ‫ً‬ ‫الكائنات‪ ،‬والتي يمكننا تعريفها‬

‫‪ .2‬الكائنات‬
‫ٌ‬
‫خة (‪ )instance‬من ص نف‪ ،‬ويمكن أن نأخ ذ الص نف ‪ Shark‬المُ ع رَّ ف أعاله‪،‬‬ ‫الك ائن ه و نس‬

‫ً‬
‫نسخة منه‪.‬‬ ‫ونستخدمه إلنشاء كائن يع ُّد‬

‫سننشئ كائنًا من الصنف ‪ Shark‬باسم ‪:sammy‬‬

‫)(‪sammy = Shark‬‬

‫ً‬
‫خة من الص نف‪.‬‬ ‫لق د أحلن ا على الك ائن ‪ sammy‬ن اتج الب اني )(‪ ،Shark‬وال ذي يعي د نس‬

‫سنستخدم في الشيفرة التالية التابعين الخاصين بالكائن ‪:sammy‬‬

‫▲‬ ‫|‬ ‫‪331‬‬


‫البرمجة بلغة بايثون‬ ‫بناء األصناف واستنساخ الكائنات‬

‫)(‪sammy = Shark‬‬
‫)(‪sammy.swim‬‬
‫)(‪sammy.be_awesome‬‬

‫يس تخدم الك ائن ‪ sammy‬الت ابعين )(‪ swim‬و )(‪ ،be_awesome‬وق د اس تدعينَاهما باس تعمال‬

‫الص ياغة النقطي ة (‪ ،).‬وال تي ُتس تخ َدم لإلش ارة إلى خاص يات (‪)properties‬أو تواب ع (‪)method‬‬

‫الكائنات‪ .‬في هذه الحالة‪ ،‬استدعينا تابعً ا‪ ،‬لذلك استعملنا قوسين مثلما نفعل عند استدعاء دالة‪.‬‬

‫الكلمة ‪ self‬هي معامل يُ مرَّ ر إلى توابع الصنف ‪ ،Shark‬في المث ال أعاله‪ِّ ،‬‬
‫يمثل ‪ self‬الك ائن‬

‫ُ‬
‫استدعيت معه‪.‬‬ ‫‪ .sammy‬يتيح المعامل ‪ self‬للتوابع الوصول إلى خاصيات الكائن الذي‬

‫الح ظ َّ‬
‫أنن ا لم نم ِّرر ش يًئا داخ ل القوس ين عن د اس تدعاء الت ابع أعاله‪ ،‬ذل ك َّ‬
‫أن الك ائن ‪sammy‬‬

‫ِّ‬
‫يوضح البرنامج التالي لنا األمر‪:‬‬ ‫تلقائيا مع العامل النقطي‪.‬‬
‫ً‬ ‫يُ مرَّ ر‬

‫‪class Shark:‬‬
‫‪def swim(self):‬‬
‫)"‪print("The shark is swimming.‬‬

‫‪def be_awesome(self):‬‬
‫)"‪print("The shark is being awesome.‬‬

‫‪def main():‬‬
‫)(‪sammy = Shark‬‬
‫)(‪sammy.swim‬‬
‫)(‪sammy.be_awesome‬‬

‫‪if __name__ == "__main__":‬‬


‫)(‪main‬‬

‫▲‬ ‫|‬ ‫‪332‬‬


‫البرمجة بلغة بايثون‬ ‫بناء األصناف واستنساخ الكائنات‬

‫ِّ‬
‫لننفذ البرنامج لنرى ما سيحدث‪:‬‬

‫‪python shark.py‬‬

‫طبع المخرجات التالية‪:‬‬ ‫ُ‬


‫ست َ‬

‫‪The shark is swimming.‬‬


‫‪The shark is being awesome.‬‬

‫في الش يفرة أعاله‪ ،‬اس تدعى الك ائن ‪ sammy‬الت ابعين )(‪ swim‬و )(‪ be_awesome‬في الدال ة‬

‫الرئيسية )(‪.main‬‬

‫‪ .3‬الباني (‪)Constructor‬‬
‫يٌ ستخدم الباني (‪ )Constructor Method‬لتهيئة البيانات األولية‪ ،‬ويُ َّ‬
‫نفذ لحظة إنشاء الكائن‪.‬‬

‫في تعري ف الص نف‪ ،‬يأخ ذ الب اني االس م __‪ ،__init‬وه و أول ت ابع يُ ع رَّ ف في الص نف‪ ،‬ويب دو‬

‫كما يلي‪:‬‬

‫‪class Shark:‬‬
‫‪def __init__(self):‬‬
‫)"‪print("This is the constructor method.‬‬

‫امج‬
‫ُ‬ ‫إذا أض فت الت ابع __‪ __init‬إلى الص نف ‪ Shark‬في البرن امج أعاله‪ ،‬فس َيطبع البرن‬

‫المخرجات التالية‪:‬‬

‫‪This is the constructor method.‬‬


‫‪The shark is swimming.‬‬
‫‪The shark is being awesome.‬‬

‫تلقائيا‪ ،‬لذا يستخدمه مطورو بايثون لتهيئة أصنافهم‪.‬‬


‫ً‬ ‫يُ َّ‬
‫نفذ الباني‬

‫▲‬ ‫|‬ ‫‪333‬‬


‫البرمجة بلغة بايثون‬ ‫بناء األصناف واستنساخ الكائنات‬

‫س ُن ِّ‬
‫عدل الباني أعاله‪ ،‬ونجعله يستخدم متغ يرًا اس مه ‪ name‬س ّ‬
‫يمثل اس م الك ائن‪ .‬في الش يفرة‬

‫التالية‪ ،‬سيكون المتغير ‪ name‬المعامل المُ مرَّ ر إلى الباني‪ ،‬ونحيل قيمته إلى الخاصية ‪:self.name‬‬

‫‪class Shark:‬‬
‫‪def __init__(self, name):‬‬
‫‪self.name = name‬‬

‫بع د ذل ك‪ ،‬يمكنن ا تع ديل السالس ل النص ية في دوالن ا لإلش ارة إلى اس م الص نف‪ ،‬على‬

‫النحو التالي‪:‬‬

‫‪class Shark:‬‬
‫‪def __init__(self, name):‬‬
‫‪self.name = name‬‬

‫‪def swim(self):‬‬
‫اإلشارة إلى االسم ‪#‬‬
‫)"‪print(self.name + " is swimming.‬‬

‫‪def be_awesome(self):‬‬
‫اإلشارة إلى االسم ‪#‬‬
‫)"‪print(self.name + " is being awesome.‬‬

‫أخ يرًا‪ ،‬يمكنن ا تع يين اس م الك ائن ‪ sammy‬عن د القيم ة "‪( "Sammy‬أي قيم ة الخاص ية ‪)name‬‬

‫بتمريره إلى )(‪ Shark‬عند إنشائه‪:‬‬

‫‪class Shark:‬‬
‫‪def __init__(self, name):‬‬
‫‪self.name = name‬‬

‫‪def swim(self):‬‬
‫)"‪print(self.name + " is swimming.‬‬

‫▲‬ ‫|‬ ‫‪334‬‬


‫البرمجة بلغة بايثون‬ ‫بناء األصناف واستنساخ الكائنات‬

‫‪def be_awesome(self):‬‬
‫)"‪print(self.name + " is being awesome.‬‬

‫‪def main():‬‬
‫تعيين اسم كائن ‪# Shark‬‬
‫)"‪sammy = Shark("Sammy‬‬
‫)(‪sammy.swim‬‬
‫)(‪sammy.be_awesome‬‬

‫‪if __name__ == "__main__":‬‬


‫)(‪main‬‬

‫أن المعام ل ‪ self‬يُ م رَّ ر‬


‫عرّ فن ا الت ابع __‪ ،__init‬وال ذي يقب ل مُ ع املين ‪ self‬و ‪( name‬ت ذكر َّ‬

‫تلقائيا إلى التابع)‪ ،‬ثم عرَّ فنا متغيرًا فيه‪.‬‬


‫ً‬

‫عند تنفيذ البرنامج‪:‬‬

‫‪python shark.py‬‬

‫سنحصل على‪:‬‬

‫‪Sammy is swimming.‬‬
‫‪Sammy is being awesome.‬‬

‫تلقائي ا‪ ،‬فلس ت بحاج ة إلى‬


‫ً‬ ‫نفذ‬ ‫لق د ُط ِب ع االس م ال ذي مرَّ رن اه إلى الك ائن‪ .‬ونظ ًرا َّ‬
‫ألن الب اني يُ َّ‬

‫اس تدعائه بش كل ص ريح‪ ،‬فيكفي تمري ر الوس ائط بين القوس ين الت اليين الس م الص نف عن د إنش اء‬

‫نسخة جديدة منه‪.‬‬

‫▲‬ ‫|‬ ‫‪335‬‬


‫البرمجة بلغة بايثون‬ ‫بناء األصناف واستنساخ الكائنات‬

‫إذا أردت إضافة معامل آخر‪ ،‬مثل ‪ ،age‬فيمكن ذلك عبر تمريره إلى التابع __‪:__init‬‬

‫‪class Shark:‬‬
‫‪def __init__(self, name, age):‬‬
‫‪self.name = name‬‬
‫‪self.age = age‬‬

‫ً‬
‫أيضا باإلضافة إلى اسمه‪:‬‬ ‫ِّ‬
‫سنمرر عُ مره‬ ‫عند إنشاء الكائن ‪،sammy‬‬

‫)‪sammy = Shark("Sammy", 5‬‬

‫ً‬
‫إذا‪ ،‬تتيح البانيات تهيئة خاصيات الكائن لحظة إنشائه‪.‬‬

‫‪ .4‬العمل مع عدة كائنات‬


‫ت تيح لن ا األص ناف إنش اء العدي د من الكائن ات المتماثل ة ال تي تتب ع نفس النم ط‪ .‬لتفهم ذل ك‬

‫بشكل أفضل‪ ،‬دعنا نضيف كائنًا آخر من الصنف ‪ Shark‬إلى برنامجنا‪:‬‬

‫‪class Shark:‬‬
‫‪def __init__(self, name):‬‬
‫‪self.name = name‬‬

‫‪def swim(self):‬‬
‫)"‪print(self.name + " is swimming.‬‬

‫‪def be_awesome(self):‬‬
‫)"‪print(self.name + " is being awesome.‬‬

‫‪def main():‬‬
‫)"‪sammy = Shark("Sammy‬‬
‫)(‪sammy.be_awesome‬‬
‫)"‪stevie = Shark("Stevie‬‬
‫)(‪stevie.swim‬‬

‫▲‬ ‫|‬ ‫‪336‬‬


‫البرمجة بلغة بايثون‬ ‫بناء األصناف واستنساخ الكائنات‬

‫‪if __name__ == "__main__":‬‬


‫)(‪main‬‬

‫ثاني ا من الص نف ‪ Shark‬يس مى ‪ stevie‬ومرَّ رن ا إلي ه االس م "‪."Stevie‬‬


‫ً‬ ‫لق د أنش أنا كائ ًن ا‬

‫اس تدعينا في ه ذا المث ال الت ابع )(‪ be_awesome‬م ع الك ائن ‪ sammy‬والت ابع )(‪ swim‬م ع‬

‫الكائن ‪ .stevie‬سننفذ البرنامج عبر األمر التالي‪:‬‬

‫‪python shark.py‬‬

‫سنحصل على المخرجات التالية‪:‬‬

‫‪Sammy is being awesome.‬‬


‫‪Stevie is swimming.‬‬

‫يب دو ظ اه ًرا في المخرج ات أنن ا نس تخدم ك ائنين مختلفين‪ ،‬الك ائن ‪ sammy‬والك ائن ‪،stevie‬‬

‫وكالهما من الصنف ‪.Shark‬‬

‫تتيح لنا األصناف إنشاء ع دة كائن ات تتب ع كله ا نفس النم ط دون الحاج ة إلى بن اء ك ل واح د‬

‫منها من البداية‪.‬‬

‫‪ .5‬فهم متغيرات األصناف والنسخ‬


‫تسمح البرمجة الكائنية باس تخدام متغ يرات على مس توى الص نف‪ ،‬أو على مس توى النس خة‬

‫(‪ .)instance‬المتغيرات هي رموز (‪ )symbols‬تدل على قيمة تستخدمها في برنامجك‪.‬‬

‫يشار إلى المتغيرات على مستوى الصنف باس م «متغ يرات الص نف» (‪ ،)class variables‬في‬

‫حين تس مى المتغ يرات الموج ودة على مس توى النس خة باس م «متغ يرات النس خة»‬

‫(‪.)instance variables‬‬

‫▲‬ ‫|‬ ‫‪337‬‬


‫البرمجة بلغة بايثون‬ ‫بناء األصناف واستنساخ الكائنات‬

‫إذا ت وقعت أن يك ون المتغيِّ ر متس ًقا في جمي ع نس خ الص نف‪ ،‬أو عن دما ت ود تهيئ ة المتغ ير‪،‬‬

‫فاألفض ل أن ُتع ِّرف ذل ك المتغ ير على مس توى الص نف‪ .‬أمَّ ا إن كنت تعلم َّ‬
‫أن المتغ ير س يختلف من‬

‫عر َفه على مستوى النس خة‪ .‬يس عى أح د مب ادئ تط وير البرمجي ات‬
‫نسخة إلى أخرى‪ ،‬فاألفضل أن ُت ِّ‬

‫ِّ‬
‫تكرر نفسك) إلى الحد من‬ ‫هو مبدأ ‪( DRY‬اختصا ًرا للعبارة ‪ ،don’t repeat yourself‬والذي يعني ال‬

‫التكرار في الشيفرة‪ .‬أي تلتزم البرمجة الكائنية بمبدأ ‪ DRY‬على تقليل التكرار في الشيفرة‪.‬‬

‫ا‪ .‬متغيرات الصنف‬

‫ٌتع رَّ ف متغ يرات الص نف داخ ل الص نف وخ ارج ك ل توابع ه وع ً‬


‫ادة م ا توض ع مباش رة أس فل‬

‫ترويسة الص نف‪ ،‬وقب ل الب اني (‪ )constructor‬والتواب ع األخ رى‪ .‬ولمَّ ا ك انت مملوك ة للص نف نفس ه‪،‬‬

‫فستشارَ ك مع جميع ُن َسخ ذلك الصنف‪ .‬وبالتالي‪ ،‬س يكون له ا نفس القيم ة بغض النظ ر عن النس خة‪،‬‬
‫ُ‬

‫معين‪.‬‬
‫َّ‬ ‫إال إن كنت ستستخدم متغير الصنف لتهيئة متغير‬

‫متغير الصنف يبدو كما يلي‪:‬‬

‫‪class Shark:‬‬
‫"‪animal_type = "fish‬‬

‫في الشيفرة أعاله أحلنا القيمة "‪ "fish‬إلى المتغير ‪.animal_type‬‬

‫يمكنن ا إنش اء نس خة من الص نف ‪( Shark‬س نطلق عليه ا ‪ ،)new_shark‬ونطب ع المتغ ير‬

‫باستخدام الصياغة النقطية (‪:)dot notation‬‬

‫‪class Shark:‬‬
‫"‪animal_type = "fish‬‬

‫)(‪new_shark = Shark‬‬
‫)‪print(new_shark.animal_type‬‬

‫▲‬ ‫|‬ ‫‪338‬‬


‫البرمجة بلغة بايثون‬ ‫بناء األصناف واستنساخ الكائنات‬

‫لننفذ البرنامج‪:‬‬

‫‪python shark.py‬‬

‫سيعيد البرنامج قيمة المتغير‪:‬‬

‫‪fish‬‬

‫دعنا نضيف مزي ًدا من متغيرات الصنف‪ ،‬ونطبعها‪:‬‬

‫‪class Shark:‬‬
‫"‪animal_type = "fish‬‬
‫"‪location = "ocean‬‬
‫‪followers = 5‬‬

‫)(‪new_shark = Shark‬‬
‫)‪print(new_shark.animal_type‬‬
‫)‪print(new_shark.location‬‬
‫)‪print(new_shark.followers‬‬

‫يمكن أن تتألف متغيرات الص نف من أي ن وع من البيان ات المتاح ة في ب ايثون تمامً ا مث ل أي‬

‫متغير آخر‪ .‬استخدمنا في هذا البرنامج السالسل النصية واألعداد الص حيحة‪ .‬لننف ذ البرن امج م رة‬

‫أخرى باستخدام األمر ‪ python shark.py‬ونرى المخرجات‪:‬‬

‫‪fish‬‬
‫‪ocean‬‬
‫‪5‬‬

‫يمكن للنس خة ‪ new_shark‬الوص ول إلى جمي ع متغ يرات الص نف وطباعته ا عن د تنفي ذ‬

‫ً‬
‫مباشرة (وليس عند إنشاء نسخة منه) وتحتل موضعً ا له ا في‬ ‫البرنامج‪ ،‬إذ ُت َ‬
‫نشأ عند إنشاء الصنف‬

‫الذاكرة ويمكن ألي كائن مُ ش َتق (نسخة) من الصنف نفسه أن يصل إليها ويقرأ قيمتها‪.‬‬

‫▲‬ ‫|‬ ‫‪339‬‬


‫البرمجة بلغة بايثون‬ ‫بناء األصناف واستنساخ الكائنات‬

‫ب‪ .‬متغيرات النسخة‬

‫تختل ف متغ يرات النس خة عن متغ يرات الص نف ب أن النس خة المش تقة من الص نف هي من‬

‫وسي َ‬
‫نشأ متغيِّ رٌ مستقل في ال ذاكرة عن د‬ ‫ُ‬ ‫تملكها وليس الصنف نفسه أي تكون على مستوى النسخة‬

‫أن متغيرات النسخة ستختلف من كائن إلى آخر‪.‬‬


‫إنشاء كل نسخة‪ .‬هذا يعني َّ‬

‫ُتعرَّ ف متغيرات النسخة ضمن التوابع على خالف متغيرات الصنف‪ .‬في مثال الص نف ‪Shark‬‬

‫أدناه‪ ،‬عرفنا متغيري النسخة ‪ name‬و ‪:age‬‬

‫‪class Shark:‬‬
‫‪def __init__(self, name, age):‬‬
‫‪self.name = name‬‬
‫‪self.age = age‬‬

‫يتعين علين ا تعري ف ه ذه المتغ يرات‪ ،‬ع بر تمريره ا‬


‫َّ‬ ‫عن دما ننش ئ كائ ًن ا من الص نف ‪ ،Shark‬س‬

‫معامالت ضمن الباني (‪ ،)constructor‬أو أي تابع آخر‪:‬‬


‫ٍ‬

‫‪class Shark:‬‬
‫‪def __init__(self, name, age):‬‬
‫‪self.name = name‬‬
‫‪self.age = age‬‬

‫)‪new_shark = Shark("Sammy", 5‬‬

‫كما هو الحال مع متغيرات األصناف‪ ،‬يمكننا بالمثل طباعة متغيرات النسخة‪:‬‬

‫‪class Shark:‬‬
‫‪def __init__(self, name, age):‬‬
‫‪self.name = name‬‬
‫‪self.age = age‬‬

‫▲‬ ‫|‬ ‫‪340‬‬


‫البرمجة بلغة بايثون‬ ‫بناء األصناف واستنساخ الكائنات‬

‫)‪new_shark = Shark("Sammy", 5‬‬


‫)‪print(new_shark.name‬‬
‫)‪print(new_shark.age‬‬

‫عند تنفيذ البرنامج أعاله باستخدام ‪ ،python shark.py‬سنحصل على المخرجات التالية‪:‬‬

‫‪Sammy‬‬
‫‪5‬‬

‫هيأناه ا ألج ل‬
‫تت ألف المخرج ات ال تي حص لنا عليه ا من قيم المتغ يرات ال تي َّ‬

‫الكائن ‪.new_shark‬‬

‫لننشئ كائنًا آخر من الصنف ‪ Shark‬يسمى ‪:stevie‬‬

‫‪class Shark:‬‬
‫‪def __init__(self, name, age):‬‬
‫‪self.name = name‬‬
‫‪self.age = age‬‬

‫)‪new_shark = Shark("Sammy", 5‬‬


‫)‪print(new_shark.name‬‬
‫)‪print(new_shark.age‬‬

‫)‪stevie = Shark("Stevie", 8‬‬


‫)‪print(stevie.name‬‬
‫)‪print(stevie.age‬‬

‫ِّ‬
‫يمرر الكائن ‪ stevie‬المعامالت إلى الباني لتعيين قيم متغيرات النسخة الخاصة به‪.‬‬

‫تسمح متغيرات النسخة‪ ،‬المملوكة لكائنات الصنف‪ ،‬لكل كائن أو نسخة أن تكون لها متغ يرات‬

‫ً‬
‫بعضا‪.‬‬ ‫خاصة بها ذات قيم مختلفة عن بعضها‬

‫▲‬ ‫|‬ ‫‪341‬‬


‫البرمجة بلغة بايثون‬ ‫بناء األصناف واستنساخ الكائنات‬

‫‪ .6‬العمل مع متغيرات الصنف والنسخة ً‬


‫معا‬
‫غالب ا م ا ُتس تخدم متغ يرات الص نف ومتغ يرات النس خة في نفس الش يفرة‪ ،‬ويوض ح المث ال‬
‫ً‬

‫الت الي يس تخدم الص نف ‪ Shark‬ال ذي أنش أناه س ً‬


‫ابقا ه ذا األم ر‪ .‬تش رح التعليق ات في البرن امج ك ل‬

‫خطوة من خطوات العملية‪:‬‬

‫‪class Shark:‬‬

‫متغيرات الصنف ‪#‬‬


‫"‪animal_type = "fish‬‬
‫"‪location = "ocean‬‬

‫باني مع متغيري النسخة ‪ age‬و ‪# name‬‬


‫‪def __init__(self, name, age):‬‬
‫‪self.name = name‬‬
‫‪self.age = age‬‬

‫تابع مع متغير النسخة ‪# followers‬‬


‫‪def set_followers(self, followers):‬‬
‫)"‪print("This user has " + str(followers) + " followers‬‬

‫‪def main():‬‬
‫الكائن األول‪ ،‬إعداد متغيرات النسخة في الباني ‪#‬‬
‫)‪sammy = Shark("Sammy", 5‬‬

‫طباعة متغير النسخة ‪# name‬‬


‫)‪print(sammy.name‬‬

‫طباعة متغير الصنف ‪# location‬‬


‫)‪print(sammy.location‬‬

‫الكائن الثاني ‪#‬‬

‫▲‬ ‫|‬ ‫‪342‬‬


‫البرمجة بلغة بايثون‬ ‫بناء األصناف واستنساخ الكائنات‬

‫)‪stevie = Shark("Stevie", 8‬‬

‫طباعة متغير النسخة ‪# name‬‬


‫)‪print(stevie.name‬‬

‫استخدام التابع ‪# set_followers‬‬


‫لتمرير متغير النسخة ‪# followers‬‬
‫)‪stevie.set_followers(77‬‬

‫طباعة متغير الصنف ‪# animal_type‬‬


‫)‪print(stevie.animal_type‬‬

‫‪if __name__ == "__main__":‬‬


‫)(‪main‬‬

‫عند تنفيذ البرنامج باستخدام ‪ ،python shark.py‬سنحصل على المخرجات التالية‪:‬‬

‫‪Sammy‬‬
‫‪ocean‬‬
‫‪Stevie‬‬
‫‪This user has 77 followers‬‬
‫‪fish‬‬

‫‪ .7‬خالصة الفصل‬
‫تطرَّ قن ا في ه ذا الفص ل إلى عِ َّدة مف اهيم‪ ،‬مث ل إنش اء األص ناف‪ ،‬وإنش اء الكائن ات‪ ،‬وتهيئ ة‬

‫الخاصيات باستخدام البانيات‪ ،‬والعمل مع أكثر من كائن من نفس الصنف‪.‬‬

‫ُتع ُّد البرمجة الكائنية أحد المفاهيم الضرورية التي ينبغي أن يتعلمها كل مبرمجي بايثون‪ ،‬إذ‬

‫تس اعد على كتاب ة ش يفرات قابل ة إلع ادة االس تخدام‪ ،‬والكائن ات ال تي ُت َ‬
‫نش أ في برن امج م ا يمكن‬

‫أن ال برامج الكائني ة ع ادة م ا تك ون أوض ح وأك ثر مقروئي ة‪،‬‬


‫اس تخدامها في ب رامج أخ رى‪ .‬كم ا َّ‬

‫▲‬ ‫|‬ ‫‪343‬‬


‫البرمجة بلغة بايثون‬ ‫بناء األصناف واستنساخ الكائنات‬

‫خصوص ا في ال برامج المعق دة ال تي تتطلب تخطيط ا دقيق ا‪ ،‬وه ذا ب دوره يس هل ص يانة‬


‫ً‬

‫البرامج مستقبال‪.‬‬

‫في البرمج ة الكائني ة‪ ،‬يش ار إلى المتغ يرات المُ عرَّ ف ة على مس توى الص نف بمتغ يرات الص نف‪،‬‬

‫في حين تسمى المتغ يرات المُ عرّ ف ة على مس توى الك ائن بمتغ يرات النس خة‪ .‬ي تيح لن ا ه ذا التمي يز‬

‫اس تخدام متغ يرات ذات قيم واح دة بينه ا ع بر متغ يرات الص نف‪ ،‬أو اس تخدام متغ يرات مختلف ة‬

‫لك ل ك ائن على ح دة ع بر متغ يرات النس خة‪ .‬كم ا يض من اس تخدام المتغ يرات الخاص ة بالص نف أو‬

‫النسخة أن تكون الشيفرة متوافقة مع مبدأ ‪.DRY‬‬

‫▲‬ ‫|‬ ‫‪344‬‬


‫‪19‬‬
‫مفهوم الوراثة‬
‫في البرمجة‬

‫▲‬ ‫|‬ ‫‪345‬‬


‫البرمجة بلغة بايثون‬ ‫مفهوم الوراثة في البرمجة‬

‫ُت ِّسهل البرمجة الكائنية كتاب ة ش يفرات قابل ة إلع ادة االس تخدام وتجنب التك رار في مش اريع‬

‫ِّ‬
‫تحقق به ا البرمج ة الكائني ة ه ذا اله دف هي مفه وم الوراث ة‬ ‫التط وير‪ .‬إح دى اآللي ات ال تي‬

‫نف ف رعي ( ‪ )subclass‬اس تخدام الش يفرة الخاص ة بص نف‬


‫(‪ ،)inheritance‬ال تي بفض لها يمكن لص ٍ‬

‫ً‬
‫مسبقا‪.‬‬ ‫ً‬
‫أيضا) موجود‬ ‫أساسي (‪ ،base class‬ويطلق عليه «صنف أب»‬

‫سيس تعرض ه ذا الفص ل بعض الج وانب الرئيس ية لمفه وم الوراث ة في ب ايثون‪ ،‬بم ا في ذل ك‬

‫وكيفية‬
‫َّ‬ ‫كيفية إنشاء األصناف األساس ية (‪ )parent classes‬واألص ناف الفرعي ة (‪،)child classes‬‬
‫َّ‬

‫وكيفية‬
‫َّ‬ ‫وكيفية اس تخدام الت ابع )(‪،super‬‬
‫َّ‬ ‫إع ادة تعري ف (‪ )override‬التواب ع والخاص يات‪،‬‬

‫ِّ‬
‫تعددة (‪.)multiple inheritance‬‬ ‫االستفادة من الوراثة المُ‬

‫‪ .1‬ما هي الوراثة؟‬
‫تق وم الوراثة على اس تخدام ش يفرة ص نف معين في ص نف آخ ر أي ي رث ص نف ي راد إنش اؤه‬

‫ش يفرة ص نف آخ ر‪ .‬يمكن تمثي ل مفه وم الوراث ة في البرمج ة بالوراث ة في علم األحي اء تمامً ا‪،‬‬

‫فاألبن اء يرث ون خاص يات معين ة من آب ائهم‪ .‬ويمكن لطف ل أن ي رث ط ول وال ده أو ل ون عيني ه‬

‫باإلض افة إلى خاص يات أخ رى جدي دة خاص ة في ه‪ .‬كم ا يتش ارك األطف ال نفس اس م العائل ة‬

‫الخاصة بآبائهم‪.‬‬

‫ً‬
‫أيضا األصناف األبن اء [‪ )]child classes‬التواب ع‬ ‫ترث األصناف الفرعية (‪ُ ،subclasses‬تسمى‬

‫ناف‬ ‫ا األص‬ ‫ً‬


‫أيض‬ ‫مى‬ ‫‪ ،base‬تس‬ ‫ية (‪classes‬‬ ‫ناف األساس‬ ‫يرات من األص‬ ‫والمتغ‬

‫اآلباء [‪.)]parent classes‬‬

‫مثاًل ‪ ،‬قد يكون لدينا ص نف أساس ي يس مى ‪ Parent‬يح وي متغ يرات األص ناف ‪last_name‬‬

‫و ‪ height‬و ‪ ،eye_color‬والتي سيرثها الصنف االبن ‪.Child‬‬

‫▲‬ ‫|‬ ‫‪346‬‬


‫البرمجة بلغة بايثون‬ ‫مفهوم الوراثة في البرمجة‬

‫لمَّ ا ك ان الص نف الف رعي ‪ Child‬ي رث الص نف األساس ي ‪ ،Parent‬فبإمكان ه إع ادة اس تخدام‬

‫شيفرة ‪ ،Parent‬مما يسمح للمبرمج بكتابة شيفرة أوجز‪ ،‬وتقليل التكرار‪.‬‬

‫‪ .2‬األصناف األساسية‬
‫أساس ا يمكن أن تس تند إلي ه األص ناف الفرعي ة المُ ِّ‬
‫تفرع ة منه ا‪ ،‬إذ‬ ‫ً‬ ‫تش كل األص ناف األساس ية‬

‫تسمح األصناف األساسية بإنشاء أصناف فرعية عبر الوراثة دون الحاجة إلى كتابة نفس الش يفرة‬

‫في ك ل م رة‪ .‬يمكن تحوي ل أي ص نف إلى ص نف أساس ي‪ ،‬إذ يمكن اس تخدامه لوح ده‪ ،‬أو جعل ه‬

‫ً‬
‫نموذجا)‪.‬‬‫قالبا (‬
‫ً‬

‫أساسيا باسم ‪ ،Bank_account‬وصنفين فرعيين مُ شتقين منه باس م‬


‫ً‬ ‫ً‬
‫صنفا‬ ‫أن لدينا‬
‫لنفترض َّ‬

‫‪ Personal_account‬و ‪ .Business_account‬س تكون العدي د من التواب ع مش تركة بين‬

‫الحس ابات الشخص ية ( ‪ )Personal_account‬والحس ابات التجاري ة (‪ ،)Business_account‬مث ل‬

‫تواب ع س حب وإي داع األم وال‪ ،‬ل ذا يمكن أن تنتمي تل ك التواب ع إلى الص نف األساسي‬

‫‪ .Bank_account‬س يكون للص نف ‪ Business_account‬تواب ع خاص ة ب ه‪ ،‬مث ل ت ابع مخص ص‬

‫ير‬ ‫افة إلى متغ‬ ‫ال‪ ،‬باإلض‬ ‫اذج األعم‬ ‫جالت ونم‬ ‫عس‬ ‫ة جم‬ ‫لعملي‬

‫‪ employee_identification_number‬موروث من الصنف األب‪.‬‬

‫وبالمثل‪ ،‬قد يحتوي الصنف ‪ Animal‬على التابعين )(‪ eating‬و )(‪ ،sleeping‬وقد يتض من‬

‫الصنف الفرعي ‪ Snake‬تابعين إضافيين باسم )(‪ hissing‬و )(‪ slithering‬خاصين به‪.‬‬

‫أساس ا ألص ناف فرعي ة تمث ل أن واع‬


‫ً‬ ‫ً‬
‫الحق ا‬ ‫دعنا ننش ئ ص ً‬
‫نفا أساس ًيا باس م ‪ Fish‬الس تخدامه‬

‫األسماك‪ .‬سيكون لكل واحدة من تلك األسماك أسماء أولى وأخيرة‪ ،‬باإلضافة إلى خص ائص مم يزة‬

‫خاصة بها‪.‬‬

‫▲‬ ‫|‬ ‫‪347‬‬


‫البرمجة بلغة بايثون‬ ‫مفهوم الوراثة في البرمجة‬

‫سننشئ ً‬
‫ملف ا جدي ًدا يس مى ‪ fish.py‬ونب دأ بالب اني‪ ،‬وال ذي س ِّ‬
‫نعرف داخل ه متغ يري الص نف‬

‫‪ first_name‬و ‪ last_name‬لكل كائنات الصنف ‪ ،Fish‬أو أصنافه الفرعية‪.‬‬

‫‪class Fish:‬‬
‫‪def __init__(self, first_name, last_name="Fish"):‬‬
‫‪self.first_name = first_name‬‬
‫‪self.last_name = last_name‬‬

‫أن معظم‬
‫القيم ة االفتراض ية للمتغ ير ‪ last_name‬هي السلس لة النص ية "‪ ،"Fish‬ألنن ا نعلم َّ‬

‫األسماك سيكون هذا هو اسمها األخير‪.‬‬

‫ل ُن ِ‬
‫ضف بعض التوابع األخرى‪:‬‬

‫‪class Fish:‬‬
‫‪def __init__(self, first_name, last_name="Fish"):‬‬
‫‪self.first_name = first_name‬‬
‫‪self.last_name = last_name‬‬

‫‪def swim(self):‬‬
‫)"‪print("The fish is swimming.‬‬

‫‪def swim_backwards(self):‬‬
‫)"‪print("The fish can swim backwards.‬‬

‫لق د أض فنا الت ابعين )(‪ swim‬و )(‪ swim_backwards‬إلى الص نف ‪ Fish‬ح تى يتس نى لك ل‬

‫األصناف الفرعية استخدام هذه التوابع‪.‬‬

‫عظميا) وليس‬
‫ً‬ ‫أن لها هيكال‬
‫أن معظم األسماك التي ننوي إنشاءها ستكون عظمية (أي َّ‬
‫ما دام َّ‬

‫روفيا)‪ ،‬فيمكنن ا إض افة بعض الخاص يات اإلض افية إلى‬


‫ً‬ ‫غض روفية (أي أن له ا هيكاًل غض‬

‫التابع )(__‪:__init‬‬

‫▲‬ ‫|‬ ‫‪348‬‬


‫البرمجة بلغة بايثون‬ ‫مفهوم الوراثة في البرمجة‬

‫‪class Fish:‬‬
‫‪def __init__(self, first_name, last_name="Fish",‬‬
‫‪skeleton="bone", eyelids=False):‬‬
‫‪self.first_name = first_name‬‬
‫‪self.last_name = last_name‬‬
‫‪self.skeleton = skeleton‬‬
‫‪self.eyelids = eyelids‬‬

‫‪def swim(self):‬‬
‫)"‪print("The fish is swimming.‬‬

‫‪def swim_backwards(self):‬‬
‫)"‪print("The fish can swim backwards.‬‬

‫ال يختل ف بن اء األص ناف األساس ية عن بن اء أي ص نف آخ ر‪ ،‬إال َّ‬


‫أنن ا نص ممها لتس تفيد منه ا‬

‫ً‬
‫الحقا‪.‬‬ ‫األصناف الفرعية المُ عرّ فة‬

‫‪ .3‬األصناف الفرعية‬
‫أن األص ناف‬
‫األص ناف الفرعي ة هي أص ناف ت رث ك ل ش يء من الص نف األساس ي‪ .‬ه ذا يع ني َّ‬

‫الفرعية قادرة على االستفادة من توابع ومتغيرات الصنف األساسي‪.‬‬

‫على س بيل المث ال‪ ،‬س يتمكن الص نف الف رعي ‪ Goldfish‬المش تق من الص نف ‪ Fish‬من‬

‫استخدام التابع )(‪ swim‬المُ عرّ ف في ‪ Fish‬دون الحاجة إلى التصريح عنه‪.‬‬

‫أنها أقسامٌ من الصنف األساسي‪ .‬فإذا كان لدينا ص ً‬


‫نفا‬ ‫يمكننا النظر إلى األصناف الفرعية على َّ‬

‫معين)‪ ،‬وص ً‬
‫نفا أساس ًّيا يس مى ‪( Parallelogram‬مت وازي األض الع)‪،‬‬ ‫فرعيا يس مى ‪َّ ( Rhombus‬‬
‫ًّ‬

‫أن المعين (‪ )Rhombus‬هو متوازي أضالع (‪.)Parallelogram‬‬


‫يمكننا القول َّ‬

‫▲‬ ‫|‬ ‫‪349‬‬


‫البرمجة بلغة بايثون‬ ‫مفهوم الوراثة في البرمجة‬

‫مختلفا قلياًل عن األصناف غير الفرعية‪ ،‬إذ يجب عليك‬


‫ً‬ ‫يبدو السطر األول من الصنف الفرعي‬

‫تمرير الصنف األساسي إلى الصنف الفرعي كمعامل‪:‬‬

‫‪class Trout(Fish):‬‬

‫ُ‬
‫الكلمة ‪ Fish‬المُ درجة بين قوسين‪.‬‬ ‫الصنف ‪ Trout‬هو صنف فرعي من ‪ .Fish‬يدلنا على هذا‬

‫يمكننا إضافة توابع جديدة إلى األصناف الفرعي ة‪ ،‬أو إع ادة تعري ف التواب ع الخاص ة بالص نف‬

‫األساس ي‪ ،‬أو يمكنن ا ببس اطة قب ول التواب ع األساس ية االفتراض ية باس تخدام الكلمة‬

‫المفتاحية ‪ ،pass‬وهو ما سنفعله في المثال التالي‪:‬‬

‫‪...‬‬
‫‪class Trout(Fish):‬‬
‫‪pass‬‬

‫يمكننا اآلن إنشاء كائن من الصنف ‪ Trout‬دون الحاجة إلى تعريف أي توابع إضافية‪.‬‬

‫‪...‬‬
‫‪class Trout(Fish):‬‬
‫‪pass‬‬

‫)"‪terry = Trout("Terry‬‬
‫)‪print(terry.first_name + " " + terry.last_name‬‬
‫)‪print(terry.skeleton‬‬
‫)‪print(terry.eyelids‬‬
‫)(‪terry.swim‬‬
‫)(‪terry.swim_backwards‬‬

‫لق د أنش أنا كائ ًن ا باس م ‪ terry‬من الص نف ‪ ،Trout‬وال ذي سيس تخدم جمي ع تواب ع الص نف‬

‫نعرفه ا في الص نف الف رعي ‪ .Trout‬يكفي أن نم ِّرر القيم ة "‪ "Terry‬إلى المتغ ير‬
‫‪ Fish‬وإن لم ِّ‬

‫ً‬
‫سلفا‪.‬‬ ‫‪ ،first_name‬أمَّ ا المتغيرات األخرى فقد جرى تهيئتها‬

‫▲‬ ‫|‬ ‫‪350‬‬


‫البرمجة بلغة بايثون‬ ‫مفهوم الوراثة في البرمجة‬

:‫ سنحصل على المخرجات التالية‬،‫عند تنفيذ البرنامج‬

Terry Fish
bone
False
The fish is swimming.
The fish can swim backwards.

.Clownfish ‫ سنس مي ه ذا الص نف‬.‫فرعي ا آخ ر يع رّ ف تابعً ا خاص ا ب ه‬


ً ً ‫لننش ئ اآلن ص‬
‫نفا‬

:‫سيسمح التابع الخاص به بالتعايش مع شقائق النعمان البحري‬

...
class Clownfish(Fish):

def live_with_anemone(self):
print("The clownfish is coexisting with sea anemone.")

:Clownfish ‫دعنا ننشئ اآلن كائنًا آخر من الصنف‬

...
casey = Clownfish("Casey")
print(casey.first_name + " " + casey.last_name)
casey.swim()
casey.live_with_anemone()

:‫ سنحصل على المخرجات التالية‬،‫عند تنفيذ البرنامج‬

Casey Fish
The fish is swimming.
The clownfish is coexisting with sea anemone.

َّ ‫ُتظه ر المخرج ات‬


‫ ق ادر على اس تخدام‬Clownfish ‫ المستنس خ من الص نف‬casey ‫أن الك ائن‬

‫ابع‬ ‫افة إلى الت‬ ‫ إض‬،Fish ‫نف‬ ‫ين بالص‬ ‫ الخاص‬swim() ‫__ و‬init__() ‫ابعين‬ ‫الت‬

▲ | 351
‫البرمجة بلغة بايثون‬ ‫مفهوم الوراثة في البرمجة‬

‫)(‪ live_with_anemone‬الخاص بالصنف الفرعي‪.‬‬

‫إذا حاولنا استخدام التابع )(‪ live_with_anemone‬في الكائن ‪ ،Trout‬فسوف يُ طلق خطأ‪:‬‬

‫)(‪terry.live_with_anemone‬‬
‫‪AttributeError: 'Trout' object has no attribute‬‬
‫'‪'live_with_anemone‬‬

‫أن الت ابع )(‪ live_with_anemone‬ينتمي إلى الص نف الف رعي ‪ Clownfish‬فق ط‪،‬‬
‫ذل ك َّ‬

‫وليس إلى الصنف األساسي ‪.Fish‬‬

‫ت رث األص ناف الفرعي ة تواب ع الص نف األساس ي ال ذي اش ُت َّقت من ه‪ ،‬ل ذا يمكن لك ل األص ناف‬

‫الفرعية استخدام تلك التوابع‪.‬‬

‫‪ .4‬إعادة تعريف توابع الصنف األساسي‬


‫عرَّ فنا في المثال السابق الصنف الفرعي ‪ Trout‬الذي اس تخدم الكلم ة المفتاحي ة ‪ pass‬ل يرث‬

‫جمي ع س لوكيات الص نف األساس ي ‪ ،Fish‬وعرّ فن ا ك ذلك ص ً‬


‫نفا آخ ر ‪ Clownfish‬ي رث جمي ع‬

‫خاص ا ب ه‪ .‬ق د ن رغب في بعض األحي ان في‬


‫ً‬ ‫ً‬
‫أيض ا تابعً ا‬ ‫س لوكيات الص نف األساس ي‪ ،‬ويُ نش ئ‬

‫استخدام بعض سلوكيات الصنف األساسي‪ ،‬ولكن ليس كلها‪ .‬يُ َ‬


‫طلق على عملية تغيير توابع الصنف‬

‫األساسي «إعادة التعريف» (‪.)Overriding‬‬

‫عند إنشاء األصناف األساسية أو الفرعي ة‪ ،‬فال ب د أن تك ون ل ك رؤي ة عام ة لتص ميم البرن امج‬

‫حتى ال تعيد تعريف التوابع إال عند الضرورة‪.‬‬

‫فرعي ا ‪ Shark‬مش ً‬
‫تقا من الص نف األساس ي ‪ ،Fish‬ال ذي س يمثل األس ماك‬ ‫ً‬ ‫سننش ئ ص ً‬
‫نفا‬

‫المخصص في األصل‬
‫َّ‬ ‫العظمية بشكل أساسي‪ ،‬لذا يتعين علينا إجراء تعديالت على الصنف ‪Shark‬‬

‫لألس ماك الغض روفية‪ .‬من منظ ور تص ميم ال برامج‪ ،‬إذا ك انت ل دينا أك ثر من س مكة غ ير عظمي ة‬

‫▲‬ ‫|‬ ‫‪352‬‬


‫البرمجة بلغة بايثون‬ ‫مفهوم الوراثة في البرمجة‬

‫خاصا بكل نوع من هذين النوعين من األسماك‪.‬‬


‫ً‬ ‫ً‬
‫صنفا‬ ‫فيستحب أن ننشئ‬
‫واحدة‪ُ ،‬‬

‫تمتلك أسماك الق رش‪ ،‬على عكس األس ماك العظمي ة‪ ،‬هياك ل مص نوعة من الغض اريف ب داًل من‬

‫جفونا‪ ،‬وال تستطيع الس باحة إلى ال وراء‪ ،‬كم ا َّ‬


‫أنه ا ق ادرة على المن اورة للخل ف‬ ‫ً‬ ‫أن لديها‬
‫العظام‪ .‬كما َّ‬

‫عن طريق الغوص‪.‬‬

‫ابع‬ ‫اني )(__‪ __init‬والت‬ ‫ف الب‬ ‫نعيد تعري‬ ‫ات‪ ،‬س‬ ‫ذه المعلوم‬ ‫وء ه‬ ‫على ض‬

‫ألن أس ماك الق رش يمكنه ا الس باحة‪.‬‬


‫)(‪ .swim_backwards‬ال نحت اج إلى تع ديل الت ابع )(‪َّ swim‬‬

‫دعنا نلقي نظرة على هذا الصنف الفرعي‪:‬‬

‫‪...‬‬
‫‪class Shark(Fish):‬‬
‫‪def __init__(self, first_name, last_name="Shark",‬‬
‫‪skeleton="cartilage", eyelids=True):‬‬
‫‪self.first_name = first_name‬‬
‫‪self.last_name = last_name‬‬
‫‪self.skeleton = skeleton‬‬
‫‪self.eyelids = eyelids‬‬

‫‪def swim_backwards(self):‬‬
‫‪print("The shark cannot swim backwards, but can sink‬‬
‫)"‪backwards.‬‬

‫لق د أع دنا تعري ف المع امالت ال تي تمت تهيئته ا في الت ابع )(__‪ ،__init‬فأخ ذ المتغ ير‬

‫ُأ‬
‫‪ last_name‬القيم ة "‪ ،"Shark‬كم ا س نِد إلى المتغ ير ‪ skeleton‬القيم ة "‪ ،"cartilage‬فيما‬

‫ُأ‬
‫س ِن َدت القيم ة المنطقي ة ‪ True‬إلى المتغ ير ‪ .eyelids‬يمكن لجمي ع ُنس خ الص نف إع ادة تعري ف‬

‫هذه المعامالت‪.‬‬

‫▲‬ ‫|‬ ‫‪353‬‬


‫البرمجة بلغة بايثون‬ ‫مفهوم الوراثة في البرمجة‬

‫يطب ع الت ابع )(‪ swim_backwards‬سلس لة نص ية مختلف ة عن تل ك ال تي يطبعه ا في الص نف‬

‫ألن أسماك القرش غير قادرة على السباحة للخلف كما تفعل األسماك العظمية‪.‬‬
‫األساسي ‪َّ ،Fish‬‬

‫يمكنن ا اآلن إنش اء نس خة من الص نف الف رعي ‪ ،Shark‬وال ذي سيس تخدم الت ابع )(‪swim‬‬

‫الخاص بالصنف األساسي ‪:Fish‬‬

‫‪...‬‬
‫)"‪sammy = Shark("Sammy‬‬
‫)‪print(sammy.first_name + " " + sammy.last_name‬‬
‫)(‪sammy.swim‬‬
‫)(‪sammy.swim_backwards‬‬
‫)‪print(sammy.eyelids‬‬
‫)‪print(sammy.skeleton‬‬

‫عند تنفيذ هذه الشيفرة‪ ،‬سنحصل على المخرجات التالية‪:‬‬

‫‪Sammy Shark‬‬
‫‪The fish is swimming.‬‬
‫‪The shark cannot swim backwards, but can sink backwards.‬‬
‫‪True‬‬
‫‪cartilage‬‬

‫لق د أع اد الص نف الف رعي ‪ Shark‬تعري ف الت ابعين )(__‪ __init‬و )(‪swim_backwards‬‬

‫اص‬ ‫ابع )(‪ swim‬الخ‬ ‫وقت الت‬ ‫ي ‪ ،Fish‬وورث في نفس ال‬ ‫نف األساس‬ ‫ين بالص‬ ‫الخاص‬

‫بالصنف األساسي‪.‬‬

‫‪ .5‬الدالة )(‪ super‬وفائدتها في الوراثة‬


‫ُأ‬
‫يمكنك باستخدام الدالة )(‪ super‬الوصول إلى التوابع الموروثة التي عي َدت كتابتها‪ .‬عن دما‬

‫نستخدم الدالة )(‪َّ ،super‬‬


‫فإننا نستدعي التابع الخاص بالص نف األساس ي الس تخدامه في الص نف‬

‫▲‬ ‫|‬ ‫‪354‬‬


‫البرمجة بلغة بايثون‬ ‫مفهوم الوراثة في البرمجة‬

‫الفرعي‪ .‬على سبيل المثال‪ ،‬قد نرغب في إعادة تعريف جانب من التابع األساسي وإض افة وظ ائف‬

‫معينة إليه‪ ،‬ثم بعد ذلك نستدعي التابع األساسي إلنهاء بقية العمل‪.‬‬

‫في برن امج خ اص بتق ييم الطالب مثاًل ‪ ،‬ق د ن رغب في تعري ف ص نف ف رعي‬

‫ابع‬ ‫ف الت‬ ‫ه تعري‬ ‫د في‬ ‫ي ‪ ،Grade‬ونعي‬ ‫نف األساس‬ ‫رث الص‬ ‫‪ Weighted_grade‬ي‬

‫)(‪ calculate_grade‬الخاص بالصنف األساسي من أجل تضمين شيفرة خاصة بحساب التق دير‬

‫َّ‬
‫المرجح (‪ ، )weighted grade‬مع الحفاظ على بقية وظائف الصنف األساسي‪ .‬عبر استدعاء التابع‬

‫)(‪ ،super‬سنكون قادرين على تحقيق ذلك‪.‬‬

‫عادة ما يُ ستخدم التابع )(‪ super‬ضمن التابع )(__‪َّ ،__init‬‬


‫ألنه المكان ال ذي س تحتاج في ه‬

‫على األرجح إلى إض افة بعض الوظ ائف الخاص ة إلى الص نف الف رعي قب ل إكم ال التهيئ ة من‬

‫الصنف األساسي‪.‬‬

‫لنض رب مثاًل لتوض يح ذل ك‪ ،‬دعن ا نع ِّدل الص نف الف رعي ‪ .Trout‬نظ ًرا َّ‬
‫ألن س مك الس لمون‬

‫َّ‬
‫المرقط من أس ماك المي اه العذب ة‪ ،‬فلنض ف متغ يرًا اس مه ‪ water‬إلى الت ابع )(__‪ ،__init‬ول ُنعط ه‬

‫القيمة "‪ ،"freshwater‬ولكن مع الحفاظ على باقي متغيرات ومعامالت الصنف األساسي‪:‬‬

‫‪...‬‬
‫‪class Trout(Fish):‬‬
‫‪def __init__(self, water = "freshwater"):‬‬
‫‪self.water = water‬‬
‫)‪super().__init__(self‬‬
‫‪...‬‬

‫لق د أع دنا تعري ف الت ابع )(__‪ __init‬في الص نف الف رعي ‪ ،Trout‬وغيرن ا س لوكه موازن ًة‬

‫بالت ابع )(__‪ __init‬المُ ع رَّ ف س ً‬


‫لفا في الص نف األساس ي ‪ .Fish‬الح ظ َّ‬
‫أنن ا اس تدعينا‬

‫▲‬ ‫|‬ ‫‪355‬‬


‫البرمجة بلغة بايثون‬ ‫مفهوم الوراثة في البرمجة‬

‫ً‬
‫راحة ض من الت ابع )(__‪ __init‬الخ اص‬ ‫الت ابع )(__‪ __init‬الخ اص بالص نف ‪ Fish‬ص‬

‫بالصنف ‪.Trout‬‬

‫بع د إع ادة تعري ف الت ابع‪ ،‬لم نع د بحاج ة إلى تمري ر ‪ first_name‬مع اماًل إلى ‪ ،Trout‬وفي‬

‫ح ال فعلن ا ذل ك‪ ،‬فس يؤدي ذل ك إلى إع ادة تع يين ‪ freshwater‬ب دالً من ذل ك‪ .‬س ُنهيِّ ئ بع د ذل ك‬

‫الخاصية ‪ first_name‬عن طريق استدعاء المتغير في الكائن خاصتنا‪.‬‬

‫ُأ‬
‫اآلن يمكنن ا اس تدعاء متغ يرات الص نف األساس ي ال تي ع ِّدت‪ ،‬وك ذلك اس تخدام المتغيِّ ر‬

‫الخاص بالصنف الفرعي‪:‬‬

‫‪...‬‬
‫)(‪terry = Trout‬‬

‫تهيئة االسم األول ‪#‬‬


‫"‪terry.first_name = "Terry‬‬

‫)(‪# super‬‬ ‫الخاص بالصنف األساسي عبر‬ ‫استخدام )(__‪__init‬‬


‫)‪print(terry.first_name + " " + terry.last_name‬‬
‫)‪print(terry.eyelids‬‬

‫استخدام )(__‪ __init‬المعاد تعريفها في الصنف الفرعي ‪#‬‬


‫)‪print(terry.water‬‬

‫استخدام التابع )(‪ swim‬الخاص بالصنف األساسي ‪#‬‬


‫)(‪terry.swim‬‬

‫سنحصل على المخرجات التالية‪:‬‬

‫‪Terry Fish‬‬
‫‪False‬‬
‫‪freshwater‬‬

‫▲‬ ‫|‬ ‫‪356‬‬


‫البرمجة بلغة بايثون‬ ‫مفهوم الوراثة في البرمجة‬

‫‪The fish is swimming.‬‬

‫ُتظهر المخرجات َّ‬


‫أن الك ائن ‪ terry‬المنس وخ من الص نف الف رعي ‪ Trout‬ق ادر على اس تخدام‬

‫المتغ ير ‪ water‬الخ اص بت ابع الص نف الف رعي )(__‪ ،__init‬إض افة إلى اس تدعاء المتغ يرات‬

‫‪ first_name‬و ‪ last_name‬و ‪ eyelids‬الخاص ة بالت ابع )(__‪ __init‬المُ ع رَّ ف في الص نف‬

‫األساسي ‪.Fish‬‬

‫يسمح لنا الت ابع )(‪ super‬المُ ض من في ب ايثون باس تخدام تواب ع الص نف األساس ي ح تى بع د‬

‫إعادة تعريف تلك التوابع في األصناف الفرعية‪.‬‬

‫تعددة (‪)Multiple Inheritance‬‬ ‫‪ .6‬الوراثة ُ‬


‫الم ِّ‬
‫المقصود بالوراث ة المتع ددة هي ق درة الص نف على أن ي رث الخاص يات والتواب ع من أك ثر من‬

‫ص نف أساس ي واح د‪ .‬ه ذا من ش أنه تقلي ل التك رار في ال برامج‪ ،‬ولكنَّه ق د يُ ِّ‬
‫عقد العم ل‪ ،‬ل ذلك يجب‬

‫استخدام هذا المفهوم بحذر‪.‬‬

‫فرعي ا ‪ Coral_reef‬ي رث من‬


‫ً‬ ‫إلظه ار كيفي ة عم ل الوراث ة المتع ِّددة‪ ،‬دعن ا ننش ئ ص ً‬
‫نفا‬

‫الصنفين ‪ Coral‬و ‪ .Sea_anemone‬يمكننا إنش اء ت ابع في ك ل ص نف أساس ي‪ ،‬ثم اس تخدام الكلم ة‬

‫المفتاحية ‪ pass‬في الصنف الفرعي ‪:Coral_reef‬‬

‫‪class Coral:‬‬

‫‪def community(self):‬‬
‫)"‪print("Coral lives in a community.‬‬

‫‪class Anemone:‬‬

‫‪def protect_clownfish(self):‬‬

‫▲‬ ‫|‬ ‫‪357‬‬


‫البرمجة بلغة بايثون‬ ‫مفهوم الوراثة في البرمجة‬

‫)"‪print("The anemone is protecting the clownfish.‬‬

‫‪class CoralReef(Coral, Anemone):‬‬


‫‪pass‬‬

‫يحت وي الص نف ‪ Coral‬على ت ابع يس مى )(‪ ،community‬وال ذي يطب ع س طرًا واح ًدا‪ ،‬بينم ا‬

‫يحت وي الص نف ‪ Anemone‬على ت ابع يس مى )(‪ ،protect_clownfish‬وال ذي يطب ع س طرًا آخ ر‪.‬‬

‫مرر الص نفين كالهم ا بين قوس ين في تعري ف الص نف ‪ ،CoralReef‬م ا يع ني َّ‬
‫أنه س يرث‬ ‫س ُن ِّ‬

‫الصنفين معً ا‪.‬‬

‫دعنا اآلن ننشئ كائنًا من الصنف ‪:CoralReef‬‬

‫‪...‬‬
‫)(‪great_barrier = CoralReef‬‬
‫)(‪great_barrier.community‬‬
‫)(‪great_barrier.protect_clownfish‬‬

‫الك ائن ‪ great_barrier‬مُ ش ٌ‬


‫تق الص نف ‪ ،CoralReef‬ويمكن ه اس تخدام التواب ع من كال‬

‫الصنفين األساسيين‪ .‬عند تنفيذ البرنامج‪ ،‬سنحصل على المخرجات التالية‪:‬‬

‫‪Coral lives in a community.‬‬


‫‪The anemone is protecting the clownfish.‬‬

‫أن التواب ع من كال الص نفين األساس يين اس ُتخدِ ما بفعالي ة في‬ ‫ُت ِ‬
‫ظه ر المخرج ات َّ‬

‫الصنف الفرعي‪.‬‬

‫ِّ‬
‫تعد دة بإعادة استخدام الشيفرات البرمجية المكتوبة في أكثر من ص نف‬ ‫تسمح لنا الوراثة المُ‬

‫أساسي واحد‪ .‬وإذا تم تعريف التابع نفسه في أكثر من ص نف أساس ي واح د‪ ،‬فسيس تخدم الص نف‬

‫▲‬ ‫|‬ ‫‪358‬‬


‫البرمجة بلغة بايثون‬ ‫مفهوم الوراثة في البرمجة‬

‫الف رعي الت ابع الخ اص بالص نف األساس ي ال ذي ظه ر أواًل في قائم ة األص ناف المُ م رَّ رة إلي ه‬

‫عند تعريفه‪.‬‬

‫أن علي ك ت وخي الح ذر في اس تخدام الوراث ة المُ تع ِّددة‪،‬‬


‫رغم فوائ دها الكث يرة وفعاليته ا‪ ،‬إال َّ‬

‫حتى ال ينتهي بك األمر بكتابة برامج مُ َّ‬


‫عقدة وغير مفهومة للمبرمجين اآلخرين‪.‬‬

‫‪ .7‬خالصة الفصل‬
‫وكيفية إع ادة تعري ف تواب ع‬
‫َّ‬ ‫وفرعية‪،‬‬
‫َّ‬ ‫كيفية إنش اء أص ناف أساس ية‬
‫َّ‬ ‫تعلمن ا في ه ذا الفص ل‬

‫وخاص يات األص ناف األساس ية داخ ل األص ناف الفرعي ة باس تخدام الت ابع )(‪ ،super‬إض افة إلى‬

‫مفهوم الوراثة المتعددة‪.‬‬

‫الوراثة هي إحدى أهم ميزات البرمجة الكائنية ال تي تجعله ا متوافق ة م ع مب دأ ‪( DRY‬ال تك رر‬

‫نفسك) ‪ ،‬وهذا يحسن إنتاجية المبرمجين‪ ،‬ويساعدهم على تصميم برامج فعالة وواضحة‪.‬‬

‫▲‬ ‫|‬ ‫‪359‬‬


‫‪20‬‬
‫التعددية الشكلية‬
‫وتطبيقاتها‬

‫▲‬ ‫|‬ ‫‪360‬‬


‫البرمجة بلغة بايثون‬ ‫التعددية الشكلية وتطبيقاتها‬

‫التعددية الشكلية (‪ )Polymorphism‬هي القدرة على اس تخدام واجه ة موح دة لع دة أش كال‬

‫مختلف ة‪ ،‬مث ل أن واع البيان ات أو األص ناف‪ ،‬وه ذا يس مح لل دوال باس تخدام كيان ات من‬

‫أن واع مختلف ة‪ .‬بالنس بة لل برامج الكائني ة في ب ايثون‪ ،‬ه ذا يع ني َّ‬


‫أنه يمكن اس تخدام ك ائن معين‬

‫ينتمي إلى ص نف مُ َّ‬


‫عين كم ا ل و ك ان ينتمي إلى ص نف مختل ف‪ .‬تس مح التعددي ة الش كلية بكتاب ة‬

‫شيفرات مرنة ومجرَّ َدة وسهلة التوسيع والصيانة‪.‬‬

‫سوف تتعلم في هذا الفصل كيفية تطبيق التعددية الشكلية على أصناف بايثون‪.‬‬

‫‪ .1‬ما هي التعددية الشكلية (‪)Polymorphism‬؟‬


‫التعددية الشكلية هي إحدى السمات األساسية لألصناف في بايثون‪ُ ،‬‬
‫وتستخ َدم عندما تك ون‬

‫هن اك تواب ع له ا نفس األس ماء في ع دة أص ناف‪ ،‬أو أص ناف فرعي ة‪ .‬يس مح ذل ك لل دوال باس تخدام‬

‫كائنات من أيٍّ من تلك األصناف والعمل عليها دون االكتراث لنوعها‪.‬‬

‫يمكن تنفي ذ التعددي ة الش كلية ع بر الوراث ة‪ ،‬أو باس تخدام تواب ِع األص ناف الفرعي ة‪ ،‬أو إع ادة‬

‫تعريفها (‪.)overriding‬‬

‫يس تخدم ب ايثون نظ ام أن واع (‪ )typing‬خ اص‪ ،‬يس مى «نظ ام التحق ق من األن واع‪ :‬البط ة‬

‫ً‬
‫نموذجا» (‪ ،)Duck Typing‬وه و حال ة خاص ة من أنظم ة التحق ق من األن واع الديناميكي ة‬

‫(‪ .)Dynamic Typing‬يس تخدم ه ذا النظ امُ التع ُّددي َة الش كلية‪ ،‬بم ا في ذل ك الرب ط المت أخر‬

‫(‪ ،)late binding‬واإليف اد ال ديناميكي (‪ .)Dynamic dispatch‬يعتم د ه ذا النظ ام على «نم وذج‬

‫اقتباس للكاتب جيمس ويتكومب رايلي‪:‬‬


‫ٍ‬ ‫بناء على‬
‫ً‬ ‫البطة»‬

‫«عن دما أرى ط ائ ًرا يمش ي مث ل بط ة‪ ،‬ويس بح مث ل بط ة‪ ،‬وص وته كص وت البط ة‪،‬‬

‫ً‬
‫بطة»‬ ‫فسأع ُّد هذا الطائر‬

‫▲‬ ‫|‬ ‫‪361‬‬


‫البرمجة بلغة بايثون‬ ‫التعددية الشكلية وتطبيقاتها‬

‫ُخ ِّ‬
‫صص ه ذا المفه وم من قب ل مهن دس الحاس وب اإليط الي أليكس م ارتيلي ( ‪)Alex Martelli‬‬

‫في رس الة إلى مجموع ة ‪ ،comp.lang.python‬يق وم نظ ام التحق ق من األن واع ه ذا ال ذي يعتم د‬

‫نموذج ا على تعري ف الك ائن من منظ ور مالءم ة الغ رض ال ذي ُأ ِ‬


‫نش ئ ألجل ه‪ .‬عن د اس تخدام‬ ‫ً‬ ‫البط ة‬

‫إن مالءم ة الك ائن لغ رض مُ َّ‬


‫عين يتح دد بن وع الك ائن فق ط‪ ،‬ولكن في نم وذج‬ ‫نظ ام أن واع ع ادي‪ ،‬ف َّ‬

‫البط ة‪ ،‬يَ تح َّدد ذل ك بوج ود التواب ع والخاص يات الض رورية ل ذلك الغ رض ب داًل من الن وع الحقيقي‬

‫ُّ‬
‫التحقق مم ا إذا ك ان ذل ك‬ ‫للك ائن‪ .‬بمع نى آخ ر‪ ،‬إذا أردت أن تع رف إن ك ان الك ائن بط ًة أم ال‪ ،‬فعلي ك‬

‫ً‬
‫بطة‪.‬‬ ‫مشي البطة‪ ،‬وصوته كصوت البطة‪ ،‬بداًل من أن تسأل عما إذا كان الكائن‬
‫َ‬ ‫الكائن يمشي‬

‫عندما تحتوي عدة أص ناف أو أص ناف فرعي ة على تواب ع له ا نفس األس ماء‪ ،‬ولكن بس لوكيات‬

‫إن تل ك األص ناف متع ِّددة األش كال ( ‪َّ )polymorphic‬‬


‫ألنه ا تس تعمل واجه ة موح دة‬ ‫مختلفة‪ ،‬نق ول َّ‬

‫يمكن استخدامها مع كيانات من أنواع مختلفة‪ .‬يمكن للدوال تقييم ومعالجة هذه التواب ع متع ِّددة‬

‫األشكال دون معرفة أصنافها‪.‬‬

‫‪ .2‬إنشاء أصناف متعددة األشكال‬


‫لالس تفادة من التَع ُّددي ة الش كلية‪ ،‬سننش ئ ص نفين مختلفين الس تخدامهما م ع ك ائنين‬

‫مختلفين‪ .‬يحتاج هذان الصنفان المختلفان إلى واجه ة موح دة يمكن اس تخدامها بطريق ة تع ُّددي ة‬

‫ِّ‬
‫سنعرف فيهما توابع مختلفة‪ ،‬ولكن لها نفس االسم‪.‬‬ ‫الشكل (‪ ،)polymorphically‬لذلك‬

‫نفا باس م ‪ Shark‬وص ُ‬


‫نفا آخ ر باس م ‪ ،Clownfish‬وس ُي ِّ‬
‫عرف ك ل منهم ا التواب ع‬ ‫سننش ئ ص ً‬

‫)(‪ swim‬و )(‪ swim_backwards‬و )(‪.skeleton‬‬

‫▲‬ ‫|‬ ‫‪362‬‬


‫البرمجة بلغة بايثون‬ ‫التعددية الشكلية وتطبيقاتها‬

‫‪class Shark():‬‬
‫‪def swim(self):‬‬
‫)"‪.‬القرش يسبح"(‪print‬‬

‫‪def swim_backwards(self):‬‬
‫ال يمكن للقرش أن يسبح إلى الوراء‪ ،‬لكن يمكنه أن يغوص "(‪print‬‬
‫)"‪.‬إلى الوراء‬

‫‪def skeleton(self):‬‬
‫)"‪.‬هيكل القرش مصنوع من الغضروف"(‪print‬‬

‫‪class Clownfish():‬‬
‫‪def swim(self):‬‬
‫)"‪.‬سمكة المهرج تسبح"(‪print‬‬

‫‪def swim_backwards(self):‬‬
‫)"‪.‬يمكن لسمكة المهرج أن تسبح إلى الخلف"(‪print‬‬

‫‪def skeleton(self):‬‬
‫)"‪.‬هيكل سمكة المهرج مصنوع من العظام"(‪print‬‬

‫بي د‬
‫في الش يفرة أعاله‪ ،‬ل دى الص نفين ‪ Shark‬و ‪ Clownfish‬ثالث ة تواب ع تحم ل نفس االس م ْ‬

‫أن وظائف تلك التوابع تختلف من صنف آلخر‪.‬‬


‫َّ‬

‫دعنا نستنسخ (‪ )instantiate‬من هذين الصنفين كائنين‪:‬‬

‫‪...‬‬
‫)(‪sammy = Shark‬‬
‫)(‪sammy.skeleton‬‬

‫)(‪casey = Clownfish‬‬
‫)(‪casey.skeleton‬‬

‫▲‬ ‫|‬ ‫‪363‬‬


‫البرمجة بلغة بايثون‬ ‫التعددية الشكلية وتطبيقاتها‬

‫أن‬
‫عند تنفيذ البرن امج باس تخدام األم ر ‪ ،python polymorphic_fish.py‬يمكنن ا أن ن رى َّ‬

‫كل كائن يتصرف كما هو متوقع‪:‬‬

‫‪.‬هيكل القرش مصنوع من الغضروف‬


‫‪.‬هيكل سمكة المهرج مصنوع من العظام‬

‫اآلن وقد أصبح لدينا كائنين يستخدمان نفس الواجه ة‪ ،‬فبمق دورنا اس تخدام ه ذين الك ائنين‬

‫بنفس الطريقة بغض النظر عن نوعيهما‪.‬‬

‫‪ .3‬التعددية الشكلية في توابع األصناف‬


‫إلظه ار كي ف يمكن لب ايثون اس تخدام الص نفين المختلفين الل ذين عرَّ فناهم ا أعاله بنفس‬

‫الطريقة‪ ،‬سننشئ أوالً حلقة ‪ ،for‬والتي ستمر على صف من الكائنات‪ .‬ثم سنستدعي التواب ع بغض‬

‫أن تلك التواب ع موج ودة في ك ل‬ ‫النظر عن نوع الصنف الذي ينتمي إليه كل كائن‪ .‬إال َّ‬
‫أننا سنفترض َّ‬

‫تلك األصناف‪.‬‬

‫‪...‬‬
‫)(‪sammy = Shark‬‬

‫)(‪casey = Clownfish‬‬

‫‪for fish in (sammy, casey):‬‬


‫)(‪fish.swim‬‬
‫)(‪fish.swim_backwards‬‬
‫)(‪fish.skeleton‬‬

‫ل دينا كائن ان‪ sammy ،‬من الص نف ‪ ،Shark‬و ‪ casey‬من الص نف ‪ .Clownfish‬تم ر حلق ة ‪for‬‬

‫▲‬ ‫|‬ ‫‪364‬‬


‫البرمجة بلغة بايثون‬ ‫التعددية الشكلية وتطبيقاتها‬

‫على ه ذين الك ائنين‪ ،‬وتس تدعي التواب ع )(‪ swim‬و )(‪ swim_backwards‬و )(‪ skeleton‬على‬

‫كل منها‪.‬‬

‫عند تنفيذ البرنامج‪ ،‬سنحصل على المخرجات التالية‪:‬‬

‫‪.‬القرش يسبح‬
‫‪.‬ال يمكن للقرش أن يسبح إلى الوراء‪ ،‬لكن يمكنه أن يغوص إلى الوراء‬
‫‪.‬هيكل القرش مصنوع من الغضروف‬
‫‪.‬سمكة المهرج تسبح‬
‫‪.‬يمكن لسمكة المهرج أن تسبح إلى الخلف‬
‫‪.‬هيكل سمكة المهرج مصنوع من العظام‬

‫مرت الحلق ة ‪ for‬على الك ائن ‪ sammy‬من الص نف ‪ ،Shark‬ثم على الك ائن ‪ casey‬المنتمي إلى‬

‫الص نف ‪ ،Clownfish‬ل ذلك ن رى التواب ع الخاص ة بالص نف ‪ Shark‬قب ل التواب ع الخاص ة‬

‫بالصنف ‪.Clownfish‬‬

‫أن ب ايثون تس تخدم ه ذه التواب ع دون أن تع رف أو تعب أ بتحدي د ن وع الص نف‬ ‫ي ُّ‬
‫دل ه ذا على َّ‬

‫ِّ‬
‫تعد َدة األشكال‪.‬‬ ‫الخاص بالكائنات‪ .‬وهذا مثال حي على استخدام التوابع بطريقة مُ‬

‫‪ .4‬التعددية الشكلية في الدوال‬


‫أي شيء‪ ،‬وهذا سيسمح باستخدام التعددية الشكلية‪.‬‬ ‫ً‬
‫أيضا إنشاء دالة تقبل ٌّ‬ ‫يمكننا‬

‫لننشئ دال ة تس مى )(‪ ،in_the_pacific‬وال تي تأخ ذ كائ ًن ا يمكنن ا تس ميته ‪ .fish‬رغم َّ‬
‫أنن ا‬

‫سنستخدم االسم ‪ ،fish‬إال َّ‬


‫أنه يمكننا استدعاء أي كائن في هذه الدالة‪:‬‬

‫…‬
‫‪def in_the_pacific(fish):‬‬

‫بع د ذل ك‪ ،‬س نجعل الدال ة تس تخدم الك ائن ‪ fish‬ال ذي مرَّ رن اه إليه ا‪ .‬وفي ه ذه الحال ة‪،‬‬

‫▲‬ ‫|‬ ‫‪365‬‬


‫البرمجة بلغة بايثون‬ ‫التعددية الشكلية وتطبيقاتها‬

‫ِّ‬
‫المعرف في كل من الصنفين ‪ Shark‬و ‪:Clownfish‬‬ ‫سنستدعي التابع )(‪swim‬‬

‫‪...‬‬
‫‪def in_the_pacific(fish):‬‬
‫)(‪fish.swim‬‬

‫ِّ‬
‫لنمررهم ا بع د‬ ‫ً‬
‫نسخا (‪ )instantiations‬من الص نفين ‪ Shark‬و ‪Clownfish‬‬ ‫بعد ذلك‪ ،‬سننشئ‬

‫ذلك إلى نفس الدالة )(‪:in_the_pacific‬‬

‫‪...‬‬
‫‪def in_the_pacific(fish):‬‬
‫)(‪fish.swim‬‬

‫)(‪sammy = Shark‬‬

‫)(‪casey = Clownfish‬‬

‫)‪in_the_pacific(sammy‬‬
‫)‪in_the_pacific(casey‬‬

‫عند تنفيذ البرنامج‪ ،‬سنحصل على المخرجات التالية‪:‬‬

‫‪.‬القرش يسبح‬
‫‪.‬سمكة المهرج تسبح‬

‫عشوائيا (‪ )fish‬إلى الدالة )(‪ in_the_pacific‬عند تعريفها‪ ،‬إال َّ‬


‫أننا ما‬ ‫ً‬ ‫رغم أننا مرَّ رنا كائنًا‬

‫زلن ا ق ادرين على اس تخدامها اس تخدامً ا فع ااًل ‪ ،‬وتمري ر نس خ من الص نفين ‪ Shark‬و ‪Clownfish‬‬

‫ائن ‪ casey‬الت ابعَ )(‪ swim‬المُ ع رَّ ف في الص نف ‪ ،Clownfish‬فيم ا اس تدعى‬


‫إليه ا‪ .‬اس تدعى الك ُ‬

‫الكائن ‪ sammy‬التابعَ )(‪ swim‬المُ عرَّ ف في الصنف ‪.Shark‬‬


‫ُ‬

‫▲‬ ‫|‬ ‫‪366‬‬


‫البرمجة بلغة بايثون‬ ‫التعددية الشكلية وتطبيقاتها‬

‫‪ .5‬خالصة الفصل‬
‫تس مح التع ُّددي ة الش كلية باس تخدام الكائن ات بغض النظ ر عن نوعه ا‪ ،‬وه ذا ي وفر لب ايثون‬

‫مرونة كبيرة‪ ،‬وقابلية لتوسيع الشيفرة الكائنية‪.‬‬

‫▲‬ ‫|‬ ‫‪367‬‬


‫‪21‬‬
‫تنقيح الشيفرات‪:‬‬
‫ِّ‬
‫منقح‬ ‫استخدام‬
‫بايثون‬

‫▲‬ ‫|‬ ‫‪368‬‬


‫البرمجة بلغة بايثون‬ ‫تنقيح الشيفرات‪ :‬استخدام ِّ‬
‫منقح بايثون‬

‫التنقيح (‪– )debugging‬في تط وير البرمجي ات– هي عملي ة البحث عم ح ل المش اكل ال تي‬

‫تمن ع عم ل البرمجي ة عماًل س ليمً ا‪ .‬ي ِّ‬


‫وفر ِّ‬
‫منقح ب ايثون ( ‪ )Python Debugger‬بيئ ة متكامل ة لتنقيح‬

‫ب رامج ب ايثون‪ ،‬إذ ت دعم ض بط مواض ع التوق ف (‪ )breakpoints‬الش رطية‪ ،‬وتنفي ذ الش يفرات‬

‫ِّ‬
‫مكدس (‪ )stack‬االستدعاء‪ ،‬وخالف ذلك‪.‬‬ ‫المصدرية سطرً ا بسطر‪ ،‬وتفحص‬

‫تفاعليا‬
‫ً‬ ‫‪ .1‬تشغيل منقح بايثون‬
‫جزءا من تث بيت ب ايثون القياس ي بش كل وح دة باس م ‪ .pdb‬يمكن توس عة‬
‫ً‬ ‫يأتي ِّ‬
‫منقح بايثون‬

‫ِّ‬
‫المنقح بمزيد من الوظائف‪ ،‬ويُ عرَّ ف بالصنف ‪ .Pdb‬يمكنك الع ودة إلى التوثي ق الرس مي للمنقح ‪pdb‬‬

‫امج قص ير يحت وي على متغ يرين ع امين‬


‫ٍ‬ ‫لمزي دٍ من المعلوم ات‪ .‬س نبدأ تجاربن ا م ع برن‬

‫(‪ )global variables‬ودال ة (‪ )function‬ال تي تحت وي على حلق ة تك رار ‪ for‬متش ِّعبة‪ ،‬والبني ة‬

‫الشهيرة ‪ if __name__ == '__main__':‬التي تستدعي الدالة )(‪:nested_loop‬‬

‫]‪num_list = [500, 600, 700‬‬


‫]'‪alpha_list = ['x', 'y', 'z‬‬

‫‪def nested_loop():‬‬
‫‪for number in num_list:‬‬
‫)‪print(number‬‬
‫‪for letter in alpha_list:‬‬
‫)‪print(letter‬‬

‫‪if __name__ == '__main__':‬‬


‫)(‪nested_loop‬‬

‫▲‬ ‫|‬ ‫‪369‬‬


‫البرمجة بلغة بايثون‬ ‫تنقيح الشيفرات‪ :‬استخدام ِّ‬
‫منقح بايثون‬

‫يمكننا اآلن تشعيل البرنامج باستخدام منقح بايثون عبر األمر اآلتي‪:‬‬

‫‪python -m pdb looping.py‬‬

‫سيؤدي استخدام خي ار س طر األوام ر ‪ -m‬إلى اس تيراد أي وح دة ب ايثون تري دها‪ ،‬وفي حالتن ا‬

‫فسنستورد الوحدة ‪ ،pdb‬والتي س نمررها إلى الخي ار ‪ -m‬كم ا ه و م بيِّ ن في األم ر الس ابق‪ .‬ستحص ل‬

‫على الناتج اآلتي بعد تنفيذك لألمر السابق‪:‬‬

‫)(>‪> /Users/sammy/looping.py(1)<module‬‬
‫]‪-> num_list = [500, 600, 700‬‬
‫)‪(Pdb‬‬

‫حالي ا (كم ا ه و‬
‫ً‬ ‫الحظن ا في أول س طر من المخرج ات احت واءه على اس م الوح دة ال تي َّ‬
‫تنفذ‬

‫موضح بالكلم ة <‪ >module‬م ع كام ل مس ار الس كربت‪ ،‬ويلي ه رقم الس طر ال تي ُن ِّفذ أول م رة (وفي‬

‫هذه الحالة سيكون الرقم ‪ ،1‬لكن ق د توج د تعليق ات أو أس طر غ ير قابل ة للتنفي ذ في بداي ة المل ف‪،‬‬

‫لذا قد يكون الرقم أكبر في بعض الحاالت)‪.‬‬

‫حالي ا‪ ،‬ولمَّ ا كنَّا ق د ش غلنا المنقح ‪pdb‬‬


‫ً‬ ‫ظه ر الس طر الث اني م ا ه و الس طر الح الي ال ذي يُ َّ‬
‫نفذ‬ ‫يُ ِ‬

‫تفاعلي ا فس يوفر لن ا س طر أوام ر تف اعلي للتنقيح‪ .‬ويمكن ك كتاب ة األم ر ‪ help‬للتع رف على األوام ر‬
‫ً‬

‫معين‪.‬‬
‫َّ‬ ‫أمر‬
‫الخاصة بالمنقح‪ ،‬و ‪ help command‬لمزيد من المعلومات حول ٍ‬

‫أن منقح ب ايثون‬


‫الحظ أن سطر أوام ر ‪ pdb‬يختل ف عن الوض ع التف اعلي في ب ايثون‪ ،‬والح ظ َّ‬

‫تلقائيا؛ لذا يمكنك استخدام األم ر ‪ quit‬أو ‪exit‬‬


‫ً‬ ‫سيبدأ من جديد حين وصوله إلى نهاية البرنامج‬

‫وقت تري د للخ روج من المنقح‪ .‬أمَّ ا إذا أردت إع ادة تش غيل المنقح من بداي ة البرن امج‬
‫ٍ‬ ‫في أي‬

‫مجد ًدا‪ ،‬فيمكنك استعمال األمر ‪.run‬‬

‫▲‬ ‫|‬ ‫‪370‬‬


‫البرمجة بلغة بايثون‬ ‫تنقيح الشيفرات‪ :‬استخدام ِّ‬
‫منقح بايثون‬

‫‪ .2‬استخدام المنقح للتنقل ضمن البرنامج‬


‫من الش ائع أثن اء عمل ك م ع منقح ب ايثون أن تس تعمل األوام ر ‪ list‬و ‪ step‬و ‪ next‬للتح رك‬

‫ضمن الشيفرة‪ .‬سنشرح هذه األوامر في ه ذا القس م‪ .‬يمكنن ا كتاب ة األم ر ‪ list‬ض من منقح ب ايثون‬

‫التف اعلي للحص ول على الش يفرات المحيط ة بالس طر الح الي‪ ،‬فل و نف ذناه عن د الس طر األول من‬

‫برنامج ‪ looping.py‬فستبدو المخرجات كما يلي‪:‬‬

‫‪(Pdb) list‬‬
‫‪1‬‬ ‫]‪-> num_list = [500, 600, 700‬‬
‫‪2‬‬ ‫]'‪alpha_list = ['x', 'y', 'z‬‬
‫‪3‬‬
‫‪4‬‬
‫‪5‬‬ ‫‪def nested_loop():‬‬
‫‪6‬‬ ‫‪for number in num_list:‬‬
‫‪7‬‬ ‫)‪print(number‬‬
‫‪8‬‬ ‫‪for letter in alpha_list:‬‬
‫‪9‬‬ ‫)‪print(letter‬‬
‫‪10‬‬
‫‪11‬‬ ‫‪if __name__ == '__main__':‬‬
‫)‪(Pdb‬‬

‫يُ شار إلى السطر الحالي بالمحرفين >‪ -‬اللذين يشيران في حالتنا إلى أول سطر من البرنامج‪.‬‬

‫ولمَّ ا ك ان برنامجن ا قص ي ًرا‪ ،‬فسنحص ل على كام ل البرن امج عن د اس تخدام األم ر ‪ .list‬فحين‬

‫ً‬
‫محيط ا بالس طر الح الي‪ ،‬لكن‬ ‫اس تخدام األم ر ‪ list‬دون أيَّ ة وس ائط‪ ،‬فس يعرض أح د عش ر س ط ًرا‬

‫يمكننا تحديد ما هي األسطر التي نريد عرضها كما يلي‪:‬‬

‫▲‬ ‫|‬ ‫‪371‬‬


‫البرمجة بلغة بايثون‬ ‫تنقيح الشيفرات‪ :‬استخدام ِّ‬
‫منقح بايثون‬

‫‪(Pdb) list 3, 7‬‬


‫‪3‬‬
‫‪4‬‬
‫‪5‬‬ ‫‪def nested_loop():‬‬
‫‪6‬‬ ‫‪for number in num_list:‬‬
‫‪7‬‬ ‫)‪print(number‬‬
‫)‪(Pdb‬‬

‫طلبن ا في المث ال الس ابق أن يع رض المنقح األس طر ‪ 3‬إلى ‪ ،7‬وذل ك باس تخدام األم ر‬

‫‪ .list 3, 7‬للتنقل عبر البرنامج سط ًرا بسطر‪ ،‬فيمكننا استخدام األمر ‪ step‬أو ‪:next‬‬

‫‪(Pdb) step‬‬
‫)(>‪> /Users/sammy/looping.py(2)<module‬‬
‫]'‪-> alpha_list = ['x', 'y', 'z‬‬
‫)‪(Pdb‬‬
‫‪(Pdb) next‬‬
‫)(>‪> /Users/sammy/looping.py(2)<module‬‬
‫]'‪-> alpha_list = ['x', 'y', 'z‬‬
‫)‪(Pdb‬‬

‫أن ‪ step‬س تتوقف داخ ل دال ة ج رى اس تدعاؤها‪ ،‬أم ا ‪next‬‬


‫الف رق بين ‪ step‬و ‪ next‬ه و َّ‬

‫فس ِّ‬
‫تنفذ ال دوال وتتوق ف في الس طر الت الي من تنفي ذ الدال ة‪ .‬س نرى ه ذا الف رق رأي العين حين‬

‫نتعام ل م ع الدال ة الموج ودة في برنامجن ا‪ .‬األم ر ‪ step‬س يمر على الحلق ات خط ً‬
‫وة خط وة ح تى‬

‫يص ل إلى نهاي ة الدال ة‪ ،‬مم ا يُ ِ‬


‫ظه ر م ا ال ذي تفعل ه الحلق ة تمامً ا‪ ،‬إذ س نبدأ بطباع ة ال رقم‬

‫)‪ print(number‬ثم ننطلق إلى طباعة األحرف )‪ print(letter‬ثم نعود إلى الرقم وهكذا‪.‬‬

‫‪(Pdb) step‬‬
‫)(>‪> /Users/sammy/looping.py(5)<module‬‬
‫‪-> def nested_loop():‬‬
‫‪(Pdb) step‬‬

‫▲‬ ‫|‬ ‫‪372‬‬


‫البرمجة بلغة بايثون‬ ِّ ‫ استخدام‬:‫تنقيح الشيفرات‬
‫منقح بايثون‬

> /Users/sammy/looping.py(11)<module>()
-> if __name__ == '__main__':
(Pdb) step
> /Users/sammy/looping.py(12)<module>()
-> nested_loop()
(Pdb) step
--Call--
> /Users/sammy/looping.py(5)nested_loop()
-> def nested_loop():
(Pdb) step
> /Users/sammy/looping.py(6)nested_loop()
-> for number in num_list:
(Pdb) step
> /Users/sammy/looping.py(7)nested_loop()
-> print(number)
(Pdb) step
500
> /Users/sammy/looping.py(8)nested_loop()
-> for letter in alpha_list:
(Pdb) step
> /Users/sammy/looping.py(9)nested_loop()
-> print(letter)
(Pdb) step
x
> /Users/sammy/looping.py(8)nested_loop()
-> for letter in alpha_list:
(Pdb) step
> /Users/sammy/looping.py(9)nested_loop()
-> print(letter)
(Pdb) step
y
> /Users/sammy/looping.py(8)nested_loop()
-> for letter in alpha_list:

▲ | 373
‫البرمجة بلغة بايثون‬ ِّ ‫ استخدام‬:‫تنقيح الشيفرات‬
‫منقح بايثون‬

(Pdb)

ِّ ‫ فس‬next ‫أمَّ ا األم ر‬


ً ‫ينفذ الدال ة بأكمله ا دون أن يرين ا العملي ة خط‬
‫ لنغل ق الجلس ة‬.‫وة بخط وة‬

ِّ
:‫المنقح مجد ًدا‬ ِّ ‫ ثم ُن‬exit ‫الحالية باستخدام األمر‬
‫شغل‬

python -m pdb looping.py

:next ‫يمكننا اآلن تجربة األمر‬

(Pdb) next
> /Users/sammy/looping.py(5)<module>()
-> def nested_loop():
(Pdb) next
> /Users/sammy/looping.py(11)<module>()
-> if __name__ == '__main__':
(Pdb) next
> /Users/sammy/looping.py(12)<module>()
-> nested_loop()
(Pdb) next
500
x
y
z
600
x
y
z
700
x
y
z
--Return--
> /Users/sammy/looping.py(12)<module>()->None

▲ | 374
‫البرمجة بلغة بايثون‬ ‫تنقيح الشيفرات‪ :‬استخدام ِّ‬
‫منقح بايثون‬

‫)(‪-> nested_loop‬‬
‫)‪(Pdb‬‬

‫تفحص القيم المُ سنَدة إلى المتغيرات أثناء مرورك على الشيفرة‪ ،‬ويمكنك فع ل‬
‫ُّ‬ ‫قد ترغب في‬

‫ذلك باستخدام األمر ‪ ،pp‬والذي يطبع قيمة التعبير المُ مرَّ ر إليه باستخدام الوحدة ‪:pprint‬‬

‫‪(Pdb) pp num_list‬‬
‫]‪[500, 600, 700‬‬
‫)‪(Pdb‬‬

‫تمل ك أغلبي ة األوام ر في المنقح ‪ pdb‬اختص ارات له ا‪ ،‬فمثاًل الش كل المختص ر من األم ر ‪step‬‬

‫ه و ‪ ،s‬والمختص ر من ‪ next‬ه و ‪ .n‬س يعرض ل ك األم ر ‪ help‬قائم ة االختص ارات المتاح ة‪ .‬يمكن ك‬

‫أيضا إعادة استدعاء آخر أمر ُن ِّفذ في المنقح بالضغط على زر اإلدخال ‪.Enter‬‬
‫ً‬

‫‪ .3‬نقاط التوقف‬
‫من المرجح َّ‬
‫أنك ستعمل على برمجيات أكبر بكثير من المثال الس ابق‪ ،‬ل ذا ق د ت رغب بتفحص‬

‫دوال أو أس طر معين ة ب داًل من الم رور على كام ل البرن امج‪ ،‬ويمكن ك أن تض بط نق اط التوق ف‬

‫(‪ )breakpoints‬باس تخدام األم ر ‪ ،break‬فس يعمل البرن امج ح تى نقط ة التوق ف المح ددة‪ .‬عن دما‬

‫تضيف نقطة توق ف فسيس ند المنقح رقمً ا إليه ا‪ ،‬وه ذه األرق ام متتالي ة وتب دأ من ‪ ،1‬وال تي يمكن ك‬

‫االستفادة منها حين التعامل مع نقاط التوقف‪ .‬يمكن إضافة نقاط توقف في أسطر برمجية معين ة‬

‫باستخدام الصيغة اآلتية في منقح ‪ pdb‬على الشكل <‪:>program_file>:<line_number‬‬

‫‪(Pdb) break looping.py:5‬‬


‫‪Breakpoint 1 at /Users/sammy/looping.py:5‬‬
‫)‪(Pdb‬‬

‫اكتب ‪ clear‬ثم ‪ y‬إلزال ة جمي ع نق اط التوق ف الحالي ة‪ ،‬يمكن ك بع دها أن تض ع نقط ة توق ف‬

‫▲‬ ‫|‬ ‫‪375‬‬


‫البرمجة بلغة بايثون‬ ‫تنقيح الشيفرات‪ :‬استخدام ِّ‬
‫منقح بايثون‬

‫مكان تعريف الدالة‪:‬‬

‫‪(Pdb) break looping.nested_loop‬‬


‫‪Breakpoint 1 at /Users/sammy/looping.py:5‬‬
‫)‪(Pdb‬‬

‫إلزال ة نق اط التوق ف الحالي ة‪ ،‬اكتب ‪ clear‬ثم ‪ y‬مج د ًدا‪ .‬يج در بال ذكر َّ‬
‫أنك تس تطيع أن‬

‫ً‬
‫شرطا‪:‬‬ ‫تضيف‬

‫‪(Pdb) break looping.py:7, number > 500‬‬


‫‪Breakpoint 1 at /Users/sammy/looping.py:7‬‬
‫)‪(Pdb‬‬

‫حينما نستعمل اآلن األمر ‪ continue‬فسيتوقف تنفيذ البرنامج عندما تكون قيمة الرقم أكبر‬

‫من ‪( 500‬أي عندما يكون مساويًا إلى ‪ ،600‬وذلك في الدورة الثانية لحلقة التكرار الخارجية)‪:‬‬

‫‪(Pdb) continue‬‬
‫‪500‬‬
‫‪x‬‬
‫‪y‬‬
‫‪z‬‬
‫)(‪> /Users/sammy/looping.py(7)nested_loop‬‬
‫)‪-> print(number‬‬
‫)‪(Pdb‬‬

‫لرؤي ة قائم ة من نق اط التوق ف ال تي ض بطت‪ ،‬فيمكن ك أن تس تعمل األم ر ‪ break‬دون أي‬

‫وسائط‪ ،‬وستحصل على معلومات حول نقاط التوقف جميعها التي ضبطتها‪:‬‬

‫‪(Pdb) break‬‬
‫‪Num Type‬‬ ‫‪Disp Enb‬‬ ‫‪Where‬‬
‫‪1‬‬ ‫‪breakpoint‬‬ ‫‪keep yes‬‬ ‫‪at /Users/sammy/looping.py:7‬‬
‫‪stop only if number > 500‬‬

‫▲‬ ‫|‬ ‫‪376‬‬


‫البرمجة بلغة بايثون‬ ِّ ‫ استخدام‬:‫تنقيح الشيفرات‬
‫منقح بايثون‬

breakpoint already hit 2 times


(Pdb)

ً
‫ إذ‬.‫ م ع رقم نقط ة التوق ف‬disable ‫أيض ا تعطي ل نقط ة توق ف باس تخدام األم ر‬ ‫يمكن ك‬

ِّ ‫سنضيف في هذا المثال نقطة توقف جديدة ثم‬


:‫نعطل أول نقطة توقف‬

(Pdb) break looping.py:11


Breakpoint 2 at /Users/sammy/looping.py:11
(Pdb) disable 1
Disabled breakpoint 1 at /Users/sammy/looping.py:7
(Pdb) break
Num Type Disp Enb Where
1 breakpoint keep no at /Users/sammy/looping.py:7
stop only if number > 500
breakpoint already hit 2 times
2 breakpoint keep yes at /Users/sammy/looping.py:11
(Pdb)

‫كلي ا فاس تخدم‬


ً ‫ وإلزال ة نقط ة التوق ف‬،enable ‫ اس تخدم األم ر‬،‫لتفعي ل نقط ة توق ف‬

:clear ‫األمر‬

(Pdb) enable 1
Enabled breakpoint 1 at /Users/sammy/looping.py:7
(Pdb) clear 2
Deleted breakpoint 2 at /Users/sammy/looping.py:11
(Pdb)

ً
‫ وهنال ك وظ ائف إض افية له ا‬،‫دقيق ا في عملي ة التنقيح‬ ‫ تحكمً ا‬pdb ‫تمنحك نقاط التوقف في‬

‫ (كم ا في‬ignore ‫تتضمن تجاهل نقاط التوقف في الجلس ة الحالي ة من البرن امج باس تخدام األم ر‬

‫ (كم ا في األمر‬command ‫ وتشغيل إجراءات في نقاط التوقف باس تخدام األم ر‬،)ignore 1 ‫األمر‬

▲ | 377
‫البرمجة بلغة بايثون‬ ‫تنقيح الشيفرات‪ :‬استخدام ِّ‬
‫منقح بايثون‬

‫تلقائي ا بع د الوص ول إليه ا وذل ك باس تخدام‬


‫ً‬ ‫حذف‬ ‫َّ‬
‫مؤقت ة س ُت َ‬ ‫‪ ،)command 1‬وإنش اء نق اط توق ف‬

‫األمر ‪( tbreak‬فلو أردنا إنشاء نقطة توقف مؤقتة في السطر الثالث مثاًل ‪ ،‬نكتب ‪.)tbreak 3‬‬

‫‪ .4‬دمج ‪ pdb‬مع البرامج‬


‫يمكن ك أن تب دأ جلس ة التنقيح باس تيراد الوح دة ‪ pdb‬وإض افة الدال ة )(‪pdb.set_trace‬‬

‫قبل السطر الذي تريد بدء جلسة التنقيح منه‪ .‬إذ سنضيف في مثالن ا الس ابق عب ارة ‪ import‬ونب دأ‬

‫عملية التنقيح داخل الدالة قبل حلقة التكرار الداخلية‪:‬‬

‫اسيتراد الوحدة ‪#‬‬


‫‪import pdb‬‬

‫]‪num_list = [500, 600, 700‬‬


‫]'‪alpha_list = ['x', 'y', 'z‬‬

‫‪def nested_loop():‬‬
‫‪for number in num_list:‬‬
‫)‪print(number‬‬

‫تشغيل المنقح هنا ‪#‬‬


‫)(‪pdb.set_trace‬‬
‫‪for letter in alpha_list:‬‬
‫)‪print(letter‬‬

‫‪if __name__ == '__main__':‬‬


‫)(‪nested_loop‬‬

‫ِّ‬
‫المنقح إلى ش يفرتك‪ ،‬فلن تحت اج إلى تش غيل برنامج ك بطريق ة خاص ة‪ ،‬أو ت ذكر‬ ‫بإض افة‬

‫ضبط نقاط التوقف‪ .‬يسمح لك اس تيراد الوح دة ‪ pdb‬واس تدعاء الدال ة )(‪ pdb.set_trace‬بب دء‬

‫▲‬ ‫|‬ ‫‪378‬‬


‫البرمجة بلغة بايثون‬ ‫تنقيح الشيفرات‪ :‬استخدام ِّ‬
‫منقح بايثون‬

‫ِّ‬
‫المنقح أثناء تنفيذ البرنامج‪.‬‬ ‫برنامج مثل المعتاد‪ ،‬وتشغيل‬

‫‪ .5‬تعديل تسلسل تنفيذ البرنامج‬


‫يسمح لن ا منقح ب ايثون بتغي ير تسلس ل تنفي ذ البرن امج باس تخدام األم ر ‪ ،jump‬وه ذا يس مح‬

‫معينة‪ ،‬أو يمكنك العودة إلى الخلف وتنفي ذ‬


‫َّ‬ ‫لك باالنتقال إلى األمام في تنفيذ البرنامج لمنع شيفرة‬

‫نش ئ قائم ًة ‪ list‬من الح روف الموج ودة في‬ ‫ً‬


‫مرة أخرى‪ .‬س نعمل هن ا م ع برن امج بس يط يُ ِ‬ ‫الشيفرة‬

‫المتغير "‪:sammy = "sammy‬‬

‫‪def print_sammy():‬‬
‫][ = ‪sammy_list‬‬
‫"‪sammy = "sammy‬‬
‫‪for letter in sammy:‬‬
‫)‪sammy_list.append(letter‬‬
‫)‪print(sammy_list‬‬

‫‪if __name__ == "__main__":‬‬


‫)(‪print_sammy‬‬

‫إذا شغلنا البرنامج بالشكل المعت اد باس تخدام األم ر ‪ python letter_list.py‬فسنحص ل‬

‫على الناتج اآلتي‪:‬‬

‫]'‪['s‬‬
‫]'‪['s', 'a‬‬
‫]'‪['s', 'a', 'm‬‬
‫]'‪['s', 'a', 'm', 'm‬‬
‫]'‪['s', 'a', 'm', 'm', 'y‬‬

‫أمَّ ا مع منقح بايثون‪ ،‬فس نرى كي ف يمكنن ا تغي ير ت رتيب التنفي ذ بتخطي أول دورة من تنفي ذ‬

‫تغير ترتيب تنفيذ الشيفرة‪:‬‬


‫حلقة التكرار‪ ،‬وعندما نفعل ذلك‪ ،‬فسنالحظ كيف َّ‬

‫▲‬ ‫|‬ ‫‪379‬‬


‫البرمجة بلغة بايثون‬ ِّ ‫ استخدام‬:‫تنقيح الشيفرات‬
‫منقح بايثون‬

python -m pdb letter_list.py


> /Users/sammy/letter_list.py(1)<module>()
-> def print_sammy():
(Pdb) list
1 -> def print_sammy():
2 sammy_list = []
3 sammy = "sammy"
4 for letter in sammy:
5 sammy_list.append(letter)
6 print(sammy_list)
7
8 if __name__ == "__main__":
9 print_sammy()
10
11
(Pdb) break 5
Breakpoint 1 at /Users/sammy/letter_list.py:5
(Pdb) continue
> /Users/sammy/letter_list.py(5)print_sammy()
-> sammy_list.append(letter)
(Pdb) pp letter
's'
(Pdb) continue
['s']
> /Users/sammy/letter_list.py(5)print_sammy()
-> sammy_list.append(letter)
(Pdb) jump 6
> /Users/sammy/letter_list.py(6)print_sammy()
-> print(sammy_list)
(Pdb) pp letter
'a'
(Pdb) disable 1
Disabled breakpoint 1 at /Users/sammy/letter_list.py:5

▲ | 380
‫البرمجة بلغة بايثون‬ ‫تنقيح الشيفرات‪ :‬استخدام ِّ‬
‫منقح بايثون‬

‫‪(Pdb) continue‬‬
‫]'‪['s‬‬
‫]'‪['s', 'm‬‬
‫]'‪['s', 'm', 'm‬‬
‫]'‪['s', 'm', 'm', 'y‬‬

‫جلسة التنقيح السابقة تضع نقطة توقف في السطر الخامس لمن ع المنقح من تنفي ذ الش يفرة‬

‫التي تلي هذه النقطة‪ ،‬ثم تكمل تنفيذ الشيفرة (مع طباعة قيمة ‪ letter‬لنرى ما الذي يحدث) ‪ ،‬ثمَّ‬

‫سنس تخدم األم ر ‪ jump‬للتخطي إلى الس طر الس ادس‪ ،‬وفي ه ذه النقط ة ك انت قيم ة‬

‫المتغير ‪ letter‬تساوي السلسلة النصية '‪ ،'a‬لكنن ا لمَّ ا تجاوزن ا الش يفرة‪ ،‬فلن تض اف ه ذه القيم ة‬

‫إلى القائم ة (‪ )list‬المس ماة ‪ ،sammy_list‬ومن بع دها عطلن ا نقط ة التوق ف لالس تمرار في تنفي ذ‬

‫طبيعيا باستخدام األمر ‪ ،continue‬وكانت النتيجة هي عدم إض افة الح رف '‪'a‬‬


‫ً‬ ‫ً‬
‫تنفيذا‬ ‫البرنامج‬

‫إلى القائمة ‪.sammy_list‬‬

‫يمكنن ا اآلن إع ادة تش غيل المنقح للع ودة إلى البرن امج وإع ادة تش غيل األم ر البرمجي ة ال تي‬

‫ِّ‬
‫المنقح‪:‬‬ ‫ً‬
‫مسبقا‪ ،‬وفي هذه المرة سنشغل أول حلقة تكرار في ‪ for‬في‬ ‫جرى تنفيذه‬

‫)(>‪> /Users/sammy/letter_list.py(1)<module‬‬
‫‪-> def print_sammy():‬‬
‫‪(Pdb) list‬‬
‫‪1‬‬ ‫‪-> def print_sammy():‬‬
‫‪2‬‬ ‫][ = ‪sammy_list‬‬
‫‪3‬‬ ‫"‪sammy = "sammy‬‬
‫‪4‬‬ ‫‪for letter in sammy:‬‬
‫‪5‬‬ ‫)‪sammy_list.append(letter‬‬
‫‪6‬‬ ‫)‪print(sammy_list‬‬
‫‪7‬‬
‫‪8‬‬ ‫‪if __name__ == "__main__":‬‬

‫▲‬ ‫|‬ ‫‪381‬‬


‫البرمجة بلغة بايثون‬ ِّ ‫ استخدام‬:‫تنقيح الشيفرات‬
‫منقح بايثون‬

9 print_sammy()
10
11
(Pdb) break 6
Breakpoint 1 at /Users/sammy/letter_list.py:6
(Pdb) continue
> /Users/sammy/letter_list.py(6)print_sammy()
-> print(sammy_list)
(Pdb) pp letter
's'
(Pdb) jump 5
> /Users/sammy/letter_list.py(5)print_sammy()
-> sammy_list.append(letter)
(Pdb) continue
> /Users/sammy/letter_list.py(6)print_sammy()
-> print(sammy_list)
(Pdb) pp letter
's'
(Pdb) disable 1
Disabled breakpoint 1 at /Users/sammy/letter_list.py:6
(Pdb) continue
['s', 's']
['s', 's', 'a']
['s', 's', 'a', 'm']
['s', 's', 'a', 'm', 'm']
['s', 's', 'a', 'm', 'm', 'y']

‫ ثم «قفزن ا» إلى الس طر‬،‫أض فنا في جلس ة التنقيح الس ابقة نقط ة توق ف في الس طر الس ادس‬

‫' ق د أض يفت م رتين إلى القائم ة‬s' ‫ ورأين ا أن السلس لة النص ية‬،‫الخ امس بع د اإلكم ال‬

َّ ‫ ثم‬،sammy_list
‫ ورأين ا في‬،‫عطلن ا نقط ة التوق ف في الس طر الس ادس وأكملن ا تنفي ذ البرن امج‬

َ
.sammy_list ‫' مضافين إلى القائمة‬s' ‫حرفي‬ ‫المخرجات وجود‬

▲ | 382
‫البرمجة بلغة بايثون‬ ‫تنقيح الشيفرات‪ :‬استخدام ِّ‬
‫منقح بايثون‬

‫ِّ‬
‫المنقح بعض أن واع القف زات‪ ،‬مث ل القف ز داخ ل وخ ارج بني ة تحكم‪ ،‬فمثاًل ال‬ ‫يمكن أن يمن ع‬

‫يمكن ك أن تقف ز إلى تنفي ذ دال ة قب ل تعري ف وس ائطها‪ ،‬وال يمكن ك أن تقف ز إلى داخ ل عب ارة‬

‫ً‬
‫أيض ا أن تقف ز خ ارج بني ة ‪ .finally‬تس مح لن ا عب ارة ‪ jump‬الموج ودة‬ ‫‪ .try:except‬وال يمكن ك‬

‫في ِّ‬
‫منقح بايثون بتغيير تسلسل تنفيذ البرنامج أثن اء تنقيح ه ل نرى إن ك ان باإلمك ان تحس ين ه ذا‬

‫الجزء أو فهم سبب مشكلة معينة في الشيفرة‪.‬‬

‫‪ .6‬جدول بأوامر ‪ pdb‬الشائعة‬


‫الج دول الت الي في ه أوام ر ‪ pdb‬المفي دة م ع اختص اراتها لتبقيه ا في ذهن ك أثن اء تعامل ك م ع‬

‫منقح بايثون‪:‬‬

‫الوظيفة‬ ‫االختصار‬ ‫األمر‬

‫طباعة قائمة الوسائط للدالة‬


‫‪a‬‬ ‫‪args‬‬
‫الحالية‪.‬‬

‫إنشاء نقطة توقف أثناء تنفيذ‬


‫‪b‬‬ ‫‪break‬‬
‫البرنامج (يتطلب وسيط)‬

‫إكمال تنفيذ البرنامج‪.‬‬ ‫‪ c‬أو ‪cont‬‬ ‫‪continue‬‬

‫توفير قائمة األوامر‪ ،‬أو توفير‬


‫‪h‬‬ ‫‪help‬‬
‫مساعدة ألمر معين‪.‬‬

‫ضبط ما هو السطر القادم الذي‬


‫‪j‬‬ ‫‪jump‬‬
‫يجب تنفيذه‪.‬‬

‫طباعة الشيفرة المصدرية‬


‫‪l‬‬ ‫‪list‬‬
‫المحيطة بالسطر الحالي‪.‬‬

‫▲‬ ‫|‬ ‫‪383‬‬


‫البرمجة بلغة بايثون‬ ‫تنقيح الشيفرات‪ :‬استخدام ِّ‬
‫منقح بايثون‬

‫الوظيفة‬ ‫االختصار‬ ‫األمر‬

‫إكمال التنفيذ حتى السطر التالي‬


‫‪n‬‬ ‫‪next‬‬
‫في الدالة‪ ،‬أو الخروج منها‪.‬‬

‫تنفيذ السطر الحالي‪ ،‬والتوقف‬


‫‪s‬‬ ‫‪step‬‬
‫في أول فرصة ممكنة‪.‬‬

‫طباعة قيمة التعبير‪.‬‬ ‫‪pp‬‬ ‫‪pp‬‬

‫الخروج من البرنامج‪.‬‬ ‫‪q‬‬ ‫‪ quit‬أو ‪exit‬‬

‫إكمال التنفيذ حتى تعيد الدالة‬


‫‪r‬‬ ‫‪return‬‬
‫ً‬
‫قيمة ما‪.‬‬

‫يمكنك قراءة المزيد عن األوامر السابقة والتعامل مع المنقح عبر توثيق بايثون الرسمي‪.‬‬

‫‪ .7‬الوحدة ‪ :code‬تنقيح الشيفرات من سطر األوامر التفاعلي‬


‫الوح دة ‪ code‬هي إح دى األدوات المفي دة ال تي يمكن اس تخدامها لمحاك اة الم ترجم‬

‫ً‬
‫فرصة لتجربة الشيفرة التي تكتبها‪.‬‬ ‫(‪ )interpreter‬التفاعلي‪ ،‬إذ توفر هذه الوحدة‬

‫تفحص الشيفرة باستخدام ِّ‬


‫منقح‪ ،‬يمكن ك إض افة الوح دة ‪ code‬لوض ع نق اط إليق اف‬ ‫ُّ‬ ‫بدالً من‬

‫كيفية عم ل الش يفرة‪ .‬الوح دة‬


‫َّ‬ ‫ُّ‬
‫لتفحص ومتابع ة‬ ‫تنفي ذ البرن امج‪ ،‬وال دخول في الوض ع التف اعلي‬

‫‪ code‬هي جزء من مكتبة بايثون القياسية‪.‬‬

‫ألنها ستمكنك من استخدام م ترجم دون التض حية بالتعقي د واالس تدامة‬ ‫ٌ‬
‫مفيدة َّ‬ ‫هذه الوحدة‬

‫ال تي توفره ا ملف ات البرمج ة‪ .‬فيمكن ك ع بر اس تخدام الوح دة ‪ code‬تجنب اس تخدام‬

‫عملية‪ .‬الس تخدامها في تنقيح‬


‫َّ‬ ‫الدال ة )(‪ print‬في ش يفرتك ألج ل التنقيح‪َّ ،‬‬
‫ألنه ا طريق ة غ ير‬

‫▲‬ ‫|‬ ‫‪384‬‬


‫البرمجة بلغة بايثون‬ ‫تنقيح الشيفرات‪ :‬استخدام ِّ‬
‫منقح بايثون‬

‫الخاص ة بالوح دة ‪ ،code‬وال تي توق ف تنفي ذ‬


‫َّ‬ ‫األخط اء‪ ،‬يمكن ك اس تخدام الدال ة )(‪interact‬‬

‫البرن امج عن د اس تدعائها‪ ،‬وت وفر ل ك س طر أوام ر تف اعلي ح تى تتمكن من فحص الوض ع‬

‫الحالي لبرنامجك‪.‬‬

‫ُتك َتب الدالة )(‪ interact‬بالشكل التالي‪:‬‬

‫‪code.interact(banner=None, readfunc=None, local=None,‬‬


‫)‪exitmsg=None‬‬

‫ُت ِّ‬
‫نفذ ه ذه الدال ة حلق ة اق رأ‪-‬قيِّ م‪-‬اطبع (تختص ر إلى ‪ ،REPL‬أي ‪،Read–eval–print loop‬‬

‫وتنش ئ نس خة من الص نف ‪ ،InteractiveConsole‬وال ذي يح اكي س لوك م ترجم‬

‫بايثون التفاعلي‪.‬‬

‫هذه هي المعامالت االختيارية‪:‬‬

‫‪ :banner‬يمكن أن تعطيه سلسلة نصية لتعيين موضع إطالق المترجم‪.‬‬ ‫•‬

‫‪ :readfunc‬يمكن استخدامه مثل التابع )(‪.InteractiveConsole.raw_input‬‬ ‫•‬

‫‪ :local‬س يعيِّ ن فض اء األس ماء (‪ )namespace‬االفتراض ي لحلق ة الم ترجم‬ ‫•‬


‫(‪.)interpreter loop‬‬

‫‪ :exitmsg‬يمكن إعطاؤه سلسلة نصية لتعيين موضع توقف المترجم‪.‬‬ ‫•‬

‫مثاًل ‪ ،‬يمكن استخدام المعامل ‪ local‬بهذا الشكل‪:‬‬

‫)(‪ - local=locals‬لفضاء أسماء محلي‬ ‫•‬

‫)(‪ - local=globals‬لفضاء أسماء عام‬ ‫•‬

‫▲‬ ‫|‬ ‫‪385‬‬


‫البرمجة بلغة بايثون‬ ‫تنقيح الشيفرات‪ :‬استخدام ِّ‬
‫منقح بايثون‬

‫))(‪ - local=dict(globals(), **locals‬الستخدام ك ل من فض اء األس ماء الع ام‪،‬‬ ‫•‬


‫وفضاء األسماء المحلي الحالي‬

‫المعامل ‪ exitmsg‬جديد‪ ،‬ولم يظهر حتى إصدار بايثون ‪ ،3.6‬لذلك إن كنت تس تخدم إص دا ًرا‬

‫ِّ‬
‫فحدثه‪ ،‬أو ال تستخدم المعامل ‪.exitmsg‬‬ ‫أقدم‪،‬‬

‫ضع الدالة )(‪ interact‬حيث تريد إطالق المترجم التفاعلي في الشيفرة‪.‬‬

‫ا‪ .‬كيفية استخدام الوحدة ‪code‬‬

‫رفية يس مى‬ ‫ً‬


‫ُريمج ا عن الحس ابات المص َّ‬
‫لتوض يح كيفي ة اس تخدام الوح دة ‪ ،code‬س نكتب ب‬

‫محليا‪.‬‬
‫ًّ‬ ‫سنعين المعامل المحلي عند القيمة )(‪ locals‬لجعل فضاء األسماء‬
‫ّ‬ ‫‪.balances.py‬‬

‫‪# code‬‬ ‫استيراد الوحدة‬


‫‪import code‬‬

‫‪bal_a = 2324‬‬
‫‪bal_b = 0‬‬
‫‪bal_c = 409‬‬
‫‪bal_d = -2‬‬

‫]‪account_balances = [bal_a, bal_b, bal_c, bal_d‬‬

‫‪def display_bal():‬‬
‫‪for balance in account_balances:‬‬
‫‪if balance < 0:‬‬
‫"‪print("Account balance of {} is below 0; add funds now.‬‬
‫))‪.format(balance‬‬

‫‪elif balance == 0:‬‬

‫▲‬ ‫|‬ ‫‪386‬‬


‫البرمجة بلغة بايثون‬ ‫تنقيح الشيفرات‪ :‬استخدام ِّ‬
‫منقح بايثون‬

‫‪print("Account balance of {} is equal to 0; add funds‬‬


‫"‪soon.‬‬
‫))‪.format(balance‬‬

‫‪else:‬‬
‫‪print("Account balance of {} is above‬‬
‫))‪0.".format(balance‬‬

‫استخدام )(‪ interact‬لبدء المترجم بفضاء أسماء محلي ‪#‬‬


‫))(‪code.interact(local=locals‬‬

‫)(‪display_bal‬‬

‫لق د اس تدعينا الدال ة )(‪ code.interact‬م ع المعام ل )(‪ local=locals‬الس تخدام فض اء‬

‫األسماء المحلي بوصفه قيمة افتراضية داخل حلقة المترجم‪.‬‬

‫ل ُن ِّ‬
‫نفذ البرن امج أعاله باس تخدام األم ر ‪ python3‬إذا لم نكن تعم ل في بيئ ة افتراض ية‪ ،‬أو‬

‫األمر ‪ python‬خالف ذلك‪:‬‬

‫‪python balances.py‬‬

‫بمجرَّ د تنفيذ البرنامج‪ ،‬سنحصل على المخرجات التالية‪:‬‬

‫)‪Python 3.5.2 (default, Nov 17 2016, 17:05:23‬‬


‫‪[GCC 5.4.0 20160609] on linux‬‬
‫‪Type "help", "copyright", "credits" or "license" for more‬‬
‫‪information.‬‬
‫)‪(InteractiveConsole‬‬
‫>>>‬

‫وضع المؤشر في نهاية السطر >>>‪ ،‬كما لو َّ‬


‫أنك في سطر األوامر التفاعلي‪ .‬من هنا‪ ،‬يمكنك‬ ‫سي َ‬
‫ُ‬

‫استدعاء الدالة )(‪ print‬لطباعة المتغيرات والدوال وغير ذلك‪:‬‬

‫▲‬ ‫|‬ ‫‪387‬‬


‫البرمجة بلغة بايثون‬ ‫تنقيح الشيفرات‪ :‬استخدام ِّ‬
‫منقح بايثون‬

‫)‪>>> print(bal_c‬‬
‫‪409‬‬
‫)‪>>> print(account_balances‬‬
‫]‪[2324, 0, 409, -2‬‬
‫))(‪>>> print(display_bal‬‬
‫‪Account balance of 2324 is 0 or above.‬‬
‫‪Account balance of 0 is equal to 0, add funds soon.‬‬
‫‪Account balance of 409 is 0 or above.‬‬
‫‪Account balance of -2 is below 0, add funds now.‬‬
‫‪None‬‬
‫)‪>>> print(display_bal‬‬
‫>‪<function display_bal at 0x104b80f28‬‬

‫نرى َّ‬
‫أنه باستخدام فضاء األسماء المحلي‪ ،‬يمكننا طباعة المتغيرات‪ ،‬واس تدعاء الدال ة‪ .‬يُ ظه ر‬

‫أن الدالة ‪ display_bal‬موجودة في ذاكرة الحاسوب‪.‬‬


‫االستدعاء األخير للدالة )(‪َّ print‬‬

‫بعد أن تنتهي من العمل على المترجم‪ ،‬يمكنك الضغط على ‪ CTRL + D‬في األنظم ة المس تندة‬

‫إلى يونكس‪ ،‬أو ‪ CTRL + Z‬في أنظمة ويندوز لمغادرة سطر األوامر ومتابعة تنفيذ البرنامج‪.‬‬

‫إذا أردت الخروج من سطر األوامر دون تنفي ذ الج زء المتبقي من البرن امج‪ ،‬ف اكتب )(‪،quit‬‬

‫وسيتوقف البرنامج‪.‬‬

‫في المثال التالي‪ ،‬سنستخدم المُ عاملين ‪ banner‬و ‪:exitmsg‬‬

‫استخدم الدالة )(‪ interact‬لبدء المترجم ‪#‬‬


‫)"‪code.interact(banner="Start", local=locals(), exitmsg="End‬‬

‫)(‪display_bal‬‬

‫عند تنفيذ البرنامج‪ ،‬ستحصل على المخرجات التالية‪:‬‬

‫‪Start‬‬

‫▲‬ ‫|‬ ‫‪388‬‬


‫البرمجة بلغة بايثون‬ ‫تنقيح الشيفرات‪ :‬استخدام ِّ‬
‫منقح بايثون‬

‫>>>‬

‫ي تيح ل ك اس تخدام المعام ل ‪ banner‬تع يين ع َّدة نق اط داخ ل ش يفرتك‪ ،‬م ع الق درة على‬

‫تحدي دها‪ .‬على س بيل المث ال‪ ،‬يمكن أن يك ون ل ديك معام ل ‪ banner‬يطب ع السلس لة النص ية‬

‫"‪ "In for-loop‬م ع معام ل ‪ exmsg‬يطب ع "‪ ،"Out of for-loop‬وذل ك ح تى تع رف مكان ك‬

‫بالضبط في الشيفرة‪.‬‬

‫من هنا‪ ،‬يمكننا اس تخدام الم ترجم مث ل المعت اد‪ .‬بع د كتاب ة ‪ CTRL + D‬للخ روج من الم ترجم‪،‬‬

‫ستحصل على رسالة الخروج‪ ،‬وسيتم تنفيذ الدالة‪:‬‬

‫‪End‬‬
‫‪Account balance of 2324 is 0 or above.‬‬
‫‪Account balance of 0 is equal to 0, add funds soon.‬‬
‫‪Account balance of 409 is 0 or above.‬‬
‫‪Account balance of -2 is below 0, add funds now.‬‬

‫سيتم تنفيذ البرنامج بالكامل بعد الجلسة التفاعلية‪.‬‬

‫بمجرد االنتهاء من استخدام الوحدة ‪ code‬لتنقيح الش يفرة‪ ،‬يجب علي ك إزال ة دوال الوح دة‬

‫‪ code‬وعبارة االستيراد حتى يُ َّ‬


‫نفذ البرنامج مثل المعتاد‪.‬‬

‫‪ .8‬الوحدة ‪ :Logging‬التنقيح بالتسجيل وتتبع األحداث‬


‫الوح دة ‪ logging‬هي ج زء من مكتب ة ب ايثون القياس ية وال تي ت وفر تتبعً ا لألح داث ال تي‬

‫تحصل أثناء تش غيل البرن امج‪ ،‬ويمكنن ا إض افة اس تدعاءات للتس جيل ض من الش يفرة لإلش ارة إلى‬

‫معين‪ .‬تس مح الوح دة ‪ logging‬بالتس جيل ألغ راض استكش اف المش اكل وإص الحها‪،‬‬
‫َّ‬ ‫ح دوث أم ر‬

‫وتس جيل األح داث المتعلق ة بتش غيل التط بيق‪ ،‬إض ً‬
‫افة إلى س جل األح داث ال ذي يس ِّجل تف اعالت‬

‫▲‬ ‫|‬ ‫‪389‬‬


‫البرمجة بلغة بايثون‬ ‫تنقيح الشيفرات‪ :‬استخدام ِّ‬
‫منقح بايثون‬

‫خصوصا لتسجيل األحداث إلى ملف‪.‬‬


‫ً‬ ‫المستخدم لتحليلها‪ .‬وتستعمل الوحدة‬

‫تبقي الوح دة ‪ logging‬س جاًل باألح داث ال تي وقعت ض من البرن امج‪ ،‬مم ا يس مح برؤي ة‬

‫ُّ‬
‫التحقق‬ ‫المخرجات المتعلقة بأي ح دث ال تي تح دث أثن اء تش غيل البرن امج‪ .‬ق د تك ون معت ا ًدا على‬

‫أن الدال ة ‪ print‬ت وفر طريق ة‬


‫حيح َّ‬
‫ٌ‬ ‫من األح داث باس تخدام الدال ة ‪ print‬في ش يفرتك‪ ،‬وص‬

‫أساس ية لمحاول ة تنقيح الش يفرة وح ل المش كالت‪ .‬لكن اس تخدام ‪ print‬لتنقيح البرن امج وتتب ع‬

‫لعدة أسباب‪:‬‬ ‫ً‬


‫موازنة مع الوحدة ‪ِّ logging‬‬ ‫ٌ‬
‫صعبة صيانته‬ ‫عملية التنفيذ وحالة التطبيق هو خيار‬

‫عبا التفري ق بين مخرج ات التنقيح والمخرج ات العادي ة للبرن امج‪ ،‬فس تختلط‬
‫سيصبح ص ً‬ ‫•‬

‫المخرجات مع بعضها‪.‬‬

‫ال توج د طريق ة س هلة لتعطي ل ال دوال ‪ print‬عن د اس تخدامها متن اثرة في مواض ع‬ ‫•‬

‫مختلفة في الشيفرة‪.‬‬

‫يصعب حذف جميع دوال ‪ print‬عند االنتهاء من التنقيح‪.‬‬ ‫•‬

‫بموثوقية عالية‪.‬‬
‫َّ‬ ‫ال يوجد سجل يوضح ما هي معلومات التشخيص واستكشاف ألخطاء‬ ‫•‬

‫ل ذا من األفض ل أن نعت اد على اس تخدام الوح دة ‪ logging‬في الش يفرة َّ‬


‫ألنه ا أفض ل‬

‫وألن الس جالت‬


‫َّ‬ ‫للتطبيقات التي تتعدى كونها سكربت بايثون قصير‪ ،‬وتوفر طريقة أنسب للتنقيح‪.‬‬

‫تعرض سلوك وأخطاء التطبيق على فترة من الزمن‪ ،‬فستحصل على صورة ش املة عمَّ ا يح دث في‬

‫عملية تطوير تطبيقك‪.‬‬

‫ا‪ .‬طباعة رسائل التنقيح إلى الطرفية‬

‫كنت معتا ًدا على استخدام الدالة ‪ print‬لترى ماذا يحدث في تطبيق ك‪ ،‬فس تكون معت ا ًدا‬
‫َ‬ ‫إذا‬

‫ً‬
‫صنفا ويُ هيِّ ئ الكائنات فيه‪:‬‬ ‫على رؤية تطبيق مثل المثال اآلتي الذي يُ ِّ‬
‫عرف‬

‫▲‬ ‫|‬ ‫‪390‬‬


‫البرمجة بلغة بايثون‬ ِّ ‫ استخدام‬:‫تنقيح الشيفرات‬
‫منقح بايثون‬

class Pizza():
def __init__(self, name, price):
self.name = name
self.price = price
print("Pizza created: {} (${})".format(self.name,
self.price))

def make(self, quantity=1):


print("Made {} {} pizza(s)".format(quantity, self.name))

def eat(self, quantity=1):


print("Ate {} pizza(s)".format(quantity, self.name))

pizza_01 = Pizza("artichoke", 15)


pizza_01.make()
pizza_01.eat()

pizza_02 = Pizza("margherita", 12)


pizza_02.make(2)
pizza_02.eat()

ِّ ُ‫__ الذي ي‬init__ ‫تحتوي الشيفرة السابقة على التابع‬


‫ لك ائن‬price ‫ و‬name ‫عرف المعاملين‬

‫ واآلخ ر باس م‬،‫ إلنش اء البي تزا‬make() ‫ أح دهما باس م‬،‫ ول دى الص نف ت ابعين‬.Pizza ‫من الص نف‬

.‫ بقيم ة ابتدائي ة تس اوي‬quantity ‫ ه ذان التابع ان يقبالن مع اماًل باس م‬:-p ‫ ألك ل البي تزا‬eat()

ِّ
:‫لنشغل البرنامج‬

python pizza.py

:‫سنحصل على المخرجات اآلتية‬

Pizza created: artichoke ($15)

▲ | 391
‫البرمجة بلغة بايثون‬ ‫تنقيح الشيفرات‪ :‬استخدام ِّ‬
‫منقح بايثون‬

‫)‪Made 1 artichoke pizza(s‬‬


‫)‪Ate 1 pizza(s‬‬
‫)‪Pizza created: margherita ($12‬‬
‫)‪Made 2 margherita pizza(s‬‬
‫)‪Ate 1 pizza(s‬‬

‫صحيح أننا نستخدم الدالة ‪ print‬لرؤية كيف تعم ل الش يفرة‪ ،‬لكن يمكنن ا اس تخدام الوح دة‬
‫ٌ‬

‫يفرة‪،‬‬ ‫ودة في الش‬ ‫ة ‪ print‬الموج‬ ‫نزل الدال‬ ‫ا‪ .‬ل‬ ‫داًل منه‬ ‫كب‬ ‫ل ذل‬ ‫‪ logging‬لفع‬

‫ونضع ‪ import logging‬في بداية الملف‪:‬‬

‫‪import logging‬‬

‫‪class Pizza():‬‬
‫‪def __init__(self, name, value):‬‬
‫‪self.name = name‬‬
‫‪self.value = value‬‬
‫…‬

‫المس توى االفتراض ي للتس جيل في وح دة ‪ logging‬ه و ‪( WARNING‬تح ذير) وال ذي ه و‬

‫مس توى أعلى بدرج ة واح دة من ‪( DEBUG‬تنقيح)‪ ،‬ولمَّ ا كنَّا نري د اس تخدام الوح دة ‪logging‬‬

‫للتنقيح في هذا المثال‪ ،‬فعلينا تغي ير الض بط لكي يك ون مس توى التس جيل ه و ‪،logging.DEBUG‬‬

‫وذلك بإضافة السطر اآلتي بعد عبارة االستيراد‪:‬‬

‫‪import logging‬‬

‫)‪logging.basicConfig(level=logging.DEBUG‬‬

‫‪class Pizza():‬‬

‫▲‬ ‫|‬ ‫‪392‬‬


‫البرمجة بلغة بايثون‬ ِّ ‫ استخدام‬:‫تنقيح الشيفرات‬
‫منقح بايثون‬

.10 ‫ هي‬DEBUG ‫ وقيم ة المس توى‬،‫ إلى قيم ة رقمي ة ثابت ة‬logging.DEBUG ‫تش ير القيم ة‬

‫ وعلى النقيض من‬،logging.debug() ‫ابع‬ ‫ إلى الت‬print ‫دوال‬ ‫ع ال‬ ‫ِّدل اآلن جمي‬ ‫لنب‬

ٌ
‫اص‬ ‫ خ‬logging.debug() ‫إن الت ابع‬
َّ ‫ ف‬،‫ ال تي هي قيم ة عددي ة ثابت ة‬logging.DEBUG

‫ وعند التعامل م ع ه ذا الت ابع فيمكنن ا اس تخدام نفس السلس لة النص ية المُ م رَّ رة‬،logging ‫بالوحدة‬

:‫ كما هو موضح أدناه‬print ‫إلى‬

import logging

logging.basicConfig(level=logging.DEBUG)

class Pizza():
def __init__(self, name, price):
self.name = name
self.price = price
logging.debug("Pizza created: {} (${})".format(self.name,
self.price))

def make(self, quantity=1):


logging.debug("Made {} {} pizza(s)".format(quantity,
self.name))

def eat(self, quantity=1):


logging.debug("Ate {} pizza(s)".format(quantity,
self.name))

pizza_01 = Pizza("artichoke", 15)


pizza_01.make()

▲ | 393
‫البرمجة بلغة بايثون‬ ِّ ‫ استخدام‬:‫تنقيح الشيفرات‬
‫منقح بايثون‬

pizza_01.eat()

pizza_02 = Pizza("margherita", 12)


pizza_02.make(2)
pizza_02.eat()

:‫ فسنحصل على الناتج اآلتي‬python pizza.py ‫عندما نشغل البرنامج باستخدام األمر‬

DEBUG:root:Pizza created: artichoke ($15)


DEBUG:root:Made 1 artichoke pizza(s)
DEBUG:root:Ate 1 pizza(s)
DEBUG:root:Pizza created: margherita ($12)
DEBUG:root:Made 2 margherita pizza(s)
DEBUG:root:Ate 1 pizza(s)

ً ‫ إض‬DEBUG ‫تمل ك رس ائل التس جيل المس توى األم ني‬


‫ وال تي تش ير إلى‬،root ‫افة إلى الكلم ة‬

‫ م ع هيكلي ة من‬logging ‫ إذ يمكن اس تخدام الوح دة‬،‫مس توى وح دة ب ايثون الخاص ة ب ك‬

‫) مختل ف لك ل وح دة من‬logger( ‫ لذا يمكنك استخدام مس ِّجل‬،‫المسجالت التي لها أسماء مختلفة‬

‫ يمكنن ا إس ناد أك ثر من مس ِّجل معً ا وإعطائه ا‬،‫ على س بيل المث ال‬.‫وح دات ب ايثون الخاص ة ب ك‬

:‫أسماء مختلفة‬

logger1 = logging.getLogger("module_1")
logger2 = logging.getLogger("module_2")

logger1.debug("Module 1 debugger")
logger2.debug("Module 2 debugger")
DEBUG:module_1:Module 1 debugger
DEBUG:module_2:Module 2 debugger

▲ | 394
‫البرمجة بلغة بايثون‬ ‫تنقيح الشيفرات‪ :‬استخدام ِّ‬
‫منقح بايثون‬

‫كيفية اس تخدام الوح دة ‪ logging‬لطباع ة الرس ائل إلى الطرفي ة‪ ،‬فلننتق ل إلى‬
‫َّ‬ ‫بع د أن فهمن ا‬

‫استخدام الوحدة ‪ logging‬لطباعة الرسائل إلى ملف‪.‬‬

‫ب‪ .‬تسجيل الرسائل إلى ملف‬

‫اله دف الرئيس ي من الوح دة ‪ logging‬هي تس جيل الرس ائل إلى مل ف ب داًل من طباعته ا إلى‬

‫الطرفية‪ ،‬إذ يؤدي وجود ملف يحت وي على البيان ات المُ َّ‬
‫خزن ة على ف ترة زمني ة طويل ة إلى إحص اء‬

‫وتق دير م ا هي التغي يرات ال تي يجب إجراؤه ا على الش يفرة أو البرن امج كك ل‪ .‬يمكنن ا تع ديل‬

‫الت ابع )(‪ logging.basicConfig‬لب دء التس جيل إلى مل ف‪ ،‬وذل ك بتمري ر المعام ل ‪،filename‬‬

‫وفي هذه الحالة سندعو الملف باسم ‪:test.log‬‬

‫‪import logging‬‬

‫)‪logging.basicConfig(filename="test.log", level=logging.DEBUG‬‬

‫‪class Pizza():‬‬
‫‪def __init__(self, name, price):‬‬
‫‪self.name = name‬‬
‫‪self.price = price‬‬
‫‪logging.debug("Pizza created: {} ($‬‬
‫))‪{})".format(self.name, self.price‬‬

‫‪def make(self, quantity=1):‬‬


‫‪logging.debug("Made {} {} pizza(s)".format(quantity,‬‬
‫))‪self.name‬‬

‫‪def eat(self, quantity=1):‬‬


‫‪logging.debug("Ate {} pizza(s)".format(quantity,‬‬

‫▲‬ ‫|‬ ‫‪395‬‬


‫البرمجة بلغة بايثون‬ ‫تنقيح الشيفرات‪ :‬استخدام ِّ‬
‫منقح بايثون‬

‫))‪self.name‬‬

‫)‪pizza_01 = Pizza("artichoke", 15‬‬


‫)(‪pizza_01.make‬‬
‫)(‪pizza_01.eat‬‬

‫)‪pizza_02 = Pizza("margherita", 12‬‬


‫)‪pizza_02.make(2‬‬
‫)(‪pizza_02.eat‬‬

‫الش يفرة الس ابقة مش ابهة كث يرًا للش يفرة الموج ودة في القس م الس ابق‪ ،‬باس تثناء أنن ا أض فنا‬

‫اس م المل ف ‪ filename‬لتخ زين مخرج ات الس جل‪ .‬وبع د تش غيل الس كربت باس تخدام األم ر‬

‫نشأ ٌ‬
‫ملف جدي ٌد في المجلد الخ اص بن ا باس م ‪.test.log‬‬ ‫‪ python pizza.py‬فمن المفترض أن يُ َ‬

‫لنفتح الملف ‪ test.log‬باستخدام ‪( vi‬أو أي محرر تفضله)‪:‬‬

‫‪vi test.log‬‬

‫ُّ‬
‫تفحص محتويات الملف‪ ،‬فسنرى ما يلي‪:‬‬ ‫عند‬

‫)‪DEBUG:root:Pizza created: artichoke ($15‬‬


‫)‪DEBUG:root:Made 1 artichoke pizza(s‬‬
‫)‪DEBUG:root:Ate 1 pizza(s‬‬
‫)‪DEBUG:root:Pizza created: margherita ($12‬‬
‫)‪DEBUG:root:Made 2 margherita pizza(s‬‬
‫)‪DEBUG:root:Ate 1 pizza(s‬‬

‫الناتج شبيه بمحتويات الطرفية ال تي رأيناه ا في القس م الس ابق‪ ،‬لكنَّه ا مُ َّ‬
‫خزن ة اآلن في مل ف‬

‫‪ .test.log‬لنع د إلى تع ديل المل ف ‪ pizza.py‬لتع ديل الش يفرة‪ ،‬س نبقي أغلبي ة الش يفرة على‬

‫حالتها‪ ،‬لكننا سنعدل معاملين في كائني ‪ pizza_01‬و ‪:pizza_02‬‬

‫▲‬ ‫|‬ ‫‪396‬‬


‫البرمجة بلغة بايثون‬ ِّ ‫ استخدام‬:‫تنقيح الشيفرات‬
‫منقح بايثون‬

import logging

logging.basicConfig(filename="test.log", level=logging.DEBUG)

class Pizza():
def __init__(self, name, price):
self.name = name
self.price = price
logging.debug("Pizza created: {} ($
{})".format(self.name, self.price))

def make(self, quantity=1):


logging.debug("Made {} {} pizza(s)".format(quantity,
self.name))

def eat(self, quantity=1):


logging.debug("Ate {} pizza(s)".format(quantity,
self.name))

# ‫تعديل معامالت الكائن‬


pizza_01 = Pizza("Sicilian", 18)
pizza_01.make(5)
pizza_01.eat(4)

# ‫تعديل معامالت الكائن‬


pizza_02 = Pizza("quattro formaggi", 16)
pizza_02.make(2)
pizza_02.eat(2)

‫ بع د تش غيل‬.python pizza.py ‫ لنعد تشغيل البرنامج باألمر‬،‫بعد حفظ التعديالت السابقة‬

ِّ ُ‫ بالم‬test.log ‫ لنستعرض محتوى الملف‬،‫البرنامج‬


:‫حرر المفضل لديك‬

▲ | 397
‫البرمجة بلغة بايثون‬ ‫تنقيح الشيفرات‪ :‬استخدام ِّ‬
‫منقح بايثون‬

‫‪vi test.log‬‬

‫وأن األس طر الس ابقة من‬


‫َّ‬ ‫أن هنالك أسطر جديدة ق د أض يفت‪،‬‬
‫عندما ننظر إلى الملف‪ ،‬فسنرى َّ‬

‫ً‬
‫موجودة‪:‬‬ ‫الماضية ما تزال‬
‫َّ‬ ‫المرة‬

‫)‪DEBUG:root:Pizza created: artichoke ($15‬‬


‫)‪DEBUG:root:Made 1 artichoke pizza(s‬‬
‫)‪DEBUG:root:Ate 1 pizza(s‬‬
‫)‪DEBUG:root:Pizza created: margherita ($12‬‬
‫)‪DEBUG:root:Made 2 margherita pizza(s‬‬
‫)‪DEBUG:root:Ate 1 pizza(s‬‬
‫)‪DEBUG:root:Pizza created: Sicilian ($18‬‬
‫)‪DEBUG:root:Made 5 Sicilian pizza(s‬‬
‫)‪DEBUG:root:Ate 4 pizza(s‬‬
‫)‪DEBUG:root:Pizza created: quattro formaggi ($16‬‬
‫)‪DEBUG:root:Made 2 quattro formaggi pizza(s‬‬
‫)‪DEBUG:root:Ate 2 pizza(s‬‬

‫أن هذه المعلومات مفيدة بكل تأكيد‪ ،‬لكن يمكننا أن نجعل السجل مليًئا بالمعلومات‬
‫وصحيح َّ‬
‫ٌ‬

‫بإض افة خاص ية ‪ .LogRecord‬وأهم م ا نري د فعل ه ه و إض افة بص مة وقت قابل ة للق راءة بس هولة‬

‫ال تي تخبرن ا م تى ُأ ِ‬
‫نش ئ الس جل‪ .‬سنض يف ذل ك إلى المعام ل ‪ ،format‬إذا نض ع ‪%(asctime)s‬‬

‫لة‬ ‫مين السلس‬ ‫توى (‪ )DEBUG‬فيجب تض‬ ‫م المس‬ ‫اء اس‬ ‫وقت‪ ،‬وإلبق‬ ‫افة ال‬ ‫إلض‬

‫النص ية‪ ،%(levelname)s‬ولإلبق اء على الرس ائل ال تي نطلب من المس جل أن يس جلها‪ ،‬فعلين ا‬

‫تض مين ‪ ،%(message)s‬ك ل سلس لة نص ية من الخاص يات الس ابقة مفص ولة عن بعض ها بنقط تين‬

‫رأسيتين ‪ :‬كما هو ظاهر في الشيفرة أدناه‪:‬‬

‫▲‬ ‫|‬ ‫‪398‬‬


‫البرمجة بلغة بايثون‬ ِّ ‫ استخدام‬:‫تنقيح الشيفرات‬
‫منقح بايثون‬

import logging

logging.basicConfig(
filename="test.log",
level=logging.DEBUG,
format="%(asctime)s:%(levelname)s:%(message)s"
)

class Pizza():
def __init__(self, name, price):
self.name = name
self.price = price
logging.debug("Pizza created: {} ($
{})".format(self.name, self.price))

def make(self, quantity=1):


logging.debug("Made {} {} pizza(s)".format(quantity,
self.name))

def eat(self, quantity=1):


logging.debug("Ate {} pizza(s)".format(quantity,
self.name))

pizza_01 = Pizza("Sicilian", 18)


pizza_01.make(5)
pizza_01.eat(4)

pizza_02 = Pizza("quattro formaggi", 16)


pizza_02.make(2)
pizza_02.eat(2)

‫ فستحص ل على أس طر‬python pizza.py ‫عن د تش غيل الش يفرة الس ابقة باس تخدام األم ر‬

▲ | 399
‫البرمجة بلغة بايثون‬ ‫تنقيح الشيفرات‪ :‬استخدام ِّ‬
‫منقح بايثون‬

‫جدي دة في المل ف ‪ test.log‬ال تي تتض من بص مة ال وقت ومس توى التس جيل (‪ )DEBUG‬والرس ائل‬

‫المرتبطة بها‪:‬‬

‫)‪DEBUG:root:Pizza created: Sicilian ($18‬‬


‫)‪DEBUG:root:Made 5 Sicilian pizza(s‬‬
‫)‪DEBUG:root:Ate 4 pizza(s‬‬
‫)‪DEBUG:root:Pizza created: quattro formaggi ($16‬‬
‫)‪DEBUG:root:Made 2 quattro formaggi pizza(s‬‬
‫)‪DEBUG:root:Ate 2 pizza(s‬‬
‫)‪2017-05-01 16:28:54,593:DEBUG:Pizza created: Sicilian ($18‬‬
‫)‪2017-05-01 16:28:54,593:DEBUG:Made 5 Sicilian pizza(s‬‬
‫)‪2017-05-01 16:28:54,593:DEBUG:Ate 4 pizza(s‬‬
‫‪2017-05-01 16:28:54,593:DEBUG:Pizza created: quattro formaggi‬‬
‫)‪($16‬‬
‫)‪2017-05-01 16:28:54,593:DEBUG:Made 2 quattro formaggi pizza(s‬‬
‫)‪2017-05-01 16:28:54,593:DEBUG:Ate 2 pizza(s‬‬

‫اعتم ا ًدا على احتياجات ك‪ ،‬ربم ا تس تعمل خاص يات ‪ LogRecord‬في ش يفراتك لتخصيص ها‪.‬‬

‫كلي ا على م رور‬ ‫ِّ‬


‫يسهل عليك فهم تطبيقك فهمً ا ً‬ ‫تسجيل رسائل التنقيح وغيرها في ملفات منفصلة‬

‫ً‬
‫فرصة لتصحيح وتعديل الشيفرات ببصيرة‪.‬‬ ‫الزمن‪ ،‬مما يعطيك‬

‫ج‪ .‬جدول بمستويات التسجيل‬

‫يمكن ك إس ناد مس توى أهمي ة إلى الح دث باس تخدام مس تويات التس جيل‪ .‬مس تويات‬

‫دءا من‬
‫ً‬ ‫التس جيل هي قيم عددي ة (ثابت ة)‪ ،‬وال تي تك ون من مض اعفات الع دد ‪ ،10‬ب‬

‫ً‬
‫أيض ا تعري ف المس تويات‬ ‫المس توى ‪ NOTSET‬ال ذي يه يئ المس ِّجل بقيم ة عددي ة تس اوي ‪ .0‬يمكن ك‬

‫عرفت مستوى بقيمة عددية مساوية للقيمة العددية لمس توى موج ود مس ً‬
‫بقا‪،‬‬ ‫َ‬ ‫الخاصة بك‪ ،‬لكن إذا‬

‫فستعيد كتابة االسم المرتبط بتلك القيمة‪.‬‬

‫▲‬ ‫|‬ ‫‪400‬‬


‫البرمجة بلغة بايثون‬ ‫تنقيح الشيفرات‪ :‬استخدام ِّ‬
‫منقح بايثون‬

‫يُ ِ‬
‫ظه ر الج دول اآلتي مختل ف مس تويات التس جيل م ع القيم العددي ة المرتبط ة به ا‪ ،‬وم ا هي‬

‫الدالة التي يمكن استعمالها الستدعاء المستوى‪ ،‬وألي مستوى من الرسائل تستخدم‪:‬‬

‫الغرض‬ ‫الدالة‬ ‫القيمة العددية‬ ‫المستوى‬

‫عرض خطأ جاد‪ ،‬وقد ال يكون‬ ‫)(‪logging.critical‬‬ ‫‪50‬‬ ‫‪CRITICAL‬‬


‫البرنامج قاباًل لالستخدام‬
‫بعده‪.‬‬

‫عرض خطأ جاد‪.‬‬ ‫)(‪logging.error‬‬ ‫‪40‬‬ ‫‪ERROR‬‬

‫اإلشارة أن شيًئ ا غير متوقع قد‬ ‫)(‪logging.warning‬‬ ‫‪30‬‬ ‫‪WARNING‬‬


‫حدث أو قد يحدث‪.‬‬

‫التأكيد أن األمور تسير على ما‬ ‫)(‪logging.info‬‬ ‫‪20‬‬ ‫‪INFO‬‬


‫يرام‪.‬‬

‫عرض معلومات تنقيحية‪.‬‬ ‫)(‪logging.debug‬‬ ‫‪10‬‬ ‫‪DEBUG‬‬

‫تضبط وحدة ‪ logging‬المستوى االفتراض ي إلى ‪ ،WARNING‬ل ذا ُ‬


‫ستس َّجل رس ائل ‪WARNING‬‬

‫و ‪ ERROR‬و ‪ CRITICAL‬افتراض ًيا‪ .‬ففي المث ال اآلتي س نعدل الض بط لإلش ارة لتض مين‬

‫مستوى ‪:DEBUG‬‬

‫)‪logging.basicConfig(level=logging.DEBUG‬‬

‫يمكن ك التع رُّ ف على المزي د من األوام ر والتعام ل معه ا ب االطالع على توثي ق‬

‫‪ logging‬الرسمي‪.‬‬

‫▲‬ ‫|‬ ‫‪401‬‬


‫البرمجة بلغة بايثون‬ ‫تنقيح الشيفرات‪ :‬استخدام ِّ‬
‫منقح بايثون‬

‫‪ .9‬خالصة الفصل‬
‫عملي ة التنقيح هي خط وة مهم ة في جمي ع مش اريع التط وير البرمجي ة‪ .‬وي وفر لن ا ِّ‬
‫منقح‬

‫بايثون ‪ pdb‬بيئة تنقيح تفاعلية يمكن استخدامها مع أي برنامج بايثون نكتبه‪ .‬باستفادتنا للميزات‬

‫التي تسمح لنا بتوقف عمل البرنامج مؤق ًت ا‪ ،‬وإلق اء نظ رة على المتغ يرات‪ ،‬وإكم ال تنفي ذ البرن امج‬

‫خط ً‬
‫وة بخط وة‪ ،‬مم ا يمكنن ا من فهم م اذا يفع ل البرن امج بالتفص يل ويس اعدنا على اكتش اف العل ل‬

‫وإصالح المشاكل المنطقية‪.‬‬

‫لتفحص الش يفرة خط ً‬


‫وة بخط وة‬ ‫ُّ‬ ‫ُتس تخ َدم الوح دة ‪ code‬إلطالق س طر األوام ر التف اعلي‬

‫بقص د فهم س لوكها‪ ،‬وتع ديل الش يفرة إن ل زم األم ر‪ .‬لق راءة المزي د ح ول ه ذا الموض وع‪ ،‬يمكن ك‬

‫مطالعة التوثيق الرسمي للوحدة ‪.code‬‬

‫تساعد الوحدة ‪– logging‬ال تي هي ج زء من مكتب ة ب ايثون القياس ية– بتتب ع األح داث ال تي‬

‫تحصل أثناء تش غيل البرن امج‪ ،‬ويمكن إخ راج ه ذه األح داث إلى ملف ات منفص لة للس ماح بتتب ع م ا‬

‫يحدث عن دما تعم ل الش يفرة‪ .‬وه ذا ي وفر لن ا الفرص ة لتنقيح الش يفرة اعتم ا ًدا على فهمن ا لمختل ف‬

‫األحداث التي تطرأ أثناء تشغيل البرنامج على فترةٍ من الزمن‪.‬‬

‫▲‬ ‫|‬ ‫‪402‬‬


‫‪22‬‬
‫إصدارات بايثون‪:‬‬
‫بايثون ‪ 3‬مقابل‬
‫بايثون ‪2‬‬

‫▲‬ ‫|‬ ‫‪403‬‬


‫البرمجة بلغة بايثون‬ ‫إصدارات بايثون‪ :‬بايثون ‪3‬مقابل بايثون ‪2‬‬

‫قبل أن ننظر إلى إمكانيات إصدارَ ي بايثون ‪ 2‬وبايثون ‪( 3‬مع االختالفات البرمجي ة الرئيس ية‬

‫بينهما) ‪ ،‬فلننظر إلى لمحة تاريخية عن اإلصدارات الرئيسية الحديثة من بايثون‪.‬‬

‫‪ .1‬بايثون ‪2‬‬
‫ُن ِش رَ ه ذا اإلص دار في أواخ ر ع ام ‪ ،2000‬وأص بحت ب ايثون ‪ 2‬لغ ة برمج ة ش املة موازن ًة‬

‫باإلص دارات ال تي تس بقها وذل ك بع د تط بيق اق تراح ‪،)Python Enhancement Proposal ( PEP‬‬

‫يزات‬
‫ٍ‬ ‫مواصفة (‪ )specification‬تقني ٌة ت ِّ‬
‫وفر معلوم ات إلى أعض اء مجتم ع ب ايثون أو تص ف م‬ ‫ٌ‬ ‫وهو‬

‫يزات برمجي ة جدي دة مث ل‬


‫ٍ‬ ‫جدي دة في اللغ ة‪ .‬باإلض افة إلى ذل ك‪ ،‬تض منت ب ايثون ‪ 2‬م‬

‫"‪ "cycle-detecting garbage collector‬ألتمتة عملية إدارة الذاكرة‪ ،‬وزيادة دعم يونيكود لت دعم‬

‫اللغة جميع المح ارف المعياري ة …إلخ‪ .‬وأثن اء عملي ة تط وير ب ايثون ‪ 2‬أض يفت م يزات جدي دة بم ا‬

‫في ذل ك توحي د األن واع واألص ناف في ب ايثون في بني ة هيكلي ة وحي دة (وذل ك في إص دار ‪2.2‬‬

‫من بايثون)‪.‬‬

‫‪ .2‬بايثون ‪3‬‬
‫تع ّد بايثون ‪ 3‬مستقبل لغة بايثون وهي قيد التطوير من اللغة‪ ،‬وه ذا إص دارٌ رئيس ٌ‬
‫ي ُن ِش ر في‬

‫أواخر عام ‪ 2008‬إلصالح بعض المشاكل الجوهرية في تصميم اإلصدارات السابقة من اللغ ة‪ ،‬وك ان‬

‫التركيز أثناء تطوير بايثون ‪ 3‬هو تحسين الشيفرات التي تبنى عليها اللغ ة وح ذف التك رارات‪ ،‬مم ا‬

‫معينة‪.‬‬
‫َّ‬ ‫أن هنالك طريقة وحيدة فقط إلنجاز مهمَّ ة‬
‫يعني َّ‬

‫التع ديالت األساس ية ال تي ح دثت في ب ايثون ‪ 3.0‬تتض من تغي ير التعليم ة ‪ print‬إلى دال ة‬

‫مُ ضمَّ نة باللغة‪ ،‬وتحسين قسمة األعداد الصحيحة‪ ،‬وتوفير دعم إضافي ليونيكود‪.‬‬

‫▲‬ ‫|‬ ‫‪404‬‬


‫البرمجة بلغة بايثون‬ ‫إصدارات بايثون‪ :‬بايثون ‪3‬مقابل بايثون ‪2‬‬

‫في البداية‪ ،‬انتشرت بايثون ‪ 3‬ببطء نتيج ًة لع دم توافقيته ا م ع ب ايثون ‪ ،2‬مم ا يع ني َّ‬
‫أن على‬

‫المستخدمين اختي ار م ا ه و اإلص دار ال ذي عليهم اس تخدامه‪ .‬باإلض افة إلى ذل ك‪ ،‬ك انت الكث ير من‬

‫المكتب ات البرمجي ة متاح ًة فق ط لب ايثون ‪ ،2‬لكن بع د تقري ر فري ق تط وير ب ايثون ‪َّ 3‬‬
‫أنه يجب أن‬

‫التخلي عن دعم ب ايثون ‪ ،2‬فب دأت عملي ة تحوي ل المكتب ات إلى ب ايثون ‪ .3‬يمكنن ا معرف ة زي ادة‬

‫االعتماد على بايثون ‪ 3‬من خالل عدد الحزم البرمجية التي ت دعم ب ايثون ‪ ،3‬وال تي هي (في وقت‬

‫كتابة هذا الكتاب) ‪ 339‬من أصل ‪ 360‬من أشهر الحزم‪.‬‬

‫‪ .3‬بايثون ‪2.7‬‬
‫بع د إص دار ب ايثون ‪ 3.0‬في ‪ ،2008‬ص دِ رَ ت نس خة ب ايثون ‪ 2.7‬في تم وز ‪ 2010‬وهي آخ ر‬
‫ُأ‬

‫ممه ًدا أم ام مس تخدمي‬


‫َّ‬ ‫إص دار من سلس لة ‪ ،2.x‬الغ رض من إص دار ب ايثون ‪ 2.7‬ه و جع ل الطري ق‬

‫ب ايثون ‪ 2.x‬لتحوي ل ب رامجهم إلى ب ايثون ‪ 3‬بتوف ير بعض التوافقي ة بينهم ا‪ .‬وه ذه التوافقي ة‬

‫حس نة في ‪ 2.7‬مث ل ‪ unittest‬ألتمت ة االختب ارات‪ ،‬و ‪argparse‬‬


‫تض منت دعم بعض الوح دات المُ ّ‬

‫لتفس ير خي ارات س طر األوام ر‪ ،‬وبعض الفئ ات في ‪ .collections‬ولخصوص ية ب ايثون ‪2.7‬‬

‫ولكونه ا جس رًا واص اًل بين اإلص دارات القديم ة من ب ايثون ‪ 2‬وبين ب ايثون ‪ ،3.0‬فأص بحت خي ا ًرا‬

‫شائعً ا بين المبرمجين بسبب توافقيتها مع الكثير من المكتبات‪.‬‬

‫عادة إلى إص دار ب ايثون ‪َّ 2.7‬‬


‫ألنه أك ثر إص دار‬ ‫ً‬ ‫عندما نتحدث اليوم عن بايثون ‪ ،2‬فنحن نشير‬

‫مستخدم؛ لكنه يُ ع ُّد َّ‬


‫أنه إصدارٌ قديم‪ ،‬وسيتوقف تطويره (التطوير الح الي ه و إص الح العل ل فق ط)‬

‫تمامً ا في ‪.2020‬‬

‫▲‬ ‫|‬ ‫‪405‬‬


‫البرمجة بلغة بايثون‬ ‫إصدارات بايثون‪ :‬بايثون ‪3‬مقابل بايثون ‪2‬‬

‫‪ .4‬االختالفات األساسية بين اإلصدارات‬


‫أن بايثون ‪ 2.7‬وب ايثون ‪ 3‬تتش اركان في الكث ير من األش ياء‪ ،‬لكن ال يج در ب ك أن‬
‫بغض النظر َّ‬

‫أنهم ا متماثلت ان ويمكن تب ديل الش يفرات بينهم ا‪ .‬ورغم َّ‬


‫أنك تس تطيع كتاب ة ش يفرات جي دة‬ ‫تظن َّ‬

‫أن هنال ك بعض االختالف ات في بني ة‬


‫أي إص دار منهم ا‪ ،‬لكن من المهم أن تفهم َّ‬
‫وب رامج مفي دة في ِّ‬

‫الش يفرات وفي طريق ة تفس يرها‪ .‬س أعرض هن ا بعض األمثل ة‪ ،‬لكن علي ك أن تعلم َّ‬
‫أنك س تواجه‬

‫المزيد من االختالفات أثناء مسيرة تعلمك لبايثون‪.‬‬

‫ا‪print .‬‬

‫في ب ايثون ‪ُ ،2‬تعامَ ل ‪ print‬معامل ة التعليم ات البرمجي ة (‪ )statement‬ب داًل من كونه ا دال ة‪،‬‬

‫ً‬
‫ارتباكا‪ ،‬إذ تتطلب الكثير من األمور داخل بايثون تمرير وس ائط (‪ )arguments‬بين‬ ‫وهذا كان يثير‬

‫فسر بايثون ‪ 2‬لطباعة " ‪،"Sammy the Shark is my favorite sea creature‬‬
‫فتحت مُ ِّ‬
‫َ‬ ‫قوسين‪ ،‬إذا‬

‫فستكتب التعليمة ‪ print‬اآلتية‪:‬‬

‫"‪print "Sammy the Shark is my favorite sea creature‬‬

‫أمَّ ا في ب ايثون ‪ ،3‬فس ُتعامَ ل )(‪ print‬معامل ة ال دوال‪ ،‬ل ذا لطباع ة السلس لة النص ية الس ابقة‪،‬‬

‫فيمكننا استخدام شكل استدعاء الدوال التقليدي كما يلي‪:‬‬

‫)"‪print("Sammy the Shark is my favorite sea creature‬‬

‫دة وس َّهاًل من التب ديل بين مختل ف‬


‫ه ذا التع ديل جع ل من البني ة اللغويَّ ة في ب ايثون موح ً‬

‫أن الدالة )(‪ print‬متوافقة مع بايثون ‪ ،2.7‬لذا س تعمل ش يفرات‬


‫دوال الطباعة فيها‪ .‬يجدر بالذكر َّ‬

‫أي اإلصدارَين‪.‬‬ ‫ً‬


‫صحيحا في ِّ‬ ‫بايثون التي تستعمل )(‪ print‬عماًل‬

‫▲‬ ‫|‬ ‫‪406‬‬


‫البرمجة بلغة بايثون‬ ‫إصدارات بايثون‪ :‬بايثون ‪3‬مقابل بايثون ‪2‬‬

‫ب‪ .‬قسمة األعداد الصحيحة‬

‫في ب ايثون ‪ُّ ،2‬‬


‫أي ع ددٍ تكتب ه دون فواص ل عش رية س ُيعامَ ل على َّ‬
‫أنه من الن وع ‪،integer‬‬

‫كالية عن دما تح اول قس مة األع داد الص حيحة على بعض ها‪ ،‬فتتوق ع في بعض األحي ان‬
‫َّ‬ ‫ت أتي اإلش‬

‫ً‬
‫أيض ا باألع داد ذات الفاص لة [‪ )]float‬كم ا في العملي ة‬ ‫حص ولك على ع ددٍ عش ري (تس مى‬

‫الرياضية التالية‪:‬‬

‫‪5 / 2 = 2.5‬‬

‫العملية التي‬
‫َّ‬ ‫لكن األعداد الصحيحة في بايثون ‪ 2‬لن تتحوَّ ل إلى أعداد عشريَّ ة عندما تتطلب‬
‫َّ‬

‫ُتج رَ ى عليه ا ذل ك‪ .‬عن دما يك ون الع ددان الموج ودان على ج َ‬


‫انبي معام ل القس مة ‪ /‬ع ددين‬

‫عملية القس م وس ُتنتِج ع د ًدا عش ريً ا إال َّ‬


‫أنه ا س ُتعيد الع دد الص حيح‬ ‫َّ‬ ‫فستجري بايثون ‪2‬‬
‫ُ‬ ‫صحيحين‪،‬‬

‫كتبت ‪ 5 / 2‬فس ُتعيد ب ايثون ‪ 2.7‬الع دد الص حيح‬


‫َ‬ ‫األص غر أو المس اوي للن اتج‪ ،‬وه ذا يع ني َّ‬
‫أنه ل و‬

‫األصغر أو المساوي للعدد ‪ ،2.5‬وهو في هذه الحالة ‪:2‬‬

‫‪a = 5 / 2‬‬
‫‪print a‬‬

‫‪2‬‬

‫إلع ادة ع دد عش ري‪ ،‬فيجب إض افة فواص ل عش ريَّ ة إلى األرق ام ال تي س ُتجري عليه ا عملي ة‬

‫القسمة كما في ‪ 5.0 / 2.0‬لكي تحص ل على النتيج ة المنطقي ة ‪ .2.5‬أم ا في ب ايثون ‪ ،3‬فقس مة‬

‫األعداد الصحيحة أصبحت كما نتوقع‪:‬‬

‫‪a = 5 / 2‬‬
‫‪print a‬‬ ‫‪# 2.5‬‬

‫▲‬ ‫|‬ ‫‪407‬‬


‫البرمجة بلغة بايثون‬ ‫إصدارات بايثون‪ :‬بايثون ‪3‬مقابل بايثون ‪2‬‬

‫َ‬
‫أردت تق ريب ن اتج القس مة فاس تخدم‬ ‫يمكن ك اس تخدام ‪ 5.0 / 2.0‬إلع ادة ‪ ،2.5‬لكن إن‬

‫المعامل ‪ //‬الموجود في بايثون ‪ ،3‬كاآلتي‪:‬‬

‫‪a = 5 // 2‬‬
‫‪print a‬‬

‫‪2‬‬

‫هذا التعديل في بايثون ‪ 3‬جعل من قسمة األعداد الصحيحة أمرًا سهاًل ‪ ،‬لكن ه ذه الم يزة غ ير‬

‫متوافقة مع بايثون ‪.2.7‬‬

‫ج‪ .‬دعم محارف يونيكود‬

‫ٌ‬
‫سلسلة من المحارف)‪،‬‬ ‫عندما تتعامل لغات البرمجة مع السالسل النصية ( ‪ ،strings‬والتي هي‬

‫فهي تفعل ذلك بطرائق مختلفة لكي تتمكن الحواسيب من تحويل األعداد إلى أحرف ورموز‪.‬‬

‫‪"Hello,‬‬ ‫تس تعمل ب ايثون ‪ 2‬مح ارف ‪ ASCII‬افتراض ًيا‪ ،‬ل ذا عن دما تكتب "!‪Sammy‬‬

‫فس تتعامل ب ايثون ‪ 2‬م ع السلس لة النص ية على َّ‬


‫أنه ا مجموع ٌة من مح ارف ‪ ،ASCII‬وال تي هي‬

‫أن مح ارف ‪ ASCII‬هي طريق ة غ ير عملي ة لترم يز المح ارف‬ ‫ٌ‬


‫دودة لح والي مئتَي مح رف‪ ،‬أي َّ‬ ‫مح‬

‫خصوصا المحارف غير الالتينية (مث ل العربي ة مثال)‪ .‬إن أردت اس تخدام ترم يز مح ارف يونيك ود‬
‫ً‬

‫(‪ )Unicode‬ال ذي ي دعم أك ثر من ‪ 128000‬مح رف ت ابع للكث ير من اللغ ات والرم وز‪ ،‬فعلي ك أن‬

‫تكتب "!‪ u"Hello, Sammy‬إذ ُتشير السابقة ‪ u‬إلى ‪.Unicode‬‬

‫تس تعمل ب ايثون ‪ 3‬مح ارف يونيك ود (‪ )Unicode‬افتراض يا‪ ،‬مم ا ي ِّ‬
‫وفر علي ك بعض ال وقت‬ ‫ً‬

‫أثناء التطوير‪ ،‬ويمكن ك كتاب ة وع رض ع دد أك بر بكث ير من المح ارف في برنامج ك بس هولة‪ .‬ي دعم‬

‫يونيكود الكثير من المحارف بما في ذل ك الوج وه التعبيري ة (‪ ،)emojis‬واس تعمالها ترم يز مح ارف‬

‫▲‬ ‫|‬ ‫‪408‬‬


‫البرمجة بلغة بايثون‬ ‫إصدارات بايثون‪ :‬بايثون ‪3‬مقابل بايثون ‪2‬‬

‫أن‬
‫تلقائي ا‪ .‬إذا كنت تحب َّ‬
‫ً‬ ‫أن األجه زة المحمول ة س تكون مدعوم ًة في مش اريعك‬
‫افتراض ي يع ني َّ‬

‫متوافقة مع بايثون ‪ 2‬فضع الحرف ‪ u‬قبل السالسل النصية‪.‬‬


‫ً‬ ‫تكون شيفرات بايثون ‪ 3‬التي تكتبها‬

‫د‪ .‬استمرار التطوير‬

‫الفارق الرئيسي بين بايثون ‪ 3‬وبايثون ‪ 2‬ليس في البني ة اللغوي ة وإنم ا في َّ‬
‫أن إص دار ب ايثون‬

‫الح لمزي دٍ من العل ل‪.‬‬


‫يزات جدي دة وإص ٍ‬
‫ٍ‬ ‫‪ 2.7‬توقف دعم ه في ‪ ،2020‬وسيس تمر تط وير ب ايثون ‪ 3‬بم‬

‫تخصيص ا أبس ط إلنش اء األص ناف‪ ،‬وطريق ًة أوض ح للتعام ل‬


‫ً‬ ‫التطويرات األخ يرة في اللغ ة تتض من‬

‫م ع المص فوفات… االس تمرار بتط وير ب ايثون ‪ 3‬يع ني َّ‬


‫أن المط ورين يمكن أن يعتم دوا على اللغ ة‪،‬‬

‫أن المش اكل ال تي ق د تح دث فيه ا س ُت َحل في ف ترةٍ قريب ة‪ ،‬ويمكن أن تص بح ال برامج‬


‫وسيطمئنون َّ‬

‫أكثر كفاءة بإضافة المزيد من الميزات للغة‪.‬‬

‫‪ .5‬نقاط أخرى يجب أخذها بالحسبان‬


‫عليك أن تضع النقاط اآلتية بالحسبان عندما تبدأ مشوار البرمجة بلغة بايثون‪ ،‬أو عندما تبدأ‬

‫معين‪،‬‬ ‫روع‬ ‫ِّ‬


‫تفكر بمش‬ ‫َ‬
‫كنت تأم ل بتعلم اللغ ة دون أن‬ ‫بتعلم لغ ة ب ايثون بع د تعلم ك لغيره ا‪ .‬إذا‬
‫َّ‬ ‫ٍ‬

‫فأنص حك ب التفكير بمس تقبل ب ايثون‪ ،‬فسيس تمر تط وير ودعم ب ايثون ‪ 3‬بينم ا س يوقف دعم‬

‫كنت ُت ِّ‬
‫خطط لالنض مام لفري ق تط وير‬ ‫َ‬ ‫ب ايثون ‪ 2.7‬عمَّ ا ق ريب (إن لم يكن ق د توق ف ‪ .) D-:‬أمَّ ا إذا‬

‫أحد المشاريع‪ ،‬فعليك أن تنظر ما هو إصدار بايثون المستخدم فيه‪ ،‬وكيف ي ؤدي اختالف اإلص دار‬

‫إلى اختالف طريق ة تعامل ك م ع الش يفرات‪ ،‬وإذا م ا ك انت المكتب ات البرمجي ة المس تعملة في‬

‫ً‬
‫مدعومة في مختلف اإلصدارات‪ ،‬وما هي تفاصيل المشروع نفسه‪.‬‬ ‫المشروع‬

‫إذا كنت ُت ِّ‬


‫فكر بب دء أح د المش اريع‪ ،‬فيج در ب ك أن تنظ ر م ا هي المكتب ات المت وفرة وم ا هي‬

‫توافقية أق ل م ع‬
‫َّ‬ ‫األولية من ب ايثون ‪ 3‬له ا‬
‫َّ‬ ‫ً‬
‫سابقا‪ ،‬اإلص دارات‬ ‫إصدارات بايثون المدعومة‪ .‬وكما قلنا‬

‫▲‬ ‫|‬ ‫‪409‬‬


‫البرمجة بلغة بايثون‬ ‫إصدارات بايثون‪ :‬بايثون ‪3‬مقابل بايثون ‪2‬‬

‫المكتب ات المبني ة لب ايثون ‪ ،2‬لكن الكث ير منه ا ق د ج رى تحويل ه إلى ب ايثون ‪ ،3‬وسيس تمر ذل ك في‬

‫السنوات األربع المقبلة‪.‬‬

‫‪ .6‬ترحيل شيفرة بايثون ‪ 2‬إلى بايثون ‪3‬‬


‫بع د أن تعرفن ا على إص دارات ب ايثون والف روق الجوهري ة فيم ا بينه ا‪ ،‬س نتعلم اآلن أفض ل‬

‫آليات وممارس ات ترحي ل الش يفرات من ب ايثون ‪ 2‬إلى ب ايثون ‪ ،3‬وم ا إن ك ان علي ك جع ل الش يفرة‬

‫متوافقة مع كال اإلصدارين‪.‬‬

‫دة من التط وير تق وم على‬ ‫ً‬


‫حقبة جدي ً‬ ‫أن اإلصدار ‪ 2‬من بايثون صدر عام ‪ُ 2000‬لي ِّ‬
‫دشن‬ ‫وجدنا َّ‬

‫الش فافية والش مولية‪ ،‬إذ ش مل ه ذا اإلص دار العدي د من الم يزات البرمجي ة‪ ،‬واس تمر في إض افة‬

‫المزيد طوال مدة تطويره‪.‬‬

‫حالي ا‪ ،‬فج اء في أواخ ر‬


‫ً‬ ‫يُ ع ُّد إصدار بايثون ‪ 3‬مستقبل بايثون‪ ،‬وهو إصدار اللغة قي د التط وير‬

‫أن اعتماد بايثون ‪ 3‬ك ان بطيًئا‬


‫بيد َّ‬ ‫عام ‪ ،2008‬ليعالج العديد من عيوب التصميم الداخلية ويُ ِّ‬
‫عدلها‪ْ .‬‬

‫بسبب عدم توافقه مع بايثون ‪.2‬‬

‫في خض م ذل ك‪ ،‬ج اء اإلص دار ب ايثون ‪ 2.7‬في ع ام ‪ 2010‬ليك ون آخ ر إص دارات ب ايثون ‪2.x‬‬

‫ولي ِّسهل على مستخدمي ب ايثون ‪ 2.x‬االنتق ال إلى ب ايثون ‪ 3‬من خالل توف ير ق در من التواف ق بين‬
‫ُ‬

‫االثنتين‪ ،‬فهذا هو الهدف األساسي من إطالقه‪.‬‬

‫ا‪ .‬ابدأ ببايثون ‪2.7‬‬

‫لالنتق ال إلى ب ايثون ‪ ،3‬أو ل دعم ب ايثون ‪ 2‬وب ايثون ‪ 3‬معً ا‪ ،‬يجب علي ك التأك د من َّ‬
‫أن ش يفرة‬

‫بايثون ‪ 2‬متوافقة تمامً ا مع بايثون ‪.2.7‬‬

‫▲‬ ‫|‬ ‫‪410‬‬


‫البرمجة بلغة بايثون‬ ‫إصدارات بايثون‪ :‬بايثون ‪3‬مقابل بايثون ‪2‬‬

‫يعم ل العدي د من المط ورين حص ريًا بش يفرات ب ايثون ‪ ،2.7‬أمَّ ا الم برمجون ال ذي يعمل ون‬

‫أن الشيفرة تعمل جي ًدا مع بايثون ‪ ،2.7‬وتتوافق معه‪.‬‬


‫بشيفرات أقدم‪ ،‬فعليهم أن يتأكدوا من َّ‬

‫ألنه اإلص دار الوحي د من ب ايثون ‪2‬‬


‫األهمية َّ‬
‫َّ‬ ‫التأكد من توافق الشيفرة مع ب ايثون ‪ 2.7‬أم رٌ ب الغ‬
‫ُّ‬

‫الذي ما يزال قيد الصيانة‪ُ ،‬‬


‫وت َّ‬
‫صح ُح ثغراته (قد توقف دعمه في وقت قراءت ك له ذا الكت اب)‪ .‬ف إذا‬

‫كنت تعم ل بإص دار س ابق من ب ايثون ‪ ،2‬فس تجد نفس ك تتعام ل م ع مش كالت في ش يفرة لم تع د‬

‫ً‬
‫أيض ا بعض األدوات ال تي ِّ‬
‫تس هل ترحي ل الش يفرة‪ ،‬مث ل‬ ‫مدعوم ة‪ ،‬ولم تع د ثغراته ا ُتص َّحح‪ .‬هن اك‬

‫الحزم ة ‪ Pylint‬ال تي تبحث عن األخط اء البرمجي ة‪ ،‬لكن ال ت دعمها إص دارات ب ايثون الس ابقة‬

‫لإلصدار ‪.2.7‬‬

‫أن ب ايثون ‪ 2.7‬م ا زالت قي د ال دعم والص يانة في‬ ‫من المهم أن تض ع في حس بانك َّ‬
‫أنه رغم َّ‬

‫الوقت الحالي‪ ،‬إال َّ‬


‫أنها ستموت في النهاية‪ .‬س تجد في ‪ PEP 373‬تفاص يل الج دول الزم ني إلص دار‬

‫ح ِّدد في ع ام ‪( 2020‬يحتم ل أن‬


‫إن أج ل ب ايثون ‪ُ 2.7‬‬
‫بايثون ‪ ،2.7‬وفي وقت ترجم ة ه ذا الكت اب‪ ،‬ف َّ‬

‫تكون قد ماتت وأنت تقرأ هذه السطور ‪.) (-:‬‬

‫ب‪ .‬االختبار‬

‫ي من عملي ة ترحي ل ش يفرة ب ايثون ‪ 2‬إلى ب ايثون ‪ .3‬ف إذا كنت‬ ‫اختب ار الش يفرة ج ٌ‬
‫زء أساس ٌّ‬

‫أن أدوات االختب ار ال تي‬ ‫ُّ‬


‫التحقق من َّ‬ ‫ً‬
‫أيض ا‬ ‫تعم ل على أك ثر من إص دار واح د من ب ايثون‪ ،‬فعلي ك‬

‫أنها تعمل كما هو متوقع‪.‬‬ ‫ُّ‬


‫للتأكد من َّ‬ ‫تستخدمها تغطي جميع اإلصدارات‬

‫يمكنك إضافة حاالت ب ايثون التفاعلي ة (‪ )interactive Python cases‬إلى السالس ل النص ية‬

‫التوثيقية (‪ )docstrings‬الخاص ة بكاف ة ال دوال والتواب ع واألص ناف والوح دات ثم اس تخدام‬
‫َّ‬

‫جزءا من عملية االختبار‪.‬‬


‫ً‬ ‫الوحدة ‪ doctest‬المُ ضمَّ نة للتحقق من عملها كما هو موضح إذ يع ُّد ذلك‬

‫▲‬ ‫|‬ ‫‪411‬‬


‫البرمجة بلغة بايثون‬ ‫إصدارات بايثون‪ :‬بايثون ‪3‬مقابل بايثون ‪2‬‬

‫إلى جانب ‪ ،doctest‬يمكنك استخدام الحزمة ‪ package.py‬لتتبع وحدة االختبار‪ .‬ستراقب‬

‫هذه األداة برنامجك وتحدد األجزاء التي ُت ِّ‬


‫نفذها من الشيفرة‪ ،‬واألج زاء ال تي يمكن تنفي ذها ولكن‬

‫نفذ‪ .‬يمكن أن تطب ع ‪ Cover.py‬تقري رًا في س طر األوام ر‪ ،‬أو تنتج مس تند ‪ُ .HTML‬تس تخدم‬
‫لم ُت َّ‬

‫ُ‬
‫اخت ِب رت‪ ،‬واألج زاء ال تي‬ ‫ع ً‬
‫ادة لقي اس فعالي ة االختب ارات‪ ،‬إذ توض ح األج زاء من الش يفرة ال تي‬

‫لم ُت َ‬
‫ختبر‪.‬‬

‫أي شيفرة غامض ة أو غ ير عادي ة‪.‬‬ ‫ذكر أنه ليس عليك اختبار كل شيء‪ ،‬لكن َّ‬
‫تأكد من تغطية ّ‬ ‫َت َّ‬

‫للحصول على أفضل النتائج‪ ،‬يُ نصح أن تشمل التغطية ‪ ٪80‬من الشيفرة‪.‬‬

‫‪ .7‬تعرف على االختالفات بين بايثون ‪ 2‬و بايثون ‪3‬‬


‫سيمكنك التعرُّ ف على االختالف ات بين ب ايثون ‪ 2‬و ب ايثون ‪ 3‬من اس تخدام الم يزات الجدي دة‬
‫ِّ‬

‫المتاحة‪ ،‬أو التي ستكون متاحة في بايثون ‪.3‬‬

‫ً‬
‫أيض ا مراجع ة توثي ق‬ ‫ً‬
‫مسبقا إلى بعض االختالفات الرئيسية بين اإلصدارين‪ ،‬ويمكنك‬ ‫تطرقنا‬

‫بايثون الرسمي لمزيد من التفاصيل‪.‬‬

‫عند البدء في ترحيل الشيفرة‪ ،‬فهناك بعض التغييرات في الصياغة عليك تعديلها فوريً ا‪.‬‬

‫‪ :Print‬حلت الدالة )(‪ print‬في بايثون ‪ 3‬مكان التعليمة ‪ print‬في بايثون ‪.2‬‬ ‫•‬

‫بايثون ‪# 2‬‬
‫"!‪print "Hello, World‬‬

‫بايثون ‪# 3‬‬
‫)"!‪print("Hello, World‬‬

‫▲‬ ‫|‬ ‫‪412‬‬


‫البرمجة بلغة بايثون‬ ‫إصدارات بايثون‪ :‬بايثون ‪3‬مقابل بايثون ‪2‬‬

‫ً‬
‫دالة تسمح بتمرير متغيرات محلية‬ ‫تغيرت التعليمة ‪ exec‬في بايثون ‪ 2‬وأصبحت‬
‫‪َّ :exec‬‬ ‫•‬

‫(‪ )locals‬وعامة (‪ )globals‬صريحة في بايثون ‪.3‬‬

‫بايثون ‪# 2‬‬
‫‪exec code‬‬ ‫‪# 1‬‬

‫‪exec code in globals‬‬ ‫‪# 2‬‬

‫)‪exec code in (globals, locals‬‬ ‫‪# 3‬‬

‫بايثون ‪# 3‬‬
‫)‪exec(code‬‬ ‫‪# 1‬‬

‫)‪exec(code, globals‬‬ ‫‪# 2‬‬

‫)‪exec(code, globals, locals‬‬ ‫‪# 3‬‬

‫‪ /‬و ‪ُ ://‬تج ِري ب ايثون ‪ 2‬القس مة التقريبي ة (‪ )floor division‬بالعام ل ‪ ،/‬بينم ا تخص ص‬ ‫•‬

‫بايثون ‪ 3‬العامل ‪ //‬إلجراء القسمة التقريبية‪.‬‬

‫بايثون ‪# 2‬‬
‫‪5 / 2 = 2‬‬

‫بايثون ‪# 3‬‬
‫‪5 / 2 = 2.5‬‬
‫‪5 // 2 = 2‬‬

‫الستخدام هذين العاملين في بايثون ‪ ،2‬استورد ‪ division‬من الوحدة __‪:__future‬‬

‫‪from __future__ import division‬‬

‫▲‬ ‫|‬ ‫‪413‬‬


‫البرمجة بلغة بايثون‬ ‫إصدارات بايثون‪ :‬بايثون ‪3‬مقابل بايثون ‪2‬‬

‫‪ :raise‬في ب ايثون ‪ ،3‬يتطلب إطالق االس تثناءات ذات الوس ائط اس تخدام األق واس‪،‬‬ ‫•‬

‫كما ال يمكن استخدام السالسل النصية كاستثناءات‪.‬‬

‫بايثون ‪# 2‬‬
‫‪raise Exception, args‬‬ ‫‪# 1‬‬

‫‪raise Exception, args, traceback‬‬ ‫‪# 2‬‬

‫"‪raise "Error‬‬ ‫‪# 3‬‬

‫بايثون ‪# 3‬‬
‫‪raise Exception‬‬ ‫‪# 1‬‬
‫)‪raise Exception(args‬‬

‫)‪raise Exception(args).with_traceback(traceback‬‬ ‫‪# 2‬‬

‫)"‪raise Exception("Error‬‬ ‫‪# 3‬‬

‫‪ :except‬في بايثون ‪ ،2‬كان من الصعب إدراج االس تثناءات المُ تع ِّددة لكن ذل ك َّ‬
‫تغير في‬ ‫•‬

‫صراحة مع ‪ except‬في بايثون ‪:3‬‬


‫ً‬ ‫بايثون ‪ .3‬الحظ َّ‬
‫أن ‪ُ as‬تستخ َدم‬

‫بايثون ‪# 2‬‬
‫‪except Exception, variable:‬‬

‫بايثون ‪# 3‬‬
‫‪except AnException as variable:‬‬
‫‪except (OneException, TwoException) as variable:‬‬

‫‪ :def‬في ب ايثون ‪ ،2‬يمكن لل دوال أن تقب ل سالس ل مث ل الص فوف أو الق وائم‪ .‬أمَّ ا في‬ ‫•‬

‫بايثون ‪ ،3‬فقد أزيل هذا األمر‪.‬‬

‫▲‬ ‫|‬ ‫‪414‬‬


‫البرمجة بلغة بايثون‬ ‫إصدارات بايثون‪ :‬بايثون ‪3‬مقابل بايثون ‪2‬‬

‫بايثون ‪# 2‬‬
‫‪def function(arg1, (x, y)):‬‬

‫بايثون ‪# 3‬‬
‫‪def function(arg1, x_y): x, y = x_y‬‬

‫‪ :expr‬لم تعد صياغة عالمة االقتب اس المائل ة `` في ب ايثون ‪ 2‬ص الحة‪ ،‬واس تخدم ب داًل‬ ‫•‬

‫عنها )(‪ repr‬أو )(‪ str.format‬في بايثون ‪.3‬‬

‫بايثون ‪# 2‬‬
‫`‪x = `355/113‬‬

‫بايثون ‪# 3‬‬
‫‪x = repr(355/113):‬‬

‫تنس يق السالس ل النص ية (‪ :)String Formatting‬لق د تغ يرت ص ياغة تنس يق السالس ل‬ ‫•‬

‫النصية من بايثون ‪ 2‬إلى بايثون ‪.3‬‬

‫بايثون ‪# 2‬‬
‫)‪"%d %s" % (i, s‬‬ ‫‪# 1‬‬
‫)‪"%d/%d=%f" % (355, 113, 355/113‬‬ ‫‪# 2‬‬

‫بايثون ‪# 3‬‬
‫)‪"{} {}".format(i, s‬‬ ‫‪# 1‬‬
‫)‪"{:d}/{:d}={:f}".format(355, 113, 355/113‬‬ ‫‪# 2‬‬

‫ت ذكر كيفي ة اس تخدام تنس يقات السالس ل النص ية من فص ل كيفي ة اس تخدام آلي ة تنس يق‬

‫السالسل النصية في بايثون ‪.3‬‬

‫‪ :class‬ليست هناك حاجة لتمرير ‪ object‬في بايثون ‪.3‬‬ ‫•‬

‫▲‬ ‫|‬ ‫‪415‬‬


‫البرمجة بلغة بايثون‬ ‫إصدارات بايثون‪ :‬بايثون ‪3‬مقابل بايثون ‪2‬‬

‫بايثون ‪# 2‬‬
‫‪class MyClass(object):‬‬
‫‪pass‬‬

‫بايثون ‪# 3‬‬
‫‪class MyClass:‬‬
‫‪pass‬‬

‫في بايثون ‪ُ ،3‬ت َ‬


‫ضبط األصناف العليا (‪ )metaclasses‬بالكلمة مفتاحية ‪.metaclass‬‬

‫بايثون ‪# 2‬‬
‫‪class MyClass:‬‬
‫‪__metaclass__ = MyMeta‬‬
‫‪class MyClass(MyBase):‬‬
‫‪__metaclass__ = MyMeta‬‬

‫بايثون ‪# 3‬‬
‫‪class MyClass(metaclass=type):‬‬
‫‪pass‬‬
‫‪class MyClass(MyBase, metaclass=MyMeta):‬‬
‫‪pass‬‬

‫‪ .8‬تحديث الشيفرة‬
‫توافقيته ا م ع‬
‫َّ‬ ‫تلقائيا إلى ب ايثون ‪ 3‬م ع الحف اظ على‬
‫ً‬ ‫هناك أ َداتان ّ‬
‫رئيسيتان لتَحديث الشيفرة‬

‫بايثون ‪ 2‬وهما‪ future :‬و ‪ .modernize‬تختلف َ‬


‫آليتا عمل ه اتين األداتين‪ ،‬إذ تح اول ‪ future‬نق ل‬

‫أفض ل ممارس ات ب ايثون ‪ 3‬إلى ب ايثون ‪ ،2‬في حين َّ‬


‫أن ‪ modernize‬تس عى إلى إنش اء ش يفرات‬

‫التوافقية‪ .‬يمكن أن تس اعدك‬


‫َّ‬ ‫موحدة لب ايثون تتواف ق م ع ‪ 2‬و ‪ 3‬وتس تخدم الوح دة ‪ six‬لتحس ين‬
‫َّ‬

‫هات ان األدات ان في إع ادة كتاب ة الش يفرة وتحدي د ورص د المش اكل المحتمل ة وتص حيحها‪ .‬يمكن ك‬

‫أن‬ ‫ُّ‬
‫والتحقق منه ا بص ريً ا‪ ،‬والتأك د من َّ‬ ‫تش غيل األداة ع بر مجموع ة ‪ unittest‬لفحص الش يفرة‬

‫▲‬ ‫|‬ ‫‪416‬‬


‫البرمجة بلغة بايثون‬ ‫إصدارات بايثون‪ :‬بايثون ‪3‬مقابل بايثون ‪2‬‬

‫ُأ‬
‫المراجع ات التلقائي ة ال تي ج ريَ ت دقيق ة‪ .‬وبمج رد انته اء االختب ارات‪ ،‬يمكن ك‬

‫تحويل الشيفرة‪.‬‬

‫بع د ه ذا‪ ،‬س تحتاج على األرجح إلى إج راء مراجع ة يدويَّ ة‪ ،‬وخاص ة اس تهداف االختالف ات‬

‫بين ب ايثون ‪ 2‬و ‪ 3‬الم ذكورة في القس م أعاله‪ .‬إن أردت اس تخدام ‪ ،future‬فعلي ك إض افة عب ارة‬

‫االستيراد التالية في جميع وحدات بايثون ‪:2.7‬‬

‫‪from __future__ import print_function, division,‬‬


‫‪absolute_imports, unicode_literals‬‬

‫أن ه ذا لن يعفي ك من إع ادة كتاب ة الش يفرة‪ ،‬إال َّ‬


‫أنه سيض من ل ك أن تتماش ى ش يفرة‬ ‫رغم َّ‬

‫بايثون ‪ 2‬مع صياغة بايثون ‪.3‬‬

‫أخ يرًا‪ ،‬يمكن ك اس تخدام الحزم ة ‪ pylint‬لتحدي د ورص د أي مش كالت محتمل ة أخ رى في‬

‫الشيفرة‪ .‬تحتوي هذه الحزمة على مئات القواعد التي تغطي مجموعة واسعة من المش كالت ال تي‬

‫قد تطرأ‪ ،‬بما فيها قواعد الدليل ‪ ،PEP 8‬باإلضافة إلى أخطاء االستخدام‪.‬‬

‫أن بعض أج زاء ش يفرتك ترب ك ‪ pylint‬وأدوات الترحي ل التلق ائي األخ رى‪ .‬ح اول‬
‫ق د تج د َّ‬

‫تبسيطها‪ ،‬أو استخدم ‪.unittest‬‬

‫‪ .9‬التكامل المستمر (‪)Continuous Integration‬‬


‫إذا أردت أن تجع ل ش يفرتك متوافق ة م ع ع دة إص دارات من ب ايثون‪ ،‬فس تحتاج إلى تش غيل‬

‫اإلط ار ‪ unittest‬باس تمرار وف ق مب دأ التكام ل المس تمر (وليس ي دويًا)‪ ،‬أي أن تفع ل ذل ك أك بر ع دد‬

‫التوافقية بين‬
‫َّ‬ ‫ممكن من الم رات أثن اء عملي ة التط وير‪ .‬إذا كنت تس تخدم الحزم ة ‪ six‬لص يانة‬

‫بايثون ‪ 2‬و ‪ ،3‬فستحتاج إلى استخدام ع َّدة بيئات عمل ألجل االختبار‪.‬‬

‫▲‬ ‫|‬ ‫‪417‬‬


‫البرمجة بلغة بايثون‬ ‫إصدارات بايثون‪ :‬بايثون ‪3‬مقابل بايثون ‪2‬‬

‫إح دى ح زم إدارة البيئ ة ال تي ق د تك ون مفي دة ل ك هي الحزم ة ‪ ،tox‬إذ س تفحص تثبيت ات‬

‫الحزمة مع مختلف إصدارات بايثون‪ ،‬وإجراء االختبارات في كل بيئ ة من بيئ ات عمل ك‪ ،‬كم ا يمكن‬

‫أن تكون بمثابة واجهة عمل للتكامل المستمر‪.‬‬

‫‪ .10‬خالصة الفصل‬
‫ممتازا وسهلة التعلم‪ ،‬ومهما كان اختيارك (ب ايثون ‪ 2‬أو‬
‫ً‬ ‫ً‬
‫توثيقا‬ ‫لغة بايثون كبيرة ج ًدا وموثقة‬

‫أن هنالك بعض االختالفات‬


‫صحيح َّ‬
‫ٌ‬ ‫حاليا‪.‬‬
‫ً‬ ‫بايثون ‪ )3‬فستتمكن من العمل على المشاريع الموجودة‬

‫أن ب ايثون ‪2.7‬‬ ‫المحورية‪ ،‬لكن ليس من الصعب االنتقال من بايثون ‪ 3‬إلى ب ايثون ‪ ،2‬وس تجد ع ً‬
‫ادة َّ‬

‫خصوص ا في ب دايات تعلم ك للغ ة‪ .‬من المهم أن تبقي ببال ك‬


‫ً‬ ‫قادرة على تشغيل ش يفرات ب ايثون ‪،3‬‬

‫أن ترك يز المط ورين والمجتم ع أص بح منص ًّبا نح و ب ايثون ‪ ،3‬وستص بح ه ذه اللغ ة رائ ً‬
‫دة في‬ ‫َّ‬

‫وأن دعم ب ايثون ‪ 2.7‬س يقل م ع م رور ال زمن‬


‫َّ‬ ‫المس تقبل وس تلبي االحتياج ات البرمجي ة المطلوب ة‪،‬‬

‫إلى أن يزول في ‪( 2020‬قد زال لحظة ترجمة الكتاب ومراجعته)‪.‬‬

‫▲‬ ‫|‬ ‫‪418‬‬

You might also like