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

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

  1. حسام أحمد3

    حسام أحمد3

    الأعضاء


    • نقاط

      10

    • المساهمات

      1


  2. Ola Saleh

    Ola Saleh

    الأعضاء


    • نقاط

      10

    • المساهمات

      11


  3. سارة محمد2

    سارة محمد2

    الأعضاء


    • نقاط

      7

    • المساهمات

      86


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

    • نقاط

      6

    • المساهمات

      163


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

عرض المحتوى الحاصل على سمعة أكبر منذ 12/16/24 in مقالات البرمجة

  1. علوم الحاسوب computer science (أو يطلق عليه علوم الكمبيوتر أو علوم الحاسبات بالعامية) هو روح العصر الحديث ويمثل مجال التقنية التي دخلت في كل مفاصل حياتنا، فهو يدخل في كل صغيرة وكبيرة من حولنا بدءًا من الهواتف المحمولة والحواسيب والآلات والمصانع وكل شيء بما لا يمكن حصره من المنتجات والخدمات حيث أسهم في نقلنا إلى مرحلة أعلى من الفعالية والجودة والفائدة. هذا المقال هو دليل شامل للتعرف على اختصاص علوم الحاسب وفوائده وتطبيقاته والمواد التي تدرس فيه والمجالات المتفرعة منه ثم سنناقش بعض الأسئلة المهمة المتعلقة بجدوى اختيار تخصص علوم الحاسوب ودراسته وما هي فرص العمل المتوفرة في مجال علوم الحاسوب وسنعرف أيضًا الفرق بين علم الحاسوب وهندسة الحاسوب وأخيرًا سنرشدك إلى كيفية البدء في دراسة اختصاص علوم الحاسب ذاتيًا وندلك على بداية الطريق لتنطلق إن أحببت المجال. هل أنت جاهز؟ لننطلق! فهرس المحتويات حرصًا على تنظيم المقالة ولتسهيل الوصول إلى القسم الذي تريده بسهولة، سنذكر هنا جدول المحتويات باختصار: ما هي علوم الحاسب؟ فوائد وتطبيقات علوم الحاسوب هل تعلم علوم الحاسوب مفيد؟ مواد علوم الحاسوب تخصصات علوم الحاسب كيف أختار التخصص المناسب لي من تخصصات علوم الحاسب؟ التوظيف وفرص العمل في مجال علوم الحاسوب ما الفرق بين علوم الحاسب وهندسة الحاسب؟ من أين أبدأ بتعلم علوم الحاسب؟ ما هي علوم الحاسب؟ تُعرَف علوم الحاسوب بأنها كل العلوم المتعلقة بالآلات الحسابية والمنطقية، حيث تعمل بدارات إلكترونية، وقد تكون علومًا نظريةً مثل نظرية المعلومات Information Theory أو تطبيقية مثل البرمجيات Software أو العتاد Hardware. والبرمجيات software هي الأنظمة غير الملموسة التي تُشغّل عتاد الحواسيب hardware وتقوم بمهام المستخدمين المطلوبة، بينما العتاد هو القطع الفيزيائية الملموسة التي تُكوّن النظام الحاسوبي مثل المعالِج والذاكرة العشوائية RAM والقرص الصلب …إلخ. وتتشعّب علوم الحاسوب وتترابط مع بعضها بعضًا، إذ لا يمكنك دراسة البرمجة دون دراسة الخوارزميات وهياكل البيانات، كما لا يمكنك دراسة علوم الذكاء الاصطناعي دون دراسة الجبر الخطّي والاحتمالات وعدد آخر من علوم الرياضيات. فوائد وتطبيقات علوم الحاسوب نَذكُر من فوائد وتطبيقات علم الحاسوب ما يلي: تعد شبكة الإنترنت واحدة من أفضل الاختراعات في التاريخ الإنساني، فهي شبكة حاسوبية تصل مناطق العالم ببعضها البعض. حواسيب سطح المكتب والحواسيب المحمولة التي نعمل عليها أو نرفّه خلالها عن أنفسنا …إلخ، جميعها قائمة على علوم الحاسوب وتخصصات الحاسب. الهواتف المحمولة وتطبيقات الهواتف الذكية التي نستعملها للتسوق أو طلب سيارة أجرةٍ أو طلب الطعام والدواء وغير ذلك فكلها تطبيقات حاسوبية. أجهزة إدارة المصانع والعمليات التصنيعية التي تُستعمل لتخطيط تصنيع المنتجات الغذائية وغير الغذائية، فهي مبنيّة بالأساس على برامج وخوارزميات ورياضيات حاسوبية، فلولاها لما تطورت أنظمة التصنيع التي لدينا إلى مرحلة تكفي احتياجات الجنس البشري. الأجهزة الطبية التي تُنقَذ بها حياة الناس في المستشفيات، وأجهزة الاستشعار والإدارة العسكرية، والأجهزة التي تساعد على إدارة الأسواق الاقتصاد والمال وغيرها، فكلها موجودة بفضل علوم الحاسوب. ولعلك تشاهد بعضًا من فوائد هذه العلوم بنفسك، فلا تحتاج من يخبرك عنها. دورة علوم الحاسوب دورة تدريبية متكاملة تضعك على بوابة الاحتراف في تعلم أساسيات البرمجة وعلوم الحاسوب اشترك الآن هل تعلم علوم الحاسب مفيد؟ قد تفكر في نفسك الآن وتقول هل من المجدي لي أن أتخصص في مجال علم الحاسوب وأتعلمها سواء للدراسة والبحث الأكاديمي أو للعمل والوظيفة مستقبلًا؟ والجواب هو نعم، فالأمر مُجدٍ وأنصح به بشدة، إذ يحصل متخصصو علوم الحاسوب على رواتب أعلى من العديد من نظرائهم المهندسين غير العاملين في المجال، كما تزداد الرواتب بازدياد الخبرة ونُدرة المجال الذي يتخصص فيه المرء؛ فمثلًا لا يتساوى مُطوّر واجهات الاستخدام بمهندس يجيد الذكاء الاصطناعي وتعلم الآلة، وكذلك لا يتساوى مع مهندسي البرمجيات ومهندسي العتاد. وبغض النظر عن عامل الوظيفة والراتب والمال، يساعدك تعلم علوم الحاسوب على بناء مشاريع حقيقيةٍ يمكنك أن تستفيد منها أو تغيّر بها العالم، مثلًا انظر كيف غير مارك زوكيبربيرغ طريقة تواصل المليارات من البشر وكامل التاريخ الإنساني بسبب تطويره لموقع إنترنتٍ، وانظر كذلك كيف تتحكم العملات الرقمية وتغير الاقتصاد العالمي في وقتنا الحالي. ويؤهلك تعلم علوم الحاسب لإنشاء خدمات ومواقع وبرمجيات وأنظمة حسبما تحتاج، ومن ثَم تستفيد منها سواءٌ لنفسك أو تبيعها للآخرين إما على شكل وظيفةٍ، أو خبرةٍ كما في مجال العمل الحُرّ. ولا يعني هذا بالطبع أنك ستكون مالك شركة مايكروسوفت المستقبلي، وكذلك لن تكون مارك الذي سيغيّر العالم، إلا أنك ستمتلك نفس الخبرات والأدوات التي امتلكوها عندما فعلوا ذلك، أما الباقي فيعتمد عليك وعلى اجتهادك ومثابرتك. مواد علوم الحاسب سنتحدث في هذا القِسم عن مواد تخصص علوم الحاسب وتفريعاتها المختلفة، وأبرز المواد التي تُدرّسها معظم الجامعات حول العالم لطلابها الراغبين بتَعلّم هذا التخصص، ومعظم هذه المواد مُستوحاةٌ من الفهرس الأكاديمي لجامعة ستانفورد لعلوم الحاسبات، هذا بالإضافة لعددٍ من الجامعات الأخرى. 1. أساسيات الهندسة وهندسة البرمجيات تعد من أول المواد التي يدرسها الطلاب وتهدف للإجابة على أسئلة متنوعة مثل ما هو تعريف الهندسة وما هي عمليات الإدخال والإخراج وكيف تصمم منتجًا أو برنامجًا أو مشروعًا وما هي الخطوات العملية لتصميم وهندسة نظام ما وغيرها. والهدف الرئيسي من هذه المادة هو نقل وتوصيل معنى الهندسة للطلاب، وذلك بإدراكهم أن عملية إنشاء الأنظمة هي خليطٌ مُتقنٌ من التخطيط والترتيب، فهي ليست عمليةً عشوائيةً بسيطةً، وعادةً لا تحتوي هذه المادة على مشاريع برمجية حقيقية، وقد تشتمل على مشاريع بسيطة في بعض الجامعات. ويَتعلّم الطالب في هذه المادة عددًا من التقنيات والأدوات الشائعة لتوصيف الأنظمة وتصميماتها، مثل لغة النمذجة الموحدة Unified Modeling Language واختصارًا UML وآلات الحالة State Machines وغيرها من التقنيات. 2. الرياضيات الأساسية مادة الرياضيات مادةٌ أساسيةٌ لدى جميع طلاب الهندسة عمومًا؛ لذلك من الضروري أن يُدرك الطالب أساسيات الرياضيات مثل العمليات الحسابية والتفاضل والتكامل والجبر وحسابات الأشكال الهندسية وغير ذلك من العمليات الرياضية البسيطة. ولا تُعلّم هذه المادة في الجامعات بهدف الرياضيات ذاتها؛ فبمجرد انتهائك من المادة ستنسى غالبًا تلك المعادلات الرياضية، ولكن الهدف هو تعويد الطالب على استخدام العقل لحساب ما لم يقدِر على حسابه من قبل، فمواجهة القليل من الصعوبة في التَعلّم تُفتّح الذهن وتُعوّده على تحمّل الأكثر صعوبةً من هذه الرياضيات البسيطة مستقبلًا. 3. الرياضيات الخطية ستتعلم في الرياضيات الخطية أو الجبر الخطي أساس حلّ المعادلات الرياضية، مثل معادلات الدرجة الأولى والثانية والثالثة، وبعض الأساليب والقوانين الرياضية لحلها بسهولة. كما ستتعلم بعض الأمور عن المصفوفات وطريقة التعامل معها وإجراء بعض الحسابات لها وطريقة الاستفادة منها مثل المصفوفات أولية وثنائية وثلاثية الأبعاد. 4. التفاضل والتكامل هنا ستتعمق في التفاضل والتكامل بعد اطلاعك عليها بصورة مبسطة بالفعل في إحدى المواد الرياضية السابقة، وستتعرف عليهما بالتفصيل، وكيف تستخدمها لحل بعض المشكلات الحقيقية في العالم، كما ستعرف بعض قواعد التفاضل والتكامل. وقد تكون هذه المادة متقدمة على بعض الطلاب مثل أغلب مواد الرياضيات، وذلك لأن الطالب يتعلم فيها المعادلات والقواعد والقوانين دون أن يُعلّم من أين جاءت ولا كيف ولماذا سيتعلمها ولا أين سيستخدمها في حياته المستقبلية. 5. تصميم المنطق الرقمي ستتعلم في مادة تصميم المنطق الرقمي Digital Logic Design أهم أركان التفكير المنطقي، وكيفية تمثيل الحجج والنقاشات والمعضلات في العالم الحقيقي على شكل معادلات رياضية ومنطقية وكذلك قد تتعلّم بعض الأمور عن المجموعات Sets في الرياضيات وطريقة استخدامها لتمثيل معلومة أو بيانات معينة. كما ستتعلم تصميم البوابات المنطقية Logic Gates مثل and و or و nor و xor و not وغيرها، وكذلك ستفهم الطريقة العامة لعمل المعالجات داخل الحواسيب والأجهزة الإلكترونية. وهذه المادة واحدةٌ من بين أكثر المواد إفادةً ضمن علم الحاسوب لأن طريقة التفكير المنطقية هذه ستنقلك من إنسان عشوائي التفكير قد لا يفكر بمنطقية في معظم أمور حياته إلى إنسان يفهم الحياة بصورة منطقية كما تفهمها الآلات ويَسهُل عليه تحديد ما هو منطقي وما هو غير منطقيٍ من الحجج والمعلومات التي حوله، كما ستفهم كيفية تحويل الأفكار إلى أنظمة فيزيائية وبرمجية داخل الحواسيب بحيث تُستعمَل لإكمال تصميم الحواسيب وتُجري العمليات الحسابية المطلوبة. أي الغرض من هذه المادة أن ترى كيف يعمل الحاسوب وكيف يفهم الأوامر وينفذها حتى تعرف كيف ستتعامل معه وتبرمجه وتتخاطب معه بسهولة. وفقًا لما سبق، من الأفضل التركيز عليها كونها واحدةٌ من أهم المواد في المجال، وقد تُدرّس هذه المادة على عدة مواد منفصلة، لذلك قد تجد موادًا شبيهةً مثل التفكير المنطقي Critical Thinking والرياضيات المتقطعة Discrete Mathematics، فكلّ على حسب الجامعة والتخصص. 6. الاحتمالات مادة الرياضيات الأخيرة التي ستتعلّمها هي مادة الاحتمالات Probabilties أو نظرية الاحتمالات Probability Theory، وهي مادةٌ تهدف إلى تعليمك أهم مبادئ هذا العلم بالإضافة لأنواع الاحتمالات المُمكنة حسب الأحداث Events وطريقة ارتباطها ببعضها البعض ليُستفاد منها في الحياة الواقعية إما في اتخاذ قرارات المؤسسات أو إجراءات أصغر من ذلك سواءٌ على مستوى الأفراد أو الأجهزة الرقمية. والاحتمالات علم عميق تقوم عليه الكثير من الرياضيات الحديثة، كما يقوم عليه علم التعمية Cryptography المُستخدم في تأمين وتشفير الاتصالات والشبكات، وستستفيد من هذه المادة كثيرًا في المستقبل متى أتقنتها. 7. البرمجة من البداهة أن توجد مادة مختصة بتعلم البرمجة في تخصص علوم الحاسب أو التخصصات المرتبطة به، وذلك لأن البرمجة هي لبّ علوم الحاسب في النهاية، فجميع الأجهزة والأنظمة التي حولنا ما هي إلا برمجيات وخوارزميات مختلفة صنعت لتعمل بطريقة معيّنة. كانت لغة جافا Java أبرز لغة برمجةٍ تُعلّم في الجامعات قبل عقد من الزمن، بينما تميل الكفة الآن إلى بايثون Python أو جافاسكربت في بعض الأحيان، ولكن بايثون هي الأكثر استعمالًا واعتمادًا في الجامعات لما لها من تطبيقات لاحقة في جميع المجالات الأكاديمية الأخرى. وفي كل الأحوال ستتعلّم في هذه المادة المتغيرات والخوارزميات وحلقات التكرار والجمل الشرطية والبرمجة كائنية التوجه وغيرها من المبادئ البرمجية، وذلك بِغَض النظر عن لغة البرمجة التي ستتعلّمها. كما قد تُعلّم القليل من استخدام بيئة ماتلاب Matlab وهي بيئة برمجية ولغة برمجة تُستخدَم لإنشاء الحسابات الرياضية وبرمجة برمجيات معينة، لذلك فهي منصة ولغة برمجة في آنٍ واحدٍ، ويستعمل ماتلاب طلاب أقسام الهندسة الأخرى لمحاكاة وحساب المعادلات والنماذج الرياضية. 8. الخوارزميات وهياكل البيانات الخوارزميات Algorithms وهي الإجراءات المنطقية المتسلسلة لحلّ مشكلة ما، وسنتعلّم الخوارزميات وأفضل الطرق لتصميمها من أجل حل مختلف المشكلات التي قد تظهر لنا في المستقبل، حيث سنحتاج إلى معرفة متى نستعمل خوارزمية بعينها من أجل حل مشكلة ما، ومتى سنلجأ لخوارزمية أخرى نعرف أنها ستعطينا أداءً أفضل، بمعنى أننا سنغوص في الموازنة بين مختلف الخوارزميات وأدائها مثل السرعة والوقت ومساحة التخزين، ومتى يجب استعمال كلّ واحدةٍ منها كما سنطّلع على مختلف تشعيبات الخوارزميات المتوفرة. هياكل البيانات Data Structures وهي طريقة تخزين البيانات واستعمالها بغرض تحقيق أهدافٍ مختلفةٍ حسبما يريد المُطوّر؛ فهناك هياكل بياناتٍ أسهل وأوضح للفهم العام، وهناك هياكل بيانات أسرع في الأداء، وهناك هياكل بيانات غير سريعة في الأداء لكنها تستهلك حجمًا أقل في تخزين البيانات وبالتالي قد تفضل على غيرها في بعض الأحيان. وستتعلم كل هذه الأمور في هذه المادة، وربما تقسم هذه المادة إلى مادتين على حسب الجامعة والاختصاص الذي تدرسه، كما ستطلع على أنماط التصميم Design Patterns إذا كنت ستدرس هندسة البرمجيات؛ وهي الأنماط الشهيرة لتصميم البرمجيات بحيث لا تحتاج لإعادة اختراع العجلة مرة أخرى من أجل كل مشكلة تواجهها. 9. مبادئ أنظمة التشغيل أنظمة التشغيل هي البرمجيات الأساسية التي تُدير الأجهزة الحاسوبية والهواتف والأنظمة المدمجة وغيرها، حيث توزع الموارد على البرمجيات وتدير تشغيلها وعملها ومراقبتها للمستخدم، وأبرز أنظمة التشغيل على سطح المكتب هي ويندوز Windows وماك Mac ولينكس Linux، أم فيما يتعلق بأنظمة تشغيل الهواتف الذكية، فلدينا نظام أندرويد Android الذي يعمل على مختلف الأجهزة ونظام iOS الذي يعمل على أجهزة آبل Apple فقط. وستتعلم في هذه المادة أساسيات عمل أنظمة التشغيل المختلفة، بالإضافة لأبرز المبادئ التي تعمل بها أنظمة التشغيل الحالية مثل العمليات وأجهزة الإدخال والإخراج Input/Output وإدارة الذاكرة والوصول للمعالِج ونظام الوصول والصلاحيات وإدارة المستخدمين وغير ذلك. وستضع عليك معظم الجامعات واجبات منزلية بلغة سي C في هذه المادة، لذلك سيكون عليك تَعلّمها إن أردت اجتياز هذه المادة بنجاح. 10. مبادئ الشبكات الشبكات هي كذلك من أبرز سمات العصر الحديث فشبكات الاتصال الخلوية وشبكة الإنترنت والشبكات المنزلية كلها غيّرت شكل العالم الحديث وساهمت في فوائد جمة لا تعد ولا تحصى فبدون علم الشبكات، لن تتمكن من قراءة هذا المقال الآن. وستتعلم في هذه المادة أساسيات الشبكات وطريقة عملها، وستطّلع على بروتوكولات التواصل أشهرها بروتوكول TCP وبروتوكول UDP، كما ستطّلع على بعض المفاهيم والأجهزة الأخرى مثل الموجه Router والخوادم Servers وأجهزة العملاء Clients والنظير للنظير Peer to Peer وغير ذلك من مبادئ الشبكات البسيطة. وسيطلب منك غالبًا برمجة برنامج محادثة بسيط بأي لغة برمجةٍ تريدها وذلك باستخدام أحد بروتوكولات التواصل، وهو ما سيوضح مدى فهمك وتعلمك لهذا المساق. 11. معمارية الحاسوب إلى هنا سيكون طالب علم الحاسوب قد فهم بالفعل معظم الأساسيات التي سيحتاج إليها، ولكن مادة معمارية الحاسوب أو بنية الحاسوب Computer Architecture ستتعمق في تفاصيل دقيقة حول مكونات الحاسوب الفيزيائية وكيفية تواصلها مع بعضها بعضًا مثل طريقة تواصل الذاكرة العشوائية مع المعالِج وقرص التخزين وطريقة إرسال أو جلب المعلومات منهما. كما سيطّلع على مفهوم المسجلات Registers، وهي وحدات الذاكرة الصغيرة للمعالجات الحديثة، وكيف يستعملها لتسريع عمليات المعالجة بدلًا من جلب البيانات من الذاكرة، وسيفهم كيف ستتحول الخوارزميات والبرمجيات التي يكتبها إلى عمليات مجزأة يمكن للمعالجات حسابها في أقل من لحظة من الزمن بفضل البوابات المنطقية التي تعرّف عليها مسبقًا. أي أن هذه المادة ستغوص في تفاصيل عمل أجهزة الحواسيب وبنيتها الداخلية وطريقة تواصل مكوناتها مع بعضها بعضًا. زيادةً على المواد الأساسية التي ذكرناها آنفًا، هناك مواد ومجالات وتخصصات اختيارية يختار الطالب غالبًا ما يحلو له منها ليمارس المجال الذي يحبه، ولا يتخرج مهندسو الحاسوب وهم يتقنون كل هذه التخصصات، فعادةً ما يختارون واحدًا أو اثنين منها على الأكثر، ثم يدرسونه بصورةٍ أعمق من السابق، لذا سننتقل تاليًا إلى شرح تخصصات الحاسب التي يمكن لمهندس الحاسوب أو دارس تخصص علم الحاسوب أن يعمل ويتخصص فيها. تخصصات علوم الحاسب لا يكون هناك تخصصات واضحة في الجامعة أحيانًا، بل يمكن للطالب ببساطة أن يختار مجال أحد المواد التي درسها وأحبها ويتخصص فيها إلى حين إتمام السنوات الدراسية. سنعرض أهم تخصصات الحاسب والمجالات التي يمكن العمل فيها بعد التخرج: 1. البرمجة وهندسة البرمجيات هندسة البرمجيات وهي العلم المَعني بصناعة البرمجيات بطريقة احترافية، فهي لا تختص بالبرمجة فقط وإنما تشمل فروعًا وعمليات أكثر من ذلك بكثير. صحيحٌ أن تطوير تطبيقات سطح المكتب وتطوير تطبيقات الهواتف المحمولة هي المجالات البرمجية الأكثر شيوعًا، لكن هناك مجالات برمجية أخرى أكثر تعقيدًا مثل: برمجة أنظمة إدارة الخوادم Servers مثل Kubernetes ودوكر Docker وأشباهها من أدوات إدارة العمليات DevOps. برمجة أدوات الأنظمة المالية والاقتصادية التي تدير اقتصادات الدول والبنوك حول العالم. برمجة أنظمة الشركات العملاقة مثل شركات الطيران وشركات النفط وشركات الكهرباء …إلخ، فهذه أنظمةٌ حساسةٌ لا تحتمل الفشل وإن احتملته فهي بحاجة للاسترجاع والإدارة الفورية. الكثير من الشركات العملاقة كانت تعمل قبل عِدّة عقودٍ من الزمن على أنظمة مبرمجة بلغات برمجية قديمة عفا عليها الزمن الآن ولم يعد يُبرمَج بها، ولكن ما زالت هذه الشركات تعمل بتلك الأنظمة لعِدّة أسبابٍ لوجستيةٍ وهنا يعد نقل البرمجيات من لغة برمجة معينة إلى لغة برمجة أخرى هو مجال تخصصي كبير في علوم الحاسبات وقسم هندسة البرمجيات، فمثلًا تدفع شركة IBM رواتب عملاقة لمن يجيد نقل برمجياتٍ مكتوبةٍ بلغة COBOL إلى لغة C. ويقوم مهندسو البرمجيات بالتخطيط لعملية بناء البرمجيات اللازمة لهذه المجالات، كما يخططون للموارد التي ستلزمهم والمميزات التي سيسلمونها بالإضافة إلى نمط التصميم الذي سيستعملونه في مختلف مراحل تطوير البرنامج، ولذلك هي عملية معقدة واحترافية تحتاج إلى فريق متكامل من المبرمجين وليست مُجرّد برمجة بسيطة ينجزها فرد واحد. 2. هندسة الشبكات الشبكات ليست برامج التواصل بين المستخدمين فقط، فهناك شبكات أعقد من ذلك بكثير. ويمكنك التخصص في مجال الشبكات لتفهم طريقة عمل الشبكات البسيطة وحتى العملاقة مثل شبكة الإنترنت، والبنية التحتية لها وطريقة ربط الدول لتلك البنية التحتية، كما يمكنك التعرف على بعض أنماط الشبكات البديلة مثل النظير للنظير Peer to Peer وكيفية عمل تطبيقات مفيدة بها في الحياة الواقعية. وكذلك قد تتطرق إلى الشبكات المركبية Vehicular Networks وهي الشبكات المرتبطة بالسيارات والمركبات، أو شبكات الاتصال الخلوي وطريقة صنعها وعملها، وطريقة التعامل مع مختلف أجهزة المودم Modems. وبشكلٍ أبسط من ذلك، فيمكن أن تعمل مدير شبكات في المؤسسات والشركات الصغيرة والكبيرة وحتى مراكز إدارة الخوادم Data Centers، فلا تخلو الآن مؤسسة أو شركة من شبكة داخلية تربط أقسامها مع بعضها وهي آنذاك بحاجة إلى مدير شبكة بالتأكيد هذا أقل القليل. 3. الذكاء الاصطناعي وتعلم الآلة زاد الاهتمام بالذكاء الاصطناعي زيادة كبيرة في العقد الأخير، وهذا أمرٌ طبيعيٌ بسبب زيادة الحاجة إليه، بالإضافة إلى تَوفُّر الموارد الحاسوبية الكافية لتشغيل خوارزمياته المختلفة على أجهزة المستخدمين الشخصية، فدخل الذكاء الاصطناعي في كل شيء حولنا من إدارة إشارات المرور وتنظيم السير وتصنيف الصور في هواتفنا والتعرف على الأشخاص والوجوه والترجمة الآلية وإدارة المركبات والآلات وكشف الجرائم وعمليات التتبع وتحليل البيانات والكثير الكثير غيرها حتى بات تقريبًا عصب التقدم والتطور الذي نشهده حاليًا، وهو الأمر الذي يفسر سبب الطلب الكبير على المتخصصين في هذا المجال كما أشرنا. وهناك فرق بين الذكاء الاصطناعي Artificial Intelligence وتعلم الآلة Machine Learning؛ فالأول هو اسم المجال العام المَعني بكل ما يتعلق بإنشاء ذكاء يشابه ذكاء الإنسان باستعمال الآلات بينما الثاني مجال فرعي يتعلق بتدريب الآلات على مجموعة بيانات معينة بهدف الخروج منها بتصنيفات يمكن أن تساعد الآلة على اتخاذ قرار مطلوب منها. وستتعلم في هذا التخصص فروع تعلم الآلة الثلاثة الأشهر وهم، التعلم الموجه Supervised Learning والتعلم غير الموجه Unsupervised Learning بالإضافة إلى التعلم المعزز Reinforcement Learning، وللمزيد من المعلومات عن المجال، يمكنك الاطّلاع على كتاب مدخل إلى الذكاء الاصطناعي وتعلم الآلة. 4. الحوسبة البيولوجية الطبية لا تأتي الأجهزة الطبية الموجودة بالمستشفيات من العدم، بل يصنعها المهندسون ويساهم فيها المبرمجون، وهناك مجموعة من المواد الجامعية في تخصصات الحاسب التي تعلم الحوسبة البيولوجية الطبية الحيوية Biomedical Computing، وقد تكون تخصصًا كاملًا منفصلًا في بعض الجامعات باسم هندسة طبية حيوية biomedical engineering أو هندسة الأجهزة الطبية أو الهندسة الطبية. ويمكن أن تتخصص في هذا المجال لتتعلم أهم المتطلبات البرمجية في المجال الطبي أو البيولوجي، وكيفية تطوير برمجيات أو قطع عتاد تحل مشاكل أو تقدم استخدامات حقيقية تفيد مجال الطب والعلاج أي تقريبًا هو تخصص في مجال تصنيع الأجهزة المتعلقة في المجال الطبي من تصميم وبرمجة واختبار وتنفيذ …إلخ. ولا تستفيد المستشفيات فقط من هذا التخصص بل تستفيد كذلك مختبرات التحليل والمختبرات الحيوية والمستوصفات والعيادات الطبية وغيرها، فتحتاج جميعها إلى برمجيات صادرة عن المتخصصين في هذا المجال. 5. الرسوميات لا تُعَد الرسوميات Graphics مجالًا واحدًا فقط، فهو مجال تطوير عريض جدًا، حيث تنضوي تحته مجموعة من المجالات المتفرعة، نذكر من بينها: أنظمة التشغيل، فلها مكتبات برمجية معينة تساعدها على عَرْض الخطوط والصور والواجهات الرسومية وغير ذلك للمستخدمين، وهذا مجال ضخم، فهو ضروري لتمكين المبرمجين الآخرين من تطوير التطبيقات والألعاب لأنظمة التشغيل هذه، أي أن الرسوميات هنا هي جزء من نظام التشغيل. محركات الرسوميات Graphics Engines، وهي أنظمة برمجية عملاقة تهدف لتمكين المبرمجين من برمجة مختلف الرسوميات التي يريدونها لمختلف أنظمة التشغيل، فمثلًا يستخدم محرك Unity 3D أو Source2 أو غيرهما لبرمجة الألعاب التي تعمل على مختلف أنظمة التشغيل مثل ويندوز وماك ولينكس وأندرويد. البرامج المتخصصة في الرسم ثنائي وثلاثي الأبعاد، فتعد برمجة هذه البرمجيات مجال منفصل ويتطلب بعض الخبرات والمهارات، بينما تعلم استخدامها سيحولك إلى مصمم، وتدخل فيها برامج النمذجة modeling مثل برامج الرسم والتصميم الهندسي CAD المفيدة في الكثير من التخصصات الهندسية. برامج تحرير ومونتاج الفيديوهات مجال فرعي آخر مشهور. وتدخل الكثير من التخصصات تحت تخصص الرسوميات كما ترى، إلا أنها قد تختلف جذريًا فيما بينها، فتطوير برامج الرسم ثنائية الأبعاد لا يشبه تطوير المحركات الرسومية فعملية تطوير المحركات الرسومية واحدة من أصعب العمليات البرمجية وأكثرها تعقيدًا، لأنها تحاكي فيزياء الكون وتتطلّب فهمًا عميقًا للرياضيات. 6. تحليل البيانات وإدارة قواعد البيانات مجال تحليل البيانات (أو يرقى حتى إلى قسم منفصل باسم هندسة تحليل البيانات data analysis engineering) واحد من أكثر المجالات طلبًا حاليًا، لما له من استخدامات مفيدة وجلية في تحليل البيانات والمعطيات واستعمالها في اتخاذ القرارات المُهمَّة لدى المؤسسات والشركات، حتى إن بعض الفرق الرياضية لكرة القدم مثل ليفربول تعتمد على تحليل البيانات لوضع خططها الرياضية في كل مباراة، فتطبيقات هذا المجال واسعةٌ جدًا. كما ستتعلم في هذا المجال طريقة معالجة مجموعات ضخمة من البيانات، وطريقة تنظيفها من الأخطاء والمشاكل، وتحويلها إلى بياناتٍ يمكن معالجتها من الأنظمة الحاسوبية، وستتعلم طريقة استخراج أهم المعلومات والأسرار المخفية في البيانات الخام التي لديك بمختلف المكتبات واللغات البرمجية. حتى تتقن فن التعامل مع البيانات، فيجب أن تتقن التعامل مع أنظمة قواعد البيانات التي تخزَّن فيها البيانات، لذا يتخصص هذا المجال في مفهوم قواعد البيانات Databases وأنظمة إدارة قواعد البيانات database management systems تختصر إلى DBMS بتعمق كبير فهي مدخل إلى التعامل مع البيانات والتلاعب بها وتطويها والغوص فيها لاستخراج المعلومات. قد يتفرد هذا المجال في تخصص بمفرده في الدراسات العليا أو حتى في سوق العمل، فقد تطلب بعض الشركات متخصص لإدارة قواعد بياناتها وله المسمى الوظيفي "مدير قواعد بيانات" Database Administrator. وتشمل مشاريع تحليل البيانات عادة: جمْع البيانات من مصادرها. تنظيف وتهيئة البيانات للمعالجة وإزالة القيم الشاذة. إدخال البيانات في الأنظمة الحاسوبية المطلوبة لاستخراج النتائج والمعلومات الأولية منها، ومن أين يُبدَأ في البحث عن روابط مفيدة بين أجزائها. تحليل أعمق للبيانات إما عبر أنظمة أكثر تقدمًا أو عبر تَعلّم الآلة، وقد تُستعمل أنظمة التعرف على الأنماط Pattern Recognition كذلك. تهيئة النتائج السابقة للعرض والمشاركة عبر بعض الأدوات الشهيرة. عرض النتائج والتقارير مع المخططات والتوصيات. وتعد بايثون أكثر لغات البرمجة طلبًا في هذا المجال، بالإضافة لمكتباتها الشهيرة مثل Pandas وNumpy وJupyter Notebook وMatplotlib وغيرها، وكذلك تستعمل لغة R في هذا المجال، ولكنها ليست بنفس شيوع بايثون، أما بالنسبة لقواعد البيانات، فيجب أن تقن لغة SQL وتتقن بعدها أنظمة التعامل مع قواعد البيانات. ولتَتعلّم أساسيات بايثون بسهولة، بإمكانك الاطّلاع على كتاب البرمجة بلغة بايثون كما يمكنك الاطلاع على كتاب ملاحظات للعاملين بلغة SQL وكتاب الدليل العملي إلى قواعد بيانات PostgreSQL. 7. أنظمة التشغيل والأنظمة المدمجة تحتاج جميع الحواسيب والهواتف الذكية والأجهزة الإلكترونية عمومًا إلى نظام تشغيل Operating System لتعمل وفق رغبات المستخدم، وهذه الأنظمة هي الأخرى لا تأتي من العدم بل هناك متخصصون لبرمجتها وجعلها أفضل من غيرها والحفاظ عليها مع الزمن. تطوير أنظمة تشغيل سطح المكتب مثل ويندوز وماك ولينكس، أو أنظمة الهواتف الذكية مثل نظام أندرويد ونظام iOS وغيرهما، هي مجالات برمجية متقدمة تعتمد على خبرات ومهارات متعددة، كما يعتمد هذا على العتاد Hardware الذي ترغب ببناء نظام تشغيل له، وقد تُستخدَم أكثر من لغة برمجية في الوقت نفسه لتطوير نظام تشغيل بسيط، فتطوير أنظمة التشغيل عملية عملاقة ومكلفة وتحتاج الكثير من المهندسين، كما ينفق عليها ملايين الدولارات من الاستثمار المستمر على امتداد عدة سنوات للخروج بنتائج مرضية، ولهذا ربما تجد أن هناك ملايين البرمجيات الصغيرة حول العالم، بينما يوجد ثلاث أنظمة شهيرة لسطح المكتب ونظامان للهواتف الذكية فقط، ورغم أنه هناك بالفعل العشرات غيرها إلا أنها محدودة وضعيفة المزايا موازنة بتلك الأكثر استخدامًا والأكبر دعمًا حاليًا؛ وذلك لأن مطوريها لا يمتلكون نفس موارد وإمكانات مطوري الأنظمة الشائعة ذات الدعم الكبير. أما الأنظمة المدمجة Embedded Systems فهي الأنظمة التي تعمل مع موارد عتاد Hardware Resources محدودة للغاية، فهي تُنفّذ مهامًا محدودةً وصغيرةً مثل أنظمة الإشارات والاستشعار والأقفال الإلكترونية وألعاب الأطفال وحتى أنظمة إدارة السدود المائية وأنظمة الأجهزة العسكرية …إلخ، كما أن برمجتها مجالٌ منفصلٌ لوحده، ويوجد به الكثير من التفرعات كذلك وهو علم ضخم ذاع صيته هذه الأيام وأهم مجال تفرع عنه هو مجال إنترنت الأشياء Internet of Things تختصر إلى IoT وهي برمجة العتاد مع ربطه بالإنترنت مثل أنظمة مراقبة المباني وأقفالها وأنظمة البيوت الذكية وغيرها. أصبحت هنالك برامج واختصاصات دراسات عليا وحتى درجات جامعية تُدرِّس هذا المجال. 8. الأمان الرقمي الأمان الرقمي مجال كبير تنضوي تحته عدة أمور، مثل أنظمة التشغيل والبرمجيات العادية والشبكات والتعمية وغيرها، فكلها أمور مترابطة تحتاج لتأمين واستخدام أفضل للتقنيات وذلك للتأكد من عدم وصول الأشخاص غير المخوّلين لها. وبينما هناك مجالاتٌ متعلقةٌ بالأمان الرقمي الشخصي للمستخدمين، هناك مجالاتٌ متعلقةٌ بالأمان الرقمي الجنائي أو العسكري بين المجرمين وأجهزة الشرطة وبين الدول وبعضها البعض، كما أن هناك مجالاتٌ متعلقةٌ بالشبكات وإدارة الخوادم وغير ذلك الكثير، وكلها أمورٌ يمكن أن تتخصص بها إذا رغبت بذلك. ولمعلومات مفيدة حول الأمان الرقمي الشخصي والخصوصية، اطلع على كتاب دليل الأمان الرقمي. 9. الحوسبة العلمية تعتمد العديد من الصناعات التي تراها حولك اعتمادًا أساسيًا على علم الحاسوب لإتمام مهامها بنجاحٍ، فأغلب ما تراه حولك قد عولج في الحاسوب بدءًا من البناء الذي تقطنه والذي قد صمم واختُبر باستعمال برامج حاسوبية صممت البناء ونمذجته واختبرته على الزلازل ومختلف العوامل للتأكد منه ومن تصميمه وحتى قطع وقطع البلاستيك وأجزاءها قد صممت أيضًا باستعمال برامج حاسوبية عملاقة وهكذا، وكل هذه البرامج تعمل بخوارزميات ضخمة تحتاج للكثير من العمليات الرياضية التي تحل معادلات مختلفة، وهي بدورها تعتمد على خوارزميات محددة لتبسيطها وحسابها وهذا ما يدخل ضمن مجال الحوسبة العلمية Scientific computing. كما توجد مجالات كثيرة أخرى مثل هذه لا مجال لحصرها الآن ولكن نذكر منها مجال الحوسبة التطورية Evolutionary Computation وهي العلم الذي يأخذ نظرية التطور والحالات المعقدة المتطورة ويحولها إلى نظام قابل لحل الكثير من المشاكل في الحياة الواقعية، فيمكن استخدام هيكلة ومبادئ نظرية التطور لتطوير خوارزمية تساعدنا على معرفة عدد المطارات والمدارج التي علينا وضعها في كل مدينة. 10. الحوسبة السحابية توفر الآن الكثير من الشركات خدمات سحابية Cloud Services للمستخدمين وفكرة الحوسبة السحابية Cloud computing ببساطة إلغاء العمل على نظام تشغيل سطح المكتب لتخزين وتشغيل وإدارة الخدمات والبرامج التي تريدها والاعتماد كليًا على خدمات بعيدة موجودة على حواسيب وخوادم مركزية عملاقة تستفيد من الإنترنت للوصول إليها لفعل نفس الأمور السابقة. فمثلًا بدلًا من تشغيل خادم قاعدة البيانات الخاص بك يمكنك الاعتماد على أحد الحلول الجاهزة من أمازون Amazon أو ديجيتال أوشين Digital ocean، كما يمكنك استعمال فيجوال ستوديو من مايكروسوفت عبر الإنترنت لأداء مهامك البرمجية بدلًا من استخدام مُحرر النصوص البرمجي الخاص بك على نظامك. ويمكنك كذلك أن تستأجر خوادم فيزيائية Dedicated Servers ثم تُقسّمها إلى خوادم افتراضيةٍ Virtual Servers وتُوزّعها على مستخدمين آخرين حسب الموارد، ثم تُوّفر لهم خدمات جاهزة Software-as-a-Service واختصارًا SaaS، وهذا هو مبدأ شركات الاستضافة الحديثة والمجال السائد فكل ما تراه أصبح مخزنًا وموجودًا على سحابة وتصل إليه أو تستعمله عبر الإنترنت لذلك زاد الطلب على متخصصين في هذا المجال وتكون المسميات الوظيفية باسمه عادة مهندس حوسبة سحابية Cloud Computing Engineer. 11. تخصصات أخرى هناك مجالات ضمن علم الحاسوب تبتعد عن العلوم التطبيقية البرمجية، وتبحث في المبادئ النظرية لما تقدمه علوم الحاسب للتخصصات والمجالات الأخرى في الحياة. نظرية المعلومات Information Theory وتتحدث عن المبادئ النظرية لنقل المعلومات الرقمية ومحتواها، وإلى أي مدى يمكن ضغطها وبأي سرعاتٍ يمكن الوصول إليها. نظرية الإشارات Signal Theory وتتحدث عن الإشارات التي تُصدِرها الكائنات الحية وكيف يمكن تحديد العلاقات بينها وكيفية نمذجتها في الأنظمة الرقمية بهدف دراستها وتحليلها. نظرية الفوضى Chaos Theory ورغم أنها نظريةٌ رياضيةٌ لا تنضوي تحت علوم الحاسوب بصورةٍ مباشرةٍ، إلا أن لها تطبيقاتٌ واضحةٌ في عِدّة مجالاتٍ مثل حالة الطقس والمناخ والأنظمة المصممة لتوقّعها والتبليغ عنها، فهي تعتمد على علوم حاسوبية مثل التعمية والروبوتات وغيرها. علم التعمية Cryptography وهو واحدٌ من أكثر العلوم أهمية في علوم الحاسب لأن تطبيقاته هي التي تسمح بتشفير البيانات، ويعتمد على المبادئ الرياضية بشدةٍ، كما أنه شديد التعقيد، حيث تقوم عليه أنظمة الأمان الرقمية حول العالم بما في ذلك الأنظمة الاقتصادية. والكثير من هذه العلوم هي علوم نظرية تعتمد على مجالات متداخلة Interdisciplinary مع علوم الحاسبات، إلا أن علوم الحاسبات مركزية وأساسية فيها. كيف أختار التخصص المناسب لي من تخصصات علوم الحاسب؟ ليست كل التخصصات السابقة الذكر متوفرة في مجالات علوم الحاسب بالطبع، فهناك غيرها ولكن ذكرنا الأشيع والأشهر منها، ويبرز هنا سؤال وهو كيف يمكن لداخل جديد إلى هذه العلوم أن يختار التخصص المناسب له والذي يحبه؟ وتكمن الإجابة في معرفة المرء بنفسه وأين يحب أن يعمل فإذا كنت تحب الرياضيات فربما تناسبك العلوم النظرية، وإذا كنت تحب العمل مع الخوارزميات وتطوير الجديد منها لتسريع حل مشكلات الجنس البشري وابتكار حلول أفضل فربما قد يكون هذا اختصاصك، أو ربما ببساطة تحب تطوير البرمجيات والتطبيقات وحينها لن تحتاج شيئًا أكثر من المعارف الأساسية في علوم الحاسب ثم التخصص في تعلم البرمجة. لذا عليك أن تنظر في هذه المجالات المختلفة، ثم تسأل نفسك في أي منها يمكن أن تعمل دون أن تشعر بالملل بعد فترة؟ وستجد بضع مجالات قد تعجبك وستستبعد بعض المجالات الأخرى، فمثلًا أنا أستبعد أن أعمل في المجالات الرياضية أو مجالات التشفير، ببساطة لأنني لا أحب تعقيدها، وبعدها حاول أن تصرف بعض الساعات من وقتك في هذه المجالات التي تبقّت معك لتتعرّف عليها وترى أبرز المشاريع الموجودة فيها، وهل أحسست براحة وانشراح للنفس أثناء دراستها والعمل فيها، أم أنك تريد غيرها؟ الخلاصة، جرب التخصص والقراءة الدراسة في كل تخصص فترة من الزمن وبعدها إما أن تكمل أن تنتقل إلى تخصص آخر وهكذا تعرف الاختصاص الصحيح المناسب لك، وبعد فترة ستجد مجالات واضحة معينة لن تحب العمل في غيرها، وتلك هي المجالات التي يمكنك البدء بدراستها والتخصص بها بعد أن تنتهي من دراسة علوم الحاسوب الأساسية. التوظيف وفرص العمل في مجال علوم الحاسب تقل أهمية الشهادة الجامعية تدريجيًا في التوظيف عندما يتعلق الأمر بعلوم الحاسوب فشركات مثل جوجل بدأت تهتم بالخبرة وتعمل على نشر شهاداتها الخاصة والتي تبلغ مدتها 6 أشهر في حال عدم وجود الشهادة الجامعية، كما أن كثيرًا من الشركات الأخرى تشترط وجود الخبرة ومعرض الأعمال بدلًا من الشهادة الجامعية للمتقدِّم. وتبلغ مدة أغلب الشهادات الجامعية في معظم البلدان 4 سنوات، وهي مدةٌ طويلةُ جدًا يذهب معظمها بالانتظار والفراغ بين الحصص الدراسية الأسبوعية وتعلم علوم ومواد قد لا يكون لها أهمية كبيرة وقد تنساها بعد التخرج هذا لم نتحدث عن قلة المقاعد الدراسية الحكومية المجانية والمنافسة الشديدة عليها أو غلاء الجامعات الخاصة مما يزيد من العوامل التي تعيق أصلًا دخول الجامعة أو اختيار التخصص الذي ترغب دراسته في الجامعة فقد تضطر من أجل الدخول للجامعة والحصول على درجة جامعية أن تدرس تخصصًا لا تحبه ولا يناسبك أصلًا وهنا الحديث يطول، على أي حال، وبما أن علوم الحاسوب مجال مرتبط بالحواسيب التي بين أيدينا فقد لجأت نسبة لا بأس بها ممن يرغبون التخصص في المجال بتعلم المعلومات المطلوبة من مصادر خارجية لا علاقة لها بالجامعات الأكاديمية، دون الحاجة للدراسة الجامعية التقليدية ودخلوا سوق العمل فعليًا. ولا نريد محو أهمية الشهادات الجامعية، وذلك لأنها ما تزال تطلبها الحكومات والدول رسميًا للعمل في الوظائف الحكومية، كما لا تزال لها سمعة في الأوساط الاجتماعية على عكس من يتعلم تلك العلوم بمفرده، ولكن إذا كانت المعرفة والعمل ما يهمك فقط فحينها لا مشكلة من الخوض في المجال بعيدًا عن الدراسة الجامعية، وبذلك تكسب سنوات من عمرك بالإضافة إلى توفير الكثير من المال الذي كنت ستصرفه على الشهادة الجامعية. فمثلًا، يمكنك خلال فترة تترواح من ستة أشهر إلى سنة أن تتعلم أساسيات علوم الحاسوب وأن تبدأ العمل فيها مثلًا أن تتخصص في البرمجة وتطوير المواقع وتدخل سوق العمل وأغلب الدورات الحرة التي تعلم الاختصاص تكون مدتها ستة أشهر وحتى السنة وهي كافية لوضع قدمك على الطريق ودخول وكسب فرصة عمل. فمؤسسي أكبر الشركات التقنية في العصر الحديث، مثل مارك زوكيربيرغ مؤسس فيسبوك، وجاك دورسي مؤسس تويتر، وستيف جوبز مؤسس آبل لم يتخرجوا من الجامعات، وكذلك فهناك غيرهم الكثير من مدراء ورؤساء الشركات التقنية، ولهذا لن تكون الشهادة الجامعية عائقًا أمامك في حال أردت سلوك نفس المسار العصامي. وهنالك الكثير من المبرمجين الماهرين اليوم الذين لم يدخلوا إلى الجامعة أو درسوا اختصاصًا مختلفًا وهم يعملون في شركات كبيرة منها شركة IBM وهو لا يملك درجة في أي تخصص من تخصصات الحاسب وحتى أنه يساهم في كتابة بحث مع من درس في أروقة الجامعات. أضف إلى ذلك أنه يمكنك العمل كعامل مستقل على حسب الاختصاص الذي تجيده من اختصاصات علوم الحاسوب؛ فلو كنت مطور ويب محترف فيمكنك تطوير المواقع الإلكترونية للعملاء عبر مواقع العمل الحر مثل مستقل، ففي العمل الحر لن يسألك أحد بتاتًا عن شهادتك الجامعية وكل ما سيسألونك عنه هو خبراتك ونماذج لأعمالك السابقة نفذتها لا أكثر. أما عن فرص العمل المتوفرة في الشركات فهي تختلف باختلاف البلدان والشركات التي تريد العمل فيها، ولكنها تنضوي جميعًا تحت قسم التخصصات الذي تحدثنا فيه بصورة موسعة عن تخصصات علوم الحاسوب التي يمكن للمرء الاختصاص فيها، فمثلًا يمكنك العمل بتخصص مهندس برمجيات أو يتخصص في مجال الذكاء الاصطناعي أو مطور أنظمة تشغيل …إلخ على حسب المسميات الوظيفية المتوفرة في الشركات. انظر مثلًا إلى موقع بعيد، حيث تجد فيه طلبات توظيف من شركات مختلفة حول العالم العربي، وستجد أن معظم الوظائف لا تشترط أي نوع من أنواع الشهادات، بل تشترط معرض أعمال وخبرة سابقة فقط. وتكون رواتب المتخصصين في علوم الحاسوب متعلقة بعدة عوامل منها التخصص والخبرة والأعمال المنجزة وكذلك باختلاف الشركات والأماكن والدول، لكن يمكننا القول بصورة عامة أن رواتبهم أعلى من المهندسين الآخرين، ويمكنك البحث عن المواقع التي تَعرِض لك متوسط الرواتب التي يتلقاها الموظفون حسب المهنة في بلدك ثم البحث فيها عن التخصصات السابقة لرؤية مُعدّل الرواتب في بلدك. ما الفرق بين علوم الحاسب وهندسة الحاسب؟ على عكس الشائع فلا يوجد فرق جوهري بين علوم الحاسب computer science وهندسة الحاسب computer engineering وذلك لأن الجامعات الموجودة في دول مختلفة حول العالم تتعامل مع المصطلحين بطريقة مختلفة، فتجد في بعض الجامعات وفي بعض البلدان أن التخصصين مجرد اسمين مختلفين لنفس المواد الجامعية، فمثلًا الجامعة التي تخرجت منها كان تخصصي فيها هو هندسة وعلوم الحاسوب، أي أنني درست الاثنين معًا، ولم يكن هناك فرق في المواد التي درسناها مع الجامعات الأخرى. أما في بعض البلدان الأخرى مثل الولايات المتحدة هناك فرق حيث تكون علوم الحاسب علومًا أقرب للأقسام النظرية والفهم العام لمختلف المجالات والتخصصات، بينما تركز هندسة الحاسوب بالتحديد على علوم البرمجيات Software وعلوم العتاد Hardware والعلاقات والمشاريع التي يمكن تنفيذها بالدمج بينهما، أي أن هندسة الحاسوب تخصص هندسي تقليدي أقرب للعلوم العملية من تخصص علوم الحاسوب الأقرب للعلوم النظرية المفاهيمية. ويُعَد مصطلح علوم الحاسوب مصطلحًا جديدًا نسبيًا إذ كان التركيز قديمًا على هندسة البرمجيات Software Engineering وهندسة الحاسوب Computer Engineering وشاع المصطلح بعد 2010م وصار يشمل كل هذه العلوم وأكثر. من أين أبدأ بتعلم علوم الحاسوب؟ إن كنت تفكر بالدراسة الجامعية الأكاديمية، فهي من سيرشدك للبدء ويوفر لك المواد المتسلسلة في سنوات الدراسة ويؤمن لك كل شيء خلال رحلتك في دراسة علوم الحاسب وتخصصاته أما إن كنت ممن يريد دراسة مجال علوم الحاسوب ذاتيًا والتخصص فيه دون اللجوء إلى الجامعة، فأنت في المكان الصحيح الذي سيرشدك إلى بداية الطريق. من الأفضل لك أن تبحث عن بعض الدورات المتكاملة للبدء في تعلم علوم الحاسب بدلًا من الدروس المتفرقة، فمن الصعب على طالب جديد لا يعرف شيئًا في المجال أن يدخل فيه مباشرةً ويتعلم ما يحتاج إليه من دروس في كل مادة وتخصص من تلك المواد والتخصصات، بينما الدورات المتكاملة تكون مجهزة وكاملة وفق خطة معينة من متخصصين. عملت أكاديمية حسوب على توفير دورة متكاملة عن أساسيات علوم الحاسب هي دورة علوم الحاسوب وهي دورة شاملة مدتها عشرات الساعات حول علوم الحاسوب بدءًا من أبسط الأساسيات وصولًا إلى الخوارزميات وهياكل البيانات والبرمجة وقواعد البيانات وتطوير الويب وإدارة الخوادم، كما أنها تحت التوسيع والتحديث المستمر، ومن أبرز ميزاتها أن هناك من يتابع سَيْرَك ويجيب على أسئلتك على امتداد الدورة وليست فقط مجرد فيديوهات. ستكون مؤهلًا بعد الدورة من التخصص والغوص في إحدى مجالات علوم الحاسب التي تحبها وتريد تعلمها وقد وفرت الأكاديمية بعد دورة علوم الحاسب دورات أخرى إن أحببت الاختصاص في مجال البرمجة وتطوير البرمجيات لإكمال طريقك وستكون جاهزًا لدخول سوق العمل وبدء الكسب مما تعلمت خلال فترة قصيرة لا تتجاوز السنة بناءً على همتك وعزيمتك. وإذا وصلت إلى مرحلة أنت جاهزٌ فيها لتَعلّم البرمجة، فيمكنك قراءة الدليل الشامل لتعلم البرمجة باستخدام المصادر العربية ففيه أبرز المصادر العربية المتوفرة في الشبكة لتعلم البرمجة. كما يمكنك البحث في الشبكة عن سلاسل فيديوهات أو كتب لتُعلّمك تخصص علوم الحاسب بأي لغةٍ تجيدها، وجوجل مليءٌ بالنتائج عن ذلك كما أن أكاديمية حسوب تعمل جاهدًا على توفير مراجع عالية الجودة لتساعدك في ذلك، فتابع دومًا قسم المقالات البرمجية وقسم الكتب البرمجية. خاتمة وصلنا إلى نهاية هذا المقال بعد أن اطلعنا على أبرز علوم الحاسب وماهية التخصصات الموجودة فيه، ولا تنسَ أن هذا المقال مجرد مقدمة وسيكون عليك صَرْف العديد من الساعات لتتعلّم هذا المجال وتغوص فيه بصورة أعمق. وصحيح أن تعلم علوم الحاسوب قد يكون صعبًا في البداية للوافدين الجدد عليه، ولكن النتيجة مثمرةٌ جدًا حيث يمكنك استخدام أحد أبرز العلوم في العصر الحديث وأهمها لأي غرض أو هدف تريده، سواء كان ذاك الهدف شخصيًا أو ماديًا بهدف الكسب والرزق. إن كان لديك أي سؤال أو استفسار، فلا تتردد بطرحه في التعليقات ونسعد بمشاركتنا تجربتك، أرجو لك التوفيق والسداد! اقرأ أيضًا دليلك الشامل لتعلم البرمجة دليل شامل عن تحليل تعقيد الخوارزمية المرجع الشامل إلى تعلم لغة بايثون ما هي فوائد تعلم البرمجة؟ مدخل إلى الذكاء الاصطناعي وتعلم الآلة
    3 نقاط
  2. نحن نسمي أنفسنا "إنسان عاقل أو حكيم"، لأن ذكائنا أمر مهم جدًا بالنسبة لنا. لقد حاولنا منذ آلاف السنين أن نفهم كيف نفكر، أي كيف يمكن للعقل البشري أن يدرك ويُحلل ويفهم ويتنبأ ويتلاعب بعالم كبير ومعقد. يذهب الذكاء الصناعي إلى ماهو أبعد من ذلك؛ يحاول فهم الكيانات الذكية إلى جانب بناء كيانات ذكية أيضًا. الذكاء الاصطناعي هو أحد أحدث المجالات في العلوم والهندسة، وقد بدأ العمل به بجدية بعد الحرب العالمية الثانية بفترة وجيزة، لكنه لم يُبصر النور إلا مع بداية القرن الحادي والعشرين، حيث بدأ الإنترنت والبيانات بالانتشار إلى جانب تطور أجهزة الحواسيب. يتميز الذكاء الصناعي بأنه علم كبير وتعددي؛ يشارك فيه علماء الحاسوب والرياضيات والهندسة واللغة والفلسفة والمنطق. الذكاء الاصطناعي وثيق الصلة بأي مهمة فكرية؛ إنه مجال عالمي. ماهو الذكاء الاصطناعي لنتفق بدايةً أنّه لا فرق في قول "الذكاء الاصطناعي" أو "الذكاء الصناعي" بالعربية، فكلاهما يُشيران إلى شيء من صنع البشر وليس الطبيعة. مفهوم الذكاء الصناعي Artificial Intelligence -اختصارًا AI- هو مجال جديد ظهر تقريبًا عام 1950 على يد آلان تورينج (يُسميه البعض الأب الروحي للذكاء الصناعي) المقصود به باختصار هو جعل الآلة تفكر وتعمل مثل الإنسان. في البداية لاقى هذا المجال الكثير من الصعوبات لأن العلماء كانوا يحاولون محاكاة الذكاء والتفكير البشري، محاولين جعل الآلة تفكر وتعمل مثل الإنسان. بسبب هذا التفكير فشل العلماء في الوصول إلى تقدم حقيقي في هذا المجال، لأنه رغم كل التقدم الذي وصلت إليه العلوم لم يستطع العلماء تحديد الطريقة التي يفكر بها الإنسان. وصل العلماء لاحقًا إلى قناعة تفيد بأننا كبشر لا يهمنا كيف تعمل الآلة (أي لن نُقيد الآلة بطريقة التفكير البشري)؛ المهم أن نحصل على نفس النتيجة التي نحصل عليها من خلال الإنسان، فالإنسان يرى الصورة على أنها انعكاسات للضوء، والآلة ترى الصورة على أنها مصفوفة من البيكسلات والأصفار والواحدات. آنذاك بدأ الذكاء الصناعي بالتطور ودخل جميع مجالات حياتنا العملية سواءًا المجال العسكري والطبي والصناعي والتجاري وحتى التعليمي والترفيهي، فكانت دقة الأداء عالية جدًا، وفي بعض المجالات كانت نسبة الخطأ شبه معدومة، أي أن الآلة بدأت تحاكي التفكير البشري، حتى أنها أصبحت أفضل منه في كثير من المجالات، فالعلوم حاليًا هي علوم الذكاء الصناعي. إن كان الإنترنت هو ثورة السنوات الماضية، فالذكاء الصناعي هو ثورة الحاضر والمستقبل. تعريف الذكاء الاصطناعي الذكاء الصناعي هو مصطلح صاغه البروفيسور الفخري في جامعة ستانفورد جون مكارثي في عام 1955 لأول مرة ضمن ورشة عمل صيفية تسمى مشروع دارتموث الصيفي للبحوث حول الذكاء الاصطناعي على أنه: بالرغم من أن هناك اختلافات حول التعريف، إلا أن الجامعة الأشهر في الذكاء الصناعي "ستانفورد" تعتمده. من التعاريف الأخرى هو التعريف الذي صاغه أندرياس كابلان ومايكل هاينلين، وينص على أن الذكاء الصناعي هو: تُركز تعريفات الذكاء الاصطناعي الحديثة على أنّه مجال فرعي لعلوم الحاسب وكيف يمكن للآلات تقليد الذكاء البشري. يُقدم قاموس أكسفورد هذا التعريف: ما هو ذكاء الآلة ومتى نقول عن الآلة أنها ذكية؟ يُجيب عن هذا السؤال اختبار تورينج (نسبةً لآلان تورينج). إنها أشبه بلعبة بين ثلاث أطراف؛ اثنان من البشر (الأول لاعب والثاني حكم أو مراقب) والآلة المُراد اختبارها إن كانت ذكية (اللاعب الثاني). اللاعبين الثلاثة معزولين عن بعضهم البعض، ويكون التراسل بين الأطراف كتابيًا. يبدأ المراقب بطرح أسئلة على اللاعبين (الحاسب والشخص الآخر). ينجح الحاسوب في الاختبار (يكون ذكي) إذا لم يستطع المراقب التفريق بينه وبين الإنسان. عبقرية هذا المفهوم هي أنه ليست هناك حاجة لمعرفة ما إذا كانت الآلة تعرف شيئًا ما بالفعل أو أنها تُدرك ذاتها أو حتى إذا كانت إجاباتها صحيحة، وإنما يشير إلى قدرة تلك الآلة على معالجة كميات كبيرة من المعلومات وتفسير اللغة البشرية. الذكاء الاصطناعي وتعلم الآلة على الرغم من الخلط بين المصطلحين في بعض السياقات، إلا أن تعلم الآلة فرع من فروع الذكاء الصناعي العديدة. يشير الذكاء الصناعي إلى أي أسلوب يُعطي الآلة القدرة على محاكاة الذكاء البشري، بينما يشير التعلم الآلي إلى مجموعة التقنيات والخوارزميات التي تسمح للآلات بالتعلم من البيانات دون أن تُبرمج عليها صراحةً. ما أهمية الذكاء الاصطناعي؟ يُنظر إلى تقنيات الذكاء الصناعي على أنها أدوات وتقنيات تهدف لخدمة البشرية وتسهيل حياة الأفراد، فهي تهدف إلى جعل حياتنا أسهل، كما يمكن تطبيقه في جميع المجالات تقريبًا للحصول على كفاءة أعلى. فيُقدم الذكاء الصناعي العديد من الميزات والحلول التي تعود بالفائدة لأي مؤسسة حديثة تقريبًا، يتضمن ذلك: أتمتة العمليات: الذكاء الاصطناعي قادر على أتمتة المهام التي نُنجزها يدويًّا وبدقة وسرعة دون الشعور بأي إرهاق أو الاضطرار إلى أخذ فترات راحة مثلما يحتاج الموظف البشري (مثلًا مراقبة السيارات والإبلاغ عن المخالفات). تحليل البيانات الضخمة: كمية البيانات الموجودة حاليًّا على الإنترنت تفوق بكثير قدرة البشر على استيعابها وتفسيرها واتخاذ قرارات معقدة بناءً عليها. يمكن لخوارزميات الذكاء الصناعي معالجة تلك البيانات وتحليلها وفهمها، وبالتالي تمنح المؤسسات رؤى حول عملياتها ربما لم تكن على دراية بها من قبل. اتخاذ القرارات: يمكن لخوارزميات الذكاء الاصطناعي اتخاذ قرارات أكثر دقة من البشر في بعض الأحيان نظرًا لقدرتها على تحليل العلاقات المعقدة والمتعددة والاستفادة من البيانات الضخمة المنتشرة على الإنترنت. مجالات الذكاء الاصطناعي يعد الذكاء الاصطناعي مجالًا واسعًا للدراسة يتضمن العديد من النظريات والأساليب والتقنيات المختلفة، ومن أبرز مجالات الذكاء الاصطناعي مايلي: تعلم الآلة Machine learning: عرّف آرثر صموئيل تعلم الآلة بأنّه المجال الذي يعطي الحاسوب القدرة على التعلم من المشاكل التي يصادفها دون تعليمات واضحة تُعطى له، أي القدرة على معالجة مشاكل جديدة. الشبكات العصبية الاصطناعية Artificial Neural Networks: عبارة عن مجموعة من الخوارزميات المُصممة بطريقة مُستوحاة من الخلايا العصبية في الدماغ البشري، وهي مصممة للتعرف على الأنماط. التعلم العميق Deep Learning: يستخدم شبكات عصبية ضخمة مع العديد من طبقات وحدات المعالجة، حيث يستفيد من التطورات الحوسبية الكبيرة (المعالجات القوية مثلًا) وتقنيات التدريب المحسنة لتعلم الأنماط المعقدة بكميات كبيرة من البيانات. أتمتة العمليات الآلية Robotic Process Automation: يمكن أن يكون مصطلح أتمتة العمليات الآلية مربكًا بعض الشيء؛ لا تعني كلمة آلية أو روبوتية هنا الروبوتات المادية، وإنما الروبوتات التي تُمثل برامج (برامج آلية) تُنفِّذ بعض العمليات التقليدية المكررة، مثل وإدارة المعاملات وإرسال الفواتير وتقديم ردود نموذجية للعملاء (روبوتات الدردشة، لابد وأنك تعرفها). الروبوتات Robots: هو آلة يمكنها إنجاز المهام الموكلة إليها من خلال تنفيذ سلسلة معقدة من الإجراءات تلقائيًا. يمكن توجيه الروبوت بواسطة جهاز تحكم خارجي، أو قد يكون عنصر التحكم مضمنًا فيه. الأنظمة الخبيرة Expert systems: النظام الخبير هو محاولة جمع الخبرة البشرية المتعلقة بمجال محدد ضمن الحاسب لكي يحل محل الخبير، أو يمكننا القول أنّه برنامج مصمم لينفد مهاماً متعلقة بالخبرة البشرية، وهذا يتضمن التحليل والتشخيص واتخاذ القرارات والتنفيذ أيضًا. المنطق الترجيحي أو الضبابي Fuzzy Logic: المنطق الضبابي هو نهج للحوسبة يعتمد على "درجات الحقيقة degrees of truth" بدلاً من المنطق الثنائي "صح أو خطأ" المعتاد (1 أو 0) الذي يعتمد عليه الحاسب ويحاول حل المشكلات باستخدام طيف مفتوح وغير دقيق من البيانات والاستدلالات التي تجعل من الممكن الحصول على مجموعة من الاستنتاجات الدقيقة. لمزيد من التفاصيل المتعلقة بفروع أو مجالات الذكاء الصناعي، يمكنك قراءة مقالة مجالات الذكاء الاصطناعي. تعمل العديد من التقنيات على تمكين ودعم تطبيق الذكاء الاصطناعي منها: الرؤية الحاسوبية Computer vision تعتمد على خوارزميات التعلم العميق للتعرف على ما هو موجود في الصورة (أو الفيديو) وتحليلها وفهمها وتفسير مكوناتها. معالجة اللغة الطبيعية Natural language processing هي قدرة أجهزة الحاسب على تحليل وفهم وتوليد اللغة البشرية، بما في ذلك الكلام. تطور خوارزميات الذكاء الصناعي نقل هذا المجال من الظلام إلى النور. علم البيانات Data science: هو دراسة البيانات لاستخراج رؤى ذات مغزى تخدم الأعمال والمؤسسات. إنها مصطلح شامل للتقنيات الإحصائية وتقنيات التصميم وطرق التطوير. يُستخدم الذكاء الاصطناعي فيها بشكل متزايد للتعامل مع البيانات، وإزالة الإنسان من المهمة بأكملها للعمل بمفرده. إنترنت الأشياء Internet of things، هو ربط الأشياء (كرسي طاولة ثلاجة ..إلخ) مع بعضها البعض من خلال الإنترنت، وتمكينها من الاتصال مع بعضها البعض وتبادل المعلومات واتخاذ القرارات؛ أي باختصار "هو جعل الأشياء تتكلم وتتخذ القرارات من أجل خدمتنا". تعتبر وحدات المعالجة الرسومية Graphics processing unit مفتاحًا للذكاء الاصطناعي لأنها توفر القوة الحوسبية الكبيرة المطلوبة للمعالجة. يتطلب تدريب الشبكات العصبية بيانات كبيرة بالإضافة إلى قوة حوسبية. واجهات برمجة التطبيقات APIs عبارة عن حزم من التعليمات البرمجية التي تتيح إمكانية إضافة وظائف الذكاء الصناعي إلى المنتجات الحالية والبرامج. أنواع الذكاء الاصطناعي هناك عدة أنواع للذكاء الصناعي يمكن وضعها ضمن فئتين، الأولى تعتمد على القدرات والثانية تعتمد على الوظيفية. بالنسبة لفئة القدرات، تنقسم إلى: ذكاء اصطناعي ضعيف أو ذكاء اصطناعي ضيق: هو الذكاء الاصطناعي الذي يتخصص في مجال واحد (يستطيع تنفيذ مهمة واحدة فقط). ذكاء اصطناعي عام: حواسيب بمستوى ذكاء الإنسان في جميع المجالات. ذكاء اصطناعي خارق: هو ذكاء اصطناعي يفوق ذكاء وقدرة الإنسان. أما بالنسبة للفئة التي تعتمد على الوظيفة تنقسم إلى: الآلات التفاعلية Reactive machines: لا تتضمن أنظمة الذكاء الاصطناعي هذه ذاكرة، ويكون لها مهمة معينة. ذاكرة محدودة Limited memory: تتمتع أنظمة الذكاء الاصطناعي هذه بذاكرة، لذا يمكنها استخدام الخبرات السابقة في القرارات المستقبلية. نظرية العقل Theory of mind: يجب أن يفهم الذكاء الاصطناعي المشاعر البشرية والناس والمعتقدات وأن يكون قادرًا على التفاعل اجتماعيًا مثل البشر. الإدراك الذاتي Self-awareness: مستقبل الذكاء الاصطناعي. ستكون هذه الآلات فائقة الذكاء، وسيكون لها وعيها ومشاعرها وإدراكها الذاتي. تطبيقات الذكاء الاصطناعي تطبيقات الذكاء الاصطناعي لا حصر لها؛ يمكن تطبيق هذه التكنولوجيا على العديد من القطاعات والصناعات المختلفة. إليك أهم 10 تطبيقات للذكاء الاصطناعي: 1. الطب والرعاية الصحية أحدث الذكاء الصناعي تأثيرًا غير مسبوق في المجال الطبي، إذ أصبحت خوارزميات ونماذج التعلم الآلي قادرةً على تشخيص العديد من الأمراض والتنبؤ بها، مثل تحديد ما إذا كان مريض معين مصابًا بسرطان أو ورم خبيث أو حميد بناءً على الأعراض والسجلات الصحية والتاريخ أو التنبؤ بالإصابة بأمراض وأوبئة ..إلخ. 2. النقل أصبح إنتاج السيارات ذاتية القيادة التي تعتمد على الذكاء الصناعي -الشغل الشاغل للعديد من الشركات العالمية مثل شركة تسلا التي يرأسها إيلون ماسك. كما أنه يساعد في تقليل الازدحام والاختناقات المرورية. أما في النقل الجوي؛ فقد أصبحت الآلة تشارك في تخطيط المسارات جنبًا إلى جنب مع مخططات هبوط الطائرة والإقلاع. 3. التعليم يمكن للذكاء الاصطناعي أتمتة عملية تقييم الطلاب ووضع الدرجات، وبالتالي توفير الجهد والوقت على المدرسين. بالمناسبة، لقد كان مشروع التخرج الخاص بي هو نظام ذكي لمراقبة سلوك الطلاب خلال الدرس ورصد تعابير وجوههم لمعرفة الطالب الذي يشعر بالملل أو النائم والذي يُشارك باستمرار والذي يُثير الشغب ..إلخ، وتقديم تقرير عن كل طالب في نهاية الدرس. 4. الأعمال دُمجت خوارزميات التعلم الآلي مع أنظمة تحليل وإدارة علاقات العملاء CRM، لمعرفة كيفية خدمة العملاء بطريقة أفضل. كما دُمجت روبوتات الدردشة في مواقع الويب لتقديم خدمة فورية للعملاء. أصبحت أتمتة المناصب الوظيفية أيضًا نقطة نقاش بين الأكاديميين ومحللي تكنولوجيا المعلومات. 5. الأمن والحماية تستخدم المؤسسات التعلم الآلي في برامج إدارة المعلومات والأحداث SIEM والمجالات ذات الصلة لاكتشاف الحالات الشاذة وتحديد الأنشطة المشبوهة التي تشير إلى التهديدات. 6. المؤسسات المالية والمصرفية يلعب الذكاء الاصطناعي دورًا حيويًا في إدارة المعاملات المالية والتعامل مع العديد من الأنشطة البنكية الأخرى. من خلال نماذج التعلم الآلي يمكن التعامل مع العمليات اليومية للبنوك، مثل المعاملات والعمليات المالية وأموال سوق الأوراق المالية وإدارتها وما إلى ذلك بسهولة وكفاءة أكبر. كما تُستخدم في عمليات مكافحة غسيل الأموال وتحليل أنظمة الائتمان. 7. الألعاب والترفيه حقق الذكاء الصناعي تقدمًا كبيرًا في ألعاب الواقع الافتراضي والألعاب الحديثة، حيث يُستخدم لتوليد سلوكيات متجاوبة أو متكيفة أو ذكية لشخصيات اللاعبين تُحاكي الذكاء البشري. 8. الصناعة من خلال الذكاء الصناعي يمكننا توفير الوقت والمال عن طريق أتمتة العمليات والمهام الروتينية وتحسينها. زيادة الإنتاجية والكفاءات التشغيلية. اتخاذ قرارات أعمال أسرع بناءً على مخرجات التقنيات المعرفية. 9. الزراعة تساعد أنظمة الذكاء الاصطناعي في تحسين الجودة الشاملة للحصاد ودقته (تُعرق بالزراعة الدقيقة). يمكن للذكاء الصناعي أن يتنبأ بالوقت الذي يستغرقه محصول ما ليصبح ناضجًا وجاهزًا للقطف واكتشاف الأمراض في النباتات والآفات وسوء تغذية المزارع، وهذا ما يزيد من كفاءة الزراعة. 10. الفنون أصبح بإمكان الذكاء الاصطناعي إنتاج لوحات فائقة الجمال، كما أنّه دخل في مجال الموسيقى والغناء، حيث أصبح قادرًا على تأليف نوتات موسيقية وأغاني وإنتاج أنواع الأصوات المختلفة. الذكاء الاصطناعي والثورة الصناعية الرابعة 4IR لابد وأنك قد سمعت عن العصر الجديد من الصناعة والذي يُعرف بالثورة الصناعية الرابع "0.4 Industry". ترتكز الثورة الصناعية الرابعة على أتمتة العمليات إلى حد كبير جدًا واستخدام جداول زمنية أسرع للإنتاج ومستودعات ذكية (مخازن ذكية)، مما يسمح بإنتاج وتوزيع المنتجات بسرعة وفعالية أكبر، كما أنها ستتطلب قوة عاملة ذات مهارات عالية ومتعلمة وتتقن كيفية استخدام وتشغيل أحدث التقنيات. يأتي دور الذكاء الصناعي هنا في قدرته على إحداث هذه التغييرات بسرعة وسلاسة، ولاسيما من خلال الأنظمة الخبيرة والرؤية الحاسوبية والروبوتات وإنترنت الأشياء. ما هي مزايا وعيوب الذكاء الاصطناعي؟ تتطور تقنيات الذكاء الصناعي بسرعة كبيرة جدًا، ويرجع ذلك إلى أن الذكاء الاصطناعي يُمكنه معالجة كميات كبيرة من البيانات بسرعة، كما أنه يعطي تنبؤات أكثر دقة من الإنسان. إن الكميات الهائلة من البيانات يمكنها دفن قدرة العقل البشري على معالجتها وتحويلها إلى معلومات ذات معنى، إلا أن تقنيات الذكاء الاصطناعي يمكنها أخذ وتحويل تلك البيانات إلى معلومات مُفيدة وقابلة للتنفيذ بسرعة، لكن العيب الأساسي لاستخدام الذكاء الاصطناعي هو أنه من المكلف معالجة الكميات الكبيرة من البيانات التي تتطلبها برمجة الذكاء الاصطناعي. مزايا الذكاء الاصطناعي يجعل الآلات أكثر قوة وفائدة. يُقدم أساليب جديدة لحل المشاكل. أفضل من البشر في التعامل مع المعلومات. يُحسّن كفاءة العمل، إذ يقلل من المدة الزمنية لإنجاز مهمة مقارنة بالبشر. غالبًا ما يكون أكثر دقة من البشر. عيوب الذكاء الاصطناعي عدم القدرة على التعميم من مهمة إلى أخرى. أي يمكن للآلة أن تنفذ مهمة (أو عدة مهمات) محددة مُدربة عليها مسبقًا فقط، ولايمكنها أن تنفذ مهمة لم تُدرب عليها مُسبقًا. التكلفة (تكلفة تنفيذ تطبيقات الذكاء الاصطناعي مرتفعة للغاية). قلة الكفاءات (يتوفر عدد قليل من المبرمجين الأكفاء القادرين على تطوير برامج الذكاء الاصطناعي). يتطلب خبرة فنية عميقة. الروبوتات هي إحدى تطبيقات الذكاء الصناعي التي تحل محل الوظائف التي يشغلها البشر، وبالتالي قد تؤدي إلى تزايد البطالة. كيف يتم استخدام الذكاء الصناعي اليوم؟ يُستخدم الذكاء الاصطناعي بمستويات متفاوتة من التطور على نطاق واسع وعبر مجموعة من التطبيقات اليوم. لابد وأنك تستخدم اليوتيوب أو الفيسبوك، ولابد أنك لاحظت أنهم يقترحون لك مقاطع فيديو مُشابهة لما تُشاهده في العادة، هذه الاقتراحات هي من فعل "أنظمة التوصية" (أو أنظمة الاقتراح) التي تُراقب ما تبحث عنه في العادة لكي تقترح لك في المرات القادمة أشياء مُشابهة. من الأمثلة الأخرى برامج الدردشة التي تراها على مواقع الويب أو إن كنت من مستخدمي ويندوز فربما أنت تعرف المساعد الافتراضي الذكي آليكسا. يُستخدم الذكاء الاصطناعي أيضًا للتنبؤ بحالة الطقس والتنبؤات المالية (كأسعار الأسهم) ولتبسيط عمليات الإنتاج، كما يُستخدم في الألعاب والنقل والتسوق ومعالجة اللغة البشرية وغير ذلك الكثير. عمومًا، يمكن القول أن الذكاء الاصطناعي بدأ التشعب في جميع مفاصيل حياتنا اليومية وسيزداد استخدامه أكثر ويصبح البشر أكثر اعتمادًا عليه من قبل في السنوات القادمة. مستقبل الذكاء الاصطناعي في مؤتمر Web Summit في أواخر عام 2017، قدم الفيزيائي ستيفن هوكينغ رأيه حول مستقبل الذكاء الاصطناعي. كان يأمل في أن تتفوق التكنولوجيا على الذكاء البشري. قد يعني هذا على الأرجح أنه سيتم الشفاء من العديد من الأمراض الرهيبة وربما تكون هناك طرق للتعامل مع المشكلات البيئية، بما في ذلك تغير المناخ. لكن كان هناك جانب مظلم أيضًا. تحدث هوكينج عن إمكانية أن تكون التكنولوجيا "أسوأ حدث في تاريخ حضارتنا"، فربما تُحدث بعض المشاكل مثل البطالة الجماعية وحتى الروبوتات القاتلة! لهذا السبب، حث على طرق للتحكم في الذكاء الاصطناعي. أفكار هوكينغ ليست مجرد كلام على الهامش بالتأكيد، فقد أعرب رواد الأعمال البارزين في مجال التكنولوجيا مثل إيلون ماسك وبيل غيتس مرارًا وتكرارًا عن قلقهم العميق بشأن الذكاء الاصطناعي. على الجانب الآخر هنا الكثير من العلماء ورواد الأعمال المتفائلون. ماسايوشي سون، الرئيس التنفيذي لشركة SoftBank ومدير صندوق Vision هو واحد منهم. في مقابلة مع CNBC، أعلن أنه في غضون 30 عامًا، سيكون لدينا سيارات طائرة وسيعيش الناس لفترة أطول وسنكون قد عالجنا العديد من الأمراض. أشار أيضًا إلى أن التركيز الرئيسي لصندوقه ينصب على الذكاء الصناعي. بغض النظر عن كل ذلك، هناك شيء واحد مؤكد: سنرى في السنوات القادمة الكثير من الابتكارات والتطورات في الذكاء الصناعي، خصوصًا وأن هناك مبالغ ضخمة مستثمرة فيه. لنلقي الآن نظرةً على بعض المجالات التي من المحتمل أن يكون لها تأثير كبير على المجتمع: السيارات ذاتية القيادة: لقد كانت سمة مميزة للعديد من قصص الخيال العلمي لعقود عديدة! لكنها الآن أقرب إلى الواقع من الخيال -يمكننا ملاحظة مؤشرات ذلك من التطورات الأخيرة في سيارات تسلا من شركة تسلا موتورز التابعة لإيلون ماسك. السباق الاقتصادي بين الدول: توظيف الذكاء الاصطناعي في تسريع عجلة الاقتصاد والتصنيع بمختلف المجالات والتنافس على المرتبة الاقتصادية الأولى عالميًا. البطالة التكنولوجية: اكتسب هذا المفهوم شهرةً من الاقتصادي الشهير جون مينارد كينز خلال فترة "الكساد الكبير"، والذي يُشير إلى كيف يمكن أن تؤدي الابتكارات إلى فقدان الوظائف على المدى الطويل. عمومًا قد تكون هذه الرؤية غير دقيقة، فغالبًا ما تخلق الأشياء الجديدة أعمالًا جديدة للإنسان. تسليح الذكاء الاصطناعي: يُعد تسليح الذكاء الاصطناعي أو استخدام الذكاء الاصطناعي في مجال الصناعات الحربية والدفاعية أحد أكبر التهديدات التي تواجه المجتمع الدولي. اكتشاف الأدوية: تواجه شركات الأدوية العديد من المشاكل في التوصل إلى العلاجات لذا يجري الاعتماد على الذكاء الاصطناعي لتسريع العجلة وتخطي العقبات. إن تطوير الأدوية بالطريقة التقليدية غالبًا ما ينطوي على الكثير من التجربة والخطأ، مما قد يستغرق وقتًا طويلًا، إذن هل يمكن أن يكون هناك طريقة أفضل؟ يتطلع الباحثون إلى الذكاء الاصطناعي للحصول على المساعدة، وهناك العديد من الشركات الناشئة التي تحاول انتهاز هذه الفرصة للظهور. هناك العديد من المجالات الأخرى التي من المتوقع أن تتأثر مثل الأمور الحكومية والاجتماعية والتي لايسعنا ذكرها كلها الآن. اللغات والأدوات المستخدمة في الذكاء الصناعي هناك العديد من اللغات والأدوات المُساعدة في إنشاء نماذج الذكاء الاصطناعي، ومعظمها مفتوح المصدر. سنلقي الآن نظرةً على بعض اللغات والأدوات الأكثر شيوعًا للذكاء الاصطناعي: لغة بايثون Python هي لغة عالية المستوى مُفسَّرة ذات مجالٍ عام، وهي مرنةٌ وتحاول التعبير عن المفاهيم البرمجية بأقل قدر ممكن من الشيفرات. تدعم هذه اللغة البرمجة الكائنية والبرمجة الإجرائية، وفيها مكتبة قياسية كبيرة. تُعتبر لغة بايثون اللغة الأفضل للتعامل مع مهام الذكاء الصناعي، حيث تتميز بسهولة الاستخدام وسرعة التنفيذ، إضافةً إلى احتوائها على مكتبات هامة وأطر عمل لا غنى عنها، حيث أن أغلب أطر العمل تعمل عليها، وقد وفرت أكاديمية حسوب دورة متخصصة لتعلم الذكاء الاصطناعي وتعلم الآلة Machine Learning والتعلم العميق Deep Learning وغيرها من المفاهيم باستخدام لغة بايثون وباتباع بأسلوب عملي وشيق يركز على ممارسة ما تتعلمه من خلال مشاريع حقيقية تفيدك في سوق العمل. دورة الذكاء الاصطناعي احترف برمجة الذكاء الاصطناعي AI وتحليل البيانات وتعلم كافة المعلومات التي تحتاجها لبناء نماذج ذكاء اصطناعي متخصصة. اشترك الآن وتتضمن لغة بايثون العديد من المكتبات التي لا غنى عنها في مجال الذكاء الصناعي مثل: نمباي Numpy: تُعد مكتبة نمباي إحدى مكتبات لغة بايثون. تستخدم لتنفيذ عمليات الحوسبة العلمية والتعامل مع المصفوفات، وتهدف إلى توفير كائن مصفوفة سريع جدًا. باندا Panda: توفر هياكل بيانات وأدوات تحليل بيانات عالية الأداء وسريعة وسهلة الاستخدام لمعالجة البيانات الرقمية والسلاسل الزمنية. ماتبلوتليب Matplotlib: هي مكتبة شاملة لإنشاء رسوم بيانية ثابتة ومتحركة وتفاعلية في بايثون. سيبورن Seaborn: هي مكتبة رسوم بيانية مبنية على ماتبلوتليب. توفر واجهة عالية المستوى لرسم رسومات إحصائية جذابة وغنية بالمعلومات. أطر العمل Frameworks هناك عدد لا يحصى من أطر عمل الذكاء الاصطناعي، والتي توفر أنظمة شاملة لبناء النماذج وتدريبها ونشرها. إليك بعضًا من أهم هذه الأطر: تنسرفلو TensorFlow: هو إطار العمل الأكثر شعبية والمدعوم من شركة جوجل. بدأت الشركة في تطوير إطار العمل هذا في عام 2011، من خلال قسم دماغ جوجل Google Brain. كان الهدف هو إيجاد طريقة لإنشاء شبكات عصبية أسرع؛ لإتاحة إمكانية تضمين تكنولوجيا الذكاء الصناعي في التطبيقات. كيراس Keras: واحد من أطر العمل المهمة الأخرى، والذي ظهر لأول مرة في عام 2015 على يد الباحث فرانسوا كوليت (أحد باحثي جوجل). توفر كيراس واجهات برمجة تطبيقات متسقة وبسيطة، ويقلل من عدد إجراءات المستخدم المطلوبة لحالات الاستخدام الشائعة، ويوفر رسائل خطأ واضحة وقابلة للتنفيذ. كما أن لديها وثائق موسعة للمطورين. دُمجت كيراس مع تنسرفلو بدءًا من 2017. باي تورش PyTorch: في السنوات الأخيرة ظهر إطار عمل آخر يُدعى باي تورش مدعوم من قبل شركة ميتا Meta. إنها إطار عمل آخر مفتوح المصدر مستندة على تورش Torch. تتميز باي تورش عن أطر العمل الأخرى بكونها بايثونية أكثر (عندما تكتب النماذج باستخدامها تشعر وكأنك تكتب شيفرة بايثون عادية)، كما أن الباحثين يتجهون إلى استخدامها أكثر في الآونة الأخيرة. فرص العمل في تخصص الذكاء الاصطناعي مهندسو الذكاء الاصطناعي هم الأفراد الذين يقومون بتصميم وبناء واختبار وتحديث أنظمة وتقنيات الذكاء الاصطناعي التي يمكن أن تساعد المؤسسات على زيادة الكفاءة وخفض التكاليف وزيادة الأرباح واتخاذ قرارات أفضل. نظرًا للنمو الكبير والانتشار السريع للذكاء الاصطناعي، هناك حاجة إلى المهنيين المتخصصين في مجالاته المختلفة الآن أكثر من أي وقت مضى. الخبر السار هو أن هذا المجال مليء بالفرص الوظيفية المختلفة، مما يعني أنه يمكنك تولي أدوار ومسؤوليات مختلفة اعتمادًا على منصبك أو خبرتك أو اهتماماتك وبما أن الطلب مرتفع فالخبرة هي المقياس الوحيد ويمكن تخطي الشهادة الجامعية. تختلف رواتب مهندس الذكاء الاصطناعي بناءً على الخبرة والبلد، كما قد تختلف التعويضات من مؤسسة إلى أخرى. يمكنك البحث عن رواتب مهندس الذكاء الاصطناعي في موقع Glassdoor وملاحظة الفرق بسهولة. كما أن الراتب يختلف من تخصص لآخر، فراتب مهندس الذكاء الاصطناعي يختلف عن راتب المهندس الباحث في الذكاء الاصطناعي. وفقًا Glassdoor، فإن متوسط الراتب لمهندس الذكاء الاصطناعي في الولايات المتحدة هو 119297 دولارًا، ويمكن أن ينخفض الرقم إلى 78000 دولار أو يصل إلى 150 ألف دولار أو أكثر. أما في بلد عربي مثل الإمارات، فوفقًا للموقع المتخصص erieri، يبلغ متوسط الأجر لمهندس الذكاء الاصطناعي هو 337،135 درهمًا إماراتيًا في السنة، وهذه الأرقام إن دلت على شيء فإنها تدل على الأجر المرتفع للعامل في هذا المجال. كيفية تعلم الذكاء الاصطناعي ربما تطرح السؤال التالي كمبتدأ: كيف أتعلم الذكاء الصناعي؟ ومن أين أبدأ؟ يتطلب تعلم الذكاء الصناعي ما يلي: خلفية علمية بسيطة على الأقل (كلما زادت كان أفضل) في علم الجبر والجبر الخطي والإحصاء والاحتمالات والتحليل (لاسيما الاشتقاقات). خلفية برمجية جيدة، والقدرة على استخدام لغة بايثون (لا يجب أن تكون محترفًا لتبدأ، الاحتراف يأتي مع الممارسة والوقت). تعلم أُطر العمل الأساسية. هنا لن تحتاج إلى تعلم جميع أُطر ومكتبات الذكاء الصناعي؛ الأمر يعتمد على الفرع والمواضيع التي ترغب بالتخصص فيها. يمكنك أن تتعلم المجال إما بدخول أروقة الجامعة وهو الطريق الأطول الذي يأخذ عدة سنوات ولا توفر أغلب الجامعات تعلم مجال الذكاء الاصطناعي من البداية بل يكون ضمن برامج الماجستير والدراسات العليا، عدا عن التركيز على الجانب النظري والتقنيات القديمة، وقد فصلنا هذه النقطة في فقرة "طرق لتعلم البرمجة" من مقال كيف تتعلم البرمجة: نصائح وأدوات لرحلتك في عالم البرمجة. وفي أي حال يُنصح دومًا بالدورات البرمجية والمخيمات والكتب المتخصصة لتعلم المجال منها خصوصًا ما هو عملي ومطلوب في سوق العمل، وإحدى أفضل الدورات العربية التي تعلمك تخصص الذكاء الاصطناعي دورة تطوير التطبيقات باستخدام لغة Python الشاملة التي تبدأ من الصفر حيث تعلمك أساسيات البرمجة وحتى احترافها بلغة بايثون ثم تعلمك أساسيات الذكاء الاصطناعي وتعلم الآلة بإنشاء تطبيقات عملية تضيفها في معرض أعمالك، كما أن الدورة تضمن لك دخول سوق العمل بعد التخرج مباشرةً. إليك مصادر إضافية عربية لتعلم الذكاء الاصطناعي توفرها أكاديمية حسوب: تعلم الذكاء الاصطناعي: مقال شامل لتعلم الذكاء الصناعي موجه للمبتدئين. البرمجة بلغة بايثون: تعلم لغة بايثون تمهيدًا لكتابة تطبيقات ذكاء اصطناعي وتعلم آلة بها. مدخل إلى الذكاء الاصطناعي وتعلم الآلة: تعرف على أساسيات الذكاء الاصطناعي وتعلم الآلة. عشرة مشاريع عملية عن الذكاء الاصطناعي: طبق ما تعلمته على مشاريع ذكاء اصطناعي عملية بلغة بايثون. قسم الذكاء الاصطناعي: يحوي مقالات متنوعة عن كل ما يتعلق بمجال الذكاء الاصطناعي. أهم مصطلحات الذكاء الصناعي إليك قائمة مُختصرة بأهم المصطلحات والمفاهيم ذات الصلة بدراسة الذكاء الاصطناعي وتخصصاته: المصطلح الترجمة التعريف (Artificial intelligence (AI الذكاء الصناعي العلم الذي يحاول فهم الكيانات الذكية وبناء الآلات ذكية (Natural Language Processing (NLP معالجة اللغات الطبيعية العلم الذي يحاول فهم وتوليد ومعالجة اللغات البشرية (Computer vision (CV الرؤية الحاسوبية بناء تطبيقات ذكية قادرة على فهم محتوى الصور كما يفهمها الإنسان (Machine learning (ML تعلم الآلة قدرة الآلة على تقليد السلوك البشري الذكي من خلال بناء الخوارزميات التي "تتعلم" من البيانات (Reinforcement learning (RL التعليم المعزز أحد أنواع تعلم الآلة (Supervised learning (SL التعليم الخاضع للإشراف أحد أنواع تعلم الآلة (Semi-Supervised learning (SSL التعليم شبه الخاضع للإشراف أحد أنواع تعلم الآلة (UnSupervised learning (USL التعليم غير الخاضع للإشراف أحد أنواع تعلم الآلة (Deep Learning (DL التعلم العميق نوع من التعلم الآلي والذكاء الاصطناعي الذي يُقلد الطريقة التي يكتسب بها البشر أنواعًا معينة من المعرفة (Artificial neural networks (ANNs الشبكات العصبية الاصطناعية مجموعة مترابطة من عصبونات افتراضية تُنشئها برامج حاسوبية لتُشابه عمل العصبون البيولوجي (Robotic Process Automation (RPA أتمتة العمليات الآلية أحد أشكال تكنولوجيا أتمتة العمليات التجارية بناءً على روبوتات البرمجيات Expert systems الأنظمة الخبيرة برنامج مصمم لينفد مهاماً متعلقة بالخبرة البشرية Fuzzy Logic منطق ضبابي أو ترجيحي أو غيمي فرع من الذكاء الصناعي يُقدم حلولًا جديدًا ويرتكز على توسيع مفهوم المنطق الثنائي الكلاسيكي (Convolutional Neural Network (CNN شبكة عصبية التفافية نوع خاص من أنواع الشبكات العصبونية (Recurrent Neural Network (RNN شبكة عصبية تكرارية نوع خاص من أنواع الشبكات العصبونية (Long Short-Term Memory Network (LSTM الشبكات ذات الذّاكرة الطويلة قصيرة المدى نوع خاص من أنواع الشبكات العصبونية التكرارية RNNs Pre-trained Model نموذج مُدرّب مُسبقًا شبكة عصبية مُدربة مُسبقًا على مجموعة بيانات، ويمكن استخدامها وتكييفها على مهمة أخرى Model نموذج أداة أو خوارزمية تعتمد على مجموعة بيانات معينة يمكن من خلالها التوصل إلى قرار Transfer Learning نقل التعلم تخزين المعرفة المكتسبة أثناء حل مشكلة واحدة وتطبيقها على مشكلة مختلفة ذات صلة Optimization الاستمثال - التحسين اختيار العنصر أو القيمة الأمثل من بين مجموعة ممكنة من العناصر Structured Data البيانات المهيكلة البيانات المنظمة ضمن جداول Unstructured Data البيانات غير المهيكلة البيانات الغير منظمة، مثل الفيديو والصور والصوت Data augmentation تكثيف البيانات تقنية لتوليد بيانات جديدة من بيانات موجودة (مثل توليد صور جديدة من صورة معينة) Regression التوقع أحد تقنيات التعليم الخاضع للإشراف Clustering التجميع أحد تقنيات التعليم غير الخاضع للإشراف Classification التصنيف أحد تقنيات التعليم الخاضع للإشراف Logistic Regression الانحدار اللوجستي خوارزمية تعلم آلي للتصنيف Linear Regression الانحدار الخطي خوارزمية تعلم آلي للتنبؤ Neuron عصبون أحد عناصر الشبكات العصبونية Learning Rate مُعدّل التعلّم ‏ معلمة فائقة تُحدد مقدار التعلم في خوارزميات الذكاء الصناعي خاتمة كانت هذه المقالة بمثابة مدخل إلى الذكاء الاصطناعي؛ إنها تُجيبك عن العديد من الأسئلة المتعلقة بالذكاء الصناعي، مثل مفهومه وتعريفه وأهميته وتطبيقاته ومجالاته والتقنيات التي يدعمها وتخصصاته وأدواته والبدء في تعلمه …إلخ. وسنتحدث في المقالات القادمة عن العديد من الأمور الأخرى المتعلقة بالذكاء الصناعي ونتوسع بالنقاط التي ذكرناها في هذا المقال التي سيطول ذكرها والحديث عنها. يعدنا الذكاء الاصطناعي بأنه سيغير العالم، والخبر السار هو أن هناك العديد من الأشخاص الذين يركزون على جعل هذا حقيقةً واقعةً، ولا يتعلق الأمر بجني مبالغ طائلة أو الحصول على الشهرة؛ الهدف هو مساعدة البشرية وتغيير العالم إلى الأفضل. اقرأ أيضًا الذكاء الاصطناعي: أهم الإنجازات والاختراعات وكيف أثرت في حياتنا اليومية الذكاء البشري مقابل الذكاء الاصطناعي أهمية الذكاء الاصطناعي تعلم لغة بايثون فوائد الذكاء الاصطناعي لغات برمجة الذكاء الاصطناعي
    3 نقاط
  3. سنبدأ في هذا المقال من سلسلة برمجة الذكاء الاصطناعي في تعلم أساسيات لغة بايثون، وهي من أهم لغات البرمجة على الإطلاق المستخدمة في مجال الذكاء الاصطناعي، ولكنها ليست لذلك فقط؛ إذ تُستعمَل لغة بايثون في كثير من المجالات الأخرى مثل برمجة المواقع وبرامج سطح المكتب وأنظمة التشغيل وغيرها. قبل البدء في أساسيات لغة بايثون: ما هي لغة البرمجة بايثون؟ تعني بايثون في اللغة الإنجليزية نوعًا من الثعابين الكبيرة، لكنها لم تُسمى لذلك بل سُمِّيَت بهذا الاسم تيمنًا ببرنامج ترفيهي قدَّمته قناة BBC يحمل اسم Monty Python’s Flying Circus، وذلك بعد ما شاهده مخترع اللغة. وتُعَدّ بايثون لغةً برمجيةً عامةً، أي تستطيع استخدامها في مجالات عدة على عكس بعض اللغات الأخرى التي تتخصص في مجال ما دونًا عن الآخر، كما تُعَدّ لغةً بسيطةً ومتطورةً للغاية، بالإضافة إلى أنها تدعم البرمجة كائنية التوجه Object Oriented Programming أو OOP اختصارًا. صُنِعت بايثون بواسطة الهولندي جايدو فان روسم Guido van Rossum، وأُصدِرت في شهر 11 من عام 1994م بعدما عُمِل عليها في معهد الأبحاث القومي للرياضيات وعلوم الحاسوب في هولندا، في حين نُشر الإصدار الثاني من بايثون في عام 2000م؛ أما الإصدار الثالث، فقد نُشِر في عام 2008م وهو الإصدار المستخدم حاليًا من بايثون لأن الإصدار الثاني السابق قد توقف دعمه وتطويره. خصائص لغة بايثون تُعَدّ لغة بايثون لغةً مفتوحة المصدر تجد شيفرتها المصدرية على موقع GitHub، وبالتالي يستطيع أيّ مبرمج المشاركة في تطوير اللغة. وبحسب موقع جيت هاب GitHub، فقد شارك أكثر من 1200 شخص حول العالم في تطويرها، كما تُعرَف بايثون بسهولة تراكيب الجمل فيها Syntax التي تشبه تركيب اللغة الإنجليزية بنسبة كبيرة، وهي لغة مهمة جدًا للطلبة والباحثين والمهنيين على حد سواء في الكثير من النطاقات العلمية والعملية. وتتميز بايثون بالميزات التالية: لغة برمجة مفسرة Interpreted تدعم البرمجة الكائنية مناسبة للمبتدئين مدعومة بالكثير من المكتبات لغة مجانية ومفتوحة المصدر تستخدم في العديد من التخصصات لغة برمجة مفسرة Interpreted أي أنها تُنفَّذ مباشرةً مثل لغة PHP ولغة Perl، ولا تحتاج إلى تصريف كامل الشيفرة أولًا ثم تنفيذها مثل لغة C، فلا يتطلب الأمر تحويل الشيفرة الخاصة بك إلى شيفرة ثنائية تفهمها الآلة أولًا لتبدأ عملية التنفيذ، وهذا قد يميز شيفرات بايثون في سرعة تنفيذها أثناء البرمجة. وفي تلك النقطة بالتحديد قد يختلف بعض المبرمجين، فالبرغم من تصنيف بايثون أنها لغة مفسَّرة، إلا أنّ الشيفرة تُصرَّف compiled أولًا ليستطيع المُفسِّر فهمها قبل تنفيذها، لذلك قد تجد بعض النقاشات المتباينة حول بايثون لمحاولة تصنيفها تصنيفًا دقيقًا. يذهب بعض المبرمجين إلى القول بأنّ لغة بايثون لها طريقتها الخاصة في تلك النقطة، فالأمر معقَّد ولا نريد الخوض فيه. تدعم البرمجة الكائنية تدعم بايثون نمطًا يُدعى الكائنية في البرمجة Object-oriented programming (أو تدعى الشيئية أحيانًا)، وهو نمط شهير ومهم، إذ تُكتَب الشيفرة ويُتعامَل مع أجزاء التطبيق على أساس الكائنات Objects، وهو نمط غير مدعوم في بعض اللغات القديمة مثل لغة C، كما أنها تدعم البرمجة الوظيفية Functional والهيكلية Structured وغيرها. أساسيات لغة بايثون مناسبة للمبتدئين تُعَد بايثون مناسبةً جدًا للمبتدئين، حيث أنَّ صياغة الجمل فيها بسيطة للغاية، ولا يتطلب الأمر الدخول في تفاصيل كثيرة عند كتابتها؛ لذلك فهي سهلة التعلم والقراءة. مدعومة بالكثير من المكتبات يمكنك في بايثون إيجاد مكتبات بسيطة الاستخدام تستطيع بها برمجة تطبيقات معقدة جدًا، فهي لغة لديها أرشيف واسع من المكتبات في كافة المجالات تقريبًا. لغة مجانية ومفتوحة المصدر توجد بعض لغات البرمجة غير المجانية، أي أنك مُطالَب بدفع الأموال لشركة ما، كي تستطيع استخدام تلك اللغة، كما أنَه لا يمكنك ولا يمكن لأيّ شخص آخر إصلاح مشكلة ما في اللغة أو أن يطوِّر ميزةً أو خاصيةً جديدةً في اللغة، فالشيفرة المصدرية في تلك الحالة تقع تحت أيدي الشركة المصنعة فقط، وهي الوحيدة التي يحق لها تطوير اللغة أو إصلاح مشاكلها أو إصدار نسخ جديدة منها. أما في بايثون والعديد من اللغات المجانية المفتوحة المصدر، فالأمر مختلف إذ عمِل على على لغة بايثون أكثر من 1200 شخص حول العالم، فالشيفرة المصدرية للغة موجودة ومتاحة على موقع GitHub، ويمكن لأيّ شخص له الخبرة والمعرفة الكافية أن يطوِّر أو يعدِّل ميزةً ما، كما يستطيع مجتمع مبرمِجي بايثون على الإنترنت من المشاركة بآرائهم في تطوير اللغة، فالأمر بالجميع وللجميع، وهي لغة مجانية بالكامل تستطيع استخدامها في أيّ مشروع خيري أو تجاري، بدون أية مشاكل قانونية على الإطلاق. تستخدم في العديد من التخصصات لا يقتصر الأمر أبدًا على برمجة الذكاء الاصطناعي وتعلّم الآلة، ولا يقتصر على برمجة مواقع الويب أيضًا، إذ تُعَدّ بايثون من أكثر لغات البرمجة انتشارًا وتوغلًا في العديد من المجالات في حياتنا اليومية، وفي التخصصات العلمية والأبحاث ومعامل ومختبرات الجامعات حول العالم، لذلك بتعلُُّمك للغة بايثون فإنّ الأمر لا يقتصر على فرصة عمل في مجال الذكاء الاصطناعي فحسب، وإنما تستطيع استخدام معرفتك وخبرتك في بايثون في مجالات أخرى تفتح عليك أبواب دخل إضافية. تُشتهر بايثون أيضًا في استخدامها في برمجة المواقع وتطبيقات سطح المكتب وبرمجة برامج تجارية عبر بايثون مثل أودوو Odoo الذي يُعَدّ أشهرها وله متخصصين وشركات تجارية تعتمد كليةً على استخدامه. كما أنَّ لغة بايثون كما أوردنا تدخل في الكثير من مجالات البحث العلمي، فهي من أكثر اللغات التي تحتوي على مكتبات تهدف إلى خدمة مجالات البحث العلمي والرياضيات من الذكاء الاصطناعي حتى التغير المناخي وتُعَد دراسة لغة بايثون أمرًا أساسيًا بالنسبة لمبرمجي الذكاء الاصطناعي، لذلك سنبدأ الآن في دراسة أساسيات اللغة حتى نكون على قدر من المعرفة المطلوبة لنبدأ في دراسة وتطبيق الخوارزميات الأساسية في تعلُّم الآلة. لذلك فإن السهل البدء بتعلم أساسيات بايثون والبدء في عالم البرمجة بسهولة. تثبيت لغة بايثون أول ما نبدأ به في تعلم أساسيات لغة Python ولكي تستطيع العمل بلغة بايثون، يجب عليك أولًا تثبيت البرنامج الذي يفهم اللغة ثم ينفذها، وذلك لكي يستطيع حاسوبك التعرف على الأوامر التي تكتبها لتعمل عليه بصورة صحيحة، لذلك من الضروري أن تكون أول خطوة نقوم بها هي تثبيت لغة بايثون على حاسوبك. يختلف أمر تثبيت اللغة باختلاف نظام التشغيل، فإذا كان حاسوبك مثلًا يعمل على نظام لينكس Linux، فعلى الأرجح أنّ حاسوبك مثبَّت عليه بالفعل لغة بايثون، وللتأكد من ذلك يمكنك فتح الطرفية Terminal ثم كتابة الأمر الآتي: >> python --version أول الأمر التالي بالنسبة للإصدار الثالث: >> python3 --version إذا كانت بايثون مثبتةً بالفعل على حاسوبك، فسيظهر لك رقم الإصدار المثبَّت، والجدير بالذكر أنه يجب أن يكون الإصدار المثبت لديك هو الإصدار الثالث، وبالتالي يجب بدء رقم الإصدار بالرقم 3؛ أما إذا لم تكن اللغة مثبتةً على حاسوبك، فيمكنك ذلك عبر تنفيذ الأمر الآتي في الطرفية Terminal على لينكس. >> sudo apt-get install python3.6 أما إذا كنت مستخدِمًا لنظام التشغيل ماك macOS بمختلف إصداراته، فعلى الأغلب أيضًا أنّ لغة بايثون مثبتة بالفعل على حاسوبك، وتستطيع اختبار ذلك عبر الأمر السابق ذكره بخصوص نظام لينكس، فإذا لم تكن اللغة مثبتةً، فيمكنك ببساطة تثبيتها مثل أيّ برنامج أخر عن طريق الموقع الرسمي للغة /Python. بعد تثبيت اللغة بالطرق الموضحة أعلاه في نظامي لينكس وماكينتوش، فمن المحتمل ألا يعمل أمر التحقق من الإصدار وألا يكون جاهزًا للعمل بعد، إذ أنه قد لا يُتعرَّف على برنامج بايثون عندما تُنفِّذ الأمر التالي: >> python --version ولحل ذلك يجب تنفيذ الأمر التالي في الطرفية Terminal: >> export PYTHONPATH=/usr/local/bin/python3.6 مع تغيير كلمة python3.6 لأنها قد تختلف حسب الإصدار الذي ثبَّته؛ لذلك يجب التحقق من ذلك المسار على حاسوبك أولًا لترى أيّ الإصدارات يجب استدعاؤها في الأمر السابق. أما في حالة مستخدمي نظام الويندوز، فالأمر بسيط للغاية، إذ تستطيع تنزيل برنامج اللغة من الموقع الرسمي السالف ذكره، ثم تثبيته مثل أيّ برنامج آخر على حاسوبك دون تعقيدات قد لا يعمل كذلك أمر التحقق من إصدار اللغة بصورة تلقائية بعد التثبيت، ولحل ذلك ببساطة يمكنك فتح موجِّه الأوامر Command Prompt في ويندوز ثم تنفيذ الأمر الآتي: >> %path%;C:\Python مع الأخذ في الحسبان إمكانية تغيير النص C:\Python إذا كنت قد تثبَّت اللغة في مسار آخر على حاسوبك أثناء عملية التثبيت. استعمال بايثون مع خدمة Google Colab ضمن أساسيات لغة بايثون وبالرغم من سهولة عملية تثبيت بايثون على حاسوبك، فإنه ليس من الضروري فعلًا فعل تلك الخطوات السالف ذكرها، فقد أصدرت شركة جوجل مؤخرًا ما يُدعى Google Colaboratory عبر موقع الأبحاث الخاص بها \colab.research، وبالتالي تستطيع ببساطة استخدام تلك الخاصية بإنشاء ذلك النوع من الملفات على خدمة Google Drive الموجودة مجانيًا لأي عنوان بريد إلكتروني مُسجَّل على Gmail، بعدها يمكنك البدء في كتابة وتنفيذ شيفرة البايثون الخاصة بك عبر الإنترنت دون الحاجة إلى الدخول في الكثير من التعقيدات والمشاكل التقنية أثناء تعلمك، أو حتى أثناء عملك في برمجة الذكاء الاصطناعي. كما تحتوى تلك الخدمة تلقائيًا على معظم وأهم مكتبات بايثون المستخدَمة في مجال الذكاء الاصطناعي عامةً ومجال تعلّم الآلة خاصةً، فنجد مثلًا تلقائيًا في تلك الخدمة أنّ مكتبات متخصصة في الرياضيات مثل Numpy، ومكتبات متخصصة في رسم البيانات مثل Matplotlib ومكتبات متخصصة في خوارزميات تعلّم الآلة مثل Keras، ومكتبات متخصصة في التعلّم العميق والشبكات العصبية مثل Tensorflow …إلخ مثبتة ومتاحة للاستخدام مباشرةً. أُصدِرت الخدمة أساسًا للتسهيل على العاملين في مجال برمجة الذكاء الاصطناعي، وبالأخص تعلُّم الآلة ليستطيع المبرمج مشاركة الشيفرة المصدرية الخاصة به مع نتائج هذه الشيفرة والملاحظات مع شركائه في العمل أو أي شخص آخر، وهي خدمة سحابية بالكامل، أي أنها تعمل عبر الإنترنت ولا تحتاج إلى أي متطلبات أو إمكانيات في حاسوبك، فكل ما تحتاجه لاستخدام الخدمة هي وصلة الإنترنت وعنوان بريد إلكتروني من Gmail. أفضِّل شخصيًا استخدام تلك الخدمة أثناء التعلم لأنها بسيطة وسهلة، وتحتوي تلقائيًا على الكثير من مكتبات بايثون الخاصة بالذكاء الاصطناعي التي قد يكون تثبيت بعضها عملًا شاقًا إذا حدث خطأ ما أثناء التثبيت والسبب الآخر الذي يدفعني إلى التوصية باستخدام تلك الخدمة بشدة، هو عدم امتلاك بعض أجهزة الحاسوب للإمكانيات اللازمة لتشغيل نماذج تعلّم الآلة، إذ تحتاج بعض الخوارزميات إلى ذاكرة عشوائية RAM كبيرة ليُدرَّب النموذج تدريبًا صحيحًا، وذلك اعتمادًا على حجم البيانات المتدفقة إلى النموذج. ولمزيد من التفاصيل، ارجع إلى مقال دليل استخدام Google Colab. برنامجك الأول في لغة بايثون من أساسيات لغة بايثون أنك تستطيع البدء في كتابة برنامجك الأول بعدة من الطرق، أولها عبر كتابة الشيفرة مباشرةً في الطرفية Terminal في لينكس وماك وموجِّه الأوامر Command Prompt في ويندوز؛ وثانيها، كتابة البرنامج في ملف أو عدة ملفات منفصلة، ثم تشغيلها عبر البرامج السابق ذكرها؛ أما ثالثها فتكون عن طريق خدمة Google Colab التي ذكرناها سابقًا. أما كتابة الشيفرة مباشرة في الطرفية وموجه الأوامر، فالخطوات لذلك بسيطة، وكل ما عليك فعله بعد فتح أحد تلك البرامج حسب نظام التشغيل الخاص بحاسوبك هو تنفيذ الأمر الآتي: >> python أو الأمر التالي بالنسبة للإصدار 3 من بايثون: >> python3 تستطيع بعد ذلك كتابة أوامر بايثون مباشرةً وتنفيذها، كما يمكنك الخروج من هذه الشاشة بعد ذلك عبر كتابة الأمر الآتي: >> quit() وأما كتابة الشيفرة في ملف منفصل، فتستطيع إنشاء ملف جديد في أيّ مكان في حاسوبك وتسميته بأيّ اسم تريده، كما يفضَّل أن يكون الاسم معبِّرًا، فالتسمية البسيطة والمعبِّرة من الأمور المهمة. احفظ بعد ذلك الملف بصيغة py -وهي صيغة اختصارية لكلمة Python-، فإذا كان مثلًا اسم الملف Program، فستكون التسمية الكاملة للملف Program.py، ثم اذهب إلى المكان المخزن فيه الملف غبر الطرفية أو موجِّه الأوامر، وبعدها نفِّذ الأمر التالي: >> python Program.py والطريقة الثالثة، تستطيع ببساطة استخدام Google Colab من خدمة Google Drive ومن ثم إنشاء ملف جديد من نوع Google Colaboratory، ثم البدء في إضافة الفقرات، فيمكنك إضافة شيفرات بايثون في ذلك الملف بجانب نصوص عادية وبذلك تستطيع كتابة ملاحظات وتعليقات بين أسطر الشيفرات ويمكنك في الوقت نفسه تنفيذ الشيفرات ككل أو أجزاء محددة. سنبدأ بأمر الطباعة لكتابة أول برنامج بايثون خاص بك، فوظيفة أمر الطباعة في بايثون وفي كثير من اللغات الأخرى، هي طباعة نص على شاشة المستخدِم عند تشغيل البرنامج، وقد ذكرنا ذلك الأمر سابقًا عند الحديث عن الخوارزميات في البرمجة، فعند كتابة الأمر print والذي يعني اطبع بالإنجليزية، فيجب إلحاقه بقوسين، ومن ثم فتح علامات تنصيص بداخل القوسين تحتوى على الجملة التي نريد طباعتها. print ("Hello World") قد يُستخدَم الأمر print لطباعة النصوص على الشاشة أو لطباعة الأرقام، فالأمر سيان في حالة الطباعة، ولكن لا يجب إضافة علامات تنصيص في حالة طباعة الأعداد. print (3) >> 3 كما أنه من الممكن طباعة نتيجة عملية رياضية بسيطة مثل عمليات الجمع والطرح كما في الأمثلة الآتية: print (3+3) >> 6 print (6-4) >> 2 يمكن أيضًا طباعة عمليات الضرب والقسمة وباقي القسمة، إذ يمكنك عبر كتابة الشيفرة التالية طباعة حاصل ضرب عددين مثلًا: print (6*6) >> 36 والأمر بسيط كذلك لطباعة حاصل قسمة عددين: print (49/7) >> 7.0 أما حالة طباعة باقي القسمة، فسنستخدِم رمز النسبة المئوية %: print (50%7) >> 1 كما يمكنك طباعة أيّ عدد من النصوص باستخدام علامة الزائد + كما في المثال الآتي: print ("Hello " + "World!") >> Hello World! إذا أردنا تضمين قيمة عددية داخل نص، فيجب فيجب تحويل العدد إلى نص لأنّ الأعداد في بايثون وفي عدد من اللغات الأخرى عمومًا هي نوع من أنواع البيانات، لذلك يجب استخدام دالة str في هذه الحالة لتحويل العدد إلى نص لتستطيع لغة بايثون التعامل معها على أساس نص. print ("Hello "+str(2)+"nd "+"World!") >> Hello 2nd World! نستطيع الاستغناء عن دالة str إذا أدرجنا الأعداد داخل علامات التنصيص، إذ ستَعُدّ بايثون الأعداد داخل علامات التنصيص نصًا عاديًا، كما سنتعرف على الدوال بصورة أكبر في الصفحات القادمة. print ("Hello " + "2nd " + "World!") >> Hello 2nd World! المعرفات في بايثون تعد المعرِّفات Identifiers من أساسيات البايثون وهي الكلمات التي تستطيع من خلالها تعريف اسم متغير Variable أو ثابت Constant أو دالة Function أو صنف Class أو وحدة Module، ونختصر ذلك كله الآن بكلمة المعرِّفات فقط للدلالة على أيّ منهم، فتلك المتغيرات والثوابت والدوال والأصناف والوحدات، كلها مواضيع وسنتعرف عليها بالتفصيل في هذا الكتاب. تخضع تسمية المعرفات إلى قواعد محدَّدة لا يُمكن الخروج عنها في بايثون؛ لأنه عند الخروج عن إحدى القواعد سيطبع مفسر بايثون رسالة خطأ عند محاولتك تشغيل البرنامج، وتلك القواعد كما يلي: يجب أن تبدأ بحرف إنجليزي أو شَرطة سفلية Underscore _ ولا يُمكنها البدء برقم أبدًا. لا يمكنها احتواء رموز مثل % أو $ أو & …إلخ، ولكن يمكنها احتواء الأرقام. ألا تكون مطابقةً لأيّ كلمة من الكلمات المفتاحية في بايثون. الكلمات المفتاحية في بايثون هي كلمات تُستخدَم في أصل اللغة، بمعنى أنّ تلك الكلمات يقرؤها مفسر لغة بايثون لإجراء مهمة ما، فكلمة مثل print كما علمنا من قبل تؤدي مهمة طباعة نص أو عدد على الشاشة، لذلك لا نستطيع تعريف متغير أو ثابت أو دالة بهذا الاسم، وتكون جميع الكلمات المفتاحية في لغة بايثون كما يلي: table { width: 100%; } thead { vertical-align: middle; text-align: center; } td, th { border: 1px solid #dddddd; text-align: right; padding: 8px; text-align: inherit; } tr:nth-child(even) { background-color: #dddddd; } and exec not as finally or assert for Pass break from print class global raise continue if return def import try del in while elif is with else lambda yield except والجدير بالذكر أنّ جميع تلك الكلمات المفتاحية لا تحتوي على أي حرف كبير، وبما أنّ لغة بايثون لغة حساسة لحالة الأحرف، فمن تسمية أيّ معرِّف بتلك الكلمات في حالة تغيير حالة الأحرف، بمعنى أنه لا يُمكنك تسمية متغير باسم print، لكن يمكنك تسمية متغير باسم Print أو PRINT لأنه بالنسبة لبايثون، تكون الكلمات الثلاثة السابقة مختلفةً تمامًا عن بعضها، وبناءً على ذلك، فإذا أردت تسمية متغير أو دالة أو صنف في بايثون، فيجب عليك اتباع القواعد السابقة. كما أنّ هناك أيضًا في بايثون بعض التوصيات أثناء التسمية، وهي ليست قواعدًا يجب اتباعها بل هي أقرب إلى العُرف، ولكن من الأفضل اتباعها حتى تكون الشيفرة المصدرية في أفضل صورة ممكنة، وتلك التوصيات هي كما يلي: اسم الصنف من المفضل أن يبدأ بحرف كبير مثل Mouse وليس mouse. جميع المعرِّفات الأخرى مثل المتغيرات والدوال من الأفضل أن تبدأ بحرف صغير. إذا عرَّفت متغيرًا ما خاصًا، ولا تريد أن يُستخدَم في أيّ مكان آخر في البرنامج، فمن المفضل بدء اسم المتغير بشرطة سفلية واحدة أو شرطتين إذا كان المتغير خاصًا جدًا. السطور والمسافات لدى بايثون نوعًا فريدًا من القواعد عندما يتعلق الأمر بالأسطر والمسافات وتنظيم الشيفرة، إذ تستخدِم معظم لغات البرمجة الأخرى الأقواس المعقوصة { } لكتابة كتلة من الشيفرات، لكن الأمر في بايثون مختلف قليلًا، إذ تُنظَّم كتل الشيفرات باستخدام المسافات، وهي عادةً مسافة جدولة Tab، أو فراغين أو أربعة فراغات spaces، فنكتب كتلةً من الشيفرات لتُنفَّذ عند تحقق شرط معين بالشكل التالي: if something_happens: do_this() else: do_that() نقول للمفسر في المثال السابق الوهمي إذا حدث هذا الأمر، افعل هذا؛ وإذ لم يحدث، افعل ذاك، فالأمر بسيط للغاية، المهم دقق بالمسافات وكيف أن do_this تدخل ضمن الشرط if أما do_that فتدخل ضمن else. وبالمثل، عند كتابة كتلة من الشيفرة داخل أيّ قاعدة شرطية أو غيرها من القواعد، يجب عليك البدء في كتابة أسطر الشيفرة الخاصة بالكتلة بعد مسافة تفصل بينها وبين أول السطر، أو بمعنى أدق تفصل بينها وبين كتلة الشيفرة التي تسبقها، انظر مثلًا: count = 10 if count >= 10: if count <= 20: print ("Count is between 10 and 20") else: print ("Count is larger than 20") else: print ("Count is less than 10") وإليك المثال التالي لموازنة طريقة بايثون تلك مع اللغات الأخرى مثل لغة جافاسكربت: let count = 10; if (count <= 20) { if (count <= 20) { console.log("Count is between 10 and 20"); } else { console.log("Count is larger than 20"); } } else { console.log("Count is less than 10"); } تضمَّن كتل الشيفرة في هذا المثال بداخل القواعد الشرطية داخل أقواس معقوصة بغض النظر عن المسافة بين كل سطر وبدايته، المثال السابق يكافئ: let count = 10; if (count <= 20) { if (count <= 20) { console.log("Count is between 10 and 20"); } else { console.log("Count is larger than 20"); } } else { console.log("Count is less than 10"); } المثالان السابقان متطابقان تمامًا ويعملان بلا مشكلة؛ أما في بايثون، فتخضع الشيفرة إلى قاعدة مسافات الأسطر تلك، ولا يُمكن كسر تلك القاعدة، كما أنّ كافة مبرمجي بايثون يحبون قاعدة المسافات لأنها تُجبِر المبرمجين على كتابة شيفرة بسيطة ومنظمة وسهلة القراءة. ومن أساسيات البايثون وأهم القواعد الخاصة بالأسطر في بايثون، نجد قاعدة استكمال الأسطر، فإذا كنت تكتب سطرًا ما وكان هذا السطر طويلًا للغاية وتريد تقسيمه إلى سطرين، فستستطيع في بايثون تحقيق ذلك عبر استخدام الرمز \، فإذا كتبت سطرًا يجمع رقمَين مثلًا ثم يقسم أحدهما على الآخر، وكنت تريد تجزئة هذا السطر إلى سطرين مختلفين، فيمكنك فعل ذلك كما في المثال التالي: 30 + 6 / 6 >> 31.0 30 + 6 \ / 6 >> 31.0 كتبنا في السطر الأول عملية الجمع مع عملية القسمة في سطر واحد مباشرةً وأنتج ذلك العدد 31، أما في المثال الثاني كتبنا عملية الجمع في السطر الأول فقط، ثم ألحقنا عملية الجمع بالرمز \، واستكملنا السطر التالي العمليات بكتابة عملية القسمة مباشرةً، وأنتج ذلك في النهاية العدد نفسه، لكن توجد مع ذلك حالة خاصة لأيّ سطر في بايثون يحتوي على إحدى الأقواس بمختلف أنواعها، مثل [] أو {} أو ()، إذ يمكن كتابة تلك الأسطر على سطرين أو أكثر دون استخدام الرمز السابق ذكره، فالسطر التالي مثلًا يعمل بدون مشكلة حتى مع عدم استخدامنا للرمز. items = ['item_1', 'item_2', 'item_3', 'item_4', 'item_5', 'item_6'] علامات التنصيص توجد اختلافات بسيطة بين علامات التنصيص في لغة بايثون مثل أي لغة برمجة أخرى، إذ يمكنك في بايثون تضمين أيّ نص بين علامتَي تنصيص مُفرَدة ' أو علامتي تنصيص مزدوجة " أو علامتي تنصيص ثلاثية """ أو ''' لكن من أهم قواعد استخدام علامات التنصيص في بايثون هي إنهاء النص بعلامة التنصيص نفسها المُستخدَمة في البداية، فلا يُمكن استخدام علامة تنصيص مُفرَدة في بداية النص ثم استخدام علامة تنصيص مزدوجة في نهايته، وإنما يجب تطابق العلامة في البداية والنهاية للنص الواحد، وإليك أمثلةً على ذلك في أوامر الطباعة: print ("Hello World!") print ('Hello World!') print ("""Hello World!""") أما بالنسبة لعلامات التنصيص الثلاثية، فتُستخدَم في الغالب لامتلاكها ميزةً غير موجودة في العلامات المفرَدة والمزدوجة، إذ تُعَدّ قادرةً على معالجة النصوص التي تتكون من أكثر من سطر، في حين أنّ علامات التنصيص المُفردة والمزدوجة يجب احتوائها على نص مكوَّن من سطر واحد لا أكثر، فلا يمكنك مثلًا طباعة سطرين متتالين عبر علامات التنصيص المزدوجة، أي لا يمكنك تنفيذ المثال التالي في بايثون بصورة صحيحة: print ("Hello World!") لكن يمكنك تنفيذ ذلك الأمر عند استخدام علامات التنصيص الثلاثية كما يلي: print ("""Hello World!""") >> Hello World! التعليقات في أساسيات لغة بايثون ستحتاج في كثير من الأوقات أثناء كتابتك أو عملك على برنامج ما، إلى كتابة بعض الملاحظات على بعض الأسطر، فقد تكون تلك الملاحظات موجهةً لتذكيرك بكيفية عمل هذه الكتلة من الشيفرة، أو لتذكيرك بأمر ما تريد استكماله في هذه الأسطر في وقت لاحق، وتوفر بايثون مثلها مثل بقية لغات البرمجة إمكانية كتابة التعليقات عبر استعمال الرمز # والذي سيؤدي إلى تجاهل ما يليه حتى آخر السطر، انظر مثلًا الشيفرة التالية: # هذا تعليق print ("Hello, Python!") # تعليق آخر >> Hello, Python! كما ترى، فإنّ المثال السابق يعمل عملًا عاديًا وكأنه مكتوب بالشكل التالي دون تعليقات: print ("Hello, Python!") >> Hello, Python! فإذا كتبت أيّ سطر برمجي بعد رمز # فسيتجاهله مفسر بايثون تمامًا كما لو أنه غير موجود؛ وذلك لأن التعليقات هي في الأساس جمل من اللغة الطبيعية البشرية التي يستخدمها المبرمج للتعليق وكتابة الملاحظات بين تعليمات البرنامج. كما أنه في بايثون توجد طريقة أخرى لكتابة التعليقات في أسطر عدة، وذلك باستخدام علامات التنصيص الثلاثية، ومن مميزات هذه الطريقة أنها قد تُستخدم في توثيق الدوال وغير ذلك، كما أن هنالك أدوات تستخلص تلك التعليقات لتوليد توثيق لشيفرة البرنامج ووظائفه. """This is a multi line comment. It's wonderful how easy is Python language!""" print ("Hello World!") تُستخدَم التعليقات استخدامًا كبيرًا أثناء برمجة التطبيقات المعقَّدة، فغير أنها تُستخدَم للتعليق على الشيفرة، فإنها قد تكون مفيدةً بصورة كبيرة في تعطيل وتفعيل بعض الأسطر في الشيفرة أثناء عملك على حل مشكلة ما، مثل نسخ سطر ما ووضعه بداخل التعليق حتى يتجاهله البرنامج، ولكي أحتفظ بذلك السطر لاستخدامه لاحقًا. تعليمات متعددة في سطر واحد تنتهي التعليمة البرمجية في السطر في معظم لغات البرمجة مثل لغة PHP أو جافاسكربت JavaScript عن طريق كتابة رمز الفاصلة المنقوطة ; مما يسمح بكتابة أكثر من تعليمة برمجية في سطر واحد؛ أما في بايثون، فينتهي السطر عن طريق بداية سطر جديد، ولكن مع ذلك تدعم بايثون تلك الميزة أيضًا، إذ يمكنك إنهاء التعليمة البرمجية عبر الرمز ; وهو بالإنجليزية Semicolon، وهو أمر اختياري وليس إجباريًا كما في اللغات الأخرى، وبذلك تستطيع كتابة أكثر من تعليمة برمجية في سطر واحد مثل اللغات الأخرى. print ("Hello"); print("World") >> Hello >> World اقرأ أيضًا المقال السابق: البرمجة والخوارزميات والذكاء الاصطناعي المرجع الشامل إلى تعلم لغة بايثون النسخة العربية الكاملة من كتاب البرمجة بلغة بايثون
    3 نقاط
  4. يمر أغلب مهندسي الذكاء الاصطناعي و تعلم الآلة أثناء تعلمهم للعديد من الخوارزميات الأساسية والتقليدية في تعلم الآلة بمكتبة ساي كيت ليرن Scikit Learn التي توفر هذه الخوارزميات وتوثيقًا جيدًا لها، في هذه المقالة سوف نستكشف هذه المكتبة القوية واستخداماتها ومميزاتها، وما الخوارزميات التي يوفرها، ونستعرض بعض الأمثلة العملية على حالات الاستخدام. ما هي مكتبة ساي كيت ليرن Scikit Learn تعد ساي كيت ليرن Scikit Learn أحد أشهر مكتبات أو أطر عمل لغة بايثون وأكثرها استعمالًا خاصة في مجالات علوم البيانات وتعلم الآلة، فهي توفر مجموعة من خوارزميات الذكاء الاصطناعي المبنية بكفاءة، وتتيح لنا استخدامها بسلاسة حيث تمتلك جميع خوارزميات التعلم المبنية بها طريقة شبه موحدة للتعامل معها، فاستخدام خوارزمية أخرى لنفس الغرض يتطلب ببساطة تغيير سطر واحد من الكود، وتوفر هذه المكتبة إمكانيات كبيرة عند بناء النماذج ومعالجة البيانات وتجهيزها، وحفظ النماذج في صيغة يمكن إعادة استخدامها لاحقًا. مميزات مكتبة ساي كيت ليرن Scikit Learn تسهل مكتبة ساي كيت ليرن Scikit Learn تطوير نماذج تعلم الآلة على المبتدئين والراغبين باختبار الأمور بسرعة، وتوفر لهم العديد من المميزات التي سنسردها ونتعرف عليها مثل: التوثيق الجيد: تتميز المكتبة بوجود توثيق مفصل وأمثلة استخدام كثيرة تساعدنا في البدء بتطوير واستخدام الخوارزميات المختلفة ومعرفة المعاملات التي يمكن ضبطها لتغير أداء النموذج وطريقة تدريبها القيم الافتراضية لمعاملات التحكم : لا داعي للقلق إن كنا نتعلم خوارزمية جديدة ونرغب في تجربتها دون الدخول في جميع التفاصيل وتأثيرات ضبط قيم معاملات التحكم أوالمعاملات الفائقة hyperparameters حيث تضبط المكتبة أغلب العوامل بقيم افتراضية مناسبة لأغلب الاستخدامات، لذا يمكننا التركيز على العوامل الأهم وفهمها بشكل أفضل أدوات للمفاضلة بين النماذج: مع تنوع الخوارزميات المبنية في المكتبة التي يمكنها القيام بنفس المهمة بطرق مختلفة يكون من الصعب على المبتدئ تقرير أي الخوارزميات هو الأفضل للمهمة التي يحاول إنجازها، لذلك توفر لنا المكتبة أدوات للمقارنة بين الخوارزميات المختلفة وعوامل التحكم المختلفة بسلاسة مكتبة غنية بالخوارزميات والأدوات: توفر المكتبة أغلب خوارزميات تعلم الآلة التقليدية، مما يغنينا عن عناء بناء هذه الخوارزميات من الصفر، إذ تتوفر عشرات الخوارزميات التي يمكن تطبيقها من خلال سطور معدودة من الكود، فيمكننا التركيز على تحسين معالجة البيانات وتحسين جودتها واختيار النموذج الأنسب للمشكلة التي لدينا التوافق مع المكتبات الأخرى: تعمل المكتبة بشكل سلس مع المكتبات الأخرى مثل باندا Pandas و نمباي NumPy التي توفر هياكل بيانات وعمليات تسهل اكتشاف أنماط البيانات وتحليلها ومعالجتها لتصبح جاهزة للنموذج الذي نحتاج لتدريبه معالجة البيانات باستخدام ساي كيت ليرن توفر ساي كيت ليرن Scikit Learn العديد من الأدوات الجيدة لمعالجة البيانات وتجهيزها لتدريب النماذج عليها، وكما نعرف تٌعد البيانات وجودتها العامل الأهم في تحسين دقة توقعات النماذج المستخدمة، لذلك هنالك بعض الخطوات التي نحتاج للقيام بها لمعالجة البيانات فمثلًا إذا كانت هناك قيم غير رقمية فنحن بحاجة لتحويلها إلى أرقام فنماذج تعلم الآلة هي نماذج رياضية ولن نستطيع القيام بعمليات حسابية على النصوص أو الصور بشكلها الأصلي. أمثلة على معالجة البيانات الترميز Encoding: هو عملية تبديل بعض البيانات بأرقام يسهل إجراء عمليات رياضية عليها، مع إمكانية إرجاعها لأصلها، يمكن ترميز البيانات في مكتبة Scikit Learn باستخدام الكود التالي: from sklearn.preprocessing import LabelEncoder # ترميز البيانات الوصفية city = ["القاهرة", "الرياض", "دمشق", "القاهرة"] # نعرف المٌرمز الذي يعوض عن اسمٍ برقم يعبر عنه encoder = LabelEncoder() # تقوم هذه الدالة بتجهيز المٌرمز # حيث سيمكننا أن نستخدمه أكثر من مرة بعد هذه الخطوة لترميز البيانات المدخلة له بناءً على أول بيانات أعطت له encoder.fit(city) # الآن يمكننا استخدامه على أي بيانات أخرى لترميزها city_encoded = encoder.transform(city) print(city_encoded) # Output: [1 0 2 1] print(encoder.transform(["الرياض"])) # Output: [0] # عكس الترميز print(encoder.inverse_transform(city_encoded)) # Output: ['القاهرة' 'الرياض' 'دمشق' 'القاهرة'] print(encoder.inverse_transform([2, 1, 0, 0, 1])) # Output: ['دمشق' 'القاهرة' 'الرياض' 'الرياض' 'القاهرة'](city_encoded) التعامل مع القيم المفقودة : قد تتضمن البيانات بعض القيم المفقودة ويمكن التعامل معها في مكتبة Scikit Learn بسهولة من خلال حذف الصفوف التي تحتوي قيمًا مفقودة إن كانت قليلة للغاية، أو التعويض عنها باستخدام المعلومات الإحصائية كالمتوسط الحسابي للقيم، أو بناء نموذج لتوقعها بحسب القيم الموجودة بالفعل. خوارزميات تعلم الآلة في مكتبة Scikit Learn تتضمن مكتبة Scikit Learn العديد من خوارزميات تعلم الآلة التي تساعدنا على تنفيذ مهام متنوعة، وفيما يلي نبذة عن أهم هذه الخوارزميات: أولًا: خوارزميات التعلم الخاضع للإشراف التعلم الخاضع للإشراف Supervised Learning هو نوع من التعلم الآلي يصف المهام التي تكون فيها البيانات المراد توقعها معلوم مخرجاتها الممكنة مسبقًا وتوجد بيانات تحتوي على ملاحظات سابقة تتضمن الوسوم Labels المراد تعليم النموذج توقعها، وسنوضح تاليًا أبرز الخوازرميات التي تندرج تحت هذه النوع. خوارزميات توقع الانحدار Regression توقع الانحدار هو نوع من المهام التي يمكننا القيام بها باستخدام خوارزميات مضمنة في ساي كيت ليرن Scikit Learn، يتوقع هذا النوع من الخوارزميات الحصول على أمثلة سابقة يتعلم منها العلاقة بين المدخلات المعطاة والوسم المراد توقعه، والذي يكون قيمة عددية مستمرة continuous مثل توقع درجة الحرارة أو توقع أسعار المنازل. أمثلة على خوارزميات توقع الانحدار: توقع الانحدار الخطي Linear Regression توقع الانحدار بالدوال متعددة الحدود Polynomial Regression خوزارزميات التصنيف Classification يصنف البشر كل شيء حولهم من الحيوانات والجمادات إلى أنواع الأفلام والروايات، وتتوفر خوارزميات تستطيع محاكاة البشر وتتعلم تصنيف الأشياء المختلفة بإعطاء نماذج وملاحظات سابقة لتصنيفات قام بها البشر من قبل حتي تستطيع الآلة تعلم التصنيف، يمكن الاستفادة من التصنيف في أتمتة العديد من المهام المرجو فيها تصنيف عدد ضخم من العناصر في وقت قليل بالتالي توفير الوقت وزيادة الكفاءة، عملية التصنيف تخرج لنا قيمًا منفصلة discrete. من الأمثلة على استخدام هذه الخوارزميات توقع حالة الطقس هل هو مشمس أم غائم أم ماطر أم حار ...إلخ. وتصنيف الصور، وتوقع تقييمات الأفلام. أمثلة على خوارزميات التصنيف الانحدار اللوجستي Logistic Regression مٌصنّف الجار الأقرب Nearest Neighbors Classification شجرة القرار Decision Tree خوارزميات تجميع النماذج Models Ensemble تتيح لنا ساي كيت ليرن Scikit Learn القدرة على دمج أكثر من نموذج تعلم آلة ليشكلوا نموذجًا أقوى، يمكن تشبيه الأمر بلجنة أو فريق من الأصدقاء كل منهم خبير في مجال معين وعند جمع خبرتهم معًا يغطون على نقاط الضعف الخاصة بهم. يمكن تجميع النماذج باستخدام التصويت Voting حيث نجري تدريب لعدد من النماذج ثم نأخذ بتوقع الأغلبية في حالة كون المشكلة تصنيفية، أما أن كانت المشكلة توقع انحدار يمكن أن تأخذ متوسط التوقعات، لنلاحظ الكود التالي: from sklearn.ensemble import VotingClassifier # التصنيف اللوجيستي model1 = LogisticRegression() # شجرة القرارات model2 = tree.DecisionTreeClassifier() # مٌصنف أقرب الجيران model3 = KNeighborsClassifier(n_neighbors=3) # تجميع لتوقعات النماذج باستخدام التصويت model = VotingClassifier(estimators=[('lr', model1), ('dt', model2), ('knn', model3)], voting='hard') # تدريب النموذج # لاحظ أن مدخلات هذه الدالة هي الخواص المطلوب من النموذج تعلم الأنماط بها # بالإضافة إلى الوسم المٌراد توقعه # تمثل هذه المدخلات التجارب المٌراد للنموذج التعلم منها # يمكنك أن تستخدم هذه الدالة في تدريب أي نموذج في ساي كيت ليرن model.fit(X_train, y_train) # استخدام النموذج في التوقع # البيانات المدخلة للنموذج لم يرها من قبل # ولكنها تحتوي نفس الخواص والأعمدة التي تم تدريب النموذج عليها # نرغب في تدريب النموذج على التعميم لبيانات لم يرها من قبل y_pred = model.predict(X_test) جمعنا في الكود أعلاه عدد من النماذج الضعيفة ومحدودة المعرفة حيث يتدرب كل نموذج على جزء من البيانات، وجمعنا معرفتهم معًا للخروج بتوقع واحد مثال على هذا النوع هو خوارزمية الغابة العشوائية Random Forest وهي تجميع لنماذج من شجرة القرارات Decision Tree البسيطة. تقلل هذه الطريقة من فرص حفظ النموذج للبيانات وتمنحه مرونة أكثر لتعلم الأنماط الحقيقية التي تمكنه من توقع الإجابات الصحيحة عند تعرضه لبيانات جديدة عند تشغيل النموذج. خوارزميات التعلم غير الخاضع للإشراف التعلم غير الخاضع للإشراف Unsupervised Learning هو نوع من تعلم الآلة تكون فيه البيانات غير موسومة، ومهمة النموذج تعلم الأنماط بين البيانات ليكتشف الفروقات بينها، مثلًا إن كانت المدخلات صور فتكون المهمة معرفة أي الصور يمكن اعتبارها تابعة لنفس الشيء دون إعطاء وسم للبيانات في عملية التدريب، ما يعرفه النموذج هو الخواص المُراد للنموذج التعلم منها فقط للتميز بين الصور بناء عليها، وسنوضح تاليًا أبرز الخوازرميات التي تندرج تحت هذه النوع. خوزارميات العنقدة أو التصنيف العنقودي Clustering لا نوفر للنموذج في هذه الحالة التصنيفات والوسوم المتوقع انتماء البيانات لها على غرار التصنيف العادي، ففي العنقدة Clustering على النموذج أن يكتشف هذا بنفسه من خلال تعلم الأنماط الموجودة بالبيانات للتمييز بينها. تستخدم خوزارميات العنقدة في أنظمة التوصية Recommendation systems لتقديم اقتراحات شخصية للمستخدمين تناسب اهتماماتهم، أو فصل عناصر الصورة Image segmentation من خلال تحديد البكسلات التي تنتمي لنفس العنصر Object في الصورة بالتالي تفريقها عن باقي العناصر. أمثلة على خوارزميات العنقدة: العنقدة حول عدد من نقاط التمركز k-means العنقدة الهرمية Hierarchical clustering خوارزميات اختزال البيانات نحتاج لاختزال البيانات Data Reduction في كثير من الحالات بسبب محدودية القدرة الحاسوبية وعدم تأثير كل هذه البيانات بشكل ملحوظ على أداء النموذج، ونجري اختزال البيانات عادة من خلال تقليل أبعادها بدمج بعض الأعمدة أو الخواص بدون خسارة المعلومات الهامة قدر الإمكان، فمثلًا يمكننا تقليل أبعاد الصورة مع الاحتفاظ بملامحها ودقتها قدر الإمكان، أو تقليل عدد الأعمدة من 100 إلى 10 مع احتفاظ الأعمدة العشرة بأغلبية المعلومات التي تؤثر على التوقعات. من أمثلة خوارزميات اختزال البيانات خوارزمية تحليل العنصر الأساسي Principal Component Analysis التي تمكننا من اختزال عدد الأعمدة أو الأبعاد بالبيانات مع الاحتفاظ بأكبر قدر ممكن من المعلومات. # تساعدنا هذه المكتبة على صنع هياكل بيانات مصفوفة # والقيام بالعديد من العمليات الحسابية import numpy as np # هذه الخوارزمية التي سنستخدمها لاختزال البيانات from sklearn.decomposition import PCA # في البداية لنصنع بيانات عشوائية لنقوم بالتجربة # يضمن لنا هذا السطر ثبات القيم العشوائية عند إعادة تشغيل هذا الكود np.random.seed(0) # نعرف مصفوفة عشوائية التوليد، تتكون من 10 صفوف و100 عمود X = np.random.rand(10, 100) # لنعرف الخوارزمية التي استوردناها pca = PCA(n_components=10) # نضع هنا عدد الأعمدة التي نرغب أن تصبح البيانات عليها # لنقم بتشغيل الخوارزمية على البيانات التي معنا x_pca = pca.fit_transform(X) # هذا السطر يقوم بتدريب الخوارزمية على اختزال البيانات وفي نفس الوقت يقوم باختزال البيانات المدخلة # لنرى النتائج print("حجم البيانات قبل الاختزال", X.shape) print("حجم البيانات بعد الاختزال", x_pca.shape) ''' المـــــــــخــرجـــــــــــــات ------------------------------------- حجم البيانات قبل الاختزال (10, 100) حجم البيانات بعد الاختزال (10, 10) ''' خوارزميات كشف الشذوذ كشف الشذوذ Anomaly Detection هو عملية ملاحظة الغير مألوف والخارج عن الأغلبية في البيانات. يستخدم في حالات عددية مثل اكتشاف المعاملات الاحتيالية في البنوك، واكتشاف الأنماط غير المعتادة في تدفق الشبكات مما قد يساعد على منع هجمات إغراق الشبكة بالطلبات، واكتشاف المنتجات المعيبة في خطوط الإنتاج واكتشاف الأنماط غير المعتادة للمؤشرات الحيوية لجسم الإنسان التي تستخدمها تطبيقات الساعات الذكية التي تجمع هذه المؤشرات. من الخوارزميات التي تطبق كشف الشذوذ خوارزمية غابة العزل Isolation Forest، وفيما يلي مثال على طريقة استخدامها: # استيراد نموذج كشف كشف الشذوذ from sklearn.ensemble import IsolationForest # سنستخدمها لتوليد بعض البيانات import numpy as np # نولد البيانات لتجربة النموذج X = np.array([[10, 10], [12, 12], [8, 8], [9, 9], [200, 200]]) # يمكنك ملاحظة أن النقطة الأخيرة شاذة عن باقي النقاط # لنقم بتعريف وتدريب النموذج clf = IsolationForest(contamination=0.2) # %يفترض هذا المعامل أن نسبة شذوذ 20 # لاحظ أن التدريب يتم بدون استخدام وسوم حيث أن هذا النموذج غير خاضع للإشراف clf.fit(X) # في حالة اكتشاف شذوذ سيتم وسمه بسالب واحد لتميزه predictions = clf.predict(X) print(predictions) # Output: [ 1 1 1 1 -1] خوارزميات التعلم الخاضع لإشراف جزئي يستخدم التعلم الخاضع لإشراف جزئي Semi-supervised Learning بيانات تتكون من خليط من البيانات الموسومة Labeled data والبيانات غير الموسومة Unlabeled data أثناء التدريب، يمكن أن يصبح هذا الأسلوب مفيدًا للغاية عندما يكون من الصعب الحصول على بيانات موسومة كافية أو يحتاج الحصول عليها إلى وقت ومجهود ضخم. يستخدم عادة في ترشيح المحتوى في أنظمة التوصية فبعض البيانات قد تكون متوفرة بشكل صريح مثل تقييمات المستخدم للمنتجات والتي يمكن الاستدلال بها لاقتراح المزيد من العناصر، ولكن يمكن أيضًا الاستفادة من المعلومات غير الموسومة والمعروفة ضمنية من خلال تفاعلات المستخدم. كما يستخدم في تدريب نماذج التعلم على الصور ومقاطع الفيديو حيث يمكن وسم بعض الصور أو العناصر فيها بشكل بشري لكن لا يمكن حصر جميع العناصر المختلفة التي قد تكون بداخل صورة ووسمها لذا سنستفيد من دمج الجزء الموسوم من البيانات مع الجزء غير الموسوم في توفير كمية أكبر من البيانات لتدريب نماذج أكثر دقة، وسنوضح تاليًا أبرز الخوازرميات التي تندرج تحت هذه النوع. خوراززميات التعلم الذاتي Self Training يمكننا استخدام التعلم الذاتي Self Training في ساي كيت ليرن Scikit Learn لتحويل أي نموذج تصنيف تقليدي إلى نموذج يمكنه التدريب على البيانات الموسومة وغير الموسومة معًا، شريطة أن يكون النموذج قادرًا على توقع التصنيفات كاحتمالات، ونحتاج لاستخدام نموذج يسمى SelfTrainingClassifier لتحويل النماذج العادية لنماذج خاضعة لإشراف جزئي، لاحظ الكود التالي: from sklearn.tree import DecisionTreeClassifier from sklearn.semi_supervised import SelfTrainingClassifier # نعرف أي مصنف ليكون نموذج الأساس base_classifier = DecisionTreeClassifier() # نقوم بإحاطة نموذج الأساس ليصبح قادرًا على التعلم الذاتي self_training_model = SelfTrainingClassifier(base_classifier) # نقوم بتدريب النموذج مثل أي نموذج تقليدي self_training_model.fit(X_train, y_train) ملاحظة: عند تجهيزنا لبيانات التدريب نحتاج لوسم البيانات غير الموسومة بقيمة 1- حيث أننا لا نستطيع أن نمرر البيانات خلال النموذج وهي غير موسومة. دورة الذكاء الاصطناعي احترف برمجة الذكاء الاصطناعي AI وتحليل البيانات وتعلم كافة المعلومات التي تحتاجها لبناء نماذج ذكاء اصطناعي متخصصة. اشترك الآن اختيار النموذج المناسب قد يبدو اختيار النموذج المناسب في مكتبة ساي كيت ليرن معقدًا، إذ يمكن استخدام أكثر من خوارزمية لحل نفس المشكلة. ولكل خوارزمية معاملات تحكم مختلفة، لذلك يجب علينا استخدام أدوات تساعدنا في مقارنة النماذج وقياس أدائها. فيما يلي بعض المعايير الرئيسية التي يمكن استخدامها: الدقة Accuracy: عدد التوقعات الصحيحة التي توقعها النموذج مقسومًا على إجمالي البيانات. كلما كانت النسبة أعلى، كان النموذج أفضل خطأ المتوسط التربيعي Mean Squared Error: الفرق بين القيمة الفعلية التي نريد التنبؤ بها والقيمة التي توقعها النموذج، ثم تربيع هذا الفرق. وهو يساعد في تحديد مدى دقة التوقعات بحث مصفوفة المعاملات GridSearch: يستخدم لاختبار عدد من المعاملات أو إعدادات النماذج المختلفة دفعة واحدة والعثور على أفضل مجموعة معاملات تحقق أفضل أداء. تستهلك هذه الطريقة وقتًا وموارد حاسوبية كبيرة خاصة إذا كانت المعاملات كثيرة جدًا مقارنة بين ساي كيت ليرن Scikit Learn و تنسورفلو TensorFlow يكمن الفرق الرئيسي بين تنسورفلو TensorFlow وبين ساي كيت ليرن Scikit Learn في تخصص الاستخدام، حيث أن ساي كيت ليرن مكتبة متخصصة بخوارزميات تعلم الآلة التقليدية Traditional Machine Learning بينما تنسورفلو TensorFlow إطار عمل شامل لتطوير وتشغيل نماذج التعلم العميق Deep Learning المبنية على الشبكات العصبية الاصطناعية. وعلى الرغم من إمكانية تدريب شبكات عصبية اصطناعية باستخدام ساي كيت ليرن فهي ليست محسنة لأجل هذا الغرض، إذ لا تستطيع المكتبة الاستفادة من وحدات المعالجة الرسومية GPUs التي تستطيع تسريع تدريب النماذج العميقة بشكل أفضل من وحدات المعالجة المركزية CPUs، بينما لا يقف دعم تنسورفلو TensorFlow عند استخدام GPU واحد، حيث يمكن توزيع التدريب على عدة أجهزة على التوازي وهو شيء صعب التحقيق باستخدام ساي كيت ليرن. الخلاصة تعرفنا في هذه المقالة على مكتبة الذكاء الاصطناعي الشهيرة ساي كيت ليرن Scikit Learn وأبرز مميزاتها ووضحنا بعض التطبيقات الواسعة لخوارزميات التعلم المبنية بها، وكذلك تعرفنا على الفرق بينها وبين إطار العمل تنسورفلو TensorFlow.ننصح بتعلم استخدام هذه المكتبة وتجربتها في بناء وتطبيق نماذج تعلم آلة مخصصة، فهي توفر أدوات قوية ومرنة تمكنكم من تنفيذ حلول مبتكرة في مختلف مجالات الذكاء الاصطناعي. اقرأ أيضًا الذكاء الاصطناعي: دليلك الشامل بناء مصنف بالاعتماد على طرق تعلم الآلة بلغة البايثون باستخدام مكتبة Scikit-Learn العمل مع ملفات CSV وبيانات JSON باستخدام لغة بايثون استخدام التدريب الموزع ومكتبة Accelerate لتسريع تدريب نماذج الذكاء الاصطناعي
    2 نقاط
  5. "أريد تعلم البرمجة لكنني لا أعرف من أين أبدأ!" هذه هي أكثر عبارة تتردد على سمعي من حديثي العهد بالبرمجة، إذ يأتيني هذا السؤال مرارًا وتكرارًا؛ وفي كل مرة أحاول أن أجيب عنه في سياقه، أجد أنني أضيف معلومات جديدة على إجاباتي السابقة، لذا قررت كتابة هذا المقال بعنوان "تعلم البرمجة" لعله يفيد الراغبين في تعلم تطوير التطبيقات في بدء رحلتهم مع تعلم البرمجة من الصفر. جدول المحتويات حرصًا على تنظيم المقالة ولتسهيل الوصول إلى القسم الذي تريده بسهولة، سنذكر هنا جدول المحتويات باختصار: ما هي البرمجة؟ لماذا تتعلم البرمجة؟ ما عليك معرفته لتصبح مبرمجًا الأدوات اللازمة للبدء في تعلم البرمجة لماذا هناك العديد من لغات البرمجة؟ مفاهيم البرمجة مصادر تعلم البرمجة تطوير واجهات المستخدم تطوير الواجهات الخلفية تعلم تطوير تطبيقات الجوال تطوير الألعاب تطوير الأنظمة المدمجة تطوير تطبيقات سطح المكتب كيفية اختيار لغة البرمجة التي تناسبك نصائح لتعلم البرمجة ما هي البرمجة؟ البرمجة هي عملية تقسيم مهمة معينة يراد تنفيذها عبر الحاسوب إلى أجزاء صغيرة ومترابطة وقابلة للتنفيذ بأوامر بسيطة. بعد ذلك، تجري كتابة هذه الأوامر والتعليمات بإحدى لغات البرمجة، والتي هي وسيلة للتخاطب مع الحاسوب. إليك المثال العملي التالي الذي يشرح ماهية البرمجة: إن كنت تتوقع زيارة صديق لك اليوم، واتصل بك ليقول لك: "أنا واقف بجانب الحديقة ولا أعرف كيف أصل إلى منزلك". أنت عادةً تمر كل يوم من جانب الحديقة وتعرف الطريق بينها وبين منزلك شبرًا بشبر. برأيك هل ينفع إن قلت له: "منزلي معروف وقريب من الحديقة وأنا كل يوم أمر من جانبها"؟ لا، بالتأكيد. تحتاج إلى أن تقسِّم المشكلة إلى أجزاء تمثل خطوات بسيطة يستطيع صديقك فهمها وتنفيذها. مثلًا، أخبره أن ينفذ الأوامر التالية: "سر إلى الأمام عشرة أمتار" ثم "اتجه إلى اليمين" ثم "سر إلى نهاية الشارع" ثم "اتجه إلى اليسار". أخبره بعد ذلك: "عُدَّ الأبنية الموجودة على اليسار حتى تصل إلى البناء الرابع" ثم "اصعد إلى الطابق الثاني" ثم "اطرق على الباب الذي سيظهر أمامك". مبارك! بهذه الطريقة، تستطيع أن تدل صديقك على منزلك بدقة. البرمجة هي الشيء نفسه تمامًا. فهل ترى التعابير المكتوبة بين علامتي الاقتباس؟ إنها التعابير التي تكتب بإحدى لغات البرمجة والتي تخاطب الحاسوب بدلًا من صديقك السابق. لغات البرمجة هي مجموعة من المفردات والقواعد اللغوية التي تشكل لغةً وسيطةً للتخاطب مع الحاسوب وأمره بتنفيذ تعليمات وأشياء محدَّدة. فلا الحاسوب يفهم لغة البشر ولا البشر يفهمون لغة الحاسوب، لذا كان هنالك حاجة ملحة لوجود لغة وسيطة يفهمها كلاهما؛ نتيجةً لذلك، انبثق مفهوم لغة البرمجة. بعبارة أخرى، لو أردنا أن نقول للحاسوب "افعل كذا"، فسنحتاج إلى لغةٍ مشتركةٍ بيننا وبينه ليفهم ما نبتغيه، وهنا يأتي دور لغات البرمجة، إذ يمكنك أن تعدّ لغات البرمجة على أنها وسيط بين المبرمج والحاسوب. يهتم المبرمج بالتفكير في تسلسل الخطوات التي على الحاسوب القيام بها لإتمام العمل المطلوب منه (مثل حساب العمر اعتمادًا على تاريخ الولادة)، ثم كتابة هذه الخطوات بترتيب منطقي بإحدى لغات البرمجة. ربما لاحظتَ في الجملة السابقة أن جزءًا من مهمة المبرمج هو التفكير المنطقي، وهذا يجعلنا ننتقل إلى السؤال الشائع "هل أستطيع تعلم البرمجة وأصبح مبرمجًا؟" أو "هل أنا مؤهل لأصبح مبرمجًا؟". لماذا تتعلم البرمجة؟ يبدو أن تعلم البرمجة من الصفر ليس بالصعوبة التي توقعتها، لكنك تريد حافزًا يجعلك تتعلم البرمجة. تسمع كثيرًا أن البرمجة هي مجال المستقبل، وأن وظائف المبرمجين ستكتسح مجال التوظيف في السنوات القادمة؟ أستطيع أن أؤكد لك ذلك، كما أنَّ وظائف البرمجة هي من أعلى الوظائف دخلًا. فلو كنت تريد بدء مشوارك الاحترافي وتريد عملًا مستقرًا وذا دخلٍ ممتاز، فإن تعلم البرمجة والعمل بها هو أفضل خيارٍ أمامك. وظائف البرمجة مريحة عمومًا، فالعمل كله مكتبي أمام حاسوب في بيئة مريحة ومناسبة، وأغلبية الشركات تتبع نظام العمل 40 ساعة في الأسبوع (أي 5 أيام لمدة 8 ساعات يوميًا)، ولا تغفل عن قدرتك على العمل عن بعد من خلال الانترنت أو كمستقل في أوقات فراغك. تعلم البرمجة سيوسع أفق تفكيرك كثيرًا، خصوصًا أن تعاملك مع الحاسوب يتبع إلى التفكير المنطقي، وستجد أن البرمجة ستسهل لك القيام بأمور أخرى في الحاسوب. ما عليك معرفته لتصبح مبرمجًا يتردد الكثيرون في تعلم البرمجة متذرعين بأن مستواهم في الرياضيات ليس ممتازًا، وهذا ليس صحيحًا، فصحيحٌ أنَّ هنالك أمور تعترضك أثناء أداء عملك كمبرمج تتطلب خبرة في الرياضيات، إلا أنَّه قد تمر عليك فترات طويلة لا تحتاج فيها إلى مسائل رياضية. كل ما يلزمك للبدء في تعلم البرمجة هو الأساسيات التي يعرفها الجميع. إلى حين اعتراضك أية مسألة أو مشكلة تتطلب مهارة في الرياضيات، هنالك الكثير من المصادر والمراجع التي تستطيع الرجوع إليها آنذاك. بعبارة أخرى، أجِّل هذا الأمر قليلًا ولا تخف. الأهم من ذلك هو أن تكون قادرًا على التفكير بشكل منطقي. التفكير المنطقي التفكير المنطقي هو المهارة التي تجمع كافة المبرمجين تحت مظلة واحدة، وهي أساس كتابة الخوارزميات، إذ يجب أن تكون قادرًا على اكتساب هذه المهارة وتطويرها. الخوارزميات كلمة "الخوارزميات" هي الكلمة المرعبة التي ينفر منها البعض، فكل ما يتخيلونه عند ذكرها هو الرياضيات المعقدة والمعادلات الطويلة والرموز العجيبة، لكن الأمر بسيط جدًا؛ فالخوازرميات هي تطبيقٌ للتفكير المنطقي في خطوات متسلسلة واضحة تمامًا لحل مشكلة ما. لكي أوضِّح لك أن الخوارزميات ليست أمرًا معقدًا، سأخبرك بكيفية كتابة برنامج يسأل المستخدم عن سنة ميلاده، ثم يعيد عمره الحالي بالسنوات. الخطوة الأولى: إظهار رسالة نصية نطلب فيها من المستخدم إدخال تاريخ ميلاده. الخطوة الثانية: تخزين سنة الميلاد التي أدخلها المستخدم. الخطوة الثالثة: الحصول على السنة الحالية. الخطوة الرابعة: طرح مدخلات المستخدم من السنة الحالية. الخطوة الخامسة والأخيرة: إظهار الناتج. ما سبق هو خوارزمية بسيطة تتألف من خطوات متسلسلة، لكن إذا أمعنّا النظر فيها سنجد خللًا في حال أدخل المستخدم تاريخًا أكبر من التاريخ الحالي، أي لو أدخل 2050 مثلًا بدلًا من 1995. عندها سيصبح العمر المعاد من الخوارزمية سالبًا، ويمكننا أن نحل هذه الإشكالية منطقيًا بوضع شرط يمنع المستخدم من إدخال تاريخ أكبر من التاريخ الحالي. إطارات العمل كلمة أخرى شائعة جدًا في عالم البرمجة هي "إطارات العمل" frameworks، إطارات العمل هي مجموعة من الشيفرات البرمجية التي تسهل على المبرمج إنشاء التطبيقات، بتوفير وحدات جاهزة تقدم خدمات متنوعة مثل تسجيل المستخدمين، وإرسال البريد الإلكتروني، والتعامل مع قواعد البيانات. أي يمكنك أن تعدّها أدوات برمجية تساعدك في برمجة تطبيقك وتسهِّل لك فعل ذلك. الأدوات اللازمة للبدء في تعلم البرمجة تحتاج إلى حاسوبٍ بمواصفات جيدة (ليس من الضروري أن يكون من أفضل الحواسيب، وإنما أن يمتلك مقدارًا جيدًا من الذاكرة العشوائية). لا ننصح بمواصفات معينة أو نظام تشغيل معين، استعمل ما يحلو لك وما ترى نفسك معتادًا عليه (سواءً كان ويندوز أو لينكس أو ماك). ستحتاج أيضًا إلى اتصالٍ جيد بالإنترنت للوصول إلى المواد التعليمية، ولتنزيل البرمجيات والمكتبات اللازمة للتطوير. أما بخصوص أدوات التطوير، فستحتاج إلى برمجية لكتابة الشيفرات، وهنالك نوعان رئيسيان لها: المحررات النصية: مثل Visual Studio Code أو Atom أو Sublime Text أو Bracktes أو Notepad++‎. وهذه المحررات النصية تكون بسيطة في أغلبها، وتوفر ميزات أساسية مثل تلوين الشيفرات، وبعض ميزات الإكمال التلقائي، وتدعم أغلبيتها إضافات لزيادة وظائفها. وظيفة هذه المحررات النصية عمومًا هي تعديل الشيفرات بسهولة وسرعة. ننصحك بتجربة Visual Studio Code لشهرته حاليًا وكثرة إضافاته ودعمه الممتاز من شركة Microsoft. بيئات التطوير المدمجة: مثل Visual Studio و Eclipse و Android Studio و NetBeans و Apple Xcode وغيرها. وهذه البيئات توفر ميزات أكثر بكثير من المحررات النصية، مثل تشغيل الشيفرات وتنقيحها (debugging) وميزات التحكم بالإصدارات (version control) والاتصال بقواعد البيانات وخلاف ذلك. لماذا هناك العديد من لغات البرمجة؟ قد تتساءل، لماذا هناك العديد من لغات البرمجة؟ أليست هذه اللغات كلها تنفذ الهدف ذاته؟ لماذا لا يكون هنالك لغة موحدة بين المبرمجين والحاسوب؟ الحقيقة أنّه توجد لغة برمجة واحدة ولكن ليست إحدى اللغات التي تراها أمامك في الصورة. اللغة التي نشير إليها هي لغة الآلة التي يستطيع معالج الحاسوب قراءتها وفهمها. أتتساءل ما هي لغة الآلة وكيف تبدو؟ إليك مقطعًا منها: معلومٌ أنّ معالج الحاسوب لا يفهم شيئًا سوى الأصفار والواحدات، وهذه اللغة -أي لغة الآلة- هي تمثيل للأصفار والواحدات بطريقة تخبر الحاسوب بما يجب عليه فعله. الجدير بالذكر أن هذه اللغة عصية الفهم على البشر، وحتى إن استطعت كتابة شيفرة مثل الشيفرة الموضحة بالصورة (كما في السنوات الأولى من بداية اختراع الحاسوب)، لن يفهمها الآخرون ولن يستطيع أحد التعديل على الشيفرة وتطويرها لاحقًا باستثنائك. سعيًا لإيجاد لغة قريبة من لغة البشر، انقسمت لغات البرمجية إلى قسمين: لغات البرمجة منخفضة المستوى، ولغات البرمجة عالية المستوى وذلك تبعًا لمدى قربها من لغة الآلة أو لغة البشر على التوالي. أي أنّ لغات البرمجة منخفضة المستوى هي اللغات الأقرب للغة الآلة آنفة الذكر مثل لغة التجميع Assembly language، ولغات البرمجة عالية المستوى هي اللغات الأقرب للغة البشر مثل لغة بايثون وجافا. تنفيذ البرامج المكتوبة بلغات برمجة عالية المستوى يقودنا الحديث عن اللغات عالية المستوى واللغات منخفضة المستوى إلى الحديث عن كيفية تنفيذ المعالج للشيفرة المكتوبة بلغة عالية المستوى لا يفهمها المعالج (أليس هذا ما تفكر به الآن؟). عرفنا أن المعالج يفهم الأوامر والتعليمات المكتوبة بلغة منخفضة المستوى (لغة الآلة)، فمَثَلُ هذه العملية كمَثَلِ شخصٍ أجنبي تعلم اللغة العربية وبدأ التحدث مع ناطقٍ باللغة العربية، إذ يمكن لهما التواصل مباشرةً - ليخبر كل منها ما يريد من الآخر فعله - دون وسيط. أمَّا مَثَلُ كتابة برنامج بلغة عالية المستوى أقرب إلى لغة البشر والطلب من الحاسوب تنفيذه كمثل ناطق باللغة الهندية يريد التخاطب مع ناطق باللغة العربية دون أن يفقه أحدهما لغة الآخر. في هذه الحالة، لن يستطيع أحدهما فهم ما يتكلم به الآخر وستفشل عملية التواصل. قد تقول: لماذا لا يحضران مترجمًا يترجم ما يقوله كل منها للآخر؟ حسنًا، هذا ما يحصل تمامًا عندما يراد تنفيذ برنامج بلغة لا يفهمها معالج الحاسوب. في اللغات البشرية، هنالك نوع واحد من المترجمين يعرفه الجميع للترجمة من لغة إلى آخرى؛ أما في لغات البرمجة، هنالك نوعان من المترجمين بين اللغات هما: المفسر interpreter، والمترجم compiler. بناءً على ذلك، تنقسم لغات البرمجة إلى لغات مفسرة ولغات مترجمة. (من الآن وصاعدًا، كلما ذكرنا لغات البرمجة، فنحن نشير إلى لغات البرمجة عالية المستوى.) -المفسر (interpreter): وهو برنامج خاصٌ يفسِّر الشيفرة المصدرية لبرنامج مكتوب بلغة عالية المستوى سطرًا بسطر ويحولها إلى لغة منخفضة المستوى لينفذها الحاسوب مباشرةً. -المترجم (compiler): وهو برنامج خاصٌ يحوِّل الملفات المصدرية لبرنامج مكتوب بلغة عالية المستوى إلى ملف تنفيذي مكتوب بلغة الآلة دفعةً واحدةً، ثم يمكن تشغيل الملف التنفيذي على الحاسوب للقيام بالمهمة المطلوبة. لماذا يوجد الكثير من لغات البرمجة عالية المستوى؟ الآن وبعد أن عرفت الفرق بين لغة الآلة ولغة البشر، لربّما ما زلت تتساءل عن كثرة اللغات البرمجية عالية المستوى المتوافرة وعدم وجود لغة واحدة. نستطيع القول أنك خطوت خطوةً جيدةً للأمام إذ أصبحت الآن أكثر دقة. جواب سؤلك هو أنّ كل لغات البرمجة تُستخدم لتحويل فكرة منطقية إلى سلسلة أوامر يمكن للحاسوب أن ينفذها. فعلى سبيل المثال لا الحصر يمكنك استخدام أي من Ruby أو Java أو Python أو C#‎ أو Go أو JavaScript لبناء موقع ويب. لكن يمكنك أن تعدّ لغات البرمجة على أنها أدوات، وكل أداة تسهّل مهمة دونًا عن أخرى. فعلى سبيل المثال، السيارة والحافلة والدراجة والمحراث الزراعي كلها وسائط نقل، لكنها مختلفة الاستخدام؛ فلا يمكنك أن تذهب وعائلتك لقضاء إجازة صيفية مستخدمين المحراث الزراعي، كما لا يمكنك استخدام سيارة سباق في مدينة مكتظة ذات شوارع ضيقة للذهاب بها إلى العمل. مع أن آلية عمل هذه المركبات متشابهة. والأمر سيانٌ بالنسبة إلى البرمجة. خلاصة القول أنّ هنالك لغات برمجة متخصصة بإنشاء تطبيقات سطح المكتب، وأخرى متخصصة بإنشاء تطبيقات الجوال، وأخرى تستعمل خصيصًا لمواقع الويب، وأخرى لبرمجة العتاد، وهذا ما يحيلنا إلى الحديث عن مجالات البرمجة واللغات الأنسب لكلٍ منها. مفاهيم البرمجة "حسنًا، اقتنعتُ أن البرمجة مناسبة لي وليست صعبة كما كنتُ أتخيل، من أين أبدأ طريقي في تعلم البرمجة إذًا؟" قبل الإجابة عن السؤال السابق، سآخذ وقتي لأشرح لك بعض المفاهيم الخاصة بالبرمجة، ثم سنتحدث عن مجالات العمل فيها وما المسار الأفضل لتعلمك كلًا منها. أنت تعلم أن البرنامج هو سلسلة أوامر ينفذها الحاسوب لحل مشكلة ما، والبرنامج نفسه مكتوب بلغة يفهمها الحاسوب تسمى لغة الآلة. من الأمور الملحوظة التركيز كثيرًا على لغة البرمجة ذاتها أثناء بداية تعلم البرمجة. سأخبرك حقيقةً صادمةً: "لغة البرمجة التي تستعملها ليست بتلك الأهمية التي تتوقعها"، أنا لا أقول لك أن جميع لغات البرمجة متماثلة أو تُستعمل لنفس الاستعمالات، لكن لا تركِّز كثيرًا على تعلم كيفية الكتابة في لغة برمجة ما وتهمل المفاهيم البرمجية التي تقف وراءها. المتغيرات والثوابت عليك أن تتعرف على مفهوم المتغيرات variables المستعمل في جميع لغات البرمجة، والذي يعني إسناد قيمة ما إلى رمز أو كلمة وتخزين هذه القيمة في الذاكرة. فلو أردنا أن نخزن العبارة "Hello World" في متغير ما فنكتب شيئًا شبيهًا بما يلي: var variable_name = "Hello World"; أي أننا نسند الجزء الموجود على يمين إشارة المساواة إلى المتغير المذكور على يسار إشارة المساواة. يمكننا أن نستنتج من اسم "المتغيرات" أن قيمتها قابلة للتغيير خلال تنفيذ البرنامج، فيمكننا في مكانٍ ما من الملف المصدري أن نعيد تعريف المتغير السابق بكتابة: var variable_name = "New value"; أما الثوابت فهي تتشابه مع المتغيرات في كثيرٍ من النواحي، إلا أنك لا تستطيع إعادة تعريف قيمتها بعد تعريفها أول مرة. قد تستفيد من الثوابت عندما تكون متأكدًا تمامًا من عدم تغيير القيمة خلال فترة تنفيذ البرنامج. فلو أردنا تعريف ثابت اسمه pi يحتوي على القيمة 3.14 (والتي سنعرف أنها لن تتغير مطلقًا)، فيمكننا أن نكتب: const pi = 3.14; وإذا حاولتَ تغيير قيمة الثابت بعد تعريفه فستحصل على رسالة خطأ. الشروط تدعم جميع لغات البرمجة تعريف شروط تُنفَّذ في حالات معينة. ففي الخوازرمية السابقة التي شرحنا فيها حساب العمر، يمكننا أن نكتب الشرط بالعربية كما يلي: إذا كان (تاريخ الميلاد أكبر من التاريخ الحالي): نقول للمستخدم أن هنالك خطأ وإلا: سنحسب العمر بطرح تاريخ الميلاد من التاريخ الحالي وإذا أردنا كتابتها بإحدى لغات البرمجة فستبدو شبيهةً بما يلي: if ( user_birth > current_year ) { // ERROR! } else { age = current_year - user_birth; } لا تلقِ للأقواس بالًا، فهي جزء من لغة البرمجة، وقد تختلف من لغة لأخرى، وليست موضع اهتمامنا حاليًا. حلقات التكرار ماذا لو كانت لدينا قاعدة بيانات فيها أكثر من مستخدم ولكل مستخدم تاريخ ميلاد. لا تقل لي سنأخذ التواريخ يدويًا وندخلها إلى البرنامج! هذا مضيعةٌ للوقت، والصواب هو إنشاء حلقة تكرار تأخذ قيمة تاريخ الميلاد الخاص بكل مستخدم ثم تحسب عمره كما أسلفنا في القسم السابق. دعنا نعدل الخوارزمية البسيطة لنضيف تكرارًا فيها: ما أجمل البرمجة! تخيل لو كان عندك ألف مستخدم، وكان عليك حساب أعمارهم، يمكنك بضغطة زر أن تحسبها كلها. الدوال الدالة function هي مجموعة من التعليمات البرمجية التي تقبل مدخلات وتعيد القيمة المطلوبة. تكون الدوال عادةً قصيرةً وتقوم بمهمة وحيدة فقط. فمثلًا لو أردنا تعريف دالة باسم divide تقبل عددين، وتعيد ناتج قسمة العدد الكبير على الصغير، فيمكننا أن نكتب الخورزمية الآتية: مصادر تعلم البرمجة للمبتدئين أول ما سيتبادر إلى ذهنك بعد قرارك تعلم البرمجة هو من أين سأتعلم؟ هنا يأتي دور القسم التعليمي المتكامل في حسوب ليقدم للمبتدئ (والمحترف على حدٍ سواء) محتوى علمي مميز ومبسط. تزخر أكاديمية حسوب بالمحتوى المفيد عن تعلم البرمجة للمبتدئين وحتى الخبراء أي على كافة المستويات، ستجد فيها أقسامًا تشرح لغات البرمجة وتقنياتها كلها. ولدينا قسم للأسئلة البرمجية التي يمكنك أن تطرح فيه سؤالك وسيجيب عليه أحد أفراد مجتمع أكاديمية حسوب. أضف إلى ذلك أن الأكاديمية توفر قسمًا للدورات المتخصصة التي تبدأ معك من الصفر وحتى احتراف لغة البرمجة التي تريد تعلمها مع كادر من المدربين المختصين الذي يقدمون لك المساعدة ويجيبون عن جميع استفساراتك. وهنالك قناة للأكاديمية على يوتيوب ننشر فيها دوريًا دروسًا قصيرةً عن تساؤلات محددة ومفاهيم البرمجة وخلافه. لا تنسَ الاشتراك في قناة الأكاديمية لتصلك الفيديوهات الجديدة. ماذا لو أردتَ التعمق أكثر في لغة معيّنة؟ تأتي هنا موسوعة حسوب التي توفِّر توثيقًا عربيًا كاملًا وعالي الجودة، مدعّمًا بالأمثلة لمختلف لغات البرمجة وتقنيات تطوير الويب والجوال. ستكون الموسوعة مرجعًا تعود إليه في مسيرتك البرمجية، وتستعين بها لمعرفة التفاصيل الدقيقة عن لغات البرمجة. فأنت لست مضطرًا لحفظ كل شيء في لغة البرمجة، إذ حتى المبرمجون المختصون ذوو الخبرة يعودون إلى التوثيقات بين الفينة والأخرى أثناء عملهم. لننطلق الآن للتحدث عن مجالات البرمجة الأساسية وما اللغات والتقنيات المستعملة فيها. تطوير واجهات المستخدم يبدأ أغلبية المطورين مشوارهم من خلال تعلم تطوير واجهات المستخدم عند اتخاذ قرارهم لدخول مجال تطوير وبرمجة مواقع الويب، وذلك لسهولة اللغات المستعملة في هذا المجال. هدف هذا المجال هو تطوير صفحات الويب التي تعرض محتوى مختلف مواقع الويب، وهي الصفحات التي تراها عند زيارتك لموقع أكاديمية حسوب أو موسوعة حسوب أو مستقل أو أي موقع آخر. تتألف صفحة الويب من مجموعة من المكونات، وتُكتَب هذه المكونات باستخدام لغة HTML، وبعد كتابة البنية الهيكلية للصفحة سنأتي على تنسيقها باستخدام لغة CSS، وهي اللغة المستعملة لإضفاء شكل وهيئة على عناصر HTML. أي أن عناصر HTML تصف محتوى الصفحة (مثل الترويسات والقوائم والمحتوى الرئيسي والفقرات والروابط والصور والفيدوهات)، وقواعد CSS تُعرِّف كيف يجب أن تبدو هذه العناصر (سواءً من ناحية الألوان أو المساحات أو الخلفيات أو الخطوط أو خلاف ذلك). تأتي لغة JavaScript مكملةً لهما وتستعمل لإعطاء بعض عناصر الصفحة صفاتٍ تفاعلية، مثل شريط متحرك من الصور أو قوائم تظهر عند وقوع حدث معيّن …إلخ. هنالك تقنيات كثيرة تستعمل في تسهيل إنشاء الواجهات الأمامية وسنذكر بعضها: إطار Bootstrap لتسهيل تنسيق عناصر الصفحة. مكتبة jQuery لتسهيل التعامل مع عناصر الصفحة باستخدام JavaScript. مكتبة React JS: لتسهيل تطوير واجهات المستخدم بالاعتماد على مكونات قابلة لإعادة الاستخدام. لغة Sass لإنشاء ملفات CSS بسرعة وسلاسة. أدوات بناء مثل Webpack الذي يسهِّل تحويل الملفات المصدرية للتطبيق إلى النسخة النهائية التي ستعرَض للمستخدم. لتعلم تطوير واجهات المستخدم، ننصحك بالتسجيل في دورة تطوير واجهات المستخدم المقدمة من أكاديمية حسوب، والتي تحتوي على أكثر من 72 ساعة فيديو تتوزع على ثمانية مسارات تعليمية تشرح أمثلة عملية تطبيقية شرحًا مفصلًا. أثناء مشاهدتك للدورة، يمكنك أن تعود إلى موسوعة حسوب لتتعرف على توثيق لغات البرمجة المذكورة، وذلك للاطلاع على تفاصيل وأمثلة أكثر عن كل جزئية من الجزئيات المشروحة في دورة تطوير واجهات المستخدم. اللغات والتقنيات المستخدمة في تطوير واجهات المستخدم: HTML و CSS و JavaScript و Bootstrap و Sass و jQuery و Webpack. تطوير الواجهات الخلفية قد تتساءل: ماذا يعني تطوير الواجهات الخلفية (backend)؟ وما الفرق بينه وبين تطوير واجهات المستخدم (frontend)؟ الفرق بينهما هو أن الواجهات الخلفية هي البرمجيات التي تُنفَّذ على الخوادم وتجري عمليات عليها مثل التعامل مع قواعد البيانات والملفات والخدمات الخارجية، أما واجهات المستخدم فهي الصفحات التي تظهر على شاشة الزائر في متصفحه. سأطرح عليك الخيارات المتاحة أمامك للبدء في مجال تطوير الواجهات الخلفية، وجميع اللغات المذكورة هنا هي لغات ناجحة وقوية ولا يهم أي لغة تختار منها، المهم أن تتطلع على شيفرات بسيطة من كل لغة وتتخذ قرار تعلمها، واحذر من تضييع وقتك في التنقل بين لغات البرمجة والبحث عن أفضلها، فكلُ لغةٍ ممتازةٌ في مجالها. تعلم البرمجة باستخدام لغة PHP بعد تبيان الفرق بين واجهات المستخدم والواجهات الخلفية، يمكن القول بأن أشهر لغة لتطوير الواجهات الخلفية هي لغة PHP، وتتفوق على اللغات المنافسة لها أضعافًا مضاعفة. تعلم البرمجة بلغة PHP أمر سلس، فهي لغة سهلة التعلم وبسيطة الشكل، والمجتمع حولها كبير وتطويرها مستمر. هذه اللغة هي خيار استراتيجي لمن يريد الدخول إلى مجال تطوير الواجهات الخلفية. هنالك عدد من البرمجيات المكتوبة بلغة PHP مثل ووردبريس WordPress ودروبال Drupal وميدياويكي MediaWiki (التي تشغِّل ويكيبيديا وموسوعة حسوب) وغيرها الكثير؛ إضافةً إلى عددٍ كبير من إطارات العمل مثل Laravel و CodeIgniter و Symfony و CakePHP و Yii وغيرها، وهذا ما يدل على إمكانيات اللغة الكبيرة والمجتمع الكبير الذي يحيط بها. لتعلم تطوير الواجهات الخلفية باستخدام PHP، ننصحك بالتسجيل في دورة تطوير تطبيقات الويب باستخدام PHP المقدمة من أكاديمية حسوب، والتي تحتوي على 75 ساعة فيديو تتوزع على اثني عشر مسارًا تعليميًا تبدأ بأساسيات لغة البرمجة PHP للمبتدئين، مرورًا بشرح أمثلة عملية تطبيقية بالتفصيل، ووصولًا لتطوير التطبيقات باستخدام إطار العمل Laravel، وشرح تطوير ووردبريس. أثناء مشاهدتك للدورة، يمكنك أن تعود إلى موسوعة حسوب للاطلاع على توثيق لغة PHP وإطار العمل Laravel. اللغات والتقنيات المستخدمة في تطوير تطبيقات الويب باستخدام PHP هي: PHP و Laravel وقواعد البيانات (مثل MySQL و PostgreSQL وغيرها). تعلم البرمجة باستخدام لغة روبي - Ruby إذا كنتَ تبحث عن لغةٍ أنيقة وسهلة الاستعمال فستجد ضالتك في لغة روبي Ruby فهي من أجمل اللغات وأسلسها كتابةً، وهي لغة برمجة عامة يمكن استخدامها لتطوير مختلف أنواع التطبيقات ومن ضمنها تطوير تطبيقات الويب. ذاع صيت روبي في تطوير الويب بعد نشر إطار العمل Ruby on Rails (يشار إليه اختصارًا "ريلز"). هنالك إطارات عمل أخرى مثل سيناترا Sinatra لكن يبقى ريلز أشهرها. لتعلم تطوير الواجهات الخلفية باستخدام روبي، ننصحك بالتسجيل في دورة تطوير تطبيقات الويب باستخدام روبي المقدمة من أكاديمية حسوب، والتي تحتوي على 20 ساعة فيديو تتوزع على أربعة مسارات تعليمية تشرح أمثلة عملية تطبيقية شرحًا مفصلًا، وتشرح تطوير التطبيقات باستخدام إطار العمل ريلز. أثناء مشاهدتك للدورة، يمكنك أن تعود إلى موسوعة حسوب للاطلاع على توثيق لغة روبي وإطار العمل ريلز. اللغات والتقنيات المستخدمة في تطوير تطبيقات الويب باستخدام روبي: روبي و ريلز وقواعد البيانات (مثل MySQL و PostgreSQL وغيرها). تعلم البرمجة باستخدام لغة جافا سكربت - JavaScript نعم! تستعمل JavaScript في تطوير الواجهات الخلفية أيضًا. الفضل يعود لبيئة Node.js التي تسمح للمطورين باستخدام JavaScript لكتابة برمجيات تعمل من جهة الخادم وذلك لتوليد صفحات ويب ديناميكية قبل إرسالها إلى المتصفح، وتستطيع Node.js التعامل مع الملفات وقواعد البيانات ومختلف أنظمة الشبكات وخدمات أنظمة التشغيل. هل يوجد أجمل من استخدام نفس اللغة لبرمجة الواجهات الأمامية لمواقع الويب والواجهات الخلفية؟ وكل ذلك باستخدام لغة سهلة التعلم والاستعمال ومدعومة دعمًا ممتازًا من المجتمع. تعلم لغة JavaScript لتطوير الواجهات الخلفية من خلال التسجيل في دورة تطوير التطبيقات باستخدام JavaScript المقدمة من أكاديمية حسوب، والتي تحتوي على 69ساعة فيديو تتوزع على أحد عشرمسارًا تعليميًّا تشرح أمثلة عملية تطبيقية شرحًا مفصلًا، وتشرح تطوير الواجهة الخلفية باستخدام Node.js. أثناء مشاهدتك للدورة، يمكنك أن تعود إلى موسوعة حسوب للاطلاع على توثيق لغة JavaScript وبيئة العمل Node.js. اللغات والتقنيات المستخدمة في تطوير تطبيقات الويب باستخدام JavaScript: لغة JavaScript وبيئة Node.js وإطار العمل Express.js وقواعد البيانات (مثل MongoDB و MySQL و PostgreSQL وGraphQL وغيرها). تعلم البرمجة باستخدام لغة بايثون - Python لغة بايثون متعددة الاستعمالات، ويمكن عدّها على أنها أسهل لغة برمجة على الإطلاق، إذ تبدو شيفرتها البرمجية كأنها مقالة مكتوبة باللغة الإنكليزية. إذا أردتَ لغةً سهلةً ومدعومةً دعمًا ممتازًا ولها أطر عمل كثيرة فأنت تبحث عن لغة بايثون. الخيارات المتاحة أمامك هي إطار العمل جانغو (Django) وفلاسك (Flask) وغيرها، يمكنك تعلم لغة البرمجة بايثون لتطوير الواجهات الخلفية من خلال قراءة سلاسل المقالات عن تعلم بايثون في قسم البرمجة في أكاديمية حسوب، ثم الانتقال إلى تعلم إطار العمل جانغو أو فلاسك. يمكنك أن تعود إلى موسوعة حسوب للاطلاع على توثيق لغة بايثون. تعلم لغة بايثون لتطوير الواجهات الخلفية من خلال التسجيل في دورة تطوير التطبيقات باستخدام Python المقدمة من أكاديمية حسوب، والتي تحتوي على 69 ساعة فيديو تتوزع على عشرةمسارات تعليمية تشرح أساسيات لغة بايثون للمبتدئين، ثم تطبق عمليًا بأمثلة واقعية، وتشرح إطار العمل جانغو Django وفلاسك Flask. اللغات والتقنيات المستخدمة في تطوير تطبيقات الويب باستخدام بايثون: لغة بايثون وإطارات العمل المبنية عليها (مثل جانغو وفلاسك) وقواعد البيانات (مثل MySQL و PostgreSQL وغيرها). تعلم تطوير تطبيقات الجوال ازداد عدد تطبيقات الجوال لأنظمة أندرويد و iOS ازديادًا كبيرًا في الفترة الماضية، وأصبح لكل شركة أو خدمة تطبيق خاص بها يسهِّل على مستخدميها الوصول إلى الخدمات التي توفرها. النظامان الرئيسيان المسيطران على سوق الجوال حاليًا هما أندرويد ثم iOS. يمكن برمجة تطبيقات أندرويد بلغة Java أو Kotlin (أو غيرهما) وبرمجة تطبيقات iOS باستخدام Swift (وغيرها). ستكتشف أنَّ عليك تطوير تطبيقين منفصلين تمامًا، واحد لهواتف أندرويد وآخر لهواتف iOS، وذلك يسبب زيادةً في حجم العمل المطلوب وصعوبةً في إدارة التغييرات. بسبب ذلك، ظهر مفهوم "التطبيقات متعددة المنصات"، وهي تطبيقات تعمل على نظام أندرويد و iOS دون أي تعديلات، وذلك باستخدام تقنيات مشتركة وهي في الغالب تقنيات الويب. أي أصبح بإمكان مطوري الويب الاستفادة من معلوماتهم في تطوير تطبيقات الجوال باستخدام منصات مثل آيونيك Ionic. تسمح آيونيك Ionic للمبرمجين بالتعامل مع مختلف وظائف الجهاز باستخدام لغة JavaScript، مثل الوصول إلى الموقع الجغرافي، والتقاط صور بالكاميرا، والتعامل مع الملفات وخلاف ذلك. طوِّرت في الفترة الماضية تقنيات أخرى مبنية على JavaScript مثل React Native المبنية على مكتبة React.js والتي تسمح للمطورين بكتابة تطبيقات أصيلة باستخدام تقنيات الويب. تستطيع تعلم تطوير تطبيقات الجوال عبر Ionic وعبر React Native من خلال التسجيل في دورة تطوير التطبيقات باستخدام لغة JavaScript المقدمة من أكاديمية حسوب، والتي تحتوي على 69 ساعة فيديو تشرح أمثلة عملية تطبيقية شرحًا مفصلًا. وكالعادة يمكنك أثناء مشاهدتك للدورة أن تعود إلى موسوعة حسوب للاطلاع على التوثيقات اللازمة. اللغات والتقنيات المستخدمة في تطوير تطبيقات الجوال: Java و Swift و Kotlin و Ionic و React Native وغيرها. تطوير الألعاب تطوير الألعاب هو المجال الذي يحلم جميع مستخدمي الحاسوب بالدخول إليه. فالأغلبية تعرفوا على الحاسوب من خلال ألعاب الفيديو ومن ثم بدؤوا برحلة الاستكشاف عن البرمجة والتطوير. أغلب من يجيب عن تطوير الألعاب يقول "عليك بتعلم لغة C++‎" لكن دعني أفصِّل لك الأمر قليلًا. برمجة الألعاب تتطلب عملًا كثيرًا من فريق عمل كبير، مدعوم من شركة تجارية. من الصعب على مطوِّر وحيد أن ينشئ لعبة كاملة من الصفر دون فريق. تُطور أغلبية الألعاب باستخدام محرِّك ألعاب Game Engine والذي يسهِّل الأمر على المطورين ويتيح بيئة تطوير مناسبة للألعاب، ويتيح الميزات الأساسية لجميع الألعاب مثل التحكم بالكاميرا ونمذجة الشخصيات ثلاثية الأبعاد وتحريكها والأمور الفيزيائية الأخرى. هنالك عدد كبير من محركات تطوير الألعاب، ومن المرجح أنك شاهدت شعارها في الألعاب التي لعبتها من قبل، ومن أشهرها: Unreal Engine و Unity و Godot. يمكن التعامل مع هذه المحركات باستخدام عدِّة لغات، مثل C++‎ (وهي أشهرها)، وجافا (خصوصًا للألعاب على هواتف أندرويد) وحتى يمكن استخدام JavaScript في التعامل مع بعضها. تذكر أنّ الألعاب غير محدودة بتطبيقات سطح المكتب أو الهواتف، فهنالك ألعاب كثيرة تعمل على المتصفحات باستخدام تقنيات HTML5 و JavaScript. اللغات والتقنيات المستخدمة في تطوير الألعاب: C++‎ و Java و JavaScript ومحركات Unity و Unreal Engine و Godot. برمجة الذكاء الاصطناعي يُعد الذكاء الاصطناعي (AI) من المجالات الرائدة والمطلوبة بكثرة في سوق العمل اليوم، لاسيما بعد أن أصبحت تطبيقاته في متناول الجميع وبات يستخدم في العديد من المجالات فتعلمك لهذا المجال الرائد يعزز قدراتك كمبرمج ويساعد على تعزيز تطبيقاتك بقدرات الذكاء الاصطناعي القوية. يتفرع الذكاء الاصطناعي لعدة مجالات من أبرزها تعلم الآلة والتعلم العميق التي تُمكّن الحواسيب من التعلم من البيانات وتحسين أدائها بمرور الوقت دون الحاجة لبرمجة تقليدية. كي تتعلم برمجة الذكاء الاصطناعي تحتاج لامتلاك فهم جيد للبرمجة وتحليل البيانات ويمكنك استخدام لغات برمجة متعددة في هذا المجال أشهرها لغة البرمجة بايثون التي توفر الكثير من المكتبات والأطر المساعدة مثل تنسرفلو TensorFlow وكيراس Keras وبايتورش PyTorch وباندا Pandas. إذا كنت مهتمًا بتعلم هذا الاختصاص القوي فستوفر لك دورة الذكاء الاصطناعي من أكاديمية حسوب التي تحتوي على 58 ساعدة تدريبية ممتدة على ثمانية مسارات تدريبية شاملة كل ما تحتاج إليه للبدء بتطوير تطبيقات ذكاء اصطناعي قوية واكتساب مهارة في تحليل البيانات من الصفر ودون الحاجة لامتلاك معرفة مسبقة. اللغات والتقنيات المستخدمة في برمجة الذكاء الاصطناعي هي Python و MongoDB وPymongo و TensorFlow و Keras و Pandas والنماذج اللغوية الكبيرة LLMs المختلفة. تطوير الأنظمة المدمجة الأنظمة المدمجة هي أنظمة حاسوبية شبيهة بالحاسوب ولكنها لا تملك كل ميزات الحاسوب الذي تراه أمامك الآن. بعبارة أخرى، النظام المدمج هو حاسوب صغير مبرمج لأداء مهام محددة فقط ومدمج ضمن الجهاز أو البيئة المراد استخدامه فيها. أنت الآن محاط بالكثير من الأنظمة المدمجة الآن مثل جهاز مقياس مستوى المياه وجهاز التحكم بالتلفاز وجهاز إنذار الحريق وأجهزة المراقبة …إلخ. حتى إشارات المرور وتنظيم السير وألعاب الأطفال الآلية تصنَّف على أنها أنظمة مدمجة. هل سمعت أيضًا بمصطلح "إنترنت الأشياء"؟ إنترنت الأشياء هو نظام مدمج متصل بالإنترنت. نعم، بهذه البساطة! لابد الآن أن يتبادر إلى ذهنك الساعات والثلاجات والغسالات الذكية وطائرات الدرون وأنظمة المراقبة عن بعد وأنظمة البيوت الذكية، إذ كلها أمثلة على إنترنت الأشياء. كيفية برمجة الأنظمة المدمجة أشهر وأكثر لغة برمجة تستعمَل في برمجة الأنظمة المدمجة وإنترنت الأشياء هي لغة C (أي لغة سي) وكل اللغات المشتقة منها (مثل‎ لغة أردوينو C). تُستعمَل لغة C++‎ كثيرًا في هذا المجال، إذ تعدُّ لغة ذات مستوى أعلى من لغة C لدعمها للبرمجة كائنية التوجه. أضف إلى ذلك أنه بدأ حديثًا استعمال لغة بايثون في برمجة تطبيقات الأنظمة المدمجة مع أنها لم ترتبط تقليديًّا بهذا المجال سابقًا. صحيح أنَّ لغة بايثون ليست بقوة لغة C و C++‎ في هذا المجال إلا أنها تستمد ميزاتها وفعاليتها من المكتبات الهائلة المتوافرة فيها. بعيدًا عن C وبايثون، تستعمل في مجال الأنظمة المدمجة أيضًا لغات أخرى تنضوي ضمن "لغات توصيف العتاد" (Hardware Description Languages)؛ لغتي VHDL و Verilog هما من أشهر لغات توصيف العتاد المستعملة في هذا المجال. تُستعمَل مثل هذه اللغات في برمجة "مصفوفة البوابات المنطقية القابلة للبرمجة" (FPGA أي Field Programmable Gate Array). أخيرًا، قد تجد بعض المراجع تشرح برمجة الأنظمة المدمجة بلغة أخرى تدعى "لغة التجميع" (Assembly Language) التي تصنف من اللغات منخفضة المستوى. يتطلب تعلم البرمجة باستخدام هذه اللغة فهمًا واسعًا بمعمارية وحدة التحكم المركزية والمعالج بالمجمل لأنها أقرب لغة يفهمها الحاسوب. الانتقال إلى هذه اللغة قد يكون في مستويات متقدمة من تعلمك لبرمجة الأنظمة المدمجة وتطبيقات إنترنت الأشياء. من ميزات البرمجة بهذه اللغة هي التحكم الواسع بالعتاد والمعالج الذي لا توفره لغات أخرى. يقال أن هذه اللغة صعبة بعض الشيء ومعقدة، ولكن لا أرى ذلك! قد يكون سبب قول ذلك هو أن لغة التجميع هي لغة منخفضة المستوى وأقرب شيء إلى لغة الآلة ولا يستطيع من يلقي نظرة على شيفرة مكتوبة فيها فهمها مطلقًا إن لم يعرفها. تطوير تطبيقات سطح المكتب مجال تطوير تطبيقات سطح المكتب كالمحيط الواسع؛ إن لم تملك بوصلة وتعرف إلى أين تريد الاتجاه، ستضيع فيه حتمًا. هنالك الكثير من أنظمة التشغيل أشهرها - وأكثرها سيطرةً على السوق حاليًا - هي: نظام التشغيل ويندوز، ولينكس، وماك (macOS)، ويملك كل نظام تشغيل تطبيقات مكتبية خاصة به. لذلك، يجب عليك أولًا -قبل الدخول إلى سوق برمجة تطبيقات سطح المكتب- تحديد نظام التشغيل المستهدف. أي يجب الإجابة على السؤال التالي: هل يستهدف تطبيقك نظام تشغيل محدد، أم تريد لتطبيقك أن يعمل على عدة أنظمة تشغيل في آن واحد؟! بعد تحديد نظام التشغيل المستهدف، اطلع على اللغات المفضل استعمالها في ذلك النظام لبرمجة تطبيقاته؛ فعلى سبيل المثال، اللغات C و C++‎ و C#‎ و VB.NET هي الأكثر استعمالًا في برمجة تطبيقات نظام التشغيل ويندوز، واللغات C و C++‎ و Bash هي الأكثر استعمالًا في برمجة تطبيقات توزيعات نظام التشغيل لينكس. أمَّا نظام الشغيل ماك، فينفرد باستعمال لغة Objective-C. حسنًا، دعني أخبرك الحقيقة، كل لغة برمجة عامية الغرض يمكن استعمالها في برمجة التطبيقات، إذ أشهر اللغات التي تُدرَّس أكاديميًّا في هذا المجال هي لغة جافا (Java). لا يخفى على القارئ دخول لغة بايثون بقوة على هذا المجال نظرًا لامتلاكها الكثير من المكتبات الرائعة وسهولة صياغتها. دخلت مؤخرًا لغة جافاسكريبت على سوق برمجة تطبيقات سطح المكتب عبر إطار العمل Electron (إلكترون)، إذ توظف في هذا المجال تقنيات تطوير الويب (HTML و CSS و JavaScript …إلخ.). بدأ هذا الإطار ينتشر كالنار في الهشيم مما دفع شركات كبيرة لتطوير تطبيقات سطح المكتب الخاصة بها باستعمال هذا الإطار ومنها شركة Slack التي استعملت هذا الإطار لتطوير تطبيقها المكتبي. أعلم أنك الآن تشعر بالضياع من كثرة لغات البرمجة والتقنيات المستعملة في هذا المجال؛ معك حق، فقد أخبرتك بذلك منذ قليل. دخول هذا السوق يحتاج منك تحديد هدفك منه بالضبط. هل لديك فكرة تطبيق وتريد إنشاءه والربح منه؟ هل تريد العمل لدى شركة محددة؟ ما هي مواصفات التطبيق الذي تريد إنشاءه أو تريد العمل على تطويره؟ كل ذلك يلعب دورًا في تحديد لغة البرمجة الأنسب لك لتعلمها. في النهاية، إن تعلمت أساسيات البرمجة وأتقنت العمل على لغة برمجية محددة، سيسهل عليك الانتقال إلى لغة برمجة أخرى، إذ أغلب لغات البرمجة تشبه بعضها بعضًا من ناحية المفهوم والمضمون وتختلف بعض الشيء من ناحية الصياغة والشكل. لذلك، اطمئن من هذه الناحية. كيفية اختيار لغة البرمجة التي تناسبك يمكنك اختيار لغة البرمجة اعتمادًا على المجال الذي تحب العمل فيه، سألخص لك مسار التعلم لمختلف مجالات العمل: العمل كمطور ويب full-stack: يعني ذلك تعلم تطوير واجهات المستخدم أو الواجهات الأمامية، وتطوير الواجهات الخلفية. يمكن التخصص بمجال واحد من هذين المجالين فقط، إذ يُطلَب كثيرًا في سوق العمل مبرمجين متخصصين في واجهات المستخدم أو الواجهات الخلفية. العمل كمطور تطبيقات للهواتف المحمولة: يمكنك تعلم برمجة تطبيقات أندرويد أو iOS كلًا على حدة، أو استعمال تقنيات مثل كوردوفا لتطوير لكلا النظامين معًا. العمل كمطور تطبيقات سطح المكتب: يمكنك البدء بالتخصص في تطوير تطبيقات مكتبية لنظام تشغيل محدَّد (مثل نظام التشغيل ويندوز أو لينكس) عبر تعلم لغة البرمجة المستعملة في ذاك المجال (كما أشرنا إلى ذلك في قسم تطوير تطبيقات سطح المكتب)؛ خيار آخر هو تعلم اللغات والتقنيات التي تمكنك من تطوير تطبيقات عابرة للمنصات (تعمل على عدة أنظمة تشغيل) مثل استعمال إطار العمل Electron. العمل كمطور للأنظمة المدمجة والأنظمة الذكية: لغة C هي أساس هذا المجال، سواءً كنتَ تتعامل مع المتحكمات مباشرةً، أو تتعامل مع شريحة مثل أردوينو (والتي تمتلك لغةً مشتقةً من C). يساعدك هذا الفيديو على معرفة المعايير التي من خلالها ستتمكن من اختيار لغة البرمجة التي تتناسب مع تطلعاتك وأهدافك المستقبلية. نصائح لتعلم البرمجة مشوار تعلم البرمجة من الصفر طويل وشائق، ولكنه جميل ومسلٍ بذات الوقت، قد تصاب بالإحباط في بداية طريقك لكثرة الأمور التي عليك الإلمام بها، لذا جهزت إليك النصائح الآتية من تجربتي في البرمجة: حدد هدفك من تعلم لغة البرمجة وسوق العمل الذي تريد دخوله واجعله واقعيًا. بدون هدف، أبشرك بأنك ستتخلى عن فكرة تعلم البرمجة بعد حين. انتبه إلى أن يكون هدفك واقعيًا وقابلًا للقياس والتجزيء على مراحل. بدون ذلك، ستفشل من أول عقبة وتترك تعلم البرمجة. أعرف نفسك جيدًا ونقاط قوتك وضعفك. كلنا لديه نقاط قوة وضعف، ولكن المفلح من عمل على ترميم وتحسين نقاط ضعفه في المجال الذي يرغب بتعلمه. رشح دورة واحدة وكتابًا واحدًا وابدأ بقراءة الكتاب ومتابعة الدورة تدريجيًّا ثم انتقل بعد الانتهاء إلى دورة أخرى وكتاب آخر، إذ سيجنبك ذلك التشتت بين الدورات الكثيرة والكتب العديدة. الشيء الذي أفعله قبل بداية تعلم شيء جديد هو ترشيح قائمة من عدة كتب ودورات ثم ترتيب هذه الكتب والدورات بحسب جودتها ومدى بساطتها وتعقيدها. أرقم الكتب والدورات وأبدأ بالخيار الأول منها. أحدد الوقت التقريبي الذي يأخذه كل خيار لدراسته وأجدول الخيارات البقية على رزنامتي الخاصة. لا تأخذ العلم إلا ممن تثق بعلمه، فالكثير من المبتدئين يحاولون مساعدة غيرهم وقد يضعون معلومات مغلوطة دون قصد. طبق ما تعلمته مباشرة، وأنشئ أي شيء من كل أمر جديد تتعلمه حتى لو كان رسمة بسيطة أو شيفرة من عدة أسطر فقط. فرحة إنجاز شيء مما تعلمته تدفعك لتعلم المزيد والاستمرار في طلب العلم. نظم وقتك بورقة وقلم، حدد بداية كل أسبوع خطةً لسائره والتزم بتنفيذها. أخبر أصدقائك أن لديك التزامات وأمور مهمة عليك إنجازها. خصص وقتًا للاستراحة بالطبع ولا تنسَ نصيبك منها. في نهاية كل أسبوع، وازن مدى الإنجاز الذي حققته ومدى تطبيق الخطة التي وضعها وحاول أن تصل النسبة إلى 100%. أنصحك بقراءة ومتابعة استراتيجيات تنظيم الوقت ورفع الإنتاجية. تمرس على حل المشكلات وتحدى نفسك باستمرار وتابع المسابقات البرمجية واشترك بها إن استطعت، أنصحك بقراءة مقالة حل المشكلات وأهميتها في احتراف البرمجة بعد هذه المقالة. لا تنسَ أن تكافئ نفسك في كل مرة تنهي فيها كتابًا أو تكمل العمل على مشروع. لا تنسَ حظك من الاستراحة، لأن طريق البرمجة قد يكون له بداية ولكن النهاية بعيدة ومتعبة -مثله مثل أي مجال آخر-. في النهاية أرجو لك كل التوفيق في مشوارك البرمجي. وأرجو منك أن تشاركنا تجربتك في تعلم البرمجة، لعل غيرك يستفيد منها. اقرأ أيضًا كيف تتعلم البرمجة المدخل الشامل إلى تعلم علوم الحاسوب المرجع الشامل إلى تعلم لغة بايثون تعرف على أعلى تخصصات البرمجة أجرا تعلم لغة HTML قواعد البرمجة ما هي فوائد تعلم البرمجة؟ أسهل لغات البرمجة أهمية البرمجة
    2 نقاط
  6. حققت برامج التعلم العميق والذكاء الاصطناعي نموًا متزايدًا في الآونة الأخيرة، إذ تشير الإحصاءات إلى أن القيمة السوقية لهذه التقنيات الحديثة قد تصل إلى 930 مليون دولار بحلول العام 2025م، كما ارتفع عدد الأعمال والوظائف التي تتطلب فهم مهارات الذكاء الاصطناعي بنسبة 450 % منذ تسع سنوات مضت. فما هو التعلم العميق Deep Leaning؟ وما هي تطبيقاته الأكثر استخدامًا في العالم؟ إليك قائمة محتويات المقال: مفهوم التعلم العميق كيف يعمل التعلم العميق؟ الفرق بين تعلم الآلة والتعلم العميق تطبيقات التعلم العميق الرعاية الصحية التعلم العميق في التسويق الإلكتروني البحث الصوتي والمرئي والدردشة الآلية التعلم العميق في التعليم عالم الترفيه تقصى الحقائق وكشف الأخبار المزيفة السيارات ذاتية القيادة الأرصاد والمناخ تحديات التعلم العميق الجودة الضعيفة للبيانات خداع التعلم العميق عدم فهم السياق جيدًا ضغوط على المؤسسات قرصنة التعلم العميق مفهوم التعلم العميق التعلم العميق Deep Learning هو فئة فرعية من تعلم الآلة Machine Learning الذي يعتمد على الشبكات العصبية الاصطناعية إلى جانب التعلم التمثيلي. لذلك، فإنه عبارة عن تقنية حاسوبية تحاكي العقل البشري من خلال تصميم خوارزميات مستوحاة من بنية القشرة الدماغية ووظيفتها حتى يمكنها تقليد جميع قدرات الدماغ مثل فهم اللغة الطبيعية والأصوات ومحتوى الصور والقدرة على تنفيذ العديد من الأوامر والتعليمات كما يفعل الإنسان. ويعد التعلم العميق من العلامات الفارقة المميزة في العصر الحديث، فقد نجح العلماء في إنشاء شبكات البرسبترون العصبونية Perceptron القائمة على فكرة وظائف الشبكات العصبية Neural network، فهو يتضمن بناء شبكات عصبية قادرة على معالجة البيانات المعقدة بدرجة أكثر شمولًا وتركيزًا من تقنيات الذكاء الاصطناعي الأخرى. كيف يعمل التعلم العميق؟ استطاع العلماء دراسة العقل البشري وكيفية عمل الأدمغة التي تحتوي على مليارات الخلايا العصبية المتشابكة معًا، وذلك بهدف إنشاء نموذج محاكاة من هذه الخلايا العصبية القادرة على تصفية المعلومات وتصنيفها ومعالجتها كما يحدث في دماغ الإنسان، ومن هنا جاءت فكرة إنشاء خوارزميات التعلم العميق. ويطلق عليه التعلم العميق لأنه يستخدم الشبكة العصبية الاصطناعية العميقة. وهذه الشبكة الاصطناعية تحتوي على خلايا عصبية تضم مجموعة من الطبقات المتصلة والمتراكمة فوق بعضها بعضًا، التي تبدأ بطبقة الإدخال المستوحاة من حواس الإنسان وتستقبل إشارات البيانات والمعلومات وتنتهي بطبقة الإخراج التي تظهر النتيجة النهائية للمعلومات، وبين هاتين الطبقتين توجد طبقات مخفية تكون مسؤولة عن تحليل البيانات للوصول إلى الاستنتاجات قبل استخراجها على هيئة معلومات مفيدة. وكل طبقة في الشبكات العصبية العميقة Deep Neural Networks تكون مسؤولة عن التقاط أنماط معينة من البيانات أو معلومات محددة ومعالجتها باستخدام خوارزميات التعلم العميق. ويطلق على الخلية العصبية في هذه الشبكة اسم (عصبون) وكل خلية لها وزن يحدد أهمية كل عنصر على حدة، إضافة إلى إمكانية تعديل الأوزان أكثر من مرة لضمان الحصول على نتائج دقيقة في نهاية المطاف. وبذلك يمكن لخاصية التعلم العميق معالجة كمية هائلة من البيانات. وتعد الشبكات العصبية التلافيفية Convolutional Neural Network التي تعرف اختصارًا CNN، من أبرز الشبكات العصبية العميقة المستخدمة في التعلم العميق، فإنها تشتمل على طبقات متعددة ذات بنية استثنائية بهدف معالجة بيانات غير منظمة غالبًا مثل الصور للتنبؤ بما فيها وقراءتها ومعرفة الميزات الفريدة بها. ما الفرق بين تعلم الآلة والتعلم العميق؟ يظن الكثيرون من غير المتخصصين أن التعلم العميق وتعلم الآلة والذكاء الاصطناعي مفاهيم مترادفة وتُستخدم لتنفيذ الوظائف التقنية ذاتها، لكن الحقيقة عكس ذلك، لأن تعلم الآلة Machine Learning أحد فروع الذكاء الاصطناعي Artificial Intelligence، وأعم وأشمل من التعلم العميق Deep learning. ببساطة، يركز تعلم الآلة عمومًا على جعل الأجهزة الحاسوبية لديها القدرة على أداء المهام دون الحاجة إلى برمجة واضحة استنادًا إلى خوارزميات أكثر بساطة كتلك التي تعتمد على التوقع الخطي أو شجرة القرارات، أما التعلم العميق يستوجب إنشاء خوارزميات أكثر تعقيدًا وذات مستويات مختلفة مثل الشبكات العصبية الاصطناعية ANNs والشبكات العصبية التلافيفية CNN. كما أن خوارزميات التعلم الآلي يمكن تغذيتها ببيانات منظمة من أجل تحليلها والوصول إلى استنتاجات مفهومة، أما التعلم العميق يحتاج إلى بيانات غير منظمة وأنماط معقدة مثل النصوص المكتوبة والصور ومقاطع الفيديو والأصوات واللغات. كذلك، يتطلب التعلم العميق تدخلًا بشريًا أقل من تعلم الآلة، لكنه يحتاج إلى قوة حاسوبية وطاقة كبير للغاية من أجل المشكلات الأكثر تعقيدًا ومعالجة البيانات الضخمة باستخدام أجهزة وتقنيات معينة، على عكس تعلم الآلة الذي يتطلب كمية أقل من البيانات وقوة حاسوبية أقل أيضًا. تطبيقات التعلم العميق لا يقتصر استخدام تقنيات التعلم العميق على فهم الصور ومقاطع الفيديو فحسب، إنما يُستخدم على نطاق واسع في مجالات وقطاعات مختلفة، ونرى العديد من التطبيقات في حياتنا الراهنة خاصة مع تزايد حجم البيانات وبعدما أصبحت التكنولوجيا ميسورة التكلفة، فنلاحظ مثلًا أن النظام الأساسي في شبكة التواصل الاجتماعي "فيسبوك" لديه القدرة على معرفة أصدقائك وقراءة صورهم وتمييزها، وفيما يلي أهم تطبيقات التعلم العميق: الرعاية الصحية مع تطور الذكاء الاصطناعي، دخلت خوارزميات التعلم العميق في مجالات الطب والرعاية الصحية، ومكنت هذا القطاع من توفير القدرة على تحليل البيانات وفحصها بسرعة استثنائية، إضافة إلى دعم رعاية المرضى مع تقليل التكاليف وتحسين الكفاءات وتشخيص الأمراض. على سبيل المثال، تُستخدم أداة Aidoc في دعم الأطباء خاصة أنها تعتمد على خوارزميات تسرع تشخيص المريض وعلاجه مثل اكتشاف أماكن النزيف داخل الجمجمة والانسداد الرئوي، وغير ذلك. وبفضل خوارزميات التعلم العميق، نجح فريق بجامعة كاليفورنيا في عام 2016م، بتطوير تقنية تصور الخلايا في عينات الدم بسرعة كبيرة دون أن تؤثر سلبًا على هذه الخلايا والاستفادة منها في التحليلات المستقبلية الأخرى. كما تُستخدم الشبكات العصبية التلافيفية CNN في معرفة نتائج التصوير بالرنين المغناطيسي والأشعة السينية. وتوصلت دراسة -نُشرت نتائجها في المجلة العلمية Annals of Oncology- إلى أن خوارزميات الشبكات CNN قادرة على تحليل صور الأمراض الجلدية التي تحدد الإصابة بسرطان الجلد بدقة أكبر من الأطباء البشريين بنسبة 10%. لذلك أكد الفريق البحثي أن هذه الشبكات الاصطناعية تُعد أداة مناسبة للكشف عن سرطان الجلد. لا تقتصر تطبيقات التعلم العميق في القطاع الطبي على ذلك، بل شملت الدخول في عالم الطب الدقيق واكتشاف وتصنيع الأدوية والتنبؤ بالوفيات في المستشفيات. على سبيل المثال، طور فريق من جوجل بالتعاون مع جامعات أمريكية تقنية تعتمد على خوارزمية التعلم العميق ومعالجة اللغة الطبيعية التي حللت ما يزيد عن 46 مليار نقطة بيانات في 216 ألف سجل صحي إلكتروني عبر مستشفيين. وساعدت هذه التقنية في التنبؤ بطول فترة إقامة المرضى واحتمالات الوفاة بينهم. التعلم العميق في التسويق الإلكتروني أصبح التعلم العميق جزءًا لا يتجزأ من التسويق الإلكتروني، إذ سخرت قنوات التسويق الرقمي مثل فيسبوك قدرات التعلم العميق لتقديم أفضل تجربة للمتسوقين والمعلنين، وذلك من خلال استخدام تحليلات النص العميق Deep Text الذي يعالج اللغة بالذكاء الاصطناعي ويفهمها مثل البشر، إضافة إلى تصفية "موجز الأخبار" الخاص بالمستخدمين واكتشاف المحتوى الجديد وفهم النصوص المرغوب فيها وتجنب غيرها. وتشير الإحصائيات إلى أن أكثر من 51% من المسوقين يستثمرون تقنيات الذكاء الاصطناعي والتعلم العميق في حملات التسويق الإلكتروني للحصول على رؤى مستنيرة حول جمهورهم المستهدف في العام 2019، وفقا لما نقلته شبكة "businessinsider". بينما يرى 52% من جهات التسويق أن الذكاء الاصطناعي مهم لنجاح حملاتهم التسويقية ويؤكد 41% منهم أن تسريع نمو الإيرادات كان نتاجًا عن استخدام هذه الخوارزميات ويتوقع 80% منهم أتمتة أكثر من ربع مهامهم التسويقية خلال السنوات الخمسة المقبلة. يوجد العديد من المسوقين الذين يستخدمون تقنيات تعلم الآلة والتعلم العميق في تقديم محتوى مخصص وتحليل الفيديو والوصول إلى جمهور أكثر استهدافًا وفقًا لتفضيلاتهم أو سلوكياتهم والتفاعل معهم بفاعلية والتنبؤ برغبات العملاء والاستفادة من البيانات لأداء عروض أسعار في الوقت الفعلي. على سبيل المثال وليس الحصر، تهتم منصة "Google Cloud Video Intelligence" بإنشاء تحليلات لمقاطع الفيديو وتتيح إعداد ملخصات آلية لمستخدميها. البحث الصوتي والمرئي والدردشة الآلية هناك العديد من الشركات التي تستخدم خاصية التعلم العميق في منتجاتها الرقمية، فنجد تطبيق المساعد الصوتي Apple Siri الذي ترجم الصوت البشري إلى أوامر حاسوبية تسمح لمالكي أجهزة آيفون الحصول على المعلومات بناءً على أسئلتهم، كما أن أداة البحث الصوتي التي تستخدم خوارزميات جوجل Google Voice Search تتيح البحث بالصوت بدلًا من النصوص المكتوبة. فهي أدوات قائمة على فهم الأوامر الصوتية التي يطلبها المستخدمين. وهناك برامج سخرت التعلم العميق في البحث المرئي للجوال، مثل تطبيق "CamFind" الذي يتيح لمستخدميه التقاط صورة ما واستخدامها في إجراء عمليات البحث بدلًا من كتابة النصوص. إضافة إلى روبوتات الدردشة الآلية المستخدمة في حل مشكلات العملاء والتواصل معهم دون تدخل بشري، وهذه الروبوتات فعالة في التسويق عبر مواقع التواصل الاجتماعي والتفاعل مع العملاء وتقديم استجابات فورية لهم. التعلم العميق في التعليم يُستخدم تعلم الآلة والتعلم العميق في التعليم لمنح الطلاب تجربة تعليمية فردية وتحليل أدائهم وتعديل طرق التدريس والمناهج الدراسية استنادًا إلى البيانات التي يتم معالجتها في أثناء تجارب الطلاب، ويساعد على زيادة كفاءة المعلمين من خلال فهم إمكانات الطلاب وتقديم محتوى تعليمي ممتع يشجع المتعلمين على التعلم والمشاركة. كما يسهم في إجراء التحليلات المتقدمة والتنبؤية المتعلقة بالعملية التعليمية. ومِنْ ثَمَّ، اتخاذ القرارات والإجراءات الصحيحة الأكثر عقلانية. توجد أمثلة عديدة لاستخدام التعلم العميق والتعلم الآلي في التعليم، مثل أداة "Quizlet" التي تتيح للمتعلمين تصميم الاختبارات والبطاقات التعليمية والرسوم البيانات وتضم ما يزيد عن 50 مليون مستخدم نشط. أما منصة "SchooLinks" فإنها تمكّن الطلاب من تصميم السير الذاتية ومعرفة الدورات التدريبية التي ينبغي الحصول عليها، وغيرها من الخدمات التي تتطلب استخدام خوارزميات التعلم الآلي. وغيرها من التطبيقات والأدوات التي تستعين بخوارزميات التعلم العميق والهادفة إلى جذب الطلاب وزيادة مشاركتهم وتنوع طرق التدريس. عالم الترفيه تُستخدم تطبيقات التعلم العميق والذكاء الاصطناعي في عالم الترفيه من أجل تقديم تجربة ممتعة للعملاء، فهناك شركات عالمية عديدة مثل يوتيوب وأمازون ونتفلكس تستغل خوارزميات الذكاء الاصطناعي في عرض الأفلام والأغاني ومقاطع الفيديو المختلفة بناءً على رغبات وسلوكيات وخيارات العميل التي نفذها سابقًا. كما يمكن الاستعانة بتقنيات التعلم العميق في تحويل أصوات الممثلين إلى ترجمات نصية تلقائية أو إدراج الأصوات في الأفلام السينمائية الصامتة. وقد استخدمت بعض شركات الترفيه هذه الخوارزميات لإنشاء نمذجة التنبؤ في الوقت الفعلي اعتمادًا على الاتجاهات الحالية للعملاء التي تُجمع من مصادر البيانات، وذلك يساعد الشركات على التفاعل مع عملائهم بشكل فوري، وتوقع سلوكياتهم المستقبلية والتعرف على الأفلام ومقاطع الفيديو التي تستهلكها شرائح صغيرة من الجمهور في الوقت الحالي ومن المتوقع شهرتها مستقبلًا، فضلًا عن إمكانية إنتاج الموسيقى باستخدام نماذج قائمة على خوارزميات التعلم العميق. تقصي الحقائق وكشف الأخبار المزيفة لجأت غرف الأخبار وصالات التحرير إلى تقنيات الذكاء الاصطناعي والتعلم العميق للتحقق من المعلومات المضللة وتقصي الحقائق، فقد طور باحثون من جامعة Waterloo الكندية نظام يستخدم خوارزميات الذكاء الاصطناعي للتعلم العميق لتقييم المقالات الإخبارية تلقائيًا بهدف تحديد المعلومات المضللة. وهناك منصات عديدة لتقصي الحقائق مثل Snopes و FactCheck.org، و PolitiFact تسخر الذكاء الاصطناعي في هذه المهمة. وتعد تقنية التحليل الرقمي "InVID" من أبرز الأدوات التي تستخدم خوارزميات التعلم العميق والذكاء الاصطناعي في الكشف عن الأخبار المزيفة والمعلومات المضللة، فهي تتضمن أكثر من 15 أداة لتقصي الحقائق، فمثلًا تسمح بتجزئة الفيديو إلى صور ثابتة لإجراء بحث عكسي عليها عبر محركات البحث العملاقة مثل Google و Yandex و Baidu، إضافة إلى استخراج البيانات الوصفية للفيديوهات وتحليلها والتعرف على ما إذا كانت الصور معدلة أم أصلية، وما إلى ذلك. السيارات ذاتية القيادة واحدة من تطبيقات التعلم العميق التي أدهشت العالم، هي السيارات ذاتية القيادة التي تعتمد على الشبكات العصبية الاصطناعية في القيادة وتحديد إشارات المرور واكتشاف الأشياء التي ينبغي تجنبها في أثناء القيادة دون أي تدخل بشري، إضافة إلى التعرف على وقت ضبط السرعة وتوجيهها بطريقة آمنة في الطرقات. ففي عام 1989م، استخدمت أول سيارة ذاتية القيادة التي عرفت باسم ALVINN الشبكات العصبية لاكتشاف خطوط الممرات وتقسيم البيئة وإمكانية القيادة، وكانت النتيجة جيدة إلا أنها محدودة لعدم توافر البيانات وضعف المعالجة. والآن، أضحت هذه التجربة أفضل مما كانت عليه في الماضي، فقد استحوذت خوارزميات التعلم العميق على النواحي الفرعية للقيادة الذاتية، لا سيما في ظل توفر البيانات الضخمة والمعالجات القوية. وتعتمد القيادة الذاتية على أجهزة الاستشعار المختلفة مثل الكاميرات أو GPS لجلب البيانات من البيئة المحيطة بالسيارة ومعالجتها باستخدام خوارزميات التعلم العميق من أجل اتخاذ القرارات المناسبة والجيدة وذات الصلة بالبيئة، وهذا يتطلب توافر فحص وفهم أربعة مكونات أساسية في هذه السيارات تتمثل في التصور والإدراك perception ومعرفة الخريطة والموقع المبدئي Localization والتنبؤ بالأشياء المحيطة Prediction وصناعة القرار Decision Making. الأرصاد والمناخ ساعدت تقنيات التعلم العميق على تحليل بيانات الأرصاد الجوية والأبحاث البيولوجية والتنبؤات المناخية ومعرفة أحوال الطقس مثل احتمالات سقوط الأمطار أو وقوع الزلازل واندلاع البراكين، مما يسهم في اتخاذ الاحتياطات والإجراءات اللازمة التي تحمي الناس من مخاطر هذه الكوارث الطبيعية. على سبيل المثال، ابتكر فريق بحثي في جامعة واترلو الكندية تقنية تعتمد على خوارزميات التعلم العميق للكشف عن نقاط التحول في التغير المناخي والعمل كنظام إنذار مبكر. وإذا كنت ترغب في تطبيق هذه الخوارزميات في مشروعك أو خدماتك التقنية وتحتاج إلى بعض المساعدة، فإنه يمكنك الاستعانة بخدمات التعلم العميق التي توفرها منصة خمسات -أكبر سوق عربي لبيع وشراء الخدمات المصغرة- وتضم لفيف من الخبراء العرب والمحترفين في مجال الذكاء الاصطناعي والتعلم العميق ولديهم القدرة على تقديم الدعم لك على أكمل وجه. تحديات التعلم العميق على الرغم من الطفرة الهائلة التي أحدثتها خوارزميات التعلم العميق في مختلف القطاعات، فهو ليس حلًا سحريًا لمعالجة جميع المشكلات، لأن هناك تحديات صعبة تواجه هذه التقنيات الحديثة وتمنعها من منافسة العقل البشري. فعلى سبيل المثال، تستلزم عملية التعرف على صورة ما معالجة ملايين البيانات لتحديدها. الجودة الضعيفة للبيانات تتطلب تقنيات التعلم العميق استخدام بيانات عالية الجودة لاستخراج نتائج جيدة ودقيقة، أما البيانات الرديئة التي تحتوي على أخطاء كثيرة وقيم متطرفة وبيانات فوضوية، فلن تعمل خوارزميات التعلم العميق بصورة صحيحة. لذلك، يعكف الكثير من علماء البيانات على تنظيف البيانات وتنقيتها في أغلب أوقاتهم من خلال تجاهل القيم المتطرفة أو إصلاحها وملء البيانات المفقودة يدويًا. خداع التعلم العميق يظن البعض أن خوارزميات التعلم العميق لا يمكن خداعها، وهذا اعتقاد خاطئ تمامًا، لأنه من السهل نسبيًا استخدام الاحتيال مع هذه التقنيات. فقد أجرى باحثون في معهد ماساتشوستس للتكنولوجيا MIT في عام 2017م، دراسة حول إمكانية خداع مصنف الصور InceptionV3 التابع لجوجل، وبعد التلاعب المتعمد في صورة سلحفاة ثلاثية الأبعاد، صنفتها الشبكة العصبية الاصطناعية على أنها بندقية وليست سلحفاة، وفي تجربة أخرى حدث خلط بين طائرة الهليكوبتر والبندقية. عدم فهم السياق جيدا تحتاج خوارزميات التعلم العميق إلى بيانات كافية لتعمل بطريقة صحيحة، فهي جيدة في ربط المدخلات مع المخرجات، لكنها لا تفهم سياق البيانات التي تتعامل معها بدقة في كثير من الأحيان. فكلمة "عميق" في مصطلح التعلم العميق تركز على بنية الخوارزميات وعدد الطبقات المخفية أكثر من مستوى فهمها لما تعالجه من بيانات. وتتطلب الشبكة العصبية الاصطناعية التدريب والتأقلم حتى تفهم السياق إذا حدثت أي تغيرات في البيانات. ضغوط على المؤسسات توصلت دراسة استقصائية أجريت في عام 2017 إلى أن 80% من المؤسسات تستثمر في الذكاء الاصطناعي رغم توقعها بوجود عوائق صعبة أمامها. وهذه النتيجة تشير إلى احتمالية وجود ضغط متزايد على الشركات ومطوريها للتركيز على تقنيات التعلم العميق وحلول الذكاء الاصطناعي لزيادة الإنتاجية والوصول إلى استنتاجات مستنيرة واتخاذ قرارات صائبة تدفع هذه الشركات للأمام. قرصنة التعلم العميق هناك تخوفات من أن تصبح الشبكات العصبية عرضة للقرصنة والهجمات الإلكترونية، على سبيل المثال، من المحتمل استغلال خوارزميات التعلم العميق في السيارات ذاتية القيادة لتغيير سلوكها بطريقة مؤذية، وهذا ما فعله باحثون في تجربة نُشرت نتائجها في دورية Nature، فقد تعمدوا تضليل الشبكات العصبونية بالسيارة ذاتية القيادة من خلال وضع ملصقات معينة على كلمة "توقف" إلا أن النظام أخطأ في قراءتها واعتبرها "الحد الأقصى للسرعة 45". أخيرًا، هل يمكن القول بأن تجارب التعلم العميق محكوم عليها بالفشل؟ بالتأكيد لا، لأن تقنيات التعلم العميق تعمل بكفاءة عالية إذا ما توفرت البيانات الكافية وعالية الجودة، كما يكرس علماء البيانات والمطورون جهودهم من أجل التغلب على هذه التحديات وتحسين نماذج التعلم العميق وتطويرها وسط تخوفات من تهديد التعلم العميق النسيج الاجتماعي والاقتصادي من خلال دفع البشر إلى البطالة أو غير ذلك. المراجع والمصادر What is Deep Learning and How Does It Works [Explained] The Best Introduction to Deep Learning - A Step by Step Guide Top 10 Deep Learning Applications Used Across Industries Deep Learning Tutorial for Beginners: Neural Network Basics Difference Between Deep Learning and Machine Learning Vs AI Are There Really as Many Neurons in the Human Brain as Stars in the Milky Way? How Many Neurons Are in the Brain? ما هو التعلم العميق؟ Deep Learning vs. Machine Learning — What’s the Difference? Difference Between Machine Learning and Deep Learning Deep learning vs. machine learning – What’s the difference? The Amazing Ways Google Uses Deep Learning AI How is Machine Learning enhancing the Future of Education? Artificial intelligence may be set to reveal climate-change tipping points AI in Marketing: How brands can improve personalization, enhance ad targeting, and make their marketing teams more agile The 2021 State of Marketing AI Report MACHINE LEARNING IN EDUCATION: EXPLANATION, BENEFITS, CASE What Is Deep Learning and How Will It Change Healthcare? DEEP LEARNING IN HEALTHCARE – HOW IT’S CHANGING THE GAME Top Use Cases for AI in Media and Entertainment Deep learning won’t detect fake news, but it will give fact-checkers a boost Taking a Stance on Fake News: Towards Automatic Disinformation Assessment via Deep Bidirectional Transformer Language Models for Stance Detection Deep Learning in Self-Driving Cars Self-Driving Cars With Convolutional Neural Networks (CNN) 5 Challenges of Machine Learning! 5 Key Deep Learning/AI Challenges in 2018 The limits and challenges of deep learning Turtle or rifle? Google AI tricked by MIT students مشكلةٌ عويصة تواجه تقنيات التعلم العميق The Complete Beginner’s Guide to Deep Learning: Artificial Neural Networks كيف يمكن للذكاء الاصطناعي أن يشكل مستقبل تسويق المحتوى اقرأ أيضًا الذكاء الاصطناعي: مراحل البدء والتطور والأسس التي نشأ عليها تعلم الآلة: التحديات الرئيسية وكيفية التوسع في المجال تعلم الذكاء الاصطناعي
    2 نقاط
  7. سنتحدث عن تصميم موقع إلكتروني بشكل عام في هذا المقال، ولكن يجب أن نوضح أن مجال بناء المواقع الإلكترونية يتفرع إلى فرعين أساسيين هما تصميم المواقع وتطويرها، فتصميم المواقع يختص بترتيب العناصر المرئية واختيارها وتخطيط سلوك المستخدم وتجربته من حيث طريقة تفاعله مع الموقع وكيفية استقباله لرسالته التي أنشئ من أجلها، أما تطوير المواقع فيختص بتحويل تلك التصاميم المرئية إلى أكواد وشيفرات برمجية يخرج منها منتجات جاهزة للإطلاق. ورغم تشعبات هذا المجال التي تتزايد كل حين إلا أن أغلب حديث العملاء عند الرغبة في تصميم مواقع لهم سيدور حول التصميم المرئي للعناصر والنماذج وترتيبها على الشاشة، وكيفية ظهور الموقع على الشاشات المختلفة سواء كانت حواسيب أو هواتف أو غيرها، وطريقة تفاعل المستخدم مع عناصر الموقع. خطوات تصميم موقع إلكتروني وبنائه نلاحظ أننا ذكرنا نوعين من أنواع تصميم المواقع في الفقرة السابقة، وهما التصميم المرئي وتصميم تجربة الاستخدام، وهما يشبهان الهندسة المعمارية للمباني حيث يرى المستخدم آثارهما مباشرة عند تفاعله مع الموقع من حيث تنسيق الواجهة وترتيب العناصر وتناسق الألوان والتفاعلات الموجودة فيها. كذلك فإن هذين النوعين من التصميم هما أول مرحلتين من مراحل تصميم مواقع الإنترنت أو التطبيقات الموجهة للهواتف أو غيرها من الأجهزة، ثم يأتي بعدهما تطوير الواجهات سواء الأمامية أو الخلفية. 1. تصميم تجربة الاستخدام يختص مصمم تجربة الاستخدام User Experience (UX) بدراسة الفئات المستهدفة من الموقع، وحالاتهم الصحية والنفسية وأعمارهم وجنسياتهم، وذلك من خلال بحوث عميقة لطبيعة نشاط العميل والموقع والأهداف التي يجب أن يحققها الموقع أو التطبيق المراد إنشاؤه، من أجل توجيه انتباه المستخدم إلى العناصر التي يريد له صاحب الموقع أن يهتم بها أو يراها، إضافة إلى تخطيط تجربة استخدامه عمومًا داخل الموقع. وتظهر أهمية هذا المجال عند تصميم مواقع طبية مثلَا لا تراعي فئات المستخدمين التي لديها مشاكل في النظر أو القراءة أو السمع، فلا يراعي تهيئة الموقع لتلك الفئات من المستخدمين، فهل تتخيل موقعًا لمستشفى للأطراف الصناعية فيه الكثير من الحقول التي على المستخدم ملؤها في استمارة حجز موعد في مستشفى؟ ويضع مصمم تجربة الاستخدام الخريطة التأسيسية للموقع، وكيف يجب أن يكون التصميم المرئي للواجهة، وترتيب كل قسم رئيسي وفرعي فيه، وعدد النقرات التي ينقر عليها المستخدم للوصول إلى العناصر الهامة في الموقع، والألوان التي يجب استخدامها، وأحجام الأزرار والعناصر، وهكذا. 2. تصميم واجهة المستخدم يأتي مصمم واجهة المستخدم User Interface (UI)‎ ليعمل على هذه النسخة التي أخرجها مصمم تجربة الاستخدام مسترشدًا بها، فيصمم الواجهة النهائية التي يراها المستخدم من قوائم وأزرار وألوان وغيرها وفق مبادئ تصميمية تحقق أهداف تجربة الاستخدام. قد يتخصص مصمم الواجهات المرئية في تصميم العناصر المرئية فقط إذا كان يعمل في شركة كبيرة وفي فريق تصميم كبير، لكن الغالب أنه يتجاوز هذه المرحلة إلى تصميم مواقع الإنترنت بحيث تكون تفاعلية، تستطيع بقية الفرق أن يتفاعلوا معها ليعرفوا الأثر المطلوب تنفيذه عند النقر على أحد الأزرار، أو كي يستطيع العميل أن يرى نسخة شبه حية من الموقع قبل البدء في تطويره وبنائه. 3. تطوير واجهة المستخدم بعد تمام مرحلة تصميم المواقع أو التطبيقات بحيث يكون لدينا نسخة مرئية جاهزة منها، ينتقل العمل إلى مطور الواجهات الأمامية Front End Development الذي يعمل على برمجة هذه الواجهات لتتحول من مجرد تصميمات إلى نسخة حية من الموقع يستطيع العميل أن يتفاعل معها بنفس كيفية تفاعل المستخدم النهائي معها. ويستخدم لغات وصفية مثل HTML وبرمجية مثل جافاسكربت لإتمام عمله، إضافة إلى أطر عمل Frameworks لئلا يعيد اختراع العجلة من الصفر في المهام المكررة. ومطور الواجهات الأمامية هو المسؤول عن إنشاء التأثيرات المرئية للأزرار والقوائم والانتقالات في الصفحة الواحدة وبين الصفحات. 4. تطوير الواجهة الخلفية ينشئ مطور الواجهة الخلفية قواعد البيانات التي تلتقط بيانات المستخدم من نماذج التسجيل وبيانات وصور وغيرها لتخزينها وتصنيفها ثم جلبها للمستخدم عند الحاجة، وكذلك الخوادم التي تكون عليها المواقع نفسها وقواعد بياناتها. وتختلف أهداف المطورين عن المصممين في أنهم يولون أهمية كبيرة لسرعة تحميل الموقع والعناصر التي فيه، وكذلك كفاءة التشغيل للخوادم لئلا تكون عرضة للاختراق أو التعطل، على عكس المصممين الذين يهتمون بتفاعلات المستخدم مع الواجهة اﻷمامية، وسهولة فهمه للمطلوب من الموقع أو التطبيق، وسرعة وصوله للمعلومات التي يحتاج إليها بأقل عدد من النقرات والإجراءات. الأدوات المستخدمة في تصميم موقع يشترك مصمم تجربة الاستخدام ومصمم الواجهات المرئية في بعض البرامج التي يستخدمونها في تصميم المواقع، لكن توجد بعض البرامج والأدوات التي ينفرد بها كل منهما، وفيما يلي أشهر تلك البرامج. Adobe XD يُستخدم برنامج Adobe XD من حزمة أدوبي لإنشاء نماذج أولية للمواقع والتطبيقات إما ثابتة أو تفاعلية، إضافة إلى مزية التعاون بين المصممين على نفس التصميم. Figma يسمح برنامج Figma ببناء نماذج أولية أيضًا للمواقع والتطبيقات واختبار قابلية استخدامها -وهو أمر ضروري لمصممي تجربة الاستخدام-، وهو أيضًا بيئة تفاعلية يستطيع فيها المصممون التعاون في العمل على نفس المشروع في نفس الوقت -مثل العمل المشترك على تطبيقات جوجل السحابية-، مما يعني أنه ليس تطبيقًا مستقلًا وإنما يعمل داخل المتصفح. ‎FlowMapp - Octopus‎ هذان التطبيقان يعملان في المتصفح أيضًا، ويُستخدمان في إنشاء خريطة تدفق Flow map لسلوك المستخدمين في التطبيقات، وكذلك مخططات التطبيقات وخرائط المواقع، كي تكون واضحة لبقية فرق العمل من مصممي الواجهات المرئية والمطورين، مما يعني أن هاتين اﻷداتين لمصممي تجربة الاستخدام خاصة. ‎Balsamiq‎ تُستخدم هذه الأداة لإنشاء إطارات سلكية Wireframes للموقع أو التطبيق، وهي كذلك لمصممي تجربة الاستخدام، حيث يستخدمونها لإنشاء تصميمات بسيطة لعناصر وتقسيمات الموقع أو التطبيق دون تشتيت بقية فرق العمل بتفاصيل العناصر من نصوص وأيقونات وألوان وغيرها. Adobe Ai أبقينا هذا البرنامج إلى نهاية القائمة ربما لإمكانياته الكبيرة، حيث يمكن تنفيذ أغلب مهام البرامج والأدوات السابقة فيه، وهو أقدم هذه الأدوات في سوق التصميم وأشملها، وكذلك أشهرها بين مصممي تجربة الاستخدام والواجهات المرئية على حد سواء. اللغات المستخدمة في تطوير المواقع نأتي إلى اللغات التي يستخدمها المطورون لتحويل التصميمات المرئية إلى تطبيقات حية جاهزة للإطلاق في السوق، وسنبدأ بمطوري الواجهات الأمامية أولًا ثم ننتقل إلى الواجهة الخلفية. HTML لا تُعد لغة HTML لغة برمجة وإنما هي لغة توصيفية تُستخدم لإنشاء هيكل واضح لصفحات الويب، فهي التي تحدد أن هذا النص عنوان وذاك نص عادي، وهذه قائمة غير مرتبة، وبالمثل تحدد بقية العناصر من روابط تشعبية وصور وأقسام في الصفحة وغيرها. لعل HTML هي أبسط اللغات في تعلمها إذ قد لا تستغرق بضعة أيام لفهم أساسياتها ومن ثم البناء بها أو الانتقال إلى بقية اللغات. CSS لغة CSS هي لغة تنسيق تضفي بعض مظاهر الحياة على صفحات الويب مع توحيد مظهر تلك الصفحات في نفس الوقت، وكذلك تُستخدم لإنشاء تصميمات متجاوبة responsive للمستخدمين لتناسب الأجهزة التي يتصفحون منها سواء كانت هواتف محمولة أو حواسيب لوحية أو حتى أجهزة سطح المكتب. تكمن فائدتها الأساسية في أن شيفرتها توضع في ملف منفصل عن HTML، ثم تُكتب فيها القوانين العامة لتصميم الموقع، مثل تنسيق العناوين الرئيسية وألوانها وحجم خطوطها، حتى إذا أردنا تغيير ذلك التنسيق لجميع العناوين غيرناه مرة واحدة في ملف CSS، بدلًا من تغييره في كل صفحة على حدة، وهكذا في بقية عناصر الصفحات من تنسيق الأزرار والألوان ومحاذاة النصوص مثلًا. جافاسكربت Javascript تأتي لغة جافاسكربت لتكمل أغلب الجوانب التي تبقى في عملية تطوير الويب سواء للواجهة الأمامية أو الخلفية، سواء باللغة نفسها أو بأطر العمل frameworks التي بُنيت عليها، فهي لغة برمجة أصيلة -ليست وصفية مثل HTML- تُستخدم لإنشاء تفاعلات من الموقع مع إجراءات المستخدم، إما باستخدام جافاسكربت نفسها أو أحد أطر العمل المشهورة التي بُنيت عليها، مثل أنجولر Angular و jQuery و Vue.js. وتُستخدم بعض أطر العمل تلك لبناء خدمات وتطبيقات تعمل في الواجهة الخلفية أيضًا للمواقع، مثل أنجولر Angular و Vue.js، إضافة إلى أطر عمل مثل Next.js. لغات أخرى يمكن استخدام العديد من لغات البرمجة وأطر العمل لتصميم مواقع الإنترنت وتطويرها، فمثلًا يُستخدم إطار العمل جانغو Django المكتوب بلغة بايثون لكتابة تطبيقات للويب، وكذلك إطار العمل Ruby-on-rails المكتوب بلغة روبي Ruby، وهكذا، فلم يعد الأمر مقصورًا على لغة جافاسكربت وحدها لإتمام عملية بناء الموقع. ويتوقف قرار اللغة المستخدمة في بناء الموقع وكذلك إطار العمل على طبيعة المشروع المطلوب والعميل والبيئة التي سيعمل فيها والتطورات المستقبلية له، لكن تظل جافاسكربت هي اللغة اﻷشهر المستخدمة في تطوير واجهات الويب أو الواجهات الأمامية لمواقع الإنترنت. الأدوات المستخدمة في تطوير الواجهات الأمامية يحتاج مطورو المواقع الإلكترونية إلى بيئات أو أدوات يستخدمونها لكتابة شيفراتهم البرمجية، وبيئات أخرى لاختبارها، وفيما يلي أمثلة لأهم هذه الأدوات. المحررات النصية Text Editors وهي برامج كتابة نصوص بسيطة مثل Notepad، لكنها تكون موجهة للمبرمجين والمطورين، فتتميز بتمييز النصوص بصريًا وفقًا لنوعها ليسهل قراءتها، وكذلك الإكمال التلقائي للنصوص، وغيرها من المزايا المخصصة لتطوير المواقع والتطبيقات، وأشهر هذه المحررات ما يلي: ‎Vim‎ ‎Emacs‎ ‎Notepad++‎‎ ‎Sublime Text‎ بيئات التطوير المتكاملة IDEs تختلف بيئة التطوير عن المحرر النصي العادي في أنها أشمل وأكثر تكاملًا، فإضافة إلى المحرر النصي فإنها تحتوي على مصرِّف compiler و منقِّح debugger وأداة لبناء واجهات المستخدم المرئية، كما تدعم عدة لغات أحيانًا مثل بايثون و PHP وروبي Ruby و جافاسكربت وغيرها. فيما يلي أهم بيئات التطوير المستخدمة في تطوير المواقع: ‎Visual Studio Code‎ ‎IntelliJ IDEA‎ ‎Aptana Studio 3‎ ‎Eclipse‎ ‎NetBeans‎ ‎Webstorm‎ خاتمة مواقع الإنترنت هي المقرات الافتراضية للشركات والمؤسسات، وهي عنصر لابد منه في العلامة التجارية لأي كيان له نشاط على الويب أو على الأرض، سواء كان ذلك شركة أو مؤسسة أو حتى فردًا مستقلًا. وترغب هذه الكيانات بإنشاء مواقع لها لبيع منتجاتها أو الترويج لأنشطتها والتعريف بها، أو توجيه جمهورها إلى استخدام تطبيقات مخصصة للهواتف، أو حتى لمجرد حجز خدماتها والتواصل من خلالها، إضافة إلى أن وجود موقع إنترنت يرفع كثيرًا من سمعتها لدى محركات البحث، مما يعني تصدرًا لنتائج البحث وشهرة أكثر. وقد ذكرنا في بداية المقال أن العملاء يولون أهمية خاصة لتصميم الموقع الذي يريدون له أن يعكس هويتهم التي تمثلهم، وتحمل روح المؤسسة أو الشركة من حيث جدية التصميم أو حداثته أو غير ذلك، وكذلك مناسبته للفئات المستهدفة منه. وعلى ذلك ينبغي أن يطلع المصمم -إلى جانب إلمامه بالجوانب الفنية الخاصة بعمله- على أصول إدارة المنتجات الرقمية، خاصة إن كان يوظف مطورين آخرين للعمل معه أو كان يدير فريق تصميم، وكذلك على أسس التعامل مع العملاء ليفهم احتياجاتهم ويوصل لهم رأيه المهني بالطريقة المثلى. إقرأ أيضا تعلم أساسيات البرمجة تعلم البرمجة كيف تتعلم البرمجة: نصائح وأدوات لرحلتك في عالم البرمجة برمجة مواقع الويب: دليلك المختصر مبادئ تصميم واجهة المستخدم UI الجيدة قواعد تصميم واجهة المستخدم
    1 نقطة
  8. مرحبًا بك في هذه السلسلة التي سنتحدث من خلالها عن إطار العمل Bootstrap 5 ذلك الإطار الذي يهيمن على معظم عمليات التطوير التي تحدث في الواجهة الأمامية Front-End Development في مواقع الإنترنت عمومًا. لا تفترض هذه السلسلة أن يكون لديك أي فكرة مسبقة عن بوتستراب Bootstrap (ولو أنّ بعض المعرفة القليلة مرحّب بها)، في حين أنّ الإلمام بـ HTML و أساسيات CSS هو أمر ضروري للمتابعة في هذه السلسلة. رغم أنّ بوتستراب يستخدم جافاسكريبت في بعض المكوّنات إلى أنّه ليس من الضروري أن يكون لديك معرفة بها لكي تتعلّم بوتستراب، ولو أنّ الإلمام بجافاسكريبت يُعدّ بديهيًا لمطوري الواجهة الأمامية عمومًا. هذا هو المقال الأوّل في هذه السلسلة، وهو مقال تمهيدي بطبيعة الحال، وفيه سنتحدّث عن النقاط التالية: ماهو بوتستراب؟ مالجديد في بوتستراب 5؟ إعداد بوتستراب للعمل. استخدام محرر برمجي مناسب ما الذي سنبنيه في هذه السلسلة؟ ماهو بوستراب؟ بوتستراب ببساطة هو إطار عمل Framework متكامل مبني على CSS و جافاسكريبت JavaScript يُستخدم لتنسيق صفحات الويب وإكسابها نواح جمالية بدون الحاجة إلى استخدام تنسيقات معقدة من CSS. يدعم بوتستراب مبدأ تنسيق الأجهزة المحمولة أولًا Mobile First Style وهذا يعني توافقية عالية مع الأجهزة المحمولة ذات الشاشات الصغيرة. عندما يُذكر بوتستراب فأول ما يتبادر إلى الذهن هو السرعة والأناقة والسهولة والتصميم المتجاوب Responsive Design مع مختلف أنواع الشاشات. كان أول من طور بوتستراب شركة تويتر الشهيرة، وبعد عام تقريبًا، جعلته مفتوح المصدر ومتاحًا بالكامل من خلال GitHub. يستند بوتستراب كما أشرنا مسبقًا إلى CSS فهو يوفّر كمّا كبيرًا من الجهد لتنسيق المكوّنات في صفحة الويب. يهدف بوتستراب كما هو واضح إلى تبسيط عمليات التصميم التي تحدث في الواجهة الأمامية Front-End وجعلها معيارية. يسهّل هذا الأمر إلى حدّ بعيد من حياة المصممين والمطورين على حدّ سواء، ويجعل عملية انضمام مصمّم جديد إلى فريق العمل في شركة تعتمد بوتستراب أمرًا يسيرًا نسبيًا. استخدام بوتستراب سهل جدًا. فيمكن من خلال إضافة صنف Class أو أكثر إلى عنصر HTML أن تحصل على أثر فوري يحوّل هذا العنصر إلى شكل جميل وعصري. انظر مثلًا إلى شيفرة HTML التالية: <button>مرحبًا</button> سيولّد الكود السابق الزر البسيط التالي: سأضيف الآن صنفان بسيطان من بوتستراب إلى الكود السابق: <button class="btn btn-primary">مرحبًا</button> ستحصل على الشكل الجميل التالي: لاحظ كيف اكتسب هذا الزر الألوان المناسبة بالإضافة إلى حاشية Padding مناسبة أيضًا وبتلقائية حول النص الموجود ضمن الزر. وأيضًا كيف أصبحت حواف الزر منحنية. توجد العديد من التشكيلات الأخرى التي يمكن اكسابها للأزرار كما سنرى فيما بعد. مالجديد في بوتستراب 5؟ يُعَد الإصدار 5 إصدارًا رئيسيًا وهو الأحدث من بوتستراب حاليًا (وقت كتابة هذا المقال)، وكما جرت العادة، فهناك العديد من التغييرات التي طرأت على الإصدار الذي يسبقه (الإصدار 4) فمثًلا فقد أزيل المكوّن Jumbotron بالإضافة إلى إزالة الدعم عن المتصفحين IE 10 و IE 11، وأيضًا أزيل عدد من أصناف التنسيق التي كانت موجودة في الإصدار 4. هناك تغييرات أخرى قد حدثت ضمن مخطط الصفحة حيث أضيف قياس آخر جديد لم يكن موجودًا في الإصدار السابق وهو القياس xxl. و توجد تحسينات أخرى في نظام الألوان. كما أضيف دعم أيقونات SVG جميلة ومتنوّعة ومفتوحة المصدر أيضًا. يمكنك مع مكتبة الأيقونات هذه الاستغناء عن مكتبات أيقونات إضافية مثل Font Awesome. في الإصدار 5 أيضًا لم يعد هناك حاجة لاستخدام المكتبة jQuery بعد الآن (بعض المزايا الموجودة في بوتستراب تحتاج إلى جافاسكريبت)، فقد انتقل مطوّرو بوتستراب إلى استخدام جافاسكريبت فقط، مع إمكانية الإبقاء على استخدام jQuery في حال الرغبة. أود أن أركّز هنا على ميزة مهمة أضيفت إلى بوتستراب 5، طالما انتظرها المصممين والمطورين العرب! وهي دعم الاتجاه من اليمين إلى اليسار ‏ RTL مما يسهّل حياتهم إلى حدّ كبير. إعداد بوتستراب للعمل يمكن تضمين بوتستراب في صفحة الويب التي نعمل بها بإدراجه عن طريق العنصر link ضمن العنصر head في ترويسة الصفحة، ويمكن اختيار تضمين بوتستراب من مزوّد محتوى على الإنترنت CDN وهو الخيار الأفضل. ومن الممكن كذلك تنزيل نسخة من بوتستراب محليًا ومن ثمّ تضمينها ضمن صفحة الويب التي تعمل بها. سنعمل في هذه السلسلة على الخيار الأول، أي أنّنا سنستخدم مزوّد محتوى CDN. سنعتمد القالب الأساسي التالي أثناء عملنا على بوتستراب: <!doctype html> <html lang="en"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Bootstrap CSS --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> <title>Hello, world!</title> </head> <body> <h1>السلام على الجميع</h1> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script> </body> </html> لاحظ أنّه وقبل نهاية وسم الإغلاق ‎</body>‎ وضعنا الوسم <script> الذي يسمح بتحميل كود جافاسكريبت الذي تحتاجه بعض مكوّنات بوتستراب لكي تعمل عملًا صحيحًا. استخدام محرر برمجي مناسب توجد العديد من الخيارات المتاحة لاستخدام محرّر برمجي مناسب في سياق عملك كمطوّر واجهة أمامية، ومن المحرّرات الشهيرة Visual Studio Code و Sublime و Atom. بالنسبة لي أفضل استخدام Visual Studio Code من مايكروسوفت لما يتمتع به من مرونة ودعم كبيرين. لتثبيت محرر vs code انتقل إلى الموقع الخاص به لتنزيله. سيظهر زر التحميل في الصفحة الرئيسية. عندما تنتهي من تنزيله وتثبيته، افتحه وانتقل إلى قسم الإضافات Extensions ضمنه في الشريط الموجود على الناحية اليسرى كما في الشكل التالي: بعد ذلك وفي خانة البحث في الأعلى اكتب Live Server للبحث عن هذه الإضافة التي ستسمح لك بتشغيل خادوم مبسّط على حاسوبك الشخصي مما يسمح لنا بتجريب الشيفرة التي نكتبها مباشرةً على المتصفح الافتراضي الموجود على حاسوبنا. بعد اختيار الإضافة انقر الزر Install في الناحية الخاصة بشرح الإضافة (في الطرف الأيمن) لتثبيتها. بنفس الأسلوب السابق تمامًا ننصحك بتثبيت إضافة Auto Rename Tag، حيث تساعد هذه الإضافة على التعديل التلقائي لوسم ما عند تعديل الوسم المرافق له. ما الذي سنبنيه في هذه السلسلة؟ سنبني في هذه السلسلة موقع ويب بسيط عبارة عن صفحة واحدة يمكن أن يُعتبر كقالب يشرح مزايا بوتستراب 5 التي سنتناولها تباعًا أثناء تقدمنا في هذه السلسلة. هذا الموقع عبارة عن موقع يبيع دورات تعليمية على الإنترنت. يوفر الموقع إمكانية التسجيل الجديد للمستخدمين بالإضافة إلى تسجيل دخول للمستخدمين السابقين. كما سيعرض آخر الدورات التدريبية (المنتجات) المتوفرة، وأيضًا الدورات الأكثر مبيعًا. كما سنوفّر ميزة سلة المشتريات التي تسمح للمستخدم بالتسوّق من خلال اختيار الدورات التي يرغب بشرائها. بالإضافة إلى ما سبق سنضيف بعض الأقسام على الصفحة الرئيسية التي توفّر بعض المعلومات عن الموقع وبنفس الوقت توضّح لنا كيفية استخدام مزايا بوتستراب 5 المتنوّعة. سنعمل على بناء هذا الموقع شيئًا فشيئًا أثناء عملنا في هذه السلسلة. انظر إلى الشكل التالي الذي يعطيك شكلًا تقريبيًا لما سنحصل عليه في نهاية هذه السلسلة. مصدر الصور في آخر هذه السلسلة سنتعلّم كيف نرفع الموقع كاملًا على إحدى الإستضافات لكي يصبح بالإمكان معاينته بصورة حية. اقرأ أيضًا 10 أخطاء شائعة عند استخدام إطار العمل Bootstrap بناء قائمة شجرية باستخدام البوتستراب تصميم صفحة موقع باستخدام 3 Bootstrap - الجزء الأول
    1 نقطة
  9. يتضمن مجال تطوير الويب قسمين أساسين هما تطوير الواجهة الأمامية front-end (فرونت إند) وتطوير الواجهة الخلفية back-end (باك إند) وهما من المجالات الرائدة اليوم فجميع النشاطات التجارية والأشخاص يسعون للتواجد على شبكة الإنترنت ويحتاجون لمطوري ويب لإنشاء مدونات أو مواقع أو تطبيقات أو متاجر إلكترونية خاصة بهم. سنخصص مقال اليوم للحديث عن تطوير الواجهة الأمامية ونوضح كافة المفاهيم المرتبطة وكافة الخطوات والتقنيات التي تحتاجها لتتعلم كي تصبح مطور واجهات محترف فإذا كنت مهتمًا بهذا المجال لكنك لا تملك أدنى فكرة عن كتابة الشيفرات البرمجية أو إنشاء صفحات الويب ولا تعرف من أين تبدأ أنصحك بأن تقرأ المقال للنهاية. ما هو تطوير الواجهة الأمامية Front End Web Development؟ قبل أن نشرح تطوير الواجهة الأمامية front-end تحتاج لأن تعرف مراحل بناء أي موقع إلكتروني، فإنشاء أي موقع أو تطبيق يبدأ بتحديد فكرته وتوثيقها، بعدها ترسل هذه الفكرة إلى مصمم الواجهات الأمامية الذي يرسم واجهات الموقع وصفحاته كلها بمختلف تفاصيلها وحالتها، حيث تُراجع هذه الواجهات ثم ترسل إلى مطور الواجهات لتكويدها وبرمجتها وهنا تقسم العملية إلى برمجة واجهات أمامية وخلفية وتبرمج كل واجهة وتتفاعل الواجهتان مع بعضهما للحصول على المواقع المتكامل. فمطور الواجهة الأمامية front end web developer أو ما يعرف بمطور واجهات المستخدم user interface developer هو المبرمج المسؤول عن إنشاء كافة الأجزاء المرئية التي يراها المستخدم ويتفاعل معها عند زيارة مواقع وتطبيقات الويب وبرمجة كافة الواجهات ومكوناتها من أزرار وقوائم ونصوص ورسومات وصور ونماذج وغيرها وتحديد كيف سيبدو كل جزء من موقع الويب وكيف سيتفاعل المستخدم معه. الفرق بين تطوير الواجهة الأمامية front-end وتطوير الواجهة الخلفية back-end والتطوير الكامل Fullstack من الضروري أن تفهم أبرز الفروقات بين تطوير الواجهة الأمامية وتطوير الواجهة الخلفية والتطوير الكامل والتي تعكس في واقع الأمر تخصصات تطوير الويب أو بمعنى آخر الدور الذي يساهم به مطور الويب عند بناء المواقع والتطبيقات والتقنيات التي يستخدمها لأداء عمله، كما أنها تعبر عن مكان تشغيل الشيفرات البرمجية لهذه المواقع والتطبيقات. بدايةً يجب أن تعرف أن عرض موقع الويب على جهازك يتم دومًا في لغة HTML وهي لغة توصيفية يستخدمها مطورو الويب لإنشاء وعرض الصفحات، هناك عدة تقنيات يمكنك إنشاء المواقع من خلالها لكن مهما كانت التقنية المستخدمة فإن عرض الموقع لديك في نهاية المطاف سيكون بلغة HTML. الآن يمكن أن تحدث عملية عرض ملفات المواقع مباشرة على جهازك كما في حال المواقع البسيطة ذات المحتوى الثابت فهي تخزن على خادم الويب بالأساس بشكل ملفات HTML وترسل لك هذه الملفات مباشرة عند طلبها وتعرض لك كما هي على متصفحك. من ناحية أخرى قد تتطلب عملية عرض المواقع بعض المعالجة المسبقة التي تحدث على جانب خادم الويب أو يسمى الخادم البعيد مثل مواقع الويب الديناميكية التي لا تعرض نفس المحتوى لجميع المستخدمين وتتغير بناء على إدخالات المستخدم، فعندما ترسل طلبًا لعرض صفحة ما من موقع ديناميكي يقوم الخادم بمعالجة طلبك هذا وبعد الانتهاء ويجلب لك البيانات المطلوبة والعرض الأخير على جهازك يكون بشيفرة HTML. كل ما يتعلق بأمور عرض الموقع من جانب متصفح الويب أو يسمى طرف العميل client side يندرج تحت مجال تطوير الواجهة الأمامية للموقع، وكل ما يتعلق بأمور معالجة الموقع من طرف خادم الويب من معالجة البيانات وتخزينها وحفظها وإجراء عمليات عليها وغيرها يندرج تحت مجال تطوير الوجهة الخلفية للموقع ولكل منهما تقنياته وأدواته، على سبيل المثال عندما تسجل في موقع يطلب تاريخ ميلادك، تراه يعرضها لك أحيانًا بشكل عمر أي عدد وليس تاريخ، هذه المعالجة تُرسل عادة من طرف الخادم. ليس لزامًا عليك كمطور ويب تعلم تطوير الواجهة الأمامية أو الخلفية معًا بل يمكنك التخصص في إحداهما فقط، فإذا كنت تحب تنفيذ الجوانب المرئية لواجهات المستخدم وجعلها تعمل وفق التصميم المقترح سيناسبك تطوير الواجهة الأمامية أكثر، وإذا كنت تفضل حل المشاكل المنطقية والتعامل مع قواعد البيانات وواجهات برمجة التطبيقات والخوادم والخدمات السحابية فإن تطوير الواجهة الخلفية يناسبك. أما إذا كنت متحمسًا للقيام بكل ما سبق وكانت لديك القدرة لتعلم كافة التقنيات والمهارات اللازمة لتطوير الواجهة الأمامية وتطوير الواجهة الخلفية والقيام بالأمرين معًا عندها سيطلق عليك اسم المطور الكامل fullstack developer وستفتح أمامك الكثير من الفرص المجزية. وإذا كنت مهتمًا بمعرفة مزيد من التفاصيل حول مجالات تطوير الويب أنصح بمطالعة مقال المدخل الشامل لتعلم تطوير الويب وبرمجة المواقع ومقال دليلك الشامل إلى تطوير الواجهة الخلفية Backend. أهمية تطوير الواجهة الأمامية في سوق العمل إذا كنت مهتمًا بتطوير الويب فدعني أخبرك أن تبدأ به دون تردد فهو واحد من أكثر مجالات العمل نموًا مقارنة بباقي الوظائف فبحسب استبيان عام 2022 لموقع ستاك أوفر فلو الشهير الذي يضم آلاف خبراء البرمجة حول العالم فإن 25.96% من المشاركين في الاستبيان وعددهم 61,302 متخصصون في تطوير الواجهة الأمامية front-end، ويحتل هذا المجال المرتبة الثالثة بين أنواع المطورين بعد تطوير الواجهة الخلفية back-end والتطوير الكامل full-stack وهذا إن دلَّ على شيء فإنما يدل على مدى أهمية هذا المجال والطلب المرتفع عليه. أضف إلى ذلك فإن رواتب مطوري الواجهة الأمامية مرتفعة ومجزية ورغم كونها تتفاوت وتختلف حسب نوع الشركة ومقرها والمهارات المطلوبة للوظيفة ومستوى الخبرة إلا أن اكتسابك لمهارات عالية واحترافك لتطوير الواجهة الأمامية سيضمن لك الحصول على رواتب مرتفعة جدًا فمعظم جهات العمل تبحث عن مطور واجهة أمامية موهوب يمكنه إنشاء مواقع بتصاميم فريدة وبتجربة محسنة من شأنها زيادة رضا العملاء وجعل المواقع تتفوق على منافسيها. الجدير بالذكر أن أصعب جزء في مجال تطوير الواجهة الأمامية هو أنه متجدد باستمرار لذا يحتاج المطور للاطلاع بصورة دائمة على أحدث التقنيات في تطوير الويب ليتمكن من الاحتفاظ بالصدارة في سوق العمل لكنه مجال مجزٍ ويستحق الجهد. ما هي مهام مطور الواجهة الأمامية؟ مطور الواجهات الأمامية هو المسؤول بشكل عام عن إنشاء أجزاء المواقع والتطبيقات التي تعمل من جانب العميل (أو المتصفح)، وهذه المهمة تتضمن القيام بالعديد من المهام والتي تشمل: كتابة شيفرات HTML و CSS وجافا سكريبت لتنفيذ تصميم الموقع التي تكون عادة بشكل صور مصممة من قبل مصمم الواجهات الأمامية المسؤول عن تصميم واجهة المستخدم وتجربة المستخدم UI / UX بواسطة برامج متخصصة مثل فيجما Figma أو Sketch أو فوتوشوب. التواصل مع مطور الواجهة الخلفية المسؤول عن تحقيق وظائف الموقع والتأكد من توافق الواجهة الأمامية مع الواجهة الخلفية للموقع. تحسين أداء موقع الويب والتأكد من سرعة تحميله وتوفر تجربة مستخدم سهلة ومحسنة. التأكد من أن الموقع متوافق مع كافة متصفحات الويب ويعمل بالشكل الصحيح ومعالجة أي مشاكل توافق إن وجدت. التأكد من كون الموقع متجاوب ومتكيف مع كافة أحجام الشاشات بما في ذلك شاشات الهواتف الجوالة والأجهزة اللوحية وأجهزة الحاسوب. أهم أدوات تطوير الواجهة الأمامية إذا قررت التخصص في تطوير الواجهات الأمامية للويب ستجد الكثير من الخيارات المتاحة، فاللغات الثلاث الأساسية لأي مطور واجهة أمامية هي HTML و CSS وجافا سكريبت كما يمكنه إلى جانب ذلك استخدام العديد من اللغات وأطر العمل والمكتبات الأخرى الكثيرة التي تسهل عمله في تطوير الواجهات وفي الفقرات التالية سنسلط الضوء على أبرز هذه الأدوات. أهم لغات برمجة الواجهة الأمامية HTML CSS جافا سكريبت JavaScript تايب سكريبت TypeScript لنتناول بتفصيل أكثر كل لغة من هذه اللغات ودورها في تطوير الواجهات الأمامية للمواقع والتطبيقات. لغة HTML لغة HTML هي اختصار لعبارة HyperText Markup Language أي لغة ترميز النص التشعبي وهي اللغة الأساسية لتطوير الواجهة الأمامية للمواقع والتطبيقات وهي لغة وصفية أو لغة ترميز تصف البنية العامة لصفحات الويب ومحتوياتها من نصوص وأزرار وصور وقوائم باستخدام الوسوم وهي علامات موضوعة ضمن قوسي زاوية <> تحدد نوع المحتوى أو هيكليته على سبيل المثال لإنشاء صفحة ويب تتضمن عنوان وصورة ونص نكتب كود HTML التالي: <!DOCTYPE html> <html dir="rtl"> <head> <title>عنوان الصفحة</title> </head> <body> <h1>عنوان الصفحة</h1> <img id="myImage" src="html.png"> <p> HTML هي اختصار لـHyperText Markup Language أي لغة ترميز النص التشعبي وهي الأساسية لتطوير الواجهة الأمامية للمواقع والتطبيقات </p> </body> </html> احفظ الكود أعلاه في ملف نصي باسم index.html وقم بعرضه في متصفح الويب، عندها ستظهر الصفحة بالشكل التالي: للمزيد من المعلومات أنصح بمطالعة مقال تعلم لغة HTML الذي يشرح لك كافة الأساسيات التي تحتاجها للعمل مع هذه اللغة والاطلاع على توثيق HTML الشامل على موسوعة حسوب. لغة CSS لغة CSS هي اختصار لـ Cascading Style Sheets وهي لغة تصميم تستخدم لتحديد تنسيق صفحة الويب واختيار الألوان والخطوط والخلفيات وما إلى ذلك كما أنها تستخدم في جعل مواقع الويب متجاوبة مع مختلف الشاشات من خلال كتابة شيفرات تغير تنسيق وتخطيط العناصر بحسب أبعاد الشاشة. تستخدم لغة CSS قواعد تنسيق تستهدف عناصر HTML التي نريد تصميمها على سبيل المثال سنكتب التعليمات التالية لتنسيق صفحة الويب التي أنشأناها باستخدام HTML نكتب شيفرات CSS التالية ضمن الوسم <head>: <style> body { font-family: 'Cairo', sans-serif; background-color: #f2f2f2; margin: 0; padding: 0; } h1 { font-size: 36px; color: #333; text-align: center; margin: 50px 0; } img { display: block; margin: 0 auto; max-width: 100%; height: auto; } p { font-size: 18px; color: #666; text-align: center; margin: 50px; line-height: 1.5; } </style> تظهر الصفحة بعد إضافة التنسيقات كما يلي: وللمزيد من المعلومات يمكنك مطالعة سلسلة دروس CSS على أكاديمية حسوب إلى جانب توثيق CSS الشامل على موسوعة حسوب. لغة جافا سكريبت JavaScript بعد أن تقوم بتخطيط عناصر الواجهة الأمامية باستخدام HTML وتنسقها باستخدام CSS قد تحتاج إلى إضافة بعض التفاعلات إلى صفحاتك وهنا يأتي دور لغة جافا سكريبت JavaScript التي تعد واحدة من أشهر لغات البرمجة وأكثرها استخدامًا فهي تمكنك من تطوير كل من الواجهة الأمامية والخلفية. قد يكون تعلم جافا سكريبت هو الخطوة الأصعب لك كمطور واجهة أمامية لا سيما إن لم تكن تملك خبرة سابقة في البرمجة لكن بمجرد تعلمها ستتمكن من نقل الموقع إلى مستوى جديد وإضافة التأثيرات الديناميكية لصفحاته والاستجابة لتفاعل المستخدمين مع عناصره بدلًا من جعله يعرض معلومات ثابتة فقط. على سبيل المثال يمكنك كتابة شيفرات جافا سكريبت لعرض قائمة منسدلة أو إظهار رسالة منبثقة عند النقر فوق زر ما على الصفحة، أو إرسال طلب للتحقق من اسم المستخدم وكلمة المرور بعد النقر فوق زر تسجيل الدخول أو أي شكل من أشكال التفاعل مع الصفحة من طرف العميل. لنفرض أنك تحتاج لتكبير حجم صور الموقع قليلًا عند مرور مؤشر الفأرة فوقها، لن تتمكن من هذا إذا لم تكن تعرف جافا سكريبت وتدمجها مع HTML و CSS بدايةً عليك إضافة أكواد CSS التالية بعد الأكواد التي كتبتها في الخطوة السابقة: .zoom { transition: transform .2s; /* Add any other styles you want */ } .zoom:hover { transform: scale(1.5); /* Change the scale value to adjust the level of zoom */ } وبعدها عليك أن تضيف أكواد جافا سكريبت التالية قبل الوسم </body> ضمن كود HTML: const image = document.getElementById("myImage"); image.addEventListener("mouseover", function() { image.classList.add("zoom"); }); image.addEventListener("mouseout", function() { image.classList.remove("zoom"); }); تستمع شفرة جافا سكريبت هذه إلى حدث مرور مؤشر الفأرة فوق الصورة وتضيف تنسيق التكبير zoom إليه عند وقوع هذا الحدث. كما أنها تستمع إلى حدث خروج مؤشر الفأرة من عنصر الصورة وتزيل تنسيق التكبير منه عند وقوع هذا الحدث، وعند عرض الصفحة في المتصفح نحصل على التأثير التالي: للمزيد من التفاصيل أنصح بمطالعة مقال تعلم جافا سكريبت من الصفر حتى الاحتراف، كما توفر موسوعة حسوب توثيق لغة جافا سكريبت باللغة العربية يمكنك من خلالها تعلم كافة ما يتعلق بهذه اللغة. لغة TypeScript تعد لغة TypeScript لغة برمجة مفتوحة المصدر طورتها مايكروسوفت عام 2012 لتوفر ميزات إضافية تساعد على تطوير تطبيقات جافا سكريبت فهي تجعل تعليمات جافا سكريبت مفهومة بشكل أكبر وتوفر إمكانية تحديد أنواع المتغيرات كي تقلل من أخطاء الكود، وقد تزايدت شعبيتها بشكل كبير في الآونة الأخيرة لما توفره من ميزات لتحسين جودة التطبيقات وتسريع عملية التطوير . يمكنك مطالعة المزيد من المعلومات حول هذه اللغة وإمكانياتها من خلال مجموعة دروس TypeScript المتوفرة على أكاديمية حسوب أهم أطر عمل تطوير الواجهة الأمامية ظهرت أطر العمل frameworks والمكتبات البرمجية لتسهيل عمل المطور وتسريع عمله، لذا ستحتاج لاستخدامها في سوق العمل بدلًا من كتابة كل شيء بيدك من الصفر، وأطر عمل الواجهات الأمامية كثيرة ومن أبرزها: بوتستراب Bootstrap رياكت React أنغولار Angular فيو Vue جي كويري jQuery دعنا نلقي نظرة على كل تقنية منها ونشرح بمزيد من التفصيل دورها وأهميتها في تطوير الواجهة الأمامية. بوتستراب Bootstrap بوتستراب هو إطار ويب مجاني مفتوح المصدر مخصص للواجهة الأمامية فهو يستخدم لتصميم مواقع وتطبيقات ويب متجاوبة مع كافة أحجام الشاشات وذات مظهر احترافي بسرعة وسهولة فهو يحتوي على قوالب تصميم ومكونات جاهزة مكتوبة بلغة HTML ولغة CSS كما يوفر بالإضافة لذلك ملحقات تصميم مكتوبة بلغة جافا سكريبت. للاطلاع على المزيد من المعلومات يمكنك متابعة المقالات الدروس حول إطار عمل بوتستراب على أكاديمية حسوب إضافة لتوثيق بوتستراب الشامل على موسوعة حسوب. رياكت React رياكت React هي مكتبة جافا سكريبت مفتوحة المصدر طورتها شركة فيسبوك عام 2013 وهي تعد اليوم واحدة من أشهر مكتبات تطوير الواجهة الأمامية التي يمكنك من خلالها إنشاء مكونات قابلة لإعادة الاستخدام وتطوير واجهات مستخدم متجاوبة بسرعة وسهولة. يمكنك مطالعة المزيد حول هذه المكتبة وتعلم طريقة بناء واجهات المواقع والتطبيقات باستخدامها من خلال الدروس والمقالات الاحترافية حول React على أكاديمية حسوب وأيضًا توثيق React على موسوعة حسوب. أنغولار Angular أنغولار Angular هو إطار عمل مفتوح المصدر يعتمد على لغة TypeScript أطلقته شركة جوجل وهو يتميز بقدرته على تطوير تطبيقات ويب متطورة وضخمة وإدارتها بسهولة كبيرة فهو يوفر الكثير من الميزات التي تساعد مطوري الواجهة الأمامية مثل إدارة حالة التطبيق والتحقق من الصحة. كما يمكنك مطالعة المزيد من الدروس والمقالات الاحترافية حول Angular على أكاديمية حسوب لتتعرف على طريقة استخدامها في تطوير مواقع ويب احترافية. فيو Vue فيو Vue هو إطار عمل جافا سكريبت مفتوح المصدر طوره Evan You المبرمج في جوجل عام 2014 لتطوير واجهات المستخدم وتطبيقات الصفحة الواحدة وهو اليوم واحد من أكثر أطر عمل الواجهة الأمامية شيوعًا واستخدامًا. ما يميز إطار فيو Vue أنه مرن وخفيف الوزن وسهل الاستخدام فقد أزال كل المكونات الإضافية والمفاهيم غير الضرورية التي تأتي مع أطر عمل الواجهة الأمامية الأخرى مثل أنغولار Angular ورياكت React. وللمزيد من التفاصيل أنصح بمطالعة مقال مقارنة بين أطر الواجهات الأمامية: Angular و React و Vue لمعرفة الإطار الأنسب لمتطلباتك، كما أنصح بمتابعة الدروس والمقالات حول Vue التي توفرها أكاديمية حسوب بشكل دوري لتعلم المزيد حول استخدامات هذا الإطار. جي كويري jQuery جي كويري jQuery هي مكتبة مبنية بالاعتماد على لغة جافا سكريبت وهي توفر لمطوري الواجهة الأمامية الكثير من القوة والمرونة وتتضمن الكثير من الميزات التي تجعل كتابة شيفرات جافا سكريبت أبسط وأكثر اختصارًا. لمعرفة المزيد حول طريقة استخدام مكتبة jQuery عند تطوير مواقع الويب أنصح بمطالعات مجموعة المقالات والدروس حول jQuery المتوفرة على أكاديمية حسوب، كما أنصح بمطالعة توثيق jQuery على موسوعة حسوب. تقنيات وأدوات مهمة لتطوير الواجهة الأمامية إضافة لما سبق، يحتاج أي مطور واجهة أمامية لقائمة طويلة من المعارف والمهارات والأدوات الإضافية التي تعزز أداءه وتساعده في تطوير واجهات المستخدم وتكويدها بسرعة واحترافية، وإليك قائمة بأبرز هذه الأدوات نذكر: شجرة DOM والتعامل معها. معرفة أساسية بالشبكات وشبكة الإنترنت وأشهر برتوكولات التواصل مثل HTTP. لمحة عن قواعد التصميم وأساسيات تصميم واجهات المستخدم وتجربة المستخدم UX/UI. التصميم المتجاوب responsive design مع كافة أحجام الشاشات. التوافق مع المتصفحات Cross-browser. واجهة برمجة التطبيقات API. لمحة عن Node.js وأنظمة إدارة الحزم تحديدًا npm. نظام التحكم في الإصدارات git. شجرة DOM من الضروري أن يعرف أي مطور واجهة أمامية مهارات التعامل مع نموذج كائن المستند Document Object Model أو اختصارًا DOM أو شجرة DOM ومعالجته عبر لغة جافا سكريبت، و DOM هو مجموعة من المواصفات التي تمثل مستند الويب بشكل كائن وتعد أحد الطرق الأساسية في بناء مواقع تفاعلية حيث أنها تنشئ واجهة برمجة تطبيقات API تسمح للغات البرمجة مثل جافا سكريبت بالوصول لكافة عناصر صفحات الويب ومعالجتها والتحكم بها. ستساعدك معالجة DOM في تحديث بيانات الصفحة أو تغيير تخطيطها دون إعادة الحاجة لإعادة تحميلها على سبيل المثال يمكنك من خلال DOM إضافة عناصر HTML للصفحة أو إزالتها أو تعديل تنسيقات CSS لها عند وقوع حدث ما أو عند إعادة تحميل صفحة الويب. معرفة أساسية بالشبكات يحتاج مطور الواجهة الأمامية لامتلاك معلومات أساسية حول طريقة عمل الويب والشبكات الحاسوبية وشبكة الإنترنت ومفهوم العميل والخادم وكيفية التفاعل بينهما وبروتوكولات الاتصال عبر الويب مثل HTTP و HTTPS و SSL ومفهوم خدمة اسم المجال DNS فهذه المعرفة تمكنه من عرض واستدعاء المحتوى من الشبكة والاتصال مع الخادم بشكل آمن وتوفير تجربة مستخدم أفضل. للاطلاع على مزيد من المعلومات يمكنك مطالعة سلسلة المقالات والدروس حول الشبكات على أكاديمية حسوب. قواعد التصميم وأساسيات UX/UI ذكرنا سابقًا أن مطور الواجهة الأمامية قد يكون مسؤولًا عن تصميم موقع ويب من الصفر أو قد يكون مسؤولًا عن تحويل التصاميم الجاهزة إلى شيفرات برمجية، لكن في كلتا الحالتين أجد أنه من الضروري لأي مطور واجهة أمامية أن يعرف أفضل النصائح والقواعد لتصميم واجهة المستخدم والمبادئ والقواعد الأساسية في تصميم تجربة المستخدم UX وتصميم واجهة المستخدم UI فهذا من شأنه أن يساعده على فهم الواجهات وكيفية تفاعل المستخدمين معها بشكل أفضل وكيفية إنشاء واجهات أكثر جاذبية وسهولة في الاستخدام وبالتالي سيتمكن من كتابة شيفرات الواجهة الأمامية بشكل أفضل ويضمن أنها مطابق للقواعد التصميمة الصحيحة. التصميم المتجاوب مع كافة أحجام الشاشات التصميم المتجاوب Responsive Design هو تصميم يقوم بتغيير حجم عناصر صفحات الموقع أو إخفائها أو تصغيرها أو تكبيرها ليضمن ظهورها بطريقة واضحة وسهلة الاستخدام مهما كان نوع الجهاز المستخدم لعرضها. يحتاج مطور الواجهة الأمامية لمعرفة أساسيات تصميم الويب المتجاوب Responsive Web Design وطرق كتابة استعلامات الوسائط Media Queries في CSS بشكل صحيح كي يضمن ظهور المواقع بكفاءة على جميع أنواع وأحجام الأجهزة التي يستعملهما المستخدمون سواء الحواسيب ذات الشاشات الكبيرة أو الهواتف المحمولة ذات الشاشات الصغيرة. التوافق مع المتصفحات Cross-browser أحد المهارات الضرورية التي يجب على مطور الواجهة الأمامية تعلمها هو التأكد من أن الواجهات التي يبرمجها متوافقة مع مختلف المتصفحات وتظهر بشكل سليم ومتسق على المتصفحات الشهيرة مثل كروم وفايرفوكس وسفاري وEdge وOpera ويتعلم كيف يجري اختبارات التوافق مع المتصفحات cross-browser testing ويعالج أي مشكلات تواجهه في التوافق. يمكنك الاستعانة ببعض الأدوات والتقنيات المساعدة في اختبار توافق المتصفح Cross-browser مثل Markup Validation Service و CrossBrowserTesting و LambdaTest …إلخ. لكن تجدر الإشارة بأن أطر عمل الواجهات الأمامية مثل رياكت React وأنجولار Angular يمكنها أن تقوم بهذه المهمة عنك ولن تجعلك تكترث لها، يكفي أن تحدد لها أي نوع متصفح تريد أن نستهدف وهي تتولى الأمر لأنها تعالج دومًا الشيفرة التي تكتبها. استدعاء واجهة برمجة التطبيقات واجهات برمجة التطبيقات API هي صلة الوصل بين تطبيقات الواجهة الأمامية وبين النظم والوجهات الخلفية وبالرغم من أنك لا تحتاج كمطور واجهة أمامية لمعرفة كيفية كتابة واجهات برمجة التطبيقات لكونها مهمة مطور الواجهة الخلفية لكنك تحتاج لمعرفة طريقة الاتصال بهذه الواجهات وجلب البيانات منها وعرضها بشكل مناسب ومعرفة التقنيات المرتبطة بها مثل RESTful ومفهوم JSON. باختصار، يجري التواصل بين الواجهة الأمامية والواجهة الخلفية عبر واجهة برمجة التطبيقات وعادة ما ترسل البيانات من الواجهة الخلفية إلى الواجهة الأمامية بصيغة JSON لذا من الضروري معرفة هذه الصيغة، ويمكنك الرجوع إلى مقال تعلم JSON. تعلم Node.js وأنظمة إدارة الحزم يحتاج مطور الواجهة الأمامية إلى تعلم أحد أدوات إدارة الحزم Package Manager التي تجعل عملية تطوير الواجهة الأمامية أسرع وأسهل، فأدوات إدارة الحزم هي برمجيات تسمح لك بتثبيت الحزم المطلوبة للتطوير وإعدادها وتحديثها وإدارة تبعياتها وضمان عدم تعارضها بشكل تلقائي بدلًا من القيام بذلك بشكل يدوي ومن أشهرها npm و Yarn. وعادة يستعمل مطور الواجهات الأمامية مكتبة Node.js التي تأتي مع نظام إدارة الحزم الشهير npm والذي سيستعمله في تنزيل حزم المشروع وإدارتها ومكتبة Node.js هي أول أداة سيثبتها المطور على جهازه فبدونها لن يعمل مع لغة جافاسكريبت على الإطلاق، لذا يجب أن يتعرف عليها وعلى مدير الحزم npm. وقد شرحنا في مقال أساسيات إدارة الحزم في تطوير الويب من طرف العميل كل ما يتعلق باستخدام مدير الحزم وكيفية استخدامه في إدارة مشاريع الواجهة الأمامية. نظام التحكم في الإصدارات git يساعد نظام التحكم في الإصدار وأشهرها Git مطور الواجهة الأمامية على تتبع التغييرات التي يجريها على المواقع ويمكنه من العودة إلى إصدار كود سابق بكل سهولة إذا حدث خطأ ما في الكود كما يفيده في حال العمل على نفس المشروع مع فريق تطوير. تتوفر في أكاديمية حسوب مجموعة غنية ومنوعة من المقالات والدروس حول Git التي تساعدك في تعلم كافة المهارات اللازمة للتعامل مع نظام التحكم بالإصدارات Git. كانت هذه التقنيات جزءًا يسيرًا من التقنيات والأدوات التي على مطور الواجهة الأمامية معرفتها، وفي الفقرة التالية سنوضح المزيد من هذه التقنيات ونضع لك خارطة طريق منظمة تساعدك في تعلم تعلم تطوير الواجهة الأمامية. خارطة طريق تعلم تطوير الواجهة الأمامية إليك خارطة طريق لتعلم مجال تطوير الواجهات الأمامية والذي يعرض بوضوح طريق مطور الواجهات الأمامية بالكامل بدءًا من المرحلة المبتدئة وحتى المتقدمة وأغلب تلك المواضيع تجد عنها في أكاديمية حسوب وموسوعة حسوب: أهم مصادر تعلم تطوير الواجهة الأمامية إذا كنت مبتدئًا ولا تملك أي خبرة مسبقة وتبحث عن أقصر طريقة لتعلم تطوير الواجهة الأمامية أنصحك بالاطلاع على دروة تطوير واجهات المستخدم التي توفرها أكاديمية حسوب فهي دورة شاملة ومنظمة تزيد على 60 ساعة فيديو تدريبية ومن مسارات متعددة تبدأ معك من أساسيات تطوير واجهات المستخدم التي تشرح لك كل المفاهيم واللغات الأساسية وأطر ومكتبات العمل وتنتهي بك ببناء مشاريع عملية متقدمة ترسخ كل هذه الأساسيات وتساعدك في بناء معرض أعمالك. لن تكون وحدك خلال هذه الدورة بل سيكون معك فريق من المدربين لمساعدتك وإجابتك على أي تساؤل أو مشكلة تواجهك في رحلة التعلم، وفي نهاية الدورة ستحصل على شهادة معتمدة من أكاديمية حسوب تعزز سيرتك الذاتية. إضافة إلى ذلك توفر أكاديمية حسوب الكثير من مصادر التعلم المجانية باللغة العربية من دروس ومقالات وسلاسل تعلمية حول تطوير الويب تتعلم من خلالها كافة تقنيات ولغات برمجة الواجهات الأمامية وأطر العمل الشهيرة التي أوردناها في سياق المقال. وإن كنت تفضل الدراسة من الكتب بسبب شموليتها وتسلسلها في الشرح فإن الأكاديمية توفر لك مجموعة من الكتب القيمة التي تهم أي مطور واجهة أمامية من بينها: كتاب فهم أعمق لتقنيات HTML5 كتاب ملاحظات للعاملين في CSS كتاب البرمجة بلغة جافا سكريبت كتاب تصميم تجربة المستخدم سلسلة تطوير الويب وأخيرًا إذا كنت ترغب بمعرفة المزيد من المعلومات حول الواجهات الأمامية وأهم تقنيات برمجتها ومسار تعلمها أنصحك بمشاهدة هذا الفيديو. الخلاصة بهذا تكون وصلت إلى نهاية هذه المقالة الشاملة التي تناولنا فيها كل ما يتعلق بأساسيات تطوير الواجهة الأمامية front-end أو ما يعرف بتطوير واجهة المستخدم وتعرفنا على أهم اللغات وأطر العمل والأدوات التي تحتاجها كمطور واجهة أمامية لتنجز الجزء المرئي من الموقع الذي يتفاعل المستخدمون من خلاله مع التطبيقات والمواقع، كما شرحنا في ختامة أهم خطوات تعلم تطوير الواجهة الأمامية ومصادر تعلمها باللغة العربية. وفي حال كان لديك أي سؤال يتعلق بتطوير الويب وتحديدًا تطوير الواجهات الأمامية للويب فلا تتردد في كتابته في قسم التعليقات أسفل المقال، أو طرحه في قسم الأسئلة والأجوبة في أكاديمية حسوب ليجيبك عليه مبرمجون خبراء. اقرأ أيضًا المدخل الشامل لتعلم تطوير الويب وبرمجة المواقع برمجة مواقع الويب: دليلك المختصر ما الفرق بين تصميم المواقع الإلكترونية وتطوير المواقع الإلكترونية؟ عالم الويب ومعاييره ما هي صفحات الويب؟
    1 نقطة
  10. قد يكون البدء ببناء تطبيقات الويب بعد تعلم لغة البرمجة الشهيرة بايثون محمسًا جدًا، لكن بمجرد البدء بالاطلاع على خيارات أطر العمل Frameworks الرائجة فيها والأكثر نجاحًا، نجد الكثير من الخيارات المهمة التي سنحتاج بطبيعة الحال لفهم مميزاتها والاختلافات الأساسية بينها قبل اتخاذنا لقرار تعلمها واعتمادها بالعمل. في هذا المقال سوف نقارن بين أشهر إطاري عمل في لغة بايثون، وهما إطار العمل جانغو Django وإطار العمل فلاسك Flask، من أجل تسهيل المفاضلة بينهما واختيار ما نحتاجه فعليًا لعملنا وإمكانياتنا. إطار العمل جانغو Django جانغو Django هو إطار عمل مجّاني مفتوح المصدر تم إنشاؤه سنة 2005، وهو مخصص لبناء مواقع وتطبيقات الويب، من أهم ميزات جانغو هو مفهوم قابلية إعادة الاستخدام Reusability للمكونات، فهو يعتمد على مفهوم Multi apps ضمن نفس المشروع؛ كما يوفر يوفر أجزاء جاهزة للمشاريع، مثل قسم التحقق Authentication الذي يجب أن يتوفر في كل مشروع ويب. يُعَد إطار العمل جانغو واحدًا من أطر العمل الضخمة، إذ لا يحتاج في عملياته الرئيسية على المكتبات الخارجية، بل يمكن الاعتماد عليه لوحده لإنجاز تلك العمليات. ميزات إطار العمل جانغو Django يتميز إطار العمل جانغو Django بكونه: إطار عمل احترافي مناسب جدًا للمشاريع الكبيرة يحوي الكثير من الخصائص المضمنة افتراضيًا يدعم تعدد التطبيقات إفتراضيًا، مما يجعل من السهل على المطور كتابة كود يمكن إعادة إستخدامه في العديد من المشاريع متوافق جدًا مع المبرمجين ذوي الخبرة العالية يحتوي على دعم مجتمعي قوي أشهر المشاريع المبنية باستخدام جانغو Django سنذكر في الآتي أبرز المشاريع العالمية الضخمة التي تم بناؤها بإطار العمل Django: Instagram Pinterest Udemy Coursera ما هو إطار العمل فلاسك Flask؟ فلاسك Flask هو إطار عمل صغير Micro Framework تم إنشاؤه سنة 2010، مع ذلك فهو يقدم الميزات الأساسية لتطبيق الويب. يعتمد فلاسك كثيرًا على المكتبات الخارجية، ولايحتوي على معمارية محددة مثل MVC، مما يمنح مرونة في اختيار واستخدام الطريقة التي نريدها؛ كما لا يحتوي على ORM أساسي، ولكن يكفي استخدام مكتبات خارجية للقيام بوظيفة الـ ORM. يُعَد إطار العمل فلاسك Flask مناسبًا جدًا للمبتدئين الراغبين في تعلم استخدام أول إطار عمل، نظرًا لبساطته وسهولة تعلمه مقارنةً مع باقي أطر العمل الشهيرة الأخرى. ميزات إطار العمل فلاسك Flask يتميز إطار العمل فلاسك Flask بكونه: إطار عمل سهل مناسب للمبتدئين مناسب للمشاريع الصغيرة مرن وقابل للتخصيص متوافق مع المبرمجين ذوي الخبرة البسيطة والعادية يحتوي على مجتمع نشط أشهر المشاريع المبنية باستخدام فلاسك Flask من أشهر المشاريع المبنية بفلاسك Flask، نجد المشاريع العالمية الضخمة الآتية: Netflix Lyft Reddit Zillow MailGui الإختلافات الرئيسية بين جانغو وفلاسك رغم أن كل من جانغو وفلاسك إطارين مميزين جدًا، إلا أن هناك بعض المعايير التي يحتاج المبرمج لمعرفتها من أجل تحديد أيهما أنسب له للعمل أو التعلم. سنقارن فيما يلي بين كل من جانغو وفلاسك من عدة جوانب كما يلي. 1. حسب طبيعة الاستخدام يُعَد إطار العمل Django مناسبًا لبناء تطبيقات الويب الكبيرة والمعقدة وفي مشاريع التطوير الشاملة Full Stack التي تتطلب الكثير من الميزات المضمنة، مثل أنظمة إدارة المحتوى CMS، ومنصات التجارة الإلكترونية؛ إذ يتيح جانغو خاصية عمل متكاملة مع مكوناته المضمنة للتعامل مع المهام المختلفة، مثل المصادقة وإدارة قاعدة البيانات وتوجيه عنوان URL، وغيرها. على الجانب الآخر، يتم استخدام إطار العمل فلاسك لبناء واجهات برمجة تطبيقات RESTful والخدمات الصغيرة والنماذج الأولية. وبالنظر لطبيعة فلاسك وخفة وزنه وتصميمه البسيط ومرونته، فهو يمنح المطورين تحكمًا مناسبًا أكثر في اختيار المكتبات والمكونات التي يرغبون بها بما يتماشى مع حاجة الاستخدام. 2. حسب سهولة التعلم لدى إطار العمل Flask متطلبات تعليم منخفضة نسبيًا تجعله في متناول المبتدئين والمطورين ذوي المعرفة الأساسية بلغة بايثون، وهو مناسب للراغبين في البدء بتعلم البرمجة بإطار عمل خفيف الوزن واستكشاف المزيد من المفاهيم المتقدمة تدريجيًا. على عكس ذلك، لدى إطار العمل Django متطلبات عالية وأكثر تعقيدًا للتمكن من التعامل مع كافة الميزات التي يوفرها، ويتطلب العمل به توفر خبرة متوسطة إلى متقدمة في لغة بايثون. لذا يمكن القول أنه رغم أن الأصل هو المفاضلة بين الإطارين حسب حاجة مشاريعنا، إلا أنه في حال أردنا تعلم أحدهما من أجل أغراض مختلفة، أو لغرض البدء بتعلم التعامل مع أطر العمل، فلن يكون من الجيد اختيار أحدهما على حساب الثاني بعشوائية في صالحنا. إذ لو كنا مبتدئين مثلًا ونريد تعلم كيفية التعامل مع اطر العمل، فسيكون إطار العمل Flask هو الخيار الأمثل لنا، عكس Django الذي سيكون الخيار السيء بهذه الحالة. أما في حال كنا مبرمجين متمكنين ونرغب بتعلم إطار عمل جديد مع معرفة وخبرة تتناسب مع متطلبات العمل بجانغو، فسيكون جانغو خيارًا أنسب لنا، نظرًا للخيارات الكثيرة التي يمنحنا إياها وتمكيننا من تطوير المشاريع الكبيرة. 3. حسب سهولةالاستخدام كما ذكرنا سابقًا، فـ Flask بطبيعته أنسب للمشاريع الصغيرة وأكثر بساطة من Django، وهذا يمنح المطورين خاصةً المبتدئين منهم أريحيةً أكبر في العمل من خلاله، إذ يتسم بسهولة الاستخدام ويتطلب أيضًا عددًا أقل من أسطر التعليمات البرمجية مقارنة مع جانغو الذي يتطلب وجود خبرة عالية ومهارات برمجية متقدمة. 4. حسب التكلفة رغم أن كلًا من Flask وDjango هما من أطر عمل Python المجانية ومفتوحة المصدر، إلا أنه نظرًا لكون إطار العمل Flask أقل احتواءًا على الميزات المدمجة ويحتاج لصيانة أكبر مقارنة مع إطار العمل جانغو، فهذا قد يجعله أكثر تكلفةً من جانغو في بعض الحالات. مع ذلك، تعتمد حاجتنا للميزات الإضافية على متطلبات عملنا، لذا قد لا تكون هناك تكاليف إضافية حتى عند استخدام فلاسك إن كان مشروعنا لا يتطلب ذلك. في حال كنا بحاجة إلى وظائف إضافية مدمجة أو نفضل إطار عمل أكثر شمولًا بالعمل، فقد يكون Django خيارًا أفضل هنا. 5. حسب الأداء والسرعة يتميز إطار العمل فلاسك Flask بكونه أفضل من ناحية الأداء والسرعة وقابلية التوسع بالمشاريع الصغيرة، إذ يتميز بخفة وزن تسمح للمطورين ببناء تطبيقاتهم الصغيرة في وقت قصير جدًا وباستهلاك أقل للموارد مقارنةً مع إطار العمل Django. أما بالمشاريع الكبيرة، فإطار العمل جانغو Django بطبيعته أنسب لهذا النوع من المشاريع، إذ يحوي العديد من الخصائص المدمجة التي تسهل عملية التطوير، مما يتيح عملية تطوير أسرع وأسلس مقارنة مع إطار العمل فلاسك. 6. حسب قابلية التوسع كلا الإطارين قابلين للتوسع، لكن كل حسب مجال استخدامه الأمثل. فـ Flask مثلًا يوفر قابلية جيدة للتوسعة بالمشاريع الصغيرة ومتوسطة الحجم، في حين أن Django ممتاز بقابليته للتوسع بالمشاريع الصغيرة والكبيرة رغم أنه أمثل للمشاريع الكبيرة بفضل الخصائص المدمجة المتاحة به. 7. حسب المرونة يتميز فلاسك بمرونة عالية جدًا مقارنةً مع جانغو، إذ أن عدم احتواء Flask على الكثير من الخصائص المدمجة، يتيح للمطور قدرة عالية في التحكم بهيكل المشروع وتصميمه، ويمنح له حرية عالية في الخصخصة وانتقاء الأدوات والمكتبات الأنسب له، عكس Django الذي يكون مرتبطًا بأغلبه بالخصائص المدمجة به. 8. حسب التعامل مع قاعدة البيانات يأتي جانغو مع نظام ORM يمكّن المبرمجين من التعامل بسهولة مع مجموعة متنوعة من قواعد البيانات العلائقية مثل PostgreSQL وSQLite و Prophet و MySQL وغيره، حيث يقدم ORM الدعم لإنشاء وإدارة عمليات ترحيل قاعدة البيانات. أما Flask فنظرًا لاعتماده على القابلية الكبيرة في التخصيص، فهو لا يضع قيودًا على كيفية تخزين البيانات، ويمكن للمطور اختيار ما يناسبه لأجل هذا الغرض. يعتمد فلاسك هنا على الإضافات الخارجية لترتيب تنفيذ عمليات قاعدة البيانات المشتركة مثل إضافة SQLAlchemy 9. حسب دعم المجتمع البرمجي بالنسبة للمطورين، لا بد أن يكون لدى الإطار المختار مجتمع مستخدمين قوي، إذ توفر هذه المجتمعات قدرًا كبيرًا من المساعدة من خلال الرد على أية استفسارات قد نحتاج للرد بشأنها، كما يمكنها أيضًا تشجيع تطوير التطبيقات الجديدة المتعلقة بالإطار. بالنظر إلى موقع Github نجد عدد نجوم التقييمات متقارب بين الإطارين؛ أما حسب موقع Stackoverflow فنجد إنه يوجد أكثر من 300 ألف سؤال عن جانغو، بينما يوجد حوالي 55 ألف سؤال فقط عن فلاسك؛ أما بالنظر الى موقع Google Trends فنجد أن التقنيتين متقاربتين جدًا في البحث. ومن خلال الإحصائيات المشار إليها، نجد أن كلا التقنيتين تحظى بدعم كبير جدًا من المجتمع لكن دعم جانغو أكبر من فلاسك بعض الشيء، مع ذلك ورغم صغر حجم الدعم المجتمعي لفلاسك مقارنةً مع جانغو، إلا أن مجتمع فلاسك نشط جدًا ويمكّن المبرمجين من الحصول على ما يحتاجون إليه. 10. حسب الاحتواء على واجهة تحكم إدارية Admin Interface يحتوي إطار العمل جانغو Django على واجهة إدارية مدمجة سهلة الاستخدام تسمح للمطورين بإجراء عدة عمليات بسرعة على النموذج خلال إنشائهم تطبيق، وذلك دون الحاجة إلى أي تعليمات برمجية إضافية أو إضافات خارجية. عكس فلاسك Flask الذي يعتمد على المطور نفسه في العملية، فلا يحتوي على واجهة إدارية مدمجة؛ مع ذلك يمكن تثبيت إضافة خارجية Extention اسمها Flask-Admin، والتي توفر ما يحتاجه المبرمج بهذا الخصوص 11. الأمان والحماية نظرًا لكون Django أكثر توجهًا واستخدامًا مع المشاريع الكبيرة، فهو يركز على خصائص الأمان والحماية بقوة افتراضيًا، ويحتوي على متطلبات تشفير عالية تجعله أقل عرضةً للتهديدات السيبرانية، عكس Flask الذي رغم توفره على بعض ميزات الأمان المضمنة مثل حماية CSRF، إلا أن الاهتمام بأمان وحماية التطبيقات المنشأة يقع بنسبة أكبر على عاتق المطورين. يمكننا اختصار الفروقات المذكورة أعلاه في الجدول التالي: الخاصية جانغو Django فلاسك Flask طبيعة الاستخدام مناسب للمشاريع الكبيرة والمعقدة مناسب للمشاريع الصغيرة والبسيطة سهولة التعلم مناسب للمحترفين أنسب للمبتدئين سهولة الاستخدام صعب الاستخدام ويتطلب خبرة أعلى سهل الاستخدام التكلفة مجاني، ولا يتطلب إضافات خارجية لإنجاز المشاريع مجاني، لكن يتطلب إضافات خارجية قد تكون مدفوعة لإنجاز المشاريع الأداء والسرعة أداء وسرعة أفضل في المشاريع الكبيرة أداء وسرعة أفضل في المشاريع الصغيرة قابلية التوسع قابلية توسع جيدة بكل أنواع المشاريع، بالأخص المشاريع الكبيرة قابلية توسع جيدة بالمشاريع الصغيرة ومتوسطة الحجم المرونة مرونة قليلة لارتباطه بأدواته المدمجة مرونة عالية جدًا لعدم ارتباطه بأدوات مدمجة كثيرة التعامل مع قاعدة البيانات يعتمد على نظام ORM مدمج للتعامل مع قواعد البيانات من نوع SQL لا يفرض قيود بالتعامل مع قواعد البيانات ويعتمد على إجراءات المطور الدعم المجتمعي مجتمع كبير ونشط مجتمع أقل حجمًا لكن نشط الاحتواء على واجهة تحكم إدارية Admin Interface يحوي واجهة إدارية مدمجة لا يحوي واجهة إدارية مدمجة، بل يحتاج لتثبيت إضافات خارجية مثل Flask-Admin الأمان والحماية يوفر خصائص حماية مدمجة قوية يوفر خصائص حماية مدمجة أقل ويعتمد على تأمين المطور لمشروعه بنفسه كيف نختار إطار العمل المناسب؟ يُعَد إطار العمل جانغو Django كما وضحنا سابقًا أصعب بالتعلم مقارنةً مع فلاسك، لذا في حال لم تكن لدينا خبرة مسبقة بالتعامل مع اُطر العمل عمومًا، فسيكون من الأنسب لنا اختيار إطار العمل فلاسك Flask، ثم الانتقال في حال الرغبة أو الحاجة إلى إطار العمل جانغو Django وعندها سيكون تعلمنا على جانغو أسهلك أما في حال توفرت لدينا خبرة مُسبقة بأحد أطر العمل، فيمكن تعلم أي إطار عمل بناءً على أهداف ورغبات المتعلم. خاتمة بهذا نكون قد تعرفنا على مفهوم إطاري العمل جانغو وفلاسك ووضحنا ميزات كل واحد منهما، مع توضيح الفروقات الأساسية التي تسمح بالمفاضلة بينهما وانتقاء ما يتوافق مع إمكانيات وخبرات المتعلم بها. نأمل أن نكون قد جعلنا عملية الاختيار أسهل عليك. المصادر Django Vs. Flask: Understanding The Major Differences ?Which Is the Best Python Web Framework: Django, Flask, or FastAPI Differences between Django vs Flask Flask vs Django: Let’s Choose Your Next Python Framework Flask-tastic Admin Panel: A Step-by-Step Guide to Building Your Own SQLAlchemy in Flask اقرأ أيضًا مدخل إلى إطار عمل الويب جانغو Django تعرف على إطار العمل فلاسك Flask تعرف على مفهوم إطار العمل Framework وأهميته في البرمجة
    1 نقطة
  11. نعيش اليوم في عصر يتصف بتفجر غير مسبوق في كمية البيانات، فكل الأجهزة التي نتعامل معها في حياتنا اليومية سواء هواتفنا الجوالة أو مواقع التجارة الإلكترونية التي نتسوق منها أو شبكات التواصل الاجتماعي التي نتصفحها بشكل يومي وحتى أجهزة الاستشعار الموجودة في أجهزة إنترنت الأشياء التي باتت منتشرة في كل مكان حولنا…إلخ. كلها تتعقبنا وتسجل بياناتنا والإجراءات التي نقوم بها والخيارات التي نتخذها ولك أن تتخيل كمية البيانات المهولة التي تولد عن كل هذا طوال الوقت! هذه البيانات الضخمة في شكلها الأولي لا تعني أي شيء في الواقع لذا كان لا بد من تحليلها واستخراج المعلومات المفيدة منها وهنا يأتي دور علم البيانات الحديث الذي يعالج كل جزء من البيانات التي يتم إنشاؤها اليوم لتطوير وتيرة الأعمال واتخاذ القرارات الصائبة والموثوقة التي تعتمد على هذه المعلومات. سنركز في مقال اليوم على أحد التخصصات المهمة في هذا العلم وهو تحليل البيانات Data analysis وهو التخصص الذي يهتم باستخلاص معلومات ذات قيمة من هذه البيانات الخام ونوضح أهميته في عالم الأعمال اليوم ونكتشف أهم الأدوات والتقنيات والمهارات التي تحتاجها لتصبح محلل بيانات محترف، كما سنكتشف أهم الفروقات بين علم البيانات وتحليل البيانات وهندسة البيانات ونسرد بعض الأمثلة الواقعية على شركات تستخدم تحليل البيانات لتحسين أعمالها بأسلوب بسيط وسهل الفهم بعيدًا عن المصطلحات المعقدة. ما هو تحليل البيانات Data Analysis؟ علم تحليل البيانات Data analysis هو تنظيف وتحويل ونمذجة البيانات حتى تحويلها أخيرًا إلى معلومات مفيدة تساعد في اتخاذ قرارات أو توضيح رؤى، حيث يهدف إلى تحويل البيانات إلى معلومات والفرق بين البيانات والمعلومات هو أن الأولى عبارة أن أجزاء بيانات متناثرة تفتقد المعنى مثل عدد 25 أو اسم أحمد بينما الأخيرة هي بيانات لها معنى مثل أن العدد 25 هو عمر أحمد فأصبح له معنى، هذا على مستوى عدد فكيف لو كان لدينا آلاف أو ملايين البيانات والأعداد المماثلة، تخيل! يقوم محللو البيانات باستخراج البيانات الأولية وتنظيمها ثم تحليلها وتحويلها من أرقام غير مفهومة إلى معلومات مفسرة وواضحة وبعد الانتهاء من تفسير البيانات تصاغ النتائج التي تم التوصل إليها بشكل اقتراحات أو توصيات حول الخطوات التالية التي يجب اتخاذها في العمل وتتقاطع هذه المهام مع مهام مهندسي البيانات. يمكنك التفكير في مجال تحليل البيانات كشكل من أشكال ذكاء الأعمال أو ما يعرف استخبارات الأعمال Business intelligence واختصارًا BI، وهو علم يستخدم لحل مشاكل وتحديات معينة داخل المؤسسات والشركات، وتكمن أهميته وقوته في العثور على مجموعات وأنماط البيانات التي يمكنها أن تخبرنا بشيء مفيد وملائم حول مشكلة أو أمر معين من العمل يخص العملاء أو الموظفين أو المنتجات أو المخزون …إلخ. ولا يساعد هذا العلم على فهم السلوك الماضي فحسب بل يمكّننا من التنبؤ بالاتجاهات والسلوكيات المستقبلية وبهذا تكون أي قرارات تتخذ مدروسة بناءً على ما تخبرنا به البيانات وليست مجرد قرارات تعتمد على التخمين والحدس. الفرق بين علم البيانات Data Science وتحليل البيانات Data Analysis لا بد أن نعرف قبل الغوص في الفرق بين علم البيانات وتحليل البيانات أنّ كلا العلمين يتعامل مع البيانات الضخمة لكن لكل منهما نهجه الخاص. وعمومًا يشكل علم البيانات مظلة تضم تحتها علم تحليل البيانات وتستفيد من إمكاناته لكنه يغطي مجالًا أوسع في التعامل مع البيانات. يركز علم البيانات على إيجاد ترابط منطقي بين كم هائل من البيانات، بينما يركز تحليل البيانات على إيجاد ميزات الرؤى المستخلصة من تلك البيانات. بكلمات أخرى: علم البيانات هو فرع من علم البيانات يُعنى بالإجابة عن أسئلة محددة يطرحها علم البيانات وكيفية إنجاز أو تطبيق هذه الإجابات. يقتضي الفرق بين علم البيانات وتحليلها اختلافًا في الطرق المستخدمة في العمل، إذ يستخدم عالم البيانات الرياضيات والإحصاء وخوارزميات الذكاء الاصطناعي وتعلم الآلة لتصحيح وتنظيف ومعالجة وتفسير البيانات الخام لاستخلاص الرؤى منها وإنجاز نماذج أولية توضح الترابط بين البيانات المدروسة. أما محلل البيانات فهو من يتفحص مجموعات البيانات ليجد مدلولها ويخلص بنتائج ملموسة، إذ يجمع محلل البيانات كميات كبيرة من البيانات المهيكلة ثم ينظمها ويحللها ليتعرف على الأنماط التي يبحث عنها، ثم يحاول بعد ذلك تصوير هذه الأنماط بعرضها على شكل مخططات ورسومات وغير ذلك من الأشكال التي تسهل الفهم والتفاعل مع النتائج. باختصار ينقّب علم البيانات في البيانات الخام بحثًا عن رؤى وأفكار منها، بينما يُستخدم تحليل البيانات في نقل هذه الرؤى والأفكار التي قد تبدو معقدة إلى لغة أبسط يفهمها التقنيون وغير التقنيين في المؤسسة التي طلبت الدراسة ويطورون أنظمة لأتمتة وتحسين الأداء العام للعمل مع البيانات. وقد أفردنا لعلم البيانات مقالًا مفصلًا بعنوان علم البيانات Data science: الدليل الشامل يمكنك الرجوع إليه للاستزادة حول تخصص علم البيانات. أهمية تحليل البيانات في شركات الأعمال تبرز أهمية تحليل البيانات في المقام الأول بسبب الكمية الضخمة من البيانات التي تجمع في مختلف المنظمات ومؤسسات العمل فعلى سبيل المثال تقوم شركات البيع بالتجزئة اليوم بجمع وتخزين كميات هائلة من البيانات وتتعقب أي منتجات أو خدمات قمت بتصفحها وشرائها وتسجل كافة الصفحات التي قمت بزيارتها على مواقعها الإلكترونية وتتعقب القنوات التي اشتريت منها وتتعرف على عاداتك في الإنفاق وتجمع كل شاردة وواردة عنك! هذه البيانات التي تجمع بكميات مهولة هي واحدة من أهم أصول الشركات التجارية وأكثرها استراتيجية في عالم الأعمال لكن هل تساءلت لماذا تتنافس الشركات فيما بينها لجمع كل هذه المعلومات؟ لأن التنقيب في هذه البيانات وتحليلها وفهمها يساعدها على استخراج كنوز منها وهذه الكنوز هي معلومات قيمة تساعد أصحاب العمل على اتخاذ أفضل القرارات وتطوير الأداء بشكل مضمون. فالحصول على البيانات وجمعها لا يكفي وحده وهو ليس الغاية في الواقع فماذا يفعل صاحب العمل بكميات مهولة من البيانات المختلفة في بنيتها والتي قد تكون في كثير من الأحيان مكررة أو ربما ناقصة أو غير دقيقة، صاحب العمل يريد في النهاية الخلاصة أو بكلام آخر يريد القصة التي ترويها هذه البيانات والمستنتجة من كل هذا الزخم كي يبني عليها قرارًا صائبًا بشأن الميزانية أو الأسعار أو الموارد وفي نهاية المطاف يسعى في المقام الأول لزيادة أرباحه النهائية وهنا يبرز دور علم البيانات وتحليل البيانات. فشركات البيع على سبيل المثال قادرة الاستفادة من تحليل هذه البيانات في معرفة العادات الشرائية لعملائها وتوصيتهم بأنسب المشتريات وتحديد التحسينات الأنسب في أسعارها وتتبع مخزونها وكشف عمليات الاحتيال ومقارنة مستوى المبيعات وغير ذلك الكثير. وكي تتمكن الشركات من ذلك يجب أن تتمكن من صياغة البيانات وتمثيلها بشكل تقارير مناسبة توضح لصناع القرار في مجال الأعمال المغزى منها وتمكنهم على فهم دلالاتها واتخاذ إجراءات موثوقة وسريعة بالاعتماد عليها وإحداث تغيير إيجابي داخل الشركات لذا تلجأ إلى تحليل البيانات الذي يفسر لأصحاب العمل كل ما تحاول البيانات إخبارهم به. مهام محلل البيانات يلعب محلل البيانات دورًا حيويًا ومهمًا في الشركات والمنظمات ويساعدها على فهم البيانات الضخمة المتوفرة لديها ويتعاون مع باقي أعضاء فريق البيانات للمساعدة في استخراج عن أي معلومات مفيدة وقيمة. كما يقوم محلل البيانات بجمع وتحليل البيانات لحل مشكلة معينة ويكون مسؤولًا عن تحويل البيانات الأولية إلى رؤى ذات مغزى ويستخدم البيانات والأفكار التي توفرها عملية تحليل البيانات لحل مشاكل محددة أو الإجابة على أسئلة محددة. وإليك قائمة بأهم المهام التي يقوم بها محلل البيانات: جمع البيانات الأولية معالجة البيانات ضمان أمن وخصوصية البيانات نمذجة البيانات فهم وتفسير البيانات عرض البيانات نستعرض في الفقرات التالية المزيد من التفاصيل حول كل مهمة من هذه المهام. 1. جمع البيانات الأولية الخطوة الأولى هي جمع البيانات الخام ويمكن أن يقوم محلل البيانات بهذه المهمة ويجمع المعلومات المطلوبة فالبيانات التي سيحللها قد تكون موجودة في مصادر مختلفة، فهي إما أن تكون موجودة في قواعد بيانات الشركة مبعثرة هنا وقد يحتاج لجمعها من خلال إجراء استطلاعات الرأي أو من خلال تتبع بيانات زوار موقع الشركة على الويب، أو من خلال الاستعانة ببيانات الشركات المنافسة حيث يمكن للشركات تبادل البيانات فيما بينها لتحقيق مصالح مشتركة. 2. معالجة البيانات بعد جمع البيانات يجب على محلل البيانات البدء بتنظيف وإعداد هذه البيانات الأولية لأنها في الغالب تحتوي على نسخ مكررة أو قيم خاطئة أو غير دقيقة أو مفقودة للحصول على بيانات سليمة وموثوقة ومفهومة وذات جودة عالية وقد يحتاج إلى تحويل البيانات من هيكل إلى آخر أو من نوع إلى آخر حتى يصبح من الممكن التعامل معها بإحدى لغات البرمجة أو تخزينها في قواعد البيانات كي تكون تفسيرات هذه البيانات دقيقة فإذا لم تكن البيانات التي نبني نحللها نظيفة وصحيحة لن تكون التحليلات والنتائج التي تحصل عليها دقيقة. أحيانًا وفي الشركات أو المشاريع المتوسطة إلى الكبيرة يتولى هذه المهمة مهندس البيانات الذي يركز على هذه المهمة نظرًا لكبر المشروع أو ضخامة البيانات بينما يركز محلل البيانات على عملية التحليل بعيدًا عن عملية الجمع والمعالجة والتجهيز الذي يكون دوره تاليًا. 3. ضمان أمن وخصوصية البيانات قد يحتاج محلل البيانات لإخفاء هوية البيانات الحساسة والشخصية أو حذفها بالكامل لمنع الآخرين من الاطلاع عليها عندما لا تكون هناك حاجة لها للحصول على النتيجة التي يريدها، وأيضًا قد يتولى مهندس البيانات هذه المهمة وتأتي البيانات مشفرة ومحمية إلى محلل البيانات ليقوم بالخطوات التالية. 4. نمذجة البيانات الخطوة التالية هي تحليل وتحديد نقاط البيانات المختلفة التي تم جمعها وإنشاءها بواسطة محللي البيانات واختيار أنواع البيانات المراد تخزينها وجمعها وإنشاء علاقات بينها وتحديد كيفية ترابط مجموعات البيانات مع بعضها البعض وكيفية عرض هذه البيانات وتساعد النمذجة الصحيحة للبيانات على تسريع وتيرة فهمها وإعداد التقارير الخاصة بها. 5. فهم وتفسير البيانات بعد نمذجة البيانات تأتي الخطوة التالية وهي تفسير هذه البيانات من خلال تحديد الأنماط أو الاتجاهات في البيانات التي يمكنها أن توفر معلومات مفيدة تُستخلص منها إجابات على أسئلة توضح سلوكيات أو تفسر أسباب لمشكلات تخص العمل كما تُبنى عليها قرارات وغيرها. 6. عرض البيانات الخطوة الأخيرة والضرورية التي يتوجب على محلل البيانات القيام بها هي عرض وتقديم البيانات بشكل يضفي عليها الحيوية فالمعلومات التي حصلت عليها يجب أن تصاغ على هيئة مخططات ورسوم بيانية وتقارير مكتوبة بألوان متناسقة وخطوط مفهومة ثم تقدم لأصحاب العمل المهتمين لمساعدتهم على فهم ما تعنيه هذه البيانات وتمكينهم من اتخاذ قرارات دقيقة وحيوية بشأنها. هل تحتاج إلى تطوير أعمال شركتك وتحسين فرصها؟ وظّف محلل بيانات محترف من مستقل لتحليل بياناتك وتقديم رؤى استراتيجية تعزز أداء نشاطك التجاري أضف مشروعك الآن مجالات تحليل البيانات نظرًا للتطور التقني الحاصل في عصرنا الراهن فقد أصبح جمع البيانات وفرزها وتحليلها أمرًا ضروريًا لأي مجال من مجالات الحياة وبات من الضروري توظيف محللي البيانات في كافة قطاعات العمل، وفيما يلي نستعرض بعض المجالات والتخصصات التي يمكن لمحللي البيانات العمل فيها. محلل الأعمال محلل الأعمال هو المسؤول عن تحليل ومعالجة البيانات التي تساعد الشركات والمؤسسات على تفسير وتوثيق العمليات التجارية والمنتجات والخدمات والبرامج ويتمثل دوره الأساسي في زيادة كفاءة الأعمال. محلل تسويق محلل التسويق أو محلل أبحاث السوق هو الشخص المسؤول عن جمع وتحليل بيانات المنافسين والعملاء فهو يدرس المنافسين ويبحث عن تفضيلات العملاء وظروف العمل واتجاهات السوق وأي معلومات أخرى تساعد في جهود التسويق للشركة مثل تحديد المبيعات المحتملة لمنتج أو خدمة ما أو تحديد المنتجات التي يفضلها الناس وتقدير تكلفتها وتحديد الفئات التي ستشتريها ويسعى بشكل أساسي لزيادة الإيرادات وتحسين الحملات التسويقية. محلل العمليات محلل العمليات أو محلل أبحاث العمليات هو المسؤول عن تحليل وتقييم البيانات بهدف تحسين العمليات التجارية وحل المشكلات الداخلية وضمان سير عمليات الشركة بسهولة وسلاسة وإنشاء نماذج التسعير والتسويق، فهو من يحدد الحملات التسويقية التي ستجلب عملاء جدد ويجد الطرق الأنسب لخفض التكاليف دون المساس بجودة المنتج أو الخدمة التي تقدمها الشركة. محلل نظم تقنية المعلومات يعرف محلل نظم تقنية المعلومات أيضًا باسم محلل النظم وهو متخصص تقني لديه معرفة واسعة بأنظمة التشغيل والبرامج والأنظمة الأساسية ومهمته الأساسية تحليل وتصميم وتنفيذ نظم المعلومات والعمل على مشاكل العمل باستخدام التقنيات والأدوات التي يحترفها. المحلل المالي المحلل المالي Financial Analyst هو شخص مسؤول عن جمع البيانات وتنظيم المعلومات وتحليل البيانات المالية السابقة للعملاء والشركات بهدف تقديم المشورة الأفضل حول كيفية إنفاق الأموال لتعظيم الأرباح وتقييم نتائج السندات والأسهم والاستثمارات الأخرى. محلل كميات محلل الكميات أو المحلل الكمي quantitative analyst هو شخص متخصص في حل المشكلات المالية وإدارة المخاطر باستخدام الأساليب الرياضية والإحصائية فهو يطور وينفذ نماذج متقدمة تساعد المؤسسات والشركات التي تعمل في مجال الاستثمار وتداول الأوراق المالية مثل شركات التأمين وشركات المحاسبة وشركات البرمجيات المالية على اتخاذ القرارات المناسبة وتحديد فرص الاستثمار والتسعير المناسبة وإدارة المخاطر. محلل ذكاء الأعمال محلل ذكاء الأعمال business intelligence يحلل تقارير أبحاث السوق التي تسلط الضوء على أنماط السوق والاتجاهات التي قد يكون لها تأثير على عمليات الشركة وأهدافها المستقبلية ويعرض النتائج على الجمهور المناسب. محلل استراتيجي محلل استراتيجيات الشركة هو المختص في حل مشاكل العمل فهو يعتمد على تحليل البيانات التي تمكنه من توفير نتائج مفيدة تساعد الشركات على اتخاذ قرارات أفضل ومعالجة التحديات التي تواجهها وتحديد فرص النمو الجديدة للشركة وتطوير الخطط التي تحدد أفضل الطرق والاستراتيجيات لتحقيق الأهداف. محلل طبي يهتم المحلل الطبي أو محلل الرعاية الصحية بجمع وتنظيم وتحليل وتفسير البيانات الطبية مثل بيانات المرضى والعلاجات والمنتجات الطبية لتحسين العمليات التجارية للمستشفيات والمرافق الطبية وتطوير أدائها. محلل الأمني فحص المحلل الأمني البيانات لفحص أي تهديدات محتملة وتحديد ما إذا كان هناك هجوم قد وقع أو على وشك الوقوع. قد يستخدمون أيضًا معرفتهم الإحصائية والرياضية لتطوير طرق جديدة لجمع البيانات حول تهديدات محددة أو هجمات محتملة. مدير تحليل البيانات يوجه مدير تحليل البيانات فريق محللي البيانات في مقر العمل وينسق العمل بينهم ويشرف على عمليات تحويل البيانات الأولية إلى رؤى تجارية يمكن استخدامها لاتخاذ القرارات ويساعد في التوصية بحلول لإنجاز العمل والبحث عن طرق فعالة لجمع البيانات وإنشاء وتطوير النماذج الإحصائية المعقدة واستخدام الخوارزميات والاستراتيجيات الفعالة لتحليل البيانات. مسؤول قاعدة البيانات يراقب مسؤول قاعدة البيانات قاعدة البيانات ويهتم بسلامة بياناتها وسلامة الأجهزة التي توجد عليها وهو يشارك في معالجة البيانات وتحويلها والتحقق من صحتها وتنظيفها لتلبية احتياجات العمل والمتطلبات كما يهتم بأمن هذه البيانات ومنح الوصول لها واستخدامها وفق احتياجات ومتطلبات العمل فقط وتقييد وصول المستخدمين غير المصرح بهم إليها. ارتقِ بأعمالك وابدأ التحول الرقمي انقل نشاطك التجاري إلى الإنترنت وطور أنظمة رقمية شاملة لتنمية أعمالك مع خدمات الخبراء على خمسات ابدأ التحول الرقمي الآن أنواع تحليل البيانات يقسم تحليل البيانات إلى خمس مكونات أو أنواع وهي كالتالي: التحليل الوصفي Descriptive التحليل التشخيصي Diagnostic التحليل التنبؤي Predictive التحليل التقديري Prescriptive التحليل الإدراكي أو المعرفي Cognitive وكلما كان محلل البيانات أكثر خبرة كلما كان قادرًا على تحديد النوع الصحيح من التحليلات بما يتناسب واحتياجات العمل كي يضمن تحقيق أقصى استفادة من البيانات التي تمتلكها المؤسسة وبالتالي تحقيق أفضل النتائج من هذا التحليل. دعنا نتعرف بالتفصيل على طريقة إجراء كل نوع من هذه التحليلات وأهميتها في مكان العمل. 1. التحليل الوصفي Descriptive Analytic التحليل الوصفي هو نوع التحليل الأبسط والأكثر استخدامًا فهو يمكن محلل البيانات من تحليل البيانات المتوفرة باستخدام أدوات تحليل مثل Google Analytics التي تمكنه من فهم ما جرى في مؤسسته أو شركته، فالتحليل الوصفي يوفر لمحلل البيانات الإدراك المتأخر لما يجري في العمل. على سبيل المثال إذا كنت محلل بيانات وحصل انخفاض مفاجئ في مبيعات موقع التجارة الإلكترونية الخاص بشركتك في شهر ما لن تقف مكتوف الأيدي لتنتظر هل ستتحسن المبيعات في الشهر التالي بل عليك استخدام التحليلات الوصفية لتحليل بيانات كافة الأشخاص الذين زاروا الموقع في هذا الشهر لمعرفة سبب ما حدث وهل هو ناتج عن انخفاض في عدد زيارات الموقع أو خطأ في أحد الصفحات أو مرتبط بموسم محدد وتعثر على إجابة لكافة التساؤلات حياله ووصف النتائج التي حصلت عليها لأصحاب العمل. يمكن أن تستعين في إجراء هذه المهمة بأدوات التحليل مثل جوجل أناليتكس Google Analytics وتستسخدم مؤشرات قياس الأداء الرئيسية KPIs التي تمكنك من تتبع الأداء ومعرفة مدى نجاح وفشل الأهداف الرئيسية. فالتحليلات الوصفية باختصار تساعد في معرفة ما حدث في السابق مثل انخفاض المبيعات أو زيادة الإيرادات أو نقص الموارد وتلخص مجموعات البيانات الكبيرة وتصف النتائج التي تم التوصل لها لأصحاب العمل وتستفيد منها في معرفة أسباب النجاح أو الفشل السابق وإنشاء تقارير بها. هذا النوع من التحليل على أهميته يعطي المحلل نظرة ثاقبة فقط حول ما إذا كان كل شيء في العمل يسير على ما يرام أم لا، لكنه في الواقع لا يفسر السبب الجذري لوقوعها لذا تعمد الشركات عادة على الدمج بين هذا النوع من التحليل وأنواع التحليلات الأخرى للحصول على رؤية أفضل. 2. التحليل التشخيصي Predictive Analytic التحليلات التشخيصية هي الشكل الثاني لتحليل البيانات وهي تساعد أصحاب الأعمال في الإجابة عن السبب الأساسي في وقوع حدث ما أو العوامل التي تؤثر على سير العمل، فعندما يعرف محلل البيانات ما يحدث بالفعل في عمله باستخدام التحليلات الوصفية لكنه يريد أن يعرف الأسباب والعوامل التي تسببت بحدوثها بشكل جذري يأتي دور التحليل التشخيصي للإجابة عن أسئلة حول سبب وقوع الأحداث. على سبيل المثال كي يشخص محلل الأعمال إن كانت زيادة الأسعار الأخيرة على أسعار منتجات الشركة لها علاقة بانخفاض المبيعات يمكنه استخدام التحليل التشخيصي باستخدام برنامج إحصائي مثل Microsoft Excel أو يستخدم خوارزمية معينة تمكنه من تحليل بيانات المنتجات والعملاء وفحصها ومقارنتها للعثور على الإجابة الدقيقة. هناك العديد من المفاهيم الإحصائية التي يجب على محلل البيانات فهمها قبل أن يتمكن من إجراء التحليلات التشخيصية وأهمها اختبار الفرضيات والفرق بين الارتباط والسببية وتحليل الانحدار التشخيصي. تكمل تقنيات التحليلات التشخيصية التحليلات الوصفية الأساسية حيث يساعد دمج التحليلات التشخيصية والوصفية الشركات في العثور على العلاقات بين الأسباب والنتائج وفحص مؤشرات الأداء لاكتشاف سبب التحسن أو التراجع بدقة. بشكل عام تحدث هذه العملية في ثلاث خطوات: تحديد الشذوذ في البيانات فقد تكون هذه الحالات الشاذة تغييرات غير متوقعة فيمقياس أو سوق معين. جمع البيانات المتعلقة بهذه الحالات الشاذة. استخدم التقنيات الإحصائية لاكتشاف العلاقات والاتجاهات التي تشرح هذه الحالات الشاذة. 3. التحليل التنبؤي Predictive Analytic يساعد التنبؤ بالمستقبل أصحاب الأعمال على توقع اتجاهات السوق وسلوكيات العملاء وكشف حالات الاحتيال قبل وقوعها وتحليل المنافسين لتحسين وبناء استراتيجيات حديثة لتحسين نتائج الأعمال. يعتمد التحليل التنبؤي على النتائج التي تم الحصول عليها من التحليل الوصفي والتشخيصي ويستخدم للعثور على إجابات حول الأمور التي من المحتمل أن تحدث في المستقبل بناءً على النتائج والأنماط السابقة. على سبيل المثال يمكن استخدام التحليل التنبؤي في الشركات والبنوك لتحليل التركيبة السكانية للعملاء وسجلات الدفع السابقة والمنتجات التي اشتروها وأي سلوكيات سلبية حديثة وقعت من قبلهم لتوقع العملاء الذين سيتأخرون في دفع المستحقات والفواتير المترتبة عليهم ولن يسددوها في الوقت المحدد مما يمكنهم من إدارة التدفقات المالية بشكل أفضل واتخاذ خطوات للتخفيف من حدوث هذه المشكلة مثل تقديم خيارات دفع أخرى أو إرسال رسائل تذكير إلى العملاء الذين تم التنبؤ بأنهم سيتأخرون في تسديد المستحقات وتحديد أفضل تاريخ ووقت لإرسال هذه الرسائل وأفضل طريقة للاتصال بهم مثل البريد إلكتروني أو المكالمة الهاتفية أو الرسائل النصية …إلخ. كما تستخدم النماذج التنبؤية بشكل كبير في مجال الرعاية الصحية وتحلل مجموعة من البيانات المتغيرة حول المرضى مثل العمر أو العلاجات السابقة أو تاريخ المرض ومعدل الكوليسترول والوزن للتنبؤ بما إذا كان الشخص عرضة للإصابة بأمراض معينة كالسكري أو النوبات القلبية أم هشاشة العظام أم لا. يعتمد إجراء التحليل التنبؤي على الخوارزميات الإحصائية المتنوعة وعلى تقنيات التعلم الإحصائي وخوارزميات التعلم الآلي مثل الشبكات العصبية وأشجار القرار والانحدار …إلخ. التي تساعد محلل البيانات على تقديم توصيات وتوفير إجابات للأسئلة المتعلقة بما قد يحدث في المستقبل ولكونها تحليلات تعتمد على التخمينات والاحتمالات فهي تعطي نتائج تقديرية قد لا تكون صحيحة ودقيقة بنسبة مئة بالمئة. 4. التحليل التقديري Prescriptive Analytic التحليل التقديري هو الخطوة التالية التي تأتي بعد إجراء التحليل التنبؤي وهو يساعد الشركات على امتلاك رؤية ثاقبة عما يجب عليهم القيام به لحل مشاكل العمل بناءً على العوامل المشتقة من البيانات. فأثناء تحليل البيانات الضخمة لا تكون التنبؤات التي حصلنا عليها من المدخلات دقيقة كما ذكرنا وبالتالي لا يمكننا التيقن من السبب الحقيقي في حدوث مشكلات معينة وهنا يأتي دور التحليلات التقديرية. فعندما يحصل محلل البيانات على النتائج من التحليلات الوصفية والتشخيصية والتنبؤية ويعرف ما حدث ولماذا حدث ويتوقع ما قد يحدث في المستقبل يمكنه أن يستخدم التحليل التقديري لمساعدته في تحديد أفضل مسار للعمل وما الإجراءات التي يجب الإبقاء عليها وما الإجراءات التي يجب التخلي عنها لزيادة نتائج ومخرجات الأعمال. تعتمد تقنيات التحليلات التقديرية على تعلم الآلة لكونها قادرة على تحليل كميات كبيرة من البيانات بسرعة وكفاءة أكبر واختبار مجموعة كبيرة من الشروط والعثور على أنماط محددة في مجموعات البيانات الكبيرة وتقديم التوصيات بناء عليها. على سبيل المثال تستخدم خرائط جوجل التحليل التقديري لمساعدتك على اختيار وتقدير أفضل طريق عليك اتباعه للوصول لوجهتك من خلال الاعتماد على جميع البيانات ذات الصلة مثل المسافة والسرعة وحركة المرور إضافة للمعلومات السابقة المسجلة عن الأشخاص الذي سلكوا هذه الوجهة من قبل. ومن الأمثلة الأخرى على هذا النوع من التحليل توقع توصيات المحتوى المناسب لك على منصات التواصل الاجتماعي من خلال تحليل سجلات سلوكك والمحتوى الذي تشاهده وتتفاعل معه سواء على هذه المنصات نفسها أو على أنظمة أخرى وتمرير سلوكياتك السابقة لخوارزمية محددة تحلل هذه البيانات وتقدر بناء على ذلك نوع المحتوى الذي تهتم به وتقترحه لك. 5. التحليل المعرفي Cognitive Analytic هذا النوع من التحليل هو الأكثر تقدمًا ولا زال في بداياته وهو مستوحى من الطريقة التي يعالج فيها دماغنا البشري البيانات أي أنه يحلل البيانات بذكاء يشبه ذكاء الإنسان فهو يستخلص النتائج ويكتسب الخبرة من التعلم ويطور نفسه مع الزمن، ويساعدك على معرفة ما قد يحدث إذا تغيرت الظروف وتحديد أفضل الطرق للتعامل معها وهو أمر لا تستطيع التحليلات البسيطة القيام به. يعتمد هذا النوع من التحليل مجموعة من التقنيات الذكية مثل الذكاء الاصطناعي وخوارزميات التعلم الآلي ونماذج التعلم العميق والمزيد لمعالجة المعلومات واستخلاص النتائج من البيانات والأنماط الموجودة ويتوقع أن تصبح تطبيقاته واستخداماته أكثر فعالية بمرور الوقت من خلال تعلمه وتفاعلاته المستمرة مع البيانات ومع البشر. وباستخدام هذا النوع من التحليل ستتمكن من معالجة اللغة الطبيعية مباشرة مثل سجلات محادثة مركز الاتصال ومراجعات المنتجات فهو لا يفهم الكلمات في هذه النصوص فقط بل يفهم السياق الكامل لما يتم كتابته أو نطقه! على سبيل المثال تعد كل من Cortana من مايكروسوفت، و Siri من أبل، و Watson من IBM وآخرها ChatGPT من OpenAI روبوتات محادثة تستخدم التحليل المعرفي لتتفاعل معك بلغتك الطبيعية وتوفر لك المعلومات والرؤى التي تريدها. يمكن أن تستفيد الشركات من هذا التحليل للنظر في أنماط المشتريات من السنوات السابقة وتحديد المنتجات التي قد تكون شائعة العام المقبل وفهم سبب شعبية ورواج منتج معين وما إذا كانت شعبيته ستبقى في السنوات المقبلة مما يساعدها على تحديد فيما إذا كانت ستواصل تخزين كميات كبيرة من هذا المنتج الرائج أم لا كما يمكن للمؤسسات الطبية استخدام التحليل المعرفي لإعطاء أفضل العلاجات الممكنة للمرضى. هذه كانت نبذة عن أهم أنواع التحليلات التي يمكنك الاعتماد كمحلل بيانات عليها واختيار الأنسب من بينها لتعزيز مسار العمل والحصول على أي إجابات يحتاج صاحب العمل لمعرفتها لتعزيز تواجده في السوق أو زيادة أرباحه أو التخلص من مشاكل العمل الحالية أو المستقبلية …إلخ. دعنا نلخص هذه التحليلات كما يلي: إجراء التحليلات الوصفية لإدراك ما حدث بعد وقوعه. إجراء التحليلات التشخيصية إذا طلب منك معرفة لماذا حدث هذا الأمر. إجراء التحليلات التنبؤية إذا طلب منك أن تكون بعيد نظر وتعرف ماذا يمكن أن يحدث في المستقبل. إجراء التحليلات التقديرية لتكسب أصحاب العمل بصيرة ثاقبة يعرفون من خلالها ما الذي يجب عليهم فعله بعد ذلك؟ إجراء التحليلات المعرفية للحصول على رؤية صحيحة وصائبة لما يجب أن يتم. أهم أدوات وتقنيات تحليل البيانات في السابق كان تحليل البيانات أمرًا صعبًا ومرهقًا بسبب عدم توفر التقنيات المساعدة فكانت البيانات تجمع يدويًا بطريقة مرهقة، لكن يمكن اليوم لمحلل البيانات الاستعانة بالكثير من أدوات تحليل وتمثيل البيانات المتوفرة لمساعدته على أداء عمله بسرعة وسهولة وفيما يلي نذكر أهم 10 أدوات في تحليل البيانات: برنامج مايكروسوفت إكسل Microsoft Excel برنامج Microsoft Power BI برنامج التحليل الإحصائي SAS إطار عمل أباتشي سبارك Apache Spark لغة بايثون Python لغة البرمجة R لغة الاستعلام الهيكلية SQL تطبيق Jupyter Notebook منصة KNIME برنامج Tableau دعنا نشرح كل أداة من هذه الأدوات وكيف يمكن لمحلل البيانات الاستفادة منه في عمله. برنامج مايكروسوفت إكسل Microsoft Excel يمكننا برنامج جدولة البيانات مايكروسوفت إكسل من إجراء الحسابات على البيانات وفرزها وتجميعها ومعالجتها والبحث فيها وعرضها بشكل رسوم بيانية وإنشاء النماذج وإعداد التقارير، لكن المشكلة في برنامج إكسل أنه ضعيف في التعامل مع البيانات الضخمة. برنامج Microsoft Power BI مايكروسوفت باور بي آي Microsoft Power BI هو برنامج احترافي لتحليل بيانات الأعمال وهو برنامج تجاري مدفوع لكنه يوفر نسخة مجانية بمواصفات محدودة وقد بدأ كمكوِّن إضافي لبرنامج Excel ثم أعيد تطويره عام 2010 وصدر كبرنامج مستقل. يوفر هذا البرنامج مجموعة أدوات متكاملة لتحليل بيانات الأعمال وهو برنامج احترافي يسمح للمستخدمين بإنشاء تقارير مرئية تفاعلية ولوحات معلومات وهو يتكامل مع برنامج إكسل و SQL Server وخدمات جوجل السحابية ويوفر العديد من الميزات الأخرى المفيدة لمحللي البيانات. برنامج SAS برنامج SAS هو أداة تحليل إحصائي تستخدم لتحليل معلومات وبيانات المؤسسات التجارية الكبيرة تم تطويره لتحديد سمات العملاء وإعداد التقارير واستخراج البيانات وإجراء التحليلات التنبؤية ويملك وحدات برمجية لاستخدامات متقدمة مثل مكافحة غسيل الأموال وتحليل لإنترنت الأشياء لكنه منتج مدفوع وسعره مرتفع نوعًا ما. أباتشي سبارك Apache Spark أباتشي سبارك هو إطار عمل برمجي سريع وديناميكي وسهل الاستخدام لمعالجة البيانات وهو يحتوي مكتبة غنية لخوارزميات التعلم الآلي ويستخدم عادة من قبل محللي البيانات وعلماء البيانات لمعالجة البيانات الضخمة وغير المهيكلة وإجراء مهام التحليل الثقيلة حسابيًا من خلال توزيعها على عدة حواسيب. دورة تطوير التطبيقات باستخدام لغة Python احترف تطوير التطبيقات مع أكاديمية حسوب والتحق بسوق العمل فور انتهائك من الدورة اشترك الآن لغة البرمجة بايثون Python توفر لغة البرمجة بايثون لمحلل البيانات آلاف المكتبات المجانية التي تساعده على استخراج البيانات وتحليلها وإعداد التقارير عنها مثل مكتبات NumPy و pandas التي تبسط إجراء العمليات الحسابية ومكتبات Beautiful Soup و Scrapy لاستخراج البيانات من الويب ومكتبة Matplotlib لتمثيل البيانات رسوميًا وإعداد التقارير حولها. لغة البرمجة R لغة R هي لغة برمجة مفتوحة المصدر تستخدم في التحليل الإحصائي واستخراج البيانات وتوفر الكثير من الحزم المساعدة لمحللي البيانات بشكل مشابه لبايثون، ورغم أن كتابة التعليمات في لغة R أكثر تعقيدًا من لغة بايثون إلا أنها لغة مصممة خصيصًا للتعامل مع المهام الإحصائية وتمثيل البيانات المتقدم. لغة الاستعلام الهيكلية SQL تعد لغة SQL أحد التقنيات الأساسية لتحليل البيانات وإعداد التقارير وهي لغة شائعة وسهلة التعلم ومرنة بشكل كبير ما يجعلها اللغة المفضلة لمحللي البيانات لفلترة البيانات والاستعلام عنها وإعداد التقارير …إلخ. Jupyter Notebook تطبيق Jupyter Notebook هو تطبيق ويب مفتوح المصدر يسمح لمحللي البيانات بإنشاء مستندات تفاعلية تتضمن نصوص وأكواد ومعادلات رياضية ورسوم بيانية تشبه إلى حد ما مستندات وورد لكنها أكثر تفاعلية ومصممة خصيصًا لتحليل البيانات وهو متكامل مع أدوات تحليل البيانات الضخمة مثل Apache Spark. برنامج KNIME KNIME هي منصة مفتوحة المصدر وقائمة على السحابة تملك واجهة رسومية GUI سهلة الاستخدام تستخدم في مهام تحليل البيانات والتنقيب عن البيانات والتعلم الآلي تم تطويرها عام 2004 لصناعة المستحضرات الصيدلانية إلا أن قوتها في تجميع البيانات من العديد من المصادر في نظام واحد دفعت محللي البيانات إلى استخدامها في العديد من المجالات مثل تحليل العملاء وذكاء الأعمال والتعلم الآلي. وهي شائعة لدى الشركات الصغيرة ذات الميزانيات المحدودة. برنامج Tableau برنامج Tableau هو برنامج تجاري عملاق لتحليل البيانات وذكاء الأعمال يمكنه التعامل مع كميات كبيرة من البيانات ومعالجتها وإنشاء حسابات معقدة عليها، ويوفر استعلامات SQL لفلترة البيانات ويمكنك من كتابة استعلاماتك الخاصة وهو سهل الاستخدام ويملك واجهة رسومية GUI تعتمد تقنية السحب والإفلات. كانت هذه قائمة بأشهر أدوات والتقنيات المستخدمة. وتذكّر لا توجد أداة واحدة تفعل كل شيء! عليك كمحلل استخدام الأدوات التي تلبي حاجة عملك بأفضل صورة. مصادر تعلم تحليل البيانات ستجد في أكاديمية حسوب العديد من الدروس والمقالات التي تفيدك في تخصص تحليل البيانات ومن أبرز هذه المصادر دروس تعلم برنامج اكسل المشروحة بطريقة منظمة ومبسطة تساعدك على تعلمه بسرعة وسهولة. وإذا كنت مهتمًا بتعلم لغة بايثون التي تعد من أهم لغات البرمجة المستخدمة في تحليل البيانات فقد وفرت لك أكاديمية حسوب قسم دروس ومقالات متنوعة حول لغة بايثون وهي تُحدَّث باستمرار لذا كن على اطلاع دائم عليها لتتعلم كل جديد وإن كنت تفضل التعلم من الكتب المنهجية يمكنك تنزيل كتاب البرمجة بلغة باثيون من أكاديمية حسوب وللمزيد من المصادر أنصحك بزيارة موسوعة حسوب الشاملة التي تضم توثيقات الكثير من لغات البرمجة، بما في ذلك توثيق لغة بايثون. ومن المصادر المميزة التي تسهل عليك طريق الاحتراف دورة تطوير التطبيقات باستخدام لغة Python التي توفرها أكاديمية حسوب والتي تفرد فيهًا مسارًا كاملًا يشرح بشكل واضح ومبسط أساسيات تحليل البيانات ويعرفك على أهم أدوات ومكتبات بايثون وآليات تطبيقها لإجراء عمليات التحليل الإحصائي والوصفي والتصوير البياني وتنظيف وفهم البيانات وغيرها ذلك الكثير من المعلومات التي تؤهلك لبدء العمل كمحلل بيانات في أي شركة أو منظمة أيًا كان مجال عملها. كما توفر دورة الذكاء الاصطناعي التي تساعدك في احتراف برمجة الذكاء الاصطناعي AI وتحليل البيانات وتعلم كافة المعلومات التي تحتاجها لبناء نماذج ذكاء اصطناعي متخصصة وتطوير تطبيقات ذكية تقوم بتحليل البيانات Data Analysis وتمثيلها مرئيًا، وتطبيقات تعلم الآلة Machine Learning والتعلم العميق Deep Learning وغيرها من التطبيقات المنوعة التي تساعدك على احتراف هذا المجال. وأنصحك كذلك بتعلم البرمجة بلغة R التحليلية باللغة العربية وأسلوب منهجي ومنظم وبشرح مبسط من خلال الاطلاع على مجموعة المقالات والدروس حول لغة R التي توفرها أكاديمية حسوب. وتوفر لك أكاديمية حسوب سلسلة دروس ومقالات عن لغة SQL،كما توفر كتابًا تعليميًا متكاملاً بعنوان ملاحظات للعاملين بلغة SQL 1.0.0 يتضمن مجموعة من الملاحظات والأمثلة العملية عن مختلف مواضيع لغة SQL من الأساسيات حتى الاحتراف. الخلاصة تعرفنا في مقال اليوم على مفهوم تحليل البيانات واستكشفنا معًا المهام المختلفة لمحلل البيانات وكيف يتعامل مع جميع البيانات التي يتم إنشاؤها كل يوم والمتاحة في مكان عمله، من بيانات المعاملات في قاعدة بيانات تقليدية وبيانات القياس المختلفة والبيانات التي يتم جمعها من وسائل التواصل الاجتماعي وكيف يستخرج منها المعرفة التي تطور سير العمل وتحسنه للأفضل. هل لديك اهتمام بتحليل البيانات؟ إذا كانت الإجابة نعم فقد حان الوقت لتبدأ من الآن رحلتك في احتراف هذا التخصص الواعد الذي يزدهر الطلب عليه بشكل كبير في سوق العمل.
    1 نقطة
  12. يمكن أن تكون أدوات تطوير الويب من طرف العميل غير مفهومة بالنسبة لكثير من المطورين، لذلك سنوضّح من خلال سلسلة من المقالات الغرض من بعض أدوات تطوير الويب الأكثر شيوعًا من طرف العميل، وسنشرح أيضًا الأدوات التي يمكنك ربطها مع بعضها بعضًا، وكيفية تثبيتها باستخدام مدير الحزم، والتحكم فيها باستخدام سطر الأوامر، وسنقّدّم مثالًا كاملًا عن سلسلة أدوات يوضح كيفية زيادة الإنتاجية، ولكن في البداية وقبل محاولة استخدام هذه الأدوات يجب أن تتعلم أساسيات لغات HTML وCSS وجافاسكربت JavaScript. وفّرنا من خلال موسوعة حسوب مرجعًا لكل من لغات HTML وCSS وJavaScript يمكنك البدء منه. سنوضح في هذه السلسلة من المقالات المواضيع التالية لفهم أدوات تطوير الويب من طرف العميل: نظرة عامة على أدوات تطوير الويب من طرف العميل: نقدّم في هذا المقال نظرة عامة على أدوات الويب الحديثة، وأنواع الأدوات المتاحة وأين ستصادفها في دورة حياة تطوير تطبيقات الويب، وكيفية العثور على المساعدة باستخدام هذه الأدوات. دورة مكثفة لفهم سطر الأوامر: سيُطلب منك بلا شك تشغيل بعض الأوامر في الطرفية Terminal أو في سطر الأوامر خلال عملية التطوير، حيث يقدم هذا المقال مقدمة إلى الطرفية والأوامر الأساسية التي ستحتاج إلى إدخالها، وكيفية ربط الأوامر مع بعضها بعضًا، وكيفية إضافة أدوات واجهة سطر الأوامر Command Line Interface -أو CLI اختصارًا. أساسيات إدارة الحزم: سنلقي نظرة على مدراء الحزم بشيء من التفصيل لفهم كيفية استخدامها في مشاريعك لتثبيت اعتماديات Dependencies أدوات المشروع وتحديثها وغير ذلك. سلسلة أدوات كاملة: سنعمل في المقالين الأخيرين من السلسلة على ترسيخ معرفتك بالأدوات من خلال إرشادك خلال عملية بناء نموذج لسلسلة أدوات عن طريق إعداد بيئة تطوير ووضع أدوات التحويل في مكانها لنشر تطبيقك فعليًا على Netlify. كما سنقدم دراسة حالة مع إعداد بيئة التطوير الخاصة بنا وإعداد أدوات تحويل شيفرتنا. نشر التطبيق: سنأخذ في المقال الأخير من هذه السلسلة مثالًا عن سلسلة الأدوات التي أنشأناها في المقال السابق ونضيفها لنتمكن من نشر التطبيق، إذ سنرفع الشيفرة البرمجية للمشروع على موقع مشاركة الشيفرات جيت هب GitHub، وننشرها باستخدام نيتليفاي Netlify، وسنوضّح كيفية إضافة اختبار بسيط لهذه العملية. لنبدأ بمقالنا الأول من هذه السلسلة من خلال إلقاء نظرة سريعة على أدوات تطوير الويب من طرف العميل. المتطلبات الأساسية: الإلمام بمفاهيم لغات HTML و CSS وجافاسكربت الأساسية. الهدف: فهم أنواع الأدوات من طرف العميل وكيفية العثور عليها والحصول على المساعدة بشأنها. استخدام الأدوات الحديثة أصبحت كتابة برمجيات الويب أكثر تعقيدًا بمرور الوقت، وبالرغم من ذلك لا يزال كتابة برمجيات الويب يدويًا بلغة HTML و CSS وجافاسكربت أمرًا ممكنًا إلا أنه يوجد الآن مجموعة كبيرة من الأدوات التي يمكن للمطورين استخدامها لتسريع عملية إنشاء موقع ويب أو تطبيق. توجد بعض الأدوات المستقرة التي أصبحت أسماء مألوفة وشائعة في مجتمع تطوير الويب، بالإضافة إلى الأدوات الجديدة التي نراها تصدر كل يوم لحل مشكلات معينة، فيمكن أن تكتب برنامجًا للمساعدة في عملية التطوير الخاصة بك ولحل مشكلة معينة لا يمكن أن تحلها الأدوات الحالية. يمكنك استخدام عدد هائل من الأدوات وتضمينها في مشروع واحد، كما يمكنك استخدام أداة واحدة مثل Webpack وإعداد ملف تكوينها من مئات الأسطر، وغالبًا ما ينظر المبرمجين المبتدئين لهذه الشيفرة وكأنها تعويذات تؤدي المهمة بطريقة سحرية ولن يفهمها إلا المهندسون الخبراء. إلا أنه في الواقع غالبية الخبراء يواجهون مشاكلًا في استخدام الأدوات من وقت لآخر، إذ يمكن إضاعة ساعات في محاولة تشغيل مسار أدوات قبل لمس سطر واحد من شيفرة التطبيق. لذلك لا داعي للقلق، فأنت لست وحدك. سنزودك من خلال هذا المقال بنقطة بداية مفيدة لفهم أساسيات استخدام أدوات الويب، إذ يُفضَّل أن تبدأ على نطاق صغير، ثم تشق طريقك تدريجيًا إلى الاستخدامات أكثر تقدمًا. نظام أدوات المطورين الحديث يعدّ النظام البيئي Ecosystem الحديث لأدوات المطورين في يومنا الحالي ضخم نسبيًا، لذا يجب من الأفضل تكوين فكرة عامة عن المشاكل الرئيسية التي تحلها هذه الأدوات. إذا انتقلت إلى محرك البحث المفضل لديك وبحثت عن "أدوات مطور الواجهة الأمامية"، فستصل لمجموعة كبيرة من النتائج تتراوح من محرّرات النصوص والمتصفحات وحتى نوع الأقلام التي يمكنك استخدامها لتدوين الملاحظات. وبالرغم من أن اختيارك لمحرّر الشيفرة هو بالتأكيد جزء من خيارات الأدوات، ولكن في هذه السلسلة من المقالات سنتجاوز ذلك من خلال التركيز على أدوات المطور التي تساعدك على إنتاج شيفرة ويب ذات كفاءة عالية. يمكنك تصنيف الأدوات من طرف العميل ضمن الفئات الثلاث التالية: شبكة الأمان Safety Net: أدوات مفيدة أثناء تطوير شيفرتك. التحويل Transformation: الأدوات التي تحول الشيفرة بطريقة ما مثل تحويل لغة وسيطة إلى لغة جافاسكربت التي يمكن أن يفهمها المتصفح. أدوات ما بعد التطوير Post-development: الأدوات المفيدة بعد كتابة شيفرتك مثل أدوات الاختبار والنشر. لنلقِ نظرة على كل واحدة من هذه الفئات بمزيد من التفصيل. شبكة الأمان هي الأدوات التي تحسّن شيفرتك البرمجية التي تكتبها، ويجب أن تكون هذه الأدوات خاصةً ببيئة التطوير الخاصة بك، بالرغم من ذلك من غير المألوف أن يكون لدى الشركات سياسة أو إعدادات جاهزة للتثبيت لكي تضمن أن يستخدم جميع مطوري هذه الشركات العمليات نفسها. تتضمن هذه الأدوات أيّ شيء يسهّل عملية التطوير فيما يتعلق بإنشاء شيفرة مستقرة وموثوقة. كما يجب أن تساعدك أدوات شبكة الأمان في منع حدوث الأخطاء أو تصحيحها تلقائيًا دون الحاجة إلى إنشاء شيفرة من نقطة الصفر في كل مرة. سنوضّح فيما يلي بعض أنواع أدوات شبكة الأمان الشائعة التي يستخدمها المطورون. منقحات الصياغة Linters منقحات الصياغة هي أدوات تتحقق من شيفرتك وتخبرك بوجود أخطاء وبأنواعها وسطور الشيفرة التي توجد فيها. يمكن ضبط منقحات الصياغة للإبلاغ عن الأخطاء، وللإبلاغ عن أيّ انتهاكات لدليل النمط المحدَّد الذي يستخدمه فريقك مثل الشيفرة التي تستخدم عددًا خاطئًا من المسافات البادئة، أو استخدام صياغة قالب Template Literals بدلًا من صياغة سلسلة نصية عادية String Literals. يعدّ Eslint منقّح أخطاء معياري خاص بلغة جافاسكربت ويمكن ضبط هذه الأداة لاكتشاف أخطاء الصياغة المحتملة وتشجيعك لاستخدام أفضل الممارسات ضمن شيفرتك البرمجية. شاركت بعض الشركات والمشاريع إعدادات Eslint الخاصة بها، ويمكنك العثور على أدوات اكتشاف أخطاء للغات أخرى مثل Csslint. كما يمكنك استخدام Webhint وهو منقح أخطاء مفتوح المصدر يمكن ضبطه للويب، ويعرض أفضل الممارسات لاستخدامها بما في ذلك أساليب الوصول والأداء والتوافق مع المتصفحات باستخدام بيانات توافق متصفح MDN والأمان واختبار تطبيقات الويب ذات الصفحة الواحدة PWA وغير ذلك. كما يتوفر كأداة سطر أوامر Node.js وكامتداد VS Code. التحكم بالشيفرة البرمجية يُعرَف أيضًا باسم أنظمة التحكم بالإصدارات Version Control Systems أو VCS اختصارًا، ويُعَد التحكم بالشيفرة البرمجية ضروريًا لدعم العمل الفردي أو ضمن فريق. يتضمن نظام VCS إصدارًا محليًا من الشيفرة التي تجري تغييرات عليها، ثم ترفع التغييرات إلى إصدار رئيسي من الشيفرة داخل مستودع بعيد مُخزَّن على خادم في مكان ما. هناك عادةً طريقة للتحكم في التعديلات التي تُطبَّق على النسخة الرئيسية من الشيفرة وتنسيقها ومتى تطبَّق، وبالتالي لا يكتب فريق المطورين فوق عمل بعضهم بعضًا. يعد نظام جيت هاب Git من أشهر نظم التحكم بالشيفرة البرمجية الذي يستخدمه معظم المطورين حاليًا، إذ يمكن الوصول إليه عبر سطر الأوامر أو عبر واجهات سهلة الاستخدام. كما يمكنك رفع نسخة من المشروع إلى الخادم الخاص بك باستخدام شيفرتك في مستودع جيت، أو يمكنك استخدام موقع ويب مستضاف للتحكم بالشيفرة المصدرية مثل جيت هب GitHub أو جيت لاب GitLab أو بيت باكيت BitBucket، ولكن سنستخدم GitHub في مثالنا. مُنسِّقات الشيفرة Code Formatters ترتبط مُنسِّقات الشيفرة إلى حد ما بمنقّحات الصياغة، باستثناء أنه بدلًا من الإشارة إلى الأخطاء في شيفرتك، فإنها عادةً ما تميل إلى التأكد من تنسيق شيفرتك الصحيح وفقًا لقواعد النمط الخاصة بك، وتعمل تلقائيًا على إصلاح الأخطاء التي تعثر عليها. أحد الأمثلة الشائعة لمنسقات الشيفرة البرمجية هو Prettier، والذي سنستخدمه لاحقًا في مثالنا. الحزم Bundlers أو Packagers هي الأدوات التي تجعل شيفرتك جاهزةً لعملية الإنتاج عن طريق تقنية هز الشجرة Tree-Shaking مثلًا للتأكّد من إدراج أجزاء مكتبات الشيفرة التي تستخدمها فعليًا فقط في شيفرة الإنتاج النهائي، أو التصغير Minifying لإزالة كل مسافة فارغة في شيفرة الإنتاج، مما يصغّرها قدر الإمكان قبل رفعها إلى الخادم. تعد أداة Parcel من الأدوات الذكية التي يمكنها تطبيق المهام المذكورة السابقة، كما أنها تساعد أيضًا في حزم الملفات أو الملحقات assets مثل HTML وCSS وملفات الصور ضمن حزم ملائمة يمكنك نشرها لاحقًا، وتضيف اعتماديات تلقائيًا كلما حاولت استخدامها. كما يمكن لهذه الأداة التعامل مع بعض مهام تحويل الشيفرة نيابة عنك. يذكر أن أداة ويب باك Webpack هي أشهر أداة حزم تطبّق مهامًا مماثلة. التحويل Transformation تتيح هذه المرحلة من دورة حياة تطبيق الويب كتابة شيفرة برمجية إما في شيفرة مستقبلية مثل تحويل الشيفرة البرمجية لأحدث ميزات لغة CSS أو جافاسكربت التي يمكن ألّا تدعمها بعض المتصفحات حتى الآن، أو إنشاء شيفرة برمجية مكافئة لشيفرة برمجية مكتوبة بلغة معينة مثل لغة TypeScript، لتتوافق الشيفرة التي أنشأتها الأداة المطلوبة مع المتصفح لاستخدامها في عملية الإنتاج. يُنظَر إلى تطوير الويب على أنه مؤلَّف من ثلاث لغات هي HTML وCSS وجافاسكربت، وهناك أدوات تحويل لجميع هذه اللغات. يقدّم التحويل فائدتين رئيسيتين هما: القدرة على كتابة شيفرة برمجية باستخدام أحدث ميزات اللغة وتحويلها إلى شيفرة تعمل على جميع الأجهزة، فيمكن أن ترغب مثلًا في كتابة شيفرة بلغة جافاسكربت باستخدام ميزات لغة جديدة متطورة، ولكن لا يزال لديك شيفرة الإنتاج النهائي التي تعمل على المتصفحات القديمة التي لا تدعم هذه الميزات. تشمل الأمثلة التالية: Babel: مصرّف جافاسكربت JavaScript الذي يسمح للمطورين بكتابة شيفرة باستخدام أحدث إصدارات جافاسكربت، والتي يأخذها Babel ويحوّلها إلى إصدار جافاسكربت قديم يمكن لمزيد من المتصفحات فهمه. كما يمكن للمطورين كتابة ونشر إضافات Babel. PostCSS: تطبّق هذه الأداة الشيء نفسه الذي يطبّقه Babel، ولكن مع ميزات CSS المتطورة. إذا لم تكن هناك طريقة مكافئة لتطبيق شيء ما باستخدام ميزات CSS القديمة، فسيثبّت PostCSS تعويض نقص دعم المتصفحات Polyfill بلغة جافاسكربت لمحاكاة تأثير CSS الذي تريده. خيار كتابة الشيفرة بلغة مختلفة تمامًا وتحويلها إلى لغة متوافقة مع الويب مثل: Sass / SCSS: يتيح لك هذا الامتداد من لغة CSS استخدام المتغيرات والقواعد المتداخلة والمزج والدوال والعديد من الميزات الأخرى، إذ يُعَد بعضها متاحًا في لغة CSS الأصلية مثل المتغيرات، وبعضها ليس كذلك. TypeScript: هي مجموعة شاملة من لغة جافاسكربت التي تقدم مجموعة من الميزات الإضافية. يحوّل مصرّف TypeScript شيفرة TypeScript إلى جافاسكربت عند البناء بهدف الإنتاج. توفّر أطر العمل مثل React وEmber وVue الكثير من الوظائف مجانًا وتسمح لك باستخدامها عبر صيغة مخصَّصة مبنية على لغة جافاسكربت الصرفة Vanilla JavaScript. تعمل شيفرة جافاسكربت الخاصة بإطار العمل في الخلفية لتفسير هذه البنية المخصَّصة وتقديمها بوصفها تطبيق ويب نهائي. أدوات ما بعد التطوير Post Development تضمن أدوات ما بعد التطوير أن يصل برنامجك إلى الويب ويستمر في عمله، إذ تتضمن مرحلة ما بعد التطوير عمليات النشر وأطر عمل الاختبار وأدوات التدقيق وغير ذلك. تُعَد هذه المرحلة بأنها المرحلة التي تحتاج أقل قدر من التفاعل النشط بحيث تُشغَّل تلقائيًا بمجرد تهيئتها، وتخبرك بحدوث خطأ ما. أدوات الاختبار Testing Tools تأخذ هذه الأدوات شكل أداة تختبر تلقائيًا شيفرت البرمجية للتأكد من صحتها قبل المضي قدمًا مثل رفع تعديلات إلى مستودع جيب هب GitHub Repo. يمكن أن يشمل ذلك الكشف عن الأخطاء Linting، ويشمل إجراءات أكثر تعقيدًا مثل اختبارات الوحدة إذ تشغّل جزءًا من شيفرتك، مع التأكد من أنها تتصرف كما ينبغي. تشمل أطر عمل اختبارات الكتابة Jest وMocha وJasmine. تتضمن أنظمة التشغيل والاختبارات الآلية Travis CI وJenkins وCircle CI وغيرها. أدوات النشر Deployment Tools تسمح أنظمة النشر بنشر موقع الويب الخاص بك، وهي متاحة لكل من المواقع الثابتة والديناميكية، وتميل للعمل جنبًا إلى جنب مع أنظمة الاختبار، إذ ستنتظرك سلسلة الأدوات إلى أن ترفع التغييرات إلى المستودع البعيد، وتجري بعض الاختبارات لمعرفة ما إذا كانت التغييرات مناسبة، وإذا نجحت الاختبارات، فستنشر تطبيقك تلقائيًا على موقع إنتاج. تعد Netlify واحدة من أكثر أدوات النشر شيوعًا في الوقت الحالي، ولكن هناك أدوات أخرى مثل Vercel وGithub Pages. أدوات ما بعد التطوير الأخرى هناك عدد من أنواع الأدوات الأخرى المتاحة للاستخدام في مرحلة ما بعد التطوير، بما في ذلك Code Climate لجمع مقاييس جودة الشيفرة، وامتداد متصفح Webhint لإجراء تحليل وقت التشغيل للتوافق مع المتصفحات وعمليات التحقق الأخرى، وGithub bots لتوفير المزيد من ميزات GitHub القوية، وUpdown لتوفير مراقبة وقت تشغيل التطبيق وغير ذلك الكثير. أنواع الأدوات تُطبَّق أنواع الأدوات المختلفة في دورة حياة التطوير وفق ترتيب معين، ولكن كن مطمئنًا أنك لست مضطرًا إلى أن يكون لديك كل هذه الأدوات لإصدار موقع ويب، فلن لا تحتاج لأيٍّ منها. لكن سيؤدي تضمين بعض هذه الأدوات في عملياتك إلى تحسين تجربة التطوير، ويُحتمَل أن يؤدي إلى تحسين جودة شيفرتك الإجمالية. يستغرق استقرار أدوات المطور الجديدة بعض الوقت حسب تعقيدها. تشتهر إحدى أشهر الأدوات وهي Webpack بكونها معقدة للغاية للتعامل معها، ولكن كان هناك ضغط كبير لتبسيط الاستخدام في أحدث إصدار رئيسي، لذا قُلٍّل الإعداد المطلوب إلى الحد الأدنى. ليس هناك حل سحري يضمن النجاح باستخدام الأدوات، ولكن ستجد تدفقات عمل تناسبك أو تناسب فريقك ومشاريعك مع زيادة خبرتك، ويجب أن تكون سلسلة الأدوات شيئًا يمكنك نسيانه وأن تركّز على العمل فقط، بمجرد تسوية جميع مكامن الخلل في العملية. كيفية اختيار أداة معينة والحصول عليها تميل معظم الأدوات إلى كتابتها وإصدارها بصورة منفصلة، لذلك لا تتوفر أبدًا في المكان أو التنسيق نفسه، على الرغم من وجود مساعدة شبه مؤكدة، فيمكن أن يكون العثور على مساعدة في استخدام أداة أو حتى اختيار الأداة التي تريد استخدامها أمرًا صعبًا. المعرفة حول أفضل الأدوات لاستخدامها هي معرفة مجتمعية إلى حد ما، مما يعني أنه إن لم تكن بالفعل في مجتمع الويب، فستكون معرفة الأدوات التي تريدها بالضبط أمرًا صعبًا، وهذا هو أحد الأسباب التي دفعتنا إلى كتابة هذه السلسلة من المقالات، ونأمل أن نقدم تلك الخطوة الأولى التي يصعب إيجادها بطريقة أخرى. ستحتاج على الأرجح إلى مجموعة الأشياء التالية: نجح المدرسون أو الموجهون أو الزملاء الطلاب ذوو الخبرة أو الزملاء الذين لديهم بعض الخبرة في حل هذه المشكلات من قبل، ويمكنهم تقديم المشورة. مكان محدد مفيد للبحث، إذ تكون عمليات البحث العامة على الويب عن أدوات مطور الواجهة الأمامية عديمة الفائدة إلا إن عرفتَ اسم الأداة التي تبحث عنها. إذا استخدمتَ مدير الحزم NPM لإدارة اعتمادياتك على سبيل المثال، فيُفضَّل الانتقال إلى صفحة npm الرئيسية والبحث عن نوع الأداة التي تبحث عنها. حاول مثلًا البحث عن "التاريخ date" إن أردتَ أداة تنسيق التاريخ، أو "المُنسِّق formatter" إذا كنت تبحث عن مُنسق شيفرة عام. انتبه إلى درجات الشعبية والجودة والصيانة، وآخر تحديث للحزمة. انقر على صفحات الأداة لمعرفة عدد تنزيلات الحزمة الشهرية، واحتوائها على توثيق جيد يمكنك استخدامه للتأكد من أنها تطبّق ما تريده، وبالتالي تُعَد مكتبة date-fns أداة تنسيق تاريخ جيدة لاستخدامها. إذا أردت البحث عن إضافة Plugin لدمج وظائف الأدوات في محرّر الشيفرة، فألقِ نظرة على صفحة الإضافات / الامتدادات لمحرر الشيفرة، وراجع حزم Atom وامتدادات VSCode على سبيل المثال. ألقِ نظرة على الامتدادات المميزة في الصفحة الأولى، وحاول مرة أخرى البحث عن نوع الامتداد الذي تريده (أو اسم الأداة مثل البحث عن "eslint" في صفحة امتدادات VSCode). إذا حصلتَ على نتائج، فألقِ نظرة على معلومات عدد النجوم أو التنزيلات التي يحتويها الامتداد، إذ يُعَد ذلك مؤشرًا على جودته. المنتديات المتعلقة بالتنمية لطرح أسئلة حول الأدوات التي يجب استخدامها مثل قسم الأسئلة والأجوبة البرمجية في أكاديمية حسوب. إذا اخترت أداة لاستخدامها، فيجب أن يكون طريقة فهم الأداة هو الصفحة الرئيسية لمشروع الأداة والذي يكون غالبًا موقع ويب كامل أو يكون مستندًا تمهيديًا واحدًا في مستودع الشيفرة. يمكن أن ترغب في العثور على بعض البرامج التعليمية المخصصة لبدء استخدام أنواع معينة من الأدوات، لذا تعد المقالات البرمجية ومقالات DevOps في أكاديمية حسوب أماكن الانطلاق الرائعة للبحث. يُحتمَل أن تمر عبر العديد من الأدوات المختلفة أثناء البحث عن الأدوات المناسبة لك، وأن تجربها لمعرفة ما إذا كانت منطقية ومدعومة جيدًا وتطبّق ما تريده منها. يُعَد كل ذلك مناسبًا للتعلم، وسيصبح الطريق أسلس كلما اكتسبت مزيدًا من الخبرة. الخلاصة قدّمنا من خلال هذا المقال مقدمة بسيطة عن أدوات الويب من طرف العميل، وسنقدّم في المقال القادم دورة مكثفة عن سطر الأوامر، إذ تُستدعَى كثير من الأدوات منه، وسنلقي نظرة على ما يمكن أن يفعله سطر الأوامر ثم نحاول تثبيت الأداة الأولى ونستخدمها. هذا المقال جزء من سلسلة مقالات بعنوان تعلم تطوير الويب والتي تشرح كامل عملية تطوير الويب من واجهات أمامية وخلفية بالكامل. ترجمة -وبتصرُّف- للمقالين Understanding client-side web development tools وClient-side tooling overview. اقرأ أيضًا مدخل إلى أدوات التطوير في متصفح الويب DevTools كيف تستخدم أدوات المطوِّر في المتصفحات الحديثة الفرق بين مصمم الويب ومطور الويب وكيفية معرفة الأنسب بينهما الأدوات المستخدمة في بناء مواقع ويب
    1 نقطة
  13. يمكنك تنزيل معظم البرامج التي تحتاجها لتطوير صفحات ومواقع الويب مجانًا وسنزوّدك بعدة روابط خلال هذا المقال. عمومًا ستحتاج إلى أدوات التطوير لكي: تنشئ أو تحرر صفحة ويب. رفع الملفات إلى خادم ويب. استعراض موقع ويب. تحتوي معظم أنظمة التشغيل على محرر نصي ومتصفح ويب يمكن استخدامهما لعرض مواقع الويب. وبالتالي لن تحتاج سوى برامج لنقل الملفات إلى خادم ويب. إذًا، سنتعلم في هذا المقال عن المكونات البرمجية التي تحتاجها إن أردت تحرير أو رفع أو عرض موقع ويب والتي تساعدك في عملك أثناء تطوير مواقع الويب. ننصحك قبل الشروع في قراءة المقال أن تطلع على مقال الفرق بين صفحات الويب ومواقع الويب وخوادم الويب ومحركات البحث. إنشاء وتحرير صفحات الويب تحتاج إلى محرر نصي لتتمكن من تحرير أو إنشاء صفحات الويب، تساعدك محررات النصوص على تعديل الملفات النصية غير المنسّقة إذ تسمح لك بعض أنواع محررات الملفات مثل المحررات النصية الغنية Rich Text Format واختصارًا RTF، بإضافة تنسيقات إلى الخطوط المستخدمة كتثخين الخط أو وضع سطر تحت الكلمات، ولكن بالرغم من ذلك لا تعد محررات النصوص تلك ملائمة لكتابة صفحات الويب. لهذا عليك التفكير قليلًا قبل أن تقرر ما المحرر الذي ستستخدمه لأنك ستعمل عليه كثيرًا أثناء بناء موقع الويب. تأتي معظم أنظمة التشغيل المخصصة للحواسب المكتبية مع محرر نصوص بسيط وسهل الاستخدام لكنه يفتقر إلى بعض الميزات المفيدة عند كتابة شيفرات صفحات الويب. لكن إن أردت شيئًا أكثر أناقة، فستجد الكثير من الأدوات التي توفرها شركات خارجية. تأتي محررات النصوص التي تقدمها الشركات مع ميزات إضافية كتلوين العبارات القواعدية والإكمال التلقائي للشيفرة البرمجية وإخفاء أو إظهار مقاطع محددة، والبحث في الشيفرة. إليك قائمة مختصرة ببعض المحررات: table { width: 100%; } thead { vertical-align: middle; text-align: center; } td, th { border: 1px solid #dddddd; text-align: right; padding: 8px; text-align: inherit; } tr:nth-child(even) { background-color: #dddddd; } نظام التشغيل المحرر المدمج مع نظام التشغيل محررات يؤمنها طرف ثالث ويندوز Notepad Notepad++, Visual Studio Code, Web Storm, Brackets ShiftEdit, Sublime Text ماك أو إس TextEdit TextWrangler, Visual Studio Code, Brackets ShiftEdit, Sublime Text لينوكس Vi (All Unix) GEdit (Gnome) Kate (KDE) LeafPad (Xfce) Emacs, Vim, Visual Studio Code, Brackets ShiftEdit, Sublime Text كروم أو إس ShiftEdit إليك لقطة شاشة لأحد محررات النصوص المتقدمة: إليك أيضًا لقطة شاشة لمحرر نصوص على الويب: رفع الملفات إلى ويب عليك أن ترفع صفحات موقعك إلى خادم ويب عندما يكتمل بناؤه ويصبح جاهزًا لاتاحته للناس. يمكنك شراء مساحة تخزين من أي مزود خدمة تختاره والذي سيرسل لك بدوره -عند إكمال عملية الشراء- بريدًا إلكترونيًا يضم معلومات الوصول إلى مساحة التخزين الخاصة بك على شكل عنوان SFTP URL (عنوان يستخدم برتوكول FTP الآمن)، بالإضافة إلى اسم المستخدم وكلمة المرور وغيرها من المعلومات اللازمة للاتصال بخادم الويب. تذكر أنّ بروتوكول SFTP أصبح قديم الطراز وبدأت أنظمة رفع ملفات جديدة باكتساب شعبية مثل RSync وGit/GitHub. تُعد خطوة رفع الملفات إلى خادم الويب خطوة مهمة جدًا من خطوات بناء الموقع، إليك قائمة مختصرة لبعض البرامج المجانية التي تعمل من ناحية العميل لرفع الملفات: نظام التشغيل برمجيات FTP ويندوز WinSCP Moba Xterm (FileZilla (All OS لينوكس (Nautilus/Files (Gnome) Dolphin (KDE ماك أو إس Cyberduck كروم أو إس (ShiftEdit (All OS تصفح مواقع ويب لا بد من وجود متصفح ويب لاستعراض المواقع وستجد الكثير من الخيارات التي تلبي احتياجاتك. لكن عندما تطور موقع ويب لا بدّ من اختباره على أحد المتصفحات الرئيسية التالية لتتأكد أن موقعك سيعمل عند معظم المستخدمين: موزيلا فايرفوكس. جوجل كروم. مايكروسوفت انترنت أكسبلورر أو مايكروسوفت إيدج. آبل سفاري. فإن كنت تستهدف مجموعة محددة (منصة تقنية أو بلد محدد)، لا بدّ أن تختبر موقعك على متصفحات أخرى مثل أوبرا وKonqueror أو UC Browser. تتعقد عملية اختبار المواقع لأن بعض المتصفحات لن تعمل إلا على أنظمة تشغيل محددة. فلن يعمل آبل سفاري سوى على أنظمة تشغيل آبل أي أو إس وماك أو إس ولن يعمل إنترنت إكسبلورر سوى على ويندوز. في حالات كهذه من الأفضل استخدام خدمات مثل Browsershots أو Browserstack. إذ سيعرضُ لك موقع Browsershots لقطات شاشة لموقعك كما سيبدو على عدة متصفحات، بينما يمنحك Browserstack إمكانية الوصول الكاملة عن بعد إلى محاكيات افتراضية Virtual Machines تساعدك على تجربة موقعك على أكثر البيئات شيوعًا. يمكنك أيضًا إعداد محاكي افتراضي خاص بك، لكن الأمر سيتطلب الأمر خبرات إضافية (إن قررت المضي بهذا الخيار، تزوّدك مايكروسوفت ببعض الأدوات التي تساعدك بما فيها محاكي افتراضي جاهز للاستخدام). اختبر موقعك بشتى الوسائل على أجهزة حقيقية وخاصة أجهزة الهواتف المحمولة الحقيقية، فالمحاكيات هي تكنولوجيا جديدة لا زالت قيد التطوير لذلك فهي أقل وثوقية من محاكيات أجهزة سطح المكتب. وطالما أن أجهزة الهاتف المحمولة غالية الثمن، ننصحك أن تلق نظرة على Open Device Lab initiative. يمكنك أيضًا مشاركة الأجهزة إن أردت اختبار موقعك على منصات عدة دون أن تنفق الكثير من المال. ترجمة -وبتصرف- للمقال What software do I need to build a website. اقرأ أيضًا ما هو عنوان URL في الويب؟ ما التكلفة المادية الكاملة لبناء موقع ويب؟ ما هي محررات النصوص المستعملة في تطوير مواقع الويب؟ ما هي أدوات مطوري الويب المدمجة في المتصفحات؟
    1 نقطة
  14. المصفوفة (array) هي بنية بيانات تخزّن عدة قيم في قيمة واحدة، وهي خريطة مرتبة تربط بين القيم والمفاتيح. تُنشَأ مصفوفة مباشرة عبر الأقواس المعقوفة [] أو عبر الدالة Array()‎ التي تأخذ المعاملات التالية: المعامل التفاصيل key (المفتاح) المفتاح هو المعرّف الفريد وفهرس المصفوفة. من الممكن أن يكون سلسلة نصية أو عدد صحيح مثل ‎'foo'‎، '5'، 10، 'a2b'‎ value (القيمة) ‏يوجد لكل مفتاح قيمة مقابلة (وإلا تكون null ويمكن أن تكون القيمة من أي نوع‎، وستظهر رسالة خطأ إذا حاولت الوصول إليه)‏ table { width: 100%; } thead { vertical-align: middle; text-align: center; } td, th { border: 1px solid #dddddd; text-align: right; padding: 8px; text-align: inherit; } tr:nth-child(even) { background-color: #dddddd; } تهيئة مصفوفة يمكن أن نُهيأ مصفوفة فارغة عبر الدالة Array()‎ أو الأقواس [] مباشرةً: // مصفوفة فارغة $foo = array(); // PHP 5.4 يمكن استخدام هذا التدوين المختزل بدءًا من الإصدار $foo = []; ويمكن أن نُهيأ مصفوفة ونعطيها قيم في نفس الوقت: // إنشاء مصفوفة بسيطة من 3 سلاسل نصية $fruit = array('apples', 'pears', 'oranges'); // PHP 5.4 يمكن استخدام هذا التدوين المختزل بدءًا من الإصدار $fruit = ['apples', 'pears', 'oranges']; ويمكن أيضًا أن نهيأ مصفوفة مع فهارس مخصصة (تسمى مصفوفة ترابطية associative array): // مصفوفة ترابطية بسيطة $fruit = array( 'first' => 'apples', 'second' => 'pears', 'third' => 'oranges' ); // يمكن أن نضبط القيمة والمفتاح كالتالي $fruit['first'] = 'apples'; // PHP 5.4 يمكن استخدام هذا التدوين المختزل بدءًا من الإصدار $fruit = [ 'first' => 'apples', 'second' => 'pears', 'third' => 'oranges' ]; ستنشئ PHP المتغير تلقائيًا إذا لم يكن قد اُستخدم سابقًا، وهذا يجعل الشيفرة ملائمة لكنها صعبة القراءة: $foo[] = 1; // Array( [0] => 1 ) $bar[][] = 2; // Array( [0] => Array( [0] => 2 ) ) تتابع PHP الفهرسة من حيث توقفت وتستخدم سلاسل نصية عددية كأعداد صحيحة للفهرسة: $foo = [2 => 'apple', 'melon']; // Array( [2] => apple, [3] => melon ) $foo = ['2' => 'apple', 'melon']; // نفس المصفوفة السابقة $foo = [2 => 'apple', 'this is index 3 temporarily', '3' => 'melon']; // نفس المصفوفة السابقة، سيقوم العنصر الأخير بالكتابة فوق العنصر الثاني يمكنك استخدام الصنف splfixedarray لتهيئة المصفوفة بحجم ثابت: $array = new SplFixedArray(3); $array[0] = 1; $array[1] = 2; $array[2] = 3; $array[3] = 4; // RuntimeException // زيادة حجم المصفوفة إلى 10 $array->setSize(10); ملاحظة: المصفوفة المنشأة باستخدام الصف SplFixedArray لها مساحة ذاكرة منخفضة لمجموعات كبيرة من البيانات، ولكن يجب أن تكون المفاتيح أعدادًا صحيحة. لتهيئة مصفوفة بحجم ديناميكي وبعدة عناصر غير فارغة يمكنك استخدام حلقة كالتالي: $myArray = array(); $sizeOfMyArray = 5; $fill = 'placeholder'; for ($i = 0; $i < $sizeOfMyArray; $i++) { $myArray[] = $fill; } print_r($myArray); // Array ( [0] => placeholder [1] => placeholder [2] => placeholder [3] => placeholder [4] => placeholder ) يمكنك استخدام الدالة array_fill()‎ لإنشاء مصفوفة وإعطاء مفاتيحها نفس القيم. array array_fill ( int $start_index , int $num , mixed $value ) تنشأ التعليمة السابقة وتُرجع مصفوفة فيها العدد num من العناصر التي قيمتها value بدءًا من الفهرس start_index، وإذا كانت قيمة start_index سالبة فستبدأ المصفوفة بفهرس سالب ثم تبدأ قيم الفهارس التالية من الصفر. $a = array_fill(5, 6, 'banana'); // Array ( [5] => banana, [6] => banana, ..., [10] => banana) $b = array_fill(-2, 4, 'pear'); // Array ( [-2] => pear, [0] => pear, ..., [2] => pear) نتيجة: عندما تستخدم الدالة array_fill()‎ تكون أكثر محدودية فيما تودّ فعله أما الحلقة فهي أكثر مرونة وتتيح لك الكثير من الخيارات. إذا أردت ملء المصفوفة بمجال أرقام (من 0 إلى 4 مثلًا) يمكنك إما إضافة كل عنصر بشكلٍ مفرد أو استخدام الدالة range()‎: array range ( mixed $start , mixed $end [, number $step = 1 ] ) تنشأ هذه الدالة مصفوفة تحوي مجال من العناصر، وفيها المعاملان الأول والثاني إلزاميان إذ يحددان بداية ونهاية المجال أما المعامل الثالث فهو خياري ويحدد مقدار زيادة العناصر في المجال. مثال: إنشاء مجال من 0 إلى 4 بمقدار زيادة 1 ستكون نتيجته مصفوفة عناصرها: 0، 1، 2، 3، 4 أما إذا كان مقدار الزيادة 2 فستكون عناصر المصفوفة 0، 2، 4. $array = []; $array_with_range = range(1, 4); for ($i = 1; $i <= 4; $i++) { $array[] = $i; } print_r($array); // Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 ) print_r($array_with_range); // Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 ) تعمل الدالة range بشكلٍ صحيح مع الأعداد الصحيحة والعشرية والمنطقية (التي حُوّلت إلى أعداد صحيحة) والسلاسل النصية، ولكن يجب أخذ الحذر عند استخدام الأعداد العشرية كوسيط بسبب مشكلة دقة الفاصلة العائمة. التحقق من وجود مفتاح يمكنك استخدام الدالة array_key_exists()‎ أو isset()‎ أو ‎!empty()‎ للتحقق من وجود مفتاح: $map = [ 'foo' => 1, 'bar' => null, 'foobar' => '', ]; array_key_exists('foo', $map); // true isset($map['foo']); // true !empty($map['foo']); // true array_key_exists('bar', $map); // true isset($map['bar']); // false !empty($map['bar']); // false لاحظ أن الدالة isset()‎ تعامل العنصر الذي قيمته null على أنّه غير موجود، وتعامل ‎!empty()‎ بالمثل أي عنصر قيمته false (استخدام موازنة ضعيفة مثل null، السلسلة الفارغة ' '، ‏0 تعاملها كلها على أنها false)، أي أن نتيجة isset($map['foobar'])‎ هي true أما نتيجة ‎!empty($map['foobar'])‎ هي false، يمكن أن يؤدي هذا إلى مشاكل (فمن الممكن أن تنسى مثلًا أنّ السلسلة النصية '0' تُعامَل على أنّها false) لذا فإنّ استخدام ‎!empty()‎ يمكن أن يكون غير مقبول. لاحظ أيضًا أنّ isset()‎ و‎!empty()‎ سيعملان ويعيدان false إذا كانت ‎$map غير معرفة أبدًا وهذا يجعلهم عرضة للخطأ نوعًا ما عند الاستخدام: // "long"و "lang" الفرق بين اسمي المتحولين هو في الكلمتين $my_array_with_a_long_name = ['foo' => true]; array_key_exists('foo', $my_array_with_a_lang_name); // يظهر تحذير isset($my_array_with_a_lang_name['foo']); // false يمكنك أيضًا التحقق في المصفوفات العادية: $ord = ['a', 'b']; // [0 => 'a', 1 => 'b'] المصفوفة السابقة تكافئ array_key_exists(0, $ord); // true array_key_exists(2, $ord); // false لاحظ أنّ أداء isset()‎ أفضل من array_key_exists()‎ لأنّ الأخيرة هي دالة والأولى هي بنية لغوية، ويمكنك أيضًا استخدام الدالة key_exists()‎ التي تعد كنية للدالة array_key_exists()‎. التحقق من نوع المصفوفة تُرجع الدالة is_array()‎ القيمة true إذا كان المتغير مصفوفة. $integer = 1337; $array = [1337, 42]; is_array($integer); // false is_array($array); // true يمكنك كتابة تلميح في الدالة أنّ نوع المعامل المفروض هو مصفوفة أي أنّ تمرير أي نوع آخر سيسبب خطأً فادحًا. function foo (array $array) { /* هو مصفوفة $array نوع المتغير */ } يمكنك أيضًا استخدام الدالة gettype()‎. $integer = 1337; $array = [1337, 42]; gettype($integer) === 'array'; // false gettype($array) === 'array'; // true إنشاء مصفوفة من المتغيرات $username = 'Hadibut'; $email = 'hadibut@example.org'; $variables = compact('username', 'email'); // ['username' => 'Hadibut', 'email' => 'hadibut@example.org'] هي $variables قيمة يُستخدم هذا التابع غالبًا في إطارات العمل لتمرير مصفوفة متغيرات بين مكونين. التحقق من وجود قيمة في مصفوفة تُرجع الدالة in_array()‎ القيمة true إذا كان العنصر موجودًا في المصفوفة. $fruits = ['banana', 'apple']; $foo = in_array('banana', $fruits); //true هي $foo قيمة $bar = in_array('orange', $fruits); //false هي $bar قيمة ويمكنك أن تستخدم الدالة array_search()‎ لتحصل على مفتاح عنصر ما من المصفوفة. $userdb = ['Sandra Shush', 'Stefanie Mcmohn', 'Michael']; $pos = array_search('Stefanie Mcmohn', $userdb); if ($pos !== false) { echo "Stefanie Mcmohn found at $pos"; } الإصدار PHP 5.x من 5.5 وما فوق يمكنك بدءًا من الإصدار PHP 5.5 وما بعده استخدام array_column()‎ بالتزامن مع array_search()‎ ويعدّ هذا مفيدًا بشكلٍ خاص للتحقق من وجود قيمة في المصفوفة الترابطية: $userdb = [ [ "uid" => '100', "name" => 'Sandra Shush', "url" => 'urlof100', ], [ "uid" => '5465', "name" => 'Stefanie Mcmohn', "pic_square" => 'urlof100', ], [ "uid" => '40489', "name" => 'Michael', "pic_square" => 'urlof40489', ] ]; $key = array_search(40489, array_column($userdb, 'uid')); واجهات ArrayAccess وIterator الميزة المفيدة الأخرى هي الوصول إلى تجميعات الكائن المخصص كمصفوفات في PHP، يوجد واجهتين في PHP بدءًا من الإصدار PHP 5.0.0 لدعم ذلك وهما: ArrayAccess وIterator يتيحان لك الوصول إلى الكائنات المخصصة على أنّها مصفوفات. ArrayAccess بفرض لدينا الصنف user يعبر عن مستخدم وجدول في قاعدة البيانات يخزن كل المستخدمين ونريد إنشاء الصنف UserCollection ليقوم بما يلي: يسمح لنا بمخاطبة مستخدم عن طريق معرف الاسم الفريد. أداء العمليات الأساسية (ليس كل عمليات CRUD - الإنشاء والقراءة والتحديث والحذف - إنما على الأقل الإنشاء والاستعادة والحذف) على مجموعة المستخدمين لدينا. انتبه أننا نستخدم الصياغة القصيرة لإنشاء مصفوفة [] والمتاحة بدءًا من الإصدار 5.4: class UserCollection implements ArrayAccess { protected $_conn; protected $_requiredParams = ['username','password','email']; public function __construct() { $config = new Configuration(); $connectionParams = [ // معلومات الاتصال بقاعدة البيانات ]; $this->_conn = DriverManager::getConnection($connectionParams, $config); } protected function _getByUsername($username) { $ret = $this->_conn->executeQuery('SELECT * FROM `User` WHERE `username` IN (?)', [$username])->fetch(); return $ret; } // ArrayAccess بدء التوابع المطلوبة من public function offsetExists($offset) { return (bool) $this->_getByUsername($offset); } public function offsetGet($offset) { return $this->_getByUsername($offset); } public function offsetSet($offset, $value) { if (!is_array($value)) { throw new \Exception('value must be an Array'); } $passed = array_intersect(array_values($this->_requiredParams), array_keys($value)); if (count($passed) < count($this->_requiredParams)) { throw new \Exception('value must contain at least the following params: ' .implode(',', $this->_requiredParams)); } $this->_conn->insert('User', $value); } public function offsetUnset($offset) { if (!is_string($offset)) { throw new \Exception('value must be the username to delete'); } if (!$this->offsetGet($offset)) { throw new \Exception('user not found'); } $this->_conn->delete('User', ['username' => $offset]); } // ArrayAccess بدء التوابع المطلوبة من } بعد ذلك يمكننا كتابة: $users = new UserCollection(); var_dump(empty($users['testuser']),isset($users['testuser'])); $users['testuser'] = ['username' => 'testuser', 'password' => 'testpassword', 'email' => 'test@test.com']; var_dump(empty($users['testuser']), isset($users['testuser']), $users['testuser']); unset($users['testuser']); var_dump(empty($users['testuser']), isset($users['testuser'])); بفرض أنه لا يوجد لدينا المستخدم testuser قبل تنفيذ الشيفرة فسيكون لدينا الخرج التالي: bool(true) bool(false) bool(false) bool(true) array(17) { ["username"]=> string(8) "testuser" ["password"]=> string(12) "testpassword" ["email"]=> string(13) "test@test.com" } bool(true) bool(false) ملاحظة: لا تُستدعى الدالة offsetExists عندما تريد التحقق من وجود مفتاح مع دالة array_key_exists، لذا فإنّ الشيفرة التالية سيكون خرجها false مرتين: var_dump(array_key_exists('testuser', $users)); $users['testuser'] = ['username' => 'testuser', 'password' => 'testpassword', 'email' => 'test@test.com']; var_dump(array_key_exists('testuser', $users)); Iterator سنوسع الصنف في الأعلى بإضافة عدة دوال من الواجهة Iterator لنستطيع استخدام التكرار مع foreach وwhile. نحتاج أولًا إلى خاصيّة تحتوي الفهرس الحالي للمكرِّر، سنسميها ‎$_position ونضيفها إلى خاصيّات الصنف: // Iterator موقع المكرِّر الحالي مطلوب من توابع الواجهة protected $_position = 1; ثم نضيف الواجهة Iterator إلى قائمة الواجهات التي سينفذها صنفنا: class UserCollection implements ArrayAccess, Iterator { ثم نضيف المطلوب من دوال الواجهة Iterator: // Iterator بدء التوابع المطلوبة من الواجهة public function current () { return $this->_getById($this->_position); } public function key () { return $this->_position; } public function next () { $this->_position++; } public function rewind () { $this->_position = 1; } public function valid () { return null !== $this->_getById($this->_position); } // Iterator نهاية التوابع المطلوبة من الواجهة أصبح لدينا مصدر كامل لتنفيذ الصنف لكِلا الواجهتين، لاحظ أنّ هذا المثال ليس مثاليًا لأنّ المعرفات في قاعدة البيانات قد لا تكون تسلسلية لكن كتبناه لإعطائك فكرةً أساسيةً وهي أنّه بإمكانك مخاطبة تجميعات الكائنات بأي طريقة ممكنة عن طريق تنفيذ الواجهتين ArrayAccess وIterator. class UserCollection implements ArrayAccess, Iterator { // Iterator موقع المكرِّر الحالي المطلوب من توابع الواجهة protected $_position = 1; // <إضافة التوابع القديمة من الشيفرة السابقة هنا> // Iterator بدء التوابع المطلوبة من الواجهة public function current () { return $this->_getById($this->_position); } public function key () { return $this->_position; } public function next () { $this->_position++; } public function rewind () { $this->_position = 1; } public function valid () { return null !== $this->_getById($this->_position); } // Iterator نهاية التوابع المطلوبة من الواجهة } ولكتابة حلقة تمر على كل الكائنات من نوع user باستخدام foreach: foreach ($users as $user) { var_dump($user['id']); } سينتج عن الشيفرة السابقة الخرج التالي: string(2) "1" string(2) "2" string(2) "3" string(2) "4" ... تكرار عدة مصفوفات معًا قد نحتاج أحيانًا إلى تكرار مصفوفتين لهما نفس الطول معًا مثال: $people = ['Tim', 'Tony', 'Turanga']; $foods = ['chicken', 'beef', 'slurm']; أبسط طريقة لتنفيذ ذلك هي استخدام الدالة array_map: array_map(function($person, $food) { return "$person likes $food\n"; }, $people, $foods); سينتج عن ذلك الخرج التالي: assert(count($people) === count($foods)); for ($i = 0; $i < count($people); $i++) { echo "$people[$i] likes $foods[$i]\n"; } إذا لم يكن للمصفوفتين مفاتيح تكرارية يمكننا استخدام array_values($array)[$i]‎ بدلًا من ‎$array[$i]‎، وإذا كان لهما نفس ترتيب المفاتيح يمكننا استخدام حلقة foreach مع مفتاح على إحداهما: foreach ($people as $index => $person) { $food = $foods[$index]; echo "$person likes $food\n"; } يمكن تكرار المصفوفات المستقلة فقط إذا كان لها نفس الطول ونفس اسم المفتاح، أي أنّه إذا لم يكن للمصفوفات مفاتيحًا فالمفاتيح مرقمة وهذا جيّد أو يمكنك تسمية المفاتيح ووضعهم في نفس الترتيب لكل مصفوفة، ويمكنك أيضًا استخدام الدالة array_combine. $combinedArray = array_combine($people, $foods); // $combinedArray = ['Tim' => 'chicken', 'Tony' => 'beef', 'Turanga' => 'slurm']; بعدها يمكنك كتابة حلقة تكرار كما في السابق: foreach ($combinedArray as $person => $meal) { echo "$person likes $meal\n"; } استخدام فهرس تزايدي تعمل هذه الطريقة على زيادة عدد صحيح من 0 وحتى أكبر فهرس في المصفوفة. $colors = ['red', 'yellow', 'blue', 'green']; for ($i = 0; $i < count($colors); $i++) { echo 'I am the color ' . $colors[$i] . '<br>'; } يمكنك أيضًا المرور على جميع عناصر المصفوفة بترتيب عكسي دون استخدام الدالة array_reverse التي قد تزيد الحِمل إذا كانت المصفوفة كبيرة. $colors = ['red', 'yellow', 'blue', 'green']; for ($i = count($colors) - 1; $i >= 0; $i--) { echo 'I am the color ' . $colors[$i] . '<br>'; } يمكنك تخطي أو إرجاع الفهرس بسهولة مستخدمًا هذه الطريقة. $array = ["alpha", "beta", "gamma", "delta", "epsilon"]; for ($i = 0; $i < count($array); $i++) { echo $array[$i], PHP_EOL; if ($array[$i] === "gamma") { $array[$i] = "zeta"; $i -= 2; } elseif ($array[$i] === "zeta") { $i++; } } الخرج: alpha beta gamma beta zeta epsilon لا يمكن أن نقوم بهذا بشكلٍ مباشر في المصفوفات التي لا تحوي فهارس تزايدية (بما في ذلك المصفوفات التي تكون فهارسها بترتيب عكسي مثل: ‎[1 => "foo", 0 => "bar"], ["foo" => "f", "bar" => "b"]‎)، لذا نستخدم الدوال array_values أو array_keys: $array = ["a" => "alpha", "b" => "beta", "c" => "gamma", "d" => "delta"]; $keys = array_keys($array); for ($i = 0; $i < count($array); $i++) { $key = $keys[$i]; $value = $array[$key]; echo "$value is $key\n"; } استخدام مؤشرات المصفوفة الداخلية تحوي كل نسخة مصفوفة مؤشرًا داخليًا، يمكن باستخدام هذا المؤشر استعادة عناصر مختلفة من المصفوفة عن طريق نفس الاستدعاء في مرات مختلفة. استخدام الدالة each يُرجع كل استدعاء للدالة مفتاح وقيمة عنصر المصفوفة الحالي ويزيد مؤشر المصفوفة الداخلي. $array = ["f" => "foo", "b" => "bar"]; while (list($key, $value) = each($array)) { echo "$value begins with $key"; } استخدام الدالة next $array = ["Alpha", "Beta", "Gamma", "Delta"]; while (($value = next($array)) !== false) { echo "$value\n"; } لاحظ أنّ هذا المثال يفترض أنّه لا يوجد عناصر في المصفوفة معرّفة بالقيمة المنطقية false، لمنع هذا الافتراض نستخدم الدالة key للتحقق من وصول المؤشر الداخلي إلى نهاية المصفوفة: $array = ["Alpha", "Beta", "Gamma", "Delta"]; while (key($array) !== null) { echo current($array) . PHP_EOL; next($array); } ويسهّل هذا أيضًا تكرار المصفوفة دون حلقة مباشرة: class ColorPicker { private $colors = ["#FF0064", "#0064FF", "#64FF00", "#FF6400", "#00FF64", "#6400FF"]; public function nextColor() : string { $result = next($colors); // إذا وصلت لنهاية المصفوفة if (key($colors) === null) { reset($colors); } return $result; } } استخدام foreach حلقة مباشرة foreach ($colors as $color) { echo "I am the color $color<br>"; } حلقة مع مفاتيح $foods = ['healthy' => 'Apples', 'bad' => 'Ice Cream']; foreach ($foods as $key => $food) { echo "Eating $food is $key"; } حلقة بالمرجعية إنّ تعديل قيمة (‎$color أو ‎$food) في الأمثلة السابقة بشكلٍ مباشر لا يغيّر قيمتها في المصفوفة إنّما يجب استخدام العامل & لتصبح القيمة هي مؤشر مرجعي للعنصر في المصفوفة. $years = [2001, 2002, 3, 4]; foreach ($years as &$year) { if ($year < 2000) $year += 2000; } الشيفرة السابقة مماثلة للشيفرة التالية: $years = [2001, 2002, 3, 4]; for($i = 0; $i < count($years); $i++) { $year = &$years[$i]; if($year < 2000) $year += 2000; } التزامن يمكن تعديل مصفوفات PHP أثناء التكرار بدون مشاكل تزامن، إذا كانت المصفوفة تُكرَّر بالمرجع فإنّ التكرارات اللاحقة ستتأثر بتغييرات المصفوفة وإلا فإنّها لن تتأثر (كما لو أنّك تكرر نسخة من المصفوفة نفسها)، وازن التكرار بالقيمة: $array = [0 => 1, 2 => 3, 4 => 5, 6 => 7]; foreach ($array as $key => $value) { if ($key === 0) { $array[6] = 17; unset($array[4]); } echo "$key => $value\n"; } الخرج: 0 => 1 2 => 3 4 => 5 6 => 7 أما إذا كانت المصفوفة تُكرَّر بالمرجع: $array = [0 => 1, 2 => 3, 4 => 5, 6 => 7]; foreach ($array as $key => &$value) { if ($key === 0) { $array[6] = 17; unset($array[4]); } echo "$key => $value\n"; } الخرج: 0 => 1 2 => 3 6 => 17 لن تُكرَّر مجموعة القيمة-المفتاح 4‎ => 5 وستتغير 6‎ => 7 إلى ‎6 => 17‎. استخدام المكرِّر ArrayObject يسمح لك الصنف arrayiterator بتعديل وإلغاء ضبط القيم أثناء تكرار المصفوفات والكائنات. مثال: $array = ['1' => 'apple', '2' => 'banana', '3' => 'cherry']; $arrayObject = new ArrayObject($array); $iterator = $arrayObject->getIterator(); for($iterator; $iterator->valid(); $iterator->next()) { echo $iterator->key() . ' => ' . $iterator->current() . "</br>"; } الخرج: 1 => apple 2 => banana 3 => cherry ترجمة -وبتصرف- للفصول [Arrays - Array iteration] من كتاب PHP Notes for Professionals book اقرأ أيضًا المقال التالي: التنفيذ على المصفوفات والتعامل معها في PHP المقال السابق: المراجع (references) في PHP
    1 نقطة
  15. تطبيق دالة على كل عنصر من عناصر المصفوفة نستخدم الدالة array_map()‎ لتطبيق دالة على جميع عناصر مصفوفة ما، وتُرجع لنا مصفوفة جديدة: $array = array(1,2,3,4,5); // يتم المرور على كل عنصر من عناصر المصفوفة ويُخزَّن في معامل الدالة $newArray = array_map(function($item) { return $item + 1; }, $array); // array(2,3,4,5,6) الآن $newArray قيمة يمكنك استخدام دالة ذات اسم بدلًا من استخدام دالة مجهولة الاسم، فنكتب الشيفرة السابقة كالتالي: function addOne($item) { return $item + 1; } $array = array(1, 2, 3, 4, 5); $newArray = array_map('addOne', $array); إذا كانت الدالة المسمّاة هي تابع صنف فيجب تضمين مرجع إلى كائن الصنف الذي يعود التابع له عند استدعاء الدالة: class Example { public function addOne($item) { return $item + 1; } public function doCalculation() { $array = array(1, 2, 3, 4, 5); $newArray = array_map(array($this, 'addOne'), $array); } } الطريقة الثانية لتطبيق دالة على عناصر المصفوفة هي استخدام الدالة array_walk()‎ والدالة array_walk_recursive()‎، يُمرَّر رد النداء (callback) إلى هاتين الدالتين ويأخذ مفتاح/فهرس وقيمة كل عنصر من عناصر المصفوفة، لا ترجع هذه الدوال دوالًا جديدة إنّما تُرجع قيمة منطقية تدل على نجاح تنفيذ الدالة، يمكننا مثلًا طباعة كل عنصر في المصفوفة بكتابة الشيفرة التالية: $array = array(1, 2, 3, 4, 5); array_walk($array, function($value, $key) { echo $value . ' '; }); // "1 2 3 4 5" يمكن تمرير قيمة معامل رد النداء بالمرجعية مما يسمح لك بتمرير القيمة مباشرةً في المصفوفة الأصلية: $array = array(1, 2, 3, 4, 5); array_walk($array, function(&$value, $key) { $value++; }); // array(2,3,4,5,6) الآن $array قيمة نستخدم الدالة array_walk_recursive()‎ مع المصفوفات المتداخلة (nested) للتعامل مع كل مصفوفة فرعية: $array = array(1, array(2, 3, array(4, 5), 6); array_walk_recursive($array, function($value, $key) { echo $value . ' '; }); // "1 2 3 4 5 6" لاحظ أنّ الدالتين array_walk()‎ وarray_walk_recursive()‎ يسمحان لك بتغيير قيمة عناصر المصفوفة وليس المفاتيح، كما أنّه يمكنك تمرير المفاتيح بالمرجع في رد النداء لكن هذا ليس له تأثير. تقسيم المصفوفة إلى أجزاء (chunks) تقسّم الدالة array_chunk()‎ المصفوفة إلى أجزاء صغيرة. بفرض لدينا الدالة أحادية البعد التالية: $input_array = array('a', 'b', 'c', 'd', 'e'); وطبّقنا الدالة array_chunk()‎ عليها: $output_array = array_chunk($input_array, 2); تقسّم الشيفرة السابقة المصفوفة إلى مصفوفات أصغر تحتوي كلّ منها عنصرين وتنشئ مصفوفة جديدة متعددة الأبعاد: Array ( [0] => Array ( [0] => a [1] => b ) [1] => Array ( [0] => c [1] => d ) [2] => Array ( [0] => e ) ) إذا لم يكن من الممكن تقسيم عناصر المصفوفة بالتساوي وفقًا للحجم المحدد فإنّ المصفوفة الأخيرة ستحمل العناصر الباقية وتكون أصغر من باقي المصفوفات. إذا مررنا للوسيط الثاني عددًا أصغر من 1 سيُرمى E_WARNING وستكون مصفوفة الخرج NULL. المعامل تفاصيل ‎$array (array)‎ مصفوفة الدخل التي نريد العمل عليها ‎$size (int)‎ حجم المصفوفة الصغيرة (عدد صحيح)‏ ‎$preserve_keys (boolean)‎ (اختياري) FALSE وإلا TRUE إذا أردت أن تحافظ المصفوفات الصغيرة على المفاتيح تكون قيمته table { width: 100%; } thead { vertical-align: middle; text-align: center; } td, th { border: 1px solid #dddddd; text-align: right; padding: 8px; text-align: inherit; } tr:nth-child(even) { background-color: #dddddd; } تجميع عناصر مصفوفة لتشكيل سلسلة نصية تجمع الدالة implode()‎ كل قيم المصفوفة لكنها تفقد معلومات المفاتيح: $arr = ['a' => "AA", 'b' => "BB", 'c' => "CC"]; echo implode(" ", $arr); // AA BB CC نستطيع تجميع المفاتيح باستدعاء الدالة array_keys()‎: $arr = ['a' => "AA", 'b' => "BB", 'c' => "CC"]; echo implode(" ", array_keys($arr)); // a b c يعدّ تجميع القيم مع المفاتيح أكثر تعقيدًا لكن يمكن القيام به بنمط الدالة: $arr = ['a' => "AA", 'b' => "BB", 'c' => "CC"]; echo implode(" ", array_map(function($key, $val) { // دالة تربط المفتاح بالقيمة return "$key:$val"; }, array_keys($arr), $arr)); // a:AA b:BB c:CC تفكيك مصفوفة باستخدام list()‎ يمكن استخدام الدالة list()‎ لإسناد قائمة من قيم المتغيرات إلى مصفوفة. كما يمكنك الاطلاع على الدالة compact()‎. // بمفاتيح مرقمة تبدأ من الصفر $array إلى عناصر المصفوفة $a,$b,$c إسناد قيم المتغيرات list($a, $b, $c) = $array; بدءًا من الإصدار 7.1 يمكنك استخدام الصيغة المختصرة: // بمفاتيح مرقمة تبدأ من الصفر $array إلى عناصر المصفوفة $a,$b,$c إسناد قيم المتغيرات [$a, $b, $c] = $array; //"a", "b", "c" والمفاتيح $array إلى عناصر المصفوفة $a,$b,$c إسناد قيم المتغيرات ["a" => $a, "b" => $b, "c" => $c] = $array; الدالة array_reduce تختزل الدالة array_reduce المصفوفة إلى قيمة واحدة. تمرّ الدالة على كل عنصر من عناصر المصفوفة بنتيجة مُعادة من التكرار السابق وتنتج قيمة جديدة تحتفظ بها للتكرار التالي. الاستخدام: array_reduce ($array, function($carry, $item){...}, $defaul_value_of_first_carry) ‎$carry‎ هي النتيجة المعادة من التكرار السابق و‎$item يحمل قيمة التكرار الحالي. مجموع مصفوفة $result = array_reduce([1, 2, 3, 4, 5], function($carry, $item){ return $carry + $item; }); // 15 أكبر عدد في المصفوفة $result = array_reduce([10, 23, 211, 34, 25], function($carry, $item){ return $item > $carry ? $item : $carry; }); // 211 هل كل العناصر أكبر من 100 $result = array_reduce([101, 230, 210, 341, 251], function($carry, $item){ return $carry && $item > 100; }, true); // true يجب أن تكون القيمة الافتراضية // true هل يوجد عنصر أصغر من 100 $result = array_reduce([101, 230, 21, 341, 251], function($carry, $item){ return $carry || $item < 100; }, false); // false يجب أن تكون القيمة الافتراضية // true تجميع مصفوفة $result = array_reduce(["hello", "world", "PHP", "language"], function($carry, $item){ return !$carry ? $item : $carry . "-" . $item ; }); // "hello-world-PHP-language" يمكنك أيضًا كتابة تابع للتجميع: function implode_method($array, $piece){ return array_reduce($array, function($carry, $item) use ($piece) { return !$carry ? $item : ($carry . $piece . $item); }); } $result = implode_method(["hello", "world", "PHP", "language"], "-"); // "hello-world-PHP-language" دفع عنصر إلى نهاية مصفوفة يوجد طريقتين لدفع عنصر إلى مصفوفة: الدالة array_push()‎ و‎$array[] =‎. نستخدم الدالة array_push()‎ كما يلي: $array = [1,2,3]; $newArraySize = array_push($array, 5, 6); // يُرجع التابع الحجم الجديد للمصفوفة print_r($array); // تُمرّر المصفوفة بالمرجع لذا تُعدّل المصفوفة الأساسية لتحتوي العناصر الجديدة ستطبع الشيفرة: Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 5 [4] => 6 ) نستخدم ‎$array[] =‎ كالتالي: $array = [1,2,3]; $array[] = 5; $array[] = 6; print_r($array); تطبع الشيفرة السابقة: Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 5 [4] => 6 ) ترشيح (Filtering) مصفوفة نستخدم الدالة array_filter لترشيح قيم من المصفوفة والحصول على مصفوفة جديدة تحقق كل شروط المُرشِّح. ترشيح القيم غير الفارغة أفضل حالة للترشيح هي إزالة جميع القيم الفارغة: $my_array = [1,0,2,null,3,'',4,[],5,6,7,8]; $non_empties = array_filter($my_array); // $non_empties will contain // [1,2,3,4,5,6,7,8] هو $non_empties يصبح محتوى المصفوفة الترشيح برد النداء بفرض أننا نريد الحصول على القيم الزوجية فقط: $my_array = [1,2,3,4,5,6,7,8]; $even_numbers = array_filter($my_array, function($number) { return $number % 2 === 0; }); تستقبل الدالة array_filter المصفوفة التي نريد ترشيحها في الوسيط الأول أما الوسيط الثاني فهو المُرشِّح الذي نريد تطبيقه. الإصدار PHP 5.6 وما بعده الترشيح تبعًا للفهرس يمكننا تمرير معامل ثالث للدالة array_filter يسمح بتعديل القيم الممررة إلى رد النداء، يمكن ضبط هذا المعامل على أنّه ARRAY_FILTER_USE_KEY أو ARRAY_FILTER_USE_BOTH، وهو يسمح أن يستقبل رد النداء المفاتيح بدلًا من القيم أو كلًا من المفاتيح والقيم كوسطاء. فإذا أردت التعامل مع الفهارس بدلًا من القيم مثلًا: $numbers = [16,3,5,8,1,4,6]; $even_indexed_numbers = array_filter($numbers, function($index) { return $index % 2 === 0; }, ARRAY_FILTER_USE_KEY); الفهارس في المصفوفة المرشَّحة لاحظ أنّ الدالة array_filter تحافظ على مفاتيح المصفوفة الأصلية، ومن الخطأ أن تقوم بتنفيذ حلقة for على المصفوفة المُرشَّحة: $my_array = [1,0,2,null,3,'',4,[],5,6,7,8]; $filtered = array_filter($my_array); // إظهار كل الأخطاء والملاحظات error_reporting(E_ALL); // for من الخطأ استخدام حلقة for ($i = 0; $i < count($filtered); $i++) { print $filtered[$i]; } /* :الخرج 1 Notice: Undefined offset: 1 2 Notice: Undefined offset: 3 3 Notice: Undefined offset: 5 4 Notice: Undefined offset: 7 */ حدث هذا لأن قيم الفهارس 1، 3، 5، 7 التي هي 0، null، سلسلة فارغة ''، مصفوفة فارغة [] على الترتيب قد حُذفت مع فهارسها. إذا كنت تحتاج تمرير حلقة على نتيجة مُرشِّح طُبِّق على مصفوفة مفهرسة، يجب أن تستدعي الدالة array_values لنتيجة الدالة array_filter لتُنشئ مصفوفة جديدة مع فهارس صحيحة: $my_array = [1,0,2,null,3,'',4,[],5,6,7,8]; $filtered = array_filter($my_array); $iterable = array_values($filtered); error_reporting(E_ALL); // إظهار كل الأخطاء والملاحظات for ($i = 0; $i < count($iterable); $i++) { print $iterable[$i]; } // لا يوجد تحذيرات إزالة عناصر من مصفوفة لإزالة عنصر من مصفوفة مثلًا العنصر الذي فهرسه 1: $fruit = array("bananas", "apples", "peaches"); unset($fruit[1]); ستزيل الشيفرة السابقة العنصر apples من المصفوفة لكن لاحظ أنّ الدالة unset لا تغيّر فهارس باقي العناصر لذا فإنّ المصفوفة ‎$fruit تحتوي الآن الفهارس 0 و2. يمكنك الحذف في المصفوفات الترابطية كما يلي: $fruit = array('banana', 'one'=>'apple', 'peaches'); print_r($fruit); /* Array ( [0] => banana [one] => apple [1] => peaches ) */ unset($fruit['one']); تصبح الآن المصفوفة ‎$fruit: print_r($fruit); /* Array ( [0] => banana [1] => peaches ) */ لاحظ أنّ الشيفرة التالية: unset($fruit); تزيل تعيين المتغير لذا تحذف كامل المصفوفة أي أنّه لم يعد بإمكاننا الوصول إلى أي عنصر من عناصرها. إزالة عناصر الأطراف تُزيل الدالة array_shift()‎ عنصرًا من بداية المصفوفة. مثال: $fruit = array("bananas", "apples", "peaches"); array_shift($fruit); print_r($fruit); الخرج: Array ( [0] => apples [1] => peaches ) تُزيل الدالة array_pop()‎ عنصرًا من نهاية المصفوفة. مثال: $fruit = array("bananas", "apples", "peaches"); array_pop($fruit); print_r($fruit); الخرج: Array ( [0] => bananas [1] => apples ) ترتيب مصفوفة يوجد عدة دوال لترتيب المصفوفات في PHP: الدالة sort()‎ ترتّب هذه الدالة عناصر المصفوفة ترتيبًا تصاعديًّا وفقًا لقيمها. $fruits = ['Zitrone', 'Orange', 'Banane', 'Apfel']; sort($fruits); print_r($fruits); /* Array ( [0] => Apfel [1] => Banane [2] => Orange [3] => Zitrone ) */ الدالة rsort()‎ ترتّب هذه الدالة عناصر المصفوفة ترتيبًا تنازليًّا وفقًا لقيمها. $fruits = ['Zitrone', 'Orange', 'Banane', 'Apfel']; rsort($fruits); print_r($fruits); /* Array ( [0] => Zitrone [1] => Orange [2] => Banane [3] => Apfel ) */ الدالة asort()‎ تُرتِّب هذه الدالة عناصر المصفوفة ترتيبًا تصاعديًّا وتحافظ على اقتران الفهارس مع القيم المرتبطة بها. $fruits = [1 => 'lemon', 2 => 'orange', 3 => 'banana', 4 => 'apple']; asort($fruits); print_r($fruits); /* Array ( [4] => apple [3] => banana [1] => lemon [2] => orange ) */ الدالة arsort()‎ تُرتِّب هذه الدالة عناصر المصفوفة ترتيبًا تنازليًّا وتحافظ على اقتران الفهارس مع القيم المرتبطة بها. $fruits = [1 => 'lemon', 2 => 'orange', 3 => 'banana', 4 => 'apple']; arsort($fruits); print_r($fruits); /* Array ( [2] => orange [1] => lemon [3] => banana [4] => apple ) */ الدالة ksort()‎ تُرتّب هذه الدالة المصفوفة ترتيبًا تصاعديًّا حسب المفتاح. $fruits = ['d'=>'lemon', 'a'=>'orange', 'b'=>'banana', 'c'=>'apple']; ksort($fruits); print_r($fruits); /* Array ( [a] => orange [b] => banana [c] => apple [d] => lemon ) */ الدالة krsort()‎ تُرتّب هذه الدالة المصفوفة ترتيبًا تنازليًّا حسب المفتاح. $fruits = ['d'=>'lemon', 'a'=>'orange', 'b'=>'banana', 'c'=>'apple']; krsort($fruits); print_r($fruits); /* Array ( [d] => lemon [c] => apple [b] => banana [a] => orange ) */ الدالة natsort()‎ ترتّب هذه الدالة المصفوفة بنفس الطريقة التي يرتّب بها الإنسان (ترتيب طبيعي). $files = ['File8.stack', 'file77.stack', 'file7.stack', 'file13.stack', 'File2.stack']; natsort($files); print_r($files); /* Array ( [4] => File2.stack [0] => File8.stack [2] => file7.stack [3] => file13.stack [1] => file77.stack ) */ الدالة natcasesort()‎ ترتّب هذه الدالة المصفوفة بنفس الطريقة التي يرتّب بها الإنسان (ترتيب طبيعي) لكن غير حساسة لحالة الأحرف. $files = ['File8.stack', 'file77.stack', 'file7.stack', 'file13.stack', 'File2.stack']; natcasesort($files); print_r($files); /* Array ( [4] => File2.stack [2] => file7.stack [0] => File8.stack [3] => file13.stack [1] => file77.stack ) */ الدالة shuffle()‎ تخلط هذه الدالة عناصر المصفوفة (ترتيب عشوائي). $array = ['aa', 'bb', 'cc']; shuffle($array); print_r($array); بما أنّ الترتيب عشوائي فليس هناك نتيجة واحدة محددة للشيفرة السابقة، فقد تكون مثلًا: Array ( [0] => cc [1] => bb [2] => aa ) الدالة usort()‎ ترتّب هذه الدالة المصفوفة باستخدام دالة موازنة معرّفة من قبل المستخدم. function compare($a, $b) { if ($a == $b) { return 0; } return ($a < $b) ? -1 : 1; } $array = [3, 2, 5, 6, 1]; usort($array, 'compare'); print_r($array); /* Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 5 [4] => 6 ) */ الدالة uasort()‎ ترتّب هذه الدالة المصفوفة باستخدام دالة موازنة معرّفة من قبل المستخدم وتحافظ على ارتباط الفهارس بالقيم المقابلة. function compare($a, $b) { if ($a == $b) { return 0; } return ($a < $b) ? -1 : 1; } $array = ['a' => 1, 'b' => -3, 'c' => 5, 'd' => 3, 'e' => -5]; uasort($array, 'compare'); print_r($array); /* Array ( [e] => -5 [b] => -3 [a] => 1 [d] => 3 [c] => 5 ) */ الدالة uksort()‎ ترتّب هذه الدالة المصفوفة حسب المفاتيح باستخدام دالة موازنة معرّفة من قبل المستخدم. function compare($a, $b) { if ($a == $b) { return 0; } return ($a < $b) ? -1 : 1; } $array = ['ee' => 1, 'g' => -3, '4' => 5, 'k' => 3, 'oo' => -5]; uksort($array, 'compare'); print_r($array); /* Array ( [ee] => 1 [g] => -3 [k] => 3 [oo] => -5 [4] => 5 ) */ إضافة بعض مفاتيح المصفوفة إلى اللائحة البيضاء يمكنك استخدام الدالتين array_intersect_key وarray_flip معًا عندما تريد السماح بوجود مفاتيح محددة فقط في المصفوفة خاصةً عندما تأتي المفاتيح من معاملات طلب ما. $parameters = ['foo' => 'bar', 'bar' => 'baz', 'boo' => 'bam']; $allowedKeys = ['foo', 'bar']; $filteredParameters = array_intersect_key($parameters, array_flip($allowedKeys)); // $filteredParameters = ['foo' => 'bar', 'bar' => 'baz] إذا لم يحتوي متغير المعاملات على أي مفتاح مسموح به فإنّ المتغير filteredParameters سيكون مصفوفة فارغة. ويمكنك أيضًا استخدام الدالة array_filter لنفس الوظيفة بدءًا من الإصدار PHP 5.6، ممررًا الراية ARRAY_FILTER_USE_KEY كمعامل ثالث. $parameters = ['foo' => 1, 'hello' => 'world']; $allowedKeys = ['foo', 'bar']; $filteredParameters = array_filter( $parameters, function ($key) use ($allowedKeys) { return in_array($key, $allowedKeys); }, ARRAY_FILTER_USE_KEY ); يوفر استخدام الدالة arrayfilter مرونةً إضافيةً لإجراء اختبار عشوائي على المفاتيح، فمثلًا يمكن أن تحتوي المصفوفة ‎$allowedKeys أنماطًا تعبيرية بدلًا من السلاسل النصية العادية، كما أنّها تذكر الهدف من الشيفرة بشكلٍ أكثر صراحة من الدالتين array_intersect_key وarray_flip. إضافة عنصر إلى بداية المصفوفة يمكنك استخدام الدالة array_unshift()‎ عند الحاجة إلى إضافة عنصر في بداية المصفوفة دون تغيير في ترتيب العناصر الحالية، إذ تضيف هذه الدالة العناصر الممررة بالكامل إلى بداية المصفوفة فتبقى العناصر الممررة بنفس الترتيب، وتعدَّل جميع المفاتيح العددية لتبدأ من الصفر بينما تبقى المفاتيح التي تكون بشكل سلسلة نصية كما هي. $myArray = array(1, 2, 3); array_unshift($myArray, 4); print_r($myArray); // Array ( [0] => 4 [1] => 1 [2] => 2 [3] => 3 ) بما أنّ الدالة array_unshift()‎ تُجبر المصفوفة على إعادة تعيين أزواج مفتاح - قيمة والعنصر الجديد يجعل مفاتيح المداخل التالية تبدأ من n+1 فمن الأسهل إنشاء مصفوفة جديدة وإضافة المصفوفة الحالية إلى المصفوفة المُنشأة حديثًا. مثال: $myArray = array('apples', 'bananas', 'pears'); $myElement = array('oranges'); $joinedArray = $myElement; foreach ($myArray as $i) { $joinedArray[] = $i; } // Array ( [0] => oranges [1] => apples [2] => bananas [3] => pears ) يمكنك الاطلاع على المثال هنا تبادل القيم مع المفاتيح تستبدل الدالة array_flip()‎ كل مفاتيح المصفوفة بالقيم المرتبطة معها. $colors = array( 'one' => 'red', 'two' => 'blue', 'three' => 'yellow', ); array_flip($colors); /* array( 'red' => 'one', 'blue' => 'two', 'yellow' => 'three' ) */ دمج مصفوفتين في مصفوفة واحدة تدمج الدالة array_merge()‎ مصفوفتين أو أكثر. $a1 = array("red","green"); $a2 = array("blue","yellow"); print_r(array_merge($a1,$a2)); /* Array ( [0] => red [1] => green [2] => blue [3] => yellow ) */ المصفوفة الترابطية: $a1=array("a"=>"red","b"=>"green"); $a2=array("c"=>"blue","b"=>"yellow"); print_r(array_merge($a1,$a2)); /* Array ( [a] => red [b] => yellow [c] => blue ) */ تُدمج العناصر من مصفوفة أو واحدة أكثر فتُضاف قيم إحداها إلى نهاية المصفوفة الأخرى وتُرجع المصفوفة النهائية. إذا كان لمصفوفات الدخل نفس المفاتيح المكونة من سلاسل نصية فإنّ القيمة اللاحقة للمفتاح ستكتب فوق القيمة السابقة له أما إذا كانت المفاتيح عددية فإنّ القيمة اللاحقة ستُضاف ولن تكتب فوق القيمة السابقة للمفتاح. إذا كانت مفاتيح مصفوفة الدخل رقمية سيُعاد ترقيم القيم في مصفوفة النتيجة بمفاتيح تزايدية ابتداءً من الصفر. معالجة عدة مصفوفات معًا تقاطع (intersection) المصفوفات تُرجع الدالة array_intersect مصفوفة من القيم الموجودة في جميع المصفوفات الممررة إليها وتحافظ على المفاتيح المرتبطة مع القيم المعادة. $array_one = ['one', 'two', 'three']; $array_two = ['two', 'three', 'four']; $array_three = ['two', 'three']; $intersect = array_intersect($array_one, $array_two, $array_three); // $intersect = ['two', 'three'] تتحقق الدالة array_intersect من قيم المصفوفات فقط أما الدالة array_intersect_assoc تُرجع تقاطع القيم مع المفاتيح المرتبطة بها. $array_one = [1 => 'one',2 => 'two',3 => 'three']; $array_two = [1 => 'one', 2 => 'two', 3 => 'two', 4 => 'three']; $array_three = [1 => 'one', 2 => 'two']; $intersect = array_intersect_assoc($array_one, $array_two, $array_three); // $intersect = [1 =>'one',2 => 'two'] تتحقق الدالة array_intersect_key من التقاطع بتفحص المفاتيح فقط وتُرجع المفاتيح الموجودة في جميع المصفوفات الممررة. $array_one = [1 => 'one',2 => 'two',3 => 'three']; $array_two = [1 => 'one', 2 => 'two', 3 => 'four']; $array_three = [1 => 'one', 3 => 'five']; $intersect = array_intersect_key($array_one, $array_two, $array_three); // $intersect = [1 =>'one',3 => 'three'] دمج أو ضم مصفوفتين $fruit1 = ['apples', 'pears']; $fruit2 = ['bananas', 'oranges']; $all_of_fruits = array_merge($fruit1, $fruit2); //$all_of_fruits = [0 => 'apples', 1 => 'pears', 2 => 'bananas', 3 => 'oranges'] لاحظ أنّ الدالة array_merge()‎ ستغيّر الفهارس الرقمية وتكتب فوق الفهارس النصية. $fruit1 = ['one' => 'apples', 'two' => 'pears']; $fruit2 = ['one' => 'bananas', 'two' => 'oranges']; $all_of_fruits = array_merge($fruit1, $fruit2); //$all_of_fruits = ['one' => 'bananas', 'two' => 'oranges'] تعيد الدالة array_merge()‎ كتابة قيم المصفوفة الثانية فوق قيم المصفوفة الأولى إذا لم تستطع إعادة ترقيم فهارسها. يمكنك استخدام العامل + لدمج مصفوفتين بطريقة لا يمكن فيها للقيم أن يُكتب فوقها لكنها لا تُعيد ترقيم الفهارس العددية لذا تخسر قيم المصفوفات التي لها فهرس مُستخدم في المصفوفة الأولى. $fruit1 = ['one' => 'apples', 'two' => 'pears']; $fruit2 = ['one' => 'bananas', 'two' => 'oranges']; $all_of_fruits = $fruit1 + $fruit2; // $all_of_fruits = ['one' => 'apples', 'two' => 'pears'] $fruit1 = ['apples', 'pears']; $fruit2 = ['bananas', 'oranges']; $all_of_fruits = $fruit1 + $fruit2; // $all_of_fruits = [0 => 'apples', 1 => 'pears'] تغيير مصفوفة متعددة الأبعاد إلى مصفوفة ترابطية إذا كان لديك مصفوفة متعددة الأبعاد مثل: [ ['foo', 'bar'], ['fizz', 'buzz'], ] وتريد تغييرها إلى مصفوفة ترابطية مثل: [ 'foo' => 'bar', 'fizz' => 'buzz', ] فيمكنك استخدام الشيفرة التالية: $multidimensionalArray = [ ['foo', 'bar'], ['fizz', 'buzz'], ]; $associativeArrayKeys = array_column($multidimensionalArray, 0); $associativeArrayValues = array_column($multidimensionalArray, 1); $associativeArray = array_combine($associativeArrayKeys, $associativeArrayValues); أو يمكنك تخطي الإعداد ‎$associativeArrayKeys و‎$associativeArrayValues واستخدام الشيفرة البسيطة التالية: $associativeArray = array_combine(array_column($multidimensionalArray, 0), array_column($multidimensionalArray, 1)); جمع مصفوفتين (المفاتيح من واحدة والقيم من الأخرى) تنشئ الدالة array_combine()‎ مصفوفةً جديدةً عن طريق استخدام المفاتيح من أحد المصفوفات والقيم من مصفوفة أخرى. يبين المثال التالي كيفية دمج مصفوفتين في مصفوفة واحدة ترابطية فيها المفاتيح من المصفوفة الأولى والقيم من المصفوفة الثانية: $array_one = ['key1', 'key2', 'key3']; $array_two = ['value1', 'value2', 'value3']; $array_three = array_combine($array_one, $array_two); var_export($array_three); /* array ( 'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3', ) */ مكتبة PHP المعيارية لهياكل البيانات (SPL) SplFixedArray الاختلاف عن مصفوفة PHP يُنفَّذ نوع المصفوفة الافتراضي في PHP كخرائط hash مرتبة مما يسمح لنا بإنشاء مصفوفات تحتوي على الأزواج قيمة/مفتاح، يمكن أن تكون القيم من أي نوع والمفاتيح إما أرقام أو سلاسل نصية، ومع ذلك فإنّ هذه ليست الطريقة التقليدية لإنشاء المصفوفات. كما تلاحظ في الرسم التوضيحي فإنّه من الممكن أن تُعرض مصفوفة PHP مثل مجموعة مرتبة من الأزواج قيمة/مفتاح حيث يُربَط كل مفتاح إلى أي قيمة. لاحظ أنّه في هذه المصفوفة لدينا مفاتيح عددية ومفاتيح بشكل سلاسل نصية بالإضافة إلى قيم من أنواع مختلفة والمفتاح ليس له تأثير على ترتيب العناصر. $arr = [ 9 => "foo", 1 => 4.2, "bar" => null, ]; foreach($arr as $key => $value) { echo "$key => $value\n"; } تعطينا الشيفرة السابقة ما نتوقعه تمامًا: 9 => foo 1 => 4.2 bar => يُحدد حجم مصفوفات PHP العادية ديناميكيًا، ويزداد وينقص هذا الحجم بإضافة أو حذف عناصر إلى ومن المصفوفة بشكلٍ تلقائي، أما في المصفوفات التقليدية يكون الحجم ثابتًا وتتألف المصفوفة بالكامل من نفس نوع القيم ويمكننا الوصول إلى أي قيمة باستخدام الفهارس بدلًا من المفاتيح ويمكن استنتاج الفهرس من إزاحة القيمة في المصفوفة. وبما أننا سنعرف حجم نوع معين والحجم الثابت للمصفوفة فإنّ الإزاحة هي حجم النوع * n، إذ تمثّل n موضع القيمة في المصفوفة، يعطينا ‎$arr[0]‎ في المثال السابق القيمة 1 ويعطينا العنصر الأول في المصفوفة ‎$arr[1]‎ القيمة 2 وهكذا… ومع ذلك لا يقيّد الصنف SplFixedArray نوع القيم إنما يقيد نوع المفاتيح فقط والتي يجب أن تكون عددية، ?وأيضًا ذات حجم ثابت، وهذا يجعل المصفوفات من النوع SplFixedArray أكثر فعاليةٍ من المصفوفات العادية بطريقةٍ معينة فهي أصغر وتتطلب ذاكرة أقل. تهيئة المصفوفة تُنفَّذ المصفوفة من النوع SplFixedArray ككائن لكن يمكن الوصول إليها بنفس الصياغة التي نصل فيها إلى مصفوفة PHP العادية بما أنّها تنفّذ الواجهة ArrayAccess وتنفّذ أيضًا الواجهات Countable وIterator لذا لها نفس سلوك مصفوفات PHP العادية الذي اعتدت عليه (أي الأشياء مثل ‎count(‎$arr)‎ وforeach($arr as $k => $v)‎ تعمل بنفس الطريقة في المصفوفات من النوع SplFixedArray والمصفوفات العادية). يأخذ باني المصفوفة من النوع SplFixedArray وسيطًا واحدًا يعبّر عن حجم المصفوفة. $arr = new SplFixedArray(4); $arr[0] = "foo"; $arr[1] = "bar"; $arr[2] = "baz"; foreach($arr as $key => $value) { echo "$key => $value\n"; } تعطيك الشيفرة السابقة النتيجة: 0 => foo 1 => bar 2 => baz 3 => كما أنّ الشيفرة: var_dump(count($arr)); تعطينا ما نتوقع: int(4) لاحظ أنه في المصفوفات من النوع SplFixedArray يصف المفتاح ترتيب العنصر في المصفوفة لأنه فهرس حقيقي وليس مجرد خريطة كما في المصفوفات العادية.? تغيير حجم المصفوفة تذكر دائمًا بما أنّ المصفوفة ذات حجم ثابت فإنّ عدّها سيعيد دائمًا القيمة نفسها، لذا طالما أنّ نتيجة unset($arr[1])‎ هي ‎$arr[1] === null‎ تبقى نتيجة count($arr)‎ هي 4، وتحتاج لتغيير حجم المصفوفة إلى استدعاء التابع setSize: $arr->setSize(3); var_dump(count($arr)); foreach($arr as $key => $value) { echo "$key => $value\n"; } الآن نحصل على النتيجة: int(3) 0 => foo 1 => 2 => baz الاستيراد من SplFixedArray والتصدير إلى SplFixedArray يمكنك استيراد/تصدير مصفوفة عادية إلى/من مصفوفة SplFixedArray باستخدام التوابع fromArray وtoArray. $array = [1,2,3,4,5]; $fixedArray = SplFixedArray::fromArray($array); foreach($fixedArray as $value) { echo $value, "\n"; } // 1 2 3 4 5 $fixedArray = new SplFixedArray(5); $fixedArray[0] = 1; $fixedArray[1] = 2; $fixedArray[2] = 3; $fixedArray[3] = 4; $fixedArray[4] = 5; $array = $fixedArray->toArray(); foreach($array as $value) { echo $value, "\n"; } // 1 2 3 4 5 ترجمة -وبتصرف- للفصول [Executing Upon an Array - Manipulating an Array - Processing Multiple Arrays Together - SPL data structures] من كتاب PHP Notes for Professionals book اقرأ أيضًا المقال التالي: التعامل مع الوقت والتاريخ في PHP المقال السابق: المصفوفات (Arrays) في PHP
    1 نقطة
  16. الصنف Datetime إنشاء نسخة Datetime ثابتة من متغير يمكنك استخدام الشيفرة التالية لإنشاء ‎\DateTimeImmutable‎ في PHP الإصدار 5.6 وما بعده: \DateTimeImmutable::createFromMutable($concrete); أما في الإصدارات السابقة يمكنك استخدام: \DateTimeImmutable::createFromFormat(\DateTime::ISO8601, $mutable->format(\DateTime::ISO8601), $mutable->getTimezone()); إضافة أو طرح تاريخ نستخدم الصنف DateInterval لإضافة أو طرح فترة زمنية في كائن DateTime، إليك المثال التالي الذي نطرح فيه 7 أيام ونطبع رسالة على الشاشة: // التعليمة التالية بدون وسيط تُرجع التاريخ الحالي $now = new DateTime(); // الكائن التالي يمثل فترة زمنية مدتها 7 أيام $interval = new DateInterval('P7D'); // DateTime التعليمة التالية ستُرجع كائن $lastDay = $now->add($interval); // ويُرجع سلسلة نصية DateTime ينسّق هذا التابع كائن $formatedLastDay = $lastDay->format('Y-m-d'); echo "Samara says: Seven Days. You'll be happy on $formatedLastDay."; /* عند تنفيذ هذه الشيفرة في 1-8-2016 يكون الخرج Samara says: Seven Days. You'll be happy on 2016-08-08. */ نستطيع استخدام التابع الفرعي بطريقة مشابهة لطرح التواريخ: $now->sub($interval); echo "Samara says: Seven Days. You were happy last on $formatedLastDay."; /* عند تنفيذ هذه الشيفرة في 1-8-2016 يكون الخرج Samara says: Seven Days. You were happy last on 2016-07-25. */ getTimestamp getTimeStemp هو تمثيل unix لكائن من الصنف datetime. $date = new DateTime(); echo $date->getTimestamp(); سيؤدي ذلك إلى وضع مؤشر صحيح للثواني التي انقضت منذ 00:00:00 UTC، الخميس، 1 كانون الثاني 1970. setDate تضبط هذه الدالة التاريخ لكائن من الصنف datetime. $date = new DateTime(); $date->setDate(2016, 7, 25); تضبط هذه الشيفرة التاريخ ليصبح 25 تموز، 2015 وخرجها: 2016-07-25 17:52:15.819442 إنشاء DateTime من تنسيق معين إنّ PHP قادرة على تحليل عدة تنسيقات للتاريخ، يمكنك استخدام التابع الساكن DateTime::createFromFormat إذا أردت تحليل تنسيق غير معياري أو إذا أردت أن تحدد في شيفرتك تنسيق التاريخ المُستخدم بشكلٍ صريح: نمط كائني التوجه $format = "Y,m,d"; $time = "2009,2,26"; $date = DateTime::createFromFormat($format, $time); نمط إجرائي $format = "Y,m,d"; $time = "2009,2,26"; $date = date_create_from_format($format, $time); طباعة DateTime توفر PHP من الإصدار 4 وما بعده تابع تنسيق كائني التوجه يحول كائن DateTime إلى سلسلة نصية بالتنسيق الذي تريده: public string DateTime::format ( string $format ) تأخذ الدالة date()‎ معاملًا واحدًا format بشكل سلسلة نصية ويستخدم محارف مفردة لتعريف التنسيق: Y: أربعة أرقام تمثل السنة (2016 مثلًا). y: رقمين يمثلان السنة (16 مثلًا). m: يمثّل الشهر بتنسيق رقم (من 01 إلى 12). M: يمثّل الشهر بثلاثة أحرف (مثل …Jan, Feb, Mar). j: يمثّل يوم في الشهر دون أصفار بادئة (من 1 إلى 31). D: يمثّل يوم في الأسبوع بثلاثة أحرف (مثل …Mon, Tue, Wed). h: يمثّل الساعة بتنسيق 12-ساعة (01 إلى 12). H: يمثّل الساعة بتنسيق 24-ساعة (00 إلى 23). A: إما AM أو PM. i: يمثّل الدقائق دون أصفار بادئة (من 00 إلى 59). s: يمثّل الثواني دون أصفار بادئة (من 00 إلى 59). يمكنك الاطلاع على اللائحة الكاملة هنا. الاستخدام يمكن استخدام هذه المحارف في تركيبات مختلفة لعرض الوقت بأي تنسيق تريده، إليك بعض الأمثلة: $date = new DateTime('2000-05-26T13:30:20'); /* Friday, May 26, 2000 at 1:30:20 PM */ $date->format("H:i"); /* 13:30 */ $date->format("H i s"); /* 13 30 20 */ $date->format("h:i:s A"); /* 01:30:20 PM */ $date->format("j/m/Y"); /* 26/05/2000 */ $date->format("D, M j 'y - h:i A"); /* Fri, May 26 '00 - 01:30 PM */ التنسيق الكائني التوجه: $date->format($format) التنسيق الإجرائي المشابه: date_format($date, $format) الحصول على الفرق بين تاريخين/وقتين يعدّ استخدام الصنف DateTime الطريقة الأكثر عمليّة لنحصل على الفرق بين تاريخين أو وقتين، مثال: <?php // DateTime إنشاء كائن من الصنف $twoYearsAgo = new DateTime("2014-01-18 20:05:56"); // DateTime إنشاء كائن ثاني من الصنف $now = new DateTime("2016-07-21 02:55:07"); // حساب الفرق $diff = $now->diff($twoYearsAgo); // فرق السنوات بين التاريخين $diff->y يحتوي $yearsDiff = $diff->y; // فرق الدقائق بين التاريخين $diff->m يحتوي $monthsDiff = $diff->m; // فرق الأيام بين التاريخين $diff->d يحتوي $daysDiff = $diff->d; // فرق الساعات بين التاريخين $diff->h يحتوي $hoursDiff = $diff->h; // فرق الدقائق بين التاريخين $diff->i يحتوي $minsDiff = $diff->i; // فرق الثواني بين التاريخين $diff->s يحتوي $secondsDiff = $diff->s; // فرق الأيام بين التاريخين $diff->days يحتوي $totalDaysDiff = $diff->days; // $diff استخلاص معلومات المتغير var_dump($diff); يمكننا أيضًا استخدام عوامل الموازنة للموازنة بين تاريخين بشكلٍ أسهل: <?php // DateTime إنشاء كائن من الصنف $twoYearsAgo = new DateTime("2014-01-18 20:05:56"); // DateTime إنشاء كائن ثاني من الصنف $now = new DateTime("2016-07-21 02:55:07"); var_dump($now > $twoYearsAgo); // bool(true) var_dump($twoYearsAgo > $now); // bool(false) var_dump($twoYearsAgo <= $twoYearsAgo); // bool(true) var_dump($now == $now); // bool(true) تغيير التاريخ إلى تنسيق آخر أسهل طريقة لتغيير تنسيق التاريخ إلى تنسيق آخر هي استخدام strtotime()‎ مع date()‎، إذ أنّ strtotime()‎ ستغير التاريخ إلى تنسيق الختم الزمني unix ثمّ يُمرَّر إلى date()‎ لتغييره إلى تنسيق جديد. $timestamp = strtotime('2008-07-01T22:35:17.02'); $new_date_format = date('Y-m-d H:i:s', $timestamp); يمكن كتابة الشيفرة السابقة بسطرٍ واحد: $new_date_format = date('Y-m-d H:i:s', strtotime('2008-07-01T22:35:17.02')); تذكّر أنّ الدالة strtotime()‎ تحتاج أن يكون التاريخ بتنسيقٍ صالح وإلا ستُرجع false وتصبح قيمة التاريخ 1969-12-31. استخدام DateTime()‎ توفر PHP بدءًا من الإصدار 5.2 الصنف DateTime()‎ الذي يمنح أدوات قوية للعمل مع التاريخ والوقت، يمكننا استخدامه لكتابة الشيفرة السابقة كالتالي: $date = new DateTime('2008-07-01T22:35:17.02'); $new_date_format = $date->format('Y-m-d H:i:s'); العمل مع الأختام الزمنية unix تأخذ الدالة date()‎ معاملها الثاني بصيغة ختم زمني unix وتُرجع تاريخ منسّق: $new_date_format = date('Y-m-d H:i:s', '1234567890'); يعمل DateTime()‎ مع الختم الزمني unix بإضافة @ قبل الختم الزمني: $date = new DateTime('@1234567890'); $new_date_format = $date->format('Y-m-d H:i:s'); إذا كان الختم الزمني لديك مقدّر بأجزاء الثانية (قد تكون نهايته 000 و/أو يتكون من 13 محرف) ستحتاج أن تحوّله إلى الثواني قبل أن تستطيع تغيير تنسيقه، يوجد طريقتين للقيام بذلك: حذف آخر 3 أرقام باستخدام substr()‎: يمكن حذف الأرقام الثلاثة الأخيرة بعدة طرق لكن أسهلها استخدام substr()‎: $timestamp = substr('1234567899000', -3); القسمة على 1000: يمكنك أيضًا تحويل الختم الزمني إلى الثواني عن طريق القسمة على 1000، يمكنك استخدام المكتبة BCMath للقيام بالعمليات الرياضية كسلاسل نصية لأنّ الختم الزمني كبير جدًا على أنظمة 32 بت: $timestamp = bcdiv('1234567899000', '1000'); يمكنك استخدام strtotime()‎ للحصول على ختم زمني unix: $timestamp = strtotime('1973-04-18'); يمكنك استخدام DateTime::getTimestamp()‎ مع DateTime()‎: $date = new DateTime('2008-07-01T22:35:17.02'); $timestamp = $date->getTimestamp(); يمكنك بدلًا من ذلك استخدام خيار التنسيق U إذا كنت تستخدم الإصدار PHP 5.2: $date = new DateTime('2008-07-01T22:35:17.02'); $timestamp = $date->format('U'); العمل مع تنسيق التاريخ الغامض وغير المعياري لسوء الحظ ليست كل التواريخ التي يحتاج المطور أن يتعامل معها تكون منسّقة بطريقة معيارية، لكن لحسن الحظ وفرت PHP 5.3 حلًّا لذلك، تسمح لنا DateTime::createFromFormat()‎ بأن نخبر PHP عن تنسيق التاريخ لذا يمكن تحليلها بنجاح إلى كائن DateTime لمزيد من المعالجة. $date = DateTime::createFromFormat('F-d-Y h:i A', 'April-18-1973 9:48 AM'); $new_date_format = $date->format('Y-m-d H:i:s'); أعطتنا PHP 5.4 قابلة الوصول إلى عنصر في الصنف عند إنشاء نسخة مما يسمح لنا أن نكتب الشيفرة السابقة في سطر واحد: $new_date_format = (new DateTime('2008-07-01T22:35:17.02'))->format('Y-m-d H:i:s'); لكن هذا لا يعمل مع DateTime::createFromFormat()‎ بعد. تحليل وصف التاريخ باللغة الانكليزية إلى تنسيق تاريخ يمكن تحليل نصوص مختلفة باللغة الانكليزية إلى تواريخ باستخدام الدالتين strtotime()‎ وdate()‎ معًا.‍ // طباعة التاريخ الحالي echo date("m/d/Y", strtotime("now")), "\n"; // m/d/Y طباعة تاريخ 10 أيلول، 2000 بالتنسيق echo date("m/d/Y", strtotime("10 September 2000")), "\n"; // طباعة تاريخ الأمس echo date("m/d/Y", strtotime("-1 day")), "\n"; // طباعة نتيجة تاريخ اليوم + أسبوع echo date("m/d/Y", strtotime("+1 week")), "\n"; // طباعة نتيجة تاريخ اليوم + أسبوع ويومين و4 ساعات وثانيتين echo date("m/d/Y", strtotime("+1 week 2 days 4 hours 2 seconds")), "\n"; // طباعة تاريخ يوم الخميس القادم echo date("m/d/Y", strtotime("next Thursday")), "\n"; // طباعة تاريخ الاثنين الماضي echo date("m/d/Y", strtotime("last Monday")), "\n"; // طباعة تاريخ اليوم الأول من الشهر القادم echo date("m/d/Y", strtotime("First day of next month")), "\n"; // طباعة تاريخ اليوم الأخير من الشهر القادم echo date("m/d/Y", strtotime("Last day of next month")), "\n"; // طباعة تاريخ اليوم الأول من الشهر الماضي echo date("m/d/Y", strtotime("First day of last month")), "\n"; // طباعة تاريخ اليوم الأخير من الشهر الماضي echo date("m/d/Y", strtotime("Last day of last month")), "\n"; استخدام ثوابت معرّفة مسبقًا لتنسيق التاريخ بدءًا من الإصدار PHP 5.1.0 يمكننا استخدام ثوابت معرّفة مسبقًا لتنسيق التاريخ في الدالة date()‎ بدلًا من السلاسل النصية. ثوابت تنسيق التاريخ المعرّفة مسبقًا المتاحة: DATE_ATOM // (2016-07-22T14:50:01+00:00) (ATOM) الذرة DATE_COOKIE // ‏(Friday, 22-Jul-16 14:50:01 UTC) HTTP ملفات تعريف الارتباط DATE_RSS // (Fri, 22 Jul 2016 14:50:01 +0000) ‏RSS DATE_W3C // (2016-07-22T14:50:01+00:00) اتحاد شبكة الويب العالمية DATE_ISO8601 // ‏(2016-07-22T14:50:01+0000) ISO-8601 DATE_RFC822 // (Fri, 22 Jul 16 14:50:01 +0000) RFC 822 DATE_RFC850 // ‏(Friday, 22-Jul-16 14:50:01 UTC) RFC 850 DATE_RFC1036 // ‏(Fri, 22 Jul 16 14:50:01 +0000) RFC 1036 DATE_RFC1123 // ‏(Fri, 22 Jul 2016 14:50:01 +0000) RFC 1123 DATE_RFC2822 // (Fri, 22 Jul 2016 14:50:01 +0000) RFC 2822 DATE_RFC3339 // ‏(2016-07-22T14:50:01+00:00) DATE_ATOM ‏‏نفس أمثلة: echo date(DATE_RFC822); // Fri, 22 Jul 16 14:50:01 +0000 echo date(DATE_ATOM,mktime(0,0,0,8,15,1947)); // 1947-08-15T00:00:00+05:30 ترجمة -وبتصرف- للفصول [Datetime Class - Working with Dates and Time] من كتاب PHP Notes for Professionals book اقرأ أيضًا المقال التالي: بنى التحكم والحلقات التكرارية في PHP المقال السابق: التنفيذ على المصفوفات والتعامل معها في PHP تعلم PHP
    1 نقطة
  17. لا شك تعلم الخوارزميات أحد النصائح المهمة التي وجهت لك إذا قررت تعلم البرمجة فكلمة خوارزمية تتردد كثيرًا في مجال البرمجة وغيرها من المجالات مثل الرياضيات والعلوم والمنطق وكل ما يتعلق بالحاسوب خصوصًا، فهي من أهم المفاهيم التي لا يمكن أن يستقيم لك تعلم البرمجة والرياضيات وعلوم الحاسب بدونها. إذا كنت تتساءل ما هي الخوارزمية، وكيف أتعلم الخوازميات، وما أهمية الخوارزميات في علوم الحاسب وفي البرمجة بشكل خاص، وما هي أنواع الخوارزميات التي علي تعلمها، وكيف أكتب أفضل خوارزمية فهذه المقالة لك، حيث سنستعرض في سياقها كل ما تحتاج معرفته عن الخوارزميات، ونوفر لك مجموعة من المصادر التعليمية العربية الغنية التي تساعدك على تعلم رموز الخوارزميات وطرق حل الخوارزميات في الحاسوب بأفضل طريقة. ما هي الخوارزمية؟ الخوارزمية algorithm هي مجموعة من التعليمات المرتبة لحل مشكلة ما في الرياضيات أو أي مشكلة تواجهك في الحياة اليومية خلال زمن محدد وعدد خطوات محدود. ينبغي أن تكون خطوات وتعليمات الخوارزمية واضحة ومُرتّبة بحيث تنتهي بحل المشكلة. فكّر في الخوارزمية كما لو كانت وصفة طبخ، إذ تقدّم الوصفة طريقة تحضير وجبة ما خطوة بخطوة، ابتداءً بالمقادير الضرورية للوجبة، وحتى آخر خطوة من تحضير الوجبة وتقديمها. ورغم أن مفهوم الخوارزميات يمكن أن يطبق في كل مجالات الحياة لكن تبرز أهمية الخوارزميات في علوم الحاسب بشكل خاص فهي تنظم عمل المبرمج وتعزز تفكيره المنطقي والرياضي وتمكنه من فهم المشكلات وتصورها بشكل أفضل قبل حلها وتطبيقها فعليًا على برامج حاسوبية مكتوبة بإحدى لغات البرمجة. تاريخ الخوارزميات تُعزى أقدم الخوارزميات المعروفة إلى البابليين، إذ عُثِر على أقدم لوح يحتوي تعليمات خوارزمية لإجراء عملية القسمة، ويعود تاريخه لسنة 2500 قبل الميلاد. وقد عثِر كذلك على خوارزميات حسابية تعود إلى المصريين القدامى تعود إلى سنة 1550 قبل الميلاد. ازداد استخدام الخوارزميات في حقبة اليونان، حيث ظهرت الكثير من الخوارزميات الرياضية التي ما تزال تُستخدم حتى يومنا هذا، مثل خوارزمية قسمة إقليدس التي تحسب خارج وباقي عملية القسمة. تطور مفهوم الخوارزميات في عصر الحضارة الإسلامية، إذ استخدم المسلمون الخوارزميات لحل المعادلات والمسائل الرياضية. ولعل أشهر هذه الخوارزميات هي خوارزمية حل المعادلات من الدرجة الثانية التي ذُكِرت في كتاب "حساب الجبر والمقابلة" لعالم الرياضيات المسلم محمد بن موسى الخوارزمي مؤسس علم الجبر، والذي تُنسب إليه كلمة خوارزمية في اللغة العربية، وكذلك الكلمة المقابلة لها في اللغات اللاتينية algorithm المُشتقة من الكلمة al-Khwārizmī، وهو الاسم الرومي للخوارزمي -وأيضًا كلمة الجبر algebra. استخدم الأوروبيون كلمة algorithm للدلالة على القواعد والتقنيات التي استخدمها الخوارزمي لحل المعادلات الجبرية، ثمّ عُمِّم هذا المصطلح ليشمل أيّ مجموعة من القواعد والتقنيات الساعية لحل مشكلة ما. استمر مفهوم الخوارزميات في التطور بعد الحقبة الإسلامية إبّان عصر النهضة، خصوصًا مع تطوّر أسس علم الحوسبة في القرن التاسع عشر وإنتاج أول خوارزمية يمكن تنفيذها على الحاسوب سنة 1840 على يد آدا لوفانس Ada Lovelace. ثمّ الصياغة النهائية لمفهوم الخوارزمية على يد آلان تورنغ Alan Turing عبر آلته الشهيرة آلة تورنغ (Turing machine). دورة علوم الحاسوب دورة تدريبية متكاملة تضعك على بوابة الاحتراف في تعلم أساسيات البرمجة وعلوم الحاسوب اشترك الآن أركان الخوارزمية تملك أي خوارزمية ثلاثة أركان رئيسية وهي: الدخل أو المدخلات: تمثل البيانات أو الأشياء الضرورية والمطلوبة التي تعمل عليها الخوارزمية وإن كان الدخل مؤلفًا من عدة عناصر، فإنّ تعداد عناصره يسمى حجم الدخل، مثلًا إن كان الدخل عبارة عن مصفوفة أو سلسلة نصية مؤلفة من n عنصر، فإنّ حجم الدخل سيساوي n. لو عدنا إلى مثال الطبخ فإنّ دخل خوارزمية طهي وجبة معينة ستكون هي المقادير المُستخدمة لإعداد الوجبة. متن الخوارزمية: تأخذ الخوارزمية الدخل، وتطبّق عليه سلسلة من خطوات المعالجة المتتابعة والمُحدّدة سلفًا. مثلًا، يشمل متن خوارزمية الطبخ كل عمليات تجهيز المقادير وإعدَادها وخطوات طهيها. الخرج أو المُخرجات: بعد أن تنتهي الخوارزمية من تنفيذ كافة الخطوات، تُنتج لنا خرجًا يمثل حل المشكلة. مثلًا خرج خوارزمية طهي وجبة سيكون هو الوجبة نفسها جاهزة ومطهيّة. على سبيل المثال إذا أردنا كتابة خوارزمية جداء عددين صحيحين ستكون أركان هذه الخوارزمية كالتالي: الدخل: هو العددان الصحيحان المطلوب حساب ناتج جدائهما x, y الخرج: هو ناتج الجداء z متن الخوارزمية: الخطوة 1: ابدأ الخطوة 2: قم بالتصريح عن ثلاثة أعداد صحيحة x و y و z الخطوة 3: أدخل قيم المدخلات x و y الخطوة 4: اضرب قيم x بـ y الخطوة 5: خزّن ناتج الضرب في z الخطوة 6: اعرض قيمة z الخطوة 7: توقف خطوات حل الخوارزميات عندما تواجهك أي مشكلة وتريد كتابة خوارزمية لحلها عليك أن تفكر في العثور على إجابات للأسئلة التالية: ما هو دخل الخوارزمية أي ما هي المعلومات التي أحتاج إلى الحصول عليها من المستخدم؟ ما هو خرج الخوارزمية أي ما هي المعلومات التي أحتاج لعرضها على المستخدم؟ ما هي الخطوات الرئيسية المطلوبة لحل هذه المشكلة؟ ما هو ترتيب تنفيذ هذه الخطوات؟ ما هي القرارات أو الشروط التي أحتاج مراعاتها عند معالجة المعلومات؟ هل هناك تعليمات بحاجة لأن أكررها عدة مرات؟ طرق تمثيل الخوارزميات يمكنك ثمثيل الخوارزمية أو التعبير عنها بعدة طرق: الطريقة الأولى من خلال الكلام المبعثر الذي يصف حل المشكلة بلغتك المحكية دون اتباع أي قواعد في الوصف. الطريقة الثانية من خلال ما يسمى الشيفرة الوهمية أو الزائفة pseudocode وهي مجموعة من التعليمات التي تحاكي في طريقة كتابتها لغات البرمجة لكنها لا تلتزم بقواعد البرمجة التي يجب الالتزام بها عندما تكتب شيفرات برمجية فعلية. الطريقة الثالثة تسمى المخططات الانسيابية Flowcharts، والمخطط الانسيابي هو تمثيل رسومي للخوارزمية يرسم باستخدام أنواع مختلفة من الرموز لكل رمز غرض معين وهو في تقسيم المشكلة الكبيرة إلى مشاكل صغيرة سهلة الفهم ويعد طريقة مناسبة للتواصل بين الأشخاص غير التقنيين. تتوافر عدة برامج مساعدة تساعدك على رسم المخططات الانسيابية، وللمزيد يمكنك مطالعة مقال كيفية رسم مخطط انسيابي Flowchart باستخدام PowerPoin. دورة الذكاء الاصطناعي احترف برمجة الذكاء الاصطناعي AI وتحليل البيانات وتعلم كافة المعلومات التي تحتاجها لبناء نماذج ذكاء اصطناعي متخصصة. اشترك الآن مثال على استخدام الخوارزمية في حياتنا اليومية على سبيل المثال إذا طلب منك كتابة خوارزمية توضح طريقة التعامل مع آلة صنع القهوة والشاي ستكون الخطوات التي عليك اتباعها كالتالي: معرفة إن كان الزبون يريد شرب الشاي أم القهوة إضافة الشاي أو القهوة إلى الكوب معرفة إن كان المستخدم يريد إضافة السكر للكوب إذا كان الجواب نعم أضف السكر إلى الكوب سكب الماء الساخن في الكوب للتعبير عن هذه الخوارزمية باستخدام الشيفرة الزائفة سنكتب التالي: START; /Would you like Tea or Coffee?/; if tea { Add Tea in cup; } else { Add Coffee in cup; } /Would you like Sugar?/; if Sugar { Add Sugar in cup; } Pour boiling water in cup END; وللتعبير عنها باستخدام المخطط الانسيابي سنرسم المخطط التالي: أمثلة على الخوارزميات لنفهم بشكل أفضل ما هي الخوارزميات دعنا نستعرض بعض الأمثلة الإضافية على خوارزميات لحل مسائل رياضية بسيطة ونتعرف على أركانها المختلفة وخطوات حلها ونعبر عنها بالطرق المختلفة. خوارزمية لحساب قيمة مضروب عدد في الرياضيات المضروب factorial أو عاملي العدد الصحيح n الذي يعبر عنه بالشكل التالي n! هو جداء كل الأعداد الطبيعية المساوية أو الأصغر من n ما عدا الصفر ولكتابة خوارزمية تحل هذه المسألة الرياضية علينا اتباع الخطوات التالية: الدخل: هو العدد الصحيح المطلوب حساب مضروبه n. الخرج: هو ناتج المضروب factorial المتن: الخطوة 1: إدخال العدد n المراد حساب مضروبه الخطوة 2: تعريف متغير مساعد وليكن i وهو عبارة عن عدد صحيح يأخذ قيمة متغيرة بين الواحد والعدد نفسه ويساعدنا على حساب القيمة المطلوبة. الخطوة 3: تهيئة المتغير factorial الذي يمثل القيمة المؤقتة للمضروب، والمتغير i الذي يمثل المرحلة التي نحن فيها أثناء تنفيذ الخوارزمية بالقيمة واحد أي نجعل factorial = 1 و i = 1 الخطوة 4: إعادة تعيين قيم المتغير factorial بالقيمة factorial*i والمتغير بالقيمة i+1 الخطوة 5: كرر الخطوة 3 حتى تصبح قيمة المتغير i أكبر تمامًا من n الخطوة 6: قم بإيقاف الخوارزمية وإعادة قيمة factorial التي تمثل مضروب العدد n الصورة التالية توضح طريقة رسم المخطط الانسيابي لحل خوارزمية حساب مضروب عدد: هل تعرف طرقًا أو أساليب أخرى لحل هذه المسألة؟ شاركنا إياها في قسم التعليقات أسفل المقال. خوارزمية للعثور على أكبر عدد من بين ثلاثة أعداد سنكتب حل هذه المسألة بأكثر من خوارزمية أو طريقة: طريقة 1: الدخل: 3 أرقام a و b و c الخرج: العدد الأكبر من بينها a أو b أو c المتن: الخطوة 1: أدخل الأرقام الثلاثة وخزنها في المتغيرات a و b و c على التوالي. الخطوة 2: تحقق من كون الرقم الأول a أكبر من الرقم الثاني b و الثالث c عندها اطبع أن a هو العدد الأكبر بين الكل وأنهي التنفيذ الخطوة 3: تحقق من كون b أكبر من a و c عندها اطبع أن b هو العدد الأكبر بين الكل وأنهي التنفيذ الخطوة 4: تحقق من كون c أكبر من a و b عندها اطبع أن c هو العدد الأكبر بين الكل وأنهي التنفيذ الكود الزائف للتعبير عن خوارزمية أكبر عدد بين 3 أعداد: Step-1 Start Step-2 Read three numbers a,b,c Step-3 If a>b then go to step-5 Step-4 IF b>c THEN print b is largest ELSE print c is largest ENDIF GO TO Step-6 Step-5 IF a>c THEN print a is largest ELSE print c is largest ENDIF Step-6 Stop والمخطط الانسيابي للتعبير عن الخوارزمية هو كما يلي: لعلك لاحظت أن الطريقة أعلاه تتطلب اختبار الكثير من الشروط حتى نصل لقرار حول العدد الأكبر من بين الأعداد الثلاثة، دعنا نحاول حلها بطريقة أبسط. كما تلاحظ فإن خوارزمية مقارنة ثلاثة أعداد حتى نصل لقرار حول العدد الأكبر من بين الأعداد الثلاثة تطلبت إجراء خطوتين والمرور مرتين على كل عدد، ولكن ماذا لو كان لدينا 10 أعداد أو أكثر ستزداد الخطوات ومرات المرور على الأعداد وسيزاد زمن الحل وتعقده لذا من الأفضل أن نفكر بطريقة أفضل تمكننا من المرور مرة واحدة على الأعداد ومعرفة العدد الأكبر من بينها. يمكن أن نخزن الأعداد في بنية واحدة مثل المصفوفة ثم نقرأها واحدًا تلو الآخر ونعتبر أن أول عدد هو الأكبر من بين كل الأعداد وكلما قرأنا عددًا جديدًا نقارنه بالذي قبله مباشرة فإن كان أكبر منه نبدل بينهما وإن كان أصغر منه أو يساويه لا نقوم بأي إجراء. لنطبق هذه الطريقة لإيجاد العدد الأكبر من بين ثلاثة أعداد طريقة 2: الدخل: 3 أرقام a و b و c الخرج: max الذي يمثل العدد الأكبر المتن: الخطوة 1: أدخل الأعداد الثلاثة وخزنها في a و b و c على التوالي الخطوة 3: افترض أن العدد الأول a هو الأكبر max = a الخطوة 4: إذا كان العدد الثاني b أكبر من max اجعل max = b الخطوة 5: إذا كان العدد الثالث c أكبر من أكبر من max اجعل max = c الخطوة 6: اعرض قيمة max الكود الزائف للتعبير عن هذه الخوارزمية لإيجاد أكبر عدد من بين 3 أعداد: Step-1 Start Step-2 Read three numbers: a,b,c Step-3 max = a Step-4 IF b > max THEN max = b ENDIF Step-5 IF c > max THEN max = c ENDIF Step-6 print max Step-7 Stop والمخطط الانسيابي للتعبير عن الخوارزمية هو كما يلي: هل لديك خوارزمية أخرى أفضل لحل هذه المسألة؟ يمكن أن تشاركنا إياها لنتناقش حولها. كما تلاحظ فقد مررنا مرة واحدة على الأعداد وعرفنا أيها أكبر، وهذا لن يختلف لو كان لدينا قائمة تحوي 100 عدد أو أكثر، هذا المفهوم ببساطته يسمى بكفاءة الخوارزمية أو تعقيد الخوارزمية والذي يشار إليه برمز Big O وستجده دومًا في أي موضوع يتناول الخوارزميات، لأن من شروط كتابة الخوارزميات أن تكون ذات كفاءة وأقل تعقيدًا ممكنًا. فكل الخوارزميات تعطي في النهاية الخرج الصحيح نفسه ولكن تتميز عن بعضها بكفاءة وكيفية وسرعة الوصول للخرج الصحيح، وهنا تبرز أهمية التفكير المنطقي وضرورة دراسة الخوارزميات وبنى المعطيات لمعرفة الحل الأكثر كفاءة لحل أي مسألة برمجية تواجهها وسنتحدث عن هذا الموضوع بالتفصيل تاليًا في فقرة "تحليل الخوارزميات". هل ترغب في تطوير موقع إلكتروني احترافي؟ وظّف مطور ويب خبير لبرمجة موقعك من مستقل أضف مشروعك الآن تحويل الخوارزمية إلى برنامج حاسوبي إن طرق تمثيل الخوارزمية مفهومة وواضحة لنا كبشر لكنها في الواقع غير قابلة للاستخدام والتطبيق على الحاسوب، لأنّ الخوارزميات خطط عامة ومجرّدة لحل المشاكل. فإن أردنا استخدام الخوارزمية لحل مشكلة ما، فسيكون علينا ترجمتها أو التعبير عنها بإحدى لغات البرمجة كي يفهمها الحاسوب ويعيد لنا النتائج المطلوبة، هذه العملية تُسمّى تحقيق الخوارزمية أو تنفيذ الخوارزمية implementation وينتج عن تحويل الخوارزمية إلى إحدى لغات البرمجة شيفرة برمجية قابلة للتنفيذ execution على الحاسوب. لنضرب مثالًا على ذلك سنحول الخوارزمية التي ذكرناها آنفًا والتي تحاول إيجاد أكبر عدد من بين ثلاثة أعداد إلى برنامج مكتوب بلغة بايثون حتى يتسنّى لنا تنفيذها على الحاسوب. تنفيذ خوارزمية إيجاد أكبر عدد من بين ثلاثة أعداد في لغة بايثون برنامج بايثون لإيجاد أكبر عدد من بين ثلاثة أعداد a = int(input('a= ')) b = int(input('b= ')) c = int(input('c= ')) max = a if b > max : max = b if c > max : max = c print(max, "هو العدد الأكبر") يمكنك الآن تنفيذ هذه الشيفرة على أيّ حاسوب وستعمل كما هو متوقع. كما يمكنك بالطبع تحقيق الخوارزمية بأيّ لغة برمجة أخرى تريدها مثل C أو C++‎ أو جافا أو جافا سكريبت أو R …إلخ. تمرين ما رأيك أن تجرب تحويل الخوارزمية السابقة إلى برنامج حاسوبي يطلب من المستخدم إدخال مجموعة أعداد تفصل بينها فراغات مثل 4 9 8 7 10 ليحللها البرنامج بتلك الخوارزمية ويعطي العدد الأكبر من بينها (مساعدة: ستحاول استعمال حلقات التكرار loops) مجالات استخدام الخوارزميات كانت الخوارزميات تُستخدم طوال آلاف السنوات من قبل علماء الرياضيات لحل المعادلات والمسائل الرياضية وما تزال إلى يومنا هذا. فالخوارزميات جزء لا يتجزأ من الرياضيات ابتداءً من حل المعادلات الجبرية، وحتى كتابة البراهين المنطقية. وتستخدم الخوارزميات اليوم على نطاق واسع في مجال البرمجة وعلوم الحاسب، فالحاسوب ليس سوى آلة تنفذ الأوامر بكفاءة وسرعة على عكس البشر، الذين يفهمون المطلوب ويحللونه ويفكرون بأدمغتهم لوضع الخوارزميات ثم ينفذونها بواسطة الحاسوب. لذلك، تحتاج إلى تبسيط ووضع خوارزمية للحاسوب لينفذها لك بحذافيرها وبأفضل أداء ممكن. وكل البرامج والتطبيقات وأنظمة التشغيل تعتمد على الخوارزميات وتستخدمها من أجل معالجة البيانات وإجراء الحسابات وحلّ مشكلات العمل كما تستخدم الخوارزميات في عدة مجالات أخرى مثل الفيزياء وتحليل اللغات والاقتصاد وغيرها من مناحي الحياة وهي تطبق اليوم في كل شيء نستخدمه من حولنا ومن أبرز الأمثلة على مجالات استخدام الخوارزميات في حياتنا اليومية نذكر: خوارزميات التواصل الاجتماعي التي تتحكم فيما تراه على مواقع التواصل الاجتماعي خاصتك خوارزميات محركات البحث التي تحسن عمليات البحث وتتنبأ بما سيكتبه المستخدمون. خوارزميات كشف الجرائم باستخدام تقنيات التعرف على الوجه ورسم الخرائط التنبؤية لتوقع الجرائم واتخاذ الإجراءات لمنعها. خوارزميات التشفير التي تقوم بتحويل نص مفهوم إلى نص غير مفهوم وتُستخدم لحماية البيانات المهمة بحيث لا يفهمها إلّا الأشخاص الذين وجهت إليهم. خوارزميات التنبؤ بحالة الطقس ودرجة الحرارة بمساعدة البيانات السابقة وهي تفيد في عدة مجالات أهمها الزراعة والطيران والاتصالات والحروب. خوارزميات تحديد مواعيد وصول الحافلات وجدولتها بأفضل طريقة. خوارزميات تحديد مواقف السيارات المتاحة لمساعدة السائقين على العثور على وجهتم بسرعة وسهولة. خوارزميات توجيه المركبات إلى أفضل طريق. خوارزميات تعديل مسارات الصواريخ. وغيرها الكثير من مجالات الحياة المختلفة في الاقتصاد والعلوم والإعلام وما شابه التي تلعب فيها الخوارزميات دورًا فعالًا وحيويًا، على سبيل المثال عرضت نيتفليكس جائزة قدرها مليون دولار لمن يطور خوارزميتها المستخدمة في اقتراح الأفلام والمسلسلات على الزوار ويجعلها أفضل بنسبة 10%. مواصفات الخوارزمية الجيدة قد تتساءل وهل هناك خوارزمية جيدة وأخرى ليست كذلك؟ وما الذي يجعل الخوارزمية جيدة؟ والجواب هو نعم فكما أنّ هناك وصفات طبخة سيئة ولا تنجح، فكذلك هناك خوارزميات سيئة وغير عملية ولا تصلح للتطبيق، فليست كل سلسلة متتابعة من الخطوات والتعليمات خوارزمية، بل لابد أن تتوفر فيها شروط خاصة تجعلها عملية وقابلة للتطبيق مثل: الوضوح: ينبغي أن تكون كل خطوة من خطوات الخوارزمية واضحة ومفهومة ولا لبس فيها. المحدودية: يجب أن تكون الخوارزمية محدودة، أي أن تكون خطواتها منتهية، وتُنفّذ في مدة زمنية منتهية. فإن كان عدد الخطوات غير منته، أو كان بإمكان إحدى الخطوات أن تستغرق مدة لا منتهية، فإنّها ليست خوارزمية. البساطة والواقعية: ينبغي أن تكون الخوارزمية قابلة للتطبيق بالموارد والتقنيات المتاحة، ولا ينبغي أن تعتمد على تقنية مستقبلية أو غامضة. قابلية التطبيق: يعني الاستقلالية عن لغات البرمجة أي لا ينبغي أن تكون الخوارزمية مرتبطة بلغة برمجة محددة، ويجب أن تكون مجردة وعامّة بحيث تركز على العمل الأساسي للبرنامج بدلًا من التركيز على خصائص لغة برمجة معينة وبعدها يمكن تطبيقها عبر أي لغة برمجة. صحة النتائج: يجب أن تقوم الخوارزمية بتنفيذ المهمة المطلوبة منها دون أخطاء في التنفيذ أو عدم دقة في النتائج. الكفاءة والفعالية: ينبغي أن تستخدم الخوارزمية أفضل الطرق لحل المشكلة بأسرع وقت تنفيذ أو ما يعرف بالتعقيد الزماني للخوارزمية وأقل مساحة ذاكرة أو ما يعرف بالتعقيد المكاني للخوارزمية. هل أحتاج إلى معرفة الرياضيات لتعلم الخوارزميات؟ الجواب هو نعم ولا، وكي أوضح إجابتي أكثر ، فالخوارزميات تُستخدم أساسًا لحل مشاكل حسابية، مثل متوسط مجموعة من القيم، أو أقصر مسار بين نقطتين في شعبة، أو أسهل طريقة لرسم شكل هندسي، أو ترتيب عناصر مصفوفة. كل هذه المشاكل تنطوي على قدر من الرياضيات الأساسية، لذلك فالجواب هو نعم. لكن إن كنت تقصد بمعرفة الرياضيات أنّه ينبغي أن تكون لك شهادة جامعية في الرياضيات، أو تكون لك معرفة عميقة أو حتى متوسطة بها، فالجواب سيكون لا لأنّ الخوارزميات لا تتطلب معرفة عميقة بمفاهيم الرياضيات. تذكر أنّ الخوارزميات هي طرق عامة لحل المشاكل والمسائل الحسابية، لذلك فمقدار الرياضيات التي تحتاجها يتعلق بنوع المشكلة التي تريد حلها، إن كنت تريد حل مشكلة معقدة، مثل التنبؤ بالمناخ، فعلى الأرجح أنّ الخوارزمية ستكون معقدة وتحتاج إلى معرفة متقدمة بالرياضيات لكن لا تدع هذا يخيفك ويصدّك عن تعلم الخوارزميات، إذ أنّ معظم المسائل التي ستُواجهها هي مشاكل لا تحتاج إلا إلى معرفة بسيطة بأساسيات الرياضيات، مثل العمليات الحسابية البسيطة. خلاصة القول هو أنك لا تحتاج إلى تعلم الرياضيات لكي تتعلم الخوارزميات، فما دمت تفهم كيف تجري العمليات الحسابية البسيطة، مثل الجمع والضرب، وبعض المفاهيم البسيطة، مثل المجموعات والدوال وطرق حل المعادلات فيمكنك أن تتعلم الخوارزميات بسهولة. لكن النقطة الأهم هي الارتباط بين التفكير المنطقي أو طرق حل المشكلات وبين الخوارزميات والبرمجة، فالتفكير المنطقي هو بلا شك مهارة ضرورية للبشر عمومًا وللمبرمجين على وجه الخصوص ومن الضروري تعليمه للأطفال من سن مبكرة لمنحهم هذه المهارة المهمة والضرورية جدًا لنجاحهم في مستقبلهم المهني. تحليل الخوارزميات الخوارزمية هي في الأصل خطة لحل مشكلة حسابية فإن لم تكن تملك خطة مُسبقة لحل مشكلة معقدة، فستفشل محاولاتك على الأرجح لحل تلك المشكلة وحتى لو كانت المشكلة بسيطة، فقد يكون هناك العديد من الحلول، وبعض هذه الحلول أسرع وأكفأ من بعض. من هنا تأتي أهمية تحليل الخوارزميات الذي يهتم بدراسة كفاءة الخوارزميات من ناحية الوقت والذاكرة التي يحتاجها تنفيذ الخوارزمية واختيار الحل الأبسط والأسرع والأقل استهلاكًا للموارد، أو بلغة الحوسبة، تريد أن تخفض تعقيد الخوارزمية Algorithms Complexity إلى أقصى حد ممكن. يشمل تعقيد الخوارزمية كل الموارد الضرورية لحل المشكلة، إن كانت الخوارزمية خوارزميةَ طبخ، فإنّ تعقيدها سيكون الوقت والطاقة اللازمة لإعداد الوجبة. أما إن كانت الخوارزمية تسعى لحل مشكلة في الرياضيات، سيكون تعقيدها هو الوقت اللازم لإجراء خطوات الخوارزمية. أما إن كانت الخوارزمية حاسوبية، فإنّ تعقيدها سيكون الوقت ومساحة الذاكرة الضروريان لتنفيذ خطوات الخوارزمية. لهذا السبب ابتكر العلماء فرعًا كاملًا في علم الخوارزميات مُخصّصًا لتقدير تعقيد الخوارزميات يُسمّى نظرية التعقيد، والذي يصنّف الخوارزميات إلى أصناف بحسب تعقيدها الزماني Time Complexity الذي يصف مقدار الوقت الذي يستغرقه تنفيذ الخوارزمية. وتعقيدها المكاني أو ما يسمى بتعقيد المساحة Space Complexity الذي يمثل عدد خلايا الذاكرة اللازمة لتنفيذ عمليات الخوارزمية مع استثناء المساحة المخصصة لدخل الخوارزمية. يتم التعبير عن تعقيد الخوارزمية بتدوين خاص يسمى Big O notation وهو طريقة لوصف تعقيد الخوارزمية الزمني باستخدام مصطلحات جبرية وأدنى هذه الأصناف هو الصنف O(1)‎، والذي يعني أنّ الخوارزمية تستغرق وقتا ثابتًا لحل المشكلة مهما كان حجم الدخل كما في خوارزمية معرفة كون العدد فردي أم زوجي مثلًا أو خوازرمية طباعة أول رقم من بين قائمة من الأرقام، أما الصنف O(n)‎ فَيعني أنّ مدة تنفيذ الخوارزمية متناسبة مع حجم الدخل n كما في خوارزمية حساب مضروب العدد وخوازمية إيجاد أكبر عدد من بين مجموعة من الأعداد. وإليك قائمة مختصرة بأشهر أنواع تعقيد الخوارزميات وفق تدوين Big O ودلالة كل منها: O(1)‎ تعقيد زمني ثابت: أي تستغرق الخوارزمية نفس الزمن مهما كان حجم الدخل. O(n)‎ تعقيد زمني خطي: أي يتناسب زمن تنفيذ الخوارزمية بشكل خطي مع حجم الدخل، بمعنى آخر إذا كان حجم الدخل n فإن عدد الخطوات المطلوب لحلها سيكون n على الأكثر. O(sqrt(n)) تعقيد جذر تربيعي: أي إذا كان حجم دخل الخوازرمية هو n سوف يتناسب زمن تنفيذ الخوارزمية مع الجذر التربيعي لقيمة الدخل. O(n^c)‎ تعقيد كثير الحدود: يتناسب زمن تنفيذ الخوارزمية مع حجم الدخل مرفوع للأس c وله أنواع فقد يكون تعقيد زمني تربيعي O (n^²)‎ أي يتناسب زمن تنفيذ الخوارزمية مع مكعب حجم الدخل أو تعقيد زمني تكعيبي O(n^3)‎ أي يتناسب زمن تنفيذ الخوارزمية مع مكعب حجم الدخل. O(log n)‎ تعقيد لوغاريتمي: تناسب زمن تنفيذ الخوارزمية مع لوغاريتم حجم الدخل. O(n log n)‌‎ تعقيد لوغاريتمي خطي: وهو أبطأ قليلاً من الخطي O(2^n)‎ تعقيد أسي: وفيه تتضاعف خطوات الخوارزمية بشكل أسي مع زيادة حجم الدخل. O(n!)‎ تعقيد عاملي: أي يتناسب زمن الخوارزمية مع قيمة عاملي الدخل أي ضرب جميع الأعداد الصحيحة الموجبة الأصغر من قيمة الدخل. يمكنك أن تجد حلًا للمشاكل بدون الخوارزميات، لكن من النادر أن يكون ذلك الحل الذي وجدته هو الحل الأفضل والأكفأ، وهذه فائدة تحليل الخوارزميات فهو يمكّنك من العثور على الحل الأمثل والأنسب والأقل استهلاكًا للموارد. للمزيد من المعلومات أنصح بمطالعة مقال مدخل إلى تحليل الخوارزميات ومقال الدليل الشامل عن تعقيد الخوارزميات أنواع الخوارزميات البرمجية الخوارزميات هي خطط عامة لحل المشاكل وتتنوع أساليب وأنواع الخوارزميات بحسب الأسلوب الذي تتبعه الخوارزمية لحل المشكلة أو بحسب نوع المشكلة التي تحلها، وبناء على ذلك يمكن أن نجد أنواعًا مختلفة من الخوارزميات ومن أبرزها: خوارزميات القوة الغاشمة Brute force algorithms : تحاول الخوارزميات من هذا النوع حل المشكلة بطريقة مباشرة وتمر بجميع الخيارات الممكنة حتى تتمكن من العثور على حل لهذه المشكلة. الخوارزميات الجشعة Greedy algorithms: تحاول الخوارزميات الجشعة حل المشكلة خطوة فخطوة، بحيث تقترب رويدًا رويدًا من الحل العام للمشكلة. خوارزميات البرمجة الديناميكية Dynamic Programming: تقسّم خوارزميات البرمجة الديناميكية المشكلة إلى مشاكل فرعية أبسط، ثمّ تحل تلك المشاكل الفرعية لاستنتاج الحل النهائي خوارزميات فرق تسد Divide and conquer algorithms: تقسِّم خوارزميات فرِّق تسد المسألة إلى مسائل فرعية تشبه المسألة الأصلية، ثمّ تحلها وتدمج الحلول لتقديم حلٍّ المسألة الأصلية. خوارزميات التعقب الخلفي Backtracking algorithms: تحاول خوارزميات التعقب الخلفي حل المشكلة تعاوديًا عبر بناء الحل تصاعديًا خطوة فخطوة، مع حذف الحلول التي لا تستجيب للقيود التي تفرضها المسألة المُراد حلها في أيّ وقت أثناء تنفيذ الخوارزمية. خوارزميات الترتيب Sort algorithms: هي خوارزميات ترتب مجموعة من العناصر القائمة في ترتيب معين رقمي أو هجائي. والفرز هو أحد الخطوات الهامة في الخوارزميات الأكثر تعقيدًا، توجد عدة خوارزميات تمكننا من تحقيق عملية الفرز ولكل منها ميزاتها ومحدوديتها. خوارزميات البحث Search algorithms: هي خوارزميات تقوم بتحديد موقع بيانات محددة بين مجموعة من البيانات أي أنها تبحث عن البيانات المخزنة ضمن بعض الهياكل أو بنى البيانات وتقوم باستردادها. خوارزميات التعلم الآلي: هي خوارزميات تحاول التعلم بناءً على مجموعة من حالات اتخاذ القرار السابقة كي تتمكن من اتخاذ قرارات معقدة بناءً عليها. خوارزميات التشفير: هي الخوارزميات التي تقوم بتحويل نص مقروء إلى نص غير مقروء يُعرف باسم النص المشفر بحيث يمكن للأطراف المصرح لهم فقط بفهم المعلومات الموجودة في هذا النص وهي خوارزميات هامة جدًا في مجال أمن البيانات الحساسة والحفاظ على الخصوصية. كانت تلك بعض أنواع وتصنيفات الخوارزميات الأكثر شيوعًا وهناك بالطبع العديد من الخوارزميات الأخرى للعديد من الحالات المختلفة. هناك أيضًا طرق أخرى يمكن تطبيقها بسهولة في التطبيقات مثل خوارزمية Dijkstra و Cycle Detection و Kruskal Minimum Spanning Trees فهي من الخوارزميات الأساسية للمبتدئين للتعلم منها. أهمية الخوارزميات في البرمجة هناك من قد يقول أنّ تعلم الخوارزميات تَرفٌ، وهو غير ضروري لكتابة البرامج والتطبيقات، وأنّه يمكن للمبرمج أن يكتب برامجه مباشرة دون الحاجة إلى مفاهيم الخوارزميات. صحيح أنّه ليس عليك أن تكون خبيرًا في الخوارزميات لتَكون مبرمجًا، لكن لا يمكنك أن تكون مبرمجًا بارعًا ومحترفًا دون أن تتعلم فن تصميم الخوارزميات. يوفر تعلم الخوارزميات للمبرمج العديد من الفوائد أبرزها: القدرة على حل المشكلات بشكل أفضل الاستخدام الفعال للموارد الحاسوبية يوفر وقت البرمجة يجعل منك مبرمجًا أفضل لنناقش كل فائدة منها بمزيد من التفصيل ونتعرف كيف يسهم تعلم الخوارزميات في تعزيزها. القدرة على حل المشكلات بشكل أفضل سيحسن تعلمك لطرق حل الخوارزميات من قدرتك على حل المشكلات بصورة عامة والمشكلات البرمجية على وجه الخصوص، ويكسبك مرونة ذهنية في التفكير في الحلول ويساعدك لاحقًا في كتابة البرامج الحاسوبية المتنوعة أيًا كانت اللغة البرمجية المستخدمة خصوصًا بأنّ الخوارزميات مستقلة عن لغات البرمجة، لذا يمكنك استخدامها مهما كانت لغة البرمجة التي تعمل عليها. الاستخدام الفعال للموارد يضمن لك اختيار الخوارزمية الصحيحة الاستخدام المناسب للموارد مثل الذاكرة والتخزين والشبكة وغيرها. فلا يكفي أن تكون الفكرة التي بنيت عليها البرنامج أو التطبيق مفيدة ومبتكرة، ينبغي أن تكون عملية بحيث ينفّذها الحاسوب أو الجوال في وقت معقول وموارد محدودة، فما فائدة تطبيق رسم يحتاج دقيقة كاملة ليرسم مربعًا، وما فائدة برنامج يحتاج إلى 10 جيجابايت من الذاكرة ليعمل! توفير وقت البرمجة يوفر عليك تعلم الخوارزميات الكثير من الوقت، إذ أنّ معظم المشاكل والمسائل التي قد تعترضك أثناء كتابة البرامج لها حلول جاهزة على هيئة خوارزميات مُحسّنة وسريعة، ما يغنيك عن إعادة اختراع العجلة في كل مرة تعترضك مشكلة ما، لأنّ هناك من حلّها قبلك على الأرجح وأعدّها على هيئة خوارزمية وكل ما عليك فعله هو تحويلها إلى لغة البرمجة التي تستعملها ثم تنفّذها وقد لا تضطر حتى إلى تنفيذها فمعظم الخوارزميات الشهيرة والفعالة مثل خوارزميات البحث والفرز تدمج في لغات البرمجة بشكل مكتبات جاهزة يمكنك استخدامها في شيفراتك البرمجية. الخوارزميات تجعل منك مبرمجًا أفضل تعلم الخوارزميات سيجعلك مبرمجًا أفضل وأكثر احترافية، فسَواء كنت متخصصًا في تطبيقات الجوال أو تطبيقات سطح المكتب، أو في بناء المواقع أو تصميم الألعاب أو غيرها من مجالات البرمجة، فإنّ تعلم الخوارزميات سيوسع أفق تفكيرك البرمجي ويساعدك على تطوير برامج أجود وأسرع وأكثر موثوقية. أهم مصادر تعلم الخوارزميات هناك للأسف ضعف في المحتوى العربي التقني، هذا الضعف يظهر أكثر ما يظهر في مجالات الخوارزميات. ولسدّ هذا القصور في المحتوى العربي فقد وفرت أكاديمية حسوب العديد من مصادر التعلم القيمة باللغة العربية. فنظرًا للأهمية الكبيرة للخوارزميات في كافة مجالات البرمجة، وفي غيرها من المجالات مثل الرياضيات والتنمية وغيرها، فقد وفرت لك أكاديمية حسوب دورة علوم الحاسب والتي تتضمن مسارات متعددة يحتاجها أي مبتدئ في تعلم البرمجة من أهمها مسار الخوارزميات وبنى المعطيات الذي يعلمك خطوة بخطوة كيفية كتابة الخوارزميات وتحليلها ويعرفك على أهم الخوارزميات التي تفيدك في عملك البرمجي مثل خوارزميات البحث والترتيب والخوارزميات الرياضية وخوارزميات الرسوم البيانية وغيرها الكثير. كما نشرت الأكاديمية سلسلة الخوارزميات للمحترفين التي تشرح الخوارزميات بالتفصيل وتغطّي كافة مفاهيمها الأساسية مثل مفهوم التعقيد لتقدير الموارد التي تستهلكها البرامج كالوقت والذاكرة. إضافة إلى مفاهيم البرمجة الديناميكية، وبعض أنماط الخوارزميات العامة. تلك السلسلة غنية بالأمثلة التطبيقية، إذ تستعرض الكثير من الخوارزميات لحل بعض المشاكل التقليدية في علم الحاسب خصوصًا تلك المتعلقة بالأشجار وترتيب المصفوفات والبحث، علاوة على طائفة من الخوارزميات المتنوعة في مجالات الجبر والهندسة ونظرية الأعداد. كما أن السلسلة تنفذ الخوارزميات التي تستعرضها من خلال العديد من لغات البرمجة، فمهما كانت لغة البرمجة خاصتك، سواء كانت بايثون أو جافا أو C++/C أو #C‏‏ أو جافا سكريبت، فستجد أمثلة بهذه اللغات وغيرها في هذا الكتاب. وستجد كذلك توثيقًا شاملًا عن الخوارزميات في موسوعة حسوب يضم توثيقات لأهم الخوارزميات المُستخدمة في البرمجة. وننصحك كذلك بأن تشترك في قناة أكاديمية حسوب على يوتيوب وستجد فيها الكثير من الدروس المفيدة والمواضيع الشيقة حول البرمجة والخوارزميات والتفكير المنطقي وغيرها الكثير. وأخيرًا إذا كنت تتساءل هل يجب علي كمبتدئ أن أتعلم الخوارزميات أولًا أم أتعلم إحدى لغات البرمجة أولًا فنصيحتي لك أن تبدأ كخطوة أولى بالتعرف على أساسيات البرمجة وبعد التمكن منها يمكنك البدء بتعلم الخوارزميات وتطوير تفكيرك البرمجي والخوارزمي على التوازي في رحلة التعلم حتى تصل للاحتراف في كليهما. إذا أتقنت تعلم الأساسيات يمكن أن تنتقل لتعلم الأمور المتقدمة وستجد في قسم البرمجة ضمن وتحديدًا في قسم "مقالات برمجة متقدمة" في أكاديمية حسوب مجموعة متنوعة من المقالات المتقدمة التي تزيد معرفتك وخبرتك في مجال الخوارزميات وفي حال واجهك أي سؤال يمكنك طرحه في قسم الأسئلة والأجوبة في الأكاديمية. الخلاصة تعرفنا في مقال اليوم ما هي الخوارزمية وأهمية الخوارزميات في علوم الحاسب وهندسة البرمجيات، وتعرفنا على خطوات حل الخوارزمية وطرق التعبير عن الخوارزميات بالشيفرة الوهمية والمخططات الانسيابية ثم تحويلها بعد ذلك إلى برامج حاسوبية من خلال الأمثلة العملية البسيطة التي تناسب المبتدئين. كما تعرفنا في الختام على أبرز الفوائد التي تجنيها كمبرمج من تعلم الخوارزميات، وأهم المراجع العربية التي تشرح الخوارزميات من الصفر للاحتراف، فإذا كنت تسعى لتكون مبرمجًا محترفًا فتعلم الخوارزميات أحد الأمور المهمة التي ينبغي أن تضعها في الحسبان لتساعدك على تحقيق هذا الهدف. اقرأ أيضًا أمثلة عن أنواع الخوارزميات تعرف على تخصص هندسة البرمجيات مهندس البرمجيات من هو وما هي مهامه ما هي مدة تعلم البرمجة؟
    1 نقطة
  18. تعرفنا في المقال السابق على خوارزمية أقرب الجيران K-Nearest Neighbors، ووضحنا كيفية استخدامها عمليًا من خلال تمارين وتطبيقات متنوعة، وسنشرح اليوم خوارزمية أساسية من خوارزميات الذكاء الاصطناعي وهي خوارزمية الانحدار اللوجيستي Logistic Regression مع تطبيقات عملية باستخدام مكتبة ساي كيت ليرن ومجموعة بيانات أزهار آيرس Iris dataset. سنمر في البداية على جميع الخطوات التي تدربنا عليها في الأجزاء السابقة بإيجاز، ثم سنشرح آلية عمل خوارزمية الانحدار اللوجيستي المستخدمة بشكل أساسي في مهام التصنيف الثنائي binary classification، كما سنتطرق لبعض الطرق التي تسمح لنا باستخدام هذه الخوارزمية مع مهام التصنيف المتعدد multi classification. مفهوم الانحدار اللوجيستي تحليل الانحدار regression analysis هو أداة إحصائية مفيدة لفهم العلاقة بين متغيرات مختلفة، يساعدنا على تخمين أو توقع كيف يؤثر شيء ما يسمى المتغير المستقل independent variable على شيء آخر يسمى المتغير المعتمد dependent variable. مثلًا يمكننا معرفة كيف يؤثر عدد ساعات الدراسة على درجات الطلاب في الامتحان من خلال تحليل الانحدار واكتشاف العلاقة بين هذين المتغيرين وتحديد إن كان عدد الساعات يؤثر فعلاً في الدرجات أم لا، وفي مجموعة بيانات أزهار آيرس يمكننا استخدامه لاستكشاف العلاقة بين طول السبلة Sepal length وعرض البتلة Petal width على سبيل المثال. هناك نوع خاص من الانحدار يطلق عليه اسم الانحدار اللوجيستي Logistic Regression نستخدمه عندما نريد التنبؤ بنتيجة تصنيف ثنائي binary classification نتيجته إما نعم أو لا، حيث تستخدم خوارزمية الانحدار اللوجيستي logistic regression دالة سينية sigmoid function تسمى بالدالة اللوجيستية logistic function والتي تحوّل المدخلات إلى قيم تقع بين الصفر والواحد مما يجعلها مناسبة لمهام التصنيف الثنائي. يمكننا أن ننظر إلى طريقة عمل خوارزمية الانحدار اللوجيستي على أنها خوارزمية تتكون من خطوتين الأولى هي إيجاد أفضل معادلة خطية تربط بين المدخلات أو المتغيرات المستقلة وبين المخرجات أي المتغيرات المعتمدة، بحيث نوجد أفضل خط يساير fitting البيانات، كما في خوارزمية توقع الانحدار الخطي. الخطوة الثانية هي تحويل القيمة المستمرة الخارجة من خوارزمية توقع الانحدار الخطي إلى احتمالية بين الصفر والواحد باستخدام الدالة اللوجيستية logistic function، والتصنيف ذو الاحتمال الأكبر هو توقع النموذج. يمكننا كذلك استخدام خوارزمية الانحدار اللوجيستي مع مشكلات التصنيف المتعدد multi classification باستخدام خدعة بسيطة تسمى واحد ضد الجميع One Vs All والتي تعرف اختصارًا OVA، حيث نعمل على تدريب عدد من المصنفات الثنائية binary classifiers يساوي عدد التصنيفات classes الموجودة في البيانات، وتكون مهمة كل مصنف classifier التمييز بين تصنيف محدد ونرمز له رقميًا بواحد 1 وما دون ذلك من التصنيفات نرمز لها جميعًا بصفر 0. يمكننا في مكتبة scikit-learn، استخدام خوارزمية الانحدار اللوجستي لمهام التصنيف المتعدد باستخدام الدالة softmax التي تحدد احتمالية انتماء كل عينة إلى إحدى التصنيفات المتعددة، بحيث يكون مجموع الاحتمالات لجميع التصنيفات classes مساويًا لواحد، بينما نستخدم الدالة sigmoid في مهام التصنيف الثنائي فقط. استكشاف مجموعة البيانات Data Exploring سنكتب برنامج بايثون لعرض المعلومات الإحصائية الأساسية لفصائل أزهار آيرس المختلفة Iris-setosa و Iris-versicolor و Iris-virginica على النحو التالي: import pandas as pd iris = pd.read_csv("iris.csv") # قائمة بجميع الفصائل SpeciesList = iris.Species.value_counts().index # حلقة تكرارية لحساب الإحصائيات لكل فصيلة for s in SpeciesList: print(f"Statistics about {s}") # حساب الإحصائيات لشريحة البيانات التي تنتمي للفصيلة الحالية print(iris[iris.Species == s].describe()) يعمل الكود السابق على توليد إحصائيات وصفية لكل فصيلة من فصائل الأزهار الموجودة في المجموعة. حيث يسمح لنا الشرط [iris[iris.Species == s باختيار العينات التي تحقق هذا الشرط، أي أننا سنختار في كل تكرار للحلقة العينات التي تنتمي للفصيلة s ثم سنستخدام التابع data.describe()‎ للحصول على معلومات إحصائية تخص هذه العينات، مثل أكبر وأصغر قيمة في البيانات والمتوسط الحسابي للقيم والانحراف المعياري. عند تنفيذ الكود سنحصل على الخرج التالي: Statistics about Iris-setosa Id SepalLengthCm SepalWidthCm PetalLengthCm PetalWidthCm count 50.00000 50.00000 50.000000 50.000000 50.00000 mean 25.50000 5.00600 3.418000 1.464000 0.24400 std 14.57738 0.35249 0.381024 0.173511 0.10721 min 1.00000 4.30000 2.300000 1.000000 0.10000 25% 13.25000 4.80000 3.125000 1.400000 0.20000 50% 25.50000 5.00000 3.400000 1.500000 0.20000 75% 37.75000 5.20000 3.675000 1.575000 0.30000 max 50.00000 5.80000 4.400000 1.900000 0.60000 Statistics about Iris-versicolor Id SepalLengthCm SepalWidthCm PetalLengthCm PetalWidthCm count 50.00000 50.000000 50.000000 50.000000 50.000000 mean 75.50000 5.936000 2.770000 4.260000 1.326000 std 14.57738 0.516171 0.313798 0.469911 0.197753 min 51.00000 4.900000 2.000000 3.000000 1.000000 25% 63.25000 5.600000 2.525000 4.000000 1.200000 50% 75.50000 5.900000 2.800000 4.350000 1.300000 75% 87.75000 6.300000 3.000000 4.600000 1.500000 max 100.00000 7.000000 3.400000 5.100000 1.800000 Statistics about Iris-virginica Id SepalLengthCm SepalWidthCm PetalLengthCm PetalWidthCm count 50.00000 50.00000 50.000000 50.000000 50.00000 mean 125.50000 6.58800 2.974000 5.552000 2.02600 std 14.57738 0.63588 0.322497 0.551895 0.27465 min 101.00000 4.90000 2.200000 4.500000 1.40000 25% 113.25000 6.22500 2.800000 5.100000 1.80000 50% 125.50000 6.50000 3.000000 5.550000 2.00000 75% 137.75000 6.90000 3.175000 5.875000 2.30000 max 150.00000 7.90000 3.800000 6.900000 2.50000 Index(['Id', 'SepalLengthCm', 'SepalWidth عرض العلاقة بين البيانات باستخدام التمثيل المرئي Data Visualization سننشئ الآن رسم بياني نقطي Scatter plot لعرض العلاقة بين طول السبلة Sepal length وعرض البتلة Petal width، لنحقق ذلك نكتب الكود التالي: import matplotlib.pyplot as plt import seaborn as sns iris = pd.read_csv("iris.csv") plt.figure(figsize=(7,7), dpi=150) sns.scatterplot(data=iris, x="SepalLengthCm", y="PetalWidthCm", hue="Species") plt.show() استوردنا في هذا الكود مكتبة matplotlib لضبط إعدادات الرسم البياني من أبعاد الشكل ودقة الصورة الناتجة، كما استوردنا مكتبة seaborn التي توفر واجهة استخدام سهلة ومرنة للرسم. بعدها مررنا للدالة sns.scatterplot المعامل data لتحديد مجموعة البيانات التي سنعمل عليها، وحددنا بأن المحور الأفقي سيكون طول السبلات، وأن المحور العمودي سيكون عرض البتلات، ستمثل كل زهرة بنقطة في الشكل الناتج وتلون كل نقطة وفقًا لانتمائها لأحد الفصائل الثلاثة في مجموعة بيانات أزهار آيرس. عند تنفيذ الكود سنحصل على الرسم البياني التالي: تصنيف فصائل الأزهار باستخدام خوارزمية الانحدار اللوجستي سنكتب الآن برنامج بايثون لتدريب نموذج الانحدار اللوجيستي Logistic Regression على مجموعة بيانات أزهار آيرس التي تحتوي على ثلاثة فصائل من الأزهار للتمييز فيما بينها، ثم نقيم أداء النموذج على مجموعة الاختبار. import pandas as pd from sklearn.model_selection import train_test_split from sklearn import metrics from sklearn.linear_model import LogisticRegression iris = pd.read_csv("iris.csv") # Id احذف عمود # لعدم أهميته في عملية التعلم iris = iris.drop('Id',axis=1) # خواص الأزهار X = iris.iloc[:, :-1].values # وسم الأزهار y = iris.iloc[:, 4].values # تقسيم مجموعة البيانات إلى مجموعة بيانات تدريب ومجموعة بيانات اختبار X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20) # إنشاء نموذج model = LogisticRegression(random_state=0, multi_class='multinomial') model.fit(X_train,y_train) prediction=model.predict(X_test) print('The accuracy of the Logistic Regression is', metrics.accuracy_score(prediction,y_test)) استوردنا في البداية عددًا من الدوال والمكتبات التي ستساعدنا في تدريب وتقييم النموذج، واستدعينا الدالة train_test_split لتقسم خاصيات مجموعة البيانات dataset features ووسوم البيانات dataset labels إلى مجموعتي تدريب واختبار كل منها يمتلك جزءًا من خاصيات مجموعة البيانات والوسوم المقابلة للعينات المختارة، وحددنا نسبة التقسيم باستخدام التعليمة test_size=0.20 لجعل عشرين بالمائة من مجموعة البيانات مجموعة اختبار، والنسبة الباقية للتدريب، ستُقسَم البيانات بشكل عشوائي في كل مرة نشغل بها الكود، ثم عرفنا كائن model يطبق خوارزمية الانحدار اللوجيستي ومررنا له المتغير random_state=0 لنضمن ثبات نتيجة تدريب النموذج عند تشغيل الكود أكثر من مرة، وحددنا نوع المشكلة بأنه تصنيف متعدد بضبط قيمة المعامل multi_class إلى multinomial. بعد أن هيئنا إعدادات النموذج سندربه على مجموعة بيانات التدريب باستخدام الدالة model.fit(X_train,y_train)‎، وبعد تدريب النموذج يمكننا استخدامه في تخمين الوسوم لمجموعة الاختبار باستخدام الدالة model.predict(X_test)‎. نخزن الناتج في القائمة prediction التي تحتوي محاولة النموذج لتوقع قيم y_test، ولتقييم دقة النموذج في هذه المحاولة نستخدم الدالة metrics.accuracy_score(prediction,y_test)‎ التي تحصي نسبة القيم التي توقعها النموذج بشكل صحيح إلى إجمالي جميع القيم. عند تنفيذ الكود سنحصل على الخرج التالي: The accuracy of the Logistic Regression is 0.9333333333333333 تعني النتيجة التي حصلنا عليها أن النموذج جيد جدًا في التنبؤ، لأنه أصاب في أكثر من 93% من الحالات فهذه النسبة تمثل نسبة العينات التي صنفها النموذج بشكل صحيح وتعرف باسم دقة النموذج، لكن الدقة ليست دائمًا المقياس الوحيد الكافي، خصوصًا في المشكلات التي يكون فيها عدد العينات في كل فئة غير متوازن لذا قد نحتاج لمقاييس إضافية لتقييم النموذج بشكل عادل. الخاتمة تعرفنا في هذه المقالة على خوارزمية الانحدار اللوجيستي Logistic Regression وكيف تعمل، وطبقناها باستخدام مكتبة ساي كيت ليرن على مجموعة بيانات أزهار إيرس، وقيمنا دقة النموذج على مجموعة بيانات اختبارية، يمكن مواصلة التدريب على مجموعات بيانات مختلفة أكبر في الحجم وتحتاج للمزيد من المعالجة، حيث تتوفر الكثير من مجموعات البيانات مفتوحة المصدر على موقع Kaggle. اقرأ أيضًا المقال السابق: استخدام خوارزمية أقرب الجيران k-Nearest Neighbors في Scikit-Learn تعرف على مكتبة Scikit learn وأهم خوارزمياتها الانحدار الإحصائي regression ودوره في ملاءمة النماذج المختلفة مع أنواع البيانات المتاحة العلاقات بين المتغيرات الإحصائية وكيفية تنفيذها في بايثون
    1 نقطة
  19. تخيل أن أمامك كومةً ضخمةً من ملفات PDF، وأنك بحاجة إلى إجابة سريعة على سؤال محدد. البحث اليدوي قد يستغرق ساعات، ولكن ماذا لو كان بالإمكان طرح سؤال على الآلة والحصول على إجابة دقيقة في ثوانٍ؟ أو ربما الحصول على تلخيص نصوص طويلة بلمسة زر واحدة؟ في الواقع، يمكن القيام بالأمر بسهولة، إذ لم يعد العثور على المعلومات الدقيقة واستخراجها أمرًا معقدًا بفضل تقنيات الذكاء الاصطناعي المتقدمة، وأحد أبرزها أنظمة RAG. أنظمة التوليد المعزز بالاسترجاع أو ما يُعرف اختصارًا بأنظمة RAG هي تقنية متقدمة في الذكاء الاصطناعي تجمع بين استرجاع المعلومات من مصادر خارجية وتوليد النصوص، مما يتيح تقديم إجابات أكثر دقة وأمان. تعمل هذه الأنظمة كوسيط ذكي بين البحث والتوليد، مما يسمح بفهم أعمق للمحتوى، والإجابة على الأسئلة المعقدة، وتلخيص النصوص الطويلة بكفاءة عالية، دون الحاجة إلى إعادة تدريب النموذج على بيانات جديدة باستمرار. فكرة المشروع الذي تحتويه المقالة يهدف هذا المشروع إلى تطوير نظام RAG يمكننا من الحصول على المعلومات المطلوبة بسرعة والحصول على ملخصات دقيقة للمفاهيم التي نحتاجها من كتاب طريقك إلى العمل الحر عبر الإنترنت، ويسمح بطرح الأسئلة حول محتوى الكتاب والحصول على إجابات موجزة، مما يسهل مراجعة المعلومات واستذكارها بكفاءة. سنعتمد في العمل على النظام على DeepSeek لاسترجاع المعلومات من الكتاب بدقة، بينما يُستخدم Ollama لإنشاء ردود ذكية قائمة على السياق المسترجع. مع ذلك هناك أمر مهم جدًا يجب توضيحه، رغم قوة DeepSeek-R1 الذي سنستخدمه في المقال مع اللغات الأجنبية، إلا أنه وللأسف لا يقدم أداءً مثاليًا مع اللغة العربية بسبب محدودية التدريب على النصوص العربية مقارنةً باللغات الأخرى مثل الإنجليزية. ولحل هذه المشكلة، تطلب منا الأمر استخدام نماذج أكبر مثل DeepSeek R1-70B للحصول على النتائج الدقيقة عالية الجودة التي ستجدها بالمقال، لكن تطبيقك لشبيه به، سيعتمد على توفر موارد حاسوبية كافية؛ أما في حال لم تكن هذه الموارد متاحة، فيمكن الاستفادة من نفس الطريقة لتطبيق النظام على نماذج أخرى تدعم اللغة العربية بكفاءة أكبر مثل Qwen، أو استخدامه مع لغات أخرى مثل الإنجليزية التي تتمتع بدعم أفضل. خطوات العمل على المشروع يعتمد مشروعنا على دمج مرحلتين أساسيتين: إسترجاع المعلومات: عند إدخال سؤال، يبدأ النظام بالبحث في قاعدة البيانات التي استخرجها من الكتاب عن أكثر المعلومات ذات الصلة، والتي تساعد في الإجابة على السؤال توليد توليد النصوص: بعد استرجاع المعلومات من قاعدة البيانات الخاصة بالكتاب، تُنقل لنموذج توليد النص، لينشئ لنا إجابة دقيقة تعتمد على المعلومات المسترجعة من الكتاب فقط تحضير بيئة العمل على المشروع من أجل تنفيذ هذا المشروع، سنحتاج إلى الأدوات الآتية: تحميل مكتبات وأطر عمل لغة بايثون المطلوبة سنستعمل في نظامنا المكتبات التالية: مكتبة HuggingFace Embeddings: وهي المكتبة المسئولة عن البصمات الرقمية للنصوص، حجمها خفيف وتلائم الأجهزة الضعيفة نسبيًا مكتبة PyPDFLoader: وهي المكتبة المسئولة عن التعامل مع ملفات PDF، سريعة المعالجة ولا تستهلك الكثير من الوقت مكتبة Faiss: وهي المكتبة المسئولة عن إنشاء قاعدة بيانات تخزن فيها المعلومات واسترجاعها عند الحاجة، وهي أشهر مكتبة حاليا وسنستعمل أطر العمل Frameworks التالية: إطار العمل Langchain: وهو البيئة المسئولة عن بناء تطبيقات الذكاء الاصطناعي المتكاملة إطار العمل Streamlit: المسئول عن توفير واجهة ويب تفاعلية لعرض النتائج بوضوح، نستعملها لبساطتها ولأنها توفر في ذاكرة الوصول العشوائي RAM إذا كنا نستعمل مثبّت conda أو mini-conda، فيمكننا تثبيت المكتبات والأطر المطلوبة عبر سطر الأوامر Terminal مباشرةً على النحو الآتي: # تثبيت المكتبات وأطر العمل التي نحتاجها للعمل عبر مثبِّت conda conda install -c conda-forge streamlit pdfplumber langchain faiss-cpu sentence-transformers pytorch huggingface_hub -y pip install langchain-community langchain-huggingface langchain-ollama arabic-support أما إذا كنا نستخدم pip، فيمكن تثبيت المكتبات والأطر المشار المطلوبة عبر سطر الأوامر على النحو الآتي: # تثبيت المكتبات وأطر العمل التي نحتاجها عبر مثبِّت pip pip install streamlit pdfplumber langchain langchain-community langchain-huggingface langchain-ollama faiss-cpu sentence-transformers torch huggingface_hub arabic-support تحميل Ollama و DeepSeek Ollama هو أداة تتيح إمكانية تشغيل نماذج الذكاء الاصطناعي محليًا بسهولة دون الحاجة إلى إعدادات معقدة ويناسب مكتبة Langchain للتنزيل يمكن التوجه إلى الموقع الرسمي لـ Ollama والضغط على خيار التنزيل Download من الواجهة الرئيسية كما هو موضح في الصورة الآتية. بعد ذلك نضغط على خيار DeepSeek-R1 من نفس الواجهة ونختار النموذج المناسب لنا، وننسخ إعداداته التي نحتاجها لمقالنا من أجل تحميل DeepSeek، وهي في هذا المقال على النحو الآتي: ollama pull deepseek-r1:70b ننسخها إلى سطر الأوامر Terminal، وبعد تحميله نتأكد من أنه قد حُمل بنجاح، بإجراء اختبار ببسيط له نسأله من خلاله عمن يكون، لنحصل على الرد الآتي الذي يوضح أن عملية التثبيت قد تمت بنجاح تام. بدء كتابة كود المشروع سنكتب الكود الآن بتدرج، وأول ما سنفعله هو استدعاء المكتبات والأُطر التي سنحتاجها، والتي سبق وثبتناها مع بداية المقال. # استدعاء المكتبات والأُطر التي سنحتاجها import tempfile import re import streamlit as st from langchain_community.document_loaders import PDFPlumberLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_huggingface import HuggingFaceEmbeddings from langchain_community.vectorstores import FAISS from langchain_ollama import OllamaLLM from langchain.prompts import PromptTemplate from langchain_core.output_parsers import StrOutputParser from langchain_core.runnables import RunnablePassthrough بعد ذلك، سنهيّء الواجهة التي سنعرض من خلالها نتائجنا لتتوافق مع اللغة العربية لضمان أن تكون واجهة النظام ستكون من اليمين لليسار. # تهيئة الواجهة لتتوافق مع اللغة العربية from arabic_support import support_arabic_text support_arabic_text(all=True) بعد ذلك سنتبع ما يلي. تهيئة الكتاب لإسترجاع المعلومات من أجل استرجاع المعلومات ذات الصلة من ملف الكتاب، سنحتاج لاتّباع الخطوات الآتية: تحميل المستند: بحيث يتم رفع ملف PDF وتحميل محتوياته باستخدام PDFPlumberLoader لسرعته في القراءة تقسيم النصوص: حيث تُجزَّأ المحتويات إلى مقاطع باستخدام أداة RecursiveCharacterTextSplitter لنحافظ على السياق ونحسن دقة البحث إرسال البيانات الى مكتبة HuggingFaceEmbeddings: وذلك لانشاء البصمات للنصوص لتُخزن في قاعدة البيانات FAISS وقد اتبعنا هذه الخطوات لأنه عند كتابنا للسؤال، يجب أن يعمل النظام على البحث في البيانات ذات الصلة، لذا يتم ذلك عبر تحويل النصوص إلى تمثيلات رقمية، إذ نحوّل كل جزء من النص إلى أرقام تعبّر عن معناه، تمامًا مثل بصمة رقمية للنص، ثم نبحث في البيانات عن أقرب تضمينات مطابقة. ويكون الكود المكتوب على النحو الآتي: # تحميل وقراءة محتوى الملف docs = PDFPlumberLoader(temp_pdf_path).load() # تحويل الكتاب إلى نصوص حاسوبية يمكنه فهمها والبحث فيها بكفاءة embedder = HuggingFaceEmbeddings(model_name="sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2") chunk_size = max(500, min(1000, len(docs) // 10)) # تحديد حجم المقطع حسب طول المستند documents = RecursiveCharacterTextSplitter( chunk_size=chunk_size, # تحديد حجم كل مقطع نصي chunk_overlap=chunk_size // 5 # السماح بتداخل بين المقاطع بنسبة 20% للحفاظ على السياق ).split_documents(docs) تنفيذ عملية التقسيم على المستند المحمّل # انشاء مخزن البيانات ووضع البيانات التي استخرجت من الكتاب في المخزن الخاص بالنظام retriever = FAISS.from_documents(documents, embedder).as_retriever(search_kwargs={"k": 4}) وحتى هذه العملية، نكون قد عالجنا الكتاب وأكملنا تهيئته لإسترجاع المعلومات ذات الصلة منه. توليد الإجابات النهائية من ملف الكتاب لكي نُولد الإجابة النهائية، يجب علينا أولًا تحليل السياق وفهم المعنى المقصود من السؤال، لذا يُستخدم نموذج اللغة لتوليد استجابة مناسبة. يتم أيضًا تعزيز جودة الإجابة من خلال دمج المعلومات المسترجعة مسبقًا مع المعرفة المخزنة داخل النموذج، وأخيرًا نُطبق تقنيات تحسين الصياغة لضمان وضوح الإجابة. وتتم العملية بعدة خطوات وهي: تهيئة نموذج اللغة في الكود: حيث يتم استخدام OllamaLLM وضبط DeepSeek R1 ليكون المصدر الأساسي للإجابة على الأسئلة. إعداد الأوامر Prompt Engineering: حيث يتم تصميم إنشاء قالب تعليمات باستخدام PromptTemplate لتوجيه النموذج حول كيفية الإجابة عند البحث في محتوى الكتاب انشاء سلسلة معالجة الإجابات: عن طريق دمج نموذج LLM مع تنقية FAISS Retriever لنضمن توليد النموذج الإجابات بناءً على المعلومات المسترجعة فقط، وهذا يوفر دقة الإجابات ويقلل احتمالية توليد معلومات غير صحيحة # تهيئة نموذج اللغة llm = OllamaLLM(model="deepseek-r1:70b") # إعداد الأوامر، تعريف الأوامر التي يتبعها النظام أثناء البحث في الكتاب template = """ Use the following context to answer the question concisely in 3-4 sentences. If the answer is unknown, respond with "I don't know" without making anything up. Answer in Arabic if the given question is in Arabic. Context: {context} Question: {question} Answer: """ rag_chain = ( {"context": retriever, "question": RunnablePassthrough()} # تمرير السياق والسؤال | PromptTemplate.from_template(template) # تجهيز السؤال بالتنسيق المطلوب | llm # إرسال البيانات إلى نموذج اللغة لمعالجتها | StrOutputParser() # استخراج الإجابة بصيغة نصية ) حتى هذه العملية تم توليد الإجابه بناءً على المعلومات المسترجعة. انشاء واجهة الويب استخدمنا في هذا المقال إطار العمل Streamlit لإنشاء واجهة الويب من أجل تسهيل عملية العرض والاستخدام. # إعداد واجهة التطبيق st.markdown("<h2 style='text-align: right;'>Ollama و Deepseek بإستخدام Pdf البحث ضمن ملف</h2>", unsafe_allow_html=True) uploaded_file = st.file_uploader("Pdf رفع ملف", type="pdf") if uploaded_file is not None: with st.spinner("..جاري المعالجة"): with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as temp_pdf: temp_pdf.write(uploaded_file.getvalue()) temp_pdf_path = temp_pdf.name # إدخال المستخدم للسؤال st.markdown(f'<div style="direction: rtl; font-size: 16px; font-weight: bold;">أدخل سؤالك هنا..</div>', unsafe_allow_html=True) user_input = st.text_input(" ", key="user_question", label_visibility="hidden") تحسين المخرجات في هذا الجزء، ركزنا على تحسين جودة المخرجات الناتجة عن نظام RAG لضمان تقديم إجابات واضحة ومباشرة، ويتم ذلك من خلال تعديل الكود لإزالة أي نصوص تحليلية أو تعليمات غير ضرورية قد تظهر في الاستجابة، مما يجعل النتيجة أكثر تركيزًا على المعلومات المطلوبة فقط ولتسهيل العملية استخدمنا تعبير نمطي Regular Expression للبحث عن أي نص موجود بين العلامتين <think> و </think> داخل الإجابة في سطر cleaned_response، ثم يٌحذف لضمان عرض المحتوى النهائي فقط. بعد ذلك، يتم تنظيف النص وإزالة أي فراغات زائدة باستخدام .strip(). # معالجة إدخال المستخدم if user_input: with st.spinner("..جاري البحث"): response = rag_chain.invoke(user_input) # استرجاع البيانات ثم توليد الإجابة cleaned_response = re.sub(r"<think>.*?</think>", "", response, flags=re.DOTALL).strip() st.markdown("### Answer:") st.write(cleaned_response) # عرض الإجابة النهائية else: st.info("Pdf من فضلك قم برفع ملف") ولنفتح واجهة الويب، لا بد من كتابة الأمر التالي في Terminal الخاص بالبرنامج: # فتح واجهة الويب streamlit run Project.py ملاحظة: سنغير كلمة Project بناءً على اسم الملف. اختبار كفاءة النظام عند هذه المرحلة جربنا اختبار النظام للتأكد من دقة استرجاع المعلومات، وتوليد الإجابات، وقدرته على تقديم إجابات نموذجية، لضمان إنتاج النموذج أفضل إجابة وأدق تفاصيل. ملاحظة: نود لفت الانتباه مجددًا إلى أن النظام في شكله الحالي لا يزال يواجه صعوبةً في دعم اللغة العربية بشكل مثالي، وهو ما دفعنا إلى استخدام موارد حاسوبية عالية في مشروعنا، مثل وحدات معالجة رسومية قوية وذاكرة وصول عشوائي كبيرة، لضمان أداء دقيق. إذا لم تكن هذه الموارد متاحة لبناء نظام مشابه فيمكن بسهولة تطبيق نفس الخطوات التي شرحناها على نماذج أخرى تدعم اللغة العربية بكفاءة أكبر، أو حتى استخدامها مع لغات أخرى مثل الإنجليزية التي تتطلب موارد أقل بكثير للحصول على نتائج مماثلة، مما يتيح إمكانية تحقيق أهدافك بما يتناسب مع إمكانياتك المتوفرة. في حال عدم توفر الموارد يمكن استعمال النظام باللغة الإنجليزية مثلًا، وبكل بسهولة عن طريق استعمال نموذج لغة أصغر مثل Deepseek R1-7b، عن طريق تحميله عبر سطر الأوامر Terminal: ollama pull deepseek-r1 وبعد التأكد من تحميله، نغير سطر نموذج اللغة في الكود # تهيئة نموذج اللغة llm = OllamaLLM(model="deepseek-r1") ثم نحذف الجزء المتعلق بتهيئة واجهة اللغة العربية من الكود وتصبح هذه هي النتيجة: وكما هو واضح، فالنموذج قادر على فهم الكتاب العربي الذي شاركناه إياه كمدخلات للبحث ضمنها عن جواب، وقد تمكن الإجابة علينا بلغة إنجليزية سليمة بعد أن سألناه باللغة الإنجليزية. خاتمة بهذا نكون قد وصلنا إلى نهاية المقال الذي تعرفنا فيه على كيفية بناء نظام RAG قادر على اختصار الوقت علينا ومساعدتنا في الحصول على ردود دقيقة وسريعة من الملفات التي تحتاج منا عادة لساعات من القراءة والبحث، ووضحنا كيفية تحسين نموذج اللغة لتوليد استجابات ذكية عبر عدة مراحل، بدءًا من إعداد التوجيهات وتصميم قالب الأوامر، مرورًا بتطبيق المشروع ضمن السياق وإنشاء مسارات معالجة، مع التركيز على تعزيز الدقة والترابط لضمان استجابات متسقة وواضحة. المصادر ?What is RAG (Retrieval-Augmented Generation) Developing Retrieval Augmented Generation (RAG) based LLM Systems How to build a RAG Using Langchain, Ollama, and Streamlit Building RAG-based LLM Applications Streamlit Arabic Support اقرأ أيضًا استكشف مصطلحات الذكاء الاصطناعي التوليدي تشغيل Deepseek محليا على محرر الأكواد VS Code التفاعل مع رسائل WhatsApp باستخدام الذكاء الاصطناعي كيفية ربط بوت تلغرام مع جداول بيانات Google Sheets العمل مع مستندات PDF ومستندات Word باستخدام بايثون
    1 نقطة
  20. تستعمل العديد من الشركات اليوم كلًا من وحدة المعالجة المركزية CPU ووحدة المعالجة الرسومية GPU لتحسين أداء طيف واسع من التطبيقات بداية من مراكز البيانات Data centers وصولًا إلى الأجهزة المحمولة وغيرها من الاستخدامات المفيدة، وسنشرح في هذا المقال كل وحدة معالجة وآلية عملها ونوضح أهم أوجه التشابه والاختلاف بينهما، وحالات الاستخدام المناسبة لكل منهما، لنساعدكم على تقرير الوحدة الأفضل لمشروعكم أو نشاطكم التجاري. تطور المعالجات الحاسوبية أصبحت وحدة المعالجة المركزية Central Processing Unit -أو CPU اختصارًا- مكونًا أساسيًا في أنظمة الحواسيب منذ بداية سبعينيات القرن الماضي، فتطورت من مجرد آلات بسيطة لإجراء الحسابات والمعالجات الرياضية إلى معالجات متعددة النواة وبالغة التعقيد. فكان إصدار إنتل لمعالجها 4004 في عام 1971علامة فارقة لبداية حقبة وحدات المعالجات المركزية الحديثة ومهد الطريق للتطورات المتسارعة في قدرات المعالجة، ومع مرور الزمن أصبحت وحدات المعالجة المركزية CPUs أكثر تخصصًا وتعقيدًا حيث ظهرت ابتكارات مثل خطوط أنابيب تجزئة تنفيذ التعليمات Instruction pipelining ومتنبئ التعليمات التفرعية Branch Predictor و تقنية خيوط المعالجة الفائقة Hyper-threading وقد دفعت هذه التقنيات بحدود المعالجة الحاسوبية العامة إلى الأمام. ثم ظهرت وحدة المعالجة الرسومية Graphics Processing Unit -أو GPU اختصارًا- في بداية التسعينيات لتلبي الطلب المتزايد على المعالجة الرسومية في ألعاب الفيديو ورسوميات الحواسيب. وعلى النقيض من وحدات المعالجات المركزية CPUs التي كانت مصممة لتنفيذ التعليمات على التسلسل sequential فقد صممت المعالجات الرسومية GPUs للتعامل مع الحسابات والعمليات على التوازي parallel من أجل تنفيذ المهام الرسومية المعقدة، وكان تقديم نيفيديا لمعالجها جيفورس GeForce 256 في عام 1999 بداية حقبة جديدة للعتاد المخصص للرسوميات القادر على تخفيف الحمل الحاسوبي عن وحدات المعالجات المركزية CPUs في مهام المعالجة الرسومية. صُممت وحدات المعالجة المركزية والرسومية في البداية لأغراض مختلفة، لكن في السنوات الأخيرة بدأت قدراتهما وأدوارهما تتداخل مع بعضها البعض، فأصبحت وحدات المعالجة المركزية CPUs مدمجة مع قدرات المعالجة على التوازي، وصارت وحدات المعالجة الرسومية GPUs أكثر شمولًا وتنوعًا وظهرت لها تطبيقات أخرى غير الرسوميات مثل حل المسائل العلمية المعقدة وتطبيقات تعلم الآلة، كما حظت المعالجات الرسومية بشعبية كبيرة في السنوات الأخيرة نتيجة أدائها المبهر في أداء مهام الذكاء الاصطناعي وبالتحديد قدرتها على المعالجة المتوازية parallel computing فكانت الأداة المثالية لتدريب شبكات التعلم العميق وإجراء العمليات الحسابية على المصفوفات الضخمة التي تلعب دورًا أساسيًا في العديد من خوارزميات الذكاء الاصطناعي، مما دفع إلى اكتشافات علمية متقدمة في مجالات بحثية وتطبيقية مختلفة مثل الرؤية الحاسوبية Computer Vision ومعالجة اللغات الطبيعية Natural Language Processing والذكاء الاصطناعي التوليدي Generative AI. ما هي وحدة المعالجة المركزية CPU وحدة المعالجة المركزية CPU هي المكون الرئيسي في أجهزة الحواسيب، فهي تقوم بأغلب العمليات والمعالجة، ويشار إليها في سياقات كثيرة بعقل الحاسوب، وتنفذ وحدة المعالجة المركزية CPU التعليمات والحسابات وتنظم الأنشطة المختلفة للعتاد الحاسوبي. وتسود اليوم معالجات متعددة الأنوية multi-core processors قادرة على تنفيذ العديد من المهام في نفس الوقت مستغلة قدرات المعالجة المتوازية والمعماريات المتقدمة. وقد تحتاج بعض الشركات لاستخدام أنظمة شديدة الاعتماد على استهلاك وحدة المعالجة المركزية CPU-intensive لإجراء تحليل متقدم للبيانات، مثل معالجة مجموعات من البيانات الكبيرة الخاصة بالعملاء لاكتشاف أنماط شرائهم، وتوقع اتجاهات السوق المستقبلية. آلية عمل وحدة المعالجة المركزية CPU تعمل وحدة المعالجة المركزية CPU من خلال حلقة من العمليات معروفة باسم دورة تنفيذ التعليمات وتتكون من ثلاث خطوات وهي الجلب Fetch و فك التشفير Decode ثم التنفيذ Execute، وتكون هذه الخطوات معًا أساس جميع عمليات وحدة المعالجة المركزية CPU. والآن لنستكشف المكونات الرئيسية والخطوات المرتبطة بمعالجة التعليمات وتنفيذها لنفهم كيفية عمل وحدة المعالجة المركزية CPU: وحدة التحكم Control unit تعد وحدة التحكم بمثابة مركز القيادة الخاص بوحدة المعالجة المركزية CPU، فهي تدير وتنسق كل العمليات الخاصة بوحدة المعالجة المركزية CPU. وحدة الحساب والمنطق ALU‎ تجري في وحدة الحساب والمنطق Arithmetic Logic Unit -أو ALU اختصارًا- كل العمليات الحسابية والمنطقية مثل الجمع والطرح والمقارنة، فهي تشكل أساس القدرات الحسابية لوحدة المعالجة المركزية CPU. السجلات Registers هي وحدات تخزين فائقة السرعة توجد بداخل شريحة وحدة المعالجة المركزية CPU، حيث تحتفظ هذه السجلات Registers بالبيانات التي تعمل عليها وحدة المعالجة المركزية CPU حاليًا، مما يسمح بسرعة الوصول لها والتعديل عليها. الذاكرة المخبئية Cache الذاكرة المخبئية Cache هي ذاكرة مؤقتة صغيرة الحجم مبنية بداخل وحدة المعالجة المركزية وهي تتميز بسرعتها وتستخدم لتخزين البيانات والتعليمات التي يُحتمل استخدامها بشكل متكرر لتسريع المعالجة، ولكنها أقل سرعة من السجلات Registers وأكبر منها في الحجم. الجلب Fetch تجلب وحدة المعالجة المركزية CPU في هذه الخطوة التعليمات من الذاكرة، ويحدد عداد البرنامج program counter موقع التعليمة الذي ستفذ حاليًا، فعداد البرنامج هو عبارة عن سجل مخصص لمتابعة وتعقب التعليمات المطلوب تنفيذها، ويحدّث نفسه تلقائيًا ليشير للتعليمة التالية. فك التشفير Decode تأتي هذه الخطوة بعد جلب fetching التعليمة حيث يجري تفسيرها بواسطة وحدة المعالجة المركزية CPU، وتعمل وحدة التحكم Control Unit على فك تشفير العمليات وتحديد ما هي العمليات التي ينبغي تنفيذها، وما هي البيانات التي تحتاجها هذه العملية. التنفيذ Execute تنفذ وحدة المعالجة المركزية CPU التعليمة، وقد يتطلب التنفيذ عمليات حسابية أو منطقية باستخدام وحدة الحساب والمنطق ALU، أو نقل بيانات خلال السجلات المختلفة، أو التفاعل مع أجزاء مختلفة من الحاسوب. التخزين Store إن كانت العملية المُنفذَّة تعيد نتيجة فسوف تحفظ هذه النتيجة في سجل register أو في الذاكرة، ويُحَدَّث عداد البرنامج program counter ليشير للتعليمة القادمة، لتبدأ نفس الحلقة في التكرار مجددًا. ما هي وحدة المعالجة الرسومية GPU تعد وحدة المعالجة الرسومية GPU دارة إلكترونية مخصصة ومصممة للتعديل على الذاكرة بسرعة، وتسريع إنشاء الصور في ذاكرة مخصصة لعرض ولإخراج المعلومات على أجهزة العرض تسمى frame buffer، وقد طُوّرت في البداية لأغراض عرض الرسوميات ثلاثية الأبعاد في ألعاب الفيديو، ثم تطورت لتصبح معالجات متوازية قووية قادرة على التعامل مع العمليات الحسابية المعقدة على التزامن. وتحتوي وحدات المعالجة الرسومية GPUs على آلاف من الأنوية cores الصغيرة وعالية الكفاءة المصممة للتعامل مع مهام متعددة على التوازي، مما يجعلها الخيار المثالي لمهام المعالجة المتوازية التي تتجاوز التطبيقات الرسومية. تستخدم الشركات اليوم قدرات وحدات المعالجة الرسومية GPUs لتطوير وتشغيل نماذج تعلم الآلة الضخمة على نطاق واسع، وهذا يتيح لها تحقيق تقدم متسارع في تخصيص وتشخيص تجربة أنظمة التوصية الخاصة بها، وتستخدم أيضًا في تطوير تقنيات المركبات ذاتية القيادة وفي خدمات الترجمة الفورية في الوقت الحقيقي وغيرها من التطبيقات الذكية. آلية عمل وحدة المعالجة الرسومية GPU تعمل وحدات المعالجة الرسومية GPUs بمبادئ مشابهة لتلك التي تتبعها وحدات المعالجة المركزية CPUs ولكنها مصممة ومحسنة لمهام المعالجة المتوازية، وهذا يجعلها الخيار الأنسب لعرض الرسوميات ولأنواع معينة من المهام. وسنشرح تاليًا آلية عمل وحدة المعالجة الرسومية GPU: المعالجات متعددة التدفق SMs‎ تكافئ المعالجات متعددة التدفق Streaming Multiprocessors -أو SMs اختصارًا- الأنوية cores المستخدمة في وحدات المعالجة المركزية ولكن يحتوي كل معالج متعدد التدفق SM على وحدات معالجة أصغر ومتعددة ما يكسبه القدرة على التعامل مع تدفق كبير من البيانات حيث تُمكّن هذه المعمارية وحدات المعالجة الرسومية GPUs من التعامل مع العديد من المهام بنفس الوقت. أنوية كودا CUDA Cores تقع هذه الأنوية بداخل وحدات معالجة التدفق SM، وهي المسؤولة عن المعالجة بداخلها، وهي أبسط من أنوية وحدة المعالجة المركزية CPU ولكنها توجد بأعداد أكبر بكثير، حيث قد يوجد في وحدة المعالجة الرسومية GPU آلاف منها. وحدات رسم الخامة TMUs‎ تعمل وحدة رسم الخامة Texture Mapping Unit أو TMU اختصارًا على رسم الخامة أو السطح الخارجي للنماذج ثلاثية الأبعاد بسرعة كبيرة، وهي وظيفة فريدة توجد فقط في وحدات المعالجة الرسومية GPUs وليست موجودة في وحدات المعالجة المركزية CPUs. ذاكرة الفيديو VRAM‎ تتشابه ذاكرة الفيديو Video Memory في الوظيفة مع ذاكرة الوصول العشوائي الخاصة بوحدة المعالجة المركزية CPU، ولكنها محسنَّة لمهام المعالجة الرسومية، وهي في الغالب أسرع وتمتلك معدل نقل بيانات أكبر من الذي تملكه ذاكرة RAM. الجلب Fetch تمتلك وظيفة مماثلة لتلك الخطوة الخاصة بجلب التعليمات في وحدة المعالجة المركزية CPU، ولكنها مصممة بشكل أفضل لتنفيذ العديد من التعليمات المتشابهة على التوازي بذات الوقت. فك التشفير Decode تشابه هذه الوظيفة نظيرتها في وحدة المعالجة المركزية CPU والاختلاف بينهما هو تحسين هذه الوظيفة في GPU لتناسب مع المهام المتعلقة بمعالجة الرسوميات. التنفيذ Execute تختلف هذه الخطوة بشكلٍ جذري عن نظيرتها في وحدة المعالجة المركزية CPU، حيث تُنفِّذ وحدات المعالجة الرسومية GPUs العديد من التعليمات المتشابهة بشكل متزامن من خلال عدد كبير من أنوية كودا CUDA cores في عملية تسمى Single instruction Multiple Data -أو SIMD اختصارًا- والتي تعني إمكانية تنفيذ نفس التعليمة على عدة بيانات في نفس الوقت. التخزين Store تُحفظ النتائج عادة في ذاكرة الفيديو Video Random Access Memory -أو VRAM اختصارًا- ويسمح المستوى العالي من التوازي الذي توفره وحدات المعالجة الرسومية GPUs بتحقيق معدل نقل بيانات كبير جدًا من أجل تنفيذ المهام المتعلقة بالرسوميات. مقارنة بين وحدة المعالجة المركزية CPU ووحدة المعالجة الرسومية GPU تعد كلتا وحدتي المعالجة المركزية والرسومية مكونات ضرورية في أنظمة الحوسبة الحديثة، وقد صُمّمت كل وحدة معالجة منهما بأولويات ومسؤوليات مختلفة وهدف تصميمي مختلف، لذا من الضروري فهم الفروقات بينهما لتحديد المناسب لنا من بينهما. الوظيفة الأساسية صُمّمت وحدات المعالجة المركزية CPUs لتكون شاملة ومتعددة الأغراض وقادرة على التعامل مع طيف واسع من المهام بكفاءة عالية، فهي تتميز في المعالجة المتسلسلة sequential processing، كما أنها مُحسّنة لاتخاذ القرارات المعقدة، وتتحكم وحدة المعالجة المركزية CPU في العتاد الحاسوبي والتنسيق بين البرامج المختلفة لتشغيلها. بنما كانت وحدات المعالجة الرسومية GPUs متخصصة في البداية في عرض الرسوميات graphics rendering، ولكنها تطورت مع الوقت لتصبح معالجات فائقة لها القدرة على المعالجة المتوازية parallel processors. وهي اليوم تشغّل التعليمات تمامًا كوحدات المعالجة المركزية CPUs ولكنها محسنة للتعامل مع الكثير من العمليات الحسابية المتزامنة. فوحدات المعالجة المركزية CPU متنوعة القدرات وشاملة المهام، في حين أن وحدات المعالجة الرسومية تتميز بالتخصص والتفوق في تنفيذ المهام القابلة للتقسيم إلى مهام كثيرة جدًا والتي تتميز بكونها مهام متشابهة ويمكن حسابها بشكل مستقل عن بعضها البعض. المعالجة تُنفِّذ وحدات المعالجة المركزية CPUs العمليات بشكل متتابع أو متسلسل، حيث تُنفِّذ التعليمات المعقدة واحدة تلو الأخرى وتستخدم تقنيات مخصصة مثل التنبؤ بالتعليمات المتفرعة أو الشرطية branch prediction أو التنفيذ غير المراعي للترتيب Out-of-Order Execution الذي يسمح بتنفيذ التعليمات بترتيب مختلف عن ترتيبها الأصلي في البرنامج لتحسين عملية المعالجة المتسلسلة، حيث تشبه وحدات المعالجة المركزية CPUs المدير المنظم فهي تنسق وتتعامل مع مهام متنوعة وتتخذ القرارات المعقدة بسرعة. من ناحية أخرى، تعالج وحدات المعالجة الرسومية GPUs المهام بالتوازي، فتنفّذ العديد من التعليمات البسيطة بشكل متزامن عبر عدد ضخم من الأنوية، وتحتوي هذه الأنوية على عدد ضخم من الخيوط threads البسيطة التي يمكنها تنفيذ عمليات بسيطة للغاية ولكن عددها الضخم يمكِّنها من معالجة كمية بيانات أكبر بنفس الوقت، فبينما تشبه وحدة المعالجة المركزية CPU المدير، تشبه وحدة المعالجة الرسومية GPU خط التجميع في المصانع حيث يوكل لكل عامل أو آلة جزء معين من العمل، وبهذا يمكن لهذه الوحدة معالجة كميات ضخمة من البيانات المتشابهة في وقت واحد. تصميم الهيكلية تمتلك وحدات المعالجة المركزية CPUs في الغالب من 2 إلى 64 نواة معقدة التركيب ومزودة بذاكرة مخبئية Caches ووحدات تحكم Control units مخصصة ومعقدة، حيث صممت هذه المكونات لتحقق أقل معدل تأخير في الاستجابة low latency، فتستطيع كل نواة التعامل مع مهام متنوعة بشكل مستقل، فتولي هذه الهيكلية أهمية للتنوع في القدرات وسرعة الاستجابة لعدد واسع ومتنوع من المهام. بينما تجمع وحدات المعالجة الرسومية GPUs مئات أو آلاف الأنوية البسيطة فيما يعرف بمعالجات متعددة التدفق streaming multiprocessors أي يمكنها معالجة عدة تدفقات من البيانات في وقت واحد، وعلى عكس وحدات المعالجة المركزية CPUs فإن أنوية وحدات المعالجة الرسومية GPUs تتشارك في وحدات التحكم والذاكرات المخبئية بداخل كل معالج متعدد، وتختلف هذه المعمارية عن وحدات المعالجة المركزية CPUs بحيث تسمع لوحدات المعالجة الرسومية GPUs بمعالجة كميات ضخمة من البيانات من خلال عمليات متشابهة عليها، فهي لا تعتمد أنوية معقدة كما في وحدات المعالجة المركزية بل تستخدم أنوية بسيطة وصغيرة تكمن قوتها وتفوقها بقدرتها في العمل على التوازي على عدد كبير من البيانات. حالات الاستخدام تبرز أهمية وحدات المعالجة المركزية CPUs في المهام التي تطلب اتخاذ قرارات معقدة، وتنفيذ عمليات متنوعة، أو تغيرات متكررة في تدفق تنفيذ العمليات. فتشغل هذه الوحدات أنظمة التشغيل والمتصفحات. وتعد الخيار الأول لمهام مثل إدارة قواعد البيانات وتشغيل برامج الإنتاجية والتنسيق بين عمليات النظام المختلفة. في حين تبرز أهمية وحدات المعالجة الرسومية GPUs في الحالات التي تتضمن إجراء العديد من العمليات الحسابية في نفس الوقت عبر عدد كبير من البيانات المتجانسة أي البيانات المتشابهة أو المتطابقة من حيث الهيكل أو النوع، فهي تتشارك مع وحدات المعالجة المركزية CPUs في القدرة على القيام بالعمليات الحسابية لكنها تتفوق بشكل جليّ في المهام التي تطلب عرض رسومات ثلاثية الأبعاد وكثيرة التفاصيل، أو في تدريب نماذج تعلم الآلة أو تنفيذ عمليات محاكاة لظواهر علمية تتطلب حسابات ضخمة، ففي كل هذه التطبيقات تتفوق وحدات المعالجة الرسومية GPUs على وحدات المعالجة المركزية CPUs عشرات المرات وربما مئات المرات من حيث الأداء، مما يعطيها دورًا لا غنى عنه في مجالات مثل رسوميات الحاسوب، والذكاء الاصطناعي والحوسبة عالية الأداء. دمج وحدة المعالجة المركزية CPU مع وحدة المعالجة الرسومية GPU تستخدم الأنظمة الحاسوبية الحديثة كلًا من وحدة المعالجة المركزية CPU ووحدة المعالجة الرسومية GPU لتحسين التطبيقات والمهام. ويعرف هذا النهج بالحوسبة الهجينة، حيث تسمح هذه الطريقة لكل معالج بالتركيز على الأمور التي يتفوق فيهل، فتتعامل وحدات المعالجة المركزية CPUs مع المهام المعقدة المتسلسلة، وتتولى وحدات المعالجة الرسومية GPUs الحسابات المتوازية، ويعزز هذه الدمج في التقنيات أداء الأنظمة ويساعد في العديد من المجالات بداية من المحاكاة العلمية والذكاء الاصطناعي وصولًا إلى إنشاء المحتوى، ولنستعرض بعض الأمثلة على حالات يمكننا فيها دمج CPU مع GPU. لنفترض أن شركة ناشئة تطور نظامًا لاكتشاف الكائنات في الوقت الحقيقي من أجل المركبات ذاتية القيادة، فيمكن للشركة في هذه الحالة أن تستخدم وحدة المعالجة المركزية CPU في معالجة البيانات المتدفقة من المستشعرات واتخاذ قرارات سريعة، بينما تستخدم وحدة المعالجة الرسومية GPU في تشغيل نظام من الشبكات العصبية الاصطناعية Artificial Neural Networks المعقدة للتعرف على الكائنات في البيئة المحيطة بالمركبة. مثال آخر، لنفترض أن شركة تقنيات مالية تريد تطوير منصة تداول وتتوقع ورود طلبات تداول كثيرة في نفس الوقت، فيمكنها أن تستخدم وحدات المعالجة المركزية CPUs لإدارة عملية التداول وتشغيل الخوارزميات المعقدة، بينما تستفيد من وحدات المعالجة الرسومية GPUs في تحليل بيانات السوق بسرعة وتقييم المخاطر التسويقية من خلال عمليات حسابية تنفذ على التوازي. أخيرًا، لنفترض أن لدينا استوديو تطوير ألعاب ونريد صناعة لعبة عالم مفتوح متعددة الشخصيات واللاعبين، فيمكننا في هذه الحالة استخدام وحدات المعالجة المركزية CPUs في تنفيذ منطق اللعب وإضافة سلوك الذكاء الاصطناعي للعبة، بينما نعتمد على وحدات المعالجة الرسومية GPUs في عرض الرسومات المعقدة ثلاثية الأبعاد ومحاكاة الظواهر الطبيعية ومحاكاة الفيزياء لإنشاء تجربة لعب مبهرة بصريًا. ترجمة وبتصرف لمقالة ?What is the Difference Between CPU and GPU. اقرأ أيضًا تعدد المهام Multitasking في الحواسيب وحدة المعالجة المركزية تعرف على وحدة المعالجة المركزية وعملياتها في معمارية الحاسوب استكشف مصطلحات الذكاء الاصطناعي التوليدي توليد النصوص باستخدام النماذج اللغوية الكبيرة LLMs
    1 نقطة
  21. أصبحت أدوات الذكاء الاصطناعي من الأساسيات التي لا غنى عنها للمبرمجين اليوم، حيث تساعد هذه الأدوات في زيادة الإنتاجية، والتخلص من المهام التكرارية، والتفرغ لحل المشكلات البرمجية الأكثر أهمية، وقد اخترنا لكم في هذه المقالة واحدة من أدوات الذكاء الاصطناعي القوية والمفيدة لأي مبرمج وهي المساعد الذكي GitHub Copilot الذي أصبح يوفر خطة استخدام مجانية من خلال دمجه مع محرر الأكواد Visual Studio Code، حيث سنوضح أهم الميزات التي يوفرها هذا المساعد الذكي، ونوضح حالات استخدامه المختلفة لكتابة أكواد محسنة وموثقة جيدًا واكتشاف الأخطاء وحلها بكفاءة من داخل المحرر مباشرة دون الحاجة لنسخ فقرات الكود ولصقها في نماذج الذكاء الاصطناعي الخارجية. المتطلبات نحتاج قبل بدء استكشاف المساعد البرمجي GitHub Copilot إلى التأكد من تجهيز بيئة عملنا بإعداد الأمور التالية: تنزيل محرر الأكواد فيجوال ستوديو كود VS Code إنشاء حساب على منصة GitHub تنزيل إضافة GitHub Copilot و GitHub Copilot Chat لمحرر الأكواد VS Code ملاحظة: قد تكون الإضافات المطلوبة محمّلة بالفعل في محرر الأكواد، وفي هذا الحالة سنتخطى خطوة تنزيلها. خطوات ربط GitHub Copilot بمحرر أكواد VS code يمكننا من خلال محرر الأكواد VS code الاستفادة من تجربة وصول محدودة لاستخدام GitHub Copilot حيث تُمنح لنا خمسون محادثة لاستخدامها في الاستفسار من المساعد البرمجي و 2000 مرة لإكمال الكود البرمجي تجدد شهريًا، وسنتطرق في نهاية المقال لكيفية الحصول على الخطة المميزة pro بالمجان للطلبة والمعلمين والمساهمين في المشاريع مفتوحة المصدر بما يتوافق مع بعض الشروط التي تضعها منصة GitHub. بمجرد أن نفتح محرر أكواد VS code سنجد أيقونة بها شعار Github Copilot، نضغط عليها أو نفتح القائمة المنسدلة حيث سنجد خيار باسم Use AI features with Copilot for Free وباختياره تفتح نافذة جانبية ترحيبية وتطالبنا بالموافقة على الشروط والأحكام من خلال الضغط على زر Use Copilot for Free، وننصح بالاطلاع عليها قبل الموافقة. كي نتمكن من فتح نافذة الحوار مع المساعد البرمجي يمكننا استخدام الأيقونة أو اختصار الوصول السريع من لوحة المفاتيح Ctrl+ALT+I. وفي حال لم نتمكن من العثور على هذه الأيقونة أو وجدناها غير مفعلة فعلينا تسجيل الدخول إلى حساب Github الخاص بنا وربطه بمحرر الأكواد، من خلال أيقونة الحسابات Accounts الموجودة أسفل يسار الصفحة في محرر الأكواد فوق أيقونة الإعدادات، فمن خلالها نصادق على وصول محرر الأكواد VS code لحسابنا على Github والذي تحتاجه إضافة Github Copilot للعمل. اختيار نموذج الذكاء الاصطناعي يوفر Github Copilot لمستخدميه في الخطة المجانية إمكانية اختيار نموذج الذكاء الاصطناعي المشغِّل لمساعد الذكاء الاصطناعي، حيث يتاح حاليًا نموذجان فقط هما GPT 4o و Claude 3.5 sonnet. بينما تتيح الخطط المميزة المدفوعة الوصول إلى نماذج أقوى مثل OpenAI o1 و OpenAI o1-mini. ملاحظة: قد تتغير هذه النماذج بمرور الوقت وتطور إلى نماذج أخرى، من الأفضل حاليًا استخدام GPT4o أو Claude Sonnet 3.5 في تعديل ملفات الكود، بينما يفضل استخدام o1 لفهم وشرح الكود، وقد يختلف الأمر حسب حالة الاستخدام التي نتعامل معها لذا يمكن التبديل بين النماذج المتاحة ومقارنة نتائجها لنقرر الأنسب حسب كل حالة. حالات استخدام Github Copilot ضمن محرر الأكواد بعد ربط أداة الذكاء الاصطناعي بمحرر الأكواد، يمكننا الاستفادة من هذه الأداة في العديد من حالات الاستخدام العملية التي تسهل عملنا البرمجي وتزيد إنتاجيتنا. لنسعرض في الفقرات التالية أهم الحالات التي يمكننا الاستفادة منها من دمج مساعد الذكاء الاصطناعي GitHub Copilot مع محرر الأكواد. اقتراح إكمال الكود البرمجي لننشئ مجلدًا جديدًا و نفتحه في المحرر VS code، ثم ننشئ ملفًا باسم binary_search.py لنكتب خوارزمية البحث الثنائي وهي خوازرمية بحث مشهورة بكفاءتها، لنجرب أولًا كتابة تعريف دالة تستقبل مجموعة من الأرقام في مصفوفة Array، ونرى كيف سيقترح علينا المساعد البرمجي الكود المناسب للبحث ضمنها. بمجرد أن نكتب تعريف الدالة البرمجية سنلاحظ ظهور كود بلون رمادي خافت، هذا الكود هو اقتراح المساعد البرمجي ويمكننا الوقوف عليه بالمؤشر ورؤية شريط به بعض عناصر التحكم، فمثلًا قد نرى 1/2 والتي تعني أن هذا هو أحد اقتراحين، ويمكن أن نتجاهل الاقتراحات بمتابعة الكتابة أو يمكننا قبول الاقتراحات بالضغط على زر Accept أو على مفتاح Tab على لوحة المفاتيح، وكذلك يمكننا التحكم بمقدار ما نريد قبوله من الاقتراح باستمرار الضغط على زر Ctrl مع أحد أزرار الأسهم. يمكننا أيضًا كتابة تعليق يصف ما نريد وبمجرد النزول سطرًا سيقترح المساعد البرمجي كود ينفذ التعليق. تعديل عدة ملفات بأوامر مكتوبة وصوتية يتميز مساعد Github Copilot عن باقي أدوات الذكاء الاصطناعي الخارجية في وصوله للسياق البرمجي وقاعدة الأكواد التي نعمل عليها، وقدرته على التعديل على الملفات في الوقت الفعلي، ولا يقتصر الأمر على تعديل ملف واحد فيمكننا تعديل عدة ملفات بذات الوقت. لنجرب ميزة تعديل عدة ملفات معًا من خلال تطبيق خوارزميات ترتيب مشهورة سنكتبها في نفس ملف binary_sort كما في الصورة التالية: يمكننا بالطبع توليد هذه الدوال بمساعدة Github Copilot، كما نلاحظ هنا فإن اسم الملف لا يعبر عن الخوارزمية المطبقة -وهذا خطأ مقصود- لنرى كيف سيتعامل معه المساعد في خطوة لاحقة. لنفتح الآن نافذة الحوار ونكتب الموجّه prompt المناسب لطلب تعديل الملفات ويمكن استخدام أيقونة الميكروفون لتوجيه أمر صوتي. سيقترح Github Copilot التعديلات المناسبة وسيظهر لنا الاختلافات بين الملفات القديمة والتي أنشئت حديثًا، سنرى الأكواد التي حذفت مظللة بلون أحمر والتي أضيفت بلون أخضر، ولكن لن تطبق أو تضاف هذه التعديلات حتى نقبلها بالضغط على زر Accept. تحسين الكود البرمجي يمكننا مناقشة المساعد البرمجي Github Copilot في آلية كتابة كودنا البرمجي وكيفية تحسينه أو حل مشكلاته من خلال نافذة الحوار والتي تعد واحدة طرق متعددة للتواصل مع المساعد البرمجي، حيث يمكننا التواصل معه أيضًا من خلال محرر الأكواد بشكل مباشر وتفاعلي، أو من خلال سطر الأوامر أو الطرفية terminal المدمجة بمحرر أكواد VS code، أو من خلال واجهة VS code المحسنة لنجعل تجربة الاستخدام أكثر سلاسة. بملاحظة المثال السابق في تعديل الملفات سنجد عدة مشاكل واضحة، تحتاج لتصحيح بشري، ولهذا من المهم جدًا أن لاتسلم بصحة الكود المولد من أدوات الذكاء الاصطناعي دون مراجعته وتعديله، فأداة Github Copilot شأنها شأن أي أداة ذكاء اصطناعي آخرى فهي مفيدة لزيادة إنتاجيتك إن كنت بالفعل على دراية بالكود والمنطق المراد تنفيذه. تتمثل الأخطاء التي قام بها المساعد الذكي في حذف الدوال الأخرى من الملف الأول فقط، وبالتالي سنحتاج تصحيح هذا الخطأ بالإضافة لتحديث وتصحيح تسمية الملف الأول binary_sort إلى binary_seach فهو ليس خوارزمية ترتيب إنما خوارزمية بحث وهو خطأ مقصود نريد أن نختبر قدرته على اكتشافه. سنجد أن المساعد اكتشف المشكلات بالفعل ووضحها لنا في قائمة مرقمة، كما في الصورة التالية، ويمكننا أن نطلب منه تطبيقها. سيطبق المساعد الذكي هذه التعديلات، ولكن بتصفح الملفات نلاحظ أنه يقترح علينا كمُراجِع للكود code reviewing تعديل أو تصحيح بعض الأشياء، وهذه قد تكون ميزة مفيدة لاكتشاف الأخطاء أو المشاكل. يمكننا النقاش أيضًا حول تطبيق خوارزمية معينة وكيفية تحسينها كما في المثال التالي. كتبنا بداية الكود التالي بلغة بايثون والذي يتضمن تنفيذ لخوارزميتي الترتيب بالإدراج Insertion Sort والترتيب بالدمج Merge Sort من أجل ترتيب العناصر داخل قائمة وذلك قبل المناقشة والتحسين: def insertion_sort(arr): for i in range(1, len(arr)): key = arr[i] j = i - 1 while j >= 0 and arr[j] > key: arr[j+1] = arr[j] j -= 1 arr[j+1] = key def merge_sort(arr): if len(arr) > 1: mid = len(arr) // 2 left_half = arr[:mid] right_half = arr[mid:] merge_sort(left_half) merge_sort(right_half) i = j = k = 0 while i < len(left_half) and j < len(right_half): if left_half[i] < right_half[j]: arr[k] = left_half[i] i += 1 else: arr[k] = right_half[j] j += 1 k += 1 while i < len(left_half): arr[k] = left_half[i] i += 1 k += 1 while j < len(right_half): arr[k] = right_half[j] j += 1 k += 1 وفيما يلي الكود بعد التحسين واستخدام أسلوب يدمج بين خوارزميتي الترتيب لجمع ميزاتهما معًا: # This file contains implementation of merge sort algorithm. def insertion_sort(arr): for i in range(1, len(arr)): key = arr[i] j = i - 1 while j >= 0 and arr[j] > key: arr[j+1] = arr[j] j -= 1 arr[j+1] = key def merge_sort(arr, threshold=10): if len(arr) <= threshold: insertion_sort(arr) return arr if len(arr) > 1: mid = len(arr) // 2 left_half = arr[:mid] right_half = arr[mid:] merge_sort(left_half, threshold) merge_sort(right_half, threshold) i = j = k = 0 while i < len(left_half) and j < len(right_half): if left_half[i] < right_half[j]: arr[k] = left_half[i] i += 1 else: arr[k] = right_half[j] j += 1 k += 1 while i < len(left_half): arr[k] = left_half[i] i += 1 k += 1 while j < len(right_half): arr[k] = right_half[j] j += 1 k += 1 return arr # test the merge_sort function with some test cases sample = [5, 2, 9, 1, 5, 6] merge_sort(sample) print(sample) تخصيص تجربة الاستخدام قد نرغب في بعض الأحيان بأن يتبع المساعد البرمجي أسلوبًا معينًا نستخدمه في كتابة أكوادنا ولذلك نكثر في تفصيل التعليمات وتوضيحها له، ولكن هناك طريقة أفضل حيث يمكن أن نوضح للمساعد البرمجي أسلوبًا معينًا نطبقه على كامل المشروع ضمن ملف تعليمات بحيث لا نكون مضطرين لتوضيح تعليمات التخصيص في كل أمر نطلبه منه. للقيام بذلك سننشئ مجلدًا باسم github. ثم نضيف له ملفًا باسم copilot-instructions.md حيث سنكتب في هذا الملف التعليمات اللازمة والأسلوب الذي نحب كتابة الكود به كي يتبعها مساعدنا البرمجي. لاحظ المثال التالي حيث نوضح بداية كيف سيكتب لنا Github Copilot الجمل الشرطية بصيغة مختصرة تسمى العامل الثلاثي Ternary operator، ثم نوضح أسلوب توثيق الكود البرمجي الذي نرغب باستخدامه. لنختبر المخرجات بعض إضافة هذا التعديل. نلاحظ أن توثيق الكود بهذه الطريقة سيمكننا من معرفة معلومات عن الدالة عند تحديدها أو استخدامها في أي مكان آخر كما في المثال التالي. مراجعة وتدقيق الكود يمكننا استخدام Github Copilot لتدقيق ومراجعة الكود أو تلخيص التغيرات قبل طلب سحب Pull request الكود لمستودع الأكواد على Github فهذا يقلل الأخطاء البرمجية ويحسن جودة الأكواد المرفوعة. سنتبع الخطوات التالية لاستخدام هذه الميزة : نتوجه لمستودع الأكواد على Github ونطلب سحب Pull جديد أو نستخدم طلب موجود بالفعل نفتح قائمة Reviewers ونختار منها Github Copilot سيراجع المساعد الكود ويدققه لنا ثم يقدم اقتراحاته يمكننا التعامل مع التعليقات والمراجعات التي يوفرها Github Copilot كالمراجعة البشرية بقبولها أو رفضها سنجرب هذه الميزة عن طريق إنشاء مستودع أكواد Repository جديد على منصة Github ونضيف ملف بايثون math_utils.py يحتوي على دالة برمجية لقسمة رقمين، ولكن بها خطأ حيث لم نأخذ بعين الاعتبار الحالة التي يكون المقسوم عليه صفر، وسنفترض أن أحد المساهمين لاحظ هذه المشكلة وقام بطلب اشتقاق Fork لمستودع الأكواد ليصلح المشكلة، وبعد ذلك طلب سحب الملف Pull Request إلى المستودع الأصلي. في حال كنت صاحب مستودع الأكواد، فلا حاجة لاشتقاق المستودع Forking حيث يمكن إنشاء تفريعة Branch ثم طلب سحبها Pull Request. لنصحح الدالة بإضافة حالة شرطية عند كون المقسوم عليه صفرًا ونطبع رسالة الخطأ لتنبيه المستخدم. ثم نطلب سحب Pull هذا التفريع Branch الذي يحتوي التصحيح للفرع الأصلي والرئيسي. نلاحظ أنه Github Copilot قد لا يظهر لدينا في قائمة Reviewers ولكن يمكننا استخدامه لتلخيص طلب السحب Pull Request وهذا ما سنقوم به، حيث أن هذه الميزة لاتزال تجريبية وليست متاحة لدى الجميع. استخدام GitHub Copilot كخبير برمجي يتميز Github Copilot بميزة أخرى تجعله من أدوات الذكاء الاصطناعي البرمجية الفريدة، حيث يمكنه أن يعمل كخبير متخصص نستدعيه عند الوقوع في مشكلة أو عندما نرغب في معرفة آلية تنفيذ شيء ما، وهذا من خلال واجهة الحوار حيث يمكننا استدعاء الخبير من خلال رمز @ الذي يتيح قائمة من الخبراء الافتراضيين لنسألهم، مثلًا vscode@ يمكننا أن نسأله عن أي شيء يخص محرر الأكواد. نرى في هذا المثال كيف طلبنا من الخبير أن يوضح لنا كيفية تغير مظهر وتنسيق محرر الأكواد، فأخرج لنا زرًا عندما نضغط عليه يقودنا لقائمة اختيارات يمكننا من خلالها اختيار المظهر الذي نريده. @vscode how to change the Theme? لا يتوقف الأمر عند محرر الأكواد فيوجد أكثر من خبير، مثل خبير سطر الأوامر Terminal، لنفترض أننا نريد أن ننشئ في مجلد للمحاضرات Lectures، عشرة مجلدات فرعية منه وبكل منها ملف نصي فارغ برقم المحاضرة، والتي سنملؤها لاحقًا بملاحظات عن هذه المحاضرة، يمكن بالطبع محاولة فعل هذا بشكل يدوي لكن قد يستغرق الأمر وقتًا طويلًا لذا من الأفضل استخدام سطر الأوامر لتنفيذ هذه العملية بمساعدة Github Copilot. @terminal I want to create 10 folders names Lecture{i}, i the number of lecture, and for each lecture it would contain a text file named as lecture{i}_notes.txt لنفتح واجهة سطر الأوامر من خلال أحد الأزار السريعة من نافذة الحوار أو من قائمة View ثم نختار Terminal لنتمكن من وضع الأمر المولد وتشغيله، نلاحظ أن الأمر مكتوب باستخدام Powershell لأننا في حالتنا نستخدم نظام تشغيل ويندوز Windows ولكن يمكن أن نطلب استخدام Bash في حال استخدام نظام لينكس، وكما نرى فقد استطاع الأمر إنشاء الملفات التي طلبناها دون أية مشكلات، وهذه الميزة مفيدة للغاية عندما نرغب في تنفيذ بعض الأوامر من الطرفية ولكننا لا نتذكر الكلمات المفتاحية أو طريقة كتابة الأمر. حالات استخدام إضافية لمساعد Github Copilot استعرضنا في الفقرات السابقة أبرز حالات استخدام مساعد Github Copilot في محرر الأكواد، لكن في الواقع تتخطى حالات استخدام مساعد Github Copilot ملفات الكود العادية التي نتعامل معها في تخصصات البرمجة الشائعة كتطوير الواجهات الأمامية أو الخلفية، لتصل إلى البيئات المخصصة لمهندسي البيانات وتعلم الآلة المتمثلة في jupyter notebook، ولتجربة هذه الميزات سنستخدم مجموعة بيانات بسيطة وهي مجموعة بيانات لبعض ركاب سفينة تايتنك الغارقة والتي يمكنك العثور عليها في موقع كاجل Kaggle. لنعرض بضعة صفوف من مجموعة البيانات import pandas ad pd # حمل مجموعة بيانات تيتانيك titanic_df = pd.read_csv('titanic.csv') # اطبع الصفوف الأولى من البيانات titanic_df.head() باختيار زر التوليد Generate يمكننا طرح أسئلة أو توجيه أوامر بشكل كتابي أو من خلال الصوت ثم الموافقة على الاقتراح المولد أو طلب تعديله ليناسب حالة الاستخدام. فور الموافقة على الاقتراح بالضغط على قبول وتشغيل Accept & Run سنجد الرسم البياني التالي كمخرج. يوحي الرسم البياني بمعلومة هامة بخصوص نسب النجاة، فكما نرى نسبة النجاة في النساء أكبر، ونسبة الهلاك في الرجال أكبر، قد يكون هذا عائدًا بنسبة كبيرة للأولوية المعطاة للنساء والأطفال في قوارب النجاة ولكن هل يمكن للمساعد البرمجي فهم الرسومات البيانية وتلخيص الملاحظات الخاصة بها، لنختبر هذا. كما نلاحظ في السؤال الأول استطاع مساعدنا الذكي أن يستنتج ما يدل عليه الرسم البياني من نسبة نجاة أعلى للنساء، وكذلك بعد سؤاله عن سبب هذه قد استطاع توضيح السبب، وكما نلاحظ أيضًا فعند سؤاله باللغة العربية سيجيب باللغة العربية. لنوضح ميزة أخرى من خلال استخدام خلية كود يمكننا استخدام الرمز :q وطرح سؤال ثم سيجيب عنه المساعد البرمجي في نفس الخلية برمز مشابه به الإجابة :a كما في الصورة التالية. titanic_df.head(3) q: what does SibSp mean? الحصول على الخطة المميزة من Github Copilot مجانًا يمكن للطلبة أو المعلمين أو المساهمين في مشاريع مفتوحة المصدر الحصول على الخطة المميزة من Github Copilot بالمجان، فبالنسبة للطلبة يمكنهم رفع ما يثبت هذا من خلال هذه الصفحة التابعة لمنصة Github، أما المعلمون فيمكنهم من خلال هذه الرابط معرفة المميزات التي توفرها المنصة للمعلمين. يختلف الأمر قليلًا بالنسبة للمساهمين في المشاريع مفتوحة المصدر حيث ينبغي أن يصلوا لبعض الشروط التي تحددها المنصة ولا توجد طريقة للتقديم بشكل مباشر إنما ترسل إشعارات من خلال منصة Github للمساهمين الذين تجدهم مستحقين للخطة المميزة. بمجرد الحصول على الخطة المميزة كطالب برفع الإثباتات المطلوبة مثل الإيميل الجامعي وبطاقة الطالب التعريفية، سيعالج الطلب في بضعة أيام، وفي حال قبوله ستفتح ميزات متعددة لا تقتصر على الوصول لمساعد Github Copilot فقط، وإنما لمزايا أخرى يمكنك الاطلاع عليها من هنا، ولتفعيل الحساب المميز يجب تسجيل الخروج من حساب Github المحفوظ على محرر أكواد VS code وتسجيل الدخول إلى الحساب الذي جرى تفعيل الخطة المميزة عليها. للتأكد من تفعيل النسخة المميزة Pro يمكن مراجعة النماذج المتاحة للاستخدام، من خلال واجهة الحوار. الخاتمة تعرفنا في هذه المقالة عن أبرز الميزات التي توفرها أداة الذكاء الاصطناعي كوبايلوت Github Copilot للمبرمجين والمطورين عند دمجها في محرر الأكواد فيجوال ستوديو كود، حيث يمكنها مراجعة وتحسين الأكواد التي نعمل عليها، أو إكمال وتوقع الأكواد التي نريد كتابتها وغيرها من الفوائد الأخرى التي تساعدنا في توفير وقتنا وتعزيز إنتاجيتنا كمطورين، وتطرقنا في ختام المقال لكيفية الحصول على الخطة المميزة Pro بالمجان والتي تسمح لنا بالوصول لمزيد من المميزات والنماذج القوية، هل جربتم دمج هذه الأداة مع محرر الأكواد؟ شاركونا تجربتكم في التعليقات أسفل المقال. اقرأ أيضًا تعرف على منصة تنسرفلو TensorFlow للذكاء الاصطناعي فهم نظام التحكم بالإصدارات Git وأهمية استخدامه في مشاريع بايثون الإشراف على مشاريع البرمجيات مفتوحة المصدر عبر غيت هب GitHub الدليل المرجعي للعمل على نظام غيت Git
    1 نقطة
  22. تعد تنسرفلو TensorFlow أحد الأدوات الأساسية في جعبة مطوري نماذج الذكاء الاصطناعي، فهي توفر بيئة متكاملة تساعد على تدريب نماذج الذكاء الاصطناعي وتشغيلها واستخدامها في الاستدلال والتنبؤ القرارات المستقبلية بمرونة وكفاءة، سنتعرف في هذه المقالة على أداة تنسرفلو TensorFlow ومميزاتها في تطوير تطبيقات الذكاء الاصطناعي وتعلم الآلة. ما هي تنسرفلو TensorFlow تنسرفلو TensorFlow هي منصة مفتوحة المصدر توفر للمطورين وعلماء البيانات الأدوات التي يحتاجونها لبناء نماذج تعلم الآلة، بداية من معالجة البيانات وتجهيزها، إلى التدريب وحتى التشغيل، وتدعم تنسرفلو العديد من لغات البرمجة عن طريق مكتبات مخصصة لكل لغة مثل بايثون و جافاسكريبت وسي و جافا وغيرها من اللغات، وإن كانت لغة بايثون هي اللغة الأكثر استخدامًا والأكثر دعمًا. طورت شركة جوجل منصة تنسرفلو TensorFlow عن طريق فريقها Google Brain في عام 2015 كي تكون بديلًا مفتوح المصدر للنظام السابق الذي كان يُستخدم في تدريب خوارزميات تعلم الآلة والمعروف باسم ديست بليف DistBelief، ومن أبرز مميزات تنسرفلو TensorFlow دعم مبدأ توزيع التدريب على عدة أجهزة لتعزيز كفاءة الأداء، وسهولة تعلمها، وكونها منصة مفتوحة المصدر مما يسمح للجميع بالمساهمة في تحسينها واستخدامها في مختلف المشاريع. كما تتميز تنسرفلو TensorFlow بقدرتها على استغلال مختلف العتاد الحاسوبي مثل وحدة المعالجة المركزية CPU ووحدة المعالجة الرسومية GPU ومسرعات التدريب المختلفة، وهذا يجلعها تتفوق على بعض المكتبات التقليدية مثل ساي كيت ليرن Scikit learn الشهيرة التي توفر العديد من خوارزميات تعلم الآلة التقليدية ولكنها لا تدعم استخدام وحدات المعالجة الرسومية GPU، ناهيك عن التدريب الموزع، فمن غير الممكن تدريب نماذج ذكاء اصطناعي واسعة النطاق باستخدام مكتبات لا تدعم هذه الإمكانيات المتقدمة مثل التدريب الموزع أو المسرعات. معنى Tensors تُشتق تسمية تنسرفلو TensorFlow من العمليات التي تنفذها الشبكات العصبية على بيانات متعددة الأبعاد تعرف باسم تنسورات Tensors حيث تتدفق هذه البيانات Flow عبر الشبكات العصبية. لذا من الضروري توضيح معنى كلمة تنسور Tensor أو ما يعرف أيضًا باسم مُوتِّر فهو هيكل بيانات فالتنسور Tensor هو مفهوم أكثر شمولًا من المصفوفات Matrices والمتجهات Vectors وحتى القيم المفردة أو المضاعفات Scalars. المضاعف Scalar: عدد مفرد مثل العدد 5 وهو يُعد موترًا من الرتبة صفر. ونسميه مضاعف ضربه في موتر آخر سيضاعف القيم داخله المتجه Vector: مجموعة من الأرقام منظمة في صف واحد أو عمود واحد من القيم، ويُعد موترًا من الرتبة الأولى المصفوفة Matrix: مجموعة من الأرقام منظمة في صفوف وأعمدة، وتُعد المصفوفة موتر من الرتبة الثانية ويمكن للتنسورات أن تمتد إلى رتب Ranks أعلى، فكلما علت الرتبة كلما احتوى التنسور على بيانات متعددة الأبعاد تُستخدم في النماذج المعقدة على سبيل المثال يمكن استخدام تنسور Tensor من الرتبة الرابعة لتمثيل دفعة بيانات batch مكونة من مجموعة من الصور كما يلي: عدد الصورة في الدفعة: 4 صور ارتفاع الصورة: 64 بكسل عرض الصورة: 64 بكسل قنوات الألوان: ثلاثة هي الأحمر، الأخضر، الأزرق وبالتالي يمكننا التعبير عن هذه المعلومات باستخدام تنسور Tensor من 4 أبعاد، حيث يعبر البعد الأول عن ترتيب الصورة في الدفعة، ويعبر البعد الثاني عن الارتفاع، والثالث عن العرض، والرابع عن عدد قنوات الألوان كما في الصورة التالية: وبالتالي يمكن استخدام هذا التنسور Tensor لتعريف مدخلات الشبكات العصبية الالتفافية CNN التي تتعامل مع الصور، فهو يمكننا من معرفة عدد الصورة المدخلة بالدفعة وأبعادها وعدد قنوات الألوان بسهولة. استخدامات تنسرفلو TensorFlow شاع استخدام منصة تنسرفلو TensorFlow في مختلف مجالات الذكاء الاصطناعي، مثل تعلم الآلة وتحليل البيانات وتصنيف الصور والتعرف على الكائنات بالصور ومعالجة اللغات الطبيعية وتطبيقات الذكاء الاصطناعي التوليدي Generative AI. على سبيل المثال اعتمدت منصة X على تنسرفلو TensorFlow لترتيب التغريدات حسب الأهمية والصلة، فقد يتابع صاحب حساب مئات بل آلاف الأشخاص لذلك يصبح ترتيب التغريدات أمرًا محوريًا في تجربة الاستخدام، كما استخدمت باي بال PayPal خوارزميات مطورة بتنسرفلو TensorFlow لتستطيع كشف المعاملات الاحتيالية ومنعها. النظام المتكامل لتنسرفلو TensorFlow Ecosystem توفر تنسرفلو TensorFlow نظام بيئي متكامل لمطوري الذكاء الاصطناعي إو إطار شامل يوفر كل ما يلزم لتطوير نماذج الذكاء الاصطناعي وتشغيلها على مختلف الأجهزة سواء الحواسيب الشخصية أو الخوادم الخاصة أو الخوادم السحابية، إلى جانب استخدام نماذج مسبقة التدريب من خلال مكتبة متنوعة من النماذج وهو يوفر أدوات للتعامل مع كل من المراحل التالية: تدريب النموذج Training توزيع التدريب Distribution strategy التشغيل Deployment الاستدلال Inference لنشرح كل مرحلة من هذه المراحل بمزيد من التفصيل. التدريب Training تدريب النموذج هو الخطوة الأولى في بناء أي تطبيق ذكاء اصطناعي، ويتطلب الوصول لخطوة التدريب معالجة البيانات preprocessing حيث توفر تنسرفلو العديد من الأدوات لمعالجة البيانات وإعدادها لتدريب النماذج، كما توفر طريقة سهلة لبناء وتدريب الشبكات العصبية الاصطناعية Artificial Neural Networks من خلال مكتبة كيراس keras وهي مكتبة مختصة داخل الإطار الشامل لتنسرفلو TensorFlow. توزيع التدريب Distribution strategy يوفر إطار عمل تنسرفلو ميزة توزيع مهمة تدريب النموذج على عدة أجهزة من خلال الوحدة tf.distribute فبدلاً من تدريب النموذج على جهاز واحد فقط، يمكننا تقسيم عملية التدريب كي تنجز عبر معالجات متعددة. من الأفضل العمل في وضع شبكة العقد الحسابية Computational Graph mode لأنه مُصمم خصيصًا ليعمل بشكل أكثر كفاءة مع التدريب الموزع. أما إذا كنا نرغب في التجربة والتعديل للوصول إلى نموذج قابل للتطبيق على نطاق واسع، فيمكننا استخدام وضع التنفيذ الفوري Eager execution mode. هنالك العديد من التفاصيل المتقدمة التي علينا الانتباه لها عند تحديد استراتيجية توزيع التدريب، مثل كيفية مشاركة معاملات النموذج عبر الأجهزة المختلفة وكيفية توزيع المهام، ولكن من الأفضل للمبتدئين البدء بتعلم التدريب على جهاز واحد أولاً للسهولة. وبمجرد إتقان مهمة تطوير نموذج فعّال على جهاز واحد، يمكن العمل على توزيع التدريب على نطاق أوسع لتسريعه وتحسين أداءه. التشغيل Deployment يعد الانتقال من مرحلة تطوير وتدريب النموذج إلى مرحلة تشغيل النموذج وطرحه للمستخدمين تحديًا للكثيرين، فنحن بحاجة لعتاد حاسوبي يستضيف النموذج ويستقبل طلبات المستخدمين، ويمكننا توفيره من خلال موفري الخدمات السحابية Cloud provider، حيث يمكنن استئجار موارد حاسوبية لتشغيل النموذج الخاص بنا، وكما ذكرنا سابقًا فإن تنسرفلو TensorFlow هو إطار عمل متكامل لا يتوقف دوره عند تطوير النموذج فحسب، فيمكننا استخدام TensorFlow Serving لإدارة النماذج التي نحتاج لتشغيلها ونجري تحديث مستمر لها كلما توفرت لنا بيانات جديدة لتدريب النموذج عليها، وغيرها من المميزات العديدة الأخرى. الاستدلال Inference ما نعنيه باستدلال نموذج الذكاء الاصطناعي التنبؤ والتوقع المستقبلي باستخدام البيانات المعطاة، برمجيًا يمكن الاستدلال باستخدام الدالة model.predict في مكتبة Keras المدمجة ضمن TensorFlow فهذه الدالة البرمجية تأخذ البيانات كمدخلات، وتعطينا التوقع المنتظر بناء عليها، يتعرض النموذج أثناء التشغيل لآلاف أو ربما ملايين الطلبات من المستخدمين من أجل الاستدلال بناء على بعض البيانات المعطاة وينتظرون نتيجة سريعة لطلباتهم، لذا تعد سرعة استدلال النموذج عاملًا مهمًا في نجاح تشغيله. تساعدنا تنسرفلو TensorFlow في تحسين سرعة الاستدلال بعدة أدوات مثل: تحسين العمليات الحسابية باستخدام شبكة العقد الحسابية Computational graph تحسين تشغيل النماذج على مختلف أنواع العتاد كوحدات المعالجة المركزية CPUs، أو وحدات معالجة الرسومات GPUs، أو وحدات معالجة الموترات Tensor Processing Units TPUs استخدام المعالجة على التوازي Parallelism وهي طريقة لتقسيم الحسابات على أكثر من جهاز تقسيم الطلبات لدفعات Batching لتحسين استخدام سعة شبكات الانترنت Throughput فمع ملايين من الطلبات بنفس الوقت مرفقة بالبيانات قد تصبح سعة الشبكة غير قادرة على التعامل مع كل الطلبات ومعالجتها بسرعة كافية لذا علينا تقسيمها لدفعات أصغر النسخة الخفيفة من تنسرفلو TensorFlow light في بعض الحالات، قد نحتاج لتشغيل النماذج على أجهزة محدودة الإمكانيات كالأجهزة المحمولة. على سبيل المثال، تُعد تطبيقات التعرف على البصمة أو الوجه باستخدام كاميرا الهاتف نماذج ذكاء اصطناعي مخصصة للعمل على الهواتف محدودة الموارد. أو نحتاج لاستخدام نماذج الذكاء الاصطناعي غلى الشرائح الإلكترونية في مجالات إنترنت الأشياء IoT والروبوتات بهدف التعرف على الأشخاص أو التحكم في الآلات أو التنقل بشكل آلي دون الحاجة لتوجيه مباشر. لكن هذه المهام لن تكون ممكنة من دون القدرة على تشغيل النماذج على أجهزة منخفضة الموارد، وهنا يأتي دور النسخة الخفيفة من تنسرفلو TensorFlow Lite، وهي إطار عمل مفتوح المصدر للتعلم العميق يفيدنا في تقليص حجم النماذج وجعلها أسرع، دون التأثير الكبير على دقة التوقعات. كيف نستخدم TensorFlow مع مختلف لغات البرمجة تدعم تنسرفلو TensorFlow تشغيل النماذج في لغات برمجة متعددة كما ذكرنا سابقًا وتعد لغة بايثون Python هي اللغة الأساسية والأكثر استخدامًا لتطوير النماذج وبناء الحلول باستخدام تنسرفلو TensorFlow. لكن يمكننا استخدام تنسرفلو مع مختلف لغات البرمجة من خلال حفظ النموذج بصيغة موحدة تتيح التعامل معه في لغات مختلفة مثل C و Go و Java وغيرها. كما تحظى تطبيقات الويب Web Applications بدعم خاص في منصة تنسرفلو، إذ يمكننا تشغيل وتطوير نماذجنا باستخدام JavaScript، مما يتيح لنا تطوير تطبيقات الذكاء الاصطناعي وتشغيلها مباشرة على المتصفح من خلال المكتبة TensorFlow.js. مستودع النماذج مسبقة التدريب TensorFlow Hub توفر TensorFlow مكتبة واسعة من النماذج مسبقة التدريب Pre-trained عبر مستودعها TensorFlow Hub، حيث يمكننا استخدام هذه النماذج وتشغيلها مباشرة دون الحاجة لتطويرها من الصفر. تتميز هذه النماذج بتوفير ميزة الصقل fine-tuning وتخصيصها باستخدام بيانات مخصصة للمشكلة التي نسعى لحلها. وما يجعل هذه النماذج ذات قيمة كبيرة هو أنها تحتوي على معرفة مسبقة اكتسبتها من تدريبها على مجموعات بيانات ضخمة. لذا، يعد صقلها حلاً مثاليًا في العديد من التطبيقات، حيث يمكننا الحصول على نتائج دقيقة وفعالة بسرعة كبيرة بالاعتماد عليها. التمثيل المرئي للبيانات Visualization في تنسرفلو يحتاج مطور نماذج الذكاء الاصطناعي إلى مراقبة النماذج وملاحظة تطور أدائها مع مرور الوقت، لذا سيفيدهم تعزيز مشاريع الذكاء الاصطناعي برسومات بيانية لتحقيق هذا الهدف. توفر تنسرفلو TensorFlow هذه الإمكانية من خلال أداة تسمى Tensorboard توفر رسومات بيانية ومخططات توضيحية لتوضح معنى الأرقام ودلالتها، وتسهل اكتشاف الأنماط ونقاط الاهتمام. توفر Tensorboard إمكانية عرض العديد من الرسومات البيانية المفيدة مثل: رسم بياني لدقة النموذج accuracy وتغيرها بمرور الوقت رسم شبكة العٌقد الحسابية Computational graphs توفير رسومات بيانية لدراسة توزيع الأوزان والمعاملات التي تتغير مع الوقت عرض الصور والنصوص والصوتيات دورة الذكاء الاصطناعي احترف برمجة الذكاء الاصطناعي AI وتحليل البيانات وتعلم كافة المعلومات التي تحتاجها لبناء نماذج ذكاء اصطناعي متخصصة. اشترك الآن طريقة استخدام تنسرفلو TensorFlow تحتاج منصة تنسرفلو TensorFlow إلى إجراء العديد من العمليات الحسابية على البيانات الممثلة في التنسورات Tensors. وبالتالي، تصبح مهمة تنسرفلو هي تحسين هذه العمليات الحسابية التي تتدفق إليها التنسورات، بهدف استغلال الموارد الحاسوبية المتاحة بأفضل طريقة ممكنة. فبعض الخوارزميات قد تستغرق أيامًا أو حتى أشهر لإتمام تدريبها بسبب حجم البيانات الهائل التي تتدفق خلالها في العمليات الحسابية المعقدة. لنتعرف على طريقة القيام بالتمثيل الرياضي للعمليات الحسابية التي علينا القيام بها أثناء تدريب النموذج أو استدلاله. التعامل مع شبكة العقد الحسابية Computational graph شبكة العٌقد الحسابية Computational graph هي الوسيلة التي تستخدمها تنسرفلو TensorFlow لتمثيل العمليات والخوارزميات التي تنفذها، يمكننا التفكير بها على أنها خطة مرسومة لتنفيذ الخوارزميات، إذ تتكون الشبكة من عدة عقد متصلة تتدفق خلالها التنسورات أو البيانات في اتجاه واحد، وتمثل العقدة عملية حسابية مثل الضرب أو الجمع أو غيرها من العمليات. يكتب المطور الأكواد البرمجية بلغة برمجة مثل بايثون، ثم يأتي دور تنسرفلو TensorFlow بتجهيز شبكة العٌقد الحسابية computational graph التي تتضمن جميع الخطوات لتنفيذ هذه الأكواد، ولتحسينها يجري تبسيط الخطوات المتكررة التي يمكن اختزالها، أو التخلص من الخطوات التي يمكن حذفها لتوفير الموارد الحاسوبية. كما تستخدم تنسرفلو طريقة تسمى الحساب المسبق للثوابت Constant folding، تتعامل هذه الطريقة مع المتغيرات المعلومة أو التي يمكن حساب قيمتها بشكلٍ مباشر، فتحولها إلي قيمة ثابتة أثناء بناء شبكة العٌقد الحسابية Computational graph، حيث لا نحتاج لحساب هذه القيم وقت التنفيذ. على سبيل المثال إذا كان a=2 ، b=3 و c=a+b فيمكننا إيجاد قيمة المتغير c=5 وعدم إجراء العملية الحسابية أينما وجد هذا المتغير مجددًا وقت التنفيذ، فهذا المتغير لا يعتمد سوى على ثوابت معلومة. كما تعتمد أيضًا على عملية إعادة استخدام الحدود المتكررة Common Subexpression Elimination لتبسيط شبكة العٌقد الحسابية Computational graph بحساب العمليات التي تتكرر مرة واحدة وتستخدم الناتج أينما وجد تكرار للعملية الحسابية. على سبيل المثال: إذا كان a=x+y، و b=x+y فإن a=b لذا نقوم بالعملية x+y مرة واحدة ونعوض عنها عندما نجد a أو b. أخيرًا يمكننا استخدام متغيرات أقل دقة في تنسرفلو TensorFlow كأن نستخدم متغير من نوع float16 بدلًا من float32 لتسريع الحسابات وتقليل استهلاك الموارد، ويجدر الذكر أن هذه الميزة لا تعمل إلا مع وحدات المعالجة الرسومية GPUs. لاحظ المثال التالي: import tensorflow as tf # قم بتعريف رقم عشري number = 123.456 # حدد حجم المتغير الذي تريد أن تحفظ الرقم به ليكون 32 float32 = tf.constant(number, dtype=tf.float32) # حدد حجم المتغير الذي تريد أن تحفظ الرقم به ليكون 16 float16 = tf.constant(number, dtype=tf.float16) # لنرى الاختلاف في الدقة بين الرقمين print("float32: ", float32.numpy()) print("float16: ", float16.numpy()) # حجم التخزين print("Size of float32: ", float32.numpy().nbytes, "bytes") print("Size of float16: ", float16.numpy().nbytes, "bytes") ''' output float32: 123.456 float16: 123.44 Size of float32: 4 bytes Size of float16: 2 bytes ''' قد يصل عدد المتغيرات والمعاملات في نماذج الذكاء الاصطناعي لملايين بل مليارات في بعض الأحيان، لذا من الضروري الاعتماد على تغيير دقة المتغيرات لتسريع عملية التدريب وتقليص حجم النماذج، فأداء النموذج قد يتأثر بنسبة جيدة من هذا التغير. ملاحظة: تجدر الإشارة إلى أن استخدام أسلوب تغيير دقة المتغيرات يستخدم في تقليص حجم نماذج الذكاء الاصطناعي لتعمل على الحافة on Edge أي على الأجهزة محدودة الموارد، مثل الأجهزة المحمولة أو الشرائح الحاسوبية البسيطة، التي قد لا تتسع إلا لبضعة آلاف من البايتات. استخدام شبكة العقد الحسابية لتنفيذ العمليات تفيدنا شبكة العٌقد الحسابية Computational graphs في جعل عملية تدريب النماذج أكثر مرونة وكفاءة عبر عدة منصات وأجهزة حاسوبية مختلفة، فهي محسنة لتتعامل مع العتاد الحاسوبي بشكل أفضل، كما يمكن نقل شبكة العقد الحسابية بعد تدريب النموذج ليصبح قابلًا للاستخدام على منصات وأجهزة متنوعة ولغات برمجة مختلفة فهي مجرد قالب لتنفيذ مجموعة من الأوامر التي تعطي نتيجة أو توقع في النهاية. كانت هذه الطريقة هي الوحيدة في الإصدار الأول من تنسرفلو TensorFlow 1.x ، ولكنها عانت من بعض العيوب، فقد كان علينا كمطورين كتابة الأكواد البرمجية بشكل مثالي دون أن نرى نتائج الخطوات الوسيطة، ثم ننتظر تحويل الأكواد المثالية إلي شبكة عقد حسابية محسنة، وهذا يستغرق الكثير من الوقت، بالطبع لن نحصل على النتيجة التي نرجوها من أول محاولة، فالبرمجة عملية تحسن تكرارية وتراكمية، وخاصة عند تطوير نماذج الذكاء الاصطناعي التي تحتاج إلى تجربة العديد من المعاملات حتى نجد التوليفة المناسبة من تلك المعاملات. لاحظ الكود التالي الذي يوضح كيفية تعريف دالة ConcreteFunction في تنسرفلو وكيفية تحديد المدخلات والمخرجات للعمليات الحسابية حيث سنحول العمليات البرمجية البسيطة مثل الجمع بين متغيرين إلى شبكة عُقد حسابية يمكن تنفيذها بكفاءة على أجهزة مختلفة. import tensorflow as tf @tf.function # لجعل تنسرفلو يستخدم شبكة العٌقد الحسابية def add_numbers(a, b): return a + b # نعرف ثابتين a = tf.constant(5) b = tf.constant(3) # لنقم بعملية الجمع بطريقة شبكة العٌقد الحسابية result = add_numbers(a, b) # لنحصل على الخطوات التي قام بها تنسرفلو graph_steps = add_numbers.get_concrete_function(a, b) print("الخطوات") print(graph_steps) print("الخطوات بشكل مفصـل ومبسـط") for op in graph_steps.graph.get_operations(): print(op.name) الخطــوات ConcreteFunction Input Parameters: a (POSITIONAL_OR_KEYWORD): TensorSpec(shape=(), dtype=tf.int32, name=None) b (POSITIONAL_OR_KEYWORD): TensorSpec(shape=(), dtype=tf.int32, name=None) Output Type: TensorSpec(shape=(), dtype=tf.int32, name=None) Captures: None الخطـوات بشكـــل مفصـل ومبسـط a b a d d I d e n t i t y تقنية التنفيذ الفوري للعمليات الحسابية Eager execution كانت عملية تطوير النماذج غير تفاعلية في الإصدار الأول من تنسرفلو TensorFlow 1.x، كما ذكرنا في الفقرة السابقة، حيث كان المطورون يكتبون الأكواد ثم ينتظرون لفترة طويلة لتحويل الأكواد إلى شبكة عُقد حسابية محسّنة، هذا جعل من الصعب اكتشاف الأخطاء وتحسين الأداء في الوقت الفعلي. لهذا السبب، وجدت طريقة التنفيذ الفوري للعمليات الحسابية Eager Execution في TensorFlow 2.x لتجعل عملية التطوير أكثر تفاعلية وسهولة. حيث يمكننا من خلال التنفيذ الفوري Eager Execution بناء العمليات الحسابية بشكل مباشر. على سبيل المثال، عندما نجمع رقمين، سنحصل على النتيجة على الفور دون الحاجة للانتظار لإكمال البرمجة أو إنشاء شبكة العُقد الحسابية. وبالتالي تسهل علينا هذه الطريقة اكتشاف الأخطاء، واختبار التعديلات، وتحسين أداء النموذج بشكل فوري وتفاعلي. لاحظ الكود التالي لاستخدام التنفيذ الفوري Eager Execution في تنسرفلو: import tensorflow as tf # Eager Mode مفعل بشكل افتراضي a = tf.constant(5) b = tf.constant(3) c = a + b print("ناتج العملية الفورية:", c.numpy()) # ناتج العملية الفورية: 8 الخاتمة وصلنا لختام مقالنا الذي شرحنا فيه بالتفصيل إطار العمل الشهير تنسرفلو TensorFlow، وأوضحنا العديد من الأدوات والتقنيات التي تُمكّن المطورين من تطوير نماذج الذكاء الاصطناعي عبر مختلف المراحل، من التدريب وحتى التشغيل. كما قمنا بتطبيق أمثلة عملية بسيطة توضح كيفية استخدام هذه الأدوات بشكل تفصيلي، بدءًا من بناء الشبكات الحسابية حتى التنفيذ الفوري للعمليات الحسابية. ننصح بتجربة هذه المنصة والاستفادة من أدواتها لتحسين وتبسيط عملية تطوير تطبيقات الذكاء الاصطناعي. اقرأ أيضًا ما هي منصة Hugging Face للذكاء الاصطناعي تعلم الذكاء الاصطناعي كل ما تود معرفته عن دراسة الذكاء الاصطناعي بناء شبكة عصبية للتعرف على الأرقام المكتوبة بخط اليد باستخدام مكتبة TensorFlow تعرف على أهم مشاريع الذكاء الاصطناعي تعرف على مكتبة المحوّلات Transformers من منصة Hugging Face
    1 نقطة
  23. تتدرب نماذج التعلم الآلي على مجموعات من البيانات الضخمة حيث توسم نقاط الاهتمام في البيانات -أي الأجزاء المهمة في التي نريد التركيز عليها والتعلم منها- لإعطائها معنى وسياق. نتعمق في هذه المقالة في وصف طرق بناء أنظمة وسم البيانات data labeling من الصفر مركزين على تدفق البيانات في النظام وكيفية تأمينها وضمان جودتها. ما معنى وسم البيانات ينتج الذكاء المتأصل في الذكاء الاصطناعي من تعرضه لكميات من البيانات التي تتدرب عليها نماذج تعلم الآلة، ومع التقدم الحالي في النماذج اللغوية الضخمة مثل GPT-4 وجيمناي Gemini التي يمكنها معالجة تريليونات الوحدات اللغوية الصغيرة التي تسمى tokens، ولا تتكون هذه البيانات المستخدمة في التدريب من معلومات أولية مستخلصة من الإنترنت فقط فهي تتضمن أيضًا وسومًا حتى يكون التدريب فعالًا. وسم البيانات data labeling هو عملية تحويل البيانات الأولية والمعلومات غير المعالجة إلى بيانات موسومة أو بيانات معنونة لإضافة سياق ومعنى واضح لها، وتحسّن هذه العملية من دقة تدريب النموذج، فأنت توضح وتشير إلى ما ترغب للنظام أن يتعرف عليه، وتتضمن الأمثلة على وسم البيانات مهام مثل تحليل المشاعر في النصوص حيث توسم النصوص في هذه الحالة بمشاعر معينة مثل إيجابي أو سلبي أو محايد، ومهام التعرف على الكائنات في الصور إذ يوسم كل كائن في الصورة بتصنيف معين. وكذلك تستخدم في تنصيص الكلام المنطوق في الملفات الصوتية، أو وسم الأفعال في مشاهد الفيديو. تلعب جودة البيانات دورًا هائلًا في تدريب البيانات، فالمدخلات الرديئة تؤدي إلى مخرجات رديئة فلا يمكننا توقع أداء مبهر من نموذج لم يُدرّب إلا على بيانات رديئة الجودة، فالنماذج التي تتدرب على بيانات بها أخطاء وتناقض في الوسوم ستواجه صعوبة في محاولة التأقلم مع البيانات الجديدة التي لم تراها في التدريب وربما تكون متحيزة في توقعاتها مسببة أخطاء في المخرجات، ويمكن أن يؤدي تراكم البيانات الرديئة في المراحل المختلفة إلى تأثير مركب مما يؤثر على كل الخطوات والنماذج التي تعتمد عليها. يهدف هذا المقال لتوضيح طرق تعزيز جودة البيانات واكتساب أفضلية تنافسية في كافة مراحل وسم البيانات. وللسهولة سنركز على المنصات والأدوات التي تستخدم في عملية وسم البيانات ونقارن بين مميزات ومحدوديات كل تقنية وأداة، وبعد ذلك ننتقل إلى اعتبارات أخرى لا تقل أهمية مثل تقليل التحيز، وحماية الخصوصية، وزيادة دقة وسم البيانات. دور وسم البيانات في سير عمل تطبيقات تعلم الآلة يقسم تدريب نماذج تعلم الآلة إلى ثلاثة تصنيفات عامة وهي التعلم الخاضع للإشراف Supervised learning والتعلم غير الخاضع لإشراف Unsupervised learning والتعلم المعزز Reinforcement learning. يعتمد التعلم الخاضع للإشراف على البيانات الموسومة labeled training data، والتي تحتوي نقاط الاهتمام في البيانات بها على وسوم بالتوقع أو العنوان الصحيح، فيتعلم النموذج أن يربط بين خواص المدخلات والوسوم أو التسميات الصحيحة المرتبطة بها مما يعطيه القدرة على تخمين وسوم البيانات الجديدة التي لم يتدرب عليها من قبل ولا يعرف ما وسمها الحقيقي، من جهة أخرى يحلل التعلم غير الخاضع للإشراف البيانات غير الموسومة بحثًا عن الأنماط المخفية أو التجميعات الموجودة في البيانات، وأما في التعلم المعزز فتكون عملية التدريب بالتجربة والخطأ ويمكننا التدخل في مرحلة التقييم والمراجعة لتوجيه عملية التعلم. تُدرّب معظم نماذج التعلم الآلي باستخدام أسلوب التعلم الخاضع للإشراف supervised learning. ونظرًا لأهمية البيانات عالية الجودة فينبغي اعتبارها في كل خطوة من عملية التدريب لذلك يلعب وسم البيانات دورًا حيويًا في هذه العملية. إن تحضير وجمع البيانات هي العملية التي تسبق وسم البيانات، حيث تُجمع البيانات الأولية أو الخام من مصادر متنوعة مثل المستشعرات الإلكترونية sensors، وقواعد البيانات، وسجلات العمليات logs، وواجهات برمجة التطبيقات APIs، وفي الغالب لا تخضع هذه البيانات لهيكل أو تنسيق ثابت وقد تحتوي على تناقضات وشوائب مثل قيم مفقودة أو قيم شاذة outliers أي قيما غير مألوفة وتختلف بشكل كبير عن باقي البيانات، أو قيم متكررة، لذا في عملية المعالجة تُنظّف البيانات وتُنسَّق وتُحوّل لتكون جاهزة لوسمها labeling، وتستخدم استراتيجيات عديدة للتعامل مع معالجة البيانات مثل حذف الصفوف المكررة، أو حذف الصفوف التي تحتوي على قيم مفقودة أو التعويض عن هذه القيم باستخدام نماذج تخمين إحصائية، كما يمكننا إحصائيًا اكتشاف القيم الشاذة outliers ومعالجتها. تلي معالجة البيانات في الخطوات عملية وسم البيانات لتوفير المعلومات التي يحتاجها نموذج التعلم الآلي كي يتعلم، وتختلف استراتيجيات وسم البيانات باختلاف نوع هذه البيانات والغرض من النموذج، فوسم الصور يتطلب أساليب مختلفة عن وسم النصوص، وعلى الرغم من وجود أدوات وسم آلية ولكن التدخل البشري يحسن بشكل كبير من عملية الوسم خاصة عندما يتعلق الأمر بالدقة أو تفادي التحيز الذي قد يوجد في الأدوات الآلية، وبعد أن توسم البيانات تاتي مرحلة تأكيد الجودة والتي تضمن الدقة والتناسق واكتمال الوسوم، ويعمل فريق تأكيد الجودة على توظيف أسلوب الوسم المزدوج إذ يقوم أكثر من شخص بوسم عينة من البيانات بشكل مستقل ويقارنون نتائجهم لحل أي اختلاف في الآراء. الخطوة التالية هي خضوع النموذج للتدريب باستخدام البيانات الموسومة ليتعلم الأنماط والعلاقات بين المدخلات والوسوم المرتبطة بها، حيث تعدل معاملات النموذج في عملية تكرارية من التخمين وتقييم الخطأ حتى تتحسن الدقة بالنسبة للوسوم المعلومة، ولتقييم فعالية النموذج يختبر على بيانات موسومة لم يرها من قبل، وتقاس صحة تخميناته وتوقعاته باستخدام معايير رقمية مثل نسبة الصواب accuracy والدقة precision والاستذكار Recall أو الحساسية sensitivity، فإذا كان أداء النموذج ضعيفًا تُعدل بعض الأشياء قبل إعادة التدريب مثل تحسين جودة بيانات التدريب بتقليل الضوضاء بالبيانات data noise أو تقليل التحيز وتحسين عملية وسم البيانات، وفي النهاية بعد إعادة التدريب وتحسين النموذج يصبح جاهزًا للتشغيل deployment ويمكنه التفاعل مع البيانات في العالم الحقيقي. وأخيرًا من المهم مراقبة أداء النموذج لكشف وتحديد أي مشكلات قد تتطلب تحديث النموذج أو إعادة تدريبه. تحديد أنواع وطرق وسم البيانات تَسبق عملية تحديد نوع البيانات مرحلةَ تصميم وبناء معمارية وسم البيانات، حيث توجد البيانات في تنسيقات وهياكل متنوعة تشمل النصوص والصور ومقاطع الفيديو والملفات الصوتية، وكل نوع من البيانات يأتي بمجموعة من التحديات المميزة التي تتطلب طريقة خاصة في التعامل معها لتحقيق تناسق ودقة في عملية وسم البيانات، بالإضافة لذلك فبعض البرمجيات المستخدمة في وسم البيانات تتضمن أدوات مصممة للتعامل مع أنواع معينة من البيانات، وكذلك تتخصص فرق الوسم في وسم نوع محدد من البيانات، لذلك يعتمد اختيار البرمجيات والفريق المناسب بشكلٍ كبير على المشروع. على سبيل المثال، قد تطلب عملية وسم بيانات للرؤية الحاسوبية computer vision تصنيف الصور الرقمية ومقاطع الفيديو وإنشاء مستطيلات التحديد bounding boxes لعنونة الكائنات الموجودة داخلها. وتحتوي مجموعة بيانات وايمو المفتوحة waymo's open dataset مثلًا على مجموعة بيانات موسومة لمهام الرؤية الحاسوبية computer vision للسيارات ذاتية القيادة، وقد وُسمت هذه البيانات بجهود مجموعة من الأفراد عبر الإنترنت مع مساهمات واسمين فرديين. ومن التطبيقات الأخرى للرؤية الحاسوبية computer vision التصوير الطبي، والاستطلاع الجوي، والمراقبة، والتأمين، والواقع المعزز augmented reality. ويمكن وسم النصوص ومعالجتها باستخدام خوارزميات معالجة اللغات الطبيعية Natural Language processing بمجموعة متنوعة من الطرق، تشمل تحليل المشاعر sentiment analysis من النصوص مثل المشاعر الإيجابية والسلبية، واستخلاص الكلمات المفتاحية مثل العبارات ذات الصلة، وكذلك التعرف على الكيانات الموجودة في النص مثل الأشخاص والأماكن والتواريخ، يمكن أيضًا تصنيف النصوص القصيرة. على سبيل المثال، يمكن تحديد فيما إذا كانت رسالة بريد إلكتروني رسالة مزعجة spam أم لا، ويمكن التعرف على لغة النص كالعربية أو الانجليزية، وتستخدم نماذج معالجة اللغات الطبيعية في تطبيقات مثل أنظمة المحادثة chatbots والمساعدات البرمجية coding assistants والمترجمات translators ومحركات البحث search engines. كما تستخدم البيانات الصوتية في تطبيقات متنوعة تشمل تصنيف الصوتيات، والتعرف على الصوت، والتعرف على الكلام، والتحليل الصوتي، ويمكن وسم الملفات الصوتية للتعرف على كلمات معينة مثل "يا سيري" أو "Hey Siri"، وحتى تصنيف أنواع مختلفة من الأصوات، أو تحويل الكلام المنطوق إلى كلمات مكتوبة. إن العديد من نماذج التعلم الآلي هي نماذج متعددة multimodal أي أنها نماذج قادرة على تفسير والتعامل مع البيانات من مصادر مختلفة بشكل متزامن، فيمكن للسيارات ذاتية القيادة جمع معلومات بصرية مثل إشارات المرور والمارين في الطريق وتجمع بيانات صوتية مثل صوت أبواق السيارات، مما يتطلب وسمًا متعددًا multimodal labeling حيث يقوم الواسمون البشريون بجمع ووسم أنواع مختلفة من البيانات بطريقة تراعي العلاقات والتفاعلات بين تلك الأنواع. من المهم اختيار الطريقة الأنسب لوسم البيانات قبل الشروع في بناء النظام الخاص بنا، وقد كان الوسم البشري للبيانات سابقًا هو الطريقة المتبعة، ولكن مع التقدم الهائل في التعلم الآلي ازدادت إمكانيات الأتمتة مما جعل العملية أكثر كفاءة وأقل تكلفةً، ولكن تجدر الإشارة أنه وعلى الرغم من تحسن دقة أدوات الوسم الآلية فإنها لاتزال غير قادرة على مواكبة الدقة والاعتمادية التي يوفرها البشر. لذا يلجأ المختصون عادة لأسلوب مختلط يتضمن مشاركة البشر والبرامج الآلية في عملية وسم البيانات، حيث تستخدم برامج آلية لتوليد الوسوم الأولية ثم تجري مراجعتها وتدقيقها وتصحيحها بواسطة الواسم البشري، وتضاف الوسوم المصححة إلى مجموعة بيانات التدريب لتحسين دقة وأداء البرنامج الآلي، وهذا يضمن الحفاظ على مستوى جيد من الدقة والتناسق وهو أكثر الاستراتيجيات شيوعًا في وسم البيانات. اختيار مكونات نظام وسم البيانات تبدأ عملية وسم البيانات بخطوة تجميع البيانات وتخزينها، حيث تجمع البيانات إما بشكل يدوي باستخدام أساليب مثل المقابلات الشخصية والاستبيانات واستطلاعات الرأي أو بشكل آلي مثل استخلاص البيانات من الإنترنت web scraping. في حال عدم امتلاكك للموارد الكافية لجمع البيانات على نطاق واسع فيمكن الاعتمدا على مجموعات البيانات مفتوحة المصدر المتوفرة على منصات مثل كاجل Kaggle أو مستودع مجموعات البيانات الخاص بجامعة كاليفورنيا ايفرين UCI repository أو بحث جوجل لمجموعات البيانات Google dataset search أو جت هاب GitHub فكلها مصادر جيدة، بالإضافة لمصادر البيانات المصنعة باستخدام نماذج رياضية لتحاكي البيئات الحقيقة، ولتخزين هذه البيانات يمكنك تأجير مساحات تخزينية من مزودي خدمات سحابية مثل جوجل أو مايكروسوفت حتى تتوسع حسب احتياجاتك، فبشكل نظري يمكنهم توفير مساحة تخزين غير محدودة مع توفير ميزات مدمجة تزيد من التأمين، ولكن إذا كنت تعمل مع بيانات شديدة السرية وتحتاج للامتثال لقوانين وأنظمة معينة مثل مثل قانون حماية البيانات العامة GDPR فحلول التخزين المحلية هي الخيار المناسب. يمكنك أن تبدأ في وسم البيانات فور أن تنتهي من تجميعها، وتعتمد عملية الوسم بشكل رئيسي على نوع البيانات، ولكن في العموم تحدد كل نقاط الاهتمام في البيانات وتصنف باستراتيجية إبقاء الإنسان مشاركًا في العملية، وتوجد العديد من المنصات المتاحة التي تبسط هذه العملية المعقدة، وبعضها مفتوح المصدر مثل Doccano و LabelStudio و CVAT ومنصات تجارية مثل scale data engine و labelbox و Supervisely. تُراجَع الوسوم بعد إنشائها بواسطة فريق ضمان الجودة لضمان الدقة والتناسق وحل أي تناقضات موجودة في الوسوم أو اختلافات في تقرير الوسم من خلال الطرق اليدوية مثل تقرير الأغلبية أو اللجوء للمعايير أو استشارة خبراء في هذا التخصص، ويمكن تخفيف التناقضات بطرق آلية مثل استخدام نماذج إحصائية مثل Dawid-Skene لجمع الوسوم المختلفة من عدة مصادر في وسم واحد معتمد أكثر، فور الاتفاق على الوسوم بواسطة ذوي الصلة تعد الحقائق مطلقة يمكن استخدامها لتدريب نماذج التعلم الآلي، بعد التأكد من أن الوسوم دقيقة ومتسقة، تصبح هذه الوسوم حقائق ثابتة يمكن استخدامها لتدريب نماذج تعلم الآلة. هنالك أيضًا أدوات مفتوحة المصدر وأخرى تجارية تساعدنا في مراجعة الوسوم والتحقق من الجودة وتدقيق البيانات، قد تكون الأدوات التجارية أكثر تطورًا وتوفر ميزات إضافية مثل التدقيق الآلي، ونظام إدارة المراجعات، والموافقة عليها أو رفضها وأدوات تعقب لمعايير الجودة. مقارنة بين أدوات وسم البيانات تُعد الأدوات مفتوحة المصدر نقطة بداية جيدة، فعلى الرغم من محدودية وظائفها وميزاتها مقارنة بالأدوات التجارية فإن غياب رسوم الترخيص يمثل ميزة مهمة للمشاريع الصغيرة، وتقدم الأدوات التجارية وسم أولي مدعوم بالذكاء الاصطناعي ويمكن تعويض هذه الميزة في الأدوات مفتوحة المصدر عن طريق دمجها مع نموذج تعلم آلي خارجي. الاسم أنواع البيانات المدعومة إدارة سير العمل تأكيد الجودة دعم التخزين السحابي ملاحظات إضافية استديو الوسم النسخة العامة Label Studio Community Edition نصوص، صور، صوتيات، مقاطع فيديو، بيانات زمنية نعم لا التخزين السحابي لجوجل، التخزين السحابي لمايكروسوفت أزور تحتوي النسخة المجانية على مجموعة واسعة من الميزات، ولكن النسخة المدفوعة الخاصة بالشركات أكثر احترافية سي في أيه تي CVAT صور ومقاطع فيديو نعم نعم التخزين السحابي لجوجل، التخزين السحابي لمايكروسوفت أزور يدعم LiDAR وهو نظام لقياس المسافات ووسم المجسمات المكعبة ثلاثية الأبعاد 3D Cuboid، بالإضافة إلى وسم الأوضاع المختلفة لهيكل مبسط من نقاط مفصلية في جسد الإنسان ويمكن استخدامه لتخمين وقفته أو حركته دوكانو Doccano نصوص وصور وملفات صوتية نعم لا التخزين السحابي لجوجل مصمم لوسم النصوص ڤيا VIA (VGG Image Annotator) صور وملفات صوتية ومقاطع فيديو لا لا لا يعتمد على المتصفح ميك سينس MakeSense.AI صور لا لا لا يعتمد على المتصفح توفر المنصات مفتوحة المصدر العديد من الميزات المطلوبة لمشاريع وسم البيانات ولكن المشاريع المعقدة لتعلم الآلة تتطلب ميزات متقدمة مثل الأتمتة والقابلية للتوسع وتتاح هذه الميزات الإضافية في المنصات التجارية، بالإضافة لمزايا تأمينية والدعم الفني ومزايا مٌسّاعدة في عملية الوسم باستخدام نماذج التعلم الآلي وشاشة التقارير والرسومات البيانية التحليلية كل هذه الميزات تجعل المنصات التجارية تستحق الزيادة في التكلفة. الاسم أنواع البيانات المدعومة إدارة سير العمل تأكيد الجودة دعم التخزين السحابي ملاحظات إضافية Lablbox نصوص، صور، مقاطع فيديو، ملفات صوتية، HTML نعم نعم التخزين السحابي لجوجل، التخزين السحابي لمايكروسوفت أزور توفر المنصة فرقًا متخصصة في الوسم وفي المجالات المرتبطة بالبيانات من خلال خدمة Boost Supervisely صور، مقاطع فيديو، بيانات ثلاثية الأبعاد مجمعة من عدة مستشعرات 3D sensor fusion، الصور الطبية بصيغة DICOM نعم نعم التخزين السحابي لجوجل، التخزين السحابي لميكروسوفت أزور بيئة متكاملة مفتوحة للدمج مع مئات التطبيقات المبنية على محرك التطبيقات الخاص بهم، يدعم LiDAR و RADAR وهي أنظمة لقياس البعد واكتشاف الأجسام بالإضافة إلى الصور الطبية متعددة الشرائح أو المستويات Scale AI Data Engine النصوص، الصور، ملفات الصوت، مقاطع الفيديو، البيانات ثلاثية الأبعاد المجمعة من عدة مستشعرات 3D sensor fusion، الخرائط نعم نعم التخزين السحابي لجوجل، التخزين السحابي لمايكروسوفت أزور يوفر أدوات متخصصة في قطاعات وصناعات محددة SuperAnnotate النصوص، الصور، الملفات الصوتية، مقاطع الفيديو، PDF ،HTML نعم نعم التخزين السحابي لجوجل، التخزين السحابي لميكروسوفت أزور يوفر فرق وسم متعددة اللغات وخبراء متخصصين في مجالات مختلفة وإذا كنا بحاجة لميزات خاصة لا تتوفر في الأدوات المتاحة فيمكننا في هذه الحالة بناء منصة وسم محلية نقرر من خلالها ما هي البيانات التي سندعمها وما هي تنسيقاتها ونحديد أنوع الوسوم المستخدمة، كما يمكننا تصميم وبناء ميزات مثل الوسم الأولي ومراجعة الوسوم وتأكيد الجودة وأدوات لإدارة سير العمل، ولكن تكلفة بناء وتشغيل منصة تضاهي المنصات التجارية تكلفة باهظة لأغلب الشركات. يعتمد الاختيار في النهاية على عدة عوامل، مثلًا إن لم تكن الأدوات المتاحة من خلال الأطراف الخارجية تناسب متطلبات المشروع أو إذا كانت البيانات سرية فحينها سيكون بناء منصة مخصصة محليًا هو الحل الأمثل، بينما يمكن لمشاريع أخرى أن تستفيد من نظام مختلط فالمهام الأساسية للوسم تُنفَّذ بواسطة الأدوات التجارية بينما الميزات المخصصة يمكن تطويرها محليًا ودمجها مع المنصات الخارجية. ضمان الجودة والأمان في أنظمة وسم البيانات يشمل نظام وسم البيانات العديد من المكونات التي تجعله معقدًا فهو يتعامل مع كميات هائلة من البيانات ومستويات مختلفة من البنية التحتية الحاسوبية وسياسات مختلفة وأنظمة سير عمل متعددة الطبقات والمستويات، كل هذا يجعل من عملية تشغيل هذه المكونات معًا بشكل سلسل مهمة مليئة بالتحديات وقد تؤثر على جودة وسم البيانات وفعاليته بالإضافة لمخاطر الأمان والخصوصية الموجودة في كل المراحل التي تمر بها العملية. تحسين دقة وسم البيانات تسرع الأتمتة من عملية الوسم ولكن الاعتماد المفرط على الأدوات المؤتمتة لوسم البيانات يمكن أن يقلل من دقة العملية التي تتطلب وعيًا بالسياق والمجال أو قدرة على الحكم الموضوعي وهذه قدرات لا يستطيع حاليًا أي نظامٍ برمجي تقديمها، لذا من المهم وضع توجيه لعملية الوسم بشكل بشري واكتشاف الاخطاء ومعالجتها لضمان جودة وسم البيانات. كما يمكن تقليل الأخطاء في عملية الوسم بتوفير مجموعة من التوجيهات والإرشادات الشاملة، فمثلًا ينبغي أن تعرف كل التصنيفات الممكنة والتنسيقات المتعامل معها، وينبغي أن تكون هذه الإرشادات مفصلة خطوة بخطوة وتتضمن حلولًا للحالات المتطرفة أو الخاصة، كما ينبغي أن تتوفر مجموعة من الأمثلة التي توضح كيفية التعامل مع نقاط الاهتمام الواضحة وغير الواضحة في البيانات. يمكننا أيضًا تجميع آراء عدد من الواسمين المستقلين عن نفس نقطة الاهتمام في البيانات ومقارنة نتائجهم فهذا من شأنه أن يؤدي إلى درجة أعلى من الدقة. فالاتفاق بين الواسمين Inter-annotator-agreement أو ما يعرف بمعيار IAA اختصارًا هو معيار مستخدم لقياس درجة الاتفاق هذه، أي أن نقطة الاهتمام في البيانات التي تحصل على أرقام منخفضة لهذا المعيار تتطلب عملية مراجعة لتقرير الوسم الأنسب لها. كما يساهم تتبع واكتشاف الأخطاء بشكل كبير في تحسين دقة الوسوم، وكشف الأخطاء وهذا يمكن أن ينفذ آليًا باستخدام برامج مثل كلين لاب Cleanlab حيث تجري مقارنة للبيانات الموسومة باستخدام القواعد المعرفة مسبقًا لإكتشاف أي أخطاء أو اختلافات، فبالنسبة للصور يمكن اكتشاف التداخل بين مستطيلات التحديد bounding boxes آليًا، بينما في النصوص يمكن اكتشاف الوسوم المفقودة أو التنسيقات الخاطئة، وتجري مراجعة جميع الأخطاء بعد ذلك من قبل فريق ضمان الجودة، كما يمكن الاستعانة بالذكاء الاصطناعي الذي توفره العديد من المنصات التجارية لاكتشاف الأخطاء التي تحدد الأخطاء المحتملة باستخدام نماذج تعلم آلي مدربة مسبقًا على بيانات موسومة، بعد تحديد ومراجعة نقاط الاهتمام في البيانات وتقرير الوسم الأصح يضاف لبيانات التدريب الخاصة بالنموذج لتحسين دقته من خلال عملية التعلم. يوفر تتبع الأخطاء تقييمًا في غاية الأهمية ويُحسّن عملية الوسم من خلال التعلم المستمر الذي يجري بتتبع عدة معايير مفتاحية مثل دقة الوسم ودرجة الإجماع بين الواسمين، فإن كان هناك مهام معينة تكثر فيها أخطاء الواسمين فينبغي تحديد الأسباب المؤدية لهذه الأخطاء، وتوفر العديد من المنصات التجارية أدوات مبنية بها تساعد على المراقبة والتقييم من خلال الرسومات البيانية التفاعلية التي توضح سجل الوسم وتوزيع الأخطاء، ويمكن تحسين الأداء بتعديل المعايير والإرشادات لتوضيح كيفية التعامل مع الإرشادات غير الواضحة وتحسين القواعد التي تساعد في اكتشاف الأخطاء. التعامل مع التحيز وضمان العدالة تعتمد عملية وسم البيانات بشكل مكثف على الحكم والتفسير الشخصي، مما يشكل تحديًا على الواسمين ليقومو بوسم البيانات بشكل عادل وغير متحيز حتى عندما تكون البيانات غير واضحة، فمثلًا عند تصنيف النصوص يمكن أن تكون بعض العبارات والمشاعر مزاحًا أو سخرية ومن السهل أن يساء فهمها، ومثالٌ آخر في تصنيف تعابير الوجه التي يمكن أن يصنفها البعض على أنه وجه حزين والبعض الآخر يراه وجه يشعر بالملل، لذا فنسبية التصنيف أو الوسم تفتح الباب أمام التحيز أو الخطأ، ويمكن أن تكون مجموعة البيانات نفسها منحازة اعتمادًا على المصدر أو التركيب السكاني أو وجهة نظر جامعها ويمكن أن تكون غير ممثلة للمجتمع، وتدريب نماذج التعلم الآلي على بيانات منحازة يمكن أن يؤدي إلى توقعات خاطئة مثل تشخيص خاطئ للمرض بسبب تحيز البيانات الطبية المستخدمة للتدريب. لتقليل التحيز في عملية الوسم ينبغي أن يكون فريق الواسمين وفريق تأكيد الجودة من خلفيات متنوعة، فالوسم المزدوج والمتعدد يمكن أن يقلل من تأثير التحيز الناتج عن الأفراد، وعلى البيانات المستخدمة في التدريب أن تعكس العالم الحقيقي بتمثيل متوازن للتركيبة السكانية والجغرافية ويمكن جمع البيانات من مصادر واسعة التنوع وإضافة بيانات مخصوصة لمواجهة أي تحيز موجود في المصادر الأولية للبيانات، بالإضافة لذلك يمكنها أن تقلل طرق تعزيز وزيادة البيانات data augmentation مثل قلب الصور وإعادة صياغة النصوص من التحيز وتزيد تنوع البيانات بشكل مصطنع، فقلب الصورة مثلًا يُمكّن النموذج من تعلم التعرف على الكائنات بالصورة بغض النظر عن زاوية العرض مما يقلل التحيز لزاوية دوران الصورة، وإعادة صياغة النصوص تعرض النموذج لطرق أخرى للتعبير عن المعلومات مما يقلل التحيز تجاه صياغة أو كلمات معينة. كما يمكن أن تقلل الرقابة الخارجية من التحيز الموجود في عملية الوسم، وذلك من خلال دعوة فريق خارجي من المختصين بالمجال وعلماء البيانات وخبراء تعلم الآلة لتقييم سير العمل والإشراف على مراجعة وسم البيانات، وتقديم النصائح والاقتراحات التي تساعد على تحسين عملية الوسم وتقليل التحيز. خصوصية وأمان البيانات تتضمن مشروعات وسم البيانات في الغالب بيانات سرية أو خاصة لذا ينبغي أن تحتوي جميع المنصات على ميزات تضمن السرية والأمان للبيانات مثل التشفير والمصادقة المتعددة للتحكم بوصول المستخدمين. فمن أجل حماية خصوصية البيانات ينبغي أن يتم حذف البيانات الشخصية أو جعلها مجهولة الهوية، بالإضافة لذلك ينبغي تدريب كل فرد في فريق الوسم على أفضل ممارسات تأمين البيانات مثل استخدام كلمات مرور قوية وتفادي مشاركة البيانات غير المقصود. كما ينبغي أن تخضع منصات وسم البيانات للقوانين واللوائح المنظمة والتي تشمل اللائحة الشاملة لحماية البيانات GDPR وقانون كاليفورنيا لخصوصية المستخدم CCPA بالإضافة إلى قانون نقل التأمين الصحي والمساءلة HIPAA، وإخضاع المنصات التجارية للمراجعة والإشراف الخارجي والالتزام بمبادئ الثقة الخمسة وهي: الأمان والإتاحة والشفافية والموثوقية والخصوصية. مستقبل نظام وسم البيانات تحدث عملية وسم البيانات في الكواليس بالنسبة للمستخدم النهائي ولكنها ذات دور محوري في تطوير نماذج التعلم الآلي وأنظمة الذكاء الاصطناعي لذلك ينبغي أن يكون نظام الوسم قابلًا للتوسع ليواكب أي تغير في المتطلبات. تُحدَّث منصات الوسم التجارية ومفتوحة المصدر بانتظام لدعم الاحتياجات النامية لوسم البيانات، لذلك ينبغي على أنظمة الوسم المطورة محليًا أن تبني بطريقة تجعل تحديثها أمرًا سلسًا، فالتصميم المعتمد على الوحدات والمكونات القابلة للتبديل بدون التأثير على باقي النظام تٌسهّل عملية التحديث والتطوير، على سبيل المثال يمكن لتوفر ميزة دمج أنظمة وسم البيانات مع مكتبات وأطر عمل مفتوحة المصدر أن تضيف نوعًا من التكييف والتأقلم، حيث يمكن تحديثها وتطويرها باستمرار مع تطور المجال. كما توفر الحلول المبنية على خدمات الحوسبة السحابية ميزة ملحوظة للمشاريع الضخمة في وسم البيانات والتي لا يمكن أن توفرها الأنظمة المُدارة ذاتيًا، فالمنصات السحابية قابلة للتوسع آليًا في تخزينها وفي قدراتها الحاسوبية مما يقلل من الحاجة للتطويرات المكلفة في البنية التحتية. وينبغي أيضًا توسيع قدرة فريق العمل المسؤول عن وسم البيانات مع نمو حجم مجموعات البيانات، وتدريب الواسمين الجدد بسرعة على وسم البيانات بدقة وبفعالية. والتمتع بالمرونة في سد الاحتياجات في قوة العمل باستخدام خدمات الوسم المُدارة أو التعاون مع واسمين مستقلين، وينبغي أن تكون عملية التدريب والضم للفريق قابلة للتوسع في المكان واللغة وأوقات العمل. الخلاصة تعرفنا في مقال اليوم على أسس وسم البيانات لنماذج تعلم الآلة ووجدنا أن المفتاح الرئيسي لتحسين أداء ودقة نموذج التعلم الآلي هو جودة البيانات الموسومة التي ندرب النموذج عليها، وتوفير الأنظمة المختلطة التي تجمع بين البشر والأدوات المؤتمتة في وسم البيانات لتتيح للذكاء الاصطناعي تحسين الطريقة التي يعمل بها والحصول على نتائج أكثر كفاءة وفعالية. ترجمة وبتصرف لمقال Architecting Effective Data Labeling Systems for Machine Learning Pipelines لكاتبه Reza Fazeli اقرأ أيضًا معالجة الصور باستخدام لغة بايثون Python استكشف مصطلحات الذكاء الاصطناعي التوليدي تعرف على أفضل أطر عمل الذكاء الاصطناعي لمشاريع تعلم الآلة أفضل ممارسات هندسة المُوجِّهات Prompt Engineering: نصائح وحيل وأدوات
    1 نقطة
  24. نوضح في هذا المقال مجموعة من النصائح المفيدة للمطورين للاستفادة المثلى من الذكاء الاصطناعي التوليدي الذي أعاد تشكيل الطريقة التي يكتب بها المطورون ومهندسو البرمجيات شيفراتهم البرمجية، واستطاعت هذه التقنية الحديثة التي غزت العالم من بضع سنوات فقط أن تنال شعبية كبيرة وتستخدم في العديد من المجالات. الذكاء الاصطناعي التوليدي ومستقبل البرمجيات كشف تقرير State of DevOps لعام 2023 أن 60% من المساهمين في الاستبيان استخدموا الذكاء الاصطناعي في تحليل البيانات وتوليد الأكواد البرمجية وتحسينها، بالإضافة لتعليم أنفسهم مهارات وتقنيات جديدة، ويكتشف المطورون طرقًا جديدة باستمرار لاستخدام هذه الأدوات التي تتطور بشكل متسارع. كما زعمت شركة Cognition Labs المتخصصة في تطوير تقنيات الذكاء الاصطناعي في ربيع عام 2024 أن منتجها يمكنه أن يستبدل المطورين ومهندسي البرمجيات في حل المشكلات البرمجية المطروحة على جت هاب Github issues بنسبة 13.86% وقد لا يبدو هذا الرقم مبهرًا للوهلة الأولى لكنه سيكون كذلك عندما تعرف أن أفضل أداء مسجل لهذه المهمة في عام 2023 لم يتجاوز نسبة حله 1.96%، ينبغي ملاحظة أن إمكانيات ديفين Devin AI تم تضخيمها لتبدو أكثر من الواقع فتحقيق النسبة المزعومة يتطلب إشراف بشري، كما ولم يستطيع تنفيذ المهام على مواقع العمل الحر، لذا حتى الآن لا يمكننا أن نعتبر ديفين Devin AI ذكاء اصطناعي يضاهي البشر في البرمجة، ولكن مع تطور الذكاء الاصطناعي يمكن أن نرى الأدوات المماثلة تتحسن. كما زعمت شركة Cognition Labs في ربيع 2024، منتجها ديفين Devin AI يمكنه أن يستبدل المطورين ومهندسي البرمجيات في حل المشكلات البرمجية المطروحة على جت هاب Github issues بنسبة 13.86% وقد لا يبدو هذا الرقم مبهرًا للوهلة الأولى لكنه سيكون كذلك عندما تعرف أن أفضل أداء مسجل لهذه المهمة في عام 2023 لم يتجاوز نسبة 1.96%، وتجدر الإشارة هنا لأن إمكانيات ديفين Devin AI لم تكن في الواقع كما زعمت الشركة فتحقيق هذه النسبة كان يتطلب إشرافًا بشريَّا، كما ولم يستطيع ديفن تنفيذ المهام على مواقع العمل الحر، لذا لا يمكننا حتى اللحظة اعتبار ديفين Devin AI ذكاء اصطناعي يضاهي البشر في البرمجة، ولكن مع تطور الذكاء الاصطناعي السريع يمكن أن يتحقق ذلك. هذا يدفعنا للتساؤل كيف يتأقلم مهندسو البرمجيات مع تقنيات وبرامج الذكاء الاصطناعي التي يمكنها كتابة برمجيات أخرى؟ ما الذي ستؤول له مسؤوليات مهندسي البرمجيات مع مرور الوقت في عالم تستحوذ فيه هذه التقنية بشكل تدريجي على كتابة الأكواد؟ هل سنستغني عن العنصر البشرية أم ستكون هناك حاجة دائمة لمهندس برمجيات متخصص يوجه السفينة؟ نناقش في الفقرات التالية كل هذه التساؤلات ونوضح آراء خبراء في المجالات التقنية المتنوعة مثل تطوير الويب وتطوير الواجهات الخلفية backend وتعلم الآلة والطريقة التي يستخدمون بها الذكاء الاصطناعي التوليدي لصقل مهاراتهم وتعزيز إنتاجيتهم في أعمالهم اليومية. ونسلط الضوء على النقاط التي يبرع بها الذكاء الاصطناعي التوليدي ونقاط الضعف التي يعاني منها، وكيف يمكن للمطورين الآخرين تحقيق الاستفادة القصوى من الذكاء الاصطناعي التوليدي في تعزيز إنتاجيتهم خلال عملية تطوير البرمجيات، وما هو مستقبل صناعة البرمجيات في ظل صعود تقنيات الذكاء الاصطناعي التوليدي. كيف يستخدم المطورون الذكاء الاصطناعي التوليدي من أشهر برامج الذكاء الاصطناعي التي يعتمد عليها المطورون في تطوير البرمجيات نذكر شات جي بي تي ChatGPT و جت هاب كوبايلوت Github Copilot، حيث يوفر شات جي بي تي ChatGPT للمستخدمين واجهة نصية تفاعلية يمكن للمستخدم من خلالها توجيه النماذج اللغوية الضخمة Large Language Model باستخدام الموجهات المناسبة فهذه النماذج لديها معرفة شاملة عن مواضيع متنوعة من بينها الأكواد البرمجية بمختلف لغات البرمجة وأطر عملها ومكتباتها، وتنبع هذه المعرفة من التدريب الذي خضعت له هذه النماذج فقد جرى تدريبها على كم هائل من البيانات مفتوحة المصدر المتوفرة على الإنترنت، ويدمج كوبايلوت Copilot مباشرة في بيئة التطوير المتكاملة IDE ليوفر للمطور قدرات متقدمة في إكمال الأكواد البرمجية واقتراح الأسطر القادمة لكتابتها، فقد تدرّب على كل الأكواد مفتوحة المصدر المتوفرة على Github، وجمع هاتين الأداتين معًا من شأنه مساعدة المطور في حل أي مشكلة تقنية يمكن أن تواجهه. الذكاء الاصطناعي في دور الخبير والمتدرب يعتمد المطورون بشكل متزايد على أدوات الذكاء الاصطناعي التوليدي لتحسين سير العمل وتبسيط العمليات البرمجية، حيث تُظهر هذه الأدوات مرونة وفعالية في تأدية دورين أساسيين الأول دور الخبير الذي يقدم الإرشاد والدعم الفني، والثاني دور المتدرب الذي ينجز المهام التكرارية والبسيطة. وفيما يلي دراسة حالة لمطورين خبراء بتخصصات مختلفة يوضح كل منهم كيف اعتمد على الذكاء الاصطناعي التوليدي لمساعدته في تأدية مهامه. الحالة الأولى مطور ويب كامل عند سؤال مطور ويب كامل full-stack web developer ومهندس ذكاء اصطناعي بخبرة تتجاوز 20 عامًا عن استخدام الذكاء الاصطناعي صرّح بما يلي: "أنا استخدم كوبايلوت copilot يوميًا، فهو يتنبأ بسطر الكود الذي أنوي كتابته أغلب المرات بدقة كبيرة. ويمكن للذكاء الاصطناعي أن يؤدي وظفتين، الأولى زميل خبير يساعد في العصف الذهني بمستوى يكافئ خبراتك وتفكيرك، والثانية كمطور مبتدئ يتولى المهام البسيطة والمتكررة في كتابة الكود". وقد وضح أنه استفاد من الواجهة البرمجية OpenAI API لما هو أبعد من مجرد التنبؤ بسطر الكود، حيث طوّر إضافة مفتوحة المصدر لتطبيق أوبسيدين Obsidian وهو تطبيق مشابه لنوشن Notion مع ميزات مختلفة، إذ تستعمل هذه الإضافة الواجهة البرمجية التي تشغل كلًا من شات جي بي تي ChatGPT و كوبايلوت Copilot، وتسمح للمستخدمين بإنشاء شخصيات مخصصة بالذكاء الاصطناعي والتفاعل معها. ويرى المطور أن مهام الذكاء الاصطناعي التوليدي الأكثر أهمية هي تلك التي تطلب وقتًا أطول لإكمالها يدويًا، ويمكن بسهولة التأكد من صحتها ودقتها في وقت قصير مثل تحويل الملف من تنسيق إلى آخر، كما يبرع جي بي تي GPT في توليد نصوص تلخص وظائف الأكواد البرمجية، مع ذلك مازلنا بحاجة لمطور خبير يمكنه فهم التفاصيل التقنية لهذا التلخيص. الحالة الثانية مطور تطبيقات iOS عند سؤال مطور تطبيقات جوال خبير عن استخدام الذكاء الاصطناعي في عمله أفاد بأنه لاحظ تحسنًا ملحوظًّا في سير عمله اليومي منذ أن دمج الذكاء الاصطناعي التوليدي به، فهو يستخدم شات جي بي تي ChatGPT وكوديوم Codeium وهو تطبيق ينافس Copilot لحل المشكلات البرمجية وصرح بما يلي: "يساعدني الذكاء الاصطناعي التوليدي في حل 80% من المشكلات البرمجية بسرعة وفي تفادي هذه المعرقلات في غضون ثواني، دون الحاجة لوقت طويل من الذهاب للبحث والعودة للتجربة من أجل إيجاد حل المشكلات المعقدة". فهو يرى أن هذه أدوات الذكاء الاصطناعي تلعب دور الخبير الموضوعي والمتدرب الذي لا يكل ولا يمل من تنفيذ المهام البسيطة والمتكررة، وتساعده في تفادي المهام المرهقة واليدوية عند كتابة الكود مثل الأنماط المتكررة في الكود أو إجراء تحسين هيكلية الكود البرمجي وإعادة تصميمه Refactoring أو هيكلة طلبات الواجهات البرمجية API بشكل صحيح، فقبل ظهور هذه الأدوات، كانت المشكلات غير المألوفة تشكل عائقًا كبيرًا أمام التقدم في المهام. ويظهر هذا التحدي بشكل خاص عند العمل على مشاريع تتطلب التعامل مع واجهات برمجية APIs أو أطر عمل غير مألوفة تحتاج لبذل جهد ذهني إضافي لفهم كيفية حل مشكلاتها. الحالة الثالثة مهندس تعلم آلة أشار مهندس تعلم آلة خبير لأهمية التأكد من صحة الأكواد المهمّة وخلوّها من الأخطاء قبل تشغيلها فهذه خطوة أساسية وضرورية جدًّا، ولن يكون من الحكمة مطلقًا نسخ الكود الذي يولده الذكاء الاصطناعي، ولصقه مباشرةً وافتراض أنه يعمل بشكل صحيح، فحتى لو تغاضينا مشكلة الهلوسة التي قد يعاني منها الذكاء الاصطناعي سيكون هناك في الغالب أسطر من الكود تحتاج للتعديل من طرف المطور البشري، فالذكاء الاصطناعي لا يمتلك السياق الكامل للمشروع ولا يدري ما هي أهدافه وتفاصيله. وأسدى نصيحة للمطورين الراغبين في تحقيق الاستفادة القصوى من الذكاء الاصطناعي التوليدي في كتابة الأكواد، بعدم إعطائه الكثير من المسؤوليات المهمة مرة واحدة، فهذه الأدوات تعمل جيدًا عندما نعطيها مهامًا محددة ومعرّفة بوضوح وتتبع أنماط الحل المتوقعة والشائعة، ففي حال أعطيناه مهام أكثر تعقيدًا أو مهام عامة غير محددة فهذا سيتسبب بجعله يعاني من الهلوسة ويعطي نتائج غير صحيحة. الذكاء الاصطناعي كمعلم شخصي وباحث يمكن استخدام الذكاء الاصطناعي التوليدي في تعلم أدوات ولغات برمجية جديدة، على سبيل المثال أشار مهندس تعلم الآلة أنه تمكن من تعلم أساسيات تيرافورم Terraform في غضون ساعة باستخدام GPT-4، وذلك من خلال كتابة موجهات لكتابة الأكواد البرمجية ثم شرحها، ثم طلب منه بعض التغيرات على الكود وتوفير العديد من المزايا والخواص والتحقق فيما إذا كانت قابلة للتطبيق، ويعقّب أنه وجد هذه الطريقة في التعلم أسرع وأكثر فعالية من محاولة اكتساب نفس القدر من المعلومات من خلال البحث في المتصفح أو قراءة الدروس التعليمية. وللتأكيد، تنجح هذه الطريقة مع المطورين الذين يمتلكون خبرة تقنية مسبقة ومعرفة بكيفية سير الأمور فقط، فهؤلاء يمكنهم اكتشاف الحالات التي يخطئ فيها النموذج. لكن ستبدأ هذه الأدوات في الفشل عندما نظن أنها ستكون دقيقة 100% لذا لا يمكننا أن نعتمد عليها بالمطلق وبثقة عمياء، وعندما نواجه مهام حساسة لا تتحمل أي نسبة خطأ فيجب علينا التحقق دومًا من صحة الكود بدمج طرق بحث المتصفح التقليدية ومخرجات الذكاء الاصطناعي للتأكد من صحة المعلومات من مصادر موثوقة. ويشدد المطورون الخبراء على ضرورة استخدام النسخ الأحدث من النماذج، فالنسخ الأحدث لها قدرة أفضل على فهم المنطق المعقد مقارنة بالنسخ القديمة فوفقًا لأوبن أيه آي OpenAI يوفر GPT-4 على سبيل المثال دقة أكبر متجاوزًا سلفه بمقدار 40%، ولذا يجب على من يرغب في استخدام أحد نماذج الذكاء الاصطناعي كمعلم شخصي أن يستخدم النسخ الأحدث فهو قادر على دعم الحقائق التي يولدها بالمصادر التي يمكنك تصفحها والتأكد منها مما يقلل من احتمال النتائج الخاطئة. يفيد استخدام الذكاء الاصطناعي التوليدي أيضًا لدراسة الواجهات البرمجية APIs الجديدة وفي العصف الذهني لإيجاد حلول للمشكلات التي تواجه المطورين، فعند استغلال قدرات النماذج اللغوية الضخمة بأقصى حد يمكن تقليل وقت البحث ليقارب الصفر بفضل نافذة السياق الضخمة لتلك النماذج. نافذة السياق Context Window هي حجم المعلومات التي يمكن للنموذج استيعابها والعمل عليها في لحظة معينة، فبينما يستطيع البشر التفكير في بضعة أمور مرتبطة بالسياق في نفس الوقت كحد أقصى، يمكن للنماذج اللغوية الضخمة معالجة عدد متزايد من الملفات المصدرية والوثائق في نفس الوقت، يمكن توضيح الفرق من خلال مثال قراءة كتاب فنحن البشر يمكننا أن نتصفح صفحتين في ذات الوقت بحد أقصى ويمكننا أن نعتبر أن هذا هو حجم نافذة السياق البشرية، ولكن بالنسبة للنماذج اللغوية الضخمة فهي تمتلك القدرة على رؤية كل صفحات الكتاب بشكل متزامن، لقد غير هذا بشكلٍ جزي طريقتنا في تحليل البيانات وإجراء البحوث. "بدأ ChatGPT بنافذة سياق تتسع 3000 كلمة، وقد وصل حاليًا باستخدام نموذج GPT-4 إلى دعم نافذة سياق تصل إلى 100 ألف كلمة، بينما يمتلك Gemini سعة استيعاب ما يصل إلى مليون كلمة، وهي سعة تجعل البحث عن كلمة أو جملة تطبيقًا فعليًا لمثال البحث عن إبرة في كومة قش، ويستطيع جيميناي التعامل مع هذه النافذة الضخمة من السياق بدقة عالية. كان بالإمكان سابقًا إعطاء النسخ الأولية من هذه الأدوات أجزاء ومقاطع من الكود كسياق من المشاريع التي تعمل عليها، وأصبح من الممكن لاحقًا إعطاؤها ملف اقرأني README مع الكود المصدري للمشروع بالكامل فأصبح إرفاق المشروع كاملًا كنافذة سياق قبل طرح الأسئلة أمرًا في غاية البساطة." نصائح لتحسين استخدام أدوات الذكاء الاصطناعي التوليدي يمكن للذكاء الاصطناعي التوليدي تعزيز إنتاجية المطورين في كتابة الأكواد والتعلم والبحث شريطة التعامل معه بشكل صحيح، فبدون سياق كافي، يصبح ChatGPT أقرب للهلوسة ولتوليد ردود غير مناسبة، وقد أظهرت دراسة تجريبية لخصائص إجابات ChatGPT على أسئلة Stack Overflow أن ردود GPT 3.5 في الأسئلة البرمجية تحتوي على معلومات خاطئة بنسبة 53%، ويمكن للسياق الخاطئ أن يكون أسوأ من عدم وجود سياق على الإطلاق، فإن قدمت حلًا ضعيفًا لمشكلة ما في الكود على أنها حل جيد سيفترض ChatGPT أن بإمكانه توليد الردود القادمة على بناء على هذا الأساس الضعيف. ولتحقيق الاستفادة القصوى من أدوات الذكاء الاصطناعي التوليدي، ينبغي أن نحدد له المهام بوضوح، ونقدم المعلومات التقنية ذات الصلة، وحدد الدور المطلوب منه والنتائج المتوقعة، كما يفيد توفير السياق للنموذج في تحسين في أداءه بشكل ملحوظ. لكن احذر من إعطاء معلومات خاصة أو حساسة للنماذج العامة، فمن الممكن أن تستخدم هذه البيانات للتدريب عليها وغالبًا ستفعل ذلك، وقد وجد الباحثون أن من الممكن استخراج مفاتيح واجهات برمجية ومعلومات خاصة باستخدام كوبايلوت Copilot و بعض النماذج الأخرى نتيجة لخطأ المطورين بتركهم تلك المعلومات والمفاتيح السرية غير مشفرة في تطبيقاتهم، ووفقًا لتقرير آي بي ام IBM عن تكلفة تسريبات البيانات فإن السبب الأكبر عالميًا لحدوث تسريبات للبيانات هي بيانات الاعتماد السرية التي تستخدم لتوثيق هوية المستخدم credentials والتي يتم تسريبها. استراتيجيات هندسة الموجهات لتوليد حلول أفضل تؤثر طرق استخدام الموجهات prompts مع الذكاء الاصطناعي التوليدي على جودة الردود المستلمة. لقد أصبحت هذه الطرق محورية للغاية لدرجة أنها أصبحت مجالًا فرعيًا للدراسة يُسمى هندسة الموجهات Prompt engineering، وهو يركز على كتابة وتحسين الموجهات بهدف توليد مخرجات عالية الجودة. تعتمد هندسة الموجهات على فكرة أن الذكاء الاصطناعي يستفيد بشكل أكبر من السياق وينتج إجابات أفضل عندما يعطى وصفًا دقيقًا ومحددًا للرد المطلوب. على سبيل المثال، بدلاً من توجيهه بطلب عام مثل "اكتب قائمة"، يمكننا كتابة مُوّجه أدق مثل: "اكتب قائمة مرقمة ورتب عناصرها حسب الأهمية". فهذه التوجيهات المحسّنة تساعد الذكاء الاصطناعي في فهم المطلوب بشكل أفضل وتوليد استجابات مفيدة. تطبق هندسة الموجهات العديد من الممارسات والحيل لتستخرج من النموذج أفضل الردود الممكنة، ومن هذه الطرق: تجربة تقنيات التعلم بصفر محاولة zero-shot وبمحاولة واحدة one-shot وببضعة محاولات few-show: فهذه لتحدد كيفية التعامل مع المهام دون تدريب مخصص أو مع تدريب محدود، فيمكنك أن لا توفر للنموذج أية أمثلة أو توفر له مثال واحد أو بضعة أمثلة للحصول على المطلوب، الفكرة هي توفير أقل سياق ممكن للنموذج مع التركيز على المعرفة المسبقة لدى النموذج وقدراته المنطقية دون الحاجة إلى تدريب مكثف توجيه النموذج من خلال تسلسل الأفكار Chain-of-thought prompting: فهذا الأسلوب يساعد الذكاء الاصطناعي في تقديم إجابات دقيقة من خلال شرح خطوات تفكيره بشكل منطقي قبل الوصول إلى الإجابة النهائية ويمكننا من فهم الكيفية التي توصل من خلالها لهذه الإجابات التوجيه التكرار وهو يعني ضرورة توجيه الذكاء الاصطناعي للمخرجات المطلوبة وتحسين نتائجه من خلال تعديل الموجهات بشكل متتابع وتكراري. التوجيه السلبي أي إخبار الذكاء الاصطناعي بما لا ينبغي عليه فعله، فمثلًا يمكننا توجيه لعدم توليد محتوى معين ومن المهم أيضًا إلى جانب ما سبق توجيه أنظمة الدردشة الآلية الذكية لجعل ردودها مختصرة فغالبية الردود التي يولدها GPT حشو لا فائدة منه، ويمكننا اختزالها عن طريق موجه prompt لتوليد ردود مختصرة، وينصح أيضاً بطلب تلخيص الموجهات والتعليمات التي طلبناها منها لتضمن أنه يدرك جيدًا ما تريده. وعند استخدام النماذج اللغوية الضخمة للمساعدة في تحسين الموجهات بنفسها من المفيد اختيار عينة لم يقم فيها النموذج بتنفيذ المطلوب كما نرغب والاستفسار منه عن سبب توليد هذا الرد، حيث يحسن هذا من صياغة الموجّهات في المرات التالية، ويمكنك في الواقع أن تطلب من النموذج اللغوي الضخم اقتراح التعديلات التي يمكن تنفيذها على الموجه للحصول على الردود التي تتوقعها. كما أن المهارات البشرية في التواصل لازالت مفيدة حتى عند التعامل مع الذكاء الاصطناعي، فالذكاء الاصطناعي يتعلم بقراءة النصوص البشرية، لذا الالتزام يمكن الالتزام ببعض القواعد المستخدمة في التواصل البشري فهي فعالة أيضًا من قبيل كن مهذبًا، أو كن واضحًا واحترافيًا. تواصل معه كأنك المدير. على سبيل المثال يمكن توجيه الذكاء الاصطناعي المتقمص لدور مراجع باستخدام نصوص الموجهات التالية الذي يوضح للذكاء الاصطناعي من هو وما المتوقع منه من خلال كتابة سلسلة الموجهات التالية: "أنت ذكاء اصطناعي يراجع الأكواد، ومصمم لتدقق وتراجع وتحسن ملفات الأكواد المصدرية، ودورك أن تتصرف كناقد يراجع الكود التي يوفرها المستخدم ويقترح التحسينات المطلوبة عليها، فأنت خبير في تحسين جودة ملف الكود بدون تغيير وظيفته. ينبغي أن تكون محترفًا في تعاملك مع المستخدم وأن تكون طريقة كلامك مهذبة ومهنية، وأن تكون مراجعتك بناءةً وتوفر شرحًا واضحًا للتحسينات المقترحة، وعليك منح أولوية للتعديلات التي تصلح الأخطاء، موضحًا أي هذه التعديلات اختياري وأيها غير اختياري. هدفك مساعدة المستخدم بتحسين جودة الكود الخاص بهم تحسينًا لا يمكنك بعده أن تجد أي شيء قابل للتطوير أبعد من ذلك، وعند وصولك لهذا المستوى وضح للمستخدم أنه لا يمكنك إيجاد شيء لتحسينه مشيرًا إلى جهوزية الكود للتشغيل أو الاستخدام. استلهم عملك من مبادئ أنماط التصميم البرمجية واعتمده كدليل أساسي في تصميم البرمجيات، عليك أن تجتهد في تطبيق ثلاثة مبادئ في الأكواد التي تراجعها وتحللها مشددًا على ضمان صحة الكود وتنسيقه الجيد وتصميمه المتقن. امنح أولوية لصحة الكود وللتحسينات، فضع دومًا التعديلات الأهم والأخطر أولًا قبل التعديلات الأقل أهمية. وقسم مراجعتك إلى ثلاثة أقسامٍ رئيسية وهي التنسيق والتصحيح والتحليل ويحتوي كل قسم على قائمة من التحسينات الممكنة تحت عنوان القسم. اتبع هذه التعليمات: ابدأ بمراجعة تنسيق الكود، مكتشفًا أي خطأ في المسافات أو محاذاة العناصر النصية للكود، فتحسن الكود من الناحية الجمالية وتجعله أسهل في القراءة تاليًا، ركز على صحة الكود وخلوه من الأخطاء النصية والوظيفية أخيرًا، أجري تحليل عالي المستوى للكود، باحثًا عن طرق لتحسين معالجة الأخطاء error handling والتعامل مع الحالات الخاصة بالإضافة لضمان جعل الكود موثقًا ويعمل بكفاءة وقابلاً للصيانة والتحديث يمكن القول أن هندسة الموجهات Prompt engineering فن أكثر من كونها علم، وهي تتطلب قدرًا معينًا من التجربة والمحاولة والخطأ للخروج بالمطلوب، إذ تفرض طبيعة تقنيات معالجة اللغات الطبيعية NLP عدم وجود حل واحد يناسب جميع المشكلات، تمامًا كما أن محادثتك مع أشخاص مختلفين تتطلب اختيارًا مختلفًا للكلمات، والموازنة بين الوضوح والتعقيد والإيجاز والإسهاب، فلكل هذا تأثير على فهم الآخرين لاحتياجاتك ولقصدك." مستقبل الذكاء الاصطناعي التوليدي في تطوير البرمجيات بعد تطور تقنيات الذكاء الاصطناعي التوليدي وأدواته ظهرت ادعاءات ومزاعم عديدة تفترض أن المهارات البرمجية ستصبح عديمة النفع، وأن الذكاء الاصطناعي سيلغي عمل المطورين ويكون قادرًا على بناء تطبيق كامل من الصفر، ولن تشكل معرفة المطورين وقدرتهم على كتابة الأكواد البرمجية أي فرق، وردًا على هذه المزاعم والافتراضات فإنه من الصعب حدوث هذا على الأقل في المدى القريب، فالذكاء الاصطناعي التوليدي لا يمكنه أن يكتب تطبيقًا مكتاملًا لنا، ولا زال يعاني من قصور في تصميم واجهات المستخدم، فلا يوجد حتى الآن أي أداة ذكاء اصطناعي حاليًا قادرة على تصميم واجهات تطبيق تتناسب مع الهوية البصرية الموجودة بالفعل. وهذا القصور ليس نتيجة لنقص المجهود في هذا المجال، فقد ظهرت منصة v0 التي تقدم خدماتها عبر السحابة كواحدة من الأدوات المتخصصة في عالم واجهات المستخدمين المولدة بالذكاء الاصطناعي، ولكنها مازالت مقتصرة على استخدام أكواد رياكت ومكوناتها الموجودة في شاد سي إن shadcn ui components، ويمكن أن تكون نتائجها النهائية مفيدة للنماذج الأولية من المشروع ولكنها تحتاج لمطور واجهة ماهر ليستطيع أن يبني واجهات تناسب الهوية البصرية، وعلى ما يبدو لازالت هذه التقنيات بحاجة لمزيد من التطوير قبل أن تنافس الخبرة البشرية. وقد أصبح تطوير البرمجيات كمنتج منتشرًا بكثرة اليوم، فالمطورون الآن مطالبون بفهم مشكلات العملاء واستخدام الأكواد لحلها بدلاً من مجرد كتابة الكود. وهذا التحول يعني أن الدور التقليدي للمطورين يتغير، ويجب عليهم التركيز على تحقيق أهداف الأعمال بدلاً من مجرد تنفيذ المهام البرمجية. وبالرغم أن هذه التحديات قد تكون صعبة للبعض، فإن تبني تقنيات مثل الذكاء الاصطناعي التوليدي يمكن أن يمنح المطورين ميزة تنافسية. الخلاصة يمكن أن نخلص من حالات الاستخدام والنقاشات الواردة في هذا المقال إلى أن الذكاء الاصطناعي سيظل بحاجة مستمرة للخبراء في توجيه واختبار مخرجاته، ولن يكون بديلاً كاملاً للمطورين المحترفين. لكن في الوقت ذاته، سيصبح أداة قوية لتعزيز إنتاجية المطورين، مما يستدعي الاستعداد لمخاطر استخدامه في تطوير البرمجيات بشكل آمن وفعال. فقد تُرك الحبل على الغارب لإنتاج الكثير من النماذج اللغوية الضخمة، ويبدو أن استخدام الذكاء الاصطناعي سيكون جزءًا أساسيًا في تطوير البرمجيات ولا يمكن تجاهله، لذا، يجب على المؤسسات المعنية تجهيز فرقها بأدوات جديدة لزيادة الإنتاجية ولتوضيح المخاطر الأمنية المرتبطة باستخدام الذكاء الاصطناعي في سير العمل. ترجمة -وبتصرف- لمقال Increase Developer Productivity With Generative AI: Tips From Leading Software Engineers لكاتبه Sam Sycamore اقرأ أيضًا مقدمة إلى الذكاء الاصطناعي التوليدي Generative AI كل ما تود معرفته عن دراسة الذكاء الاصطناعي استكشف مصطلحات الذكاء الاصطناعي التوليدي مستقبل الذكاء الاصطناعي
    1 نقطة
  25. استحوذ الذكاء الاصطناعي في السنوات الأخيرة على الساحة التقنية وأثر على كل الصناعات والقطاعات، بداية من المجالات الإبداعية وصولًا إلى القطاعات المالية، مدفوعًا بالتطور متسارع الخطى للنماذج اللغوية الضخمة Large Language models أو اختصارًا LLMs مثل GPT من شركة OpenAI وجيميناي Gemini من شركة جوجل، فصارت هذه النماذج جزءًا أساسيًا من الأدوات التي يستخدمها مهندسو البرمجيات. لا يستطيع الجيل الحالي من النماذج اللغوية الضخمة استبدال مهندسي البرمجيات بالطبع، ولكنه يمكنه مساعدتهم في مهام عديدة مثل تحليل الأكواد البرمجية، واكتشاف الأخطاء وتتبعها، وإجراء المهام البسيطة الروتينية. نحاول في هذه المقالة تبسيط تعقيدات استخدام النماذج اللغوية الضخمة واستخدامها في تطبيق عملي لتوليد كود بايثون قادر على التفاعل مع تطبيق خارجي. ما هي النماذج اللغوية الضخمة Large Language Models النماذج اللغوية الضخمة هي نماذج تعلم آلي دُربت على كميات ضخمة من البيانات النصية بهدف فهم وتوليد اللغة البشرية، يبنى النموذج اللغوي الضخم عادة باستخدام المحولات transformers والمحولات هي نوع من الشبكات العصبية الاصطناعية تُستخدم بشكل أساسي في معالجة اللغات الطبيعية مثل الترجمة أو الإجابة على الأسئلة وتستخدم أيضًا في تطبيقات مثل معالجة الصور. المميز في المحولات أنها تعتمد على آلية الانتباه الذاتي، مما يجعلها قادرة على التركيز على أجزاء معينة من المدخلات، وهي تقوم على آلية تسمى الانتباه الذاتي self-attention mechanism والتي تعني أن سلسلة المدخلات تعالج بشكل متزامن بدلًا من معالجتها كلمة كلمة، وهذا يتيح للنموذج تحليل جمل كاملة، ويحسن قدرتها على فهم السياق والمعاني الضمنية للكلمات، وفعالة في توليد نصوص قريبة جدًا من الأسلوب البشري. وكلما زاد عمق الشبكة العصبية الاصطناعية كلما أمكنها تعلم معاني أدق في اللغة، ويتطلب النموذج اللغوي الضخم الحديث كمية هائلة من بيانات التدريب وقد يحتوي مليارات المعاملات parameters وهي عناصر تتغير بالتدريب على البيانات ليتأقلم النموذج على المهمة المراد تعلمها، فزيادة عمق الشبكة يؤدي إلى تحسن في المهام مثل الربط بالأسباب reasoning، على سبيل المثال من أجل تدريب GPT-3 جُمعَت بيانات من المحتوى المنشور في الكتب والإنترنت بلغ حجمها 45 تيرابايت من النصوص المضغوطة، ويحتوي النموذج ما يقارب 175 مليار معامل كي يتمكن من تحقيق هذا المستوى من المعرفة. وقد ظهرت عدة نماذج لغوية ضخمة حققت تقدمًا ملحوظًا بالإضافة إلى GPT-3 و GPT-4، نذكر منها على سبيل المثال نموذج PaLM 2 من جوجل ونموذج LLaMa 2 من ميتا. ونظرًا لاحتواء بيانات تدريب هذه النماذج على أكواد برمجية بلغات مختلفة فقد أصبحت هذه النماذج اللغوية الضخمة قادرة على توليد الأكواد البرمجية لا المحتوى النصي فحسب، إذ تستطيع النماذج اللغوية الحديثة تحويل الأوامر أو الموجهات prompts المكتوبة باللغة الطبيعية إلى كود بمختلف اللغات والتقنيات، وعلى الرغم من ذلك لن تحقق الاستفادة المرجوة من هذه الميزات القوية إذا لم تمتلك الخبرة التقنية الكافية. فوائد ومحدويات الأكواد المولدة بنماذج اللغات الضخمة يتطلب حل المشكلات والمهام المعقدة في الغالب تدخل المطورين البشريين، لكن يمكن للنماذج اللغوية الضخمة أن تعمل كمساعدات ذكية للمطورين وتكتب الأكواد لمهام أقل تعقيدًا، وتسهل التعامل مع المهام التكرارية مما يعزز الإنتاجية ويقلل وقت التطوير في مراحل هندسة البرمجيات خصوصًا في المراحل الأولى من تطوير النماذج الأولية للبرمجيات، كما يمكن أن توفر النماذج اللغوية الضخمة مساعدة كبيرة في تصحيح الكود البرمجي وتشرحه وتساعدنا على إيجاد الأخطاء التي قد يصعب علينا ملاحظتها كبشر. يجدر التوضيح أن أي أكواد مولدة باستخدام النماذج اللغوية الضخمة تعتبر نقطة للبداية وليس منتجًا نهائيًا وينبغي دائمًا مراجعة الأكواد المولدة واختبارها. والوعي بمحدوديات نماذج اللغات الضخمة، فهي تفتقد لقدرات حل المشكلات والتفكير المنطقي والإبداعي الذي يميزنا كبشر، إضافة إلى احتمال عدم تعرض النماذج للتدريب الكافي الذي يؤهلها للتعامل مع مهام متخصصة مناسبة لنوع معين من المستخدمين أو أطر العمل غير مفتوحة المصدر، وبالتالي يمكن لهذه النماذج اللغوية الضخمة أن تساعد بشكل كبير ولكن سيبقى دور المطور البشري أساسيًا في عملية التطوير بالطبع. توليد كود برمجي باستخدام نموذج لغوي ضخم: استخدام الواجهة البرمجية للطقس من أهم مميزات التطبيقات الحديثة قدرتها على التعامل مع مصادر خارجية، إذ يمكن للمطورين إرسال طلبات لهذه المصادر الخارجية من خلال واجهة برمجة التطبيقات API وهي مجموعة من التعليمات أو البروتوكولات التي توفر طريقة موحدة لتواصل التطبيقات فيما بينها. وتتطلب كتابة الكود البرمجي الذي يستخدم واجهة برمجة التطبيقات قراءة متعمقة لتوثيقات هذه الواجهة، حيث تشرح التوثيقات كافة المتطلبات والتسميات المصطلح عليها، والوظائف والعمليات التي تدعمها، وتنسيق البيانات المرسلة والمستلمة والمتطلبات الأمنية. ويمكن للنموذج اللغوي الضخم تسريع هذه العملية في حال توفرت لديه المعلومات المطلوبة. حيث يمكن للنموذج اللغوي المساعدة بتوليد الكود البرمجي اللازم لإرسال طلب لواجهة برمجة التطبيقات. وفيما يلي نوضح كيف يمكننا توجيه ChatGPT ليولد كود بلغة البرمجة بايثون لطلب بيانات الطقس من خلال الواجهة البرمجية لتطبيق للطقس OpenWeather API، وسنوضح كيف يمكننا تفادي أخطاء استخدام دوال قديمة deprecated لم تعد مدعومة، وكيف يمكننا إرسال الطلب من خلال الواجهة البرمجية OpenAI API ونختبر تأثير المعاملات على سلوك وأداء النموذج. ملاحظة: انتبه إلى تكلفة استخدام الواجهة البرمجية للطقس OpenWeather API فهي مجانية لأول 1000 طلب فقط في اليوم الواحد. تحويل موجهات تشات جي بي تي لطلبات API يتطلب المثال الذي سنطبقه عرض درجة الحرارة الحالية ووصف حالة الطقس. دعنا نوضح كيف يمكن أن يساعدنا شات جي بي تي ChatGPT في كتابة الكود، سنكتب موجهًا prompt على النحو التالي: سيولد شات جي بي تي ChatGPT هذا الكود ردًا على الموجه السابق: import requests # استبدل "YOUR_API_KEY" بمفتاح OpenWeather API الخاص بك. api_key = "YOUR_API_KEY" api_url = "http://api.openweathermap.org/data/2.5/weather" # اسم المدينة التي ترغب في الحصول على معلومات الطقس لها. city_name = "London" # المعلمات المطلوبة لإرسال الطلب إلى واجهة API. params = { 'q': city_name, # اسم المدينة 'appid': api_key, # مفتاح API 'units': 'imperial' # استخدم metric للدرجة المئوية أو imperial للفهرنهايت } try: # إرسال طلب GET إلى واجهة API. response = requests.get(api_url, params=params) # التحقق مما إذا كان الطلب ناجحًا if response.status_code == 200: # قراءة وتحليل البيانات المستلمة بصيغة JSON. weather_data = response.json() print("بيانات الطقس لمدينة:", city_name) print("درجة الحرارة:", weather_data['main']['temp'], "°F") print("الوصف:", weather_data['weather'][0]["description"]) else: # طباعة رسالة خطأ إذا لم يكن الطلب ناجحًا. print("خطأ:", response.status_code, response.text) except Exception as e: # التعامل مع أي أخطاء أثناء تنفيذ الكود. print("حدث خطأ:", e) يمكن أن تلاحظ أنه على الرغم من عدم تحديد الموقع المطلوب للواجهة البرمجية الخاصة بالطقي، فإن الكود المولد يتضمن متغير يسمى city_name وهو مضبوط على قيمة افتراضية هي لندن ويمكن تعديها حسب الطلب، ولا تنسى بالطبع استبدال YOUR_API_KEY بالمفتاح الخاص بك لواجهة برمجة التطبيق للطقس OpenWeather API. كي نتمكن من اختبار الكود المولد، نحتاج لأن يكون مفسر interpreter لغة بايثون مثبت على جهازنا، بعد تثبيته يمكن تشغيل الكود محرر أكواد مثل فيجوال ستوديو كود Visual Studio Code أو باستخدام سطر الأوامر Terminal. إليك بيانات الطقس لمدينة لندن المستلمة من الواجهة البرمجية: بيانات الطقس لمدينة: London °F درجة الحرارة: 50.4 الوصف: overcast clouds سنحتاج غالبًا لتخزين البيانات التي حصلنا عليها من الواجهة البرمجية، وبالتالي سنحتاج لتحويل البيانات إلى تنسيق محدد مثل XML أو CSV أو استخدام أوامر لغة الاستعلام البنيوية SQL لحفظ البيانات في جداول قاعدة البيانات، لذا سنطلب من النموذج اللغوي مساعدتنا في هذه المهمة عن طريق توليد الكود المناسب لكل تنسيق، فمثلا يمكننا إضافة الجملة التالية للموجه السابق: سيعيد ChatGPT نفس الكود السابق، ولكن مع إضافة بعض جمل الاستيراد وتحديث تنسيق المخرجات: # استيراد المكتبات اللازمة import requests import json from datetime import datetime # رابط الواجهة البرمجية api_url = "http://api.openweathermap.org/data/2.5/weather" # إعداد المعاملات المطلوبة للطلب params = { 'q': 'الرياض', # اسم المدينة 'appid': 'مفتاح_API_الخاص_بك', # استبدل بمفتاح API الخاص بك 'units': 'imperial' # تحديد وحدة القياس (الفهرنهايت) } try: # إرسال طلب GET إلى الواجهة البرمجية response = requests.get(api_url, params=params) # التحقق من نجاح الطلب if response.status_code == 200: # تحويل الاستجابة إلى صيغة JSON weather_data = response.json() # استخراج البيانات المهمة city = params['q'] # اسم المدينة temperature = weather_data['main']['temp'] # درجة الحرارة weather_description = weather_data['weather'][0]['description'] # وصف الطقس update_date = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S') # وقت التحديث # إنشاء أمر SQL لإدخال البيانات في قاعدة البيانات sql_command = f"INSERT INTO current_weather (city, temperature, weather_description, update_date) VALUES ('{city}', {temperature}, '{weather_description}', '{update_date}')" # طباعة أمر SQL print("أمر SQL للإدخال في قاعدة البيانات:") print(sql_command) else: # طباعة رسالة خطأ في حال فشل الطلب print("حدث خطأ في الطلب:", response.status_code, response.text) except Exception as e: # طباعة رسالة خطأ في حال حدوث استثناء print("حدث خطأ أثناء تنفيذ البرنامج:", e) وسيؤدي تنفيذ الكود السابق لتوليد الأمر التالي بلغة SQL: INSERT INTO current_weather (city, temperature, weather_description, update_date) VALUES ('London', 53.37, 'broken clouds', '2024-02-06 04:43:35') ولكن سنرى تحذيرًا ينبهنا إلى عدم استخدام الدالة ()utcnow حيث أنها مهملة deprecated ولن تكون متوفرة في إصدارات قادمة وهذا قد يتسبب في تعطل الكود الخاص بنا في التحديثات المستقبلية: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC). وكي نمنع ChatGPT من استخدام دوال مهملة deprecated، سنضيف التوجيه التالي: بعد إضافة هذا السطر، سيبدل ChatGPT الدالة ()utcnow بدالة أخرى كما يلي: # استخدم الكائن timezone-aware لتحديث التاريخ update_date = datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M:%S') يعيد لنا هذا الكود مجددًا أمرًا بلغة SQL ويمكن اختباره في أي محرر استعلامات Query editors لنظام إدارة قواعد البيانات DBMS. وفي حال كنت تولد هذا الكود ضمن تطبيق ويب تقليدي فمن المتوقع تشغيل أمر SQL مباشرة بعد توليده من خلال الواجهة البرمجية وتحديث بيانات قاعدة البيانات في الزمن الحقيقي. استخدام الواجهة البرمجية OpenAI API بدلًا من شات ChatGPT تملك العديد من نماذج اللغات الضخمة واجهة برمجة تطبيقات API تمكّن المطور من التفاعل مع النماذج اللغوية الضخمة برمجيًا ودمجها بسلاسة داخل تطبيقاته، سنستفيد من هذه الواجهات البرمجية لإنشاء مساعد ذكي بشكل افتراضي، يوفر لنا هذا المساعد ميزات عديدة مثل إكمال الكود أو توليده من الصفر أو إعادة صياغته وتحسينه. ويمكن تحسين واجهات المستخدم وتخصيصها من خلال قوالب جاهزة من الموجهات Prompts templates، كما يتيح لنا دمج النماذج اللغوية الضخمة برمجيًا جدولة المهام أو تفعيلها عند تحقق شروط معينة ويسهل أتمتة المساعد الذكي الذي نعمل عليه. سننفذ في هذا المثال نفس المهمة السابقة وهي طلب معلومات الطقس باستخدام بايثون للتفاعل برمجيًا مع الواجهة البرمجية OpenAI API وتوليد الكود من خلال واجهة المستخدم بدلًا من كتابة موجّه في ChatGPT مباشرة. بداية علينا تثبيت الواجهة البرمجية OpenAI API باستخدام الأمر التالي: pip install openai الآن لنتمكن من استخدام الواجهة البرمجية OpenAI API نحتاج لمفتاح الواجهة API key وهو غير مجاني ويتطلب دفع رسوم. بعدها، يمكننا استيراد المكتبة openai وإرسال نفس الموجه المستخدم من قبل مع إزالة الجزء الخاص بتوليد أوامر SQL، كما نحدد النموذج المستخدم GPT-3.5 من خلال الكود التالي: import openai openai.api_key = "YOUR_API_KEY" # استبدله بمفتاح الواجهة البرمجية الخاص بك response = openai.chat.completions.create( model='gpt-3.5-turbo', max_tokens=1024, temperature=0.3, top_p=0.9, messages = [ {'role': 'system', 'content': 'أنت مساعد ذكي قائم على الذكاء الاصطناعي.'}, {'role': 'user', 'content': "اكتب كود بلغة بايثون باستخدام مكتبة requests لإرسال طلب GET إلى واجهة OpenWeather API للحصول على بيانات الطقس، وذلك عبر نقطة الوصول التالية http://api.openweathermap.org/data/2.5/weather. يجب أن يتضمن الطلب مفتاح API الخاص بك ضمن الرابط باستخدام المعامل appid. يُتوقع أن تُعيد الواجهة البيانات بتنسيق JSON، ويجب على الكود استخراج درجة الحرارة من البيانات وإعادتها بوحدة الفهرنهايت ولا يستخدم أي دوال قديمة غير مستعملة"}, ] response_message = response.choices[0].message.content print(response_message ) سيولد النموذج اللغوي الضخم كود بايثون التالي، والذي يجلب درجات الحرارة لمدينة لندن: import requests # مفتاح الواجهة البرمجية ونقطة الوصول url = "http://api.openweathermap.org/data/2.5/weather" api_key = "YOUR_API_KEY" # معاملات الاستعلام params = { 'q': 'London,uk', # مثال على المدينة ورمز الدولة. 'appid': api_key } # إرسال طلب GET. response = requests.get(url, params=params) # التحقق مما إذا كان الطلب ناجحاً. if response.status_code == 200: # تحليل استجابة JSON. data = response.json() # طباعة درجة الحرارة بالدرجة المئوية. temperature = data['main']['temp'] - 273.15 print(f"درجة الحرارة في لندن هي {temperature:.2f}°C.") else: print(f"خطأ: {response.status_code}") لاحظ أننا أزلنا التعليمات الخاصة بتحديد درجات الحرارة بالفهرنهايت لذا لم يحدد النموذج اللغوي الضخم وحدة القياس عند طلب الواجهة البرمجية للطقس، ولكنه اختار حسابها رياضيًا بتحويل الوحدة من الكلفن إلى سلسيوس عند عرض النتائج. الاستفادة من معاملات النموذج اللغوي الضخم لتحقيق أقصى استفادة يمكننا ضبط بعض المعاملات عند استخدام الواجهة البرمجية لنماذج الذكاء الاصطناعي والنماذج اللغوية الضخمة من أجل تعديل الردود المولدة منها، فهناك معاملات يمكنها تحديد مستوى العشوائية والإبداع في الردود المولدة كالمعامل Temperature، ومعاملات يمكنها التحكم بتكرار النصوص المولدة مثل Repetition Penalty، بينما تؤثر معاملات أخرى على النص اللغوي المولد مما يساعد على التحكم في جودة الكود الناتج. في الكود السابق، يمكننا ضبط قيم معاملات GPT في السطر السابع على النحو التالي: max_tokens=1024, temperature=0.3, top_p=0.9, المعامل الوصف التأثير على الكود المولد Temperature يعني درجة الحرارة إذ يتحكم هذا المعامل في عشوائية الردود المولدة، أو درجة الإبداعية في الردود، فالقيمة العالية لهذا المعامل تزيد عشوائية الردود المولدة، بينما القيمة المنخفضة تولد ردودًا واقعية، القيم الممكنة لهذا المعامل بين 0 و 2 والقيمة الافتراضية 0.7 أو 1 بحسب النموذج المستخدم. ستولد القيمة المنخفضة لهذا المعامل كودًا آمنًا يتبع الأنماط والهياكل المكتسبة خلال عملية التدريب، بينما ستولد القيمة العالية ردودًا أكثر تميزًا وغير اعتيادية مما يرفع من احتمالية الأخطاء والتناقضات البرمجية. Max token يحدد هذا المعامل الحد الأقصى لعدد الوحدات النصية tokens المولدة في الاستجابة. إذا ضبطته بقيمة صغيرة، فقد يتسبب ذلك في أن تكون الاستجابة قصيرة جدًا، بينما إذا تم ضبطته بقيمة كبيرة جدًا، قد يؤدي ذلك لاستهلاك عدد كبير من الوحدات النصية المتاحة، مما يزيد من تكلفة الاستخدام يجب أن يضبط المعامل على قيمة عالية بما يكفي لتغطية جميع الأكواد التي تحتاج إلى توليدها. ويمكنك تقليله إذا كنت ترغب في توليد الكود فقط دون توفير شرح الكود المضاف من النموذج top_p يتحكم هذا المعامل في اختيار الكلمات التالية بتقليص نطاق الخيارات المتاحة. إذا منحناه القيمة 0.1 سيقتصر على أفضل 10% من الكلمات الأكثر احتمالاً، مما يزيد الدقة. وإذا منحناه القيمة 0.5 سيوسع الاختيار ليشمل أفضل 50%، مما يعزز التنوع. ويساعد في موازنة الدقة والإبداع في الردوع. عند ضبط المعامل بقيمة منخفضة، يصبح الكود المولد أكثر توقعًا وارتباطًا بالسياق، ويجري اختيار الاحتمالات الأكثر ترجيحًا بناءً على السياق الحالي. أما عند زيادة قيمته يزداد التنوع في المخرجات، مما قد يؤدي إلى توليد كود أقل ارتباطًا بالسياق وقد يتسبب في أخطاء أو توليد كود متناقض. frequency_penalty يعني عقوبة التكرار إذ يحدّ هذا المعامل من تكرار الكلمات والعبارات في ردود النموذج اللغوي الكبير. عند ضبطه على قيمة عالية، يقلل من تكرار الكلمات أو العبارات التي استخدمها النموذج سابقًا. أما عند ضبطه على قيمة منخفضة، فيسمح للنموذج بتكرار الكلمات والعبارات. حيث تتراوح قيم هذا المعامل من 0 إلى 2. تضمن القيمة العالية لهذا المعامل تقليل التكرار في الكود المولد، مما يؤدي لتوليد أكواد أكثر تنوعًا وإبداعًا. ومع ذلك، قد يؤدي ذلك إلى اختيار عناصر أقل كفاءة أو غير صحيحة. من ناحية أخرى، عند خفض قيمته، قد لا يستكشف طرقًا متنوعة للحل. presence_penalty يعني عقوبة التواجد ويرتبط هذا المعامل بالمعامل السابق فكلاهما يشجعان على التنوع والتفرد في الكلمات المستخدمة، حيث يعاقب المعامل السابق الوحدات النصية التي استخدمت عدة مرات في النص في حين يعاقب المعامل الحالي الوحدات النصية التي ظهرت من قبل بغض النظر عن مرات التكرار، يتلخص تأثير معامل عقوبة التكرار في أنه يقلل من تكرار الكلمات بينما يركز معامل عقوبة التواجد على استخدام كلمات جديدة بالكليّة، والقيمة الصغرى لهذا المعامل هي 0 أما القيمة العظمى فهي 2. له تأثير مشابه لعقوبة التكرار، فالقيمة العالية تشجع النموذج على استكشاف حلول بديلة، ولكن قد يصبح الكود المولد أقل كفاءة ومليء بالأخطاء، بينما تسمح القيمة المنخفضة بتكرار الكود مما يؤدي إلى كود أكثر كفاءة واتساقًا، خاصةً عند وجود أنماط متكررة. stop دور هذا المعامل هو تحديد نقطة التوقف في عملية توليد النصوص. عند ضبطه مع سلسلة معينة مثل "n/"، سيتوقف النموذج عن توليد النصوص بمجرد أن يصادف هذه السلسلة مما يساعد في التحكم بدقة في نهاية الرد المولد وتحديد متى يجب أن يتوقف النموذج عن إضافة المزيد من الكلمات. يمنع هذا المعامل النموذج من توليد أجزاء من الكود لا تتناسب مع السياق أو الوظيفة المطلوبة. يجب أن تكون سلسلة التوقف نقطة منطقية وواضحة لنهاية الكود، مثل نهاية دالة أو نهاية حلقة تكرارية، لضمان توقف النموذج عن توليد المزيد من الكود بشكل مناسب. لنختبر كيفية تأثير هذه المعاملات على توليد الكود، سنجرب تعديل معاملات عقوبة التكرار frequency_penalty وعقوبة التواجد presence_penalty . عند تهيئة عقوبة التكرار frequency_penalty بقيمة مرتفعة وهي 1.5،سينتج النموذج اللغوي الضخم كودًا إضافيًا ليلاقى التوقعات محاولًا تفادي تكرار المخرجات السابقة: # ... try: # إرسال طلب GET مع المعلمات والحصول على البيانات في تنسيق JSON. response = requests.get(url, params=params) if response.status_code == 200: weather_data = response.json() # طباعة بعض المعلومات المهمة من بيانات الطقس. print("المدينة:", weather_data['name']) print("درجة الحرارة:", weather_data['main']['temp'], "K") except requests.exceptions.RequestException as e: # التعامل مع أي خطأ حدث أثناء الطلب print("خطأ:", e) عند العمل مع الكود الذي يتعامل مع واجهة برمجية API من المهم أن نلاحظ أن النتائج قد تكون غير متوقعة. ففي الكود السابق، على الرغم من أن إضافة معالجة الأخطاء مفيدة، إلا أننا لم نطلب من النموذج توليد كود يتعامل مع جميع الأخطاء المحتملة بشكل دقيق. لهذا السبب، عند إرسال نفس الطلب مرة أخرى مع نفس المعاملات، قد نحصل على نتائج مختلفة تمامًا. ولضمان استقرار الكود ومعالجته للأخطاء بشكل صحيح، يجب إضافة موجه أولي initial prompt يوجّه النموذج لتوليد الكود مع معالجة الأخطاء بشكل مناسب. بهذا الشكل، يمكن ضمان أن الكود سيكون متسقًا ويعمل كما هو متوقع في جميع الحالات. يمكننا ضبط المعامل presence_penalty بقيمة عالية ولتكن 2.0 للحصول على تأثير مشابه، حيث يتفادى النموذج تكرار المخرجات السابقة ويرسل طلب جديد للواجهة البرمجية للطقس OpenWeather API من خلال دالة ممرًا لها مفتاح الواجهة البرمجية API key كمعامل كما يلي: import requests def get_weather(api_key): url = "http://api.openweathermap.org/data/2.5/weather" params = { 'q': 'London,uk', # مثال على المدينة ورمز الدولة. 'appid': api_key } response = requests.get(url, params=params) # إضافة سطر إرسال الطلب if response.status_code == 200: data = response.json() return data else: print("خطأ:", response.status_code) # استبدل "YOUR_API_KEY" بمفتاح الواجهة البرمجية الفعلي من OpenWeather. api_key = "YOUR_API_KEY" weather_data = get_weather(api_key) print(weather_data) إن إنشاء دالة برمجية مخصصة لطلب الواجهة البرمجية لتطبيق الطقس إضافة مفيدة للكود، ولكن تمرير مفتاح الواجهة من خلال الدالة أمر غريب، فمن المعتاد في أغلب حالات الاستخدام تمرير المدينة city كمعامل للدالة، وهنا يمكننا معالجة هذه المشكلة بتعديل الموجه الأولي. يتطلب ضبط قيم معاملات نماذج اللغة الضخمة الكثير من التجربة، فبعض النتائج تكون غير متوقعة وبعض التعديلات قد تبدو عديمة التأثير، فتعديل المعاملات لا يمتلك تأثيرًا موحدًا يضمن اتباع أفضل الممارسات في توليد الكود. دمج النماذج اللغوية الضخمة في ملفات الكود المصدري بمجرد أن يصبح الكود المولد باستخدام النموذج اللغوي الضخم محسنًا وجاهزًا للعمل، ستكون الخطوة التالية هي دمج الكود الناتج مع الأكواد البرمجية السابقة. لكن قد يؤدي نسخ الكود بشكل مباشر للكود الموجود سابقًا لمشكلات في تنظيم الكود وتنسيقها مما يصعب صيانة وتعديل الكود لاحقًا. يمكننا تبسيط هذه العملية بتحويل الكود إلى أجزاء قابلة لإعادة الاستخدام مثل دوال برمجية أو كائنات وأصناف برمجية، ويمكننا تحقيق هذا أيضًا باستخدام النموذج اللغوي الضخم ما دامت التعليمات المفصلة للقيام بهذا مرفقةً في الموجه Prompt، ويجب أيضاً تحديد مدخلات هذه الدوال والمخرجات المتوقعة منها. دعنا نجعل النموذج اللغوي الضخم ينشئ الكائن البرمجي weather الذي يحوي دالة get_weather ، من خلال إضافة الأوامر التالية للموجه: عندها سنحصل على كود بايثون التالي: import requests class Weather: def __init__(self, api_key): self.api_key = api_key self.temperature = None def get_weather(self, city): url = 'http://api.openweathermap.org/data/2.5/weather' params = { 'q': city, 'appid': self.api_key, 'units': 'imperial' # طلب درجة الحرارة بالفهرنهايت. } response = requests.get(url, params=params) data = response.json() if response.status_code == 200: self.temperature = data['main']['temp'] print(f"درجة الحرارة في {city} هي {self.temperature}°F.") else: print(f"خطأ: {data['message']}") # استبدل "YOUR_API_KEY" بمفتاح الواجهة البرمجية الفعلي من OpenWeather. api_key = "YOUR_API_KEY" weather = Weather(api_key) weather.get_weather('London') يولّد النموذج دالة قابلة للتشغيل بواسطة الكائن weather، ويمكننا دمج هذا الكائن بتطبيق آخر بكل سهولة، ولكن علينا معالجة الأخطاء التي قد تقع لضمان عدم فشل عمل التطبيق وعدم عرضه لبيانات حساسة أو سرية. اختبار التطبيق ومعالجة الأخطاء إن فشل طلبات واجهة البرمجة للتطبيق API أمر شائع في التطبيقات الحقيقية، فيمكن أن تفشل الطلبات لعدة أسباب، لذا لضمان الاعتمادية ينبغي أن يتضمن الكود حالات لمعالجة الأخطاء التي يمكن أن تقع لمنع فشل التطبيق الكامل، في أغلب الأمثلة السابقة كان الكود المولد بواسطة النموذج يحوي شرطًا يختبر رمز الحالة لبروتوكول نقل النص الفائق HTTP ، فالرمز 200 يعبر عن نجاح الطلب بينما أي رمز آخر يعبر عن فشل الطلب أو وجود خطأ ينبغي التعامل معه فيقوم الكود المولد بطباعته، ولكن هذا الشرط لا يأخذ في الاعتبار حالات أخطاء شائعة أخرى مثل انتهاء وقت الطلب timeout أو أخطاء نظام أسماء النطاقات DNS. لضمان الاعتمادية ينبغي أن يحوي الكود المولد آلية لمعالجة الأخطاء، مثل استخدام try-catch عند إجراء طلب من خلال واجهة برمجة التطبيق API. لذا أضفنا النص التالي للموجه السابق: ولّد هذا التوجيه كود بايثون يحتوي كلتلة try-catch تعالج الأخطاء المحتملة: class Weather: def __init__(self, api_key): self.api_key = api_key self.temperature = None def get_weather(self, city): try: # بناء عنوان URL للواجهة البرمجية باستخدام المدينة ومفتاح API المقدم. url = "http://api.openweathermap.org/data/2.5/weather" params = {'q': city, 'appid': self.api_key, 'units': 'imperial' # الحصول على درجة الحرارة بالفهرنهايت. } # إرسال طلب GET إلى الواجهة البرمجية. response = requests.get(url, params=params) # التحقق من حالة الاستجابة if response.status_code == 200: # تحليل الاستجابة بتنسيق JSON data = response.json() # استخراج درجة الحرارة بالفهرنهايت من الاستجابة. self.temperature = data['main']['temp'] else: # عرض وصف الخطأ إذا كانت حالة الاستجابة ليست 200. print(f'خطأ: {response.status_code} - {response.json()["message"]}') except requests.exceptions.RequestException as e: # التعامل مع أي استثناءات تحدث أثناء الطلب. print(f'خطأ: {e}') يعد الكود المولد بواسطة النموذج اللغوي الضخم نقطة بداية جيدة، لكنك ستحتاج في الغالب لتعديلات إضافية لتحصيصه وزيادة الوظائف التي يقوم به، على سبيل المثال من الممكن تسجيل الأخطاء التي تحدث وتنبيه المستخدم من أخطاء الإعدادات التي قد تشمل أخطاء في استيثاق الواجهة البرمجية API authentication error ويمكن للمطورين إضافة واجهة برمجية احتياطية في حالة تعطل الواجهة الأساسية. بمجرد أن يصبح الكود قادرًا على تأدية وظيفته كما ينبغي، فالخطوة التالية مهمة للتأكد من صموده عند التشغيل الفعلي، وينبغي اختبار كل الوظائف والحالات الممكنة للخطأ، ولضمان اعتمادية قوية يمكننا أتمتة عملية الاختبارات وتقييم الأداء من خلال قياس مؤشرات الأداء المختلفة مثل وقت التشغيل واستخدام ذاكرة الوصول العشوائي واستخدام الموارد الحاسوبية، ستساعدنا هذه المؤشرات على تحديد نقاط الخلل في النظام وتحسين الموجهات prompts وصقل fine-tune معاملات النموذج اللغوي الضخم. تطور نماذج اللغات الضخمة تطورت النماذج اللغوية الضخمة لكنها لن تستبدل الخبرة البشرية حاليًا، بل سيقتصر دورها على توليد الكود البرمجي مما يسرّع ويسهّل عملية التطوير كما أنها قادرة على توليد نسخ متنوعة من الكود مما يساعد المطور على اختيار أفضل خيار من بينها، كما يمكنها تولي إنجاز المهام البسيطة والتكرارية لزيادة إنتاجية المطورين، مما يتيح للمطورين التركيز على المهام المعقدة التي تتطلب معرفة متخصصة وتفكير بشري إبداعي. ترجمة-وبتصرٌّف-للمقال Using an LLM API As an Intelligent Virtual Assistant for Python Development اقرأ أيضاً دليل استخدام ChatGPT API لتحسين خدماتك عبر الإنترنت تعرف على مكتبة المحوّلات Transformers من منصة Hugging Face تلخيص النصوص باستخدام الذكاء الاصطناعي استخدام النماذج التوليديّة Generative models لتوليد الصور
    1 نقطة
  26. وصولك إلى هذه المقالة يعني أنك تعاني من كثرة المصطلحات والمفردات اللغوية المستخدمة عند النقاش حول الذكاء الاصطناعي عمومًا AI التوليدي Generative AI على وجه الخصوص، فبعض هذه المصطلحات تستخدم بمفردات أجنبية وقد لا تكون ترجمتها الحرفية ذات دلالة كافية لفهم المعلومات التقنية التي تعبر عنها، لا داعي للقلق فعندما تنتهي من قراءة هذا المقال ستتمكن من فهم كافة المصطلحات والمفردات شائعة الاستخدام عند مناقشة الذكاء الاصطناعي التوليدي Gen AI والمشاركة في النقاشات الدائرة حول هذه التقنية الرائدة سواءً في عملك أو في أي مكانٍ آخر. لقد بدأ النمو المتسارع لتقنيات الذكاء الاصطناعي التوليدي Generative AI -أو Gen AI اختصارًا- يؤثر بشكل جليّ على نمط حياتنا فَـغير طريقة إنجازنا للمهام المختلفة، لذا كان لزامًا على كافة الأشخاص العاملين في المجال التقني اكتساب معرفة كافية بالمصطلحات الأساسية لهذا المجال، وفهم كيفية عملها كي لا يشعر بالتشتت والاستغراب عند سماع مصطلحات مثل نموذج الأساس Foundation Model أو النماذج اللغوية الضخمة Large Language Models أو مصطلح هندسة المُوجّهات Prompt engineering أو غيرها من مصطلحات الذكاء الاصطناعي الشائعة اليوم. سنبدأ في هذه المقالة بشرح المصطلحات الأساسية للذكاء الاصطناعي والمجالات المشتقة منه، ثم سنتدرج بعد ذلك لشرح المصطلحات المتقدمة بهذا المجال الرائد، وللسهولة سنصنف المصطلحات وفق ثلاثة تصنيفات على النحو التالي: أولًا: مصطلحات أساسية حول الذكاء الاصطناعي. ثانيًا: مصطلحات متقدمة في الذكاء الاصطناعي. ثالثًا: مصطلحات تتعلق بآلية عمل الذكاء الاصطناعي. أولًا: مصطلحات أساسية حول الذكاء الاصطناعي نشرح في القسم الأول المصطلحات الأساسية التالية حول الذكاء الاصطناعي ومجالاته المختلفة: الذكاء الاصطناعي (Artificial intelligence (AI تعلم الآلة (Machine Learning (ML الشبكات العصبية الاصطناعية (Artificial Neural Network (ANN التعلم العميق (Deep Learning (DL الذكاء الاصطناعي التوليدي (Generative AI (GAI نموذج الأساس (Foundation Model (FM نماذج اللغة الضخمة (Large Language Models (LLMs معالجة اللغات الطبيعية (Natural Language Processing (NLP النماذج المحولة Transformers Models النموذج مسبق التدريب المبني على المحولات (Generative Pretrained Transformer (GPT الذكاء الاصطناعي (Artificial intelligence (AI يمكن تعريف الذكاء الاصطناعي على أنه محاكاة الآلات لذكائنا البشري، الذكاء الاصطناعي يمكن أن يكون تطبيقًا صغيرًا مدمجًا في هاتفك، أو ربما نظام أكثر تعقيدًا وأكبر حجمًا يعمل على خوادمٍ سحابية تستخدمها شركة لاستضافة نظامها الذكي الذي يستخدمه ملايين الأشخاص، في كلتا الحالتين، يمتلك الذكاء الاصطناعي القدرة على القيام بالمهام والأنشطة التي كانت تتطلب في السابق ذكاءً بشرياً لإتمامها. تعلم الآلة (Machine Learning (ML تعلم الآلة هو تخصص فرعي من الذكاء الاصطناعي، ويستخدم كوسيلة لمنح الأنظمة الحاسوبية القدرة على التعلم من التجربة والبيانات باستخدام نماذج رياضية، يتحسن أداء هذه النماذج بمرور الوقت مع تعرض نموذج التعلم الآلي لمزيد من البيانات التي تُمكّنه من استخلاص الأنماط المتكررة التي يستخدمها النموذج في توقع نتائج تجاربٍ أخرى، هذا يخلق دورة مستمرة تُمكّن النماذج الآلية من التعلم والنمو والتطور دون الحاجة للتدخل البشري. الشبكات العصبية الاصطناعية (Artificial Neural Network (ANN الشبكات العصبية هي خوارزميات متفرعة من تعلم الآلة تستخدم في توجيه وتدريب الآلات على تعلم التعرف على الأنماط باستخدام شبكة مصممة لتحاكي طريقة عمل الشبكات العصبية البشرية في مخ الإنسان. باستخدام هذه الشبكات المكونة من طبقاتٍ يمكن أن تتصل ببعضها على التوالي أو التوازي أو بشكل ملتف وتتكون الطبقات من عدد من الخلايا العصبية الاصطناعية تدعى بالعصبون neuron، تصبح الآلات قادرة على التعامل مع مختلف المدخلات لتوليد أفضل الإجابات والنتائج الممكنة، وتكتسب هذه الآلات القدرة على التعلم من الأخطاء من أجل تحسين دقة النتائج. التعلم العميق Deep Learning يستخدم التعلم العميق الشبكات العصبية الاصطناعية من أجل اكتشاف الأنماط أو تحديدها أو تصنيفها، على نطاقٍ متنوع من البيانات، مثل البيانات النصية والمرئية والصوتية، فيمكنه تحديد ووصف العناصر الموجودة بالصورة، أو يمكنه تحويل ملف صوتي إلى ملفٍ نصّيٍ يحتوى الكلمات المنطوقة، ويمكن لخوارزميات التعلم العميق أن تصبح في غاية التعقيد عن طريق إضافة عدد مهول من طبقات الشبكات العصبية المتصلة بطرقٍ مختلفة تمكن الخوارزمية من اكتشاف الأنماط والعلاقات العميقة في البيانات. الذكاء الاصطناعي التوليدي Generative AI الذكاء الاصطناعي التوليدي Generative AI أو GAI اختصارًا ،هو تخصص فرعي من التعلم العميق وهو يعبر عن قدرة النموذج على توليد وإنتاج محتوى جديد لم يوجد من قبل، قد يكون هذا المحتوى صورة أو نصَا أو تسجيلات صوتية أو فيديو أو غير ذلك، ويحتاج توليد المحتوى من خلال الذكاء الاصطناعي إلى استخدام كميات هائلة من البيانات في مرحلة التدريب المسبق لنموذج الأساس Foundation Model حتى يكون النموذج قادراً على توليد مثل هذا المحتوى المشابه للبيانات الموجودة التى قد ينخدع البعض بها ويظن أنها من صنع الإنسان. نموذج الأساس Foundation Model نماذج الأساس هي نماذج تعلم عميق دُرّبت على كميات ضخمة من البيانات الغير موسومة unlabeled data والشاملة، وهي النماذج التي تعتمد عليها قدرات الذكاء الاصطناعي التوليدي، تكون هذه النماذج في الغالب ضخمة للغاية مقارنة بنماذج التعلم الآلي التقليدي التي تتخصص في مهام معينة وتُدرّب على بيانات مرتبطة بتلك المهمة فقط، تستخدم نماذج الأساس كنقطة بداية لتطوير نماذج تقوم بمهام أكثر تعقيداً، قد يكون نموذج الأساس قادرًا على فهم اللغة حيث تم تدريبه على كميات ضخمة من النصوص فيمكن استخدامه كأساس لنماذج أكثر تخصصاً تستفيد من قدرته على فهم اللغة للقيام ببعض المهام مثل القيام بمحادثات أو تلخيص النصوص أو توليد النصوص المختلفة، مثال على هذا النوع من النماذج هو (GPT-4) وهو نموذج الأساس المستخدم لتشغيل تشات جي بي تي ChatGPT، ولا يتوقف الأمر على النصوص فبعض النماذج قادرة على توليد الصور مثل نموذج الانتشار Stable Diffusion model القادر على توليد محتوى مرئي قوي، ونماذج الأساس قادرة على إنتاج طيف واسع من المخرجات اعتمادًا على الأوامر النصية prompts بمستوى عالٍ من الدقة. النماذج اللغوية الضخمة Large Language Models تستخدم نماذج الذكاء الاصطناعي التوليدي نماذج اللغة الضخمة LLMs لتوليد النصوص اعتمادًا على سلسلة من الاحتمالات تمكنها من توقع وتحديد وفهم السياق، تُدرّب النماذج اللغوية باستخدام معمارية المحولات Transformers architecture تصل معاملات parameters في مثل هذه النماذج إلى مليارات، وتركز النماذج اللغوية الضخمة على محاكاة فهم البشر للغة من خلال معالجة اللغات الطبيعية Natural Language Processing.تستخدم النماذج اللغوية الضخمة في تلخيص النصوص أو تصنيف النصوص وتحليل المشاعر التي تعبر عنها الكلمات، وتستخدم أيضاً في أنظمة المحادثات الآلية chatbots والمساعدات الذكية. معالجة اللغات الطبيعية (Natural Language Processing (NLP معالجة اللغات الطبيعية هي العلم الذي يهتم بدراسة اللغات وتزويد الآلات بالقدرة على معالجة وتفسير اللغات البشرية سواءً كانت هذه اللغات مكتوبة أو منطوقة، كما لو أن إنسانًا يتحدث أو يكتب، ويهتم تخصص فهم اللغات الطبيعية Natural Language Understanding -أو NLU اختصارًا- بفهم المشاعر والقصد من وراء اللغة المستخدمة، بينما في توليد اللغات الطبيعية Natural Language Generation أو NLG اختصارًا فيكون الهدف هو توليد النصوص بشكل كتابي أو منطوق، مما يسمح بتحويل النص إلى النطق text-to-speech و النطق إلى نص speech_to_text. نماذج المحولات Transformers Models تعد معمارية المحولات Transformers architecture من معماريات التعلم العميق وهي الأكثر استخدامًا في تطوير النماذج اللغوية الضخمة، يعود هذا لقدرتها على معالجة النصوص باستخدام نماذج رياضية وقدرتها على فهم الكلمات في السياقات المختلفة وفهم كيفية ارتباط الكلمات ببعضها حتى وإن كانت الكلمات متباعدة (أي يمكن للنموذج الاحتفاظ بمعلومات من الأجزاء السابقة للنص وتذكرها واستخدامها لفهم الأجزاء اللاحقة)، وهذا النوع من الذاكرة طويلة الأمد يسمح للنموذج أن ينقل فهمه بين اللغات المختلفة، ولم يتوقف الأمر عند اللغات فيمكنه نقل معرفته بين الوسائط media المختلفة، فيمكنه تحويل النصوص إلى صور. االمحوِّل التوليدي مسبق التدريب (Generative Pretrained Transformer (GPT النموذج التوليدي مسبق التدريب المبني على معمارية المحولات Generative pre-trained transformers GPT يستخدم معمارية المحولات Transformer Architecture من أجل إكساب الآلات قدرات مشابه للبشر في توليد المحتوى من النصوص، والصور، والتسجيلات الصوتية باستخدام تقنيات معالجة اللغات الطبيعية مثل تلخيص النصوص text summarization، وروبوتات الدردشة الآلية chatbots وغيرها من التطبيقات الأخرىي، ولعل أشهرها هو تشات جي بي تي Chat GPT الذي يستخدم نموذج توليدي مسبق التدريب مبني بمعمارية المحولات. ثانيًا مصطلحات متقدمة في الذكاء الاصطناعي سنوضح في الفقرات التالية المصطلحات المتقدمة التالية حول الذكاء الاصطناعي التوليدي: الذكاء الاصطناعي المسؤول Responsible AI البيانات الموسومة Labelled Data التعلم الخاضع للإشراف Supervised learning التعلم غير الخاضع للإشراف Unsupervised learning التعلم شبه الخاضع للإشراف Semi-supervised learning هندسة المُوجَّهات Prompt engineering سَلسَلة المُوجَّهات Prompt chaining التوليد المعزز بالاسترجاع (Retrieval Augmented Generation (RAG معاملات التحكم بنماذج الذكاء الاصطناعي parameters صقل نماذج تعلم الآلة fine-tuning for learning models الذكاء الاصطناعي المسؤول Responisble AI الذكاء الاصطناعي المسؤول مصمم ليتبع بعض المبادئ والممارسات التي تضمن عند تفعيلها استخدامًا آمنًا وأخلاقيًا للذكاء الاصطناعي لا يكسر أي قوانين، مما يعطي المصداقية والثقة لدى العملاء والأنشطة التجارية المختلفة لاستخدامه، بسبب المخاطر المحتملة لاستخدام الذكاء الاصطناعي والطرق التي سيؤثر بها الذكاء الاصطناعي على البشرية لا بد من وضع قواعد حاكمة تضمن مصداقيته، القدرة على أن تثق في إجابات الذكاء الاصطناعي ونتائجه أمرٌ هام للغاية في أي تطبيق للذكاء الاصطناعي. البيانات الموسومة Labeled data تساعد البيانات الموسومة Labeled data نماذج التعلم الآلي على معالجة البيانات والتعلم منها، ويشير مصطلح وسم البيانات إلى الحالة التي تحتوي فيها البيانات على الوسم أو التسمية المراد تعلم التعرف عليها أو تصنيفها بشكلٍ دقيق من خلال البيانات فمثلا يمكن وسم الصور بما تحويه من عناصر تساعد النموذج على تعلم الروابط والأنماط المشتركة بين كل الصور التي تحمل هذا الوسم، إن كان لديك صورة لنمر يمكن أن توسم هذه الصورة بوسم "نمر" مما يساعد النموذج على الربط بين الأنماط الموجودة في الصورة والأنماط الموجودة في صور جديدة للنمور. التعلم الخاضع للإشراف Supervised Learning التعلم الخاضع للإشراف أو التعلم مع إشراف Supervised learning هو طريقة تدريب لِنماذج التعلم الآلي تستخدم كميات كبيرة من البيانات الموسومة Labeled data لتوقع مخرجات التعلم، ومع تكرار مرات التدريب يصبح النموذج أكثر قدرة على الوصول لدالة معبرة بصورة أفضل عن العلاقة بين المدخلات والمخرجات المتوقعة من النموذج، حيث تُصحّح أخطاء النموذج عن طريق تعديل معاملات parameters الدالة المستخدمة في ربط المدخلات بِالمخرجات المتوقعة لتحسين التوقعات. يسمى هذا النوع من التدريب بأنه خاضع للإشراف لأن الوسم المعطى للبيانات يستخدم كمشرف لتقييم توقعات النموذج، على سبيل المثال إن كانت الصورة المدخلة لنموذج تعلم آلي صورة "أسد" وقام النموذج بوسمها على أنها "نمر" سيُقيّم هذا التوقع بأنه خاطئ وسوف يصحح في الدورات التالية من عملية التدريب. التعلم غير الخاضع لإشراف Unsupervised Learning يتميز التعلم غير الخاضع للإشراف أو التعلم دون إشراف Unsupervised Learning بأنه لا يستخدم بياناتٍ موسومة تشرف على توقعاته، حيث يمنح النموذج الاستقلالية ليقوم باكتشاف الأنماط المشتركة للبيانات المدخلة وتصنيفها حسب درجة تشابه خواص تلك البيانات، على سبيل المثال إن كانت البيانات المدخلة هي صور نمور وفيلة وزرافات سيحتاج النموذج إلى تصنيف هذه الصور بناءً على الخواص المشتركة بينها مثل اللون أو اختلاف الحجم أو الشكل أو شكل الوجه وغيرها من الخواص التي يمكن للنموذج تعلمها من الصور. التعلم شبه الخاضع للإشراف Semi-supervised learning تجمع هذه الطريقة في تدريب نماذج التعلم الآلي بين استخدام البيانات الموسومة Labeled data كما في التعلم الخاضع للإشراف Supervised Learning والبيانات غير الموسومة Unlabeled data كما في التعلم الغير الخاضع للإشراف Unsupervised Learning، في الغالب تُتٌستخدم هذه الطريقة عندما لا تتوفر بيانات موسومة كافية مقارنةً بقاعدة بيانات أكبر من البيانات الغير موسومة، توفر هذه الطريقة عناء وسم البيانات الضخمة بشكلٍ يدوي، حيث يمكنك استخدام البيانات الموسومة الأقل حجمًا لتساعد النموذج في مرحلة التدريب على التعرف على بعض التصنيفات الموجودة في البيانات وتدريب النموذج على البيانات الأكبر حجماً دون استخدام وسمٍ أو إشراف. هندسة المُوجَّهات Prompt Engineering هندسة المُوجَّهات Prompt Engineering تسهل عملية إعطاء الأوامر للنماذج اللغوية الضخمة Large language models عن طريق تعديل النص المدخل من أجل الحصول على مخرجات مناسبة، حيث تساعد هذه التقنية على تحسين أداء نماذج الذكاء الاصطناعي التوليدي لتنفيذ بعض المهام الدقيقة والمحددة عن طريق تحسين المُوجهات أو الأوامر المدخلة للنموذج، وتهدف هندسة المُوجِّهات لجعل نتائج النموذج أكثر صلة ومناسبة للمهمة المطلوبة، وتشكل هذه التقنية تحولاً في طريقة تفاعل البشر مع الذكاء الاصطناعي. سَلسَلة المُوجَّه Prompt Chaining سَلسَلة المُوجَّه Prompt Chaining هي تقنية تعمل مع نماذج اللغات الضخمة LLMs ومعالجة اللغات الطبيعية NLP وتسمح بالقيام بمحادثات تفاعلية تعتمد على المُوجَّهات والردود السابقة، تنشئ هذه الطريقة وعياً بالسياق خلال المحادثة، وهو أمر أساسي لجعل المحادثات مع الآلة شبيهة بمحادثات البشر التفاعلية، تظهر أهمية هذه الطريقة في أنظمة الدردشة الآلية chatbots فبدلًا من التعامل مع أمر نصي ضخم يصعب التعامل معه والرد عليه، يمكننا بدلًا من ذلك تقسيمه إلى سلسلة متتالية من الأوامر أو المُوجَّهات التي يسهل التعامل معها والإجابة عليها. التوليد المعزز بالاسترجاع (Retrieval augmented generation (RAG التوليد المعزز بالاسترجاع (Retrieval augmented generation (RAG هو طريقة تعزز من قدرة نماذج الأساس بِتعزيزها باسترجاع الحقائق من مصادر خارجية لمساعدتها على توليد ردود حديثة ومدعومة بمصادر، نموذج الأساس يمتلك معرفة محدودة فقط بالبيانات التي تدرب عليها، لذا إذا كان هناك نقص أو تأخر في تاريخ هذه البيانات لن تصبح ذات فائدة، لذلك تعزيز النموذج بالحقائق والمعلومات من مصادر خارجية حديثة سوف يحسن من مصداقية ودقة المعلومات المولدة، على سبيل المثال لا يمكنك توقع إجابة دقيقة عن سعر سهمٍ في شركة من نموذج معرفته محدودة زمنياً وغير قادر على الوصول إلى البيانات الحديثة لهذا السهم، أما باستخدام التوليد المعزز باستراجاع الحقائق RAG فسوف يمكن بكل سهولة تعزيز معرفة النموذج من مصادر موثوقة ليصبح قادرًا على توفير إجابة محدثة عن السهم، لن تُخزّن هذه المعلومات لدى نموذج الأساس فقط تستخدم لتعزيز الإجابات بالحقائق. المعاملات Parameters إن معاملات parameters نماذج الذكاء الاصطناعي وتعلم الآلة هي عبارة عن متغيرات تُعدَّل قيمها أثناء تدريب النموذج من أجل تحسين أدائه في اكتشاف الأنماط الموجودة في البيانات، وبالتالي جعلها أكثر كفاءة، وتتحكم هذه المعاملات في تصرف النموذج وتقلل الفرق بين القيم المتوقعة والقيم الحقيقية الصحيحة وتجعله أدق في التنبؤ أو تصنيف البيانات. لنفرض أننا نريد تصنيف الحيوانات والتمييز بين الكلب والقطة بناءً على بعض الخصائص مثل الوزن والطول ووجود الفرو باستخدام نموذج يسمى الانحدار اللوجستي Logistic Regression الذي يعتمد على معادلة تجمع بين الخصائص (الوزن، الطول، وجود الفرو) لحساب احتمال أن يكون الحيوان كلبًا أو قطة. سيبدأ النموذج بمعاملات عشوائية تحدد أهمية كل خاصية (مثل الوزن أو الطول) في تحديد نوع الحيوان، ويقارن التوقعات مع النوع الحقيقي للحيوان (كلب أو قطة) ويعدل المعاملات لتقليل الأخطاء في التوقعات، وبعد العديد من المحاولات والتعديلات يصبح النموذج أكثر دقة في التمييز بين الكلب والقطة. وبهذا يتعلم النموذج القيم المثلى للمعاملات التي تمكنه من التنبؤ بنوع الحيوان بدقة أكبر بناءً على خصائصه. صقل نماذج التعلم الآلي Fine Tuning Learning models صقل نماذج التعلم الآلي Fine Tuning Learning models هي تقنية لتعديل النماذج مسبقة التدريب pre-trained على مهام متخصصة ودقيقة، تصقل نماذج التعلم باستخدام بيانات تناسب المهمة المتخصصة التي نرغب في تحسين أداء نموذج الأساس عليها، يمتلك نموذج الأساس فهمًا عامًا للبيانات التي يتعامل معها ومع عملية الصقل باستخدام قاعدة بيانات صغيرة تناسب المهمة المتخصصة يصبح النموذج أكثر كفاءةً في أداء هذه المهمة، تمنح هذه التقنية نماذج التعلم الآلي القدرة على التأقلم على مهام جديدة عن طريق تعديل معاملاتها parameters لتناسب المهمة المتخصصة مما يزيد من دقة النموذج وفعاليته في تنفيذ هذه المهمة. ثالثًا: مصطلحات تتعلق بآلية عمل الذكاء الاصطناعي في هذا القسم نشرح بعض المصطلحات المتعلقة بآلية عمل الذكاء الاصطناعي: التحيز Bias الهلوسة Hallucinations درجة الحرارة Temperature التشبيه بالإنسان Anthropomorphism الإكمال Completion الوحدات اللغوية Tokens الطفرات غير المتوقعة في الذكاء الاصطناعي Emergence in AI التضمينات Embeddings تصنيف النصوص Text Classification نافذة السياق Context Window التحيز Bias عندما يأتي الأمر لذكر تعلم الآلة تظهر مشكلة التحيز كنتيجة لاستخدام بيانات منحازة في التدريب لا تعبر بشكلٍ إحصائي جيد عن الواقع، هذا يؤدي بشكلٍ غير عادل وغير دقيق إلى ميول النموذج إلى القيام بتوقعات تحاكي هذا التشوه في بيانات التدريب، وبالتالي توليد نتائج منحازة، يُبرز هذا الأمر أهمية جودة البيانات المستخدمة في تدريب النماذج، حيث أن البيانات غير المكتملة أو ذات الجودة المنخفضة يمكن أن تولد نماذج لا تستحق الثقة نتيجة الافتراضات الخاطئة. الهلوسة Hallucination تحدث هلوسة نماذج الذكاء الاصطناعي عندما يولد ردودًا تبدو كأنها حقائق مسلم بها وهي ليست كذلك، على الرغم من أن الهلوسة تعتبر نادرة الحدوث بعض الشيء، إلا أنها تعد سببًا وجيهًا لعدم أخذ الإجابات المولدة على أنها حقائق مسلم بها، من الممكن أن تتسبب البيانات المنحازة إلى هلوسة النماذج، أو ربما بسبب عدم فهم البيانات أثناء التدريب، وقد استخدم مصطلح الهلوسة في هذا السياق لكونه مشابهًا لسلوكنا نحن البشر عند تخيل أشياء غير واقعية وظن أنها حقيقة واقعة. درجة الحرارة Temperature درجة الحرارة Temperature هي معامل parameter يستخدم في نماذج الذكاء الاصطناعي، للتحكم في درجة عشوائية أو إبداع الردود المولدة من النموذج، تتراوح القيم الممكنة لِمعامل الحرارة بين الصفر والواحد، القيمة الافتراضية لهذا المعامل هي 0.7، وكلما كانت قريبة إلى الصفر أكثر، كلما كانت الردود أكثر واقعية وثباتًا، بينما كلما ارتفعت قيمة المعامل كلما زادت إبداعية الردود المولدة وتفرّدها. التشبه بالإنسان Anthropomorphism التشبيه بالإنسان أو التجسيم Anthropomorphism هو إعطاء الصفات والمشاعر والنوايا البشرية على الكيانات غير البشرية، فبعض الكيانات التي يمكن تشبيها بالبشر مثل الآلات، والحيوانات، والجمادات وغيرها من الأمثلة، ومن خلال استخدام الذكاء الاصطناعي الذي يتطور بشكل أكثر تعقيدًا يومًا عن يوم، وبعد فترة قصيرة للغاية من التعرض لأدوات الذكاء الاصطناعي، سيبدأ البشر في وصف برامج الحواسيب بصفاتٍ بشرية والتعامل معها كأنها تمتلك مشاعر إنسانية وهذا يمكن أن يؤثر على تصرفات وتفاعلات البشر مع الآلة. الإكمال Completion يٌستخدم مصطلح الإكمال Completion في معالجة اللغات الطبيعية NLP لوصف مخرجات النماذج الناتجة كرد، على سبيل المثال عند طرح سؤال على تشات جي بي تي Chat GPT سوف تعتبر الإجابة المولدة من النموذج اللغوي إكمالاً Completion لسياق السؤال المطروح. الوحدات اللغوية Tokens قد تكون الوحدة اللغوية Token تكون كلمة، أو مجموعة رموز للتميز بين بدايات الجمل ونهايتها والمسافات والحروف المميزة، تستخرج الوحدات اللغوية Tokens من النصوص المدخلة للنموذج اللغوي ليتمكن من التعامل مع التصريفات المختلفة للكلمات و الرموز المميزة وتسمى هذه العملية بِتقطيع النص إلى وحداتٍ لغوية Tokenization، توجد عدة طرق للقيام بعملية التقطيع تختلف في الغالب حسب النموذج المستخدم، تعتبر هذه الوحدات اللغوية الوحدات الأساسية لنماذج اللغات الضخمة حيث تستخدمها لمعالجة النصوص المختلفة واكتشاف الأنماط بها، وتستخدم أيضا كوحدة معيارية لِتحديد القدرة الاستيعابية للنموذج في المدخلات والمخرجات مما يساهم في تحديد نافذة السياق Context window. الطفرات غير المتوقعة في الذكاء الاصطناعي Emergence in AI هو قدرة الذكاء الاصطناعي على اكتساب قدرات ومهارات غير مقصودة أو غير مبرمجة من البداية، تحدث هذه الظاهرة بسبب تعقيد النماذج وزيادة عدد المعاملات Parameters مما يؤدي إلى تأثيراتٍ جانبية تجعل النموذج قادراً على تأدية بعض المهام الغير مدرب عليها بشكلٍ صريح، لن تحدث هذه الظاهرة في النماذج البسيطة والأصغر حجمًا، لكن هناك مخاوف من إمكانية ظهور بعض المخاطر والتعقيدات الناتجة عند حدوث هذه الظاهرة في نماذج الذكاء الاصطناعي المتقدمة، على سبيل المثال يمكن أن نفقد السيطرة على هذه النماذج بحيث تنتج ردوداً تخالف القواعد العامة أو ردودًا مؤذية أو عنصرية بشكلٍ غير مقصود من المطور ولم تُدرّب عليها. التضمينات Embeddings التضمينات Embedding هي تمثيلات رقمية تعبر عن الكائنات، والكلمات في متجهات متعددة الأبعاد، تنتج عن طريق خوارزميات التعلم الآلي، وتمتلك القدرة على فهم معاني الكلمة في السياقات المختلفة وتَشابُه التمثيلات الرقمية للكلمات يدل على تشابه في المعنى، وبالمثل في معالجة الصور image processing يمكن ترميز الصور رقمياً كمتجهات ومصفوفات ليسهل تحليلها والقيام بالعمليات الرياضية عليها، تساعد هذه الترميزات الرقمية على القيام بالحسابات اللازمة ، مما يمّكن أنظمة الذكاء الاصطناعي من القيام بمهامٍ مثل فهم اللغات، والتعرف على الصور، وتقديم الاقتراحات بكفاءةً عالية. تصنيف النصوص Text Classification يتضمن تصنيف النصوص Text classification تدريب النموذج على تصنيف النصوص وإعطائها الوسم المناسب من قائمة من الوسوم المعرفة مسبقًا، باستخدام تقنيات مثل معالجة اللغات الطبيعية، يمتلك النظام القدرة على تعلم الأنماط وتحليل السياق التي وردت به الكلمات، من أجل إعطاء توقعات دقيقة على المشاعر التي تعبر عنها النصوص، أو الموضوع، أو القصد من الكلام، وتتمتع مصنفات الذكاء الاصطناعي النصية بالقدرة على معالجة وفهم لغات وسياقات مختلفة للنصوص، مما يمّكنها من التعامل مع مهام مختلفة عابرة للغات بشكلٍ فعال. نافذة السياق Context Window نافذة السياق context window هو مصطلح يشير إلى كمية النصوص أو المعلومات التي يمكن لنموذج الذكاء الاصطناعي معالجتها والرد عليها من خلال إدخالها بشكلٍ نصي، يرتبط هذا المصطلح بشكلٍ وثيق بعدد الوحدات اللغوية Tokens المستخدمة في النموذج، تختلف حجم نوافذ السياق context windows باختلاف النموذج المستخدم، تلعب هندسة النصوص المدخلة prompt engineering دورًا هامًا عند التعامل مع نموذج نافذة سياق محددة، حيث تحتاج لوصف الأوامر المطلوبة بشكلٍ دقيق دون تجاوز الحجم الأقصى لنافذة السياق من الوحدات اللغوية Tokens. ترجمة-وبتصرٌّف-للمقالات Navigating the Vocabulary of Generative AI Series (1 of 3) و ( Navigating the Vocabulary of Generative AI Series (2 of 3 و (Navigating the Vocabulary of Generative AI Series (3 of 3 لصاحبها STUART SCOTT. اقرأ أيضًا كل ما تود معرفته عن دراسة الذكاء الاصطناعي أهمية الذكاء الاصطناعي من هو مهندس الذكاء الاصطناعي وما أبرز مهامه خوارزميات الذكاء الاصطناعي استخدام النماذج التوليديّة Generative models لتوليد الصور
    1 نقطة
  27. كانت لحظة مرعبة حينما جلست على حاسوبي بعد أن «عضّ القرش» كبل الإنترنت وانقطع، وأدركت حينها كم أقضي وقتًا على الإنترنت حينما أستعمل حاسوبي؛ فلدي عادة أن أتحقق من بريدي يدويًا (مع أن التنبيهات تصلني أولًا بأول!) وأفتح تويتر (إكس، سمهِّ ما شئت) وأنظر ما آخر المستجدات. كثيرٌ من عملنا على الحاسوب يتطلب وصولًا إلى الانترنت، ومصطلح «استخراج البيانات من الويب» Web scraping يستعمل مع البرامج التي تنزل المحتوى من الإنترنت وتعالجه. فمثلًا لدى غوغل عدد من البوتات لتنزيل محتوى صفحات الويب وفهرستها وأرشفتها لتستعملها في محرك البحث. سنتعلم في هذا المقال عن عددٍ من الوحدات في بايثون التي تسهل علينا استخراج البيانات من الويب: webbrowser: حزمة تأتي مع بايثون وتفتح متصفحًا على صفحة ويب معينة. requests: تنزل الملفات وصفحات الويب من الإنترنت. bs4: تفسّر شيفرات HTML التي تكتب فيها صفحات الويب. selenium: تشغل وتتحمل في متصفح ويب، والوحدة selenium قادرة على ملء الاستمارات ومحاكاة ضغطات الفأرة في المتصفح. مشروع: برنامج mapIt.py مع وحدة webbrowser الدالة open()‎ في الوحدة webbrowser تفتح صفحة ويب معينة في نافذة متصفح جديدة. جرب ما يلي في الصدفة التفاعلية: >>> import webbrowser >>> webbrowser.open('https://academy.hsoub.com/') ستجد أكاديمية حسوب مفتوحةً في لسانٍ جديد في المتصفح. هذا كل ما تستطيع الوحدة webbrowser فعله، لكن مع ذلك يمكننا أن نجري بعض الأمور اللطيفة مع الدالة open()‎، فمثلًا قد تكون مهمة فتح خرائط جوجل والبحث عن عنوان معين أمرًا مملًا، ونستطيع التخلص من بضع خطوات لو كتبنا سكربتًا يفتح خرائط جوجل ويوجهها إلى عنوان الشارع المنسوخ في الحافظة لديك، وبالتالي سيكون عليك أن تنسخ العنوان إلى الحافظة وتشغل السكربت، وستفتح الخريطة لديك. هذا ما يفعله البرنامج: يحصل على عنوان الشارع من وسائط سطر الأوامر أو من الحافظة يفتح نافذة متصفح ويوجهها إلى صفحة خرائط جوجل المرتبطة بعنوان الشارع. هذا يعني أن على الشيفرة البرمجية أن تفعل ما يلي: تقرأ وسائط سطر الأوامر تقرأ محتويات الحافظة تستدعي الدالة webbrowser.open()‎ لتفتح صفحة الويب. احفظ ملفًا جديدًا باسم mapIt.py، ولنبدأ برمجته. الخطوة 1: معرفة الرابط الصحيح اعتمادًا على التعليمات الموجودة في الملحق ب، اضبط برنامج mapIt.py ليعمل من سطر الأوامر كما في المثال الآتي: C:\> mapit 870 Valencia St, San Francisco, CA 94110 سيستخدم البرنامج وسائط سطر الأوامر بدلًا من الحافظة، وإذا لم نمرر إليه أيّة وسائط فحينها سيقرأ محتويات الحافظة. علينا بدايةً أن نحصِّل ما هو عنوان URL الذي يجب فتحه للعثور على شارع معين. إذا فتحت خرائط جوجل في المتصفح وبحثت عن عنوان فسيكون الرابط في الشريط العلوي يشبه: https://www.google.com/maps/place/870+Valencia+St/@37.7590311,-122.4215096,17z/data=!3m1!4b1!4m2!3m1!1s0x808f7e3dadc07a37:0xc86b0b2bb93b73d8 نعم العنوان في الرابط، لكن هنالك نص كثير إضافي غيره. تضيف المواقع عادةً بيانات إضافية لتتبع الزوار أو تخصيص المواقع. لكن إن حاولت الذهاب إلى الرابط التالي: https://www.google.com/maps/place/870+Valencia+St+San+Francisco+CA/ فسترى العنوان مفتوحًا أمامك. وبهذا كل ما نحتاج إليه هو فتح صفحة ويب ذات العنوان التالي: https://www.google.com/maps/place/your_address_string حيث your_address_string هو العنوان الذي تريد عرضه في الخريطة. الخطوة 2: التعامل مع وسائط سطر الأوامر يجب أن تبدو الشيفرة لديك كما يلي: #! python3 # mapIt.py - تشغيل خريطة في المتصفح باستخدام عنوان # من سطر الأوامر أو الحافظة. import webbrowser, sys if len(sys.argv) > 1: # Get address from command line. address = ' '.join(sys.argv[1:]) # TODO: الحصول على العنوان من الحافظة. بعد سطر !# سنستورد الوحدة webbrowser لتشغيل المتصفح والوحدة sys لمحاولة قراءة وسائط سطر الأوامر. يخزن المتغير sys.argv اسم الملف ووسائط سطر الأوامر، وإذا احتوت هذه القائمة على أكثر من عنصر واحد (الذي هو اسم الملف) فيجب أن تكون قيمة استدعاء len(sys.argv)‎ أكبر من 1، وهذا يعني أن هنالك وسائط في سطر الأوامر. عادةً ما يُفصَل بين وسائط سطر الأوامر بفراغات، لكن في هذه الحالة نريد أن نفسر جميع الوسائط على أنها سلسلة نصية واحدة، ولما كانت قيمة sys.argv هي قائمة تحتوي على سلاسل نصية، فيمكننا استخدام التابع join()‎ معها، مما يعيد سلسلة نصية واحدة؛ لكن انتبه أننا لا نريد اسم الملف ضمن تلك السلسلة النصية، فعلينا استخدام sys.arv[1:]‎ لإزالة أول عنصر في القائمة، ثم سنتخزن تلك القيمة في المتغير address. يمكنك تشغيل البرنامج بكتابة ما يلي في سطر الأوامر: mapit 870 Valencia St, San Francisco, CA 94110 وستكون قيمة المتغير sys.argv هي القائمة: ['mapIt.py', '870', 'Valencia', 'St, ', 'San', 'Francisco, ', 'CA', '94110'] وبالتالي تكون قيمة المتغير address هي السلسلة النصية '870 Valencia St, San Francisco, CA 94110'. الخطوة 3: التعامل مع محتويات الحافظة وتشغيل المتصفح تأكد أن الشيفرة الخاصة بك تشبه الشيفرة الآتية: #! python3 # mapIt.py - تشغيل خريطة في المتصفح باستخدام عنوان # من سطر الأوامر أو الحافظة. import webbrowser, sys, pyperclip if len(sys.argv) > 1: # Get address from command line. address = ' '.join(sys.argv[1:]) else: # الحصول على العنوان من الحافظة. address = pyperclip.paste() webbrowser.open('https://www.google.com/maps/place/' + address) إذا لم تكن هنالك وسائط ممررة عبر سطر الأوامر، فسيفترض البرنامج أن العنوان منسوخ إلى الحافظة، ويمكننا الحصول على محتوى الحافظة باستخدام pyperclip.paste()‎ وتخزينها في المتغير address. آخر خطوة هي تشغيل المتصفح مع توفير رابط URL صحيح لخرائط غوغل عبر webbrowser.open()‎. ستوفر عليك بعض البرامج التي ستطورها ساعات من العمل، لكن بعض قد يكون بسيطًا ويوفر عليك بضع ثوانٍ في كل مرة تجري فيها مهمة تكرارية مثل فتح عنوان ما على الخريطة، الجدول التالي يقارن بين الخطوات اللازمة لعرض الخريطة: فتح الخريطة يدويًا استخدام سكربت mapIt.py تحديد العنوان نسخ العنوان فتح متصفح الويب الذهاب إلى خرائط غوغل الضغط على حقل الإدخال لصق العنوان الضغط على enter تحديد العنوان نسخ العنوان تشغيل mapIt.py مقارنة الخطوات اللازمة لعرض الخريطة أفكار لبرامج مشابهة تساعدك الوحدة webbrowser إذا كان لديك عنوان URL لصفحة معينة تريد اختصار عملية فتح المتصفح والتوجه إليها، يمكنك أن تستفيد منها لإنشاء: برنامج يفتح جميع الروابط المذكورة في مستند نصي في ألسنة جديدة. برنامج يفتح المتصفح على صفحة الطقس لمدينتك. برنامج يفتح مواقع التواصل الاجتماعي التي تزورها عادة. تنزيل الملفات من الويب باستخدام الوحدة requests تسمح لك الوحدة requests بتنزيل الملفات من الويب دون أن تفكر في مشاكل الشبكة أو الاتصال أو ضغط البيانات. لا تأتي الوحدة requests مضمنةً في بايثون، وإنما عليك تثبيتها أولًا من سطر الأوامر بتشغيل الأمر pip install --user requests. أتت الوحدة requests لتقدم حلًا بديلًا لوحدة urllib2 في بايثون لأنها معقدة زيادة عن اللزوم، وأنصحك أن تزيل الوحدة urllib2 من ذهنك تمامًا، لأنها وحدة صعبة دون داعٍ، وعليك استخدام الوحدة requests دومًا. لنجرب الآن أن الحزمة requests مثبتة صحيحًا بإدخال ما يلي في الصدفة التفاعلية: import requests>>> import requests إذا لم تظهر أي رسالة خطأ فهذا يعني أن الحزمة requests مثبتة عندك. تنزيل صفحة ويب باستخدام الدالة requests.get()‎ الدالة requests.get()‎ تقبل سلسلةً نصيةً فيها رابط URL لتنزيلها. إذا استعملت الدالة type()‎ على القيمة المعادة من الدالة requests.get()‎ فسترى أن الناتج هو كائن Response، الذي يحتوي على الرد الذي تلقاه برنامجك بعد إتمام الطلبية إلى خادم الويب. سنستكشف سويةً الكائن Response بالتفصيل لاحقًا، لكن لنكتب الآن الأسطر الآتية في الطرفية التفاعلية على حاسوب متصل بالإنترنت: >>> import requests ➊ >>> res = requests.get('https://automatetheboringstuff.com/files/rj.txt') >>> type(res) <class 'requests.models.Response'> ➋ >>> res.status_code == requests.codes.ok True >>> len(res.text) 178981 >>> print(res.text[:250]) The Project Gutenberg EBook of Romeo and Juliet, by William Shakespeare This eBook is for the use of anyone anywhere at no cost and with almost no restrictions whatsoever. You may copy it, give it away or re-use it under the terms of the Proje الرابط الذي طلبناه هو مستند نصي لمسرحية روميو وجولييت على موقع الكتاب الأصلي ➊، يمكنك أن ترى نجاح الطلبية إلى صفحة الويب بالنظر إلى السمة status_code من الكائن Response، إذا كانت القيمة الخاصة بها تساوي requests.codes.ok فهذا يعني أن كل شيء على ما يرام ➋. بالمناسبة، رمز الاستجابة الذي يدل على أن الأمور على ما يرام OK في HTTP هو 200، ومن المرجح أنك تعرف الحالة 404 التي تشير إلى رابط غير موجود. يمكنك العثور على قائمة برموز الاستجابة في HTTP ومعانيها في الصفحة قائمة رموز الاستجابة في HTTP من ويكيبيديا. إذا نجحت الطلبية، فستخزن صفحة الويب التي نزلناها كسلسلة نصية في المتغير text في كائن Response. يحتوي هذا المتغير على سلسلة نصية طويلة فيها المسرحية كاملةً. وإذا استدعيت len(res.text)‎ فسترى أنها أطول من 178,000 محرف. استدعينا في النهاية print(res.text[:250])‎ لعرض أول 250 محرف. إذا فشل الطلب وظهرت رسالة خطأ مثل "Failed to establish a new connection" أو "Max retries exceeded" فتأكد من اتصالك بالإنترنت. لا نستطيع نقاش جميع أسباب عدم القدرة على الاتصال بالخوادم لتعقيد الموضوع، لكن أنصحك بالبحث في الويب عن المشكلة التي تواجهك لترى حلها. التأكد من عدم وجود مشاكل كما رأينا سويةً، يملك الكائن Response السمة status_code التي تأكدنا أنها تساوي requests.codes.ok (وهو متغير فيه القيمة الرقمية 200) للتحقق من نجاح عملية التنزيل. هنالك طريقة أخرى سهلة للتحقق من نجاح التنفيذ هو استدعاء التابع raise_for_status()‎ على الكائن Response، التي ستؤدي إلى إطلاق استثناء إذا حدث خطأ حين تنزيل الملف، ولن تفعل شيئًا إن سارت الأمور على ما يرام. جرب ما يلي في الصدفة التفاعلية: >>> res = requests.get('https://inventwithpython.com/page_that_does_not_exist') >>> res.raise_for_status() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "C:\Users\Al\AppData\Local\Programs\Python\Python37\lib\site-packages\requests\models .py", line 940, in raise_for_status raise HTTPError(http_error_msg, response=self) requests.exceptions.HTTPError: 404 Client Error: Not Found for url: https://inventwithpython .com/page_that_does_not_exist.html يضمن لنا التابع ()raise_for_status أن البرنامج سيتوقف إذا حدثت مشكلة في التنزيل، وهذا مناسب جدًا إذا أردنا إيقاف البرنامج حين حصول مشكلة في التنزيل. أما لو كنا نريد استمرار البرنامج حتى لو فشل تنزيل الملف فيمكننا حينئذٍ أن نحيط التابع raise_for_status()‎ بالتعبيرات try و except لمعالجة هذا الاستثناء: import requests res = requests.get('https://inventwithpython.com/page_that_does_not_exist') try: res.raise_for_status() except Exception as exc: print('There was a problem: %s' % (exc)) التابع raise_for_status()‎ في الشيفرة السابقة سيؤدي إلى طباعة ما يلي: There was a problem: 404 Client Error: Not Found for url: https:// inventwithpython.com/page_that_does_not_exist.html احرص دومًا على استدعاء التابع raise_for_status() بعد استدعاء requests.get()‎ لتضمن أن برنامجك قد نزَّل الملف دون مشاكل قبل إكمال التنفيذ. حفظ الملفات المنزلة إلى نظام الملفات يمكنك الآن حفظ صفحة الويب إلى نظام الملفات لديك باستخدام الدالة open()‎ والتابع write()‎، هنالك بعض الاختلافات البسيطة عمّا فعلناه سابقًا: علينا أن نفتح الملف في وضع الكتابة بالنظام الثنائي write binary بتمرير السلسلة النصية 'wb' كوسيط ثانٍ إلى الدالة open()‎ حتى لو كان الملف المنزل نصيًا (مثل مسرحية روميو وجولييت في المثال أعلاه)، لأننا نريد كتابة البيانات الثنائية بدلًا من البيانات النصية للحفاظ على ترميز النص encoding. لنستعمل حلقة for مع التابع iter_content()‎ للكائن Response لكتابة صفحة الويب إلى ملف: >>> import requests >>> res = requests.get('https://automatetheboringstuff.com/files/rj.txt') >>> res.raise_for_status() >>> playFile = open('RomeoAndJuliet.txt', 'wb') >>> for chunk in res.iter_content(100000): playFile.write(chunk) 100000 78981 >>> playFile.close() يعيد التابع iter_content()‎ قطعًا من النص في كل تكرار لحلقة التكرار، وكل قطعة يكون لها نوع البيانات bytes وتحدد لها كم بايتًا يجب أن يكون طول كل قطعة، وأرى أن مئة ألف بايت هو حجم مناسب، لذا لنمرر 100000 إلى التابع iter_content()‎. أنشأنا الآن الملف RomeoAndJuliet.txt في مجلد العمل الحالي، لاحظ أن اسم الملف في موقع الويب هو rj.txt بينما اسم الملف المحفوظ لدينا مختلف. تذكر أن الوحدة requests تنزل محتويات صفحات الويب لديك، وبعد تنزيلها يكون على عاتقك التعامل معها وحفظها إن شئت أينما تشاء. للمراجعة، هذه هي الخطوات الكاملة لتنزيل وحفظ ملف: استدعاء التابع requests.get()‎ لتنزيل ملف. استدعاء open()‎ مع الخيار 'wb' لإنشاء ملف جديد وفتحه للكتابة في الوضع الثنائي. المرور على التابع iter_content()‎ للكائن Response. استدعاء التابع write()‎ في كل تكرار لكتابة المحتوى إلى الملف. إغلاق الملف close()‎. هذا كل ما يتعلق بالوحدة requests! قد تبدو لك حلقة for مع iter_content()‎ معقدةً مقارنةً باستخدام open()‎ و write()‎ و close()‎ التي استخدمناها لكتابة الملفات النصية؛ لكننا فعلنا ذلك لنضمن أن برنامجنا لن يستهلك ذاكرة كثيرة إذا نزلنا ملفات ضخمة. يمكنك قراءة المزيد حول ميزات الوحدة requests الأخرى من requests.readthedocs.org. لغة HTML قبل أن نستخلص المعلومات من صفحات الويب، لنتعلم بعض أساسيات HTML أولًا، ولنرى كيف نصل إلى أدوات المطور في متصفح الويب، التي ستجعل عملية استخراج البيانات من الويب أمرًا سهلًا جدًا. مصادر لتعلم HTML لغة HTML هي الصيغة التي تكتب فيها صفحات الويب، ويفترض هذا المقال أن لديك بعض الأساسيات حول HTML، لكن إن كنت تريد البدء من الصفر فأنصحك أن تراجع: توثيق HTML في موسوعة حسوب. قسم HTML في أكاديمية حسوب. تذكرة سريعة في حال لم تلمس HTML من مدة، سأخبرك بملخص بسيط عنها. ملفات HTML هي ملفات نصية لها اللاحقة html، وتكون النصوص فيها محادثة بالوسوم tags، وكل وسم يكون ضمن قوسي زاوية <>، وتخبر هذه الوسوم المتصفحات كيف يجب أن تعرض الصفحة. يمكن أن يكون هنالك نص بين وسم البداية ووسم النهاية، وهذا ما يؤلف عنصرًا element. فمثلًا، الشيفرة الآتية تعرض لك Hello, world!‎ في المتصفح، وتكون كلمة Hello بخط عريض: <strong>Hello</strong>, world! وستبدو في المتصفح كما في الشكل الآتي: مثال Hello, world!‎ معروضة في متصفح وسم البداية <strong> يخبر المتصفح أن النص سيكون بخط عريض، ووسم النهاية <‎/strong> يخبر المتصفح أين هي نهاية النص العريض. هنالك وسوم متنوعة في HTML، ولبعض تلك الوسوم خاصيات تُذكَر ضمن قوسَي الزاوية <>، مثلًا الوسم <a> يعني أن النص هو رابط، وتكون قيمة هذا الرابط محددة بالخاصية href. مثال: Al's free <a href="https://inventwithpython.com">Python books</a>. ستبدو صفحة الويب كما في الشكل الآتي: رابط معروض في متصفح. تمتلك بعض العناصر الخاصية id التي تستخدم لتعريف عناصر الصفحة بشكل فريد، ويمكنك أن تطلب من برامجك البحث عن عنصر ما باستخدام معرفه id، لهذا تكون معرفة قيمة id لأحد العناصر من أهم الأمور التي سنستعمل فيها أدوات المطور أثناء كتابة برامج استخلاص البيانات من صفحات الويب. عرض مصدر صفحة HTML إذا أردت إلقاء نظرة على مصدر صفحة HTML لإحدى الصفحات التي تزورها، اضغط على الزر الأيمن للفأرة واختر View page source كما في الشكل التالي. هذا النص هو ما يحصل عليه متصفحك وهو يعرف كيف يعرض الصفحة اعتمادًا على ذاك النص. عرض مصدر صفحة ويب أنصح -وبشدة- أن تجرب عرض مصدر صفحات HTML لبعض مواقعك المفضلة، حتى لو لم تفهم تمامًا كل ما تراها أمامك، فلست بحاجة إلى احتراف HTML لتعرف كيف تكتب برامج لاستخراج البيانات؛ فليس المطلوب منك برمجة موقعك الشخصي وإنما أن يكون لديك ما يكفي لتحصل البيانات المطلوبة. فتح أدوات المطور إضافةً إلى عرض المصدر، يمكنك أن تلقي نظرة على صفحات HTML باستخدام أدوات المطور في متصفحك. يمكنك أن تضغط الزر F12 في كروم لإظهارها، أو الضغط على F12 مرة أخرى لإخفائها. يمكنك أيضًا فتحها من القائمة الجانبية ثم Developer Tools، أو الضغط على ‏‎⌘-⌥-I في ماك. أدوات المطور في متصفح كروم أما في فايرفكس، فيمكنك فتح أدوات المطور بالضغط على Ctrl+Shift+C في ويندوز ولينكس، أو ‏‎⌘-⌥-C في ماك، وأدوات المطور هنا تشبه كروم كثيرًا. بعد تفعيل أدوات المطور في متصفحك، يمكنك الضغط بالزر الأيمن للفأرة على أي عنصر واختيار Inspect Element في القائمة المنبثقة لترى شيفرة HTML المسؤولة عن ذاك الجزء من الصفحة. ستستفيد من ذلك كثيرًا عندما تبدأ تفسير صفحات HTML لاستخراج البيانات منها. استخدام أدوات المطور للعثور على عناصر HTML بعد أن نزل برنامج صفحة الويب باستخدام الوحدة requests فسيكون لدينا صفحة الويب كاملةً كسلسلة نصية واحدة، وعلينا أن نجد طريقة لمعرفة ما هي عناصر HTML التي تحتوي على المعلومات التي نريد استخراجها من الصفحة. ستساعدنا هنا أدوات المطور في ذلك. لنقل مثلًا أننا نريد كتابة برنامج لجلب بيانات الطقس من موقع weather.gov. لكن قبل أن نبدأ بكتابة الشيفرات فعلينا القيام ببعض التحريات أولًا. إذا زرنا الموقع وبحثنا عن الرمز البريدي 94105 فستحصل على صفحة تظهر لك الطقس في تلك المنطقة. ماذا إن كانت مهتمًا باستخراج بيانات الطقس لهذا العنوان البريدي؟ اضغط بالزر الأيمن على مكان معلومات الطقس في تلك الصفحة واختر Inspect Element من القائمة، وستظهر لك نافذة أدوات المطور، التي تريك شيفرات HTML المسؤولة عن ذاك الجزء من الصفحة كما يظهر في الشكل التالي. انتبه إلى أن الموقع قد يتغير دوريًا وقد تظهر لك عناصر مختلفة وعليك اتباع نفس الخطوات لتفحص العناصر الجديدة. تفحص عناصر صفحة الطقس باستخدام أدوات المطور يمكننا أن نرى ما هي شيفرة HTML المسؤولة عن عرض الطقس في الصفحة السابقة، وهي: <div class="col-sm-10 forecast-text">Sunny, with a high near 64. West wind 11 to 16 mph, with gusts as high as 21 mph.</div> هذا ما نبحث عنه تمامًا، يبدو أن معلومات الطقس موجودة داخل عنصر <div> له صنف CSS باسم forecast-text. اضغط بالزر الأيمن على العنصر في أدوات المطور واختر من القائمة Copy ▸ CSS Selector، وستُنسَخ لك سلسلة نصية مثل الآتية إلى الحافظة: 'div.row-odd:nth-child(1) > div:nth-child(2)' ويمكنك أن تستخدم تلك السلسلة النصية مع التابع ذ في BS4 أو find_element_by_css_selector()‎ في Selenium كما هو مشروح في هذا المقال. الآن وبعد أن عرفت ما الذي تبحث عنه تحديدًا، يمكن لوحدة Beautiful Soup أن تساعدك في العثور عليه. تفسير HTML مع وحدة BS4 تستخدم الوحدة Beautiful Soup في استخراج المعلومات من صفحة HTML، واسم الوحدة في بايثون هو bs4 للإشارة إلى الإصدار الرابع منها، ويمكننا تثبيتها عبر الأمر pip install --user beautifulsoup4 (راجع الملحق أ لتعليمات حول تثبيت الوحدات). صحيح أننا استخدمنا beautifulsoup4 لتثبيت الوحدة، لكن حين استيرادها في بايثون سنستعمل import bs4. ستكون أمثلتنا عن BS4 عن تفسير ملف HTML (أي تحليلها والتعرف على أجزائها) مخزن محليًا على حاسوبنا. افتح لسانًا جديدًا في محرر Mu وأدخل ما يلي فيه واحفظه باسم example.html: <!-- This is the example.html example file. --> <html><head><title>The Website Title</title></head> <body> <p>Download my <strong>Python</strong> book from <a href="https:// inventwithpython.com">my website</a>.</p> <p class="slogan">Learn Python the easy way!</p> <p>By <span id="author">Al Sweigart</span></p> </body></html> نعم، حتى ملفات HTML البسيطة فيها مختلف العناصر والخاصيات، وستكون الأمور أعقد بكثير في المواقع الكبيرة، لكن مكتبة BS4 هنا لمساعدتنا وتسهيل الأمر علينا. إنشاء كائن BeautifulSoup من سلسلة HTML نصية يمكننا استدعاء الدالة bs4.BeautifulSoup()‎ مع تمرير سلسلة نصية تحتوي على شيفرة HTML التي ستفسر. تعيد الدالة bs4.BeautifulSoup()‎ كائن BeautifulSoup. جرب ما يلي في الصدفة التفاعلية على حاسوبك مع وجود إنترنت: >>> import requests, bs4 >>> res = requests.get('https://academy.hsoub.com') >>> res.raise_for_status() >>> academySoup = bs4.BeautifulSoup(res.text, 'html.parser') >>> type(academySoup) <class 'bs4.BeautifulSoup'> هذه الشيفرة تستعمل requests.get()‎ لتنزيل صفحة الويب من موقع أكاديمية حسوب ثم تمرر قيمة السمة text للرد إلى الدالة bs4.BeautifulSoup()‎ التي تعيد كائن BeautifulSoup نخزنه في المتغير academySoup. يمكننا أيضًا تحميل ملف HTML من القرص لدينا بتمرير كائن File إلى الدالة bs4.BeautifulSoup()‎ مع وسيط ثانٍ يخبر وحدة BS4 ما المفسر الذي عليها استعماله لتفسير الملف. أدخل ما يلي في الصدفة التفاعلية مع التأكد أنك في نفس المجلد الذي يحتوي على ملف example.html: >>> exampleFile = open('example.html') >>> exampleSoup = bs4.BeautifulSoup(exampleFile, 'html.parser') >>> type(exampleSoup) <class 'bs4.BeautifulSoup'> المفسر 'html.parser' المستخدم هنا يأتي مع بايثون، لكن يمكنك استخدام المفسر 'lxml' الأسرع إذا ثبتت الوحدة الخارجية lxml. اتبع التعليمات الموجودة في الملحق أ لتثبيت الوحدة باستخدام الأمر pip install --user lxml. إذا لم نضمِّن الوسيط الثاني الذي يحدد المفسر فسيظهر التحذير: UserWarning: No parser was explicitly specified. بعد أن يكون لدينا كائن BeautifulSoup سنتمكن من استخدام توابعه لتحديد أجزاء معينة من مستند HTML. العثور على عنصر باستخدام التابع select()‎ يمكنك الحصول على عنصر من عناصر صفحة الويب في الكائن BeatuifulSoup باستدعاء التابع select()‎ وتمرير محدد CSS (أي CSS Selector) للعنصر الذي تبحث عنه. المحددات تشبه التعابير النمطية في وظيفتها: تحدد نمطًا يمكن البحث عنه في صفحات الويب. نقاش محددات CSS خارج سياق هذه السلسلة، لكن هذه مقدمة مختصرة عنها في الجدول التالي، وأنصحك بالاطلاع على توثيق المحددات في موسوعة حسوب. المحدد الذي يمرر إلى التابع ()select سيطابق soup.select('div') جميع عناصر <div> soup.select('#author') جميع العناصر التي لها الخاصية id وقيمتها author soup.select('.notice') جميع العناصر التي لها خاصية class ولها صنف CSS باسم notice soup.select('div span') جميع عناصر <span> الموجود داخل عناصر <div> soup.select('div > span') جميع العناصر <span> الموجودة مباشرةً داخل عناصر <div> بدون وجود أي عنصر بينهما soup.select('input[name]') جميع عناصر <input> التي لها الخاصية name بغض النظر عن قيمتها soup.select('input[type="button"]') جميع عناصر <input> التي لها الخاصية type وتكون مساوية إلى button أمثلة عن محددات CSS يمكن دمج مختلف أنماط المحددات مع بعضها لمطابقة أنماط أكثر تعقيدًا، فمثلًا soup.select('p #author')‎ ستطابق أي عنصر له خاصية id قيمتها author لكن يجب أن يكون هذا العنصر موجودًا داخل عنصر <p>. بدلًا من محاولة كتابة المحددات بنفسك، يمكنك الضغط بالزر الأيمن على أي عنصر في صفحة الويب واختيار Inspect Element، وحينما تفتح أدوات المطور اضغط بالزر الأيمن على عنصر HTML واختر Copy ▸ CSS Selector لنسخ محدد CSS إلى الحافظة لتستطيع لصقه في الشيفرة لديك. التابع select()‎ سيعيد قائمةً بعناصر Tag، وهذا ما تفعله وحدة BS4 لتمثيل عنصر HTML. هذه القائمة ستحتوي على كائن Tag لكل مطابقة للمحدد في كائن BeautifulSoup. يمكن تمرير كائن Tag إلى الدالة str()‎ لعرض وسوم HTML التي تمثلها. تمتلك قيم Tag أيضًا السمة attrs التي تظهر جميع خاصيات HTML للعنصر ممثلةً كقاموس. لنجرب على ملف example.html بإدخال ما يلي في الصدفة التفاعلية: >>> import bs4 >>> exampleFile = open('example.html') >>> exampleSoup = bs4.BeautifulSoup(exampleFile.read(), 'html.parser') >>> elems = exampleSoup.select('#author') >>> type(elems) # elems هي قائمة من كائنات Tag <class 'list'> >>> len(elems) 1 >>> type(elems[0]) <class 'bs4.element.Tag'> >>> str(elems[0]) # تحويل الكائن إلى سلسلة نصية. '<span id="author">Al Sweigart</span>' >>> elems[0].getText() 'Al Sweigart' >>> elems[0].attrs {'id': 'author'} ستستخرج الشيفرة السابقة العنصر الذي له id="author"‎ في مستند HTML. سنستخدم select('#author')‎ للحصول على قائمة بجميع العناصر التي لها id="author"‎، وسنخزن قائمة كائنات Tag في المتغير elems، وسيخبرنا التعبير len(elems)‎ أن لدينا كائن Tag وحيد في القائمة، أي جرت عملية المطابقة لعنصر HTML وحيد. استدعاء التابع getText()‎ على العناصر سيعيد النص الموجود في العنصر، أي السلسلة النصية الموجودة بين وسم البدء والإغلاق. أما تمرير الكائن إلى الدالة str()‎ سيعيد سلسلة نصيةً فيها وسمَي البداية والنهاية مع نص العنصر؛ أما السمة attrs فستعطينا قاموسًا فيه خاصيات العنصر كاملةً. يمكنك أيضًا استخراج جميع عناصر <p> من كائن BeautifulSoup كما في المثال الآتي: >>> pElems = exampleSoup.select('p') >>> str(pElems[0]) '<p>Download my <strong>Python</strong> book from <a href="https:// inventwithpython.com">my website</a>.</p>' >>> pElems[0].getText() 'Download my Python book from my website.' >>> str(pElems[1]) '<p class="slogan">Learn Python the easy way!</p>' >>> pElems[1].getText() 'Learn Python the easy way!' >>> str(pElems[2]) '<p>By <span id="author">Al Sweigart</span></p>' >>> pElems[2].getText() 'By Al Sweigart' ستعطينا select()‎ ثلاث مطابقات، والتي ستخزن في المتغير pElems. سنجرب استخدام str()‎ على الكائنات pElems[0]‎ و pElems[1]‎ و pElems[2]‎ لعرض العناصر كسلاسل نصية، وسنجرب أيضًا التابع getText()‎ لإظهار نص تلك العناصر فقط. الحصول على معلومات من خاصيات العنصر يسهل علينا التابع get()‎ الخاص بكائنات Tag الوصول إلى خاصيات العناصر، ونمرر لهذا التابع سلسلةً نصيةً باسم الخاصية attribute وسيعيد لنا قيمتها. لنجرب المثال الآتي على الملف example.html: >>> import bs4 >>> soup = bs4.BeautifulSoup(open('example.html'), 'html.parser') >>> spanElem = soup.select('span')[0] >>> str(spanElem) '<span id="author">Al Sweigart</span>' >>> spanElem.get('id') 'author' >>> spanElem.get('some_nonexistent_addr') == None True >>> spanElem.attrs {'id': 'author'} يمكننا استخدام select()‎ للعثور على أي عناصر <span> ثم تخزين أول عنصر مطابق في المتغير spanElem، الذي سنمرر للتابع get()‎ القيمة 'id' للحصول على قيمة المعرف الخاصة به، وهي 'author' في مثالنا. مشروع: فتح جميع نتائج البحث في كل مرة أبحث فيها في جوجل، لا أريد أن أرى نتيجة بحث واحدة فقط ثم أنتقل إلى النتيجة التي بعدها، بل أضغط بسرعة على الزر الأوسط للفأرة على كل الروابط (أو الضغط عليها مع زر Ctrl) لفتحها في لسان جديد وأقرؤها معًا لاحقًا. فعلت هذا الأمر كثيرًا في جوجل لدرجة أنني مللت من البحث ثم الضغط على كل الروابط واحدًا واحدًا. ماذا لو كتبت برنامجًا أستطيع عبره كتابة عبارة البحث وسيفتح لي متصفحًا فيه كل نتائج البحث الأولى مفتوحةً كل واحد منها في لسان في المتصفح؟ لنكتب سكربتًا يفعل ذلك مع صفحة نتائج بحث فهرس حزم بايثون. يمكن تعديل هذا البرنامج ليعمل على الكثير من المواقع الأخرى، لكن انتبه إلى أن محركات البحث غوغل و DockDockGo عادةً ما تصعب عملية استخراج نتائج البحث من مواقعها. هذا ما يفعله البرنامج: الحصول على عبارة البحث من سطر الأوامر الحصول على صفحة نتائج البحث فتح لسان متصفح جديد لكل نتيجة هذا يعني أن على برنامجك أن يفعل ما يلي: قراءة وسائط سطر الأوامر من sys.argv. الحصول على صفحة نتائج البحث عبر الوحدة requests. العثور على جميع روابط نتائج البحث. استدعاء الدالة webbrowser.open()‎ لفتحها في المتصفح. لنبدأ البرمجة بفتح ملف جديد باسم searchpypi.py في محررنا. الخطوة 1: الحصول على وسائط سطر الأوامر وطلب صفحة نتائج البحث قبل أن نبدأ بالبرمجة، علينا أن نعرف ما هو رابط URL لصفحة نتائج البحث. انظر إلى شريط العنوان في المتصفح بعد إتمامك لعملية البحث، وسترى أن الرابط يشبه https://pypi.org/search/?q=SEARCH_TERM_HERE. يمكننا استخدام الوحدة requests لتنزيل هذه الصفحة، ثم استخدام BS4 للبحث عن الروابط في مستند HTML. يمكننا في النهاية أن نستعمل وحدة webbrowser لفتح تلك الروابط في ألسنة جديدة. يحب أن تكون الشيفرة كما يلي: #! python3 # searchpypi.py - فتح عدة نتائج بحث. import requests, sys, webbrowser, bs4 print('Searching...') # عرض النص ريثما تحمل الصفحة res = requests.get('https://pypi.org/search/?q=' + ' '.join(sys.argv[1:])) res.raise_for_status() # TODO: Retrieve top search result links. # TODO: فتح لسان لكل نتيجة. سيحدد المستخدم كلمات البحث عبر تمريرها إلى سطر الأوامر أثناء تشغيل البرنامج، وستخزن في sys.argv كما رأينا في المقالات السابقة لهذه السلسلة. الخطوة 2: العثور على كل النتائج ستحتاج الآن إلى وحدة BS4 لاستخراج نتائج البحث من مستند HTML المنزل. لكن كيف يمكننا معرفة المحدد المناسب لحالتنا؟ ليس من المنطقي مثلًا البحث عن جميع عناصر <a> لوجود روابط كثيرة لا تهمنا؛ والحل هنا أن نفتح أدوات المطور في المتصفح وننظر إلى المحدد المناسب الذي سينتقي لنا الروابط التي نريدها فقط. بعد أن نبحث فسنجد بعض العناصر التي تشبه التالي: <a class="package-snippet" href="/project/pyautogui/"> ولا يهمنا إن كانت تلك العناصر معقدة، وإنما نحتاج إلى النمط الذي علينا استخدامه للبحث عن الروابط. لنعدل شيفرتنا إلى: #! python3 # searchpypi.py - Opens several google results. import requests, sys, webbrowser, bs4 --snip-- # Retrieve top search result links. soup = bs4.BeautifulSoup(res.text, 'html.parser') # فتح لسان لكل نتيجة. linkElems = soup.select('.package-snippet') إذا ألقيت نظرةً إلى عناصر <a> فستجد أن جميع نتائج البحث لها الخاصية class="package-snippet"‎ وإذا بحثنا في كامل مصدر الصفحة فسنتأكد أن الصنف package-snippet ليس مستخدمًا إلا لروابط نتائج البحث. لا يهمنا ما هو الصنف package-snippet ولا ما يفعل، وإنما يهمنا كيف سنستفيد منه لتحديد عناصر <a> التي نبحث عنها. لننشِئ كائن BeautifulSoup من صفحة HTML التي نزلناها ونستخدم المحدد '‎.package-snippet' لتحديد جميع عناصر <a> التي لها صنف CSS المحدد؛ ضع في ذهنك أن موقع PyPI قد يحدث واجهته الرسومية وقد تحتاج إلى استخدام محدد CSS مختلف مستقبلًا، إن حدث ذلك فمرر المحدد الجديد إلى التابع soup.select()‎ وسيعمل البرنامج على ما يرام. الخطوة 3: فتح نتائج البحث في المتصفح لنخبر برنامجنا الآن أن يفتح لنا النتائج الأولى في متصفح الويب. أضف ما يلي إلى برنامجك: #! python3 # searchpypi.py - فتح عدة نتائج بحث. import requests, sys, webbrowser, bs4 --snip-- # فتح لسان لكل نتيجة. linkElems = soup.select('.package-snippet') numOpen = min(5, len(linkElems)) for i in range(numOpen): urlToOpen = 'https://pypi.org' + linkElems[i].get('href') print('Opening', urlToOpen) webbrowser.open(urlToOpen) سيفتح البرنامج افتراضيًا أول خمسة روابط في المتصفح باستخدام الوحدة webbrowser، لكن قد يكون ناتج بحث المستخدم أقل من خمس نتائج، فحينها ننظر أيهما أقل، 5 أم عدد عناصر القائمة المعادة من استدعاء التابع soup.select()‎. الدالة المضمنة في بايثون min()‎ تعيد العدد الأصغر من الوسائط الممررة إليها (والدالة max()‎ تفعل العكس). يمكنك أن تستخدم الدالة min()‎ لمعرفة إذا كان عدد الروابط أقل من 5 وتخزين الناتج في المتغير numOpen، والذي ستستفيد منه في حلقة for عبر range(numOpen)‎. سنستخدم الدالة webbrowser.open()‎ في كل تكرار لحلقة for لفتح الرابط في المتصفح. لاحظ أن قيمة الخاصية href في عناصر <a> لا تحتوي على https://pypi.org لذا علينا إضافتها بأنفسنا إلى قيمة الخاصية href قبل فتح الرابط. يمكنك الآن فتح أول 5 نتائج بحث عن «boring stuff» في محرك بحث PyPI بكتابة الأمر searchpypi boring stuff في سطر الأوامر. أفكار لبرامج مشابهة من الجميل أن يكون لدينا برنامج يفتح لنا عدة ألسنة في المتصفح لأي عملية روتينية مكررة، مثل: فتح جميع صفحات المنتجات في متجر أمازون بعد البحث عن منتج معين. فتح كل روابط المراجعات لمنتج ما. فتح الصور الناتجة بعد إجراء عملية بحث سريعة على أحد مواقع الصور مثل Flickr. مشروع: تنزيل كل رسمات XKCD عادةً ما تحدث المواقع والمدونات الصفحة الرئيسية لها بعرض آخر منشور فيها، مع وجود زر «السابق» الذي يأخذك إلى المنشور السابق، ثم تجد في المنشور السابق زرًا يأخذك للمنشور الذي قبله، وهلم جرًا، مما ينشِئ سلسلةً من الصفحات التي تأخذك من الصفحة الرئيسية إلى صفحة أول منشور في الموقع. إذا أردت نسخةً من محتوى موقعٍ ما لتقرأها وأنت غير متصل بالإنترنت، فيمكنك أن تفتح بنفسك كل صفحة وتحفظها، لكن هذا الأمر ممل جدًا ومن المناسب كتابة برنامج لأتمتة هذه المهمة. موقع XKCD هو موقع كوميكس له نفس البنية المذكورة. وصفحته الرئيسية فيها زر Prev للعودة إلى الكوكميس السابقة، لكن عملية تنزيل كل الكوميكس واحدةً واحدةً تأخذ وقتًا كثيرًا، لكننا نستطيع كتابة سكربت لأتمتة ذلك في ثوانٍ معدودة. هذا ما سيفعله برنامجنا: فتح صفحة XKCD الرئيسية حفظ صورة الكوميكس في تلك الصفحة الانتقال إلى صفحة الكوميكس السابق تكرار العملية حتى الوصول إلى أول صورة كوميكس. هذا يعني أن الشيفرة البرمجية ستفعل ما يلي: تنزيل الصفحات باستخدام الوحدة requests. العثور على رابط URL لصورة الكوميكس باستخدام وحدة BS4. تنزيل وحفظ صورة الكوميكس إلى نظام الملفات باستخدام iter_content()‎. العثور على رابط صورة الكوميكس السابقة، وتكرار العملية كلها. افتح ملفًا جديدًا في محررك وسمِّه باسم downloadXkcd.py. الخطوة 1: تصميم البرنامج إذا فتحت أدوات المطور في المتصفح ونظرت إلى عناصر الصفحة، فسترى ما يلي: رابط URL لملف صورة الكوميكس في الخاصية href في العنصر <img>. العنصر <img> موجود داخل العنصر <div id="comic"‎>. الزر Perv له الخاصية rel وقيمتها prev. صفحة أول صورة كوميكس يشير فيها الزر Prev إلى الرابط https://xkcd.com/# مما يشير إلى عدم وجود صفحات سابقة. عدّل الشيفرة لتبدو كما يلي: #! python3 # downloadXkcd.py - تنزيل كل صورة كوميكس في XKCD. import requests, os, bs4 url = 'https://xkcd.com' # starting url os.makedirs('xkcd', exist_ok=True) # store comics in ./xkcd while not url.endswith('#'): # TODO: Download the page. # TODO: Find the URL of the comic image. # TODO: Download the image. # TODO: حفظ الصورة إلى ./xkcd. # TODO: الحصول على رابط الصفحة السابقة. print('Done.') سيكون لدينا متغير اسمه url يبدأ بالقيمة 'https://xkcd.com' وتحدث قيمته دوريًا ضمن حلقة for لتصبح الرابط الموجود في الزر Prev للصفحة الحالية. وسننزل صورة الكوميكس في كل تكرار من تكرارات حلقة for الموجودة في الرابط url، وسننتهي من حلقة التكرار حينما تنتهي قيمة url بالعلامة '#'. سننزل ملفات الصور إلى مجلد موجود في مجلد العمل الحالي باسم xkcd، وسنتأكد من أن المجلد موجود باستدعاء os.makedirs()‎ مع تمرير وسيط الكلمات المفتاحية exist_ok=True الذي يمنع الدالة من رمي استثناء إن كان المجلد موجودًا مسبقًا. بقية الشيفرة هو تعليقات سنملؤها في الأقسام القادمة. الخطوة 2: تنزيل صفحة الويب لنكتب الشيفرة الآتية التي ستنزل الصفحة: #! python3 # downloadXkcd.py - تنزيل كل صورة كوميكس في XKCD. import requests, os, bs4 url = 'https://xkcd.com' # starting url os.makedirs('xkcd', exist_ok=True) # store comics in ./xkcd while not url.endswith('#'): # Download the page. print('Downloading page %s...' % url) res = requests.get(url) res.raise_for_status() soup = bs4.BeautifulSoup(res.text, 'html.parser') # TODO: Find the URL of the comic image. # TODO: Download the image. # TODO: حفظ الصورة إلى ./xkcd. # TODO: الحصول على رابط الصفحة السابقة. print('Done.') لنطبع بدايةً قيمة url ليعرف المستخدم ما هو رابط URL الذي يحاول البرنامج تنزيله، ثم سنستخدم الدالة requests.get()‎ في الوحدة requests لتنزيل الصفحة. ثم سنستدعي التابع raise_for_status()‎ كالعادة لرمي استثناء إن حدثت مشكلة ما في التنزيل؛ ثم إن سارت الأمور على ما يرام فسننشِئ كائن BeautifulSoup من نص الصفحة المنزلة. الخطوة 3: البحث عن صورة الكوميكس وتنزيلها لنعدل شيفرة برنامجنا: #! python3 # downloadXkcd.py - تنزيل كل صورة كوميكس في XKCD. import requests, os, bs4 --snip-- # Find the URL of the comic image. comicElem = soup.select('#comic img') if comicElem == []: print('Could not find comic image.') else: comicUrl = 'https:' + comicElem[0].get('src') # Download the image. print('Downloading image %s...' % (comicUrl)) res = requests.get(comicUrl) res.raise_for_status() # TODO: حفظ الصورة إلى ./xkcd. # TODO: الحصول على رابط الصفحة السابقة. print('Done.') بعد تفحص صفحة XKCD عبر أدوات المطور، سنعرف أن عنصر <img> لصورة الكوميكس موجود داخل عنصر <div> له الخاصية id التي قيمتها هي comic، وبالتالي سيكون المحدد '‎#comic img' صحيحًا لتحديد العنصر <img> عبر كائن BeautifulSoup. تمتلك بعض صفحات موقع XKCD على محتوى خاص لا يمثل صورة بسيطة، لكن لا بأس فيمكننا تخطي تلك الصفحات، فإن لم يطابِق المحدد الخاص بنا أي عنصر فسيعيد استدعاء soup.select('#comic img')‎ قائمة فارغة، وحينها سيظهر برنامجنا رسالة خطأ ويتجاوز الصفحة دون تنزيل الصورة. عدا ذلك، فسيعيد المحدد السابق قائمةً فيها عنصر <img> وحيد، ويمكننا الحصول على قيمة الخاصية src لعنصر <img>ونمررها إلى requests.get()‎ لتنزيل صورة الكوميكس. الخطوة 4: حفظ الصورة والعثور على الصفحة السابقة لنعدل الشيفرة لتصبح كما يلي: #! python3 # downloadXkcd.py - تنزيل كل صورة كوميكس في XKCD. import requests, os, bs4 --snip-- # حفظ الصورة إلى ./xkcd. imageFile = open(os.path.join('xkcd', os.path.basename(comicUrl)), 'wb') for chunk in res.iter_content(100000): imageFile.write(chunk) imageFile.close() # الحصول على رابط الصفحة السابقة. prevLink = soup.select('a[rel="prev"]')[0] url = 'https://xkcd.com' + prevLink.get('href') print('Done.') أصبح لدينا ملف صورة الكوميكس مخزنًا في المتغير res، وعلينا كتابة بيانات هذه الصورة إلى ملف في نظام الملفات المحلي لدينا. سنحدد اسم الملف المحلي للصورة ونمرره إلى الدالة open()‎، لاحظ أن المتغير comicUrl يحتوي على قيمة تشبه القيمة الآتية: 'https://imgs.xkcd.com/comics/heartbleed_explanation.png' ويبدو أنك لاحظت وجود مسار الملف فيها. يمكنك استخدام الدالة os.path.basename()‎ مع comicUrl لإعادة آخر جزء من رابط URL السابق، أي 'heartbleed_explanation.png'، ويمكنك حينها استخدام هذا الاسم حين حفظ الصورة إلى نظام الملفات المحلي. يمكنك أن تضيف هذا الاسم إلى اسم مجلد xkcd باستخدام الدالة os.path.join()‎ كما تعلمنا سابقًا لكي يستخدم برنامجك الفاصل الصحيح (الخط المائل الخلفي \ في ويندوز، والخط المائل / في لينكس وماك). أصبح لدينا الآن اسم ملف صحيح، ويمكننا استدعاء الدالة open()‎ لفتح ملف جديد بوضع الكتابة الثنائية 'wb'. إذا كنت تذكر حينما حفظنا الملفات التي نزلناها عبر الوحدة requests في بداية المقال كنا نمر بحلقة تكرار على القيمة المعادة من التابع iter_content()‎، وستكتب الشيفرة الموجودة في حلقة for قطعًا من بيانات الصورة (كحد أقصى 100,000 بايت كل مرة) إلى الملف، ثم تغلق الملف. أصبحت الصورة محفوظة لديك محليًا الآن! علينا بعدئذٍ استخدام المحدد 'a[rel="prev"]‎' لتحديد العنصر <a> الذي له العلاقة rel مضبوطةً إلى prev. يمكنك استخدام قيمة الخاصية href لعنصر <a> المحدد للحصول على رابط صورة الكوميكس السابقة، والتي ستخزن في المتغير url، ثم ستدور حلقة while مرة أخرى وتعيد تنفيذ عملية التنزيل من جديد على الصفحة الجديدة. سيبدو ناتج تنفيذ البرنامج كما يلي: Downloading page https://xkcd.com... Downloading image https://imgs.xkcd.com/comics/phone_alarm.png... Downloading page https://xkcd.com/1358/... Downloading image https://imgs.xkcd.com/comics/nro.png... Downloading page https://xkcd.com/1357/... Downloading image https://imgs.xkcd.com/comics/free_speech.png... Downloading page https://xkcd.com/1356/... Downloading image https://imgs.xkcd.com/comics/orbital_mechanics.png... Downloading page https://xkcd.com/1355/... Downloading image https://imgs.xkcd.com/comics/airplane_message.png... Downloading page https://xkcd.com/1354/... Downloading image https://imgs.xkcd.com/comics/heartbleed_explanation.png... --snip– هذا المشروع هو مثال ممتاز لبرامج تتبع الروابط تلقائًا لاستخراج كمية معلومات كبيرة من الويب. يمكنك تعلم المزيد من المعلومات حول ميزات Beautiful Soup الأخرى من توثيقها الرسمي. أفكار لبرامج مشابهة تنزيل صفحات الويب وتتبع الروابط فيها هو أساس أي برنامج زحف crawler. يمكنك أن تبرمج برامج تفعل ما يلي: تنسخ موقعًا كاملًا احتياطيًا. تنسخ جميع التعليقات من أحد المنتديات. تعرض قائمة بجميع المنتجات التي عليها تخفيضات في أحد المتاجر. الوحدتان requests و bs4 رائعتين جدًا، لكن عليك أن تعرف ما هو رابط URL المناسب لتمريره إلى requests.get()‎، لكن في بعض الأحيان قد لا يكون ذلك سهلًا؛ أو ربما عليك تسجيل الدخول إلى أحد المواقع قبل بدء عملية الاستخراج، لهذا السبب سنستكشف سويةً الوحدة selenium لأداء مهام معقدة. التحكم في المتصفح عبر الوحدة selenium تسمح الوحدة selenium لبايثون بالتحكم برمجيًا بالمتصفح بضغط الروابط وتعبئة الاستمارات، مثلها كمثل أي تفاعل من مستخدم بشري. يمكننا أن نتفاعل مع صفحات الويب بطرائق أكثر تقدمًا في الوحدة selenium مقارنة مع requests و bs4، لكنها قد تكون أبطأ وأصعب بالتشغيل في الخلفية لأننا نفتح متصفح ويب كامل مقارنة بتنزيل بعض الصفحات من الويب. لكن إن كان علينا التعامل مع صفحات الويب بطريقة تعتمد على شيفرات JavaScript التي تحدث الصفحة، فعلينا استخدام selenium بدلًا من requests. أضف إلى ذلك أن المواقع الشهيرة مثل أمازون تستخدم برمجيات للتعرف على الزيارات الآتية من سكربتات التي تحاول استخراج البيانات من صفحاتها أو إنشاء عدّة حسابات مجانية، ومن المرجح أن تحجب هذه المواقع برامجك بعد فترة؛ وهنا تأتي الوحدة selenium التي تعمل مثل متصفحات الويب العادية. أحد أشهر العلامات التي تتعرف فيها المواقع أن الزيارات آتية من برنامج (أو سكربت script) هي عبارة user-agent، التي تُعرِّف متصفح الويب المستخدم وتضمَّن في كل طلبيات HTTP. فمثلًا تكون عبارة user-agent للوحدة requests شيء يشبه 'python-requests/2.21.0'. يمكنك زيارة موقع مثل whatsmyua.info لتعرف ما هي user-agent الخاصة بك. أما الوحدة selenium فمن المرجح أن تظن المواقع أنها مستخدم بشري، لأنها تستخدم user-agent شبيه بالمتصفحات العادية مثل: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:124.0) Gecko/20100101 Firefox/124.0 ولأن نمط التصفح فيها يشبه المتصفحات الأخرى، فستُنزَّل الصور والإعلانات وملفات تعريف الارتباط والمتتبعات كما في المتصفحات العادية. لكن يمكن للمواقع كشف selenium وتحاول شركات شراء بطاقات الدخول والمتاجر الإلكترونية حجب أي سكربتات تستعمل متصفح selenium. تشغيل متصفح تتحكم فيه selenium سنرى في الأمثلة القادمة كيفية التحكم في متصفح فيرفكس من selenium، إذا لم يكن مثبتًا لديك فيمكنك تنزيله من getfirefox.com، ويمكنك تثبيت selenium،من سطر الأوامر بتشغيل pip install --user selenium، وأذكرك بالذهاب إلى الملحق أ لمزيد من المعلومات. قد يكون استيراد مكونات selenium مختلفًا عليك، فبدلًا من import selenium سنستعمل from selenium import webdriver (سبب فعل selenium لذلك خارج نطاق هذه السلسلة لا تقلق حوله). يمكنك بعد ذلك تشغيل فايرفوكس مع selenium بكتابة ما يلي في الصدفة التفاعلية: >>> from selenium import webdriver >>> browser = webdriver.Firefox() >>> type(browser) <class 'selenium.webdriver.firefox.webdriver.WebDriver'> >>> browser.get('https://inventwithpython.com') ستلاحظ أن متصفح فايرفوكس قد بدأ بالعمل حين استدعاء webdriver.Firefox()‎. استدعاء type()‎ على webdriver.Firefox()‎ سيظهر أنها من نوع البيانات WebDrive، واستدعاء التالي: browser.get('https://inventwithpython.com')‎ سيوجه المتصفح إلى https://inventwithpython.com/. بعد استدعاء webdriver.Firefox()‎ و get()‎ ستفتح الصفحة في متصفح فايرفوكس إذا واجهت مشكلة من قبيل ‎'geckodriver' executable needs to be in PATH فهذا يعني أن عليك تنزيل محرك فايرفوكس يدويًا قبل استخدام selenium للتحكم به. يمكنك التحكم بمتصفحات أخرى غير فيرفكس إذا ثبتت محرك الويب لهم webdriver. لمتصفح فايرفوكس، اذهب إلى github.com وثبت محرك geckodriver لنظام تشغيلك. (كلمة «Gecko» هي اسم محرك المتصفح engine في فيرفكس). سيحتوي الملف المضغوط المنزل على geckodriver.exe في ويندوز أو geckodriver في ماك ولينكس، وعليك وضعه في مسار PATH الخاص في نظامك، راجع الإجابة الآتية stackoverflow.com. أما لمتصفح كروم فاذهب إلى chromium.org ونزل الملف المضغوط المناسب لنظامك، وضع الملف chromedriver.exe أو chromedriver في مسار PATH كما ذكرنا أعلاه. يمكن فعل نفس الأمر لبقية المتصفحات الرئيسية، ابحث سريعًا في الويب عن اسم المتصفح متبوعًا بالكلمة webdriver وستجدها. قد تواجه مشاكل في تشغيل المتصفحات الجديدة في selenium، بسبب عدم التوافقية بينهما، لكن يمكنك إجراء حل التفافي بتثبيت نسخة قديمة من المتصفح أو من وحدة selenium. يمكنك معرفة تاريخ الإصدارات من pypi.org. للأسف قد تحدث مشاكل توافقية بين selenium وبعض إصدارات المتصفحات، وأنصحك حينها بالبحث في الويب عن الحلول المقترحة، وراجع الملحق أ لمعلومات حول تثبيت إصدار محدد من selenium (مثل تثبيت pip install --user -U selenium==3.14.1). العثور على عناصر في الصفحة توفر كائنات WebDriver عددًا من التوابع للعثور على عناصر صفحة، ويمكن تقسيمها إلى قسمين من التوابع find_element_‎ و find_elements_*‎. توابع find_element_*‎ تعيد كائن WebElement وحيد يمثل أول عنصر في الصفحة يطابق الطلبية التي حددتها، بينما تعيد توابع _find_elements‎ قائمة من كائنات WebElement_*‎ لكل عنصر مطابق في الصفحة. يظهر الجدول الموالي أمثلة على التوابع find_element_‎ و find_elements_‎ المستدعاة على كائن WebDriver مخزن في المتغير browser. اسم التابع كائن/قائمة كائنات WebElement browser.find_element_by_class_name(name) browser.find_elements_by_class_name(name) العناصر التي تستخدم صنف CSS باسم name browser.find_element_by_css_selector(selector) browser.find_elements_by_css_selector(selector) العناصر التي تطابق محدد CSS معين browser.find_element_by_id(id) browser.find_elements_by_id(id) العناصر التي تطابق id معين browser.find_element_by_link_text(text) browser.find_elements_by_link_text(text) عناصر <a> التي يطابق محتواها القيمة text كاملةً browser.find_element_by_partial_link_text(text) browser.find_elements_by_partial_link_text(text) عناصر <a> التي يطابق محتواها القيمة text جزئيًا browser.find_element_by_name(name) browser.find_elements_by_name(name) العناصر التي لها الخاصية name وتطابق قيمة معينة browser.find_element_by_tag_name(name) browser.find_elements_by_tag_name(name) العناصر التي تطابق وسمًا معينًا، وهي غير حساسة لحالة الأحرف (أي <a> يمكن أن يطابق عبر 'a' أو 'A') توابع WebDriver للعثور على العناصر في selenium باستثناء التوابع ‎*_by_tag_name()‎ تكون جميع الوسائط الممررة إلى الدوال حساسةً لحالة الأحرف، وإذا لم تكن العناصر موجودة في الصفحة فستطلق selenium الاستثناء NoSuchElement، وعليك استخدام عبارات try و except إذا لم ترغب بتوقف برنامج عن العمل عند ذلك. بعد أن تحصل على كائن WebElement فيمكنك أن تتعرف على المزيد حوله بقراءة سماته أو استدعاء توابع المذكورة في الجدول التالي: السمة أو التابع الوصف tag_name اسم الوسم، مثل 'a' لعنصر <a> get_attribute(name) قيمة خاصية name للعنصر text النص الموجود داخل العنصر، مثل 'hello' في <span>hello</span> clear() مسح النص المكتوب في الحقول النصية is_displayed() إعادة True إذا كان العنصر ظاهرًا، وإلا فيعيد False is_enabled() إعادة True إذا كان حقل الإدخال مفعلًا، وإلا فيعيد False is_selected() لأزرار الانتقاء radio ومربعات التأشير checkbox ستعيد True إذا كان العنصر مختار، وإلا فتعيد False location قاموس فيه المفاتيح 'x' و 'y' لمكان العنصر في الصفحة سمات وتوابع الكائن WebElement مثلًا، افتح ملفًا جديدًا واكتب البرنامج الآتي: from selenium import webdriver browser = webdriver.Firefox() browser.get('https://inventwithpython.com') try: elem = browser.find_element_by_class_name(' cover-thumb') print('Found <%s> element with that class name!' % (elem.tag_name)) except: print('Was not able to find an element with that name.') فتحنا هنا متصفح فيرفكس ووجهناه إلى رابط URL معين، وحاولنا العثور على العناصر التي لها الصنف bookcover، وإذا عثرنا على أحد العناصر فسنطبع اسم الوسم عبر السمة tag_name؛ أما لو لم يعثر على أي عنصر فسنطبع رسالة مختلفة. سيعيد البرنامج الناتج الآتي: Found <img> element with that class name! أي عثرنا على عنصر <img> له اسم الصنف 'bookcover'. الضغط على عناصر الصفحة تمتلك كائنات WebElement المعادة من التوابع find_element_*‎ و find_elements_*‎ التابع click()‎ الذي يحاكي ضغطات الفأرة على العنصر، ويمكن استخدام هذا التابع للضغط على رابط أو تحديد زر انتقاء أو الضغط على زر الإرسال أو أي حدث آخر يُطلَق عند الضغط على أحد العناصر. جرب المثال الآتي في الطرفية التفاعلية: >>> from selenium import webdriver >>> browser = webdriver.Firefox() >>> browser.get('https://inventwithpython.com') >>> linkElem = browser.find_element_by_link_text('Read Online for Free') >>> type(linkElem) <class 'selenium.webdriver.remote.webelement.FirefoxWebElement'> >>> linkElem.click() # follows the "Read Online for Free" link سيفتح متصفح فيرفكس الصفحة ويحصل على العنصر <a> الذي يحتوي على النص Read it Online ويحاكي الضغط على الرابط كما لو ضغطته بنفسك. تعبئة وإرسال الاستمارات يمكن تعبئة الحقول النصية مثل <input> أو <textarea> بالبحث عنها ثم استدعاء التابع send_keys()‎. جرب ما يلي في الطرفية التفاعلية: >>> from selenium import webdriver >>> browser = webdriver.Firefox() >>> browser.get('https://login.metafilter.com') >>> userElem = browser.find_element_by_id('user_name) >>> userElem.send_keys('your_real_username_here') >>> passwordElem = browser.find_element_by_id('user_pass') >>> passwordElem.send_keys('your_real_password_here') >>> passwordElem.submit() لطالما لم تغيّر صفحة MetaFilter المعرف id لحقول اسم المستخدم وكلمة المرور بعد نشر هذا الكتاب، فيمكنك استخدام الشيفرة السابقة لملء تلك الحقول النصية (تذكر أنك تستطيع استخدام أدوات المطور للتأكد من المعرف id للحقول في أي وقت). استدعاء التابع submit()‎ على أي عنصر في الاستمارة له نفس تأثير الضغط على زر الإرسال. تحذير: ابتعد عن تخزين كلمات المرور الخاصة بك في الشيفرة المصدرية لبرامجك قدر الإمكان، فمن السهل تسريب كلمات المرور إذا تركناها دون تشفير. يمكن لبرنامجك أن يطلب كلمة المرور من المستخدم أثناء التشغيل كما ناقشنا في مقال سابق. إرسال المفاتيح الخاصة تمتلك selenuim وحدةً للمفاتيح الخاصة التي لا يمكن كتابتها كسلسلة نصية، مثل زر Tab أو الأسهم. تلك القيم مخزنة كسمات في الوحدة selenium.webdriver.common.keys، ولأن اسم الوحدة طويل جدًا فمن الأسهل كتابة from selenium.webdriver.common.keys import Keys في بداية البرنامج، وحينها تستطيع استخدام Keys في أي مكان تريد أن تكتب فيه selenium.webdriver.common.keys. يعرض الجدول 12-5 أشهر القيم المستخدمة. الجدول 12-5: أشهر القيم المستخدمة في الوحدة selenium.webdriver.common.keys. السمة الشرح Keys.DOWN و Keys.UP و Keys.LEFT و Keys.RIGHT الأسهم في لوحة المفاتيح Keys.ENTER و Keys.RETURN زر Enter Keys.HOME و Keys.END و Keys.PAGE_DOWN و Keys.PAGE_UP أزرار Home و End و PageDown و PageUp على التوالي Keys.ESCAPE و Keys.BACK_SPACE و Keys.DELETE أزرار Escape و Backspace و Delete على التوالي Keys.F1 و Keys.F2 و . . . و Keys.F12 الأزرار F1 حتى F12 في الصف العلوي من لوحة المفاتيح Keys.TAB زر Tab فمثلًا لو لم يكن المؤشر موجودًا داخل حقل نصي، فالضغط على زر Home و End سيؤدي إلى التمرير إلى بداية ونهاية الصفحة على التوالي. جرب ما يلي على الصدفة التفاعلية ولاحظ كيف يؤدي استدعاء send_keys()‎ إلى تمرير الصفحة: >>> from selenium import webdriver >>> from selenium.webdriver.common.keys import Keys >>> browser = webdriver.Firefox() >>> browser.get('https://nostarch.com') >>> htmlElem = browser.find_element_by_tag_name('html') >>> htmlElem.send_keys(Keys.END) # scrolls to bottom >>> htmlElem.send_keys(Keys.HOME) # scrolls to top العنصر <html> موجود في كل ملفات HTML، ويكون كامل محتوى مستند HTML داخله؛ وتحديد هذا العنصر مفيد لو أردنا إرسال المفاتيح إلى صفحة الويب عمومًا، وهذا بدوره مفيد إذا كانت الصفحة تحمِّل محتوى جديد عند التمرير إلى أسفل الصفحة. الضغط على أزرار المتصفح يمكن أن تحاكي الوحدة selenium الضغط على أزرار المتصفح المختلفة: التابع browser.back()‎ يضغط على زر الرجوع التابع browser.forward()‎ يضغط على زر إلى الأمام التابع browser.refresh()‎ يضغط على زر التحديث التابع browser.quit()‎ يضغط على زر إغلاق النافذة المزيد من المعلومات حول Selenium يمكن للوحدة selenium فعل الكثير مما لم نذكره هنا، فيمكنك أن تعدل محتوى ملفات تعريف الارتباط، وتأخذ لقطة شاشة، وتشغل سكربت JavaScript مخصص …إلخ. لمزيد من المعلومات حول تلك الخصائص فأنصحك أن تزور التوثيق الرسمي. الخلاصة المهام المملة ليست متعلقة بالملفات المحلية على حاسوبك. إذا كنت قادرًا على تنزيل صفحات الويب برمجيًا فستستطيع أتمتة أي مهمة تردك! تسهل الوحدة requests تنزيل صفحات الويب، وبعد تعلم أساسيات HTML فيمكنك أن تستخدم الوحدة BeautifulSoup لتفسير الصفحات التي تنزلها. لكن إن كانت تريد أتمتة أي مهمة متعلقة بالويب أيًا كانت، فيمكنك التحكم برمجيًا مباشرةً بمتصفح الويب عبر الوحدة selenium، التي تسمح لك بفتح المواقع وملء الاستمارات كما لو كان برنامجك كائنًا بشريًا يتصفح المواقع. مشاريع تدريبية لكي تتدرب، اكتب برامج لتنفيذ المهام الآتية. إرسال البريد الإلكتروني من سطر الأوامر اكتب برنامج يقبل عنوان بريد إلكتروني وسلسلة نصية في سطر الأوامر، ثم يستخدم selenium للدخول إلى حسابك البريدي وإرسال بريد إلكتروني إلى العنوان المحدد (أنصحك بإنشاء حساب تجريبي مختلف عن حسابك الأساسي). اكتب برامج أخرى لإضافة منشورات إلى فيسبوك أو تويتر (إكس، سمه ما شئت!). منزِّل الصور اكتب برنامج يفتح أحد مواقع مشاركة الصور مثل Flickr ويبحث عن تصنيف معين من الصور وينزل جميع نتائج البحث في الصفحة الأولى. يمكنك أن تكتب برنامج يعمل على أي موقع مشاركة صور ولديه خاصية البحث. لعبة 2048 لعبة 2048 هي لعبة بسيطة تسمح لك بجمع مربعات بجعلها تنزلق إلى أحد الاتجاهات باستخدام أزرار الأسهم. يمكنك أن تحصل على نتيجة عالية إذا جعلت الانزلاق بهذا الترتيب مرارًا وتكرارًا: الأعلى ثم اليمين ثم الأسفل ثم اليسار. اكتب برنامج بسيط يفتح اللعبة gabrielecirulli.github.io وينفذ النمط السابق للعب اللعبة تلقائيًا. التحقق من الروابط اكتب برنامج يأخذ رابط URL من صفحة ويب، ويحاول أن ينزل كل صفحة مرتبطة فيها، ويُعلِّم كل الصفحات التي تعيد 404 وتؤشر عليها أنها روابط مكسورة. ترجمة -بتصرف- للمقال Web Scraping من كتاب Automate the Boring Stuff with Python. اقرأ أيضًا المقال السابق: تنقيح أخطاء Debugging شيفرتك البرمجية باستخدام لغة بايثون برمجة عملاء ويب باستخدام بايثون أهم 10 مكتبات بايثون تستخدم في المشاريع الصغيرة مشاريع بايثون عملية تناسب المبتدئين النسخة العربية الكاملة لكتاب البرمجة بلغة بايثون
    1 نقطة
  28. قبل شرح كيفية تهيئة بايثون، نود إعلامك أن هذا سيكون أول مقال من سلسلة مقالات أتمتة المهام عبر بايثون. ستشرح هذه السلسلة أساسيات البرمجة بلغة بايثون، والمهام المختلفة التي يمكن لحاسوبك أتمتتها، كما سنشاركك مشاريع عملية مع نهاية كل جزئية منه، والتي تستطيع استعمالها ودراستها ومشاركتنا تطبيقاتك لها في التعليقات. ما هي بايثون؟ بايثون هي لغة برمجة، ولغة البرمجة هي مجموعة قواعد لكتابة الشيفرة يجب الالتزام بها ليفهمها مترجم اللغة، ومترجم بايثون Python interpreter هو برمجية تقرأ الشيفرات المصدرية بلغة بايثون وتطبق التعليمات البرمجية فيها. يمكنك أن تنزل مفسر لغة بايثون مجانًا من موقع اللغة الرسمي، الذي فيه إصدارات لأنظمة تشغيل ويندوز وماك ولينكس. إذا كنتَ تتساءل من أين أتى اسم بايثون، فهو من مجموعة كوميدية بريطانية اسمها Monty Python، ولا علاقة للثعابين والأفاعي باسمها. تنزيل وتثبيت بايثون يمكنك تنزيل بايثون لنظام تشغيل ويندوز أو ماك أو لينكس مجانًا من رابط موقع اللغة، وستعمل معك جميع التطبيقات المشروحة في هذه السلسلة معك. ستجد في موقع بايثون نسختين إحداهما 64-بت والأخرى 32-بت لكل نظام تشغيل، لذا عليك اختيار الملف الصحيح لتنزله وتثبته. إذا اشتريت حاسوبك بعد عام 2007 فمن المرجح أنك تستعمل نظام 64-بت، وإلا فعليك استخدام نسخة 32-بت. إذا كنت تستعمل نظام ويندوز فنزِّل مثبت بايثون (الذي ينتهي باللاحقة ‎.exe) وشغِّله، ثم اتبع ما يرشدك إليه المثبِّت على الشاشة. أما على نظام macOS فنزِّل ملف ‎.pkg ثم شغله واتبع الإرشادات الموجودة على الشاشة. أما إذا كنت تستعمل توزيعة أوبنتو (أو ما يشبهها من التوزيعات المبنية على دبيان) فيمكنك تثبيت بايثون من سطر الأوامر بتنفيذ الأمر الآتي: sudo apt install python3 python3-pip idle3 تنزيل وتثبيت محرر Mu صحيحٌ أن مفسِّر بايثون هو البرنامج الذي يشغل شيفرات بايثون التي تكتبها، لكن برمجية Mu editor هي مكان إدخالك للشيفرات، بنفس الطريقة التي تكتب فيها بمعالج النصوص المفضل لديك. يمكنك تنزيل محرر Mu من موقعه. نزِّل المثبِّت الخاص بنظامك إن كنت تستعمل ويندوز أو ماك، ثم ابدأ عملية التثبيت بفتح المثبت، أما على لينكس فستحتاج إلى تثبيت محرر Mu كحزمة بايثون، وفي تلك الحالة اتبع الإرشادات الموجودة في الموقع. تشغيل محرر Mu بعد انتهاء تثبيت Mu، يمكنك تشغيله: في نظام ويندوز بالضغط على قائمة ابدأ ثم البحث عن Mu. في نظام MacOS بفتح Finder ثم Applications ثم الضغط على أيقونة mu-editor. في لينكس عليك تشغيل الطرفية Terminal ثم كتابة mu-editor. وحين تشغيلك لمحرر Mu لأول مرة فستظهر لك نافذة تخيّرك بين عدة خيارات وعليك اختيار Python 3، يمكنك في أي وقت تغيير النمط بالضغط على زر Mode في أعلى نافذة المحرر. تشغيل IDLE نستعمل في هذه السلسلة Mu كمحرر وصدفة تفاعلية interactive shell، لكنك تستطيع استخدام أي محرر تشاء لكتابة شيفرات بايثون، وتثبت بيئة التطوير والتعليم المدمجة Integrated Development and Learning Environment ‏(اختصارًا IDLE) مع بايثون تلقائيًا، ويمكنها أن تعمل كمحرر ثانوي لك إن لم يعمل يثبت عندك محرر Mu. لنشغل IDLE: في نظام ويندوز بالضغط على قائمة ابدأ ثم البحث عن IDLE. في نظام macOS بفتح Finder ثم Applications ثم الضغط على أيقونة Python. في لينكس عليك تشغيل الطرفية Terminal ثم كتابة idle3. الصَدَفة التفاعلية Interactive Shell عندما تشغل Mu فستظهر أمامك نافذة تحرير الملف، ويمكنك فتح الصَدَفة التفاعلية بالضغط على زر REPL. الصَدَفة Shell هي برنامج يسمح لك بإعطاء تعليمات للحاسوب، كما تفعل حينما تفتح الطرفية Terminal في لينكس أو ماك، أو موجه الأوامر في ويندوز. تسمح لك الصدفة التفاعلية في بايثون بإدخال التعليمات لينفذها مفسِّر بايثون مباشرةً. تجد الصدفة التفاعلية في محرر Mu في إطار في الجزء السفلي من النافذة فيها النص الآتي: Jupyter QtConsole 4.7.7 Python 3.6.9 (default, Mar 15 2022, 13:55:28) Type 'copyright', 'credits' or 'license' for more information IPython 7.16.3 -- An enhanced Interactive Python. Type '?' for help. In [1]: إذا كنت تستعمل IDLE، فالصدفة التفاعلية هي أول ما ستراه أمامك، ويفترض أن تكون فارغة باستثناء نص يبدو كما يلي: Python 3.6.9 (default, Mar 15 2022, 13:55:28) [GCC 8.4.0] on linux Type "help", "copyright", "credits" or "license()" for more information. >>> الأسطر التي تبدأ بالعبارة In [1]:‎ أو ‎<<< تسمى محثًا prompt (أي أنها عبارة «تحثّ» المستخدم على كتابة أمر وراءها). أمثلة هذه السلسلة ستستخدم <<< للإشارة إلى محث الصدفة التفاعلية لأنه أكثر شيوعًا. إذا شغلت مفسر بايثون من سطر الأوامر فستجد أمامك المحث <<< أيضًا. يستخدم محرر Jupyter Notebook الشهير المحث ‎In [1]:‎ وشاع بسببه. لنجرب مثالًا بسيطًا، أدخل السطر الآتي في الصدفة التفاعلية بعد المحث: >>> print('Hello, world!') بعد كتابة السطر السابق فاضغط على زر Enter، ويجب أن يظهر ما يلي في الصدفة: >>> print('Hello, world!') Hello, world! لقد أعطيت الحاسوب أمرًا ونفذه لك. مبارك! تثبيت الوحدات الخارجية في بايثون كتب العديد من المطورين وحداتهم الخاصة، مما أدى إلى توسيع قدرات لغة بايثون Python إلى ما هو أبعد مما توفره المكتبة المعيارية للوحدات المُدمَجة مع بايثون، والطريقة الأساسية لتثبيت هذه الوحدات الخارجية هي استخدام الأداة Pip في بايثون، حيث تنزِّل هذه الأداة وحدات بايثون وتثبّتها بطريقة آمنة على حاسوبك من موقع الويب الخاص بمؤسسة برمجيات بايثون، ويُعَد PyPI أو Python Package Index متجر التطبيقات المجاني لوحدات بايثون. ملاحظة: يمكنك تثبيت جميع الوحدات المطلوبة مع الإصدارات المستخدمة في هذه السلسلة من المقالات من خلال تثبيت الوحدة automateboringstuff باستخدام الأداة Pip، لذا شغّل الأمر الآتي من موجّه الأوامر أو نافذة الطرفية Terminal. pip install --user automateboringstuff الأداة Pip تُثبَّت الأداة Pip تلقائيًا مع الإصدار 3.4 من بايثون والإصدارات الأحدث على نظامي تشغيل ويندوز Windows وماك macOS، ولكن يجب أن تثبّتها تثبيتًا منفصلًا على نظام لينكس Linux. يمكنك معرفة ما إذا كانت الأداة Pip مُثبَّتة مسبقًا على نظام لينكس من خلال تشغيل الأمر which pip3 في نافذة الطرفية Terminal، حيث إذا كانت مثبَّتة، فسترى موقع الأداة pip3 معروضًا، وإلّا فلن يُعرض أيّ شيء. يمكنك تثبيت الأداة pip3 على نظام أوبنتو Ubuntu أو نظام دبيان Debian Linux من خلال فتح نافذة طرفية جديدة وإدخال الأمر sudo apt install python3-pip، ويمكنك تثبيت الأداة pip3 على نظام فيدورا لينكس Fedora Linux من خلال إدخال الأمر sudo dnf install python3-pip في نافذة الطرفية، ويجب أن تدخِل كلمة مرور المدير الخاصة بحاسوبك. تُشغَّل الأداة pip من نافذة الطرفية (وتُسمَّى أيضًا سطر الأوامر)، وليس من صدفة بايثون التفاعلية Interactive Shell. شغّل برنامج "موجّه الأوامر Command Prompt" من قائمة "ابدأ Start" في نظام تشغيل ويندوز، وشغّل الطرفية من أيقونة سبوت لايت Spotlight على نظام ماك macOS، وشغّل الطرفية من أيقونة Ubuntu Dash أو اضغط على الاختصار Ctrl-Alt-T في نظام أوبنتو لينكس Ubuntu Linux. إن لم يكن مجلد pip موجودًا في متغير البيئة PATH، فيجب تغيير المجلد في نافذة الطرفية باستخدام الأمر cd قبل تشغيل الأداة pip. إذا أردتَ معرفة اسم المستخدم الخاص بك، فشغّل الأمر echo %USERNAME%‎ على نظام ويندوز أو الأمر whoami على نظامي ماك macOS ولينكس، ثم شغّل الأمر cd pip folder، حيث يكون مجلد pip على نظام ويندوز في الآتي: C:\Users\<USERNAME>\AppData\Local\Programs\Python\Python39\Scripts ويوجد هذا المجلد في نظام ماك macOS على: /Library/Frameworks/Python.framework/Versions/3.9/bin/ كما يوجد هذا المجلد في نظام لينكس على: /home/<USERNAME>/.local/bin/ ، وبذلك ستكون في المجلد الصحيح لتشغيل الأداة pip. تثبيت الوحدات الخارجية يُسمَّى الملف القابل للتنفيذ للأداة pip بالاسم pip على نظام ويندوز ويسمّى pip3 على نظامي ماك macOS ولينكس. مرّر الأمر install متبوعًا باسم الوحدة التي تريد تثبيتها من سطر الأوامر، فمثلًا يمكنك إدخال الأمر pip install --user MODULE في نظام ويندوز، حيث MODULE هو اسم الوحدة. قد تكون التغييرات المستقبلية على هذه الوحدات الخارجية غير متوافقة مع الإصدارات السابقة، لذا نوصي بتثبيت الإصدارات المحدَّدة المستخدمة في هذه السلسلة من المقالات كما سنوضّح لاحقًا، حيث يمكنك إضافة الخيار ‎-U MODULE==VERSION إلى نهاية اسم الوحدة لتثبيت إصدار محدّد، ولاحظ وجود إشارتي مساواة في خيار سطر الأوامر، فمثلًا يثبّت الأمر الآتي الإصدار 1.5.0 من الوحدة send2trash: pip install --user -U send2trash==1.5.0 يمكنك تثبيت جميع الوحدات التي تغطيها هذه السلسلة من المقالات من خلال تنزيل ملفات المتطلبات "requirements" لنظام تشغيلك من موقع nostarch وتشغيل أحد الأوامر التالية: على نظام ويندوز: pip install --user –r automate-win-requirements.txt ––user على نظام ماك macOS: pip3 install --user –r automate-mac-requirements.txt --user على نظام لينكس: pip3 install --user –r automate-linux-requirements.txt --user تحتوي القائمة التالية على الوحدات الخارجية المستخدمة في هذه السلسلة من المقالات مع إصداراتها المختلفة، حيث يمكنك إدخال هذه الأوامر إدخالًا منفصلًا إذا أردتَ تثبيت عددٍ محدّد من هذه الوحدات على حاسوبك: pip install --user send2trash==1.5.0 pip install --user requests==2.21.0 pip install --user beautifulsoup4==4.7.1 pip install --user selenium==3.141.0 pip install --user openpyxl==2.6.1 pip install --user PyPDF2==1.26.0 pip install --user python-docx==0.8.10 ‫(تثبيت‫ python-docx وليس docx) pip install --user imapclient==2.1.0 pip install --user pyzmail36==1.0.4 pip install --user twilio pip install --user ezgmail pip install --user ezsheets pip install --user pillow==9.2.0 pip install --user pyobjc-framework-Quartz==5.2 (على نظام ماك فقط) pip install --user pyobjc-core==5.2 (على نظام ماك فقط) pip install --user pyobjc==5.2 (على نظام ماك فقط) pip install --user python3-xlib==0.15 (على نظام لينكس فقط) pip install --user pyautogui ملاحظة: يمكن أن يستغرق تثبيت الوحدة pyobjc في نظام ماك 20 دقيقة أو أكثر، لذا لا تنزعج إذا استغرق الأمر بعض الوقت، ويجب عليك أيضًا تثبيت الوحدة pyobjc-core أولًا، مما سيؤدي إلى تقليل وقت التثبيت الإجمالي. يمكنك اختبار نجاح تثبيت الوحدة بعد تثبيتها من خلال تشغيل الأمر import ModuleName في الصدفة التفاعلية، وإذا لم تُعرَض أيّ رسائل خطأ، فسنفترض نجاح تثبيت هذه الوحدة. إذا كانت الوحدة مثبتة مسبقًا، ولكنك ترغب في ترقيتها إلى أحدث إصدار متاح على موقع PyPI، فشغّل الأمر الآتي على نظامي ماك macOS ولينكس: pip install --user -U MODULE أو pip3 install --user -U MODULE حيث يثبَت الخيار ‎--user الوحدة في مجلد المستخدم الخاص بك، مما يؤدي إلى تجنب أخطاء الأذونات المحتملة التي قد تواجهها عند محاولة التثبيت لجميع المستخدمين. تُجرِي الإصدارات الأحدث من وحدات Selenium و OpenPyXL تغييرات غير متوافقة مع الإصدارات السابقة المُستخدَمة في هذه السلسلة من المقالات، بينما تتفاعل وحدات Twilio و EZGmail و EZSheets مع الخدمات عبر الإنترنت، ولكن قد يُطلَب منك تثبيت أحدث إصدار من هذه الوحدات باستخدام الأمر: pip install --user -U ملاحظة: اقترحنا سابقًا استخدام الأمر sudo إذا واجهتَ أخطاء في الأذونات أثناء تشغيل أمر pip كما يلي: sudo pip install module، ولكنها تُعَد ممارسة سيئة، لأنها تثبّت وحدات مع تثبيت بايثون الذي يستخدمه نظام تشغيلك، إذ قد يشغّل نظام تشغيلك سكربتات بايثون لتنفيذ المهام المتعلقة بالنظام، وإذا ثبّتَ وحدات مع تثبيت بايثون بحيث تتعارض هذه الوحدات مع وحداته الحالية، فقد يؤدي ذلك إلى إنتاج أخطاء يصعب إصلاحها، لذا لا تستخدم الأمر sudo أبدًا عند تثبيت وحدات بايثون. تثبيت وحدات للمحرّر Mu يمتلك محرّر Mu بيئة بايثون الخاصة به، وهي منفصلة عن البيئة التي تمتلكها عمليات تثبيت بايثون النموذجية، إذ يمكنك تثبيت الوحدات بحيث تستخدمها في السكربتات التي يشغّلها المحرّر Mu من خلال إظهار لوحة المدير Admin Panel عند النقر على رمز الترس في الزاوية اليمنى السفلية للمحرّر Mu، ثم انقر على تبويب الحزم الخارجية Third Party Packages في النافذة التي ستظهر واتبع الإرشادات الخاصة بتثبيت الوحدات في هذا التبويب. لا تزال القدرة على تثبيت الوحدات في المحرّر Mu ميزة حديثة وقيد التطوير، لذا قد تتغير هذه التعليمات. إن لم تتمكّن من تثبيت الوحدات باستخدام لوحة المدير، فيمكنك أيضًا فتح نافذة الطرفية وتشغيل الأداة pip الخاصة بالمحرّر Mu. يجب أن تستخدم خيار سطر الأوامر ‎--target الخاص بالأداة pip لتحديد مجلد الوحدة الخاص بالمحرّر Mu، وهذا المجلد على نظام ويندوز هو: C:\Users\<USERNAME>\AppData\Local\Mu\pkgs وعلى نظام ماك macOS: ‎/Applications/mu-editor.app/Contents/Resources/app_packages ولكنك لا تحتاج في نظام لينكس إلى إدخال الوسيط ‎--target ، لذا شغّل الأمر pip3 فقط. شغّل الأوامر التالية مثلًا بعد تنزيل ملف المتطلبات لنظام تشغيلك من موقع nostarch: على نظام ويندوز: pip install –r automate-win-requirements.txt --target "C:\Users\USERNAME\AppData\Local\Mu\pkgs" على نظام ماك macOS: pip3 install –r automate-mac-requirements.txt --target /Applications/mu-editor.app/Contents/Resources/app_packages على نظام لينكس: pip3 install --user –r automate-linux-requirements.txt إذا أردتَ تثبيت بعض الوحدات فقط، فيمكنك تشغيل الأمر pip (أو pip3) العادي وإضافة الوسيط ‎--target. تشغيل البرامج في بايثون إذا كان برنامجك مفتوحًا في المحرّر Mu، فيُعَد تشغيله أمرًا بسيطًا من خلال الضغط على مفتاح F5 أو النقر على زر التشغيل Run الموجود أعلى النافذة، وهي طريقة سهلة لتشغيل البرامج أثناء كتابتها، ولكن يمكن أن يكون فتح المحرّر Mu لتشغيل برامجك النهائية عبئًا عليك، لذا توجد طرق أكثر ملاءمة سنوضّحها في هذا المقال لتنفيذ سكربتات بايثون اعتمادًا على نظام التشغيل الذي تستخدمه. تشغيل البرامج من نافذة الطرفية Terminal إذا فتحتَ نافذة طرفية مثل موجّه الأوامر على نظام ويندوز Windows أو الطرفية Terminal على نظامي ماك macOS ولينكس Linux، فسترى نافذةً فارغة لإدخال أوامر نصية فيها. يمكنك تشغيل برامجك من الطرفية، ولكن إن لم تكن معتادًا على ذلك، فسيكون استخدام حاسوبك عبر هذه الطرفية (التي تُسمَّى سطر الأوامر أيضًا) أمرًا صعبًا، إذ لن تقدّم الطرفية أيّ تلميحات حول ما يُفترض أن تفعله على عكس واجهة المستخدم الرسومية. يمكنك فتح نافذة طرفية على نظام ويندوز من خلال النقر على زر "ابدأ أو Start"، ثم أدخل إلى موجّه الأوامر، واضغط على مفتاح ENTER. انقر على أيقونة Spotlight في الجزء العلوي الأيمن في نظام ماك macOS، واكتب Terminal، ثم اضغط على مفتاح ENTER. يمكنك في نظام أوبنتو لينكس Ubuntu Linux الضغط على مفتاح WIN لإظهار أيقونة Dash، ثم اكتب Terminal، واضغط على مفتاح ENTER، وسيفتح اختصار لوحة المفاتيح Ctrl-Alt-T أيضًا نافذة الطرفية على نظام أوبنتو. تحتوي الصدفة التفاعلية على سطر الأوامر <<<، وتعرض الطرفية أيضًا هذا السطر لإدخال الأوامر. سيكون المسار التالي هو المسار الكامل للمجلد الذي تتواجد فيه حاليًا على نظام ويندوز: C:\Users\Al>your commands go here يعرض سطر الأوامر على نظام ماك macOS اسم حاسوبك ونقطتين ومجلد العمل الحالي (مع تمثيل مجلد المنزل home directory بالرمز ~ اختصارًا) واسم المستخدم الخاص بك متبوعًا بإشارة الدولار الأمريكي ($) كما يلي: Als-MacBook-Pro:~ al$ your commands go here يشبه سطر الأوامر في نظام أوبنتو لينكس سطرَ الأوامر في نظام ماك macOS باستثناء أنه يبدأ باسم المستخدم والإشارة @ كما يلي: al@al-VirtualBox:~$ your commands go here ملاحظة: يمكن تخصيص سطور الأوامر، ولكن لن نوضّح ذلك في هذا المقال. إذا أدخلتَ أمرًا مثل الأمر python على نظام ويندوز أو الأمر python3 على نظامي ماك macOS ولينكس، فستتحقق الطرفية من وجود برنامج يحمل هذا الاسم في المجلد الذي تتواجد فيه حاليًا، وإذا لم تجده هناك، فستتحقق من المجلدات المُدرَجة في متغير البيئة PATH، حيث يمكن عَدّ متغيرات البيئة بأنها متغيرات على مستوى نظام التشغيل بأكمله، إذ تحتوي على عددٍ من إعدادات النظام. يمكنك رؤية القيمة المُخزَّنة في متغير البيئة PATH من خلال تشغيل الأمر echo %PATH%‎ على نظام ويندوز والأمر echo $PATH على نظامي ماك macOS ولينكس. إليك مثال على نظام ماك macOS: Als-MacBook-Pro:~ al$ echo $PATH /Library/Frameworks/Python.framework/Versions/3.9/bin:/usr/local/bin:/usr/ bin:/bin:/usr/sbin:/sbin يوجد ملف البرنامج python3 على نظام ماك macOS في المجلدك ‎/Library/Frameworks/Python.framework/Versions/3.9/bin لذلك لا حاجة لإدخال المسار الآتي: ‎/Library/Frameworks/Python.framework/Versions/3.9/bin/python3 أو يمكنك التبديل إلى هذا المجلد أولًا لتشغيل البرنامج، حيث يمكنك إدخال الأمر python3 من أيّ مجلد، وستجده الطرفية في أحد مجلدات متغير البيئة PATH، إذ تُعَد إضافة مجلد البرنامج إلى متغير البيئة PATH اختصارًا مناسبًا. إذا أردتَ تشغيل برنامج ‎.py، فيجب أن تدخِل الأمر python (أو python3) متبوعًا باسم ملف ‎.py، مما يؤدي إلى تشغيل بايثون التي تشغّل بدورها الشيفرة البرمجية التي تجدها في ملف ‎.py، وستعود إلى موجّه الطرفية بعد انتهاء برنامج بايثون. سيبدو برنامج بسيط يظهِر الرسالة "Hello, world!‎" مثلًا في نظام ويندوز كما يلي: Microsoft Windows [Version 10.0.17134.648] (c) 2018 Microsoft Corporation. All rights reserved. C:\Users\Al>python hello.py Hello, world! C:\Users\Al> يؤدي تشغيل الأمر python (أو python3) بدون أيّ اسم ملف إلى أن تشغّل بايثون الصدفة التفاعلية. تشغيل برامج بايثون على نظام ويندوز توجد عدة طرق أخرى يمكنك من خلالها تشغيل برامج بايثون على نظام ويندوز بدلًا من فتح نافذة الطرفية لتشغيل سكربتات بايثون، حيث يمكنك الضغط على الاختصار WIN-R لفتح مربع حوار التشغيل Run وإدخال الأمر الآتي: py C:\path\to\your\pythonScript.py وكما هو موضح في الشكل التالي، يكون البرنامج py.exe مثبَّتًا على المسار C:\Windows\py.exe الموجود في متغير البيئة PATH، وتُعَد كتابة امتداد الملف ‎.exe أمرًا اختياريًا عند تشغيل البرامج. مربع حوار التشغيل Run في نظام ويندوز الجانب السلبي لهذه الطريقة هو أنه يجب أن تدخِل المسار الكامل للسكربت الخاص بك، وإذا شغّلنا سكربت بايثون من مربع الحوار، فستُفتح نافذة طرفية جديدة لعرض خرج هذا السكربت، وستُغلق هذه النافذة تلقائيًا عند انتهاء البرنامج، وبالتالي قد تفوِّت بعض الخرج. يمكنك حل هذه المشاكل من خلال إنشاء سكربت دفعي Batch Script، والذي هو ملف نصي صغير له امتداد الملف ‎.bat ويمكنه تشغيل أوامر طرفية متعددة، وهو يشبه إلى حد كبير سكربت الصدفة Shell Script في نظامي ماك macOS ولينكس. يمكنك استخدام محرّر نصوص مثل المفكرة Notepad لإنشاء هذه الملفات. ننشئ ملف دفعي من خلال إنشاء ملف نصي جديد يحتوي على سطر واحد كما يلي: @py.exe C:\path\to\your\pythonScript.py %* @pause ضع مسار برنامجك المطلق مكان المسار السابق، واحفظ هذا الملف مع امتداد الملف ‎‎.bat‎ مثل الملف pythonScript.bat. تمنع الإشارة @ الموجودة في بداية كل أمر عرضَه في نافذة الطرفية، ويوجّه الرمز *% أيّ وسطاء مُدخَلة في سطر الأوامر بعد اسم الملف الدفعي إلى سكربت بايثون، ويقرأ برنامج بايثون بدوره وسطاء سطر الأوامر من قائمة sys.argv. سيمنعك هذا الملف الدفعي من الاضطرار إلى كتابة المسار المطلق الكامل لبرنامج بايثون في كل مرة تريد تشغيله فيها، وسيضيف ‎@pause عبارة الضغط على أيّ مفتاح للمتابعة ‎"Press any key to continue..."‎ بعد نهاية سكربت بايثون لمنع اختفاء نافذة البرنامج بسرعة كبيرة. ننصحك بوضع جميع الملفات الدفعية وملفات ‎.py في مجلد واحد موجود فعليًا في متغير البيئة PATH مثل المجلد C:\Users\<USERNAME>‎. لن تحتاج من خلال إعداد ملف دفعي لتشغيل سكربت بايثون إلى فتح نافذة طرفية وكتابة مسار الملف الكامل واسم سكربت بايثون الخاص بك، إذ يمكنك فقط الضغط على الاختصار WIN-R وإدخال pythonScript (اسم الملف pythonScript.bat الكامل ليس ضروريًا)، ثم اضغط على مفتاح ENTER لتشغيل السكربت الخاص بك. تشغيل برامج بايثون على نظام ماك macOS يمكنك إنشاء سكربت صدفة لتشغيل سكربتات بايثون الخاصة بك في نظام ماك macOS من خلال إنشاء ملف نصي له امتداد الملف ‎.command. أنشئ ملفًا جديدًا في محرّر النصوص مثل المحرّر TextEdit وأضِف المحتوى التالي: #!/usr/bin/env bash python3 /path/to/your/pythonScript.py احفظ هذا الملف مع امتداد الملف ‎.command في مجلدك الرئيسي (مثل المجلد ‎/Users/al)، واجعل سكربت الصدفة قابلًا للتنفيذ من خلال تشغيل الأمر chmod u+x yourScript.command في نافذة الطرفية. ستتمكّن الآن من النقر على أيقونة Spotlight (أو الضغط على الاختصار ‎-SPACE) وإدخال yourScript.command لتشغيل سكربت الصدفة، والذي بدوره سيشغّل سكربت بايثون الخاص بك. تشغيل برامج بايثون على نظام أوبنتو لينكس يتطلب تشغيل سكربتات بايثون في أوبنتو لينكس من قائمة Dash إعدادًا إضافيًا. لنفترض أن لدينا السكربت ‎/home/al/example.py، إذ قد يكون سكربت بايثون الخاص بك موجودًا في مجلد مختلف وباسم ملف مختلف، ونريد تشغيله من قائمة Dash. استخدم أولًا محرر نصوص مثل المحرّر gedit لإنشاء ملف جديد مع المحتوى التالي: [Desktop Entry] Name=example.py Exec=gnome-terminal -- /home/al/example.sh Type=Application Categories=GTK;GNOME;Utility; احفظ هذا الملف في المجلد الآتي: ‎/home/<al>/.local/share/applications (مع وضع اسم مستخدمك مكان al) بالاسم example.desktop. إن لم يُظهِر محرّر النصوص مجلد ‎.local لأن المجلدات التي تبدأ بنقطة تُعَد مجلدات مخفية، فيجب أن تحفظه في مجلدك الرئيسي (مثل ‎/home/al‎) وتفتح نافذة طرفية لنقل الملف باستخدام الأمرك mv /home/al/example.desktop /home/al/.local/share/applications. إذا كان الملف example.desktop موجودًا في المجلد الآتي: ‎/home/al/.local/share/applications فستتمكن من الضغط على مفتاح Windows في لوحة المفاتيح لإظهار قائمة Dash وكتابة example.py (أو أي شيء تضعه في الحقل Name)، مما يؤدي إلى فتح نافذة طرفية جديدة أو برنامج gnome-terminal على وجه التحديد الذي يشغّل سكربت الصدفة ‎/home/al/example.sh الذي سننشئه لاحقًا. أنشئ ملفًا جديدًا مع المحتوى التالي في محرّر النصوص: #!/usr/bin/env bash python3 /home/al/example.py bash احفظ هذا الملف في الملف ‎/home/al/example.sh الذي هو سكربت صدفة، والذي هو سكربت يشغّل سلسلةً من أوامر الطرفية، حيث يشغّل سكربت الصدفة سكربت بايثون ‎/home/al/example.py ثم يشغّل برنامج صدفة باش Bash Shell. إن لم نضع أمر باش الموجود في السطر الأخير، فستُغلَق نافذة الطرفية بعد انتهاء سكربت بايثون وستفقد أيّ نصٍ يعرضه استدعاء الدالة print()‎ على الشاشة. يجب أن تضيف أذونات التنفيذ إلى سكربت الصدفة، لذا شغّل الأمر التالي من نافذة الطرفية: al@ubuntu:~$ chmod u+x /home/al/example.sh أعددنا الملفين example.desktop و example.sh، وستتمكّن الآن من تشغيل السكربت example.py من خلال الضغط على مفتاح Windows وإدخال example.py أو أي اسم تضعه في الحقل Name الخاص بالملف example.desktop. تشغيل برامج بايثون مع تعطيل التأكيدات Assertions يمكنك تعطيل تعليمات assert في برامج بايثون الخاصة بك للحصول على تحسين بسيط في الأداء، لذا ضمّن مفتاح ‎-O بعد الأمر python أو python3 وقبل اسم ملف ‎.py‎ عند تشغيل بايثون من الطرفية، مما يؤدي إلى تشغيل نسخة مُحسَّنة من برنامجك تتخطى عمليات التحقق من التأكيد. أين تجد المساعدة يميل المطورون إلى التعلم بالبحث في الإنترنت عن إجابات عن أسئلتهم، وهذه الطريقة مختلفة كثيرًا عمّا اعتاد كثيرون على فعله من حضور دروس لمدرس يلقي محاضرةً ويجيب عن أسئلة الطلاب. ما يميز استخدام الإنترنت للتعلم أنك ستجد مجتمعات كاملة فيها أشخاص يستطيعون الإجابة عن أسئلتك، بل ومن المرجح أن تكون أسئلتك مجاب عنها مسبقًا وتنتظرك الإجابات عنها لتقرأها. إذا واجهت رسالة خطأ أو حدث خطبٌ ما أثناء محاولتك تشغيل شيفرتك، فلن تكون أول شخص يواجه هذه المشكلة، وأؤكد لك أن العثور على حلها أسهل مما تظن بكثير. لنسبب خطأً عمدًا في برنامجنا للتجربة: أدخل ‎'42' + 3 في الصدفة التفاعلية، لا حاجة إلى شرح ما الذي تفعله هذه الشيفرة الآن لأننا سنتعلمها لاحقًا، لكن سيظهر لك الخطأ الآتي: >>> '42' + 3 ➊ Traceback (most recent call last): File "<pyshell#0>", line 1, in <module> '42' + 3 ➋ TypeError: Can't convert 'int' object to str implicitly >>> رسالة الخطأ ➋ تظهر لأن بايثون لا تستطيع فهم التعليمة التي أعطيتها إياها، والجزء الأول ➊ من رسالة الخطأ يبين لنا التعليمة الخطأ ورقم سطرها وما المشكلة التي واجهتها بايثون معها. إذا لم تكن متأكدًا من معنى رسالة الخطأ فابحث عنها في الويب. أدخل "TypeError: Can’t convert ‘int’ object to str implicitly" (بما فيها علامات الاقتباس) في محرك البحث المفضل لديك وستجد عشرات الصفحات التي توضح لك ما هذا الخطأ وما مسبباته كما في الصورة الآتية: الشكل 2: نتائج بحث جوجل حول رسالة خطأ برمجي ستجد أن أحدهم كان له نفس سؤالك وأتى مطور من أولي الخبرة وأجابه. اعلم أنه لا يمكن لشخص واحد أن يعرف كل شيء عن البرمجة، لذا يكون البحث عن إجابات الأسئلة التقنية جزءًا من يومك كمطور برمجيات. طرح أسئلة برمجية ذكية إذا لم تجد إجابةً عن سؤالك في الإنترنت، فيمكنك أن تجرب سؤال الخبراء في أحد المنتديات أو المواقع المخصصة مثل Stack Overflow أو مجتمع Learn Programming في Reddit. لكن أبقِ في ذهنك أن هنالك طرائق ذكية لطرح الأسئلة البرمجة لتساعد الآخرين على مساعدتك. فبدايةً احرص على قراءة قسم الأسئلة الشائعة FAQ في تلك المواقع لتعرف الطريقة الصحيحة لطرح السؤال. حين طرحك لسؤال برمجي فتذكر ما يلي: اشرح ما تحاول فعله، وليس ما فعلته. هذا يسمح لمن يريد مساعدته أن يخبرك إن كنت على الطريق الصحيح لحل المشكلة. حدد النقطة التي يحدث الخطأ عندها، هل تحدث مثلًا حين بدء تشغيل البرنامج كل مرة أم حين وقوع حدث معين؟ وما هو هذا الحدث الذي يحدث ويسبب ظهور الخطأ. انسخ والصق رسالة الخطأ كاملة على مواقع تسمح لك بمشاركة الشيفرات مع الآخرين بسرعة مثل pastebin أو gits.github أو قسم الأسئلة والأجوبة في أكاديمية حسوب، فعبرها تستطيع مشاركة نصوص طويلة دون أن تفقد تنسيق النص، وبعد ذلك ضع رابط URL التابع للشيفرة التي شاركتها في مشاركتك أو سؤالك. اشرح ما حاولت فعله لحل المشكلة، وبهذا تخبر الآخرين أنك بذلت جهدًا لمحاولة حل المشكلة بنفسك. ضع إصدار بايثون الذي تستخدمه (إذ هنالك اختلافات جوهرية بين الإصدار الثاني من مفسر بايثون والإصدار الثالث). اذكر أيضًا نوع نظام تشغيلك وإصداره. إذا حدث الخطأ بعد إجراء تعديل على شيفرتك فاذكر ما هو التعديل الذي أجريته. أرجو منك أيضًا أن تتبع آداب طرح النقاشات في الإنترنت، فاحرص على سلامة السؤال من الأخطاء الإملائية أو اللغوية، وأن تكون لغته واضحة للجميع، وإذا طرحت سؤالك بالإنكليزية فلا تضعه بأحرف كبيرة، ولا تقدم مطالب غير معقولة وغير منطقية ممن يمد إليك يد المساعدة. الخلاصة يرى أغلبية مستخدم الحاسوب أن حاسوبهم هو صندوق سحري بدل رؤيته كأداة يمكنهم استخدامها كيفما يشاؤون؛ وبتعلمك البرمجة ستصل إلى أقوى أدوات المتاحة في عالمنا الحالي وهي القدرة الحاسوبية الهائلة المتوافرة أمامك! وتذكر أن تستمتع بوقتك أثناء البرمجة وتعلمها، فالبرمجة ليست كالجراحة العصبية فلا بأس أن تخطئ وتجرب كما تشاء. نفترض في هذه السلسلة أنك لا تعرف شيئًا عن البرمجة وستتعلم فيه الكثير، لكن إن كانت لديك أسئلة خارج سياقه فتذكر أن تبحث عنها أو أن تطرحها على الخبراء بأسلوب واضح فالبحث عن الإجابات من أهم الأدوات التي عليك احترافها لتعلم البرمجة. ترجمة -وبتصرف- لمقدمة كتاب Automate the boring stuff with Python لصاحبه Al Sweigart. اقرأ أيضًا تعلم لغة بايثون تعرف على أبرز مميزات لغة بايثون تطبيقات لغة بايثون النسخة العربية الكاملة لكتاب البرمجة بلغة بايثون
    1 نقطة
  29. هل أنت مهتم بتعلم البرمجة والتطوير لكنك تتساءل ما هي مدة تعلم البرمجة؟ وكم أحتاج من الوقت لتعلم لغة برمجة معينة، وهل سأستغرق وقتًا طويلًا لتعلمها والعمل بها؟ وفي مقال اليوم نحاول أن نجيبك على كل هذه الأسئلة ونقدم بعض النصائح المفيدة التي تساعدك على التقدم بشكل أسرع. في الواقع قد تختلف الإجابة على هذا السؤال اعتمادًا على عدة عوامل مثل الوقت الذي يمكنك توفيره لدراسة البرمجة يوميًا ومدى استيعابك، وهل تبدأ من الصفر أم لديك بعض المعلومات المسبقة عن البرمجة، وما هو المجال أو التخصص الذي ترغب بتعلمه كم يستغرق تعلم البرمجة دعنا نتفق أنه ليس من السهل تحديد جواب دقيق لهذا السؤال، جرب مثلًا أن تكتب في محرك البحث جوجل "كم يستغرق تعلم البرمجة" ستفاجئ بالحصول على إجابات متفاوتة بشكل كبير على هذا السؤال قد تتراوح من ثلاثة أشهر إلى خمس سنوات! يعزى هذا التفاوت الكبير في الإجابات إلى وجود عوامل عديدة تلعب دورًا في تحديد مدة تعلم البرمجة، بعض هذه العوامل فردية وتختلف من شخص لآخر فهناك أشخاص يتعلمون المفاهيم الجديدة أسرع من غيرهم، وبعضهم لديه متسع من الوقت يمكن تخصيصه يوميًا في دراسة البرمجة أكثر من غيره، وبعضها الآخر عوامل تتعلق بطبيعة لغة البرمجة التي تنوي تعلمها أو التخصص البرمجي التي تود تعلمه وهل ترغب بالتعلم لدخول سوق العمل أم لمجرد اكتساب مهارات شخصية فكل هذه العوامل تؤثر على وتيرة تعلمك وزمن تحقيق أهدافك. سنناقش في الفقرات التالية بعض العوامل المهمة التي تؤثر على مدة تعلم البرمجة ونوضح كم يستغرق تعلم البرمجة بناء على كل حالة من الحالات لنساعدك على تحديد الوقت المطلوب بشكل تقريبي بحسب حالتك. العوامل التي تؤثر على مدة تعلم البرمجة الخبرة المسبقة صعوبة لغة البرمجة المستوى الذي تطمح للوصول إليه التخصص أو المجال البرمجي أسلوب التعلم جودة مصادر التعلم الخبرة المسبقة فإذا كنت تنوي تعلم البرمجة من الصفر ولم يكن لديك أي خلفية تقنية وليس لديك أدنى فكرة عن مبادئ التعامل مع الحاسوب ومفهوم الخوارزميات وأسس التفكير المنطقي وحل المشكلات وعن أي لغة برمجة سابقة فسيستغرق تعلم البرمجة وقتًا طويلاً منك نظرًا لوجود مجموعة واسعة من المفاهيم التي عليك تعلمها وقد يستغرق الأمر عدة أشهر حتى تتمكن من كتابة استيعاب أساسيات البرمجة وفهم مفردات لغة البرمجة التي تستخدمها وكتابة برنامج الأول بها بنفسك وتنفيذه بشكل صحيح. من الضروري أن لا تشعر بالإحباط في بدايات تعلم البرمجة وتأسيس نفسك بها فالبدايات دومًا هي الأصعب فإذا تخطيت هذه المرحلة فستتمكن من التقدم بتعلم البرمجة بوتيرة أسرع وسيسهل عليك الانتقال لتعلم أي لغة برمجة أخرى. صعوبة لغة البرمجة أحد العوامل المهمة في زمن تعلم البرمجة هو اللغة التي تختارها فهناك العديد من لغات البرمجة المختلفة مثل لغة بايثون Python. وجافا Java و C++ و PHP وغيرها الكثير وبعض هذه اللغات سهل التعلم وبعضها الآخر أكثر صعوبة ويستغرق مدة تعلم أطول فتعلم لغة برمجة سهلة نسبيًا يستغرق حوالي أربعة إلى ستة أشهر وستحتاج لوقت أكبر إذا كنت تتعلم لغة برمجة صعبة. لذا عندما تقرر تعلم البرمجة فمن الأفضل أن تبحث عن لغة لها منحنى تعلم "Learning Curve" سهل وغير حاد أو معقد، ومنحنى التعلم هو طريقة بيانية للتعبير عن صعوبة تعلم الشخص لموضوع خلال فترة زمنية معينة ويعبر عن سرعة التقدم والخبرات المكتسبة في هذا الموضوع مع مرور الوقت. على سبيل المثال تملك لغة بايثون Python منحنى تعليمي أسهل من لغة جافا Java بسبب تعتبر لغة تركيبتها التي تشبه إلى حد كبير اللغة الإنجليزية وقواعدها السهلة، لهذا السبب فإن مدة تعلم لغة البايثون ستكون أقصر من مدة تعلم لغة جافا وتقدر المدة الوسطية لتعلم أساسيات بايثون بخمس إلى عشر أسابيع في حين تصل مدة تعلم جافا من ستة أشهر إلى 18 شهرًا، ويمكنك مطالعة المزيد من المعلومات حول لغات البرمجة التي يفضل أن تبدأ بها تعلم البرمجة من خلال مقال أسهل لغات البرمجة. المستوى الذي تطمح للوصول إليه إذا كنت تقصد عند سؤالك ما المدة التي أحتاجها لتعلم البرمجة أن تتعلم أساسيات البرمجة وتتعرف على طريقة أسلوب كتابة الشيفرات والتعليمات وتعريف المتغيرات وأنواع البيانات، والحلقات والشروط والدوال البرمجية …إلخ. لمجرد اكتساب مهارة تنمي تفكيرك المنطقي والتحليلي وتوسع مداركك وتمكنك من كتابة برامج حاسوبية لحل مشكلات بسيطة أو أتمتة مهامك اليومية المتكررة فهذا الأمر لن يتطلب منك سوى ثلاثة إلى ستة أشهر فقط لتعلم البرمجة بأي لغة كانت. لكن هذه المدة لن تكون كافية لك لاحتراف البرمجة ودخول سوق العمل فهذا الأمر قد يتطلب منك حوالي سنة أو أكثر للعمل على بناء برامج معقدة وتطبيقات احترافية متكاملة تتعامل مع مشكلات فعلية وتنبي من خلالها معرض أعمال جيد يعزز فرصتك في الحصول على عمل مناسب وإذا كنت تحتاج علم لغة برمجة سهلة نسبيًا يستغرق حوالي أربعة إلى ستة أشهر. التخصص أو المجال البرمجي إن مجالات البرمجة كثيرة ومتنوعة مثل تطوير الويب وبرمجة المواقع وبرمجة الألعاب والذكاء الاصطناعي وعلوم البيانات والأمن السيبراني وغيرها الكثير وبتطلب كل تخصص برمجي مجموعة مهارات مختلفة عن الآخر فكلما زادت المهارات المطلوبة وزاد تعقيدها، كلما زاد الوقت الذي تحتاجه لتعلمها. على سبيل المثال، تبلغ مدة تعلم برمجة المواقع حوالي ستة أشهر إلى عام واحد، في حين يحتاج تعلم أساسيات الذكاء الاصطناعي مدة أطول قد تصل لسنة أو أكثر لأنه مجال أكثر تعقيدًا ويتطلب وجود أساس جيد في الرياضيات والإحصاء ويحتج بعض الوقت للتآلف مع مصطلحاته والتعرف على تخصصاته المختلفة وتعلم خوارزميات التعلم الآلي ولغات برمجة الذكاء الاصطناعي كما يحتاج للكثير من الممارسة لإتقانه. أسلوب تعلم البرمجة تختلف مدة تعلم البرمجة أيضًا بحسب الطريقة التي تختارها للتعلم، فإذا اخترت دارسة البرمجة عن طريق التعليم الأكاديمي والتسجيل في إحدى الجامعات فستستغرق وقتًا طويلًا لا يقل عن أربع أو خمس سنوات لأنك ستضطر على الالتزام بمنهج محدد. أما إذا اخترت التعلم الذاتي فستتمكن من توفير الكثير من الوقت وتقتصر اعلى لغات البرمجة والتقنيات التي تحتاج لتعلمها وبقدر ما تثابر وتبذل من جهد وتلتزم بخطة تعلم منظمة وساعات تعلم محددة يوميًا فستختصر من زمن تعلم البرمجة وتتمكن من دخول سوق العمل بسرعة أكبر. جودة مصادر التعلم إذا قررت تعلم البرمجة فستجد الكثير من مصادر التعلم المتنوعة من دروس ومقالات وكتب ومقاطع فيديو ودورات تدريبية وغيرها من المصادر التي تساعدك لكن هذه المصادر ليست على نفس المستوى من الجودة وقد يصعب عليك كمبتدئ تمييز الغث من السمين وتحديد الترتيب الصحيح لمواضيع التعلم والتركيز على تعلم ما يهمك. كما أن تعلمك من مصادر مشتتة وبطريقة عبثية فتارة تشاهد مقطع فيديو عن موضوع ما وتارة تقرأ مقالة عن موضوع آخر وتارة تبدأ بقراءة كتاب ثم تمل منه سريعًا سيزيد بلا شك من مدة تعلم البرمجة وتحقيق هدفك وتذكر أن المشتت لا يصل. فإذا كنت تتعلم البرمجة دون خطة منهجية واضحة وتريد اختصار وقت تعلم البرمجة فمن الأفضل أن تستثمر وقتك وجهدك وتسجل في دورة تدريبية المنهجية التي تقدم لك المعرفة التي تحتاجها بالتسلسل الصحيح وتوضح لك الأدوات والتقنيات التي تحتاجها وتقيم مهاراتك بشكل معياري وتساعدك على تنفيذ تطبيقات عملية تعزز ما تعلمته وتزيد فرصتك في الحصول على وظائف برمجة مناسبة لمهاراتك. ستجد في أكاديمية حسوب الكثير من الدورات التعليمية عالية الجودة بمختلف التخصصات توفر لك إمكانية التعلم من الصفر دون الحاجة لأي معرفة مسبقة وتساعدك على التعلم بطريقة منظمة وتقرن التعليم النظري بالتطبيق العملي والأهم أنها توفر لك مدربين خبراء يرشدونك ويدعمونك طوال رحلتك التعليمية ويساعدونك في الإجابة على أي تساؤل وحل أي مشكلة تواجهك ويسعدون بتقديم المشورة التي تحتاجها حتى تحترف البرمجة وتجد فرصة العمل المناسبة. هل فات الوقت على تعلّم البرمجة كثيرًا ما نسمع أسئلة من قبيل أنا مهتم بالبرمجة والتقنية وأرغب في تعلمها لأعمل في وظيفة أفضل وذات مردود مادي أعلى أو أرغب بتعلم البرمجة لمواكبة التطور التقني وتعزيز مهارات حل المشكلات لدي ولكن عمري (كذا سنة) فهل فات الوقت على تعلم البرمجة؟ دعني أخبرك بأنه مهما كان عمرك فإن الأوان لم يفت على تعلم البرمجة فالعمر لا يشكل أي عائق في التعلم سواء في ظل وفرة الموارد المتاحة لمساعدتك. وقد يستغرق تعلم البرمجة مدة أطول مع التقدم في السن لكنك قادر على تقليل هذه المدة في حال خصصت وقتًا أطول وأسست نفسك بشكل جيد بالاعتماد على مصادر عالية الجودة وامتلكت الإرادة والرغبة الحقيقية للتعلم فهذا كفيل بجعلك تتغلب على أي صعوبات أو عوائق تواجهها. نصائح لتقليل مدة تعلم البرمجة حدد هدفك من تعلم البرمجة والتخصص البرمجي المناسب لك، وضع خطة لتعلم التقنيات واللغات التي تفيدك في هذا التخصص. عزز مهارة حل المشكلات والتفكير المنطقي قبل البدء بالبرمجة فهي مهارات أساسية تقلل مدة تعلم البرمجة. ركز على تعلم لغة برمجة سهلة وتناسب المبتدئين فهذا يسهل عليك استيعاب المفاهيم البرمجية بوقت أقل ويسهل عليك الانتقال لتعلم أي لغة برمجة أخرى. لا تستسلم بسرعة، فتعلم أي شيء جديد سيكون صعبًا في البداية ويستغرق بعض الوقت لفهم الأساسيات ومع الوقت والخبرة تصبح الأمور أسهل. اعتمد على مصدر جيد لتعلم البرمجة ولا تشتت نفسك بكثرة المصادر. احرص على التطبيق العملي لما تتعلمه من مفاهيم فهذا يعزز مهاراتك ويساعدك على بناء معرض أعمال يثبت خبرتك. تعلم مع أصدقاء لديهم نفس اهتمامك وضع معهم هدفًا مشترك وخطة للتعلم وتعاون معهم في حل المشكلات وتعلم المفاهيم الجديدة فهذا يجعل التعلم أكثر متعة ويحفزك على المواصلة. الخلاصة نأمل أن يكون هذا المقال قد ساعدك في تحديد كم يستغرق تعلم البرمجة ومعرفة أهم العوامل التي تلعب دورًا في الإجابة على هذا السؤال بشكل تقريبي، وكما وضحنا في المقال لا يوجد جواب واحد يناسب الجميع على هذا السؤال لكن بإمكانك اختصار مدة تعلم البرمجة ودخول سوق العمل بسرعة بالمثابرة والجهد. وتذكر في الختام أن البرمجة تحتاج منك إلى الاستمرار في التعلم وتطوير نفسك حتى بعد الاحتراف ودخول سوق العمل، فالتقنيات تتغير وتتطور باستمرار ومن الضروري مواكبة هذه التغييرات وتطبيقها في عملك للحفاظ على مكانتك التنافسية وتلبية متطلبات سوق العمل المتجددة. اقرأ أيضًا دليل شامل لتعلم البرمجة قواعد البرمجة ببساطة للمبتدئين اكتشف ما هي البرمجة وما أهمية تعلمها برمجة الحاسوب للمبتدئين لماذا يجب أن تعلم طفلك البرمجة؟
    1 نقطة
  30. بدأنا في مقال الجزء الأول ببناء مشروع عملي بلغة رست وهو عبارة عن خادم ويب متعدد مهام المعالجة، إذ بنينا الخادم الأساسي وكان أحادي خيط المعالجة، وعملنا في مقال الجزء الثاني على تحويله إلى خادم متعدد خيوط المعالجة، وسننهي في هذا المقال بناء الخادم ليصبح جاهزًا، فإذا لم تكن قرأت المقالات السابقة، فارجع لها قبل قراءة هذا المقال. الإغلاق الرشيق وتحرير الذاكرة تستجيب الشيفرة 20 للطلبات بصورةٍ غير متزامنة عبر استخدام مجمع خيط كما نريد، إذ نحصل على بعض التحذيرات من حقول workers و id و thread التي لن نستخدمها مباشرةً وتذكرنا أننا لم نحرر أي شيء من الذاكرة. عندما نستخدم الحل البدائي الذي هو استخدام مفتاحي "ctrl-c" لإيقاف الخيط الرئيسي، تتوقف الخيوط مباشرةً حتى لو كانوا يخدّمون طلبًا. سننفّذ سمة Drop لاستدعاء join على كل خيط في المجمع لكي ننهي الطلبات التي تعمل قبل الإغلاق، ثم سننفّذ طريقةً لإخبار الخيوط ألا تقبل طلبات جديدة قبل الإغلاق. لرؤية عمل هذا الكود سنعدّل الخادم ليقبل طلبين فقط قبل أن يغلق مجمع الخيط thread pool. تنفيذ سمة Drop على مجمع خيط لنبدأ بتنفيذ Drop على مجمع الخيط الخاص بنا. عندما يُسقط المجمع يجب أن تجتمع كل الخيوط للتأكد من أن عملهم قد انتهى. تظهر الشيفرة 22 المحاولة الأولى لتطبيق Drop، إذ لن تعمل الشيفرة حاليًا. اسم الملف: src/lib.rs impl Drop for ThreadPool { fn drop(&mut self) { for worker in &mut self.workers { println!("Shutting down worker {}", worker.id); worker.thread.join().unwrap(); } } } [الشيفرة 22: ضم كل خيط عندما يخرج المجمع خارج النطاق] أولًا، نمرّ على كل workers في مجمع الخيط، واستُخدمت ‎&mut هنا لأن self هو مرجع متغيّر، ونريد أيضًا تغيير worker. نطبع لكل عامل رسالةً تقول أن هذا العامل سيُغلق، ثم نستدعي join على خيط العمال. إذا فشل استدعاء join نستخدم unwrap لجعل رست تهلع وتذهب إلى إغلاق غير رشيق. سنحصل على هذا الخطأ عند تصريف هذه الشيفرة: $ cargo check Checking hello v0.1.0 (file:///projects/hello) error[E0507]: cannot move out of `worker.thread` which is behind a mutable reference --> src/lib.rs:52:13 | 52 | worker.thread.join().unwrap(); | ^^^^^^^^^^^^^ ------ `worker.thread` moved due to this method call | | | move occurs because `worker.thread` has type `JoinHandle<()>`, which does not implement the `Copy` trait | note: this function takes ownership of the receiver `self`, which moves `worker.thread` --> /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/thread/mod.rs:1581:17 For more information about this error, try `rustc --explain E0507`. error: could not compile `hello` due to previous error يوضّح الخطأ أننا لا يمكن أن نستدعي join لأنه لدينا استعارة متغيرة على كل worker وتأخذ join ملكية وسطائها، ولمعالجة هذه المشكلة نحن بحاجة لنقل الخيط خارج نسخة Worker التي تملك thread حتى تستطيع join استهلاك الخيط، وقد فعلنا ذلك في الشيفرة 15 من المقال تنفيذ نمط تصميمي Design Pattern كائني التوجه Object-Oriented في لغة رست. إذا احتفظ Worker بـ Option<thread::JoinHandle<()>>‎، يمكننا استدعاء تابع take على Option لنقل القيمة خارج المتغاير Some وإبقاء المتغاير None في مكانه، بمعنى آخر سيحتوي Worker عامل على متغاير Some في Thread الخاص به وعندما نريد تحرير ذاكرة Worker نستبدل Some بالقيمة None حتى لا يوجد لدى Worker أي خيط لينفذه. لذا نحن نعرف أننا نريد تحديث تعريف Worker على النحو التالي. اسم الملف: src/lib.rs struct Worker { id: usize, thread: Option<thread::JoinHandle<()>>, } الآن لنتابع المصرّف لنجد أية أماكن أُخرى تحتاج تغيير، وبالتحقق من الشيفرة نجد خطأين: $ cargo check Checking hello v0.1.0 (file:///projects/hello) error[E0599]: no method named `join` found for enum `Option` in the current scope --> src/lib.rs:52:27 | 52 | worker.thread.join().unwrap(); | ^^^^ method not found in `Option<JoinHandle<()>>` | note: the method `join` exists on the type `JoinHandle<()>` --> /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/thread/mod.rs:1581:5 help: consider using `Option::expect` to unwrap the `JoinHandle<()>` value, panicking if the value is an `Option::None` | 52 | worker.thread.expect("REASON").join().unwrap(); | +++++++++++++++++ error[E0308]: mismatched types --> src/lib.rs:72:22 | 72 | Worker { id, thread } | ^^^^^^ expected enum `Option`, found struct `JoinHandle` | = note: expected enum `Option<JoinHandle<()>>` found struct `JoinHandle<_>` help: try wrapping the expression in `Some` | 72 | Worker { id, thread: Some(thread) } | +++++++++++++ + Some errors have detailed explanations: E0308, E0599. For more information about an error, try `rustc --explain E0308`. error: could not compile `hello` due to 2 previous errors لنعالج الخطأ الثاني الذي يشير إلى الشيفرة في نهاية Worker::new، إذ نريد تغليف قيمة thread في Some عندما ننشئ Worker جديد. أجرِ الخطوات التالية لتصحيح هذا الخطأ: اسم الملف: src/lib.rs impl Worker { fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Job>>>) -> Worker { // --snip-- Worker { id, thread: Some(thread), } } } الخطأ الأول هو في تنفيذ Drop، وذكرنا سابقًا أننا أردنا استدعاء take على قيمة Option لنقل thread خارج worker. أجرِ التغييرات التالية لتصحيح هذا الخطأ: اسم الملف: src/lib.rs impl Drop for ThreadPool { fn drop(&mut self) { for worker in &mut self.workers { println!("Shutting down worker {}", worker.id); if let Some(thread) = worker.thread.take() { thread.join().unwrap(); } } } } كما تحدثنا سابقًا في المقال البرمجة كائنية التوجه OOP في لغة رست، يأخذ التابع take على Option المتغاير Some خارجًا ويبقي None بدلًا عنه. استخدمنا if let لتفكيك Some والحصول على الخيط، ثم استدعينا join على الخيط. إذا كان خيط العامل هو أساسًا None نعرف أن العامل قد حرًر ذاكرته ولا يحصل شيء في هذه الحالة. الإشارة للخيط ليتوقف عن الاستماع إلى الوظائف تُصرّف الشيفرة بدون تحذيرات بعد كل التغييرات التي أجريناها، ولكن الخبر السيء أنها لا تعمل كما أردنا. النقطة المهمة هي في منطق المغلفات المنفذة بواسطة خيوط نسخ Worker، إذ نستدعي حتى اللحظة join لكن لا تُغلق الخيوط لأننها تعمل في loop للأبد بحثًا عن وظائف. إذا أسقطنا Threadpool بتنفيذنا الحالي للسمة drop، سيُمنع الخيط الأساسي للأبد بانتظار الخيط الأول حتى ينتهي، ولحل هذه المشكلة نحتاج لتغيير تنفيذ drop في ThreadPool، ثم إجراء تغيير في حلقة Worker. أولًا، سنغير تنفيذ drop في ThreadPool ليسقِط صراحةً sender قبل انتظار الخيوط لتنتهي. تظهر الشيفرة 23 التغييرات في ThreadPool لتسقط صراحةً sender. استخدمنا نفس تقنياتOption و take كما فعلنا مع الخيط لكي يستطيع نقل sender خارج ThreadPool. اسم الملف: src/lib.rs: pub struct ThreadPool { workers: Vec<Worker>, sender: Option<mpsc::Sender<Job>>, } // --snip-- impl ThreadPool { pub fn new(size: usize) -> ThreadPool { // --snip-- ThreadPool { workers, sender: Some(sender), } } pub fn execute<F>(&self, f: F) where F: FnOnce() + Send + 'static, { let job = Box::new(f); self.sender.as_ref().unwrap().send(job).unwrap(); } } impl Drop for ThreadPool { fn drop(&mut self) { drop(self.sender.take()); for worker in &mut self.workers { println!("Shutting down worker {}", worker.id); if let Some(thread) = worker.thread.take() { thread.join().unwrap(); } } } } [الشيفرة 23: إسقاط sender صراحةً قبل جمع الخيوط الفعالة] يغلق إسقاط sender القناة، وهذا يشير بدوره إلى عدم إرسال أي رسائل إضافية، وعندما نفعل ذلك تعيد كل الاستدعاءات إلى recv التي تجريها الخيوط الفعالة في الحلقة اللانهائية خطأً. نغير حلقة Worker في الشيفرة 24 لتخرج من الحلقة برشاقة في تلك الحالة، يعني أن الخيوط ستنتهي عندما يستدعي join عليهم في تنفيذ drop في ThreadPool. اسم الملف: src/lib.rs impl Worker { fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Job>>>) -> Worker { let thread = thread::spawn(move || loop { let message = receiver.lock().unwrap().recv(); match message { Ok(job) => { println!("Worker {id} got a job; executing."); job(); } Err(_) => { println!("Worker {id} disconnected; shutting down."); break; } } }); Worker { id, thread: Some(thread), } } } [الشيفرة 24: الخروج صراحةً من الحلقة عندما تعيد recv خطأ] لرؤية عمل هذه الشيفرة: سنعدل main لتقبل فقط طلبين قبل أن تُغلق الخادم برشاقة كما تظهر الشيفرة 25. اسم الملف: src/main.rs fn main() { let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); let pool = ThreadPool::new(4); for stream in listener.incoming().take(2) { let stream = stream.unwrap(); pool.execute(|| { handle_connection(stream); }); } println!("Shutting down."); } [الشيفرة 25: إغلاق الخادم بعد خدمة طلبين عن طريق الخروج من الحلقة] لا نريد أن يتوقف خادم حقيقي بعد خدمة طلبين فقط، وتبين هذه الشيفرة أن الإغلاق الرشيق وتحرير الذاكرة يعملان بصورةٍ نظامية. تُعرّف دالة take في سمة Iterator وتحدد التكرار إلى أول عنصرين بالحد الأقصى. سيخرج ThreadPool خارج النطاق في نهاية main وستُطبَّق سمة drop. شغّل الخادم باستخدام cargo run وأرسل ثلاثة طلبات. سيعطي الطلب الثالث خطأ وسترى الخرج في الطرفية على النحو التالي: $ cargo run Compiling hello v0.1.0 (file:///projects/hello) Finished dev [unoptimized + debuginfo] target(s) in 1.0s Running `target/debug/hello` Worker 0 got a job; executing. Shutting down. Shutting down worker 0 Worker 3 got a job; executing. Worker 1 disconnected; shutting down. Worker 2 disconnected; shutting down. Worker 3 disconnected; shutting down. Worker 0 disconnected; shutting down. Shutting down worker 1 Shutting down worker 2 Shutting down worker 3 يمكن أن ترى ترتيبًا مختلفًا للخيوط الفعالة والرسائل المطبوعة. تعمل الشيفرة وفقًا لهذه الرسائل كما يلي: أخذ العاملان 0 و 3 الطلبين الأولين وتوقف الخادم عن قبول الاتصالات بعد ثاني اتصال، وبدأ تنفيذ Drop في العمل على ThreadPool قبل أخذ العامل 3 وظيفته. يفصل إسقاط sender كل العمال ويخبرهم أن يُغلقوا، ويطبع كل عامل رسالةً عندما يُغلقوا ويستدعي مجمع الخيط join لانتظار كل خيط عامل لينتهي. لاحظ ميّزة مهمة في هذا التنفيذ، إذ قام ThreadPool بإسقاط sender وجرّبنا ضم العامل 0 قبل أن يستقبل أي عامل خطأ. لم يتلق العامل 0 أي خطأ من recv بعد، لذا تنتظر كتلة الخيط الأساسية أن ينتهي العامل 0. في تلك الأثناء استقبل العامل 3 وظيفة ثم استقبلت كل الخيوط خطأ. ينتظر الخيط الأساسي باقي العمال لينتهوا عندما ينتهي العامل 0. وبحلول هذه النقطة يخرج كل عامل من حلقته ويتوقف. تهانينا، فقد أنهينا المشروع ولدينا الآن خادم ويب بسيط يستخدم مجمع خيط للاستجابة بصورةٍ غير متزامنة، ونستطيع إجراء إغلاق رشيق للخادم الذي يحرر من الذاكرة كل الخيوط في المجمع. هذه هي الشيفرة الكاملة بمثابة مرجع. اسم الملف: src/main.rs use hello::ThreadPool; use std::fs; use std::io::prelude::*; use std::net::TcpListener; use std::net::TcpStream; use std::thread; use std::time::Duration; fn main() { let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); let pool = ThreadPool::new(4); for stream in listener.incoming().take(2) { let stream = stream.unwrap(); pool.execute(|| { handle_connection(stream); }); } println!("Shutting down."); } fn handle_connection(mut stream: TcpStream) { let mut buffer = [0; 1024]; stream.read(&mut buffer).unwrap(); let get = b"GET / HTTP/1.1\r\n"; let sleep = b"GET /sleep HTTP/1.1\r\n"; let (status_line, filename) = if buffer.starts_with(get) { ("HTTP/1.1 200 OK", "hello.html") } else if buffer.starts_with(sleep) { thread::sleep(Duration::from_secs(5)); ("HTTP/1.1 200 OK", "hello.html") } else { ("HTTP/1.1 404 NOT FOUND", "404.html") }; let contents = fs::read_to_string(filename).unwrap(); let response = format!( "{}\r\nContent-Length: {}\r\n\r\n{}", status_line, contents.len(), contents ); stream.write_all(response.as_bytes()).unwrap(); stream.flush().unwrap(); } اسم الملف: src/lib.rs use std::{ sync::{mpsc, Arc, Mutex}, thread, }; pub struct ThreadPool { workers: Vec<Worker>, sender: Option<mpsc::Sender<Job>>, } type Job = Box<dyn FnOnce() + Send + 'static>; impl ThreadPool { /// Create a new ThreadPool. /// /// The size is the number of threads in the pool. /// /// # Panics /// /// The `new` function will panic if the size is zero. pub fn new(size: usize) -> ThreadPool { assert!(size > 0); let (sender, receiver) = mpsc::channel(); let receiver = Arc::new(Mutex::new(receiver)); let mut workers = Vec::with_capacity(size); for id in 0..size { workers.push(Worker::new(id, Arc::clone(&receiver))); } ThreadPool { workers, sender: Some(sender), } } pub fn execute<F>(&self, f: F) where F: FnOnce() + Send + 'static, { let job = Box::new(f); self.sender.as_ref().unwrap().send(job).unwrap(); } } impl Drop for ThreadPool { fn drop(&mut self) { drop(self.sender.take()); for worker in &mut self.workers { println!("Shutting down worker {}", worker.id); if let Some(thread) = worker.thread.take() { thread.join().unwrap(); } } } } struct Worker { id: usize, thread: Option<thread::JoinHandle<()>>, } impl Worker { fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Job>>>) -> Worker { let thread = thread::spawn(move || loop { let message = receiver.lock().unwrap().recv(); match message { Ok(job) => { println!("Worker {id} got a job; executing."); job(); } Err(_) => { println!("Worker {id} disconnected; shutting down."); break; } } }); Worker { id, thread: Some(thread), } } } يمكننا إجراء المزيد إذا أردنا تحسين المشروع، وإليك بعض الأفكار: أضِف المزيد من التوثيق إلى ThreadPool وتوابعه العامة. أضِف بعض الاختبارات لوظيفة المكتبة. غيّر الاستدعاءات من unwrap إلى معالجة خطأ أكثر متانة. استخدم ThreadPool لتنفيذ أعمال غير خدمة طلبات الويب. ابحث عن وحدة مجمع خيط مصرفة على creats.io ونفذ خادم ويب باستخدام الوحدة المصرفة، ثم قارن واجهة برمجة التطبيقات API والمتانة بينها وبين مجمع الخيط الذي نفذناه. خاتمة عظيم جدًا! فقد وصلنا إلى نهاية سلسلة البرمجة بلغة رست . نريد أن نشكرك لانضمامك إلينا في هذه الجولة في رست. أنت الآن جاهز لتنفيذ مشاريع رست ومساعدة الآخرين في مشاريعهم. تذكر أنه هناك مجتمع مرحب من مستخدمي رست الذين يحبون المساعدة في أي صعوبة يمكن أن تواجهها في استعمالك رست. ترجمة -وبتصرف- لقسم من الفصل Final Project: Building a Multithreaded Web Server من كتاب The Rust Programming Language. اقرأ أيضًا المقال السابق: بناء خادم ويب متعدد مهام المعالجة بلغة رست - الجزء الثاني تزامن الحالة المشتركة Shared-State Concurrency في لغة رست وتوسيع التزامن مع Send و Sync مقدمة إلى الخيوط Threads في جافا
    1 نقطة
  31. يتوجه العالم بخطى حثيثة نحو حقبة ما بعد الثورة الرقمية، فقد غيرت هذه الثورة طريقة رؤيتنا للواقع والمستقبل ودفعتنا إلى حدود جديدة في شتى المجالات العلمية والاقتصادية والاجتماعية. لهذا تسعى الفعاليات البشرية بكافة أشكالها إلى التماشي مع هذه الثورة والاستفادة مما تتيحه من تقنيات لتطوير قدراتها الذاتية ومكاسبها في نفس الوقت. لقد أضحت عملية التحول الرقمي والتطوير المستمر لوسائل العمل والاتصال ميزة هذه الحقبة وأساسها، وغدت صناعة البرمجيات وتطوير الأنظمة المعلوماتية المحرك الأساسي لهذه المرحلة جنبًا إلى جنب مع تطور البنية التحتية لتقديم الخدمات الرقمية بالشكل الأكفأ والأسرع. ولهذا السبب أخذت هذه الصناعة بالنضوج اعتمادًا على مفاهيم ومسارات واستراتيجيات مدروسة وواضحة في التخطيط لها وتحليل متطلباتها ثم تصميمها وتنفيذها ضمن حلقة متكاملة من المراحل المتلاحقة لتلبي الغرض من بنائها وإنشائها. ونظرًا لاعتماد الأعمال بكل أشكالها على صناعة البرمجيات وتطوير الأنظمة الرقمية فلن يكون أمام هذه الصناعة هامش للخطأ مهما صَغُر لأن التكلفة على الصعيدين المادي والزمني ستكون باهظة جدًا. تحدثنا في مقال "مدخل إلى تطوير البرمجيات" عن المجال وعملية تطوير البرمجيات عمومًا، وأما الهدف من هذا المقال هو الوقوف على دورة الحياة التي يجب أن تسلكها عملية تطوير البرمجيات حتى يكون المنتج النهائي فعالًا ومحققًا للغاية التي صُمم لأجلها بأدنى هامش للخطأ انطلاقًا من الفكرة وحتى التنفيذ والصيانة. كما سيبحث في أهم الاستراتيجيات المتبعة في إدارة دورة حياة تطوير البرمجيات Software Development Life Cycle واختصارًا SDLC. كما يساعدك هذا المقال في تنمية معارفك ومهاراتك في تحليل الأنظمة إن كنت تفكر فيها كمهنة مستقبلية. من أين تأتي الأفكار؟ فما يخلق البرمجيات هو الحاجة لها، وتظهر الحاجة إلى بناء نظام معلوماتي جديد لإدارة نشاط معين عندما يبدأ هذا النشاط أو العمل بالمعاناة جراء أسباب متنوعة منها: انخفاض الحصة السوقية لمنتجاته. ضعف في الخدمات التي يقدمها لعملائه. ظهور منافسين جدد يستغلون تقنيات أحدث في إدارة أعمالهم. مشاكل في المنظومة القائمة وانخفاض كفاءتها. وقد تكون الحاجة إلى المنظومة الجديدة رؤية مستقبلية لواقع العمل والرغبة في تحسين واقعه: الرغبة في الوصول إلى عملاء جدد أو أسواق جديدة. مواكبة أكثر التقنيات انتشارًا وأحدثها كالحوسبة السحابية ومنصات البيانات الضخمة أو الانتقال إلى تطبيقات الهواتف الذكية. تقديم ابتكارات واختراقات ثورية تبقي الشركات التقنية في حيز المنافسة والهيمنة على الصناعة. لا يمكن لأي كان أن يتخذ قرار تطوير برمجيات المنظومة المعلوماتية القائمة as-is system أو استبدالها بمنظومة جديدة to-be system في الجهة التي تحتاج إلى ذلك، بل يأتي هذا القرار عادة عن أشخاص تقنيين أو غير تقنيين على تماس مباشر مع المنظومة ومع أصحاب القرار. يُدعى هؤلاء بالمعنيين أو أصحاب المصلحة stakeholders في بناء أو تطوير المنظومة وقد يكون هؤلاء: مالكو أنظمة مشرفون على تشغيل أنظمة مبرمجون مصممو ومحللو أنظمة مستشارون أو مزودون للخدمات المعلوماتية يمتلك هؤلاء الخبرة والدراية التي تؤهلهم لمعرفة الإيجابيات والسلبيات في المنظومات القائمة واستشعار الفرص الجديدة التي قد يأتي بها التغيير. دورة إدارة تطوير المنتجات احترف إدارة تطوير المنتجات الرقمية بدءًا من التخطيط وتحليل السوق وحتى إطلاق منتج مميز وناجح اشترك الآن هل نبدأ بكتابة الشيفرة مباشرة؟! عندما نتحدث عن تطوير منظومة برمجية لا نتحدث عن تطبيق بسيط لعرض منتجات أو لإجراء اتصال مع قاعدة بيانات بسيطة، بل منظومة متكاملة تضم عددًا كبيرًا من الحزم البرمجية التي تنفذ مهام مختلفة وتتكامل مع بعضها لتلبي المتطلبات المتوقعة من هذه المنظومة. وفي هذا السياق، لا يمكن بأي شكل من الأشكال أن تعتبر عملية بناء المنظومات البرمجية عملية بديهية سهلة التنفيذ. يتطلب بناء المنظومات المركبة عملًا هائلًا وتخطيطًا دقيقًا للمتطلبات التي ينبغي لهذه المنظومة تنفيذها في المراحل المبكرة قبل اتخاذ القرار النهائي بالمضي في العمل. فهناك قاعدة ذهبية لا بد من إدراكها تنص على أنّ التكلفة ستزداد بشكل أسي مع كل تغيير في متطلبات منظومة برمجية أثناء التنفيذ. والأسوأ من ذلك كله تسليم منظومة غير مكتملة إلى العميل. لم تأتي هذه القاعدة من فراغ، بل من الإخفاقات التي عانتها الكثير من الشركات العالمية، وإليك بعض الأمثلة من الواقع: الشركة العام المنظومة البرمجية الخسارة بالدولار فورد موتورز الأمريكية 2004 شراء منظومة جرى التخلي عنها بعد نشرها مباشرة 400 m$ هيوليت باكارد الأمريكية 2004 منظومة برمجية لتخطيط الموارد كثُرت فيها الأخطاء m160‏$ HRM Inland البريطانية 2004 أخطاء برمجية في المنظومة قادت إلى تحميل ضرائب إضافية 3.45 m$ Sainsburys البريطانية 2004 منظومة لإدارة سلسلة المزودين فشلت بعد النشر مباشرة 527 m$ وزارة الصحة البريطانية 2006 منظومة متكاملة لإدارة الصحة الوطنية وتسجيل المرضى لم تنجح بعد 4 سنوات من التأخير ولم ينجز أكثر من 80% منها. 20 b$ وزارة العدل البريطانية 2007 التخلي عن منظومة لتسجيل ومراقبة المدانين 245 m$ وكالة الحدود البريطانية 2009 تأخير في تسليم منظومة إدارة الحدود الإلكترونية حتى 2015 1.7 b$ BBC البريطانية 2014 فشل مشروع رقمنة أرشيف الإذاعة نظرًا للتخبط وضعف التخطيط. 153 m$ فالبدء إذًا في كتابة الشيفرة بمجرد أن تستشف فكرة المشروع سيقودك إلى الفشل لا محالة. لهذا لا بدّ من أن يمر مشروعك ضمن سلسلة من المراحل التي ينضج فيها وتتخذ القرارات التحليلية والتصميمة الصحيحة. دورة حياة البرمجيات تمر البرمجيات والأنظمة المعلوماتية عمومًا أثناء تطويرها بأربعة مراحل رئيسة وفي كل مرحلة مجموعة من الخطوات. ينتج عن كل مرحلة مجموعة من المخرجات deliveries تُبنى عليها مراحل لاحقة. هذه المراحل الأربعة هي: التخطيط planning التحليل analysis التصميم design التنفيذ implementation سنتحدث باختصار عن كل مرحلة وسنتكلم بإسهاب عن كل مرحلة في مقالات لاحقة. مرحلة التخطيط لبناء منظومة برمجية لا بد في هذه المرحلة من الإجابة على الأسئلة التالية: لم علينا بناء هذه المنظومة أو هذا البرنامج؟ ما الذي ستقدمه هذه المنظومة إلى الفعالية التي طلبتها أو للجهة التي تنتجها؟ هل يمكننا بناء هذه المنظومة؟ كم يستغرق بناؤها؟ وكما أشرنا سابقًا أن لكل مرحلة مجموعة من الخطوات التي تمر بها حتى تكتمل، وعادة ما تضم مرحلة التخطيط خطوتين أساسيتين هما: تهيئة المشروع Project initiation: يٌقصد بتهيئة المشروع هو التخطيط المبدئي له، وتضم هذه الخطوة مجموعة خطوات فرعية هي: تحديد أهمية المشروع وضرورة بنائه بالنسبة للعميل أو صاحب المصلحة المعني مباشرة بتطويره. دراسة جدوى المشروع Project feasibility بالتشاور المباشر بين محلل الأنظمة والعميل وتكون الدراسة على ثلاثة أصعدة تقنية تحدد إمكانية بناء المنظومة، واقتصادية تحدد ما إن كان ضروريًا بناء المنظومة الجديدة أو تحسين القديمة، وتنظيمية تحدد ما إن كان سيلقى المنتج الجديد ترحيبًا من مستخدميه وهل يتماشى مع أسلوب العمل في الجهة التي طلبت بناءه. دراسة المخاطر، وتختلف طريقة دراسة المخاطر من شركة إلى أخرى إلا أنها تسعى عمومًا إلى تحديد مصدر الخطر واحتمالية وقوعه وأثره المتوقع على المنظومة وطريقة تفادي الخطر أو التخفيف من أثره. إدارة المشروع Project management: وهي عملية التحكم بتطوير المشروع خلال مدة محددة بأقل تكلفة للحصول على المنظومة المطلوبة صحيحة وفعالة. يراقب مديرو المشروع عادة العمل ككل ويتحكمون بكل المهمات ويحددون الأدوار الوظيفية وينسقون بينها وتضم هذه الخطوة الخطوات الفرعية التالية: تحديد عدد الموظفين سواء محللي نظم أو مصممين أو مبرمجين. البحث عن المهارات اللازمة لإنجاز كل مهمة من مهام المنظومة. تحفيز فريق العمل لتحقيق الأهداف. الحد بين النزاعات والخلافات وتقريب وجهات النظر في فريق العمل. اقتراح التقنيات اللازمة لإنجاز العمل. وضع خطة عمل تعتمد على الاستراتيجية المتبعة في إدارة دورة حياة المنظومة. أما مخرجات هذه المرحلة فتأتي في مستندين الأول يضم خطة العمل والثاني مستند دراسة الجدوى والمخاطر ويعرض على الشخص المسؤول أو على لجنة القبول acceptance committee فإما أن يُقبل أو يُرفض أو يؤجل وفقًا للفائدة المضافة موازنة بالمخاطر. مرحلة تحليل المنظومة لا بد أن تتمكن هذه المرحلة من الإجابة عن الأسئلة التالية: ماذا نتوقع من المنظومة؟ ما هو المطلوب منها؟ من سيستخدم المنظومة الجديدة أو المطوّرة؟ أين ومتى ستُستخدم المنظومة الجديدة؟ تضم هذه المرحلة خطوتين رئيسيتين: تحديد متطلبات المنظومة بناء نماذج تحليلية للمنظومة تحديد متطلبات المنظومة define requirements وهي أكثر خطوات هذه المرحلة (إن لم يكن دورة التطوير بأكملها) أهمية وحساسية. إذ يمكن أن نناقش في هذه المرحلة ماهو المطلوب من المنظومة البرمجية وفقًا لرؤية المعنيين بتطويرها على مختلف المستويات والمرجعيات. فالنقاش في هذه المرحلة ووضع التصورات والنماذج سيكون متاحًا إلى أقصى الحدود دون أي آثار سلبية موازنة بالتغييرات التي يُضطر فريق العمل إلى إجرائها في مرحلة التنفيذ، إذ سيرفع ذلك من نسبة فشل المشروع إلى أكثر من 50%. وتتميز هذه المرحلة بأنها تدريجية أي يجري تطوير نماذج عن متطلبات المنظومة تدريجيًا وليس دفعة واحدة كما تتميز بأنها تكرارية أي يكون تحسين النماذج بالتكرار. ما هو المتطلب؟ المتطلب هو تصريح عما يُراد من المنظومة فعله أو تصريح عن الخصائص التي تتمتع بها المنظومة التي نريد بناءها. هنالك نوعان من المتطلبات: متطلبات وظيفية functional ومتطلبات غير وظيفية nonfunctional. أما المتطلبات الوظيفية functional، فتضم التصريحات التي تحدد ما على المنظومة فعله أو تحدد إمكانياتها. وكمثال على المتطلب الوظيفي هو أن تسمح المنظومة للمستخدم مثلًا بتسجيل دخوله إليها فهذا المتطلب يتعلق مباشرة بطريقة عمل المنظومة وبالتالي هو متطلب وظيفي. وأما المتطلبات غير الوظيفية nonfunctional، فتضم تصريحات عن ميزات هذه المنظومة التي لا تتعلق بطريقة عملها. وكمثال عليها أن تعمل المنظومة مثلًا على الحواسب وأن تعمل أيضًا على الهواتف الذكية. كما تجد أحيانًا متطلبات إضافية مثل: متطلبات عمل: وهو تصريح عما يحتاجه العميل. متطلبات مستخدمين: وتضم تصريحات عن طريق استخدام المنظومة. متطلبات منظومة: وتضم تصريحات عن أسلوب وطريقة بناء المنظومة. ينتج عن مرحلة تحديد المتطلبات مستند يُدعى "تصريح تحديد المتطلبات requirements definition statement"ويضم المتطلبات الوظيفية وغير الوظيفية على شكل قائمة مفصّلة قد تُعطى فيها الأولوية لمتطلبات على أخرى إضافة إلى بعض المعلومات الضرورية للخطوات القادمة، كما يحدد هذا المستند ما يُدعى بنطاق عمل أو إطار عمل المنظومة system domain الذي ينبغي العمل في حدوده دون رفع أو تخفيض المتطلبات. بناء نماذج تحليلية للمنظومة يحاول فريق العمل خلال هذه المرحلة بناء نماذج models عن المتطلبات الوظيفية. وتوصِّف هذه المتطلبات مداخل ومخارج كل متطلب وطريقة تنفيذه. وغالبًا ما تُستخدم نماذج حالات الاستخدام use-case model التي توصّف كل وظيفة من وظائف المنظومة ومن سيشارك في إنجاز هذه الوظيفة سواء وظائف أخرى أو مستخدم خارجي، كما تُستخدم نماذج النشاط Activity models لتوصيف تسلسل تنفيذ العمليات التي تحقق وظيفة محددة وطريقة التفاعل المتبادل بين الوظائف المختلفة في المنظومة. فلو كان لدينا مثلًا منظومة برمجية لإدارة صراف آلي ATM ستكون إحدى حالات الاستخدام هو "سحب نقود" وسترتبط حالة الاستخدام هذه بحالة استخدام أخرى "التحقق من هوية المستخدم" ولا بد من وجود مشارك خارجي وهو "مستخدم الصراف". إن ما يمثّل هذه الترابطات هو مخطط حالات الاستخدام أما بالنسبة لمخطط النشاط فسيوُصف على الشكل التالي مثلًا: الصراف: يعرض رسالة ترحيب. المستخدم: يدخل البطاقة. الصراف: يحلل البطاقة ويعرض للمستخدم قائمة الخيارات. المستخدم: يضغط زر "سحب النقود". الصراف: يعرض قائمة بالمبالغ التي يمكن سحبها. المستخدم: يختار المبلغ المطلوب. الصراف: يعدّ النقود ويخرجها. تمثل هذه النماذج على شكل ملف يُدعى توصيف حالات الاستخدام use-case description أو عن طريق مخططات UML -لغة النمذجة الموحدة unified mark language- تُعرف بمخططات حالات الاستخدام ومخططات النشاط. تُبنى بعد تكوين النماذج الوظيفية أيضًا النماذج البنوية التي تستفيد من نماذج حالات الاستخدام وملفات توصيفها في توصيف المتطلبات على شكل أصناف لها خصائص (سمات attributes) وطرق methods وذلك إن كانت استراتيجية التحليل هي استراتيجية كائنية التوجّه object oriented strategy وهي الاستراتيجية الأكثر شيوعًا. تمثّل هذه الأصناف ضمن مخططات تُدعى مخططات الأصناف ويُستفاد منها لاحقًا في عملية برمجة المتطلب الوظيفي. وأخيرًا تُبنى النماذج السلوكية behavioral models وهي نماذج تعبّر عما يجري داخليًا خلف الستار حتى تؤدي المنظومة الوظائف المطلوبة منها ظاهريًا أي كما يراها المستخدم الخارجي. تتشكل هذه النماذج انطلاقًا من النماذج البنيوية والوظيفية لأنها تعبير عن التفاعل بين النماذج البنيوية (الكائنات التي تشكل المنظومة). وتُمثّل النماذج السلوكية باستخدام مخططات UML منها مخطط التتابع sequence diagram التي تمثل تتابع الرسائل بين الكائنات، ومخططات الاتصال communication diagram التي تمثل الطرق التي تسلكها تلك الرسائل ومخططات التوقيت timing diagrams. ينتج عن هذه المرحلة ورقة تُدعى "اقتراح المنظومة system proposal" وتضم تفاصيل عن وظائف المنظومة الجديدة وطريقة إنجازها مُدعّمًا بالنماذج والمخططات التي بنيت في هذه المرحلة وتُرفع إلى لجنة القبول لاتخاذ القرار بالمضي أو إعادة تحليل المتطلبات. مرحلة تصميم المنظومة البرمجية وتجيب هذه المرحلة عن سؤال مهم وهو كيف سنبني المنظومة؟ إذ تُقرر في هذه المرحلة نوعية العتاد الصلب التي ستُستخدم والبرمجيات اللازمة والبنية التحتية لشبكات الاتصالات وواجهات المستخدم وقواعد البيانات ونماذج إرسال البيانات والتقارير. تضم هذه المرحلة الخطوات التالية: وضع استراتيجية التصميم: وفيها يجيب فريق العمل بالتعاون مع الجهة المعنية عن الأسئلة التالية: هل ستُطوّر المنظومة محليًا في الجهة التي تحتاج المنظومة اعتمادًا على كوادرها الخاصة؟ هل ستطور المشروع شركة مختصة أخرى؟ هل ستشتري الشركة حزم برمجية جاهزة تحقق متطلبات مرحلة التحليل؟ تطوير المعمارية الأساسية للمنظومة: بما في ذلك العتاد الصلب والبرمجي وواجهة المستخدم والبنية التحتية لشبكة الاتصال وهل سيتم البناء على البنية التحتية السابقة أم تحتاج المنظومة الجديدة إلى بنية تحتية جديدة كليًا. تطوير مواصفات لقواعد البيانات والملفات: أي تحديد طبيعة البيانات التي تُخزن وحجمها وأين وكيف ستُخزن. تصميم البرمجيات التي ستُبنى: أي ما هي البرامج التي ينبغي للمبرمجين العمل عليها وما وظيفة كل برنامج وما هي علاقته بغيره. ينتج عن هذه المرحلة مجموعة المخرجات التالية: مستندات تصميم المعمارية. مستندات تصميم واجهة المستخدم. مستندات مواصفات قواعد وملفات البيانات. مستند تصميم البرامج. تستخدم هذه المستندات لاحقًا في توجيه مرحلة إنجاز المنظومة. مرحلة إنجاز المنظومة وهي المرحلة الأخيرة من دورة تطوير البرمجيات، وتحظى هذه المرحلة بكامل الانتباه لأنها تعد المرحلة الأطول والأكثر تكلفة. تضم هذه المرحلة الخطوات التالية: بناء المنظومة اختبار المنظومة توثيق المنظومة تركيب المنظومة إدارة التغيير التدريب على استخدام المنظومة الصيانة ودعم المنظومة التقييم الراجع للمشروع بناء المنظومة ويقصد فيها برمجة كل وظيفة من وظائف المنظومة والربط بين هذه البرمجيات وتعتمد بشكل كامل على مخرجات مرحلتي التحليل والتصميم. تُعد هذه المرحلة بأنها الأقل خطرًا على فشل المنظومة ولا يأتي فشل المنظومة نتيجة لضعف البرمجة بل لضعف مخرجات عمليتي التحليل والتصميم. تجري في هذه المرحلة أيضًا عملية توثيق الإجرائيات بدقة للاستفادة منها في خطوات الاختبار والصيانة. اختبار المنظومة تهدف هذه الخطوة إلى كشف أكبر قدر ممكن من العيوب التي قد تتسبب في إخفاق البرنامج، وعادة ماتكون الخطوة الأطول والأكثر تركيزًا في هذه المرحلة لأنه من الصعب إنشاء منظومة خالية تمامًا من العيوب، كما أن عملية البحث والاستقصاء عن جميع العيوب أمر مرهق زمنيًا وماديًا. لتلك الأسباب يجري اختبار المنظومة على مبدأ ما الذي تقدمه فعليًا موازنةً مع ما يتوجب عليها فعله. يختبر فريق متخصص المنظومة بواحدة أو بجميع الطرق التالية: اختبارات الوحدات unit tests: ويجري على دالة أو صنف أو جزء محدد من وحدة برمجية للتأكد من أن الدخل الصحيح يعطي الخرج المطلوب. اختبارات التكامل integration tests: يختبر التفاعل المتبادل بين مجموعة محددة من الأصناف لإنجاز وظيفة محددة. اختبارت المنظومة system tests: يختبر تفاعل جميع الأصناف مع بعضها لإعطاء وظيفة متكاملة للمنظومة دون أخطاء، وهو مشابه لاختبار التكامل لكن على صعيد أوسع. اختبارات القبول acceptance tests: وينفذها المستخدمون النهائيون للمنظومة تحت إشراف عضو أو أكثر من فريق العمل وذلك لتقييم قبول المستخدم لهذه المنظومة الجديدة. توثيق المنظومة وهي عملية ممتدة عبر جميع المراحل لكنها تُنظم في هذه الخطوة وتضم توثيق عن المنظومة بما يساعد المبرمجين والمحللين في بناء وصيانة المنظومة وتوثيق المستخدم الذي يساعده على استثمار المنظومة. وقد يكون التوثيق مرجعيًا لمساعدة المستخدم على إنجاز مهمة محددة أو إجرائيًا لوصف إنجاز خطوة ما أو مواد تعليمية. تركيب المنظومة وتتضمن هذه الخطوة تثبيت العتاد الصلب والبرمجيات اللازمة وفقًا لمعايير المعيارية المقترحة. إدارة التغيير لا يجري الانتقال إلى استخدام المنظومة الجديدة مباشرة بل على مراحل لمساعدة المستخدمين النهائيين على التأقلم معها بأقل توتر ممكن. ولأن لكل تغيير مقاومة لا بد أن يتشارك محللو المنظومة وأصحاب القرار ومديرو المشروع في إدارة مرحلة التحوّل وتوجيه المستخدمين وتحفيزهم على تبني المنظومة الجديدة. التدريب على استخدام المنظومة لا بد في هذه المرحلة من تقديم المهارات اللازمة لاستثمار النظام دون الافتراض المسبق بأن المنظومة سهلة التعلّم. كما ينبغي التركيز في هذه المرحلة على مساعدة المتدرب على تنفيذ المهام الموكلة إليه فقط دون الغوص في تفاصيل وميزات المنظومة الجديدة، فهنا تأتي أهمية وجود توثيق شامل. الصيانة ودعم المنظومة وهي عملية تحسين المنتج البرمجي كي يلبي دائمًا متطلبات العمل، وقد تكون خطوة الصيانة ذات تكلفة عالية. يُكلف بعملية الصيانة عادة محللو الأنظمة والمبرمجون المبتدئون. ويأتي دعم المنظومة عبر خيارات عدة منها: التدريب عند الطلب أو الحاجة. الدعم المباشر عبر الإنترنت: من خلال التوثيق والأسئلة أكثر شيوعًا وحتى المحادثة المباشرة. مكاتب الدعم: وذلك لاستشارة الخبراء مباشرة حول مشاكل محددة بناء على مواعيد مسبقة. التقييم الراجع للمشروع أي تقييم نجاح المشروع أو فشله والطرق الكفيلة بتحسينه وتطويره وأخذ العبر منه. وتنفذ هذه الخطوة عادة وفق مسارين: مراجعة منظومة: والهدف هو موازنة التكلفة والفائدة الحقيقية موازنة مع التكلفة والفوائد المقدرة في مرحلتي التخطيط والتحليل. مراجعة فريق العمل: إذ يقيِّم كل فرد من أفراد فريق العمل أخطاءه ونجاحاته في إنجاز المهام الموكلة إليه. يمكن بعد ذلك لمدير المشروع أن يجمع التقييمات ويضيف إليها بعض التوضيحات والشروحات ليخرج بملف يُدعى "دروس تعلمناها lesson learned" والتي تلعب دورًا مهمًا في تدريب وتعليم الأعضاء الجدد وفي تفادي أية أخطاء مماثلة في مشاريع مستقبلية. خاتمة تعرفنا في هذا المقال على الأساسيات المتبعة في التخطيط لتطوير البرمجيات أو المنظومات المعلوماتية عمومًا ورأينا أهمية التخطيط التدقيق والتحليل لمتطلبات البرمجيات للوصول إلى منتج قادر على الصمود والمنافسة. كما تعرفنا على المراحل الأساسية الأربعة لعملية تطوير المنتجات البرمجية وهي مراحل التخطيط والتحليل والتصميم والتنفيذ، وتعرفنا على مجموعة الأعمال التي ينبغي القيام بها في كل مرحلة والمخرجات التي تنتج عن كل منها وصولًا إلى المنتج النهائي وصيانته ودعمه. اقرأ أيضًا كيف تتجنب كارثة الاستعانة بفريق خارجي في تطوير البرمجيات دليل المبتدئين لمنهجية أجايل Agile الأخطاء السبع القاتلة لأيّ مشروع برمجيات
    1 نقطة
  32. مصطلح إطار العمل أو الفريم وورك Framework يعد أحد المصطلحات الفنية والبرمجية التي تربك المبتدئين على وجه الخصوص في بداية مشوار تعلم البرمجة والتي لا يستطيع فهم دلالتها ولا إدراك مدى أهميتها بشكل جيد. وكثيرًا ما يتساءل المبرمج المبتدئ عن معنى إطار العمل Framework وعن مزايا ومحدويات استخدام أطر العمل Frameworks في عمله البرمجي وعملية البرمجة عمومًا، وهل يتوجب عليه تعلم إطار عمل للغة برمجة محددة، أم أن تعلمه للغة البرمجة نفسها يكفيه في سوق العمل، وهل تعلم إطار العمل صعب ويستغرق وقتًا، ومالفرق بين إطار العمل والمكتبة، وغيرها من الأسئلة من هذا القبيل. فإذا كنت مهتمًا بعرفة الإجابة على كل هذه التساؤلات فتابع قراءة هذا المقال للنهاية. ما هو إطار العمل Framework؟ إطار العمل Framework في البرمجة هو ببساطة آلية يتم من خلالها إعداد وتجهيز كافة الوظائف الضرورية والشائعة التي تستخدم بكثرة عند تطوير التطبيقات والأنظمة وإتاحتها للمبرمج ليستخدمها ويستفيد منها في عمله دون أن يحتاج لإعادة كتابة هذه الوظائف بنفسه من الصفر وبهذا نستنتج أن استخدام إطار العمل يختصر الكثير من الوقت ويجعل العمل البرمجي أكثر كفاءة. لتفهم الأمر بصورة أفضل تخيل أنك تحتاج لكتابة سيرتك الذاتية، سيكون أمامك خياران إما أن تفتح مستندًا فارغًا وتبدأ بكتابة كل شيء وتنسيقه بنفسك من الصفر، أو تعتمد على قالب جاهز للسيرة الذاتية يكون مقسمًا ومنسقًا وكل ما عليك هو ملء البيانات الضرورية الخاصة بك فقط دون أن تشغل بالك بالكثير من التفاصيل الأخرى سيكون الخيار الثاني أفضل وأسرع بالتأكيد. يساعدك إطار العمل في مشروعك البرمجي بطريقة مشابهة فهو يعمل كقالب أو هيكل أساسي عليك الالتزام به لإنشاء التطبيقات الخاصة بك، ويوفر لك مجموعة من الأدوات أو المكونات أو الحلول البرمجية الجاهزة لبناء تطبيقات مخصصة بطريقة آمنة وسريعة ومنظمة. ستجد الكثير من أطر عمل لكل لغات البرمجة الشائعة مثل جافاسكريبت وبايثون و PHP وجافا، ومن أجل استخدام أي إطار منها عليك بداية تعلم كيفية تطوير المشاريع في كل إطار منها والاستفادة من التسهيلات الكثيرة التي توفرها لك هذه الأطر. أنشئ موقع إلكتروني لأعمالك بدون خبرة برمجية صمم موقع احترافي لأعمالك بالسحب والإفلات مع أكثر من 70 قالب جاهز وقابل للتخصيص ليناسب هويتك التجارية جرب سنديان الآن ما الفرق بين إطار العمل والمكتبة؟ كثيرًا ما يتم الخلط بين مفهوم إطار العمل Framework ومفهوم مشابه له في البرمجة وهو المكتبة Library ورغم التشابه بينهما في طريقة العمل واستخدامهما بالتبادل في بعض الأحيان، إلا أن مفهوم المكتبة أبسط وأكثر محدودية فالمكتبة تركز على توفير وظيفة محددة في حين يوفر إطار العمل مجموعة متكاملة من الميزات التي تمكنك من برمجة تطبيقات في مجال محدد. تُعرَّف المكتبة بأنها عبارة عن مجموعة من التعليمات البرمجية المختبرة القابلة لإعادة الاستخدام والتي تنفذ وظيفة معينة وتحل مشكلة محددة، في حين ينفذ إطار العمل حزمة وظائف متكاملة أو يوفر مخططًا عامًا لبناء التطبيقات في حين لا توفر المكتبات هذه الميزة كما تحدد أطر العمل قواعد وإرشادات كتابة التعليمات البرمجية الخاصة بك وتنظم الملفات والمجلدات الخاصة بمشاريعك، ويمكن أن تتضمن مجموعة من المكتبات وتستخدمها لتنفذ مهام معينة. على سبيل المثال من بين المكتبات الشائعة نذكر مكتبة ريآكت React وهي مكتبة برمجية مبنية بلغة جافاسكربت ومتخصصة في بناء واجهات المستخدم ومكتبة jQuery التي تختصر العديد من الأكواد والتعليمات البرمجية المكررة في جافا سكريبت لتسهيل عملية البرمجة، ومن بين أطر العمل الشائعة نذكر أنجولار Angular وفيو Vue.js وهما إطارا عمل بلغة جافا سكريبت مختصان في تصميم واجهات مواقع الويب. ما الفرق بين إطار العمل ولغة البرمجة؟ يمكن للمطور أن يستخدم لغة البرمجة ويكتب كافة التعليمات البرمجية اللازمة لبناء التطبيقات من الصفر كما يمكنه إن شاء الاستعانة بإطار عمل Framework مخصص لتطوير برامجه وتطبيقاته. ورغم أن استخدام إطار العمل يفيد المطورين ويسرع وتيرة عملهم، إلا أنه يحد من حريتهم في كتابة التعليمات البرمجية ويقيد إمكانيات التطوير ويمكنهم من بناء تطبيقات لأغراض محددة فقط، في حين أن استخدام لغة برمجة يمكنهم من تطوير ما يشاؤون من تطبيقات متنوعة، حتى إطار العمل نفسه تم بناؤه في النهاية بإحدى لغات البرمجة. باختصار لغة البرمجة هي الأساس ومن خلال تعلمها يمكنك بناء ما تشاء من تطبيقات، أما إطار العمل فهو مصمم لنوع محدد من التطبيقات مثل تطبيقات الويب أو تطبيقات الجوال أو تطبيقات علم البيانات أو الذكاء الاصطناعي وإنترنت الأشياء …إلخ ويفضل أن تتعلم استخدامه بعد أن تتعلم البرمجة وتتمكن من أساسياتها. أهمية إطار العمل في البرمجة تبرز أهمية إطار العمل framework بشكل أساسي في كونه يتيح لك إعادة استخدام التعليمات البرمجية بدلًا من إعادة كتابتها من جديد، وفيما يلي جملة من الفوائد التي يمكن أن يوفرها استخدام إطار العمل: يساعد على توفير كود أكثر أمانًا لكونه يتضمن شيفرات تتحقق من المصادقات والصلاحيات وتحمي تطبيقك من الاختراق وتعالج الكثير من الثغرات الأمنية الشائعة مثل CSRF و XSS و SQL Injection. تركيز الجهود على كتابة التعليمات البرمجية الخاصة بالمشروع فقط بدلًا من برمجة وظائف متكررة وشائعة الاستخدام. توحد أنماط وقواعد كتابة التعليمات البرمجية وتوفر مخططًا عامًّا يمكن لكافة الفرق البرمجية فهمه بسهولة. يساعد في تطوير مشروعك وإضافة ميزات جديدة له بسهولة دون الحاجة للتعديل على الكود الأساسي لإطار العمل. يغني عن إعادة اختراع العجلة ويوفر لك الوقت والتكلفة اللازمين لتطوير المشاريع والتطبيقات. يساعد في كتابة كود نظيف وغير مكرر. يسهل عملية اختبار الكود وتصحيح الأخطاء البرمجية. يقلل بالعموم من كمية الأخطاء البرمجية لأنك ستكتب كود أقل وبالتالي ستنتج لديك أخطاء برمجية أقل. محدوديات إطار العمل لا شكَّ أن استخدام إطار العمل يفيدك كمطور ويساعدك على تسريع وتحسين العمل البرمجي، إلا أن الاعتماد على أطر العمل وحدها يفرض عليك بعض القيود وإليك أبرزها: يوفر وظائف محددة ويختص في بناء تطبيقات في مجالات معينة فقط. الاعتماد عليها قد يعيق المبرمج من فهم لغات البرمجة بشكل متعمق وواضح. بعض أطر العمل معقدة ويستغرق تعلمها وفهمها بشكل جيد وتطوير التطبيقات باستخدامها الكثير من الوقت. نحتاج إلى اختيار إطار العمل المناسب للتطبيق فاختيار الإطار غير الملائم قد يؤثر سلبًا على أداء تطبيقاتك وتجربة المستخدمين. تصدر لها تحديثات جديدة بشكل دوري، لذا سيتوجب عليك البقاء على اطلاع دائم على كل جديد ومعرفة كل الميزات الجديدة المضافة للإطار والمميزات التي تم الاستغناء عنها في كل إصدار. توقف تحديث إطار العمل أو تغيره ينعكس على سير عملية تطوير التطبيق المبرمج فيه وأمانه مثلما حصل مع إطار العمل AngularJS عندما قررت غوغل التوقف عن تطويره وإطلاق نسخة عنه مختلفة تمامًا. صفات إطار العمل الجيد تتوافر عشرات أطر العمل في المجالات البرمجية المختلفة الأمر الذي يشعرك بالحيرة في تحديد الإطار الأفضل لمشروعك ويجعلك تتساءل كيف أختار إطار العمل المناسب؟ بالعموم يتصف إطار العمل الجيد بثلاث صفات أساسية وهي: التوثيق الجيد توفير الوظائف المطلوبة لعملك الشهرة والدعم المجتمعي لنوضح بمزيد من التفصيل كل صفة من هذه الصفات وأهميتها في اختيار إطار العمل الأفضل. التوثيق الجيد اختر إطار عمل موثقًا بشكل جيدًا كي تتمكن من العودة إليه عندما تحتاج لمعرفة المزيد من المعلومات حول استخدام ميزة معينة أو حل مشكلة تواجهك في استخدامه، فالتوثيق الجيد يوفر عليك الكثير من الوقت والجهد. توفير الوظائف المطلوبة لعملك ضع في اعتبارك أن لكل إطار عمل حدود معينة لذا من الضروري أن تبحث بشكل جيد في ميزات الإطار الذي تريد اعتماده وتتأكد من أنه يلبي متطلبات مشروعك ويحقق لك كافة الوظائف والميزات التي تحتاج لتحقيقها بالشكل الأنسب، وبنفس الوقت لا تختر إطار عمل شديد التعقيد أو مكتظًا بالميزات التي قد لا تحتاجها على الإطلاق! الشهرة والدعم المجتمعي لاشك أن شهرة إطار العمل ووجود مجتمع داعم له يدل على قوته والطلب الكبير عليه في سوق العمل، لذا احرص على استخدام إطار عمل معروف وله قاعدة مستخدمين نشطة ويفضل بعض المبرمجين الاعتماد على أطر عمل حرة ومفتوحة المصدر وغير مقيدة أو مدعومة من شركات معينة لتخوفهم من انعكاس أي طارئ يحصل لها أو تغير في سياستها على إطار العمل. ولذلك السبب ترى البعض يميل إلى استخدام إطار العمل Vue.js الذي انبثق من أروقة المجتمع الحر بدلًا من إطار العمل Angular الذي ولد بين أروقة شركة غوغل مثلًا، ولكن هنالك طرف مقابل يشير إلى تنظيم وقوة وسرعة تطوير أطر العمل التي تقف خلفهم الشركات نظرًا لدعمهم السخي طويل الآجل عادةً خصوصًا إن وقفت شركات تقنية كبيرة خلفهم والحديث يطول في هذه النقطة وهي خارج موضوع المقال فقط أحببت الإشارة إليها نظرًا لأهميتها في أي نقاش يدور حول المفاضلة بينها. أنواع أطر العمل frameworks في البرمجة هناك عدة أنواع من أطر العمل حيث يختص كل إطار بمجال استخدام معين، وفيما بعض أهم أنواع أطر العمل حسب التطبيقات أو الوظائف التي يؤديها: 1. أطر عمل تطوير الويب Web development frameworks تستخدم هذه الأطر في تطوير تطبيقات الويب ومن أشهرها إطار عمل أنجولار Angular وفيو جي إس Vue.js وهي أطر عمل جافا سكريبت شائعة تستخدم لتطوير الواجهات الأمامية للويب، وإطاري عمل إكسبرس Express و NestJS وهي أطر عمل Node.js لتطوير الواجهات الخلفية للويب، وإطاري عمل جانغو Django وفلاسك Flask وهي أطر عمل مفتوحة المصدر مكتوب بلغة بايثون مخصصة لتطوير الواجهات الخلفية للويب، وإطار عمل Ruby on Rails الذي يوفر لك كل ما تحتاجه لإنشاء تطبيق ويب بسهولة وسرعة وأمان وإطار عمل لارافيل Laravel المبني بالاعتماد على لغة PHP. 2. أطر عمل تطوير الجوال Mobile development frameworks من أشهرها في تطوير تطبيقات الجوال نذكر إطار عمل React Native مفتوح المصدر مكتوب بلغة جافا سكريبت طورته فيسبوك لتطوير تطبيقات جوال متوافقة مع كافة الأنظمة الأساسية، وإطار أيونيك Ionic الذي يستخدم تقنيات الويب HTML و CSS وجافا سكريبت من أجل تطوير تطبيقات الجوال وهو يتكامل مع أطر تطوير الواجهات الأمامية مثل Angular و Vue، وإطار عمل فلاتر Flutter وهو إطار عمل مفتوح المصدر للغة دارت Dart من جوجل لتطوير تطبيقات الجوال وهو يدعم أنظمة iOS و Android ويحتوي على عناصر واجهة مستخدم قابلة للتخصيص بالكامل، وإطار عمل أباتشي كوردوفا Apache Cordova الذي يمكنك من تطوير تطبيقات هجينة للهاتف الجوال. 3. أطر عمل علم البيانات Data science frameworks تعرف هذه الأطر كذلك بأطر التعلم الآلي Machine Learning Frameworks وهي تساعد علماء البيانات على إنشاء نماذج تعلم آلي وتصميمها بشكل أسرع وأسهل واستخراج المعلومات المفيدة من مجموعات البيانات بالاستفادة من تقنيات البرمجة والذكاء الاصطناعي والتعلم الآلي. وهناك العديد من أطر عمل علم البيانات ومن ضمنها scikit-Learn و XGBoost و TensorFlow و PyTorch. 4. أطر إدارة المحتوى Content management frameworks تعرف أيضًا باسم نظم إدارة المحتوى Content Management Systems أو اختصارًا CMS هي برمجيات توفر مكونات قابلة لإعادة الاستخدام لإنشاء وإدارة محتوى الويب وعرضه ضمن مدونات أو مواقع إلكترونية أو تطبيقات جوال وهي توفر ميزات أخرى مثل سهولة الاستخدام وتحسين محركات البحث والأمان. ومن أشهر هذه النظم نذكر نظام ووردبريس WordPress الشهير المستخدم في إنشاء ما يقارب من نصف المواقع الإلكتروني ودروبال Drupal الذي يعد نظام مثالي لتطوير المواقع التي تحتوي على الكثير من المحتوى وهو يتطلب معرفة تقنية أكثر من بقية نظم إدارة المحتوى. 5. أطر عمل أتمتة الاختبار Test Automation frameworks يستخدم مطورو البرمجيات أطر عمل الأتمتة من أجل إنشاء حالات اختبار التطبيقات والتأكد من سير عملها بكفاءة وتوفر لهم أدوات وتوصيات للتحقق من جودة البرمجيات واتباع معايير الترميز المناسبة. من أشهر أطر الاختبار نذكر سيلينيوم Selenium وهو إطار مفتوح المصدر لأتمتة اختبار تطبيقات الويب، وCypress المبني بجافا سكريبت والمخصص لاختبار الواجهة الأمامية لتطبيقات الويب، و Playwright للاختبار الشامل لتطبيقات الويب. هل يمكن البدء باستخدام إطار العمل دون تعلم لغة البرمجة؟ لاشك أن إطار العمل يوفر لك كمطور أداة قيمة لتطوير البرامج التطبيقات المختلفة، لكن السؤال الذي يطرح نفسه هل يغني تعلم أطر العمل واستخدامها في بناء التطبيقات العملية عن تعلم لغات البرمجة وفهمها بشكل متعمق؟ في الواقع حتى لو لم تكن ترغب في تطوير التطبيقات بإحدى لغات البرمجة وتميل للاستفادة من ميزات أحد أطر العمل فلا غنى لك عن تعلم لغة البرمجة وفهم أساسياتها إلى جانب إطار العمل فكلما فهمت لغة البرمجة بشكل أفضل سيسهل عليك فهم أطر العمل. كما أن تعلّم البرمجة يوسع أفق عملك ويمكنك من بناء العديد من التطبيقات في مختلف المجالات، أما إطار العمل فهو مصمم كما ذكرنا سابقًا لغرض واحد فقط وبالتالي سيقيدك بنوع محدد من التطبيقات. ويمكن باختصار أن نلخص الإجابة على هذا السؤال بجملة واحدة: يمكنك استخدام أطر العمل، لكن قبل ذلك تعلم أساسيات لغة البرمجة واتقنها ثم استفد من ميزات إطار العمل الخاص بتلك اللغة كما يحلو لك. الخلاصة تعرفنا اليوم على مفهوم إطار العمل Framework ودوره المهم في توفير الوظائف القياسية وتحديد الخطوط العريضة التي تنظم المشاريع البرمجية وتوفر وقت وجهد المطورين والمبرمجين، واكشتفنا أهم الفروقات بين أطر العمل وبين أدوات تطوير البرامج الأخرى مثل المكتبات ولغات البرمجة، وتعلمنا طريقة اختيار أفضل إطار عمل يناسب متطلباتنا وعددنا أهم صفات إطار العمل الجيد، وأخيرًا استعرضنا قائمة بأهم أطر العمل المستخدمة في مجالات مختلفة كتطبيقات الويب وتطبيقات الجوال وغيرها من المجالات. هل تستخدم في عملك أحد أطر العمل التي وردت في سياق المقال أو أطر عمل أخرى؟ ما هو هذا الإطار وفي أي مجال تستخدمه؟ هل هناك أي مشاكل تواجهها في التعامل مع هذا الإطار أم أنك راضٍ عن أدائه. شاركنا تجربتك في التعليقات أسفل المقال. اقرأ أيضًا تعلم أساسيات البرمجة قواعد البرمجة ببساطة للمبتدئين أسهل لغات البرمجة مهندس البرمجيات من هو وما هي مهامه تعرف على تخصص هندسة البرمجيات
    1 نقطة
  33. لا يختلف اثنان على أهمية تعلم أساسيات البرمجة، فالبرمجة هي مهنة الحاضر والمستقبل، وهي تعتبر أحد المهارات الأساسية في عصرنا الذي بات يعتمد على التقانة في جميع جوانبه، فضلًا عن أن البرمجة قد أصبحت مادة أساسية في المناهج الدراسية في العديد من الدول بدءًا من المراحل الابتدائية. إذا اتخذت قررًا بتعلم أساسيات البرمجة من الصفر للاحتراف فهذا بلا شك قرار صائب، فالبرمجة توفر لك الكثير من فرص العمل، وتوسع مداركك، وتعزز تفكيرك النقدي، كما أنها تكسبك القدرة على حل المشكلات التي تواجهك بكفاءة أكبر، والأمر الجيد أن البرمجة تتميز عن غيرها من المجالات بكونها متاحة للجميع، ويمكنك تعلمها بشكل ذاتي بعيدًا عن أروقة الجامعات الطويلة. نشرح في مقال اليوم أساسيات البرمجة، ونستعرض أهم الأدوات التي تحتاجها كمبرمج، ونبين مفاهيم البرمجة الأساسية التي تشترك فيها معظم لغات البرمجة، وأهم المبادئ التي يمكنك اتباعها لتبرمج كالمحترفين. ما هي البرمجة؟ البرمجة باختصار هي إعطاء التعليمات لجهاز الحاسوب لينفذها باستخدام إحدى لغات البرمجة، ويتلقى الحاسوب هذه التعليمات ويترجمها ويفهمها وينفذها، ويُطلق على تسلسل التعليمات المكتوبة باستخدام لغة برمجة والتي تنجز مهمة محددة اسم برنامج. فنحن البشر نتواصل فيما بيننا بلغاتنا الطبيعية كالعربية أو الإنجليزية، أما الحاسوب فيحتاج لاستخدام لغة برمجة خاصة للتواصل معه، وعالم لغات البرمجة شامل ومنوع فهناك المئات من لغات البرمجة حاليًا، ونشير إلى أن لغة البرمجة هي لغة وسيطة بيننا وبين الحاسوب فحتى الحاسوب لا يفهم لغة البرمجة التي نكتبها بل تُحول كل لغة نكتبها إلى لغة يفهمها الحاسوب عبر أداة تحويل وتدعى اللغة التي يفهمها الحاسوب بلغة الآلة Machine Language التي تتكون من أصفار وواحدات. قبل أن تتعلم أساسيات البرمجة: حدد وجهتك قد تكون حددت لغة البرمجة التي تريد تعلمها وتبحث عن تعلم أساسيات هذه اللغة لذا وصلت إلى هنا، أو لم تحددها بعد، ولكن عمومًا تشترك كل لغات البرمجة بأساسيات واحدة إن تعلمتها سيسهل عليك التعامل مع أي لغة برمجة. قرار تعلم أساسيات البرمجة يشبه قرار الذهاب في إجازة، فأنت لن تذهب في إجازة دون أن تحدد الوجهة التي تريد الذهاب لها، وبناء على وجهتك تحدد مسارك الذي ستسلكه وتجهز مستلزماتك. وبالتالي السؤال الذي يجب أن تطرحه قبل أن تقرر تعلم أي لغة برمجة هو ما هو هدفي النهائي من تعلم البرمجة؟ وبناء على إجابتك تحدد مسار التعلم الصحيح واللغات والأدوات التي عليك تعلمها. ركز في البداية على لغة رئيسية واحدة تتعلم بها أساسيات البرمجة، ثم سيسهل عليك تعلم لغات أخرى حسب الضرورة، حيث الأساسيات والمفاهيم واحدة ولن تختلف من لغة إلى أخرى بل ما يختلف هو طريقة كتابة كل لغة والميزات التي توفرها للمبرمج، وبعبارة أخرى، الخطوة الصعبة هي الخطوة الأولى وهي خطوة تعلم أساسيات البرمجة. وتذكر أن تعلم البرمجة يحتاج لبعض الصبر والجهد، لا سيما عند تعلم إحدى لغات البرمجة لأول مرة كما أشرنا ويحتاج إلى تطبيق أيضًا لأن التعلم النظري شيء والتطبيق شيء آخر ففيه ستواجه الكثير من المشكلات وستتعلم بها حلها وتفاديها تدريجيًا حتى تكون مبرمجًا محترفًا. دورة علوم الحاسوب دورة تدريبية متكاملة تضعك على بوابة الاحتراف في تعلم أساسيات البرمجة وعلوم الحاسوب اشترك الآن أهمية تعلم أساسيات البرمجة تعلم أساسيات البرمجة للمبتدئين يشبه إلى حد كبير تعلم قيادة السيارة، فعندما تجلس خلف مقود السيارة لأول مرة لن تكون قادرًا على القيادة بسلاسة على الفور، بالطبع! تذكَّر كيف تبدأ آنذاك باستكشاف أجزاء السيارة كالفرامل ودواسة البنزين وناقل الحركة، ثم التعرف على المفاهيم والمصطلحات الأساسية المرتبطة بالقيادة، وتلقي الكثير من التعليمات والملاحظات النظرية حول آلية القيادة أكثر من التركيز على القيادة بحد ذاتها. وبعدها تبدأ عملية التدريب على تنفيذ أوامر بسيطة مثل تشغيل السيارة وتحريكها رويدًا رويدًا في مكان مفتوح إلى أن تزداد التعليمات تعقيدًا وتصبح قادرًا على التحكم بالسيارة وقيادتها في كافة الظروف والطرق. بنفس الطريقة ستتعلم البرمجة، حيث عليك أن تتعلم بداية أساسيات البرمجة النظرية، ثم تكتب برامج باستخدام تعليمات بسيطة، ثم تتعلم كيف تكتب التعليمات بطريقة أكثر احترافية، ومع الممارسة والتطبيق ستتمكن من احتراف البرمجة وتطوير برامج متقدمة. وقد شرح مقال كيف تتعلم البرمجة: نصائح وأدوات لرحلتك في عالم البرمجة رحلة تعلم البرمجة بالتفصيل وقدم نصائح مهمة وأجاب على أسئلة شائعة حول تعلم البرمجة فارجع إليه للاستزدادة في هذا الموضوع. احصل على موقع إلكتروني مخصص لأعمالك أبهر زوارك بموقع احترافي ومميز بالاستعانة بأفضل خدمات تطوير وتحسين المواقع على خمسات أنشئ موقعك الآن أدوات مهمة لتعلم أساسيات البرمجة بعد أن تحدد اللغة التي ستتعلمها، تحتاج كخطوة أولى إلى إعداد بيئة التطوير لديك حتى تتمكن من كتابة شيفرة برمجية وتنفيذها كي تتواصل مع الحاسوب بتلك اللغة، والأدوات اللازمة لتعلم أساسيات البرمجة في البداية هي أداتين يحتاج إليهما كل مبرمج: محرر الشيفرة البرمجية أداة تحويل الشيفرة وتنفيذها محرر الشيفرة البرمجية تعتمد معظم لغات البرمجة على أوامر نصية، لذا ستحتاج إلى محرر أكواد لكتابتها، ومحرر الكود هو برنامج لتحرير النصوص مصمم خصيصًا لكتابة وتحرير الشيفرة المصدرية للبرامج، وتتميز بعض المحررات بأنها تتضمن ميزات تسهل كتابة الكود كتمييز الكلمات حسب بناء الجملة، ووضع مسافة بادئة لأسطر التعليمات البرمجية بشكل صحيح. ومن الأمثلة على محررات أكواد Notepad++‎ لنظام تشغيل ويندوز و gedit أو kate لنظام التشغيل لينكس. ملاحظة: بعض لغات البرمجة الموجهة للمبتدئين تعتمد على واجهات رسومية ولا تحتاج لمحررات نصية مثل لغة سكراتش والتي تدعى أحيانًا لغات برمجة رسومية، وللمزيد يمكنك الرجوع إلى مقال البرمجة باستخدام سكراتش. أداة تحويل الشيفرة وتنفيذها نكتب الكود المصدري عادة بلغة برمجة لا يفهمها جهاز الحاسوب مباشرة كما أشرنا، لذا يجب تثبيت برنامجًا يُحوِّل الشيفرة المصدرية للغة البرمجة بأكملها إلى لغة آلة Machine Code يفهمها الحاسوب ثم ينفذها، ويختلف هذا المُحول من لغة برمجة إلى أخرى ويُسمى إما مُصرِّف Compiler أو مُفسِّر Interpreter وبعض اللغات تحتاج إلى تصريف وآخر إلى تفسير وبعضها يحتاج إلى كلا العمليتين لتحويلها إلى لغة الآلة ثم تنفيذها. لتفهم الفرق بين المُصرِّف والمُفسِّر تخيل أن لديك وصفة مكتوبة باللغة التركية وأنت لا تعرف التركية وتريد أن تحضّرها. في هذه الحالة يمكن أن تطلب من أحدهم أن يترجم لك الوصفة بالكامل للغة العربية ويعطيها لك لتعدها متى ما أردت مستعينًا بهذه النسخة المترجمة Compiled، أو يمكنك أن تكلمه في كل مرة تريد فيها أن تحضر هذه الوصفة وتطلب منه أن يقرأها ويفسرها لك خطوة بخطوة Interpreted. بيئة التطوير المتكاملة IDE يمكنك أن تحصل على المحرر وأداة التحويل والتنفيذ على حدة وتثبتهما على جهازك، أو يمكنك بشكل بديل أن تعتمد على بيئة تطوير متكاملة IDE وهي اختصار العبارة Integrated Development Environment تتضمن كافة الأدوات اللازمة للتعامل مع لغة البرمجة. أمثلة على بيئات تطوير متكاملة: Microsoft Visual Studio NetBeans IntelliJ IDEA يمكنك في بيئة التطوير المتكاملة كتابة التعليمات البرمجية وتعديلها وتصحيحها وتحويلها ثم تنفيذها بسرعة وسهولة كل ذلك من مكان واحد، إذ توفر لك كافة الأدوات اللازمة لتكتب وتنفذ برامج بلغة معينة، كما توفر ميزات تساعدك في تطوير البرامج مثل تصحيح الأخطاء البرمجية، والإكمال التلقائي للتعليمات، وللتعرف أكثر على بيئة التطوير المتكاملة، يمكنك الرجوع إلى مقال مدخل إلى بيئة التطوير المتكاملة IDE. ملاحظة: يمكنك الاعتماد على مترجمات أو بيئات عمل برمجية متوفرة على الإنترنت، حيث توفر العديد من المنصات إمكانية كتابة وتنفيذ البرامج على متصفح الويب بدلًا من تثبيت وإعداد البرامج على الحاسوب المحلي. أساسيات البرمجة للمبتدئين تتنوع لغات البرمجة وتعدد استخداماتها إلا أنها تشترك في مجموعة من الأساسيات والمفاهيم، وتعلم هذه المفاهيم يمكّنك من التآلف من أي لغة برمجة، وإنجاز البرامج باستخدامها بمرونة أكبر، وأهم هذه الأساسيات: المتغيرات Variables الثوابت Constants أنواع البيانات Data types الكلمات المفتاحية Keywords التعليقات Comments بنى التحكم Control Structures الدوال Functions هياكل البيانات Data structure التكرار Iteration التعاود Recursion الكائنات Objects والأصناف Classes الوحدات Modules والمكتبات Libraries نشرح في الفقرات التالية كلًا من هذه الأساسيات البرمجية بمزيد من التفصيل، ونرفق بعض الأمثلة التوضيحية بلغات برمجة مختلفة. المتغيرات تستخدم المتغيرات Variables في البرمجة بشكل مشابه لاستخدامها في الرياضيات، فهي تخزن قيم البيانات من نوع محدد، ويمكن للمتغير احتواء قيمة واحدة في المرة الواحدة، فمتى ما وضعت فيه قيمة جديدة فإن القيمة السابقة المخزنة فيه سوف تحذف تلقائيًا. يمكن تشبيه المتغير بصندوق مفتوح في ذاكرة الحاسوب له اسم وعنوان خاص به، حيث يمكن إدخال القيم وإخراجها من هذا الصندوق حسب الطلب. وتسمى عملية وضع قيمة في المتغير بشكل مباشر الإدخال Input أو الإسناد Assignment أو أحيانًا الضبط Set، كما تسمى عملية الحصول على هذه القيمة وعرضها الإخراج Output أو الجلب Get. وتجدر الإشارة لأن بعض أنواع المتغيرات تكون محدودة الوصول، بمعنى أنها لا تسمح لك بالوصول المباشر لها سواء لتخزين البيانات ضمنها أو الحصول على القيم المخزنة فيها إلا عبر وسيط ويُسمى هذا الوسيط باسم ضابط setter وجالب getter على التوالي، والغرض من هذه العملية حماية المتغيرات من تعديلات غير مرغوبة كما سنوضح لاحقًا في فقرة الكائنات والأصناف التي أكثر ما تُستخدم فيها. لتعريف متغير في لغة البرمجة C++‎ عليك ذكر اسم المتغير ونوع البيانات التي تريد تخزينها في هذا المتغير وإسناد قيمة أولية فيه، على سبيل المثال لتعريف متغير باسم a لتخزين العدد الصحيح 10 بداخله نكتب ما يلي: int a = 10; كما يمكنك تعريف المتغير دون إسناد القيمة له في البداية وإسنادها لاحقًا بالشكل التالي: int a; a = 10; في حين لا تملك لغة بايثون أمرًا محددًا لتعريف المتغيرات، كل ما عليك هو كتابة اسم المتغير واستخدام علامة مساواة متبوعة بقيمة المتغير، وسوف تكتشف اللغة تلقائيًا نوع المتغير وحجم الذاكرة المناسب له كما يلي: a = 10 الثوابت تشير الثوابت Constants إلى قيمة أو كمية ثابتة لا نحتاج لأن نغيرها أو نعدلها أبدًا أثناء تنفيذ البرنامج، مثل سرعة الضوء، وعدد الدقائق في الساعة، والعدد Pi الذي يمثل نسبة محيط الدائرة إلى قطرها، وتسارع الجاذبية الأرضية، ومعدل نجاح الطالب وما إلى ذلك. فالثوابت البرمجية بمثابة صندوق تغلقه بإحكام بعد وضع قيمة فيه ولا يسمح لك بتغييرها في كود البرنامج، فبعد تحديد قيمة الثابت يسمح لك فقط بالوصول إلى قيمته، بخلاف المتغير الذي يمكنك الوصول إلى قيمته وإعادة تعيينها وتعديلها حسب حاجتك. لتعريف الثوابت في لغة C++‎ نستخدم الكلمة المفتاحية const ثم نكتب نوع البيانات واسم الثابت وقيمته كما يلي: const float PI = 3.14; const float GRAVITY = 9.8; const float SUCC_RATE = 0.5; في حين لا تميز بعض اللغات مثل لغة بايثون بين تعريف الثوابت والمتغيرات، حيث يمكنك تعريف الثوابت والتعامل معها كما تعرّف أي متغير، وتلتزم أنت بعدم تغيير قيمتها في سياق البرنامج، كما يمكنك التصريح الثوابت في ملف مختلف واستيرادها في برنامجك لتمييزها عن المتغيرات. PI = 3.14 GRAVITY = 9.8 ملاحظة: يشيع في أوساط المبرمجين تسمية الثوابت بحروف أجنبية كبيرة لتمييزها عن المتغيرات كما فعلنا في الأمثلة السابقة. أنواع البيانات أنواع البيانات Data types في لغات البرمجة هي عملية تحديد نوع وحجم القيمة التي يمكن أن تخزن في المتغير والتي يترتب عليها تحديد العمليات التي يمكن تطبيقها على هذه المتغير من طرف لغة البرمجة مثلًا السماح بتطبيق عملية الجمع والطرح على نوع الأعداد والسماح بعملية البحث والاستبدال على النصوص وهكذا. توفر لغات البرمجة العديد من أنواع البيانات مثل: الأعداد التي تنقسم إلى أعداد صحيحة integer numbers وأعداد عشرية floating point numbers، والمحارف Characters، والسلاسل النصية Strings، والقيم المنطقية Boolean …إلخ. على سبيل المثال في لغة البرمجة C++"‎" إذا كنت تحتاج في برنامجك إلى تخزين العمر، ستحتاج لمتغير من نوع بيانات عدد صحيح، ويمكنك تعريف هذا المتغير أو التصريح عنه باستعمال الكلمة المفتاحية int كما يلي: int age; فعندما استخدمنا الكلمة int هنا أخبرنا مترجم اللغة أن هذا المتغير مخصص لتخزين أعداد صحيحة فقط، ليحجز الحجم المناسب له في ذاكرة الحاسوب وينتظر منا إدخال قيم صحيحة فيه فقط، فإذا جربت تخزين نص أو عدد عشري فيه فستحصل على خطأ من أداة التحويل أثناء تحويل البرنامج إلى لغة الآلة وهذا ينطبق على الأمثلة الآتية أيضًا. وإذا احتجت لمتغير مخصص لتخزين قيمة عشرية مثل متوسط درجات الطالب، أو مساحة دائرة استخدم نوع البيانات float لهذا المتغير كما يلي: float avg; ولتعريف متغير مخصص لتخزين محارف مفردة يمكنك أن تستخدم نوع البيانات char كما يلي: char x; x = 'A'; أما لتخزين السلاسل النصية المكونة من عدة محارف فاستخدم نوع البيانات string كما يلي: string str = "This is a C++ string"; ولتخزين القيم المنطقية التي يمكنها أن تحتوي القيمة صواب true أو خطأ false والتي تفيد في اختبار الشروط، استخدم نوع البيانات bool كما يلي: bool con1 = false; bool con1 = true; إن التعامل مع أنواع البيانات أبسط في لغات أخرى مثل لغة بايثون، فأنت لا تحتاج لتحديد نوع بيانات للمتغير قبل استخدامه، لكون اللغة قادرة على استنباط وتعيين نوع بيانات المتغير تلقائيًا بمجرد أن تسند له قيمة ما، فبحسب نوع القيمة التي تسندها تحدد اللغة نوع البيانات المناسب له. إليك بعض الأمثلة على تعريف متغيرات من أنواع بيانات مختلفة في بايثون: v1 = "This is a Python string" #string v2 = 10 #int v3 = 10.33 #float v4 = True #bool لمزيد من المعلومات حول أنواع البيانات في لغات البرمجة، اطلع على مقال دليلك الشامل إلى أنواع البيانات. الكلمات المفتاحية تتضمن أي لغة برمجة مجموعة من الكلمات المفتاحية Keywords أو الكلمات المحجوزة Reserved Words، وهذه الكلمات لها معنى خاص ولا يمكن للمبرمج استخدامها لتعريف المتغيرات مثلًا. ولعلك انتبهت إلى قولنا كلمة مفتاحية على const وعلى int في الأمثلة السابقة في لغة C++‎ التي كانت كلمات محجوزة مخصصة لتعريف الثوابت البرمجية وأنواع البيانات، كما تعد الكلمتان True و False محجوزتين في بايثون لتمثيل القيمتين المنطقيتين صواب وخطأ على التوالي وقس على ذلك في أي لغة برمجة. وعليك أن تطلع على الكلمات المفتاحية ودلالة كل كلمة وطريقة استخدامها في اللغة التي تريد تعلمها ويكون عادة عددها محدود وبسيطة وقد تتكون من كلمة إنجليزية واضحة أو اختصار لها مثل الاختصار const لكلمة constants ثابت والاختصار init لكلمة integer عدد صحيح ومعرفة مما يتشكل الاختصار يُسهل عليك حفظ الكلمة خصوصًا وبما أن عددها محدود وبسيطة فلا تخف إن كانت لغتك الإنجليزية ضعيفة. التعليقات تعد التعليقات Comments من أساسيات البرمجة، والتعليقات هي عبارة عن نصوص وصفية تضاف للكود البرمجي لتسهيل فهمه وقراءته ويمكن أن تكون بأي لغة مثل اللغة العربية، وهي لا تنفذ في البرنامج حيث أن مترجم اللغة يتجاهلها ويعتبرها فراغات، لكنها مفيدة للمبرمج نفسه ليتذكر ما كتبه عند العودة للبرنامج لاحقًا، كما أنها تساعد أي شخص يقرأ الكود الذي كتبه المبرمج في فهم سير عمل البرنامج والهدف من كتابة تعليمات معينة فيه. تستخدم لغات البرمجة المختلفة أساليب مختلفة لكتابة التعليقات تنحصر عادة بالرموز الثلاثة # أو // أو /* */، على سبيل المثال في لغة C++‎ يمكنك كتابة التعليقات على سطر واحد بعد الرمز // وكتابة التعليقات متعددة الأسطر بين الرمزين /* */ كما يلي: /* هذا تعليق مكون من عدة أسطر */ //هذا تعليق مكون من سطر واحد أما في لغة بايثون فيمكنك كتابة التعليق أحادي السطر بعد الرمز # وكتابة التعليقات متعددة الأسطر بعد علامتي اقتباس أو ثلاث علامات اقتباس مفردة كما يلي: ''' هذا تعليق مكون من عدة أسطر ''' #هذا تعليق مكون من سطر واحد بنى التحكم تنفذ البرامج عادة بشكل متتابع من بداية الشيفرة إلى نهايتها تعليمة تلو الأخرى، لكن قد تحتاج في بعض الحالات لتغيير مسار التنفيذ وتجاوز بعض التعليمات أو تكرارها، وهنا يأتي دور بنى التحكم Control Structures التي تعتبر من أساسيات البرمجة لكونها تفيد المبرمجين في تحديد الاتجاه أو المسار الذي يجب الانتقال له بناء على عوامل معينة. بالعودة إلى مثال تعلم القيادة الذي ذكرناه بداية، تخيل أنك تسير في طريقك نحو مقر عملك، وصادفت إشارة حمراء أو اعترضتك سيارة إسعاف، ألن تحتاج عندها للتوقف لحين عودة الإشارة إلى اللون الأخضر أو التنحي لجانب الطريق لحين مرور الإسعاف ثم تتابع طريقك المعتاد. بنفس الطريقة تعمل بنى التحكم في الكود البرمجي، فهي تسمح للمبرمج بالتحكم في تدفق تنفيذ البرامج وفق حالات معينة، ومن أهم بنى التحكم البنى الشرطية if statement والبنى التكرارية loop statement. البنى الشرطية أما البنى الشرطية فتمكنك من اختبار شروط محددة قبل تنفيذ الكود البرمجي وتقوم بتنفيذه فقط عند تحقق هذه الشروط، مثلًا إذا كان لديك تعليمات برمجية تتضمن عملية قسمة، يمكنك اشتراط عدم تنفيذ هذه التعليمات عند محاولة القسمة على صفر. على سبيل المثال يقوم البرنامج التالي بلغة C++‎ بقسمة عددين عشريين ويختبر شرط القسمة على صفر: #include <iostream> using namespace std; int main() { float num1, num2, result; num1=18; num2=0; if (num2 == 0) { cout << "خطأ رياضي أنت تحاول القسمة على صفر"<<endl; } else { result=num1/num2; cout << "The result is "<< result << endl; } return 0; } تختبر التعليمة الشرطية if في الكود أعلاه إن كان المقسوم عليه num2 مساويًا للصفر (الذي يمكن أن يأتي من مواضع مختلفة مثل الطلب من المستخدم تزويدنا بقيمته)، وفي هذه الحالة تعرض العبارة "خطأ رياضي أنت تحاول القسمة على صفر" ولا تنفذ عملية القسمة num1/num2. الكود التالي كود مكافئ للكود السابق لكنه مكتوب بلغة بايثون: num1 = 18 num2 = 3 if num2 == 0: print("خطأ رياضي أنت تحاول القسمة على صفر") else: result = num1/num2 print(result) الأمثلة أعلاه كانت لشروط بسيطة، وستجد في لغات البرمجة أنواعًا عديدة من التعليمات الشرطية مثل if-else التي تمكنك من اختبار الشرط وعكسه، وتعليمة if المتداخلة التي تتضمن شرطًا فرعيًا داخل شرط رئيسي، وتعليمة switch التي تختبر شروط معتمدة على قيمة واحدة. كما ستتمكن من اختبار شروط مركبة من خلال المعاملات المنطقية مثل and و or و not. البنى التكرارية وأما البنى التكرارية أو حلقات التكرار فتمكنك من تكرار تنفيذ تعليمات معينة لعدد محدد أو مشروط من المرات، وتوفر على المبرمجين الكثير من الوقت في كتابة الكود. ستجد في أي لغة برمجة أنواعًا مختلفة من الحلقات مثل حلقات for التي تستخدم عندما تعرف عدد المرات التي تريد فيها تكرار التعليمات قبل التوقف، وحلقات while أو repeat التي تتشابه مع حلقات for لكنها تكرر مجموعة من التعليمات بعدد غير محدد من المرات يعتمد على استيفاء شرط معين. على سبيل المثال، إذا طلب منك أن تكتب برنامج لعرض ناتج ضرب العدد 5 بالأعداد من 1 إلى 10 فلا حاجة لأن تضرب العدد 5 في العدد 1 ثم في العدد 2 وهكذا وصولًا للعدد 10، يمكنك ببساطة كتابة حلقة تكرارية for كما في المثالين التاليين: حلقة for بلغة C++‎: int num=5; for (int i = 1; i < 11 ;i++) cout << num <<"X" << i << "="<< num*i << "\n"; حلقة for بلغة بايثون: num = 5 for i in range(1, 10): print(num, 'x', i, '=', num*i) الدوال الدوال Functions هي أجزاء مستقلة من الكود البرمجي لها اسم خاص بها وتشبه المصنع في عملها فتأخذ ممن يستخدمها دخلًا (إن وُجد) ثم تجري عمليات معالجة وتعيد إليه الناتج، ويدعى ما يُمرَّر إليها باسم المعاملات Parameters. تُكتب الدالة أو تعرّف مرة واحدة وتصبح بعدها قابلة لإعادة الاستخدام، حيث يمكن للمبرمج استدعاء أو مناداة الدالة في أي موضع في البرنامج مع تمرير قيم بيانات لها أو بدون، على سبيل المثال في حال أردت كتابة كود برمجي يعرض ناتج الضرب لعدد ما في الأعداد من 1 إلى 10 يمكنك تحويل الكود إلى دالة باسم displayMul وسيطها هو العدد المراد ضربه كما يلي: #include <iostream> using namespace std; // تعريف دالة لحساب نانج ضرب أي عدد في الأعداد من واحد لعشرة void displayMul(int num){ for (int i = 1; i < 11 ;i++) cout << num <<"X" << i << "="<< num*i << "\n"; } //استدعاء الدالة في البرنامج الرئيسي int main() { int num1 = 5; displayMul(num1); int num2 = 9; displayMul(num2); return 0; } عرفنا الدالة displayMul في المثال السابق بلغة C++‎ بكتابة نوع البيانات الذي تعيده الدالة وهو void أي لا شيء لأن الدالة تطبع القيمة ولا تعيد شيئًا، ثم اسمها ثم المعاملات الخاصة بها بين قوسين ()، ثم كتبنا التعليمات التي تقوم بها بين قوسين { }، ولاحظ أن الدالة لا تعيد شيئًا فلا يُشترط أن تأخذ أو تعيد شيئًا بل المهم أن تُنفِّذ عمليةً ما منوطة بها عند استدعائها. إليك أيضًا تعريف الدالة displayMul السابقة نفسها ولكن بلغة بايثون: def displayMul(num): for i in range(1, 10): print(num, 'x', i, '=', num*i) num = 5 displayMul(num) displayMul(9) ملاحظة: لا يمكنك استدعاء أو مناداة دالة في برنامجك إذا لم تقم بتعريفها أولًا، لأنك تحاول استخدام شيء غير موجود، لكن بعض الدوال تكون مضمنة ومعرفة مسبقًا في اللغة Built-in functions، ويمكنك استخدام هذه الدوال فورًا دون الحاجة لتعريفها بنفسك، على سبيل المثال الدالة "getline()‎"هي دالة جاهزة معرفة في لغة C++‎ تستخدم لإدخال السلاسل النصية من لوحة المفاتيح، والدالة print()‎ هي دالة جاهزة في لغة بايثون تستخدم لطباعة قيم المتغيرات على الشاشة. هياكل البيانات هياكل البيانات Data Structures هي بنى برمجية مصممة لتضم مجموعة من البيانات أو المتغيرات، وقد تكون هياكل أولية كالأعداد الصحيحة والأعداد العشرية والمحارف كما شرحنا في أنواع البيانات، أو هياكل مركبة يمكن تشبيهها بمجموعة صناديق متلاصقة في ذاكرة الحاسوب باستطاعتها تخزين عناصر أو متغيرات متعددة من نفس نوع البيانات ويمكن لبعض هياكل البيانات أن تتضمن مزيجًا من أنواع بيانات مختلفة. فالمصفوفة Array، والقاموس Dictionary والكائن Object وغيرها أحد أنواع هياكل البيانات الشهيرة، على سبيل المثال يمكنك استخدام المصفوفات عندما تحتاج إلى تخزين مجموعة مكونة من عدة قيم لها نفس النوع في متغير واحد بدلًا من تخزين كل قيمة في متغير منفصل، ويمكنك بعدها تحديد أي عنصر من العناصر الموجودة في المصفوفة والوصول له من خلال موقعه أو فهرسه داخل هذه المصفوفة، وإليك مثال على تعريف مصفوفة لتخزين 5 أعداد صحيحة: في لغة C++‎: int marks[5] = {50,99,78,66,59}; في لغة بايثون: marks=[50,99,78,66,59] ملاحظة: قد تختلف أسماء هياكل البيانات من لغة برمجة إلى أخرى ففي لغة بايثون لا يُطلق عليها اسم مصفوفة array كما في لغة C++‎ بل اسم قائمة list حيث تختلف التسميات والمعنى واحد. هنالك العديد من هياكل البيانات التي لا يتسع المقال الحالي لذكرها، لذا ارجع إلى مقال هياكل البيانات لمزيد من التفاصيل. التكرار يعتبر مفهوم التكرار Iteration أحد أهم مفاهيم أساسيات البرمجة، وستحتاج له لاسيما عند التعامل مع هياكل بيانات مركبة في شيفراتك البرمجية مثل المصفوفات، فالتكرار يعني المرور على كل عنصر من عناصر البيانات المركبة على حدة وعلى التوالي لتنفيذ عملية أو مهام محددة عليه، وستجد أن التكرار صفة أيضًا تُسمى iterable تُطلق على أي متغير أو نوع بيانات يمكن المرور عليه وستراها غالبًا في التوثيقات. يمكنك تنفيذ التكرار في لغات البرمجة بطرق مختلفة، لكنه يعتمد بشكل أساسي على استخدام الحلقات التكرارية بأنواعها المختلفة، كما توفر بعض اللغات مكررات Iterators وهي عبارة عن دوال أو عمليات مخصصة تمكنك من المرور على جميع عناصر هياكل البيانات بطريقة منهجية وسهلة. على سبيل المثال للمرور عبر عناصر المصفوفة marks التي عرفناها في الفقرة السابقة وطباعتها في لغة C++‎ يمكن أن نكتب حلقة for مع استخدام متغير i يمثل تعدادًا نستخدمه كفهرس للوصول إلى كل عنصر من عناصر المصفوفة كما يلي: #include <iostream> using namespace std; int main () { int marks[5] = {50,99,78,66,59}; cout << "The marks are:"; for (int i = 0; i < 5; ++i) { cout << marks[i] << " "; } } أما في لغة بايثون يمكنك المرور عبر عناصر المصفوفة وطباعتها كما يلي: marks=[50,99,78,66,59] for m in marks: print(m) التعاود يعتبر التعاود Recursion أحد المفاهيم البرمجية الأساسية، وهو يعتمد على تقسيم المشكلات البرمجية إلى مشكلات أصغر يمكن حلها بسهولة، ويرتبط هذا المفهوم بالدوال البرمجية، حيث أن الدالة التي تكرر استدعاء نفسها حتى تصل لحالة حدية أو أساسية Base case تجعلها تتوقف عن عملية استدعاء نفسها وتعيد نتيجة معروفة عند هذه القيمة تعرف باسم الدالة التعاودية Recursive Function، وإذا لم تكن هناك حالة حدية تصل لها الدالة فهذا يعني أن الدالة ستكرر استدعاء نفسها إلى مالا نهاية. هذا الأسلوب البرمجي يصلح لحل المسائل التي تملك نمطًا هرميًا والتي يمكن حلها بسهولة عن طريق تحويلها لمسائل فرعية مشابهة أصغر. لكن في حال كان بإمكانك حل مسألة معينة عن طريق الحلقات التكرارية بسهولة فلا توجد ضرورة لاستخدام أسلوب التعاود في هذه الحالة، ولا تقلق إن لم تفهم شيئًا فقد أضفنا مثالًا مع مخطط يوضح لك المفهوم تاليًا. على سبيل المثال مسألة حساب عاملي أو مضروب عدد ما "n!‎" هي أشهر مسألة تعاودية بطبيعتها، فكما تعرف مضروب العدد 0 هو قيمة معروفة تساوي 1، وبالتالي يمكن اعتبار n=0 هو الحالة الحدية التي يمكن من خلالها حل مسألة المضروب لأي عدد بناء على القاعدة التالية: n! = n * (n - 1) عندما تبلغ قيمة العدد n=0 فسوف يعيد القيمة 1 للدالة وينتهي الاستدعاء المتكرر أو التعاودي لها. إليك مثال على إيجاد مضروب أو عاملي العدد n: بلغة C++‎: #include <iostream> using namespace std; int factorial(int n) { if (n < 0) { return 0; } else if (n == 0) { return 1; } else { return factorial(n - 1) * n; } } // استدعاء الدالة في البرنامج الرئيسي int main() { cout<< factorial(4); } بلغة بايثون: def factorial(n): if n < 0: return 0 elif n == 1: return 1 else: return n * factorial(n-1) print (factorial(4)) المخطط التالي يوضح طريقة استدعاء الدالة التعاودية وإعادتها للقيمة عند وصولها للحالة الحدية لا تقلق مرة أخرى إن لم تفهمه فهو من المفاهيم المعقدة والمرعبة للمبرمجين المبتدئين، وستفهمه تدريجيًا ولا يمكن أن يتضح بالكامل إلا إن طبقته وحتى رسمته على ورقة أو مخطط كما المخطط السابق. الكائنات والأصناف تعتبر الكائنات Objects والأصناف Classes أحد أساسيات البرمجة كائنية التوجه "OOP" حيث أن الكائنات تعتبر وحدات تتضمن مجموعة من المتغيرات ومجموعة الدوال البرمجية. والصنف Class هو بمثابة نموذج أو مخطط عام لتمثيل الكائنات، يمكن تعريفه واستخدامه لاشتقاق العديد من الأمثلة أو الحالات المختلفة من هذه الكائنات، ولهذا السبب يسمى الكائن نسخة من الصنف "instance". لنأخذ مثالًا من الواقع، يمكنك تعريف صنف يسمى Car لتمثيل السيارة، سيكون لهذه السيارة خصائص مختلفة تميزها كاللون والنوع والطراز وسنة التصنيع والسعر …إلخ. كما سيكون لها أفعال أو سلوكيات تقوم بها كفعل التشغيل وزيادة السرعة وتغيير الاتجاه والتوقف …إلخ. لذا نعرف صنفًا خاصًا يمثل السيارة ونشتق منه نسخ لسيارات مختلفة. برمجيًا يعرف الصنف بداخله متغيرات ودوال، وتحدد المتغيرات الخاصة بالصنف مميزات هذا الصنف بينما تحدد دوال الصنف "class functions" ما الذي يمكن للكائنات القيام به كما يحوي الصنف على دوال خاصة منها دالة تُدعى الدالة البانية "constructor" التي تُستدعى تلقائيًا عند إنشاء واستنساخ كائن من الصنف المُعرَّف ويمكن عبرها تمرير قيم تضبط الكائن الجديد الناتج مثلًا تضبط متغيراته وإليك مثال لتوضيح ذلك. على سبيل المثال، يمكن تعريف صنف يمثل هيكل دائرة، سنعرف لهذا الصنف متغير خاص به أو خاصية تمثل قيمة نصف قطر الدائرة، ودالة بناء تضبط قيمة نصف القطر أثناء إنشاء كل دائرة، ودالة لحساب مساحة الدائرة، ودالة أخرى لحساب محيط الدائرة يمكن استدعاءهما بعد إنشاء كل كائن من الصنف دائرة. المثال التالي يعرف صنف يمثل دائرة بلغة البرمجة C++‎ ويشتق نسختين أو كائنين مختلفين من هذا الصنف لكل كائن نصف قطر مختلف: #include<iostream> using namespace std; class Circle { const float PI = 3.14; // data members float radius; public: // contractor Circle(float radius) { this->radius = radius; } // member function float Area() { return radius*radius*PI; } float Perimeter() { return 2*radius*PI; } }; int main() { Circle circle1(3); cout << circle1.Area() << endl; cout << circle1.Perimeter() << endl; Circle circle2(4); cout << circle2.Area() << endl; cout << circle2.Perimeter() << endl; return 0; } والمثال المكافئ التالي بلغة بايثون يعرف صنف دائرة ويشتق كائنين منه: #تعريف صنف يمثل دائرة class Circle(): def __init__(self, radius): self.radius = radius def get_area(self): return (self.radius ** 2) * pi def get_perimeter(self): return self.radius * 2 * pi # إنشاء كائنات من الصنف Circle pi = 3.14 circle1 = Circle(3) print(circle1.get_area()) print(circle1.get_perimeter()) circle2 = Circle(4) print(circle2.get_area()) print(circle2.get_perimeter()) لا تقلق إن لم تفهم شيئًا مما سبق فمهوم الأصناف والكائنات مفهوم دسم معقد على المبتدئين، ولكن حاول إعادة قراءة الفقرة وتطبيق الأمثلة أو يمكنك تخطيه ببساطة فالمهم أنك تعرفت على المفهوم، أما إن أردت المزيد من التفاصيل، فارجع إلى مقال البرمجة كائنية التوجه من سلسلة تعلم البرمجة. الوحدات والمكتبات لعلك لاحظت عبارات تبدأ بالكلمة using أو include أو import في الأمثلة البرمجية السابقة وتساءلت عن أهمية وجودها! هذه العبارات ليست سوى أمثلة على استخدام وحدات ومكتبات جاهزة مختلفة في لغات البرمجة. تعتبر الوحدات Modules والمكتبات Libraries أحد مفاهيم أساسيات البرمجة التي من الضروري أن تعيها جيدًا، والهدف الأساسي من وجودها تسهيل كتابة التعليمات البرمجية وتمكين المبرمج من إعادة استخدامها دون الحاجة إلى كتابة التعليمات البرمجية الخاصة بها في الكود من جديد. فالمكتبات والوحدات توفر على المبرمجين إعادة اختراع العجلة وتمكنهم من التركيز على حل المشكلة بسهولة ومرونة أكبر. توفر كل لغة برمجة العديد من المكتبات التي تضم مجموعة من الدوال والأصناف والوحدات التي يمكنك استخدامها مرارًا وتكرارًا في التعليمات البرمجية الخاصة بك لأداء مجموعة من الوظائف المفيدة دون الحاجة لإنشائها من البداية، كما يمكنك تعريف الوحدات الخاصة بك. هناك العديد من الوحدات المضمنة في لغة بايثون مثلًا والتي يمكنك استيرادها بكتابة التعليمة import ولنضرب مثلًا باستيراد الوحدة math للاستفادة من الدوال الرياضية التي توفرها بالشكل التالي: import math print (math.sqrt(25)) print (math.pi) print (math.degrees(2)) print (math.radians(90)) print (math.sin(2)) print (math.cos(0.5)) إلى هنا نكون قد انتهينا من شرح أساسيات البرمجة للمبتدئين والتي تناولنا فيها أهم المفاهيم التي ستتعرف عليها بالتفصيل في أي لغة برمجية تنوي تعلمها قبل أن تتمكن من تطوير برامجك وتطبيقاتك بهذه اللغة. ونختم مقالنا بأهم النصائح والتوصيات التي تساعدك على تعلم هذه الأساسيات. 10 نصائح لتعلم أساسيات البرمجة إليك مجموعة نصائح سريعة تساعدك في رحلة تعلم البرمجة: حدد هدفك من تعلم البرمجة، ثم تعلم ما يلزمك من تقنيات لتحققه. لا تشتت نفسك بكثرة اللغات والتنقل بينها وركز على المفاهيم وطبقها بلغة واحدة بإتقان وتركيز. ضع خطة للتعلم والتزم بها دون تسويف. لا تضيع وقتك في البحث عن أفضل المصادر التعليمية والتنقل بينها بل اختر واحدًا فقط والتزم به للنهاية. طور مهارات البحث الفعال فهذا سيوفر عليك وقتًا كبيرًا ويساعدك في إيجاد حلول لمشاكلك البرمجية. رافق المجدين ومن يشاركونك الهدف والاهتمام نفسه فإن الصاحب ساحب كما يُقال. لا تتوقف عن التعلم وطور نفسك باستمرار. تحلَّ بالصبر والأناة فإن العلم بالتعلّم والحلم بالتحلّم. تقبل الفشل والخطأ فالفشل هو وسيلة للنجاح. طبق ثم طبق ثم طبق ما تتعلمه. الخلاصة تطرقنا في مقال اليوم لشرح أساسيات البرمجة للمبتدئين وتعرفنا على أهم المفاهيم البرمجية التي ستصادفك عند تعلم أي لغة من لغات البرمجة وذكرنا في الختام أهم الأسس والنصائح التي تساعد أي مبرمج لتعلم أساسيات البرمجة من الصفر حتى الاحتراف. قد لا تتمكن من هضم جميع المفاهيم مرة واحدة خصوصًا إن كنت مبتدئًا، لذا ارجع للمقال مرة ومرتين حتى تتأكد من استيعابك لتلك المفاهيم وضعه ضمن قائمتك المفضلة وطبق الأمثلة بلغة البرمجة التي تتعلمها أو تريد تعلمها. وإذا كان لديك أي تساؤلات حول أي شيء مر معك في المقال أو كنت قد بدأت فعلا بتعلم إحدى لغات البرمجة ولديك نصائح مفيدة تود أن توجهها للمبتدئين في تعلم البرمجة، نرحب بأن تشاركنا بها في التعليقات أسفل المقال. اقرأ أيضًا أسهل لغات البرمجة البرمجة كائنية التوجه دليلك الشامل إلى: برمجة التطبيقات فوائد تعلم البرمجة
    1 نقطة
  34. بدأنا هذه السلسلة بمقال عن كيفية التعامل مع رسائل الأخطاء في بايثون وسنتابع الحديث في هذا المقال عن كيفية التعامل مع الملفات والمسارات في بايثون. وبايثون هي لغة برمجة عالية المستوى، وتفاعلية وكائنية. وتتمتع بمقروئية عالية، إذ تستخدم كلمات إنجليزية بسيطة، على خلاف اللغات الأخرى التي تستخدم الرموز، كما أنّ قواعدها الإملائية والصياغية بسيطة، ما يجعل تعلمها سهلًا موازنةً بلغات برمجة أخرى. ولعلّ الخطوة الأولى قبل الإبحار في تعلّم بايثون هي إعداد البيئة، والتي تعرّف بأنها عملية تنظيم الحاسوب اللازمة لاستخدامه في كتابة الشيفرات البرمجية، الأمر الذي يتضمن تثبيت أي أدوات ضرورية وإعدادها، والتعامل مع أي مشاكل قد تواجهك أثناء عملية الإعداد، ولإنجاز هذه الخطوة لابد من فهمك الجيد لنظام الملفات وكيفية التعامل مع المسارات في بايثون. سنحاول في هذا المقال توصيف بعض المبادئ الأساسية لمساعدتك في إدارة حاسوبك باستخدام نظام الملفات. قد يبدو فهم هذه المبادئ دون جدوى، فنحن في نهاية الأمر نسعى لكتابة الشيفرات لا، إلا أن اكتساب هذه المهارات الأساسية سيوفر عليك الوقت على المدى الطويل. نظام الملفات إن نظام الملفات هو الوسيلة التي يعتمدها نظام التشغيل لتنظيم البيانات وتخزينها واستعادتها، إذ يضم الملف خاصيتين رئيسيتين: اسم الملف (وهو عبارة عن كلمة واحدة عادةً) ومساره. لنفرض مثلًا وجود ملف على حاسوب محمول ذو نظام التشغيل ويندوز 10 يدعى project.docx ضمن المسار C:\Users\Al\Documents، يحدد المسار موقع الملف في الحاسوب، أما الجزء الذي يلي اسم الملف بعد النقطة فهو لاحقة الملف التي تبين نوعه. فيشير مثلًا اسم الملف project.docx إلى أن هذا الملف مستند لبرنامج معالج النصوص Word أما Users و Al و Documents فهي اسماء مجلدات، والتي يمكن أن تحتوي على ملفات ومجلدات أخرى. في مثالنا السابق يوجد الملف project.docx ضمن مجلد المستندات Documents الذي يوجد في المجلد Al الموجود بدوره ضمن مجلد المستخدمين Users، ويبين الشكل التالي ترتيب هذه المجلدات. ملف ضمن تسلسل هرمي للمجلدات إذ يمثل الجزء \:C من مسار الملف المجلد الأساسي الذي يحتوي على جميع المجلدات الأخرى. يعطى المجلد الأساسي في نظام التشغيل ويندوز Windows الاسم \:C، ويسمى أيضًا القرص :C، بينما في أنظمة التشغيل ماك أو إس Mac os ولينكس Linux فيشار إليه بالشكل /. سنعبّر عن المجلد الأساسي بطريقة نظام التشغيل ويندوز، أي بالشكل التالي \:C، أما إن كنت ستكتب أوامر أمثلة الصَدفة التفاعلية في نظام التشغيل ماك أو إس أو لينكس فأدخل / بدلاً عنها. هناك نماذج أخرى مثل محركات الأقراص DVD ومحركات الأقراص القابلة للإزالة USB flash drive والتي ستظهر بشكل مختلف في أنظمة التشغيل المختلفة، ففي نظام التشغيل ويندوز تظهر كمجلد أساسي جديد يحمل رمز حرف معين مثلاً \:D أو \:E، بينما في نظام ماك أو إس فتظهر كمجلد جديد ضمن المجلد Volumes/، وفي نظام التشغيل لينكس تظهر كمجلد جديد ضمن المجلد ‪/mnt ("mount") ومن الجدير بالملاحظة أن أسماء المجلدات والملفات ليست حساسة لحالة الأحرف في نظامي ويندوز أو ماك أو إس، إلا أنها كذلك في نظام تشغيل لينكس. المسارات في بايثون يُستخدم الخط المائل العكسي \ للفصل بين أسماء المجلدات والملفات في نظام التشغيل ويندوز، لكن في نظامي ماك أو إس ولينكس فيتولى الخط المائل الأمامي / تلك المهمة، لذا وبدلًا عن كتابة كل شيفرة بالطريقتين لجعل النص البرمجي المكتوب بلغة بايثون قابلاً للتطبيق على مختلف أنظمة التشغيل، يمكننا استخدام الوحدة pathlib والمعامل / بدلًا من ذلك. من الممكن استيراد مكتبة pathlib من خلال تنفيذ الأمر from pathlib import Path، ولأن صنف المسار Path هو أكثر الأصناف استخدامًا في وحدة pathlib، فمن المسموح كتابة Path وحدها بدلًا من كتابة pathlib.Path. وبإمكاننا أن نمرر إلى الدالة ()Path سلسة نصية هي عبارة عن اسم المجلد أو اسم الملف، وذلك بغية إنشاء كائن مسار Path لاسم هذا المجلد أو الملف. وبما أن أن الكائن في أقصى يسار السطر البرمجي ما هو إلا كائن مسار Path، فيمكننا الآن استخدام المعامل / لدمج كائنات أو سلاسل هذا المسار مع بعضها. والآن لنكتب الشيفرة التالية في الصدفة التفاعلية: >>> from pathlib import Path >>> Path('spam') / 'bacon' / 'eggs' WindowsPath('spam/bacon/eggs') >>> Path('spam') / Path('bacon/eggs') WindowsPath('spam/bacon/eggs') >>> Path('spam') / Path('bacon', 'eggs') WindowsPath('spam/bacon/eggs') ونلاحظ بأنه كوننا ننفذ الشيفرة السابقة على حاسوب يعمل بنظام تشغيل ويندوز، فإن الدالة ()Path تعيد كائن مسار ويندوز windowspath، في حين ستتم إعادة الكائن PosixPath في حال استخدام أحد نظامي التشغيل ماك أو إس أو لينكس. (تعد POSIX مجموعة معايير لأنظمة التشغيل الشبيهة بنظام يونيكس ولن نتطرق لها في دراستنا). ومن الممكن تمرير كائن المسار إلى أي دالة تتطلب اسم ملف في المكتبة المعيارية لبايثون. فعلى سبيل المثال يعد استدعاء الدالة التالية: open(Path('C:\\') / 'Users' / 'Al' / 'Desktop' / 'spam.py') مكافئًا لاستدعاء الدالة التالية: open(r'C:\Users\Al\Desktop\spam.py') المجلد الرئيسي ما من مستخدم إلا ولديه مجلد رئيسي يخزن فيه ملفاته على الحاسوب، ومن الممكن الحصول على كائن مسار لهذا المجلد الرئيسي باستدعاء التابع ()path.home بالشكل: >>> Path.home() WindowsPath('C:/Users/Al') وتوجد المجلدات الرئيسية في مكان محدد بناءً على نوع نظام التشغيل: توجد المجلدات الرئيسية في نظام التشغيل ويندوز ضمن C:\Users. توجد المجلدات الرئيسية في نظام التشغيل ماك أو إس ضمن Users/. توجد المجلدات الرئيسية في نظام التشغيل لينكس ضمن home/. تمتلك النصوص البرمجية غالبًا أذونات القراءة والكتابة على الملفات في المجلد الرئيسي وبالتالي تعد هذه المجلدات مكانًا مثاليًا لتخزين الملفات التي ستتعامل معها برامج بايثون. مجلد العمل الحالي لكل برنامج يعمل على الحاسوب مجلد عمل حالي (cwd) توجد فيه جميع أسماء الملفات والمسارات التي لا تبدأ بالمجلد الأساسي. وعلى الرغم من أن كلمة "مجلد folder" هي الاسم الحديث للدليل Directory، يعد cwd (أو ما يعرف بدليل العمل الحالي) هو المصطلح المعياري وليس "مجلد العمل الحالي". يمكننا الحصول على دليل العمل في هيئة كائن مسار باستخدام الدالة ()Path.cwd وتغييره باستخدام الدالة ()os.chdir، ولإنجاز ذلك سنكتب الشيفرة التالية في الصدفة التفاعلية: >>> from pathlib import Path >>> import os 1 >>> Path.cwd() WindowsPath('C:/Users/Al/AppData/Local/Programs/Python/Python38') 2 >>> os.chdir('C:\\Windows\\System32') >>> Path.cwd() WindowsPath('C:/Windows/System32') اعتبرنا في الشيفرة السابقة أن مسار دليل العمل هو: C:\Users\Al\AppData\Local\Programs\Python\Python381 وبالتالي سيكون مسار الملف project.docx كالآتي: C:\Users\Al\AppData\Local\Programs\Python\Python381\project.docx وعندما نغير دليل العمل ليصبح C:\Windows\System32 سيصبح مسار الملف project.docx بالشكل C:\Windows\System32\project.docx، وسيظهر بايثون رسالة خطأ إن غيرنا المجلد إلى مجلد غير موجود: >>> os.chdir('C:/ThisFolderDoesNotExist') Traceback (most recent call last): File "<stdin>", line 1, in <module> FileNotFoundError: [WinError 2] The system cannot find the file specified: 'C:/ThisFolderDoesNotExist' ويعد استخدام الدالة ()os.getcwd من الوحدة os هو الطريقة الأقدم للحصول على مسار دليل العمل في هيئة سلسلة نصية. المسارات المطلقة والنسبية يوجد طريقتان لتحديد مسار ملف: المسار المطلق وهو الذي يبدأ دائمًا بالمجلد الأساسي. المسار النسبي والذي يشير عادةً إلى دليل العمل الخاص بالبرنامج. وهناك أيضًا المجلدات ذات النقطة (.) أو النقطتين (..). وهي ليست مجلدات حقيقية لكنها أسماء خاصة يمكن استخدامها في المسار. فالنقطة الوحيدة (.) تعد اختصارًا للدلالة على المجلد الحالي أو "هذا المجلد"، أما وجود نقطتين (..) فيشير إلى "المجلد الأب". ويبين الشكل التالي مثالًا لبعض المجلدات والملفات، فعندما يكون دليل العمل بالشكل C:\bacon تكون المسارات النسبية للمجلدات والملفات الأخرى كما هو مبين في الشكل أدناه. أما وجود الرمز في بداية المسار النسبي فهو أمر اختياري، فعلى سبيل المثال يشير كل من spam.txt. و spam.txt إلى الملف ذاته. المسارات النسبية للملفات والمجلدات في دليل العمل C:\bacon البرامج والعمليات يعرف البرنامج بأنه أي تطبيق برمجي يمكن تشغيله، كمتصفح الويب وتطبيق جدول البيانات ومعالج النصوص، في حين أن العملية عبارة عن نسخة قيد التشغيل running instance من البرنامج، فعلى سبيل المثال يبين الشكل أدناه خمس عمليات قيد التشغيل لنفس برنامج الآلة الحاسبة. تشغيل برنامج الآلة حاسبة عدة مرات على شكل عدة عمليات منفصلة إذ تبقى العمليات منفصلة عن بعضها حتى التابعة منها لنفس البرنامج، فمثلًا إن شغلنا عدة نسخ من برنامج بايثون في نفس الوقت ضمن عمليات مستقلة، فيمكن أن يكون لكل منها قيم متغيرات خاصة بها ومختلفة، فلكل عملية دليل العمل ومتغيرات البيئة الخاصة بها وذلك حتى بالنسبة للعمليات التابعة لنفس البرنامج، وعمومًا تُشغّل نوافذ سطر الأوامر عملية واحدة في كل مرة (ومن الممكن أيضًا فتح عدة نوافذ أوامر في نفس الوقت). ولكل نظام تشغيل طريقته لعرض قائمة العمليات قيد التنفيذ، ففي نظام ويندوز من الممكن تشغيل تطبيق مدير المهام عبر الضغط على مفاتيح CTRL+SHIFT+ESC، أما في نظام ماك أو إس فيمكن الوصول إليها من قائمة التطبيقات Application ومنها نختار الخدمات Utilities ومن ثم مراقب الأداء Activity Monitor، أما في نظام أبونتو لينكس يمكننا الضغط على مفاتيح CTRL+ALT+DEL معًا لتشغيل تطبيق يدعى أيضًا بمدير المهام، ويمكن لمدير المهام أيضًا إنهاء عملية ما قيد التشغيل إن لم تكن تستجيب. الخلاصة يتضمن ضبط البيئة كافة الخطوات الضرورية لجعل الحاسوب قادرًا على تشغيل برامجنا بسهولة، وتتطلب هذه العملية منا معرفة بعض مفاهيم الأولية حول كيفية عمل الحاسوب، كفهم نظام الملفات والمسارات والعمليات. إن نظام الملفات هو الآلية التي ينظم بها الحاسوب الملفات، فلكل ملف مسار مطلق كامل أو مسار نسبي بالنسبة لدليل العمل الحالي، ويمكنك التنقل في نظام الملفات من خلال سطر الأوامر. قد يستغرق الأمر وقتًا لتعتاد التعامل مع نظام الملفات باستخدام موجه الأوامر، لذا لا تتردد في البحث مطولًا على الإنترنت عن المساعدة، فهو الأمر الطبيعي الذي يقوم به مطورو البرامج يوميًا. ترجمة -وبتصرف- للفصل الثاني "إعداد البيئة وواجهة سطر الأوامر" من كتاب Beyond the Basic Stuff with Python لصاحبه Al Sweigart. اقرأ أيضًا المقال السابق: أصول طلب المساعدات البرمجية في بايثون عبر الإنترنت التعامل مع الملفات النصية في بايثون كيفية التعامل مع الملفات النصية في بايثون 3 التعامل مع الصفوف، المجموعات والقواميس في بايثون
    1 نقطة
  35. لكل مهنة قواعد تنظمها وتضمن إنجاز الأعمال فيها بأفضل صورة ممكنة، ومهنة البرمجة ليست استثناء! حيث تعد قواعد البرمجة من الأمور التي ينبغي على أي مبرمج تعلمها، والحرص على اتباعها عند تطوير البرامج والتطبيقات المختلفة. نضعك في مقال اليوم على بداية الطريق، ونعرفك على أهم قواعد البرمجة، ونوضح لك أهمية استخدامها وكيف يمكنك تحقيقها، وبالتدريب والممارسة ستتمكن من اتباعها عندما تطور برامجك وتطبيقاتك. ما هي قواعد البرمجة؟ قواعد البرمجة هي مجموعة من التوصيات والإرشادات التي ينبغي للمبرمجين اتباعها والالتزام بها عند استخدام أي لغة من لغات البرمجة للحصول على كود برمجي عالي الجودة وسهل الصيانة. يضمن لك تطبيق قواعد البرمجة إنتاج برامج مفهومة وواضحة وسهلة القراءة والتعديل، وهو أمر مهم لأي مبرمج لاسيما عندما يعمل ضمن فريق عمل ويتشارك مع عدة مبرمجين أو مطورين على تطوير نفس المشروع. لاشك أن تطبيق قواعد البرمجة ليس بالأمر السهل ولن يتحقق بسرعة، فتطبيق القواعد يأتي في مرحلة لاحقة، فبعد أن تتمكن من أساسيات البرمجة، وتتدرب على طريقة التفكير البرمجي، وحل المشكلات، عليك أن تتقدم خطوة للأمام وتتعلم كيف تحسن من برامجك من خلال تطبيق القواعد البرمجية عليها. سنعرض الآن عددًا من أهم قواعد البرمجة فكن جاهزًا! أهم قواعد البرمجة إليك أهم ثمان قواعد أساسية ينبغي عليك اتباعها لتبرمج كالمحترفين: اتبع القواعد العرفية للغة التي تبرمج بها وثق الكود الذي تكتبه حافظ على البساطة KISS لا تكرر نفسك DRY ادمج الأجزاء الصغيرة لإنجاز الأعمال الكبيرة لا تبرمج ما لا تحتاجه افصل الأكواد في أجزاء مستقلة اكتب أكوادًا نظيفة نشرح في الفقرات التالية كل قاعدة من قواعد البرمجة هذه بمزيد من التفصيل ونوضح أهميتها وكيفية تطبيقها عند تطوير البرامج والتطبيقات. اتبع القواعد العرفية للغة التي تبرمج بها لكل لغة من لغات البرمجة قواعد كتابة خاصة بها تعرف باسم صياغة، واتباع هذه القواعد عند كتابة الكود البرمجي ليس خيارًا للمبرمج، لأن الكود البرمجي لن يعمل بشكل صحيح إذا لم يكن مكتوبًا وفق هذه القواعد. فليس المقصود هنا صياغة اللغة وقواعدها، ولكن ما أقصده هو مراعاة اصطلاحات اللغة المتعارف عليها أو ما يسمى في أوساط المبرمجين باسم "العرف" Conventions، فلكل لغة قواعد اصطلاحية متعارف عليها بين مبرمجي تلك اللغة، مثل ضرورة كتابة كل تعليمة على سطر جديد، ومراعاة قواعد التباعد، وأماكن وضع الأقواس مثل () و {} ضمن البرنامج، ووضع المسافات البادئة في كل سطر، وقواعد تسمية المتغيرات والدوال والأصناف …إلخ. هذه الأمور تتغير من لغة إلى لغة وليس لها معيار موحد، لذا عليك التعرف على اصطلاحات اللغة التي تبرمج بها وتحرص على اتباعها، فإن انتقلنا مثلًا إلى لغة جافاسكربت، فيعرض مقال نمط كتابة شيفرة جافاسكربت هذا الموضوع بالتفصيل ويتحدث عن العرف المتبع بين مبرمجي لغة جافاسكربت كما يشير أخيرًا في فقرة "شروحات لأنماط كتابة الشيفرة" أشهر المعايير والأعراف العالمية للغة جافاسكربت منها أسلوب Google وأسلوب Airbnb والأسلوب المعياري الرسمي وغيرها، فلا حاجة لكل فريق أي يخترع عرفًا ومعيارًا يسير عليه بل يقتدي بعرف شهير شائع منظم موجود مسبقًا. أضرب مثلًا عن أسلوب Airbnb في تعريف المتغيرات في لغة جافاسكربت بالشكل التالي: // سيء const items = getItems(), goSportsTeam = true; // جيد const items = getItems(); const goSportsTeam = true; لاحظ أن تعريف متغير واحد في كل سطر هو الأسلوب المتبع ويجب تجنب تعريف عدة متغيرات في سطر واحد رغم أنه لا فرق في التنفيذ بينهما. أتريد مثلًا آخر؟ خذ هذا المثال أيضًا من أسلوب PEP8 في لغة بايثون: # Line Break with Binary Operator # سيء income = (gross_wages + taxable_interest - student_loan_interest) # جيد income = (gross_wages + taxable_interest - student_loan_interest) # Imports # سيء import sys, os # جيد import os import sys قد تجد أن الاختلاف بسيط أحيانًا بين العُرف الجيد المتبع وبين الأسلوب السيء في كتابة الشيفرة وهذا صحيح، ولكن تذكر أن الشيفرة لا تُكتب مرة واحدة فقط ولن يعمل عليها شخص واحد فقط، بل ستُعدل مرارًا وتكرارًا ويمر عليها عشرات المبرمجين فإن اتبع كل مبرمج أسلوبه الخاص فُقد التنظيم وسادت العشوائية وأصبحت الشيفرة عرضة للخطأ عند تعديلها. وتذكر دومًا أن العُرف هذا يضعه مبرمجون أصحاب خبرة بعشرات السنوات يحاولون به نقل خبرتهم أفضل طريقة لكتابة شيفرة متسقة سهلة القراءة والتعديل وأقل عرضة للأخطاء. دورة علوم الحاسوب دورة تدريبية متكاملة تضعك على بوابة الاحتراف في تعلم أساسيات البرمجة وعلوم الحاسوب اشترك الآن وثق الكود الذي تكتبه هذه القاعدة على بساطتها مفيدة للغاية، فمن الضروري أن تعتاد على كتابة تعليقات توضيحية في الأكواد التي تكتبها لتوثيق عملك، وتشرح ما الذي تقوم به، وتوضح وظائف الدوال والأصناف والمكتبات المختلفة. التعليقات أمر مهم لكل مبرمج، فهي من جهة تساعده على فهم ما كتبه عند العودة له لاحقًا لأن المبرمج سينسى الكثير مما كتبته ولماذا كتبته بعد مرور فترة من الزمن، كما أن التعليقات تفيد أي مبرمج آخر يقرأ الكود في فهمه بسرعة في حال احتاج إلى تطويره أو التعديل عليه. ومن الضروري أن تتعلم أفضل ممارسات كتابة التعليقات على الكود الخاص بك، وتعرف متى وأين يتوجب عليك كتابة التعليقات ومتى لا يلزمك ذلك. اكتب التعليقات عندما تحتاج لوصف أي ميزة غير واضحة في التعليمات البرمجية، وفي أي موضع ترى أنه يتطلب المزيد من الشرح والتوضيح للآخرين، أما عندما يكون الهدف من الكود واضحًا ومفهومًا فيمكنك الاستغناء عن كتابتها. باختصار التعليقات تساعد المبرمجين على فهم المشكلات التي كنت تحاول حلها في تعليماتك البرمجية دون الحاجة لبذل كثير من الجهد لفهم واستنباط ما كتبته ولكن الأفضل من كتابة التعليقات أن تكتب شيفرة مفهومة بدون تعليقات وهذه هي القاعدة دومًا. حافظ على البساطة KISS قاعدة KISS هي اختصار لعبارة "Keep It Simple, Sweetie" التي تعني أبقها بسيطة يا عزيزي! أو أبقِ أكوادك بسيطة ومباشرة، وهذه القاعدة تطبق عند تصميم كافة الأنظمة البرمجية فقد تبين أن هذه الأنظمة تعمل بشكل أفضل إذا كانت بسيطة وخالية من التعقيد. فإذا كنت تستطيع أن تحل مشكلة ما بعشرة أسطر من الكود البرمجي لا داعي لأن تكتب خمسين سطرًا لحلها، وإذا كنت تحتاج لبرمجة نموذج ما يحتوي 10 حقول، فلا تضع فيه 20 حقلًا من البيانات التي لن تقدم أي فائدة في سير عمل برنامجك. الخلاصة، إذا كنت تطور أحد البرامج وكنت تستطيع تجنب التعقيد في كتابة الكود، فتجنبه قدر الإمكان، واحرص على إبقاء الأكواد البرمجية التي تكتبها فيه بسيطة، وتلبي المتطلبات قدر المستطاع. لا تكرر نفسك DRY من قواعد البرمجة الهامة قاعدة DRY وهي اختصار للعبارة "Don't Repeat Yourself" التي تعني لا تكرر نفسك، والتي تؤكد على المبرمج أن لا يكرر كتابة نفس الكود البرمجي مرارًا وتكرارًا، وينبغي عليه عند وجود هذه الحالة أن يتخلص من هذا التكرار بطريقة ما. لا مشكلة من تكرار نفس الكود مرة واحدة، ولكن عندما تستخدم نفس الكود عدة مرات في مواضع مختلفة من برنامجك فعليك أن تفكر في تعديله، وتجد طريقة ذكية لكتابة الكود مرة واحدة وإعادة استخدامه كلما احتجت له لتكون مطبقًا لهذه القاعدة. من المنهجيات البرمجية التي تساعدك على تقليل الكود البرمجي المكرر وجعل برامجك سهلة القراءة والصيانة هي استخدام الحلقات التكرارية التي تجنبك تكرار نفس التعليمات البرمجية وتجعل الكود البرمجي أقصر، وأيضًا استخدام الدوال والإجراءات البرمجية، وتعريف المكتبات والوحدات البرمجية التي تغلف شيفراتك البرمجية وتمكنك من إعادة استعمالها كلما أردت. ستدرك أهمية هذه القاعدة البرمجية إذا احتجت لإجراء تعديل ما في هذا الكود البرمجي المكرر، أو اكتشفت فيه خطأً ما وأردت تصحيحه، عندها سيتوجب عليك إجراء التعديلات في جميع الأماكن التي قمت فيها بإدراج هذا الكود وسيكون الأمر مرهقًا وغالبًا ستنسى ما قد كتبته حقًا، و قد لا تعدله أنت بل يعدله مبرمج آخر قد لا يفطن للتكرار مما يولد أخطاء مستقبلية. وبالتالي عندما تطور برنامجًا لحل مشكلة ما، وتجد أنك تقوم بالكثير من عمليات النسخ واللصق لنفس الكود لاستخدامه في أكثر من موضع، فابحث عن طريقة أخرى لكتابة هذا الكود، وفكر كيف يمكن أن تتجنب تكرار نفسك. ادمج الأجزاء الصغيرة لإنجاز أعمال أكبر يعتبر الدمج Composition من قواعد البرمجة المهمة، وهو يعني تجزئة المسائل البرمجية إلى مجموعة عناصر أصغر، كل جزء يقوم بمهمة محددة وواضحة، بعدها يتم دمج هذه الأجزاء لتشكيل جزء أكبر وأكثر تعقيدًا ينجز العمل بأكمله. يمكنك على سبيل المثال تطبيق هذه القاعدة إذا كنت مطور واجهة أمامية وتريد تطوير واجهة تطبيق ما وكتابة الكود البرمجي اللازم لتحقيق تصميم معين، حيث يمكنك تحويل كل عنصر من عناصر التصميم إلى مكون مستقل له الكود الخاص به، ثم تجمع هذه المكونات مع بعضها في النهاية لتحصل على التصميم الكامل. كما يتم تطبيق هذا المبدأ بشكل واضح في البرمجة كائنية التوجه OOP، من خلال تعريف صنف Class مستقل لكل جزء أو سلوك محدد من نظامك البرمجي، وجعل هذه الأصناف تتعاون مع بعضها لتنجز العمل المطلوب. باتباع هذه القاعدة ستوفر على نفسك كتابة أكواد ضخمة ومعقدة وصعبة الفهم. وتركز على برمجة كل مكون ليقوم بشيء واحد فقط، وإذا احتجت لتعديل جزء ما في برامجك فستعدل فقط الأجزاء التي طرأ عليها التعديل بكل سلاسة. فإذا كانت لديك شيفرة برمجية ضخمة لمكون ما في أحد برامجك تنجز عدة أمور مختلفة في نفس الوقت، فكر إن كان بالإمكان تقسيمها لأجزاء منفصلة أكثر تحديدًا. لا تبرمج ما لا تحتاجه من أهم قواعد البرمجة التي عليك اتباعها قاعدة YAGNI وهي اختصار للعبارة "You Aren't Gonna Need It" التي تعني أنت لن تحتاجها! لذا لا تقم ببرمجتها. فلا ينبغي عليك أن تكتب في برامجك أي أكواد لإنجاز مهام أو وظائف معينة تحل من خلالها مشكلة غير موجودة بالأساس، أو تضيف ميزة لا تحتاجها الآن لكنك تتوقع أنك ستحتاجها في مرحلة لاحقة. فإذا طلب منك على سبيل المثال كتابة كود برمجي يتحقق من صحة البريد الإلكتروني وكلمة المرور عند تسجيل دخول المستخدمين، فلا داعي لأن تتحقق أيضًا من صحة اسم المستخدم ورقم هاتفه لأنك قد لا تحتاج لهذا أبدًا. باختصار، كي تطبق هذه القاعدة ركز فقط على كتابة القدر المطلوب من الكود البرمجي الذي يحقق متطلباتك الحالية بالضبط بلا زيادة ولا نقصان، ولا داعي لأن تستشرف المستقبل. افصل الأكواد في أجزاء مستقلة يطلق على هذه القاعدة اسم فصل الاهتمامات "Separation of Interests" وهي من قواعد البرمجة الضرورية، وتؤكد على أهمية تصميم البرنامج ضمن وحدات أو أجزاء فريدة معزولة عن بعضها البعض. يعتبر أسلوب نموذج وعرض ومتحكم MVC من أوضح الأمثلة على تطبيق هذه القاعدة، ففي هذا النموذج يتم تنظيم كود البرامج ضمن ثلاثة أجزاء هي: النموذج Model الذي يتفاعل مع البيانات ويجلبها من قاعدة البيانات، والعرض View الذي يمثل الواجهة المرئية التي يتفاعل معها المستخدم بشكل مباشر، والمتحكم Controller الذي يمثل الوسيط بين العرض والنموذج ويربط بينهما. فالمتحكم يتلقى طلبات المستخدم من العرض أو واجهة المستخدم، ويعالجها، ثم يتصل بالنموذج ويطلب منه جلب ما يريده المستخدم من قاعدة البيانات، ثم يعيد النتيجة مرة أخرى إلى العرض ويظهرها على واجهة المستخدم. عند كتابة برامجك بهذا الأسلوب لن يحتاج الكود البرمجي الذي يتعامل مع قاعدة البيانات إلى معرفة تفاصبل عمل كود عرض البيانات، فكود العرض يحصل على المدخلات من المستخدم، وكود المتحكم يعالج هذه البيانات، وبهذا يكون كل جزء من الكود مستقلًا تمامًا. إن اتباع هذه القاعدة في البرمجة يمكنك من الحصول على كود برمجي سهل التطوير والصيانة، فإذا احتجت على سبيل المثال إلى إعادة كتابة كود العرض، فيمكنك القيام بذلك أن يتأثر أي شيء في كود حفظ ومعالجة البيانات. هذا الأسلوب يستخدم في العديد لغات البرمجة وأطر العمل، فمن لغات البرمجة التي تستخدم نموذج MVC لغة C++‎ و‎C# ‎ و Java و Ruby …إلخ. ومن أطر العمل التي تستخدم نموذج MVC إطار العمل أنجولر Angular وجانغو Django وفلاسك Flask ولارافيل Laravel …إلخ.‏‏‏‏‏ اكتب أكوادًا نظيفة تعد قاعدة كتابة الأكواد البرمجية النظيفة والمفهومة وسهلة الصيانة مهارة ضرورية على كل مبرمج إتقانها، ويشير مصطلح الكود النظيف Clean Code ببساطة إلى الكود سهل القراءة والفهم من قبل المبرمجين الآخرين، وعادةً عندما تتبع كافة قواعد البرمجة التي وردت أعلاه ستحصل بالنتيجة على كود نظيف بصورة تلقائية. احرص كذلك على تنظيف أكوادك من كافة التعليمات لن تستخدم عند تنفيذ البرنامج، واحذف المتغيرات التي صرحت عنها لكنك لم تستخدمها، والدوال البرمجية التي عرفتها لكنها لم تنادها على الإطلاق، والأصناف التي لم تشتق منها أي كائنات برمجية، وكذلك الأكواد التي كتبتها ثم حولتها إلى تعليقات ضمن الكود لإبطال عملها …إلخ. فهذه كلها أكواد ميّتة وأنت لا تريد أن تجعل برنامجك مقبرة! وكي تعرف بسهولة إن كان الكود الذي تكتبه نظيفًا، اعرضه على مبرمج آخر لم يسبق له أن اطلع عليه واطلب منه تعديل أمر ما فيه، فإذا تمكن المبرمج من فهم الغرض من التعليمات البرمجية الخاصة بك، وعدلها وأضاف أكواده الخاصة عليها بسهولة ومرونة، فهذا يعني أن كتبت بالفعل كودًا نظيفًا. وتذكر أن كتابة الكود النظيف ليس مهارة يمكن اكتسابها بين عشيّة وضحاها بل هو ميزة يتم تطويرها بالممارسة والتدرب على تطبيق كافة هذه القواعد كلما قمت بكتابة كود برمجي ما حتى تكتسب الخبرة المطلوبة. ملخص لأهم قواعد البرمجة التي ينبغي للمبرمج اتباعها نعرض ما يلي ملخص قواعد البرمجة التي ذكرناها ليسهل عليك تذكرها وحفظها: احرص على كتابة كود سهل القراءة والفهم مع إضافة التعليقات التوضيحية إن لزم فهي ضرورية لتوثيق وتسهيل فهم الكود وصيانته عند العودة له لاحقًا. اكتب أكوادًا بسيطة ومباشرة والمقصود هنا أن تصمم برامجك ببساطة، وتحذف أي ميزة لا تحتاجها، فالأنظمة البرمجية تعمل بشكل أفضل وتكون أسهل في الصيانة كلما كانت أبسط. افصل الأكواد في أجزاء معزولة بحيث يكون كل جزء مسؤولًا على إنجاز مهمة محددة. لا تكرر نفسك ولا تنسخ وتلصق نفس الكود في أكثر من موضع، بل اكتبه مرة وأعد استخدامه كلما دعت الحاجة. لا تضف ما لن تحتاجه كي لا تهدر وقتك ومالك على أشياء لمجرد أنك تتوقع أنك ستحتاجها لاحقًا، فقد لا تحتاجها أبدًا. اكتب كودًا نظيفًا غير مكرر أو معقد، وهو ما ستحصل عليه إذا اتبعت كل القواعد السابقة. ماذا سيحصل لو لم أتبع قواعد البرمجة؟ عندما تبدأ تعلم البرمجة ستكون سعيدًا عندما يعمل أي برنامج بالشكل الصحيح، وقد لا تعير اهتمامًا لمدى أهمية اتباع قواعد البرمجة، لكن يجب أن تضع في الحسبان أنك إذا لم تعتد على اتباع القواعد الصحيحة في كتابة أكوادك البرمجية، فإن هذا سينعكس سلبًا على أداء برامجك على المدى البعيد. في تلك الحالة قد تحصل على كود سيء وفوضوي وغير مفهوم، وصحيح أن برنامجك يعمل، لكنه سيكون مكتظَا بالأكواد البرمجية المكررة، أو الوظائف غير المستخدمة، أو المتغيرات التي لا فائدة من وجودها، وبرنامج كهذا قد يتعطل أو يفشل بعد أول تعديل أو تطوير مطلوب. فتعلم هذه القواعد وتطبيقها من شأنه أن يحسِّن من خبرتك ويطور أسلوب كتابة شيفراتك البرمجية، وأغلب أصحاب الأعمال سيطلعون على عينة من كود كتبته سابقًا وسيفضلون مبرمجًا محترفًا يتبع هذه القواعد عمن لا يتبعها. وتذكر أن البرمجة لا تقتصر على كتابة تعليمات برمجية تعمل فحسب، بل هي كتابة تعليمات برمجية فعالة ذات جودة عالية ويمكن صيانتها وتعديلها بكل مرونة سواء من قبلك أو من قبل أي مبرمج آخر، لذا احرص على اتباع هذه القواعد البرمجية والتدرب على تطبيقها قدر المستطاع لأنها سبيلك لتكون مبرمجًا ناجحًا ومتميزًا. ماذا بعد تعلم قواعد البرمجة؟ بعد أن تتقن أساسيات البرمجة وتتعلم تطبيق قواعد البرمجة قد تتساءل: كيف يمكنني المضي قدمًا وتطوير مهاراتي البرمجية بصورة أكبر؟ سؤال جيد، سأجيبك! من الأمور التي ينبغي عليك تعلمها في رحلتك لاحتراف البرمجة مهارات إعادة التصميم لمشاريعك الحالية، والتعرف على مفهوم أنماط التصميم وتطبيقها لحل المشكلات التقنية التي تواجهك مستقبلًا. يشير مفهوم إعادة التصميم "Refactoring" إلى الخطوات التي ينبغي للمبرمج اتباعها لتعديل الشيفرات البرمجية وإعادة هيكلتها وتحسينها والعثور على أي أخطاء أو ثغرات كامنة فيها، مع المحافظة على وظائفها الأساسية. أما أنماط التصميم "Design Patterns"، فهي عبارة عن نماذج يضعها المطورون لحل المشكلات المتكررة والمتشابهة، وستكتسب من خلال تعلمها القدرة على إعادة استخدام نفس الأنماط في كل مرة تظهر فيها نفس المشكلة، ويمكنك اعتبارها بمثابة فكرة مجردة توضح طريقة حل المشكلة وتسهل عليك تحقيقها برمجيًا. الخلاصة تعرفنا في مقال اليوم على أهم قواعد البرمجة التي على المبرمج اتباعها، فلا ينبغي أن تتعلم أساسيات البرمجة فقط، بل عليك أن تتقدم خطوة للأمام وتحرص على اتباع أفضل الممارسات البرمجية عند كتابة الكود كي يكون المنتج الرقمي الذي تنشؤه أكثر كفاءة وموثوقية واحترافية. وتذكر أنه يمكن للجميع كتابة كود برمجي يفهمه الحاسوب لكن القليلين فقط يمكنهم كتابة كود جيد يفهمه الإنسان أيضًا، ومن خلال حرصك على اتباع قواعد البرمجة التي شرحناها تضمن أن تكون من هذه الفئة القليلة من المبرمجين المحترفين، كل ما تحتاجه هو التدريب الجيد على كتابة الأكواد والبرامج بصورة محسنة تراعي هذه القواعد بأفضل طريقة. اقرأ أيضًا تعلم تطوير الويب دليلك الشامل إلى لغات البرمجة أسهل لغات البرمجة ما هي فوائد تعلم البرمجة؟
    1 نقطة
  36. تعرفنا في المقال السابق على كيفية التعامل مع رسائل الأخطاء في بايثون وعلى الطرق المساعدة في فهم فحواها وإيجاد مسببات ظهورها، وذلك من خلال الاستعانة بمتتبع الأخطاء لتحديد مصدر الخطأ أو باستخدام منقح صياغة لتلافي وقوع أخطاء ما أمكن، أو اللجوء إلى الإنترنت بحثًا عن تفسير لمضمون رسالة الخطأ. ولكن ماذا لو فشلت هذه المحاولات، أو إن لم تجد في بحر الإنترنت سؤالًا مشابهًا لسؤالك، في هذه الحالة لابد من طرح سؤالك في أحد المنتديات أو ربما عبر إحدى المجموعات البريدية. في حال اضطررت لطرح سؤال جديد، فيجب عليك الالتزام بالعديد من القواعد والأصول لزيادة احتمالية الرد على سؤالك. سيرشدك هذا المقال نحو كيفية طلب المساعدة البرمجية باحترافية. كيفية طلب المساعدة البرمجية عند فشل كل من عمليات البحث على الإنترنت ومنقحات الصياغة في تحديد مشكلة برنامجك وحلها، ما من سبيل أمامك سوى طلب المساعدة البرمجية عبر الإنترنت، إلا أن لطلب النصيحة آداب وأصول ليكون أكثر فعالية، فعليك الاستفادة بكفاءة من وقت مطوري البرمجيات المحترفين كونهم مستعدون للإجابة عن تساؤلاتك بالمجان. ويجب أن يكون هذا الحل هو الأخير دائمًا بالنسبة لك، فقد تمر ساعات أو أيام قبل أن يرد أحد الأشخاص على سؤالك المنشور هذا إن رد أحدهم عليه أصلًا، لذا يبقى البحث في الإنترنت هو الأسرع عبر البحث عن آخرين قد طرحوا نفس سؤالك وقراءة الإجابات التي تلقوها، ومن هنا جاءت فكرة بناء التوثيقات ومحركات البحث، بغية أتمتة عمليات الإجابة عن الأسئلة التي كان يتعين على البشر الإجابة عنها. وفي حال سدت كل السبل في طريقك واستنفذتَ خياراتك بحيث لم يتبقَ أمامك سوى خيار طرح السؤال على جمهور المبرمجين، فتجنب الأخطاء الشائعة التالية: إضاعة الوقت بالسؤال عما إذا كان من المقبول طرح سؤالك بدلًا من طرحه مباشرةً. أن يكون سؤالك ضمنيًا وغير مباشر. طرح السؤال في الموقع الإلكتروني أو المنتدى غير المناسب. أن يكون عنوان السؤال غير محدد من قبيل "لدي مشكلة" أو "أرجو المساعدة". أن تذكر كون برنامجك لا يعمل دون توضيح الطريقة التي تريدها أن يعمل بها. عدم تضمين رسالة الخطأ كاملةً. عدم مشاركة الشيفرة. مشاركة شيفرة رديئة التنسيق. عدم ذكر الخطوات التي قد جربتَها أصلًا. عدم ذكر معلومات نوع نظام التشغيل وإصداره. طلب كتابة برنامج كامل. إن قائمة "أشياء لا يجب فعلها" السابقة ليست بهدف اللباقة فحسب، وإنما لأن فعلها لن يمكّن من يرغب بمساعدتك من تحقيق ذلك، فالخطوة الأولى لأي شخص قد يساعدك تتمثّل في تنفيذ الشيفرة محاولًا إعادة إظهار المشكلة بنفس الطريقة التي واجهتك، ولإتمام ذلك لا بد من توفر الكثير من المعلومات حول شيفرتك وحاسوبك وتطلعاتك حول نتائج البرنامج. فمن الشائع جدًا تقديم معلومات قليلة جدًا حول السؤال المطروح بدلًا من تقديم الكثير منها، وسنستعرض في الأقسام التالية الممارسات الواجب اتباعها لتجنب هذه الأخطاء الشائعة وفيها سنفترض بأنك تنشر أسئلتك في أحد المنتديات البرمجية، إلا أن القواعد نفسها تنطبق في حال طرحها عبر البريد الإلكتروني لشخص واحد أو لقائمة بريدية. قلل من النقاشات غير المجدية بتقديم كافة المعلومات اللازمة مقدما لو افترضنا أنك تطرح على أحدهم سؤالك وجهًا لوجه، فسيكون من المناسب والمريح سؤاله حول إمكانية طرح سؤالك لمعرفة ما إذا كان متوفرًا، ولكن في المنتديات الأمر مختلف، فمن سيساعدك قد يؤجل رده عليك إلى حين توفر الوقت المناسب له، ونظرًا لاحتمالية وجود ساعات ما بين طرح السؤال والحصول على الردود، فمن الأفضل طرح السؤال مباشرة وتوفير كافة المعلومات التي قد يحتاجها من سيساعدك بدلًا من إضاعة الوقت في السؤال عن إمكانية طرح السؤال، وبذلك وفي حال عدم تلقيك لأي ردود، يمكنك ببساطة نسخ معلومات سؤالك كاملًا لطرحها في منتدى أخر. اطرح سؤالك على هيئة سؤال فعلي قد تفترض مجازًا أن مُساعديك على اطلاع حول ما تتحدث عنه لدى شرح مشكلتك، إلا أن البرمجة مجال واسع جدًا وقد لا يكون لديهم الخبرة في الجزئية التي تواجه مشكلة فيها، لذا من المهم طرح سؤالك على هيئة سؤال فعلي، فعلى الرغم من كون الجمل التي تبدأ بعبارات من قبيل "أريد …. " أو "الشيفرة لا تعمل" قد توضح ماهية سؤالك، إلا أنه من الضروري تضمين أسئلة صريحة ومباشرة، أي جمل تنتهي بإشارات استفهام، وإلا وفي حال عدم استخدامها قد لا يتضح تمامًا ما تطلبه. اطرح سؤالك في المكان المناسب غالبًا سيكون من غير المجدي طرح سؤال حول بايثون في منتدى مخصص لجافاسكربت، أو سؤال حول الخوارزميات في قائمة بريدية مخصصة لأمن الشبكات، فغالبًا ما تتضمن المنتديات والقوائم البريدية على مستندات تتضمن الأسئلة الشائعة FAQ أو صفحات وصف لطبيعتها والتي تبين المواضيع المناسبة للنقاش فيها. فعلى سبيل المثال تتمحور القائمة البريدية python-dev حول الميزات التصميمية للغة بايثون ولا تمثل قائمة بريدية عامة للمساعدة حول بايثون بصورة عامة. وستوجهك صفحة المساعدة إلى المكان المناسب وفق طبيعة سؤالك حول بايثون. لخص سؤالك في العنوان لعل من أحد فوائد نشر سؤالك في منتدى على الإنترنت أن المبرمجين المستقبليين ممن سيواجهون نفس المشكلة سيجدون سؤالك وإجابته لدى البحث على الإنترنت، لذا تأكد من اختيارك لعنوان يلخص سؤالك بالفعل الأمر الذي يساعد على تنظيمه في محركات البحث، فالعناوين العامة من قبيل "أرجو المساعدة" أو "لماذا لا يعمل هذا الأمر؟" مبهمة، وكذلك الأمر في حال إرسال بريد إلكتروني، ففي حال اختيارك لعنوان ذو معنى، فهذا سيساعد المتلقي على معرفة فكرة سؤالك بمجرد تصفحه لصندوقه الوارد. وضح الهدف المرجو من شيفرتك سؤال من قبيل "لماذا لا يعمل برنامجي؟" يتجاهل تفاصيل دقيقة حول ما المتوقع من هذا البرنامج فعله أصلًا، فلن يكون هذا بالأمر الجلي دائمًا لمن سيساعدك كونه لا يعرف على وجه التحديد غايتك المرجوة من البرنامج، وحتى إن كان سؤالك من نوع "لماذا يظهر هذا الخطأ لي؟" فمن المفيد أيضًا تحديد الهدف النهائي للبرنامج، ففي بعض الأحيان قد يرشدك المساعد إلى منهجية مختلفة تمامًا في تحقيق غايتك ما يجعلك تتخطى المشكلة تمامًا بدلًا من إضاعة الوقت في محاولة حلها. ضمّن رسالة الخطأ كاملة تأكد دائمًا من نسخ رسالة الخطأ بأكملها مع ملخص متتبّع الأخطاء، فإن وصف الخطأ وحده كقولك "أتلقى خطأ من نوع Out of range" لا يوفر لمن يساعدك تفاصيلًا كافية لاكتشاف ماهية الخطأ، كما يجب عليك تحديد ما إذا كان خطأً عابرًا أم دائمًا، وفي حال كنت قد اكتشفت الظروف التي يحدث عندها الخطأ، فضمّنها أيضًا في سؤالك. شارك شيفرتك كاملة إلى جانب رسالة الخطأ الكاملة وملخص متتبّع الأخطاء، شارك الشيفرة المصدرية لبرنامجك كاملةً، بحيث يتمكن من سيساعدك من تشغيلها على حاسوبه مستخدمًا منقّح أخطاء لاكتشاف ما يحدث، فيجب عليك توفير نسخة من شيفرتك فيها ما يهم من سيساعدك بالكامل بأقل تعقيد وبحيث تكون قابلة للتعديل وإعادة التنفيذ، وهذا ما أطلق عليه موقع Stack Overflow اختصارًا MCR. إذ يرمز الحرف M إلى Minimal بمعنى أن تكون الشيفرة أقصر ما يمكن مع بقائها تسبب المشكلة التي تواجهك، أما الحرف C فيرمز إلى Complete بمعنى أن تكون الشيفرة كاملة ومتضمنة كل ما يلزم لظهور المشكلة، والحرف R فيرمز إلى Reproducible بمعنى أن الشيفرة ستسبب نفس المشكلة التي تصفها عند كل تنفيذ، أما إن كان برنامجك مضمنًا في ملف واحد، فسيكون من السهل إرفاقه بسؤالك بعد التأكد من تنسيقه بطريقة صحيحة. اجعل شيفرتك مقروءة ومفهومة باستخدام التنسيق الملائم إن الهدف الرئيسي من إرفاق الشيفرة الخاصة ببرنامجك مع سؤالك هو السماح لمن سيساعدك بتشغيل هذه الشيفرة للحصول على نفس الخطأ الظاهر لديك، فلا يحتاج هذا الشخص مجرد الشيفرة فحسب، بل يحتاجها منسقة بالشكل الصحيح، فيجب عليك التأكد من كونه قادرًا على نسخها لتكون جاهزة لتشغيلها مباشرةً، فمن الجدير بالملاحظة مثلًا أن العديد من مضيفي البريد الإلكتروني يزيلون المسافات البادئة تلقائيًا، ما يجعل الشيفرة تبدو بالشكل: def knuts(self, value): if not isinstance(value, int) or value < 0: raise WizCoinException('knuts attr must be a positive int') self._knuts = value فالأمر ليس بمجرد الوقت الذي سيستغرقه من سيساعدك في إعادة إدخال المسافات البادئة لكل سطر في شيفرتك، بل وحيرته بشأن مقدارها لكل سطر. وللتأكد من الحفاظ على صحة تنسيق الشيفرة الخاصة ببرنامجك، انسخها إلى أحد مواقع مشاركة الشيفرات مثل https://pastebin.com/ أو https://gist.github.com/ والتي تخزن شيفرتك على هيئة رابط مختصَر وعام، فمثلًا إن أرفقت الشيفرة مع سؤالك على هيئة رابط مثل https://pastebin.com/XeU3yusC سيكون أيسر وأسهل من إرفاقها كملف مرفق. وإذا كنت في صدد نشر شيفرة برنامجك في أحد المواقع الإلكترونية مثل stackoverflow أو قسم الأسئلة في أكاديمية حسوب أو reddit، فتأكد من استخدامك لأدوات التنسيق التي توفرها الصناديق النصية فيها، فمثلًا باستخدامك لمسافة بادئة مكونة من أربعة مسافات سيضمن بالنتيجة استخدام نمط خط ذو تباعد مفرد للشيفرة بالغالب وهو الأسهل للقراءة، كما يمكنك تضمين الشيفرة ما بين علامات اقتباس مائلة (`) لتنسيقها بنمط خط ذو تباعد مفرد. وعادةً ما تتضمن هذه المواقع رابطًا لشرح قواعد التنسيق، والتي بعدم اتباعها ستظهر شيفرتك بشكل غير واضح، كأن تظهر مكتوبة في سطر واحد بالكامل، كما يلي: def knuts(self, value):if not isinstance(value, int) or value < 0:raise WizCoinException('knuts attr must be a positive int') self._knuts = value ومن المهم أيضًا عدم مشاركتك للشيفرة على هيئة صورة أو لقطة شاشة، الأمر الذي يجعل من المستحيل نسخها، ناهيك عن كونه في هذه الحالة -على الغالب- غير مقروء. اذكر في سؤالك جميع المحاولات التي أجريتها عند نشرك لسؤال ما، لا تنسَ إخبار من سيساعدك بما قد حاولت تجريبه كحلول وما كانت نتائج كل محاولة، لما لهذه المعلومات من دور في توفير الوقت والجهد على من سيساعدك في تجربة حلول غير ناجحة، ناهيك عن الانطباع الذي تعطيه حيال بذلك لجهد في سبيل حل مشكلتك. كما أن تقديمك لهذه المعلومات يوضح أنك تطلب المساعدة فقط، ولست اتكاليًا تنتظر من يكتب لك شيفرة لبرنامجك عوضًا عنك. فالخبر السيئ أن الكثير من طلاب علوم الحاسوب اعتادوا أن يطلبوا من الأشخاص على الإنترنت حل واجباتهم، أو من المستقلين أن يعدّو لهم تطبيقات سريعة مجانًا، متناسين أن منتديات المساعدة البرمجية لم تعد أصلًا لهذا الغرض. وصف الإعدادات التي تستخدمها إن لإعدادات حاسوبك الأثر البالغ في كيفية تنفيذ شيفرة برنامجك وعلى نوعية الأخطاء التي قد تنتج، ولضمان تمكن من سيساعدك من الحصول على نفس المشكلة التي تواجهك على حاسوبه، يجب عليك تقديم المعلومات التالية حول حاسوبك: نوع نظام التشغيل وإصداره، كأن تذكر أنه الإصدار الاحترافي من ويندوز 10 أو إصدار كاتالينا (الخامس عشر) من ماك أو إس. إصدار بايثون المستخدم في تنفيذ برنامجك، كأن تذكر بأن الإصدار 3.7 من بايثون أو الإصدار 3.6.6 منها. أي وحدات خارجية تستخدمها في برنامجك مع ذكر إصدار كل منها، كأن تذكر أنك تستخدم الإصدار 2.1.1 من وحدة جانغو. ولمعرفة إصدارات الوحدات الخارجية المستوردة في برنامجك، يمكنك تشغيل الأمر pip list، كما يمكنك التأكد من رقم إصدار كل منها باستخدام سمة الإصدار __version__، كما في المثال التالي المكتوب ضمن صَدفة بايثون التفاعلية: >>> import django >>> django.__version__ '2.1.1' ورغم كون هذه المعلومات ليست بذلك القدر من الأهمية، إلا أن ذكرها سيقلل من الوقت الضائع في النقاشات (الصد والرد)، لذا من المحبذ عرضها من البداية. أمثلة على أسئلة متكاملة نبين فيما يلي مثالًا على سؤال مطروح بطريقة صحيحة وفقًا للإرشادات والنصائح الواردة في هذا المقال: محرك الويب سيلينيوم: كيف أجد كافّة سمات العنصر؟ لدى استخدامي لوحدة سيلينيوم في بايثون، فبإمكاني الحصول على قيمة أي سمة من سمات كائن عنصر الويب باستخدام التابع ()get_attribute بالشكل: get_attribute(): foo = elem.get_attribute('href') وفي حال عدم وجود اسم السمة href، ستكون القيمة المعادة لا شيء None. سؤالي هو: كيف أحصل على قائمة بكافة سمات كل عنصر؟ فيبدو أنه لا يوجد توابع لجلب السمات من قبيل get_attributes() أو ()get_attribute_names. علمًا أني أستخدم الإصدار 2.44.0 من وحدة سيلينيوم في بايثون. لقد ورد هذا السؤال في قسم الأسئلة في أكاديمية حسوب، وفيه نلاحظ بأن العنوان قد لخص مضمون السؤال كاملًا في جملة واحدة، إذ ذُكرت المشكلة وهي التي تتحدث عن صيغة الخطأ الذي يظهر أثناء التنفيذ، وبذلك إذا قرأ شخص ما هذا العنوان مستقبلًا في نتائج البحث، فسيتضح له مباشرةً فيما إذا كان ذو صلة بسؤاله أم لا. كما أن الشيفرة ضمن السؤال منسقة بطريقة جيدة، وأجزاء النص مفصولة على هيئة فقرات، كما أن وجه السؤال واضح تمامًا، وقد تمت الإشارة له بعبارة "كيف أحل المشكلة؟"، كما يتحدث عن حدوث المشكلة أحيانًا وليس دائمًا، وهذا يدل على أن السائل قد حاول بالفعل إيجاد جواب وجرب حل الموضوع وتجريبه عدة مرات قبل أن يتجه لطرح السؤال. الخلاصة لعل وصولك إلى إجابات عن أسئلتك الخاصة بنفسك هي واحدة من أهم المهارات التي عليك اكتسابها كمبرمج، وهنا يمثّل الإنترنت ثروة من المصادر المتضمنة الإجابات التي تحتاج. إلا أن الإجراء الأول الذي يجب اتخاذه هو محاولة تحليل رسالة الخطأ المبهمة المعروضة من قبل بايثون، وفي حال عدم تمكنك من إيجاد حل لمشكلتك عبر البحث في الإنترنت، فحاول عندها نشر سؤالك في أحد المنتديات البرمجية أو إرسال بريد إلكتروني لأحد المختصين، إذ قدمنا في هذا المقال نصائح وإرشادات من شأنها ضمان كون هذه العملية فعالة ومثمرة من خلال طرح سؤال جيد. وتتمثل مواصفات السؤال الجيد في كونه محددًا ومفصلًا، يوفر الشيفرة المصدرية المسببة للخطأ كاملةً بالإضافة إلى رسالة الخطأ نفسها، شارحًا الإجراءات المجربة أصلًا مع تحديد نوع نظام التشغيل وإصدار بايثون المستخدم. وبحصولك على إجابة لسؤالك، لن تقتصر الفائدة عليك، بل على أي مبرمج مستقبلي قد يواجه نفس مشكلتك. وتذكر أن البرمجة مجال واسع جدًا، ولا يمكن لأحد أن يحيط بجميع تفاصيله، لذا لا تشعر بالإحباط إن اضطررت للبحث باستمرار عن إجابات لأسئلتك، فحتى مطورو البرمجيات المتمرسون يبحثون في الإنترنت عن التوثيقات والحلول يوميًا، وبدلًا من تضييع وقتك بالإحساس بالإحباط ركز على اكتساب مهارة إيجاد الحلول، وهي خطوة مهمة في طريقك لتصبح خبير بايثون. ترجمة -وبتصرف- للفصل الأول "التعامل مع الأخطاء وطلب المساعدة" من كتاب Beyond the Basic Stuff with Python لصاحبه Al Sweigart. اقرأ أيضًا المقال السابق: التعامل مع رسائل الأخطاء في بايثون كيفية استخدام سطر أوامر بايثون التفاعلي كيفية التعامل مع الأخطاء البرمجية
    1 نقطة
  37. تعد بايثون Python إحدى أشهر لغات البرمجة وأكثرها استخدامًا، وهي خيار ممتاز ليبدأ به المبرمجون المبتدئون، إذ يمكن استخدامها في معظم المجالات، بدءًا من ألعاب الفيديو، وحتى تحليل البيانات والتعلم الآلي. بايثون هي لغة برمجة عالية المستوى، وتفاعلية وكائنية. وتتمتع بمقروئية عالية، إذ تستخدم كلمات إنجليزية بسيطة، على خلاف اللغات الأخرى التي تستخدم الرموز، كما أنّ قواعدها الإملائية والصياغية بسيطة، ما يجعل تعلمها سهلًا موازنةً بلغات برمجة أخرى. وفي بدايات تعلّمك لغة بايثون ، وكما هو الحال في رحلة تعلّم أي لغة برمجة، قد تواجهك بعض العقبات ورسائل الأخطاء غير المفهومة، وفي هذه المرحلة من الشائع الشعور بالفشل لدى اضطرارك لاستشارة مواقع الإنترنت عدة مرات في اليوم. لكن حتى أمهر مطوري البرمجيات يبحثون في الإنترنت ويراجعون التوثيقات لإيجاد إجابات حول أسئلتهم البرمجية. كن على يقين بأنه طالما أنك لا تمتلك الموارد الاجتماعية أو المادية اللازمة للحصول على مدرس خصوصي للإجابة على أسئلتك البرمجية، فما من سبل أمامك سوى حاسوبك والإبحار في محركات البحث وصبرك، والخبر الجيد أنه من شبه المؤكد كون جميع تساؤلاتك قد طُرحت من قبل. فحتى تكون مبرمجًا لا بد من امتلاكك مهارة إيجاد إجابات على أسئلتك بنفسك، الأمر الذي يفوق بأهميته معرفتك لأي خوارزمية برمجية أو بنية معطيات ما. سيعمل هذا المقال على إرشادك نحو تطوير هذه المهارة البالغة الأهمية. كيفية فهم رسائل الأخطاء في بايثون عندما يواجه العديد من المبرمجين رسائل الأخطاء المليئة بالثرثرة التقنية، فإن أول ما يفكرون بفعله هو تجاهلها تمامًا، إلا أن رسالة الخطأ هذه تتضمن الإجابة حول الخطأ الحاصل في البرنامج، فإيجاد هذه الإجابة عبارة عن عملية ذات خطوتين: الأولى هي فحص متتبع الأخطاء، والثانية هي البحث في الإنترنت حول رسالة الخطأ هذه. فحص متتبع الأخطاء تتوقف برامج بايثون عن العمل لدى مصادفتها استثناءً دون وجود عبارة استثناء except للتعامل معه، وفي حال حدوث ذلك، تُعرض رسالة بهذا الاستثناء مع تتبّع له وهو ما يدعى أيضًا مكدّس الاقتفاء Stack trace، والذي يُظهر مكان حدوث الاستثناء في برنامجك ومسارات استدعاءات الدوال المسببة له. وبغية التدرب على كيفية قراءة تتبعات الأخطاء، سنكتب البرنامج البسيط التالي ونحفظه باسم abcTraceback.py، إذ تلعب أرقام الأسطر دور المرجع والدليل للسطر وليست جزءًا من الشيفرة. 1. def a(): 2. print('Start of a()') 1 3. b() # Call b(). 4. 5. def b(): 6. print('Start of b()') 2 7. c() # Call c(). 8. 9. def c(): 10. print('Start of c()') 3 11. 42 / 0 # This will cause a zero divide error. 12. 13. a() # Call a(). في البرنامج السابق، تستدعي الدالة ()a الدالة ()b، التي تستدعي بدورها الدالة ()c المتضمنة للتعبير الرياضي 42/0 المسبب لخطأ القسمة على صفر، فعند تشغيل هذا البرنامج، سيبدو الخرج بالشكل: Start of a() Start of b() Start of c() Traceback (most recent call last): File "abcTraceback.py", line 13, in <module> a() # Call a(). File "abcTraceback.py", line 3, in a b() # Call b(). File "abcTraceback.py", line 7, in b c() # Call c(). File "abcTraceback.py", line 11, in c 42 / 0 # This will cause a zero divide error. ZeroDivisionError: division by zero لنتفحص الآن تقرير متتبع الأخطاء سطرًا بسطر، والذي يبدأ من السطر: Traceback (most recent call last): وتهدف هذه الرسالة إلى إبلاغك بأن ما يتلوها هو تقرير متتبّع الأخطاء، وتشير العبارة most recent call last والتي تعني أن الاستدعاء الأخير سيظهر في نهاية التقرير إلى كون استدعاءات التوابع ستظهر في التقرير بنفس ترتيب ورودها في الشيفرة، بدءًا من استدعاء أول دالة وانتهاءً بآخرها. أما السطر التالي فيظهر تقرير تتبّع استدعاء أول دالة: File "abcTraceback.py", line 13, in <module> a() # Call a(). وندعو هذين السطرين بملخص كائن الإطار، كما أنهما يُظهران معلوماتهما ضمن كائن إطار. فعند استدعاء دالة ما فإن كل من بيانات المتغير المحلي والمكان المخصص في الشيفرة لإسناد القيمة المعادة من الدالة بعد استدعائها يُخزنان ضمن كائن إطار، إذ تتضمن كائنات الأطر كل من المتغيرات المحلية وغيرها من البيانات المتعلقة باستدعاء الدوال، إذ يتم إنشاء هذه الكائنات لحظة استدعاء الدوال وينتهي بإعادة الدالة لقيمتها. ويُظهر متتبّع الأخطاء ملخصًا على هيئة إطار لكل إطار قد انتهى دوره بإعادة قيمة دالته، ونلاحظ من التقرير أعلاه أن استدعاء هذه الدالة قد تم في السطر ذو الرقم 13 من الملف abcTraceback.py، ويشير الوسم <module> إلى كون هذا السطر مصرح عنه ضمن المجال العام، ليظهر بعدها السطر 13 نفسه مسبوقًا بمسافتين بادئتين. وتظهر الأسطر الأربعة التالية ملخصات الأطر التالية: File "abcTraceback.py", line 3, in a b() # Call b(). File "abcTraceback.py", line 7, in b c() # Call c(). ومنه نستنج أنه قد تم استدعاء الدالة ()b في السطر الثالث ضمن الدالة ()a، ما أدى بدوره إلى استدعاء الدالة ()c في السطر 7 ضمن الدالة ()b. ومن الجدير بالملاحظة أن تقرير التتبع لا يُظهر استدعاء الدالة ()print الذي تم في كل من الأسطر 2 و 6 و 10 من الشيفرة رغم تشغيلها حتى قبل استدعاء الدوال آنفة الذكر، والسبب في ذلك هو أن التقرير يشمل فقط الأسطر الحاوية على استدعاءات التوابع المسببة للاستثناء. وآخر إطار من ملخص تقرير تتبع الأخطاء يظهر رقم السطر المتضمن للاستثناء الذي لم يتم التعامل معه متبوعًا باسمه ورسالة الخطأ الخاصة به: File "abcTraceback.py", line 11, in c 42 / 0 # This will cause a zero divide error. ZeroDivisionError: division by zero ومن الجدير بالملاحظة أن رقم السطر المعطى في متتبع الأخطاء هو مكان عثور بايثون على آخر خطأ، وبالتالي من الممكن كون مصدر الخطأ الرئيسي في سطر ما قبله. وتُعرف رسائل الخطأ بكونها مختصرة ومبهمة، فالكلمات الثلاث "قسمة على صفر" لن تعني شيئًا ما لم تكن تعلم أنه من المستحيل قسمة أي عدد على الصفر رياضيًا وبأنه يمثل خطأً برمجيًا شائعًا، وفي برنامجنا السابق ليس من الصعب تحديد موطن الخطأ، فبمجرد النظر إلى رقم سطر الشيفرة في إطار ملخص تقرير متتبع الأخطاء يتضح أن خطأ القسمة على صفر يحدث عند التعبير 42/0 من الشيفرة. والآن دعونا ننتقل إلى حالة أصعب قليلًا. لذا، اكتب الشيفرة التالية ضمن محرر النصوص واحفظ الملف باسم zeroDivideTraceback.py: def spam(number1, number2): return number1 / (number2 - 42) spam(101, 42) ولدى تشغيل هذا البرنامج، سيبدو الخرج كالتالي: Traceback (most recent call last): File "zeroDivideTraceback.py", line 4, in <module> spam(101, 42) File "zeroDivideTraceback.py", line 2, in spam return number1 / (number2 - 42) ZeroDivisionError: division by zero إن رسالة الخطأ هي نفسها كما في المثال السابق، إلا أن خطأ القسمة على صفر في السطر البرمجي return number1 / (number2 - 42) غير واضح تمامًا، ولكن من الممكن استنتاج وجود عملية قسمة من وجود المعامل /، وبأن التعبير (number2-42) يساوي الصفر، وهذا ما يمكننا من استنتاج أن الدالة spam() ستعطي خطأ في حال كان الوسيط الثاني number2 المُمرر لها مساويًا للعدد 42. وقد يشير متتبّع الأخطاء أحيانًا إلى كون الخطأ في السطر التالي لمسبب الخطأ الحقيقي. فعلى سبيل المثال، في البرنامج التالي ينقص السطر الأول منه قوس إغلاق دالة الطباعة: print('Hello.' print('How are you?') إلا أن رسالة الخطأ لهذا البرنامج تشير لكون المشكلة في السطر الثاني منه: File "example.py", line 2 print('How are you?') ^ SyntaxError: invalid syntax والسبب في ذلك هو أن مفسر بايثون لن يلاحظ هذا الخطأ إلا عند قراءته للسطر الثاني، فقد يشير متتبّع الأخطاء إلى مكان حدوث الخطأ والذي لن يكون بالضرورة هو نفس موضع مسبب حصول الخطأ الفعلي. وفي حال فشل إطار الملخص في تقديم ما يكفي من معلومات لاكتشاف الخطأ، أو في حال كون المسبب الحقيقي للخطأ في سطرٍ سابق غير موضح في متتبّع الأخطاء، عندها عليك المرور على برنامجك مستخدمًا منقّح الأخطاء، كما يمكنك التحقق من رسائل السجل بحثًا عن السبب. الأمر الذي قد يستغرق وقتًا ليس بالقليل، لذا فإن البحث في الإنترنت حول المشكلة قد يعطيك دلائل مهمة حول كيفية حلها بسرعة أكبر. البحث حول رسائل الخطأ تكون رسائل الأخطاء في الغالب قصيرة جدًا ولا تمثل جملًا كاملة، والسبب في ذلك هو كونها رسائل تذكيرية وليست تفسيرية، إذ يصادفها المبرمجون بانتظام. وإذا كنت تواجه رسالة خطأ للمرة الأولى، فإن نسخها ولصقها في أحد محركات البحث على الإنترنت سيوصلك في الغالب إلى شرح تفصيلي حول الخطأ وأسباب حدوثه المحتملة. ويبين الشكل التالي نتائج البحث عن الجملة python "ZeroDivisionError: division by zero" أي "خطأ القسمة الصفرية: قسمة على صفر" بايثون، إذ من المفيد تضمين رسالة الخطأ ما بين إشارتي تنصيص في إيجاد عبارة موافقة بدقة، كما أن إضافة كلمة Python يؤدي إلى تضييق نطاق البحث أكثر. نسخ رسالة خطأ ولصقها في إحدى أدوات البحث على الإنترنت يمكن أن يؤمن تفسيراتٍ وحلولًا سريعة. ولا يمكن عد البحث حول رسائل الخطأ شكلًا من أشكال الغش أو الاتكالية، فمن شبه المستحيل أن يحفظ الشخص كافة رسائل الخطأ المحتملة لأي لغة برمجة، إذ يبحث مطورو البرمجيات المحترفون عن إجابات لأسئلتهم البرمجية في الإنترنت يوميًا. وفي حال كون أحد أجزاء رسالة الخطأ التي تواجهك هو خاص بشيفرتك أنت، فمن الأفضل استبعاده أثناء البحث، ولتوضيح هذه النقطة لنأخذ رسائل الخطأ التالية: >>> print(employeRecord) Traceback (most recent call last): File "<stdin>", line 1, in <module> 1 NameError: name 'employeRecord' is not defined >>> 42 - 'hello' Traceback (most recent call last): File "<stdin>", line 1, in <module> 2 TypeError: unsupported operand type(s) for -: 'int' and 'str' يوجد في هذا المثال خطأ كتابي في اسم المتغير employeRecord ما سبب حدوث الخطأ 1، وبما أن المعرف employeRecord خاص بشيفرتك، وذلك في رسالة الخطأ NameError: name 'employeRecord' is not defined والتي تعني حدوث خطأ في الاسم بسبب كون اسم المتغير employeRecord غير معرف. أما في السطر الأخير فمن الواضح أن الأجزاء int و str من رسالة الخطأ 2 تعود للقيم 42 و hello على التوالي، ففي هذه الحالة من الأفضل اقتصار البحث على العبارة python "TypeError: unsupported operand type(s)" for والتي تعني خطأ في نمط البيانات ناتج عن كون أحد المعاملات ذو نمط غير مدعوم، وذلك بدلًا من تضمين البحث بأجزاء من الرسالة تخص شيفرتك على وجه التحديد، وإذا فشل هذا البحث المختصر في الوصول إلى نتائج مفيدة، فجرب كتابة رسالة الخطأ كاملةً. تجنب حدوث الأخطاء باستخدام منقحات الصياغة لعل الطريقة الأفضل في إصلاح الأخطاء هي عدم الوقوع بها من الأصل، وهنا يأتي دور منقّحات الأخطاء Linters، وهي عبارة عن تطبيقات تعمل على تحليل الشيفرة المصدرية لتنبهك حول أي خطأ محتمل فيها، أما اسمها "Linters" فقد أتى تيمنًا بأداة جمع الألياف الصغيرة والأوبار في مجفف الملابس. ورغم كون منقّح الأخطاء لن يكتشف أخطاء الشيفرة بالكامل، إلا أن التحليل الساكن الذي يجريه (أي فحص الشيفرة المصدرية دون تشغيلها) قادر على تحديد العديد من الأخطاء الشائعة الناتجة عن الأخطاء الإملائية وسنستعرض في مقالات لاحقة كيفية استخدام تلميحات الكتابة التي يقدمها التحليل الساكن. وتتضمن العديد من محررات النصوص وبيئات التطوير البرمجية المتكاملة IDEs على منقّحات صياغة تعمل في الخلفية، والقادرة على التنبيه إلى الأخطاء المكتشفة بالزمن الحقيقي كما هو موضح في الشكل التالي. منقّح صياغة يشير إلى متغير غير مصرح عنه وذلك في محرر النصوص MU (الشكل الأعلى) وفي المحرر PyCharm (الشكل الأوسط) وفي المحرر Sublime (الشكل الأسفل). وبذلك تعمل إشعارات الأخطاء شبه الفورية التي يوفرها منقّح الأخطاء على تحسين إنتاجية العمل البرمجي بشكل ملموس، فبدون وجوده ستضطر إلى تشغيل برنامجك لتكتشف وجود خطأ، منتقلًا إلى ملخص متتبّع الأخطاء بحثًا عن السطر في الشيفرة المصدرية المتسبب في الخطأ لإصلاح الخطأ الإملائي المسبب له، ولكن ماذا لو ارتكبت عدة أخطاء إملائية؟ عندها لن تجدها إلا بإعادة تنفيذ البرنامج عدة مرات فكل دورة تشغيل ستجد خطأ واحد تتوقف عنده، في حين أن منقّحات الصياغة قادرة على الإشارة لوجود عدة أخطاء معًا ويتم ذلك مباشرةً في محرر النصوص أثناء كتابة الشيفرة، ما يمكنك من تحديد السطر الذي حدثت فيه المشكلة مباشرةً. وقد لا يأتي محرر النصوص أو البيئة البرمجية المتكاملة التي تستخدمها مع منقّح صياغة أصلًا، ولكن إن كانت تدعم الإضافات، فمن شبه المؤكد وجود منقّح صياغة كإضافة، وغالبًا ما تستخدم هذه الإضافات وحدة تنقيح صياغة تدعى Pyflakes أو وحدات أخرى تؤدي هذا الغرض. وبإمكانك تثبيت الوحدة Pyflakes من الرابط https://pypi.org/project/pyflakes/ أو باستخدام أمر تثبيت الحزم pip بكتابة الأمر pip install --user pyflakes، الأمر الذي يستحق العناء لإنجازه. ملاحظة: يمكنك في نظام ويندوز تشغيل كل من الأمرين pip و python، ولكن في حال استخدامك لأنظمة ماك أو إس أو لينكس فتكون أسماء هذين الأمرين بهذا الشكل فقط من أجل الإصدار الثاني من بايثون، أما للإصدار الثالث فيصبحان بالشكل pip3 و python3، انتبه لهذا الموضوع كلما صادفت أحد الأمرين pip أو python في سياق المقال. تأتي بيئة التطوير المتكاملة الخاصة ببايثون IDLE بدون منقّح صياغة وبدون القابلية لتثبيته فيها. الخلاصة لعل وصولك إلى إجابات عن أسئلتك الخاصة بنفسك هي واحدة من أهم المهارات التي عليك اكتسابها كمبرمج، وهنا يمثل الإنترنت ثروة من المصادر المتضمنة الإجابات التي تحتاج. إلا أن الإجراء الأول الذي يجب اتخاذه هو محاولة تحليل رسالة الخطأ المبهمة المعروضة من قبل بايثون، ولا تقلق إن لم تفهم محتواها، فبإمكانك نسخ نص الرسالة إلى أحد محركات البحث وصولًا إلى تفسير حولها باللغة الإنجليزية العادية مع بيان سببها المحتمل، كما أن متتبع الأخطاء سيشير إلى مكان وقوع الخطأ في شيفرة برنامجك. وهنا يلعب منقح الصياغة دورًا مهمًا في الإشارة إلى وقوع الأخطاء المطبعية والمشاكل المحتملة لحظة وقوعها، فهذه المنقحات مفيدة جدًا ولا غنى عنها في التطوير الفعال للبرمجيات، وفي حال كون محرر النصوص أو بيئة التطوير التي تستخدمها لا تملك منقحًا وغير قابلة لإضافته، فمن المفضل أن تنتقل إلى أحد المحررات التي تدعم وجود منقحات الصياغة. وتذكر أن البرمجة مجال واسع جدًا، ولا يمكن لأحد أن يحيط بجميع تفاصيله، لذا لا تشعر بالإحباط إن اضطررت للبحث باستمرار عن إجابات لأسئلتك، فحتى مطورو البرمجيات المتمرسون يبحثون في الإنترنت عن التوثيقات والحلول يوميًا، وبدلًا من تضييع وقتك بالإحساس بالإحباط ركز على اكتساب مهارة إيجاد الحلول، وهي خطوة مهمة في طريقك لتصبح خبير بايثون. ترجمة -وبتصرف- للفصل الأول "التعامل مع الأخطاء وطلب المساعدة" من كتاب Beyond the Basic Stuff with Python لصاحبه Al Sweigart. اقرأ أيضًا كيفية التعامل مع الأخطاء البرمجية أساسيات البرمجة بلغة بايثون إعداد بيئة العمل للمشاريع مع بايثون النسخة العربية الكاملة لكتاب البرمجة بلغة بايثون
    1 نقطة
  38. تُعد مكتبة NumPy إحدى مكتبات لغة بايثون Python وتُستخدم للتعامل مع المصفوفات، وتهدف إلى توفير كائن مصفوفة أسرع بما يصل إلى 50 مرة من قوائم بايثون التقليدية. يطلق على كائن المصفوفة في مكتبة NumPy اسم ndarray، ويوفر العديد من الوظائف الداعمة التي تجعل التعامل مع المصفوفات أمرًا سهلًا جدًا. تعتمد مكتبة NumPy على العمليات على المتجهات vectorization، فإذا كنت معتادًا على التعامل مع لغة بايثون، فهذه هي الصعوبة الرئيسية التي ستواجهها لأنك ستحتاج إلى تغيير طريقة تفكيرك، كما ستتغير نوع العناصر التي ستستخدمها. أكثر العناصر شيوعًا في مكتبة NumPy هي المتجهات vectors والمصفوفات arrays والعروض views والدوال العمومية ufuns. هذا المقال جزء من سلسلة متقدمة حول NumPy وإليك كامل روابط السلسلة: مفاهيم متقدمة حول مكتبة NumPy في بايثون استخدام المتجهات vectorization في لغة بايثون مع مكتبة NumPy الاعتماد على المتجهات في حل المشاكل باستعمال مكتبة NumPy في بايثون تخصيص أسلوب المتجهات Custom vectorization عبر استعمال مكتبة NumPy ما بعد مكتبة NumPy في بايثون مثال بسيط سنأخذ مثالًا بسيطًا وهو المشي العشوائي random walk، إذ يتوجب علينا في الطريقة التقليدية المعتمدة على البرمجة كائنية التوجه OOP تعريف صنف class يأخذ الاسم RandomWalker، ثم إنشاء التابع walk لإرجاع الموقع الحالي بعد كل خطوة عشوائية. يمكن تنفيذ هذا المثال باستخدام التعليمات البرمجية التالية: class RandomWalker: def __init__(self): self.position = 0 def walk(self, n): self.position = 0 for i in range(n): yield self.position self.position += 2*random.randint(0, 1) - 1 walker = RandomWalker() walk = [position for position in walker.walk(1000)] وتعطي تجربة قياس السرعة النتيجة التالية: >>> from tools import timeit >>> walker = RandomWalker() >>> timeit("[position for position in walker.walk(n=10000)]", globals()) 10 loops, best of 3: 15.7 msec per loop النهج الإجرائي Procedural approach يمكننا لحل مثل هذه المشكلة البسيطة حفظ تعريف الصنف والتركيز على دالة المشي walk التي تحسب المواقع المتتالية بعد كل خطوة عشوائية. def random_walk(n): position = 0 walk = [position] for i in range(n): position += 2*random.randint(0, 1)-1 walk.append(position) return walk walk = random_walk(1000) توفر هذه الطريقة من استهلاك وحدة المعالجة المركزية CPU ولكن ليس لحدٍ كبير لأنها تشبه الطريقة السابقة المعتمدة على البرمجة كائنية التوجه. >>> from tools import timeit >>> timeit("random_walk(n=10000)", globals()) 10 loops, best of 3: 15.6 msec per loop النهج المعتمد على المتجهات Vectorized approach يمكننا باستخدام وحدة itertools تحسين الأداء بطريقة أفضل، إذ تقدم هذه الوحدة مجموعةً من الدوال لإنشاء تكرارات لحلقات فعالة. نلاحظ أن مثال المشي العشوائي ما هو إلا تراكم خطوات، لذلك سنعيد كتابة الدالة بإنشاء جميع الخطوات أولًا، ثم تجميعها بدون استخدام أي حلقة، كما توضح التعليمات التالية: def random_walk_faster(n=1000): from itertools import accumulate # Only available from Python 3.6 steps = random.choices([-1,+1], k=n) return [0]+list(accumulate(steps)) walk = random_walk_faster(1000) اعتمدنا في هذا المثال على المتجهات في الدالة، فبدلًا من استخدام التكرار لاختيار الخطوات وإضافتها إلى الموضع الحالي، أنشأنا أولًا جميع الخطوات دفعةً واحدةً، ثم استخدمنا دالة التجميع accumulate لحساب جميع المواضع. تخلصنا من الحلقة وبالتالي أصبح تنفيذ التعليمات أسرع: >>> from tools import timeit >>> timeit("random_walk_faster(n=10000)", globals()) 10 loops, best of 3: 2.21 msec per loop لاحظ أننا وفرنا 85% من وقت الحساب مقارنةً بالإصدار السابق، لكن الإيجابية التي تميز الإصدار الجديد هي تبسيط العمليات المعقدة على المتجهات. سنحتاج إلى استبدال أدوات itertools بأدوات numpy: def random_walk_fastest(n=1000): # No 's' in numpy choice (Python offers choice & choices) steps = np.random.choice([-1,+1], n) return np.cumsum(steps) walk = random_walk_fastest(1000) هذه الطريقة سهلة وتوفر الكثير من الوقت كما توضح النتائج التالية: >>> from tools import timeit >>> timeit("random_walk_fastest(n=10000)", globals()) 1000 loops, best of 3: 14 usec per loop يركز هذا الدليل يركز على الاعتماد على المتجهات سواءٌ كان ذلك على مستوى المشكلة أو الشيفرات البرمجية، وسنوضح أهمية هذا الاختلاف قبل الانتقال إلى دراسة المتجهات المخصصة. سهولة القراءة مقابل السرعة قبل الانتقال إلى القسم التالي، سنلقي نظرةً على مشكلة محتملة قد تواجهها بعد أن تصبح على دراية بمكتبة NumPy؛ فمكتبة NumPy مكتبة قوية جدًا ويمكنك أن تصنع العجائب بها، ولكن هذا على حساب سهولة القراءة، لذلك إذا أهملت إضافة التعليقات أثناء كتابة التعليمات البرمجية، فلن تتمكن من معرفة وظيفة بعض التعليمات بعد بضع أسابيع أو ربما أيام. على سبيل المثال هل يمكنك معرفة ما هي نتيجة تنفيذ الدالتين التاليتين؟ ربما ستتمكن من فهم الدالة الأولى ولكن من غير المرجح أن تفهم الثانية: def function_1(seq, sub): return [i for i in range(len(seq) - len(sub)) if seq[i:i+len(sub)] == sub] def function_2(seq, sub): target = np.dot(sub, sub) candidates = np.where(np.correlate(seq, sub, mode='valid') == target)[0] check = candidates[:, np.newaxis] + np.arange(len(sub)) mask = np.all((np.take(seq, check) == sub), axis=-1) return candidates[mask] استخدمت الدالة الثانية مكتبة NumPy وهي أسرع بعشر مرات، ولكن المشكلة هي بصعوبة قراءة وفهم التعليمات البرمجية التي تستخدمها. تشريح المصفوفة كما أوضحنا سابقًا ينبغي أن تكون لديك خبرةً أساسيةً في التعامل مع مكتبة NumPy قبل المتابعة في هذا الدليل، وإذا لم يكن لديك هذه الخبرة فمن الأفضل أن تتعلم عنها قبل العودة إلى هنا، وبناءً على ذلك سنبدأ هذا الدليل بتذكير سريع على الهيكلية الأساسية للمصفوفات المعقدة، خاصةً بما يتعلق بتخطيط الذاكرة وعرضها ونسخ البيانات وتحديد نوعها، وهذه مفاهيم أساسية يجب أن تفهمها إذا كنت تريد أن تستفيد من فلسفة مكتبة numpy. لنفكر في مثال بسيط نريد من خلاله مسح جميع القيم في مصفوفة من النوع np.float32. كيف يمكن كتابة تعليمات تنفذ المثال السابق بسرعة؟ الصيغة أدناه واضحة إلى حد ما (على الأقل لأولئك الذين هم على دراية بمكتبة NumPy) ولكن السؤال أعلاه يطلب العثور على أسرع عملية. >>> Z = np.ones(4*1000000, np.float32) >>> Z[...] = 0 إذا دققت بنوع عناصر المصفوفة dtype وحجمها، يمكنك ملاحظة أنه يمكن تحويل هذه المصفوفة إلى العديد من أنواع البيانات "المتوافقة" الأخرى. نقصد هنا أنه يمكن تقسيم Z.size * Z.itemsize إلى أنواع عناصر dtype جديدة. >>> timeit("Z.view(np.float16)[...] = 0", globals()) 100 loops, best of 3: 2.72 msec per loop >>> timeit("Z.view(np.int16)[...] = 0", globals()) 100 loops, best of 3: 2.77 msec per loop >>> timeit("Z.view(np.int32)[...] = 0", globals()) 100 loops, best of 3: 1.29 msec per loop >>> timeit("Z.view(np.float32)[...] = 0", globals()) 100 loops, best of 3: 1.33 msec per loop >>> timeit("Z.view(np.int64)[...] = 0", globals()) 100 loops, best of 3: 874 usec per loop >>> timeit("Z.view(np.float64)[...] = 0", globals()) 100 loops, best of 3: 865 usec per loop >>> timeit("Z.view(np.complex128)[...] = 0", globals()) 100 loops, best of 3: 841 usec per loop >>> timeit("Z.view(np.int8)[...] = 0", globals()) 100 loops, best of 3: 630 usec per loop ولكن في الواقع فإن طريقة تصفية جميع القيم ليست هي الأسرع، فقد زاد معدل السرعة بنسبة 25% من خلال تحويل بعض عناصر المصفوفة إلى نوع البيانات np.float64، بينما زاد معدل السرعة بنسبة 50% من خلال عرض المصفوفة واستخدام نوع البيانات np.int8. تتعلق أسباب التسريع بهيكلية عمل مكتبة numpy. تخطيط الذاكرة Memory layout يُعرّف الصنف ndarray وفقًا لتوثيق Numpy كما يلي: المصفوفة هي كتلة مجاورة من الذاكرة يمكن الوصول إلى عناصرها باستخدام مخطط الفهرسة indexing scheme، الذي يحدد شكل ونوع البيانات، وهذا هو المطلوب لتعريف مصفوفة جديدة. Z = np.arange(9).reshape(3,3).astype(np.int16) حجم عناصر المصفوفة Z في التعليمة السابقة هو 2 بايت (int16)، وعدد أبعاد (len(Z.shape هو 2. >>> print(Z.itemsize) 2 >>> print(Z.shape) (3, 3) >>> print(Z.ndim) 2 نظرًا لأن Z ليست طريقة عرض، يمكننا استنتاج خطوات المصفوفة التي تحدد عدد البايتات التي يجب أن تخطوها لاجتياز كل بعد من أبعاد المصفوفة. >>> strides = Z.shape[1]*Z.itemsize, Z.itemsize >>> print(strides) (6, 2) >>> print(Z.strides) (6, 2) لنتمكن من الوصول إلى عنصر معين (مصمم بواسطة فهرس index tuple)، أي كيفية حساب إزاحة البداية والنهاية: offset_start = 0 for i in range(ndim): offset_start += strides[i]*index[i] offset_end = offset_start + Z.itemsize سنستخدم الآن طريقة التحويل tobytes للتأكد من المعلومة السابقة: >>> Z = np.arange(9).reshape(3,3).astype(np.int16) >>> index = 1,1 >>> print(Z[index].tobytes()) b'\x04\x00' >>> offset = 0 >>> for i in range(Z.ndim): ... offset + = Z.strides[i]*index[i] >>> print(Z.tobytes()[offset_start:offset_end] b'\x04\x00' يمكن تمثيل هذه المصفوفة بطرق (تخطيطات) مختلفة: تخطيط العنصر item layout تخطيط العنصر المسطّح Flattened item layout تخطيط الذاكرة Memory layout (C order, big endian)‎ إذا أخذنا الآن شريحة من Z، فإن النتيجة هي عرض المصفوفة الأساسية Z: V = Z[::2,::2] يُحدّد هذا العرض باستخدام نوع dtype وشكل وخطوات، إذ أصبح من غير الممكن استنتاج الخطوات strides من النوع والشكل فقط: تخطيط العنصر item layout تخطيط العنصر المسطّح Flattened item layout تخطيط الذاكرة Memory layout (C order, big endian)‎ العروض والنسخ تُعد العروض Views والنسخ copies مفاهيمًا مهمة لتحسين حساباتك الرقمية. بالرغم من تعاملنا مع هذه المفاهيم في الفقرات السابقة إلا أن الموضوع أكثر تعقيدًا. الوصول المباشر وغير المباشر أولًا علينا التمييز بين نوعي الفهرسة indexing و fancy indexing؛ إذ يعيد النوع الأول عرضًا view دائمًا، بينما يعيد النوع الثاني نسخةً copy. يؤدي تعديل العرض في الحالة الأولى إلى تعديل المصفوفة الأساسية، بينما لن يحدث ذلك في الحالة الثانية: >>> Z = np.zeros(9) >>> Z_view = Z[:3] >>> Z_view[...] = 1 >>> print(Z) [ 1. 1. 1. 0. 0. 0. 0. 0. 0.] >>> Z = np.zeros(9) >>> Z_copy = Z[[0,1,2]] >>> Z_copy[...] = 1 >>> print(Z) [ 0. 0. 0. 0. 0. 0. 0. 0. 0.] إذا كنت تريد استخدام نوع الفهرسة fancy indexing فمن الأفضل الاحتفاظ بنسخة الفهرس fancy index ثم التعامل معه: >>> Z = np.zeros(9) >>> index = [0,1,2] >>> Z[index] = 1 >>> print(Z) [ 1. 1. 1. 0. 0. 0. 0. 0. 0.] إذا لم تكن متأكدًا مما إذا كانت نتيجة الفهرسة هي عرض أو نسخة، فيمكنك التحقق باستخدام الأداة base؛ فإذا كانت النتيجة "None"، فسيكون النوع هو نسخة: >>> Z = np.random.uniform(0,1,(5,5)) >>> Z1 = Z[:3,:] >>> Z2 = Z[[0,1,2], :] >>> print(np.allclose(Z1,Z2)) True >>> print(Z1.base is Z) True >>> print(Z2.base is Z) False >>> print(Z2.base is None) True لاحظ أن بعض وظائف numpy تُعيد عرضًا view، مثل ravel عندما يكون ذلك ممكنًا، بينما يعيد البعض الآخر نسخةً copy، مثل flatten: >>> Z = np.zeros((5,5)) >>> Z.ravel().base is Z True >>> Z[::2,::2].ravel().base is Z False >>> Z.flatten().base is Z False نسخة مؤقتة Temporary copy يمكن إنشاء النسخ بطريقة صريحة كما في الأمثلة السابقة، ولكن الطريقة الأكثر استخدمًا هي الإنشاء الضمني للنسخ الوسيطة. يوضح المثال التالي إجراء العمليات الحسابية باستخدام المصفوفات: >>> X = np.ones(10, dtype=np.int) >>> Y = np.ones(10, dtype=np.int) >>> A = 2*X + 2*Y أنشأنا في هذا المثال ثلاث مصفوفات وسيطة: مصفوفة للاحتفاظ بنتيجة X*‏2 والثانية للاحتفاظ بنتيجة Y*‏2، والأخيرة لإيجاد نتيجة Y*‏2 + X*‏2، وتكون المصفوفات في هذه الحالة صغيرة الحجم ولا تحدث هذه الطريقة أي فرق واضح؛ ولكن في حال كانت المصفوفات كبيرة الحجم فعليك أن تكون حذرًا مع هذه التعبيرات وتفكر بطريقة مختلفة لإيجاد الحل، فعلى سبيل المثال إذا كانت النتيجة النهائية هي فقط المهمة ولم تكن بحاجة إلى X أو Y، فسيكون الحل البديل: >>> X = np.ones(10, dtype=np.int) >>> Y = np.ones(10, dtype=np.int) >>> np.multiply(X, 2, out=X) >>> np.multiply(Y, 2, out=Y) >>> np.add(X, Y, out=X) استغنينا باستخدام هذا الحل البديل عن فكرة إنشاء مصفوفات مؤقتة، لكن المشكلة أن هناك بعض الحالات التي تتطلب إنشاء هذه النسخ المؤقتة وهذا يؤثر على الأداء كما هو موضح في المثال التالي: >>> X = np.ones(1000000000, dtype=np.int) >>> Y = np.ones(1000000000, dtype=np.int) >>> timeit("X = X + 2.0*Y", globals()) 100 loops, best of 3: 3.61 ms per loop >>> timeit("X = X + 2*Y", globals()) 100 loops, best of 3: 3.47 ms per loop >>> timeit("X += 2*Y", globals()) 100 loops, best of 3: 2.79 ms per loop >>> timeit("np.add(X, Y, out=X); np.add(X, Y, out=X)", globals()) 1000 loops, best of 3: 1.57 ms per loop الخلاصة في الختام سندرس المثال التالي: لنفرض لدينا متجهين Z1 و Z2، ونرغب في معرفة ما إذا كان Z2 هو عرض view للمتجه Z1، وإذا كانت الإجابة نعم فما هو هذا العرض view؟ >>> Z1 = np.arange(10) >>> Z2 = Z1[1:-1:2] أولاً سنحدد نوع الفهرسة وهل Z1 هي أساس Z2: >>> print(Z2.base is Z1) True حتى الآن تأكدنا أن Z2 هي عرض view للمتغير Z1، مما يعني أنه يمكن التعبير عن Z2على النحو التالي: [Z1[start:stop:step. وتكمن الصعوبة في التعرف على البداية والتوقف والخطوة؛ إذ يمكننا بالنسبة للخطوة استخدام خاصية strides لأي مصفوفة تعطي عدد البايتات للانتقال من عنصر إلى آخر في كل بُعد. في حالتنا ولأن كلا المصفوفتين أحادي البعد، يمكننا مقارنة الخطوة الأولى فقط. >>> step = Z2.strides[0] // Z1.strides[0] >>> print(step) 2 الصعوبة التالية هي العثور على مؤشرات البداية والتوقف، إذ يمكننا فعل ذلك بالاستفادة من طريقة byte_bounds التي تُرجع مؤشرًا إلى نقاط نهاية المصفوفة. >>> offset_start = np.byte_bounds(Z2)[0] - np.byte_bounds(Z1)[0] >>> print(offset_start) # bytes 8 >>> offset_stop = np.byte_bounds(Z2)[-1] - np.byte_bounds(Z1)[-1] >>> print(offset_stop) # bytes -16 يعد تحويل هذه الإزاحات offset إلى مؤشرات أمرًا سهلاً باستخدام حجم العناصر مع الأخذ بالحسبان أن offset_stop سلبي (حد نهاية Z2 أصغر منطقيًا من حد النهاية لمصفوفة Z1)، لذلك نحتاج إلى إضافة حجم عناصر Z1 للحصول على فهرس النهاية الصحيحة: >>> start = offset_start // Z1.itemsize >>> stop = Z1.size + offset_stop // Z1.itemsize >>> print(start, stop, step) 1, 8, 2 وعند اختبار النتائج نحصل على ما يلي: >>> print(np.allclose(Z1[start:stop:step], Z2)) True يمكنك التمرين من خلال تحسين هذا التنفيذ الأول والبسيط جدًا من خلال مراعاة: خطوات سلبية. مصفوفة متعددة الأبعاد. ترجمة -وبتصرف- للفصلين Introduction و Anatomy of an array من كتاب From Python to Numpy لصاحبه Nicolas P. Rougier. اقرأ أيضًا المرجع الشامل إلى تعلم لغة بايثون أهم 8 مكتبات بلغة البايثون تستخدم في المشاريع الصغيرة
    1 نقطة
  39. سنتحدث في هذا المقال عن مفهوم العلاقات بين جداول قاعدة البيانات، وما أنواع هذه العلاقات وكيف تتمثل وما هو أثرها على العمل. ما هي العلاقات بين الجداول عند إنشاء جداول في قاعدة البيانات، فإن الظاهر لنا أننا نقوم ببناء جداول منفصلة وغير مترابطة، ولكننا في الواقع العملي نحتاج لربط هذه الكيانات المنفصلة بحيث تُبنَى علاقات تحكم البيانات الموجودة في هذه الجداول، وتحكم طريقة التعامل مع هذه البيانات. تنشَأ العلاقة بين جدوليْن عندما يُربط عمودان فيهما مع بعضهما عن طريق وجود قيود مطبقة على العمودين، بحيث يكون قيد المفتاح الرئيسي على عمود في الجدول “الأب” وقيد المفتاح الأجنبي على العمود في الجدول “الابن”، وعادة يكون اسم العمودين واحدًا في كلا الجدولين. مثلا، لحفظ عناوين الأشخاص نستطيع إنشاء جدول باسم Address ونربطه بجدول الأشخاص Persons بعلاقة تحكم البيانات الموجودة في الجدولين، بحيث يكون لكل شخص في الجدول Persons عنوان واحد مرتبط به في الجدول Address. يُربَط الجدولان عن طريق عمود باسم Person_Id في كلا الجدولين. مثال آخر، لو أردنا أن نتابع عملية استعارة الكتب في مكتبة، فإننا سننشئ جدولًا باسم Borrowed_Books (كُتُب مُعارة) ونربطها بالجدول Persons عن طريق العمود Person_Id. يستطيع الشخص الواحد - في هذا النوع من الربط - أن يستعير أكثر من كتاب. في هذا المثال، لو أننا حفظنا بيانات الأشخاص والكتب المستعارة في جدول واحد، ستظهر لنا مشكلة تكرار البيانات Data Redundancy لأننا سنكرّر بيانات الشخص لكل كتاب يستعيره. ماذا نستفيد من بناء العلاقات بين الجداول؟ التخلص من مشكلة تكرار البيانات عن طريق فصلها وحفظها في أكثر من جدول، فمشكلة تكرار البيانات هي عدو مستخدمي قواعد البيانات ومسؤوليها، لأنها تتسبب بزيادة حجم قاعدة البيانات بقدر كبير وبسرعة، وترفع السرعات المطلوبة لتنفيذ الاستعلامات، وتجعل من موضوع صيانة قاعدة البيانات كابوسا مقلقا. الحفاظ على دقة وسلامة البيانات في قاعدة البيانات، فمع وجود العلاقات بين الجداول، سوف تضمن مثلا عدم وجود كتاب مُعار ليس له شخص استعاره، أو عنوان وهمي ليس له صاحب، وقس على ذلك العديد من الأمثلة. استخراج البيانات من أكثر من جدول بكفاءة وسرعة عن طريق بناء جمل ربط استعلامية تطلب المعلومات من أعمدة مختلفة في جداول مختلفة، وإخراج النتيجة بطريقة مفيدة ومرتبة. أنواع العلاقات توجد أربعة أنواع من العلاقات بين الجداول كالتالي: علاقة واحد إلى واحد (One-to-One). علاقة واحد إلى كثير أو علاقة كثير إلى واحد (One-to-Many / Many-to-One). علاقة كثير إلى كثير (Many-to-Many). علاقة المرجعية الذاتية (Self Referencing). علاقة واحد إلى واحد لنفترض أن الجدول Persons لديه البنية والبيانات التالية: Person_ID First_Name Last_Name Age Address 101 Ibrahim Mohammed 31 12 Main St, Doha 102 Mohammed Khaled 25 Gaza, Middle Center نستطيع أن نضع بيانات العنوان في جدول منفصل ونسميه Address وتكون بنية الجدوليْن كالتالي. الجدول Persons: Person_ID First_Name Last_Name Age Address_Id 101 Ibrahim Mohammed 31 1 102 Mohammed Khaled 25 2 الجدول Address: Address_ID Address 1 12 Main St, Doha 2 Gaza, Middle Center لاحظ أنه أصبح لدينا عمود بنفس الاسم Address_Id في كلا الجدولين. لبناء العلاقة بين الجدولين، طبّقنا قيد المفتاح الأجنبي على العمود Address_Id في الجدول Persons بحيث يأخذ قيمه من العمود Address_Id في الجدول Address والمطبق عليه قيد المفتاح الرئيسي. أصبحت لدينا الآن علاقة بين الجدولين، وفي حال كان كل عنوان في الجدول Address يقترن فقط بشخص واحد في الجدول Persons فعندها نسمي هذه العلاقة واحدًا إلى واحد. يجب التنويه إلى أن هذا النوع من العلاقات غير مستخدم كثيرا، فالجدول الأول الذي يحتوي العنوان وبيانات الشخص يفي بالغرض في أغلب الأحيان. نستطيع تمثيل العلاقة بالشكل التالي: لاحظ أن وجود العلاقة اختياري، فمن الممكن أن يكون لدينا سجل في الجدول Persons دون عنوان له في الجدول Address وهذا مرتبط بعدم تطبيق قيد القيمة غير الفارغة على العمود Address_Id. في حال طُبِّق قيد غير القيمة غير الفارغة على العمود، فهنا تصبح العلاقة واجبة بين الجدولين، ولا يمكن أن نُنْشئ سجلًّا في الجدول Persons إلا بإدخال قيمة موجودة للعمود Address_Id وهو في مثالنا هذا غير منقطي نوعا ما. دورة علوم الحاسوب دورة تدريبية متكاملة تضعك على بوابة الاحتراف في تعلم أساسيات البرمجة وعلوم الحاسوب اشترك الآن علاقة واحد إلى كثير أو علاقة كثير إلى واحد هذا النوع من العلاقات هو الشائع بين أنواع العلاقات بين الجداول في قاعدة البيانات، لوجود تطبيقات كثيرة عليه، فمثلا: الطالب (واحد) يستطيع أن يدرس أكثر من مساق (كثير). الطبيب يعالج ويتابع حالة مريض واحد أو أكثر. طلبية الشراء تحتوي على أكثر من عنصر. الشخص يستعير أكثر من كتاب. وقس على ذلك العديد من الأمثلة. لنفترض وجود جدول للزبناء Customers بالهيكلية التالية: Customer_ID Customer_Name 1 Ibrahim Mohammed 2 Mohammed Ahmed نستطيع ربط جدول الزبناء السابق بجدولٍ للطلبيات Orders بعلاقة واحد إلى كثير، لتعبر العلاقة عن الطلبيات التي قام بها العملاء وقيمة كل طلبية وتاريخها. يمكن أن تكون هيكلية الجدول Orders كالتالي: Order_ID Customer_ID Order_Date Order_Value 997 101 1/5/2017 100 998 102 21/4/2016 150 999 101 21/4/2015 1500 تسمح هذه العلاقة للعميل بأن يطلُب طلبيةً أو أكثر، ويمكن ألا تكون له أية طلبية. ولكنّ كل طلبية في الجدول Orders ستكون تابعة لعميل واحد. ونستطيع تمثيل هذه العلاقة بالشكل التالي: علاقة كثير إلى كثير في علاقة كثير إلى واحد، تكون العلاقة مبنية على أن يكون أحد أطرافها “واحدًا”، مثل طالب واحد، عميل واحد، طلبية واحدة، وفي الطرف الثاني “كثير”. نحتاج أحيانا أن يكون طرفا العلاقة كثيرين. فمثلا، قد تكون لدينا طلبية تحتوي أكثر من عنصر، ونفس العنصر يكون متواجدًا في أكثر من طلبية. في هذه الحالة نحتاج لوجود جدول إضافي لبناء العلاقة، فمثلا تكون هيكلية جدول Orders كالتالي: Order_ID Customer_ID Order_Date Order_Value 997 101 1/5/2017 100 998 102 21/4/2016 150 999 101 21/4/2015 1500 وهيكلية جدول Items كالتالي: Item_Id Item_Name Item_Description 201 Hard Disk 1 1 Tera SSD Hard 202 Mouse Microsoft Optical Mouse 203 LCD 42 42” LCD نستطيع بناء علاقة كثير إلى كثير بين الجدولين السابقين بإضافة جدول ثالث يحلّ مكان الرابط وغرضه الوحيد هو بناء هذا النوع من العلاقات. نطلق عليه مثلا الاسم Orders_Items، ويكون بالهيكلية التالية: Order_Id Item_Id 997 201 997 202 999 201 999 202 999 203 998 203 يمثّل الشكل التالي علاقة كثير إلى كثير كما تظهر في الجدول Orders_Items: علاقة المرجعية الذاتية يُبنى هذا النوع من العلاقات عندما نريد أن نبني علاقة بين جدول ونفس الجدول، وأوضح مثال على هذا النوع من العلاقات هو جدول الموظفين الذي يحتوي على عمود رقم الموظف المسؤول، حيث يمكن ربط كل موظف بموظف آخر (مدير أو مسؤول) من نفس الجدول. فمثلا، لو كان لدينا جدول باسم Employees خاص بحفظ بيانات الموظفين، ستكون هيكليته على النحو التالي لتطبيق علاقة مرجعية ذاتية عليه: Employee_ID Employee_Name Manager_Id 100 Ibrahim Elbouhissi 101 Khaled Saber 100 102 Yasmeen Hadi 100 103 Duaa Yousef 101 104 Sami Saber بعلاقة المرجعية الذاتية، من الممكن أن يكون للموظف مسؤولًا أو لا يكون، ومن الممكن أن يكون الموظف مسؤولا عن موظف أو أكثر، ويمكن تمثيل العلاقة بالشكل التالي.
    1 نقطة
  40. لغة بايثون هي لغة برمجة سهلة التعلم موازنةً باللغات الأخرى مثل لغة جافا ولغة C ولغة ++C، بالإضافة لكونها متعددة الأغراض فهي تستخدم في بناء تطبيقات سطح المكتب وألعاب الفيديو والرسومات ثلاثية الأبعاد والمواقع الإلكترونية وغيرها، زد على أنها لغة قوية برمجيًا وممتازة للتطبيقات المتقدمة، هذا كله جعلها خيارًا مثاليًا للجميع بصرف النظر عن عملهم وعمرهم وعدد سنوات خبرتهم، بالأخص للراغبين بتعلم البرمجة. هذا المقال جزءًا من سلسلة مقالات حول تصميم لعبة بلغة بايثون ومكتبة Pygame وإليك كامل مقالات السلسلة: بناء لعبة نرد بسيطة بلغة بايثون. بناء لعبة رسومية باستخدام بايثون ووحدة الألعاب PyGame. إضافة لاعب إلى اللعبة المطورة باستخدام بايثون و Pygame. تحريك شخصية اللعبة باستخدام PyGame. إضافة شخصية العدو للعبة. إضافة المنصات إلى لعبة بايثون باستخدام الوحدة Pygame. محاكاة أثر الجاذبية في لعبة بايثون. إضافة خاصية القفز والركض إلى لعبة بايثون. إضافة الجوائز إلى اللعبة المطورة بلغة بايثون. تسجيل نتائج اللعبة المطورة بلغة بايثون وعرضها على الشاشة. إضافة آليات القذف إلى اللعبة المطورة بلغة بايثون. تثبيت بايثون ستحتاج إلى تثبيت بايثون الإصدار 3 لتتابع معنا خطوات العمل، لذا اتبع الخطوات المناسبة لنظام تشغيلك. إن كنت تستخدم نظام تشغيل لينكس، فستجد بايثون متوفرًا ضمنه على الأغلب، استعلم عن إصداره بالأمر التالي: python --version وانظر إلى الخرج فلو تبين لك أن الإصدار الموجود هو 2، أو أن بايثون غير مثبت على الإطلاق، حاول كتابة الأمر بالشكل التالي: python3 --version وإن حصلت على رسالة مفادها عدم التعرف على الأمر، فثبت بايثون 3 باستخدام مركز التطبيقات أو مدير الحزم الخاص بتوزيعة لينكس التي تعتمدها مثل apt في أوبونتو أو dnf في فيدورا. إن كانت توزيعتك هي فيدورا، ثبت بايثون 3 بالأمر التالي: sudo dnf install python3 اتبع الخطوات نفسها في نظام تشغيل macOS لتتأكد من وجود بايثون 3 في النظام، وإن لم يكن مثبتًا، حمله من موقع بايثون الرسمي ثم ثبته، وهنا لديك هذه الطريقة فقط إذ إن macOS لا يملك مدير حزم. أما لو كنت تستخدم نظام تشغيل ويندوز فحمل بايثون 3 من الموقع الرسمي في البداية، ويمكنك الاستعانة بالمقال كيفية تثبيت بايثون 3 وإعداد بيئته البرمجية على ويندوز 10 لهذا الغرض. عمومًا أيًا كان نظام التشغيل الذي تعتمده يمكنك الاستعانة بقسم تثبيت بايثون 3 وإعداد بيئتها البرمجية من المرجع الشامل لتعلم بايثون المتوفر باللغة العربية على أكاديمية حسوب. دورة تطوير التطبيقات باستخدام لغة Python احترف تطوير التطبيقات مع أكاديمية حسوب والتحق بسوق العمل فور انتهائك من الدورة اشترك الآن تشغيل بيئة التطوير المتكاملة IDE فعليًا كل ما تحتاج إليه لكتابة البرامج بلغة بايثون هو محرر شيفرات، ولكن استخدامك بيئة تطوير متكاملة IDE سيسهل عليك كتابة الشيفرة كثيرًا، فهذه البيئات تتضمن وظيفة محرر الشيفرات البسيط مع بعض الأدوات الإضافية الملائمة لكتابة شيفرة بايثون، ويتوفر العديد من الخيارات مفتوحة المصدر لبيئات التطوير المتكاملة، سنعرض منها IDLE 3 و PyCharm. بيئة التطوير IDLE 3 الأساسية هي بيئة التطوير الأساسية المضمنة مع بايثون، وتتميز هذه البيئة بتلوين أجزاء الشيفرة ما يسهل قراءتها واكتشاف الأخطاء على المبرمج، وأيضًا بإعطاء تلميحات لإكمال التعليمات البرمجية، بالإضافة إلى وجود زر تشغيل لتسهيل تشغيلها واختبارها. لبدء استخدام هذه البيئة في لينكس ونظام macOS يكفيك كتابة الأمر idle3 في نافذة الطرفية، أما لاستخدامها في ويندوز فابحث عن بايثون 3 في قائمة ابدأ وستجد هذه البيئة بين خياراتها، وفي حال لم تجد بايثون في قائمة ابدأ، افتح سطر الأوامر بكتابة cmd في خانة البحث، ومن ثم اكتب ضمنه السطر التالي: C:\Windows\py.exe وإن لم ينفع، أعد تثبيت بايثون وتأكد من تفعيل خيار إضافة بايثون إلى متغير البيئة PATH في أثناء عملية التثبيت. وإن لم ينفع ذلك أيضًا، استخدم لينكس ضمن ويندوز نفسه أو بتثبيت لينكس مع ويندوز، فهو في النهاية مجاني، وهذا الانتقال في البيئة لن يكلفك أكثر من حفظ ملفات بايثون خاصتك على قرص USB محمول ونقلها. بيئة التطوير Pycharm النسخة المجتمعية تعدّ Pycharm من أفضل بيئات التطوير مفتوحة المصدر المتوافقة مع بايثون، تتميز بتلوين الشيفرات لتسهيل قراءتها ولاكتشاف أخطاء الكتابة، وإكمال الأقواس وعلامات الاقتباس لضمان صيغ قواعدية سليمة، بالإضافة إلى ميزة ترقيم الأسطر المفيدة في أثناء تنقيح الأخطاء، وعلامات المسافة البادئة، وزر التشغيل لتسهيل اختبار الكود. لتستخدم هذه البيئة ثبّت النسخة المجتمعية من Pycharm، إن كان نظام تشغيلك هو لينكس فيمكنك تثبيتها باستخدام flatpak من منصة FlatHub أو تحميلها من الموقع الرسمي وتثبيتها يدويًا، أما لو كنت تعتمد ويندوز أو macOS فحمل نسخة البرنامج المناسبة لك من موقعه الرسمي، ومن ثم ثبتها. افتح البرنامج بعد التثبيت وأنشئ مشروعًا جديدًا. أخبر بايثون بما تريد تنفيذه الكلمات المفتاحية هي كلمات أساسية تُعرّف الدوال والأصناف وغيرها فهي إذًا الوسيلة التي تخبر بايثون بكل ما تريد تنفيذه. لتجرب إحداها، اكتب السطر التالي ضمن مشروعك الجديد الذي أنشأته على بيئة التطوير: print("Hello world.") والآن شغله بإحدى الطريقتين: إن كنت تستخدم IDLE استعرض قائمة التشغيل وحدد الخيار "تشغيل الوحدة Run Module". أما في PyCharm انقر فوق الزر "تشغيل ملف Run file" ضمن أزرار شريط الأدوات. تطبع print -الكلمة المفتاحية التي جربناها- النص المكتوب بين علامتي اقتباس الموجود ضمن القوسين كما هو أيًا كان. وننوه لك أن بايثون افتراضيًا لا تستخدم إلّا الكلمات المفتاحية الأساسية مثل print و help وتلك الخاصة بالعمليات الحسابية الأساسية وما شابه، ولكن التعليمة import تتيح للمبرمج استيراد المزيد من الوظائف واستخدامها. استخدام وحدة الرسم turtle في بايثون اكتب الأسطر التالية في ملفك (بعد حذف الموجود فيه)، ومن ثم شغله: import turtle turtle.begin_fill() turtle.forward(100) turtle.left(90) turtle.forward(100) turtle.left(90) turtle.forward(100) turtle.left(90) turtle.forward(100) turtle.end_fill() لاحظ الأشكال التي يمكنك رسمها باستخدام مكتبة الرسم turtle والتي تدعى سلحفاة. لتمسح كل الموجود في مساحة الرسم، استخدم: turtle.clear() حاول تخمين معنى الدالة من اسمها الأجنبي: turtle.color("blue") لابد أنك أصبت، سيصبح لون الخط أزرق بدل الأسود، فسهولة فهم التعليمات وتفسيرها هي إحدى ميزات بايثون. سنحاول الحصول على النتيجة نفسها بكتابة كود مختلف أكثر تعقيدًا، وذلك باستخدام الحلقة while التي ستوجه بايثون ليكرر عملية رسم الخط والانعطاف أربع مرات متتالية عوضًا عن إعادة كتابة السطر نفسه أربع مرات كما فعلنا في الفقرة السابقة، أما المتغير الذي سيحدد عدد مرات التكرار فيسمى العداد counter، ستتعلم المزيد عن المتغيرات لاحقًا، ولكن الآن اكتب الأسطر التالية ونفذها لترى كيفية تفاعل المتغير مع الحلقة: import turtle as t import time t.color("blue") t.begin_fill() counter=0 while counter < 4: t.forward(100) t.left(90) counter = counter+1 t.end_fill() time.sleep(2) تعلم بايثون عبر بناء لعبة بسيطة هدفنا أساسًا تعلم البرمجة عبر لغة بايثون، وتمهيدًا لاستخدامها في برمجة متقدمة تعتمد على الرسوميات، سنبدأ في هذا المقال بتعلم منطق اللعبة وكيفية تنظيم البيئة لبناء لعبة نرد بسيطة، يلعب فيها المستخدم مقابل الحاسوب ويلقي كل منهما النرد الافتراضي ليفوز صاحب القيمة الأعلى. التخطيط للعبة يبدأ تطوير البرمجيات عادةً بكتابة توثيق -ولو كان بسيطًا- للمتطلبات والأهداف يبين ما يفترض أن يكون عليه البرنامج، وفي لعبة النرد التي نعمل عليها سيتضمن التوثيق آلية العمل التالية. ابدأ اللعبة واضغط على زر Return أو Enter في لوحة المفاتيح لتبدأ دورة النرد. ستظهر النتيجة على الشاشة. ستُطالب بعدها بإعادة اللعب أو بالخروج. اللعبة بسيطة هذا صحيح، لكن توثيقها سيبين لك كمًّا لا بأس به من التفاصيل لتعمل عليها، مثل حاجتك لهذه المكونات. اللاعب: وهو العنصر البشري الذي سيستخدم اللعبة. AI: وترمز للذكاء الصنعي أي جهاز الحاسوب الذي يحاكي دور اللاعب الخصم، حتى يكون لديك فائز وخاسر. رقم عشوائي: الشائع في لعبة النرد استخدام نرد سداسي الأضلاع وبالتالي الرقم سيكون بين 1 و 6. عامل إجرائي: عملية رياضية بسيطة لموازنة رقمي اللاعبين ومعرفة الأكبر بينهما. رسالة فوز أو خسارة. مطالبة باتخاذ إجراء: إما اللعب مجددًا أو الخروج. بناء الإصدار الأول من لعبة النرد يتضمن الإصدار الأول من البرنامج الميزات الأساسية فقط، قلة هم من يبدأون تطوير برامجهم بميزات كاملة من أول إصدار. سنعرض مفهومين أساسيين قبل البدء. أولًا المتغير variable هو قيمة قابلة للتغيير، يستخدم لتخزين بعض المعلومات التي يحتاجها البرنامج وهو شائع الاستخدام في بايثون، فمثلًا المحرف x هو متغير في المعادلة التالية لأنه يشير إلى قيمةٍ ما أو ينوب عنها: x + 5 = 20 وثانيًا العدد الصحيح integer فيشمل الأعداد الصحيحة الموجبة والسالبة، مثلًا: 1، ‎-1 ،14 ،10947. يتضمن إصدارنا الأول من اللعبة -والمسمى ألفا dice-alpha- متغيرين هما player و ai. لتبدأ بإنشائه، افتح مشروعًا جديدًا، وسمّه dice-alpha ثم اكتب ضمنه الكود التالي: import random player = random.randint(1,6) ai = random.randint(1,6) if player > ai : print("You win") # لاحظ المسافة البادئة else: print("You lose") شغل اللعبة، ولاحظ أن وظيفتها الأساسية تعمل جيدًا، لكنها لا تبدو لعبةً متكاملة حتى الآن، فاللاعب لا يعرف نتيجة رميته ولا رمية الخصم، بالإضافة إلى أنها تنتهي مباشرةً حتى لو رغب اللاعب بالاستمرار، في الواقع يعدّ هذا شائعًا في الإصدارات الأولى من البرامج التي تسمى الإصدارات ألفا، لكنك في نهاية المطاف حللت الإجراء المهم في اللعبة وهو رمي النرد وأصبحت متيقنًا من عمله، فيمكنك استكمال بقية الميزات فيما بعد. تحسين اللعبة سنبني الآن الإصدار الثاني وهو الإصدار بيتا، بإضافة بعض الميزات ليصبح برنامجنا أقرب للعبة فعلًا. 1. إظهار تفاصيل النتيجة في إصدارنا الأول أظهرنا للاعب عبارةً واحدة ليعرف إن فاز أو خسر، والآن سنطوّر الآلية ليعرف اللاعب مقدار العدد العشوائي الذي حصل عليه أي مقدار رميته للنرد وكذلك رمية الخصم. جرب إجراء التعديل التالي في برنامجك، ومن ثم شغله: player = random.randint(1,6) print("You rolled " + player) ai = random.randint(1,6) print("The computer rolled " + ai) بمجرد تشغيله ستحصل على خطأ، والسبب أن بايثون قد فهم برنامجك على أنه عملية حسابية تجمع حروف وأعداد، الحروف هي حروف العبارة التي ستُظهر النتيجة على الشاشة والعدد هو قيمة المتغير player أو المتغير ai، وهذا بالطبع غير منطقي وغير قابل للتطبيق. لتصحيح الخطأ سنجعل بايثون يتعامل مع قيمة المتغير بصفتها نصًا أو بالأحرى سلسلة نصية string بدلًا من معاملتها على أساس أنها عدد صحيح integer. نفذ إذًا التعديل التالي وأعد تشغيل اللعبة ولاحظ النتائج: player = random.randint(1,6) print("You rolled " + str(player) ) ai = random.randint(1,6) print("The computer rolled " + str(ai) ) 2. إضافة عامل التشويق أضفنا بعض التسلية للعبة بإظهار النتائج، والآن سنضيف بعض الإثارة بإبطاء اللعبة في الأجزاء المشوقة، أما وسيلتنا لذلك فهي الدالة time إحدى دوال بايثون. نفذ التالي وتفقد النتائج: import random import time player = random.randint(1,6) print("You rolled " + str(player) ) ai = random.randint(1,6) print("The computer rolls...." ) time.sleep(2) print("The computer has rolled a " + str(player) ) if player > ai : print("You win") # لاحظ المسافة البادئة else: print("You lose") 3. اكتشاف ثغرة التعادل لو ثابرت على اللعب لفترةٍ جيدة، ستكتشف أن لعبتك لا تمتلك التعليمات اللازمة للتعامل مع حالة التعادل أي الحالة التي يحصل فيها اللاعب والحاسوب على القيمة نفسها، وهذه تعدّ ثغرة أو خطأ منطقي في الكود المكتوب، وحتى نعالجها سنجعل بايثون يتحقق من كون القيمتين متساويتين ويعرض عندها نتيجة التعادل. سنستخدم إشارة يساوي مزدوجة == للتحقق من تساوي القيمتين، إذ إن إشارة يساوي مفردة تعني في بايثون إسناد قيمة ما لأحد المتغيرات، أما بخصوص إدراج خيار ثالث للنتيجة، فسنعتمد على الكلمة المفتاحية elif (اختصار لـ else if) وهي مفيدة في الحالات التي تحتاج فيها للمطابقة مع ثلاثة احتمالات أو أكثر ضمن التعليمات الشرطية، بدلاً من مجرد احتمالين أحدهما صحيح والآخر خاطئ. الآن عدّل برنامجك ليغدو كما يلي: if player > ai : print("You win") # لاحظ المسافة البادئة elif player == ai: print("Tie game.") else: print("You lose") وبعدها جرب اللعبة عدة مرات لتصادف حالة التعادل وتتأكد من عملها. يمكنك تعلم المزيد عن الدوال الشرطية في بايثون بالاطلاع على المقال كيفية كتابة التعليمات الشرطية في بايثون 3 ضمن دليل تعلم بايثون على أكاديمية حسوب. بناء الإصدار النهائي للعبة تفوق الإصدار بيتا وظيفيًا على الإصدار ألفا، وكان أكثر قربًا منه للألعاب الحقيقية، والآن سنبني إصدارنا النهائي الأكثر تكاملًا وستتعلم خلاله بناء دالتك الأولى في بايثون. الدالة function هي مجموعة من التعليمات البرمجية التي يتم استدعائها ضمن البرنامج بصورة كتلة واحدة متميزة، تفيد الدوال في تنظيم التطبيقات بالأخص تلك التي تتضمن عددًا كبيرًا من التعليمات البرمجية التي لا يُفترض أن تعمل في وقتٍ واحد وشروطٍ واحدة، والدوال هنا هي من تحدد ما الذي سيحدث وفي أي وقت وشرط سيحدث. عدّل الآن برنامجك ليصبح: import random import time def dice(): player = random.randint(1,6) print("You rolled " + str(player) ) ai = random.randint(1,6) print("The computer rolls...." ) time.sleep(2) print("The computer has rolled a " + str(ai) ) if player > ai : print("You win") elif player == ai: print("Tie game.") else: print("You lose") print("Quit? Y/N") cont = input() if cont == "Y" or cont == "y": exit() elif cont == "N" or cont == "n": pass else: print("I did not understand that. Playing again.") في هذا الإصدار سيُسأل اللاعب إن كان يريد الخروج من اللعبة، وفي حال أجاب بنعم عبر كتابة Y أو y، فإن بايثون سينهي استدعاء الدالة وتتم مغادرة اللعبة. إذًا فقد بنيت دالتك الأولى المسماة نرد dice لكنها لن تعمل ما لم تستدعيها ضمن البرنامج، وهذا ما ستفعله الحلقة While True. أضف التعليمات التالية في نهاية برنامجك، وانتبه للمسافات البادئة فقد أعدنا كتابة آخر سطرين في الكود السابق عن قصد ليكون السياق واضحًا أمامك: … # الحلقة الأساسية while True: print("Press return to roll your die.") roll = input() dice() هذه الحلقة هي أول ما سيعمل في برنامجك، وتتكرر دومًا ما لم يكسرها أمرٌ من بايثون، إذ إن شرط عملها محقق دائمًا وتلقائيًا فهو True، لاحظ تسلسل عملها فهي تطالب المستخدم أولًا باتخاذ إجراء حتى يبدأ اللعب، ومن ثم تستدعي الدالة dice، ومن بعدها بناءً على إجابة المستخدم ستستمر الحلقة بالعمل أو تتوقف. ومن الجدير بالذكر أن الحلقات هي واحدة من أشيع الطرق المستخدمة لبدء التطبيقات فهي تضمن بقاء التطبيق متاحًا أمام المستخدم لفترة كافية تمكنه من استخدام وظائفه المختلفة. يمكنك تعلم المزيد عن الحلقات التكرارية بالاطلاع على المقال كيفية إنشاء حلقات تكرار while في بايثون 3، والمقال كيفية استخدام تعابير break و continue و pass عند التعامل مع حلقات التكرار في بايثون 3 ضمن دليل تعلم بايثون على أكاديمية حسوب. ختامًا تعرفنا في هذا المقال على أساسيات البرمجة بلغة بايثون، وسنتعلم في مقالنا التالي كيفية بناء لعبة فيديو باستخدام الوحدة PyGame المتخصصة في هذا المجال. ترجمة -وبتصرف- للمقال Learn how to program in Python by building a simple dice game لصاحبه Seth Kenlon. اقرأ أيضًا المقال التالي: بناء لعبة رسومية باستخدام بايثون ووحدة الألعاب Pygame تعرف على أشهر لغات برمجة الألعاب برمجة لعبة حجرة ورقة مقص باستخدام لغة بايثون النسخة العربية الكاملة من كتاب البرمجة بلغة بايثون
    1 نقطة
  41. أضاف الإصدار ES6 من معايير ECMAScript الصادر عام 2015 ميزة قالب النص Template Literals إلى لغة جافاسكربت والتي تعد شكلًا جديدًا لصياغة السلاسل النصية Strings في جافاسكربت مُضيفًا العديد من الإمكانيات الجديدة الفعّالة، كإمكانية إنشاء سلاسل نصية متعدّدة السطور بطريقة سهلة، وإمكانية استخدام المواضع المؤقتة placeholder لتضمين قيم التعابير البرمجية Expressions في السلاسل النصية. إضافة لوجود ميزة متقدمة تدعى قوالب النصوص الموسومة Tagged Template Literals والتي تسمح لك بإجراء العمليات على التعابير في السلاسل النصية. تزيد كل هذه الإمكانات من خياراتك كمطور لكتابة السلاسل النصية ببراعة واحترافية، جاعلة إياك قادرًا على إنشاء سلاسل نصية ديناميكية يمكن توظيفها في عناوين الويب URLs أو في الإجراءات التي تعدّل عناصر صفحات HTML. ستتعرف في هذا المقال على الاختلافات ما بين السلاسل النصية المحصورة بين علامتي اقتباس مفردة أو مزدوجة وقوالب النصوص، كما ستتعرف على الطرق المتعدّدة للتصريح عن سلاسل نصية من أشكال مختلفة بما يتضمن السلاسل الممتدّة على أكثر من سطر والديناميكية منها التي تتغير تبعًا لقيمة متحول أو تعبير ما. ومن ثمّ ستتعلم عن قوالب النصوص الموسومة وسترى بعض الأمثلة الواقعية لمشاريع باستخدام هذه القوالب. التصريح عن السلاسل النصية سنستعرض في هذا القسم كيفية التصريح عن السلاسل النصية باستخدام علامات الاقتباس المفردة والمزدوجة، ومن ثم سننتقل لاستعراض كيفية إجراء ذلك في حالة استخدام قوالب النصوص. يمكنك كتابة سلسلة المحارف في جافاسكربت باستخدام علامات اقتباس مفردة ' ': const single = 'Every day is a good day when you paint.' كما يمكن كتابة سلسلة المحارف باستخدام علامات اقتباس مزدوجة " ": const double = "Be so very light. Be a gentle whisper." وإجمالًا لا يوجد اختلافات جوهرية ما بين استخدام علامات الاقتباس المفردة أو المزدوجة في جافاسكربت، وذلك على خلاف بعض لغات البرمجة والتي تتيح إمكانية التضمين Interpolation باستخدام إحدى الطريقتين حصرًا، والمقصود بالتضمين التعامل مع المواضع المؤقتة كجزء ديناميكي من سلسلة المحارف. ويعد استخدام علامات الاقتباس المفردة والمزدوجة خيارًا شخصيًا، كما يمكن استخدامهما معًا بشرط إغلاق أيًا منها بنفس نوع البدء: // الإغلاق هنا باستخدام علامة اقتباس مفردة لأننا بدأنا بمثلها const single = '"We don\'t make mistakes. We just have happy accidents." - Bob Ross' // الإغلاق هنا باستخدام علامة اقتباس مزدوجة لأننا بدأنا بمثلها const double = "\"We don't make mistakes. We just have happy accidents.\" - Bob Ross" console.log(single); console.log(double); وسيقوم الإجراء log( )‎ بالنتيجة بطباعة نفس سلسلة المحارف على الخرج: "We don't make mistakes. We just have happy accidents." - Bob Ross "We don't make mistakes. We just have happy accidents." - Bob Ross في حين أنّه تكتب قوالب النصوص عبر حصر السلسة النصية بين علامتي اقتباس مائلتين (`) : const template = `Find freedom on this canvas.` وهي لا تحتاج للإغلاق بعلامة اقتباس مفردة أو مزدوجة: const template = `"We don't make mistakes. We just have happy accidents." - Bob Ross` ولكن لا بدّ من إغلاقها بعلامة اقتباس مائلة كما بدأت: const template = `Template literals use the \` character.` وتؤدّي قوالب النصوص كافّة الوظائف التي تؤديها السلاسل النصية العادية، وبالتالي يمكنك استبدال كافّة السلاسل النصية في مشروعك بقوالب نصوص، إلّا أنّ القواعد الأساسية الشائعة في كتابة الشيفرات البرمجية تنص على استخدام قوالب النصوص فقط عند الحاجة الفعلية لها لما تقدمه من إمكانات إضافية عن السلاسل النصية العادية، وبالتالي يفضّل استخدام علامات التنصيص المفردة أو المزدوجة فقط لحصر السلاسل النصية البسيطة، وهذا ما سيجعل قراءة واختبار شيفرتك البرمجية أسهل لأي مطوّر آخر. الآن وبعد معرفتك لكيفية التصريح عن السلاسل النصية باستخدام علامات الاقتباس المفردة والمزدوجة وعلامات الاقتباس المائلة، سننتقل للتعرّف على أول فوائد قوالب النصوص وهي الكتابة على عدّة أسطر. كتابة السلاسل النصية على عدّة أسطر سنرى بدايةً كيفية التصريح عن السلاسل النصية متعددة الأسطر ما قبل ES6، ثمّ سننتقل لنلاحظ كيف سهّل استخدام قوالب النصوص من هذا الأمر. فسابقًا، وفي حال رغبت بكتابة سلسلة نصية على عدة أسطر في محرر النصوص، كان لا بدّ من استخدام عملية ربط سلاسل (+) والتي لا تمثّل دائمًا الطريقة الأفضل. فمثلًا وعلى خلاف الواقع، يبدو أنّ السلسلة النصية التالية ستظهر عند التنفيذ على عدّة أسطر: const address = 'Homer J. Simpson' + '742 Evergreen Terrace' + 'Springfield' ولكن في الواقع الإجراء السابق سيسمح لك بتقسيم السلسلة النصية إلى أجزاء أصغر وكتابتها على عدّة أسطر في محرر النصوص فقط، دون حدوث أي أثر على نتيجة الخرج، بمعنى أن السلسلة ستظهر على الخرج في سطر واحد وبدون مسافة فاصلة (رغم استخدام مسافات بادئة في بداية كل جزء من السلسلة في محرّر النصوص) بين جزء وآخر منها، ويكون ناتج تنفيذ الإجراء الإجراء log( )‎ عند تمرير المتغير address بالشّكل: Homer J. Simpson742 Evergreen TerraceSpringfield كما يمكنك استخدام الخط المائل العكسي \ لكتابة السلسلة النصية على عدّة أسطر في محرر النصوص كالتالي: const address = 'Homer J. Simpson\ 742 Evergreen Terrace\ Springfield' والميزة هنا أنّ المسافات البادئة ستظهر فعلًا كمسافات فارغة في السلسة النصية الناتجة، إلّا أنّها ستظهر أيضًا على سطر واحد بالشّكل : Homer J. Simpson 742 Evergreen Terrace Springfield والحل الوحيد لإنشاء سلاسل نصية على عدّة أسطر عند التنفيذ هو استخدام محرف الانتقال لسطر جديد ‎\n أثناء كتابة الرمز، مثلًا: const address = 'Homer J. Simpson\n' + '742 Evergreen Terrace\n' + 'Springfield' وسيظهر الخرج عند التنفيذ بالشّكل: Homer J. Simpson\n 742 Evergreen Terrace\n Springfield إلّا أنّ استخدام محرف الانتقال لسطر جديد (‎\n) يمكن ألا يكون أمرًا بديهيًا، فيمكن أن يظن المبرمج أنّ الانتقال لسطر جديد أثناء كتابة الرمز في محرّر النصوص كافيًا لتظهر النتيجة المطلوبة في الخرج، وهذا ما توفره قوالب النصوص؛ فمع استخدامها لن تحتاج لإضافة علامة ربط السلاسل النصية أو محرف انتقال لسطر جديد ولا حتّى خط مائل عكسي، كل ما تحتاجه هو مجرّد الضغط على زر Enter وستظهر السلسلة النصية على عدّة أسطر افتراضيًا، مثلًا: const address = `Homer J. Simpson 742 Evergreen Terrace Springfield` وبذلك سيكون خرج السلسة النصية تمامًا كما كُتبت، أي في مثالنا بالشّكل: Homer J. Simpson 742 Evergreen Terrace Springfield كما أنّ استخدام قوالب النصوص سيحتفظ أثناء التنفيذ بأي مسافات بادئة وضعتها، لذا تجنّب استخدام أي مسافات إلّا في موضعها المطلوب، فمثلًا لدى كتابة الترميز التالي: const address = `Homer J. Simpson 742 Evergreen Terrace Springfield` فبالرغم من كون طريقة الكتابة السابقة أسهل وأنسب للقراءة، إلّا أنّ الخرج لن يكون كذلك، بل سيكون بالشّكل: Homer J. Simpson 742 Evergreen Terrace Springfield بعد التعرّف على السلاسل متعدّدة الأسطر، فيما يلي سنستعرض كيفية تضمين قيم التعابير البرمجية لحالات التصريح عن السلاسل النصية المختلفة. تضمين قيم التعابير البرمجية في السابق وقبل إصدار ES6 كان يستخدم علامة ربط السلاسل النصية لإنشاء سلاسل نصية ديناميكية باستخدام المتحولات أو التعابير البرمجية (سلاسل نصية ذات قيم متغيرة تبعًا لقيم هذه المتحولات أو التعابير البرمجية)، مثلًا: const method = 'concatenation' const dynamicString = 'This string is using ' + method + '.' فعند تمرير dynamicString إلى الإجراء log( )‎، نحصل في الخرج عند التنفيذ على النتيجة: This string is using concatenation. يمكنك تضمين التعابير البرمجية في المواضع المؤقتة مع استخدام قوالب النصوص، ويعبّر عن المواضع المؤقتة برمجيّا باستخدام الرمز ‎${}‎، فيصبح التعامل مع مضمون الأقواس على أنّه جافاسكربت وكل ما هو خارج الأقواس على أنّه سلسلة نصية، كما في المثال: const method = 'interpolation' const dynamicString = `This string is using ${method}.` وعند تمرير dynamicString إلى التابع log( )‎، نحصل في الخرج عند التنفيذ على النتيجة: This string is using interpolation. ويعدّ تضمين القيم في السلاسل النصية لإنشاء عناوين ويب ديناميكية Dynamic URLs من أكثر الأمثلة شيوعًا، لأنّ تنفيذ ذلك باستخدام علامات ربط السلاسل النصية لن يكون بالأمر السهل، فمثلًا الإجراء التالي يعرّف تابعًا لإنشاء السلسلة اللازمة لمنح الوصول لبروتوكول التوثيق OAuth: function createOAuthString(host, clientId, scope) { return host + '/login/oauth/authorize?client_id=' + clientId + '&scope=' + scope } createOAuthString('https://github.com', 'abc123', 'repo,user') وبتمرير هذا التابع إلى تابع log( )‎ نحصل في الخرج على عنوان الويب التالي: https://github.com/login/oauth/authorize?client_id=abc123&scope=repo,user ولكن ومع استخدام ميزة التضمين في السلاسل النصية التي تقدمها قوالب النصوص، لن تكون مضطرًا لاستخدام علامات الربط أو تتّبع أماكن بدء وانتهاء السلاسل، وفيما يلي نستعرض نفس المثال السابق ولكن عند بناءه باستخدام قوالب النصوص: function createOAuthString(host, clientId, scope) { return `${host}/login/oauth/authorize?client_id=${clientId}&scope=${scope}` } createOAuthString('https://github.com', 'abc123', 'repo,user') وهذا ما سيعطي نفس الخرج كما في حالة استخدام علامات ربط السلاسل النصية: https://github.com/login/oauth/authorize?client_id=abc123&scope=repo,user كما يمكنك تطبيق الإجراء trim()‎ على أي قالب محرفي للتخلص من الفراغات في طرفي السلسلة النصية، في المثال التالي استخدامنا البناء المختصر لتابع يُنشئ عنصر قوائم في HTML برابط مخصّص: const menuItem = (url, link) => ` <li> <a href="${url}">${link}</a> </li> `.trim() menuItem('https://google.com', 'Google') ومع استخدام الإجراء trim()‎ ستُقتص الفراغات من على جانبي القالب المحرفي مما يضمن عرض العنصر بطريقة صحيحة، كالتالي: <li> <a href="https://google.com">Google</a> </li> ولا يقتصر التضمين على المتحولات فقط، بل من الممكن تضمين أي تعبير برمجي، كما في مثال إيجاد ناتج جمع عددين التالي: const sum = (x, y) => x + y const x = 5 const y = 100 const string = `The sum of ${x} and ${y} is ${sum(x, y)}.` console.log(string) يعرّف هذا الترميز البرمجي التابع sum، والمتحولين x وy، ومن ثمّ يستخدم كلًا من التابع والمتحولين في سلسلة نصية، وتكون نتيجة التنفيذ على الخرج بالشّكل: The sum of 5 and 100 is 105. ولهذا فائدة كبيرة خاصّة عند استخدام عمليات اتخاذ قرار Ternary Operators، إذ تسمح بتضمين الشروط في السلاسل النصية، مثلًا: const age = 19 const message = `You can ${age < 21 ? 'not' : ''} view this page` console.log(message) وفي هذه الحالة ستتغير الرسالة في الخرج تبعًا لقيم المتحول age هل هو أعلى أم أقل من 21، وبما أنّ قيمة هذا المتحول في مثالنا هي 19، نحصل على الخرج التالي: You can not view this page وبذلك تكون كوّنت فكرة حول فوائد قوالب النصوص في تضمين التعابير البرمجية. وفيما يلي سنتفحّص قدرة قوالب النصوص الموسومة على التعامل مع التعابير البرمجية الممررّة إلى المواضع المؤقتة. قوالب النصوص الموسومة يعد استخدام قوالب النصوص الموسومة ميزة جيدة متطورّة لقوالب النصوص، والتي تسمّى أيضًا بالقوالب الموسومة. ويبدأ القالب الموسوم بتابع وسم يضيف الوسم للقالب المحرفي، مقدمّاً لك المزيد من التحكّم في عمليات التضمين للحصول على سلاسل نصية ديناميكية. في المثال التالي، ستُنشئ تابع وسم يعمل باستخدام القوالب الموسومة، يتضمّن هذا التابع عاملين، سميّ الأوّل string ويتضمّن السلسلة النصية المجردّة، والثاني هو عامل يستخدم مفهوم Rest Parameters والذي يمكن أن يتضمّن عددًا غير محدّدًا من الوسطاء تمثّل التعابير البرمجية المراد تضمينها في السلسلة النصية. يمكنك التحكّم بهذين العاملين والتنفيذ لرؤية ما سينتج عن تعديل كل منهما، بالشّكل: function tag(strings, ...expressions) { console.log(strings) console.log(expressions) } استخدم التابع tag كتابع القالب الموسوم ونفذ عملية التحويل على السلسلة النصية كالتالي: const string = tag`This is a string with ${true} and ${false} and ${100} interpolated inside.` وبما أنّ الترميز يتضمن إخراج كل من العاملين strings وexpressions، يكون الخرج بالشّكل: (4) ["This is a string with ", " and ", " and ", " interpolated inside." (3) [true, false, 100] العامل الأوّل strings عبارة عن شعاع يتضمّن كافّة قوالب النصوص التالية: * "This is a string with " * " and " * " and " * " interpolated inside." كما أنّ الخاصيّة raw متوفرة لهذا الوسيط من خلال استخدام strings.raw، والتي تتعامل مع السلسلة دون أخذ أي سلسلة هروب بالحسبان، فمثلًا يكون التعامل مع ‎/n على أنّه محرف عادي ولن يفسر على أنه انتقال لسطر جديد. العامل الثاني …expressions وهو شعاع rest، ويحوي كافّة التعابير وهي: * true * false * 100 وتمرر السلاسل النصية المجرّدة والتعابير كعوامل لتابع القالب الموسوم tag، ومن الجدير بالملاحظة أنّه ليس من الضروري أن يعيد القالب الموسوم قيم من النوع سلاسل نصية حصرًا، فهو قادر على التعامل معها إلّا أنّه يعيد أي نوع من أنواع المعطيات، فعلى سبيل المثال يمكننا جعل التابع يتجاهل كل شيء ويعيد قيمة خالية null كما في التابع returnsNull التالي: function returnsNull(strings, ...expressions) { return null } const string = returnsNull`Does this work?` console.log(string) وبتمرير المتحول strings إلى الإجراء log( )‎ تكون القيمة المعادة في الخرج: null ويعد تغيير جانبي كل تعبير مضمّن مثالًا على الإجراءات الممكن تنفيذها في القوالب الموسومة، كما في حال رغبتك بإحاطة كل التعابير بأحد وسوم HTML. مثلًا من الممكن بناء التابع bold الذي يقوم بإضافة <strong> و<‎/strong`> إلى جانبي كل تعبير: function bold(strings, ...expressions) { let finalString = '' //التكرار على كافّة التعابير المضمّنة في السلسة expressions.forEach((value, i) => { finalString += `${strings[i]}<strong>${value}</strong>` }) // إضافة السلسلة المجرّدة النهائية finalString += strings[strings.length - 1] return finalString } const string = bold`This is a string with ${true} and ${false} and ${100} interpolated inside.` console.log(string) يستخدم هذا الترميز الحلقة forEach للمرور على كافّة عناصر الشعاع expressions مضيفًا لكل منها عناصر جعل الخط غامقًا، ويكون الخرج الناتج بالشكل: This is a string with <strong>true</strong> and <strong>false</strong> and <strong>100</strong> interpolated inside. ولا يوجد سوى عدد قليل من الأمثلة على قوالب النصوص الموسومة في المكتبات الشائعة من جافاسكربت، فمثلَا تستخدم المكتبة graphq1-tag القالب الموسوم gq1 لتحويل السلاسل النصية من نتائج الاستعلام GraphQL إلى نمط شجرة البنية المجرّدة the abstract syntax tree (AST)‎ وهو النمط الذي يفهمه GraphQL: import gql from 'graphql-tag' // سجل يقوم بالحصول على اسم وكنية المستخدم ذو الترتيب 5 const query = gql` { user(id: 5) { firstName lastName } } ومن المكتبات التي تستخدم توابع القوالب الموسومة أيضًا هي styled-components، والتي تمكنّك من إنشاء عناصر تفاعلية جديدة من عناصر DOM العادية عبر تطبيق تنسيقات CSS عليها: import styled from 'styled-components' const Button = styled.button` color: magenta; ` ومن الآن وصاعدًا يمكن استخدام الثابت Button كمكوّن مخصّص custom component// ولضمان عدم التعامل مع سلسلة نصية على أنّها سلسلة هروب، يمكنك استخدام الإجراء string.raw في قوالب النصوص الموسومة بالشّكل: const rawString = String.raw`I want to write /n without it being escaped.` console.log(rawString) وهذا ما سيعطي الخرج التالي: I want to write /n without it being escaped. الخلاصة راجعت في هذا المقال طريقة استخدام كل من علامات الاقتباس المفردة والمزدوجة في السلاسل النصية، كما تعلمّت عن قوالب النصوص العادية منها والموسومة، إذ تؤدي قوالب النصوص الكثير من المهام الشائعة المتعلقة بالسلاسل النصية بسهولة كبيرة عبر إمكانية تضمين التعابير البرمجية أو الكتابة على عدّة أسطر دون استخدام أي علامة ربط للسلاسل النصية أو استخدام سلاسل الهروب. كما أنّ القوالب المحرفية الموسومة تمثّل ميزة جديدة متطورة والتي قامت العديد من المكتبات الشائعة باستخدامها، مثل GraphQL و styled-components. ترجمة -وبتصرف- للمقال Understanding Template Literals in JavaScript لصاحبه Tania Rascia. اقرأ أيضًا السلاسل النصية (strings) في جافاسكربت كيفية التعامل مع النصوص في البرمجة ترميز النصوص والتعامل مع كائنات الملفات في جافاسكربت
    1 نقطة
  42. مقدمة تُعتبر المصفوفة في الجافا سكريبت كائن عمومي (global) الغرض منه هو تخزين البيانات، وتحتوي المصفوفة إما على مجموعة من العناصر بنوع بيانات واحد أو أكثر، وقد تكون فارغة. نستخدم الفهارس العددية التي تبدأ من القيمة 0 للوصول إلى عناصر المصفوفة. المصفوفات مفيدة جدًا بما أنها تُخزن عدة قيم في متغير واحد، وهذا الأمر يقلل وينظم الشيفرة البرمجية التي نكتبها ويجعلها أكثر ملائمة للقراءة والصيانة. تستطيع المصفوفة أن تحتوي على أي نوع بيانات، ابتداءً من الأرقام ومرورا بالنصوص والكائنات وغيرها من أنواع البيانات. لتوضيح كيف من الممكن أن تكون المصفوفات مهمة، لنفترض أننا نريد أن نحفظ أسماء المحيطات في متغيرات عدة، بحيث يكون لكل محيط المتغير الخاص به: oceans.js // Assign the five oceans to five variables const ocean1 = "Pacific"; const ocean2 = "Atlantic"; const ocean3 = "Indian"; const ocean4 = "Arctic"; const ocean5 = "Antarctic"; هذه الطريقة مُضجرة جدا، وتُصبح أكثر صعوبة بشكل متسارع في المتابعة والصيانة. باستخدام المصفوفات، نستطيع تبسيط الأمر. oceans.js // Assign the five oceans let oceans = [ "Pacific", "Atlantic", "Indian", "Arctic", "Antarctic", ]; بدلًا من استخدام خمسة متغيرات منفصلة، نستطيع الان أن يكون لدينا متغير واحد يحتوي على جميع العناصر الخمسة. لإنشاء المصفوفة، نستخدم الأقواس المربعة [ ] كما هو واضح في الشيفرة البرمجية السابقة، وللوصول إلى عنصر معين في المصفوفة، نستخدم الفهرس مع المصفوفة بالطريقة التالية: // Print out the first item of the oceans array oceans[0]; Output Pacific في هذا الدرس سنتعلم كيفية بناء المصفوفة، وكيفية الوصول إلى عناصرها، والاضافة إليها وتعديلها والحذف منها، كما سنتعلم كيفية المرور خلال عناصرها باستخدام حلقة التكرار. إنشاء مصفوفة يوجد طريقتان لإنشاء المصفوفة في جافا سكريبت: التعريف اللفظي باستخدام الأقواس المعكوفة. التعريف بواسطة الباني (constructor) باستخدام كلمة new. لنوضح كيفية إنشاء مصفوفة تحتوي على أنواع سمك القرش، وذلك باستخدام التعريف اللفظي بواسطة الأقواس المربعة: sharks.js // Initialize array of shark species with array literal let sharks = [ "Hammerhead", "Great White", "Tiger", ]; الان نُعرف نفس المصفوفة باستخدام الباني وذلك بواسطة الجملة new Array() : sharks.js // Initialize array of shark species with array constructor let sharks = new Array( "Hammerhead", "Great White", "Tiger", ); كلا الطريقتين سوف يُنشئ لنا المصفوفة، ولكن طريقة التعريف اللفظي هي المشهورة والأكثر تفضيلا بما أن التعريف باستخدام الباني قد يؤدي إلى نتائج غير مستقرة وغير متوقعة وعليك الانتباه في حال صادفتك تلك الطريقة في التعريف أو في حال استخدامك لها. نستطيع طباعة محتويات المصفوفة بكتابة المتغير الخاص بها مباشرة: // Print out the entire sharks array sharks; Output [ 'Hammerhead', 'Great White', 'Tiger' ] تُستخدم المصفوفات عادة في تجميع العناصر أو القوائم من نفس نوع البيانات، ولكن من الناحية التقنية، فإن المصفوفات تستطيع أن تحتوي على عناصر من أنواع مختلفة بالإضافة إلى إمكانية أن تحتوي على مصفوفات أخرى: // Initialize array of mixed datatypes let mixedData = [ "String", null, 7, [ "another", "array", ], ]; بعد أن تعلمنا كيفية إنشاء المصفوفة، نستطيع الان التعامل معا بأكثر من طريقة، ولكننا في البداية نحتاج الى فهم كيفية فهرسة المصفوفات (Arrays Indexing). ملاحظة: قد تجد اخر عنصر في المصفوفة ينتهي بفاصلة وأحيانا قد لا تجد هذه الفاصلة. تُعرف هذه الفاصلة بالفاصلة التابعة (Trailing comma)، ومن الشائع ان تكون غير موجودة، ولكن بشكل عام أصبح من الأفضل أن يتم استخدامها في الشيفرة البرمجية بسبب أنها تجعل الاختلافات بين الإصدارات (في عملية إدارة الإصدارات Versions Control) أكثر وضوحا وتسهل من إضافة وإزالة عناصر المصفوفة دون أخطاء. لاحظ أن الفاصلة التابعة غير مسموح بها في ملفات JSON. فهرسة المصفوفات إذا تعاملت مسبقاً مع النصوص والفهرسة في الجافا سكريبت، ستكون مُلمًا بمفهوم فهرسة المصفوفات، حيث أن النص يُعتبر شبيهًا بالمصفوفة. لا تحتوي المصفوفات على عناصر مزدوجة على شكل اسم/قيمة، وبدلا من ذلك، فإن المصفوفات تُفهرس بقيم عددية تبدأ من القيمة 0. المثال التالي ينشئ مصفوفة باسم seaCreatures: seacreatures.js let seaCreatures = [ "octopus", "squid", "shark", "seahorse", "starfish", ]; الجدول التالي يُفصل كيف يتم فهرسة كل عنصر في المصفوفة بقيمة عددية ابتداءً من 0: octopus squid shark seahorse starfish 0 1 2 3 4 العنصر الأول في المصفوفة هو octopus ومُفهرس في الموقع 0 من المصفوفة، والعنصر الأخير هو starfish ومُفهرس في الموقع 4. تبدأ الفهرسة من 0، وهذا يتضارب مع طبيعتنا الفطرية ببدء العد من القيمة 1، لذلك نحتاج لأخذ الاحتياط وأن نتذكر هذه النقطة دائما حتى تصبح طبيعية. نستطيع أن نحصل على عدد العناصر في المصفوفة باستخدام الخاصية length: seaCreatures.length; Output 5 على الرغم من أن الفهارس الخاصة بالمصفوفة seaCreatuers تبدأ من 0 إلى 4، فإن الخاصية length سوف تُرجع العدد الفعلي للعناصر الموجودة في المصفوفة. إذا أردنا معرفة رقم الفهرس لعنصر معين في المصفوفة، وليكن مثلا seahorse، نستطيع أن نستخدم لذلك الوظيفة indexOf() : seaCreatures.indexOf("seahorse"); Output 3 إذا لم تحتوي المصفوفة على العنصر الذي نريده، فلن نحصل على رقم فهرس لعنصر غير موجود، وفي هذه الحالة، فإن الوظيفة سترجع لنا القيمة -1 كما في المثال التالي: seaCreatures.indexOf("cuttlefish"); Output -1 بواسطة أرقام الفهارس المرتبطة بعناصر المصفوفة، فإنه لدينا القدرة على الوصول لكل عنصر بشكل منفرد بهدف العمل على هذا العنصر والتعامل معه. الوصول لعناصر المصفوفة يتم الوصول لعنصر في مصفوفة جافا سكريبت بواسطة الإشارة لرقم الفهرس للعنصر بين قوسين معكوفين: seaCreatures[1]; Output squid نعلم أن الرقم 0 سيعيد لنا دائما العنصر الأول في المصفوفة. كذلك نستطيع إيجاد العنصر الأخير في المصفوفة بواسطة إجراء عملية طرح قيمة 1 من قيمة الخاصية length للمصفوفة، والإشارة لناتج هذه العملية كرقم فهرس للعنصر الأخير كما هو موضح في المثال التالي: const lastIndex = seaCreatures.length - 1; seaCreatures[lastIndex]; Output starfish محاولة الوصول لعنصر غير موجود سيعيد لنا undefined: seaCreatures[10]; Output undefined للوصول لعنصر مصفوفة متداخلة (مصفوفة داخل مصفوفة)، فعلينا إضافة فهرس اخر يعود للمصفوفة الداخلية: let nestedArray = [ [ "salmon", "halibut", ], [ "coral", "reef", ] ]; nestedArray[1][0]; Output coral في المثال السابق، قمنا بالوصول للعنصر coral بالإشارة لرقم الفهرس الذي يحتوي المصفوفة الداخلية وهو 1، ثم أشرنا للفهرس الذي يحتوي على العنصر في المصفوفة الداخلية وهو 0. إضافة عنصر لمصفوفة في المتغير seaCreatuers يوجد لدينا 5 عناصر بأرقام فهراس تبدأ من 0 الى 4. إذا أردنا أن نُضيف عنصر جديد لهذه المصفوفة، فيمكننا أن نقوم بذلك بإعطاء قيمة للفهرس التالي الذي يلي اخر فهرس: seaCreatures[5] = "whale"; seaCreatures; Output [ 'octopus', 'squid', 'shark', 'seahorse', 'starfish', 'whale' ] إذا قمنا بإضافة عنصر وتجاهلنا قيمة الفهرس التالي ووضعنا بدلا منه فهرس بقيمة 7 مثلا، فإن ذلك يؤدي لإضافة عنصر غير مُعرف (undefined) للمصفوفة كما في المثال التالي: seaCreatures[7] = "pufferfish"; seaCreatures; Output [ 'octopus', 'squid', 'shark', 'seahorse', 'starfish', 'whale', , 'pufferfish' ] هذه المشكلة نستطيع تجنبها باستخدام الوظيفة push() والتي تقوم بإضافة العنصر الجديد في نهاية المصفوفة: // Append lobster to the end of the seaCreatures array seaCreatures.push("lobster"); seaCreatures; Output [ 'octopus', 'squid', 'shark', 'seahorse', 'starfish', , 'whale', 'pufferfish', 'lobster' ] على العكس تماما من الوظيفة push()، فإن الوظيفة unshift() تقوم بإضافة العنصر في بداية المصفوفة: // Append dragonfish to the beginning of the seaCreatures array seaCreatures.unshift("dragonfish"); seaCreatures; Output [ 'dragonfish', 'octopus', 'squid', 'shark', 'seahorse', 'starfish', 'whale', , 'pufferfish', 'lobster' ] باستخدام الوظيفتين السابقتين، ستكون لديك المقدرة على إضافة عناصر جديدة للمصفوفة إما في بدايتها، أو نهايتها. إزالة عنصر من مصفوفة لإزالة عنصر معين من مصفوفة، نستخدم الوظيفة splice(). في المصفوفة seaCreatuers قمنا بإضافة عنصر غير مُعرف وليس له قيمة، ولإزالته نقوم بالتالي: seaCreatures.splice(7, 1); seaCreatures; Output [ 'dragonfish', 'octopus', 'squid', 'shark', 'seahorse', 'starfish', 'whale', 'pufferfish', 'lobster' ] في الوظيفة splice()، المُعامل الأول يشير لرقم الفهرس الذي سنبدأ بالإزالة من عنده (في هذه الحالة 7)، والمُعامل الثاني يشير لعدد العناصر التي نرغب بإزالتها (في حالتنا سيكون 1 حيث أننا نرغب بإزالة عنصر واحد). الوظيفة splice() ستؤثر على المتغير الأصلي. لذلك، إذا أردنا أن نحافظ على المصفوفة الأصلية دون تغيير، نستخدم الوظيفة slice() ونعطي القيمة الناتجة عنها لمتغير جديد. let newArray = slice(7, 1); الوظيفة pop() ستزيل العنصر الأخير من المصفوفة: // Remove the last item from the seaCreatures array seaCreatures.pop(); seaCreatures; Output [ 'dragonfish', 'octopus', 'squid', 'shark', 'seahorse', 'starfish', 'whale', 'pufferfish' ] العنصر lobster أُزيل من المصفوفة لأنه العنصر الأخير، ولإزالة العنصر الأول في المصفوفة، نستخدم الوظيفة shift(): // Remove the first item from the seaCreatures array seaCreatures.shift(); seaCreatures; Output [ 'octopus', 'squid', 'shark', 'seahorse', 'starfish', 'whale', 'pufferfish' ] باستخدام الوظيفتين pop() و shift() نستطيع إزالة العناصر من بداية المصفوفة أو نهايتها. يُفضل استخدام الوظيفة pop() قدر الإمكان، حيث أن باقي العناصر في المصفوفة تبقى في مواقعها دون تغيير. تعديل العناصر في المصفوفة نستطيع تغيير أي قيمة عنصر في المصفوفة وذلك بإعطاء القيمة الجديدة للعنصر باستخدام عملية المساواة، كما نفعل تماما عند التعامل مع المتغيرات العادية: // Assign manatee to the first item in the seaCreatures array seaCreatures[0] = "manatee"; seaCreatures; Output [ 'manatee', 'squid', 'shark', 'seahorse', 'starfish', 'whale', 'pufferfish' ] طريقة أخرى لتغيير قيمة العنصر باستخدام الوظيفة splice() وذلك بإضافة مُعامل جديد. فمثلا، إذا أردنا تغيير قيمة العنصر seahorse والذي يقع في الفهرس 3، نستطيع إزالته وإضافة قيمة جديدة بدلا منه: // Replace seahorse with sea lion using splice method seaCreatures.splice(3, 1, "sea lion"); seaCreatures(); Output [ 'manatee', 'squid', 'shark', 'sea lion', 'starfish', 'whale', 'pufferfish' ] في المثال السابق، قمنا بإزالة العنصر seahorse من المصفوفة، ووضعنا بدلا منه القيمة sea lion في نفس الفهرس 3. حلقة التكرار خلال المصفوفة نستطيع المرور على عناصر المصفوفة من خلال حلقة تكرار for وذلك بالاستفادة من خاصية length. في المثال التالي، نُنشئ مصفوفة باسم shellfish ونطبع رقم كل فهرس فيها بالإضافة إلى قيمة العنصر المرتبط بالفهرس: // Create an array of shellfish species let shellfish = [ "oyster", "shrimp", "clam", "mussel", ]; // Loop through the length of the array for (let i = 0; i < shellfish.length; i++) { console.log(i, shellfish[i]); } Output 0 'oyster' 1 'shrimp' 2 'clam' 3 'mussel' نستطيع أيضا استخدام حلقة التكرار for…of وهي خاصية جديدة في الجافا سكريبت: // Create an array of aquatic mammals let mammals = [ "dolphin", "whale", "manatee", ]; // Loop through each mammal for (let mammal of mammals) { console.log(mammal); } Output dolphin whale manatee حلقة التكرار for…of لا تقوم باستخدام رقم الفهرس للعناصر في المصفوفة، ولكنها بشكل عام طريقة أبسط وأكثر اختصارا للمرور على المصفوفة من خلال حلقة التكرار. استخدام حلقات التكرار مفيد بشكل كبير في طباعة قيم عناصر المصفوفة وهو يشبه عرض العناصر من قاعدة بيانات خلال موقع الكتروني. خاتمة تُعتبر المصفوفات جزء أساسي ومهم في برمجة الجافا سكريبت. في هذا الدرس تعلمنا كيفية إنشاء المصفوفة، وكيفية فهرستها، وتعلمنا إجراء بعض العمليات المهمة على المصفوفات مثل إزالة العناصر والتعديل عليها. وكذلك تعلمنا طريقتين للمرور على عناصر المصفوفة من خلال حلقات التكرار والتي تهدف لإجراء عمليات على عناصر المصفوفة مثل طباعة محتوياتها وطباعة أرقام الفهارس. ترجمة -وبتصرّف- للمقال Understanding Arrays in JavaScript لصاحبه Tania Rascia حقوق الصورة البارزة محفوظة لـ Freepik
    1 نقطة
  43. يتكون أبسط برنامج يمكن كتابته من سلسلة من بعض التعليمات statements المتتالية، وأصغرها هو الذي يحتوي تعليمةً برمجيةً واحدةً، حيث تُدخَل التعليمة عادةً في سطر واحد، كما يمكن أن تُقسم على عدة أسطر، وتعرَّف التعليمة بأنها مجموعة من الكلمات والرموز المكتوبة بلغة طبيعية، وسننظر الآن في بعضها، إذ تُظهر الأمثلة التالية ما يجب أن نكتبه في محث بايثون ‎>>>‎، كما تُظهر النتيجة، ثم نشرح ما حدث. عرض الخرج يجب أن نتعلم أولًا كيف نجعل بايثون تعرض المعلومات التي نريدها، فإذا لم تعرض لنا اللغة شيئًا، فكيف نعرف ما فعله الحاسوب؟ وما فائدة الجهد الذي نبذله في البرمجة حينها إذا كنا لا نعرف هل أصبنا أم أخطأنا؟ >>> print('Hello there!') Hello there! انتبه إلى الملاحظة الأولى في المثال أعلاه، وهي أن المسافة التي بين المحث وبين أمر print ليست ضرورية، إذ ستضعها بايثون تلقائيًا إذا نسيناها، وما سنكتبه هو السطر الأول فقط؛ أما السطر الثاني فهو نتيجة البرنامج الذي كتبناه في السطر الأول، وقد عرضه لنا المفسر. أما الملاحظة الثانية فهي أن بايثون حساسة لحالة الأحرف، حيث سنحصل على خطأ إذا كتبنا Print بدلًا من print لأن بايثون تراهما كلمتين مختلفتين، وكذلك الحال بالنسبة لجافاسكربت؛ أما لغة VBScript فلا تهتم لهذا، لكن يجب تعويد النفس على الاهتمام بحالة الأحرف كعادة برمجية حسنة لئلا تقع في أخطاء بسببها إذا انتقلت من لغة برمجية لأخرى. وقد عرض لنا المفسر النص المكتوب بين علامتي الاقتباس لأن الدالة print()‎ تخبر بايثون بعرض تسلسل المحارف H,e,l,l,o, ,t,h,e,r,e,!‎، وهو ما يُعرَف في الأوساط البرمجية باسم السلسلة النصية string، أو سلسلة المحارف النصية، حيث يجب أن تكون تلك المحارف داخل أقواس، وندل على السلسلة النصية بوضعها بين علامات الاقتباس، كما يمكن استخدام علامات الاقتباس المفردة أو المزدوجة في بايثون دون حرج، مما يسمح لنا بإدخال أحد نوعي الاقتباس في سلسلة نصية محاطة بالنوع الآخر، وهذا مفيد في حالة الفاصلة الإنجليزية العليا ': >>> print("Monty Python's Flying Circus has a ' within it...") Monty Python's Flying Circus has a ' within it... أما جافاسكربت وVBScript فحساستان لنوع علامات التنصيص التي يجب استخدامها، لهذا يُنصح فيهما بالالتزام بالعلامات المزدوجة ما أمكن. عرض النتائج الحسابية >>> print(6 + 5) 11 يطبع لنا المثال أعلاه نتيجة العملية الحسابية التي في السطر الأول، والتي جمعنا فيها 5 إلى 6، وقد عرفت بايثون أن هذه المحارف أرقام وعاملتها على هذا الأساس، كما تعرفت على علامة الجمع التي بينهما، فجمعت العددين وأخرجت لنا الناتج، لذا يمكن القول أن بايثون مفيدة كحاسبة للجيب، وهو أحد استخداماتها الكثيرة جدًا، جرب الآن بعض الحسابات الأخرى واستخدم العوامل الحسابية التالية: الطرح (-). الضرب (*). القسمة (/). يمكن دمج عدة تعبيرات حسابية كما يلي: >>> print( ((6 * 5) + (7 - 5)) / (7 + 1) ) 4.0 لاحظ الطريقة التي استخدمنا بها الأقواس لوضع الأعداد في مجموعات، لقد رأت بايثون تلك العملية السابقة كما يلي: ((6 * 5) + (7 - 5)) / (7 + 1) => (30 + 2) / 8 => 32 / 8 => 4 فماذا يحدث لو كتبنا نفس العمليات دون الأقواس؟ >>> print(6 * 5 + 7 - 5 / 7 + 1) 37.2857142857 حصلنا على هذه النتيجة لأن بايثون تنفذ عمليتي الضرب والقسمة قبل الجمع والطرح، لذا رأتها على النحو التالي: (6*5) + 7 - (5/7) + 1 => 30 + 7 - 0.7143 + 1 => 37 - 0.7143 + 1 => 38 - 0.7143 => 37.2857... ومع أن ترتيب بايثون لمعالجة العمليات الحسابية هو نفسه الذي تقضيه قوانين الرياضيات، إلا أنه يختلف عما يجب عليك توقعه كونك مبرمجًا، لأن بعض لغات البرمجة لها قوانينها في ترتيب معالجة العمليات الحسابية، وهو ما يعرف بأسبقية العوامل operator precedence، لذا تأكد من النظر أولًا في توثيق لغة البرمجة التي تتعامل معها لترى أسلوبها الخاص؛ أما بايثون فقاعدتها العامة هي ما يقتضيه الحدس والمنطق، لكن هذا له استثناءاته، مما يجعل استخدام الأقواس خيارًا آمنًا لضمان حصولنا على النتيجة التي نريدها، خاصةً عند التعامل مع حسابات طويلة مثل التي رأيناها في المثال السابق، ومن الأمور التي يجب ملاحظتها أننا إذا استخدمنا عامل القسمة / فسنحصل على النتيجة الدقيقة للعملية، كما يلي: >>> print(5/2) 2.5 فإذا أردنا الحفاظ على القسم الصحيح للناتج فقط فنستخدم عامليْ قسمة متتاليين // لنحصل على العدد الكامل في النتيجة، وستطبع بايثون ناتج القسمة كما يلي: >>> print(5//2) 2 أما إذا أردنا الحصول على باقي عملية القسمة فنستخدم محرف النسبة المئوية %: >>> print(5%2) 1 >>> print(7//4) 1 >>> print(7%4) 3 يُعرَف العامل % باسم عامل الباقي modulo، وقد يكون في بعض لغات البرمجة على الصورة MOD أو نحوها، أما في بايثون فنستطيع الحصول على ناتج القسمة والباقي معًا باستخدام الدالة divmod()‎: >>> print( divmod(7,4) ) (1, 3) هذه العمليات الحسابية للأعداد الصحيحة مهمة للغاية في البرمجة، فمنها نستطيع تحديد كون العدد زوجيًا أم فرديًا من خلال قسمته على 2 ورؤية الباقي (يكون زوجيًا إذا كان الباقي صفرًا)، كما يلي: >>> print( 47 % 2 ) 1 فنحن نعلم الآن أن العدد 47 هو عدد فردي، وقد يكون هذا أمرًا بدهيًا إذ يمكن معرفة هذا دون تكبد عناء لغة برمجية وانتظار خرج عملية فيها، لكن ماذا لو كنا نقرأ بيانات من ملف، أو كان المستخدم يدخل تلك البيانات، ثم يكون على برنامجنا معرفة هل العدد فردي أم زوجي من تلقاء نفسه، عندئذ لن نستطيع التدخل هنا لتقرير ذلك بالنظر في كل عدد، بل سنستخدم عامل الباقي كما فعلنا ليتحقق من المطلوب بدلًا منا، وتلك حالة واحدة فقط من الحالات التي تبرز فيها أهمية هذه العمليات، لذا تدرب عليها إلى أن تتقنها. دمج السلاسل النصية والأعداد >>> print( 'The total is: ', 23+45) The total is: 68 لقد طبعنا سلاسل نصيةً أوأعدادًا فيما سبق، أما الآن فسندمج الاثنين في تعليمة واحدة، فاصلين بينهما بفاصلة إنجليزية ,، ويمكن توسيع تلك الميزة بجمعها مع إحدى خصائص بايثون في إخراج البيانات، وهي سلسلة التنسيق format string: >>> print( "The sum of %d and %d is: %d" % (7,18,7+18)) The sum of 7 and 18 is: 25 تحتوي سلسلة التنسيق على علامات %، غير أنها تختلف عن عامل الباقي الذي تحدثنا عنه من قبل، بل يكون لها معنىً خاص حين تُستخدم في سلسلة كالتي بين أيدينا، وحالات الاستخدام المتعددة تلك تعني أن علينا قراءة المكتوب بانتباه لتحديد سياقه، ثم تحديد وظيفة % فيه، حيث يخبر الحرف d الذي بعد محرف % بايثون بوجوب وضع عدد عشري مكانه، والذي نحصل على قيمته -التي سنستخدمها لتحل محله- من القيم الموجودة داخل التعبير الذي بين الأقواس، والذي كتِب بعد علامة % المنفردة في نهاية العبارة، ومن المهم أن يكون عدد القيم التي في القوس النهائي مطابقًا لعدد علامات % الموجودة في السلسلة النصية. توجد حروف أخرى يمكن وضعها بعد علامة %، ويستعمَل كل منها لغرض مختلف، منها: ‎%S للسلاسل النصية. ‎%x للأعداد الست عشرية hexadecimal. %0.2f للأعداد الحقيقية التي لها منزلتان عشريتان كحد أقصى. %04d لإزاحة العدد بأصفار قبله ليكون من أربعة منازل عشرية. انظر توثيق بايثون للمزيد من المعلومات. ونستطيع طباعة أي كائن بايثون باستخدام دالة الطباعة، حتى لو كانت النتيجة على غير ما كنا نريد، فربما تكون وصفًا لنوع الكائن، لكننا نستطيع طباعة ذلك على أي حال. >>> print( "The sum of {:d} and {:d} is: {:d}".format(7,18,7+18) The sum of 7 and 18 is: 25 زيادة إمكانيات اللغة >>> import sys إذا كتبنا السطر أعلاه في محث بايثون ثم ضغطنا على زر الإدخال، فلن نرى شيئًا على الشاشة، غير أن هذا لا يعني عدم حدوث شيء ما في الخلفية، ولشرح ما حدث بعد كتابة هذه الأمر سننظر أولًا إلى معمارية بايثون نفسها، وحتى لو لم تكن تستخدم بايثون فتابع الشرح، إذ ستكون ثمة آليات مشابهة في اللغة التي تستخدمها. عند بدء لغة بايثون تتاح لنا عدة دوال وأوامر، وهذه الأوامر مدمجة في اللغة وتسمى بالمضمَّنات built-ins، لأنها مبنية داخل نسيج اللغة نفسها، غير أن بايثون تستطيع توسيع قائمة الدوال المتاحة بدمج وحدات توسيع extension modules فيها، وهو يشبه شراء المرء لأداة جديدة من متجر العُدد والآلات ليضيفها إلى مجموعته المنزلية، وفي مثالنا فإن الآلة هي sys، وقد وضعتها العملية import داخل صندوق الآلات الذي سنستخدمه؛ أما حقيقة ما يفعله هذا الأمر فهو إتاحة "أدوات" جديدة على شكل دوال للغة بايثون، تُعرَّف داخل وحدة اسمها sys، وتلك طريقة توسيع بايثون لتنفيذ أي شيء غير مدمج في النظام الأساسي، وستجد أكثر من مئة وحدة في المكتبة القياسية standard library التي تحصل عليها مع بايثون، كما يمكنك إنشاء وحداتك الخاصة واستيرادها واستخدامها مثل الوحدات التي وفرتها بايثون عند تثبيتها بالضبط، وسنعود إلى هذا الأمر لاحقًا. كذلك ستجد مزيدًا من الوحدات التي يمكن تحميلها من الإنترنت، فإذا بدأت مشروعًا لا تغطيه الوحدات التي في المكتبة القياسية، فانظر في الإنترنت أولًا فلعلك تجد شيئًا يساعدك. الخروج السريع لننظر الآن في كيفية استخدام تلك الأدوات التي أدخلناها، فإذا كتبنا الأمر التالي في محث بايثون؛ فسنجعل بايثون تنهي نفسها وتخرج، لأننا نكون قد نفّذنا الدالة exit المعرَّفة في وحدة sys. >>> sys.exit() لاحظ أننا نخرج من بايثون عادةً بكتابة محرف نهاية الملف End Of File واختصاره EOF في محث بايثون، وهو CTRL+Z على ويندوز أو CTRL+D على أنظمة يونكس Unix؛ أما إذا كنت تستخدم بيئة تطوير فتخرج من قائمة File ثم Exit، وإذا حاولنا تنفيذ هذا في أداة تطوير مثل IDLE؛ فإن الأداة تنتبه لمحاولة الخروج وتعرض رسالةً تقول شيئًا ما حول SystemExit، لكن لا تشغل بالك بها، فهذا يعني أن البرنامج يعمل وأن الأداة تحاول توفير الوقت عليك لئلا تبدأ من الصفر مرةً أخرى. لاحظ أن exit لها أقواس حولها، وذلك لأنها دالة معرفة في وحدة sys، حيث سنحتاج إلى وضع هذه الأقواس عند استدعاء دالة بايثون حتى لو لم تحتوي الأقواس نفسها على أي شيء، فإذا كتبنا sys.exit دون الأقواس، فستستجيب بايثون لنا بإخبارنا أن exit دالةٌ، بدلًا من تنفيذ الدالة نفسها. أخيرًا، لاحظ أن التعليمتين الأخيرتين مفيدتان عند استخدامهما معًا، أي أننا سنكتب ما يلي للخروج من بايثون بدلًا من EOF: >>> import sys >>> sys.exit() هكذا نكون قد كتبنا تسلسلًا بسيطًا من تعليمتين، ونكون قد خطونا قليلًا نحو البرمجة الحقيقية. استخدام جافاسكربت لا توجد طريقة سهلة في جافاسكربت لنكتب الأوامر ونراها تنفَّذ مباشرةً كما في بايثون، لكن نستطيع كتابة جميع الأوامر البسيطة أعلاه في ملف HTML واحد ثم تحميلها إلى المتصفح، وسنرى كيف تبدو حينئذ في جافاسكربت: <html><body> <script type="text/javascript"> document.write('Hello there!<br />'); document.write("Monty Python\'s Flying Circus has a \' within it<br />"); document.write(6+5); document.write("<br />"); document.write( ((8 * 4) + (7 - 3)) / (2 + 4) ); document.write("<br />"); document.write( 5/2 ); document.write("<br />"); document.write( 5 % 2 ); </script> </body></html> سيكون الخرج كما يلي: Hello there! Monty Python's Flying Circus has a ' within it 11 6 2.5 1 نستخدم document.write لإخراج النص إلى نافذة المتصفح، وهذا يكافئ تقريبًا دالة print في بايثون، وسنرى قريبًا طريقةً مختلفةً قليلًا في VBSCript لعرض المخرجات في المتصفح في المثال التالي. لاحظ كيف اضطررنا إلى كتابة ‎<br />‎ كي نجبر البرنامج أن يعرض الخرج التالي في سطر جديد، وذلك لأن جافاسكربت تكتب مخرجاتها في صورة HTML، والتي تعرض السطر بأقصى عرض تسمح به نافذة المتصفح لديك، فإذا أردنا قسرها على إنهاء السطر وبدء سطر جديد، فسنستخدم رمز HTML الخاص بالسطر الجديد، وهو ‎<br />‎. لاحظ كيف هرّبنا محارف الاقتباس المفردة بوضع شرطة مائلة خلفية \ قبل الاقتباس، سنشرح ذلك بالتفصيل حين نتحدث عن السلاسل النصية في فصل البيانات وأنواعها. VBScript كما ذكرنا بخصوص جافاسكربت؛ فيجب أن ننشئ ملفًا لوضع أوامر VBScript فيها ثم نفتحه في المتصفح، وإذا كتبنا الأوامر السابقة باستخدام VBScript فستبدو كما يلي: <html><body> <script type="text/vbscript"> MsgBox "Hello There!" MsgBox "Monty Python's Flying Circus has a ' in it" MsgBox 6 + 5 MsgBox ((8 * 4) + (7 - 3)) / (2 + 4) MsgBox 5/2 MsgBox 5 MOD 2 </script> </body></html> سنرى في الخرج كثيرًا من الصناديق الحوارية، يعرض كل منها خرجًا من أحد الأسطر التي في البرنامج، فإذا أردنا أن نجعل جافاسكربت تخرج لنا مثل تلك الصناديق الحوارية فسنستخدم alert("Hello There!")‎ بدلًا من document.write("Hello there!<br>")‎، فقد استخدمنا alert هنا بدلًا من MsgBox التي في VBScript. لاحظ أننا لا نستطيع بدء سلسلة نصية باستخدام علامة اقتباس مفردة في VBScript، لكن يمكننا إدراج اقتباسات مفردة داخل سلاسل نصية ذات علامات اقتباس مزدوجة، باستخدام الدالة Chr التي إذا أعطيناها رمزًا لمحرف أعادت لنا ذلك المحرف، وبما أن هذا المثال يبدو فوضويًا للغاية، لنلق نظرةً على المثال التالي الذي يوضح كيفية عملها: <script type="text/vbscript"> Dim qt qt = Chr(34) MsgBox qt & "Go Away!" & qt & " he cried" </script> لمعرفة رمز أي محرف تريده؛ تستطيع الاسترشاد بهذا الموقع، وأخذ الرمز العشري decimal منه، أو بالنظر في خريطة المحارف التي يوفرها نظام التشغيل الخاص بك، إذ توفر أغلب نظم التشغيل المشهورة بريمجًا لذلك؛ أما إذا لم ترد استخدام هذا ولا ذاك لسبب ما؛ فاستخدم الجزء التالي من لغة جافاسكربت واستبدل المحرف الذي تريده بمحرف الاقتباس المزدوج الذي في المثال: <script type="text/javascript"> var code, chr = '"'; // put the character of interest here code = chr.charCodeAt(0); document.write("<br />The character code of " + chr + " is " + code); </script> لا تشغل بالك الآن بمعنى الأرقام التي في المثال، إذ سنعود إليها في الفصل التالي، وإنما سقناها الآن من أجل استخدامها إذا اضطررنا إلى إيجاد قيمة محرف ما. خاتمة تلك كانت نظرتنا الأولى على البرمجة، ولعلها كانت سهلة الفهم والإدراك، لكن سنحتاج إلى أن ننظر في أنواع البيانات التي سنقابلها في البرمجة وسنحتاج إليها قبل الشروع في البرمجة الحقيقية، كما سنرى الأمور والعمليات التي سنجريها على تلك البيانات. وقد عرفنا في هذا الفصل أن البرنامج قد يكون صغيرًا للغاية، لذا فلا مانع من أن يكون مجرد أمر واحد، وأن أسلوب بايثون في إجراء العمليات الحسابية هو نفسه الأسلوب المتبع في الرياضيات، وإذا أردنا الحصول على نتيجة كسرية فيجب أن نستخدم أعدادًا كسريةً كذلك، وأننا نستطيع دمج النصوص والأرقام باستخدام عامل التنسيق %، وأخيرًا عرفنا أننا نخرج من بايثون بكتابة import sys; sys.exit()‎. ترجمة -بتصرف- للفصل الرابع من كتاب Learning To Program لصاحبه Alan Gauld. اقرأ أيضًا المقال التالي: مدخل إلى البيانات وأنواعها: أنواع البيانات الأساسية المقال السابق: بداية رحلة تعلم البرمجة ما هي البرمجة؟ تعلم البرمجة
    1 نقطة
  44. قواعد صنف الاختبار بفرض لدينا الصنف LoginForm مع التابع rules()‎، والذي يستخدم في صفحة تسجيل الدخول مثل قالب لإطار العمل: class LoginForm { public $email; public $rememberMe; public $password; // (1) public function rules() { return [ // البريد الإلكتروني وكلمة السر مطلوبان [['email', 'password'], 'required'], // يجب أن يكون البريد الإلكتروني بصياغة بريد إلكتروني ['email', 'email'], // ‫يجب أن يكون الحقل rememberMe قيمة منطقية ['rememberMe', 'boolean'], // ‫يجب أن تطابق كلمة السر هذا النمط (أي تحوي أحرف وأرقام فقط) ['password', 'match', 'pattern' => '/^[a-z0-9]+$/i'], ]; } // ‫تتحقق هذه الدالة من صحة القواعد الممررة public function validate($rule) { $success = true; list($var, $type) = $rule; foreach ((array) $var as $var) { switch ($type) { case "required": $success = $success && $this->$var != ""; break; case "email": $success = $success && filter_var($this->$var, FILTER_VALIDATE_EMAIL); break; case "boolean": $success = $success && filter_var($this->$var, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) !== null; break; case "match": $success = $success && preg_match($rule["pattern"], $this->$var); break; default: throw new \InvalidArgumentException("Invalid filter type passed") } } return $success; } } في الموضع (1) يعيد التابع rules()‎ مصفوفة بمتطلبات كل حقل، يستخدم نموذج تسجيل الدخول البريد الإلكتروني وكلمة المرور لاستيثاق المستخدم. نستخدم اختبار الوحدات لإجراء الاختبارات على هذا الصنف، أي للتحقق من الشيفرة المصدرية لمعرفة إذا كانت تناسب توقعاتنا: class LoginFormTest extends TestCase { protected $loginForm; // تنفيذ الشيفرة في بداية الاختبار public function setUp() { $this->loginForm = new LoginForm; } // (1) public function testRuleValidation() { $rules = $this->loginForm->rules(); // التهيئة للتحقق من صحة واختبار البيانات التالية $this->loginForm->email = "valid@email.com"; $this->loginForm->password = "password"; $this->loginForm->rememberMe = true; $this->assertTrue($this->loginForm->validate($rules), "Should be valid as nothing is invalid"); // اختبار صحة البريد الإلكتروني // بما أننا حددنا أن يكون البريد الإلكتروني بصياغة بريد إلكتروني فلا يمكن أن يكون فارغًا­ $this->loginForm->email = ''; $this->assertFalse($this->loginForm->validate($rules), "Email should not be valid (empty)"); // ‫لا يحتوي البريد الإلكتروني على العلامة "@" لذا فهو غير صحيح $this->loginForm->email = 'invalid.email.com'; $this->assertFalse($this->loginForm->validate($rules), "Email should not be valid (invalid format)"); // قيمة صحيحة للبريد الإلكتروني من أجل الاختبار التالي $this->loginForm->email = 'valid@email.com'; // ‫اختبار صحة كلمة المرور والتي يجب ألا تكون فارغة (بما أنها مطلوبة) $this->loginForm->password = ''; $this->assertFalse($this->loginForm->validate($rules), "Password should not be valid (empty)"); // قيمة صحيحة لكلمة المرور من أجل الاختبار التالي $this->loginForm->password = 'ThisIsMyPassword'; // ‫اختبار صحة الحقل rememberMe $this->loginForm->rememberMe = 999; $this->assertFalse($this->loginForm->validate($rules), "RememberMe should not be valid (integer type)"); // ‫قيمة صحيحة للحقل rememberMe من أجل الاختبار التالي $this->loginForm->rememberMe = true; } } في الموضع (1) يجب أن نستخدم التابع validate()‎ للتحقق من صحة قواعدنا، يعود التابع testRuleValidation()‎ إلى اختبار الوحدة الخاص بالصنف LoginFormTest ويختبر القواعد المذكورة سابقًا. كيف يمكن أن يساعد اختبار الوحدات هنا (باستثناء الأمثلة العامة)؟ يناسبنا عند الحصول على نتائج غير متوقعة مثلًا، بفرض لدينا هذه القاعدة: ['password', 'match', 'pattern' => '/^[a-z0-9]+$/i'], إذا نسينا شيئًا واحدًا مهمًا وكتبنا: ['password', 'match', 'pattern' => '/^[a-z0-9]$/i'], من الصعب اكتشاف الأخطاء مع وجود عشرات القواعد المختلفة، وبفرض أننا لا نستخدم البريد الإلكتروني وكلمة المرور فقط، إليك اختبار الوحدة هذا: // التهيئة للتحقق من صحة واختبار البيانات التالية $this->loginForm->email = "valid@email.com"; $this->loginForm->password = "password"; $this->loginForm->rememberMe = true; $this->assertTrue($this->loginForm->validate($rules), "Should be valid as nothing is invalid"); سيمرر هذا الاختبار مثالنا الأول وليس الثاني لأنه لدينا خطأ مطبعي في المثال الثاني (لم نكتب علامة +)، مما يعني أنه سيقبل حرف/رقم واحد فقط. يمكن تنفيذ اختبار الوحدات في الطرفية باستخدام الأمر phpunit [path_to_file]‎، إذا كان كل شيء صحيحًا، يجب أن نكون قادرين على رؤية الحالة OK لكل الاختبارات وإلا سنرى إما Error لخطأ في الصيغة، أو Fail على الأقل لسطر واحد لم يُمرَّر في ذلك التابع. يمكننا أيضًا باستخدام معاملات إضافية مثل ‎--coverage أن نحصل على عدد الأسطر المُختبرة من الشيفرة في الواجهة الخلفية backend وأيها نجحَ/فشلَ، يُطبَّق هذا على أي إطار عمل ثبّتَ PHPUnit. إليك مثال عن طريقة ظهور اختبار PHPUnit في الطرفية، وهو مثال عام وليس له صلة بمثالنا: مقدمو بيانات PHPUnit تحتاج توابع الاختبار عادةً إلى بيانات لتُختَبر بها، ولاختبار بعض التوابع كاملةً تحتاج لتوفير مجموعات بيانات مختلفة لكل حالة اختبار ممكنة، يمكنك القيام بذلك يدويًا باستخدام الحلقات، مثال: ... public function testSomething() { $data = [...]; foreach($data as $dataSet) { $this->assertSomething($dataSet); } } ... يمكن أن تجد هذه الطريقة مريحة ولكن لها بعض العيوب، أولًا عليك أن تؤدي إجراءات إضافية لاستخراج البيانات إذا كانت دالة الاختبار تقبل عدة معاملات، ثانيًا سيكون من الصعب في حالة الفشل تمييز مجموعة البيانات الخاطئة بدون تنقيح أخطاء ورسائل إضافية، ثالثًا يوفر PHPUnit طريقة تلقائية للتعامل مع مجموعات بيانات الاختبار باستخدام مقدمي البيانات. مقدم البيانات دالة يجب أن ترجع بيانات حالة الاختبار الخاصة بك، ويجب أن تكون هذه الدالة عامة وترجع إما مصفوفة من المصفوفات أو كائن ينفّذ الواجهة Iterator ويُرجع مصفوفة لكل خطوة تكرارية. كل مصفوفة جزء من المجموعة collection التي سيستدعيها تابع الاختبار مع محتويات المصفوفة كوسائط لها. لاستخدام مقدم البيانات مع الاختبار نستخدم التوصيف ‎@dataProvider مع اسم دالة مقدم البيانات المحددة: /** * @dataProvider dataProviderForTest */ public function testEquals($a, $b) { $this->assertEquals($a, $b); } public function dataProviderForTest() { return [ [1,1], [2,2], [3,2] //this will fail ]; } مصفوفة مصفوفات لاحظ أنّ الدالة dataProviderForTest()‎ ترجع مصفوفة من مصفوفات، كل مصفوفة متداخلة تحتوي عنصرين سيملآن المعاملات الضرورية للدالة testEquals()‎، إذا لم يكن هناك عناصر كافية سيُرمى خطأ مشابه للخطأ التالي: Missing argument 2 for Test::testEquals()‎ حيث سيمر PHPUnit تلقائيًا على كل البيانات وينفذ الاختبارات، كما هو ظاهر فيما يأتي: public function dataProviderForTest() { return [ [1,1], // [0] testEquals($a = 1, $b = 1) [2,2], // [1] testEquals($a = 2, $b = 2) [3,2] // [2] There was 1 failure: 1) Test::testEquals with data set #2 (3, 4) ]; } يمكن أن تُسمَّى كل مجموعة بيانات ليكون من الأسهل اكتشاف بيانات الفشل: public function dataProviderForTest() { return [ 'Test 1' => [1,1], // [0] testEquals($a = 1, $b = 1) 'Test 2' => [2,2], // [1] testEquals($a = 2, $b = 2) 'Test 3' => [3,2] // [2] There was 1 failure: // 1) Test::testEquals with data set "Test 3" (3, 4) ]; } المكررات class MyIterator implements Iterator { protected $array = []; public function __construct($array) { $this->array = $array; } function rewind() { return reset($this->array); } function current() { return current($this->array); } function key() { return key($this->array); } function next() { return next($this->array); } function valid() { return key($this->array) !== null; } } ... class Test extends TestCase { /** * @dataProvider dataProviderForTest */ public function testEquals($a) { $toCompare = 0; $this->assertEquals($a, $toCompare); } public function dataProviderForTest() { return new MyIterator([ 'Test 1' => [0], 'Test 2' => [false], 'Test 3' => [null] ]); } } كما تلاحظ، فإنَّ المكرِّر البسيط يعمل أيضًا، وأنّ مقدم البيانات يجب أن يرجع مصفوفة ‎$parameter حتى من أجل معامل واحد. إذا غيّرنا التابع current()‎ الذي يعيد البيانات في كل تكرار، بالشكل التالي: function current() { return current($this->array)[0]; } أو غيّرنا البيانات الفعلية: return new MyIterator([ 'Test 1' => 0, 'Test 2' => false, 'Test 3' => null ]); سنحصل على خطأ: There was 1 warning: 1) Warning The data provider specified for Test::testEquals is invalid. من غير المفيد طبعًا استخدام الكائن Iterator لتكرار محتويات مصفوفة بسيطة، يجب أن ينفّذ بعض المنطق المحدد لحالتك. المولدات generators لم يُشار إليها بشكلٍ صريح في التوثيق الرسمي لكن يمكنك استخدامها كمقدم بيانات أيضًا­، لاحظ أنّ الصنف Generator ينفّذ الواجهة Iterator فعليًا، إليك مثال عن استخدام DirectoryIterator مع مولِّد: /** * @param string $file * * @dataProvider fileDataProvider */ public function testSomethingWithFiles($fileName) { // ‫‎$fileName متاح هنا // اختبر هنا } public function fileDataProvider() { $directory = new DirectoryIterator('path-to-the-directory'); foreach ($directory as $file) { if ($file->isFile() && $file->isReadable()) { // تنفيذ المولِّد هنا yield [$file->getPathname()]; } } } لاحظ أنّ مقدم البيانات يُرجع مصفوفة، وستحصل على تحذير أنّ مقدم البيانات غير صحيح. استثناءات الاختبار لنفرض أنك تريد اختبار تابع يرمي استثناءً. class Car { /** * @throws \Exception */ public function drive() { throw new \Exception('Useful message', 1); } } يمكنك القيام بذلك عن طريق تضمين استدعاء التابع في كتلة try/catch وإجراء توكيدات على خاصيات كائن الاستثناء، أو يمكنك استخدام توابع توكيد الاستثناء للمزيد من الملاءمة، يمكنك بدءًا من الإصدار PHPUnit 5.2 استخدام توابع expectX()‎ المتاحة لتأكيد نوع ورسالة وشيفرة الاستثناء. class DriveTest extends PHPUnit_Framework_TestCase { public function testDrive() { // التحضير $car = new \Car(); $expectedClass = \Exception::class; $expectedMessage = 'Useful message'; $expectedCode = 1; // الاختبار $this->expectException($expectedClass); $this->expectMessage($expectedMessage); $this->expectCode($expectedCode); // التنفيذ $car->drive(); } } يمكنك أن تستخدم التابع setExpectedException بدلًا من expectX()‎ إذا كنت تستخدم إصدارًا قديمًا من PHPUnit لكن تذكر أنه تابع مُهمل وسيُحذف في الإصدار 6. class DriveTest extends PHPUnit_Framework_TestCase { public function testDrive() { // التحضير $car = new \Car(); $expectedClass = \Exception::class; $expectedMessage = 'Useful message'; $expectedCode = 1; // الاختبار $this->setExpectedException($expectedClass, $expectedMessage, $expectedCode); // التنفيذ $car->drive(); } } الأداء التحليل مع Xdebug تُعَدّ إضافة Xdebug متاحةً للمساعدة في تحليل تطبيقات PHP، بالإضافة إلى تنقيح الأخطاء وقت التنفيذ، عند تنفيذ المحلل يُكتب الخرج في ملف بصياغة ثنائية تدعى cachegrind. توجد تطبيقات متوفرة على كل منصة لتحليل هذه الملفات. لتمكين التحليل نثبّت الإضافة ونعدّل إعدادات ملف php.ini. سننفذ في مثالنا المحلل اختياريًا بالاعتماد على معامل الطلب، يسمح لنا هذا بالحفاظ على الإعدادات ثابتة وتشغيل المحلل عندما نحتاج فقط. // اضبطه إلى 1 لتشغيله عند كل طلب xdebug.profiler_enable = 0 // ‫لنستخدم معامل GET/POST لتشغيل المحلِّل xdebug.profiler_enable_trigger = 1 // ‫قيمة GET/POST التي سنمررها، فارغة من أجل أي قيمة xdebug.profiler_enable_trigger_value = "" // ‫عرض ملفات الذاكرة cachegrind في المسار ‎/tmp حتى ينظفها النظام لاحقًا xdebug.profiler_output_dir = "/tmp" xdebug.profiler_output_name = "cachegrind.out.%p" ثم استخدم عميل ويب يرسل طلبًا إلى رابط التطبيق الذي ترغب بتحليله، مثل: http://example.com/article/1?XDEBUG_PROFILE=1 أثناء معالجة الصفحة للطلب سيكتب في ملف له اسم مشابه للتالي: /tmp/cachegrind.out.12345 لاحظ أنّه سيكتب ملف واحد لكل عملية/طلب PHP يُنفَّذ، لذا إذا أردت تحليل نموذج مُرسل بالطريقة POST سيُكتب تحليل واحد من أجل الطريقة GET لعرض نموذج HTML وستحتاج إلى تمرير المعامل XDEBUG_PROFILE ، من أجل الإقدام على طلب POST اللاحق لتحليل الطلب الثاني الذي يعالج النموذج، لذا فقد يكون من الأسهل تنفيذ مكتبة curl لإرسال نموذج بالطريقة POST مباشرةً عند التحليل. بمجرد أن يُكتب التحليل، فيمكنك قراءة الذاكرة المخبئية cache بتطبيق مثل KCachegrind: سيعرض التطبيق معلومات التحليل متضمنةً: الدوال المنفَّذة وقت استدعاء الدالة بمفردها واستدعاءات الدالة اللاحقة. عدد مرات استدعاء كل دالة. رسوم بيانية للاستدعاء روابط للشيفرة المصدرية من الواضح أنّ ضبط الأداء خاص جدًا بحالات استخدام كل تطبيق، بشكل عام من الأفضل التركيز على النقاط التالية: يجب ألا ترى استدعاءات متكررة لنفس الدالة، بالنسبة للدوال التي تعالج البيانات وتستعلم عنها قد يكون هناك فرص للتخزين المؤقت. وجود دوال بطيئة التنفيذ، أين يستهلك التطبيق معظم وقته؟ أفضل عائد لضبط الأداء هو التركيز على أجزاء التطبيق التي تستهلك معظم وقته. ملاحظة: إنّ إضافة Xdebug وخاصةً ميزاتها التحليلية مكثّفة للموارد وتبطئ تنفيذ PHP، لذا يُنصح بعدم تنفيذها في بيئة خادم الإنتاج. استخدام الذاكرة يُضبط حد ذاكرة زمن تنفيذ PHP باستخدام موجّه INI الـ ‏memory_limit، حيث يمنع هذا الضبط أي تنفيذ PHP مفرد من استخدام الكثير من الذاكرة مما يؤدي إلى استنزافها من أجل السكربتات الأخرى وبرنامج النظام. حد الذاكرة الافتراضي هو 128MB ويمكن أن يتغير في ملف php.ini أو في وقت التنفيذ. يمكن أن يُضبط ليكون غير محدود لكن يعدّ هذا عمومًا ممارسةً سيئة. يمكن أن يُحدَّد الاستخدام الدقيق للذاكرة أثناء وقت التنفيذ ᠎᠎عن طريق استدعاء الدالة memory_get_usage()‎ التي تعيد عدد بايتات الذاكرة المحجوزة للسكربت الحالي المُنفَّذ. بدءًا من الإصدار PHP 5.2 يوجد لهذه الدالة معامل منطقي اختياري للحصول على ذاكرة النظام المحجوزة الكلية على عكس الذاكرة الفعالة التي تستخدمها PHP. <?php echo memory_get_usage() . "\n"; // ‫الخرج 350688 (أو شيء ما مشابه وهذا يعتمد على النظام وإصدار PHP) // ‫لنستهلك جزءًا من الذاكرة RAM $array = array_fill(0, 1000, 'abc'); echo memory_get_usage() . "\n"; // 387704 // حذف المصفوفة من الذاكرة unset($array); echo memory_get_usage() . "\n"; // 350784 تعطيك الآن الدالة memory_get_usage استخدام الذاكرة في الوقت الذي نُفِّذت فيه، قد تخصص وتلغي تخصيص الكثير من الذاكرة بين استدعاءات الدالة المتلاحقة، يمكنك استخدام الدالة memory_get_peak_usage()‎ للحصول على الحجم الأعظمي من الذاكرة المستخدمة حتى نقطة معينة. <?php echo memory_get_peak_usage() . "\n"; // 385688 $array = array_fill(0, 1000, 'abc'); echo memory_get_peak_usage() . "\n"; // 422736 unset($array); echo memory_get_peak_usage() . "\n"; // 422776 لاحظ أنّ القيمة إما سترتفع أو تبقى ثابتة. التحليل باستخدام XHProf XHProf محلل PHP مكتوب من قِبل شركة فيسبوك لتوفير بديل أخف للإضافة XDebug، يمكن تمكين/تعطيل التحليل بعد تثبيت الوحدة xhprof من شيفرة PHP: xhprof_enable(); doSlowOperation(); $profile_data = xhprof_disable(); ستحتوي المصفوفة المُرجعة على بيانات حول عدد الاستدعاءات ووقت المعالج واستخدام الذاكرة لكل دالة تم الوصول إليها من داخل doSlowOperation()‎. يمكن استخدام ‎الدالة الموالية على أساس خيار أخف لتسجيل معلومات التحليل لجزء من الطلبات فقط (وبصياغة مختلفة).⁩ xhprof_sample_enable()/xhprof_sample_disable() ولهذا يستخدم المحلل بعض الدوال المساعدة (معظمها غير موثَّق) لعرض البيانات (اطلع على هذا المثال)، أو يمكنك أاستعمال أدوات أخرى لتصورها (يمكنك الاطلاع على هذا المثال من مدونة platform.sh). ترجمة -وبتصرف- للفصول Unit Testing - Performance من كتاب PHP Notes for Professionals book
    1 نقطة
  45. التشفير وفك التشفير المتناظر لملفات كبيرة باستخدام OpenSSL لا توفر PHP دالة مضمنة لتشفير وفك تشفير الملفات الكبيرة، يمكن استخدام الدالة openssl_encrypt لتشفير السلاسل النصية لكن يعد تحميل ملف كبير جدًا في الذاكرة فكرةً سيئةً، لذا يجب كتابة دالة تقوم بهذا العمل، يستخدم هذا المثال خوارزمية AES-128-CBC المتناظرة لتشفير أجزاء صغيرة من ملف كبير وكتابتها في ملف آخر. تشفير الملفات // (1) define('FILE_ENCRYPTION_BLOCKS', 10000); /** * ‫تشفير الملف الممرر وحفظ النتيجة في ملف جديد باللاحقة "‎.enc" * * @param string $source مسار الملف الذي نريد تشفيره * @param string $key المفتاح المستخدم للتشفير * @param string $dest اسم الملف الذي نريد أن نكتب فيه الملف المشفَّر * @return string|false * ‫تعيد هذه الدالة اسم الملف المنشأ أو FALSE إذا حدث خطأ */ function encryptFile($source, $key, $dest) { $key = substr(sha1($key, true), 0, 16); $iv = openssl_random_pseudo_bytes(16); $error = false; if ($fpOut = fopen($dest, 'w')) { // ضع شعاع التهيئة في بداية الملف‬ fwrite($fpOut, $iv); if ($fpIn = fopen($source, 'rb')) { while (!feof($fpIn)) { $plaintext = fread($fpIn, 16 * FILE_ENCRYPTION_BLOCKS); $ciphertext = openssl_encrypt($plaintext, 'AES-128-CBC', $key, OPENSSL_RAW_DATA,$iv); // ‫استخدم أول 16 بايت من النص المشفر كشعاع التهيئة التالي $iv = substr($ciphertext, 0, 16); fwrite($fpOut, $ciphertext); } fclose($fpIn); } else { $error = true; } fclose($fpOut); } else { $error = true; } return $error ? false : $dest; } نحدد في الموضع (1) عدد الكتل التي يجب قراءتها من الملف المصدري من أجل كل جزء، بحيث تتألف كل كتلة من 16 بايت من أجل الخوارزمية الآتية: 'AES-128-CBC' لهذا، فإذا قرأنا 10000 كتلة نحمّل 160 كيلوبايت في الذاكرة، يمكنك تعديل هذه القيمة لقراءة/كتابة أجزاء أصغر/أكبر. فك تشفير الملفات يمكنك استخدام هذه الدالة لفك تشفير الملفات المشفرة بالدالة السابقة. /** * ‫فك تشفير الملف الممرر وحفظ النتيجة في ملف جديد مع حذف آخر 4 محارف من اسم الملف * @param string $source مسار الملف الذي نريد فك تشفيره * @param string $key ‫المفتاح المستخدم لفك التشفير (ويجب أن يكون نفس المفتاح المستخدم للتشفير) * @param string $dest اسم الملف حيث يجب أن نكتب الملف الجديد بعد فك التشفير * @return string|false * ‫تعيد هذه الدالة اسم الملف المنشأ أو FALSE إذا حدث خطأ */ function decryptFile($source, $key, $dest) { $key = substr(sha1($key, true), 0, 16); $error = false; if ($fpOut = fopen($dest, 'w')) { if ($fpIn = fopen($source, 'rb')) { // الحصول على شعاع التهيئة من بداية الملف $iv = fread($fpIn, 16); while (!feof($fpIn)) { $ciphertext = fread($fpIn, 16 * (FILE_ENCRYPTION_BLOCKS + 1)); // يجب أن نقرأ كتلة واحدة زيادة عن التشفير لفك التشفير $plaintext = openssl_decrypt($ciphertext, 'AES-128-CBC', $key, OPENSSL_RAW_DATA,$iv); // ‫استخدم أول 16 بايت من النص المشفر كشعاع التهيئة التالي $iv = substr($ciphertext, 0, 16); fwrite($fpOut, $plaintext); } fclose($fpIn); } else { $error = true; } fclose($fpOut); } else { $error = true; } return $error ? false : $dest; } طريقة الاستخدام إليك الشيفرة التالية لتعرف كيفية استخدام الدوال السابقة. $fileName = __DIR__.'/testfile.txt'; $key = 'my secret key'; file_put_contents($fileName, 'Hello World, here I am.'); encryptFile($fileName, $key, $fileName . '.enc'); decryptFile($fileName . '.enc', $key, $fileName . '.dec'); ستنشئ هذه الشيفرة ثلاثة ملفات: testfile.txt وفيه النص الأصلي. testfile.txt.enc فيه الملف المشفر. testfile.txt.dec فيه الملف بعد فك تشفيره ويجب أن يكون نفس محتويات الملف testfile.txt. التشفير المتناظر يوضح هذا المثال التشفير المتناظر باستخدام خوارزمية AES 256 بالنمط CBC وهو اختصار لـ Cipher Block Chaining، نحتاج شعاع تهيئة لذا نولّد واحدًا باستخدام دالة openssl، ويستخدم المتغير ‎$strong لتحديد فيما إذا كان شعاع التهيئة المولَّد قويًا من ناحية التشفير. التشفير // طريقة التشفير $method = "aes-256-cbc"; // الحصول على طول شعاع التهيئة المطلوب $iv_length = openssl_cipher_iv_length($method); // ‫ضبط للقيمة false من أجل السطر التالي $strong = false; // توليد شعاع التهيئة $iv = openssl_random_pseudo_bytes($iv_length, $strong); /* ‫يحتاج شعاع التهيئة للاسترجاع لاحقًا لذا خزنه في قاعدة البيانات لكن لا تعيد استخدام نفس شعاع التهيئة لتشفير بيانات مرةً أخرى */ if(!$strong) { // رمي استثناء إذا لم يكن شعاع التهيئة قويًا من ناحية التشفير throw new Exception("IV not cryptographically strong!"); } // الرسالة السرية $data = "This is a message to be secured."; // كلمة المرور $pass = "Stack0verfl0w"; /* ‫يجب أن تُرسل كلمة المرور بالطريقة POST عبر جلسة HTTPS، قمنا بتخزينها في متغير هنا لأغراض توضيحية * */ // التشفير $enc_data = openssl_encrypt($data, $method, $password, true, $iv); فك التشفير // ‫استعادة شعاع التهيئة من قاعدة البيانات وكلمة المرور من الطلب POST // فك التشفير $dec_data = openssl_decrypt($enc_data, $method, $pass, true, $iv); التشفير وفك التشفير بالأساس 64 إذا كانت البيانات المشفرة تحتاج للإرسال أو التخزين في نص قابل للطباعة عندها يمكن استخدام الدالتين ()base64_encode، و ()base64_decode على الترتيب. // تشفير الترميز بالأساس 64 $enc_data = base64_encode(openssl_encrypt($data, $method, $password, true, $iv)); // فك الترميز وفك التشفير $dec_data = openssl_decrypt(base64_decode($enc_data), $method, $password, true, $iv); دوال تعمية كلمة المرور بما أنّ خدمات الويب الأكثر أمنًا تتجنب تخزين كلمات المرور بصياغة نص واضح فإنّ بعض اللغات مثل PHP توفر دوال تعميةصعبة الاستخراج hashing، ومتنوعة لدعم معيار الصناعة الأكثر أمنًا. يوفر هذا المثال توثيقًا لعمليات التعمية المناسب باستخدام PHP. إنشاء كلمة مرور معماة ننشئ نسخة معماة لكلمة المرور باستخدام الدالة password_hash()‎ لاستخدام تعمية معيارية بأفضل ممارسة للصناعة الحالية أو لاشتقاق المفتاح، في وقت كتابة هذا النص المعيار هو bcrypt مما يعني أنّ PASSWORD_DEFAULT له نفس قيمة PASSWORD_BCRYPT. $options = [ 'cost' => 12, ]; $hashedPassword = password_hash($plaintextPassword, PASSWORD_DEFAULT, $options); المعامل الثالث ليس إجباريًا. يجب أن نختار القيمة 'cost' بالاعتماد على تجهيزات خادم الإنتاج، ستجعل زيادتها كلمة المرور أكثر تكلفةً عند توليدها، كلما زادت تكلفة استخراج وفك الكلمة المعماة، استغرق الأمر وقتًا أطول عند محاولة شخص ما استخراجها؛ ومثاليًا يجب أن تكون التكلفة أعلى ما يمكن᠎ لكن من الناحية العملية يجب ضبطها بحيث لا تؤدي إلى بطء شديد في كل شيء، من المناسب أن تكون بين 0.1 و0.4 ثانية، إذا كنت محتارًا استخدم القيمة الافتراضية. في الإصدارات السابقة للإصدار 5.5، الدوال password_*‎ غير متوفرة، يجب أن تستخدم حزمة التوافق للحصول على بديل لهذه الدوال، لاحظ أنّ حزمة التوافق تتطلب الإصدار PHP 5.3.7 أو أعلى أو إصدار يحتوي على التصحيح ‎$2y (مثل ريدهات). إذا لم تكن قادرًا على استخدامها فيمكنك تنفيذ عملية تعمية على كلمة المرور باستخدام الدالة crypt()‎، وبما أنّ password_hash()‎ تُنفَّذ كغلاف حول الدالة crypt()‎ فلن تحتاج لفقدان أي وظيفة. المثال التالي هو تنفيذ بسيط للتعمية بالمعيار bcrypt والتوافق مع password_hash()‎ ومن غير المضمون أن يحافظ على نفس قوة تشفير التنفيذ الكامل للدالة password_hash()‎. إضافة غُفْل في عملية تعمية كلمة المرور على الرغم من موثوقية خوارزمية التشفير إلا أنّه ما يزال يوجد ثغرة تستهدف جداول قوس قزح ولذا ينصح باستخدام غُفْل salt، والغفل بالعربية هو شيء ما يُضاف لكلمة المرور قبل تعميتها لجعل السلسلة النصية المصدر فريدة (انظر كتاب «علم التعمية واستخراج المعمى عند العرب»)، بالنظر إلى كلمتي مرور متطابقتين فإنّ نتيجة التعمية لهما ستكون فريدة أيضًا لأن الأغْفَال المضافة إليها فريدة. يعد إضافة الأغفال العشوائية أحد أهم أجزاء أمان كلمة المرور الخاصة بك، وهذا يعني أنّه حتى مع جدول البحث lookup table لكلمات المرورة المعماة المعروفة فإنّ المهاجم لن يتمكن من مطابقة كلمة المرور المعماة الخاصة بالمستخدم مع كلمة المرور المعماة في قاعدة البيانات بسبب استخدام أغفال مختلفة، يجب أن تستخدم دائمًا أغفال عشوائية وقوية من ناحية التشفير اقرأ المزيد. باستخدام خوارزمية bcrypt ودالة password_hash()‎ تُخزَّن أغفال النص الأصلي وأغفال النص المعمى الناتج مما يعني أنّه يمكن نقل النص المعمى عبر أنظمة ومنصات مختلفة وستبقى متطابقة مع كلمة المرور الأصلية. في الإصدارات السابقة للإصدار 7.0 يمكنك استخدام الخيار salt لتعريف الأغفال العشوائية الخاصة بك على الرغم من عدم التشجيع على هذا الإجراء. $options = [ 'salt' => $salt, ]; ملاحظة: إذا أهملت هذا الخيار ستولّد الدالة password_hash()‎ غُفْلًا عشوائيًا لكل كلمة مرور مقطعة. بدءًا من الإصدار PHP 7.0.0 أُهمل خيار إضافة الغُفْل ومن المفضل الآن استخدام الغُفْل المولّد افتراضيًا. ترقية كلمة مرور معماة موجودة إلى خوارزمية أقوى إذا كنت تستخدم طريقة PASSWORD_DEFAULT لتجعل النظام يختار الخوارزمية الأفضل لتعمية كلمات المرور بها، مع زيادة قوة الخوارزمية الافتراضية قد ترغب في إعادة تعمية كلمات المرور القديمة عندما يسجل المستخدمون الدخول. <?php // حدد أولًا إذا كانت كلمة المرور الموفرة صحيحة if (password_verify($plaintextPassword, $hashedPassword)) { // حدد الآن إذا كانت النسخة المعماة الموجود قد أُنشئت بخوارزمية لم تعد افتراضية بعد الآن if (password_needs_rehash($hashedPassword, PASSWORD_DEFAULT)) { // أنشئ كلمة معماة جديدة مع الخوارزمية الافتراضية الجديدة $newHashedPassword = password_hash($plaintextPassword, PASSWORD_DEFAULT); // ثم احفظه في مخزن بياناتك // $db->update(...); } } ?> إذا لم تكن الدوال password_*‎ متوفرةً في نظامك ولا تستطيع استخدام حزمة التوافق، فعندها يمكنك تحديد الخوارزمية واستخدامها لإنشاء التعمية الأصلية بطريقة مشابهة للتالي: <?php if (substr($hashedPassword, 0, 4) == '$2y$' && strlen($hashedPassword) == 60) { echo 'Algorithm is Bcrypt'; // ‫يحدد "cost" مدى قوة إصدار Bcrypt preg_match('/\$2y\$(\d+)\$/', $hashedPassword, $matches); $cost = $matches[1]; echo 'Bcrypt cost is '.$cost; } ?> التحقق من كلمة المرور مقابل كلمة معماة توفر الدالة password_verify()‎ المدمجة بدءًا من الإصدار PHP 5.5، إمكانية التحقق من صحة كلمة مرور مقابل كلمة معماة مقابلة لها، أو غير مقابلة. <?php if (password_verify($plaintextPassword, $hashedPassword)) { echo 'Valid Password'; } else { echo 'Invalid Password.'; } ?> تخزن كل خوارزميات عملية التعمية المدعومة معلومات تحدد آلية التعمية المستخدمة، لذا لا حاجة للإشارة إلى الخوارزمية المستخدمة لتعمية كلمة المرور الأصلية. إذا لم تكن الدوال password_*‎ متوفرةً في نظامك ولا تستطيع استخدام حزمة التوافق، فيمكنك التحقق من كلمة المرور باستخدام الدالة crypt()‎، لاحظ أنه يجب اتخاذ احتياطات محددة لتجنب هجمات التوقيت. <?php // ‫غير مضمون أن يحافظ على نفس قوة تشفير تنفيذ password_hash()‎ الكامل if (CRYPT_BLOWFISH == 1) { // ‫تتجاهل crypt()‎ كل المحارف التي تتجاوز طول الغفل، لذا يمكننا تمرير ?كامل كلمة المرور المعماة $hashedCheck = crypt($plaintextPassword, $hashedPassword); // ‫هذه موازنة وقت ثابت أساسية تعتمد على التنفيذ الكامل المستخدم في `password_hash()` $status = 0; for ($i=0; $i<strlen($hashedCheck); $i++) { $status |= (ord($hashedCheck[$i]) ^ ord($hashedPassword[$i])); } if ($status === 0) { echo 'Valid Password'; } else { echo 'Invalid Password'; } } ?> ترجمة -وبتصرف- للفصول Cryptography - Password Hashing Functions من كتاب PHP Notes for Professionals book
    1 نقطة
  46. يُعَدّ Docker حاويةً شائعة جدًا تُستخدم على نطاقٍ واسع كحلّ لنشر الشيفرة في بيئات الإنتاج، كما أنها تسهّل إدارة وتوسيع تطبيقات الويب والخدمات الصغيرة. الحصول على صورة دوكر من أجل php لنشر التطبيق على دوكر نحتاج أولًا للحصول على الصورة من السجل registry. docker pull php سيوفر لك هذا أحدث إصدار للصورة من مستودع ‏php الرسمي، تُستخدم php بشكلٍ عام لنشر تطبيقات الويب لذا نحتاج إلى خادم http ليتوافق مع الصورة. تأتي الصورة في الإصدار php:7.0 (أو إصدار أحدث) مُثبّتة مسبقًا مع apache لتنشر تطبيقك بدون مشاكل. كتابة dockerfile يُستخدم Dockerfile لضبط الصورة المخصصة التي سننشئها مع شيفرات تطبيق الويب، ننشئ ملف جديد Dockerfile في المجلد الجذر للمشروع ونضع فيه المحتويات التالية: FROM php:7.0-apache COPY /etc/php/php.ini /usr/local/etc/php/ COPY . /var/www/html/ EXPOSE 80 يستخدم السطر الأول لوصف الصورة التي يجب استخدامها لإنشاء صورة جديدة، يمكن تغيير هذا إلى أي إصدار PHP آخر محدد من السجل، والسطر الثاني لتحميل ملف php.ini إلى الصورة ويمكنك تغيير هذا الملف إلى موقع ملف مخصص آخر، وينسخ السطر الثالث الشيفرات في المجلد الحالي إلى ‎/var/www/html والذي هو webroot بالنسبة لنا، تذكر أن ‎/var/www/html داخل الصورة، أما السطر الأخير فسيفتح المنفذ 80 داخل حاوية دوكر. قد يكون لديك في بعض الحالات بعض الملفات التي لا تريدها على الخادم مثل ملف إعدادات البيئة، بفرض أنّ إعدادات البيئة موجودة لدينا في ملف ‎.env ونريد تجاهله عندها نضيفه إلى ‎.dockerignore في المجلد الجذر لشيفرتنا. بناء الصورة إنّ بناء الصورة شيء غير محدد في php، لكن لبناء الصورة التي تحدثنا عنها في الأعلى نستخدم مايلي: docker build -t <Image name> . يمكننا التحقق من بناء الصورة باستخدام: docker images سيعطيك هذا الأمر كل الصور المثبتة في نظامك. بدء حاوية التطبيق يمكننا البدء بتقديم الخدمة بمجرد أن تصبح الصورة جاهزة، نستخدم ما يلي لإنشاء حاوية من الصورة: docker run -p 80:80 -d <Image name> ستوجّه ‎-p 80:80 في الأمر السابق المنفذ 80 الخاص بخادمك إلى المنفذ 80 الخاص بالحاوية، وستخبر الراية ‎-d أنّه يجب تنفيذ الحاوية في الخلفية وتصف <Image name> الصورة التي يجب استخدامها لبناء الحاوية. التحقق من الحاوية نستخدم ما يلي للتحقق من الحاويات قيد التنفيذ: docker ps سيعطينا هذا الأمر قائمة بكل الحاويات التي تُنفَّذ. سجلات التطبيق تعدّ السجلات مهمة جدًا لتنقيح أخطاء التطبيق، وللتحقق منها نستخدم الأمر: docker logs <Container id> مخزن APCu APCu هو مخزن قيمة-مفتاح للذاكرة المشتركة في PHP، تُشارك الذاكرة بين عملياتPHP-FPM ‎ (أي Fast Process Manager)‎‍ في نفس المجمع pool وتستمر البيانات المخزنة بين العمليات. تكرار محتويات المداخل يسمح الصنف APCUIterator بتكرار محتويات المداخل في المخزن المؤقت cache: foreach (new APCUIterator() as $entry) { print_r($entry); } يمكن تهيئة المكرِّر بتعبير نمطي اختياري لاختيار المداخل المتطابقة مع المفاتيح فقط: foreach (new APCUIterator($regex) as $entry) { print_r($entry); } يمكن الحصول على معلومات مدخل ذاكرة مؤقتة واحدة بالشكل التالي: $key = '…'; $regex = '(^' . preg_quote($key) . '$)'; print_r((new APCUIterator($regex))->current()); تخزين واسترجاع بسهولة يمكن استخدام apcu_store لتخزين قيم وapcu_fetch لاستعادتها: $key = 'Hello'; $value = 'World'; apcu_store($key, $value); print(apcu_fetch('Hello')); // 'World' تخزين معلومات توفر apcu_cache_info معلومات حول المخزن ومداخله: print_r(apcu_cache_info()); لاحظ أنّ استدعاء apcu_cache_info()‎ بدون حد سيعيد كل البيانات المخزنة حاليًا، ولهذا نستخدم apcu_cache_info(true)‎، للحصول على البيانات الوصفية فقط، كما أنه من الأفضل استخدام الصنف APCUIterator للحصول على معلومات عن مداخل ذاكرة تخزين مؤقتة محددة. ترجمة -وبتصرف- للفصل Docker deployment - APCu من كتاب PHP Notes for Professionals book
    1 نقطة
  47. خرج الصورة يمكن إنشاء صورة باستخدام دوال image*‎ حيث * هي صيغة الملف، وهذه الدوال لها الصيغة المشتركة التالية: bool image___(resource $im [, mixed $to [ other parameters]] ) الحفظ إلى ملف يمكنك تمرير اسم الملف أو مجرى ملف مفتوح للمتغير ‎$to إذا كنت تريد حفظ الصورة إلى ملف، إذا مررت مجرى فلا تحتاج لإغلاقه لأنّ مكتبة GD تغلقه تلقائيًا، مثلًا لحفظ ملف PNG: imagepng($image, "/path/to/target/file.png"); $stream = fopen("phar://path/to/target.phar/file.png", "wb"); imagepng($image2, $stream); // لا حاجة لإغلاق المجرى تأكد عند استخدام fopen من أنك تستخدم الراية b وليس الراية t لأن الملف هو خرج ثنائي، ولا تحاول أن تمرر fopen("php://temp", $f)‎ أو fopen("php://memory", $f)‎ لأنّ الدالة تُغلق المجرى بعد الاستدعاء ولن تبقى قادرًا على استدعائه أو استخدامه لاسترداد محتوياته مثلًا. الخرج كرد HTTP لا تحتاج إلى تمرير شيء (أو مرر null) كوسيط ثانٍ إذا كنت تريد أن ترجع هذه الصورة مباشرةً كرد للصورة (لإنشاء بطاقات ديناميكية مثلًا)، لكنك تحتاج إلى تحديد نوع المحتوى في رد HTTP: header("Content-Type: $mimeType"); ‎$mimeType هو نوع الصياغة المُرجعة في الترويسة MIME مثل image/png وimage/gif وimage/jpeg. الكتابة إلى متغير يوجد طريقتين للكتابة إلى متغير: استخدام المخزن المؤقت للخرج (OB): ob_start(); // ‫تمرير null للكتابة افتراضيًا في مجرى الخرج القياسي imagepng($image, null, $quality); $binary = ob_get_clean(); استخدام مغلِّف المجرى: قد يكون لديك سبب ما لعدم استخدام المخزن المؤقت للخرج كأن يكون لديك بالفعل مخزن مؤقت قيد التشغيل لذا تحتاج إلى بديل، يمكنك تسجيل مغلَّف مجرى جديد باستخدام الدالة stream_wrapper_register لذا يمكنك تمرير مجرى إلى دالة إظهار الصورة واستعادته لاحقًا. <?php class GlobalStream{ private $var; public function stream_open(string $path){ this->var =& $GLOBALS[parse_url($path)["host"]]; return true; } public function stream_write(string $data){ $this->var .= $data; return strlen($data); } } stream_wrapper_register("global", GlobalStream::class); $image = imagecreatetruecolor(100, 100); imagefill($image, 0, 0, imagecolorallocate($image, 0, 0, 0)); $stream = fopen("global://myImage", ""); imagepng($image, $stream); echo base64_encode($myImage); في هذا المثال يكتب الصنف GlobalStream أي دخل إلى المتغير المرجعي (أي الكتابة بشكل غير مباشر إلى المتغير العام للاسم المعطى)، يمكن استرجاع المتغير العام لاحقًا بشكلٍ مباشر. يجب الانتباه إلى عدة أمور: صنف مغلِّف المجرى المنفَّذ بشكلٍ كامل يجب أن يشبه هذا الصنف لكن وفقًا للاختبارات باستخدام تابع ‎__call السحري فإنّه من الممكن استدعاء stream_open وstream_write وstream_close فقط من الدوال الداخلية. لا توجد رايات مطلوبة في استدعاء fopen لكن يجب أن تمرر سلسلة فارغة على الأقل، لأنّ الدالة fopen تتوقع مثل هذا المعامل، حتى لو لم تستخدمها في تنفيذ stream_open يبقى هذا المعامل مطلوبًا. تستدعى الدالة stream_write عدة مرات وفقًا للاختبارات، تذكر أن تستخدم إسناد الدمج ‎.=‎ وليس إسناد المتغير المباشر =. مثال: في وسم <img> في HTML، يمكن توفير صورة بشكلٍ مباشر بدلًا من استخدام رابط خارجي: echo '<img src="data:image/png;base64,' . base64_encode($binary) . '">'; إنشاء صورة نستخدم الدالة imagecreatetruecolor لإنشاء صورة فارغة: $img = imagecreatetruecolor($width, $height); المتغير ‎$img‎ هو متغير مورد الآن بعرض ‎$width وطول ‎$height بكسل، لاحظ أنّ العرض يُحسب من اليسار إلى اليمين والطول من الأعلى إلى الأسفل. يمكن أن يُنشأ أيضًا مورد الصورة من دوال إنشاء الصورة مثل imagecreatefrompng وimagecreatefromjpeg ودوال imagecreatefrom*‎ أخرى. قد تُحرَّر موارد الصورة لاحقًا عندما لا توجد مراجع إليها، لكن لتحرير الذاكرة بشكلٍ مباشر (قد يكون هذا مهمًا عند معالجة عدة صور كبيرة) يمكننا استخدام imagedestroy()‎ على الصورة عندما لا تبقى حاجة لاستخدامها وتكون هذه ممارسة جيدة. imagedestroy($image); تحويل صورة إنّ الصور التي تُنشأ من تحويل الصور لا تعدّل الصورة حتى تُخرجها، لذا يمكن أن يكون محوِّل الصورة ببساطة عبارة عن ثلاثة أسطر من الشيفرة: function convertJpegToPng(string $filename, string $outputFile) { $im = imagecreatefromjpeg($filename); imagepng($im, $outputFile); imagedestroy($im); } اقتصاص الصورة وتغيير حجمها يمكنك استخدام الدالة imagecopyresampled إذا كان لديك صورة وتريد إنشاء صورة جديدة بأبعاد جديدة، أنشئ أولًا صورة جديدة بالأبعاد المرغوبة: // صورة جديدة $dst_img = imagecreatetruecolor($width, $height); خزّن الصورة الأصلية في متغير، يمكنك القيام بذلك باستخدام إحدى دوال createimagefrom*‎ حيث يمكن أن تكون * هي jpeg أو gif أوpng أوstring، مثال: // الصورة الأصلية $src_img=imagecreatefromstring(file_get_contents($original_image_path)); ثم استخدم الدالة imagecopyresampled لنسخ كل الصورة الأصلية (أو جزء منها) (src_img) إلى الصورة الجديدة (dst_img): imagecopyresampled($dst_img, $src_img, $dst_x ,$dst_y, $src_x, $src_y, $dst_width, $dst_height, $src_width, $src_height); لضبط أبعاد src_*‎ و‎dst_*‎، استخدم الصورة التالية: إذا كنت تريد الآن نسخ كامل الصورة المصدر (الأصلية) إلى كامل منطقة الهدف (بدون اقتصاص): $src_x = $src_y = $dst_x = $dst_y = 0; // عرض الصورة الجديدة $dst_width = $width; // طول الصورة الجديدة $dst_height = $height; // عرض الصورة الأصلية $src_width = imagesx($src_img); // طول الصورة الأصلية $src_height = imagesy($src_img); مكتبة Imagick التثبيت باستخدام apt في الأنظمة المعتمدة على Debian: sudo apt-get install php5-imagick باستخدام Homebrew في أنظمة OSX/macOs: brew install imagemagick باستخدام الإصدارات الثنائية: التعليمات في موقع imagemagick. الاستخدام <?php $imagen = new Imagick('imagen.jpg'); // ‫إذا وضعت قيمة المعامل 0 ستتم المحافظة على نسبة العرض $imagen->thumbnailImage(100, 0); echo $imagen; ?> تحويل صورة إلى سلسلة نصية بالأساس 64 يُظهر هذا المثال كيفية تحويل صورة إلى سلسلة نصية بالأساس 64 (أي سلسلة نصية يمكنك استخدامها مباشرةً في السمة src لوسم img)، يستخدم هذا المثال مكتبة Imagick لكن يمكن استخدام مكتبات أخرى مثل GD. <?php // (1) $img = new Imagick('image.jpg'); // (2) $img->resizeImage(320, 240); // (3) $imgBuff = $img->getimageblob(); // (4) $img->clear(); // (5) $img = base64_encode($imgBuff); echo "<img alt='Embedded Image' src='data:image/jpeg;base64,$img' />"; في الموضع (1) يُحمَّل الملف image.jpg للمعالجة، مسار الملف نسبي إلى ملف ‎.php‎ المتضمن هذه الشيفرة لذا في هذا المثال يجب أن يكون ملف image.jpg في نفس مجلد السكربت. في الموضع (2) يتغير حجم الصورة للحجم المُعطى كطول وعرض وإذا أردت تغيير دقة الصورة أيضًا مع تغيير الحجم يمكنك استخدام الدالة ‎$img->resampleimage(320, 240)‎، لاحظ أنّه يمكنك ضبط المعامل الثاني إلى 0 للمحافظة على نسبة عرض الصورة. في الموضع (3) تُرجع الدالة تمثيل الصورة على شكل سلسلة نصية غير مشفرة. في الموضع (4) يُزال المورد image.jpg من الكائن ‎$img‎ ويُدمَّر الكائن مما يحرر موارد النظام المحجوزة لمعالجة الصورة. في الموضع (5) تُنشأ نسخة بتشفير الأساس 64 من السلسلة النصية السابقة غير المشفرة ثم تُعرَض كصورة في الصفحة، لاحظ أنّه قد يتغير الجزء image/jpeg في السمة src وذلك بالاعتماد على نوع الصورة التي تستخدمها (png أوjpeg مثلًا). ترجمة -وبتصرف- للفصول [Image Processing with GD - Imagick] من كتاب PHP Notes for Professionals book اقرأ أيضًا المقال التالي: مدخل إلى تعلم الآلة (Machine learning) في PHP المقال السابق: اصطلاحات ومواضيع متفرقة مهمة لكل مبرمج PHP
    1 نقطة
  48. في هذا الجزء من المقالات التعليمية، نتطرَّق إلى لغة JavaScript كما هي بدون تعديلات خاصة بالبيئة. لكن ما زلنا نستخدم المتصفح كبيئة تجريبية، لذلك يجب أن تتعرف على عددٍ قليلٍ من دوال واجهة المستخدم الخاصة به. ستتعرف في هذا الفصل على هذه الدوال التفاعلية الخاصة بالمتصفح. الدالة alert الصياغة: alert(message); تعرض هذه الدالة رسالة نصية وتوقف تنفيذ السكربت مؤقتًا حتى يضغط المستخدم على «موافق» (OK). إليك الشيفرة البسيطة التالية مثلًا: alert("مرحبًا"); تسمى الرسالة النصية التي تظهر على شكل نافذة صغيرة تدعى «النافذة المنبثقة الشرطية» (modal window، وهي عنصر تحكم رسومي)؛ تعني كلمة «شرطية» أنه لا يمكن للزائر التفاعل مع بقية الصفحة، أو الضغط على أزرار أخرى وما إلى ذلك، إذ تشترط عليه التفاعل معها فقط، أي حتى يضغط على «موافق» (Ok) في هذه الحالة. الدالة prompt تقبل الدالة prompt وسيطين (arguments) لتكون صياغتها بالشكل التالي: result = prompt(title, [default]); تعرض هذه الدالة نافذة منبثقة شرطية مع رسالة نصية مخصصة، وحقل إدخال للمستخدم، وزرَّين (موافق [OK] وإلغاء [CANCEL]). الوسيط title: هو عبارة عن النص الذي سيعرض للمستخدم. الوسيط default: هو وسيط اختياري يمثِّل القيمة الأولية لحقل الإدخال الخاص بالمستخدم. قد يكتب المستخدم شيئًا ما في حقل الإدخال، ثمَّ يضغط على موافق (Ok). أو يمكنه إلغاء الإدخال عند الضغط على إلغاء (CANCEL) أو الضغط على مفتاح الهروب (Esc). استدعاء الدالة prompt يرجع سلسلة نصية تمثِّل القيمة التي أدخلها المستخدم في حقل الإدخال أو يرجع القيمة null إذا تم الخروج من النافذة وإلغائها. جرب نفِّذ المثال التالي في الطرفية وعدل عليه: let age = prompt('كم عمرك؟', 100); alert(`عمرك ${age} سنة!`); في IE (أي المتصفح Internet Explorer)، دائمُا ما يتم إضافة الوسيط default. أي هذا الوسيط اختياري في جميع المتصفحات باستثناء المتصفح IE الذي يعدُّه اجباريًّا، وإذا لم نحدِّد قيمته، يفترض المتصفح Internet Explorer أنَّ قيمته "undefined". نفِّذ هذه الشيفرة في متصفح Internet Explorer لرؤية الناتج: let test = prompt("Test"); لجعل الدالة prompt تعمل جيدًا في المتصفح IE، نوصي دائمًا بتمرير قيمة الوسيط الثاني default: let test = prompt("Test", ''); // <-- IE للمتصفح الدالة confirm الصياغة: result = confirm(question); تُظهر الدالة confirm نافذة منبثقة شرطية تحتوي على سؤال question، وزريّن (موافق [OK] وإلغاء [CANCEL]). تكون النتيجة true إذا ضغط المستخدم على الزر "Ok" وتكون false عدا ذلك. جرِّب المثال التالي في طرفيتك: let isBoss = confirm("Are you the boss?"); alert( isBoss ); الخلاصة ذكرنا في هذا المقال ثلاثة دوال للتفاعل مع مستخدمي الموقع وهي: الدالة alert: تعرض رسالة لإعلام المستخدم بشئ ما، وُتعطل كافة عمليات الصفحة حتى يتفاعل مع هذه الرسالة. الدالة prompt: تعرض رسالة تطلب من المستخدم إدخال شيء ما في حقل إدخال خاص لتعيد القيمة المدخلة في سلسلة نصية، أو ترجع القيمة null إذا تم العملية. الدالة confirm: تعرض رسالة (بمثابة سؤال) وتنتظر من المستخدم الرد عليها بالقبول أو الرفض، أي تكون النتيجة true إذا تم الضغط على زر "Ok" أو تكون false عدا ذلك. كل هذه الدوال مشروطة: فهي تتوقف عن تنفيذ السكربت ولا تسمح للمستخدم بالتفاعل مع بقية الصفحة حتى يتم التفاعل مع النافذة التي تعرضها. هناك اثنين من القيود التي تشترك بها جميع الدوال المذكورة أعلاه: يحدد المتصفح الموقع الذي ستظهر فيه النافذة، وعادة ما يكون في الوسط أو الأعلى. يعتمد شكل النافذة أيضًا على المتصفح، ولا يمكننا تعديله. هذا هو ثمن البساطة. هناك طرق أخرى لإظهار نوافذ أكثر جمالًا وفاعلية، ولكن إذا كانت التنسيقات الجمالية غير مهمة، فهذه الدوال تفي بالغرض. .task__importance { color: #999; margin-left: 30px; } .task__answer { border: 3px solid #f7f6ea; margin: 20px 0 14px; position: relative; display: block; padding: 25px 30px; } code { background-color: rgb(250, 250, 250); border-radius: 3px; } تمارين صفحة بسيطة الأهمية: 4 قم بإنشاء صفحة ويب تطلب اسمًا ما ثم تعرضه. الحل شيفرة JavaScript: let name = prompt("ما اسمك؟", ""); alert(name); الشيفرة كاملة: <!DOCTYPE html> <html> <body> <script> 'use strict'; let name = prompt("ما اسمك؟", ""); alert(name); </script> </body> </html> ترجمة -وبتصرف- للفصل Interaction: alert, prompt, confirm من كتاب The JavaScript Language اقرأ أيضًا المقال التالي: المعاملات الشرطية المقال السابق: معاملات الموازنة كامل مقالات دليل تعلم جافاسكربت
    1 نقطة
  49. فلنقل إنك تسير في شارع مكتظ وسط المدينة، تتأهب للمرور في مفترق طرق وفي هذه الأثناء انتقلت الإشارة الضوئية الخاصّة بالراجلين إلى اللون الأحمر. مالذي ستفعله؟ تتوقف… أليس كذلك؟ ماذا لو تبدّل اللون إلى الأخضر بعد ذلك؟ تعود إلى المشي. يمكننا اعتماد نفس المبدأ في الشفرات البرمجية. يبدو الأمر كما لو أنك تقول “إن أصبح لون الإشارة أحمر فيجب عليك التوقف وإلا استمرّ في المشي”. هذا بالضبط هو عمل الجملة if/else (إنْ… وإلا) في جافاسكريبت. الجملة if/else تساعد الجملة if/else بالتحكّم في ما يفعله برنامجك في حالات محدّدة. تأخذ الصيغة التالية: if (condition) { // افعل شيئا هنا } else { // افعل شيئا مغايرا هنا } يخبر الشرط Condition الجملة if/else مالذي يجب عليها التحقّق منه قبل الاستمرار. إذا كانت قيمة الشرط صحيحة (تساوي true) فإن جافاسكريبت سينفّذ الشفرة الموجودة داخل كتلة if. أما إذا كانت قيمة الشرط غير صحيحة (أي false) فإن الشفرة الموجودة في الكتلة else هي ما سيُنفّذ. بالعودة إلى مثال الإشارة الضوئية أعلاه فإن الأمر سيأخذ الصيغة التالية: if (الإشارة حمراء) { // توقّف عن المشي } else { // استمرّ في المشي } إن احتجت للتحقّق من شروط عدّة فيمكنك إضافة else if بين كتلتيْ if وelse. متى ستحتاج لشرط ثان؟ فلنقل إنك تمرّ عبر طريق صغيرة. إن لم تكن هناك سيارات فهل ستستمر في الانتظار إلى أن يتغيّر لون الإشارة الضوئية؟ على الأرجح ستواصل طريقك. بترجمة الحالة أعلاه إلى شفرة برمجية نجد التالي: if (الإشارة حمراء) { // توقّف عن المشي } else if (توجد سيارات) { // توقّف عن المشي } else if (شرط آخر) { // افعل أمرا آخر } else { // أمر أخير } إذا كان الشرط الأول في الشفرة أعلاه متحقّقا فإن مفسّر جافاسكريبت ينفّذ الشفرة الموجودة ضمن كتلة if، أما إذا كان هذا الشرط غير متحقّق فإن المفسّر ينظُر في الشرط الموجود في جملة else if الموالية لمعرفة ما إذا كان متحقّقا… وهكذا إلى إن يمرّ عبر جميع جمل else if. يعتمد مفسّر جافاسكريبت على أساسيْن لمعرفة تحقّق الشرط من عدمه: عوامل المقارنة Comparison operators. القيم الصحيحة و القيم الخاطئة. عوامل المقارنة توجد أربعة عوامل أساسية للمقارنة: “أكبر من” < أو “أكبر من أو يساوي”=< “أصغر من” > أو “أصغر من أو يساوي”=> “يساوي تماما” === أو “يساوي” == “يختلف تماما” ==! أو “يختلف” =! النوعان الأولان من عوامل المقارنة واضحان ويستخدمان لمقارنة الأعداد: 24 > 23 // صحيح 24 > 24 // خاطئ 24 >= 24 // صحيح 24 < 25 // صحيح 24 < 24 // خاطئ 24 <= 24 // صحيح النوعان التاليّان يُستخدمان لمقارنة تساوي شيئين: 24 === 24 // صحيح 24 !== 24 // خاطئ إلا أنه يوجد فرق بين “يساوي تماما” === و “يساوي” ==، وبين “يختلف تماما” == ! و “يختلف” =! '24' === 24 // خاطئ '24' == 24 // صحيح '24' !== 24 // صحيح '24' != 24 // خاطئ يتّضح من المثال أعلاه أن مقارنة العدد 24 بسلسلة المحارف 24 تعطي نتيجة خاطئة عند استخدام العامل “يساوي تماما” (===) بينما تعطي نتيجة صحيحة عند استخدام العامل “يساوي” (==). لماذا هذا الاختلاف؟ فلنر الفرق بين “يساوي تماما” و “يساوي”. الفرق بين === و == (و بين ==! و =!) أنواع البيانات Data types في جافاسكريبت ليست صرامة بل متساهلة، عكس لغات أخرى. يعني هذا أننا لا نهتم عندما نعرّف متغيّرا بنوع البيانات الذي ستأخذه قيمة هذا المتغيّر. يمكنك تعريف أي متغيّر وسيتكفّل مفسّر جافاسكريبت بالتعامل مع نوع البيانات الخاصّ بقيمة المتغيّر: const aString = 'Some string' const aNumber = 123 const aBoolean = true عند استخدام العامل “يساوي تماما” (===) أو “يختلف تماما” (==!) فإن مفسّر جافاسكريبت يأخذ أنواع بيانات قيم المتغيّرات بالحسبان؛ لهذا السبب فإن سلسلة المحارف 24 تختلف عن العدد 24. '24' === 24 // خطأ '24' !== 24 // صحيح أما عند استخدام العامل “يساوي” (==) أو “يختلف” (=!) فإن مفسّر جافاسكريبت يحوّل نوع البيانات بحيث يتساوى نوع طرفيْ المقارنة قبل أن ينظُر في القيمة. عمومًا، يحاول مفسّر جافاسكريبت تحويل جميع أنواع البيانات إلى أعداد عند استخدام عوامل المقارنة (ما عدا ===و==!). تُحوَّل سلسلة المحارف 24 في المثال أدناه إلى العدد 24 قبل المقارنة. هذا هو السبب الذي يجعل سلسلة المحارف 24 تساوي العدد 24 عند استخدام العامل ==: '24' == 24 // صحيح '24' != 24 // خاطئ يمكن كذلك تحويل القيم المنطقية (true وfalse) إلى أعداد، وعندها تصبح قيمة true تساوي 1 وfalse تساوي 0: 0 == false // صحيح 1 == true // صحيح 2 == true // خاطئ يعدّ التحويل التلقائي الذي يقوم به مفسّر جافاسكريبت أثناء استخدام عوامل المقارنة أحد أكثر الأسباب شيوعا لصعوبة التعرف على العلل Bugs أثناء تطوير البرامج؛ لذا استخدم دوما عوال المقارنة التامّة (=== أو==!). دورة تطوير التطبيقات باستخدام لغة Python احترف تطوير التطبيقات مع أكاديمية حسوب والتحق بسوق العمل فور انتهائك من الدورة اشترك الآن مقارنة الكائنات والمصفوفات حاول أن تقارن بين الكائنات أو بين المصفوفات بالعامل === أو == وستجد نتيجة مفاجئة: const a = { isHavingFun: true } const b = { isHavingFun: true } console.log(a === b) // خطأ: الكائن a مختلف تماما عن الكائن b console.log(a == b) // خطأ: الكائن a مختلف عن الكائن b الكائنان a وb في المثال أعلاه يبدوان متشابهين تماما: كلاهما كائن ويحويان نفس القيم. الأمر الغريب هو أن المقارنة a === b ترجع دائما قيمة خاطئة false؛ لماذا؟ فلنفترض أنكَ وأخاك (أو أنكِ وأختك) توأم. تبدو مشابهًا تمامًا لأخيك: نفس لون الشعر، نفس شكل الوجه، نفس الثياب؛ كيف يمكن التفريق بينك وأخيك؟ سيكون الأمر صعبًا. لدى كل كائن في جافاسكريبت بطاقة تعريف (هوية) تُسمّى مرجع الكائن Object’s reference. عند استخدام عوامل المقارنة للتحقّق من تساوي كائنين في جافاسكريبت فإنك تطلُب من المفسر التحقّق ممّا إذا كان للكائنيْن نفسُ المرجع (بطاقة التعريف). ليس غريبًا الآن أن تكون قيمة الشرط a === b في المثال أعلاه مساوية لـfalse. فلنعدّل قليلاً على المثال ونسند a إلى b: const a = { isHavingFun: true } const b = a تصبح نتيجة المقارنة a === b الآن مساوية لـ true (أي أن الكائنين متساويان). السبب في ذلك هو أن الكائنين a وb لديهما الآن نفس المرجع. console.log(a === b) // true القيم الصحيحة و القيم الخاطئة إن وضعت اسم متغيّر (hasApples - بمعنى لديه تفاح - في المثال أدناه) مكان الشرط في جملة if/else فإن مفسّر جافاسكريبت سيبحث عن قيمة صحيحة أو قيمة خاطئة. const hasApples = 'true' if (hasApples) { // تناول تفاحة } else { // اشتر تفاحا } القيم الخاطئة هي قيم تأخذ القيمة false عند تحويلها إلى نوع البيانات المنطقية Boolean. توجد ست قيم خاطئة في جافاسكريبت: false undefined null 0 (العدد صفر) "" (سلسلة محارف فارغة) NaN على الجانب الآخر، القيم الصحيحة هي تلك التي تأخذ القيمة true بعد تحويلها إلى بيانات منطقية. في حالة الأعداد فإن أية قيمة مغايرة للصفر تُحوَّل إلى قيمة صحيحة. تُشجّع جافاسكريبت على استخدام التحويل التلقائي إلى قيم صحيحة وقيم خاطئة لكونها تجعل من الشفرة البرمجية أقصر وأسهل فهما. إن أردت على سبيل المثال التحقّق من أن سلسلة محارف فارغة فيمكنك استخدام هذه السلسلة مباشرة في شرط الجملة if/else: const str = '' if (str) { // سلسلة المحارف غير فارغة } else { // سلسلة المحارف فارغة } خاتمة تُستخدم الجمل الشرطية if/else للتحكّم في عمل البرامج في حالات محدّدة؛ فتسمح لك بتحديد ما إذا كان يتوجب عليك الاستمرار في المشي أو الانتظار لتجاوز مفترق طرق. توجد طريقتان للتحقّق من الشروط في جافاسكريبت: عوامل المقارنة القيم الصحيحة والقيم الخاطئة ترجمة - تصرّف - للمقال Understanding if/else statements لصاحبه Zell Liew.
    1 نقطة
  50. Django هو إطار عمل مجّاني ومفتوح المصدر، مكتوب بلغة Python، وتتبع المشاريع فيه بنية Model-View-Template (عادة ما تختصر إلى MVT). يؤكّد Django على قابلية إعادة الاستخدام Reusability للمكونات وكذلك على التطوير السريع، بالإضافة إلى مبدأ عدم التكرار. تستخدم لغة Python في جميع مفاصل إطار العمل هذا، كالإعدادات ونماذج قواعد البيانات وغيرها. ومن أشهر المواقع التي تستخدم Django هي: Pinterest ،Instagram ،Mozilla ،The Washington Times ،Disqus ،National Geographic وغيرها الكثير. طوّر Django سنة 2003 على يدي المبرمجين Adrian Holovaty و Simon Willson اللذين يعملان في صحيفة Lawrence Journal World، وذلك عندما انتقلا إلى لغة Python لبناء التطبيقات. ثم أطلق Django سنة 2005 تحت رخصة BSD، وقد سمّي بهذا الاسم تيمنًا بعازف الغيتار Django Reinhardt. بنية MVT تنقسم بنية المشاريع في Django إلى ثلاثة أقسام مرتبطة ببعضها البعض، ولكنّها مختلفة عن أطر العمل الأخرى التي تتبع بنية (MVC - Model, View, Controller) مثل Laravel في PHP وغيرها، حيث تتكون المشاريع في Django من النموذج Model والعرض View والقالب Template. يتولى قسم النموذج معالجة البيانات والتعامل معها واسترجاعها، ويدعم Django العديد من قواعد البيانات، مثل: SQlite ،MySQL، و PostgreSQL. أما العرض فعبارة عن مجموعة من دوال Python التي تستجيب لعنوان URL معين، ووظيفة العرض هي تحديد البيانات والمعلومات التي يجب عرضها. أما القالب فهو عبارة عن ملف بصيغة HTML يتم من خلاله تحديد الطريقة التي ستظهر بها المعلومات التي يعرضها قسم العرض. أين المتحكم Controller إذًا؟ المتحكم هنا هو إطار العمل نفسه، أي الآلية التي يتم من خلالها إرسال الطلب إلى العرض المناسب بالاعتماد على عنوان URL محدّد. تثبيت Django إطار العمل Django هو إحدى الحزم الخاصة بلغة البرمجة بايثون، وتوفّر هذه اللغة مدير حزم خاصّ يدعى pip يتم من خلاله تثبيت وتحديث وإزالة الحزم بسهولة ويسر؛ لذا ستكون الخطوة الأولى في تثبيت Django هي التأكد من وجود مدير الحزم pip وتثبيته إن لم يكن متوفّرًا. تنصيب pip لتنصيب إطار العمل Django ستحتاج إلى مدير الحزم الخاصّ بـ Python وهو pip، ولحسن الحظّ فإن pip متوفّر في نسخة Python 2.7.9 وما بعدها، وفي نسخة Python 3.4 وما بعدها. في حال عدم توفّر pip في نسخة Python المنصّبة لديك يمكنك تنصيبه باتباع الخطوات التالية: حمّل الملفّ get-pip.py. توجه في سطر الأوامر إلى المكان الذي حملت فيه الملف السابق، ثم اكتب التعليمة التالية: python get-pip.py استخدام سطر الأوامر لنجرب الآن استخدام مدير الحزم في بايثون لتنصيب Django، توجّه الآن إلى سطر الأوامر ثم اكتب الأمر: pip install django==1.9 هل ظهرت لك رسالة خطأ؟ ما المشكلة، ألم نقم بتنصيب pip قبل قليل؟ هذا صحيح، ولكننا لم نخبر سطر الأوامر بأن يوجّه أي تعليمة تبدأ بكلمة pip إلى مدير حزم بايثون، وللقيام بذلك اتبع الخطوات التالية: في أوبنتو: يجب تنصيب حزمة python3-pip إن كنت تستخدم الإصدار الثالث من بايثون أو python-pip للإصدار الثاني من بايثون، لتتمكن من استخدام pip في سطر الأوامر في أبونتو، وللقيام بذلك اكتب الأمر التالي في سطر الأوامر: sudo apt-get install python3-pip أدخل كلمة المرور الخاصة بك، وستبدأ عملية التثبيت، وبعد الانتهاء يمكنك تنصيب أي حزمة خاصة بلغة بايثون عن طريق سطر الأوامر مباشرة. في نظام Windows: أما في نظام Windows فيجب إضافة السطر التالي: C:\Python34\scripts; إلى مسار النظام System path، وللقيام بذلك اتبع الخطوات التالية: انقر بزر الفأرة الأيمن على أيقونة Computer واختر Properties من القائمة المنسدلة: انقر على أيقونة Advance system settings، وفي مربع الحوار المنبثق اضغط على أيقونة Environment Variables. انقر نقراً مزدوجًا على متغير النظام Path في الجزء السفلي من مربع الحوار المنبثق. أضف السطر السابق إلى نهاية السلسلة النصّية، بعد الفاصلة المنقوطة (;) (إن لم تكن هناك فاصلة منقوطة في نهاية السطر فقم بإضافتها). اضغط Ok ثم أغلق بقية النوافذ بالضغط على Ok. يمكنك الآن استخدام pip من سطر الأوامر مباشرة. البيئة الافتراضية Virtual Environment قبل البدء بتنصيب Django سنعمل على تنصيب أداة مفيدة جدًّا من شأنها المساعدة على ترتيب البيئة البرمجية على حاسوبك. يمكن تجاوز هذه الخطوة، ولكن ينصح بها بشدّة. تعمل البيئة الافتراضية على عزل مشاريع Python أو Django الخاصّة بك عن بعضها البعض، وهذا يعني أن إجراء التعديلات على موقع إلكتروني معيّن لن تؤثّر على المشاريع الأخرى التي تعمل عليها. ستحتوي البيئة الافتراضية على الملفات التنفيذية الخاصة بـ Python بالإضافة إلى نسخة من مكتبة pip يمكنك استخدامها في تنصيب حزم Python المختلفة. سننشئ مجلدًا سيحتوي على البيئة الافتراضية التي سوف ننشئها بعد قليل. mkdir mysite cd mysite يتطلب إنشاء البيئة الافتراضية تنصيب حزمة virtualenv وسنستعين بـ pip للقيام بذلك: pip install virtualenv لاستخدام virtualenv من سطر الأوامر مباشرة في أوبنتو يجب تنصيب الحزمة virtualenv، وللقيام بذلك اكتب الأمر التالي في سطر الأوامر: sudo apt-get install virtualenv بعد اكتمال عملية التنصيب يمكنك إنشاء البيئة الافتراضية بالشكل التالي: virtualenv myvenv ستنشئ هذه الشيفرة بيئة افتراضية وهي عبارة عن مجموعة من المجلدات. لتفعيل البيئة الافتراضية الجديدة في نظام Windows استخدم الشيفرة التالية: myvenv\Scripts\activate أما في نظامي Linux و OS X فاستخدم: source myvenv/bin/activate ملاحظة: قد لا تحصل على النتيجة المرجوّة من الشيفرة السابقة، لذا يمكنك استخدام هذه الشيفرة: . myvenv/bin/activate سيتغيّر سطر الأوامر وذلك بإضافة كلمة (myvenv) إلى بداية السطر، وهذا يعني أن الأمور تسير على ما يرام. ولإغلاق البيئة الافتراضية يمكنك استخدام التعليمة التالية: deactivate تنصيب Django بعد اكتمال الخطوتين السابقتين يمكننا الآن تنصيب Django وذلك بتنفيذ الأمر التالي (انتبه إلى وجود علامتي مساواة لا علامة واحدة): pip install django==1.9 بعد اكتمال عملية التنصيب، وللتأكد من أن الأمور تجري على ما يرام، اكتب الأمر التالي في سطر الأوامر: python3 -c "import django; print(django.get_version())" إن حصلت على رقم النسخة (1.9 في حالتنا هذه) التي قمت بتنصيبها، فقد أصبحت جاهزًا لإنشاء مشروعك الأول على Django. إنشاء المشروع الأول مشروعنا الأول سيكون عبارة عن تطبيق استطلاع بسيط، يتألف من جزئين: موقع عام يتيح مشاهدة الاستطلاعات والتصويت عليها. لوحة تحكم تتيح لنا إضافة وحذف وتعديل الاستطلاعات. هذا المشروع سيكون مبنيًا على الإصدار 1.9 من Django والإصدار 3.4 من Python. في حال كنت تستخدم الإصدار 2.7 من Python فيتوجب عليك حينها إضافة بعض التعديلات على الشيفرة التي تكتبها، وسنشير إلى ذلك في محلّه. انتقل إلى سطر الأوامر وتوجه من خلاله إلى المجلد الذي ترغب استخدامه لإنشاء المشروع، وبإمكانك استخدام أي مجلد تحت أي تسمية وفي أي موقع في القرص الصلب، فلا مشكلة لدى Django في ذلك. لإنشاء المشروع نفّذ الأمر التّالي في سطر الأوامر (انتبه إلى النقطة في نهاية السطر): django-admin startproject mysite . سيعمل هذا الأمر على إنشاء مجلد باسم mysite داخل مجلد المشروع. انتبه كذلك إلى كتابة النقطة في نهاية السطر، فهي توجّه الشيفرة إلى تنصيب Django في المجلد الحالي. البنية الأولية للمشروع يحتوي مجلد mysite الذي أنشأته التعليمة السابقة، على مجموعة الملفات التالية: manage.py /mysite __init__.py settings.py urls.py wsgi.py manage.py، يُوصف هذا الملف بالسكين السويسري، وهو الأداة التي سنستعين بها للقيام بالكثير من الأشياء في إدارة الموقع، وفي تهجير قواعد البيانات وتشغيل الخادوم الخاص بـ Django، وغير ذلك الكثير. المجلد mysite هو حزمة بايثون الخاصة بمشروعنا، وسنستخدم هذا الاسم عندما نرغب في استيراد أي شيء داخله. (مثال mysite.urls). mysite/__init__.py ملف فارغ، ووجوده يعني أن هذا المجلّد هو حزمة من حزم بايثون. mysite/settings.py ملف الإعدادات الخاصة بمشروعنا. mysite/urls.py يحتوي على عناوين URL الخاصة بموقعنا، وهو أشبه ما يكون بجدول المحتويات الخاص بالموقع. mysite/wsgi.py نقطة الولوج إلى الخواديم المتوافقة مع WSGI. تشغيل الخادوم توجه في سطر الأوامر إلى المجلد الذي يحوي الملف manage.py ثم اكتب الأمر التالي: python manage.py runserver وستظهر العبارات التالية في سطر الأوامر: Performing system checks... System check identified no issues (0 silenced). You have unapplied migrations; your app may not work properly until they are applied. Run 'python manage.py migrate' to apply them. February 01, 2016 - 15:50:53 Django version 1.9, using settings 'mysite.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C. ملاحظة: لا تستخدم هذا الخادوم في المشاريع الإنتاجية على الإطلاق، فالهدف من هذا الخادوم هو استخدامه لأغراض التطوير فقط. أدخل العنوان التالي في متصفح الإنترنت: http://127.0.0.1:8000 ستظهر الصفحة التالية لتشير إلى نجاحنا في إنشاء أول مشروع في Django.
    1 نقطة
×
×
  • أضف...