البرمجة بلغة بايثون تعلم البرمجة وكتابة البرامج وتنقيحها بلغة بايثون تأليف ليزا تاغليفيري ترجمة محمد بغات عبد اللطيف ايمش تحرير جميل بيلوني تصميم الغالف فرج الشامي أكاديمية حسوب © النسخة األولى 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...................................... .6استخدام المُ ِّ نسقات 153.......................................... .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....................... ِّ .6الوراثة المُ تعددة (358...............)Multiple Inheritance .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 ----- --------------Undefined MachinePolicy Undefined UserPolicy Undefined Process RemoteSigned CurrentUser Undefined LocalMachine أن المس تخدم الح الي يمكن ه تنفي ذ الس كربتات الموثوق ة ال تي ِّ نُزلت من الش بكة. ه ذا يؤك د َّ يمكننا اآلن تنزيل الملفات التي سنحتاج إليها إلعداد بيئة برمجة بايثون. ج .تثبيت 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. likely Software installed as 'EXE', install location is 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 سنحصل على المخرجات التالية: Length Name LastWriteTime Mode ------ ---- ------------- ---- Include 2:20 PM 8/22/2016 d----- 37 | ▲ البرمجة بلغة بايثون تثبيت بايثون وإعداد بيئة العمل 2:20 PM 8/22/2016 d----- Lib Scripts 2:20 PM 8/22/2016 d----- 107 pyvenv.cfg 2:20 PM 8/22/2016 -a---- تعم ل ه ذه الملف ات م ع بعض ها لض مان أن تك ون مش اريعك معزول ٌة عن س ياق اآلل ة المحلي ة، أن لكي ال تختلط ملفات النظ ام م ع ملف ات المش اريع .وه ذا أم رٌ حس ٌن إلدارة اإلص دارات ولض مان َّ الحزم التي يحتاجها. كل مشروع يملك وصواًل إلى ٍ عليك تفعيل البيئة الستخدامها ،وذلك بكتاب ة األم ر الت الي ال ذي س ُي ِّ نفذ س كربت التفعي ل في المجلد :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برمجي ة باس م ،venvوهي ج ٌ زء من مكتب ة ب ايثون 3القياس ية .س نثبِّت 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ب داًل من pip3 َ كنت تس تخدم ب ايثون 3خ ارج البيئ ة االفتراض َّية ،فيجب علي ك حينه ا اس تخدام ئت أم ا إذا إن ش َ. 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 python3dev 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ب داًل من pip3 َ كنت تس تخدم ب ايثون 3خ ارج البيئ ة االفتراض ية ،فيجب علي ك حينه ا اس تخدام ئت أم ا إذا إن ش َ. 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ب داًل من pip3.6 َ كنت تس تخدم ب ايثون 3خ ارج البيئ ة االفتراض ية ،فيجب علي ك حينه ا اس تخدام ئت أم ا إذا إن ش َ. 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 نافذة الطرفية ستخرج قائمة من الحزم والوحدات التي يمكنك تثبيتها على النحو التالي: python3 micropython app-engine-python wxpython python boost-python zpython python-markdown gst-python homebrew/versions/gst- homebrew/apache/mod_python python010 Caskroom/cask/kk7ds- homebrew/python/python-dbus python-runtime Caskroom/cask/mysql- homebrew/python/vpython 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ب داًل من pip3 َ كنت تس تخدم ب ايثون 3خ ارج البيئ ة االفتراض ية ،فيجب علي ك حينه ا اس تخدام ئت أم ا إذا إن ش َ. ألن pythonو pipستستدعيان إصدارًا قديمً ا من بايثون python3و pip3حصرًاَّ . ز .إنشاء برنامج بسيط ً ً ِ يطا يع رض العب ارة برنامج ا بس لننش ئ بع د أن أكملن ا ض بط بيئتن ا االفتراض ية، أن البيئ ة تعم ل بالش كل الص حيح ،ولكي تتع وَّ د على إنش اء «مرحبا بالع الم!» ،وبه ذا س نتحقق من َّ َ كنت واف ًدا جدي ًدا على اللغة. برامج بايثون إن 67 | ▲ البرمجة بلغة بايثون تثبيت بايثون وإعداد بيئة العمل علينا أواًل تشغيل محرر ملفات نصية إلنشاء ملف جديد ،وليكن المحرر nanoالذي يعمل من سطر األوامر: (my_env) sammys-MBP:~ sammy$ nano hello.py بعد فتح الملف في نافذة الطرفية ،سنكتب البرنامج الخاص بنا: )"!print("Hello, World أغلق محرر nanoبالضغط على Ctrl+xثم اضغط على yعندما يسألك عن حفظ الملف. بعد أن يُ َ غلق المحرر nanoوتعود إلى سطر األوامر ،حاول تنفيذ البرنامج: python hello.py (my_env) sammys-MBP:~ sammy$ َ أنشأته إلى طباعة الناتج التالي في الطرفية: سيؤدي برنامج 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وال ذي يُ ع رَ ض في المخرج ات بمجرد إدخال األمر ،إلى جانب إشعار حقوق الملكية ،وبعض األوامر التي يمكن ك كتابته ا للحص ول على معلومات إضافية: )4 2020, 15:43:14 Python 3.7.7 (default, Jun [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فنحص ل على المخرجات التالية: )4 2020, 15:43:14 Python 3.7.7 (default, Jun [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, pythondateutil, numpy, pytz, matplotlib Successfully installed cycler-0.10.0 matplotlib-2.0.2 numpy1.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بقيمة عشوائية # x = 8 يجب اس تخدام التعليق ات الس طرية عن د الض رورة وحس ب ،كم ا ينبغي أن ت ِّ وفر إرش ادات مفيدة للشخص الذي يقرأ البرنامج. .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نوعه ا ع دد صحيح ،سنتطرق إلى أنواع البيانات في الفصل التالي). التعليم ة = 103204934813 my_intهي تعليم ة إس ناد ( ،)assignment statement وتتألف من األجزاء التالية: • اسم المتغير ()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 غير مسموح بالشرطات 4int int4 ال يمكن البدء برقم $MY_INT MY_INT أي رمز غير ال يمكن استخدام ّ another int another_int الشرطة السفلية ال ينبغي أن يتكون االسم من أكثر من كلمة واحدة من األم ور ال تي يجب أخ ذها في الحس بان عن د تس مية المتغ يرات ،ه و َّ أنه ا حساس ة لحال ة أن my_intو MY_INTو My_Intو mY_iNtكله ا مختلف ة .ينبغي أن تتجنب األحرف ،وهذا يعني َّ 92 | ▲ البرمجة بلغة بايثون المتغيرات واستخداماتها اس تخدام أس ماء متغيِّ رات متماثل ة لض مان أال يح دث خل ط عن دك أو عن د المتع اونين مع ك ،س واء الحاليين والمستقبليِّ ين. أخ يرًا ،ه ذه بعض المالحظ ات ح ول أس لوب التس مية .من المتع ارف علي ه عن د تس مية المتغيرات أن تبدأ اسم المتغير بحرف ص غير ،وأن تس تخدم الش رطة الس فلية عن د فص ل الكلم ات. ِّ ً يفض ل بعض األش خاص اس تعمال تنس يق س نام الجم ل أيض ا ،وق د الب دء بح رف كب ير مقب ول ولكن ه ذه الخي ارات ( ،camelCaseالخلط بين األحرف الكب يرة والص غيرة) عن د كتاب ة المتغ يرات، َّ أقل شهرة. تنسيق غير شائع تنسيق شائع myInt my_int Int4 int4 myFirstString my_first_string لماذا غير متعارف عليه أسلوب سنام الجمل ( )camelCaseغير شائع الحرف األول كبير أسلوب سنام الجمل ( )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المستخدمة قبل اسم المتغير داخل الدالة. َ أي خطأ عندما نستدعي ) print(sharkخ ارج الدال ة. بسبب استخدام ،globalفلن يُ طلق ُّ رغم َّ أن ذل ك يُ ع ُّد من الع ادات غ ير المس تحبة في أنه يمكن ك اس تعمال متغ ير ع ام داخ ل دال ة ،إال َّ البرمج ةَّ ، ألنه ا ق د ت ؤثر على مقروئي ة الش يفرة ع دا عن الس ماح لج زء من الش يفرة بتع ديل قيم ة متغير قد يستعمله جزء آخر. هناك شيء آخر يجب تذكره ،وهو َّ أنك إذا أشرت إلى متغير داخل دال ة ،دون إس ناد قيم ة ل ه، محليا ،يجب عليك إسناد قيمة له داخل متن الدالة. متغير ضمنيا .لجعل فسيعَ ّد هذا المتغير عامً ا ُ ًّ ًّ ٍ عن د التعام ل م ع المتغ يرات ،يك ون ل ك الخي ار بين اس تخدام المتغ يرات العام ة أو المحلي ة. يُ َّ فض ل في العادة استخدام المتغيرات المحلية ،ولكن إن وجدت نفسك تس تخدم نفس المتغ ير في عدة دوال ،فقد ترغب في جعله عامً ا .أمَّ ا إن كنت تحتاج المتغير داخل دالة أو ص نف واح د فق ط، فقد يكون األولى استخدام متغير محلي. 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 وطباعة السلسلة عن طريق استدعاء المتغيِّ ر: !# Hello, World )print(hw 108 | ▲ البرمجة بلغة بايثون أنواع البيانات والتحويل بينها مث ل األع داد ،هن اك العدي د من العملي ات ال تي يمكن إجراؤه ا على السالس ل النص ية من أج ل تحقي ق النت ائج ال تي نس عى إليه ا .السالس ل النص ية مهم ة لتوص يل المعلوم ات إلى المس تخدم، وكذلك لتمكين المستخدم من تمرير المعلومات إلى البرنامج. .5القوائم ()Lists القائمة ( )listعب ارة عن تسلس ل م َّ رتب قاب ل للتغي ير ( .)mutableوكم ا ُتع رَّ ف السالس ل النصية باستخدام عالمات االقتباس ،يتم تعريف القوائم باستخدام األقواس المعقوفة []. َّ ً صحيحة: مثاًل ،هذه قائمة تحوي أعدا ًدا ][-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س تكون معين ،ب ً النص ية يرتب ط بفه رس ّ الفهارس والمحارف المرتبطة بها كاآلتي: ! k r a h s 11 10 9 8 7 6 5 y m m a s 4 3 2 1 0 وكم ا الحظت ،س يرتبط المح رف Sب الفهرس ،0وس تنتهي السلس لة النص ية ب الفهرس 11م ع ً رس خ ٌ اص ب ه ،وفي مثالن ا الرم ز ! .الح ظ أن الف راغ بين كلمتَي Sammyو Sharkل ه فه ٌ أيض ا َّ ً رس خ ٌ أيض ا ،وأيَّ ة رم وز أو عالم ات ت رقيم اص به ا سيكون له الفهرس .5عالم ة التعجب ! له ا فه ٌ أن المح ارف في ب ايثون له ا فه رس أخرى مثل * ?;.&$#سترتبط ٍ بفهرس مخص ص له ا .حقيق ة َّ أن بإمكاننا الوصول إلى السالسل النص ية وتع ديلها كم ا نفع ل م ع أن واع البيان ات خاص بها ستعني َّ المتسلسلة األخرى. ا .الوصول إلى المحارف بفهارس موجبة يمكنن ا الحص ول على مح رف من سلس لة نص ية باإلش ارة إلي ه ع بر فهرس ه .يمكنن ا فع ل ذل ك لة نص ً عرف في المث ال اآلتي سلس ً بوض ع رقم الفه رس بين قوس ين معق وفين [] .س ُن ِّ ية ونطب ع المحرف المرتبط بالفهرس المذكور بين قوسين: "!ss = "Sammy Shark )]print(ss[4 128 | ▲ البرمجة بلغة بايثون السالسل النصية والتعامل معها الناتج: y معي ٍن في سلس لةٍ نص يةٍ ،فس ُتعيد ب ايثون المح رف الموج ود في ذاك رس عندما ُنشير إلى فه ٍ ّ الموض ع ،ولمَّ ا ك ان المح رف yموج و ًدا في الفه رس الراب ع في السلس ية لة النص "! "Sammy Sharkفعندما طبعنا ] ss[4فظهر الحرف .y معين ة ض من خالص ة م ا س بق ،أرق ام الفه ارس ستس مح لن ا بالوص ول إلى مح ارف ّ سلسلة نصية. ب .الوصول إلى المحارف بفهارس سالبة إذا ك انت ل ديك سلس ٌ ً انطالق ا من نهايته ا ،فعندئ ذٍ لة طويل ٌة وأردن ا تحدي د أح د محارفه ا لكن دءا من الفه رس .-1ل و أردن ا أن نس تخدم الفه ارس نستطيع اس تخدام األرق ام الس البة للفه ارس ،ب ً السالبة مع السلسلة النصية ! ،Sammy Sharkفستبدو كما يلي: ! k r a h s -1 -2 -3 -4 -5 -6 -7 y m m a s -8 -9 -10 -11 -12 يمكنن ا أن نطب ع المح رف 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 # Shark )]print(ss[6:11 سنحصل على نفس النتائج بتضمين معامل ثالث هو الخطوة وقيمته :1 # Shark )]print(ss[6:11:1 ً أن ب ايثون ُ ستض ِّمن جمي ع المح ارف بين فهرس ين ،وإذا إذا ،إذا ك انت الخط وة 1فه ذا يع ني َّ ً َ أن بعض ذفت الخط وة فس تع ُّدها ب ايثون مس ح اوية للواح د .أم ا ل و زدن ا الخط وة ،فس نرى َّ المحارف ستهمل: # SmySak )]print(ss[0:12:2 ألق تحديد الخطوة بقيمة 2كما في ] ss[0:12:2سيؤدي إلى تجاوز حرف بين كل حرفينِ ، ً نظرة على المحارف المكتوبة بخط عريض: !Sammy Shark ُأ ً أيض ا عن دما ك انت الخط وة .2إذا وض عنا أن الف راغ الموج ود في الفه رس 5ق د همِ ل الح ظ َّ ً قيمة أكبر للخطوة ،فسنحصل على سلسلةٍ نصيةٍ فرعيةٍ أصغر بكثير: # Sya )]print(ss[0:12:4 حذف الفهرسين وترك النقط تين الرأس يتين س يؤدي إلى إبق اء كام ل السلس لة ض من المج ال، ً سي ِّ إضافة إلى ذل ك، حدد عدد المحارف التي سيتم تخطيها. لكن إضافة معامل ثالث وهو الخطوة ُ ِّ ترتيب معك وس إذا يمكن ك من كتاب ة السلس لة النص ية ب يمكن ك تحدي د رقم س الب كخط وة ،مم ا ٍ 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 • َّ تتحقق إذا احت وت السلس لة النص ية على أح رف فق ط (دون أرق ام )(:str.isalpha َّ تحقق ذلك. رموز) ،أي تعيد trueإن أو رموز). • َّ تتحقق إذا كانت جميع أحرف السلسلة النصية صغيرة. )(: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 أن السلسلة النصية الجديدة هي السلسلة األولى لكن بين كل حرفين فراغ: فسنجد َّ b a l l o o n . a h a s S a m m y ً أيضا استخدام الدالة )( str.joinإلنشاء مقلوب سلسلة نصية: يمكننا )))print("".join(reversed(balloon .noollab a sah ymmaS لم ن رغب في إض افة أيَّ ة سلس لة نص ية إلى أخ رى ،ل ذا أبقين ا على السلس لة النص ية فارغ ًة دون 140 | ▲ البرمجة بلغة بايثون السالسل النصية والتعامل معها محت وى داخله ا .الدال ة )( str.joinمفي ٌ ً أيض ا لجم ع قائم ة ( )listمن السالس ل النص ية دة وإخراجها إلى سلسلةٍ وحيدة .ل ُن ِ فصل بين كلماتها بفاصلة من القائمة اآلتية: نشئ سلسلة نصية يُ َ ))]"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دوال اإلحصاء بع د أن تعرفن ا على آلي ة فهرس ة المح ارف في السالس ل النص ية ،ح ان ال وقت لمعاين ة بعض الدوال التي ُتحصي السالسل النصية أو تعيد أرقام الفه ارس .يمكنن ا أن نس تفيد من ذل ك بتحدي د عدد المحارف التي نريد استقبالها من مدخالت المستخدم ،أو لموازنة السالسل النصية. عدة دوال ُتستخدم لإلحصاء .لننظ ر أواًل لدى السالسل النصية –كغيرها من أنواع البيانات– ِّ أي ن وع متسلس ل من البيان ات ،بم ا في ذل ك األن واع string إلى الدال ة )( lenال تي ُتعي د ط ول َّ و 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التقلي دي ،تك ون الص ياغة المختزل ة هي "!World "Hello,بينم ا السلس لة النص ية المج رَّ دة هي !World Hello,دون عالمتَي أن السلسلة النصية هي ما نراه في نافذة الطرفية عندما ُنش ِّغل برن امج ب ايثون .لكن االقتباس .أي َّ وألن القيم بعض السالس ل النص ية ق د تحت وي على عالم ات اقتب اس ،مث ل اقتباس نا لمقول ةٍ م ا. َّ المُ صنَّفة على َّ أنها سالسل نصية بالصياغة المختزلة والقيم الفعلية المجرَّ دة للسالس ل النص ية غ ير متساوية ،فمن الضروري في أغلب الح االت إض افة تنس يق إلى ص ياغة السلس لة النص ية المختزل ة لعرضها كما ينبغي. .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 Shark # 1. Shrimp # 2. Squid # 10. عالمة الجدولة األفقية ال تي وض عناها ع بر مح رف الته ريب \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ل ذا س يبدو الناتج كاآلتي: 27 9 3 64 16 4 125 25 5 216 36 6 343 49 7 512 64 8 729 81 9 1000 100 10 1331 121 11 1728 144 12 ً أيض ا تحدي د حجم ث ابت للحق ل لنحص ل على أعم دة متس اوية الع رض ،مم ا يض من يمكنن ا إظهار األعداد الكبيرة بصورة صحيحة: for i in range(3,13): ))print("{:6d} {:6d} {:6d}".format(i, i*i, i*i*i الناتج: 27 9 3 64 16 4 159 | ▲ البرمجة بلغة بايثون مدخل إلى تنسيق النصوص 125 25 5 216 36 6 343 49 7 512 64 8 729 81 9 1000 100 10 1331 121 11 1728 144 12 ً أيضا تعديل محاذاة النص الموجود في األعمدة باستخدام الرموز > و ^ و < ،وتبديل يمكننا 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 الناتج: ! 5 red balloons Sammy has ً محرف ا أعطين ا في المث ال الس ابق حقاًل بحجم 4مح ارف للع دد ،5وأعطين ا حقاًل بحجم 16 بيا) .وكم ا رأين ا من ن اتج المث ال الس ابق ،يتم للسلسلة النصية ( balloonsألنه ا سلس لة طويل ة نس ً افتراضيا إلى اليسار واألعداد إلى اليمين ،يمكن ك أن ُتغيِّ ر من ه ذا بوض ع محاذاة السالسل النصية ً رم ز خ اص للمح اذاة بع د النقط تين الرأس يتين مباش ً رة .إذ س يؤدي الرم ز > إلى مح اذاة النص إلى ِّ فسيوس ط النص في الحق ل ،والرم ز < س يؤدي إلى محاذات ه إلى اليمين. يس ار الحق ل ،أم ا الرم ز ^ ِّ ونوسط السلسلة النصية: لنجعل محاذاة العدد إلى اليسار ))"print("Sammy has {0:<4} red {1:^16}!".format(5, "balloons الناتج: ! balloons red Sammy has 5 أن مح اذاة الع دد 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 الناتج: !76 percent of a pizza Sammy ate ِّ حد دنا داخل القوسين المعقوصين رقم فهرس القيمة العددية ثم وضعنا النقطتين الرأسيتين ثم اخترن ا حجم الحق ل ثم وض عنا نقط ًة .لنض بط ع دد المن ازل العش رية الظ اهرة ،ثم نخت ار ن وع الحقل عبر رمز التحويل .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 -11 # )print(c + d 169 | ▲ البرمجة بلغة بايثون العمليات الحسابية ً مشابها مع األعداد العشرية: الجمع سيكون e = 5.5 f = 2.5 8.0 # )print(e + f إذا جمعنا عددين عشريين معً ا ،ستعيد بايثون عد ًدا عشريًّ ا. ص ياغة الط رح تش به ص ياغة الجم ع ،م ا ع دا أن ك ستس تبدل بعام ل الط رح ()- عامل الجمع (:)+ g = 75.67 h = 32 # 43.67 )print(g - h ً صحيحا من عدد عش ري .س تعيد ب ايثون ع د ًدا عش ريًّ ا إذا ك ان أح د األع داد هنا ،طرحنا عد ًدا المتضمنة في المعادلة عشريًّ ا. .3العمليات الحسابية األحادية يتكون التعبير الرياضي األحادي ( )unary mathematical expressionمن مك ِّون أو عنص ر واح د فق ط ،ويمكن في ب ايثون اس تخدام العالم تين +و -بمفردهم ا ع بر قرنهم ا بقيم ة إلع ادة القيمة نفسها (عبر العامل ،)+أو تغيير إشارة القيمة (عبر العامل . )- تشير عالمة الجمع -رغم َّ أنها ال ُتستخدم كثيرًا -إلى هوية القيمة ( ،)identity of the value أي تعيد القيمة نفسها .يمكننا استخدام عالمة الجمع مع القيم الموجبة: i = 3.3 3.3 # )print(+i 170 | ▲ البرمجة بلغة بايثون العمليات الحسابية ُ فستعاد القيمة نفسها ،وفي هذه الحالة ستكون عندما نستخدم عالمة الجمع مع قيمة سالبة، ً أيضا: قيمة سالبة j = -19 -19 )print(+j # عالم ة الط رح ،على خالف عالم ة الجم ع ،تغيِّ ر إش ارة القيم ة .ل ذلك ،عن دما نض عها م ع قيم ة موجبةُ ، ستعاد القيمة السالبة منها: i = 3.3 -3.3 # )print(-i بالمقاب ل ،عن دما نس تخدم عام ل الط رح األح ادي ( )minus sign unary operatorم ع قيم ة ُ فستعاد القيمة الموجبة منها: سالبة، j = -19 # 19 )print(-j ُ ستع ِيد العمليتان الحسابيتان األحاديتان +و -إمَّ ا هوية القيمة المعطاة ،أو القيمة المعاكس ة في اإلشارة للقيمة المعطاة على التوالي. .4الضرب والقسمة مث ل الجم ع والط رح ،الض رب والقس مة في ب ايثون مش ابهان لم ا ه و مع روف في الرياض يات. عالمة الضرب في بايثون هي * ،وعالمة القسمة هي ./ فيما يلي مثال على ضرب عددين عشريين في بايثون: k = 100.1 171 | ▲ البرمجة بلغة بايثون العمليات الحسابية l = 10.1 1011.0099999999999 # )print(k * l عن دما ُتج رَ ى عملي ة القس مة في ب ايثون ،3فس يكون الع دد المُ ع اد دائمً ا عش ريًّ ا ،ح تى ل و استخدمت عددين صحيحين: m = 80 n = 5 16.0 # )print(m / n هذا أحد االختالفات الرئيسية بين بايثون 2و بايثون .3اإلجابة في بايثون 3تك ون كس رية، ُ فستعاد القيمة .5.5أمَّ ا في بايثون ،2فحاصل التعبير فعند استخدام /لتقسيم 11على 2مثاًل ، 11/2هو .5 يُ ج ِري العامل /في بايثون 2قسمة عملية القسمة مع تقريب الن اتج إلى أص غر ع دد ص حيح له (ه ذه العملي ة ت دعى القس مة التقريبي ة [ ،)]floor divisionإذ َّ أنه إن ك ان حاص ل القس مة يساوي ،xفسيكون ناتج عملية القس مة في ب ايثون 2أك بر ع دد من األع داد الص حيحة األص غر من أو تس اوي .xإذا َّ نفذت المث ال ) print(80 / 5أعاله في ب ايثون 2ب داًل من ب ايثون ،3فس يكون الناتج هو ،16دون الجزء العشري. في ب ايثون ،3يمكن ك اس تخدام العام ل //إلج راء القس مة التقريبي ة .التعب ير 100 // 40 س يعيد القيم ة .2القس مة التحتي ة مفي دة في ح ال كنت تري د أن يك ون حاص ل القس مة ً صحيحا. عد ًدا 172 | ▲ البرمجة بلغة بايثون العمليات الحسابية .5عامل باقي القسمة ()Modulo العام ل %ه و ب اقي القس مة ( ،)moduloوال ذي يُ رج ع ب اقي عملي ة القس مة .ه ذا مفي د للعث ور على األعداد التي هي مضاعفات لنفس العدد .المثال التالي يوضح كيفية استخدام عامل الباقي: o = 85 p = 15 # 10 )print(o % p ألن عام ل حاص ل قس مة 85على 15ه و ،5والب اقي .10القيم ة 10هي ال تي س ُتعاد هن ا َّ الباقي يعيد باقي عملية القسمة. فسيعاد عدد عشري: إذا استخدمنا عددين عشريين مع عامل الباقي، ُ q = 36.0 r = 6.0 0.0 # )print(o % p باق ،لذلك تعاد القيمة .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 1063173305051.292 )print(s ** t # األس ** سينتج عنه عدد عشري كبير. رفع العدد العشري 52.25إلى القوة 7عبر عامل ّ .7أسبقية العمليات الحسابية قيم أن المع امالت س ُت َّ في بايثون ،كما هو الح ال في الرياض يات ،علين ا أن نض ع في حس اباتنا َّ ً وفقا لنظام األسبقية ،وليس من اليسار إلى اليمين ،أو من اليمين إلى اليسار. إذا نظرنا إلى التعبير التالي: u = 10 + 10 * 5 قد نقرأه من اليس ار إلى اليمين ،ولكن ت َّ أن عملي ة الض رب س ُتجرَ ى أواًل ،ل ذا إن اس تدعينا ذكر َّ ) ،print(uفسنحصل على القيمة التالية: 60 قيم أواًل ،وس ينتج عنه ا الع دد ،50ثم يض اف إليه ا الع دد 10لنحص ل ألن 5 * 10س ُت َّ ه ذا َّ على 60في النهاية. إذا أردنا بداًل من ذلك إضافة القيمة 10إلى ،10ثم ضرب المجموع في ،5فيمكننا استخدام األقواس كما نفعل في الرياضيات تمامً ا: u = (10 + 10) * 5 100 # )print(u 174 | ▲ البرمجة بلغة بايثون العمليات الحسابية إحدى الطرق البسيطة لتذكر األسبقيات هي حفظ البيتين التاليين لتذكر أوائل كلماتهما: ً ً طريقا ضيقا ...قم جد قم أبعد األسبقية العملية الحرف 1 القوس قم 2 األس أبعد 3 الضرب ً ضيقا 4 القسمة قم 5 الجمع جد 6 الطرح ً طريقا .8عامل اإلسناد ()Assignment Operators أكثر عامل اإلسناد استخدامً ا هو إشارة التساوي = .يُ سنِد عامل اإلسناد (أو عامل التعيين) = القيم ة الموج ودة على يمين ه إلى المتغ ير الموض وع على يس اره .على س بيل المث الُ ،تس نِد التعليمة v = 23العدد الصحيح 23للمتغير .v من الشائع استخدام عامالت اإلس ناد المركب ة ال تي تج ري عملي ة رياض ية على قيم ة المتغ ير، ثم ُتسنِد القيمة الجديدة الناتجة إلى ذلك المتغير .تجمع عوامل اإلسناد المركبة بين عامل رياضي والعام ل =؛ ففي ح ال الجم ع ،نس تخدم +م ع = للحص ول على عام ل اإلس ناد الم ركب = .+لنطبِّ ق ذلك في مثال عملي: 175 | ▲ البرمجة بلغة بايثون العمليات الحسابية w = 5 w += 1 6 # )print(w أوالًُ ،نس نِد القيم ة 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 # 0 ))print(abs(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 )(8.0, 63.5 # ))print(divmod(a,b في هذا المثال ،العدد 8.0ه و حاص ل القس مة التحتي ة للع دد 985.5مقس ومً ا على ،115.25 و 63.5هو الباقي. ُّ للتحقق من نتيجة )(:divmod يمكنك استخدام عامل القسمة التحتية //و عامل الباقي % 8.0 # # 63.5 )print(a//b )print(a%b ج .القوة ()Power في بايثون ،يمكنك استخدام عامل القوة ** (أو األس) لرفع عدد إلى ق وة معين ة ،أو يمكن ك استخدام الدالة )( powالمضمَّ نة التي تأخذ عددين وتجري العملية نفسها. ً كيفية عمل الدالة )( ،powلنقل َّ أبحاثا على البكتيريا ،ونريد أن نق َّدر ع دد أننا نجري لتوضيح َّ البكتيريا التي سنحصل عليها في نهاية اليوم إذا بدأنا ببكتيريا واحدة. أن البكتيريا التي نعمل عليها تتضاعف في كل ساعة ،لذلك النتيجة النهائية ستكون لنفترض َّ 2قوة العدد الكلي لعدد الساعات التي مرت ( 24في حالتنا). 181 | ▲ البرمجة بلغة بايثون العمليات الحسابية hours = 24 )total_bacteria = pow(2,hours # 16777216 )print(total_bacteria لق د مرَّ رن ا ع ددين ص حيحين للدال ة )( ،powوالنتيج ة ال تي حص لنا عليه ا ،وال تي ِّ تمثل ع دد البكتيريا بحلول نهاية اليوم ،هي أكثر من 16مليون بكتيريا. أس "3بش كل ع ام على بالش كل 3³وال تي تك افئ ،3 × 3 × 3 في الرياض يات ،نكتب "ّ 3 أي .27ولحس اب 3³في ب ايثون ،نكتب ) ،pow(3,3إذ تقب ل الدال ة )( powاألع داد الص حيحة ِّ وتوفر بدياًل لعامل األس **. واألعداد العشرية، د .تقريب األعداد تقريب األعداد ( )Rounding Numbersضروري عند العمل مع األعداد العشرية التي تحتوي على الكث ير من المن ازل (األج زاء) العش رية .تقب ل الدال ة المض منة )( roundع ددين :أح دها ِّ يمثل ِّ يحدد عدد المنازل العشرية المراد اإلبقاء عليها (أي قيمة التقريب). العدد المراد تقريبه واآلخر سنستخدم هذه الدالة لتقريب عدد عشري له أكثر من 10منازل عشرية والحص ول على ع دد بأربعة منازل عشرية فقط: i = 17.34989436516001 # 17.3499 ))print(round(i,4 في المث ال أعاله ،تم تق ريب الع دد 17.34989436516001إلى َّ 17.3499 ألنن ا ح َّددنا عدد المنازل العشرية التي ينبغي االقتصار عليها بأربعة. 182 | ▲ البرمجة بلغة بايثون العمليات الحسابية ً أن الدال ة )( roundتق ِّرب األع داد إلى األعلى ،ل ذا ب داًل من إع ادة ،17.3498 الح ظ أيض ا َّ ألن ال رقم ال ذي يلي الم نزل العش ري 8ه و ال رقم .9وس يقرَّ ب أي ع دد فق د أع ادت َّ ،17.3499 متبوع بالعدد 5أو أكبر إلى العدد الصحيح التالي. المالية؛ فال يمكنن ا في الحياة اليومي ةُ ،نق ِّرب األع داد ألس باب كث يرة ،وخاص ة في التع امالت َّ تقسيم فلس واحد بالتساوي بين عدة أصدقاء مثال. ِّ نحدد في ه قيم س نكتب في المث ال الت الي برنامج ا بس يطا يمكن ه حس اب البقش يش ،إذ س المتغ يرات ،ولكن يمكن ك إع ادة كتاب ة البرن امج لجع ل المس تخدمين ي دخلون القيم بأنفس هم .في ه ذا المث ال ،ذهب 3أص دقاء إلى مطعم ،وأرادوا تقس يم الف اتورة ،وال تي تبل غ 87.93دوال ًرا بالتساوي ،باإلضافة إلى إكرامية (بقشيش) بنسبة :٪20 إجمالي الفاتورة # bill = 87.93 بقشيش # ٪ 20 tip = 0.2 عدد الناس الذين سيتشاركون الفاتورة # 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 49.5 # ))print(sum(some_floats 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 # 50.0 # 0 ))print(sum(some_floats, 0.5 ))print(sum({-10: 'x', -20: 'y', -30: 'z'},60 القيمة االفتراضية للوسيط الثاني هي .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 # Sammy == sammy: )print("Sammy == sammy: ", Sammy == sammy False السلس لة " "Sammyأعاله ال تس اوي السلس لة النص ية "َّ ،"sammy ألنهم ا ليس تا متم اثلتين تمامً ا؛ فإح داهما تب دأ بح رف كب ير ،Sواألخ رى بح رف ص غير .sولكن ل و أض فنا متغ يرًا آخ ر قيمته " ،"Sammyفستكونان متساويتين: "Sammy = "Sammy "sammy = "sammy "also_Sammy = "Sammy 189 | ▲ البرمجة بلغة بايثون العمليات المنطقية (البوليانية) )print("Sammy == sammy: ", Sammy == sammy False # Sammy == sammy: )print("Sammy == also_Sammy", Sammy == also_Sammy True # Sammy == also_Sammy: ً أيض ا اس تخدام ع امالت الموازن ة األخ رى ،بم ا في ذل ك > و < لموازن ة سلس لتين يمكن ك نص يتين .س توازن ب ايثون ه ذه السالس ل النص ية بحس ب ال ترتيب المعجمي في نظ ام ً أيضا تقييم القيم المنطقية باستخدام عامالت الموازنة: محارف .ASCIIويمكنك t = True f = False True t != f: # )print("t != f: ", t != f أن Trueال تساوي .False تبيِّ ن الشيفرة البرمجية أعاله َّ الحظ الفرق بين العاملين = و ==. إسناد قيمة yإلى # x x = y و xمتساويين # x == y تتحقق مما إذا كان y ِّ يحدد قيم ة أح د المتغ يرين، األول = ،هو عام ل اإلس ناد ( ،)assignment operatorوال ذي س ِّ يحدد م ا إذا ك انت ويجعله ا مس اوية لقيم ة اآلخ ر .الث اني == ،وه و عام ل الموازن ة ال ذي س القيمتان متساويتين. .2العامالت المنطقية هن اك ثالث ة ع امالت منطقي ة (ُ )Boolean operatorsتس تخدم لموازن ة القيم .وتعي د إمَّ ا Trueأو .Falseه ذه الع امالت هي( and ،و) ،و ( orأو) ،و ( notالنفي) ،وق د عرَّ فناه ا في الجدول أدناه. 190 | ▲ البرمجة بلغة بايثون العمليات المنطقية (البوليانية) العامل الشرح الصياغة and إن كان كال التعبيرين صحيحين x and y True إن كان أحد التعبيرين على األقل or x or y ً صحيحا True إن كان التعبير خطأ True not not x ع ً ادة م ا ُتس تخ َدم الع امالت المنطقي ة لتق ييم م ا إذا ك ان تعب يران منطقي ان ص حيحين أم ال. على سبيل المثال ،يمكن استخدامها لتحديد ما إذا كان الط الب ق د نجحَّ ، وأنه مُ س جل في الفص ل، فسي َ ضاف الطالب إلى سجل النظام .مثال آخ ر ه و تحدي د م ا وإذا كانت كلتا الحالتان صحيحتين، ُ إذا كان المستخدم عمياًل ً نشطا لمتجر إلكتروني استنا ًدا إلى ما إذا ك ان لدي ه رص يد في المتج ر ،أو َّ أنه اشترى خالل األشهر الستة الماضية. كيفية عمل العامالت المنطقية ،دعنا نقيِّ م التعابير الثالث التالية: لفهم َّ كال التعبيرين صحيحان # ))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 ألن التعب ير 1.4 ه ذا المث ال يعي د َّ ،False > يقيم إلى القيم ة ،False َّ -0.2 و ) (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 x not القيمة المُ عادة True not False False not True ُتس تخ َدم ج داول الحقيق ة في المنط ق الرياض ياتي كث يرًا ،وهي مفي دة ،ويجب حفظه ا ووضعها في الحسبان عند إنشاء الخوارزميات البرمجية. .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 anemone shrimp squid shark shark 4 3 2 1 0 يب دأ العنص ر األول ،أي السلس لة النص ية ،sharkعن د الفه رس ،0وتنتهي القائم ة عن د الفهرس 4الذي يقابل العنصر .anemone ألن كل عنصر في قوائم بايثون يقابل ه رقم فه رس ،يمكنن ا الوص ول إلى عناص ر الق وائم نظرًا َّ ومعالجتها كما نفعل مع أنواع البيانات المتسلسلة األخرى. يمكننا اآلن استدعاء عنصر من القائمة من خالل رقم فهرسه: cuttlefish # )]print(sea_creatures[1 َّ موضح في الجدول أعاله .المث ال تتراوح أرقام الفهارس في هذه القائمة بين 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تبدو الفهارس السالبة كما يلي: shark cuttlefish squid shrimp anemone -5 -4 -3 -2 -1 في المثال التالي ،سنطبع العنصر squidباستخدام فهرس سالب: squid # )]print(sea_creatures[-3 يمكننا ضم ( )concatenateسلسلة نصية مع سلسلة نصية أخرى باستخدام العامل :+ # Sammy is a shark )]print('Sammy is a ' + sea_creatures[0 ً أيض ا اس تخدام لقد ضممنا السلسلة النصية Sammy is aمع العنص ر ذي الفه رس .0يمكنن ا ِّ لضم قائمتين أو أكثر معً ا (انظر الفقرة أدناه). المعامل + أي عنصر من عناصر القائمة والعمل عليه. تساعدنا الفهارس على الوصول إلى ِّ 200 | ▲ البرمجة بلغة بايثون النوع :Listمدخل إلى القوائم .2تعديل عناصر القائمة يمكنن ا اس تخدام الفهرس ة لتغي ير عناص ر القائم ة ،عن طري ق إس ناد قيم ة إلى عُ نص ر مُ فه رس ّ ويسهل تعديل وتحديث عناصرها. من القائمة .هذا يجعل القوائم أكثر مرونة، إذا أردن ا تغي ير قيم ة السلس لة النص ية للعنص ر الموج ود عن د الفه رس ،1من القيم ة cuttlefishإلى ،octopusفيمكننا القيام بذلك على النحو التالي: 'sea_creatures[1] = 'octopus اآلن ،عندما نطبع ،sea_creaturesستكون النتيجة: # ['shark', 'octopus', 'squid', 'mantis )print(sea_creatures ]'shrimp', 'anemone ً أيضا تغيير قيمة عنصر باستخدام فهرس سالب: يمكننا 'sea_creatures[-3] = 'blobfish ['shark', 'octopus', 'blobfish', # )print(sea_creatures ]''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يمكنن ا فع ل ذلك عن طريق كتابة: ['shark', 'octopus', # )]print(sea_creatures[:3 ]''blobfish لق د ُطبعَ ت العناص ر من بداي ة القائم ة ّ حتى العنص ر ذي الفه رس .3لتض مين جمي ع العناص ر الموجودة في نهاية القائمة ،سنعكس الصياغة: ['blobfish', 'mantis shrimp', # )]print(sea_creatures[2: ]''anemone ً أيض ا اس تخدام الفه ارس الس البة عن د اقتط اع الق وائم ،تمامً ا كم ا ه و الح ال م ع يمكنن ا الفهارس الموجبة: ]'['octopus', 'blobfish ['blobfish', 'mantis # # )]print(sea_creatures[-4:-2 )]print(sea_creatures[-3: ]'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 ][1, 3, 5, 7, 9 )]print(numbers[1:11:2 # س يطبع التعب ير ] numbers[1: 11: 2القيم ذات الفه ارس المحص ورة بين ( 1مش مولة) و ( 11غير مشمولة) ،وسيقفز البرنامج بخطوتين كل مرة ،ويطبع العناصر المقابلة. يمكنن ا ح ذف المُ ع املين األوَّ ل يين ،واس تخدام الخط وة وح دها بع ِّدها مع اماًل وف ق الص ياغة التالية:]::z[ : ][0, 3, 6, 9, 12 # )]print(numbers[::3 طب ع إال العناص ر ال تي عن د طباع ة القائم ة 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 ['shark', 'octopus', 'blobfish', # )print (sea_creatures ]''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 ['shark', 'blobfish', 'mantis # )print(sea_creatures ]'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 ]'['shark', 'anemone', 'yeti crab # )print(sea_creatures َّ الفهرس ين ( 1مش مول) و 4 تمكنا من إزالة العناص ر الموج ودة بين باستخدام مجال مع ،del َ (غير مشمول) ،والقائمة أضحت مكوَّ نة من 3عناصر فقط بعد إزالة 3عناصر منها. .6بناء قوائم من قوائم أخرى موجودة يمكن أن تتض مَّ ن عناص ر الق وائم ق وائم أخ رى ،م ع إدراج ك ل قائم ة بين قوس ين معق وفين داخل األقواس المعقوفة الخارجية التابعة لقائمة األصلية: sea_names = [['shark', 'octopus', 'squid', 'mantis shrimp'], ]]'['Sammy', 'Jesse', 'Drew', 'Jamie تسمى القوائم المُ تضمّ نة داخل قوائم أخرى بالقوائم المتشعبة (.)nested lists يتعين علين ا اس تخدام فه ارس متع ددة تقاب ل للوص ول إلى عنص ر ض من ه ذه القائم ة ،س َّ 207 | ▲ البرمجة بلغة بايثون النوع :Listمدخل إلى القوائم مستوى التشعُّ ب: Sammy # )]print(sea_names[1][0 shark # )]print(sea_names[0][0 فهرسها .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فس ُيعَ اد فه رس العنصر األول. # ['anchovy', 'barracuda', 'cod', 'eel', )print(fish ]''flounder', 'goby', 'herring', 'ide # 6 ))'print(fish.index('herring سوف يُ َ طل ق خطأ في حال مرَّ رنا قيمة غير موجودة في القائمة إلى التابع )(..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 ['ide', 'herring', 'goby', 'flounder', 'eel', # )print(fish ]''cod', 'barracuda', 'anchovy بع د اس تخدام الت ابع )( ،.reverseص ارت القائم ة تب دأ بالعنص ر ،ideوال ذي ك ان في نهاي ة القائمة من قبل ،كما ستنتهي القائمة بالعنصر ،anchovyوالذي كان في بداية القائمة من قبل. ط .التابع )(list.count يعي د الت ابع ) list.count(xع دد م رات ظه ور القيم ة xفي القائم ة .ه ذا الت ابع مفي د في حال كنا نعمل على قائمة طويلة بها الكثير من القيم المتطابقة. إذا ك ان ح وض الس مك كب يرًا ،على س بيل المث ال ،وك انت عن دنا ع دة أس ماك من الن وع ،neon tetraفيمكننا استخدام التابع )( .countلتحديد العدد اإلجمالي ألسماك هذا النوع. في المثال التالي ،سنحسب عدد مرات ظهور العنصر :goby 1 # ))'print(fish.count('goby رة واح ً تظه ر السلس لة النص ية gobyم ً دة فق ط في القائم ة ،ل ذا س ُيعيد الت ابع )(.count ً أيض ا م ع قائم ة مكوَّ ن ة من أع داد ص حيحة ،ويوض ح المث ال الع دد .1يمكنن ا اس تخدام ه ذا الت ابع التالي ذلك. أن وجباته ا الغذائي ة يتتبع المشرفون على الح وض أعم ار األس ماك الموج ودة في ه للتأك د من َّ مناس بة ألعماره ا .ه ذه القائم ة الثاني ة المُ س ماة fish_agesتتواف ق م ع أن واع الس مك في 214 | ▲ البرمجة بلغة بايثون النوع :Listمدخل إلى القوائم ألن األسماك ال تي ال يتج اوز عمره ا عامً ا واح ًدا له ا احتياج ات غذائي ة خاص ة، القائمة .fishنظ ًرا ّ فسنحسب عدد األسماك التي عمرها عامً ا واح ًدا: ]fish_ages = [1,2,4,3,2,1,1,2 3 # ))print(fish_ages.count(1 يظه ر الع دد الص حيح 1في القائم ة fish_agesثالث م رات ،ل ذلك يعي د الت ابع )(.count العدد .3 ي .التابع )(list.sort ُ استدعِ ي معها .سنستخدم قائم ة يُ ستخدم التابع )( list.sortلترتيب عناصر القائمة التي األعداد الصحيحة fish_agesلتجريب التابع )(:.sort )(fish_ages.sort ][1, 1, 1, 2, 2, 2, 3, 4 # )print(fish_ages مرت ً َّ ُ بة. فستعاد تلك القائمة باستدعاء التابع )( .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أو ifإض افية ،ل ذا وع بحلق ة .forويمكن أن يُ َ علي ه ض من تعب ٍ ير متب ٍ سيساعدك الفهم العميق لحلقات 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لنع د كتاب ة المث ال الس ابق ال ذي أنش أنا في ه القائم ة shark_lettersباس تخدام حلق ة ،forوه ذا سيس ف اعدنا في فهم كي تعمل list comprehensionsعملها: ][ = shark_letters for letter in 'shark': )shark_letters.append(letter )print(shark_letters عن د إنش ائنا للقائم ة ع بر اس تخدام الحلق ة ،forفيجب تهيئ ة المتغ ير ال ذي س ُنس نِد العناص ر 217 | ▲ البرمجة بلغة بايثون النوع :Listمدخل إلى القوائم إلي ه كقائم ة فارغ ة ،وه ذا م ا فعلن اه في أوّ ل س طر من الش يفرة الس ابقة .ثم ب دأت حلق ة for ً تعملة المتغ ير letterلإلش ارة إلى قيم ة بال دوران على عناص ر السلس لة النص ية ' 'sharkمس العنصر الح الي ،ومن ثم أض فنا ك ل عنص ر في السلس لة النص ية إلى القائم ة ض من حلق ة forوذل ك باس تخدام الدال ة ) .list.append(xالن اتج من حلق ة forالس ل ابقة يماث ناتج 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لكن إذا قوسين ( ) ويُ َ احت وى الص ف على قيم –ح تى ل و ك انت قيم ًة واح ً دة فق ط– فيجب وض ع فاص لة في ه مث ل )= ('blue coral', .coralإذا اس تخدمنا الدال ة )( printعلى الن وع ،tuple أن القيمة الناتجة ستوضع بين قوسين: بين َّ فسنحصل على الناتج اآلتي الذي يُ ّ )print(coral ('blue coral', 'staghorn coral', 'pillar coral', 'elkhorn )'coral عن د التفك ير ب النوع tupleوغ يره من ب نى البيان ات ال تي ُتع ُّد من أن واع «التجميع ات» ( ،)collectionsفمن المفي د أن تض ع ببال ك مختل ف التجميع ات الموج ودة في حاس وبك :تش كيلة الملف ات الموج ودة عن دك ،وق وائم التش غيل للموس يقى ،والمفض لة الموج ودة في متص فحك، ورس ائل بري دك اإللك تروني ،ومجموع ة مق اطع الفي ديو ال تي تس تطيع الوص ول إليه ا من التلف از، والكثير .نوع ( tupleصف) شبيه بالنوع ( listقائمة) ،لكن القيم الموجودة فيه ال يمكن تعديلها، وبس بب ذل ك ،ف أنت تخ بر اآلخ رين َّ أنك ال تري د إج راء أيَّ ة تع ديالت على ه ذه السلس لة من القيم عن دما تس تعمل الن وع tupleفي ش يفرتك .إض ً افة إلى م ا س بق ،ولع دم الق درة على تع ديل القيم، 225 | ▲ البرمجة بلغة بايثون النوع :Tupleفهم الصفوف ست َّ فسيكون أداء برنامجك أفضل ،حيث ُ َ تعملت الص فوف ب داًل من نفذ الشيفرة بشكل أسرع إذا اس القوائم (.)lists .1فهرسة الصفوف يمكن الوصول إلى كل عنصر من عناصر الصف بمفرده َّ ألنه سلسلة مرتب ة من العناص ر ،وذل ك عبر الفهرسة .وكل عنص ر يرتب ط ب رقم فه رس ،ال ذي ه و ع دد ص حيح يب دأ من الفه رس .0س تبدو الفهارس من مثال coralالسابق والقيم المرتبطة بها كاآلتي: blue coral staghorn coral pillar coral elkhorn coral 0 1 2 3 العنص ر األول ال ذي يُ ِّ مثل السلس لة النص ية ' '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إذا أردن ا اس تخدام الفه ارس أح د عناص ره السالبة فالناتج كاآلتي: blue coral staghorn coral pillar coral elkhorn coral -4 -3 -2 -1 إذا أردن ا طباع ة العنص ر ' '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هذا مثال على ذلك: sammy-shark # )]'print(sammy['username 238 | ▲ البرمجة بلغة بايثون النوع :Dictionaryفهم القواميس تتصرف القواميس مثل قواعد البيان ات ،فهي ب داًل من فهرس ة العناص ر بأع داد ص حيحة ،كما ه و الح ال في الق وائمِّ ، فإنه ا ُتفه رس العناص ر (أو قيم الق اموس) بمف اتيح ،ويمكن ك ع بر تل ك المفاتيح الحصول على القيم المقابلة لها. باس تدعاء المفت اح ،usernameسنحص ل على القيم ة المرتبط ة ب ه ،وهي .sammy-shark وبالمِ ثل ،يمكن استدعاء القيم األخرى في القاموس sammyباستخدام نفس الصياغة: # 987 # True ]'sammy['followers ]'sammy['online ب .استخدام التوابع للوصول إلى العناصر ً أيض ا اس تخدام بعض التواب ع باإلض افة إلى اس تخدام المف اتيح للوص ول إلى القيم ،يمكنن ا المُ ضمّ نة ،مثل: • )( :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 dict_values([True, 'sammy-shark', # ))(print(sammy.values )]987 يُ عي د كال الت ابعين )( valuesو )( keysق وائم غ ير مرتب ة تض م مف اتيح وقيم الق اموس عرض من الصنف dict_valuesو dict_keysعلى التوالي. ٍ sammyعلى هيئة كاِئني إن أردت الحصول على األزواج الموجودة في القاموس ،فاستخدم التابع )(:items ))(print(sammy.items المخرجات ستكون: dict_items([('online', True), ('username', 'sammy-shark'), )])('followers', 987 س تكون النتيج ة المع ادة على هيئ ة قائم ة مكون ة من أزواج (value )key,من الصنف .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 {'Drew': 'squidly', 'Sammy': 'sammy- # )print(usernames }'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 {'followers': 481, 'username': 'JOctopus', # )print(jesse 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 {'username': 'sammy-shark', 'followers': 987, # )print(sammy }'online': False يغي ر الس طر )}False ّ sammy.update({'online':القيم ة المرتبط ة بالمفت اح ' '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ثم ِّ نفذه في بيئ ة البرمج ة المحلي ة من ناف ذة الطرفي ة باستخدام األمر .python grade.pyفي هذه الحالة ،الدرجة 70تل بي الش رطّ ، ألنه ا أك بر من ،65 لذلك ستحصل على المخرجات التالية عند تنفيذ البرنامج: درجة النجاح لنغير اآلن نتيجة هذا البرنامج عبر تغيير قيمة المتغير 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: )".الرصيد يساوي ،0أضف مبلً ًا"(print غا قريب else: )".رصيدك أكبر من print("0 اآلن ،هناك ثالثة مخرجات محتملة يمكن أن ُتطبع عند تنفيذ البرنامج: • إن ك ان المتغ ير balanceيس اوي ،0فسنحص ل على المخرج ات من التعليم ة ( elifأي • إذا ُ ض ِبط المتغ ير balanceعن د ع دد م وجب ،فس وف نحص ل على المخرج ات من • إذا ُ ض ِبط المتغير balanceعن د ع دد س الب ،فسنحص ل على المخرج ات من التعليم ة if ً قريبا.)". مبلغا السلسلة "الرصيد يساوي ،0أضف ً التعليمة ( elseأي طباعة السلسلة "رصيدك أكبر من .)".0 (أي السلسلة "الحساب فارغ ،أضف مبلغا اآلن ،أو ستحصل على غرامة"). 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فسيطبع البرنامج إلى التعليمة التالية ... • امج ،B+إذا ك انت الدرج ة تس اوي إذا كانت الدرج ة أك بر من أو تس اوي ،80فس يطبع البرن ُ • إذا كانت الدرجة أكبر من أو تساوي ،70فسيطبعُ البرنامج ،Bإذا كانت الدرجة تس اوي 69 ُ 79أو أقل ،فسيمرّ البرنامج إلى التعليمة التالية ... أو أقل ،فسيمرّ البرنامج إلى التعليمة التالية ... • البرنامج ،B-وإذا ك انت الدرج ة تس اوي ُ إذا كانت الدرجة أكبر من أو تساوي ،65فسيطبع • أي من الشروط المذكورة أعاله. سيطبع البرنامج ،Fألنه لم يتم استيفاء ِّ 64أو أقل ،فسيمرّ البرنامج إلى التعليمة التالية ... .4تعليمات ifالمتشعبة بع د أن تتع ود على التعليم ات ifو elifو ،elseيمكن ك االنتق ال إلى التعليم ات الش رطية المتشعبة (.)nested conditional statements ِّ المتشعبة في الحاالت التي نري د فيه ا التحق ق من ش رط ث انوي يمكننا استخدام تعليمات if ُّ التأكد من تحقق الشرط الرئيسي .لهذا ،يمكننا حشر تعليمة if-elseداخل تعليم ة if-else بعد لنلق نظرة على صياغة ifالمتشعبة: أخرى. ِ 256 | ▲ البرمجة بلغة بايثون التعليمات الشرطية if statement1: تعليمة ifالخارجية # )"print("true تعليمة ifالمتشعبة # if nested_statement: )"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الخارجية # if statement1: )"print("hello world ifالمتشعبة األولى # if nested_statement1: )"print("yes elifالمتشعبة األولى # elif nested_statement2: )"print("maybe elseالمتشعبة األولى # else: )"print("no elifالخارجية # elif statement2: )"print("hello galaxy ifالمتشعبة الثانية # if nested_statement3: )"print("yes elifالمتشعبة الثانية # elif nested_statement4: )"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لطلب إدخ ال رقم من المس تخدم ،ثم س نأخذ مدخالت المستخدم عبر الدالة )(ُ input ِّ سنحول المتغير guess ونس ِن َدها إلى المتغير ،guessثم من سلس لة نص ية إلى ع دد ص حيح .وقب ل انته اء حلق ة التك رار ،فعلين ا زي ادة قيم ة المتغ ير number_of_guessesبمقدار ،1لكيال ُت َّ نفذ حلقة التكرار أكثر من 5مرات. وفي النهاية ،كتبنا التعليم ة 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 يب دأ البرن امج بتنفي ذ حلق ة التك رار الخارجي ة ،ويُ َّ نفذ أوّ ل دوران فيه ا ،وأوَّ ل دوران س يؤدي إلى ال دخول إلى حلق ة التك رار الداخلي ة ،مم ا ي ؤدي إلى تنفي ذها إلى أن تنتهي تمامً ا .ثم س يعود تنفيذ البرنامج إلى بداية حلقة التكرار الخارجية ،ويبدأ بتنفيذ ال دوران الث اني ،ثم سيص ل التنفي ذ إلى حلقة التكرار الداخلي ة ،وس ُت َّ نفذ حلق ة التك رار الداخلي ة بالكام ل ،ثم س يعود التنفي ذ إلى بداي ة حلق ة التك رار الخارجي ة ،وهلم ج رًا إلى أن ينتهي تنفي ذ حلق ة التك رار الخارجي ة أو إيق اف حلق ة التك رار ع بر اس تخدام التعليم ة breakأو غيره ا .ل ُن ِ نش ئ مث ااًل يس تعمل حلق ة forمتش عبة لكي نفهم كي ف تعم ل بدق ة ،إذ س تمر حلق ة التك رار الخارجي ة في المث ال اآلتي على قائم ة من األرق ام اس مها ،num_listأم ا حلق ة التك رار الداخلي ة فس تمر على قائم ة من السالس ل النص ية اسمها :alpha_list ]num_list = [1, 2, 3 ]'alpha_list = ['a', 'b', 'c for number in num_list: )print(number for letter in alpha_list: )print(letter سيظهر الناتج اآلتي عند تشغيل البرنامج: 1 a b c 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 here continue ))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؛ ه ذه التعليم ة اختياري ة، يمكن أن تنتج الدالة قيمة، ُ نهي الدال ة مباش ً رة عمله ا وتوق ف تنفي ذهاُ ، وتم رَّ ر قيم ة التعب ير ال ذي وفي ح ال اس تخدامها ،فس ُت ِ ُ يعقبه ا إلى المُ س تدعي ( .)callerإذا لم يلي التعليم ة returnأي ش يء ،فس ُتعيد الدالة َ القيمة .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 وسنحصل على المخرجات التالية: .هذه هي الدالة الرئيسية !مرحبا بالعالم لمَّ ا اس تدعينا الدال ة )( helloداخ ل )( ،mainثم َّ نفذنا الدال ة )( 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 | ▲ البرمجة بلغة بايثون الدوال :تعريفها واستعمالها عن دما ِّ ننفذ البرن امج باس تخدام األم ر some_args.py ،pythonسنحص ل على المخرجات التالية: 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 ِّ ثبت ة عن دك ،مث ل ،matplotlibوهي لننفذ اآلن التعليم ة importم ع وح دة ق د ال تك ون مُ َّ مكتبة للرسم ثنائي األبعاد: 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عناص ر .داخ ل الحلق ة ،س يطبع البرن امج ع د ًدا ص ً إلى ( 25مش مول) .يُ م رّّ ر الع ددان الص حيحان 1و 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نموذج ع ام ُتنس ج على منوال ه كائن ات يُ ِ فيع ِّرف الص نف نش ئها الم برمجُ . • الك ائن ( :)objectنس ٌ خة (ُ )instanceتش تق من ص نف ،فه و تجس يد عملي للص نف داخ ل ً مجموعة من الخاصيات التي تميز أي كائن يُ ستنسخ ( )instantiatedمنه. َ البرنامج. ُتستخ َدم األصناف إلنشاء أنماط ،ثم ُتستعمل تلك األنماط إلنشاء الكائنات. ابع ستتعلم في هذا الفصل َّ كيفية إنشاء األصناف والكائنات ،وتهيئ ة الخاص يات باس تخدام ت ٍ بان ( ،)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. ألنهم ا معرفت ان داخ ل الص نف Shark؛ أي َّ ُتس مَّ ى مث ل ه ذه ال دوال «ت ابع» (َّ )method أنهم ا دالتان تابعتان للصنف .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تسمى والمتغ يرات من األص ناف األساس ية (classes ،baseتس ً أيض مى ا األص ناف اآلباء [.)]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وال ذي سيس تخدم جمي ع تواب ع الص نف Fishوإن لم ِّ نعرفه ا في الص نف الف رعي .Troutيكفي أن نم ِّرر القيم ة " "Terryإلى المتغ ير ً سلفا. ،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 أن الك ائن َّ ُتظه ر المخرج ات ابع ▲ افة إلى الت | 351 إض،Fish نف ين بالص الخاصswim() __ وinit__() ابعين الت البرمجة بلغة بايثون مفهوم الوراثة في البرمجة )( 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 الخاص ين بالص نف األساس ي ،Fishوورث في نفس ال وقت الت ابع )( swimالخ اص بالصنف األساسي. .5الدالة )( superوفائدتها في الوراثة ُأ يمكنك باستخدام الدالة )( superالوصول إلى التوابع الموروثة التي عي َدت كتابتها .عن دما نستخدم الدالة )(َّ ،super فإننا نستدعي التابع الخاص بالص نف األساس ي الس تخدامه في الص نف 354 | ▲ البرمجة بلغة بايثون مفهوم الوراثة في البرمجة الفرعي .على سبيل المثال ،قد نرغب في إعادة تعريف جانب من التابع األساسي وإض افة وظ ائف معينة إليه ،ثم بعد ذلك نستدعي التابع األساسي إلنهاء بقية العمل. في برن امج خ اص بتق ييم الطالب مثاًل ،ق د ن رغب في تعري ف ص نف ف رعي Weighted_gradeي رث الص نف األساس ي ،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 استخدام )(____init الخاص بالصنف األساسي عبر )(# super )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 ]-> num_list = [500, 600, 700 1 ]'alpha_list = ['x', 'y', 'z 2 3 4 def nested_loop(): for number in num_list: 5 6 )print(number 7 for letter in alpha_list: 8 )print(letter 9 10 if __name__ == '__main__': 11 )(Pdb يُ شار إلى السطر الحالي بالمحرفين > -اللذين يشيران في حالتنا إلى أول سطر من البرنامج. ولمَّ ا ك ان برنامجن ا قص ي ًرا ،فسنحص ل على كام ل البرن امج عن د اس تخدام األم ر .listفحين ً محيط ا بالس طر الح الي ،لكن اس تخدام األم ر listدون أيَّ ة وس ائط ،فس يعرض أح د عش ر س ط ًرا يمكننا تحديد ما هي األسطر التي نريد عرضها كما يلي: 371 | ▲ تنقيح الشيفرات :استخدام ِّ منقح بايثون البرمجة بلغة بايثون (Pdb) list 3, 7 3 4 def nested_loop(): for number in num_list: )print(number 5 6 7 )(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 Where Disp Enb Num Type at /Users/sammy/looping.py:7 keep yes 1 breakpoint 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 keep no at /Users/sammy/looping.py:7 breakpoint 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 -> def print_sammy(): 1 ][ = sammy_list 2 "sammy = "sammy 3 for letter in sammy: 4 )sammy_list.append(letter 5 )print(sammy_list 6 7 if __name__ == "__main__": 8 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المفي دة م ع اختص اراتها لتبقيه ا في ذهن ك أثن اء تعامل ك م ع منقح بايثون: األمر الوظيفة االختصار طباعة قائمة الوسائط للدالة args a break b continue cأو cont إكمال تنفيذ البرنامج. help h توفير قائمة األوامر ،أو توفير jump j list l الحالية. إنشاء نقطة توقف أثناء تنفيذ البرنامج (يتطلب وسيط) مساعدة ألمر معين. ضبط ما هو السطر القادم الذي يجب تنفيذه. طباعة الشيفرة المصدرية المحيطة بالسطر الحالي. 383 | ▲ تنقيح الشيفرات :استخدام ِّ منقح بايثون األمر البرمجة بلغة بايثون الوظيفة االختصار إكمال التنفيذ حتى السطر التالي next n step s pp pp طباعة قيمة التعبير. quitأو exit q الخروج من البرنامج. return r إكمال التنفيذ حتى تعيد الدالة في الدالة ،أو الخروج منها. تنفيذ السطر الحالي ،والتوقف في أول فرصة ممكنة. ً قيمة ما. يمكنك قراءة المزيد عن األوامر السابقة والتعامل مع المنقح عبر توثيق بايثون الرسمي. .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لرؤية كيف تعم ل الش يفرة ،لكن يمكنن ا اس تخدام الوح دة ٌ loggingلفع ل ذل كب داًل منه ا .ل نزل الدال ة printالموج ودة في الش يفرة، ونضع 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لتخ زين مخرج ات الس جل .وبع د تش غيل الس كربت باس تخدام األم ر نشأ ٌ python pizza.pyفمن المفترض أن يُ َ ملف جدي ٌد في المجلد الخ اص بن ا باس م .test.log لنفتح الملف 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 | ▲ تنقيح الشيفرات :استخدام ِّ منقح بايثون البرمجة بلغة بايثون ظه ر الج دول اآلتي مختل ف مس تويات التس جيل م ع القيم العددي ة المرتبط ة به ا ،وم ا هي يُ ِ الدالة التي يمكن استعمالها الستدعاء المستوى ،وألي مستوى من الرسائل تستخدم: المستوى القيمة العددية الغرض الدالة CRITICAL 50 )(logging.critical ERROR 40 )(logging.error عرض خطأ جاد. WARNING 30 )(logging.warning اإلشارة أن شيًئ ا غير متوقع قد INFO 20 )(logging.info DEBUG 10 )(logging.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 البرمجة بلغة بايثون ب .قسمة األعداد الصحيحة أي ع ددٍ تكتب ه دون فواص ل عش رية س ُيعامَ ل على َّ أنه من الن وع ،integer في ب ايثون ُّ ،2 كالية عن دما تح اول قس مة األع داد الص حيحة على بعض ها ،فتتوق ع في بعض األحي ان ت أتي اإلش َّ ً أيض ا باألع داد ذات الفاص لة [ )]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 # 2.5 print a 407 | ▲ إصدارات بايثون :بايثون 3مقابل بايثون 2 البرمجة بلغة بايثون َ أردت تق ريب ن اتج القس مة فاس تخدم يمكن ك اس تخدام 5.0 / 2.0إلع ادة ،2.5لكن إن المعامل //الموجود في بايثون ،3كاآلتي: a = 5 // 2 print a 2 هذا التعديل في بايثون 3جعل من قسمة األعداد الصحيحة أمرًا سهاًل ،لكن ه ذه الم يزة غ ير متوافقة مع بايثون .2.7 ج .دعم محارف يونيكود ٌ سلسلة من المحارف)، عندما تتعامل لغات البرمجة مع السالسل النصية ( ،stringsوالتي هي فهي تفعل ذلك بطرائق مختلفة لكي تتمكن الحواسيب من تحويل األعداد إلى أحرف ورموز. تس تعمل ب ايثون 2مح ارف ASCIIافتراض ًيا ،ل ذا عن دما تكتب "!Sammy "Hello, فس تتعامل ب ايثون 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مستقبل بايثون ،وهو إصدار اللغة قي د التط وير ً عام ،2008ليعالج العديد من عيوب التصميم الداخلية ويُ ِّ أن اعتماد بايثون 3ك ان بطيًئا بيد َّ عدلهاْ . بسبب عدم توافقه مع بايثون .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 # 1 exec code # 2 exec code in globals # 3 )exec code in (globals, locals بايثون # 3 • # 1 )exec(code # 2 )exec(code, globals # 3 )exec(code, globals, locals /و ُ ://تج ِري ب ايثون 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 # 1 raise Exception, args # 2 raise Exception, args, traceback # 3 "raise "Error بايثون # 3 raise Exception # 1 )raise Exception(args • # 2 )raise Exception(args).with_traceback(traceback # 3 )"raise Exception("Error تغير في :exceptفي بايثون ،2كان من الصعب إدراج االس تثناءات المُ تع ِّددة لكن ذل ك َّ ً صراحة مع exceptفي بايثون :3 أن ُ asتستخ َدم بايثون .3الحظ َّ بايثون # 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 # 1 )"%d %s" % (i, s # 2 )"%d/%d=%f" % (355, 113, 355/113 بايثون # 3 # 1 )"{} {}".format(i, s # 2 )"{:d}/{:d}={:f}".format(355, 113, 355/113 ت ذكر كيفي ة اس تخدام تنس يقات السالس ل النص ية من فص ل كيفي ة اس تخدام آلي ة تنس يق السالسل النصية في بايثون .3 • :classليست هناك حاجة لتمرير objectفي بايثون .3 415 | ▲ إصدارات بايثون :بايثون 3مقابل بايثون 2 البرمجة بلغة بايثون بايثون # 2 class MyClass(object): pass بايثون # 3 class MyClass: pass ضبط األصناف العليا ( )metaclassesبالكلمة مفتاحية .metaclass في بايثون ُ ،3ت َ بايثون # 2 class MyClass: __metaclass__ = MyMeta class MyClass(MyBase): __metaclass__ = MyMeta بايثون # 3 class MyClass(metaclass=type): pass class MyClass(MyBase, metaclass=MyMeta): pass .8تحديث الشيفرة توافقيته ا م ع تلقائيا إلى ب ايثون 3م ع الحف اظ على رئيسيتان لتَحديث الشيفرة َّ هناك أ َداتان ّ ً آليتا عمل ه اتين األداتين ،إذ تح اول futureنق ل بايثون 2وهما future :و .modernizeتختلف َ أن modernizeتس عى إلى إنش اء ش يفرات أفض ل ممارس ات ب ايثون 3إلى ب ايثون ،2في حين َّ َّ التوافقية .يمكن أن تس اعدك موحدة لب ايثون تتواف ق م ع 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فستتمكن من العمل على المشاريع الموجودة صحيح َّ ً المحورية ،لكن ليس من الصعب االنتقال من بايثون 3إلى ب ايثون ،2وس تجد ع ً أن ب ايثون 2.7 ادة َّ خصوص ا في ب دايات تعلم ك للغ ة .من المهم أن تبقي ببال ك ً قادرة على تشغيل ش يفرات ب ايثون ،3 أن ترك يز المط ورين والمجتم ع أص بح منص ًّبا نح و ب ايثون ،3وستص بح ه ذه اللغ ة رائ ً دة في َّ وأن دعم ب ايثون 2.7س يقل م ع م رور ال زمن المس تقبل وس تلبي االحتياج ات البرمجي ة المطلوب ة، َّ إلى أن يزول في ( 2020قد زال لحظة ترجمة الكتاب ومراجعته). 418 | ▲