اذهب إلى المحتوى

لوحة المتصدرين

  1. سامح أشرف

    سامح أشرف

    الأعضاء


    • نقاط

      5

    • المساهمات

      2934


  2. Emad Saif

    Emad Saif

    الأعضاء


    • نقاط

      3

    • المساهمات

      205


  3. محمود خليل5

    محمود خليل5

    الأعضاء


    • نقاط

      2

    • المساهمات

      13


  4. ابراهيم الخضور

    • نقاط

      2

    • المساهمات

      164


المحتوى الأكثر حصولًا على سمعة جيدة

المحتوى الأعلى تقييمًا في 04/07/22 في كل الموقع

  1. لدي نص يتم الحصول عليه من حقل إدخال ، وأقوم بتحويل هذا النص إلى مصفوفة من الأرقام عبر تقسيمه من خلال فاصلة , comma: <?php $ages = "15,12,24"; $all_ages = explode(',', $ages); var_dump($all_ages); لكن المشكلة أني أحصل على مصفوفة من النصوص strings وليس مصفوفة من الأرقام: array(3) { [0]=> string(2) "15" [1]=> string(2) "12" [2]=> string(2) "24" } كيف أقوم تحويل هذه المصفوفة إلى مصفوفة من الأرقام integers في PHP؟
    2 نقاط
  2. كتابة برنامج يطبع العبارة "مرحبا بالعالم!‎" وتنفيذه هو أحد التقاليد الأساسية في مجال البرمجة، ويشكل أول برنامج بسيط وكامل للمبتدئين، وكذلك يُعدُّ اختبارًا لأنظمة وبيئات البرمجة، كما يعطي البرنامج فكرة عن الصياغة الأساسية للغات البرمجة. ستتعلم في هذه المقالة كيفية كتابة برنامج "مرحبا بالعالم!" في بايثون 3. المتطلبات الأساسية يجب أن يكون لديك بايثون 3 مثبتًا، بالإضافة إلى إعداد بيئة برمجة محلية على حاسوبك. إن لم تكن قد ثبَّت بايثون وأعددت البيئة البرمجة، فعد إلى الدرس السابق واتبع الخطوات اللازمة لإنجاز ذلك قبل إكمال هذا الدرس. مرحلة كتابة البرنامج لكتابة البرنامج "مرحبا بالعالم!‎"، سننشئ ملفًا جديدًا باسم hello.py، ثم نفتحه بمحرر نصوص لسطر الأوامر، (مثل nano الموجود على أنظمة لينكس): nano hello.py إن لم يكن لديك المُحرِّر nano، فأنشئ الملف hello.py وافتحه باستعمال أي محرِّر موجود على نظام التشغيل لديك (مثل المفكرة على أنظمة ويندوز). بمجرد فتح الملف النصي في نافذة الطرفية (أو محرِّر النصوص)، سنقوم بكتابة برنامجنا فيه وذلك بكتابة التعليمة البرمجية التالية: print("مرحبا بالعالم!‎") دعنا نشرّح هذه التعليمة. print()‎ هي دالة (function) تخبر الحاسوب بتنفيذ إجراء ما. نعرف أنَّها دالة لأنها تستخدم الأقواس. تطلب print()‎ من بايثون أن يعرض أو يخرج ما نضعه بين القوسين. بشكل افتراضي، ستُعرَض المُخرجات في نافذة الطرفية عند تنفيذ البرنامج. بعض الدوال، مثل print()‎، هي دوال مُدمجة (built-in) في بايثون بشكل افتراضي. هذه الدوال المدمجة متوفرة لنا دائمًا لاستخدامها في برامجنا. يمكننا أيضًا تعريف دوالنا الخاصة وبناءها من عناصر أخرى. داخل قوسي الدالة print()‎ توجد سلسلة من الأحرف - مرحبا بالعالم!‎‎ - محاطة بعلامتي اقتباس. وهذه الأحرف الموضوعة بين علامات الاقتباس تُسمى سلاسل نصية (strings) وهي أحد أنواع البيانات التي سنتعرف عليها لاحقًا. بعد الانتهاء من كتابة البرنامج، يمكنك الخروج من nano عن طريق الضغط على ctrl+x، وعندما يُطلب منك حفظ الملف، اضغط على y. بعد الخروج من المُحرِّر nano، ستعود إلى نافذة الطرفية. دورة تطوير التطبيقات باستخدام لغة Python احترف تطوير التطبيقات مع أكاديمية حسوب والتحق بسوق العمل فور انتهائك من الدورة اشترك الآن مرحلة تنفيذ البرنامج بعد الانتهاء من كتابة برنامج "مرحبا بالعالم!‎"، فنحن جاهزون لتنفيذه. سنستخدم الأمر python3 معقوبًا باسم ملف البرنامج: python3 hello.py سيعرض برنامج hello.py الذي أنشأته للتو المخرجات التالية على نافدة الطرفية: مرحبا بالعالم!‎ دعني أشرح لك ما فعله البرنامج بمزيد من التفصيل. في الشيفرة البرمجية، مررنا السلسلة النصية مرحبا بالعالم!‎‎ إلى الدالة print()‎ التي وظيفتها طباعة ما يُمرَّر إليها على مجرى الخرج (نافذة الطرفية في حالتنا هذه). في هذا المثال، السلسلة النصية مرحبا بالعالم!‎‎ تُسمى أيضًا وسيطًا (argument)، نظرًا لأنها قيمة مُمرّرة إلى دالة. علامتا الاقتباس اللتان تحيطان بالسلسلة النصية مرحبا بالعالم!‎‎ لن تُطبعا على الشاشة لأنهما تُستخدمان لإعلام بايثون بأنّهما تحتويان على سلسلة نصية. تُحدِّد علامتا الاقتباس مُبتدأ السلسلة النصية ومنتهاها. بعد تنفيذ البرنامج، يمكنك الآن التأكد من أنّك نجحت في تثبيت بايثون 3، وأنّ البرنامج مكتوب ومُصَاغ صياغةً صحيحة. الخلاصة تهانينا! لقد أتممت كتابة أول برنامج لك، برنامج "مرحبا بالعالم!‎"، في بايثون 3. من الآن وصاعدًا، يمكنك استخدام الدالة print()‎ لعرض أية عبارات نصية أو قيم أخرى، ويمكنك أيضًا إنشاء ملفات برامج جديدة وتنفيذها بالطريقة ذاتها. لتعلم المزيد حول لغة بايثون، ننصحك بمتابعة سلسلة مقالات عن كيفية البرمجة في بايثون 3، والتي تأخذك خطوةً بخطوة لتعلم كيفية تثبيت بايثون وإعداد بيئة البرمجة، إضافةً إلى المفاهيم الأساسيات للغة، وأنواع البيانات والدوال والأصناف والبرمجة الكائنية وغيرها من المفاهيم؛ كما وفرنا دورةً تعليمية شاملةً حول تعلم التطوير واحترافه عن طريق لغة بايثون، وذلك انطلاقًا من الصفر إلى الاحتراف، وهذا في دورة تطوير تطبيقات باستخدام لغة بايثون، التي تمكّنك من تعلّم التطوير بلغة بايثون للتطبيقات ولمواقع الويب بالاعتماد على النظريات السليمة والتطبيق العملي والدعم المباشر. ترجمة -وبتصرّف- للمقال How To Write Your First Python 3 Program لصاحبته Lisa Tagliaferri اقرأ أيضًا المقالة اللاحقة: كيفية استخدام سطر أوامر بايثون التفاعلي المقالة السابقة: كيفية تثبيت بايثون 3 وإعداد بيئتها البرمجية المرجع الشامل إلى تعلم لغة بايثون تعرف على أبرز مميزات لغة بايثون كتاب البرمجة بلغة بايثون
    1 نقطة
  3. تعد بايثون Python واحدة من أشهر لغات البرمجة وأكثرها استخدامًا، وهي لغة ممتازة ليبدأ بها المبرمجون الجدد. يمكن استخدامها في كل المجالات، بدءًا من ألعاب الفيديو ومعالجة اللغات، وصولًا لتحليل البيانات والتعلم الآلي. بايثون هي لغة برمجة عالية المستوى، ومُفسرة interpreted وتفاعلية وكائنية، وتتمتع بمقروئية عالية، إذ تستخدم كلمات إنجليزية بسيطة، على خلاف اللغات الأخرى التي تستخدم الرموز، كما أنّ قواعدها الإملائية والصياغية بسيطة ومفهومة، ما يجعل تعلم لغة بايثون سهلًا مقارنةً بلغات برمجة أخرى. هذا المقال هو دليلك الشامل إلى التعرف على كل ما يخص لغة بايثون وكيفية تعلمها بأقصر السبل. جدول المحتويات حرصًا على تنظيم المقالة ولتسهيل الوصول إلى القسم الذي تريده بسهولة، سنذكر هنا جدول المحتويات باختصار: تاريخ بايثون مميزات لغة بايثون تطبيقات ومجالات استخدام لغة بايثون لماذا بايثون؟ أهمية تعلم لغة بايثون كيفية تعلم لغة بايثون نصائح لتعلم لغة بايثون تاريخ بايثون ظهرت لغة بايثون في أواخر الثمانينيات على يد المبرمج الهولندي جايدو فان روسم Guido van Rossum، وقد عُدَّت خليفة للغة ABC. كما استفادت من الكثير من اللغات السابقة لها، مثل Modula-3 و C و C++‎ و Algol-68 و SmallTalk، وغيرها من اللغات وأحدثت ثورة في عالم البرمجة لسهولتها وتعدد استخداماتها. نُشِر الإصدار 2.0 من لغة بايثون عام 2000، وقدّم العديد من الميزات الجديدة التي سهلت كتابة الكود على المبرمجين، مثل القوائم الفهمية List Comprehensions، ونظام كنس المُهملات garbage collection إلا أن هناك بعض العيوب التصميمية وأوجه القصور التي لم تتمكن سلسلة إصدارات ‎2.x‎ من تداركها. أطلق بعدها الإصدار 3.0 من لغة بايثون المعروف أيضًا باسم Python 3000 أو Py3k في عام 2008، والذي شكّل طفرة في اللغة وصحح العديد من عيوبها، لكنه لم يكن متوافقًا تمامًا مع الإصدارات السابقة)، ولهذا السبب قرر فريق التطوير الاستمرار ودعم إصدار أخير من سلسلة بايثون ‎2.x‎، وهو بايثون 2.7 لغاية عام 2020 وبعدها توقف الدعم ولم يعد الإصدار يتلقى أي تحديثات أو ميزات جديدة. النسخة الحالية من بايثون هي Python 3.11 وقد صدرت في السادس من ديسمبر/كانون الأول عام 2022، وتضمنت عدة تحسينات أبرزها تحسين سرعة التنفيذ، وتحسين رسائل الخطأ لتساعد المبرمج على تحديد الموقع الدقيق للخطأ ضمن البرنامج والعمل على تصحيحه بسرعة أكبر. مميزات لغة بايثون تتميز بايثون بعدة أمور عن غيرها من لغات البرمجة، من أبرزها: سهولة التعلم: يسهل تعلم لغة بايثون، إذ تتألف من عدد قليل من الكلمات المفتاحية، وتتميز بصياغة بسيطة وواضحة. المقروئية: شيفرة لغة بايثون واضحة ومنظمة وسهلة القراءة وتحاكي اللغة الطبيعية. سهولة الصيانة: شيفرة بايثون سهلة الصيانة إلى حد بعيد. مفتوحة المصدر حيث يمكن لأي شخص الاطلاع على شيفرة بايثون وإضافة تعديلات و ميزات جديدة عليها أو تطوير مكتبات تلبي مختلف المتطلبات. مكتبة قياسية واسعة: تحتوي مكتبة بايثون القياسية على عدد كبير من الحزم المحمولة التي تتوافق مع الأنظمة الشبيهة بيونكس و Windows و macOS. الوضع التفاعلي: تدعم بايثون الوضع التفاعلي، مما يتيح إمكانية تنفيذ الشيفرات مباشرةً على سطر الأوامر وتنقيح هذه الشيفرات بسهولة. محمولية بايثون: يمكن تشغيل لغة بايثون على طيف واسع من المنصات والأجهزة، مع الاحتفاظ بنفس الواجهة على جميع تلك المنصات. التوسعية: من أهم مميزات بايثون هو توفرها على عدد هائل من الوحدات والمكتبات، التي يمكنها توسيع قدرات اللغة في كل المجالات. دعم البرمجة الكائنية OOP: وهذا يمكن المبرمجين من كتابة تعليمات برمجية قابلة لإعادة الاستخدام ويسرع وتيرة عملهم. قواعد البيانات: توفر بايثون واجهات لجميع قواعد البيانات الأساسية. الرسوميات: تدعم بايثون التطبيقات الرسومية. دعم البرامج الكبيرة: بايثون مناسبة للبرامج الكبيرة والمعقدة. سأضرب مثالًا على الميزتين الأكثر شيوعًا بين الداخلين الجدد على المجال تعلم البرمجة وهما سهولة التعلم والمقروئية العالية بما أنهما تسهلان طريق التعلم ولتوضيح هاتين الميزتين، لذا إليك المثال البسيط التالي الذي يطبع كلمة مرحبًا على الشاشة: print('مرحبًا') لاحظ كيف يبدو البرنامج بلغة بايثون في حين يكون البرنامج نفسه الذي يقوم بطباعة هذه الكلمة بلغة أخرى مثل C كما يلي: #include <stdio.h> int main() { printf("مرحبًا"); return 0; } كما تلاحظ التعليمة في لغة بايثون واضحة ومباشرة في حين تتضمن لغة C كلمات ورموزًا غريبة وصعبة الفهم على المبتدئين مثل ‎#include‎ ووجود حرف f ملحقًا بكلمة print التي تعني "اطبع". رغم بساطة هذا المثال إلا أنه يعطيك فكرة عن مدى البساطة في كتابة شيفرات لغة بايثون ما يجعلها لغة مثالية للأشخاص الذين يبدأون للتو في تعلم البرمجة، وستدرك الفرق في سرعة كتابة الأكواد وسهولة الصيانة واكتشاف وتصحيح الخطأ بشكل أوضح عند كتابة برامج أكثر تعقيدًا. دورة تطوير التطبيقات باستخدام لغة Python احترف تطوير التطبيقات مع أكاديمية حسوب والتحق بسوق العمل فور انتهائك من الدورة اشترك الآن تطبيقات ومجالات استخدام لغة بايثون تُستخدم لغة بايثون في شتى المجالات، فهي لغة برمجة متعددة الأغراض General Purpose ولها عدة تطبيقات لا يتسع المقال لذكرها لذا سنكتفي هنا بذكر أبرز مجالات استخدام لغة بايثون وهي: تحليل البيانات تطوير مواقع الويب واستخراج بيانات المواقع الذكاء الاصطناعي وتعلم الآلة تطوير تطبيقات سطح المكتب والألعاب برمجة العتاد واللوحات الإلكترونية دعنا نستكشف المزيد عن كل مجال من هذه المجالات ونتعرف على أهميته ومساهمة لغة بايثون فيه. 1. تحليل البيانات أصبحت لغة بايثون إحدى اللغات البارزة في مجال علم البيانات لما توفره من مكتبات متخصصة مثل NumPy و Pandas و Matplotlib التي تسهل على المبرمجين تطوير برامج لتحليل البيانات والتعلم الآلي وتمكن علماء ومحللي البيانات من معالجة هذه البيانات وإجراء الحسابات الإحصائية المعقدة عليها بل وتمثيلها بيانيًا واستخراج المعلومات منها بسرعة وكفاءة أكبر. 2. تطوير مواقع الويب واستخراج بيانات المواقع تعد لغة بايثون لغة ملائمة جدًا لتطوير مواقع الويب وبالتحديد الواجهة الخلفية لمواقع الويب، فهي لغة تعمل من طرف الخادم ويمكنها التواصل مع قواعد البيانات ومعالجة بياناتها بسهولة، كما أنها توفر العديد من أطر العمل التي تسرع وتيرة تطوير مواقع وتطبيقات ويب احترافية وآمنة من أشهرها جانغو Django و فلاسك Flask. وتوفر مكتبات تسمى مكتبات ORM توفر طرقًا مبتكرة للاستعلام عن البيانات من قاعدة بيانات ومعالجتها باستخدام نموذج موجه للكائنات Object-relational mapping مثل SQLAlchemy و Django ORM وهي أسهل وأسرع من كتابة استعلامات بلغة SQL التقليدية. كما تلبي لغة بايثون طلبك إن كنت مهتمًا بموضوع استخراج البيانات من صفحات الويب أو المتاجر الإلكترونية المختلفة بهدف دراستها والبحث ضمنها ومقارنة الأسعار فيما بينها، فهي قادرة على استخراج البيانات تلقائيًا من المواقع Web Scraping بسرعة وتنسيقها بطريقة منظمة، وتمثيلها رسوميًا من خلال كتابة أكواد مختصرة ومباشرة بفضل مكتباتها المتنوعة التي توفر كافة الوظائف الضرورية للقيام بذلك وأبرزها Beautiful Soup و Scrapy و Selenium. احصل على موقع إلكتروني مخصص لأعمالك أبهر زوارك بموقع احترافي ومميز بالاستعانة بأفضل خدمات تطوير وتحسين المواقع على خمسات أنشئ موقعك الآن 3. الذكاء الاصطناعي وتعلم الآلة لم يعد الذكاء الاصطناعي وتعلم الآلة مصطلحات غريبة في عصرنا الحالي بل أصبحت من المواضيع الرائجة والمطبقة بكثرة، وهنا أيضًا تبرز لغة بايثون كلغة ملائمة بشكل مثالي لتطبيق مفاهيم الذكاء الاصطناعي وجعل الحواسيب والأجهزة التي نتعامل معها في حياتنا اليومية ذكية وقادرة على التعلم بنفسها ومساعدتنا في اتخاذ القرارات، ومن أشهر المكتبات التي توفرها بايثون في مجال الذكاء الاصطناعي نذكر NumPy و Pandas و Scikit-Learn ...إلخ. دورة الذكاء الاصطناعي احترف برمجة الذكاء الاصطناعي AI وتحليل البيانات وتعلم كافة المعلومات التي تحتاجها لبناء نماذج ذكاء اصطناعي متخصصة. اشترك الآن 4. تطوير تطبيقات سطح المكتب والألعاب. تستخدم لغة بايثون بشكل كبير لتطوير وبرمجة تطبيقات سطح المكتب ذات الواجهات الرسومية GUI سواء التطبيقات البسيطة كالآلة الحاسبة أو تطبيقات تشغيل الوسائط أو التطبيقات الأكثر تعقيدًا من خلال توفير مجموعة مكتبات قوية ومليئة بأدوات واجهة المستخدم مثل Tkinter و wxPython و PyQt التي تسهل على المبرمج تخطيط وإنشاء تطبيقات سطح مكتب متوافقة مع مختلف أنظمة التشغيل. كما تعتبر بايثون ملائمة بشكل مثالي لتطوير الألعاب فهي توفر العديد من المكتبات وأطر العمل المساعدة مثل PyGame و Pyglet و PyKyra و PyOpenGL و Panda3D ...إلخ. التي تجعل من إنشاء الألعاب التفاعلية أسهل بكثير من استخدام لغات برمجة أخرى. 5. برمجة العتاد واللوحات الإلكترونية إذا كنت مهتمًا ببرمجة العتاد واللوحات الإلكترونية وبرمجة التطبيقات المضمنة Embedded Product وانترنت الأشياء فيمكنك البدء باستخدام شريحة راسبيري باي Raspberry Pi التي تعتبر حاسوبًا أوليًّا يعمل بنظام لينكس Linux ويستخدم لغة بايثون بشكل ضمني ليمكن المبرمجين والمتعلمين من تطوير مشاريع عملية رائعة مثل ساعة ذكية تعرض الوقت أو بوت للرد الآلي أو تطبيق بث مباشر على يوتيوب أو تطبيق للتحكم بالكاميرا وجعلها تلتقط الصور وتسجل مقاطع الفيديو ...إلخ. بكل سهولة. هذه كانت بعض المجالات البارزة التي تستخدم فيها لغة بايثون، إضافة إلى الكثير من المجالات الأخرى التي لا يسعنا حصرها هنا. لماذا بايثون؟ إنّ تحديد أفضل لغة برمجة للتعلم قد يكون مهمة صعبة ولو سألت عدة أشخاص عن لغة البرمجة التي يجب تعلمها، فستحصل على عدة إجابات، ويكفي أن تدخل على جوجل وتكتب أفضل لغة برمجة، وستجد آراءً مختلفةً، وجدالًا لا ينتهي حول هذا الموضوع. لا أريد أن أبدأ حرب لغات البرمجة هنا، ولكنني سأحاول في هذه الفقرة تقديم بعض الحجج لتبرير لماذا أرى أنّ بايثون هي لغة المستقبل، وأن تعلم لغة بايثون مثالي للمبتدئين الذين يريدون دخول عالم البرمجة وعلوم الحاسوب. شعبية لغة بايثون بحسب استطلاع موقع stackoverflow، تحتل لغة بايثون المرتبة الرابعة في لغات البرمجة الأكثر استخدامًا من قبل المبرمجين والمطورين حول العالم بعد JavaScript و HTML/CSS و SQL، متفوقة على لغات مثل جافا و ++C و C#‎‏‎‏‎‎‎‎، كما أنها سادس أكثر لغة برمجة مرغوبة من قبل المبرمجين. فبايثون ليست لغة قوية وفعالة فحسب، بل هي فوق ذلك محبوبة من قبل المبرمجين، ولا عجب في ذلك فهي سهلة ومرنة وتوفر مكتبات هائلة للمبرمجين تسهل عليهم الكثير من الجهود في كتابة الكود، فهل لا يزال لديك شك في أن تعلم لغة بايثون هو خيار مثالي لك؟! يوضح المخطط التالي إحصائية أجرتها منصة StackOverlow عام 2022 عن أكثر لغة شعبية مفضلة في أوساط المبرمجين وموضع لغة بايثون فيها: كما يوضح المخطط التالي إحصائية أخرى أجرتها منصة StackOverlfow أيضًا عام 2022 عما إذا كانت لغة البرمجة محبوبة (الأزرق) أم مخفية (البنفسجي) وللغة بايثون نصيب جيد من المحبوبية: دعم لغة بايثون نظرًا لشعبيتها الكبيرة، تتمتع بايثون بدعم جيد على جميع المستويات تقريبًا. وباعتبارها اللغة المفضلة للمبتدئين، فهناك مجتمع داعم كبير ومتعاون وكم هائل من المراجع والمواد والدورات التعليمية التي تشرح مفاهيم البرمجة الأساسية، إضافة إلى صياغة اللغة وتطبيقاتها. فسواء كنت هاويًا، وتحب تعلم البرمجة كهواية، أو لأجل استخدامها في مجال عملك، مثل تحليل البيانات ومعالجة اللغات الطبيعية وغير ذلك، أو كنت تريد أن تعمل كمستقل، أو تدخل سوق العمل وتحقق دخلًا من البرمجة، ففي جميع هذه الحالات، سيكون تعلم لغة بايثون خيارًا مثاليًا لك. بايثون مطلوبة في السوق تُستخدم لغة بايثون من قبل بعض أكبر الشركات في مجال التكنولوجيا، مثل Uber و PayPal و Google و Facebook و Instagram و Netflix و Dropbox و Reddit. إضافةً إلى هذا، تُستخدم بايثون بكثافة في مجال الذكاء الاصطناعي والتعلم الآلي وتحليل البيانات ومراقبة الأنظمة وغير ذلك. يقدر موقع stackoverflow، الدخل السنوي لمطوري بايثون بحوالي 71 ألف دولار، وبالرغم من أن الاستبيان الذي أجراه الموقع مبني على مشاركين معظمهم من الولايات المتحدة والهند وألمانيا ولا يعكس الرواتب في منطقتنا العربية إلا أن الرقم كبير بالمقارنة مع باقي المهن، ويدل على أهمية هذه اللغة وأجرها المرتفع في سوق العمل. ولا ننسى أن لغة بايثون كما أشرنا لغة عامة الأغراض وقادرة على إيجاد الحلول الفعالة في العديد من المجالات المختلفة وهذا من شأنه بكل تأكيد حث أرباب العمل على توظيف مطوري بايثون والاستفادة من مهاراتهم وخبراتهم في عدة مجالات. أهمية تعلم لغة بايثون قد تمكنت لغة بايثون طيلة هذه السنوات من لحظة انطلاقها إلى اليوم من إثبات إمكانياتها لتعد واحدة من أهم لغات البرمجة وأكثرها شعبية وجدارة كما أشرنا، ويبرز اسمها بين أوساط المبرمجين والمطورين والطلاب على حد سواء كما أن مختلف الجامعات بدأت بتدريسها في الفصول الأولى للطلاب وتراها المخيمات والدورات البرمجة خيارها الأول لتعليم البرمجة لغير المختصين. أضف إلى ذلك أن لغة بايثون نالت ثقة الكثير من المواقع والشركات العملاقة واليوم تستخدمها كل من شركات Spotify و Google و Amazon بشكل أساسي إضافة إلى Facebook التي تستخدم بايثون لمعالجة الصور وإدارة بنيتها التحتية، وفي كل يوم تتحول شركات جديدة معروفة عالميًا إلى استخدام بايثون مثل YouTube و DropBox و Instagram التي قررت كذلك استخدامها وفضلتها على PHP. كما تُستخدم لغة بايثون أيضًا من قبل بعض الجهات العلمية والبحثية، مثل وكالة الفضاء الأمريكية ناسا، والتي لها مستودع خاص بالمشاريع المُطورة ببايثون كما أنها تقدم دورات تدريبية لتعليم لغة بايثون من الصفر للاحتراف لعلمائها ومهندسيها ليتمكنوا من معالجة بياناتهم بشكل أفضل وأسرع. كيفية تعلم لغة بايثون تعرفت إلى الآن على بايثون وأهميتها ومميزاتها واستخدامات لغة بايثون المختلفة وفرص العمل فيها، واقتنعت بأهمية تعلم لغة بايثون لذا قد تتساءل من أين تبدأ؟ سأجيبك في هذا القسم بالتفصيل. هنالك مساران لتعلم البرمجة عمومًا وتعلم لغة بايثون خصوصًا، إما في أروقة الجامعة أو عبر دورات متخصصة، أما في مسار الجامعة فستتكفل بوضع خطة تعلم عبر فصولها وسنواتها وفي كل الأحوال قد تلجأ إلى الدورات حتى لو دخلت الجامعة بسبب الكم النظري الكبير الذي تعطيه الجامعة غافلة الجانب العملي التطبيقي أو بسبب نسيان اللغة وعدم البرمجة فيها إن جرى تدريسها في السنوات الأولى وهنا تجد نفسك تبحث عن دورات برمجة متخصصة. سأختصر عليك الطريق وأشير إلى أفضل دورة برمجة متخصصة لتعلم لغة بايثون وهي دورة تطوير التطبيقات بلغة بايثون من أكاديمية حسوب وهي دورة منهجية شاملة بعدد ساعات يزيد عن 60 معدة من قبل مبرمجين أكفاء تأخذ بيدك خطوة بخطوة لتعلم لغة بايثون من الصفر وحتى الاحتراف وتبني خلالها الكثير من التطبيقات العملية، وهي كفيلة بأن تؤهلك لبدء حياتك المهنية كمطور بايثون ودخول سوق العمل والحصول على أول وظيفة خلال ستة أشهر. وإن كنت ممن يفضلون التعلم من خلال الكتب الإلكترونية لما توفره من شمولية وتنظيم في المعلومات، فيمكنك تنزيل كتاب البرمجة بلغة باثيون من أكاديمية حسوب. هل تريد المزيد من المصادر؟ ما رأيك بزيارة موسوعة حسوب الشاملة التي تضم توثيقات الكثير من لغات البرمجة، بما في ذلك توثيق لغة بايثون. ننصحك أيضًا بالاطلاع على قسم دروس ومقالات متنوعة حول لغة بايثون وهذه الدروس تُحدَّث باستمرار لذا كن على اطلاع دائم عليها لتواكب كل جديد وإن كنت مهتمًا بتعلم لغات برمجة أخرى، فيمكنك زيارة قسم البرمجة في الأكاديمية. وإن أشكل عليك شيء ما فيمكنك أن تسأل عنه في قسم الأسئلة والأجوبة الخاص بالأكاديمية ليجيبك عنه أحد المبرمجين أو تطرحه للنقاش مع المهتمين في مجتمع حسوب IO. نصائح لتعلم لغة بايثون أخيرًا وليس آخرًا، إليك أهم النصائح التي عليك اتباعها لتعلم لغة بايثون من الصفر حتى الاحتراف. 1. حدد المجال الذي تريد التخصص فيه مجالات العمل في بايثون متنوعة وتحديد المجال أو المسار الوظيفي الذي تنوي التخصص فيه سيمكنك من تحديد المفاهيم والمهارات الفنية التي يتوجب عليك تعلمها والتركيز عليها دون سواها، وضع خطة زمنية لإتقان جميع المهارات اللازمة لتحقيق هدفك والتزم بها قدر المستطاع. فإذا كان هدفك من تعلم بايثون هو إنشاء مواقع ويب ضع في خطتك تعلم Django أو Flask، وإذا كان هدفك هو تطوير الألعاب فضع في خطتك التعرف على إحدى المكتبات القوية في تطوير الألعاب مثل Pyglet أو Panda3D أو Pygame ...إلخ. 2. تعلم أساسيات لغة بايثون أيًا كان المجال الذي حددته في الخطوة السابقة فلا بد لك في البداية من تعلم أساسيات لغة البايثون التي تمثل أساسًا لأي لغة برمجة والتي تشمل: طريقة تثبيت لغة بايثون على جهازك وإنشاء بيئة افتراضية. صياغة الجمل والعبارات في بايثون تعريف المتغيرات وأنواع البيانات الأولية. العمليات الحسابية والمنطقية الأساسية. عمليات الإدخال والإخراج ومفهوم الاستثناءات وطرق معالجتها. الدوال البرمجية وطريقة تعريفها واستدعائها. هياكل البيانات المركبة مثل القوائم والمجموعات والقواميس تعليمات التحكم بتدفق البرنامج مثل التعليمات الشرطية والحلقات التكرارية. مفاهيم البرمجة كائنية التوجه أهم المكتبات القياسية التي تستخدم في العديد من المشاريع. طرق التعامل مع الملفات. الخبر الجيد هنا أن تعلم هذه الأساسيات لن يستغرق منك الكثير من الوقت لأن بايثون كما أشرنا لغة سلسة وبسيطة وسهلة التعلم. 3. تعلم المواضيع المتقدمة التي تخدم أهدافك بعد إتقان المفاهيم الأساسية عليك الانتقال خطوة للأمام والتعرف على مواضيع متقدمة تتعلق بشكل مباشر بالتخصص الذي تنوي العمل به والمسار هنا يختلف حسب التخصص الذي اخترته لنفسك والبدء بإتقان جميع المهارات اللازمة لتحقيق هدفك. يمكنك في هذه المرحلة على سبيل المثال التعرف على مفاهيم مثل قواعد البيانات والتعامل معها، وتعلم مكتبات بايثون والتدريب على استخدامها من خلال تطبيقها في برامج عملية بالطبع ستتطلب المشاريع المختلفة مكتبات مختلفة لذا من المهم التعرف على المكتبات الأكثر شيوعًا في مجالك والتركيز عليها. كما ستحتاج لتعلم أحد أطر عمل بايثون Python Frameworks التي تساعدك على تطوير مشاريعك وكما ذكرنا بالنسبة للمكتبات ستعتمد الأطر التي عليك تعلمها على التخصص الذي تنوع العمل به. 4. عزز ما تعلمته في مشاريع عملية يفترض الآن أنك تملك كافة المهارات اللازمة والأسس النظرية، لكن المعرفة التقنية وحدها لا تكفي لذا حان الوقت لبدء التدرب على تطوير مشاريع لصقل كل هذه المهارات. لذلك من الضروري أن تتدرب على تطوير مجموعة من المشاريع في مجال تخصصك وتبني معرض أعمال يظهر هذه المهارات فهذا يعزز فرصتك للحصول على وظائف فعلية وبدء حياتك المهنية كمطور بايثون. يمكنك ريثما تحصل على فرصة عمل مناسبة أن تعمل بشكل مستقل على مواقع العمل الحر مثل مستقل وخمسات وتنجز المشاريع للعملاء عبر هذه المنصات. 5. لا تهمل مهاراتك الناعمة لاشك أن المهارات الفنية ومعرض الأعمال القوي أمر ضروري لأي مبرمج لكن هناك نوعًا آخر من المهارات الضرورية لأي مبرمج والتي يفضل أصحاب العمل توفرها لدى المطورين والمبرمجين وأهمها: مهارات حل المشكلات والتفكير المنطقي الرغبة في التعلم المستمر والاطلاع على كل جديد في مجالك. مهارات التواصل الفعال والعمل الجماعي خاتمة تعرفنا في مقال اليوم على لغة بايثون ورأينا كيف أنها تجمع بين البساطة والسهولة من جهة وبين القوة والفعالية من جهة أخرى، وتعرفنا على أهم مميزات بايثون ومستقبلها الواعد الذي يفتح لمتعلمها الكثير من الفرص والآفاق. وختمنا المقال بأهم الخطوات والنصائح لتتعلم بايثون بسرعة واحترافية. هل أنت متحمس لتعلم بايثون أو بدأت فعلًا بتعلمها ولديك أي استفسار حول أي من المواضيع التي ذكرناها في المقال؟ اكتبها في قسم التعليقات أسفل المقال وسنحرص على الإجابة عليها بأقرب فرصة. وفّقك الله تعالى.
    1 نقطة
  4. بعد أن أخذت فكرة عامة عن لغة البرمجة بايثون وتعرف على تاريخها والفرق بين أهم إصدارين لها، الإصدار 2 و الإصدار 3 في الدرس السابق، ستتعلم في هذا الدرس كيفية تثبيت بايثون على نظام تشغيلك وإعداد البيئة البرمجية اللازمة لكتابة البرامج وتنفيذها خلال رحلتك التعليمية هذه. فهرس هذا الدرس -لسهولة الانتقال إلى نظام التشغيل الذي تريده- هو: كيفية تثبيت بايثون 3 وإعداد بيئة برمجية على أوبنتو 16.04 كيفية تثبيت بايثون 3 وإعداد بيئة برمجية على أوبنتو 18.04 كيفية تثبيت بايثون 3 وإعداد بيئة برمجية على ديبيان 8 كيفية تثبيت بايثون 3 وإعداد بيئته البرمجية على CentOS 7 كيفية تثبيت بايثون 3 وإعداد بيئته البرمجية على macOS كيفية تثبيت بايثون 3 وإعداد بيئته البرمجية على ويندوز 10 الأمور التي سنسلط الضوء عليها هي: تثبيت بايثون 3 على نظام تشغيلك ثم إعداد بيئته البرمجية. تتمثل عملية تهيئة البيئة البرمجية بإعداد بيئة وهمية تمكِّنك من إنشاء مساحة معزولة في حاسوبك مخصصة لمشاريع بايثون، مما يعني أنَّ كل مشروع تعمل عليه يملك مجموعة من الاعتماديات (dependencies) والتي لن تؤثِّر على غيرها من المشاريع. يوفِّر لنا ضبط بيئةٍ برمجيةٍ تحكمًا أكبر بمشاريع بايثون وإمكانية التعامل مع إصداراتٍ مختلفةٍ من حزم بايثون وهذا مهمٌ كثيرًا عندما تتعامل مع الحزم الخارجية. بعد تثبيت بايثون وإكمال إعداد البيئة الوهمية، سنعلمك كيفية إنشاء برنامجٍ بسيطٍ يعرض العبارة «Hello World!‎» (أهلًا بالعالم!) الشهيرة، وبهذا سنتحقق من عمل البيئة عملًا صحيحًا، وستصبح آنذاك طريقة إنشاء برامج بايثون وتنفيذها مألوفةً لديك مما يمهد الطريق لكتابة وتنفيذ مشاريع بايثون اللاحقة. اختر مما يلي الدرس الخاص بنظام تشغيل حاسوبك (حاولنا شمل أشهر أنظمة التشغيل، لينكس وويندوز وماك) وانتقل إليه لاتباع الخطوات اللازمة لتنفيذ ما سبق. كيفية تثبيت بايثون 3 وإعداد بيئة برمجية في أوبنتو 16.04 أوبنتو هي إحدى أشهر توزيعات نظام التشغيل لينكس. تأتي أنظمة لينكس غالبًا محملةً بنسخة بايثون مثبتة وجاهزة للعمل. مع ذلك، لا يكون الإصدار المُثبَّت مطابق للإصدار الذي نريده في بعض الأحيان. سيأخذ هذا الدرس بيدك لتعليمك كيفية تثبيت الإصدار 3 من بايثون على أوبنتو 16.04 مع ضبط بيئته البرمجية. سيشرح لك خطوةً بخطوة عملية تثبيت بايثون 3 على جهازك المحلي وضبط البيئة البرمجية عبر سطر الأوامر. صحيح أن هذه الخطوات مخصصة للإصدار 16.04 من أوبنتو، إلا أنه يمكن الاستفادة منها في التوزيعات الأخرى المعتمدة على ديبيان. كيفية تثبيت بايثون 3 وإعداد بيئة برمجية على أوبنتو 18.04 أوبنتو هي إحدى أشهر توزيعات نظام التشغيل لينكس والذي يحوي نسخة بايثون مثبَّتةً وجاهزةً للعمل. مع ذلك، لا يكون الإصدار المُثبَّت مطابقًا للإصدار الذي نريده في بعض الأحيان. سيرشدك هذا الدرس لكيفية تثبيت الإصدار 3 من بايثون على أوبنتو 18.04 مع ضبط بيئته البرمجية. سيشرح لك خطوةً بخطوة عملية تثبيت بايثون 3 على جهازك المحلي وضبط البيئة البرمجية عبر سطر الأوامر. صحيح أن هذه الخطوات مخصصة للإصدار 18.04 من أوبنتو، إلا أنه يمكن الاستفادة منها في التوزيعات الأخرى المعتمدة على ديبيان. كيفية تثبيت بايثون 3 وإعداد بيئة برمجية على ديبيان 8 ديبيان هي إحدى أشهر توزيعات نظام التشغيل لينكس أيضًا. تكون بايثون مثبتة في معظم أنظمة التشغيل لينكس ولكن لا يكون الإصدار المُثبَّت مطابقًا للإصدار الذي نريده في بعض الأحيان. سيرشدك هذا المقال خطوةً بخطوة لتثبيت بايثون 3 على جهازك المحلي ذي نظام التشغيل ديبيان 8 وضبط البيئة البرمجية عبر سطر الأوامر. صحيح أن هذه الخطوات مخصصة للإصدار 8 من ديبيان، إلا أنه يمكن الاستفادة منها في التوزيعات الأخرى المعتمدة على ديبيان. كيفية تثبيت بايثون 3 وإعداد بيئته البرمجية على CentOS 7 CentOS هي إحدى توزيعات نظام التشغيل لينكس أيضًا. تأتي أنظمة لينكس غالبًا محملةً بنسخة بايثون مثبتة وجاهزة للعمل. مع ذلك، لا يكون الإصدار المثبت مطابق للإصدار الذي نريده. سيأخذ هذا الدرس بيدك لتعليمك كيفية تثبيت الإصدار 3 من بايثون على CentOS 7 مع ضبط بيئته البرمجية واختبارها عبر سطر الأوامر. كيفية تثبيت بايثون 3 وإعداد بيئته البرمجية على macOS إن كان نظام تشغيلك هو macOS، فهذا الدرس هو لك. ستتلعم فيه خطوةً بخطوة كيفية تثبيت بايثون 3 على macOS، وتثبيت بيئتها البرمجية عبر سطر الأوامر، ولا تقلق إن لم يكن لديك أدنى فكرة عن استعمال سطر الأوامر. بدايةً، يشرح المقال كيفية تثبيت Xcode -هي بيئة تطوير متكاملة (IDE)- ثم تثبيت وإعداد Homebrew استعدادًا لتثبيت بايثون 3. ينتقل بعدها إلى إعداد البيئة الوهمية وإنشاء وتنفيذ برنامج بسيط (أشرنا إليه في آنفًا). كيفية تثبيت بايثون 3 وإعداد بيئته البرمجية على ويندوز 10 إن كنت من مستخدمي نظام التشغيل الشهير ويندوز، فقد أتيت إلى الدرس الصحيح. سيُرشِدُك هذا الدرس خطوةً بخطوة إلى تثبيت بايثون 3 في ويندوز 10، وتهيئة بيئته البرمجية عبر سطر الأوامر. الخطوة الأولى لإنجاز ذلك هي فتح وإعداد PowerShell -برنامج من ميكروسوفت يوفر واجهة سطر الأوامر- ثم تثبيت مدير الحزم Chocolatey وذلك من أجل تثبيت بايثون 3. يُعرِّج بعدها على إعداد البيئة الوهمية وإنشاء برنامج بسيط وتنفيذه (أشرنا إليه في آنفًا). اقرأ أيضًا الدرس التالي: كيف تكتب أول برنامج لك في بايثون 3 الدرس السابق: اعتبارات عملية للاختيار ما بين بايثون 2 و بايثون 3 المرجع الشامل إلى تعلم لغة بايثون تعرف على أبرز مميزات لغة بايثون كتاب البرمجة بلغة بايثون
    1 نقطة
  5. Python هي لغةٌ سهلة القراءة للغاية ومتنوعة ومتعددة الاستخدامات، واسمها مستوحى من مجموعة كوميدية بريطانية باسم «Monty Python»، وكان أحد الأهداف الأساسية لفريق تطوير بايثون هو جعل اللغة مرحةً وسهلة الاستخدام، وإعدادها بسيطٌ، وطريقة كتابتها مباشرة وتعطيك تقريرًا مباشرًا عند حدوث أخطاء، وهي خيارٌ ممتازٌ للمبتدئين والوافدين الجدد على البرمجة. لغة بايثون هي لغة متعددة الاستعمالات، وتدعم مختلف أنماط البرمجة مثل كتابة السكربتات والبرمجة كائنية التوجه (object-oriented)، وهي مناسبةٌ للأغراض العامة، واستعمالها يتزايد في سوق العمل إذ تعتمدها منظماتٌ مثل «United Space Alliance» (شركة في مجال إرسال مركبات فضائية وتتعاقد معها ناسا) و «Industrial Light & Magic» (أستوديو للتأثيرات السينمائية وللرسوم المتحركة)، وتوفِّر بايثون قدراتٍ كثيرةٍ لمن يريد تعلم لغة برمجة جديدة. طوِّرَت اللغة في نهاية الثمانينات من القرن الماضي، ونُشِرَت أوّل مرة في عام 1991، طُوِّرَت بايثون من قِبل Guido van Rossum، وهو عضوٌ نشطٌ للغاية في المجتمع. وتعتبر بايثون على أنَّها بديلٌ عن لغة ABC، وأوّل إصدار منها كان يتضمن التعامل مع الاستثناءات (exception handling) والدوال والأصناف (classes) مع إمكانية الوراثة فيها. وعدما أُنشِئ منتدى محادثة في Usenet باسم comp.lang.python في 1994، فبدأت قاعدة مستخدمي بايثون بالنمو، مما مهّد الطريق لها لتصبح واحدة من أكثر لغات البرمجة شيوعًا وخصوصًا لتطوير البرمجيات مفتوحة المصدر. لمحة عامة قبل أن ننظر إلى إمكانيات إصدارَي بايثون 2 وبايثون 3 (مع الاختلافات البرمجية الرئيسية بينهما)، فلننظر إلى لمحة تاريخية عن الإصدارات الرئيسية الحديثة من بايثون. بايثون 2 نُشِرَ هذا الإصدار في أواخر عام 2000، وأصبحت بايثون 2 لغة برمجة شاملة مقارنةً بالإصدارات التي تسبقها وذلك بعد تطبيق اقتراح PEP ‏(Python Enhancement Proposal)، وهو مواصفةٌ (specification) تقنيةٌ التي توفِّر معلومات إلى أعضاء مجتمع بايثون أو تصف ميزاتٍ جديدة في اللغة. بالإضافة إلى ذلك، تضمنت بايثون 2 ميزاتٍ برمجية جديدة مثل «cycle-detecting garbage collector» لأتمتة عملية إدارة الذاكرة، وزيادة دعم يونيكود لتدعم اللغة جميع المحارف المعيارية …إلخ. وأثناء عملية تطوير بايثون 2 أضيفت ميزات جديدة بما في ذلك توحيد الأنواع والأصناف في بايثون في بنية هيكلية وحيدة (وذلك في إصدار 2.2 من بايثون). بايثون 3 تُعتَبر بايثون 3 هي مستقبل لغة بايثون وهي النسخة قيد التطوير من اللغة، وهذا إصدارٌ رئيسيٌ نُشِر في أواخر عام 2008 لإصلاح بعض المشاكل الجوهرية في تصميم الإصدارات السابقة من اللغة، وكان التركيز أثناء تطوير بايثون 3 هو تحسين الشيفرات التي تبنى عليها اللغة وحذف التكرارات، مما يعني أنَّ هنالك طريقة وحيدة فقط لإنجاز مهمّة معيّنة. التعديلات الأساسية التي حدثت في بايثون 3.0 تتضمن تغير العبارة print إلى دالة مُضمَّنة باللغة، وتحسين قسمة الأعداد الصحيحة، وتوفير دعم إضافي ليونيكود. في البداية، انتشرت بايثون 3 ببطء نتيجةً لعدم توافقيتها مع بايثون 2، مما يعني أنَّ على المستخدمين اختيار ما هو الإصدار الذي عليهم استخدامه. بالإضافة إلى ذلك، كانت الكثير من المكتبات البرمجية متاحةً فقط لبايثون 2، لكن بعد تقرير فريق تطوير بايثون 3 أنَّه يجب أن التخلي عن دعم بايثون 2، فبدأت عملية تحويل المكتبات إلى بايثون 3. يمكننا معرفة زيادة الاعتماد على بايثون 3 من خلال عدد الحزم البرمجية التي تدعم بايثون 3، والتي هي (في وقت كتابة هذا المقال) 339 من أصل 360 من أشهر الحزم. بايثون 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، فنحن نشير عادةً إلى إصدار بايثون 2.7 لأنَّه أكثر إصدار مستخدم؛ لكنه يُعتَبَر أنَّه إصدارٌ قديم، وسيتوقف تطويره (التطوير الحالي هو إصلاح العلل فقط) تمامًا في 2020. الاختلافات الأساسية بغض النظر أنَّ بايثون 2.7 وبايثون 3 تتشاركان في الكثير من الأشياء، لكن لا يجدر بك أن تظن أنَّهما متماثلتان ويمكن تبديل الشيفرات بينهما. وعلى الرغم من أنَّك تستطيع كتابة شيفرات جيدة وبرامج مفيدة في أيّ إصدار منهما، لكن من المهم أن تفهم أنَّ هنالك بعض الاختلافات في بنية الشيفرات وفي طريقة تفسيرها. سأعرض هنا بعض الأمثلة، لكن عليك أن تعلم أنَّك ستواجه المزيد من الاختلافات أثناء مسيرة تعلمك لبايثون. print في بايثون 2، تُعامَل print كتعبيرٍ برمجيٍ بدلًا من كونها دالة، وهذا كان يثير ارتباكًا لأنَّ الكثير من الأمور داخل بايثون تتطلب تمرير وسائط (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()‎ بشكلٍ صحيحٍ في أيّ الإصدارَين. قسمة الأعداد الصحيحة في بايثون 2، أيُّ عددٍ تكتبه دون فواصل عشرية سيُعامَل على أنَّه من النوع integer، تأتي الإشكالية عندما تحاول قسمة الأعداد الصحيحة على بعضها، فتتوقع في بعض الأحيان حصولك على عددٍ عشري (تسمى أيضًا بالأعداد ذات الفاصلة العائمة float) كما في التعبير الرياضي: 5 / 2 = 2.5 لكن الأعداد الصحيحة في بايثون 2 لن تتحول إلى أعداد عشرية عندما تتطلب العملية التي تُجرى عليها ذلك. عندما يكون العددان الموجودان على جانبَي معامل القسمة / عددين صحيحين، فإن بايثون 2 ستجري عملية القسم وستُنتِج عددًا عشريًا إلا أنها ستُعيد العدد الصحيح الأصغر أو المساوي للناتج، وهذا يعني أنَّه لو كتبتَ ‎5 / 2 فستُعيد بايثون 2.7 العدد الصحيح الأصغر أو المساوي للعدد 2.5، وهو في هذه الحالة 2: a = 5 / 2 print a 2 لإعادة عدد عشري، فيجب إضافة فواصل عشرية إلى الأرقام التي ستُجري عليها عملية القسمة كما في ‎5.0 / 2.0 لكي تحصل على النتيجة المنطقية 2.5. أما في بايثون 3، فقسمة الأعداد الصحيحة أصبحت كما نتوقع: a = 5 / 2 print a 2.5 يمكنك استخدام ‎5.0 / 2.0 لإعادة 2.5، لكن إن أردتَ تقريب ناتج القسمة فاستخدم المعامل // الموجود في بايثون 3، كالآتي: a = 5 // 2 print a 2 هذا التعديل في بايثون 3 جعل من قسمة الأعداد الصحيحة أمرًا سهلًا، لكن هذه الميزة غير متوافقة مع بايثون 2.7. دعم محارف يونيكود عندما تتعامل لغات البرمجة مع السلاسل النصية (strings، والتي هي سلسلةٌ من المحارف)، فهي تفعل ذلك بطرائق مختلفة لكي تتمكن الحواسيب من تحويل الأعداد إلى أحرف ورموز. تستعمل بايثون 2 محارف ASCII افتراضيًا، لذا عندما تكتب "Hello, Sammy!‎" فستتعامل بايثون 2 مع السلسلة النصية كمجموعة من محارف ASCII، والتي هي محدودةٌ لحوالي مئتَي محرف، أي أنَّ محارف ASCII هي طريقة غير عملية لترميز المحارف خصوصًا المحارف غير اللاتينية (كالعربية مثلًا). لاستخدام ترميز محارف يونيكود (Unicode) الذي يدعم أكثر من 128000 محرف تابع للكثير من اللغات والرموز، فعليك أن تكتب u"Hello, Sammy!‎"‎ حيث تُشير السابقة u إلى Unicode. تستعمل بايثون 3 محارف يونيكود (Unicode) افتراضيًا، مما يوفِّر عليك بعض الوقت أثناء التطوير، ويمكنك كتابة وعرض عدد أكبر بكثير من المحارف في برنامجك بسهولة. يدعم يونيكود الكثير من المحارف بما في ذلك الوجوه التعبيرية (emojis)، واستعمالها كترميز محارف افتراضي يعني أنَّ الأجهزة المحمولة ستكون مدعومةً في مشاريعك تلقائيًا. إذا كنت تحب أنَّ تكون شيفرات بايثون 3 التي تكتبها متوافقةً مع بايثون 2، فأبقِ على حرف u قبل السلاسل النصية. استمرار التطوير الفارق الرئيسي بين بايثون 3 وبايثون 2 ليس في البنية اللغوية وإنما في أنَّ إصدار بايثون 2.7 سيتوقف دعمه في 2020، وسيستمر تطوير بايثون 3 بميزاتٍ جديدة وإصلاحٍ لمزيدٍ من العلل. التطويرات الأخيرة في اللغة تتضمن تخصيصًا أبسط لإنشاء الأصناف، وطريقةً أوضح للتعامل مع المصفوفات… الاستمرار بتطوير بايثون 3 يعني أنَّ المطورين يمكن أن يعتمدوا على اللغة، وسيطمئنون أنَّ المشاكل التي قد تحدث فيها ستُحَل في فترةٍ قريبة، ويمكن أن تصبح البرامج أكثر كفاءة بإضافة المزيد من الميزات للغة. نقاط أخرى يجب أخذها بالحسبان عليك أن تضع النقاط الآتية بعين الاعتبار عندما تبدأ مشوارك كمبرمج بلغة بايثون، أو عندما تبدأ بتعلم لغة بايثون بعد تعلمك لغيرها، وهنا ننصحك بتعلمها أكاديميًا باحترافية، من خلال الانضمام إلى دورة تطوير تطبيقات باستخدام لغة بايثون المقدمة من أكاديمية حسوب. إذا كنتَ تأمل بتعلم اللغة دون أن تفكِّر بمشروعٍ معيّن، فأنصحك بالتفكير بمستقبل بايثون، فسيستمر تطوير ودعم بايثون 3 بينما سيوقف دعم بايثون 2.7 عمّا قريب. أما إذا كنتَ تُخطِّط للانضمام لفريق تطوير أحد المشاريع، فعليك أن تنظر ما هو إصدار بايثون المستخدم فيه، وكيف يؤدي اختلاف الإصدار إلى اختلاف طريقة تعاملك مع الشيفرات، وإذا ما كانت المكتبات البرمجية المستعملة في المشروع مدعومةً في مختلف الإصدارات، وما هي تفاصيل المشروع نفسه… إذا كنت تُفكّر ببدء أحد المشاريع، فيجدر بك أن تنظر ما هي المكتبات المتوفرة وما هي إصدارات بايثون المدعومة. وكما قلنا سابقًا، الإصدارات الأوليّة من بايثون 3 لها توافقية أقل مع المكتبات المبنية لبايثون 2، لكن الكثير منها قد جرى تحويله إلى بايثون 3، وسيستمر ذلك في السنوات الأربع المقبلة. الخلاصة لغة بايثون كبيرة جدًا وموثقة توثيقًا ممتازًا وسهلة التعلم، ومهما كان اختيارك (بايثون 2 أو بايثون 3) فستتمكن من العمل على المشاريع الموجودة حاليًا. صحيحٌ أنّ هنالك بعض الاختلافات المحورية، لكن ليس من الصعب الانتقال من بايثون 3 إلى بايثون 2، وستجد عادةً أنَّ بايثون 2.7 قادرة على تشغيل شيفرات بايثون 3، خصوصًا في بدايات تعلمك للغة. من المهم أن تبقي ببالك أنَّ تركيز المطورين والمجتمع أصبح منصبًّا على بايثون 3، وسيصبح هذه اللغة رائدةً في المستقبل وستلبي الاحتياجات البرمجية المطلوبة، وأنَّ دعم بايثون 2.7 سيقل مع مرور الزمن إلى أن يزول في 2020. ترجمة -وبتصرّف- للمقال Python 2 vs Python 3: Practical Considerations لصاحبته Lisa Tagliaferri اقرأ أيضًا المقالة التالية: تثبيت بايثون على مختلف أنظمة التشغيل وإعداد بيئتها البرمجية المرجع الشامل إلى تعلم لغة بايثون كتاب البرمجة بلغة بايثون مميزات لغة بايثون
    1 نقطة
  6. بدأت في رفع مشروع خاص بي مبني بإستخدام لارافيل Laravel على خادم server ولكن بعد إعداد كل الموقع وتثبيت apache .. إلخ، ظهر لي الخطأ التالي عند الدخول إلى الموقع: Error in exception handler: The stream or file "/var/www/laravel/app/storage/logs/laravel.log" could not be opened: failed to open stream: Permission denied in /var/www/laravel/bootstrap/compiled.php:8423 أعتقد أن سبب المشكلة خطأ في التصاريح بسبب عبارة "Permission denied" وحاولت تغير صلاحيات المجلد storage من خلال الأمر التالي: chmod -R 775 storage لكن مازال الخطأ موجودًا، كيف أحل هذه المشكلة،؟ هل توجد خطوات أخرى على القيام بها؟
    1 نقطة
  7. سؤال أين تستعمل المخططات التدفقية ما أعرفه أن في البرمجة تستعمل أكواد و ليس أشكال
    1 نقطة
  8. عند إتمام الدورة علوم الحاسوب و إجتياز الإمتحان هل يمكن أن أحصل على شهادة مترجمة للإسبانية
    1 نقطة
  9. حاليًا يتوفر يتوفر شهادة واحدة فقط يمكن الرجوع اليها برابط مباشر على موقع الأكاديمية، ومحتواها يكون باللغتين العربية والانكليزية فقط، يمكنك التواصل مع مركز المساعدة في حال كنت مضطرًا على ذلك وطرح استفسارك
    1 نقطة
  10. خرائط التدفق تُستخدم لعدة أمور تكوين فكرة عامة عن البرنامج , حيث تطبيق البرنامج نفسه عن طريق الاكواد يأخذ وقت كبير نسبيًا لذا نستخدم خرائط التدفق لتنظيم أفكارنا قبل البدأ بكتابة الأكواد فيُصبح الأمر أسهل عند كتابة الأكواد حيث يكون بالفعل لدينا فكرة عما نقوم بتنفيذه مناقشة البرنامج قبل التنفيذ, فكما قلنا سابقًا خرائط التدفق تعطينا فكرة عامة مما يسمح لنا بمناقشة الخوارزمية المقدمة عبر خريطة التدفق وتعديلها قبل الشروع في التنفيذ حتى يكون التعديل أسهل يسهل فهمها بغض النظر عن اللغة, فعند كتابة الشفرة البرمجية بلغة جافا مثلًا أو بايثون لا يسهل قرائتها إلا من قِبل مبرمج جافا أو بايثون, فبالتالي خريطة التدفق يمكن إعتبارها لغة مُوحدة لشرح وتوصيل فكرة البرنامج والخوارزمية بغض النظر عن لغة المبرمج
    1 نقطة
  11. يمكنك إستخدام الوسم firstof الذي يسمح لك بوضع أكثر من شرط في الكود الخاص بك من خلال : {% firstof var1 var2 var3 %} أو يمكنك إستخدام الأسطر الإفتراضية الخاصه بـ Django و هي الأكثر شيوعاً في الإٍستخدام من خلال : {% ?: exp1 exp2 exp3 %} {% ?: exp1 exp2 %} مع إستبدال exp1 - exp2 - exp3 بالشروط التي تريد وضعها في الكود الخاص بك
    1 نقطة
  12. نعم ، يمكنك إستعمال فلتر yesno لحل هذه المشكلة ، وهو بسيط جدًا {{ value|yesno:"yeah,no,maybe" }} هنا إذا كانت قيمة الـ value = true سيقوم بطباعة yeah إذا كانت قيمة value = false سيقوم بطباعة no إذا كانت قيمة value = none سيقوم بطباعة maybe كذلك يمكنك جعلها بهذه الشكل {{ value|yesno:"yeah,no" }} هنا سيتم تحويل الـ none لـ false ، يمكنك الإطلاع أكثر من خلال توثيق django على الفلتر توثيق فلتر yesno من django
    1 نقطة
  13. يمكنك كذلك أن تستعمل الدالة substr على النحو التالي: <?php // النص الأصلي $oldstr = "Hello, World!"; // نُحدد المكان الذي نريد أن نضيف فيه النص الجديد $pos = strpos($oldstr,"World"); // النص الجديد الذي نريد إضافته $str_to_insert = "My "; // نستعمل الدالة substr لتقسيم النص ونقوم بتجميلع بالشكل الذي نريده $str = substr($oldstr, 0, $pos) . $str_to_insert . substr($oldstr, $pos); echo $str; // Hello, My World! بهذا الشكل سوف تحصل على النتيجة المطلوبة، الآن يمكن تحويل الكود السابق إلى دالة ليسهل إستخدامها: <?php function insert_str($original_str, $position, $str_to_insert){ return substr($original_str, 0, $position) . $str_to_insert . substr($original_str, $position); } echo insert_str("Hello, World!", 7, "My "); // Hello, My World! توثيق الدالة substr()‎ في موسوعة حسوب أيضًا يمكنك إستعمال الدالة substr_replace للقيام بهذا الأمر بشكل بسيط على النحو التالي: <?php // النص الأصلي $oldstr = "Hello, World!"; // نُحدد المكان الذي نريد أن نضيف فيه النص الجديد $pos = strpos($oldstr,"World"); // النص الجديد الذي نريد إضافته $str_to_insert = "My "; echo substr_replace($oldstr, $str_to_insert, $pos, 0); // Hello, My World!
    1 نقطة
  14. يمكنك الاستعانة بالوظيفة substr_replace لإستبدال سلسلة نصية معينة ضمن سلسلة أخرى نحددها لها، سنحتاج في هذا التلاعب ببعض الوظائف الأخرى. فيما يلي بعض الخطوات الوصفية: تخزين السلسة النصية الأصلية في متغير. تخزين السلسلة النصية الفرعية في متغير. تخزين الموضع الابتدائي للسلسلة النصية الفرعية. حساب طول السلسلة النصية الفرعية. يعطينا هذا فكرة عن احداثي هاته السلسلة في السلسلة الأم. مثال: تقع World ما بين الموضعين 7 و (موضعها الابتدائي + طولها). نسمي الموضع الأول أ والثاني ب. استبدال ما بين الموضعين أ و ب بالسلسلة النصية المرادة. مثال عملي: <?php // تعريف سلسلة نصية $str = "Hello, World!"; // تعريف السلسلة النصية الفرعية $word = "World"; // تخزين الموضع الابتدائي السلسة النصية الفرعية $pos = strpos($str, $word); // pos + length و pos استبدال ما بين الموضعين $newstr = substr_replace($str, 'My', $pos , strlen($word)); // طباعة النتيجة echo $newstr; // Hello, My! الدالة strpos()‎ في PHP الدالة substr_replace()‎ في PHP
    1 نقطة
  15. لاحظ بعدما تقوم بعملية انشاء السجل ماذا تفعل: return redirect('/team/edit'); مبدئياً في ملف التوجيهات لا يوجد توجيه مُعرف بهذا الشكل إلا: Route::put('/team/{team}',[TeamController::class,'update']); Route::delete('/team/{team}',[TeamController::class,'destroy']); هاذين التوجيهين الميثود الخاصة بهم هي put للأول و delete للثاني، و أنت في هذه الحالة عندما تُعيد توجيه المُستخدم إلى رابط معين يتم طلبه بالطريقة get لذلك ظهرت هذه المُشكلة و ذلك هو شرحها. إن كنت تريد إعادة التوجيه إلى صفحة التعديل فالرابط هو: /team/{team}/edit و ليس: /team/edit يتوجب عليك كتابة: return redirect("/team/{$team->id}/edit"); أو إستخدام التابع back الذي يُعيد المُستخدم الى الصفحة السابقة بما أنها صفحة التعديل. return back();
    1 نقطة
  16. يمكنك التأكد من أنه قد تم إرسال الـ Cookies من خلال أدوات المطورين DevTools ثم تبويبت Application ثم Cookies ثم localhost عليك أيضًا أن تتأكد من أن قيمة $dbt->last_id ليست null وأنها تحتوي على نص أو رقم. مع العلم أن بعد أن تظهر لديك الـ cookie في المتصفح سيمكنك أن تصل إليها من خلال JavaScript طالما أن الخاصية HttpOnly فارغة (غير محددة).
    1 نقطة
  17. يجب التأكد من معلومات الإتصال بقاعدة البيانات مثل اسم المستخدم وكلمة السر واسم قاعدة البيانات الموجودة في الملف env، وكذلك يجب التأكد من أن خادم MySQL يعمل بشكل سليم، كما يجب تهجير البيانات من خلال الأمر التالي: php artisan migrate:fresh --seed ملاحظة الأمر السابق سوف يقوم بحذف البيانات الموجودة في قاعدة البيانات (إن كانت تحتوي على أي بيانات). بعد تنفيذ الأمر السابق يمكن أن تقوم بتشغيل المشروع من خلال الأمر التالي: php artisan serve
    1 نقطة
  18. في لغة SQL يُعد هذا هو السلوك الذي يجب اعتماده عند حذف الكائن المشار إليه. وهذه ليست خاصة في Django نفسه. بل هو جزء من SQL. يتم استخدام on_delete لإخبار Django بما يجب فعله مع النموذج التي تعتمد على كائنات أخرى الذي قمت بحذفه. (على سبيل المثال، علاقة ForeignKey)، مثلًا المنشور الواحد في مدونة ما قد يكون له علاقة ForeignKey مع جدول comments لعرض التعليقات الخاصة بمنشور معين، وهذه الخاصية هي التي تحدد ما الذي سيحدث في حالة حذف المنشور، هل سيتم حذف التعليقات أم إبقائها أم ربما تريد إظهار خطأ يمنعك من حذف أي منشور لديه تعليقات عن طريق الخطأ. وهناك سبعة إجراءات يمكن اتخاذها عند وقوع مثل هذا الحدث (أي عند حذف كائن من جدول ما): CASCADE: عند حذف الكائن المشار إليه، احذف أيضًا الكائنات التي لها مراجع (عندما تقوم بإزالة منشور من مدونة ما على سبيل المثال، قد ترغب في حذف التعليقات الخاصة بهذا المنشور أيضًا).في لغة SQL يتم إستعمال كلمة CASCADE PROTECT: منع حذف الكائن المشار إليه (إن كان هناك أي إشارات له من كائنات أخرى). ولحذفه، سيتعين عليك حذف جميع الكائنات التي تشير إليه يدويًا، في لغة SQL يتم إستعمال كلمة RESTRICT RESTRICT: (تم إضافتها في الإصدار 3.1 من Django)، تشبه الخيار السابق، ولكنها تتبع معيار لغة SQL بشكل أدق، وفي حالة حدوث خطأ يتم عرض خطأ من نوع RestrictedError ، بخلاف PROTECT، تسمح بحذف الكائن المشار إليه إذا كان يشير أيضًا إلى كائن مختلف يتم حذفه في نفس العملية، ولكن عبر علاقة CASCADE. SET_NULL: يتم تعيّن المرجع إلى NULL (يتطلب أن يكون الحقل nullable أي أن قيمة null تساوي True). على سبيل المثال، عندما تحذف مستخدمًا، قد ترغب في الاحتفاظ بالتعليقات التي نشرها في منشورات المدونة، ويتم عرض التعليقات من قِبل مستخدم مجهول أو تم حذفه. في لغة SQL يتم إستعمال كلمة SET NULL SET_DEFAULT: يقوم بتعيين القيمة الافتراضية default. في لغة SQL يتم إستعمال كلمة SET DEFAULT SET(): تقوم بتعيين قيمة معينة. هذا ليس جزءًا من معيار SQL ويتم التعامل معه بالكامل بواسطة Django فقط، وهنا مثال لكيفية إستخدامها من توثيق Django الرسمي: from django.conf import settings from django.contrib.auth import get_user_model from django.db import models def get_sentinel_user(): return get_user_model().objects.get_or_create(username='deleted')[0] class MyModel(models.Model): user = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.SET(get_sentinel_user), ) DO_NOTHING: يتم إستخدامها للإشارة إلى كائن غير موجود بالفعل، وقد تسبب الكثير من المشاكل في قاعدة البيانات مما ينتج عنه مشاكل وأخطاء تظهر للمستخدمين، في لغة SQL يتم إستعمال NO ACTION يمكنك الوصول إلى توثيق كل الخيارات السابقة في وثائق Django من هنا. في أغلب الحالات، CASCADE هو الخيار الأكثر إستخدامًا، ولكن بالنسبة لكل مفتاح ForeignKey، يجب أن تسأل نفسك دائمًا ما هو السلوك المتوقع في هذا الموقف. أحيانًا ما يكون PROTECT و SET_NULL مفيدًا في بعض الحالات. تحتوي الأكاديمية على مقالة (النماذج Models والاستعلام عن البيانات في Django) تمكنك من تجهيز وإعداد نماذج في Django وتتضمن أيضًا عمل علاقة ForeignKey بين النماذج.
    1 نقطة
  19. بإمكانك قراءة توثيق أي مكتبة من خلال الدالة help والتي قد تساعدك كثيرًا في فهم كيفية عمل المكتبة من خلال توثيق مكتوب باللغة الإنجليزية، مما يعطيك لمحة حول الدوال والمتغيرات والأصناف الموجودة في هذه المكتبة، يمكنك أن تقوم بإستخدام الدالة help كالتالي: >>> help('numpy') Help on package numpy: NAME numpy DESCRIPTION NumPy ===== Provides 1. An array object of arbitrary homogeneous items 2. Fast mathematical operations over arrays 3. Linear Algebra, Fourier Transforms, Random Number Generation How to use the documentation ---------------------------- Documentation is available in two forms: docstrings provided with the code, and a loose standing reference guide, available from `the NumPy homepage <https://www.scipy.org>`_. We recommend exploring the docstrings using `IPython <https://ipython.org>`_, an advanced Python shell with TAB-completion and introspection capabilities. See below for further instructions. The docstring examples assume that `numpy` has been imported as `np`:: >>> import numpy as np -- More -- لاحظ أن توثيق أغلب المكتبات كبير للغاية لذلك يتم عرض جزء صغير فقط ويمكنك أن تقوم بعرض المزيد من خلال الضغط على Enter. كما يمكنك أن تستعمل نفس الدالة لقراءة توثيق دالة ميعنة أو صنف معين من خلال كتابة اسم المكتبة ثم اسم الدالة أو الصنف ويفصلهما نقطة، كالتالي: >>> help('numpy.array') Help on built-in function array in numpy: numpy.array = array(...) array(object, dtype=None, *, copy=True, order='K', subok=False, ndmin=0, like=None) Create an array. Parameters ---------- object : array_like An array, any object exposing the array interface, an object whose __array__ method returns an array, or any (nested) sequence. dtype : data-type, optional The desired data-type for the array. If not given, then the type will be determined as the minimum type required to hold the objects in the sequence. copy : bool, optional If true (default), then the object is copied. Otherwise, a copy will only be made if __array__ returns a copy, if obj is a nested sequence, or if a copy is needed to satisfy any of the other requirements (`dtype`, `order`, etc.). order : {'K', 'A', 'C', 'F'}, optional Specify the memory layout of the array. If object is not an array, the newly created array will be in C order (row major) unless 'F' is specified, in which case it will be in Fortran order (column major). If object is an array the following holds. ===== ========= =================================================== -- More -- للخروج من التوثيق يمكنك الضغط على q أو Ctrl + c فقط. ولطباعة محتوى مكتبة معينة يمكنك أن تستعمل دالة open والتابع __file__ لقراءة ملفات المكتبة ثم طبعاتها، كالتالي: >>> import flask >>> f = open(flask.json.__file__, 'r') >>> content = f.read() >>> print(content) بالتأكيد فتح ملفات المكتبة وتصفحها سيكون أفضل وأسهل وأكثر عملية، ويمكنك الحصول على مسار أي مكتبة من خلال التابع __file__ أيضًا كالتالي: >>> flask.__file__ 'C:\\Python38\\lib\\site-packages\\flask\\__init__.py'
    1 نقطة
  20. بعد المقدمة الموجزة التي تحدثنا فيها عن أساسيات اللغة TypeScript في المقال السابق، سنكون جاهزين لبدء رحلتنا لنصبح مطورين شاملين لتطبيقات الويب باستخدام TypeScript. سنركز في هذا القسم على المشاكل التي قد تنشأ عن استخدام اللغة لتطوير تطبيقات express للواجهة الخلفية وReact للواجهة الأمامية، بدلًا من تقديم مدخل موّسع عن كل جوانب اللغة. وسنركز أيضًا على استخدام أدوات التطوير المتاحة بالإضافة إلى الميزات التي تقدمها اللغة. تجهيز كل شيء لبدء العمل ثَبّت ما تحتاجه لاستخدام TypeScript على المحرر الذي تختاره، ستحتاج إلى تثبيت الموسِّع typescript hero إن كنت ستعمل على Visual Studio Code. لا يمكن تنفيذ شيفرة TypeScript مباشرة كما ذكرنا سابقًا، بل علينا تصريفها إلى شيفرة JavaScript قابلة للتنفيذ. عندما تصرّف شيفرة اللغة إلى JavaScript ستصبح عرضًة لإزالة الأنواع. أي ستزال مسجلات النوع والاستدلالات والأسماء المستعارة للأنواع وكل معطيات نظام تحديد النوع الأخرى، وستكون النتيجة شيفرة JavaScript صرفة جاهزة للتنفيذ. نقصد أحيانًا بالحاجة إلى التصريف في بيئات الإنتاج، أن نوجد "خطوة لبناء التطبيق". حيث تُصرّف كل شيفرة TypeScript خلال خطوة بناء التطبيق إلى شيفرة JavaScript ضمن مجلد منفصل، ومن ثم تُنفِّذ بيئة الإنتاج الشيفرة الموجودة ضمن هذا المجلد. يُفضَّل في بيئات الإنتاج أن نستخدم التصريف في الزمن الحقيقي، وإعادة التحميل التلقائي لنتمكن من متابعة النتائج بشكل أسرع. لنبدأ بكتابة أول تطبيق لنا باستخدام TypeScript. ولتبسيط الأمر، سنستخدم حزمة npm تُدعى ts-node. حيث تصرّف هذه المكتبة ملف TypeScript وتنفذه مباشرة. وبالتالي لا حاجة لخطوة تصريف مستقلة. يمكن تثبيت المكتبة ts-node والحزمة الرسمية للغة TypeScript لكافة المشاريع globally كالتالي: npm install -g ts-node typescript إن لم تستطع أو لم ترد تثبيت حزم شاملة، يمكنك إنشاء مشروع npm وتثبت فيه الاعتماديات اللازمة فقط ومن ثم تُنفِّذ شيفرتك ضمنه. كما سنستخدم المقاربة التي اتبعناها في القسم 3، حيث نهيئ مشروع npm بتنفيذ الأمر npm init في مجلد فارغ، ونثبّت بعدها الاعتماديات بتنفيذ الأمر: npm install --save-dev ts-node typescript كما يجب أن نهيئ تعليمة scripts ضمن الملف package.json كالتالي: { // .. "scripts": { "ts-node": "ts-node" }, // .. } يمكنك استخدام ts-node ضمن المجلد بتنفيذ الأمر npm run ts-node. وتجدر الملاحظة أن استخدام ts-node من خلال الملف package.json يقتضي أن تبدأ كل أسطر الأوامر بالرمز "--". لذا سيكون عليك تنفيذ الأمر التالي إن أردت مثلًا تنفيذ الملف file.ts باستخدام ts-node: npm run ts-node -- file.ts نشير أيضًا إلى وجود أرضية عمل خاصة باللغة TypeScript على الإنترنت، حيث يمكنك تجريب شيفرتك والحصول على شيفرة JavaScript الناتجة وأخطاء التصريف المحتملة بسرعة. ملاحظة: يمكن أن تتضمن أرضية العمل قواعد تهيئة مختلفة (وهذا ما سنوضحه لاحقًا) عما هو موجود في بيئة التطوير الخاصة بك، لهذا قد تجد تحذيرات مختلفة. يمكن تعديل قواعد التهيئة لأرضية العمل هذه من خلال القائمة المنسدلة config. ملاحظة عن أسلوب كتابة الشيفرة إن لغة JavaScript بحد ذاتها مريحة الاستخدام، ويمكنك أن تنفذ ما تريده بطرق مختلفة في أغلب الأحيان. فعلى سبيل المثال يمكنك استخدام الدوال named، أو anynamous، وقد تستخدم const، أو var، أو let للتصريح عن متغير، وكذلك الاستخدامات المختلفة للفاصلة المنقوطة. سيختلف هذا القسم عن البقية بطريقة استخدام الفاصلة المنقوطة. ولا يمثل هذا الاختلاف طريقة خاصة باللغة لكنه أكثر ما يكون أسلوبًا لكتابة شيفرة أي نوع من JavaScript. واستخدام هذا التنسيق أو عدمه سيعود كليًا للمبرمج. لكن من المتوقع أن يغير أسلوبه في كتابة الشيفرة لتتماشى مع الأسلوب المتبع في هذا القسم، إذ يجب إنجاز تمارين القسم مستخدمًا الفواصل المنقوطة ومراعيًا أسلوب كتابة الشيفرة المستخدم فيه. كما ستجد اختلافًا في تنسيق الشيفرة في هذا القسم بالمقارنة مع التنسيق الذي اتبعناه في بقية أقسام المنهاج كتسمية المجلدات مثلًا. لنبدأ بإنشاء دالة بسيطة لتنفيذ عملية الضرب. ستبدو تمامًا كما لو أنها مكتوبة بلغة JavaScript: const multiplicator = (a, b, printText) => { console.log(printText, a * b); } multiplicator(2, 4, 'Multiplied numbers 2 and 4, the result is:'); وكما نرى، فالدالة مكتوبة بشيفرة JavaScript عادية دون استخدام ميزات TS. ستصرّف وتنفذ الشيفرة بلا مشاكل باستخدام الأمر npm run ts-node -- multiplier. لكن ما الذي سيحدث إن مررنا نوعًا خاطئًا من المعاملات إلى الدالة؟ لنجرب ذلك! const multiplicator = (a, b, printText) => { console.log(printText, a * b); } multiplicator('how about a string?', 4, 'Multiplied a string and 4, the result is:'); عند تنفيذ الشيفرة، سيكون الخرج: "Multiplied a string and 4, the result is: NaN". أليس من الجيد أن تمنعنا اللغة من ارتكاب هذا الخطأ؟ سترينا هذه المشكلة أولى مزايا TS. لنعرف أنواعًا للمعاملات ونرى ما الذي سيتغير. تدعم اللغة TS أنواعًا مختلفة، مثل: number، وstring، وArray. يمكنك إيجاد قائمة بالأنواع في توثيق TS على الانترنت. كما يمكن إنشاء أنواع مخصصة أكثر تعقيدًا. إنّ أول معاملين لدالة الضرب من النوع number والثالث من النوع string. const multiplicator = (a: number, b: number, printText: string) => { console.log(printText, a * b); } multiplicator('how about a string?', 4, 'Multiplied a string and 4, the result is:'); لم تعد الشيفرة السابقة شيفرة JavaScript صالحة للتنفيذ. فلو حاولنا تنفيذها، لن تُصرَّف: إنّ إحدى أفضل ميزات محرر TS، أنك لن تحتاج إلى تنفيذ الشيفرة حتى ترى المشكلة. فالإضافة VSCode فعالة جدًا، حيث ستبلغك مباشرة إن حاولت استخدام النوع الخاطئ. إنشاء أول نوع خاص بك لنطور دالة الضرب إلى آلة حاسبة تدعم أيضًا الجمع والقسمة. ينبغي أن تقبل الآلة الحاسبة ثلاث معاملات: عددين وعملية قد تكون الضرب multiply، أو الجمع add، أو القسمة divide. تحتاج الشيفرة في JavaScript إلى تقييم إضافي للمعامل الثالث لتتأكد من كونه قيمة نصية. بينما تقدم TS طريقة لتعريف أنواع محددة من الدخل، بحيث تصف تمامًا الأنواع المقبولة. وعلاوة على ذلك، ستظهر لك TS معلومات عن القيم الصالحة للاستخدام ضمن المحرر. يمكن إنشاء نوع باستخدام التعليمة الداخلية type في TS. سنصف فيما سيأتي النوع Operation الذي عرًفناه: type Operation = 'multiply' | 'add' | 'divide'; يقبل النوع Op ثلاثة أشكال من الدخل وهي تمامًا القيم النصية الثلاثة التي نريد. يمكننا باستخدام العامل OR ('|') تعريف متغير يقبل قيمًا متعددة وذلك بإنشاء نوع موحَّد union type.لقد استخدمنا في الحالة السابقة القيمة النصية بحرفيتها (وهذا ما يدعى التعريف المختصر للنوع النصي string literal types)، لكن باستخدام الأنواع الموحَّدة، ستجعل المصرِّف قادرًا على قبول قيمة نصية أو عددية: string | number. تُعرّف التعليمة type اسمًا جديدًا للنوع أو ما يسمى اسمًا مستعارًا للنوع. وطالما أن النوع المُعرَّف هو اتحاد بين ثلاث قيم مقبولة، فمن المفيد إعطاء النوع اسمًا مستعارًا يصفه بشكل جيد. لنلق نظرة على الآلة الحاسبة: type Operation = 'multiply' | 'add' | 'divide'; const calculator = (a: number, b: number, op : Operation) => { if (op === 'multiply') { return a * b; } else if (op === 'add') { return a + b; } else if (op === 'divide') { if (b === 0) return 'can\'t divide by 0!'; return a / b; } } ستلاحظ الآن أنك لو مررت الفأرة فوق النوع Operation في المحرر، ستظهر لك مباشرة اقتراحات عن طريقة استخدامه: ولو أردنا استخدام قيمة غير موجودة ضمن النوع Operation، ستظهر لك مباشرة إشارة التحذير الحمراء ومعلومات إضافية ضمن المحرر: لقد أبلينا جيدًا حتى اللحظة، لكننا لم نطبع بعد النتيجة التي تعيدها دالة الآلة الحاسبة. غالبًا ما نريد معرفة النتيجة التي تعيدها الدالة، ومن الأفضل أن نضمن أن الدالة ستعيد القيمة التي يفترض أن تعيدها. لنضف إذًا القيمة المعادة number إلى الدالة: type Operation = 'multiply' | 'add' | 'divide'; const calculator = (a: number, b: number, op: Operation): number => { if (op === 'multiply') { return a * b; } else if (op === 'add') { return a + b; } else if (op === 'divide') { if (b === 0) return 'this cannot be done'; return a / b; } } سيعترض المصرِّف مباشرة على فعلتنا، ذلك أن الدالة ستعيد في إحدى الحالات (القسمة على صفر) قيمة نصية. هناك عدة طرق لحل المشكلة. إذ يمكن إعادة تعريف النوع المعاد ليتضمن القيم النصية string على النحو التالي: const calculator = (a: number, b: number, op: Operation): number | string => { // ... } أو قد ننشئ نوعًا جديدًا للقيم المعادة يتضمن النوعين اللذين تعيدهما الدالة تمامًا مثل النوع Operation. type Result = string | number const calculator = (a: number, b: number, op: Operation): Result => { // ... } لكن السؤال الذي يطرح نفسه هو: هل من الطبيعي لدالة أن تعيد قيمة نصة؟ عندما تصل أثناء كتابة الشيفرة إلى حالة تضطر فيها إلى التقسيم على صفر، فإن خطأً جسيمًا قد وقع في مرحلة ما، وينبغي أن يلقي التطبيق خطأً ثم يعالج عند استدعاء الدالة. عندما تحاول أن تعيد قيمًا لم تكن تتوقعها أصلًا، ستمنعك التحذيرات التي تراها في محرر TSمن اتخاذ قرارات متسرعة، وتضمن لك عمل شيفرتك كما أردتها. وعليك أن تدرك أمرًا آخر، فحتى لو عرّفنا أنواعًا لمعاملاتنا، فإن شيفرة JavaScript المتولدة عند التصريف لن تكون قادرة على التحقق من هذه الأنواع أثناء التنفيذ. وإن كانت قيمة المعامل الذي يحدد العملية قادمةً من مكتبة خارجية على سبيل المثال، فلن تضمن أنها واحدة من القيم المسموحة. لذلك من الأفضل أن تنشئ معالجات للأخطاء، وأن تكون منتبهًا لحدوث ما لا تتوقعه. وفي الحالة التي تصادفك فيها عدة قيم مقبولة بينما ينبغي رفض بقية القيم وإلقاء خطأ، ستجد أن كتلة switch…case أكثر ملائمة من كتلة "if….else". ستبدو شيفرة الآلة الحاسبة التي طورناها على النحو التالي: type Operation = 'multiply' | 'add' | 'divide'; type Result = number; const calculator = (a: number, b: number, op : Operation) : Result => { switch(op) { case 'multiply': return a * b; case 'divide': if( b === 0) throw new Error('Can\'t divide by 0!'); return a / b; case 'add': return a + b; default: throw new Error('Operation is not multiply, add or divide!'); } } try { console.log(calculator(1, 5 , 'divide')) } catch (e) { console.log('Something went wrong, error message: ', e.message); } لا بأس بما فعلنا حتى الآن، لكن من الأفضل لو استخدمنا سطر الأوامر لإدخال القيم بدلًا من تغييرها ضمن الشيفرة في كل مرة. سنجرب ذلك كما لو كنا ننفذ تطبيق Node نظامي، باستخدام process.argv. لكن مشكلة ستقع: الحصول على الأنواع في حزم npm من خلال Type@ لنعد إلى الفكرة الأساسية للغة TS. تتوقع اللغة أن تكون كل الشيفرة المستخدمة قادرة على تمييز الأنواع، كما تتوقع ذلك من شيفرة مشروعك الخاص الذي هيِّئ بشكل مناسب. ولا تتضمن المكتبة TS بذاتها سوى الأنواع الموجودة في الحزمة TS. من الممكن كتابة أنواع خاصة بك لمكتبة، لكن ذلك غير ضروري إطلاقًا! فمجتمع TS قد فعل ذلك بالنيابة عنّا. وكما هو حال npm، يرحب عالم TS بالشيفرة مفتوحة المصدر. ومجتمع TS مجتمع نشط ويتفاعل دومًا مع آخر التحديثات والتغييرات في حزم npm المستخدمة أكثر. ستجد غالبًا كل ماتحتاجه من أنواع حزم npm، فلا حاجة لإنشاء هذه الأنواع بنفسك لكل اعتمادية قد تستخدمها. عادة ما نحصل على الأنواع المعرّفة في الحزم الموجودة من خلال منظمة Types@ وباستخدام npm. إذ يمكنك إضافة الأنواع الموجودة في حزمة إلى مشروعك بتثبيت حزمة npm لها نفس اسم حزمتك لكنه مسبوق بالبادئة Types@. فعلى سبيل المثال ستُثبَّت الأنواع التي توفرها المكتبة express بتنفيذ الأمر npm install --save-dev @types/express. تجري صيانة وتطوير Types@ من قبل Definitely typed، وهو مشروع مجتمعي يهدف إلى صيانة أنواع كل ما هو موجود في مكان واحد. قد تحتوي حزمة npm في بعض الأحيان الأنواع الخاصة بها ضمن الشيفرة، فلا حاجة في هذه الحالة إلى تثبيت تلك الأنواع بالطريقة التي ذكرنا سابقًا. طالما أن المتغير العام process قد عُرِّف من قبل Node، سنحصل على الأنواع التي يؤمنها بتثبيت الحزمة types/node@: npm install --save-dev @types/node لن يعترض المصرِّف على المتغير process بعد تثبيت الأنواع. ولاحظ أنه لا حاجة لطلب الأنواع ضمن الشيفرة، إذ يكفي تثبيت الحزمة التي تُعرِّفها. تحسينات على المشروع سنضيف تاليًا سيكربت npm لتشغيل كلا من برنامج دالة الضرب، وبرنامج الآلة الحاسبة: { "name": "part1", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "ts-node": "ts-node", "multiply": "ts-node multiplier.ts", "calculate": "ts-node calculator.ts" }, "author": "", "license": "ISC", "devDependencies": { "ts-node": "^8.6.2", "typescript": "^3.8.2" } } سنجعل دالة الضرب تعمل من خلال سطر الأوامر عند إجراء التعديلات التالية: const multiplicator = (a: number, b: number, printText: string) => { console.log(printText, a * b); } const a: number = Number(process.argv[2]) const b: number = Number(process.argv[3]) multiplicator(a, b, `Multiplied ${a} and ${b}, the result is:`); وسننفذ البرنامج كالتالي: npm run multiply 5 2 لو نفذنا البرنامج بمعاملات ليست من النوع الصحيح، كما تُظهر الشيفرة التالية: npm run multiply 5 lol سيعمل البرنامج أيضًا معطيًا الخرج التالي: Multiplied 5 and NaN, the result is: NaN والسبب في ذلك أن تنفيذ الأمر ('Number('lol سيعيد القيمة NaN وهذه القيمة من النوع number. لهذا لا يمكن أن تنقذنا TS من مأزق كهذا. لا بدّ في هذه الحالات من تقييم البيانات التي نحصل عليها من سطر الأوامر لكي نمنع سلوكًا كهذا. ستبدو النسخة المحسّنة من "دالة الضرب" كالتالي: interface MultiplyValues { value1: number; value2: number; } const parseArguments = (args: Array<string>): MultiplyValues => { if (args.length < 4) throw new Error('Not enough arguments'); if (args.length > 4) throw new Error('Too many arguments'); if (!isNaN(Number(args[2])) && !isNaN(Number(args[3]))) { return { value1: Number(args[2]), value2: Number(args[3]) } } else { throw new Error('Provided values were not numbers!'); } } const multiplicator = (a: number, b: number, printText: string) => { console.log(printText, a * b); } try { const { value1, value2 } = parseArguments(process.argv); multiplicator(value1, value2, `Multiplied ${value1} and ${value2}, the result is:`); } catch (e) { console.log('Error, something bad happened, message: ', e.message); } عندما ننفذ البرنامج الآن: npm run multiply 1 lol سنحصل على رسالة خطأ مناسبة للوضع: Error, something bad happened, message: Provided values were not numbers! يحتوي تعرف الدالة parseArguments بعض الأشياء الملفتة: const parseArguments = (args: Array<string>): MultiplyValues => { // ... } سنجد أولًا أنّ المعامل arg هو مصفوفة من النوع "string"، وأنّ القيم المعادة من النوع "MultiplayValues" الذي عُرِّف بالشكل التالي: interface MultiplyValues { value1: number; value2: number; } لقد استخدمنا في تعريف هذا النوع التعليمة Interface للغة TS، وهي إحدى الطرق المتبعة لتحديد شكل الكائن. إذ ينبغي كما هو واضح في حالتنا، أن تكون القيمة المعادة كائنًا له خاصيتين value1 وvalue2 من النوع "number". التمارين 9.1 - 9.3 التثبيت سننجز التمارين من 9.1 إلى 9.7 ضمن مشروع Node واحد. أنشئ المشروع في مجلد فارغ مستخدمًا الأمر npm init وثبِّت حزمتي ts-node وtypescript. أنشئ أيضًا ملفًا باسم tsconfig.json ضمن المجلد بحيث يحتوي الشيفرة التالية: { "compilerOptions": { "noImplicitAny": true, } } يستخدم هذا الملف لتحديد الطريقة التي سيفسر بها مصرِّف TS الشيفرة المكتوبة، وما هو مقدار التشدد الذي سيفرضه المصرِّف، وما هي الملفات التي ينبغي مراقبتها أو تجاهلها، والكثير الكثير من الأشياء. سنستخدم حاليًا خيار المصرِّف noImplicitAny الذي يشترط أن تحمل جميع المتغيرات أنواعًا محددة. 9.1 مؤشر كتلة الجسم ضع شيفرة هذا التمرين في الملف bmiCalculator.ts. اكتب دالة باسم calculateBmi تحسب مؤشر كتلة الجسم BMI بناء على طول محدد (سنتيمتر) ووزن محدد (كيلو غرام)، ثم أعد رسالة مناسبة تحمل النتيجة. استدعي الدالة من شيفرتك ومرر إليها معاملات جاهزة ثم اطبع النتيجة. ينبغي أن تطبع الشيفرة التالية: console.log(calculateBmi(180, 74)) النتيجة التالية: Normal (healthy weight) أنشئ سكربت npm لكي تنفذ البرنامج باستخدام الأمر npm run calculateBmi 9.2 آلة حاسبة لساعات التمرين ضع شيفرة هذا التمرين في الملف exerciseCalculatore.ts. اكتب دالة باسم calculateExercise تحسب متوسط ساعات التمرين اليومية وتقارنها بعدد الساعات التي ينبغي الوصول إليها يوميًا، ثم تعيد كائنًا يتضمن القيم التالية: عدد الأيام عدد أيام التمرين القيمة المستهدفة أساسًا متوسط الوقت المحسوب قيمة منطقية تحدد إن تم تحقيق الهدف أم لا. تقييمًا بين 1-3 يصف حسن التمرين خلال ساعات التمرين. قرر أسلوب التقييم كما تشاء. قيمة نصية تصف التقييم تمرر ساعات التمرين اليومية إلى الدالة مثلل مصفوفة تحتوي على عدد ساعات التمرين كل يوم خلال فترة التمرين. فلو فرضنا أن ساعات التمرين خلال أسبوع موزعة كالتالي: يوم الاثنين 3، يوم الثلاثاء 0، يوم الأربعاء 2، يوم الخميس 4.5 وهكذا، ستكون المصفوفة مشابهة للمصفوفة التالية: [3, 0, 2, 4.5, 0, 3, 1] عليك أن تنشئ واجهة interface من أجل توصيف الكائن الذي سيحمل النتيجة. لو استدعيت الدالة وقد مررت لها المصفوفة [3, 0, 2, 4.5, 0, 3, 1] والقيمة 2 للمعامل الآخر ستكون النتيجة على النحو: { periodLength: 7, trainingDays: 5, success: false, rating: 2, ratingDescription: 'not too bad but could be better', target: 2, average: 1.9285714285714286 } أنشئ سكربت npm لينفذ الأمر npm run calculateExercise الذي يستدعي الدالة بمعاملات قيمها موجودة مسبقًا في الشيفرة. 9.3 سطر الأوامر عدّل التمرينين السابقين بحيث يمكنك تمرير قيم معاملات الدالتين calculateBmi وcalculateExercise من خلال سطر الأوامر. يمكن أن تنفذ برنامجك على سبيل المثال على النحو التالي: $ npm run calculateBmi 180 91 Overweight أو على النحو: $ npm run calculateExercises 2 1 0 2 4.5 0 3 1 0 4 { periodLength: 9, trainingDays: 6, success: false, rating: 2, ratingDescription: 'not too bad but could be better', target: 2, average: 1.7222222222222223 } وانتبه إلى أنّ المعامل الأول للدالة السابقة هو القيمة المستهدفة. تعامل مع الاستثناءات والأخطاء بطريقة مناسبة. وانتبه إلى أنّ الدالة exerciseCalculator ستقبل قيمًا لمعاملاتها بأطوال مختلفة. قرر بنفسك كيف ستجمّع كل البيانات المطلوبة. المزيد حول قواعد تهيئة TS لقد استخدمنا في التمارين السابقة قاعدة تهيئة واحدة هي noImplicitAny. وهي بالفعل نقطة انطلاق جيدة، لكن يجب أن نطلع بشيء من التفصيل على الملف "config". يحتوي الملف tsconfig.json كل التفاصيل الجوهرية التي تحدد الطريقة التي ستنفذ بها TS مشروعك. فيمكنك أن تحدد مقدار التشدد في تفحص الشيفرة، وأن تحدد الملفات التي ستدرجها في المشروع والتي ستستثنيها (يستثنى الملف "node_modules" افتراضيًا)، وأين ستخزّن الملفات المصرِّفة (سنتحدث أكثر عن هذا الموضوع لاحقًا). لنضع القواعد التالية في الملف tsconfig.json: { "compilerOptions": { "target": "ES2020", "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "esModuleInterop": true } } لا تقلق بخصوص القواعد في الجزء compilerOptions من الملف، فسنمر عليها بشيئ من التفصيل في القسم 2. يمكنك أن تجد شروحات عن كل قاعدة تهيئة من خلال توثيق TS، أو من خلال صفحة الويب tsconfig page، أو من خلال تعريف تخطيط الملف tsconfig والذي صيغ لسوء الحظ بطريقة أقل وضوحًا من الخيارين السابقين. إضافة المكتبة express إلى الخلطة وصلنا إلى مرحلة لا بأس بها. فمشروعنا قد ثّبت، ويحتوي على نسخة قابلة للتنفيذ من الآلة الحاسبة. لكن طالما أنا نهتم بالتطوير الشامل لتطبيقات الويب، فقد حان الوقت لنعمل مع بعض طلبات HTTP. لنبدأ بتثبيت المكتبة express: npm install express ثم سنضيف سكربت start إلى الملف package.json { // .. "scripts": { "ts-node": "ts-node", "multiply": "ts-node multiplier.ts", "calculate": "ts-node calculator.ts", "start": "ts-node index.ts" }, // .. } سنتمكن الآن من إنشاء الملف index.ts، ثم سنكتب ضمنه طلب HTTP-GET للتحقق من الاتصال بالخادم: const express = require('express'); const app = express(); app.get('/ping', (req, res) => { res.send('pong'); }); const PORT = 3003; app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); }); يبدو أن كل شيء يعمل على ما يرام، لكن كما هو متوقع، لا بدّ من تحديد نوع كل من المعاملين req وres للدالة app.get (لأننا وضعنا قاعدة تهيئة تفرض أن يكون لكل متغير نوع). لو نظرت جيدًا، ستجد أن VSCode سيعترض على إدراج express. ستجد خطًا منقطا أصفر اللون تحت التعليمة require. وعندما نمرر الفأرة فوق الخطأ ستظهر الرسالة التالية: إنّ سبب الاعتراض هو أن require يمكن أن تُحوَّل إلى import. لننفذ النصيحة ونستخدم import كالتالي: import express from 'express'; ملاحظة: تقدم لك VSCode ميزة إصلاح المشاكل تلقائيًا بالنقر على زر "…Quick fix". انتبه إلى تلك الاصلاحات التلقائية، وحاول أن تتابع النصائح التي يقدمها محرر الشيفرة، لأن ذلك سيحسّن من شيفرتك ويجعلها أسهل قراءة. كما يمكن أن يكون الإصلاح التلقائي للأخطاء عاملًا رئيسيًا في توفير الوقت. سنواجه الآن مشكلة جديدة. سيعترض المصرِّف على عبارة import. وكالعادة يمثل المحرر المكان الأفضل لإيجاد حلول للمشاكل: لم نثبّت أنواع express كما يشير المحرر، لنثبتها إذًا: npm install --save-dev @types/express وهكذا سيعمل البرنامج بلا أخطاء. فلو مررنا الفأرة على عبارة require سنرى أن المصرِّف قد فسّر كل ما يتعلق بالمكتبة express على أنه من النوع "any". لكن عند استخدام imports فسيعرف المصرِّف الأنواع الفعلية للمتغيرات: يعتمد استخدام عبارة الإدراج على أسلوب التصدير الذي تعتمده الحزمة التي ندرجها. وكقاعدة أساسية: حاول أن تدرج وحدات الشيفرة باستخدام التعليمة import أولًا. سنستخدم دائمًا هذا الأسلوب عند كتابة شيفرة الواجهة الأمامية. فإن لم تنجح التعليمة import، جرّب طريقة مختلطة بتنفيذ الأمر ('...')import...= require. كما نوصيك بشدة أن تطلع أكثر على وحدات TS. لا تزال هنالك مشكلة عالقة: يحدث هذا لأننا منعنا وجود معاملات غير مستخدمة عند كتابة قواعد التهيئة في الملف tsconfig.json. { "compilerOptions": { "target": "ES2020", "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, "esModuleInterop": true } } ستسبب لك التهيئة مشاكلًا إن استخدمت دوال معرّفة مسبقُا لمكتبة وتتطلب تصريحًا عن متغير حتى لو لم يستخدم مطلقًا كالحالة التي تواجهنا. ولحسن الحظ فقد حُلًت هذه المشكلة على مستوى قواعد التهيئة. وبمجرد تمرير مؤشر الفأرة فوق الشيفرة التي سببت المشكلة سيعطينا فكرة الحل. وسننجز الحل هذه المرة بالنقر على زر الإصلاح السريع. إن كان من المستحيل التخلص من المتغيرات غير المستخدمة، يمكنك أن تضيف إليها البادئة (_) لإبلاغ المصرِّف بأنك قد فكرت بحل ولم تصل إلى نتيجة! لنعدّل اسم المتغير req ليصبح req_. وأخيرًا سنكون مستعدين لتشغيل البرنامج. ويبدو أن كل شيء على مايرام. ولتبسيط عملية التطوير، ينبغي علينا تمكين ميزة إعادة التحميل التلقائي، وذلك لتحسين انسيابية العمل. لقد استخدمنا سابقًا المكتبة nodemon التي توفر هذه الميزة، لكن البديل عنها في ts-node هي المكتبة ts-node-dev. وقد جرى تصميم هذه الأخيرة لتُستخدم فقط في بيئة التطوير، حيث تتولى أمور إعادة التصريف عند كل تغيير، وبالتالي لا حاجة لإعادة تشغيل التطبيق. لنثبّت المكتبة ts-node-dev كاعتمادية تطوير: npm install --save-dev ts-node-dev ثم علينا إضافة سكربت خاص بها ضمن الملف package.json. { // ... "scripts": { // ... "dev": "ts-node-dev index.ts", }, // ... } وهكذا ستحصل على بيئة تطوير تدعم إعادة التحميل التلقائي للمشروع بتنفيذ الأمر npm run dev. التمرينان 9.4 - 9.5 9.4 استخدام المكتبة Express أضف المكتبة express إلى اعتماديات التطبيق، ثم أنشئ وصلة تخديم endpoint لطلبات HTTP-GET تدعى hello تجيب على الطلب بالعبارة 'Hello FullStack'. ينبغي أن تُشغّل التطبيق باستخدام الأمر npm start وذلك في بيئة الإنتاج وبالأمر npm run dev في بيئة التطوير التي من المفترض أن تستخدم المكتبة ts-node-dev لتشغيل التطبيق. استبدل محتوى الملف tsconfig.json بالمحتوى التالي: { "compilerOptions": { "noImplicitAny": true, "noImplicitReturns": true, "strictNullChecks": true, "strictPropertyInitialization": true, "strictBindCallApply": true, "noUnusedLocals": true, "noUnusedParameters": true, "noImplicitThis": true, "alwaysStrict": true, "esModuleInterop": true, "declaration": true, } } تأكد من عدم وجود أية أخطاء! 9.5 تطبيق ويب لقياس مؤشر الكتلة BMI أضف وصلة تخديم لحاسبة مؤشر الكتلة يمكن استخدامها بإرسال طلبات HTTP-GET إلى وصلة التخديم bmi، بحيث يكون الدخل على شكل معاملات استعلام نصية (query string parameters). فلو أردت مثلًا الحصول على مؤشر كتلة شخص طوله 180 ووزنه 72، ستحصل عليه بطلب العنوان http://localhost:3002/bmi?height=180&weight=72. ستكون الاستجابة بيانات json لها الشكل التالي: { weight: 72, height: 180, bmi: "Normal (healthy weight)" } اطلع على توثيق express لتعرف آلية الوصول إلى بارامترات الاستعلام. إن كانت معاملات الطلب من نوع خاطئ أو مفقودة، أجب برمز حالة مناسب ورسالة الخطأ التالية: { error: "malformatted parameters" } لا تنسخ شيفرة الحاسبة إلى الملف index.ts، بل اجعلها وحدة TS مستقلة يمكن إدراجها ضمن هذا الملف. كوابيس استخدام النوع any قد نلاحظ بعد أن أكملنا تنفيذ أول وصلة تخديم أننا بالكاد استخدمنا TS في هذا الأمثلة الصغيرة. وقد نلاحظ أيضًا بعض النقاط الخطرة عند تفحص الشيفرة بعناية. لنضف وصلة تخديم طلبات HTTP-GET تدعى calculate إلى تطبيقنا: import { calculator } from './calculator' // ... app.get('/calculate', (req, res) => { const { value1, value2, op } = req.query const result = calculator(value1, value2, op) res.send(result); }); عندما نمرر مؤشر الفأرة فوق الدالة calculate، ستجد أنها تحمل نوعًا على الرغم من أن الشيفرة ذاتها لا تتضمن أية أنواع. وبتمرير مؤشر الفأرة فوق القيم المستخلصة من الطلب، ستظهر مشكلة جديدة: ستحمل جميع المتغيرات النوع any. لن نتفاجأ كثيرًا بما حدث، لأننا في الواقع لم نحدد نوعًا لأي قيمة منها. تُحل المشكلة بطرق عدة، لكن علينا أولًا أن نفهم سبب حدوث هذا السلوك وما الذي جعل القيم من النوع any. كل متغير في TS لا يملك نوعًا ولا يمكن الاستدلال على نوعه، سيعتبر من النوع any ضمنًا. وهذا النوع هو بمثابة نوع "بديل" ويعني حرفيًا "أيًا كان النوع". ويحدث هذا الأمر كثيرًا عندما ينسى المبرمج أن يحدد نوعًا للقيم التي تعيدها الدالة ولمعاملاتها. كما يمكن أن نصُرّح بأن نوع المتغيّر هو any. والفرق الوحيد بين التصريح عن هذا النوع أو تضمينه هو في مظهر الشيفرة المكتوبة، فلن يكترث المصرِّف لأي فرق. لكن سينظر المبرمجون إلى هذا الموضوع بشكل مختلف. فتضمين النوع any يوحي بالمشاكل، لأنه ينتج عادة عن نسيان تحديد نوع المتغير أو المعامل، كما يعني أنك لم تستخدم TS بالطريقة الملائمة. وهذا هو السبب في وجود قاعدة التهيئة noImplicitAny على مستوى المصرِّف. ومن الأفضل أن تبقيها دائمًا مفعّلة. في الحالات النادرة التي لا تعرف فيها فعلًا نوع المتغيًر، عليك التصريح على أنه من النوع any. const a : any = /* افعل هذا إن كنت لا تعلم حقًا نوع المتغير */ لقد فعلنا القاعدة في مثالنا، لماذا إذًا لم يعترض المصرِّف على القيم التي تحمل النوع any ضمنًا؟ يعود السبب إلى الحقل query من كائن الطلب العائد للمكتبة express، فهو يمتلك النوع any صراحة. وكذلك الأمر بالنسبة للحقل request.body الذي يُستخدم لإرسال المعلومات إلى التطبيق. هل يمكننا منع المطور من استخدام any نهائيًا؟ لدينا لحسن الحظ طرق أخرى غير استخدام tsconfig.ts لإجبار المطور على اتباع أسلوب محدد في كتابة الشيفرة. إذا يمكننا استخدام المدقق eslint لإدارة أسلوب كتابة الشيفرة. لنثبت eslint إذًا: npm install --save-dev eslint @typescript-eslint/eslint-plugin @typescript-eslint/parser سنُهيئ المدقق بحيث يمنع التصريح بالنوع "any". اكتب القواعد التالية في الملف ذو اللاحقة "eslintrc.": { "parser": "@typescript-eslint/parser", "parserOptions": { "ecmaVersion": 11, "sourceType": "module" }, "plugins": ["@typescript-eslint"], "rules": { "@typescript-eslint/no-explicit-any": 2 } } لنكتب أيضًا السكربت lint داخل الملف package.json ليتحقق من وجود ملفات لاحقتها "ts.": { // ... "scripts": { "start": "ts-node index.ts", "dev": "ts-node-dev index.ts", "lint": "eslint --ext .ts ." // ... }, // ... } سيعترض المدقق لو حاولنا أن نصرّح عن متغير من النوع any. ستجد في ‎@typescript-eslint الكثير من قواعد المدقق eslint المتعلقة باللغة TS، كما يمكنك استخدام القواعد الأساسية للمدقق في مشاريع هذه اللغة. من الأفضل حاليًا استخدام الإعدادات الموصى بها، ثم يمكننا لاحقًا تعديل القواعد عندما نحتاج إلى ذلك. وعلينا الانتباه إلى التوصيات المتعلقة بأسلوب كتابة الشيفرة بما يتوافق مع الأسلوب الذي يتطلبه هذا القسم وكذلك وضع فاصلة منقوطة في نهاية كل سطر من أسطر الشيفرة. سنستخدم حاليًا ملف قواعد المدقق الذي يتضمن ما يلي: { "extends": [ "eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:@typescript-eslint/recommended-requiring-type-checking" ], "plugins": ["@typescript-eslint"], "env": { "node": true, "es6": true }, "rules": { "@typescript-eslint/semi": ["error"], "@typescript-eslint/no-explicit-any": 2, "@typescript-eslint/explicit-function-return-type": 0, "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }], "no-case-declarations": 0 }, "parser": "@typescript-eslint/parser", "parserOptions": { "project": "./tsconfig.json" } } هناك بعض الفواصل المنقوطة المفقودة، لكن إضافتها أمر سهل. والآن علينا إصلاح كل ما يحتاج إلى إصلاح. التمرينان 9.6 - 9.7 9.6 المدقق ESlint هيئ مشروعك ليستخدم الإعدادات السابقة وأصلح كل المشاكل. 9.7 تطبيق ويب لحساب ساعات التمرين أضف وصلة تخديم إلى تطبيقك الذي يحسب ساعات التمرين اليومية. ينبغي أن تستخدم الوصلة لإرسال طلب HTTP-POST إلى وصلة التخديم المقابلة exercises متضمنة معلومات الدخل في جسم الطلب. { "daily_exercises": [1, 0, 2, 0, 3, 0, 2.5], "target": 2.5 } سيكون الجواب بصيغة json على النحو التالي: { "periodLength": 7, "trainingDays": 4, "success": false, "rating": 1, "ratingDescription": "bad", "target": 2.5, "average": 1.2142857142857142 } إن لم يكن جسم الطلب بالتنسيق الصحيح، أعد رمز الحالة المناسب مع رسالة الخطأ هذه: { error: "parameters missing" } أو هذه: { error: "malformatted parameters" } بناء على الخطأ. ويحدث الخطأ الثاني إن لم تمتلك القيم المدخلة النوع المناسب، كأن لا تكون أرقامًا أو لا يمكن تحويلها إلى أرقام. يمكن أن تجد أن التصريح عن متغير بأنه من النوع any مفيدًا في هذا التمرين عندما تتعامل مع البيانات الموجودة ضمن جسم الطلب. ستمنعك طبعًا قواعد تهيئة المدقق، لكن يمكنك أن تلغي تفعيل هذه القاعدة من أجل سطر محدد من الشيفرة بوضع هذا التعليق قبل السطر المطلوب. // eslint-disable-next-line @typescript-eslint/no-explicit-any انتبه بأنك ستحتاج إلى تهيئة صحيحة لتتمكن من الاحتفاظ ببيانات جسم الطلب. راجع القسم 3. ترجمة -وبتصرف- للفصل First steps with TypeScript من سلسلة Deep Dive Into Modern Web Development
    1 نقطة
  21. TypeScript هي لغة برمجة مصممة لتنفيذ مشاريع JavaScript ضخمة، صممتها Microsoft. فقد بُنيت على سبيل المثال برنامج مثل Azure Management Portal الذي يبلغ عدد أسطر شيفرته 1.2 مليون، وبرنامج Visiual Studio Code الذي يبلغ عدد أسطر شيفرته 300 ألف باستخدام TypeScript. تقدم TypeScript ميزات عديدة لدعم مشاريع JavaScript الضخمة مثل أدوات تطوير أفضل وتحليل شيفرة ساكنة والتحقق من الأنواع عند الترجمة والتوثيق على مستوى الشيفرة. المبدأ الرئيسي تمثل اللغة TypeScript مجموعة مطوّرة من تعليمات JavaScript قادرة على تمييز الأنواع وتترجم عادة إلى شيفرة JavaScript صرفة. ويمكن للمطور أن يحدد إصدار الشيفرة الناتجة طالما أن إصدار ECMAScript هو الإصدار 3 أو أحدث. ويعني أنّ هذه اللغة مجموعة مطوّرة من تعليمات JavaScript أنها تتضمن كل ميزات JavaScript بالإضافة إلى ميزات خاصة بها. وتعتبر كل شيفرات JavaScript شيفرات TypeScript صحيحة. تتألف TypeScript من ثلاثة أقسام منفصلة لكنها متكاملة مع بعضها: اللغة المصرِّف خدمة اللغة تتألف اللغة من القواعد والكلمات المحجوزة (تعليمات) ومسجلات الأنواع Type annotations وتتشابه قواعدها مع مثيلاتها في JavaScript لكنها ليست متماثلة. وأكثر ما يتعامل معه المبرمجون من تلك الأقسام هي اللغة. تنحصر مهمة المصرِّف في محو المعلومات المتعلقة بالنوع بالإضافة إلى التحويلات على الشيفرة. إذ تمكن عملية تحويل الشيفرة من نقل شيفرة TypeScript إلى شيفرة JavaScript قابلة للتنفيذ. يزيل المصرِّف كل ما يتعلق بالأنواع أثناء الترجمة، وبالتالي لا تميز هذه اللغة الأنواع بشكل فعلي قبل الترجمة. تعني عملية التصريف بالمعنى المتعارف عليه، تحويل الشيفرة من الشكل الذي يمكن للإنسان قراءته وفهمه إلى الشكل الذي تفهمه الآلة. أما عملية الترجمة في TypeScript فهي عملية تحويل الشيفرة من شكل يفهمه الإنسان إلى شكل آخر يفهمه الإنسان أيضًا، لذا من الأنسب أن تسمى هذه العملية بالنقل Transpilling. لكن مصطلح الصريف هو الأشيع في هذا المضمار وسنستخدمه نحن بدورنا. ينفذ المصرِّف أيضًا عملية تحليل الشيفرة ما قبل التنفيذ. إذ يمكنه إظهار رسائل التحذير والخطأ إن كان هناك سبب لذلك، كما يمكن أن يُهيَّئ لتنفيذ مهام إضافية كضم الشيفرة الناتجة في ملف واحد. تجمع خدمة اللغة معلومات عن الأنواع الموجودة في الشيفرة المصدرية. وبالتالي ستتمكن أدوات التطوير من استخدامها في تقديم ميزة إكمال الشيفرة في بيئات التطوير وطباعة التلميحات وتقديم اقتراحات لإعادة كتابة أجزاء من الشيفرة. الميزات الرئيسية للغة TypeScript سنقدم تاليًا وصفًا لبعض ميزات اللغة TypeScript. والغاية من ذلك تزويدك بالأساسيات التي تقدمها اللغة وميزاتها، وذلك للتعامل مع الأفكار التي سنراها تباعًا في المنهاج. مسجلات الأنواع وهي طريقة خفيفة في TypeScript لتسجيل الأنواع التي نريد أن تمرر أو تعاد من الدوال أو أنواع المتغيرات. فلقد عرفنا في المثال التالي على سبيل المثال الدالة birthdayGreeter التي تقبل معاملين أحدهما من النوع string، والآخر من النوع number، وستعيد قيمة من النوع string. const birthdayGreeter = (name: string, age: number): string => { return `Happy birthday ${name}, you are now ${age} years old!`; }; const birthdayHero = "Jane User"; const age = 22; console.log(birthdayGreeter(birthdayHero, 22)); نظام الخصائص المعرفة للأنواع تستخدم اللغة TypeScript الخصائص المعرفة للأنواع structural typing. ويعتبر عنصران في هذا النظام متوافقان إن كان لكل ميزة في النوع الأول ميزة تماثلها تمامًا في النوع الثاني. ويعتبر النوعان متطابقان إذا كانا متوافقان مع بعضهما. الاستدلال على النوع يحاول المصرِّف أن يستدل على نوع المعلومة إن لم يحدد لها نوع. إذ يمكن الاستدلال على نوع المتغير بناء على القيمة التي أسندت له. تحدث هذه العملية عند تهيئة المتغيرات والأعضاء، وعند إسناد القيم الافتراضية للمعاملات، وعند تحديد القيمة التي تعيدها دالة. لنتأمل على سبيل المثال الدالة Add: const add = (a: number, b: number) => { /* تستخدم القيمة المعادة لتحديد نوع القيمة التي تعيدها الدالة*/ return a + b; } يستدل المصرِّف على نوع القيمة المعادة للدالة بتعقب الشيفرة حتى الوصول إلى عبارة return. تعيد هذه العبارة مجموع المعاملين a وb. وكما نرى فكلا المعاملين من النوع number وهكذا سيستدل المصرِّف على أن القيمة التي تعيدها الدالة من النوع number. وكمثال أكثر تعقيدًا، لنتأمل الشيفرة التالية (قد يكون المثال صعب الفهم قليلًا إن لم تكن قد استخدمت TypeScript مسبقًا. يمكنك تخطي هذا المثال حاليًا.) type CallsFunction = (callback: (result: string) => any) => void; const func: CallsFunction = (cb) => { cb('done'); cb(1); } func((result) => { return result; }); بداية نجد تصريحًا لاسم نوع مستعار type alias يدعى CallsFunction. يُمثل نوع دالة تقبل معاملًا واحدًا callback يمثِّل بدوره دالة تتلقى معاملًا من النوع "string" وتعيد قيمة من النوع any. وكما سنرى لاحقًا فالنوع any هو شكل من أشكال الحروف البديلة wildcards والتي يمكن أن تحل محل أي نوع. بعد ذلك نعرّف الدالة func من النوع CallsFunction. يمكننا أن نستدل من نوع الدالة بأن معاملها الدالة cb ستقبل فقط معاملًا من النوع string.ولتوضيح ذلك سنورد مثالًا آخر تُستدعى فيه دالة كمعامل لكن بقيمة من النوع number، وسيسبب هذا الاستدعاء خطأً في TypeScript. وأخيرًا نستدعي الدالة func بعد أن نمرر إليها الدالة التالية كمعامل: (result) => { return result; } وعلى الرغم من عدم تحديد أنواع معاملات الدالة، يمكننا الاستدلال من سياق الاستدعاء أن المعامل result من النوع String. إزالة الأنواع تزيل TypeScript جميع الأنواع التي يبنيها نظام تحديد الأنواع أثناء الترجمة: فلو كانت الشيفرة قبل الترجمة كالتالي: let x: SomeType; ستكون بعد الترجمة: let x; ويعني هذا عدم وجود أية معلومات عن الانواع أثناء التنفيذ، فلا يشير أي شيء على أن متغيرًا X على سبيل المثال قد عُرِّف أنه من نوع ما. سيكون النقص في المعلومات عن الأنواع في زمن التنفيذ مفاجئًا للمبرمجين الذين اعتادوا على استخدام تعليمات التحقق Reflection وغيرها من أنظمة إظهار البيانات الوصفية. هل علينا فعلا استعمال TypeScript؟ إن كنت من متابعي المنتديات البرمجية على الانترنت، ستجد تضاربًا في الآراء الموافقة والمعارضة لاستخدام هذه اللغة. والحقيقة أنّ مدى حاجتك لاستخدام الدوال التي تقدمها TypeScript هي من يحدد وجهة نظرك. سنعرض على أية حال بعض الأسباب التي قد تجعل استخدام هذه اللغة مفيدًا. أولًا: ستقدم ميزة التحقق من الأنواع وميزة التحليل الساكن للشيفرة (قبل الترجمة والتنفيذ). كما يمكننا أن نطلب قيمًا من نوع محدد وأن نتلقى تحذيرات من المصرِّف عندما نستخدم هذه القيم بشكل خاطئ. سيقلل هذا الأمر الأخطاء التي تحصل وقت التنفيذ، كما يمكن أن يقلل من عدد اختبارات الأجزاء unit tests التي يحتاجها التطبيق وخاصة ما يتعلق باختبارات الأنواع الصرفة pure types. ولا تحذرك عملية التحليل الساكن للشيفرة من الاستخدام الخاطئ للأنواع وحسب، بل تشير إلى الأخطاء الأخرى ككتابة اسم المتغير أو الدالة بشكل خاطئ أو استخدام المتغير خارج المجال المعرّف ضمنه. ثانيًا: يمكن لميزة تسجيل الأنواع أن تعمل كشكل من أشكال التوثيق على مستوى الشيفرة. إذ يمكنك أن تتحقق من خلال بصمة الدالة signature من الأنواع التي تتلقاها الدالة والأنواع التي ستعيدها. سيبقى هذا الشكل من التوثيق محدّثًا أثناء تقدم العمل، وسيسهّل ذلك التعامل مع مشاريع جاهزة وخاصة للمبرمجين الجدد. كما ستساعد كثيرًا عند العودة إلى مشاريع قديمة. يمكن إعادة استخدام الأنواع في أي مكان من الشيفرة، وستنتقل أية تغييرات على تعريف النوع إلى أي مكان استخدم فيه هذا النوع. وقد يجادل البعض بأن استخدام JSDoc سينجز التوثيق على مستوى الشيفرة بشكل مماثل، لكنه لا يرتبط بالشيفرة بشكل وثيق كما تفعل أنواع TypeScript، وقد يسبب هذا خللًا في تزامن عرض المعلومات، بالإضافة إلى أنها أطول. ثالثًا: ستقدم بيئة عمل اللغة ميزة إكمال الشيفرة بشكل أفضل لأنها تعلم تمامًا نوع البيانات التي تعالجها. وتعتبر الميزات الثلاث السابقة مفيدة للغاية عند إعادة كتابة الشيفرة. فسيحذرك التحليل الساكن للشيفرة من الأخطاء في شيفرتك، وسيرشدك معالج إكمال الشيفرة إلى الخصائص التي يقدمها المتغير أو الكائن أو حتى خيارات لإعادة كتابة الشيفرة بشكل أنسب، وسيساعدك التوثيق على مستوى الشيفرة في فهم الشيفرة المكتوبة. وبهذه المساعدة التي تقدمها لك بيئة عمل هذه اللغة، سيكون من السهل استخدام الميزات الأحدث من لغة JavaScript وفي أية مرحلة تقريبًا بمجرد تغيير إعدادات التهيئة. ما الأمور التي لا يمكن للغة TypeScript أن توفرها لك؟ لقد ذكرنا سابقًا أن تسجيل الأنواع والتحقق منها فقط في مراحل ما قبل التنفيذ. فحتى لو لم يشر المصرِّف إلى أخطاء فقط تحدث الأخطاء أثناء التنفيذ. تحدث أخطاء زمن التنفيذ بشكل متكرر عند التعامل مع مصدر دخل خارجي كالبيانات المستقبلة كطلب عبر شبكة. وضعنا أخيرًا قائمة بالمشاكل التي قد تواجهنا عند استخدام TypeScript، ويجب الانتباه إليها: الأنواع غير المكتملة أو الخاطئة أو المفقودة التي مصدرها مكتبات خارجية قد تجد في بعض المكتبات الخارجية أنواعًا غير معرّفة أو ذات تعريف خاطئ بشكل أو بآخر. والسبب المرجح أنّ المكتبة لم تُكتَب بلغة Typescript، وأنّ المبرمج الذي صرّح عن النوع يدويًا قد ارتكب خطأً. عليك في هذه الحال كتابة التصريح عن النوع يدويًا بنفسك. لكن هناك فرصة كبيرة أن يكون أحدهم قد فعل ذلك مسبقًا عوضًا عنك، تحقق من موقع DefinitelyTyped أو صفحة GitHub الخاصة بهذا الموقع أولًا. وهذان المصدران هما الأكثر شعبية لإيجاد ملفات تعريف الأنواع. في حال لم يحالفك الحظ، لابدّ أن تبدأ من الصفر بقراءة توثيق TypeScript بما يخص تعريف الأنواع. قد يحتاج الاستدلال على النوع إلى بعض المساعدة إن الاستدلال على النوع في هذه اللغة جيد جدًا لكنه ليس مثاليًا. قد تعتقد أحيانًا أنك صرحت عن نوع بشكل مثالي، لكن المصرِّف يحذرك بشكل مستمر من أن خاصية محددة غير موجودة أو أنّ التصريح بهذه الطريقة غير مسموح. عليك في حالات كهذه مساعدة المصرِّف بتنفيذ عملية تحقق إضافية من النوع الذي صرحت عنه، وخاصة فيما يتعلق بالتحويل بين الأنواع type casting أو حاميات الأنواع type gaurds. عند التحويل بين الأنواع أو عند استخدام الحاميات فأنت بذلك تضمن للمصرِّف أن القيمة التي وضعتها هي بالتأكيد من النوع المصرح عنه وهذا مصدر للأخطاء. ربما عليك الاطلاع على التوثيق فيما يتعلق بحاميات الأنواع أو مؤكدات الأنواع Type Assertions. أخطاء الأنواع الغامضة من الصعب أحيانًا فهم طبيعة الخطأ الذي يعطيه نظام تحديد الأنواع، وخاصة إن استخدمت أنواع معقدة. وكقاعدة أساسية، ستحمل لك رسائل خطأ TypeScript المعلومات الأكثر أهمية في نهاية الرسالة. فعندما تظهر لك رسالة طويلة مزعجة، ابدأ بالقراءة من آخر الرسالة. ترجمة -وبتصرف- للفصل Background and introduction من سلسلة Deep Dive Into Modern Web Development
    1 نقطة
×
×
  • أضف...