المحتوى عن 'تنقيح'.



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

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

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

نوع المُحتوى


التصنيفات

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

التصنيفات

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

التصنيفات

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

التصنيفات

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

التصنيفات

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

التصنيفات

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

التصنيفات

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

التصنيفات

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

أسئلة وأجوبة

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

التصنيفات

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

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

  1. إن كنت مطور ويب فأنت تعاني حتماً من مشكلة اكتشاف الأخطاء ومعالجتها أو ما يعرف بـ debugging، فمثلاً إذا كان لديك خطأ في شيفرة JavaScript فهناك احتمال ضئيل أن يظهر لك المستعرض رقم السطر الذي يحوي الخطأ، وحتى إن أظهره لك فليس من الضروري أن يكون هذا السطر هو المسبب للخطأ. وإذا ما اتجهنا نحو أخطاء ومشاكل مظهر الصفحة CSS فالأمر أشبه بالتنجيم. فمثلاً إذا واجهت مشكلة في تنسيق الصفحة فالحل الوحيد هو العودة إلى ملف CSS والقيام ببعض التعديلات ومن ثم الرجوع إلى المستعرض لرؤية ما إذا كانت هذه التعديلات قد حلت المشكلة، وهكذا في رحلة مكوكية بين المحرر والمستعرض حتى تجد المشكلة. لكن باستخدام أدوات المطور DevTools تستطيع تتبع مشاكل المظهر بفعالية، واكتشاف أخطاء جافاسكربت بسهولة، بالإضافة إلى أنها تقدم لك إضاءات ومعلومات حول الأداء والتي يمكن استخدامها لتحسينه. الشيفرة المصدرية الخاصة بمثال الرزنامة
  2. تملك المتصفحات الحديثة أدوات تطوير مبينة فيها للتعامل مع لغة JavaScript وتقنيات الويب الأخرى، وهذه الأدوات تتضمن سطر الأوامر (Console) الذي يشبه سطر الأوامر الخاص بأنظمة يونكس، إضافةً إلى أدواتٍ لتفحص (inspect) شجرة DOM، وأدوات للتنقيح (debugging)، وتحليل نشاط الشبكة. يمكن استخدام سطر الأوامر (Console) لإنشاء سجل من المعلومات كجزءٍ من عملية تطوير تطبيقات JavaScript، ويسمح لك بالتفاعل مع صفحة الويب بتنفيذ تعليمات JavaScript على عناصر الصفحة. وهذا يعني أنَّ سطر الأوامر يسمح لك بكتابة وإدارة ومراقبة شيفرات JavaScript عند الحاجة. سنشرح في هذا الدرس كيفية التعامل مع سطر الأوامر باستعمال JavaScript في المتصفحات، وسنعطي لمحة عن أدوات التطوير الأخرى المبنية في المتصفحات والتي يمكنك استعمالها في عملية تطوير تطبيقات الويب. العمل مع سطر الأوامر (Console) في المتصفح أغلبية متصفحات الويب الحديثة التي تدعم لغة HTML و XHTML القياسية ستوفِّر لك وصولًا إلى سطر أوامر الذي يمكنك استخدامه (عبر لغة JavaScript) بما يشبه طريقة استخدام الطرفية (terminal) في أنظمة يونكس. سنشرح الآن كيفية الوصول إلى سطر الأوامر في متصفحَي Firefox و Chrome. متصفح Firefox لفتح Web Console في متصفح Firefox، فاضغط على زر القائمة ☰ في الزاوية العليا اليمنى بجوار شريط العنوان. ثم اضغط على زر Developer الذي يقع تحت أيقونة المفك، والذي سيفتح قائمة Web Developer، ومن ثم اضغط على خيار Web Console. وهذا سيفتح لوحةً في أسفل نافذة المتصفح: يمكنك أيضًا الدخول إلى سطر الأوامر عبر اختصار لوحة المفاتيح Ctrl+Shift+K على نظامَي لينكس وويندوز، أو Command+Option+K على ماك. يمكننا التفاعل مع سطر الأوامر باستخدام JavaScript بعد أن استطعنا فتحه. متصفح Chrome لفتح JavaScript Console في متصفح Chrome فيمكنك النقر على القائمة في الزاوية العليا اليمنى من نافذة المتصفح (التي يُرمَز لها بثلاث نقط عمودية) ومن ثم اختيار More Tools ثم Developer Tools. ستُفتح لوحةٌ جديدة فيها اللسان Console في الشريط العلوي الذي عليك أن تضغط عليه للوصول إلى سطر الأوامر (هذا إن لم يكن هذا اللسان مفعّلًا من البداية): يمكنك أيضًا الوصول إلى سطر الأوامر بالضغط على اختصار لوحة المفاتيح Ctrl+Shif+J في نظامَي لينكس وويندوز، أو Command+Option+J في نظام ماك، وهذا سيؤدي إلى فتح لسان Console مباشرةً. يمكننا التفاعل مع سطر الأوامر باستخدام JavaScript بعد أن استطعنا فتحه. التعامل مع سطر الأوامر يمكنك كتابة شيفرات JavaScript داخل سطر الأوامر. لنبدأ بإظهار تحذير يحتوي على السلسلة النصية Hello, World!‎: alert("Hello, World!"); بعد أن تضغط على زر Enter بعد كتابة سطر JavaScript السابق، فيمكن أن تشاهد نافذة التحذير الآتية في متصفحك: ملاحظة: سيُظهِر سطر الأوامر نتيجة تنفيذ التعابير البرمجية، وسيُظهِر undefined إذا لم تتم إعادة (return) قيمة من التعبير المُنفَّذ. بدلًا من عرض نوافذ تحذير التي علينا الضغط على زر OK للخروج منها، يمكننا معرفة ناتج تعابير JavaScript بطباعتها إلى سطر الأوامر عبر الدالة console.log. فلو أردنا طباعة السلسلة النصية Hello, World!‎ سنكتب التعبير البرمجي الآتي في سطر الأوامر: console.log("Hello, World!"); وسيُطبَع السطر الآتي في نافذة سطر الأوامر: Hello, World!‎ يمكننا استخدام JavaScript لإجراء حسابات رياضية في سطر الأوامر: console.log(2 + 6); الناتج: 8 وسيستطيع المتصفح إجراء حسابات على أرقام أكبر: console.log(34348.2342343403285953845 * 4310.23409128534); الناتج: 148048930.17230788 لا تغفل عن إمكانية إجراء عمليات مُقسَّمة على أكثر من سطر عبر استعمال المتغيرات: let d = new Date(); console.log("Today's date is " + d); الناتج: Today's date is Wed Jun 21 2017 15:49:47 GMT-0400 (EDT) إذا أردتَ تعديل التعبير الذي كتبته في سطر الأوامر، فاضغط على زر السهم العلوي ↑ في لوحة مفاتيحك للحصول على السطر السابق، وهذا ما يسمح لك بتعديله ثم تنفيذه مجددًا. يوفر لك سطر أوامر المتصفح القدرة على تجربة شيفرات JavaScript في الوقت الحقيقي بما يشبه واجهة سطر الأوامر في أنظمة يونكس. التعامل مع ملف HTML يمكنك أيضًا إجراء عمليات على ملف HTML موجود مسبقًا أو على مستند مولّد ديناميكيًا عبر سطر الأوامر؛ وهذا يسمح لنا بتجربة كيفية تعامل شيفرات JavaScript مع عناصر HTML وقواعد CSS وسكربتات JavaScript الموجودة في صفحة الويب. أبقِ في ذهنك أنّك إذا أعدتَ تحميل الصفحة بعد تعديلها في سطر الأوامر فستعود إلى حالتها الأصلية قبل التعديل، ولذا احرص على حفظ أيّة تعديلات تريد الإبقاء عليها. لنحفظ مستند HTML الآتي باسم index.html لكي نجِّرب تعديلها عبر سطر الأوامر: <!DOCTYPE html> <html lang="en-US"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Today's Date</title> </head> <body> </body> </html> إذا حفظتَ مستند HTML السابق في ملفٍ ما وفتحتَه باستخدام متصفحك المفضّل فيجب أن تشاهد صفحةً فارغةً عنوانها «Today’s Date». يمكنك الآن فتح سطر الأوامر لاستعمال JavaScript لتعديل الصفحة، وسنبدأ بكتابة شيفرة JavaScript لإضافة ترويسة في الصفحة: let d = new Date(); document.body.innerHTML = "<h1>Today's date is " + d + "</h1>" ستحصل على الناتج الآتي في سطر الأوامر: "<h1>Today's date is Sat Jun 24 2017 12:16:14 GMT-0400 (EDT)</h1>" يجب أن تبدو الصفحة الآن كما يلي: يمكنك أيضًا تعديل أنماط الصفحة، مثل لون الخلفية: document.body.style.backgroundColor = "lightblue"; الناتج: "lightblue" وكذلك الأمر مع لون النص في الصفحة: document.body.style.color = "white"; الناتج: "white" يجب أن تبدو الصفحة الآن كما يلي: يمكنك أيضًا إنشاء فقرة جديدة عبر العنصر <p>: let p = document.createElement("P"); بعد إنشاء العنصر، حان الوقت لإضافة عقدة نصية (text node) التي يمكننا إضافتها إلى الفقرة الجديدة: let t = document.createTextNode("Paragraph text."); سنضيفها الآن إلى الفقرة المُعرَّفة عبر المتغير p: p.appendChild(t); وأخيرًا سنضيف الفقرة المُخزَّنة في المتغير p والنص الموجود فيها إلى المستند: document.body.appendChild(p); إذا أكملتَ الخطوات السابقة، فيجب أن تبدو صفحة HTML السابقة كما يلي: يوفِّر لنا سطر الأوامر البيئة المناسبة لإجراء تجرب على صفحات HTML، لكن من المهم أن نبقي في ذهننا أنَّنا لا نعدل مستند HTML فعليًا عندما ننفذ التعليمات البرمجية في سطر الأوامر، وإنما ستذهب جميع تعديلاتنا إذا أعدنا تحديث الصفحة. لمحة عن أدوات التطوير الأخرى اعتمادًا على أدوات المطوِّر التي يوفرها متصفحك، فستقدر على استخدام أدوات أخرى لمساعدتك في عملية تطوير الويب، لنطلع على تلك الأدوات. عرض شجرة DOM في كل مرة يتم فيها تحميل صفحة الويب، فسيُنشِئ المتصفح ما يسمى شجرة DOM (اختصار للعبارة Document Object Model) للصفحة. شجرة DOM تتألف من كائنات التي تُمثِّل عناصر HTML ضمن البنية الهرمية للعناصر. وشجرة DOM متاحة ضمن لسان Inspector في متصفح Firefox أو لسان Elements في متصفح Chrome. تسمح لك هذه الأدوات بعرض وتعديل عناصر DOM وتسمح لك بمعرفة ما هي وسوم HTML المسؤولة عن عرض جزء معيّن من الصفحة. ويمكن أيضًا من هذا اللسان معرفة ما هي قيمة المعرِّف ID لصورةٍ معيّنةٍ على سبيل المثال. ستكون بنية الصفحة التي عدلناها (وقبل إعادة تحميل الصفحة) في لسان DOM كما يلي: يمكنك أيضًا رؤية ما هي قواعد CSS المطبقة في لوحة جانبية بجوار اللسان الذي يعرض بنية شجرة DOM، مما يسمح لك بمعرفة ما هي الأنماط المُطبّقة على عنصر DOM داخل مستند HTML أو عبر ملف أنماط CSS خارجي. هذه صورةٌ تظهر أنماط العنصر body في أدوات المطوِّر في Firefox: لتعديل عقدة من عقد DOM فانقر نقرًا مزدوجًا فوق العنصر المُحدَّد وأجرِ التعديلات اللازمة، فحاول مثلًا أن تحوِّل العنصر <h1> إلى <h2>. تذكَّر أنَّ الصفحة ستعود إلى حالتها الأصلية المحفوظة إذا أعدت تحميلها. لسان الشبكة يمكن في لسان الشبكة Network في أدوات المطوِّر الموجودة في متصفحك أن تراقب وتسجِّل الطلبيات الشبكية، إذ يُظهِر هذا اللسان جميع الطلبيات الشبكية التي يجريها المتصفح بما في ذلك ما طَلَبَهُ عند تحميل الصفحة، وكم استغرقت كل طلبية من الوقت، وسيوفِّر تفاصيل عن كل طلبية؛ وهذا سيساعد كثيرًا في معرفة سبل تحسين أداء الصفحة وتسريع تحميلها وتنقيح مشاكل الشبكة. يمكنك استخدام لسان الشبكة جنبًا إلى جنب مع سطر الأوامر، أي يمكنك بدء عملية تنقيح (debug) الصفحة في سطر الأوامر ثم الانتقال إلى لسان الشبكة لرؤية النشاطات الشبكية دون إعادة تحميل الصفحة. لتعلّم المزيد حول لسان الشبكة، فأنصحك بقراء working with Firefox’s Network Monitor أو getting started with analyzing Network performance with Chrome’s DevTools. التصميم المتجاوب عندما يكون موقع الويب متجاوبًا (responsive)، فهذا يعني أنَّه صُمِّمَ وطوِّرَ لكي يظهر ويعمل بشكل مناسب على مجال واسع من الأجهزة المختلفة مثل الهواتف المحمولة والحواسيب اللوحية والحواسيب المكتبة والمحمولة. قياس الشاشة وكثافة البكسلات ودعم اللمس هي عوامل مهمة يجب أخذها بالحسبان عند تطوير مواقع متجاوبة، ويجب عليك –كمطور ويب– أن تفكر في مبادئ التصميم المتجاوب عند إنشاء المواقع لإتاحتها للآخرين بغض النظر عن الجهاز الذي يصلون إلى موقعك عبره. يوفر لك متصفح Firefox و Chrome أدواتٍ للتأكد من تطبيقك لمبادئ التصميم المتجاوب أثناء إنشائك وتطويرك لمواقع وتطبيقات الويب. وستتمكن بوساطة تلك الأدوات أن تحاكي مختلف الأجهزة لكي تختبر تطبيقك وتحلّل مشاكله أثناء التطوير. اقرأ المزيد عن Responsive Design Mode في متصفح Firefox أو Device Mode في Chrome لتعلم طريقة الاستفادة من تلك الأدوات لإنشاء مواقع ويب تلبي احتياجات جميع المستخدمين. الخلاصة أخذنا في هذا الدرس لمحةً عن طريقة التعامل مع سطر الأوامر الموجود في المتصفحات الحديثة، بالإضافة إلى بعض المعلومات عن أدوات التطوير التي يمكنك الاستفادة منها في عملك. لتعلّم المزيد عن JavaScript فاقرأ كتاب تعلم JavaScript، وإذا كنتَ مهتمًا بمكتبة jQuery فأنصحك بالاطلاع على كتاب تعلم jQuery. ترجمة –وبتصرّف– للمقال How To Use the JavaScript Developer Console لصاحبته Lisa Tagliaferri
  3. تأتي وحدة التسجيل (logging) مبدئيا توزيعة بايثون المعيارية وتقدم حلا لمتابعة الأحداث التي تحصُل أثناء عمل البرمجية. تستطيع إضافة استدعاءات التسجيل للشيفرة البرمجية الخاصة بك للإشارة لما تحقق من أحداث. تسمح لك وحدة التسجيل بإعداد كل من التسجيلات التشخيصية التي تسجل الأحداث المقترنة بعمليات التطبيق، بالإضافة إلى تسجيلات التدقيق التي تسجل الأحداث الخاصة بحركات المستخدم بهدف تحليلها. وحدة التسجيل هذه مختصة في حفظ السجلات في ملفات. لماذا نستخدم وحدة التسجيل؟ تحافظ وحدة التسجيل على سجل الأحداث التي تحدث خلال عمل البرنامج، مما يجعل من رؤية مخرجات البرنامج المتعلقة بأحداثه أمراً متاحاً. قد يكون استخدام الأمرprint أمرا مألوفا لك خلال الشيفرة البرمجية لفحص الأحداث. يقدم الأمر print طريقة بدائية لإجراء عملية التنقيح الخاصة بحل المشاكل خلال عمل البرمجية. بينما يعد تضمين تعليمات print خلال الشيفرة البرمجية طريقة لمعرفة مسار تنفيذ البرنامج والحالة الحالية له، إلا أن هذه الطريقة اُثبت أنها أقل قدرة على الصيانة من استخدام وحدة التسجيل في بايثون، وذلك للأسباب التالية: باستخدام تعليمات print يصبح من الصعب التفرقة بين مخرجات البرنامج الطبيعية وبين مخرجات التنقيح لتشابههما. عندما تنتشر تعليمات print خلال الشيفرة البرمجية، فإنه لا توجد طريقة سهلة لتعطيل التعليمات الخاصة بالتنقيح. من الصعب إزالة كافة تعليمات print عندما تنتهي من عملية التنقيح. لا توجد سجلات تشخيصية للأحداث. من الجيد البدء بالتعود على استخدام وحدة التسجيل المعيارية في بايثون خلال كتابة الشيفرة البرمجية بما أنها طريقة تتلاءم أكثر مع التطبيقات التي يكبر حجمها عن سكريبتات بايثون بسيطة، وكذلك بما أنها تقدم طريقة أفضل للتنقيح. طباعة رسائل التنقيح في وحدة التحكم إذا كنت متعودا على استخدام تعليمات print لرؤية ما يحدث في برنامجك خلال العمل، فمن المحتمل مثلا أنك تعودت على رؤية برنامج يُعرف صنفًاClass وينشئ منه عناصر كما في المثال التالي: 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__ التي تستخدم لتعريف خصائصname وprice للصنفPizza. كما تحتوي على الدالتين make لصنع البيتزا، وeat لأكلها وتأخذان المعطى quantity ذا القيمة الافتراضية 1. لنشغل البرنامج: >> python pizza.py وسنحصل على المخرج التالي: Output Pizza created: artichoke ($15) Made 1 artichoke pizza(s) Ate 1 pizza(s) Pizza created: margherita ($12) Made 2 margherita pizza(s) Ate 1 pizza(s) تسمح لنا تعليمات print برؤية أن البرنامج يعمل، ولكننا نستطيع أن نستخدم وحدة التسجيل لذات الغرض بدلا من ذلك. لنقم بإزالة تعليمات print من الشيفرة البرمجية، ونستورد الوحدة باستخدام الأمر import logging: import logging class Pizza(): def __init__(self, name, value): self.name = name self.value = value ... المستوى التلقائي للتسجيل في وحدة التسجيل هو مستوى التحذير (WARNING)، وهو مستوى فوق مستوى التنقيح (DEBUG). بما أننا سنستخدم الوحدة بغرض التنقيح في هذا المثال، سنحتاج الى تعديل إعدادات التسجيل لتصبح بمستوى التنقيح logging.DEBUG بحيث تعود معلومات التنقيح لنا من خلال لوحة التحكم. ونقوم بإعداد ذلك بإضافة ما يلي بعد تعليماتة الاستيراد: import logging logging.basicConfig(level=logging.DEBUG) class Pizza(): ... هذا المستوى المتمثل بlogging.DEBUG يشير لقيد رقمي قيمته 10. سنستبدل الآن جميع تعليمات print بتعليمات logging.debug()، (logging.DEBUG ثابت بينما logging.debug() دالة). نستطيع أن نمرر لهذه الدالة نفس المدخلات النصية لتعليماتة 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() pizza_01.eat() pizza_02 = Pizza("margherita", 12) pizza_02.make(2) pizza_02.eat() لهذا الحد، نستطيع تشغيل البرنامج عبر تنفيذ الأمر python pizza.py وسنحصل على المخرج التالي: Output 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 والتي تشير لمستوى المُسجل (logger) الذي يتم استخدامه. يعني ما سبق أن وحدة التسجيل logging من الممكن أن يتم استخدامها لإعداد أكثر من مُسجل بأسماء مختلفة. فمثلا، نستطيع إنشاء مسجلين باسمين مختلفين ومخرجات مختلفة كما هو موضح بالأسفل: logger1 = logging.getLogger("module_1") logger2 = logging.getLogger("module_2") logger1.debug("Module 1 debugger") logger2.debug("Module 2 debugger") Output DEBUG:module_1:Module 1 debugger DEBUG:module_2:Module 2 debugger بعد أن أصبحت لدينا المعرفة اللازمة لكيفية استخدام الوحدة 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, 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() الشيفرة البرمجية هنا هي نفسها الموجودة سابقا عدا أننا أضفنا اسم الملف الذي سنقوم بحفظ التسجيلات فيه. بمجرد تشغيلنا للشيفرة السابقة، سنجد في نفس المسار الملف test.log. لنفتحه باستخدام محرر النصوص nano (أو أي محرر نصوص من اختيارك): $ nano 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_01 و pizza_02: ... # Modify the parameters of the pizza_01 object pizza_01 = Pizza("Sicilian", 18) pizza_01.make(5) pizza_01.eat(4) # Modify the parameters of the pizza_02 object pizza_02 = Pizza("quattro formaggi", 16) pizza_02.make(2) pizza_02.eat(2) عند تنفيذ الشيفرة بعد حفظ التعديلات، ستُضاف التسجيلات الجديدة للملف وسيكون محتواه كالتالي: 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) تُعد البيانات الموجودة في الملف مفيدة، ولكننا نستطيع جعلها أكثر إعلاماً بإضافة بعض الإعدادات. بشكل أساسي، فإننا نريد أن نجعل السجلات مفصلة أكثر بإضافة الوقت الذي أنشئ السجل فيه. نستطيع إضافة المعطى المسمى format ونضيف له النص %(asctime)s الذي يشير للوقت، كذلك، للإبقاء على ظهور مستوى التسجيل في السجلات، لابد أن نضيف النص %(levelname)s بالإضافة للسجل نفسه %(message)s. لابد من الفصل بين كل خيار في المعطى format بالعلامة : كما هو موضح بالأسفل: import logging logging.basicConfig( filename="test.log", level=logging.DEBUG, format="%(asctime)s:%(levelname)s:%(message)s" ) ....... عندما ننفذ الشيفرة السابقة، سنحصل على تسجيلات جديدة في ملف test.log تتضمن الوقت الذي أنشئ فيه التسجيل بالإضافة لمستوى التسجيل ورسالة التسجيل: Output 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) تبعا لاحتياجاتك، من الممكن أن تضيف إعدادات أخرى للمسجل بحيث تجعل التسجيلات التي يتم حفظها في الملف مرتبطة بك نوعا ما. التنقيح بواسطة التسجيل في ملفات خارجية يتيح لك فهما شاملا لبرنامج بايثون مع مرور الوقت، معطيا الفرصة لحل المشاكل التي تظهر وتغيير ما تحتاج تغييره في الشيفرة البرمجية استنادا لما لديك من بيانات تسجيلات تاريخية وأحداث وحركات تمت خلال عمل البرنامج. جدول بمستويات التسجيل تستطيع نسب مستوى الأهمية للحدث الذي يتم تسجيله بواسطة المُسجل وذلك بإضافة مستوى الخطورة (Severity Level). مستويات الخطورة موضحة في الجدول الذي بالأسفل. تتمثل مستويات التسجيل تقنيا بأرقام (ثوابت)، بفرق قيمة بين كل مستوى ب 10، تبدأ من المستوىNOTEST ذي القيمة 0. تستطيع أن تُعرف مستويات خاصة بك مرتبطة بالمستويات المعرفة مسبقا. إذا عَرَّفْتَ مستوى بنفس القيمة الرقمية، فإنك تستبدل اسم المستوى المرتبط بتلك القيمة. المستوى القيمة الرقمية الدالة الاستخدام CRITICAL 50 ()logging.critical اظهار الأخطاء الخطيرة، البرنامج قد لا يستمر بالعمل ERROR 40 ()logging.error إظهار مشكلة خطيرة WARNING 30 ()logging.warning الإشارة لحدث غير متوقع حصل أو قد يصحل INFO 20 ()logging.info الإشارة أن الحدث حصل كما هو متوقع DEBUG 10 ()logging.debug فحص المشاكل، وإظهار معلومات تفصيلية خاتمة الوحدة logging هي وحدة ضمن التوزيعة المعيارية لبايثون، وتقدم حلا لمتابعة الأحداث التي تحدث خلال عمل البرمجية مع إمكانية تسجيل هذه الأحداث في ملفات خارجية أو إظهارها على الطرفية. وهذا يتيح لك فهما شاملا لبرنامج بايثون مع مرور الوقت. ترجمة – بتصرّف – للمقال How To Use Logging in Python 3 لصاحبته Lisa Tagliaferri.
  4. نعني بالتنقيح Debugging في مجال تطوير البرمجيات، عملية إيجاد وحل المشاكل التي تمنع البرمجية من العمل على نحو سليم. يُقدم مُنقح بايثون بيئة تنقيح لبرامج بايثون، ويدعم إعداد نقاط الفصل (Breakpoints)، التدرج خلال الشيفرة البرمجية (Stepping) سطرًا بسطر والعديد من المزايا. التفاعل مع مُنقح بايثون يأتي مُنقح بايثون مرفقًا مع توزيعة بايثون المعيارية على هيئة وحدة بايثون باسم pdb، ومن الممكن أن يُستخدم في الشيفرة البرمجية كعنصر من الصنف Pdb، ولمزيد من المعلومات تستطيع قراءة التوثيق الرسمي للوحدة pdb. سوف نبدأ العمل باستخدام برنامج صغير يحتوي على متغيرين ودالة تحتوي على حلقة تكرار بالإضافة لسطر استدعاء الدالة من خلال التركيبة if __name__ == '__main__':. 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() نستطيع الآن تشغيل البرنامج السابق من خلال مُنقح بايثون في الطرفية باستخدام الأمر التالي: python -m pdb looping.py يستورد الخيار –m في الأمر أي وحدة بايثون وتشغيلها كبرنامج. في هذه الحالة نقوم باستيراد الوحدة pdb وتمريرها كما هو مكتوب في الأمر. عند تنفيذ الأمر السابق سوف تحصل على المُخرج التالي: > /Users/sammy/looping.py(1)<module>() -> num_list = [500, 600, 700] (Pdb) يحتوي السطر الأول في المُخرج على اسم الملف الحالي الذي نقوم بتنقيحه – بالمسار الكامل -، ومن ثم يوجد رقم سطر الشيفرة التي يقف عليها مؤشر المُنقح (في هذه الحالة 1، ولكن في حالة وجود تعليق أو سطر غير تنفيذي سيكون الرقم أكبر من ذلك). السطر الثاني عبارة عن سطر الشيفرة الذي يتم تنفيذه. يُقدم مُنقح بايثون وحدة تحكم (Console) تفاعلية لإجراء عملية التنقيح وتستطيع استخدام أمر المساعدةhelp للتعرف على الأوامر المتاحة في المُنقح، وأيضا من الممكن أن تستخدم صيغة المساعدة مع الأمرhelp command للتعرف أكثر على تفاصيل أمر معين. سيعيد المُنقح عمله مرة أخرى تلقائيا عندما يصل لنهاية البرنامج. إذا أردت الخروج من وحدة تحكم المُنقح، أدخل الأمرquit أوexit. إذا أردت إعادة تشغيل عملية التنقيح مرة أخرى وفي أي مكان من البرنامج، أدخل الأمرrun. استخدام المُنقح للتدرج خلال البرنامج عند العمل على تنقيح البرامج باستخدام مُنقح بايثون، فإنك غالبا ستستخدم أوامر step، list وnext للمرور على الشيفرة البرمجية. خلال هذا الجزء من المقال سنتناول هذه الأوامر. من خلال نافذة الأوامر، نستطيع إدخال الأمرlist للحصول على السياق المحيط للسطر الحالي. فمثلا، من السطر الأول في البرنامج looping.py الذي عرضناه في الأعلى — num_list = [500, 600, 700] — سيكون تنفيذ الأمرlist معه بالشكل التالي: (Pdb) list 1 -> num_list = [500, 600, 700] 2 alpha_list = ['x', 'y', 'z'] 3 4 5 def nested_loop(): 6 for number in num_list: 7 print(number) 8 for letter in alpha_list: 9 print(letter) 10 11 if __name__ == '__main__': (Pdb) السطر الحالي يشار إليه بالعلامة -> في بدايته وهو في حالتنا هذه السطر الأول من البرنامج. بحكم أن البرنامج الذي نستخدمه هنا صغير نسبيا، فإننا تقريبا نحصل على كافة الأسطر في البرنامج عند استخدامالأمر list. بدون تزويد معطيات مع الأمر list، نحصل من استخدام الأمر على 11 سطراً من الشيفرة البرمجية محيطة بالسطر الحالي في المُنقح، ولكننا نستطيع تحديد الأسطر التي نريد عرضها بالشكل التالي: (Pdb) list 3, 7 3 4 5 def nested_loop(): 6 for number in num_list: 7 print(number) (Pdb) في الأمر السابق قمنا بعرض الأسطر 3-7 باستخدام الأمر list 3,7. للمرور خلال البرنامج سطرا بسطر، نستخدم الأمرstep أو next. (Pdb) step > /Users/sammy/looping.py(2)<module>() -> alpha_list = ['x', 'y', 'z'] (Pdb) (Pdb) next > /Users/sammy/looping.py(2)<module>() -> alpha_list = ['x', 'y', 'z'] (Pdb) الفرق بين الأمرstep والأمرnext أن الأمرstep سوف يتوقف مع استدعاء دالة، بينما الأمر next يُنفذ الدالة عند استدعائها. يتجلى الفرق بين الأمرين عند التعامل مع الدوال. في مثالنا المستخدم، سيقوم الأمرstep بالتعداد خلال حلقات التكرار بمجرد الدخول في استدعاء الدالة nested_loop() بحيث يظهر تماما ما تقوم به حلقة التكرار من طباعة رقم ومن ثم الدخول في حلقة تكرار طباعة الحروف المقترنة بالرقم ومن ثم العودة لطباعة رقم جديد وهكذا. (Pdb) step > /Users/sammy/looping.py(5)<module>() -> def nested_loop(): (Pdb) step > /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: (Pdb) الأمرnext، بدلا من ذلك، سيستدعي الدالة دون الدخول في خطوات تنفيذها خطوة-بخطوة. لنخرج من المُنقح ونعد تشغيله مرة أخرى: 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 -> nested_loop() (Pdb) أثناء عملك في تنقيح الشيفرة البرمجية الخاصة بك، قد تريد فحص قيمة متغير، وهو ما تستطيع تنفيذه باستخدام الأمرpp والذي يقوم بطباعة القيمة باستخدام وحدة pprint: (Pdb) pp num_list [500, 600, 700] (Pdb) أغلب الأوامر في مُنقح pdb لديها اختصارات، فمثلا، الأمرstep له اختصار هوs ولأمرnext يوجدn. يسرد أمر المساعدة help كافة الاختصارات لكل الأوامر. بالإضافة لذلك، تستطيع استدعاء الأمر الأخير بالضغط على زر الإدخال (Enter) في لوحة المفاتيح. نقاط الفصل من المؤكد أنك ستعمل على برامج أكبر من المثال المستخدم هنا، لذلك، غالبا ستحتاج أن تتوقف عند وظيفة معينة أو سطر محدد أثناء تنقيحك للشيفرة البرمجية، وذلك بدلا من المرور على كافة أسطر البرنامج. ستتمكن باستخدام الأمرbreak لإعداد نقاط الفصل من تشغيل البرنامج حتى نقطة معينة مسبقا فيه تـسمى نقطة فصل Break point. عندما تضيف نقطة فصل، سيعطيها المُنقح رقما خاصا بها. الأرقام المُعطاة لنقاط الفصل تكون أرقاماً متعاقبة وتبدأ من 1، وتستطيع الإشارة لنقاط الفصل باستخدام أرقامها أثناء عملك في المُنقح. تُضاف نقاط الفصل في أسطر معينة باستخدام الصيغة التالية <program_file>:<line_number> كما هو موضح بالأسفل: (Pdb) break looping.py:5 Breakpoint 1 at /Users/sammy/looping.py:5 (Pdb) اكتب الأمرclear ومن ثم y لإزالة نقاط الفصل الحالية. تستطيع بعد ذلك إضافة نقطة فصل في مكان تعريف الدالة: (Pdb) break looping.nested_loop Breakpoint 1 at /Users/sammy/looping.py:5 (Pdb) تستطيع كذلك إضافة شرط لنقطة الفصل: (Pdb) break looping.py:7, number > 500 Breakpoint 1 at /Users/sammy/looping.py:7 (Pdb) لو أدخلنا الآن الأمرcontinue، فإن البرنامج سيتوقف عندما تكون قيمة المتغيرnumber أكبر من 500. (Pdb) continue 500 x y z > /Users/sammy/looping.py(7)nested_loop() -> print(number) (Pdb) للحصول على قائمة بنقاط الفصل المُعدة حاليا للعمل، استخدم الأمرbreak فقط (دون معطيات) وسوف تحصل على معلومات نقاط الفصل التي قمت بإعدادها. (Pdb) break Num Type Disp Enb Where 1 breakpoint keep yes at /Users/sammy/looping.py:7 stop only if number > 500 breakpoint already hit 2 times (Pdb) نستطيع تعطيل نقطة فصل من البرنامج باستخدام الأمرdisable ومن ثم ندخل رقم نقطة الفصل. في هذه الجلسة (المثال المشروح) قمنا بإضافة نقطة فصل أخرى ومن ثم عطلنا النقطة الأولى: Pdb) break looping.py:11 Breakpoint 2 at /Users/sammy/looping.py:11 (Pdb) disable 1 Disabled breakpoint 1 at /Users/sammy/looping.py:7 (Pdb) break Num Type Disp Enb Where 1 breakpoint keep no at /Users/sammy/looping.py:7 stop only if number > 500 breakpoint already hit 2 times 2 breakpoint keep yes at /Users/sammy/looping.py:11 (Pdb) لتفعيل نقطة الفصل نستخدم الأمرenable، ولإزالة نقطة الفصل نستخدم الأمرclear: (Pdb) enable 1 Enabled breakpoint 1 at /Users/sammy/looping.py:7 (Pdb) clear 2 Deleted breakpoint 2 at /Users/sammy/looping.py:11 (Pdb) تقدّم لك نقاط الفصل في pdb قدرة كبيرة في التحكم، فمثلا، من الإضافات أنك تستطيع تجاهل نقطة الفصل خلال الدورة الحالية من البرنامج باستخدام الأمرignore أو تنفيذ حدث معين عند الوصول لنقطة فصل معينة باستخدام الأمرcommand. تستطيع كذلك إضافة نقاط فصل مؤقتة بواسطة الأمرtbreak، بحيث يقوم المُنقح بحذفها تلقائيا عند الوصول إليها وتنفيذها للمرة الأولى (لإضافة نقطة فصل مؤقتة في السطر رقم 3، ندخل الأمرtbreak 3 ). تضمين المُنقح في الشيفرة البرمجية تستطيع تشغيل جلسة تنقيح في الشيفرة البرمجية مباشرة وذلك باستيراد الوحدة pdb إضافة الدالة pdb.set_trace قبل السطر الذي تريد أن تبدأ الجلسة من عنده. في مثالنا المستخدم خلال هذا المقال، سوف نقوم باستيراد الوحدة pdb واضافة الدالة المذكورة قبل البدء بحلقة التكرار الداخلية في الدالة nested_loop: # Import pdb module import pdb num_list = [500, 600, 700] alpha_list = ['x', 'y', 'z'] def nested_loop(): for number in num_list: print(number) # Trigger debugger at this line pdb.set_trace() for letter in alpha_list: print(letter) if __name__ == '__main__': nested_loop() بإضافة المُنقح في الشيفرة البرمجية الخاصة بك، فأنت لست بحاجة لتشغيل الشيفرة بطريقة معينة أو أن تتذكر إعدادات نقاط الفصل، وستتمكن من تشغيل البرنامج بطريقة عادية وتفعيل المُنقح من خلال التنفيذ. تعديل مسار عمل البرنامج يتيح لك مُنقح بايثون تغيير مسار التنفيذ (Execution Flow) خلال زمن التنفيذ باستخدام الأمر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 letters_list.py فإننا سوف نحصل على النتيجة التالية: Output ['s'] ['s', 'a'] ['s', 'a', 'm'] ['s', 'a', 'm', 'm'] ['s', 'a', 'm', 'm', 'y'] لنستعرض كيفية استخدام مُنقح بايثون في تغيير مسار عمل البرنامج السابق بحيث نقوم بالقفز قُدما خلال الشيفرة البرمجية للبرنامج أثناء التشغيل بعد الدورة الأولى من حلقة التكرار: 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 (Pdb) continue ['s'] ['s', 'm'] ['s', 'm', 'm'] ['s', 'm', 'm', 'y'] قمنا خلال جلسة التنقيح السابقة بوضع نقطة فصل عند السطر رقم 5 لمنع الشيفرة البرمجية من الاستمرار، ومن ثم قمنا بطباعة بعض الأحرف والاستمرار من خلال الأمرcontinue لإظهار ماذا يحدث. ثم استخدمنا الأمرjump لتجاهل السطر 6. عند هذه النقطة، المتغيرletter يساوي القيمة a ولكننا تجاهلنا السطر الذي يقوم بإضافة هذه القيمة للقائمة. بعد ذلك قمنا بتعطيل نقطة الفصل وتركنا البرنامج يستمر في التنفيذ. في النهاية، فإن الحرفa لم يُضف للقائمة sammy_list. لنعد تشغيل جلسة التنقيح، ونستخدم المُنقح في العودة للخلف خلال التشغيل بهدف إعادة تنفيذ جملة الإضافة للقائمة sammy_list والتي تم تنفيذها خلال التكرار الأول من حلقة التكرار: > /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 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'] خلال جلسة التنقيح السابقة، قمنا بإضافة نقطة فصل عند السطر 6، وقمنا بالعودة للخلف للسطر 5 بعد الاستمرار.طبعنا ما تحتويه القائمة خلال التنفيذ وذلك لكي نظهر أن الحرف s قد أٌضيف مرتين. وبعد ذلك قمنا بتعطيل نقطة الفصل وجعلنا البرنامج يستمر في التنفيذ. النتيجة الظاهرة توضح أن الحرف s أضيف مرتين في بداية القائمة sammy_list. يمنع المنقّح بعض استخدامات الأمرjump ، وخاصة عندما يُعدَّل مسار البرنامج للأمام أو الخلفمن خلال جمل لم تُعرَّف. فمثلا، لا تستطيع القفز إلى دوال قبل أن تعرّف المعطيات الخاصة بها، وكذلك لا تستطيع الدخول في وسط جملة try:except أو الخروج من كتلة الشيفرة البرمجية لـ finally. ملخص ما نستطيع ذكره عن الأمرjump، أنك من خلال استخدامه في مُنقح بايثون تستطيع تغيير مسار التنفيذ خلال التنقيح لمعرفة هل هذا التغيير مفيد ضمن ظروف ومعطيات محددة أم لا، وكذلك يساعدك في فهم أصل أو مكان الخلل والمشاكل التي تظهر خلال تنفيذ البرنامج. جدول أوامر المنقح pdb هنا نلخص لكم أوامر المُنقح pdb مع شرح بسيط عما يقدمه كل أمر لكي يساعدك على التذكر خلال تنقيح البرامج على بايثون: الأمر الاختصار العمل help h يقدم قائمة بالأوامر المتاحة أو شرحا لأمر معين jump j تحديد السطر القادم للتنفيذ list l طباعة السياق (ما حول السطر الحالي) للتعرف أكثر على محيط التنفيذ الحالي next n الاستمرار في التنفيذ حتى السطر القادم الذي تصل فيه الدالة الحالية أو تعود step s تنفيذ السطر الحالي والتوقف عند أول فرصة متاحة pp pp طباعة متغير أو تعبير معين quit أو exit q الخروج من البرنامج return r الاستمرار في التنفيذ حتى تعود الدالة الحالية تستطيع أن تقرأ أكثر عن الأوامر وكيفية العمل مع المنقح من خلال الاطلاع على التوثيق الرسمي في بايثون. خاتمة يعد تنقيح البرمجيات خطوة مهمة في أي مشروع لبناء وتطوير برمجية. يقدم مُنقح بايثون بيئة تفاعلية تستطيع الاستفادة منها في تنقيح أي برنامج بايثون. الأوامر المتاحة خلال المنقح تتيح لك وقف البرنامج الخاص بك، والاطلاع على قيم متغيراته خلال التنفيذ وتعديلها إذا رغبت، وكذلك التحكم في مسارات التنفيذ وغيره من الخصائص التي تساعدك في فهم ما يقوم به برنامجك بشكل كامل ولكي تضع يدك على المشاكل والقضايا التي تظهر خلال التنفيذ. ترجمة – بتصرّف – للمقال How To Use the Python Debugger لصاحبته Lisa Tagliaferri.