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

هدى جبور

الأعضاء
  • المساهمات

    26
  • تاريخ الانضمام

  • تاريخ آخر زيارة

كل منشورات العضو هدى جبور

  1. بدأنا في مقال الذكاء الاصطناعي: دليلك الشامل الحديث عن الذكاء الاصطناعي وعرفناه وتحدثنا عن مجالاته وحقوله وتطبيقاته ولكن بإيجاز ثم انتقلنا في مقال مجالات الذكاء الاصطناعي إلى التعرف على أهم الحقول والمجالات التي يرتكز عليها الذكاء الاصطناعي وبذلك مهدنا للانتقال إلى التحدث عن تطبيقات الذكاء الاصطناعي الذي سنركز عليه في هذا المقال. أهم تطبيقات الذكاء الاصطناعي مع التطور المذهل الذي شهده الذكاء الاصطناعي والضجة التي أحدثها والقدرات التي أظهرها، أصبح من الضروري توظفيه أحسن توظيف لتحسين العديد من المجالات. لقد بات الذكاء الصناعي في يومنا هذا ضروريًّا لما يُقدّمه من حلول لمشكلات معقدة بطريقة فعّالة في العديد من المجالات والصناعات، مثل الرعاية الصحية والترفيه والشؤون المالية والتعليم وما إلى ذلك. يجعل الذكاء الاصطناعي حياتنا اليومية أكثر راحة وسرعة خصوصًا في هذا الزمن الذي من سمته التعقيد. سنُلقي الضوء على أهم تطبيقات الذكاء الاصطناعي في مختلف المجالات الحياتية. تطبيق الذكاء الاصطناعي في مجال التجارة الإلكترونية بلغت مبيعات التجزئة الإلكترونية في جميع أنحاء العالم في عام 2019 حوالي 3.5 تريليون دولار أمريكي ومن المتوقع أن تتجاوز 6.5 تريليون دولار أمريكي في عام 2023. لعبت التطورات الحديثة في الذكاء الاصطناعي دورًا رئيسيًا في هذا النمو السريع، حيث تجلى ذلك في إضافة تجربة أفضل للعملاء وحلول مبتكرة في صناعة التجارة الإلكترونية وخلق الميزة التنافسية لبائعي التجزئة. تعتبر توصيات المنتجات وتجارب التسوق الشخصية والمساعدين الافتراضيين وروبوتات الدردشة والبحث الصوتي من أكثر الاستخدامات المميزة للذكاء الاصطناعي في التجارة الإلكترونية. فيما يلي أهم خمس فوائد لنشر الذكاء الاصطناعي في أعمال التجارة الإلكترونية الخاصة بك: المساعدين الافتراضيين أو روبوتات الدردشة: روبوتات محادثة تستخدم تقنيات معالجة اللغة وتعلم الآلة لفهم استفسارات العملاء وتقديم الدعم المطلوب وفقًا لذلك. منع الغش: تقنيات الذكاء الصناعي يمكنها اكتشاف عمليات الاحتيال والغش بفعالية كبيرة من خلال التقاط أنماط الاستخدام. البحث الذكي عن المنتجات: يوفر الذكاء الصناعي مايُسمى "بالبحث الذكي" الذي يتضمن قدرات بحث مُتقدمة مثل البحث متعدد الأوجه Faceted search (خيارات محددة وذات صلة لتصفية صفحة النتائج) والتنقل والإكمال التلقائي وقوائم المنتجات الموصى بها وعمليات البحث الأخيرة وذات الصلة والعديد من الميزات الأخرى التي تُدمج مع تقنيات البحث المعمول بها. أنظمة التوصية والاقتراح: أنظمة تعتمد على تقنيات الذكاء الصناعي، تهدف إلى توقع إعجاب المستخدم بمنتج معين لعرضه عليه. لابد وأنك لاحظت ذلك على العديد من المواقع وليس فقط مواقع التجارة الإلكترونية؛ ربما لاحظت أن اليوتيوب مثلًا يُظهر لك فيديوهات مُشابة للفيديوهات التي تُفضل مشاهدتها في العادة. الأتمتة: يمكن لشركات التجارة الإلكترونية أتمتة كل شيء من عرض منتجات جديدة على قنوات متعددة إلى مزامنة المبيعات وتحديد المعاملات عالية المخاطر وتقديم خصومات للعملاء المخلصين وما إلى ذلك. يمكن أيضًا توفير الوقت والطاقة ورأس المال التشغيلي من خلال أتمتة دعم العملاء. تطبيق الذكاء الاصطناعي في مجال الصناعة يُعطي مهندسي تكنولوجيا المعلومات والباحثين في الذكاء الاصطناعي اهتمامًا مستمرًا ومتزايدًا بتحسين جودة حياتنا اليومية، وهذا يمتد ليشمل الصناعة أيضًا، وفي ظل هذا التقدم التكنولوجي الذي نعيشه أصبح من المستحيل تجنب التفاعل مع أنظمة الذكاء الاصطناعي، وتأتي ضرورة تطبيقه من مشاكل التحكم الإداري والهندسي ومن التعقيد المتزايد للأنظمة الصناعية الحالية، وكذلك من تزايد النفقات، والقيود الزمنية، ومحدودية توافر الخبرة البشرية، وغيرها الكثير من القضايا الأخرى. إن مستقبل العمل الصناعي الواضح، ستكون الثورة الصناعية الرابعة أو ما يعرف بالثورة الصناعية الرابعة "Industry 4.0 " مؤتمتة إلى حد كبير جدًا، مع استخدام جداول زمنية أسرع للإنتاج ومستودعات ذكية، مما يسمح بإنتاج وتوزيع المنتجات بسرعة وفعالية أكبر، كما أنها ستتطلب قوة عاملة ذات مهارة عالية ومتعلمة وتتقن كيفية استخدام وتشغيل أحدث التقنيات، ومن الواضح أن هذا يمثل عددًا كبيرًا من التغييرات لما اعتدنا عليه تقليديًا في هذا القطاع. إن أنظمة الذكاء الاصطناعي يمكن أن تساعد الصناعة على إحداث هذه التغييرات بسرعة وسلاسة، ولاسيما من خلال الأنظمة الخبيرة والرؤية الحاسوبية والروبوتات وإنترنت الأشياء. كيف سيؤثر الذكاء الصناعي على مستقبل العمليات الصناعية؟ إنترنت الأشياء الصناعي: يُقصد به إنترنت الأشياء عند تطبيقه على الصناعات التحويلية. إنه مفهوم يهدف إلى دمج آلات التصنيع الذكية (اتصال من آلة إلى آلة) وإجراء تحليلات متقدمة للبيانات الضخمة التي تقدمها مختلف أنواع الآلات للمساعدة في جعل كل عامل وكل مصنع أكثر كفاءة. على سبيل المثال يمكن استخدام نظام MindSphere من شركة Siemens، لربط المنتجات والمصانع والأنظمة والآلات مع بعضها، وهي واحدة من أهم الأسس التي تتيح استخدام الذكاء الاصطناعي في الصناعة. الرؤية الحاسوبية Computer Vision: من خلال تقنيات الرؤية الحاسوبية يمكن "زيادة الإنتاجية" من خلال استخدام أنظمة مراقبة العاملين والتحقق من أنهم جميعًا يستفيدون بأفضل شكل من أوقات عملهم. يمكننا أيضًا "مراقبة الجودة الآلية" عن طريق إجراء فحوصات مراقبة الجودة بسرعة وموثوقية أكبر بكثير من أي موظف بشري. الأنظمة الخبيرة Expert Systems: توفر الأنظمة الخبيرة للمهندسين الصناعيين أداة قوية لحل المشكلات. يمكن للأنظمة الخبيرة أن تكون بمثابة مساعدة في اتخاذ القرار، وكمستشار لنمذجة المشكلات وإجراء التحليل. تطبيق الذكاء الاصطناعي في مجال الطب والرعاية الصحية للذكاء الاصطناعي تطبيقات عديدة في مجال الرعاية الصحية، وهذا يشمل اكتشاف وتشخيص الأمراض ووصف الأدوية المناسبة وتصنيف المرضى والحفاظ على السجلات الطبية وتتبعها والتعامل مع قضايا التأمين الصحي. تشخيص الأمراض والتنبؤ بها: تُستخدم تطبيقات الذكاء الاصطناعي في الرعاية الصحية لبناء آلات متطورة يمكنها اكتشاف الأمراض والتعرف على الخلايا السرطانية وبعض الأمراض الأخرى. ربما تكون قد سمعت عن النظام الخبير مايسين MYCIN الذي يستطيع ﺗﺸﺨﻴﺺ اﻷﻣﺮاض المعدية، ﺧﺎﺻﺔً ﻋﺪوى اﻟﺪم كما أنه يساعد على اﻗﺘﺮاح العلاج المناسب. من الأنظمة الأخرى الشهيرة هو النظام IBM Watson الذي يُستخدم في التشخيص وتحديد خيارات العلاج للمرضى. تصّنيع الأدوية: استخدمت شركة Pfizer الذكاء الاصطناعي طوال عملية تطوير لقاحها ضد الكورونا للتأكد من أن لقاح COVID-19 يلبي احتياجات الأفراد. رعاية المرضى: تشمل تطبيقات الذكاء الاصطناعي الأخرى استخدام مساعدين صحيين افتراضيين عبر الإنترنت وروبوتات دردشة لمساعدة المرضى والمُمرضين في العثور على المعلومات الطبية وجدولة المواعيد وفهم عملية الفوترة وإكمال العمليات الإدارية الأخرى. يُعتقد أيضًا أن الابتكارات المستقبلية تشمل الجراحة الروبوتية بمساعدة الذكاء الاصطناعي والممرضات أو الأطباء الافتراضيين. تطبيق الذكاء الاصطناعي في مجال الفضاء يُعتبر اكتشاف الفضاء مهمة خطرة بالنسبة للبشر، وهنا يأتي دور الذكاء الصناعي الذي يمكنه أن ينوب عن البشر من خلال الروبوتات والأنظمة الخبيرة التي تحاكي عمل البشر. من الأمثلة على ذلك هي مركبة "مارس روفر Mars rover" التي تستطيع السير بمفردها على سطح المريخ. تعمل شركة ناسا NASA أيضًا على استخدام تقنيات الذكاء الاصطناعي الأخرى في استكشاف الفضاء وأتمتة تحليل صور المجرات والكواكب وتطوير مركبات فضائية ذكية مستقلة يمكنها تجنب الحطام الفضائي دون تدخل بشري وإنشاء شبكات اتصال أكثر كفاءة وخالية من التشويه باستخدام أجهزة تعتمد على الذكاء الاصطناعي. يُستخدم الذكاء الصناعي أيضًا للمراقبة عن بعد وتقديم الملاحظات للتحكم في الأقمار الصناعية. إحدى الأمثلة على ذلك هو استخدام شركة سبيس إكس SpaceX تقنيات الذكاء الاصطناعي لتجنب اصطدام أقمارها الصناعية مع الأقمار الصناعية الأخرى. تطبيق الذكاء الاصطناعي في مجال الفن والإبداع تتجاوز إمكانات الذكاء الاصطناعي لمحاكاة عمليات التفكير البشري المهام الإدراكية مثل التعرف على الأشياء، أو المهام التفاعلية مثل قيادة السيارة. إنّها تمتد إلى الأنشطة الإبداعية. ذكر فرانسوا كوليت (أحد أشهر باحثي جوجل) في كتابه "Deep Learning with Python" عام 2017، إن الجزء الأكبر من المحتوى الثقافي الذي سنستهلكه في المستقبل القريب، سيكون بمساعدة كبيرة من الذكاء الاصطناعي. لقد كان محقًا تمامًا، فمن منا لم يسمع بالنموذج المذهل ChatGPT الذي أطلقتها OpenAI منذ مدة قصيرة، حيث يمكن لهذا النموذج أن يوّلد لك قصصًا قصيرة بمجرد أن تعطيه عنوانًا. بعيدًا عن ChatGPT، وفي صيف عام 2015 أطلقت جوجل خوارزمية حلم عميق Deep Dream التي تستخدم فيه شبكات عصبية التفافية CNNs والتي تُعالج الصور وتخلق ظواهر باريدوليا في الصور المعالجة لجعلها أشبه بصور تكون بالأحلام. في عام 2016؛ ربما تكون قد جربت أيضًا تطبيق بريزما Prisma لتحويل صورك إلى لوحات ذات أنماط مختلفة. في صيف عام 2016، كان إخراج أول فيلم قصير تجريبي باسم Sunspring، باستخدام نص مكتوب بواسطة شبكات LSTMs. ربما حتى أنك استمعت مؤخرًا إلى موسيقى أُنتجت بالكامل باستخدام الذكاء الصناعي (هناك الكثير على اليوتيوب). يمكن للذكاء الصناعي أيضًا أن يقوم بتوليد الصور بمجرد وصفها، وهذا ماقد يكون له أهمية كبيرة في مجالات مثل التصميم، حيث قد تلجأ الكثير من الشركات لاستخدام هذه التقنيات بدلًا من توظيف مصممين وتحمل تكاليف أكبر. تطبيق الذكاء الاصطناعي في مجال الألعاب والترفيه تتضمن معظم الألعاب شكلًا من أشكال الذكاء الاصطناعي، فغالبًا ما يحاول المطورون إضفاء الطابع الذكي على شخصيات اللعبة الخاصة بهم - إن إضفاء هذا الطابع بدون استخدام تقنيات الذكاء الصناعي هو أمر مُعقد للغاية. إليك بعض الأمثلة: تستخدم ألعاب Alien Isolation التي صدرت في عام 2014 الذكاء الاصطناعي لملاحقة اللاعب طوال اللعبة. تستخدم اللعبة نظامي ذكاء اصطناعي - "Director AI" الذي يكتشف موقعك دومًا و "Alien AI"، مع أجهزة استشعار وسلوكيات تُمسك اللاعب باستمرار. يمكن لخوارزميات الذكاء الاصطناعي أن تلعب ألعابًا استراتيجية (التي تحتاج تخطيط) مثل الشطرنج، حيث تحتاج الآلة إلى التفكير في عدد كبير من الأماكن الممكنة. تطبيق الذكاء الاصطناعي في مجال التمويل التمويل Finance مجال متنوع يشمل مجموعة واسعة من القضايا، بدءًا من مراقبة الشركات العامة إلى تدفق الصفقات المصرفية الاستثمارية. من المتوقع أن تنمو صناعة الخدمات المالية عالميًّا إلى 26 تريليون دولار أمريكي مع نهاية عام 2022. عند دمج سياق استخدام تقنيات الذكاء الصناعي مع سياق الأطر المالية والعمليات والتقارير والتقييم. يمكننا النظر إلى التمويل من الزوايا الثلاث التالية: وجهات نظر المنظمة: أنواع المنظمات المختلفة لها متطلبات ووجهات نظر مختلفة يجب أخذها في الاعتبار. إجراءات: هناك إجراءات مختلفة يمكن أن تتخذها المنظمة. السياق المالي: يمكن أن يكون لهذه الإجراءات سياقات مختلفة، تتضمن: التنبؤ والميزنة، الخدمات المصرفية للأفراد، الخدمات المصرفية الاستثمارية، عمليات سوق الأوراق المالية، عمليات العملات المشفرة. لاتخاذ قرارات مدروسة ومخططة في الوقت الحقيقي Real-time حول هيكلة التدفقات المالية وعرضها وإدارتها والإبلاغ عنها، يجب أن يكون هناك تركيز مستمر على الطبيعة المتغيرة للشركة، ويجب بناء البنية التحتية المالية وتصميمها وفقًا لذلك. هنا يأتي دور تعلم الآلة ML ومعالجة اللغات الطبيعية NLP، حيث يمكن أن تساعد في تصميم مثل هذا النظام. يوضح الشكل التالي كيف يُفكّر المصرفيون البريطانيون في أن ML و NLP يمكن أن تحسن عملياتهم في المجالات المختلفة. النقاط الزرقاء تُشير إلى الفائدة الحالية. النقاط البنفسجية تُشير إلى الفائدة المتوقعة في السنوات الثلاث التالية. توضح التقديرات أن هناك تحسينات كبيرة في الكفاءة التشغيلية بالإضافة إلى الرؤى والتحليلات والاستنتاجات، من المتوقع أيضًا أن تتحسن نتائج مكافحة الاحتيال ومكافحة غسيل الأموال إلى الأفضل. تطبيق الذكاء الاصطناعي في مجال الأعمال مع الكم الهائل من البيانات المتاحة اليوم وتعقيدات الأسواق والعملاء والأعمال لم يعد بإمكان الشركات الاعتماد على أساليب العمل التقليدية لدفع النمو، فكان لابد من إدخال تقنيات الذكاء الصناعي لزيادة الإيرادات وتحسين تجربة العملاء وزيادة الإنتاجية والكفاءة ودفع نمو الأعمال والتحوّل. باستخدام الذكاء الاصطناعي في الأعمال التجارية، يمكن للشركات الآن فهم العملاء وإشراكهم في عملية الإنتاج وأتمتة العمليات التجارية والإدارية وتحسين الإنتاجية والإيرادات مع تقليل النفقات التشغيلية. ربما سمعت سابقًا بمصطلح "ذكاء الأعمال"، إنّه يُشير إلى النظريات والمنهجيات والعمليات والخصائص والتقنيات التي تعمل على تحويل البيانات الخام إلى معلومات ذات مغزى تخدم الأعمال. الآن مع الحجم الهائل من البيانات، أصبحت عملية الحصول على معلومات من البيانات أمرًا صعبًا للغاية. هنا أتى دور الذكاء الصناعي وتخصص علوم البيانات الذي يتداخل إلى حد كبير مع تعلم الآلة، حيث أصبح بالإمكان التعامل مع البيانات مهما كان حجمها واستثمارها بأفضل شكل ممكن لتحقيق النمو. تطبيق الذكاء الاصطناعي في مجال الزراعة والمناخ يمكن أن تساعد روبوتات الذكاء الاصطناعي في حصاد المحاصيل بحجم أكبر ووتيرة أسرع من العمال البشر. يستخدم الذكاء الاصطناعي أيضًا لتحديد العيوب ونقص المغذيات في التربة ومراقبة المحاصيل، وذلك من خلال تقنيات الرؤية الحاسوبية والروبوتات وتطبيقات التعلم الآلي. يمكن للذكاء الاصطناعي أيضًا تحليل مكان نمو الأعشاب الضارة واقتراح حلول لمعالجة المشكلات والآفات الزراعية. فيما يلي أهم استخدامين حاليًا للذكاء الصناعي في هذا المجال: استخدام الروبوتات في حصاد المزارع ومواجهة تحديات العمالة: تساعد هذه الآلات في تحسين حجم المحصول وتقليل النفايات الناتجة عن ترك المحاصيل في الحقل، بالإضافة إلى خفض تكاليف اليد العاملة وندرتها إلى جانب السرعة في الحصاد. تعتمد هذه الآلات على المستشعرات وتقنيات الرؤية الحاسوبية ونماذج الذكاء الاصطناعي لتحديد موقع المنتجات الممكن حصادها والمساعدة في انتقاء الثمار المناسبة. التحليلات التنبؤية واتخاذ القرار الصحيح: وهذا يتضمن توقع أفضل وقت للزرع وتوقعات غلة المحاصيل وتوقعات الأسعار. على سبيل المثال استخدم علماء ICRISAT أداة تحليلات تنبؤية للوصول إلى موعد محدد لبذر البذور للحصول على أقصى إنتاجية، كما أنها تُعطي أفكارًا حول سلامة التربة وتوصي بالأسمدة المناسبة لها. يمكن للذكاء الصناعي أيضًا التنبؤ بالعواصف والزلازل وحالة الطقس عمومًا. تطبيق الذكاء الاصطناعي في مجال التعليم للذكاء الاصطناعي العديد من التطبيقات في مجال التعليم، مثل أتمتة المهام الإدارية وأتمتة عملية وضع الدرجات للطلاب ومراقبة سلوكهم وحتى تعليمهم من خلال المُدرّسين الافتراضيين بمساعدة الأنظمة الخبيرة. على سبيل المثال، النظام الخبير GUIDON يُعلّم طلبة الطب القواعد اللازمة لاختيار العلاج المناسب للأمراض المصاحبة للالتهابات البكتيرية المُعدية، وذلك باختيار حالة مرضية تُعرض على الطلبة ومن ثم يُصحح النظام الإجابة ويعرض الأسلوب الصحيح للحل. مثال آخر هو نظام التدريب الذكي Intelligent Tutoring System والذي يمكن أن يوفر ملاحظات دقيقة ومحددة للطلاب طوال فترة تدريبهم أو تعليمهم. تطبيق الذكاء الاصطناعي في مجال الأمن السيبراني إن إمكانية إنشاء برامج ذكية قادرة على التعلم من النشاط السابق وتطبيق رؤى وتحليلات لحل المشكلات المعقدة، يمكنها إحداث ثورة في كل جانب من جوانب الأعمال الحديثة تقريبًا، وهذا يمتد ليشمل الأمن السيبراني أيضًا. إن التطورات المستمرة في البرامج الخبيثة والتهديدات الأخرى تجعل الأمن السيبراني التقليدي أضعف. وفقًا لإحصائية كشفتها شركة Capgemini، فإن ما يقرب من 60٪ من المؤسسات، لن تكون قادرة على تحديد التهديدات الخطيرة بدون تقنيات الذكاء الاصطناعي. تعود أهمية الذكاء الصناعي في الأمن السيبراني إلى العوامل التالية: الذكاء الصناعي قادر على تحديد التهديدات المحتملة للأمن السيبراني والتنبؤ بها والاستجابة لها والتعرف عليها دون الاعتماد على المدخلات البشرية. يمكن لأدوات الذكاء الاصطناعي المتطورة أيضًا التعلم بشكل مستقل بناءً على السلوكيات المُكتشفة سابقًا. يساعد الذكاء الصناعي في ملء الفجوات في القوى العاملة في مجال الأمن السيبراني: تتسارع وتيرة التحول الرقمي في جميع أنحاء العالم، وتوافر المتخصصين المدربين وذوي الخبرة في مجال الأمن السيبراني لا يواكب هذا التطور. يمكن للذكاء الصناعي ملء تلك الفجوات. يعزز الذكاء الصناعي إمكانية التعرف بسرعة على التهديدات: أدوات الأمان التي تعمل بالذكاء الاصطناعي قادرة على فرز الأحداث، وتقليص الوقت المطلوب للاستجابة للحوادث. تطبيق الذكاء الاصطناعي في إدارة الموارد البشرية تُمكّنك تقنيات الذكاء الصناعي من أتمتة معظم المهام المتكررة، مما يسمح للمؤسسات بتوفير الوقت والموارد، مثلًا تُستخدم في عمليات التوظيف لفلترة السير الذاتية وفقًا لاحتياجات الشركة لتسهيل عملية التوظيف. إليك أهم الأدوار التي يلعبها الذكاء الاصطناعي في هذا المجال: تبسيط التوظيف وإزالة التحيزات. مُساعدة موظفي الموارد البشرية في إنجاز الأعمال من خلال أتمتة العمليات. تحسين عمليات تأهيل الموظفين الجدد. تطوير استراتيجية تدريب أكثر فائدة؛ يضمن الذكاء الاصطناعي تعلم موظفيك بشكل أسرع مع التركيز على المهارات التي يحتاجون إليها لمواكبة مجالهم. تطبيق الذكاء الاصطناعي في مجال النقل يُستخدم الذكاء الاصطناعي في تحسين إجراءات السلامة والكفاءة، بحيث تتمكن البلدات والمدن - وكذلك المدن الذكية التي تتبنى مفهوم إنترنت الأشياء - من تقليل عدد حوادث الطرقات وتنظيم حركة السير وتقليل الاختناقات المرورية (بالاستفادة من مبدأ خوارزميات النمل) وكذلك تحسين عملية جدولة النقل العام. كما تعمل العديد من الشركات العملاقة على تصنيع سيارات ذاتية القيادة. الذكاء الصناعي قادر أيضًا على إجراء العديد من الأعمال المتعلقة بالسفر مثل ترتيبات السفر واقتراح الفنادق والرحلات الجوية والفحوصات الأمنية في المطار. كما أن الذكاء الصناعي يُستخدم في عمليات توفير الوقود، إذ توظف حاليًا نماذج الذكاء الاصطناعي في عملية ترشيح الطرق الأكثر توفيرًا للوقود. تجدر الإشارة إلى أن الذكاء الاصطناعي بات جزءًا أساسيًّا من أنظمة الملاحة، فمثلًا تستخدم تطبيقات GPS مثل Waze وخرائط Google الذكاء الاصطناعي لتزويد المستخدمين بأفضل طريق ممكن إلى وجهتهم مع مراعاة عوامل مثل حركة المرور وبناء الأبنية والطقس. إذا أردت أيضًا البدء في تعلم لغة بايثون اللغة الأساسية لكتابة تطبيقات ونماذج الذكاء الاصطناعي وأيضًا تعلم أساسيات الذكاء الاصطناعي وتعلم الآلة، فيمكنك تعلمها من خلال دورة الذكاء الاصطناعي التي تشرح لك بأسلوب عملي وشيق برمجة الخوارزميات والمفاهيم البرمجية وراء تعلم الآلة Machine Learning والتعلم العميق Deep Learning وغيرها، وتمكنك من تطوير مشاريع حقيقية باستخدام لغة بايثون Python تفيدك في سوق العمل وهي دورة شاملة مع مُدربين مُميزين يُرافقونك طوال الدورة للإجابة عن استفساراتك. دورة الذكاء الاصطناعي احترف برمجة الذكاء الاصطناعي AI وتحليل البيانات وتعلم كافة المعلومات التي تحتاجها لبناء نماذج ذكاء اصطناعي متخصصة. اشترك الآن خاتمة تناولنا في هذه المقالة أهم تطبيقات الذكاء الاصطناعي في مختلف المجالات. للذكاء الاصطناعي العديد من التطبيقات في كل مكان. لا مفر من القول أن الذكاء الاصطناعي هو المستقبل، وأن الشركات والمؤسسات التي لا تحاول إدخاله في أعمالها اليوم ستكون متخلفة غدًا. يُمثل كتاب مدخل إلى الذكاء الاصطناعي وتعلم الآلة نقطة بدءٍ مناسبةٍ للمبتدئين الذين يرغبون الخوض في هذا المجال. يبدأ الكتاب معك من الأساسيات ليمهد الطريق أمامك للدخول إلى هذا المجال. يمكنك أيضًا الاطلاع على العديد من المقالات المتعلقة بالذكاء الصناعي، والتي توفرها أكاديمية حسوب من هنا. اقرأ أيضًا تعلم الذكاء الاصطناعي أهمية الذكاء الاصطناعي برمجة الذكاء الاصطناعي
  2. تُعَدّ المصفوفات Arrays والشرائح Slices في لغة جو بُنى بيانات تتألف من تسلسل مرتب من العناصر، وتكون هذه الأنواع من بُنى المعطيات ذات فائدة كبيرة عندما تعمل مع مجموعة من القيم التي ترتبط مع بعضها البعض بطريقة ما، كما أنها تسمح لك بالاحتفاظ بالبيانات المتشابهة أو ذات الصلة ببعضها معًا وتنفيذ العديد من العمليات عليها كلها أو على مجموعات جزئية منها ودفعةً واحدةً. تتسم المصفوفات في لغة جو بأنها ثابتة الحجم، أي لن يكون بإمكانك تغيير ذلك بعد تحديد حجمها لأول مرة، فإذا صرّحت مثلًا عن مصفوفة a بعدد عناصر x، فستخصِّص جو لها ذاكرةً تتسع لعدد العناصر المُحدَّد x، وبالتالي لا يمكنك لاحقًا الإضافة إلى هذه المصفوفة أكثر من x عنصر، فصحيح أنّ ذلك يُفقدها المرونة، إلا أنه يجعلها أسرع. وتتسم الشرائح في جو بكونها ديناميكيةً، مما يُتيح لك تغيير حجمها باستمرار أينما دعت الحاجة لذلك، وتعطي الخاصية الديناميكية المرونة العالية إلا أن ذلك يكون على حساب الأداء أو السرعة، وتُشبه الشرائح إلى حد كبير مفهوم القوائم Lists في لغة البرمجة بايثون والمصفوفات في أغلب اللغات الأخرى، ويمكنك في العديد من المواقف استخدام المصفوفات أو الشرائح، لكن في الحالات التي تحتاج فيها إلى زيادة أو تقليل عدد العناصر، فلا بد من استخدام الشرائح، لأنه في حالة المصفوفات لن تكون قادرًا على ذلك. سيغطّي هذا المقال المصفوفات والشرائح بالتفصيل، كما سيزودك بالمعلومات الضرورية لاتخاذ القرار المناسب عند الاختيار بين أنواع البيانات هذه، وستراجع أيضًا الطرق الشائعة للتصريح والعمل مع كل من المصفوفات والشرائح. المصفوفات تُعَدّ المصفوفة بنية معطيات تجميعية تتألف من مجموعة من العناصر من النوع نفسه، وكل عنصر في المصفوفة يمكنه تخزين قيمة واحدة فيه. تتميز عناصر المصفوفة عن بعضها من خلال عدد محدد يعطى لكل عنصر ويسمى فهرسًا index، بحيث يكون فهرس أول عنصر في المصفوفة 0 دائمًا، كما تُحدَّد سعة المصفوفة لحظة إنشائها، وبمجرد تعريف حجمها لا يمكن تغييره، وبما أنّ حجم المصفوفة ثابت، فهذا يعني أنه يخصص الذاكرة مرةً واحدةً فقط، مما يجعل المصفوفات غير مرنة نوعًا ما للعمل معها، لكنه يزيد من أداء برنامجك، لهذا السبب تُستخدَم المصفوفات عادةً عند تحسين البرامج. تعريف المصفوفات تُعرّف المصفوفات من خلال التصريح عن حجمها ضمن قوسين [ ] ثم نوع البيانات ثم القيم المحددة بين الأقواس المعقوصة { }. [capacity]data_type{element_values} مثال: [3]string{"blue coral", "staghorn coral", "pillar coral"} ملاحظة: تمثِّل كل مصفوفة تُعرّفها نوع بيانات مختلف بحد ذاته اعتمادًا على نوع البيانات data_type والحجم capacity، فالمصفوفة السابقة مثلًا من نوع string وحجمها 3، تختلف عن مصفوفة من نوع string وحجمها 2. عندما تُصرّح عن مصفوفة بدون تهيئتها بقيم أوليّة، فستُعدّ لغة جو أنّ قيم جميع العناصر أصفار في حالة الأعداد وفي حالة السلاسل ''"، فالمصفوفة التالية مثلًا لم نحدد لها قيمًا أوليّةً، وبالتالي ستهيئها جو بأصفار على أساس قيم افتراضية: var numbers [3]int يكون الخرج كما يلي: [0 0 0] يمكنك أيضًا إسناد قيم عناصر المصفوفة عند إنشائها بوضعها ضمن قوسين معقوصين { } بالشكل التالي: coral := [4]string{"blue coral", "staghorn coral", "pillar coral", "elkhorn coral"} fmt.Println(coral) خزنا المصفوفة ضمن متغير ثم طبعنا قيمتها ويكون الخرج كما يلي: [blue coral staghorn coral pillar coral elkhorn coral] لاحظ أنه لا يوجد فصل واضح بين العناصر المطبوعة، لذا يُفضَّل استخدام الدالة ()fmt.Printf مع العنصر النائب q% لكي توضَع علامتَي اقتباس مزدوجة لكل عنصر لتحديده: fmt.Printf("%q\n", coral) يكون الخرج كما يلي: ["blue coral" "staghorn coral" "pillar coral" "elkhorn coral"] وضعنا الرمز n\ للنزول سطر بعد طباعة المصفوفة. فهرسة المصفوفات والشرائح يمكن استدعاء عنصر محدد من المصفوفة أو الشريحة من خلال الفهرسة، إذ يمتلك كل عنصر فهرسًا والذي قيمته int تبدأ من الصفر وتزداد تصاعديًا. سنستخدِم مصفوفةً في الأمثلة التالية، ولكن يمكنك أيضًا استخدام شريحة، إذ ستكون الفهرسة متطابقةً في كل منهما، فمن أجل المصفوفة coral ستكون الفهرسة كما يلي: 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; } "blue coral" "staghorn coral" "pillar cora" "elkhorn coral" 3 2 1 0 لاحظ أنّ العنصر الأول blue coral يحمل الفهرس رقم 0 ويحمل العنصر الأخير elkhorn coral الفهرس رقم 3. بما أن كل عنصر يمتلك فهرسًا خاصًا به، يمكننا الوصول إلى العنصر الذي نريده من خلال هذا الفهرس وإجراء العمليات عليه، فمثلًا نريد الآن الوصول إلى العنصر الثاني من المصفوفة: fmt.Println(coral[1]) سيكون الخرج كما يلي: staghorn coral كما يمكنك بالطريقة ذاتها الوصول إلى أيّ عنصر من المصفوفة: coral[0] = "blue coral" coral[1] = "staghorn coral" coral[2] = "pillar coral" coral[3] = "elkhorn coral" لاحظ أن هناك 4 عناصر في المصفوفة، وبالتالي تكون الفهارس من 0 إلى 3، لذا لا تحاول وضع فهرس خارج هذه الحدود، فإذا حاولت مثلًا في المصفوفة السابقة الوصول إلى عنصر يحمل الفهرس 4 أو 5 أو 18، فسيظهر لك خطأ لأن هذا العنصر غير موجود أو أنك تتجاوز حدود المصفوفة: fmt.Println(coral[18]) يكون الخرج كما يلي: panic: runtime error: index out of range في العديد من لغات البرمجة الأخرى مثل بايثون، يمكنك الوصول للعناصر من خلال الفهرسة السلبية، لكن لا يمكنك ذلك في جو، أي يجب استخدام الأعداد الموجبة للوصول إلى العناصر، وإلا سيظهر لك خطأ كما في المثال التالي: fmt.Println(coral[-1]) يكون الخرج كما يلي: invalid array index -1 (index must be non-negative) يمكنك ضم عناصر سلسلة في مصفوفة أو شريحة مع سلاسل أخرى باستخدام العامل +: fmt.Println("Sammy loves " + coral[0]) يكون الخرج كما يلي: Sammy loves blue coral تمكنا من وصل العنصر الموجود في الفهرس رقم 0 بالسلسلة النصية Sammy loves، لأن كل عنصر في المصفوفة هو سلسلة نصية بحد ذاته بما أننا حددنا نوع بيانات المصفوفة على أنه string وبالتالي كل عنصر فيها يُمثّل سلسلةً نصيةً. يمكننا الوصول إلى كل عنصر بصورة منفصلة والعمل مع تلك العناصر باستخدام أعداد الفهرس التي تتوافق مع العناصر داخل مصفوفة أو شريحة ما. تعديل عناصر المصفوفة يمكنك تعديل قيمة عنصر محدَّد ضمن المصفوفة بالطريقة نفسها التي تُعدّل فيها قيمة متغير من أيّ نوع بيانات وذلك بعد الوصول إلى ذلك العنصر من خلال رقم الفهرس الخاص به، ويمنحنا هذا مزيدًا من التحكم في البيانات الموجودة في الشرائح والمصفوفات، كما سيسمح لنا بمعالجة العناصر الفردية برمجيًا. coral[1] = "foliose coral" سنطبع الآن المصفوفة لنرى التعديل: fmt.Printf("%q\n", coral) يكون الخرج كما يلي: ["blue coral" "foliose coral" "pillar coral" "elkhorn coral"] معرفة حجم المصفوفة الآن بعد أن عرفت كيفية التعامل مع العناصر الفردية لمصفوفة أو شريحة، دعنا نلقي نظرةً على دالتين ستمنحانك مزيدًا من المرونة عند العمل مع بُنى المعطيات هذه. الدالة الأولى هي ()len وهي دالة مُضمّنة في جو تساعدك على العمل مع المصفوفات والشرائح، بحيث نُمرر لهذه الدالة المصفوفة أو الشريحة وتعيد لنا عدد عناصرها كما في المثال التالي: len(coral) سيكون الخرج 4 لأن عدد العناصر في المصفوفة هو 4. مثال آخر، سننشئ مصفوفة أعداد صحيحة ونحسب عدد عناصرها: numbers := [13]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12} fmt.Println(len(numbers)) يكون الخرج كما يلي: 13 قد لا نشعر بأهمية استخدام هذه الدالة عندما يكون عدد عناصر المصفوفة قليلًا كما في الأمثلة السابقة، لكن عندما نتعامل مع مصفوفات كبيرة، ستظهر الحاجة أكثر لهذه الدالة، كما سنغطي بعد ذلك كيفية إضافة عنصر إلى نوع بيانات المجموعة ونوضِّح كيف أنّ إلحاق أنواع البيانات الثابتة هذه -بسبب الطول الثابت للمصفوفات- سيؤدي إلى حدوث خطأ. إضافة عناصر إلى مصفوفة الدالة الأخرى التي سنتعرّف عليها هي ()append وهي خاصة بالشرائح، إذ تضيف هذه الدالة عنصرًا جديدًا إلى الشريحة، ولا يمكن استخدام هذه الدالة مع المصفوفات لأن المصفوفات لا يمكن تغيير حجمها ببساطة كما سبق وذكرنا، فلتكن لدينا المصفوفة التالية على سبيل المثال: coral := [4]string{"blue coral", "foliose coral", "pillar coral", "elkhorn coral"} إذا حاولت إضافة عنصر جديد black coral إلى هذه المصفوفة من خلال الدالة ()append: coral = append(coral, "black coral") ستحصل على خطأ: first argument to append must be slice; have [4]string ولحل هذه المشكلة، سنلجأ إلى نوع بيانات آخر وهو الشرائح. الشرائح تُعَدّ الشريحة تسلسلًا مرتبًا من العناصر والتي يمكن أن يتغير طولها (قابلة للتغيير)، حيث يمكن للشرائح أن تزيد حجمها ديناميكيًا، فعند إضافة عناصر جديدة إلى شريحة وإذا لم يكن للشريحة حجم ذاكرة كافي لتخزين العناصر الجديدة، فستطلب ذاكرةً أكبر من النظام حسب الحاجة، ولهذا السبب هي شائعة الاستخدام أكثر من المصفوفات. تمكّنك الخاصيّة الديناميكية للشرائح من العمل معها في الحالات التي تحتاج فيها إلى تغيير طول عدد عناصر البيانات بأمان، وهذه هي الخاصية الوحيدة التي تتميز بها الشرائح عن المصفوفات. التصريح عن شريحة يُصرّح عن الشرائح من خلال تحديد نوع البيانات مسبوقًا بقوسَي فتح وإغلاق مربعَين [] ليس فيهما أي قيمة -خلاف نوع المصفوفة التي تحتاج إلى تحديد حجمها- وقيم بين أقواس معقوصة {}. وتكون شريحة من الأعداد الصحيحة كما يلي: []int{-3, -2, -1, 0, 1, 2, 3} شريحة من الأعداد الحقيقية: []float64{3.14, 9.23, 111.11, 312.12, 1.05} شريحة من السلاسل: []string{"shark", "cuttlefish", "squid", "mantis shrimp"} يمكنك أيضًا إسنادها إلى متغير: seaCreatures := []string{"shark", "cuttlefish", "squid", "mantis shrimp"} ثم طباعة هذا المتغير: fmt.Println(seaCreatures) يكون الخرج كما يلي: [shark cuttlefish squid mantis shrimp] مثال آخر: seaCreatures := []string{"shark", "cuttlefish", "squid", "mantis shrimp", "anemone"} سنطبع الشريحة لكن باستخدام الدالة ()fmt.Printf مع العنصر النائب q% كما فعلنا مع المصفوفات سابقًا: fmt.Printf("%q\n", seaCreatures) يكون الخرج كما يلي: ["shark" "cuttlefish" "squid" "mantis shrimp" "anemone"] إذا رغبت في إنشاء شريحة بطول معيّن دون تحديد عناصرها، فيمكنك استخدام الدالة ()make المضمنة: oceans := make([]string, 3) فإذا طبعناها، فسيكون الخرج كما يلي: ["" "" ""] يمكنك أيضًا إنشاء شريحة بطول محدَّد كما فعلنا أعلاه لكن مع حجز مساحة إضافية من خلال تمرير عدد العناصر التي نريد حجز ذاكرة لها بصورة استباقية على أساس وسيط ثالث: oceans := make([]string, 3, 5) المقصود هنا أنه ستُنشأ شريحة بطول 3 لكن ستُحجز ذاكرة لخمس عناصر إضافية، أي ستحجز بالمجمل 8 عناصر، والهدف من ذلك هو تحسين الأداء، أي نتوقع أنه ستُضاف 5 عناصر على الأكثر لاحقًا، فنحجز لهم ذاكرةً مسبقًا لتجنب التأخير الذي سيحدث عند حجز ذاكرة إضافية في وقت تشغيل البرنامج بحيث نستفيد من الخاصية الديناميكية والأداء كما في المصفوفات. يمكنك استخدام الدالة ()append التي تحدثنا عنها سابقًا لإضافة عنصر جديد إلى الشريحة. تقطيع المصفوفات تدعم المصفوفات إضافةً إلى الفهرسة عملية الاقتطاع slicing أيضًا، إذ تُستخدم الفهرسة للحصول على عناصر مفردة؛ أما عملية الاقتطاع فتتيح الحصول على جزء من المصفوفة، أي عدة عناصر متتالية، ويمكنك إجراء ذلك عن طريق إنشاء نطاق من أرقام الفهرس مفصولةً بنقطتين على صورة [الفهرس الأول: الفهرس الثاني] أو [first_index:second_index]، ومن المهم ملاحظة أنه عند تقطيع المصفوفة ستكون النتيجة شريحةً وليست مصفوفةً. لنفترض أنك ترغب فقط في طباعة العناصر الوسطى من المصفوفة coral بدون العنصر الأول والأخير، إذ يمكنك إجراء ذلك عن طريق إنشاء شريحة تبدأ من الفهرس 1 وتنتهي قبل الفهرس 3 مباشرةً كما يلي: fmt.Println(coral[1:3]) يكون الخرج كما يلي: [foliose coral pillar coral] لاحظ أننا وضعنا الرقم 1 ثم نقطتين ثم 3، بالنسبة للرقم 1 فقد وضعناه لأنه يمثّل نقطة البداية حيث يتواجد ثاني عنصر من المصفوفة؛ أما 3 فهو نقطة النهاية لكنها لا تؤخذ، وإنما تؤخذ القيمة التي قبلها مباشرةً، أي أنه ستؤخذ العناصر من 1 إلى 2، باختصار، العنصر المُحدد بالرقم الأول سيكون مشمولًا دائمًا بعملية الاقتطاع؛ أما العنصر المُحدد بالرقم الأخير فلن يكون مشمولًا. هناك بعض القيم الافتراضية المفيدة في خاصية التقطيع، فإذا حُذف الفهرس رقم 1 first_index -أي العنصر الثاني-، فستكون القيمة الافتراضية له صفرًا، وإذا حُذف الرقم الثاني second_index فإنّ القيمة الافتراضية تكون طول السلسلة النصية التي سيجري اقتطاعها. coral[:2] // اقتطاع العناصر من الموقع 0 إلى الموقع 2 (غير مشمول)‏ coral[1:] // اقتطاع العناصر من الموقع 1 (مشمول) إلى نهاية السلسلة نريد مثلًا من أول عنصر حتى العنصر الثاني: fmt.Println(coral[:3]) يكون الخرج كما يلي: [blue coral foliose coral pillar coral] أو مثلًا نريد من العنصر الأول حتى النهاية: fmt.Println(coral[1:]) يكون الخرج كما يلي: [foliose coral pillar coral elkhorn coral] التحويل من مصفوفة إلى شريحة في حال احتجت إلى تغيير حجم المصفوفة يمكنك تحويلها إلى شريحة من خلال الآلية التي اتبعناها في الفقرة السابقة لتقطيع المصفوفة، ويمكن إنجاز ذلك من خلال استخدام النقطتين : بدون تحديد البداية أو النهاية، أي كما يلي: coral[:] لاحظ أنه هنا لا يُحوّل المُتغير بحد ذاته -والذي يمثّل المصفوفة- إلى شريحة، لكن ما يحدث هو أنه عند استخدامك للتقطيع مع المصفوفات، ستُعيد جو نسخةً تمثّل الجزء الذي اقتطعته على أساس شريحة، أي أنّ المتغير coral نفسه لا يحوّل، وإنما تُعاد نسخة منه، وهذا منطقي، ففي جو لا يمكنك تغيير نوع المتغير مهما كان نوعه، إذًا نكتب كما يلي: coralSlice := coral[:] إذًأ ستمثّل coralSlice نسخة شريحة من المصفوفة coral، فإذا طبعناها، فسنحصل على ما يلي: [blue coral foliose coral pillar coral elkhorn coral] يمكنك الآن مثلًا إضافة عنصر جديد وليكن black coral إلى الشريحة كما يلي: coralSlice = append(coralSlice, "black coral") fmt.Printf("%q\n", coralSlice) سنحصل على الخرج التالي عند طباعتها: ["blue coral" "foliose coral" "pillar coral" "elkhorn coral" "black coral"] يمكنك أيضًا إضافة أكثر من عنصر دفعةً واحدةً: coralSlice = append(coralSlice, "antipathes", "leptopsammia") يكون الخرج كما يلي: ["blue coral" "foliose coral" "pillar coral" "elkhorn coral" "black coral" "antipathes" "leptopsammia"] يمكنك دمج شريحتين معًا من خلال ()append لكن يجب أن تضع ثلاث نقاط ... بعد اسم الشريحة الثانية كما يلي: moreCoral := []string{"massive coral", "soft coral"} coralSlice = append(coralSlice, moreCoral...) يكون الخرج كما يلي: ["blue coral" "foliose coral" "pillar coral" "elkhorn coral" "black coral" "antipathes" "leptopsammia" "massive coral" "soft coral"] حذف عنصر من شريحة لا تمتلك جو دوالًا جاهزةً مثل باقي اللغات لحذف عنصر، إذ يجب عليك الاعتماد على مبدأ التقطيع لحذف العناصر، فلحذف عنصر يجب عليك تقطيع الشريحة لشريحتين، بحيث تمثِّل الأولى جميع العناصر التي قبله وتمثِّل الثانية العناصر الذي بعده، ثم دمج هاتين الشريحتين الجديدتين معًا بدون العنصر الذي تريد حذفه، أي كما يلي بفرض أنّ i هو فهرس العنصر المراد إزالته: slice = append(slice[:i], slice[i+1:]...) نريد فرضًا حذف العنصر elkhorn coral الموجود في الفهرس 3 من الشريحة coralSlice: coralSlice := []string{"blue coral", "foliose coral", "pillar coral", "elkhorn coral", "black coral", "antipathes", "leptopsammia", "massive coral", "soft coral"} coralSlice = append(coralSlice[:3], coralSlice[4:]...) fmt.Printf("%q\n", coralSlice) يكون الخرج كما يلي: ["blue coral" "foliose coral" "pillar coral" "black coral" "antipathes" "leptopsammia" "massive coral" "soft coral"] نلاحظ أنّ العنصر الذي حددناه قد حُذف من الشريحة، ويمكنك أيضًا حذف عدة قيم أو مجال من القيم دفعةً واحدةً، إذ تريد مثلًا حذف "elkhorn coral" و "black coral" و "antipathes"، أي تريد حذف العناصر الموجودة في الفهارس 3 و 4 و 5: coralSlice := []string{"blue coral", "foliose coral", "pillar coral", "elkhorn coral", "black coral", "antipathes", "leptopsammia", "massive coral", "soft coral"} coralSlice = append(coralSlice[:3], coralSlice[6:]...) fmt.Printf("%q\n", coralSlice) يكون الخرج كما يلي: ["blue coral" "foliose coral" "pillar coral" "leptopsammia" "massive coral" "soft coral"] عدد عناصر الشريحة صحيح أنه يمكنك استخدام التابع ()len لمعرفة عدد عناصر الشريحة، لكنه سيعطيك عدد العناصر الظاهرة وليس عدد العناصر التي حُجز لها مكان في الذاكرة، وللتوضيح، يجب عليك العودة إلى الدالة ()make وتتذكر حينما كتبنا: oceans := make([]string, 3, 5) هنا أنشأنا شريحة عدد عناصرها الظاهر 3 لكن حجزنا ذاكرة لخمسة عناصر وقد شرحنا ذلك سابقًا، فإذا استخدمنا الآن الدالة ()len لمعرفة عدد عناصر الشريحة oceans، فستُعيد 3؛ أما إذا استخدمنا الدالة ()cap، فستعطي 5 وهذا هو الفرق الوحيد بينهما. لاحظ أن الدالة ()cap ليس لاستخدامها معنًى مع المصفوفات لأن الحجم ثابت، أي الحجم الظاهر هو نفسه المحجوز دومًا، لذا اقتصر تعريف ()cap على العمل مع الشرائح ولا تعمل مع المصفوفات. الاستخدام الشائع للدالة ()cap هو إنشاء شريحة بعدد محدد مسبقًا من العناصر ثم ملء تلك العناصر برمجيًا، إذ يؤدي ذلك إلى تجنب عمليات التخصيص غير الضرورية المحتملة التي قد تحدث باستخدام ()append لإضافة عناصر تتجاوز السعة المخصصة حاليًا كما في المثال التالي: numbers := []int{} for i := 0; i < 4; i++ { numbers = append(numbers, i) } fmt.Println(numbers) يكون الخرج كما يلي: [0 1 2 3] أنشأنا شريحةً ثم أنشأنا حلقة for تتكرر أربع مرات. أضفنا في كل تكرار القيمة الحالية لمتغير الحلقة i إلى شريحة الأعداد numbers، وقد يؤدي ذلك إلى عمليات تخصيص غير ضرورية للذاكرة والتي قد تؤدي إلى إبطاء برنامجك، فعند إضافة عناصر إلى شريحة فارغة، فإنه في كل مرة تستدعي فيها الدالة ()append تتحقق جو من سعة الشريحة، فإذا كان العنصر المضاف سيجعل الشريحة تتجاوز هذه السعة، فستُخصص ذاكرة إضافية لها، مما يؤدي إلى إنشاء عبء إضافي في برنامجك ويمكن أن يؤدي إلى إبطاء التنفيذ. سنملأ الآن الشريحة بدون استخدام ()append وذلك عن طريق التخصيص المسبق للعناصر كما تعلمت سابقًا في بداية المقال: numbers := make([]int, 4) for i := 0; i < cap(numbers); i++ { numbers[i] = i } fmt.Println(numbers) يكون الخرج كما يلي: [0 1 2 3] استخدمنا هنا الدالة ()make لإنشاء شريحة وجعلناها تخصص 4 عناصر مسبقًا، ثم استخدمنا بعد ذلك الدالة ()cap في الحلقة للتكرار على كل عنصر من الشريحة (العناصر تكون كلها أصفار كما أشرنا سابقًا)، ثم ملأنا الشريحة بالقيم التي نريدها وهي قيم متغير الحلقة i، ولاحظ أنّ استخدام الدالة ()cap هنا بدلًا من ()append سيتجنب أيّ تخصيصات إضافية للذاكرة. الشرائح متعددة الأبعاد يمكنك أيضًا تعريف الشرائح متعددة الأبعاد، أي شريحة تتضمّن شريحةً أو أكثر؛ يمكن القول شرائح متداخلة، إذ نضع هنا الشرائح ضمن قوسين داخل الشريحة التي تضمها. مثال: seaNames := [][]string{{"shark", "octopus", "squid", "mantis shrimp"}, {"Sammy", "Jesse", "Drew", "Jamie"}} يجب عليك استخدام عدة مؤشرات للوصول إلى عنصر داخل هذه الشريحة، بحيث نستخدِم مؤشرًا واحدًا لكل بُعد من أبعاد البنية: fmt.Println(seaNames[1][0]) fmt.Println(seaNames[0][0]) تعني التعليمة [seaNames[1][0 أنك تريد الوصول إلى العنصر الأول 0 من الشريحة ذات الفهرس 1؛ أما التعليمة الثانية، فتشير إلى أنك تريد الوصول إلى العنصر الأول 0 من الشريحة ذات الفهرس 0، لذا سيكون الخرج كما يلي: Sammy shark فيما يلي قيم الفهرس لبقية العناصر الفردية: seaNames[0][0] = "shark" seaNames[0][1] = "octopus" seaNames[0][2] = "squid" seaNames[0][3] = "mantis shrimp" seaNames[1][0] = "Sammy" seaNames[1][1] = "Jesse" seaNames[1][2] = "Drew" seaNames[1][3] = "Jamie" عند العمل مع الشرائح متعددة الأبعاد من المهم أن تضع في الحسبان أنك ستحتاج إلى الإشارة إلى أكثر من رقم فهرس واحد من أجل الوصول إلى عناصر محددة داخل الشريحة المتداخلة التي تعمل عليها. الخاتمة تعلمت في هذا المقال كيفية العمل مع المصفوفات والشرائح والروابط في جو، وتعرّفت على العديد من حالات الاستخدام لكل منها، كما تعرّفت على بعض الأخطاء الشائعة في التعامل مع هذه البُنى وعلى دوال أساسية فيها، وأصبحت لديك القدرة أيضًا على التفريق بين الشرائح والمصفوفات ومتى تستخدم أيًا منهما. ترجمة -وبتصرف- للمقال Understanding Arrays and Slices in Go لصاحبه Gopher Guides. اقرأ أيضًا المقال السابق: التعرف على الروابط Maps في لغة جو Go مقدمة عن المصفوفات Arrays والشرائح Slices الخاصة بلغة Go التعامل مع السلاسل في لغة جو Go استخدام المتغيرات والثوابت في لغة جو Go التعرف على GOPATH في لغة جو Go
  3. مصطلح الذكاء الاصطناعي هو أكثر مصطلح رنان واسع الشهرة في عصرنا الحالي وهناك سببٌ واحدٌ لذلك؛ فتنتنا بالذكاء الذي يمنحنا نحن البشر مكانة خاصة بين أشكال الحياة، وقد تظهر أسئلة مثل "ما هو الذكاء؟" وسؤال "كيف يمكن قياس الذكاء؟" أو "كيف يعمل الدماغ؟" وكل هذه الأسئلة ذات مغزى عند محاولة فهم الذكاء الاصطناعي، وقد جاوبنا عنها وفصلنا فيها وفي شرح الذكاء الاصطناعي وتعريفاته في مقالة الذكاء الاصطناعي: دليلك الشامل وسنتحدث في هذا المقال بالتفصيل عن مجالات الذكاء الاصطناعي. ما هو الذكاء الاصطناعي؟ عرفنا في المقال السابق الذكاء الاصطناعي ولكن لابد في بداية المقال من الإشارة باختصار إليه وإلى مدى انتشار الذكاء الاصطناعي حولنا هذه الأيام. يمكن القول أن الذكاء الاصطناعي هو العملية الناتجة عن تحويل الآلات والحواسيب من أدوات مطيعة منفذة للأوامر فقط إلى أدوات آمرة تعطي اقتراحات وتتخذ القرارات بمفردها دون تدخل بشري بناء على معطيات أو تدريبات مسبقة. كنا سابقًا نبحث عن النتائج لنصل إلى ما نريد أما اليوم باتت الآلات تعرض لنا نتائج تكون في بعض الحالات مطابقة تمامًا لما نضمر البحث عنه أو نميل إلى إليه خصوصًا فيما يتعلق بنية الشراء أو المشاهدة أو حتى البحث وذلك بناءً على إحاطة الحواسيب والهواتف بنا وتسجيلها كل شاردة وواردة عنا. دخل الذكاء الاصطناعي في أغلب الحواسيب والأجهزة المحيطة بنا، فاصرخ الآن اسم المساعد الآلي في هاتفك ليجيبك مباشرةً وكأنه المارد المختبئ في المصباح السحري، وانشر صورة في إحدى منصات التواصل الاجتماعي لتتعرف على الأشخاص مباشرة أو تخمنهم ونتوقع في السنوات القادمة أن يصبح الأساس فيها ويمتد إلى سائر مجالات الحياة وكل ذلك لم يأت من فراغ بل مبني على مجالات وأسس متينة سنتعرف عليها تاليًا. أهم مجالات الذكاء الاصطناعي يتضمن الذكاء الصناعي العديد من المجالات أو الفروع، وكلٌ منها يعالج مواضيع محددة أو يُقدّم مناهج وأساليبًا مختلفة، كما أن معظمها يتضمن جوانبًا علميةً وهندسيةً في نفس الوقت تجتمع كلها ليُبنى عليها علم الذكاء الصناعي، وسنتحدث عن أشهر مجالات الذكاء الاصطناعي بشيئٍ من التفصيل. 1. تعلم الآلة Machine learning في عام 1959 نُشرت ورقة بحثية مثيرة للفضول تتحدث عن استخدام التعلم الآلي في لعبة الداما Checkers في مجلة "IBM للبحوث والتطوير" من تأليف آرثر صموئيل الذي يعمل في شركة IBM. كان الهدف هو التحقق من إمكانية برمجة الحاسب، بحيث يتعلم لعب لعبة الداما بطريقة أفضل مما يمكن أن يلعبه الشخص الذي كتب البرنامج، أي أن الحاسب يلعب معك ويتحسن أداؤه باستمرار بعد كل مرة يلعب ضدك فيها لدرجة يصبح فيها أفضل منك "يتعلم ويتحسن". لقد قدّم آرثر صموئيل التعلم الآلي في ورقته البحثية تلك باعتباره مجالًا فرعيًا من علوم الحاسب، يمنحها القدرة على التعلم دون أن تُبرمج صراحةً. إن السمة الرئيسية للتعلم الآلي هي مفهوم التعلّم الذاتي (على الرغم من عدم ذكره صراحةً في تعريف آرثر صموئيل). إنّه يشير إلى تطبيق النمذجة الإحصائية لاكتشاف الأنماط وتحسين الأداء بناءً على البيانات والمعلومات التجريبية؛ كل ذلك بدون أوامر برمجية صريحة. كان ذلك نهجًا ثوريًّا في علوم الحاسب والبرمجة، لأن تطوير البرامج في ذلك الوقت، كان فقط عبارة عن قائمة من الأوامر التي تتبع سير عمل منطقي مُحدد. دورة تطوير التطبيقات باستخدام لغة Python احترف تطوير التطبيقات مع أكاديمية حسوب والتحق بسوق العمل فور انتهائك من الدورة اشترك الآن أنواع تعلم الآلة في الذكاء الاصطناعي ينقسم تعلم الآلة -وهو أحد أهم ركائز ومجالات الذكاء الاصطناعي- إلى أربعة أنواع أساسية بناءً على أسلوب وطريقة التعلم، أولها التعليم الخاضع للإشراف Supervised learning وهنا تُعطى الخوارزمية مجموعةً من البيانات بالإضافة إلى الخرج الصحيح لها. الأمر يُشبه أن تُعطي طفلًا في الثالثة من عمره مجموعةً من الصور، ولتكن 10 صور؛ بعضها يُمثّل مربع والأخرى تُمثّل مستطيل وتعرضها عليه وتخبره أن هذه صور مربع وتلك صور مستطيل. هنا الخوارزمية الذكية القادرة على التعلم هي عقل الطفل، ومجموعة البيانات التي يتعلم منها هي الصور العشر. يمكن تصنيف مهام التعليم بإشراف إلى نوعين، هما: التصنيف Classification التوقع Regression النوع الثاني هو التعليم غير الخاضع للإشراف UnSupervised learning، وهنا تُعطى الخوارزمية مجموعةً من البيانات بدون الخرج الصحيح لها، ويكون على عاتق الخوارزمية اكتشاف الأنماط المخفية في البيانات والفروقات بينها. نفس المثال السابق لكن هنا لن نخبر الطفل (الخوارزمية الذكية) أيّ الصور هي صور مربع وأيّ الصور هي مستطيل، لكنه سيكون قادرًا على معرفة أنهما شيئان مختلفان، فإذا أعطيته صورة مربع جديدة (ليست من ضمن الصور العشر) وطلبت منه أن يُصنفها سيضعها تلقائيًا في جانب المربعات (نمط). يمكن تصنيف مهام التعليم بدون بإشراف إلى نوعين، هما: التجميع Clustering. الربط Association. أما النوع الثالث هو التعليم شبه الخاضع للإشراف Semi-Supervised Learning يمزج بين النوع الأول والثاني، ويهدف إلى تحسين أداء التعلم. تظهر الحاجة إليه عندما يكون لديك كمية صغيرة من البيانات الغير مُعلّق عليها التي تريد استخدامها في نموذجك. في هذه الحالة يمكنك استخدام أنظمة التعلم العميق لتسمية تلك البيانات، وبالتالي تحويلها من بيانات غير خاضعة للإشراف إلى بيانات خاضعة للإشراف -وهي عملية تسمى التسمية الزائفة Pseudo-Labeling. ملاحظة: نقول عن مجموعة بيانات أنّها غير معنونة أو غير مُسماة Unlabeled، عندما لا تتضمن تعليقات توضيحية (تسميات) لكل عينة بيانات فيها. بينما نقول عنها معنونة أو مُسماة Labeled في الحالة المُعاكسة مثل إذا كان لدينا مجموعة بيانات مكونة من 10 صور، وكل صورة لديها تعليق يوضح ماهيتها (صورة كلب قطة سيارة ..إلخ) نقول عنها "مجموعة بيانات مُسماة"، وإذا لم تتضمن تعليقات توضيحية تُسمى "مجموعة بيانات غير مُسماة". أما النوع الرابع هو التعليم المُعزز Reinforcement learning، هو التعلم من خلال التفاعل مع البيئة. هنا يتعلم الوكيل Agent (الوكيل هو الخوارزمية أو الروبوت أو البرنامج) من من عواقب أفعاله، بدلاً من تعليمه صراحةً. يختار الوكيل أفعاله على أساس تجاربه السابقة (الاستغلال) وأيضًا من خلال الخيارات الجديدة (الاستكشاف)، أي أن التعلم يرتكز على مبدأ التجربة والخطأ. بالعودة للمثال السابق نفسه، نعطي الطفل صورة من مجموعة الصور العشر، ونسأله هل هي صورة مربع أم مستطيل، فإذا كانت إجابته صحيحة نعطيه دولارًا (مكافأة) وإن أخطأ نوبخه (عقاب)، ثم نعطيه الصورة الثانية ونكرر نفس العملية. سيسعى الطفل إلى الحصول على أكبر قدر من الدولارات (تعظيم مكافأته)، وبالتالي سيكون قادرًا على التفريق بين الصور في نهاية المطاف. 2. الشبكات العصبية الاصطناعية Artificial Neural Networks الشبكات العصبية الاصطناعية هي تطبيقات برمجية للبنية العصبية لأدمغتنا؛ إنها تحاول تبسيط وتقليد سلوك الدماغ (فقط تشبيه، ليس إلا). يتكون الدماغ من خلايا عصبية، وهي خلايا قابلة للاستثارة كهربائيًا ويُمكنها معالجة ونقل المعلومات عبر إشارات كهربائية وكيميائية. بالمقابل تتكون الشبكات العصبية الاصطناعية من خلايا عصبية، حيث: الخلية العصبية هي الوحدة الحسابية الأساسية في أي شبكة عصبية، أي كما في الدماغ. تأخذ الخلايا العصبية المدخلات (البيانات) وتعالجها وتمررها إلى الخلايا العصبية الأخرى الموجودة في الطبقات الأخرى من الشبكة، حتى تصل المخرجات المعالجة إلى طبقة الخرج النهائية. تحتوي الشبكة العصبية الاصطناعية البسيطة على ثلاث طبقات فقط - طبقة الإدخال وطبقة الإخراج والطبقة المخفية. الشكل التالي يوضح المقصود: شبكة عصبية بثلاث طبقات (طبقة دخل - طبقة داخلية خفية - طبقة خرج) 3. التعلم العميق Deep Learning إذا أردنا اختصار التعلم العميق بجملة واحدة، فستكون "التعلم العميق هو شبكة عصبية اصطناعية تمتلك عددًا كبيرًا من الطبقات الداخلية الخفية". إنّه أسلوب جديد لتعلم التمثيلات من البيانات (تعلم الميزة Feature Learning أو تعلم التمثيل Feature Representation)، يرتكز على تعلم "طبقات" متتالية تمثيلات ذات مغزى بطريقة متزايدة. كلمة "عميق" في "التعلم العميق" لا تشير إلى أي نوع من الفهم "الأعمق" الذي يُحقق من خلال النهج، بل إنّه يُمثّل ببساطة فكرة الطبقات المتتالية للتمثيلات. قد تكون الأسماء الأخرى المناسبة لهذا الحقل هي "تعلم التمثيلات الطبقية" أو "تعلم التمثيلات الهرمية"، حيث تتعلم الشبكة تمثيلات أعقد مع ازدياد عمق الطبقة. غالبًا ما يتضمن التعلم العميق عشرات أو حتى مئات من طبقات التمثيل المتتالية، إلا أن بعض المناهج الأخرى للتعلم الآلي تميل إلى التركيز على استخدام طبقة تعلم واحدة أو طبقتين فقط (يُسمى ذلك أحيانًا "التعلم الضحل Shallow Learning"). تعلّم هذه التمثيلات الطبقية يكون من خلال نماذج تسمى "الشبكات العصبية" (التي تعرفنا عليها منذ قليل)، حيث تكون منظمة في طبقات مكدسة واحدة تلو الأخرى. ملاحظة يُقصد بتعلّم التمثيل Representation learning أو تعلّم الميزة Feature learning، مجموعة من التقنيات التي تسمح للنظام بمعرفة التمثيلات اللازمة لاكتشاف الميزات أو تصنيفها من البيانات الخام تلقائيًا. سنلقي الآن نظرةً على كيفية قيام شبكة عميقة مكونة من 3 طبقات خفية بتحويل صورة رقم مكتوب بخط اليد (الرقم 4) عبر هذه الطبقات، من أجل التعرف عليه، حيث تظهر لنا في أقصى اليسار الصورة الأصلية التي تمثل الدخل، تليها 3 طبقات مع التمثيلات المقابلة لكل منها. تنتهي الشبكة بطبقة خرج تشير إلى الرقم: يمكنك أن تلاحظ أن الشبكة تحوّل الصورة الرقمية إلى تمثيلات تختلف عن بعضها في كل طبقة، كما أن كل تمثيل أعقد من سابقه (من الأبسط "الصورة الأصلية" إلى الأعقد "تمثيل الصورة في آخر طبقة مخفية"). يمكنك التفكير في الشبكة العميقة على أنها عملية متعددة المراحل لتقطير المعلومات، حيث تمر المعلومات من خلال مرشحات Filters متتالية وتكون أكثر "نقاء" بطريقة متزايدة من أول طبقة إلى آخر طبقة مخفية (أي يتغير تمثيل الصورة إلى شكل يمكن أن تفهمه الخوارزمية أكثر عبر الطبقات). إنجازات التعلم العميق على الرغم من أن التعلم العميق هو حقل فرعي قديم إلى حد ما من التعلم الآلي، إلا أنه لم يبرز إلا في أوائل عام 2010. في السنوات القليلة التي تلت ذلك حقق التعلم العميق ثورةً في هذا المجال، حيث حقق نتائج ملحوظة في جميع المشكلات الإدراكية، مثل "الرؤية" و "السمع"؛ المشكلات التي تبدو سهلة جدًا بالنسبة للإنسان، لكنها كانت بعيدة المنال بالنسبة للآلات سابقًا. لنكون أكثر دقة، حقق التعلم العميق الإنجازات التالية، التي كانت صعبة تاريخياً في التعلم الآلي): التعرّف على الكلام بمستوى قريب من البشر. نسخ الكلام المكتوب بخط اليد Handwriting transcription بمستوى قريب من البشر. تصنيف الصور بمستوى قريب من البشر. القيادة الذاتية بمستوى قريب من البشر. تحسين الترجمة الآلية. الإجابة عن الأسئلة. تحسين نتائج البحث في محركات البحث. تحسين استهداف الإعلانات. المساعدين الرقميين مثل Google Now أو Amazon Alexa. ما الفرق بين الشبكات العصبية الاصطناعية والتعلم العميق؟ التعلم العميق هو توسيع للشبكات العصبية، فبدلًا من استخدام طبقة مخفية واحدة أصبح هناك عدد كبير أو كبير جدًا من الطبقات المخفية. إن التطور الكبير في العتاديات الحوسبيّة ساهم في ظهور التعلم العميق، لأنّه يتطلب قدرات حوسبية كبيرة. ما الفرق بين تعلم الآلة والتعلم العميق؟ تعلم الآلة هو فرع من الذكاء الصناعي، أما التعلم العميق فهو فرع من تعلم الآلة قدّم نهجًا مختلفًا وثوريًّا لمعالجة المشكلات. لاحظ أن التعلم العميق Deep Learning هو الدائرة الصغيرة التي يشملها تعلم الآلة Machine Learning والتي بدورها تشكل جزءًا من الدائرة الأكبر المتمثلة في الذكاء الصناعي Artificial Intelligence. 4. أتمتة العمليات الآلية Robotic Process Automation تمتلك الشركات الناجحة اليوم عددًا أقل من الموظفين مقارنة بما كان عليه الحال في الماضي. مثلًا شركة كوداك Kodak في ذروتها في عام 1973 وظفت 120.000، ولكن عندما اشترى فيسبوك Facebook انستغرام Instagram في عام 2012، كان موقع مشاركة الصور (انستغرام) لديه 13 عامل فقط؛ يعود الفضل في ذلك إلى مبادئ الأتمتة. ما المقصود بأتمتة العمليات الآلية RPA؟ لا تعني كلمة آلية أو روبوتية هنا الآلات والروبوتات الفيزيائية وإنما الروبوتات التي تُمثل برامج تحاكي عمل الإنسان (برامج نشبهها بالروبوتات لأنها تقوم بأعمال الإنسان). عندما نقول RPA، فنحن نشير إلى البوتات bots أو الروبوتات التي تعمل كبرمجيات آلية أو يمكن القول أنّها تقنية تحاكي الطريقة التي يتفاعل بها البشر مع البرامج لأداء مهام كبيرة الحجم وقابلة للتكرار (مثلًا نسخ ولصق الملفات من مكان لآخر أو تسجيل بعض المعلومات على الحاسب أو حذف الرسائل بعد مرور شهر ..إلخ). تتضمن بعض الأمثلة ما يلي: إرسال الفواتير. إدخال وتغيير وتتبع الموارد البشرية HR. مطابقة السجلات المالية. المستندات والعقود ومعلومات الموظف. تقديم ردود نموذجية للعملاء. نقل البيانات من نظام إلى آخر. الكشف عن المشكلات المتعلقة بخدمة العملاء واتخاذ الإجراءات لحل المشاكل. 5. الروبوتات Robots تعود أصول كلمة "جسم آلي" أو جسمال اختصارًا إلى عام 1921 في مسرحية كتبها كاريل كابيك بعنوان "Rossum’s Universal Robots"، وتأتي كلمة روبوت من الكلمة التشيكية robata التي تشير إلى العمل القسري. هناك خلاف حول تعريف الروبوتات، لكن يمكن القول أنها الآلة التي يمكنها إنجاز المهام الموكلة إليها من خلال تنفيذ سلسلة معقدة من الإجراءات تلقائيًا. يمكن توجيه الروبوت بواسطة جهاز تحكم خارجي، أو قد يكون عنصر التحكم مضمنًا فيه. هل تعرف فيليبي؟ إنّه روبوت يعمل بالذكاء الصناعي يمكنه طهي البرجر. إن كنت قد ذهبت إلى أحد فروع مطعم CaliBurger، فربما ستتمكن من مشاهدته وهو يطهو (لديهم فرع في الإمارات). يقول الرئيس التنفيذي والمؤسس المشارك لشركة Miso Robotics التي بنت النظام: "فيليبي يساعد على تحسين جودة الطعام بسبب الاتساق (يخلو من التناقضات) ويقلل من تكاليف الإنتاج، لقد بنينا الروبوت ليكون في حالة امتثال صارم للمعايير التنظيمية." ما هو الروبوت؟ هناك العديد من الاختلافات في التعاريف، لأن الروبوتات تتضمن عددًا لا يُحصى من الأشكال والوظائف، لكن يمكننا تلخيصها في بضعة أجزاء رئيسية هي: المادي Physical: يمكن أن يتراوح حجم الروبوت من الآلات الصغيرة التي يمكنها استكشاف أجسادنا إلى الأنظمة الصناعية الضخمة إلى الآلات الطائرة إلى السفن تحت الماء. يجب أيضًا أن يكون هناك نوع من مصادر الطاقة لها، مثل البطارية أو الكهرباء أو الطاقة الشمسية. الإجرائي Act: يجب أن يكون الروبوت قادرًا على اتخاذ إجراءات معينة. يمكن أن يشمل ذلك تحريك عنصر أو حتى التحدث. الحسي Sense: يجب أن يفهم الروبوت بيئته من أجل أن يتخذ إجراءًا ما. يمكن تحقيق ذلك من خلال أجهزة الاستشعار وأنظمة التغذية الراجعة. الذكاء Intelligence: هذا لا يعني أن يمتلك كل قدرات الذكاء الصناعي الممكنة؛ يجب أن يكون الروبوت قابلًا للبرمجة ليكون قادرًا على اتخاذ الإجراءات - من خلال البرمجة يمكننا إضافة الطابع الذكي للآلة. مستقبل الروبوتات على الرغم من أن الروبوتات هي أذكى التقنيات، إلا أنها من الممكن أن تُخطئ، كما أن سوقها مُعقّد جدًا وتطورها يبدو متقطعًا ومتقلبًا. يقول شلونتز من شركة كوبالت في هذا الصدد: 6. المنطق الترجيحي أو الضبابي Fuzzy Logic جاءت نظرية المنطق الضبابي -التي هي ركيزة من ركائز مجالات الذكاء الاصطناعي- لتسد الثغرات الكبيرة في المنطق الكلاسيكي المعروف بالمنطق الثنائي (صحيح أو خاطئ، 0 أو 1)، الذي يعتمد على الأساليب الكمية لتحليل الأنظمة واتخاذ القرارات. إذا كانت الدقة مطلوبة عند التعامل مع الأنظمة والقرارات البسيطة، فإن تحقيق الدقة غير ممكن في المنطق الكلاسيكي، وأحيانًا غير مطلوب عند التعامل مع المسائل المعقدة، فكلما زاد تعقيد المسألة، فقدت العبارات الدقيقة فائدتها وفقدت العبارات المُقيدة دقتها. يعتمد المنطق الضبابي أو الغيمي على الأساليب الإحصائية ويقدم طريقة للتعامل مع القرارات بشكل ضبابي وبدون حدود مباشرة للقرارات. الفرق بين المنطق الضبابي والمنطق الكلاسيكي هو فرق فلسفي مهم يعتمد على جدلية الأهمية والدقة، فليس كل ما هو دقيق واضح مهم، ليس كل مهم دقيق، فأحيانًا الدقة متعبة قاتلة والغموض رحمة. ما هو المنطق الضبابي؟ بفرض أننا نريد تصنيف الأشخاص إلى مجموعات حسب الطول. لدينا مجموعة للأشخاص طوال القامة (أي الشخص الذي يعتبر طويل) ومجموعة للأشخاص قصار القامة (الشخص الذي نعتبره قصير)، نلاحظ أن جملة "يعتبر طويل" وجملة "يعتبر قصير" هي جمل نسبية، إذ أن مفهوم الشخص الطويل والقصير يختلف من مكان لآخر ومن منطقة لأخرى - في هذا المثال سنعتبر أن الشخص الطويل هو الشخص الذي طوله يساوي أو يتجاوز 170 سم، عندها أي شخص وليكن x نقول أنه ينتمي لمجموعة الأشخاص الطوال إذا حقق شرط أن يكون طول x أكبر من 170 سم، لكن بفرض لدينا شخص طوله 169 فهل من الصحيح اعتباره شخص غير طويل لأنه لم يحقق خاصية مجموعة الأشخاص الطوال! فمن خلال النظر لا نستطيع تمييز شخص طوله 170 من شخص طوله 169، فكيف سنتعامل مع هذه الحالات الحرجة؟ حسب المنطق الكلاسيكي ومجموعاته الكلاسيكية، فإن هذا الشخص (169 سم) لن ينتمي لمجموعة طوال القامة، بالتالي نحن بحاجة لتعريف آخر للمجموعات من أجل القدرة على جعل هذه الحالات ممكنة، وباختصار شديد يمكن القول إننا بحاجة إلى حد فاصل بين انتماء وعدم انتماء أكثر مرونة ونسبية. هنا يأتي دور المنطق الضبابي والمجموعات الضبابية، فمن خلاله يمكننا إضافة عدد كبير من المجموعات (مثلًا: طويل جدًا، طويل، متوسط، قصير، قصير جدًا …إلخ)، حيث تُضاف هذه المجموعات وفقًا لتحليلات واستبيانات وإحصاءات دقيقة، وبالتالي نحصل على إجابات أكثر دقة ومرونة. 7. الأنظمة الخبيرة Expert systems المعلومات هي ناتج تحليل البيانات التي تعتبر المادة الخام، فالمعلومات تبدأ من حيث تنتهي البيانات، ومنه ظهرت المعلومات متخذة من قواعد البيانات أساسًا لها، فنظم قواعد البيانات تتضمن العلاقات التي تربط بين البيانات للحصول على المعلومات. أما المعارف فهي استنتاجية أكثر منها حسابية أو بيانية، ومنه تبدأ المعارف من حيث تنتهي المعلومات، ومنه ظهرت قواعد المعرفة Knowledge Base والنظم الخبيرة، وهو البديل الأرقى لنظم المعلومات. ما هو النظام الخبير؟ هو نظام ذكي يستخدم القواعد المأخوذة من الخبرة الإنسانية (والمنظمة ضمن قواعد بيانات) على هيئة شروط ونتائج في مجال معين ويستخدم طرق الاشتقاق والاستدلال لاستخراج واستنتاج النتائج المعللة بالأسباب والناتجة عن تطابق هذه الشروط أو النتائج مع شرط أو نتيجة ما والخاصة بمشكلة معينة يراد إيجاد حل لها. هذه الأنظمة لديها قدرات مميزة في مجالات معينة مثل التخطيط وتحليل العوارض وتشخيص الأخطاء وتشخيص الأمراض وفي التصميم وفي نظم دعم اتخاذ القرار وغيرها من المجالات المتخصصة التي تم فهم العمليات المطلوبة لها، والتي تتناسب مع القدرات التمثيلية والاستنتاجية لهياكل الأنظمة المستخدمة. استخدامات النظم الخبيرة يمكن استخدام النظم الخبيرة في العديد من المجالات والمهام، إليك بعضها: التفسير: تستخدم النظم الخبيرة بكثرة في تفسير المواقف من واقع المعلومات المتاحة منها. أشهر الأمثلة هو النظام الخبير PUFF الذي يُستخدم في تشخيص أمراض الرئة. التنبؤ: يُستخدم النظام الخبير METEOR للتنبؤ بالعواصف على المدى القصير. التشخيص: يُستخدم النظام DIET لمساعدة أطباء التغذية في عملية وصف الحمية الغذائية. كما يُستخدم النظام MYCIN لتشخيص أمراض الدم و وصف العلاج أيضًا. إزالة الأعطال: يُحدد النظام ACE مواقع الأعطال في الشبكات الهاتفية ويقترح الصيانة المناسبة. التخطيط: النظام الخبير KNOBS يساعد مراكز القيادات الجوية التكتيكية على التخطيط للمهام من خلال معرفة الأهداف والإمكانيات المتاحة والمهام المخططة. تُستخدم النظم الخبيرة أيضًا في المراقبة والتصميم والتدريب والتعليم والتحكم. 8. معالجة اللغات الطبيعية Natural Language Processing بعض المراجع تعتبر معالجة اللغات الطبيعية مجرد مجال من مجالات الذكاء الاصطناعي لكن لنكون دقيقين؛ معالجة اللغات الطبيعية -اختصارًا NLP- هي مجال تتقاطع فيه علوم الحاسب والذكاء الصناعي واللسانيات (اللغويات أو علم اللغة). إنّها المجال الذي يهتم ببناء وتطوير الأنظمة التي يمكنها معالجة وفهم وتوليد لغة الإنسان. منذ نشأتها في الخمسينيات وحتى وقت قريب جدًا، كانت معالجة اللغات مجالًا بحثيًّا أكثر مما هو تطبيقيًّا، إلا أن التطورات الأخيرة التي شهدتها في العقد الماضي، أدت إلى استخدام البرمجة اللغوية العصبية بكثرة في العديد من التطبيقات التجارية والرعاية الصحية والتمويل والقانون والتسويق والموارد البشرية وغيرها الكثير. استخدامات معالجة اللغات الطبيعية الآن وبعد أن تعرّفنا على معالجة اللغات الطبيعية، دعنا نتحدث عن بعض استخداماتها وتطبيقاتها في المجالات المختلفة: تصنيف النص Text Classification: إحدى المزايا الخاصة بخدمات البريد الإلكتروني؛ قدرتها على فصل الرسائل العشوائية Spam عن الرسائل العادية. تمثل هذه العملية واحدة من حالات الاستخدام الشهيرة لمعالجة اللغات والمعروفة باسم "تصنيف النص". من التطبيقات الأخرى التي تستخدم تصنيف النص هي: تصنيف وتنظيم المحتوى، دعم العملاء، التجارة الإلكترونية E-commerce، محركات البحث. استخراج المعلومات Information extraction: هي عملية استخراج معلومات معينة من المستندات. إحدى الأمثلة على استخدامها في تطبيقات العالم الحقيقي هي الدعاية القصيرة التي نراها على اليمين عندما نبحث عن اسم شخصية مشهورة على جوجل. كما أنها تُستخدم أيضًا في روبوتات الدردشة Chatbots واستخراج البيانات من الاستمارات والإيصالات …إلخ. الترجمة الآلية Machine Translation: وفقًا لتعريف جامعة ستانفورد؛ هي مهمة التحويل التلقائي من لغة طبيعية إلى أخرى مع الحفاظ على معنى النص المُدخل وفصاحته، وتستخدم العديد من الشركات مثل جوجل (مُترجم جوجل الشهير) ومايكروسوفت الذكاء الصناعي والتعلم الآلي لتقديم مُترجمات آلية عالية الجودة. التجارة الإلكترونية E-commerce: لعبت التطورات الحديثة في تعلم الآلة و معالجة اللغات دورًا رئيسيًا في النمو السريع الذي شهدته التجارة الإلكترونية. عند زيارة الصفحة الرئيسية لأي بائع تجزئة إلكتروني، ستجد الكثير من المعلومات على هيئة نصوص وصور تعبر عن المنتجات وأصنافها. يسعى تجار التجزئة إلى استخدام هذه المعلومات بذكاء لإرضاء العملاء وبناء ميزة تنافسية، وهنا يأتي دور معالجة اللغات لحل العديد من المشكلات ذات الصلة مثل تحليل مراجعات الزبائن والبحث عن المنتجات وتوصيات المنتج ..إلخ. الرعاية الصحية HealthCare: تُطبّق معالجة اللغات في جميع الصناعات والقطاعات الرئيسية وتحسّنها، وهذا يشمل مجال الطب والرعاية الصحية. يمكن للباحثين فرز البيانات غير المهيكلة لتحسين رعاية المرضى والجهود البحثية وتشخيص الأمراض …إلخ. تُطبق معالجة اللغات أيضًا في العديد من المجالات كالموراد المالية والقانون ومواقع التواصل الإجتماعي. انظر مثلًا مقال تحليل المشاعر في النصوص العربية باستخدام التعلم العميق الذي يطبق ما تحدثنا عنه على نصوص عربية بمشروع عملي. بماذا تختلف معالجة اللغات الطبيعية عن التعلم الآلي والتعلم العميق؟ على الرغم من التداخل الكبير بين معالجة اللغات والتعلم العميق وتعلم الآلة، إلا أنها مجالات مختلفة تمامًا. في البداية كانت تعتمد مناهج معالجة اللغات على الاحتمالات والإحصاء والقواعد والاستدلال، لكن في العقود القليلة الماضية بدأت تتأثر كثيرًا بمناهج تعلم الآلة، وفي الآونة الأخيرة ومع تطور التعلم العميق، لاحظنا استخدام واسع لمناهجه في بناء تطبيقات معالجة اللغات. إذًا هي مجالات تتقاطع مع بعضها، لكن كل منها مُستقل عن الآخر. يُمثل كتاب مدخل إلى الذكاء الاصطناعي وتعلم الآلة نقطة بدءٍ مناسبةٍ للمبتدئين الذين يرغبون الخوض في هذا المجال. يبدأ الكتاب معك من الأساسيات ليمهد الطريق أمامك لتعلم هذا المجال. يمكنك أيضًا الاطلاع على العديد من المقالات المتعلقة بالذكاء الصناعي، والتي توفرها أكاديمية حسوب من هنا. إذا أردت أيضًا البدء بتعلم خوازرميات الذكاء الاصطناعي وتعلم الآلة وبناء تطبيقات عملية تفيدك في سوق العمل يمكنك الاشتراك في دورة الذكاء الاصطناعي التي توفرها الأكاديمية والتي ستتعلم فيها الكثير من المواضيع الرائدة مثل التعامل مع مختلف النماذج اللغوية الكبيرة LLMs مثل GPT من OpenAI و LLaMA 2 من Meta وكيفية دمجها مع تطبيقاتك كما ستتعلم في هذه الدورة أساسيات تحليل البيانات Data Analysis وتمثيلها مرئيًا، وبرمجة خوارزميات تعلم الآلة Machine Learning والتعلم العميق Deep Learning وغيرها من المواضيع المفيدة بأسلوب عملي وشيق. دورة الذكاء الاصطناعي احترف برمجة الذكاء الاصطناعي AI وتحليل البيانات وتعلم كافة المعلومات التي تحتاجها لبناء نماذج ذكاء اصطناعي متخصصة. اشترك الآن خاتمة تعرفنا في مقال اليوم على أهم مجالات الذكاء الاصطناعي ولكن للذكاء الاصطناعي فروع ومجالات عديدة أخرى يزداد عددها باستمرار ولا يمكن حصرها في مقالٍ واحد وهذا العلم مازال في تطور متسارع. اقرأ أيضًا تعلم الذكاء الاصطناعي تطبيقات الذكاء الاصطناعي أهمية الذكاء الاصطناعي
  4. تمتلك معظم لغات البرمجة نوع بيانات يُمثّل بنية معطيات يُعرف بالقاموس dictionary أو التجزئة hash، إذ تربط هذه البنية أو هذا النوع البيانات على صورة أزواج (مفتاح-قيمة). تُعَدّ الخرائط أو الروابط maps مفيدةً للغاية في كثير من الحالات مثل أن تريد إعطاء كل طالب رقمًا يُميّزه عن باقي الطلاب، إذ يمكنك في هذه الحالة تعريف رابطة يربط اسم كل طالب (قيمة) برقم يُميّزه (مفتاح)، فالخرائط Maps في لغة جو هي بنية معطيات توجد في لغات أخرى مثل بايثون، وتُعرّف الخرائط في لغة جو من خلال وضع الكلمة map متبوعةً بنوع بيانات المفاتيح (في مثالنا السابق سيكون أعداد صحيحة) ضمن قوسين [ ] ثم نوع بيانات القيم (سلاسل نصية في مثالنا)، وأخيرًا توضع أزواج (مفتاح، قيمة) ضمن قوسين معقوصين {}: map[key]value{} سيوضّح المثال التالي الأمر أكثر؛ إذ سنعرّف رابطة مفاتيحه هي الاسم name والحيوان animal واللون color والموقع location، وقيمه هي Sammy و shark و blue و ocean على التوالي. map[string]string{"name": "Sammy", "animal": "shark", "color": "blue", "location": "ocean"} لاحظ أنّ المفتاح يُوضَع على اليسار والقيمة على اليمين ويُفصل بينهما بنقطتين : كما يُفصل بين كل زوج (مفتاح:قيمة) بفاصلة , ولاحظ أيضًا أننا استخدمنا نوع البيانات string لكل من القيم والمفاتيح، وهذا ليس إجباريًا، لكنه يعتمد على ما ستستخدِمه من بيانات. يمكنك تخزين الخرائط ضمن متغيرات كما في أيّ نوع بيانات آخر: sammy := map[string]string{"name": "Sammy", "animal": "shark", "color": "blue", "location": "ocean"} fmt.Println(sammy) يكون الخرج كما يلي: map[animal:shark color:blue location:ocean name:Sammy] لاحظ أنه قد حدث تغيير في مواقع الأزواج عند طباعة الرابطة، وسبب ذلك هو أنّ جو تُخزّن هذه الأزواج ضمن مناطق متفرقة من الذاكرة، فالترتيب هنا غير مهم، وما يهمنا فقط هو أن تكون كل قيمة مرتبطةً بمفتاح نصل إليها من خلاله. الوصول إلى عناصر الرابطة يمكننا الوصول إلى قيم محدَّدة في الرابطة بالرجوع إلى المفاتيح المرتبطة بها، فإذا أردنا مثلًا الحصول على اسم المستخدِم من الرابطة sammy، فيمكننا ذلك عن طريق كتابة ["sammy["name كما يلي: fmt.Println(sammy["name"]) يكون الخرج كما يلي: Sammy تتصرف الخرائط مثل قواعد البيانات، لكن بدلًا من فهرسة العناصر بأعداد صحيحة كما هو الحال في الشرائح slice، فإنها تسند لمفتاح، ويمكنك عبر تلك المفاتيح الحصول على القيم المقابلة لها، أي باستدعاء المفتاح "name"، سنحصل على القيمة المرتبطة به وهي "Sammy"، وبالمِثل، فيمكن استدعاء القيم الأخرى في الرابطة sammy باستخدام الصيغة ذاتها: fmt.Println(sammy["animal"]) //shark تُعيد fmt.Println(sammy["color"]) //blue تُعيد fmt.Println(sammy["location"]) //ocean تُعيد من خلال تخزين البيانات على هيئة أزواج (مفتاح:قيمة)، سيصبح بإمكانك الوصول إلى القيمة التي تريدها من خلال ذكر اسم المفتاح الذي يُميّزه. المفاتيح والقيم keys/values لا تمتلك لغة جو أيّة دوال مُضمّنة تمكّنك من سرد جميع المفاتيح أو القيم، ففي بايثون مثلًا هناك الدالة ()‎.kyes التي تعرض لك جميع المفاتيح التي تتضمنها الرابطة أو ()‎.values التي تعرض كل القيم، لكن يمكنك التكرار على عناصر الرابطة في جو من خلال العامِل range كما يلي: for key, value := range sammy { fmt.Printf("%q is the key for the value %q\n", key, value) } ستُعيد range هنا قيمتين من أجل كل زوج في الرابطة، إذ ستُمثِّل القيمة الأولى المفتاح key والثانية القيمة value، كما أنّ نوع بيانات key سيكون نفسه نوع بيانات key في الرابطة sammy والأمر نفسه بالنسبة لمتغير القيمة value، وبالتالي سيكون الخرج كما يلي: "animal" is the key for the value "shark" "color" is the key for the value "blue" "location" is the key for the value "ocean" "name" is the key for the value "Sammy" صحيح أنه لا توجد دوال جاهزة لاستخراج المفاتيح، لكن يمكنك استخراجها من خلال كتابة شيفرة بسيطة كما يلي: keys := []string{} for key := range sammy { keys = append(keys, key) } fmt.Printf("%q", keys) وبالتالي سنحصل على شريحة بجميع المفاتيح: ["color" "location" "name" "animal"] كما ذكرنا هو أنّ المفاتيح غير مرتبة، ولكن يمكنك ترتيبها إذا أردت من خلال الدالة ()sort.Strings: sort.Strings(keys) يكون الخرج كما يلي: ["animal" "color" "location" "name"] يمكنك إجراء الأمر نفسه لاستخراج القيم، لكن هنا سنعرّف شريحةً يكون عدد عناصرها هو عدد الأزواج الموجودة في الرابطة وذلك لكي لا نضطر في كل مرة إلى طلب حجز مساحة إضافية كما فعلنا في المثال السابق حين عرّفنا شريحةً فارغةً ثم في كل تكرار وسّعنا حجمها بإضافة عنصر جديد. sammy := map[string]string{"name": "Sammy", "animal": "shark", "color": "blue", "location": "ocean"} items := make([]string, len(sammy)) var i int for _, v := range sammy { items[i] = v i++ } fmt.Printf("%q", items) إذًا عرّفنا شريحةً بالحجم المطلوب تمامًا بحيث يقابل عدد عناصر الرابطة (كل عنصر يمثّل زوج)، ثم نُعرّف متغير الفهرسة i وندخل في حلقة التكرار على عناصر الرابطة، ولاحظ أنه وضعنا عامِل _ في بداية الحلقة إشارةً إلى أن المفتاح لا نريده، ويكون الخرج كما يلي: ["ocean" "Sammy" "shark" "blue"] يمكنك استخدام الدالة المضمّنة len لمعرفة عدد العناصر الموجودة في الرابطة كما يلي: sammy := map[string]string{"name": "Sammy", "animal": "shark", "color": "blue", "location": "ocean"} fmt.Println(len(sammy)) يكون الخرج كما يلي: 4 تفقد وجود عنصر في رابطة عند محاولة الوصول إلى عنصر غير موجود في القائمة، ستُعيد جو 0 إشارةً إلى أن هذا العنصر غير موجود في الرابطة، ولهذا السبب ستحتاج إلى طريقة بديلة للتمييز بين الصفر المخزن والمفتاح المفقود، لذا انظر إلى المثال التالي، إذ سنعرّف رابطةً فارغةً ثم سنحاول الوصول إلى عنصر غير موجود: counts := map[string]int{} fmt.Println(counts["sammy"]) نظرًا لأن المفتاح sammy غير موجود، فستعيد جو 0 كما ذكرنا، فهو يعطي قيمة صفرية تلقائيًا لجميع المتغيرات التي ليس لديها قيمة: 0 هذا غير مرغوب فيه وقد يؤدي إلى حدوث خلل في برنامجك في الكثير من الحالات، ولحل المشكلة هناك قيمة اختيارية ثانية يمكنك الحصول عليها عند البحث عن عنصر في الرابطة، وهي قيمة منطقية bool تُدعى ok وتكون قيمتها true إذا عُثِر على العنصر أو false إذا لم يُعثر على العنصر، وتستخدَم كما يلي: count, ok := counts["sammy"] يمكنك إذا أحببت استخدام هذه القيمة المُعادة ok لطباعة رسالة تُرشدك فيما إذا كان العنصر موجودًا أم لا: if ok { fmt.Printf("Sammy has a count of %d\n", count) } else { fmt.Println("Sammy was not found") } يكون الخرج كما يلي: Sammy was not found يمكنك في جو الجمع بين التصريح عن متغير والفحص الشرطي مع كتلة if/else، إذ يتيح لك هذا اختصار التعليمات البرمجية لإنجاز عملية الفحص: if count, ok := counts["sammy"]; ok { fmt.Printf("Sammy has a count of %d\n", count) } else { fmt.Println("Sammy was not found") } عند محاولة الوصول لعنصر ضمن رابطة ما في جو، من الأفضل التحقق من وجودها لتجنب الزلات أو الأخطاء البرمجية في برنامجك. تعديل الخريطة Map تُعَدّ الخرائط هياكل بيانات قابلة للتغيير mutable، أي يمكن تعديلها، وسنتعلم في هذا القسم كيفية إضافة عناصر إلى رابطة وكيفية حذفها. إضافة وتغيير عناصر الرابطة يمكنك إضافة أزواج قيمة-مفتاح إلى رابطة دون استخدام توابع أو دوال باستخدام الصياغة التالية، حيث نضع اسم متغير الرابطة متبوعةً بالمفتاح بين قوسين [] متبوعة بالعامل = ثم القيمة: map[key] = value سنضيف في المثال التالي زوج مفتاح-قيمة إلى رابطة تُسمى usernames: usernames := map[string]string{"Sammy": "sammy-shark", "Jamie": "mantisshrimp54"} usernames["Drew"] = "squidly" fmt.Println(usernames) يكون الخرج كما يلي: map[Drew:squidly Jamie:mantisshrimp54 Sammy:sammy-shark] لاحظ أنّ الرابطة حُدّثت بالزوج Drew:squidly نظرًا لأنّ الخرائط غير مرتبة، فيمكن أن يظهر الزوج المُضاف في أيّ مكان في مخرجات الرابطة، فإذا استخدمنا الرابطة usernames لاحقًا في ملف برنامجك، فسيظهر فيه الزوج المضاف حديثًا. يمكن استخدام هذه الصياغة لتعديل القيمة المرتبطة بمفتاح معيّن، ففي هذه الحالة سنشير إلى مفتاح موجود سلفًا ونمرِّر قيمةً مختلفةً إليه. سنعرِّف في المثال التالي رابطة باسم followers لتعقّب متابِعي المستخدِمين على شبكة معيّنة، إذ حصل المستخدِم "drew" على عدد من المتابعين الإضافيين اليوم، لذلك سنحدّث القيمة المرتبطة بالمفتاح "drew" ثم سنستخدِم الدالة Println()‎ للتحقق من تعديل الرابطة: followers := map[string]int{"drew": 305, "mary": 428, "cindy": 918} followers["drew"] = 342 fmt.Println(followers) يكون الخرج كما يلي: map[cindy:918 drew:342 mary:428] نرى في الخرج السابق أنّ عدد المتابعين قد قفز من 305 إلى 342. a يمكننا استخدام هذه الطريقة لإضافة أزواج قيمة-مفتاح إلى الخرائط عبر مدخلات المستخدِم، إذَا سنكتب برنامجًا سريعًا usernames.go يعمل من سطر الأوامر ويسمح للمستخدِم بإضافة الأسماء وأسماء المستخدِمين المرتبطة بها: package main import ( "fmt" "strings" ) func main() { usernames := map[string]string{"Sammy": "sammy-shark", "Jamie": "mantisshrimp54"} for { fmt.Println("Enter a name:") var name string _, err := fmt.Scanln(&name) if err != nil { panic(err) } name = strings.TrimSpace(name) if u, ok := usernames[name]; ok { fmt.Printf("%q is the username of %q\n", u, name) continue } fmt.Printf("I don't have %v's username, what is it?\n", name) var username string _, err = fmt.Scanln(&username) if err != nil { panic(err) } username = strings.TrimSpace(username) usernames[name] = username fmt.Println("Data updated.") } } نُعرّف أولًا الرابطة ضمن ملف usernames.go ، ثم نضبط حلقة التكرار على الأسماء، وتطلب بعد ذلك من المستخدِم إدخال اسم وتصرّح عن متغير لتخزِّنه فيه، ويجب أن تتحقق بعد ذلك من حدوث خطأ في عملية الإدخال من المستخدِم، ففي حال حدث خطأ، فستخرج من البرنامج. تلتقط الدالة Scanln المُدخلات التي يدخلها المستخدِم بالكامل بما في ذلك محرف العودة إلى بداية السطر Carriage return، لذا أنت بحاجة إلى إزالة أي فراغ زائد من الدخل باستخدام الدالة strings.TrimSpace. تتحقق كتلة if من وجود الاسم في الرابطة أو لا، فإذا لم يكن الاسم موجودًا، فسيطبع ملاحظات للمستخدِم تُشير إلى ذلك ثم يطلب إدخال اسم جديد، ويتحقق البرنامج مرةً أخرى من وجود خطأ، ففي حال لم يكن هناك خطأ، فسيَقص محرف الإرجاع ويُسند الاسم المُدخل من المستخدِم على أساس قيمة لمفتاح الاسم ثم يطبع الملاحظات التي تفيد بأن البيانات قد حُدّثت. سننفِّذ البرنامج من سطر الأوامر: $ go run usernames.go سترى الخرج التالي: Enter a name: Sammy "sammy-shark" is the username of "Sammy" Enter a name: Jesse I don't have Jesse's username, what is it? JOctopus Data updated. Enter a name: اضغط على CTRL + C عند الانتهاء من اختبار البرنامج للخروج من البرنامج. يوضح هذا المثال كيف يمكنك تعديل الخرائط بآلية تفاعلية، وستفقد جميع بياناتك بمجرد خروجك من هذا البرنامج باستخدام CTRL + C، إلا إذا خزّنت البيانات في ملف بطريقةٍ ما. للتلخيص، يمكنك إضافة عناصر إلى الرابطة أو التعديل عليها من خلال الصيغة map[key] = value. حذف عناصر من الرابطة مثلما يمكنك إضافة أزواج قيمة-مفتاح إلى الرابطة أو تغيير قيمه، يمكنك أيضًا حذف العناصر الموجودة في الرابطة، فلإزالة زوج قيمة-مفتاح من الرابطة، استخدم الدالة ()delete التي تحتوي على وسيطين، إذ يمثِّل الوسيط الأول الرابطة والثاني المفتاح: delete(map, key) لتكن لدينا الرابطة التالية التي تُعبّر عن الأذونات: permissions := map[int]string{1: "read", 2: "write", 4: "delete", 8: "create", 16:"modify"} الآن مثلًا لم تعُد بحاجة إلى إذن التعديل، لذا ستُزيله من الرابطة، ثم ستطبع الرابطة لتأكيد إزالتها: permissions := map[int]string{1: "read", 2: "write", 4: "delete", 8: "create", 16: "modify"} delete(permissions, 16) fmt.Println(permissions) يكون الخرج كما يلي: map[1:read 2:write 4:delete 8:create] يزيل السطر (delete(permissions, 16 القيمة المرتبطة بالمفتاح 16 ضمن رابطة الأذونات ثم يُزيل المفتاح نفسه. إذا كنت ترغب في مسح الرابطة بجميع قيمها، فيمكنك إجراء ذلك عن طريق إسناد رابطة فارغة من النوع نفسه لها كما في المثال التالي: permissions = map[int]string{} fmt.Println(permissions) سيُظهر الخرج أنّ الرابطة قد أصبحت فارغةً: map[] بما أن الرابطة هي نوع بيانات قابل للتعديل mutable data type فيمكن التعديل عليها بالإضافة والحذف. الخاتمة ألقينا في هذا المقال نظرةً على الخرائط في جو، إذ تتألف الخرائط من أزواج قيمة-مفتاح، وتوفر حلًا ممتازًا لتخزين البيانات دون الحاجة إلى فهرستها، إذ يتيح لنا ذلك استرداد القيم بناءً على معانيها وعلاقتها بأنواع البيانات الأخرى. ترجمة -وبتصرُّف- للمقال Understanding Maps inGo لصاحبه Gopher Guides. اقرأ أيضًا المقال السابق: البيانات المنطقية Boolean في لغة جو Go تعرف على أنواع البيانات في لغة جو Go استخدام المتغيرات والثوابت في لغة جو Go التعامل مع السلاسل في لغة جو Go
  5. نحن نسمي أنفسنا "إنسان عاقل أو حكيم"، لأن ذكائنا أمر مهم جدًا بالنسبة لنا. لقد حاولنا منذ آلاف السنين أن نفهم كيف نفكر، أي كيف يمكن للعقل البشري أن يدرك ويُحلل ويفهم ويتنبأ ويتلاعب بعالم كبير ومعقد. يذهب الذكاء الصناعي إلى ماهو أبعد من ذلك؛ يحاول فهم الكيانات الذكية إلى جانب بناء كيانات ذكية أيضًا. الذكاء الاصطناعي هو أحد أحدث المجالات في العلوم والهندسة، وقد بدأ العمل به بجدية بعد الحرب العالمية الثانية بفترة وجيزة، لكنه لم يُبصر النور إلا مع بداية القرن الحادي والعشرين، حيث بدأ الإنترنت والبيانات بالانتشار إلى جانب تطور أجهزة الحواسيب. يتميز الذكاء الصناعي بأنه علم كبير وتعددي؛ يشارك فيه علماء الحاسوب والرياضيات والهندسة واللغة والفلسفة والمنطق. الذكاء الاصطناعي وثيق الصلة بأي مهمة فكرية؛ إنه مجال عالمي. ماهو الذكاء الاصطناعي لنتفق بدايةً أنّه لا فرق في قول "الذكاء الاصطناعي" أو "الذكاء الصناعي" بالعربية، فكلاهما يُشيران إلى شيء من صنع البشر وليس الطبيعة. مفهوم الذكاء الصناعي 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 مُعدّل التعلّم ‏ معلمة فائقة تُحدد مقدار التعلم في خوارزميات الذكاء الصناعي خاتمة كانت هذه المقالة بمثابة مدخل إلى الذكاء الاصطناعي؛ إنها تُجيبك عن العديد من الأسئلة المتعلقة بالذكاء الصناعي، مثل مفهومه وتعريفه وأهميته وتطبيقاته ومجالاته والتقنيات التي يدعمها وتخصصاته وأدواته والبدء في تعلمه …إلخ. وسنتحدث في المقالات القادمة عن العديد من الأمور الأخرى المتعلقة بالذكاء الصناعي ونتوسع بالنقاط التي ذكرناها في هذا المقال التي سيطول ذكرها والحديث عنها. يعدنا الذكاء الاصطناعي بأنه سيغير العالم، والخبر السار هو أن هناك العديد من الأشخاص الذين يركزون على جعل هذا حقيقةً واقعةً، ولا يتعلق الأمر بجني مبالغ طائلة أو الحصول على الشهرة؛ الهدف هو مساعدة البشرية وتغيير العالم إلى الأفضل. اقرأ أيضًا الذكاء الاصطناعي: أهم الإنجازات والاختراعات وكيف أثرت في حياتنا اليومية الذكاء البشري مقابل الذكاء الاصطناعي أهمية الذكاء الاصطناعي تعلم لغة بايثون فوائد الذكاء الاصطناعي لغات برمجة الذكاء الاصطناعي
  6. نوع البيانات المنطقي أو البولياني Boolean -واختصارًا bool نسبة إلى العالم George Boole- يمثَّل بتمثيل ثنائي فقط عادة صح true أو خطأ false أو 1 أو 0 أو يوجد ولا يوجد وهكذا، ويُستخدم هذا النوع في البرمجة بصورة كبيرة في عمليات المقارنة والتحكم بسير عمل البرنامج. يُمثَّل نوع البيانات هذا في لغة جو بالقيمة 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; } العامل توضيح == المساواة =! عدم المساواة > أصغر < أكبر ‎<=‎ أكبر أو يساوي =< أصغر أو يساوي سنستخدِم العددين الصحيحين التاليين لتوضيح آلية عمل هذه المتغيرات: x := 5 y := 8 من الواضح أنّ قيمة x أصغر من y، وسنستخدِم كل العوامل التي ذكرناها في الجدول السابق وسنرى خرج البرنامج مع كل حالة في الشيفرة التالية: package main import "fmt" func main() { x := 5 y := 8 fmt.Println("x == y:", x == y) fmt.Println("x != y:", x != y) fmt.Println("x < y:", x < y) fmt.Println("x > y:", x > y) fmt.Println("x <= y:", x <= y) fmt.Println("x >= y:", x >= y) } سيكون الخرج كما يلي: x == y: false x != y: true x < y: true x > y: false x <= y: true x >= y: false سألنا جو في الشيفرة أعلاه ما يلي: هل x تساوي y؟ والإجابة كانت false طبعًا. هل x لا تساوي y؟ والإجابة true. هل x أصغر من y؟ والإجابة true. هل x أكبر من y؟ والإجابة false. هل x أصغر أو يساوي y؟ والإجابة true. هل x أكبر أو يساوي y؟ والإجابة false. استخدَمنا الأعداد الصحيحة هنا، لكن يمكنك استخدام الأعداد العشرية أيضًا، كما يمكن أيضًا استخدام السلاسل النصية مع العوامل المنطقية، وتجدر الإشارة إلى أن مقارنة السلاسل حساسة لحالة المحارف، فالمحرف s لا يساوي المحرف S كما في المثال التالي: Sammy := "Sammy" sammy := "sammy" alsoSammy := "Sammy" fmt.Println("Sammy == sammy: ", Sammy == sammy) fmt.Println("Sammy == alsoSammy", Sammy == alsoSammy) يكون الخرج كما يلي: Sammy == sammy: false Sammy == alsoSammy true لاحظ أنه عندما قارنا كلمة Sammy بكلمة sammy كان الخرج false؛ أما عندما قارنّا كلمة Sammy مع Sammy كان الخرج true، وبالتالي كما ذكرنا تكون مقارنة السلاسل النصية حساسةً لحالة المحارف. يمكنك أيضًا استخدام عوامل المقارنة الأخرى، مثل > و < لمقارنة السلاسل، وفي هذه الحالة ستقارن جو هذه السلاسل اعتمادًا على الترتيب المُعجمي lexicographically اعتمادًا على قيم ASCII للمحارف، كما يمكنك أيضًا تقييم القيم المنطقية باستخدام عوامل المقارنة، إذ سنختبر في المثال التالي فيما إذا كان المتغير المنطقي t الذي يحمل القيمة true لايساوي المتغير المنطقي f الذي يحمل القيمة false. t := true f := false fmt.Println("t != f: ", t != f) يكون الخرج كما يلي: t != f: true انتبه إلى أن العامِل = يختلف عن العامِل ==، إذ يُستخدَم الأول لعمليات الإسناد والثاني للاختبار المساواة، ويوضح المثال التالي الفرق، ففي الحالة الأولى نُسند قيمة y إلى x وفي السطر التالي نختبر مساواة x مع y. x = y // إسناد قيمة المتغير اليميني إلى المتغير اليساري x == y // تقييم نتيجة المساواة بين المتغيرين العوامل المنطقية يوجد نوعان من العوامل المنطقية في الجبر المنطقي والمستخدَمان لتحديد العلاقة بين المتغيرات هما and و or، إضافةً إلى عامل النفي not، إذ يرمَز في لغة جو للعامل المنطقي and بالرمز && وللعامل or بالرمز || وللعامل not بالرمز ! كما يلي: x && y تعني أنه إذا كان كل من x و y مٌحققان أي كلاهما true، فسيكون الناتج true وإلا فسيكون false. x || y تعني أنه إذا كان أحدهما true، فسيكون الناتج true. x! تعني أنه إذا كانت x قيمتها true، فسيكون الخرج false، وإذا كانت false فسيكون الخرج true. كثيرًا ماتُستخدَم هذه العوامل في البرمجة ولا سيما عند محاولة اختبار تعابير متعددة أو شروط متعددة، فإذا كنت مثلًا تبني برنامجًا يُحدِّد فيما إذا كان الطالب ناجحًا أم لا في إحدى المواد الجامعية، فيجب أن يكون الطالب قد حضر 4 جلسات عمليّة على الأقل x، ويجب أن يحصل على 40% من درجة الامتحان العملي على الأقل y و60% من درجة الامتحان (النظري + العملي) على الأقل z، أي لدينا 3 متغيرات x y z ويجب أن تتحقق كلها، أي x && y && z، ولنرى مثالًا عن استخدام هذه العوامل كما يلي: fmt.Println((9 > 7) && (2 < 4)) // التعبيران محققان fmt.Println((8 == 8) || (6 != 6)) // التعبير الأول صحيح فقط fmt.Println(!(3 <= 1)) // التعبير خاطئ، لكن مع النفي يصبح صحيح يكون الخرج كما يلي: true true true لدينا في السطر الأول ((fmt.Println((9 > 7) && (2 < 4، نلاحظ أنّ 9 أكبر من 7 و 2 أصغر من 4، وبالتالي فإن طرفَي العلاقة محققان، وبالتالي سيطبع true، وفي السطر الثاني ((fmt.Println((8 == ? || (6 != 6 نلاحظ أنّ 8 تساوي 8 مُحققة، لكن 6 لا تساوي 6 غير مُحققة ولكن مع ذلك سيطبع true، لأنه في حالة العامل المنطقي || يكفي أن يكون أحد طرفَي العلاقة محققًا؛ أما في السطر الأخير ((fmt.Println(!(3 <= 1، فنلاحظ أنّ 1=<3 تقييمها false، لكن بما أننا نستخدِم معامل النفي، فسيكون الخرج هو الحالة المعاكسة، أي true. لا يختلف المثال التالي عما سبق إلا في نوع البيانات، إذ سنستخدِم نوع البيانات العشرية بدل الصحيحة: fmt.Println((-0.2 > 1.4) && (0.8 < 3.1)) // تعبير واحد فقط صحيح fmt.Println((7.5 == 8.9) || (9.2 != 9.2)) // التعبيران خاطئان fmt.Println(!(-5.7 <= 0.3)) // التعبير صحيح ولكن يصبح مع النفي خاطئًا يمكنك أيضًا كتابة تعليمات مركبة باستخدام && و || و !: !((-0.2 > 1.4) && ((0.8 < 3.1) || (0.1 == 0.1))) يكون الخرج كما يلي: true نلاحظ أن نتيجة التركيب (0.8 < 3.1) || (0.1 == 0.1) هي true فكلا الطرفَين محققَين، لكن نلاحظ أنّ الطرف (-0.2 > 1.4) غير محقق، أي تقييمه false، وبالتالي سيكون خرج التركيب السابق بأكمله هو false، وبما أنه لدينا إشارة النفي، فسيكون الخرج هو true. أي باختصار، العوامل المنطقية && و || و ! تقيم تعبيرات ثم تعيد قيمة منطقية ناتجة عن تقييمها. جداول الحقيقة لتعزيز قدراتك البرمجية لا بدّ أن يكون لديك القليل من الفهم عن الفرع المنطقي للرياضيات، وفيما يلي جداول الحقيقة لعامل المقارنة ==، ولكل من العوامل المنطقية &&، || و !. ويفضل أن تحفظها، لتصبح راسخة في ذهنك إذ ستسرع من عملية اتخاذ القرار البرمجي لديك: جدول الحقيقة لعامِل المقارنة ==: x == y الخرج true == true true true == false false false == true false false == false true جدول الحقيقة للعامِل المنطقي and أو &&: x and y الخرج true and true true true and false false false and true false false and false false جدول الحقيقة للعامِل المنطقي or أو ||: x or y الخرج true or true true true or false true false or true true false or false false جدول الحقيقة للعامِل المنطقي not أو !: not x الخرج not false true not true false استخدام العوامل المنطقية للتحكم بسير عمل البرنامج يمكنك استخدام العوامل المنطقية أو عوامل المقارنة للتحكم بسير عمل البرنامج من خلال استخدامها مع جمل الشرط if .. else، فعند تحقق شرط ما يتخذ البرنامج إجراءً محددًا استجابةً لذلك عند تلك النقطة، أي إذا تحقق هذا افعل هذا وإلا لا تفعل وتابع فيما كنت تفعله، ويوضح المثال التالي هذا الأمر: if grade >= 65 { // شرط Condition fmt.Println("Passing grade") // بند Clause } else { fmt.Println("Failing grade") } المقصود من الشيفرة أنه إذا كانت درجة الطالب أكبر أوتساوي 65، فاطبع أنه ناجح، وإلا اطبع أنه راسب، أي إذا كانت درجة الطالب 83 مثلًا، فسيطبع Passing grade وإذا كانت 59 سيطبع Failing grade. الخاتمة استعرضنا في هذا المقال العوامِل المنطقية وعوامل المقارنة التي تُستخدم في الجبر المنطقي وفي العديد من التطبيقات في عالم البرمجة، كما تعرّفنا أيضًا على جداول الحقيقة وأظهرنا كيفية استخدام العوامل المنطقية وعوامل المقارنة في التحكم في سير عمل البرنامج. ترجمة -وبتصرُّف- للمقال Understanding Boolean Logic inGo لصاحبه Gopher Guides. اقرأ أيضًا المقال السابق: العمليات الحسابية في لغة جو Go استخدام المتغيرات والثوابت في لغة جو Go التعامل مع السلاسل في لغة جو Go تحويل أنواع البيانات في لغة جو Go
  7. تُعَدّ الأعداد شائعةً في البرمجة، إذ تُستخدَم لتمثيل أشياء مثل أبعاد حجم الشاشة والمواقع الجغرافية والمال والنقاط ومقدار الوقت الذي مضى في الفيديو ومواضع الصور ضمن الألعاب والألوان من خلال ربطها مع الأرقام …إلخ، كما يرتبط الأداء الفعال في العديد من البرامج ارتباطًا وثيقًا بكيفية إنجاز العمليات الحسابية، لذا تُعَدّ أمرًا مهمًا عليك إتقانه، كما ستجعل منك براعتك في الرياضيات مبرمجًا أفضل لكنها ليست شرطًا أساسيًا، فإذا لم يكن لديك خلفية في الرياضيات، فحاول التفكير في الرياضيات بوصفها أداةً لتحقيق ما ترغب في تحقيقه وطريقةً لتحسين تفكيرك المنطقي. سنعمل مع أهم نوعين من الأعداد المستخَدمة في لغة جو وهما الأعداد الصحيحة والعشرية: الأعداد الصحيحة: هي أعداد سالبة أو موجبة مثل 1, 0, 1-, … إلخ. الأعداد العشرية هي التي تحتوي فواصل عشرية مثل 9.0, 2.25-, … إلخ. العوامل الرياضية العامل operator هو رمز يمثل عملية وغالبًا ما تكون عملية رياضية، فمثلًا العامل + يمثل عملية الجمع الرياضية. نستعرض في الجدول التالي أهم العوامل المستخدَمة في لغة جو والتي سنتطرق لها في هذا المقال، ويمكنك ملاحظة أنّ أغلب هذه العوامل مألوفة لديك من خلال دراستك للرياضيات وبعضها غير مألوف. 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; } العملية الوظيفة x + y جمع العددين x و y -------- -------- x - y طرح العددين x و y -------- -------- x * y ضرب العددين x و y -------- -------- x / y قسمة العددين x و y -------- -------- x % y باقي قسمة x على y -------- -------- x+ ضرب قيمة المتغير بالعدد +1 -------- -------- x- ضرب قيمة المتغير بالعدد -1 سيغطي المقال أيضًا العوامل المركبة التي تكون إحدى مركباتها عامل حسابي مع إشارة اليساوي مثل =+ و =*. الجمع والطرح يمكنك إنجاز عمليات الجمع والطرح في لغة جو تمامًا مثل استخدامك للآلة الحاسبة كما في المثال التالي من أجل الأعداد الصحيحة: fmt.Println(1 + 5) يكون الخرج كما يلي: 6 يمكنك تهيئة متغيرات تُخزّن تلك القيم ثم تطبع نتيجة جمعها بدلًا من تمرير الأعداد مباشرةً إلى دالة الطباعة: a := 88 b := 103 fmt.Println(a + b) يكون الخرج كما يلي: 191 قد يكون العدد الصحيح سالبًا، ففي هذه الحالة نضع إشارة سالب قبله بكل بساطة كما يلي: c := -36 d := 25 fmt.Println(c + d) يكون الخرج كما يلي: -11 الأمر نفسه بالنسبة للأعداد العشرية، إذ يمكنك إنجاز عمليات الجمع كما في المثال التالي: e := 5.5 f := 2.5 fmt.Println(e + f) يكون الخرج كما يلي: 8 لاحظ أن الناتج هو عدد بدون فاصلة عشرية، إذ منوقع أنّ الخرج يحتوي على فاصلة عشرية بما أنّ عملية الجمع بين عددين عشريين أي 8.0، والسبب في ذلك هو أن دالة الطباعة تحوِّل الخرج تلقائيًا إلى قيمة صحيحة من خلال إسقاط الفواصل العشرية، ولتجنب حدوث ذلك نستخدِم العنصر النائب 2f.%، إذ تشير f إلى وجود عدد حقيقي و2 إلى إبقاء عددين بعد الفاصلة. fmt.Printf("%.2f", e + f) يكون الخرج كما يلي: 8.00 عملية الطرح نفسها كما في الجمع مع استبدال العامل + بالعامل -: g := 75.67 h := 32.0 fmt.Println(g - h) يكون الخرج كما يلي: 43.67 لا يمكنك في لغة جو إنجاز عملية حسابية بين عددين من نوعي بيانات مختلفين مثل int و float64 كما في المثال التالي: i := 7 j := 7.0 fmt.Println(i + j) سيكون الخرج إشعارًا بعدم تطابق نوعي البيانات كما يلي: i + j (mismatched types int and float64) العمليات الحسابية الأحادية يتكون التعبير الرياضي الأحادي Unary Arithmetic Operation من مكوِّن أو عنصر واحد فقط، إذ يمكننا في لغة جو استخدام علامتَي الجمع والطرح على أساس عنصر أحادي مُقترن بقيمة، ولتبسيط الأمر، يُعَدّ إشارة + أو - تتلو قيمة أو متغير (كأنما نضرب -1 أو +1 بمتغير). ستوضّح الأمثلة أكثر: تشير علامة الجمع على الرغم من عدم استخدامها بصورة شائعة إلى هوية القيمة identity، ويمكننا استخدامها مع القيم الموجبة كما يلي: i := 3.3 fmt.Println(+i) سيكون الخرج كما يلي: 3.3 عند استخدام إشارة الجمع مع عدد سالب، فلن تتغير إشارة هذا العدد، أي سيبقى سالبًا كما يلي: j := -19 fmt.Println(+j) يكون الخرج كما يلي: -19 هنا المتغير موجب، ثم في دالة الطباعة اسبقناه بالإشارة -، وبالتالي تتبدّل إشارته من موجب إلى سالب: k := 3.3 fmt.Println(-k) يكون الخرج كما يلي: 3.3- وبصورة بديلة عند استخدام العامل الأحادي سالب الإشارة مع قيمة سالبة كما يلي: j := -19 fmt.Println(-j) سيكون الخرج كما يلي: 19 الهدف من استخدام العملية الأحادية + والعملية الأحادية - هو إعادة هوية القيمة أو الإشارة المعاكسة لقيمة. الضرب والقسمة كما فعلنا في عمليات الجمع والطرح، لكن نستخدِم هنا عوامل مختلفة هي * للضرب و / للقسمة، وفيما يلي مثال عن عملية الضرب بين عددين عشريين: k := 100.2 l := 10.2 fmt.Println(k * l) يكون الخرج كما يلي: 1022.04 بالنسبة للقسمة يجب عليك معرفة أنّ الناتج قد يختلف تبعًا لنوع البيانات المختلفة، ففي حال قسّمت أعدادًا صحيحةً، فسيكون ناتج القسمة عددًا صحيحًا أيضًا، إذ ستُسقط أية فواصل عشرية إذا وجدت. سنقسّم في المثال التالي عددين صحيحين 80/6 كما يلي: package main import ( "fmt" ) func main() { m := 80 n := 6 fmt.Println(m / n) } سيكون الخرج كما يلي: 13 لاحظ إسقاط الفاصلة العشرية من الخرج، فإذا أردت إبقاء الأعداد بعد الفاصلة، فعليك استخدام النوع العشري مع هذه البيانات عبر تحويلها باستخدام float32()‎ أو float64()‎: package main import ( "fmt" ) func main() { s := 80 t := 6 r := float64(s) / float64(t) fmt.Println(r) سيكون الخرج كما يلي: 13.333333333333334 باقي القسمة يمكنك إيجاد باقي قسمة عدد على عدد آخر من خلال العامل %، وهذا مفيد جدًا في الكثير من الحالات مثل إيجاد مضاعفات الأعداد، فلنلق نظرةً على المثال التالي: o := 85 p := 15 fmt.Println(o % p) سيكون الخرج كما يلي: 10 ناتج قسمة 85 على 15 هو 55 والباقي 10، لذا سيُخرج البرنامج العدد 10، وإذا أردت إيجاد باقي القسمة في حالة الأعداد العشرية، فيمكنك استخدام الدالة ()Mod من الحزمة math: package main import ( "fmt" "math" ) func main() { q := 36.0 r := 8.0 s := math.Mod(q, r) fmt.Println(s) } سيكون الخرج كما يلي: 4 ترتيب العمليات الحسابية كما في الرياضيات، علينا أن نضع في الحسبان أن العوامل تُطبّق حسب الأولوية وليس من اليسار إلى اليمين أو من اليمين إلى اليسار، فإذا نظرت إلى التعبير الرياضي التالي: u = 10 + 10 * 5 هنا يُطبق الضرب أولًا ثم ناتج الضرب 50 يُجمع مع 10 لأن الأولوية للضرب على الجمع أو الطرح ويكون الخرج كما يلي: 60 استخدم الأقواس إذا أردت مثلًا جمع 10 مع 10 أولًا لأن ما بين الأقواس له الأولوية على ما هو خارجها، أي كما يلي: u := (10 + 10) * 5 fmt.Println(u) سيكون الخرج كما يلي: 100 ترتيب إجراء العمليات الحسابية هو كما يلي: الأقواس Parentheses > الأس Exponent> الضرب Multiplication> القسمة Division> الجمع Addition> الطرح Subtraction. ويمكن اختصار أوائل كلمات تلك العمليات بالبيت التالي: "قم أبعد ضيقًا … قم جد طريقًا". عوامل الإسناد من المألوف لديك استخدام عامل المساواة = لإسناد قيمة إلى متغير مثل إسناد القيمة 10 إلى المتغير x بكتابة x=10، كما يمكنك جعل الأمر أكثر إثارةً من خلال إدخال العمليات الحسابية إلى هذه المعادلة، إذ يمكنك استخدام العامل + أو - أو * أو / مع العامل السابق لتطبيق عمليات حسابية محددة، فإذا كان لديك مثلًا متغير x قيمته 5 وأردت جعل قيمته 7، فيمكنك كتابة x += 2 وهذا يكافئ كتابة x = x+2، وبالتالي تصبح قيمة x تساوي 7، أو يمكنك ضرب قيمة x بالقيمة 3 من خلال كتابة x *= 3 وهذا يكافئ x = x*3 أو يمكنك استخدام عامل باقي القسمة أيضًا x %= 2 والذي يكافئ x = x%2 وهكذا بالنسبة لباقي العمليات، ويوضّح المثال التالي الأمر أكثر: w := 5 w += 1 fmt.Println(w) يكون الخرج كما يلي: 6 تُستخدَم عوامل الإسناد المركبة كثيرًا في حالة حلقات for والتي ستستخدِمها عندما تريد تكرار عملية عدة مرات كما في المثال التالي: package main import "fmt" func main() { values := []int{0, 1, 2, 3, 4, 5, 6} for _, x := range values { w := x w *= 2 fmt.Println(w) } } يكون الخرج كما يلي: 0 2 4 6 8 10 12 استخدمنا حلقة for في المثال أعلاه للتكرار على الشريحة values، إذ هيّأنا المتغير w في كل تكرار بقيمة x الحالية ثم ضربناها بالقيمة 2 وطبعنا الخرج. تمتلك لغة جو عامل إسناد مركب لكل عامل رياضي، وقد ناقشنا ذلك في هذا المقال، فلإضافة 1 إلى المتغير نفسه ثم إسناد القيمة الجديدة للمتغير نفسه، نكتب ما يلي والتي تكافئ y=y+1: y += 1 طرح 1 ثم إسناد: y -= 1 ضرب بالعدد 2 ثم إسناد: y *= 2 قسمة على العدد 3 ثم إسناد: y /= 3 باقي قسمة المتغير على العدد 3 ثم إسناد: y %= 3 تُعَدّ عوامل الإسناد المركبة مفيدةً عندما تحتاج إلى زيادة أو تقليل قيمة المتغيرات تدريجيًا أو عندما تحتاج إلى أتمتة عمليات معينة في برنامجك. الخاتمة ناقشنا في هذا المقال العديد من العوامل التي يمكنك استخدامها في لغة جو مع أنواع البيانات العددية الصحيحة والعشرية، كما يمكنك الاطلاع على المقالات السابقة من سلسلة البرمجة بلغة Go لمزيد من التفاصيل عن المتغيرات والتعامل مع البيانات في لغة جو. ترجمة -وبتصرف- للمقال How To Do Math in GowithOperators لصاحبه Gopher Guides. اقرأ أيضًا المقال السابق: تحويل أنواع البيانات في لغة جو Go استخدام المتغيرات والثوابت في لغة جو Go التعامل مع السلاسل في لغة جو Go
  8. تُستخدَم أنواع البيانات في لغة جو للإشارة إلى نوع معيَّن من البيانات وتحديد القيم التي يمكنك إسنادها لذلك النوع والعمليات التي يمكنك إجراؤها عليها، فهناك أوقات نحتاج إلى تحويل القيم من نوع إلى آخر لمعالجتها بطريقة مختلفة، فقد نحتاج مثلًا إلى وصل القيم العددية بالسلاسل النصية أو إظهار الفواصل العشرية لأعداد صحيحة، وغالبًا ما تُعامَل البيانات التي يُدخلها المستخدِم في جو على أنها سلاسل نصية، حتى إذا تضمنت أعدادًا، وبالتالي يتوجب عليك تحويلها إلى بيانات عددية إذا أردت إدخالها في عمليات حسابية. تُعَدّ جو لغةً ثابتةً تتطّلب تحديد النوع statically typed language، لذا تكون أنواع البيانات مرتبطةً بالمتغيرات وليس بالقيم، أي في حال كان لديك متغير من النوع int، فلا يمكن أن يُسنَد إليه متغير من نوع آخر، وسيرشدك هذا المقال إلى كيفية تحويل الأعداد والسلاسل النصية، بالإضافة إلى تقديم بعض الأمثلة التوضيحية. تحويل الأنواع العددية هناك نوعان رئيسيان من البيانات العددية في جو وهما الأعداد الصحيحة والأعداد العشرية. ستعمل في بعض الأحيان على شيفرة برمجية كتبها شخص آخر، وقد تحتاج إلى تحويل عدد صحيح إلى عدد عشري أو العكس، أو قد تجد أنك تستخدم عددًا صحيحًا في الوقت الذي تحتاج إلى أعداد عشرية، لذلك تتوفر في جو توابع مضمّنة تُسهِّل عليك التحويل بين الأنواع العددية. التحويل بين أنواع الأعداد الصحيحة تتضمن جو العديد من أنواع البيانات الصحيحة التي يمكنك التبديل بينها حسب الحاجة ومتطلبات الأداء أو لأسباب أخرى، فيُنشئ جو في بعض الأحيان مثلًا قيمًا عدديةً من النوع int تلقائيًا، وبالتالي في حال أدخلت أعدادًا من النوع int64، فلن تتمكن استخدام العدد السابق الذي ولدته جو مع العدد الذي أدخلته ضمن تعبير رياضي واحد لأنهما من نوعين مختلفين. افترض أنه لديك متغير من النوع int8 وتحتاج إلى تحويله إلى int32، فيمكنك إجراء ذلك عن طريق استخدام الدالة int32()‎: var index int8 = 15 var bigIndex int32 bigIndex = int32(index) fmt.Println(bigIndex) يكون الخرج كما يلي: 15 عرّفنا متغير index من النوع int8 ومتغير bigIndex من النوع int32 ثم حوّلنا نوع المتغير index إلى النوع int32 وخزّنا النتيجة في المتغير bigIndex ثم طبعنا قيمته، وللتأكد من عملية التحويل أو لتفقّد نوع البيانات لأحد المتغيرات، استخدم العنصر النائب T% مع دالة الطباعة fmt.Printf كما يلي: fmt.Printf("index data type: %T\n", index) fmt.Printf("bigIndex data type: %T\n", bigIndex) يكون الخرج كما يلي: index data type: int8 bigIndex data type: int32 لاحظ أنه يطبع نوع البيانات للمتغير وليس قيمته. يمكنك أيضًا التحويل من نوع بيانات كبير إلى نوع أصغر مثل تحويل من int64 إلى int8 كما يلي: var big int64 = 64 var little int8 little = int8(big) fmt.Println(little) يكون الخرج كما يلي: 64 لكن انتبه إلى أنه عند التحويل من نوع أكبر إلى نوع أصغر قد تتجاوز القيمة الأكبر بالقيمة المطلقة التي يمكن لهذا النوع تخزينها، ففي حال تجاوزت القيمة تلك، فستحدث عملية التفاف wraparound كما في المثال التالي: var big int64 = 129 var little = int8(big) fmt.Println(little) يكون الخرج كما يلي: -127 أكبر قيمة يمكن أن يخزنها متغير من النوع int8 هي 127 وأصغر قيمة -127، فإذا تجاوزتها، فسيحدث التفاف، وبما أنّ 129 في المثال السابق أكبر من القيمة العظمى التي يمكن للنوع المحدد تخزينه، فقد حدث التفاف إلى القيمة الأصغر، أي حوّله إلى أصغر قيمة ممكنة فيه. تحويل الأعداد الصحيحة إلى أعداد عشرية الأمر مشابه لعمليات التحويل التي أجريناها منذ قليل، إذ سنستخدِم هنا الدالة float64()‎ أو float32()‎ لإجراء عمليات التحويل: var x int64 = 57 var y float64 = float64(x) fmt.Printf("%.2f\n", y) يكون الخرج كما يلي: 57.00 لاحظ أننا حوّلنا نوع المتغير x ذو القيمة الابتدائية 57 من int64 إلى float64، وبالتالي أصبحت57.00، أخيرًا استخدمنا العنصر النائب ‎%.2f ضمن دالة الطباعة للإشارة إلى عدد عشري مع الإبقاء على رقمين بعد الفاصلة. وبذلك يمكنك استخدام float32()‎ أو float64()‎ لتحويل الأعداد العشرية إلى أعداد صحيحة. تحويل الأعداد العشرية إلى أعداد صحيحة يمكنك تحويل الأعداد العشرية إلى أعداد صحيحة باستخدام الدوال نفسها التي استخدمناها سابقًا عند التحويل بين أنواع الأعداد الصحيحة، ولكن انتبه إلى أنّ تغير النوع من عشري إلى صحيح سيفقدك الأعداد الموجودة بعد الفاصلة (الأجزاء العشرية أي الأرقام التي بعد الفاصلة العشرية)، وبالتالي قد تؤثر على دقة الحالة أو العملية كما في المثال التالي: var f float64 = 390.8 var i int = int(f) fmt.Printf("f = %.2f\n", f) fmt.Printf("i = %d\n", i) يكون الخرج كما يلي: f = 390.80 i = 390 عرّفنا في المثال السابق متغير f من النوع العشري وهيأناه بقيمة 390.8 ثم عرّفنا متغير i من النوع الصحيح وهيّأناه بقيمة المتغيّر f بعد تحويّله إلى النوع الصحيح من خلال الدالة int ثم طبعنا قيمتهما، ولاحظ أنه عندما حوّلنا القيمة 390.8 إلى 390، أُسقطت القيمة الموجودة بعد الفاصلة، وتجدر الملاحظة إلى أنّ جو لا تُقرِّب العدد؛ وإنما تهمل كل الأعداد بعد الفاصلة فقط. ولنأخذ المثال التالي الذي يُعرِّف المتغير b ويعطيه القيمة 125.0 والمتغير c مع القيمة 390.8 ثم يطبعهما على شكل عدد صحيح: b := 125.0 c := 390.8 fmt.Println(int(b)) fmt.Println(int(c)) يكون الخرج كما يلي: 125 390 عند تحويل عدد عشري إلى عدد صحيح باستعمال int()‎، تقتص لغة Go الأعداد العشرية وتبقي على العدد الصحيح فقط، وانتبه أننا قلنا "تقتص" أي أنها تزيل الفواصل العشرية دون إجراء عملية تقريب، فلن يُقرَّب العدد 390.8 إلى 391 بل سيصبح بعد التحويل 390. تحويل الأعداد عبر القسمة تُسقط جو الفواصل إذا وُجِدت أيضًا عند تقسيم على آخر صحيح: a := 5 / 2 fmt.Println(a) يكون الخرج كما يلي: 2 إذا كان أحد الأعداد في عملية القسمة من النوع العشري float، فستُعَدّ كل الأعداد عشريةً وكذلك الناتج كما يلي: a := 5.0 / 2 fmt.Println(a) يكون الخرج كما يلي: 2.5 كما تلاحظ لم تُسقَط الأعداد بعد الفاصلة هذه المرة. تحويلات السلاسل النصية تُعَدّ السلسلة النصية تسلسلًا مؤلفًا من محرف واحد أو أكثر، ويمكن أن يكون المحرف حرفًا أبجديًا أو عددًا أو رمزًا، وتُعَدّ السلاسل النصية إحدى الأشكال الشائعة من البيانات في عالم البرمجة، وقد نحتاج إلى تحويل السلاسل النصية إلى أعداد أو أعداد إلى سلاسل نصية في كثير من الأحيان خاصةً عندما نعمل على البيانات التي ينشئها المستخدِمون. تحويل الأعداد إلى سلاسل نصية يمكن إنجاز ذلك من خلال استخدام التابع strconv.Itoa من إحدى حزم لغة جو القياسية strconv في حزمة جو القياسية. وذلك بتمرير العدد الصحيح أو العشري إلى هذا التابع والذي سيتكفل بإجراء عملية التحويل إلى سلسلة نصية، إذ سنحوّل العدد الصحيح 12 إلى سلسلة نصية في المثال التالي: package main import ( "fmt" "strconv" ) func main() { a := strconv.Itoa(12) fmt.Printf("%q\n", a) } عرّفنا متغير a يُمثّل سلسلة نصية وأسندنا إليه القيمة المُعادة من الدالة strconv.Itoa والتي ستعبّر عن العدد 12 بوصفه سلسلةً نصيةً، ثم استخدمنا دالة الطباعة لإظهار نتيجة التحويل، كما أننا استخدمنا معها العنصر النائب q% لإظهار السلسلة النصية مع علامتي الاقتباس ويكون الخرج كما يلي: "12" تشير علامات الاقتباس حول العدد 12 إلى أنّ العدد الصحيح قد أصبح سلسلةً نصيةً. يمكنك البدء في معرفة مدى إمكانية تحويل الأعداد الصحيحة إلى سلاسل من خلال المتغيرات، ولنفترض أنك تريد تتبع التقدم اليومي في البرمجة للمستخدِم وتريد إدخال عدد سطور التعليمات البرمجية التي يكتبها في كل مرة، كما تريد عرض هذه الملاحظات للمستخدِم مع طباعة قيم السلسلة والأعداد الصحيحة في الوقت نفسه: package main import ( "fmt" ) func main() { user := "Sammy" lines := 50 fmt.Println("Congratulations, " + user + "! You just wrote " + lines + " lines of code.") } سيعطي الخرج الخطأ التالي: invalid operation: ("Congratulations, " + user + "! You just wrote ") +lines (mismatched types string and int) لا يمكنك وصل السلاسل النصية مع الأعداد الصحيحة في جو، لذلك يجب عليك تحويل المتغير lines إلى سلسلة: package main import ( "fmt" "strconv" ) func main() { user := "Sammy" lines := 50 fmt.Println("Congratulations, " + user + "! You just wrote " + strconv.Itoa(lines) + " lines of code.”) } يكون الخرج كما يلي: Congratulations, Sammy! You just wrote 50 lines of code. إذا أردت تحويل عدد عشري إلى سلسلة، فالأمر مشابه لما سبق. استخدم التابع fmt.Sprint من الحزمة fmt من مكتبة جو القياسية، إذ يعيد هذا التابع السلسلة النصية المكافئة للعدد العشري الذي مررته له: package main import ( "fmt" ) func main() { fmt.Println(fmt.Sprint(421.034)) f := 5524.53 fmt.Println(fmt.Sprint(f)) } يكون الخرج كما يلي: 421.034 5524.53 يمكنك إجراء تجربة وصل عدد حقيقي مع سلسلة نصية بعد تحويله إلى سلسلة كما يلي: package main import ( "fmt" ) func main() { f := 5524.53 fmt.Println("Sammy has " + fmt.Sprint(f) + " points.") } يكون الخرج كما يلي: Sammy has 5524.53 points. نجحت عملية التحويل بالفعل والدليل على ذلك أن عملية الوصل نجحت. تحويل السلاسل إلى أعداد يمكن استخدام الحزمة strconv من مكتبة جو القياسية لإنجاز عملية التحويل من سلاسل نصية إلى أعداد صحيحة وعشرية، إذ تحتاج لهكذا عملية تحويل كثيرًا لا سيما عندما تحتاج إلى إدخال البيانات من المستخدِم، فقد تحتاج مثلًا إلى أن يُدخل المستخدِم عمره والذي تُعده جو سلسلةً وليس عددًا، لذا أنت بحاجة إلى تحويله إلى عدد صحيح، فإذا كان العدد المدخل صحيحًا، فاستخدم الدالة strconv.Atoi؛ أما إذا كان عشريًا، فاستخدم الدالة strconv.ParseFloat. سنكمل الآن مع المثال السابق نفسه الذي تحدثنا فيه عن المستخدِم الذي يتتبع سطور التعليمات البرمجية المكتوبة كل يوم، فإذا أردت معالجة تلك القيم رياضيًا لتقديم ملاحظات أكثر تشويقًا للمستخدِم، فستحتاج لتحويلها إلى أعداد أولًا: package main import ( "fmt" ) func main() { lines_yesterday := "50" lines_today := "108" lines_more := lines_today - lines_yesterday fmt.Println(lines_more) } سيتولد الخطأ التالي عند تنفيذ الشيفرة السابقة: invalid operation: lines_today - lines_yesterday (operator - not defined on string) المتغيران اللذان تحاول طرحهما مُمثلان على أساس سلاسل نصية، لذا لا يمكن إجراء حسابات عليهما، وبالتالي سنصلح المشكلة من خلال استخدام التابع strconv.Atoi()‎ لتحويل قيم المتغيرات إلى أعداد صحيحة: package main import ( "fmt" "log" "strconv" ) func main() { lines_yesterday := "50" lines_today := "108" yesterday, err := strconv.Atoi(lines_yesterday) if err != nil { log.Fatal(err) } today, err := strconv.Atoi(lines_today) if err != nil { log.Fatal(err) } lines_more := today - yesterday fmt.Println(lines_more) } استخدمنا if لتجنب توقف البرنامج بسبب حدوث خطأ غير متوقع مثل أن تكون السلسلة التي نرغب بتحويلها ليست عددًا صحيحًا أساسًا أو أنها سلسلة فارغة، ويدلنا على حدوث مثل هذه الأخطاء الدالة strconv.Atoi من خلال إعادة القيمة nil في حال كانت السلسلة الممررة غير ملائمة لعملية التحويل، وبالتالي في حال حدوث خطأ سندخل إلى تعليمة if ثم سنسجّل الخطأ من خلال log.Fatal ونخرج من البرنامج. يكون الخرج كما يلي: 58 إذا حاولت تحويل سلسلة لا تمثّل عددًا صحيحًا: package main import ( "fmt" "strconv" ) func main() { a := "not a number" b, err := strconv.Atoi(a) fmt.Println(b) fmt.Println(err) } فستحصل على الخطأ التالي: 0 strconv.Atoi: parsing "not a number": invalid syntax لم تُسنَد قيمة إلى المتغير b نظرًا لفشل الدالة strconv.Atoi في إجراء التحويل على الرغم من أنه قد صُرِّح عن b، ولاحظ أنّ قيمة b تساوي 0، وذلك لأنّ جو لديها قيم افتراضية يُشار إليها بالقيم الصفرية في جو، كما توفر strconv.Atoi خطأً يصف سبب فشل تحويل السلسلة النصية أيضًا. التحويل بين السلاسل والبايتات تُخزّن السلاسل النصية في جو على هيئة شريحة من البايتات، ويمكنك التحويل من سلسلة إلى شريحة من البايت أو العكس من خلال الدوال ()byte[] و ()string: package main import ( "fmt" ) func main() { a := "my string" b := []byte(a) c := string(b) fmt.Println(a) fmt.Println(b) fmt.Println(c) } خزّنتَ هنا سلسلةً في المتغير a ثم حوّلتها إلى شريحة من البايتات b ثم حوّلتها إلى سلسلة c من جديد، وبعد ذلك طبعتَ a و b و c على الشاشة، ويكون الخرج كما يلي: my string [109 121 32 115 116 114 105 110 103] my string يمثِّل السطر الأول السلسلة النصية الأصلية ويمثِّل السطر الثاني السلسلة النصية بعد تحويلها إلى شريحة من البايتات؛ أما السطر الثالث، فيُظهر أمان عملية التحويل من وإلى شريحة بايتات. الخاتمة وضحنا في هذا المقال كيفية تحويل العديد من أنواع البيانات الأصلية المهمة إلى أنواع بيانات أخرى باستخدام التوابع المُضمّنة، إذ يوفِّر لك تحويل أنواع البيانات في جو مرونةً إضافيةً في مشاريعك البرمجية. ترجمة -وبتصرف- للمقال How To Convert Data Types inGo لصاحبه Gopher Guides. اقرأ أيضًا المقال السابق: استخدام المتغيرات والثوابت في لغة جو Go مقدمة عن المصفوفات Arrays والشرائح Slices الخاصة بلغة Go 3 طرائق لنسخ الملفات في Go
  9. تُعَدّ المتغيرات مفهومًا برمجيًا مهمًا يتوجّب عليك فهمه وإتقانه، فهي رموز تدل على القيم التي تستخدِمها في برنامجك، وسنتحدّث في هذا المقال عن أساسيات المتغيرات وأفضل الممارسات عند التعامل معها. فهم المتغيرات تُخصَّص للمتغير من الناحية الفنية مساحة تخزينية في الذاكرة توضَع القيمة المرتبطة به فيها، ويُستخدَم اسم المتغير للإشارة إلى تلك القيمة المُخزَّنة في ذاكرة البرنامج والتي هي جزء من ذاكرة الحاسوب، ويشبه المُتغيِّر بأنه عنوان تُعلِّقه على قيمة مُعيَّنة كما في الصورة التالية، إذ تشير variable name إلى اسم المتغير وvalue إلى قيمته: لنفترض أنه لدينا عددًا صحيحًا يساوي 1032049348 ونريد تخزينه في متغيِّر بدلًا من إعادة كتابة هذا العدد الطويل كل مرة، لذلك سنستخدِم شيئًا يُسهِّل تذكّره مثل المتغير i، i := 1032049348 إذا نظرنا إليه على أنَّه عنوانٌ مرتبط بقيمة، فسيبدو على النحو التالي: يمثّل i اسم المتغير وتُربَط به القيمة 1032049348 التي هي من نوع عدد صحيح integer، كما تُعَدّ العبارة i := 1032049348 أنها تعليمة إسناد وتتألف من الأجزاء التالية: اسم المتغير i. معامِل تعريف المتغير المختصر =:. القيمة التي أُسنِدَت إلى المتغير 1032049348. نوع البيانات تكتشفه اللغة تلقائيًا. تُسند القيمة السابقة من خلال هذه الأجزاء إلى المتغير i، ونكون عند تحديد قيمة المتغير قد هيّئنا أو أنشأنا ذلك المتغير، وبعد ذلك يمكنك استخدام ذلك المتغير بدلًا من القيمة كما في المثال التالي: package main import "fmt" func main() { i := 1032049348 fmt.Println(i) } ويكون الخرج كما يلي: 1032049348 يسهل استخدام المتغيرات علينا إجراء العمليات الحسابية، إذ سنعتمد في المثال التالي على التعليمة السابقة i = 1032049348 وسنطرح من المتغير i القيمة 813 كما يلي: fmt.Println(i - 813) ويكون الخرج كما يلي: 1032048535 يُجري جو Go العملية الحسابية ويطرح 813 من المتغير i ويعيد القيمة 1032048535. يمكن ضبط المتغيرات وجعلها تساوي ناتج عملية حسابية ما، إذ سنجمع الآن عددين معًا ونخزِّن قيمة المجموع في المتغير x: x := 76 + 145 يشبه المثال أعلاه إحدى المعادلات التي تراها في كتب الجبر، إذ تُستخدَم المحارف والرموز لتمثيل الأعداد والكميات داخل الصيغ والمعادلات، وبصورة مماثلة تُعَدّ المتغيرات أسماءً رمزيةً تمثِّل قيمةً من نوع بيانات معيّن، والفرق في لغة جو أنه عليك التأكد دائمًا من كتابة المتغير على الجانب الأيسر من المعادلة، ولنطبع الآن x كما يلي: package main import "fmt" func main() { x := 76 + 145 fmt.Println(x) } يكون الخرج كما يلي: 221 أعادت جو القيمة 221 لأنه قد أُسنِد إلى المتغير x مجموع العددين 76 و 145، كما يمكن أن تمثل المتغيرات أيّ نوع بيانات وليس الأعداد الصحيحة فقط كما يلي: s := "Hello, World!" f := 45.06 b := 5 > 9 // ستُرجع قيمة منطقية، إما صواب أو خطأ array := [4]string{"item_1", "item_2", "item_3", "item_4"} slice := []string{"one", "two", "three"} m := map[string]string{"letter": "g", "number": "seven", "symbol": "&"} فإذا طبعت أيًّا من المتغيرات المذكورة أعلاه، فستعيد جو قيمة المتغير، ففي الشيفرة التالية مثلًا سنطبع متغيرًا يمثّل شريحة slice من سلسلة نصية: package main import "fmt" func main() { slice := []string{"one", "two", "three"} fmt.Println(slice) } يكون الخرج كما يلي: [one two three] لقد حددنا الشريحة ‎[]string{"one", "two", "three"}‎ إلى المتغير slice ثم استخدمنا دالة الطباعة fmt.Println لطباعتها. تأخذ المتغيرات مساحةً صغيرةً من ذاكرة الحاسوب لتسمح لك بوضع القيم في تلك المساحة. التصريح عن المتغيرات هناك عدة طرق للتصريح عن متغير في جو، فيمكن التصريح عن متغير يسمى i من نوع البيانات int بدون تهيئة، أي بدون قيمة أوليّة كما يلي: var i int يمكن تهيئة المتغير من خلال استخدام المعامِل = كما يلي: var i int = 1 يُطلق على كل من هذين النموذجين للتصريح بالتصريح الطويل للمتغيرات long variable declaration، في حين يمثِّل النوذج التالي الأسلوب القصير أو المختصر short variable declaration: i := 1 في هذه الحالة نحن لانحدد نوع البيانات ولانستخدِم الكلمة المفتاحية var، حيث يستنتج جو الصنف تلقائيًّا. تبنى مجتمع جو المصطلحات التالية من خلال الطرق الثلاث للتصريح عن المتغيرات: استخدِم النموذج الطويل var i int عندما لا تُهيئ المتغير فقط. استخدِم النموذج المختصر i := 1، عند التصريح والتهيئة. إذا لم تكن ترغب في أن يستنتج جو نوع البيانات الخاصة بك، ولكنك لا تزال ترغب في استخدام تصريح قصير للمتغير، فيمكنك تمرير القيمة إلى باني نوع البيانات الذي تريده كما يلي: i := int64(1) في حين لا يُعَدّ استخدام النموذج الطويل التالي من المصطلحات الشائعة في جو: var i int = 1 يُعَدّ اتباع الطريقة التي يحدد فيها مجتمع جو عادات التصريح عن المتغيرات من الممارسات الجيدة، وذلك حتى يتمكن الآخرون من قراءة برامجك بسلاسة. القيم الصفرية Zero Values تأخذ أنواع البيانات المُعرّفة ضمن جو قيمًا صفرية على أساس قيمة أوليّة في حال لم تحدَّد لها قيمة أولية كما في المثال التالي: package main import "fmt" func main() { var a int var b string var c float64 var d bool fmt.Printf("var a %T = %+v\n", a, a) fmt.Printf("var b %T = %q\n", b, b) fmt.Printf("var c %T = %+v\n", c, c) fmt.Printf("var d %T = %+v\n\n", d, d) } يكون الخرج كما يلي: var a int = 0 var b string = "" var c float64 = 0 var d bool = false يُستخدم الرمز T% داخل الدالة fmt.Printf لطباعة نوع بيانات المتغير. لاحظ أن القيمة الصفرية المقابلة للسلاسل النصية تمثّلها السلسلة "" والقيمة الصفرية للبيانات المنطقية bool تمثّلها القيمة false. هذا مهم ففي بعض اللغات توضع قيم عشوائية للمتغيرات في حال لم تُهيئ بقيمة أولية، وبالتالي قد نرى أن متغيرًا منطقيًا يأخذ القيمة None أو شيء آخر، وهذا يُنتج عدم اتساقية للبيانات، فالصنف bool لا يمكن أن يكون إلا 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; } صالح غير صالح التفسير user-Name userName غير مسموح استخدام الواصلات Hyphens 4i i4 لا يمكن البدء برقم user user$ لا يمكن استخدام أيّ رمز غير الشرطة السفلية user Name userName لا ينبغي للمتغير أن يتكون من أكثر من كلمة واحدة من الأمور التي يجب أخذها في الحسبان عند تسمية المتغيرات هو أنَّها حساسة لحالة المحارف، وهذا يعني أنَّ my_int و MY_INT و My_Int و mY_iNt كلها مختلفة، أي ينبغي أن تتجنب استخدام أسماء متغيرات متماثلة لضمان ألا يحدث خلط عندك أو عند المتعاونين معك حاليًا أو في المستقبل، كما أنّ حالة المحرف الأول من المتغير لها معنى خاص في جو، فإذا بدأ المتغير بمحرف كبير، فيمكن الوصول إلى هذا المتغير من خارج الحزمة التي أُعلن عنه فيها؛ أما إذا بدأ المتغير بمحرف صغير، فهو متاح فقط داخل الحزمة التي أُعلن عنه فيها كما في المثال التالي: var Email string var password string يبدأ هنا اسم المتغير Email بمحرف كبير، وبالتالي يمكن الوصول إليه بواسطة حزم أخرى، في حين يبدأ المتغير password بمحرف صغير ولا يمكن الوصول إليه إلا داخل الحزمة الُمعلن عنه فيها. من الشائع في جو استخدام أسماء متغيرات مختَصرة جدًا أو قصيرة، إذ يُفضّل كتابة user بدلًا من كتابة userName، كما يلعب النطاق Scope دورًا في اختصار اسم المتغير، فكلما كان نطاق المتغير أصغر، كلما كان اسم المتغير أصغر: names := []string{"Mary", "John", "Bob", "Anna"} for i, n := range names { fmt.Printf("index: %d = %q\n", i, n) } عند استخدام المتغيرات نفسها في أماكن مختلفة من البرنامج، يُفضّل إعطاءها أسماء واضحة لكي لا يربك ذلك الأشخاص الآخرين الذين يقرأون شيفرة البرنامج، لكن في المثال أعلاه استخدمنا المتغيرين i و n لأننا نستخدِمهما مرةً واحدةً فقط ومباشرةً، لذا لن يسبب ذلك أيّ مشكلة في قراءة أو فهم الشيفرة. يُفضّل عند تسمية المتغيرات استخدام تنسيق سنام الجَمل camelCase أو سنام الجمل المرتفع CamelCase عند كتابة المتغيرات بدلًا من استعمال الشرطة السفلية multi_word أو العادية multi-word. الجدول التالي يتضمن بعض الملاحظات المفيدة: شائع غير شائع التفسير user_name userName الشرطات السفلية غير شائعة الاستخدام index i لا يُفضّل استخدام الاسم الكامل وإنما الاسم المختَصر serveHttp serveHTTP يجب كتابة الاختصارات بمحارف كبيرة الخيار الأهم الذي عليك التمسك به هو الاتساق، فإذا بدأت العمل في مشروع يستخدِم تنسيق سنام الجَمل في تسمية المتغيرات، فمن الأفضل الاستمرار في استخدام ذلك التنسيق. إعادة إسناد قيم للمتغيرات Reassigning يمكن تغيير قيم المتغيرات في جو بسهولة كما تشير كلمة "متغير"، وهذا يعني أنه يمكنك إسناد قيمة مختلفة إلى متغير قد أُسنِدَت له قيمة مسبقًا بسهولة بالغة، إذ تُعَدّ القدرة على إعادة الإسناد مفيدةً للغاية، فقد تحتاج مثلًا خلال أطوار برنامجك إلى استلام قيم جديدة من المستخدِم وإسنادها إلى متغير قد حُدّدَت قيمته سابقًا أو قد تحتاج إلى تغيير قيمة متغير اعتمادًا على أحداث معينة، كما أنّ سهولة إعادة إسناد قيم المتغيرات مفيدة أيضًا في البرامج الكبيرة التي قد تحتاج خلالها إلى تغيير القيم باستمرار. سنُسّند إلى المتغير i الذي نوعه int العدد 76 ثم نعيد إسناده بالقيمة 42: package main import "fmt" func main() { i := 76 fmt.Println(i) i = 42 fmt.Println(i) } يكون الخرج كما يلي: 76 42 يوضِّح المثال أنه يمكننا تعريف متغير وإسناد قيمة له ثم تغيير قيمته بإعادة إسناد قيمة أخرى له ما بسهولة من خلال استخدام معامل الإسناد =. ملاحظة: لاحظ أننا نستخدِم المعامِل =: عند التهيئة والتصريح عن متغير والمعامِل = عند إعادة الإسناد (تعديل قيمة المتغير)، وبالتالي لايمكنك استخدام المعامل =: بدلًا من = عند تغيير قيمة المتغير. بما أنّ لغة جو هي لغة تحتاج إلى تحديد النوع typed language، فعند إسناد قيمة جديدة إلى متغير يجب أن تكون هذه القيمة من نوع بيانات المتغير، فلا يمكن مثلًا إسناد قيمة تُمثّل عددًا صحيحًا إلى متغير من نوع سلسلة نصيّة أو العكس، فإذا حاولت فعل ذلك: i := 72 i = "Sammy" فستحصل على الخرج التالي الذي يُمثّل خطأً، والذي يخبرك فيه بأن مثل هذه العملية غير مسموحة كما أوضحنا: cannot use "Sammy" (type string) as type int in assignment لا يمكنك أيضًا تعريف أكثر من متغير واحد بالاسم نفسه: var s string var s string ستحصل على خطأ كما يلي: s redeclared in this block لايمكنك استخدام المعامل =: بدلًا من = عند محاولة تعديل قيمة متغير كما أشرنا سابقًا كما يلي: i := 5 i := 10 فالخرج التالي يُظهر خطًأ مفاده أنه لا يوجد متغير جديد على الطرف الأيسر، إذ تُفسِّر جو وجود المعامِل =: بأننا نريد التصريح عن متغير جديد أو تهيئته بقيمة أولية. no new variables on left side of := ستحسِّن تسمية المتغيرات الخاصة بك بطريقة سليمة قابلية قراءة برنامجك سواءً لك أو للآخرين ولاسيما عند العودة إليه مستقبلًا. الإسناد المتعدد يمكنك في لغة جو إسناد عدة قيم إلى عدة متغيرات في الوقت نفسه، إذ يتيح لك هذا تهيئة عدة متغيرات دفعةً واحدةً، ويمكن أن تكون كل من هذه المتغيرات من أنواع بيانات مختلفة كما يلي: j, k, l := "shark", 2.05, 15 fmt.Println(j) fmt.Println(k) fmt.Println(l) يكون الخرج كما يلي: shark 2.05 15 هنا أُسند إلى المتغير j السلسلة "shark" والمتغير k القيمة 2.05 والمتغير l القيمة 15. إسناد قيم لعدة متغيرات في سطر واحد يمكن أن يجعل الشيفرة مختصَرةً ويقلل من عدد الأسطر، ولكن تأكد من أنّ ذلك ليس على حساب قابلية القراءة. المتغيرات العامة والمحلية عند استخدام المتغيرات داخل البرنامج، من المهم أن تضع نطاق المتغير variable scope في حساباتك، إذ يشير نطاق المتغير إلى المواضع التي يمكن الوصول منها إلى المتغير داخل الشيفرة، حيث لا يمكن الوصول إلى جميع المتغيرات من جميع أجزاء البرنامج، فبعض المتغيرات عامة وبعضها محلي، إذ تُعرّف المتغيرات العامة خارج الدوال؛ أما المتغيرات المحلية، فتوجد داخل الدوال، ويعطي المثال التالي فكرةً عن المتغيرات العامة والمحلية: package main import "fmt" var g = "global" func printLocal() { l := "local" fmt.Println(l) } func main() { printLocal() fmt.Println(g) } يكون الخرج كما يلي: local global استخدمنا var g = "global"‎ للتصريح عن متغير عام خارج الدالة ثم عرّفنا الدالة printLocal()‎ وبداخلها المتغير المحلي l المسنَد إليه قيمة ثم تعليمة لطباعته. في الدالة الرئيسية نستدعي الدالة printLocal()‎ ثم نطبع قيمة المتغير العام g، وبما أنّ g متغير عام، فيمكننا الوصول إليه من داخل الدالة printLocal()‎ مباشرةً كما في المثال التالي: package main import "fmt" var g = "global" func printLocal() { l := "local" fmt.Println(l) fmt.Println(g) } func main() { printLocal() fmt.Println(g) } يكون الخرج كما يلي: local global global يختلف هذا المثال عن المثال السابق في أننا نحاول الوصول إلى المتغير العام g مباشرةً من داخل الدالة printLocal وهذا مايُفسّره خرج البرنامج، حيث تطبع الدالة printLocal قيمة كل من l و g هذه المرة وليس فقط l. إذا حاولت الوصول إلى قيمة المتغير المحلي من خارج الدالة، فستفشل وستظهر رسالة خطأ تشير إلى ذلك: package main import "fmt" var g = "global" func printLocal() { l := "local" fmt.Println(l) } func main() { fmt.Println(l) } يكون الخرج كما يلي: undefined: l أي أن المتغير غير مُعرّف في نطاق الدالة الرئيسية، إذ لا يمكنك الوصول إلى المتغير المحلي إلا ضمن النطاق الذي عُرّف ضمنه ونطاقه في هذا البرنامج هو الدالة printLocal، فلنلق الآن نظرةً على مثال آخر بحيث نستخدِم اسم المتغير نفسه لمتغير عام ومتغير محلي كما يلي: package main import "fmt" var num1 = 5 func printNumbers() { num1 := 10 num2 := 7 fmt.Println(num1) fmt.Println(num2) } func main() { printNumbers() fmt.Println(num1) } يكون الخرج كما يلي: 10 7 5 صرّحنا في البرنامج السابق عن المتغير num1 مرتين؛ مرة ضمن النطاق العام var num1 = 5 والأخرى num1 := 10 ضمن نطاق محلي داخل الدالة printNumbers. عندما نطبع num1 من البرنامج الرئيسي -أي داخل الدالة main-، سنرى قيمة 5 مطبوعةً لأن main لا ترى سوى المتغير العام؛ أما عندما نطبع num1 من داخل الدالة printNumbers، فإنه سيرى المتغير المحلي وسوف يطبع القيمة 10، وعلى الرغم من أنّ printNumbers يُنشئ متغيرًا جديدًا num1 ويُسند له قيمة 10، إلا أنه لا يؤثر على المتغير العام وستبقى قيمته 5. عند التعامل مع المتغيرات، من المهم أن تختار بين استخدام المتغيرات العامة أو المحلية. يُفضل في العادة استخدام المتغيرات المحلية، ولكن إذا وجدت نفسك تستخدم نفس المتغير في عدة دوال، فقد ترغب في جعله عامًا. أما إن كنت تحتاج المتغير داخل دالة أو صنف واحد فقط، فقد يكون الأولى استخدام متغير محلي. الثوابت تشبه الثوابت المتغيرات إلا أنه لا يمكن تعديلها بعد التصريح عنها، وهي مفيدة عندما تريد استخدام قيمة محددة في برنامجك ولا تريد تعديلها أبدًا مثل قيمة باي pi في الرياضيات 3.14 أو إذا أردنا التصريح عن معدل الضريبة لنظام عربة التسوق، فيمكننا استخدام ثابت ثم حساب الضريبة في مناطق مختلفة من برنامجنا، فإذا تغير معدل الضريبة في وقت لاحق، فسيتعيّن علينا فقط تغيير هذه القيمة في مكان واحد في برنامجنا؛ أما إذا استخدمنا متغيرًا، فمن الممكن تغيير القيمة عن طريق الخطأ في مكان ما في برنامجنا، مما قد يؤدي إلى حساب غير صحيح. يمكننا استخدام الصيغة التالية للتصريح عن ثابت: const shark = "Sammy" fmt.Println(shark) يكون الخرج كما يلي: Sammy إذا حاولت تعديل قيمة الثابت بعد التصريح عنه، فسنحصل على الخطأ التالي: cannot assign to shark يمكن أن تكون الثوابت من دون نوع untyped، وهذا مفيد عند التعامل مع أعداد مثل بيانات الأعداد الصحيحة، فإذا كان الثابت من النوع untyped فيُحوّل صراحةً، حيث لا تُحوَّل الثوابت التي لديها نوع typed. package main import "fmt" const ( year = 365 leapYear = int32(366) ) func main() { hours := 24 minutes := int32(60) fmt.Println(hours * year) fmt.Println(minutes * year) fmt.Println(minutes * leapYear) } يكون الخرج كما يلي: 8760 21900 21960 عرّفنا المتغير year على أنه ثابت من دون نوع untyped، وبالتالي يمكن استخدامه مع أيّ نوع بيانات آخر؛ أما لو حددنا له نوعًا وليكن int32 كما فعلنا مع الثابت leapYear، فلن نستطيع التعامل معه إلا مع بيانات من النوع نفسه لأنه typed constant. عندما عرّفنا المتغير hours بدون تحدبد نوعه، استنتجت جو تلقائيًا أنه من النوع int لأننا أسندنا القيمة 24 له؛ أما عندما عرّفنا المتغير minutes، فقد حددنا له صراحةً نوع البيانات int32 من خلال التعليمة minutes := int32(60)‎. دعنا الآن نتصفح كل عملية حسابية وسبب نجاحها: hours * year هنا المتغير hours من النوع الصحيح والثابت year من دون نوع، وبالتالي لإجراء العملية تحوِّل جو الثابت year إلى النوع المطلوب؛ أي تحوّله إلى النوع int. minutes * year هنا المتغير minutes من النوع int32 والثابت year من دون نوع، لذا تحوِّل جو الثابت year إلى النوع int32. minutes * leapYear المتغير minutes والثابت leapYear كلاهما من النوع int32، لذا لن تحتاج جو لأيّ عملية تحويل فكلاهما متوافقان. إذا حاولت إجراء عملية حسابية مثل الضرب بين نوعين مختلفين أي typed، فلن ينجح الأمر: fmt.Println(hours * leapYear) يكون الخرج كما يلي: invalid operation: hours * leapYear (mismatched types int and int32) هنا hours هي من النوع int كما تحدثنا والثابت leapYear من النوع int32، بما أنّ جو لغة تعتمد على تحديد النوع typed language، فهذا يعني أنّ النوعين int و int32 غير متوافقين لإجراء العمليات الحسابية، ولحل المشكلة عليك تحويل أحدهما إلى نوع الآخر. الخاتمة لقد مررنا في هذا المقال على بعض حالات الاستخدام الشائعة للمتغيرات في جو، فالمتغيرات هي لبنة مهمة في البرمجة، إذ تُمثِّل حاضنةً لمختلف أنواع البيانات في جو ومن خلالها نستطيع إجراء العديد من العمليات وتخزين القيم التي نحتاجها. ترجمة -وبتصرف- للمقال How To Use Variables and Constants in Go لصاحبه Gopher Guides. اقرأ أيضًا المقال السابق: التعامل مع السلاسل في لغة جو Go الدليل السريع إلى لغة البرمجة Go كتابة أول برنامج (ومكتبة) لك باستخدام لغة البرمجة Go التعرف على GOPATH في لغة جو Go كتابة التعليقات في لغة جو Go
  10. تُعَدّ السلسلة النصية تسلسلًا من محرف واحد -أي حرف أبجدي أو عدد أو رمز- أو أكثر ويمكن أن تكون ثابتًا constant أو متغيرًا variable، كما تتبع السلاسل النصية الترميز الموحد يونيكود Unicode (معيار يُمكّن الحواسيب من تمثيل النصوص المكتوبة بأغلب نظم الكتابة ومعالجتها، بصورة متناسقة). تُعَدّ السلاسل النصية في جو غير قابلة للتغيير Immutable، وهو المصطلح المعاكس لمصطلح Mutable الذي يشير إلى أنواع البيانات التي يمكن التعديل على القيم التي تحتويها حتى بعد إنشاءها. أي أنه وبعد إنشاء نوع البيانات وتخزينه في الذاكرة، يمكن التعديل على بياناته. تدخل النصوص في كل شيء، لذا فإن نوع البيانات الذي هو السلسلة النصية string مهم جدًا في كل لغات البرمجة، وستتعلم في هذا المقال كيفية إنشاء السلاسل وطباعتها وربطها وتكرارها وتخزينها في متغيرات. صياغة السلاسل النصية String Literals غالبًا ما تكون السلاسل عبارة عن نصوص عادية مكتوبة، لذا قد ترغب في العديد من الحالات أن تحصل على تحكم أكبر في كيفية ظهور هذه السلاسل بغية جعلها مقروءة أكثر للآخرين، وذلك بإضافة علامات الترقيم وفواصل الأسطر والمسافات البادئة …إلخ. وستتعرف فيما يلي على بعض الطرق التي يمكنك من خلالها تمثيل السلاسل النصية بالصياغة المطلوبة في جو، ولكن يجب عليك في البداية فهم الفرق بين صياغة السلسلة النصية وقيمتها؛ فالسلسلة النصية مع صياغتها هي ما نراه في الشيفرة المصدرية لبرنامج الحاسوب بما في ذلك علامتَي الاقتباس مثلًا؛ أما قيمة السلسلة، فهي ما نراه عند التعامل مع السلسلة عند تشغيل البرنامج مثل استدعاء الدالة fmt.Println معها، ففي برنامج طباعة النص "Hello, World!‎" مثلًا، تكون صياغة السلسلة هي "Hello, World!‎" وقيمتها هي Hello, World!‎، أي بدون علامتَي الاقتباس. إذًا قيمة السلسلة هي ما تراه خرجًا على نافذة الطرفية عند تشغيل برنامج جو. قد تحتاج في بعض الأحيان إلى تضمين علامتَي الاقتباس بحيث تظهر في قيمة السلسلة عندما تقتبس من مصدر مثلًا، ولكن بما أنّ صياغة السلسلة وقيمتها غير متكافئين، فستحتاج غالبًا لإضافة تنسيق محدد إلى السلسلة لضمان ظهور علامة الاقتباس في قيمة السلسلة كما هو متوقع. علامات الاقتباس وتفسيرها تتيح لغة جو Go استخدام علامات الاقتباس الخلفية ` أو علامات الاقتباس المزدوجة " لتعريف السلاسل النصية، فبالتالي عندما ترغب باستخدام علامات الاقتباس المزدوجة، فيمكنك تضمينها ضمن سلسلة تستخدِم علامات اقتباس خلفية والعكس بالعكس كما في المثال التالي: `Sammy says, "Hello!"` أو الحالة المعاكسة: "Sammy likes the `fmt` package for formatting strings.." يمكنك بهذه الطريقة الجمع بين علامات الاقتباس الخلفية والمزدوجة والتحكم في عرض علامات الاقتباس داخل السلسلة النصية، لكن تذكّر أنّ استخدام علامات الاقتباس الخلفية في جو سيؤدي إلى إنشاء سلسلة نصية أولية raw string literal واستخدام علامات الاقتباس المزدوجة سيؤدي إلى إنشاء سلسلة نصية مُفسّرة interpreted string literal. محارف الهروب Escape Characters يمكنك استخدام محارف خاصة داخل السلاسل النصية لها معنى خاص بالنسبة للغة جو مثل " ولكن ماذا لو أردنا استعمال علامة الاقتباس " نفسها ضمن سلسلة نصية؟ نلجأ هنا إلى مفهوم الهروب والذي يعني إخبار المُصرِّف أن لا يفسر المحرف التالي له بمعناه الخاص مثل تهريب علامة الاقتباس " والعكس أيضًا أي إعطاء معنى خاص مع محارف محددة إن وجدت ضمن السلسلة النصية مثل محرف السطر الجديد ‎\n، إذ تبدأ جميع محارف الهروب بمفتاح الشرطة المائلة للخلف \ يليها مباشرةً المحرف المراد تهريبه داخل السلسلة، ومن أبرز حالات استعمال محرف التهريب: \: تهريب تفسير الشرطة المائلة \ بمعناها الخاص أي محرف التهريب نفسه. "\: تهريب علامة اقتباس مزدوجة. n\: إعطاء الحرف n معنى خاص وهو تفسيره إلى الانتقال إلى السطر التالي (أول حرف من كلمة new line أي سطر جديد) أي كأنك تضغط على حرف الإدخال enter. t\: إعطاء الحرف t معنى خاص وهو مفتاح الجدولة Tab، أي تفسيره بمسافة بادئة أفقية. سنستخدِم في المثال التالي محرف الهروب "\ لإضافة علامات الاقتباس: fmt.Println("Sammy says, \"Hello!\"") سيكون الخرج كما يلي: Sammy says, "Hello!" إذًا باستخدام محرف الهروب "\ يمكنك استخدام علامات الاقتباس المزدوجة لإحاطة سلسلة تتضمن نصًا بين علامتَي اقتباس مزدوجتين، وسنستخدم الآن محرف هروب آخر وهو n\ للانتقال إلى السطر التالي: fmt.Println("This string\nspans multiple\nlines.") سيكون الخرج كما يلي: This string spans multiple lines. يمكنك أيضًا استخدام عدة محارف هروب ضمن السلسلة في الوقت نفسه كما في المثال التالي: fmt.Println("1.\tShark\n2.\tShrimp\n10.\tSquid") سيكون الخرج كما يلي: 1. Shark 2. Shrimp 10. Squid يساعدك محرف الهروب t\ في عرض البيانات المُجدولة بمحاذاة أفقية واحدة، إذ يستبدلها المُصرِّف بمسافة بادئة أفقية بطول ثابت مما يساعدك في جعل البيانات المعروضة قابلة للقراءة بوضوح. تُستخدَم محارف الهروب لإضافة تنسيق إضافي إلى السلاسل التي قد تكون من الصعب أو المستحيل تحقيقها، إذ لن تتمكن بدون محارف الهروب من إنشاء سلسلة مثل Sammy says, "I like to use the fmt package"‎. السلسلة النصية الأولية raw string literal لنفرض مثلًا أنك لا تريد استخدام تنسيق خاص داخل السلاسل النصية، فقد ترغب بمقارنة أو تقييم سلاسل شيفرة الحاسوب التي تستخدِم الشرطة المائلة للخلف، لذلك لا تريد أن يستخدمها جو على أساس محرف هروب، وبالتالي تخبر السلسلة النصية الأولية جو أن يتجاهل جميع التنسيقات والتفسيرات داخل سلسلة بما في ذلك محارف الهروب. سننشئ هنا سلسلةً أوليةً باستخدام علامتَي الاقتباس الخلفية: fmt.Println(`Sammy says,\"The balloon\'s color is red.\"`) سيكون الخرج كما يلي: Sammy says,\"The balloon\'s color is red.\" نستنتج أنّ استخدام سلسلة نصية أولية يؤدي إلى تجاهل علامات الاقتباس وأية محارف وتنسيقات خاصة يمكن للغة جو أن تفسرها بمعنى مختلف، وبالتالي يمكنك الاحتفاظ بالشرطة المائلة العكسية والمحارف الأخرى التي تُستخدم على أساس محارف هروب. السلاسل النصية المفسرة هي سلسلة نصية موضوعة بين علامتي اقتباس مزدوجتين "..". كل شيء موجود بداخل علامتي الاقتباس سيُعرض باستثناء الأسطر الجديدة (المُعبر عنها بالرمز n\) وعلامات الاقتباس المزدوجة. في حال أردت أن تظهر هذه الرموز أيضًا، يمكنك استخدام مفتاح الهروب (أو الإلغاء) / قبلها. مثال: fmt.Println("Say \"hello\" to Go!") الخرج: Say "hello" to Go! غالبًا ستستخدم السلاسل المُفسرة لأنها تتعامل مع المحارف الخاصة وتسمح بتخطيها أيضًا (تحكم أكبر). طباعة السلاسل النصية على عدة أسطر تجعل طباعة السلاسل النصية على أسطر متعددة النص أكثر قابليةً للقراءة، وتمكّنك أيضًا من تجميع السلاسل لإنشاء نص مُنظّم ونظيف أو استخدامها للاحتفاظ بفواصل الأسطر في حال كانت تعبر عن قصيدة أو أغنية. يمكنك كتابة السلسلة بالطريقة التي تريد أن تظهر بها تمامًا وإحاطتها بعلامتَي الخلفية الاقتباس لإنشاء سلاسل تمتد على عدة أسطر، لكن لا تنسى أنّ ذلك سيجعل منها سلسلةً نصية أوليةً. ` This string is on multiple lines within three single quotes on either side. ` سيكون الخرج كما يلي: This string is on multiple lines within three single quotes on either side. لاحظ أنّ هناك سطر بداية ونهاية فارغين، ولتجنب ذلك ضع السطر الأول فورًا بعد علامة الاقتباس الخلفي وفي السطر الأخير ضع علامة الاقتباس الخلفي مباشرةً بعد آخر كلمة. `This string is on multiple lines within three single quotes on either side.` إذا كنت بحاجة إلى إنشاء سلسلة مفسرة متعددة الأسطر، فيمكنك إنجاز ذلك بعلامتَي اقتباس مزدوجة واستخدام العامِل +، ولكن ستحتاج إلى إدخال فواصل الأسطر من خلال محرف الهروب في الأماكن التي تريدها كما في المثال التالي: "This string is on\n" + "multiple lines\n" + "within three single\n" + "quotes on either side." بالرغم من أنّ علامتَي الاقتباس الخلفية تُسهّل طباعة النص الطويل وقراءته، لكن إذا كنت بحاجة إلى سلسلة نصية مفسرة، فستحتاج إلى استخدام علامتَي الاقتباس المزدوجة. طباعة السلاسل يمكنك طباعة السلاسل باستخدام حزمة fmt من مكتبة النظام ثم استدعاء الدالة ()Println منها: fmt.Println("Let's print out this string.") سيكون الخرج كما يلي: Let's print out this string. يجب عليك استيراد حزم النظام عند استخدامها، وبالتالي سيكون البرنامج اللازم لطباعة السلسلة كما يلي: package main import "fmt" func main() { fmt.Println("Let's print out this string.") } ربط السلاسل يُقصَد بربط السلاسل Concatenation ضم أو وصل السلاسل معًا من طرف إلى طرف لإنشاء سلسلة جديدة، إذ يمكنك ربط السلاسل باستخدام العامِل +، وضَع في الحسبان أنه عند التعامل مع الأرقام سيكون العامل + عاملًا للجمع، ولكن عند استخدامه مع السلاسل فهو عامل ربط. سنربط في المثال التالي السلسلة "Sammy" والسلسلة "Shark" لإنشاء سلسلة نصية جديدة، وسنطبع الناتج مباشرةً من خلال دالة الطباعة كما يلي: fmt.Println("Sammy" + "Shark") سيكون الخرج كما يلي: SammyShark يمكنك إضافة مسافة فارغة للفصل بين الكلمتَين من خلال إضافتها بين علامتي الاقتباس بعد الكلمة الأولى كما يلي: fmt.Println("Sammy " + "Shark") سيكون الخرج كما يلي: Sammy Shark لا يمكنك استخدام العامل + بين نوعين مختلفين من البيانات، فلا يمكنك مثلًا ربط السلاسل والأعداد الصحيحة معًا، وإذا حاولت ذلك: fmt.Println("Sammy" + 27) فسيظهر الخطأ التالي: cannot convert "Sammy" (type untyped string) to type int invalid operation: "Sammy" + 27 (mismatched types string and int) إذا أردت إنشاء السلسلة النصية "Sammy27"، فيمكنك ذلك بوضع العد 27 بين علامتَي اقتباس "27" بحيث لا يكون عددًا صحيحًا وإنما سلسلةًإ إذ يكون استخدام الأعداد ضمن السلاسل مفيدًا في كثير من الحالات مثل الرموز البريدية أو أرقام الهواتف، فقد ترغب مثلًا بجعل رمز البلد ورمز المنطقة معًا بدون فاصل بينهما. عندما تربط سلسلتين فهذا يعني أنك ستُنشئ سلسلةً جديدةً يمكنك استخدامها في جميع أنحاء برنامجك. تخزين السلاسل في المتغيرات المتغيرات هي مفهوم برمجي هام يشير إلى القيم ونوع القيم التي تستخدمها في برنامجك. يحدد نوع المتغير (نوع البيانات) نوع القيم التي يمكنه تخزينها والعمليات التي يمكن إجراؤها عليه، إذ يمكنك التفكير فيها على أساس صندوق فارغ يمكنك ملؤه بقيمة أو ببيانات، كما تُعَدّ السلاسل النصية بيانات، لذا يمكنك استخدامها لملء متغير، كما يسهِّل استخدام المتغيرات لتخزين السلاسل العمل مع السلاسل في أي برنامج. لتخزين سلسلة داخل متغير، ما عليك سوى إسناد السلسلة إلى متغير من النوع string، وسنخزّن هنا مثلًا سلسلةً داخل المتغير الذي اسميناه s، كما يمكنك استخدام أيّ اسم تراه مُعبّرًا، لكن يُفضل الأسماء القصيرة: s := "Sammy likes declaring strings." يمكنك الآن طباعة هذا المتغير الذي يُمثّل السلسلة السابقة: fmt.Println(s) سيكون الخرج: Sammy likes declaring strings. يُسهّل عليك استخدام المتغيرات مع السلاسل معالجة السلاسل والتعامل معها كثيرًا، فكل ما عليك فعله هو تخزينها في متغير مرةً واحدة لتتمكن من استخدام هذا المتغير الذي يحملها في أيّ مكان في برنامجك. التعامل مع السلاسل النصية ومعالجتها تحتوي حزمة strings في جو على العديد من الدوال المتاحة للعمل مع نوع بيانات السلسلة النصية string، إذ تمكّنك هذه الدوال من تعديل السلاسل والتعامل معها بسهولة، إذ تُعَدّ هذه الدوال إجراءات تتمثل بمجموعة من التعليمات البرمجية التي تُطبق على السلاسل لأهداف مختلفة. حزمة السلاسل في جو هي حزمة مدمجة (مُضمنة في الشيفرة المصدر) وبالتالي عند تثبيت جو تُثبّت معها، وبما أنها حزمة مُدمجة فهذا يعني أن كل الدوال التابعة لها مدمجة أيضًا ومتاحة للعمل مباشرةً، وستتعرف فيما يلي هذه الدوال وستتعلم كيفية استخدامها. تبديل حالة الأحرف من صغير إلى كبير والعكس تُستخدَم الدالتان strings.ToUpper و strings.ToLower للتبديل بين حالتَي الأحرف الكبيرة والصغيرة، حيث تحوّل الدالة الأولى كل محارف السلسلة الأولى المُعطاة إلى الحالة الكبيرة وتعيدها على أساس سلسلة جديدة وبالطبع إذا كان الحرف كبير أصلًا، فلن يتغير، في حين تحوّل الدالة الثانية المحارف إلى الحالة الصغيرة وتعيدها على أساس سلسلة جديدة. سنحوّل في المثال التالي كل محارف السلسلة "Sammy Shark" إلى حالتها الكبيرة: ss := "Sammy Shark" fmt.Println(strings.ToUpper(ss)) سيكون الخرج كما يلي: SAMMY SHARK يمكنك أيضًا تحويلها إلى الحالة الصغيرة: fmt.Println(strings.ToLower(ss)) سيكون الخرج كما يلي: sammy shark بما أنك تستخدم دوال السلاسل، فلابد أن ستستورد الحزمة أولًا، وإلا فلن يتعرّف المُصرِّف على تلك الدوال: package main import ( "fmt" "strings" ) func main() { ss := "Sammy Shark" fmt.Println(strings.ToUpper(ss)) fmt.Println(strings.ToLower(ss)) } تفيد الدالتان strings.ToUpper و strings.ToLower كثيرًا في حالة مقارنة وتقييم السلاسل، لأنه يجعل حالة المحارف بحالة متسقة، فإذا قارنت مثلًا بين كلمتَي Sammy و sammy، فستكون النتيجة أنهما غير متماثلتان لأن جو حساسة لحالة الأحرف سواءً كان ذلك بالنسبة للقيم أو المتغيرات، لكن إذا طبقت الدالة strings.ToLower على الكلمة الأولى قبل المقارنة، فسيكون الناتج أنهما متماثلتان، ومن هنا تأتي أهميتهما. دوال البحث في السلاسل تحتوي حزمة السلاسل النصية في جو على العديد من الدوال التي تمكّنك من إنجاز عمليات البحث في السلاسل مثل البحث عن تسلسل محدد من المحارف داخل سلسلة ما، ومن أشهر هذه الدوال: strings.HasPrefix تبحث في السلسلة من بدايتها. strings.HasSuffix تبحث في السلسلة من نهايتها. strings.Contains تبحث في أيّ مكان في السلسلة. strings.Count تعيد عدد المرات التي ظهرت بها السلسلة ضمن السلسلة المعطاة. تسمح لك الدالة الأولى والثانية بالبحث عن محرف أو سلسلة من المحارف المحددة في بداية أو نهاية السلسلة، أي اختبار فيما إذا كانت تنتهي أو تبدأ بمجموعة من المحارف، فلاختبار فيما إذا كانت السلسلة "Sammy Shark" تبدأ بكلمة Sammy وتنتهي بكلمة Shark مثلًا، سنكتب ما يلي: ss := "Sammy Shark" fmt.Println(strings.HasPrefix(ss, "Sammy")) fmt.Println(strings.HasSuffix(ss, "Shark")) سيكون الخرج كما يلي: true true يمكنك استخدام الدالة strings.Contains مثلًا لاختبار احتوائها على السلسلة "Sh": fmt.Println(strings.Contains(ss, "Sh")) سيكون الخرج كما يلي: true يمكنك أيضًا حساب عدد مرات ظهور المحرف S في السلسلة Sammy Shark: fmt.Println(strings.Count(ss, "S")) سيكون الخرج كما يلي: 2 سنجرب الآن حساب عدد مرات ظهور الحرف s بالحالة الصغيرة: fmt.Println(strings.Count(ss, "s")) سيكون الخرج كما يلي: 0 ملاحظة: تذكّر ما أشرنا إليه سابقًا بخصوص حساسية جو لحالة الأحرف، فهذا سيُفسّر نتيجة الخرجَين السابقَين. تحديد طول السلسلة تُستخدَم الدالة len لحساب عدد المحارف الموجودة ضمن سلسلة نصية ما -أي طولها-، وهذه الدالة مفيدة في الكثير من الحالات مثل معرفة طول السلسلة أو قص السلاسل الأطول من طول محدد أو إذا لإجبار المستخدِم على إدخال طول محدد لكلمة المرور، وفي المثال التالي سنحسب طول سلسلة محددة: import ( "fmt" "strings" ) func main() { openSource := "Sammy contributes to open source." fmt.Println(len(openSource)) } سيكون الخرج كما يلي: 33 في المثال أعلاه أسندنا السلسلة "Sammy contributes to open source.‎" إلى المتغير openSource ثم مررنا المتغير openSource إلى الدالة len لحساب طولها ووضعناها ضمن الدالة fmt.Println لطباعة النتيجة مباشرةً، ويجب أن تضع في ذهنك أنّ الدالة len ستحسب طول السلسلة مع احتساب أي شيء ضمنها مثل الرموز والأرقام والفراغات …إلخ. دوال معالجة السلاسل النصية وتعديلها توجد دوال إضافية للتعامل مع السلاسل مثل strings.Join و strings.Split و strings.ReplaceAll، إذ تستخدَم الدالة strings.Join لربط شريحة من السلاسل مع بعضها مع إمكانية فصلها بفاصل محدد كما في المثال التالي: fmt.Println(strings.Join([]string{"sharks", "crustaceans", "plankton"}, ",")) سيكون الخرج كما يلي: sharks,crustaceans,plankton كان الفاصل هنا هو فاصلة ","، كما يمكنك مثلًا إضافة فراغ بعد الفاصلة أيضًا كما يلي: strings.Join([]string{"sharks", "crustaceans", "plankton"}, ", ") يمكنك استخدام الدالة strings.Split أيضًا لتقسيم السلاسل اعتمادًا على فاصل محدد كما في المثال التالي: balloon := "Sammy has a balloon." s := strings.Split(balloon, " ") fmt.Println(s) سيكون الخرج شريحةً من السلاسل كما يلي: [Sammy has a balloon] قد يكون من الصعب تحديد محتوى هذه الشريحة بمجرد النظر إليه باستخدام الدالة strings.Println، لذا يمكنك استخدام الدالة fmt.Printf مع الرمز q% لطباعة السلاسل مع علامتَي الاقتباس كما يلي: fmt.Printf("%q", s) سيكون الخرج كما يلي: ["Sammy" "has" "a" "balloon."] توجد دالة أخرى مشابهة للدالة السابقة هي strings.Fields، لكن هذه الدالة تتجاهل أيّة فراغات في السلسلة وبالتالي لا تقسم إلى الحقول الفعلية: data := " username password email date" fields := strings.Fields(data) fmt.Printf("%q", fields) سيكون الخرج كما يلي: ["username" "password" "email" "date"] تستخدَم الدالة strings.ReplaceAll لاستبدال محرف أو عدة محارف في السلسلة بمحرف جديد أو أكثر، إذ سنمرر لهذه الدالة السلسلة المطلوب تعديلها على أساس وسيط أول، ففي المثال التالي سنمرر المتغير balloon الذي يحمل القيمة Sammy has a balloon ثم سنمرر لها السلسلة المطلوب استبدالها وهي has ثم السلسة البديلة وهي had كما يلي: fmt.Println(strings.ReplaceAll(balloon, "has", "had")) سيكون الخرج كما يلي: Sammy had a balloon. سيكون لديك تحكم كبير في السلاسل من خلال الدوال السابقة. الخاتمة تعلمت في هذه المقالة أساسيات العمل مع نوع بيانات السلاسل النصية في جو بدءًا من إنشاء السلاسل وطباعتها وربطها وتكرارها ووصولًا إلى التعامل معها على أساس متغيرات ضمن برنامجك، كما تعلمت أيضًا عدة طرق لصياغة السلاسل النصية وتنسيقها بالإضافة إلى تقنيات مثل محارف الهروب تمكّنك من عرض السلاسل النصية في برنامجك على الشاشة كما تريد لكي يتمكن المستخدِم النهائي من قراءة كل المخرجات بسهولة ثم تعرفت أخيرًا على أشهر الدوال المستخدَمة في معالجة السلاسل النصية وتعديلها. ترجمة -وبتصرف- للمقال An Introduction to Working with Strings in Go ومقال How To Format Strings in Go ومقال An Introduction to the Strings Package in Go لصاحبها Gopher Guides. اقرأ أيضًا المقال السابق: تعرف على أنواع البيانات في لغة جو Go الدليل السريع إلى لغة البرمجة Go الدروس المستفادة من البرمجة بلغة Go 3 طرائق لنسخ الملفات في Go
  11. تٌعَدّ المتغيرات مفهومًا برمجيًا هامًا يشير إلى القيم ونوع القيم التي تستخدمها في برنامجك، إذ يحدد نوع المتغير -أو نوع البيانات- نوع القيم التي يمكنه تخزينها والعمليات التي يمكن إجراؤها عليه. من الناحية الفنية، يُخصَّص للمتغير مساحة تخزينية في الذاكرة توضع القيمة المرتبطة به فيها. يُستخدم اسم المتغير للإشارة إلى تلك القيمة المُخزَّنة في ذاكرة البرنامج التي هي جزء من ذاكرة الحاسوب. ستغطي هذه المقالة أنواع المتغيرات المهمة والأساسية التي تحتاجها مبدأيًا، كما ستتعرّف على المتغيرات في جو وستكون قادرًا على فهمها والتعامل معها، وبالتالي ستمتلك القدرة على كتابة تعليمات برمجية أكثر وضوحًا وتعمل بكفاءة. يمكن التفكير في أنواع المتغيرات كما العالم الحقيقي، فنحن نتعامل مثلًا مع الأعداد من مجموعات عددية مختلفة مثل مجموعة الأعداد الطبيعية (0 ، 1 ، 2 ، …) والأعداد الصحيحة (… ، -1 ، 0 ، 1 ، …) والأعداد غير الكسرية مثل π. عند التعامل مع المسائل الرياضية قد نجمع بين الأعداد التي تنتمي إلى مجموعات عددية مختلفة لنحصل على نتيجة ما مثلًا إضافة العدد 5 إلى π: 5 + π يمكننا الآن الاحتفاظ بالمعادلة كما هي لتكون إجابةً أو يمكننا تقريب العدد π إلى منزلة عشرية مناسبة ثم جمعه مع العدد 5، أي كما يلي: 5 + π = 5 + 3.14 = 8.14 لكن إذا حاولت جمع أيّ عدد مع نوع بيانات آخر وليكن كلمة مثلًا، فسيكون هذا بدون معنى مثل: shark + 8 هناك فصل بين أنواع البيانات في الحواسيب، إذ يختلف كل نوع عن الآخر بحيث يوجد نوع مخصص للكلمات ونوع آخر للأعداد، ويجب الانتباه عند استخدام أو تطبيق العمليات على هذه المتغيرات. الأعداد الصحيحة كما هو الحال في الرياضيات، فإن الأعداد الصحيحة Integers في الحاسب هي أعداد موجبة أو سالبة إضافةً إلى الصفر، أي (‎… ، -1 ، 0 ، 1 ، …‎). يُعبَّر عن الأعداد الصحيحة في لغة جو من خلال النوع int، كما يجب أن تكتب العدد الصحيح كما هو بدون فواصل بين الأعداد كما في اللغات البرمجية الأخرى، فعادةً تُفصَل الأعداد الكبيرة بفواصل لتسهيل قرائتها، فقد يُكتب المليون مثلًا بالصورة 1,000,000 وفي لغات البرمجة هذا غير مسموح، ويمكن طباعة العدد الصحيح ببساطة كما يلي: fmt.Println(-459) والنتيجة هي: -459 أو يمكنك تعريف متغير من النوع الصحيح ليمثل هذا العدد كما يلي: var absoluteZero int = -459 fmt.Println(absoluteZero) والنتيجة هي: -459 يمكنك أيضًا إجراء العمليات الحسابية على الأعداد الصحيحة في جو، ففي الشيفرة التالية سنستخدِم معامل الإسناد ‎:=‎ لتعريف وتقييم المتغير sum: sum := 116 - 68 fmt.Println(sum) والنتيجة هي: 48 نلاحظ أنه قد طُرح العدد 68 من العدد 116 وخُزّن الناتج 48 في المتغيّر sum. ستتعرف على المزيد من التفاصيل المتعلقة بالتصريح عن المتغيرات لاحقًا، وهناك العديد من الطرق لاستخدام الأعداد الصحيحة في جو ستتعرف على معظمها خلال رحلتك التعليمية هذه. الأعداد العشرية يُعَدّ العدد ذو الفاصلة العشرية Floating-Point عددًا عشريًا ويمكن كتابته على صورة حاصل ضرب في على النحو التالي: 10*12.5 = 2^10*1.25 = 125. وتُستخدَم الأعداد العشرية لتمثيل الأعداد الحقيقية التي لا يمكن التعبير عنها بالأعداد الصحيحة، إذ تتضمن الأعداد الحقيقية جميع الأعداد الكسرية وغير الكسرية، ولهذا السبب يمكن أن تحتوي أرقام عشرية على جزء كسري مثل 9.0 أو 116.42- في جو، فالعدد العشري في جو هو أيّ عدد يحتوي على فاصلة عشرية ببساطة: fmt.Println(-459.67) والنتيجة هي: -459.67 يمكنك أيضًا تعريف متغير يمثّله كما يلي: absoluteZero := -459.67 fmt.Println(absoluteZero) والنتيجة هي: -459.67 يمكنك أيضًا إجراء العمليات الحسابية عليه كما فعلنا مع الأعداد الصحيحة: var sum = 564.0 + 365.24 fmt.Println(sum) والنتيجة هي: 929.24 يجب أن تأخذ في الحسبان أنّ العدد 3 لا يساوي العدد 3.0، إذ يشير العدد 3 إلى عدد صحيح في حين 3.0 إلى عدد عشري. حجم الأنواع العددية يحتوي جو على نوعين من البيانات العددية بالإضافة إلى التمييز بين الأعداد الصحيحة والعشرية، وهما الساكنة static والديناميكية dynamic، فالنوع الأول مستقل عن المعمارية architecture-independent، أي أنّ حجم البيانات بواحدة البِتّ bit لا يتغير بغض النظر عن الجهاز الذي تعمل عليه الشيفرة. معظم معماريات أجهزة الحاسب في هذه الأيام هي إما 32 بِتّ أو 64 بِتّ، فإذا فرضنا مثلًا أنك تريد تطوير برنامج لحاسبك المحمول، فسترغب بجعله يعمل بنظام ويندوز حديث معماريته 64 بِتّ، لكن إذا كنت تعمل على تطوير برنامج لجهاز مثل ساعة اللياقة البدنية fitness watch، فربما ستُجبر على العمل بمعمارية 32 بِتّ. إذا استخدمت نوع المتغيرات المستقلة مثل int32، فسيكون حجم التخزين للمتغير ثابتًا بغض النظر عن المعمارية التي تُجري عملية التصريف عليها، أي باختصار، سيجعل استخدامك للمتغيرات من النوع الأول هذا المتغير ذا حجم ثابت في أيّ معمارية أو بيئة تستخدمها. يُعَدّ النوع الثاني نوعًا خاصًا بالتنفيذ implementation-specific، إذ يمكن هنا أن يختلف حجم البِتّ بناءً على المعمارية التي بُنيَ البرنامج عليها، فإذا استخدمت النوع int، فسيكون حجم المتغير هو 32 بِتّ عند تصريف برنامج جو لمعمارية 32 بِتّ؛ أما إذا صُرِّف البرنامج بمعمارية 64 بِتّ، فسيكون حجم المتغير 64 بِتّ، لذا يُسمى ديناميكيًا. هناك أنواع لأنواع البيانات نفسها إضافةً إلى أنواع البيانات ذات الأحجام المختلفة، فالأعداد الصحيحة مثلًا لها نوعين أساسيين هما ذات إشارة signed وعديمة الإشارة unsigned، فالنوع int8 هو عدد صحيح له إشارة سالبة أو موجبة ويمكن أن يكون له قيمة من ‎-128 إلى 127. أما النوع uint8 فهو عدد صحيح عديم الإشارة أي موجب دومًا، ويمكن أن يكون له فقط قيمة موجبة من 0 إلى 255. يمتلك جو الأنواع التالية المستقلة عن نوع المعمارية architecture-independent للأعداد الصحيحة: uint8 unsigned 8-bit integers (0 to 255) uint16 unsigned 16-bit integers (0 to 65535) uint32 unsigned 32-bit integers (0 to 4294967295) uint64 unsigned 64-bit integers (0 to 18446744073709551615) int8 signed 8-bit integers (-128 to 127) int16 signed 16-bit integers (-32768 to 32767) int32 signed 32-bit integers (-2147483648 to 2147483647) int64 signed 64-bit integers (-9223372036854775808 to 9223372036854775807) تأتي أعداد الفاصلة العشرية والأعداد المركبة أو العقدية complex numbers أيضًا بأحجام مختلفة: float32 IEEE-754 32-bit floating-point numbers float64 IEEE-754 64-bit floating-point numbers complex64 complex numbers with float32 real and imaginary parts complex128 complex numbers with float64 real and imaginary parts يوجد أيضًا نوعان بديلان alias للأعداد بغية إعطائها اسمًا هادفًا: byte alias for uint8 rune alias for int32 الهدف من الأسماء البديلة مثل البايت byte هو تحسين مقروئية الشيفرة وتوضيحها مثل حالة استعمال الاسم byte للإشارة إلى تخزين السلاسل النصية لكونه مقياسًا شائعًا في الحوسبة المتعلقة بالمحارف والنصوص خلاف حالة استعمال الاسم uint8 الذي يشيع استعماله مع الأعداد رغم أن كلاهما يصيران إلى نوع واحد عند تصريف البرنامج، فبذلك مثلًا أينما رأيت التسمية byte في برنامج تعرف أنك تتعامل مع بيانات نصية وأينما رأيت الاسم uint8 تعرف أنك تتعامل مع بيانات عددية. الاسم البديل رون rune مختلف قليلًا، فعلى عكس البايت byte و uint8 اللذان يمثلان البيانات نفسها، يمكن أن يكون الرون بايتًا واحدًا أو أربعة بايتات، أي مجالًا من 8 إلى 32 بت وهو مايحدده النوع int32، كما يُستخدم الرون لتمثيل محرف الترميز الموحد يونيكود Unicode (معيار يُمكّن الحواسيب من تمثيل النصوص المكتوبة بأغلب نُظم الكتابة ومعالجتها، بصورة متناسقة). يحتوي جو إضافةً إلى ذلك على الأنواع التالية الخاصة بالتنفيذ: uint unsigned, either 32 or 64 bits int signed, either 32 or 64 bits uintptr unsigned integer large enough to store the uninterpreted bits of a pointer value يُحدَّد حجم الأنواع الخاصة بالتنفيذ من خلال المعمارية التي صُرّف البرنامج من أجلها. اختيار حجم الأنواع العددية في برنامجك عادةً ما يكون اختيار الحجم الصحيح للنوع مرتبطًا بأداء المعمارية المستهدفة التي تبرمج عليها أكثر من ارتباطه بحجم البيانات التي تعمل عليها، وهناك إرشادات أساسية عامة يمكنك اتباعها عند بداية أي عملية تطوير. تحدثنا سابقًا أنّ هناك أنواع مستقلة عن المعمارية وأنواع خاصة بالتنفيذ، فبالنسبة لبيانات الأعداد الصحيحة من الشائع في جو استخدام أنواع تنفيذ مثل int أو uint بدلًا من int64 أوuint64، إذ ينتج عن ذلك عادةً سرعة معالجة أكبر على المعمارية المستهدفة، فإذا كنت تستخدم int64 مثلًا وأنجزت عملية التصريف على معمارية 32 بِتّ، فسيستغرق الأمر ضعف الوقت على الأقل لمعالجة هذه القيم بحيث تستغرق دورات معالجة إضافية لنقل البيانات من معمارية لأخرى؛ أما إذا استخدمت int بدلًا من ذلك، فسيعرّفه البرنامج على أنه حجم 32 بِتّ لمعمارية 32 بِتّ وسيكون أسرع في المعالجة. إذا كنت تعرف أنّ بياناتك لن تتجاوز مجالًا محددًا من القيم، فإن اختيار نوع مستقل عن المعمارية يمكن أن يزيد السرعة ويقلل من استخدام الذاكرة، فإذا كنت تعلم مثلًا أنّ بياناتك لن تتجاوز القيمة 100 وستكون موجبةً فقط، فسيجعل اختيار uint8 برنامجك أكثر كفاءةً لأنه يتطلب ذاكرةً أقل. بعد أن تعرّفت على بعض المجالات المحتملة لأنواع البيانات العددية، فلنلقِ نظرةً على ما سيحدث إذا تجاوزت هذه النطاقات في البرنامج. الفرق الطفحان والالتفاف Overflow vs Wraparound تتعامل جو مع حالة الطفحان overflow أو بلوغ الحد الأعظمي wraparound عند محاولة تخزين قيمة أكبر من نوع البيانات المصمم لتخزينه اعتمادًا على ما إذا كانت القيمة محسوبة في وقت التصريف compile time أو في وقت التشغيل runtime، إذ يحدث خطأ في وقت التصريف عندما يعثر البرنامج على خطأ أثناء محاولته إنشاء البرنامج؛ أما الخطأ في وقت التشغيل، فيحدث بعد تصريف البرنامج أثناء تنفيذه بالفعل. ضبطنا قيمة المتغير maxUint32 في المثال التالي إلى أعلى قيمة ممكنة: package main import "fmt" func main() { var maxUint32 uint32 = 4294967295 // Max uint32 size fmt.Println(maxUint32) } سيكون الخرج: Output4294967295 إذا أضفنا العدد 1 إلى المتغير maxUint32 في وقت التشغيل، فسيحدث التفاف إلى القيمة 0، أي سيكون الخرج: 0 سنعدِّل الآن البرنامج ونضيف العدد 1 إلى المتغير maxUint32 قبل وقت التصريف: package main import "fmt" func main() { var maxUint32 uint32 = 4294967295 + 1 fmt.Println(maxUint32) } إذا عثر المُصرّف compiler في وقت التصريف على قيمة كبيرة جدًا بحيث لا يمكن الاحتفاظ بها في نوع البيانات المحدد، فسيؤدي ذلك إلى حدوث خطأ طفحان overflow error، وهذا يعني أنّ القيمة المحسوبة كبيرة جدًا بالنسبة لنوع البيانات الذي حددته. إذًا سيظهر الخطأ التالي في الشيفرة السابقة لأنّ المصرف قد عثر على قيمة كبيرة جدًا لا تُلائم مجال النوع المحدَّد: prog.go:6:36: constant 4294967296 overflows uint32 ومعرفة أحجام بياناتك وما تتعامل معه يساعد على تجنب أخطاء الطفحان تلك في برنامجك مستقبلًا لذا يجب الانتباه! ستتعرّف الآن على كيفية تخزين القيم المنطقية أو البوليانية boolean. القيم المنطقية يمتلك نوع البيانات المنطقية قيمتين؛ إما صح true أو خطأ false، وتعرَّف على أنها من النوع bool عند التصريح عنها، كما تُستخدَم القيم المنطقية لتمثيل قيم الحقيقة المرتبطة بالجبر المنطقي في الرياضيات والذي يُعلم الخوارزميات في علوم الحاسوب، كما يُعبَّر عن القيمتَين true و false في جو بمحرفين صغيرين دائمًا وهما t و f على التوالي. تُعطينا العديد من العمليات الحسابية إجابات يتم تُقيَّم إما بصح أو خطأ مثل: أكبر من: 500 > 100 إجابتها true أو 1 > 5 إجابتها false. أقل من: 200 < 400 true أو 4 < 2 false. يساوي: 5 = 5 true أو 500 = 400 false. يمكنك تخزين قيمة منطقية في متغير بالصورة التالية: myBool := 5 > 8 ثم يمكنك طباعتها من خلال الدالة ()fmt.Println كما يلي: fmt.Println(myBool) بما أن العدد 5 ليس أكبر من 8، فسنحصل على الخرج التالي: false عندما تكتب المزيد من البرامج في جو، ستصبح أكثر درايةً بكيفية عمل القيم المنطقية وكيف يمكن للوظائف والعمليات المختلفة التي تُقيَّم إلى صح أو خطأ أن تغيِّر مسار البرنامج. السلاسل النصية Strings تُعَدّ السلسلة النصية سلسلةً من محرف (حرف أبجدي أو عدد أو رمز) واحد أو أكثر، ويمكن أن تكون سلسلة ثابتة أو متغيرة. يوجد صياغتان لتعريف السلاسل النصية في جو، فإذا استخدمت علامتَي الاقتباس الخلفية ``` لتمثيل السلسلة بداخلها، فهذا يعني أنك ستُنشئ سلسلةً أوليّةً raw string literal؛ أما إذا استخدمت علامتَي الاقتباس المزدوجة "، فهذا يعني أنك ستُنشئ سلسلةً مُفسّرةً interpreted string literal. السلسلة النصية الأولية هي تسلسل من المحارف بين علامتَي اقتباس خلفية ````` وتُسمى أيضًا علامتَي التجزئة الخلفية back ticks. سيُعرض كل شيء داخل هاتين العلامتين كما هو، وهذا لا يشمل علامتَي الاقتباس، فهما مجرد دليل لنقطة بداية ونهاية السلسلة مثل: a := `Say "hello" to Go!` fmt.Println(a) سيكون الخرج كما يلي: Say "hello" to Go! يُستخدَم رمز الشرطة المائلة الخلفية \ (انتبه؛ الشرطة المائلة للخلف نقصد بها الرمز \ وليس الرمز /) لتمثيل المحارف الخاصة ضمن السلسلة النصية، فإذا عُثر في سلسلة نصيّة مُفسّرة على الرمز n\ فهذا يعني الانتقال إلى سطر جديد، ولكن الشرطة المائلة الخليفة ليس لها أيّ معنى ضمن السلاسل الأولية كما في المثال التالي: a := `Say "hello" to Go!\n` fmt.Println(a) سيكون الخرج كما يلي: Say "hello" to Go!\n لاحظ أنّ السلسلة النصية السابقة هي سلسلة أوليّة، أي غير مُفسّرة، وبالتالي تُعرَض كما هي ولن يكون للرمز n\ أيّ معنى خاص. تُستخدَم السلاسل الأولية أيضًا لإنشاء سلاسل متعددة الأسطر: a := `This string is on multiple lines within a single back quote on either side.` fmt.Println(a) سيكون الخرج كما يلي: This string is on multiple lines within a single back quote on either side. لاحظ هنا تأثير السلاسل الأولية؛ إذ ذكرنا سابقًا أنها تطبع السلسلة كما هي. السلسلة النصية المفسرة هي سلسلة نصية موضوعة بين علامتَي اقتباس مزدوجتين " "، إذ سيعرض كل شيء موجود بداخل علامتي الاقتباس باستثناء الأسطر الجديدة وعلامات الاقتباس المزدوجة نفسها إلا ما جرى تهريبه منها، فإذا أردت إظهار هذه الرموز في هذه السلسلة، فيمكنك استخدام محرف الهروب \ قبلها مثل: a := "Say \"hello\" to Go!" fmt.Println(a) سيكون الخرج كما يلي: Say "hello" to Go! ستستخدِم غالبًا السلاسل المُفسرة لأنها تتعامل مع المحارف الخاصة وتسمح بتخطيها أيضًا وبالتالي تملك تحكمًأ أكبر. سلاسل صيغة التحويل الموحد UTF-8 تُعَدّ صيغة التحويل الموحد UTF-8 أو UTF اختصارًا للمصطلح الذي يترجم إلى صيغة تحويل نظام الحروف الدولي الموحد، وهذا الترميز وضع من قبل كل من روب بايك وكين تومسن لتمثيل معيار نظام الحروف الدولي الموحد للحروف الأبجدية لأغلب لغات العالم، وتُمثَّل فيه الرموز ذات العرض المتغير بحجم يتراوح بين بايت واحد وأربعة بايت للرمز الواحد. يدعم جو صيغة التحويل هذه دون أي إعداد خاص أو مكتبات أو حزم، ويمكن تمثيل الأحرف الرومانية مثل الحرف A بقيمة ASCII مثل الرقم 65، لكن سيكون ترميز UTF-8 للمحارف الخاصة مثل المحرف 世 مطلوبًا، كما يستخدِم جو النوع رون لبيانات UTF-8. a := "Hello, 世界" يمكنك استخدام الكلمة المفتاحية range داخل الحلقة for للتكرار على فهارس أيّ سلسلة نصية، إذ ستُغطى الحلقات لاحقًا في المقالات القادمة، كما تُستخدم الحلقة for في المثال التالي لحساب عدد البايتات ضمن سلسلة محددة: package main import "fmt" func main() { a := "Hello, 世界" for i, c := range a { fmt.Printf("%d: %s\n", i, string(c)) } fmt.Println("length of 'Hello, 世界': ", len(a)) } عرّفنا المتغير a في المثال السابق وأسندنا إليه السلسة النصية Hello, 世界 التي تحتوي على محارف UTF-8، ثم استخدمنا حلقة for مع الكلمة المفتاحية range للتكرار على محارف السلسلة، إذ تُفهرس الكلمة المفتاحية range عناصر السلسلة المحددة وتعيد قيمتين الأولى هي فهرس البايت والثانية هي قيمة البايت ا-لتي تمثِّل هنا محرف السلسلة- وبترتيب ورودها نفسه في السلسلة. تُستخدَم الدالة fmt.Printf كما هي العادة من أجل الطباعة على الشاشة، حيث حددنا لها التنسيق بالصورة d: %s\n%، إذ تشير d% إلى وجود عدد صحيح مكانها وهو الفهرس i الذي مثّل المُعطى الثاني للدالة، والرمز s% إلى وجود سلسلة نصية أو محرف وهو المحرف c المُمثّل بالمُعطى الثالث والرمز الأخير للانتقال إلى سطر جديد، ولاحظ أيضًا أننا وضعنا c ضمن الدالة string وذلك لكي تعامل معاملة سلسلة، ثم طبعنا أخيرًا طول المتغير a من خلال استخدام الدالة len. كما ذكرنا سابقُا؛ الرون هو اسم بديل للنوع int32 ويمكن أن يتكون من واحد إلى أربعة بايت، إذ يُستخدم 3 بايتات لتمثيل المحرف 世 والكلمة المفتاحية range تُدرك ذلك، وبالتالي عندما تصل إليه تقرأ 3 بايتات متتالية على أنها فهرس لمحرف واحد وهذا واضح من الخرج التالي. 0: H 1: e 2: l 3: l 4: o 5: , 6: 7: 世 10: 界 length of 'Hello, 世界': 13 لاحظ أنه عند طباعة الطول حصلنا على 13، بينما عدد الفهارس هو 8 وهذا يُفسّر ماذكرناه في الأعلى. لن تعمل دائمًا مع سلاسل UTF-8، ولكن عندما تعمل معها ستكون مُدركًا لسبب تمثيلها باستخدام النوع رون الذي يمكن أن يكون طوله من 8 إلى 32 بت وليس int32 واحدة فقط. التصريح عن أنواع البيانات للمتغيرات بعد أن تعرفت على أنواع البيانات الأولية المختلفة، سننتقل إلى كيفية إسناد هذه الأنواع إلى المتغيرات في جو. يمكننا تحديد متغير باستخدام الكلمة المفتاحية var متبوعة باسم المتغير ونوع البيانات المطلوب، إذ سنصرّح في المثال التالي عن متغير يسمى pi من النوع float64، أي الكلمة المفتاحية var هي أول ما يُكتب عند التصريح عن متغير، ثم اسم المتغير ثم نوع البيانات: var pi float64 يمكن إسناد قيمة ابتدائية للمتغير اختياريًا: var pi float64 = 3.14 تُعَدّ جو لغةً ثابتة الأنواع statically-typed language مثل لغة C و Java و ++C، وهذا يعني أن كل تعليمة في البرنامج تُفحَص في وقت التصريف، كما يعني أيضًا أنّ نوع البيانات مرتبط بالمتغير؛ أما في اللغات ديناميكية الأنواع مثل بايثون أو PHP، فيرتبط نوع البيانات بالقيمة، فقد يُصرَّح مثلًا عن نوع البيانات في جو عند التصريح عن المتغير كما يلي: var pi float64 = 3.14 var week int = 7 يمكن أن يكون كل من هذه المتغيرات نوع بيانات مختلف إذا عرّفته بطريقة مختلفة، لكن بعد التصريح عنه لأول مرة لن تكون قادرًا على تغيير ذلك؛ أما في لغة PHP فالأمر مختلف، إذ يرتبط نوع البيانات بالقيمة كما يلي: $s = "sammy"; // يأخذ المتغير ديناميكًا نوع سلسلة نصية $s = 123; // يأخذ المتغير ديناميكيًا نوع عدد صحيح كان المتغير s سلسلةً نصيةً ثم تغيَّر إلى عدد صحيح اوتوماتيكيًا تبعًا للقيمة المُسندة إليه. سنتعرّف الآن على أنواع البيانات الأكثر تعقيدًا مثل المصفوفات. المصفوفات Arrays تُعَدّ المصفوفة متغيرًا واحدًا يتألف من تسلسل مرتب من العناصر ذات النوع نفسه، وكل عنصر في المصفوفة يمكن تخزين قيمة واحدة فيه. عناصر المصفوفة تتميز عن بعضها من خلال رقم محدد يعطى لكل عنصر يسمى فهرس index، وأول عنصر في المصفوفة دائمًا يكون فهرسه 0. تُحدَّد سعة المصفوفة لحظة إنشائها، وبمجرد تعريف حجمها لا يمكن تغييره، وبالتالي بما أنّ حجم المصفوفة ثابت، فهذا يعني أنه يخصص الذاكرة مرةً واحدةً فقط، وهذا يجعل المصفوفات غير مرنة نوعًا ما للعمل معها، لكنه يزيد من أداء برنامجك، ولهذا السبب تُستخدم المصفوفات عادةً عند تحسين البرامج. تُعَدّ الشرائح Slices التي ستتعرف عليها بعد قليل أكثر مرونةً، إذ تُعَدّ نوعًا من البيانات القابلة للتغيير وتكوّن ما قد تعتقد أنه مصفوفات بلغات أخرى. تُعرّف المصفوفات من خلال التصريح عن حجمها ثم نوع البيانات ثم القيم المحددة بين الأقواس المعقوصة {}. [capacity]data_type{element_values} مثال: [3]string{"blue coral", "staghorn coral", "pillar coral"} يمكنك إسناد المصفوفة إلى متغير ثم طباعتها كما يلي: coral := [3]string{"blue coral", "staghorn coral", "pillar coral"} fmt.Println(coral) سيكون الخرج كما يلي: [blue coral staghorn coral pillar coral] الشرائح Slices تُعَدّ الشريحة تسلسلًا مرتبًا من العناصر وطولها قابلًا للتغيير، إذ يمكن للشرائح أن تزيد حجمها ديناميكيًا. إذا لم يكن للشريحة حجم ذاكرة كافي لتخزين العناصر الجديدة عند إضافة عناصر جديدة إلى شريحة، فستطلب ذاكرةً أكبر من النظام حسب الحاجة، ولهذا السبب هي شائعة الاستخدام أكثر من المصفوفات. يُصرّح عن الشرائح من خلال تحديد نوع البيانات مسبوقًا بقوس فتح وإغلاق مربع [] والقيم بين أقواس معقوصة {}، وفيما يلي مثالًا عن شريحة من الأعداد الصحيحة: []int{-3, -2, -1, 0, 1, 2, 3} شريحة من الأعداد الحقيقية: []float64{3.14, 9.23, 111.11, 312.12, 1.05} شريحة من السلاسل النصية: []string{"shark", "cuttlefish", "squid", "mantis shrimp"} يمكنك أيضًا إسنادها إلى متغير: seaCreatures := []string{"shark", "cuttlefish", "squid", "mantis shrimp"} ثم طباعة هذا المتغير: fmt.Println(seaCreatures) سيكون الخرج كما يلي: [shark cuttlefish squid mantis shrimp] يمكنك استخدام الكلمة المفتاحية append لإضافة عنصر جديد إلى الشريحة، وسنضيف السلسلة seahorse إلى الشريحة السابقة على سبيل المثال كما يلي: seaCreatures = append(seaCreatures, "seahorse") سنطبع الشريحة الآن للتأكد من نجاح العملية: fmt.Println(seaCreatures) سيكون الخرج كما يلي: [shark cuttlefish squid mantis shrimp seahorse] كما تلاحظ، إذا كنت بحاجة إلى إدارة حجم غير معروف من العناصر، فستكون الشريحة الخيار الأفضل. الخرائط Maps تُعَدّ الخرائط -أو الروابط- نوع بيانات مختلف يُمثّل قاموسًا أو رابطًا يربط قيمة مع مفاتحها، إذ تستخدِم الخرائط أزواج المفاتيح والقيم لتخزين البيانات، كما تُعَدّ مفيدةً جدًا عندما يتطلب الأمر البحث عن القيم بسرعة بواسطة الفهارس أو المفاتيح هنا، فمثلًا في حالة كان لديك مستخدِمين وتريد تسجيلهم في بنية بيانات تربط معلومات كل مستخدم -أي القيمة- بعدد فريد لهذا المستخدِم -أي مفتاح-، فالخرائط أُنشئت لهذا الأمر. تُنشأ الخرائط باستخدام الكلمة المفتاحية map متبوعة بنوع بيانات المفاتيح بين قوسين معقوفين [] متبوعًا بنوع بيانات القيم، ثم أزواج القيم والمفاتيح في أقواس معقوصة. map[key]value{} عادةً ما تُستخدَم الخرائط للاحتفاظ بالبيانات المرتبطة ببعضها كما عرضنا في المثال السابق أو كما في المثال التالي: map[string]string{"name": "Sammy", "animal": "shark", "color": "blue", "location": "ocean"} يمكنك أن تلاحظ أنه بالإضافة إلى الأقواس المعقوصة، توجد أيضًا نقطتان في جميع أنحاء الخريطة، إذ تمثل الكلمات الموجودة على يسار النقطتين المفاتيح وعلى اليمين القيم، كما تجدر الملاحظة أيضًا إلى أنّ المفاتيح يمكن أن تكون من أيّ نوع بيانات في جو، فالمفاتيح الموجودة في الخريطة (الرابطة) أعلاه هي الاسم والحيوان واللون والموقع، ويفضل أن تكون من الأنواع القابلة للمقارنة وهي الأنواع الأولية primitive types مثل السلاسل النصية string والأعداد الصحيحة ints وما إلى ذلك، إذ يُحدد النوع الأساسي من خلال اللغة ولا يُنشأ من دمج أيّ أنواع أخرى، كما يمكن للمستخدِم أيضًا تحديد أنواع جديدة، إلا أنه يُفضّل إبقاءها بسيطةً لتجنب أخطاء البرمجة. سنخزّن الخريطة أعلاه ضمن متغير ثم سنطبعها: sammy := map[string]string{"name": "Sammy", "animal": "shark", "color": "blue", "location": "ocean"} fmt.Println(sammy) سيكون الخرج كما يلي: map[animal:shark color:blue location:ocean name:Sammy] إذا أردت الوصول إلى لون سامي sammy وطباعته فيمكنك كتابة ما يلي: fmt.Println(sammy["color"]) سيكون الخرج كما يلي: blue تُعَدّ الخرائط أو الروابط عناصر مهمة في كثير من البرامج التي قد تُنشأ في جو كونها توفِّر إمكانية فهرسة عملية الوصول إلى البيانات. خاتمة إلى هنا تكون قد تعرّفت على أنواع البيانات الأساسية في جو إضافةً إلى بُنى البيانات المهمة مثل المصفوفات والشرائح والخرائط، إذ ستكوِّن الفروق بين هذه الأنواع أهميةً كبيرةً لك أثناء تطوير مشاريعك باستخدام جو، وستجعلك تدرك أهمية ذلك أكثر، كما أنّ فهمك الجيد لأنواع البيانات سيجعلك قادرًا على معرفة متى وكيف وفي أيّ وقت ستستخدِم أو ستغيّر نوع بيانات المتغير حسب الحاجة. ترجمة -وبتصرف- للمقال Understanding Data Types in Go لصاحبه Gopher Guides. اقرأ أيضًا المقال السابق: كتابة التعليقات في لغة جو Go دليلك الشامل إلى أنواع البيانات الدليل السريع إلى لغة البرمجة Go الدروس المستفادة من البرمجة بلغة Go 3 طرائق لنسخ الملفات في Go
  12. التعليقات هي عبارات دخيلة على الشيفرات البرمجية وليست جزءًا منها، إذ يتجاهلها المُصرّف compiler والمُفسّر interpreter، كما يُسهِّل تضمين التعليقات في الشيفرات من قراءتها وفهمها ومعرفة وظيفة كل جزء من أجزائها، لأنها توفر معلومات وشروحات حول ما يفعله كل جزء من البرنامج. يمكن أن تكون التعليقات بمثابة مُذكِّرات لك بناءً على الغرض من البرنامج، أو يمكنك كتابتها لمساعدة المبرمجين الآخرين على فهم الشيفرة، ويُستحسَن كتابة التعليقات أثناء كتابة البرامج أو تحديثها لأنّك قد تنسى السياق وتسلسل الأفكار لاحقًا، و قد تكون التعليقات المكتوبة لاحقًا أقل فائدةً على المدى الطويل. صياغة التعليقات تبدأ التعليقات بالمحرفَين //وتنتهي بنهاية السطر الحالي، وغالبًا ما نضع فراغًا بعد هذين المحرفين لجعل التعليق مُرتبًا أكثر مثل: // This is a comment // هذا تعليق على الشيفرة تُتجاهل التعليقات كما ذكرنا أي وكأنها غير موجودة، وبالتالي عند تشغيل البرنامج لن يطرأ أي حدث يُشير إلى وجودها، فالتعليقات ضمن التعليمات البرمجية مُخصصة ليقرأها البشر وليس للحاسب، ففي برنامج "Hello، World!‎" مثلًا يمكنك إضافة التعليقات كما يلي: package main import ( "fmt" ) func main() { // ‫اطبع العبارة "Hello, World!‎" إلى الطرفية fmt.Println("Hello, World!") } مثال آخر لوضع التعليقات ضمن حلقة for التي تُكرِّر تنفيذ كتلة برمجية أو مجموعة من التعليمات البرمجية: package main import ( "fmt" ) func main() { // عرف المتغير التالي على أنه شريحة من سلاسل نصية sharks := []string{"hammerhead", "great white", "dogfish", "frilled", "bullhead", "requiem"} // حلقة تكرار للمرور على كل عنصر من عناصر القائمة وطباعته for _, shark := range sharks { fmt.Println(shark) } } نستنتج من المثالين السابقين أن التعليقات يجب أن تكون على سويّة التعليمات التي توضحها، أي بالمسافة البادئة نفسها للشيفرة التي تُعلّق عليها، وبالتالي يجب أن يكون تعليق بدون مسافة بادئة تسبُقه من أجل تعريف دالة بدون مسافة بادئة، وكل مقطع برمجي مسبوق بمسافة بادئة سيكون له تعليقات تتماشى مع هذه المسافة. لاحظ على سبيل المثال كيف سنُعلّق على الدالة main، ولاحظ كيف سنضع التعليقات بما يتماشى مع كل مقطع مسبوق بمسافة بادئة: package main import "fmt" const favColor string = "blue" func main() { var guess string // إنشاء حلقة تكرار for { // اطلب من المستخدم تخمين لوني المفضل fmt.Println("Guess my favorite color:") // اقرأ ما أدخله المستخدم واطبع النتيجة if _, err := fmt.Scanln(&guess); err != nil { fmt.Printf("%s\n", err) return } // تأكد إن خمن اللون الصحيح if favColor == guess { // اللون الذي أدخله صحيح fmt.Printf("%q is my favorite color!\n", favColor) return } // اللون الذي أدخله خطأ ونطلب منه تكرار الإجابة fmt.Printf("Sorry, %q is not my favorite color. Guess again.\n", guess) } } تهدف التعليقات كما ذكرنا إلى مساعدة المبرمجين سواءً كان المبرمج الذي كتب الشيفرة أو أي شخص آخر يستخدِم المشروع أو يساعد فيه، كما يجب أن تُحفظ التعليقات وتحدّث بطريقة صحيحة بما يتماشى مع مستوى التعليمات البرمجية ومحتواها وإلا فمن الأفضل عدم كتابته. يجب أن يكون التعليق على شيفرة ما هو توضيح لمضمونها أو للفكرة التي أنتجت هذه الشيفرة وليس كتابة أسئلة أو شيء آخر، أي يجب أن تُجيب التعليقات عن السبب الذي أنتج الشيفرة. التعليقات الكتلية يمكن استخدام التعليقات الكتليّة Block Comments -أي عدة أسطر من التعليقات- لتوضيح الشيفرات البرمجية المعقدة التي تتوقع بأن لا يكون القارئ على دراية بها، إذ تنطبق هذه التعليقات الطويلة على جزء من الشيفرة أو جميعها، كما توضع في نفس مستوى المسافة البادئة للشيفرة، كما يمكن كتابة التعليقات الكتلية بطريقتين؛ الأولى من خلال المحرفَين السابقَين // وتكرارهما من أجل كل سطر مثل: // First line of a block comment // Second line of a block comment أما الطريقة الثانية، فمن خلال علامة الفتح */ التي نضعها في بداية التعليق وعلامة الإغلاق */ التي نضعها في نهاية التعليق، إذ يُستخدَم // عادةً مع عمليات التوثيق؛ أما /* ... */ لتصحيح الأخطاء debugging. /* تعليق طويل يمتد على أكثر من سطر */ سنستخدم التعليقات الكتليّة في المثال التالي لتوضيح الدالة ()MustGet: // ‫تأخذ الدالة MustGet رابطًا وتعيد الصفحة الرئيسية له // وإن حصل أي خطأ ستظهره func MustGet(url string) string { resp, err := http.Get(url) if err != nil { panic(err) } defer resp.Body.Close() var body []byte if body, err = ioutil.ReadAll(resp.Body); err != nil { panic(err) } return string(body) } من الشائع رؤية التعليقات الكتلية في بداية الدوال التي تُقدّمها جو، وهذه التعليقات هي التي تُنشئ أيضًا توثيق الشيفرة البرمجية الخاصة بك، كما تٌستخدَم التعليقات الكتلية أيضًا عندما تتطلب الشيفرة شرحًا كاملًا. تجنب قدر الإمكان استخدام التعليقات الكتليّة باستثناء الأهداف التوثيقية، وثِق بقدرة المبرمجين الآخرين في فهم التعليقات المختصرة إلا إذا كان لديك هدفًا محددًا من كتابة هذه التعليقات الطويلة لأغراض تعليمية مثلًا. التعليقات السطرية توضَع التعليقات السطرية Inline comments على السطر نفسه الذي توجد فيه التعليمة البرمجية، وهي مثل التعليقات الأخرى أي تبدأ بالمحرفَين `// ومسافة بيضاء واحدة، إذ تبدو التعليقات الضمنيّة عمومًا كما يلي: [code] // تعليق سطري يشرح سطر الشيفرة لا ينبغي الإكثار من استخدام التعليقات السطرية، ولكن يمكن أن تكون فعالة لشرح الأجزاء الصعبة من الشيفرة عند استخدامها في محلها، وقد تكون مفيدةً أيضًا إذا ظننت أنَّك قد لا تتذكر سطرًا من الشيفرة في المستقبل أو إذا كنت تتعاون مع شخص قد لا يكون على دراية بجميع جوانب الشيفرة، فإذا كنت لا تستخدِم الكثير من الرياضيات في برامجك في جو Go ولم يكن هناك توضيح مسبق على سبيل المثال، فقد لا تعلم أنت أو المتعاونون معك أنّ الشيفرة التالية ستنشئ عددًا عقديًا، لذلك قد ترغب في إضافة تعليق سطري كما يلي: z := x % 2 // ‫ احصل على باقي قسمة العدد x يمكن أيضًا استخدام التعليقات السطرية لشرح السبب وراء فعل شيء ما أو لتعطي بعض المعلومات الإضافية كما في المثال التالي: x := 8 // إسناد قيمة للعدد يجب استخدام التعليقات السطرية عند الضرورة وعندما توفِّر إرشادات مفيدةً للشخص الذي يقرأ البرنامج. تعليق جزء من الشيفرة بدواعي الاختبار والتنقيح يمكن أيضًا استخدام المحرفَين // أو رمزي الفتح والإغلاق /*...*/ لتعليق جزء من الشيفرة وتعطيله أثناء اختبار أو تنقيح البرنامج الذي تعمل عليه بالإضافة إلى استخدام التعليقات على أساس وسيلة لتوثيق الشيفرة، أي عندما تواجه أخطاء بعد إضافة أسطر جديدة إلى الشيفرة، فسترغب في تعليق بعضها لمعرفة موضع الخلل. يمكن أن يتيح لك استخدام الرمزين /*...*/ تجربة بدائل أخرى أثناء إعداد الشيفرة أو للتعليق على التعليمات البرمجية التي تفشل أثناء استمرار العمل على أجزاء أخرى من التعليمات البرمجية الخاصة بك. // دالة تضيف عددين func addTwoNumbers(x, y int) int { sum := x + y return sum } // دالة تضرب عددين func multiplyTwoNumbers(x, y int) int { product := x * y return product } func main() { /* ‫علقنا في هذا المقال استدعاء الدالة addTwoNumbers لأنه يولد خطأ لم نكتشفه فلا نريد إيقاف الشيفرة a := addTwoNumbers(3, 5) fmt.Println(a) */ m := multiplyTwoNumbers(5, 9) fmt.Println(m) } يتيح لك تعليق الشيفرة البرمجية تجربة عدة طرق ومقاربات برمجية، بالإضافة إلى مساعدتك على العثور على مصدر الخطأ من خلال التعليق المنهجي لبعض أجزاء البرنامج وتشغيلها، وتذكر أنك تستخدمه لأغراض الاختبار والتنقيح. خاتمة يساعدك استخدام التعليقات في برامج جو على جعل برامجك أكثر قابلية للقراءة سواءً لك أو لغيرك، كما ستسهِّل التعليقات المناسبة وذات الصلة والمفيدة من تعاون الآخرين معك في مشاريع البرمجة وتجعل شيفرتك أكثر وضوحًا. سيسمح لك التعليق الصحيح على الشيفرة في جو باستخدام الأداة Godoc، وهي أداة تستخرِج التعليقات من التعليمات البرمجية الخاصة بك وتُنشئ وثائق لبرنامج جو الخاص بك. ترجمة -وبتصرُّف- للمقال How To Write Comments in Go لصاحبه Gopher Guides. اقرأ أيضًا المقال السابق: التعرف على GOPATH في لغة جو Go الدليل السريع إلى لغة البرمجة Go بناء خادم بروتوكول التحكم في الإرسال TCP متزامن في لغة البرمجة Go
  13. ستفهم في هذه المقالة ماذا يعني GOPATH وكيف يعمل وكيفية إعداده لأنها خطوة هامة عند إعداد بيئة التطوير، بالإضافة إلى فهم كيفية عثور جو على الملفات المصدرية وتثبيتها وإنشائها. في هذه المقالة سوف نستخدم GOPATH عند الإشارة إلى مفهوم بنية المجلد التي سنناقشها، كما سنستخدِم GOPATH$ للإشارة إلى متغير البيئة الذي سيستخدِمه جو للعثور على بنية المجلد. تُعَدّ مساحة عمل جو Go Workspace الطريقة التي يدير بها جو ملفات المصدر والملفات الثنائية والكائنات المخزنة مؤقتًا التي ستُستخدَم في وقت لاحق لعمليات التصريف السريع، وعادةً ما تكون لديك مساحة عمل واحدة فقط، إذ من الممكن أن تكون لديك أكثر لكن يُستحسن واحدة فقط، كما يكون GOPATH هو مجلد الجذر لها. انتبه إلى أنه بدءًا من الإصدار 1.13 أضاف مطوروا لغة Go آلية جديدة لإدارة المكتبات التي يعتمد عليها مشروع مكتوب بلغة جو تدعى وحدات جو Go Modules -سنتحدث عنها لاحقًا- وأصبحت هذه الآلية الطريقة المعتمد حاليًا في إضافة إعتماديات المشروع وإدارة هيكلة مجلده الرئيسي، وصحيح أن هذه الآلية قد حلت مكان GOPATH إلا أنه من الجيد فهم الآلية القديمة هذه التي قد تكون مستعملة في مشاريع قديمة أو تمر معك في شيفرة ما، ولمزيد من التفاصيل ومعرفة أحدث المستجدات عد إلى توثيق workspaces الرسمي من لغة جو. ضبط متغير البيئة GOPATH$ يحمل متغير البيئة GOPATH$ قائمةً تتضمن أماكن ليبحث فيها جو عن مساحات العمل. يتوقع جو في الحالة الافتراضية أنّ موقع GOPATH الخاص بك هو HOME/go$، حيث HOME$ هو المجلد الجذر لحساب المستخدِم الخاص بك على الحاسب، ويمكنك تغيير ذلك من خلال تعديل متغير البيئة GOPATH$ حسب توثيق جو. الفرق بين GOPATH$ و GOROOT$ يُعَدّ GOROOT$ المكان الذي تتواجد فيه شيفرة جو والمصرِّف compiler والأدوات الأخرى التابعة له، أي أنه لا يتضمن الشيفرة المصدرية الخاصة بك، وعادةً ما يكون مسار GOROOT$ هو usr/local/go/ ومسار GOPATH$ هو HOME/go$، كما تجدر الإشارة إلى أنك لست بحاجة إلى إعداد المتغير GOROOT$ بعد الآن، إذ كان ذلك مطلبًا في السابق. مكونات مساحة العمل توجد ثلاثة مجلدات داخل مساحة عمل جو أو GOPATH وهي bin و pkg و src، كما يملك كل مجلد من هذه المجلدات وظيفةً خاصةً في جو. . ├── bin ├── pkg └── src └── github.com/foo/bar └── bar.go يمثّل المجلد GOPATH/bin$ المكان الذي توضع فيه الملفات الثنائية (التنفيذيّة) التي تم تثبيتها بواسطة الأمر go install. يستخدِم نظام التشغيل متغير البيئة PATH$ للعثور على الملفات الثنائية التي يمكن تنفيذها بدون كتابة المسار الكامل، لذا يوصى بإضافة المجلد bin إلى المتغير PATH$ العام، فإذا لم تضف GOPATH/bin$ مثلًا إلى متغير البيئة PATH$، فسنحتاج إلى كتابة ما يلي: $ $GOPATH/bin/myapp أما إذا كان مُضافًا إليه لكان بالإمكان تشغيله بكتابة ما يلي: $ myapp توضع في المجلد GOPATH/pkg$ ملفات الكائنات المُصرّفة مسبقًا والتي تُستخدَم لتسريع عملية التصريف في وقت لاحق، ومن الجدير بالذكر أنّ معظم المطورين لن يحتاجوا إلى التعامل مع هذا المجلد، فإذا كنت تواجه مشكلات في التصريف، فيمكنك حذف هذا المجلد بأمان وسيُعيد جو بناءه. توضع في المجلد src شيفرة جو المصدرية وهي الملفات التي يتم كتابتها وإنشاؤها باستخدام لغة جو والتي تكون لاحقتها ‎.go، الملفات المصدرية يستخدمها مُصرّف جو لإنشاء ملفات قابلة للتنفيذ (ملفات ثنائية يمكن تشغيلها على نظامك لتنفيذ المهام التي تتضمنها). وانتبه جيدًا مرةً أخرى إلى أنّ هذه الملفات ليست الملفات الموجودة في GOROOT$، كما ستوضع هذه الملفات في المسار GOPATH/src/path/to/code$ أثناء كتابة برامج وحزم ومكتبات جو. ما هي الحزم؟ تُعَدّ الحزم طريقةً بسيطةً لتجزئة برنامجك إلى أجزاء أصغر مُقسّمة حسب الغرض أو الوظيفة، كما يُمكن الإشارة للحزم على أنها مكتبات libraries أو وحدات modules، تركيب الحزم مع بعضها يشكل مُجمل برنامجك. الشيفرات التي تُكتب في جو تُنظّم ضمن حزم، إذ تمثل الحزمة جميع الملفات الموجودة في مجلد واحد على القرص. تتبع جو القواعد التالية في كيفية تقسيم برنامج إلى حزم: تُخزّن الحزم مع جميع ملفات جو المصدرية المكتوبة من قبل المستخدِم ضمن المجلد GOPATH/src$. الحزمة غالبًا عبارة عن مجلد داخل مشروعك به الملفات التي تحمل اسم الحزمة. لابد من وجود حزمة واحدة على الأقل في أي برنامج أو مكتبة. إذا كان البرنامج عبارة عن برنامج تنفيذي (وليس مكتبة - library) فإنه يجب وجود حزمة باسم main (أي package main) تكون هي مدخل البرنامج كما رأينا سابقًا. وكتذكير لما ذكرناه سابقًا: لابد لكل ملف شفرة برمجية في Go أن ينتمي إلى حزمة (package) ما. لابد لكل حزمة في Go أن تنتمي إلى مجلد ما. لا يمكن لحزمتين التواجد على مستوى نفس المجلد، لكن يمكن لعدة ملفات أن تنتمي إلى نفس الحزمة (يعني مجلد به عدة ملفات). يمكن أن تتواجد حزمة داخل حزمة أخرى لكن كلٌ في مجلد فرعي على حِدى. يمكن للمجلد الرئيسي لمشروعك أن يحتوي على حزمة ما، واحدة فقط، باقي الحزم الخاصة به يمكنها أن تتواجد في مجلدات فرعية. غياب حزمة main من برنامج ما، يجعل منه مكتبة فقط وليس برنامجا تشغيليا قائما بحد ذاته. إذا كانت الشيفرة الخاصة بك موجودةً في المسار GOPATH/src/blue/red$ فيجب أن يكون اسم الحزمة التي تنتمي إليها الشيفرة هو red، ويمكنك استيراد هذه الحزمة كما يلي: import "blue/red" في حالة الحزم المتواجدة ضمن مستودعات على مواقع استضافة الشيفرات مثل GitHub و BitBucket، فيجب تضمين المسار الكامل في عملية الاستيراد، فإذا أردنا استيراد الشيفرة المصدرية من الرابط https://github.com/gobuffalo/buffalo، فسنكتب ما يلي: import "github.com/gobuffalo/buffalo" وستُخزَّن في الموقع التالي على القرص: $GOPATH/src/github.com/gobuffalo/buffalo خاتمة تعرّفت في هذه المقالة على المجلد GOPATH الذي يحتوي على مجموعة من المجلدات التي يتوقع جو وجود الشيفرة المصدرية الخاصة بك بداخلها، بالإضافة إلى ماهية تلك المجلدات وما تحتوي عليها، كما تعرّفت على كيفية تغيير الموقع الافتراضي HOME/go$ له، وتعرّفت على الآلية التي يبحث بها جو عن الحزم داخل بنية المجلد. قُدّمت Go Modules في الإصدار 1.11 من جو، وتهدف إلى استبدال مساحات عمل جو و GOPATH، وعلى الرغم من أنه يُوصى ببدء استخدامها إلا أنّ بعض البيئات قد لا تكون جاهزةً لاستخدامها مثل بيئات الشركة corporate environments. يُعَدّ GOPATH أكثر الجوانب تعقيدًا في إعداد جو ولكن بمجرد إعداده يمكنك نسيانه بعدها على الغالب. ترجمة -وبتصرُّف- للمقال Understanding the GOPATH لصاحبه Gopher Guides. اقرأ أيضًا المقال السابق: كتابة برنامجك الأول في جو Go تثبيت لغة جو وإعداد بيئة برمجة محلية لها على ويندوز الدليل السريع إلى لغة البرمجة Go بناء خادم بروتوكول التحكم في الإرسال TCP متزامن في لغة البرمجة Go
  14. ستتعلم في هذه المقالة كيفية كتابة برنامج بسيط باستخدام لغة جو، إذ سنحاول اتباع العادة التي جرت عليها دروس تعلم لغات البرمجة، وهي ببساطة كتابة جملة "Hello, World!‎" أي "أهلًا بالعالم!"، لكن سنجعل الأمور أكثر متعةً من خلال جعل البرنامج يسأل المستخدِم عن اسمه لكي يطبع الاسم بجانب عبارة الترحيب، وبعد الانتهاء من كتابة البرنامج سيكون خرج البرنامج مشابهًا للخرج التالي: Please enter your name. Sammy Hello, Sammy! I'm Go! المتطلبات يجب أن تكون قد أعددت بيئة تطوير جو على حاسبك، فإذا لم يكن لديك بيئة تطوير جاهزة، فيمكنك العودة إلى المقالات السابقة واتباع التعليمات: تثبيت لغة جو وإعداد بيئة برمجة محلية على أبونتو. تثبيت لغة جو وإعداد بيئة برمجة محلية على نظام ماك macOS. تثبيت لغة جو وإعداد بيئة برمجة محلية على ويندوز. الخطوة 1 - كتابة برنامج "Hello, World!‎" الأساسي افتح محرر نصوص سطر الأوامر مثل نانو nano وانشئ ملفًا جديدًا: $ nano hello.go اكتب البرنامج التالي بعد فتح الملف النصي في الطرفية: package main import "fmt" func main() { fmt.Println("Hello, World!") } مكونات الشيفرة: الحزمة package: هي كلمة مفتاحية keyword في جو تحدِّد اسم الحزمة التي ينتمي لها هذا الملف، أي الملف الذي تكتب فيه البرنامج، إذ لا بدّ أن يكون لكل ملف حزمة ما، ولا بدّ أن تنتمي كل حزمة في جو إلى مجلد ما، كما لا يمكن لحزمتَين التواجد على مستوى نفس المجلد، لكن يمكن لعدة ملفات أن تنتمي إلى نفس الحزمة (يعني مجلد به عدة ملفات)، كما يمكن أن تتواجد حزمة داخل حزمة أخرى لكن كلٌ في مجلد فرعي على حِدى. في مثالنا السابق، أعطينا main كاسم لحزمتنا، وهو اسم خاص، حيث يُعامل مُصرّف compiler لغة جو هذه الحزمة على أنها مدخل البرنامج، أي أن التعليمات الموجودة في هذه الحزمة يتم تشغيلها أولًا. أسبقنا اسم الحزمة بالكلمة المفتاحية package. import كلمة مفتاحية أخرى وتعني استرِد أو اجلِب المكتبة الفلانية أو الحزمة الفلانية. fmt اختصار format أو formatting وهي مكتبة قياسية standard library تأتي مع جو، وهي خاصة ببناء وطباعة النص. لاحظ أن اسم المكتبات أو الحزم المُراد استيرادها دائما ما يتم إحاطتها بعلامة اقتباس "". في التعبير fmt.Println استعملنا دالة Println من الحزمة fmt التي استوردناها، ولاستعمال أيّ حزمة في جو يكفي كتابة اسمها ثم نقطة ثم اسم الدالة التي تريد استعمالها، وهنا أردنا طباعة نص "Hello, World!‎"، لذا لاحظ أننا مررنا القيمة بين علامتَي اقتباس "" ﻷنها سلسلة نصية string. احفظ الملف البرمجي الذي أنشأته واخرج من المحرر عن طريق كتابة CTRL + X وتأكيد الخروج بالضغط على المفتاح Y عندما يطلب منك، ويمكنك الآن تجربة برنامجك. الخطوة 2 - تشغيل البرنامج يمكنك تشغيل أيّ برنامج مكتوب بلغة جو من خلال كتابة الكلمة المفتاحية go متبوعة باسم الملف، وبالتالي لتشغيل البرنامج السابقة سنكتب: $ go run hello.go الخرج: Hello, World! التفسير: بدايةً يُصرِّف البرنامج قبل تشغيله، أي إنشاء برنامج قابل للتنفيذ يمكن للحاسوب فهمه وتنفيذه، إذ يحوَّل إلى ملف ثنائي، وبالتالي عند استدعاء go run سيُصرَّف الملف البرمجي ثم يُشغل الملف التنفيذي الناتج. غياب حزمة main من برنامج جو يجعل منه مكتبة فقط وليس برنامجًا بحد ذاته (حزمة تنفيذية)، لذا تتطلب برامج جو وجود هذه الحزمة، كما تتطلب وجود دالة ()main واحدة تعمل على أساس نقطة دخول للبرنامج بحيث لا تأخذ هذه الدالة أيّ وسائط ولا تُعيد أيّ قيم. تُنفَّذ الشيفرة أو البرنامج بعد انتهاء عملية التصريف من خلال وضع الدالة ()main في الحزمة main، والتي تتضمن طباعة السلسلة النصية "Hello, World!‎" عن طريق استدعاء دالة fmt.Println أي ("!fmt.Println("Hello, World، وتُدعى السلسلة النصية وسيطًا لتلك الدالة بما أنها تُمرَّر إليها. ملاحظة: لا تُطبَع علامتَا الاقتباس الموجودتان على جانبي Hello, World!‎ على الشاشة لأنك تستخدمهما لإخبار جو من أين تبدأ السلسلة الخاصة بك وأين تنتهي. ستستكشف في الخطوة التالية كيفية جعل البرنامج تفاعليًّا أكثر. الخطوة 3 - إدخال معلومات من المستخدم لاستخدامها في البرنامج سيطبع البرنامج السابق الخرج نفسه في كل مرة تستدعيه بها، كما يمكنك إضافة بعض التعليمات إلى البرنامج بحيث تجعله يطلب من المستخدِم إدخال اسمه لكي يُطبع بجانب عبارة الترحيب. بإمكانك تعديل برنامجك السابق، ولكن يُفضَّل أن تُنشئ برنامجًا جديدًا يسمى greeting.go باستخدام المحرِّر نانو: nano greeting.go أضف التعليمات التالية: package main import ( "fmt" ) func main() { fmt.Println("Please enter your name.") } استخدامنا دالة fmt.Println لطباعة النص على الشاشة كما في المرة السابقة. أضف الآن السطرvar name string لتخزين مُدخلات المستخدِم: package main import ( "fmt" ) func main() { fmt.Println("Please enter your name.") var name string } سيُنشئ السطر السابق متغيرًا جديدًا اسمه name باستخدام الكلمة المفتاحية var، وحددنا نوع هذا المتغير على أنه string، أي سلسلة نصية. أضف الآن السطر fmt.Scanln(&name)‎ إلى الشيفرة: package main import ( "fmt" ) func main() { fmt.Println("Please enter your name.") var name string fmt.Scanln(&name) } يخبر التابع fmt.Scanln الحاسب أن ينتظر إدخالًا من لوحة المفاتيح ينتهي بسطر جديد (الضغط على Enter) أو المحرف n\، إذ توقف عملية الإدخال هذه البرنامج مؤقتًا إلى حين انتهاء المستخدِم من إدخال أيّ نص يريده، ثم يستمر البرنامج عندما يضغط المستخدم على مفتاح الإدخال ENTER من لوحة المفاتيح، إذ تُلتقط بعد ذلك كافة ضغطات المفاتيح بما في ذلك ضغطات المفتاح ENTER وتُحوّل إلى سلسلة من المحارف. بما أن الهدف هو استخدام النص (اسمه) الذي يدخله المستخدِم لوضعه بجانب العبارة الترحيبية التي تظهر في خرج البرنامج، فسينبغي عليك حفظ هذه المحارف عن طريق تخزينها في متغير من النوع string أي في المتغير name، إذ يُخزّن جو هذه السلسلة في ذاكرة الحاسب إلى حين انتهاء تشغيل البرنامج. أخيرًا، أضف السطر fmt.Printf("Hi, %s! I'm Go!", name)‎ إلى برنامجك لطباعة الخرج: package main import ( "fmt" ) func main() { fmt.Println("Please enter your name.") var name string fmt.Scanln(&name) fmt.Printf("Hi, %s! I'm Go!", name) } استخدمنا هذه المرة الدالة fmt.Printf في عملية الطباعة ﻷنها ستسمح لنا بتنسيق عملية الطباعة بالطريقة التي نريدها، إذ تأخذ هذه الدالة وسيطَين الأول هو سلسلة نصية تتضمن العنصر النائب s% (العنصر النائب Placeholder هو متغير يأخذ قيمة في وقتٍ لاحق أي ينوب عن القيمة الحقيقة في البداية)، والثاني هو المُتغير الذي سيُحقن في هذا العنصر النائب، وهذه الدالة تُسمى دالة مرنة، أي تأخذ عددًا غير مُحدد من المعطيات، كما أن المُعطى الأول قد يتضمن أكثر من عنصر نائب لكن هذا لايهمنا الآن، ونفعل ذلك لأن لغة جو لا تدعم تضمين المتغيرات ضمن السلاسل النصية مباشرة كما تفعل لغات أخرى مثل لغة جافاسكربت. احفظ الملف البرمجي الذي أنشأته واخرج من المحرِّر عن طريق الضغط على CTRL + X وتأكيد الخروج بالضغط على المفتاح Y عندما يطلب منك. شغّل البرنامج الآن وستُطالب بإدخال اسمك، لذا أدخله واضغط على ENTER، وقد لا يكون الخرج هو بالضبط ما تتوقعه: Please enter your name. Sammy Hi, Sammy ! I'm Go! بدلًا من طباعة Hi, Sammy! I'm Go!‎، هناك سطر فاصل بعد الاسم مباشرةً، إذ التقط البرنامج جميع ضغطات المفاتيح بما في ذلك المفتاح ENTER الذي ضغطنا عليه لإخبار البرنامج بالمتابعة، لذا تكمن المشكلة في السلسلة، إذ يؤدي الضغط على المفتاح الإدخال ENTER إلى إنشاء رمز خاص يُنشئ سطرًا جديدًا وهو الرمز n\. افتح الملف لإصلاح المشكلة: $ nano greeting.go أضف السطر التالي: ... fmt.Scanln(&name) ... ثم السطر التالي: name = strings.TrimSpace(name) استخدمنا هنا الدالة TrimSpace من الحزمة strings في مكتبة جو القياسية على السلسلة التي التقطتها باستخدام fmt.Scanln، إذ تزيل الدالة strings.TrimSpace محارف المسافة space characters بما في ذلك الأسطر الجديدة من بداية السلسلة ونهايتها، إذًا ستُزيل محرف السطر الجديد في نهاية السلسلة التي أُنشِئت عند الضغط على ENTER. ستحتاج لاستخدام الحزمة strings إلى استيرادها في الجزء العلوي من البرنامج. ضع ما يلي ضمن البرنامج: import ( "fmt" ) أضف السطر التالي لاستيراد الحزمة strings: import ( "fmt" "strings" ) سيكون برنامج الآن كما يلي: package main import ( "fmt" "strings" ) func main() { fmt.Println("Please enter your name.") var name string fmt.Scanln(&name) name = strings.TrimSpace(name) fmt.Printf("Hi, %s! I'm Go!", name) } احفظ الملف البرمجي الذي أنشأته واخرج من المحرِّر عن طريق الضغط على الاختصار CTRL + X وتأكيد الخروج بالضغط على الزر Y عندما يطلب منك. شغّل البرنامج: $ go run greeting.go ستحصل على الناتج المتوقع هذه المرة بعد إدخال اسمك والضغط على مفتاح ENTER: Please enter your name. Sammy Hi, Sammy! I'm Go! أصبح لديك الآن برنامج جو يأخذ مدخلات من المستخدِم ويطبعها على الشاشة. الخاتمة تعلمت في هذه المقالة كيفية كتابة برنامج بسيط يطبع رسالة ترحيبية، كما تعلمت كيفية إنشاء برنامج يأخذ مُدخلات من المستخدِم ويعالجها ويطبع رسالةً تفاعليةً، كما يمكنك الآن التلاعب بهذا البرنامج وتعديل بعض الأمور بداخله مثل أن تجعله يطلب اسم اللون المُفضّل للمستخدِم أو اسم فريقه المُفضل ويطبع تلك المعلومات على الشاشة. ترجمة -وبتصرُّف- للمقال How To Write Your First Program in Go لصاحبه Gopher Guides. اقرأ أيضًا المقال السابق: تثبيت لغة جو وإعداد بيئة برمجة محلية لها على ويندوز الدليل السريع إلى لغة البرمجة Go بناء خادم بروتوكول التحكم في الإرسال TCP متزامن في لغة البرمجة Go
  15. جو Go هي لغة برمجة حديثة ذات قواعد syntax عالية المستوى على غرار لغات البرمجة النصية مثل بايثون وروبي وجافا سكربت، وقد طوّرتها شركة جوجل Google في عام 2007 لتكون ملائمة لنوعية احتياجات جوجل الحسابية من حيث التصريف compilation السريع وسهولة البرمجة والتنفيذ الفعّال. تعتبر جو لغة بسيطة جدًا من ناحية القواعد، فعدد الكلمات المفتاحية بها والأنواع الأساسية فيها ضئيل مقارنة بباقي اللغات، كما أنها تقلل كثيرًا من فكرة وجود طرق متعددة لتنفيذ مهمة ما، حتى أنها لا تحتوي على حلقة while وتقتصر فقط على حلقة for مما يجعل هذه اللغة سهلة التعلم ومناسبة للمبرمجين الجدد والخبراء ويميّزها عن باقي اللغات. تعالج جو عمليات التزامن بشكل مبتكر، بالإضافة إلى توفير الأدوات اللازمة لبناء ثنائيات محلية native binaries (برامج تنفيذية executables أو مكتبات shared libraries) لاستخدامها في منصات وأماكن أخرى. جو هي لغة برمجة متعددة الاستخدامات يمكن استخدامها في العديد من مشاريع البرمجة، إلا أنها مناسبة بشكل خاص لبرامج الشبكات والأنظمة الموزعة، ومن هذا المُنطلق اكتسبت لقب "لغة السحابة". تركز لغة جو على مساعدة المبرمجين من خلال تقديم مجموعة مميزة من الأدوات وجعل التنسيق جزءًا من مواصفات اللغة وتسهيل النشر عن طريق تحويل البرنامج إلى ملف تنفيذي. سترشدك هذه المقالة إلى كيفية تثبيت جو على جهاز محلي بنظام تشغيل ويندوز 10 وإعداد بيئة برمجة باستخدام سطر الأوامر. المتطلبات جهاز مثبت عليه نظام ويندوز 10 مع إمكانية الوصول على أساس مدير والاتصال بالانترنت. الخطوة 1: فتح وتهيئة PowerShell سننجز عميلة التثبيت والإعداد من خلال واجهة سطر الأوامر command line -ومعروفة أيضًا باسم الصدفة shell- وهي طريقة غير رسومية للتفاعل مع الحاسوب، إذ أنه لا توجد أزرار أو أشكال توضيحية، فقط تكتب الأمر بصيغة نصية وتنفذه، ثم تحصل على الاستجابة من الحاسب، كما يمكِّنك سطر الأوامر من تعديل وأتمتة العديد من المهام التي تقوم بها على الحاسوب كل يوم وهو أداة أساسية لمطوري البرامج. يُعَدّ PowerShell برنامجًا من مايكروسوفت يوفر واجهةً لصدفة سطر الأوامر، إذ تُنفَّذ المهام الإدارية عن طريق تشغيل أوامر cmdlets أي command-lets، وهي أصناف Classes متخصصة من إطار العمل NET. الذي يمكنه تنفيذ العمليات، وقد أصبح PowerShell مفتوح المصدر في عام 2016، وهو متوفر الآن على أطر العمل لكل من نظامَي ويندوز ويونكس UNIX بما في ذلك ماك Mac ولينكس Linux. يمكنك النقر بزر الفأرة الأيمن فوق رمز قائمة ابدأ في الزاوية اليسرى السفلية من شاشتك للعثور على PowerShell على جهازك، ثم انقر فوق بحث واكتب PowerShell في شريط البحث، ثم انقر بزر الفأرة الأيمن فوق Windows PowerShell، ولأسباب تتعلق بهذه المقالة يُرجى فتحه على أساس مسؤول -أو مدير- من خلال اختيار Run as Administrator، وعندما ينبثق لك مربع حوار سيسألك هل تريد السماح لهذا التطبيق بإجراء تغييرات على جهاز الكمبيوتر الخاص بك؟ انقر فوق نعم yes، وبعد إجراء ما ذكرناه ستظهر لك النافذة التالية: انتقل الآن إلى مجلد النظام من خلال الأمر التالي: $ cd ~ سينقلك تنفيذ هذا الأمر إلى المجلد PS C:\Users\sammy. يجب عليك الآن إعداد الأذونات من خلال PowerShell لمتابعة عملية التثبيت، ففي الحالة الافتراضية ستكون مهيأةً للتشغيل في الوضع الأكثر أمانًا، كما تجدر الإشارة إلى أنه هناك مستويات قليلة من الأذونات التي يمكنك إعدادها على أساس مسؤول: المُقيّد Restricted: هي سياسة التنفيذ الافتراضية، وفي هذا الوضع لن تتمكن من تشغيل البرامج النصية scripts، وسيعمل PowerShell فقط على أساس صدفة تفاعلية مع هذه البرامج. الموقّع AllSigned: سيمكنك هذا الوضع من تشغيل جميع البرامج النصية وملفات الضبط الموقَّعة عبر التوقيع الرقمي بواسطة ناشر موثوق، مما يعني أنه من المحتمل أن تٌعرِّض جهازك لخطر تشغيل البرامج النصية الضارة التي وقّع عليها ناشر موثوق به. الموقّعة عن بعد RemoteSigned: يتيح لك تشغيل البرامج النصية وملفات الضبط المُحمّلة من الإنترنت والموقَّعة من قِبل ناشرين موثوقين، أي أنه يعرّض جهازك للخطر أيضًا إذا كانت هذه البرامج النصية الموثوقة ضارة. بدون قيود Unrestricted: ستُشغَّل جميع البرامج النصية وملفات الضبط التي نُزِّلت من الإنترنت عند تأكيدك أنّ الملف قد نُزِّل من الإنترنت، وهنا لا يلزم وجود توقيع رقمي، وبالتالي فإنك تُعرّض جهازك لخطر تشغيل البرامج النصية غير الموقّعة والتي من المحتمل أن تكون ضارةً. سنعتمد في هذه المقال على مستوى RemoteSigned في سياسة التنفيذ للمستخدِم الحالي، وبالتالي سيمنح PowerShell إمكانية قبول البرامج النصية الموثوقة دون الحاجة إلى جعل الأذونات واسعةً أكثر مثل المستوى بدون قيود. نفّذ ما يلي ضمن PowerShell: $ Set-ExecutionPolicy -Scope CurrentUser سيطالبك PowerShell بعد ذلك بتقديم سياسة تنفيذ، لذا أدخل ما يلي لاستخدام RemoteSigned: $ RemoteSigned سيُطلب منك تأكيد التغيير في سياسة التنفيذ بعد الضغط على ENTER، لذا اكتب المحرف y للسماح بتنفيذ التغييرات، كما يمكنك التأكد من نجاح ذلك من خلال الاستعلام عن الأذونات الحالية كما يلي: $ Get-ExecutionPolicy -List سيكون الخرج كما يلي: Scope ExecutionPolicy ----- --------------- MachinePolicy Undefined UserPolicy Undefined Process Undefined CurrentUser RemoteSigned LocalMachine Undefined هذا يؤكد أنّ المستخدِم الحالي يمكنه تشغيل نصوص برمجية موثوقة مُنزَّلة من الإنترنت، ويمكنك الآن الانتقال إلى تنزيل الملفات التي سنحتاجها لإعداد بيئة برمجة جو. الخطوة 2 - تثبيت مدير الحزم شوكولاتي Chocolatey يُعَدّ مدير الحزم مجموعةً من أدوات البرامج التي تعمل على أتمتة عمليات التثبيت، إذ يتضمن ذلك التثبيت الأولي للبرنامج وترقيته وتهيئته وإزالة البرامج حسب الحاجة، إذ يحتفظ مُدير الحزم بالبرامج المُثبّتة في موقع مركزي ويمكنه صيانة جميع حزم البرامج في النظام وغيرها. يُعَدّ شوكولاتي Chocolatey مدير حزم يمكن التفاعل معه من خلال سطر أوامر ومُصمَّم لنظام التشغيل ويندوز ويعمل مثل apt-get على لينكس، كما يُعَدّ برمجية مفتوحة المصدر يساعدك على تثبيت التطبيقات والأدوات بسرعة، وستتعلم في هذه المقالة كيفية استخدامه لتنزيل ما تحتاجه لبيئة التطوير الخاصة بك. اقرأ البرنامج النصي أو السكربت قبل تثبيته لتؤكِّد على أنك موافق على التغييرات التي سيجريها على جهازك، ولإنجاز ذلك استخدم إطار عمل NET. لتنزيل وعرض البرنامج شوكولاتي ضمن نافذة الطرفية. ابدأ بإنشاء كائن WebClient اسمه script$ والذي يشارك إعدادات الاتصال بالإنترنت مع Internet Explorer: $ $script = New-Object Net.WebClient ألق نظرةً على الخيارات المتاحة عن طريق تمرير كائن script$ مع المحرف | إلى الصنف Get-Member: $ $script | Get-Member سيؤدي ذلك إلى عرض جميع الأعضاء -أي الخصائص والدوال- الخاصة بالكائن WebClient: . . . [secondary_label Snippet of Output] DownloadFileAsync Method void DownloadFileAsync(uri address, string fileName), void DownloadFileAsync(ur... DownloadFileTaskAsync Method System.Threading.Tasks.Task DownloadFileTaskAsync(string address, string fileNa... DownloadString Method string DownloadString(string address), string DownloadString(uri address) #method we will use DownloadStringAsync Method void DownloadStringAsync(uri address), void DownloadStringAsync(uri address, Sy... DownloadStringTaskAsync Method System.Threading.Tasks.Task[string] DownloadStringTaskAsync(string address), Sy… . . . بالنظر إلى الخرج، يمكنك تحديد طريقة DownloadString المستخدَمة لعرض البرنامج النصي أو السكربت والتوقيع في نافذة PowerShell، واستخدِم هذه الطريقة لفحص البرنامج النصي: $ $script.DownloadString("https://chocolatey.org/install.ps1") ثبّت شوكولاتي بعد فحص البرنامج النصي بكتابة ما يلي في PowerShell: $ iwr https://chocolatey.org/install.ps1 -UseBasicParsing | iex يسمح لك أمر iwr -وهو أحد أوامر cmdlet- أو Invoke-WebRequest باستخراج البيانات من الويب، إذ سيؤدي ذلك إلى تمرير البرنامج النصي إلى iex، أو Invoke-Expression cmdlet، والذي سينفذ محتويات البرنامج النصي ويشغّل عملية تثبيت مدير حزم شوكولاتي. سيصبح بإمكانك بعد تثبيت شوكولاتي من خلال PowerShell البدء في تثبيت أدوات إضافية باستخدام أمر choco، وإذا كنت بحاجة إلى تحديث شوكولاتي في أيّ وقت في المستقبل، فنفّذ الأمر التالي: $ choco upgrade chocolatey يمكنك تثبيت ما تبقى من أدوات لتجهيز بيئة برمجة جو بعد تثبيت مدير الحزم. الخطوة 3 - تثبيت محرر النصوص Nano (خطوة اختيارية) ستثبّت في هذه الخطوة محرر النصوص نانو nano، وهو محرر نصوص يستخدِم واجهة سطر الأوامر، كما يمكنك استخدام نانو لكتابة البرامج مباشرةً داخل PowerShell، وهذه الخطوة ليست إلزاميةً، إذ يمكنك أيضًا استخدام محرر نصوص بواجهة مستخدِم رسومية مثل Notepad، ولكن توصي هذه المقالة باستخدام نانو، إذ سيساعدك على اعتياد استخدام PowerShell. استخدم شوكولاتي لتثبيت نانو: $ choco install -y nano تُستخدَم الراية y- للتأكيد التلقائي -أي الموافقة- على تشغيل البرنامج النصي. يمكنك استخدام الأمر nano بعد تثبيت نانو لإنشاء ملفات نصية جديدة، كما ستستخدِمه لاحقًا في هذه المقالة لكتابة برنامج جو الأول الخاص بك. الخطوة 4 - تثبيت جو ستستخدِم شوكولاتي كما في الخطوة السابقة لتثبيت جو: $ choco install -y golang ملاحظة: كلمة go عبارة عن كلمة صغيرة وتتطابق مع العديد من الحزم، وبالتالي أصبح من الشائع استخدام كلمة golang على أساس مصطلح لتثبيت الحِزم وعند البحث على الإنترنت عن مقالات متعلقة بلغة جو، وقد وُلِّد مصطلح Golang من رابط الموقع الرسمي لجو وهو golang.org. سيثبّت PowerShell جو الآن وستشاهد الخرج التالي: Environment Vars (like PATH) have changed. Close/reopen your shell to see the changes (or in powershell/cmd.exe just type `refreshenv`). The install of golang was successful. Software installed as 'msi', install location is likely default. Chocolatey installed 1/1 packages. See the log for details (C:\ProgramData\chocolatey\logs\chocolatey.log). يمكنك الآن التحقق من نجاح عملية التثبيت عن طريق إغلاق PowerShell وإعادة فتحه مرةً أخرى على أساس مسؤول ثم تنفيذ الأمر التالي للتحقق من إصدار لغة جو المُثبَّت: $ go version سترى خرجًا مُشابهًا للخرج التالي: go version go1.12.1 windows/amd643.7.0 حيث يعرض لك تفاصيل النسخة الحالية المثبتة على حاسبك من جو. يمكنك الآن إعداد مساحة عمل لمشاريع التطوير الخاصة بك. الخطوة 5 - إنشاء مساحة العمل الخاصة بك لبناء مشاريع جو يمكنك إنشاء مساحة عمل البرمجة الخاصة بك بعد تثبيت شوكولاتي ونانو ولغة جو، إذ ستحتوي مساحة العمل على مجلدَين في جذرها وهما: src: مجلد ستوضَع فيه ملفات جو المصدرية وهي الملفات التي المكتوبة والمنشأة باستخدام لغة جو، إذ يستخدِمها مُصرِّف جو لإنشاء ملفات قابلة للتنفيذ وهي ملفات ثنائية يمكن تشغيلها على نظامك لتنفيذ المهام التي تتضمنها). bin: مجلد ستوضَع فيه الملفات الثنائية التي أُنشِئت وثبِّتَت بواسطة أدوات جو؛ وبعبارة أخرى هي البرامج التي المصرَّفة بواسطة الشيفرة المصدرية الخاصة بك أو غيرها من التعليمات البرمجية المصدرية المرتبطة بجو والتي قد نزِّلت. من المحتمل أن يحتوي المجلد الفرعي src على عدة مستودعات للتحكم في الإصدارات مثل Git و Mercurial و Bazaar، وهذا يسمح لك باستيراد أساسي canonical import للشيفرة في مشروعك وهو عملية استيراد تشير إلى حزمة مؤهلة وجاهزة بالكامل مثل github.com/digitalocean/godo. سترى مجلدات مثل github.com أو golang.org عندما يستورد برنامجك مكتبات خارجية، فإذا كنت تستخدِم -أو لديك- شيفرات برمجية على إحدى المواقع مثل GitHub، فستضع أيضًا هذه المشاريع أو الملفات المصدرية ضمن هذا المجلد وستتعرّف على ذلك بعد قليل. ستبدو مساحة العمل النموذجية هكذا: . ├── bin │ ├── buffalo # أمر تنفيذي │ ├── dlv # أمر تنفيذي │ └── packr # أمر تنفيذي └── src └── github.com └── digitalocean └── godo ├── .git # البيانات الوصفية لمستودع جيت ├── account.go # ملف الحزمة ├── account_test.go # اختبار ملف الحزمة ├── ... ├── timestamp.go ├── timestamp_test.go └── util ├── droplet.go └── droplet_test.go يُعَدّ المجلد الافتراضي لمساحة العمل في جو بدءًأ من الإصدار 1.8المجلد الرئيسي home للمستخدِم الذي يحتوي على مجلد فرعي باسم go أي HOME/go$، فإذا كنت تستخدِم إصدارًا أقدم من 1.8، فمن الأفضل الاستمرار في استخدام الموقع HOME/go$ لمساحة عملك. نفّذ الأمر التالي للانتقال إلى المجلد HOME$: $ cd $HOME أنشئ بعدها مجلدًا لبيئة العمل بتنفيذ الأمر التالي: $ mkdir go/bin, go/src سيؤدي ذلك إلى إنشاء بنية المجلد التالية: └── $HOME └── go ├── bin └── src سابقًا أي قبل الإصدار 1.8 كان يجب عليك استخدام متغير بيئة محلي يسمى GOPATH$ من أجل تحديد المكان الذي يمكن للمُصرِّف فيه العثور على الشيفرة المصدرية المطلوب استخدامها في مشروعك، سواءً كانت الشيفرة محليةً أو على موقع استضافة خارجي (عمومًا، تعتبر هذه الطريقة جيدة أكثر كما أن بعض الأدوات مازالت تعتمد على استخدامه) لكن لا يطلبضبط متغير البيئة ذاك صراحة. يجب أن يكون متغير البيئة GOPATH$ قد حُدّدَ فعلًا نظرًا لأنك استخدَمت شوكولاتي في عملية التثبيت، ويمكنك التحقق من ذلك بالأمر التالي: $ $env:GOPATH يجب أن ترى الخرج التالي مع اسم المستخدِم الخاص بك بدلًا من sammy: C:\Users\sammy\go عندما يُصرِّف ويثبّت جو الأدوات، فسيضعها في المجلد GOPATH/bin$، وللراحة فإنه من الشائع إضافة المجلد الفرعي bin الخاص بمساحة العمل إلى ‎$PATH، ويمكنك إنجاز ذلك من خلال الأمر setx في PowerShell: $ setx PATH "$($env:path);$GOPATH\bin" سيسمح لك ذلك بتشغيل أيّ برامج تصرّفها أو تنزّلها عبر أدوات جو في أيّ مكان على نظامك. الآن وبعد أن أنشأت المجلد الجذر لمساحة العمل وضبطت مجموعة متغيرات البيئة GOPATH$ الخاصة بك، فقد أصبح بإمكانك إنشاء مشاريعك المستقبلية باستخدام بنية المجلد التالية، ويفترض هذا المثال أنك تستخدِم موقع GitHub لاستضافة مشروعك: $GOPATH/src/github.com/username/project إذا كنت تعمل على مشروع https://github.com/digitalocean/godo، فسيُخزَّن في المجلد التالي: $GOPATH/src/github.com/digitalocean/godo إن هذه البنية للمشاريع ستجعل المشاريع متاحةً باستخدام الأمر go get، كما أنها ستساعدك أيضًا في عمليات القراءة، إذ يمكنك الوصول إلى مكتبة godo مثلًا من خلال الأمر السابق كما يلي: $ go get github.com/digitalocean/godo ملاحظة: إذا لم يكن جيت git مُثبّتًا لديك، فسيفتح ويندوز مربع حوار يسألك عما إذا كنت تريد تثبيته، وعندها انقر فوق نعم yes للمتابعة واتبع إرشادات التثبيت. يمكنك أيضًا التحقق من نجاح عملية التنزيل من خلال سرد محتويات المجلد: $ ls -l $GOPATH/src/github.com/digitalocean/godo يجب أن تشاهد خرجًا يشبه الخرج التالي: Directory: C:\Users\sammy\go\src\github.com\digitalocean\godo Mode LastWriteTime Length Name ---- ------------- ------ ---- d----- 4/10/2019 2:59 PM util -a---- 4/10/2019 2:59 PM 9 .gitignore -a---- 4/10/2019 2:59 PM 69 .travis.yml -a---- 4/10/2019 2:59 PM 1592 account.go -a---- 4/10/2019 2:59 PM 1679 account_test.go -rw-r--r-- 1 sammy staff 2892 Apr 5 15:56 CHANGELOG.md -rw-r--r-- 1 sammy staff 1851 Apr 5 15:56 CONTRIBUTING.md . . . -a---- 4/10/2019 2:59 PM 5076 vpcs.go -a---- 4/10/2019 2:59 PM 4309 vpcs_test.go تكون بذلك قد أنشأت مساحة عمل خاصة بك وضبطت متغيرات البيئة اللازمة، وفي الخطوة الثالثة سنختبر مساحة العمل هذه من خلال كتابة شيفرة برنامج بسيط. الخطوة 6 - إنشاء برنامج بسيط ستنشئ برنامجًا بسيطًا بلغة جو Go يطبع العبارة “Hello, World!‎” بغية اختبار مساحة العمل والتعرف أكثر على جو، كما ستنشئ هنا ملفًا مصدريًا واحدًا لجو وليس مشروعًا متكاملًا، لذا لا داعي لأن تكون ضمن مساحة العمل الخاصة بك لإنجاز ذلك. افتح محرر نصوص سطر الأوامر نانو من المجلد الرئيسي وأنشئ ملفًا جديدًا: $ nano hello.go اكتب برنامجك في الملف الجديد: package main import "fmt" func main() { fmt.Println("Hello, World!") } ستستخدم هذه الشيفرة حزمة fmt وستستدعي الدالة Println لطباعة Hello, World!‎ الممررة على أساس وسيط للدالة. اخرج الآن من المحرر nano بالضغط على مفتاحَيCTRL+ X، وعند مطالبتك بحفظ الملف، اضغط على Y ثم ENTER، ثم شغّل برنامج hello.go الذي أنشأته عند الخروج من nano والعودة إلى الصدَفة: $ go run hello.go سترى الخرج التالي: Hello, World! بذلك يكون اختبار مساحة العمل الخاصة بك قد أكتمل. خاتمة تهانينا، لقد أنشأت مساحة عمل خاصة بك لكتابة الشيفرات البرمجية وإنشاء المشاريع بلغة جو على جهاز يعمل بنظام تشغيل ويندوز 10. ترجمة -وبتصرَُف- للمقال How To Install Go and Set Up a Local Programming Environment on Windows 10 لصاحبه Gopher Guides. اقرأ أيضًا المقال السابق: تثبيت لغة جو وإعداد بيئة برمجة محلية على نظام ماك macOS تثبيت لغة جو وإعداد بيئة برمجة محلية على أبونتو فهم، تنصيب وتهيئة بيئة عمل لغة البرمجة Go بدء العمل مع ويندوز 10
  16. جو Go هي لغة برمجة حديثة ذات قواعد syntax عالية المستوى على غرار لغات البرمجة النصية مثل بايثون وروبي وجافاسكربت، وقد طوّرتها شركة جوجل Google في عام 2007 لتكون ملائمة لنوعية احتياجات جوجل الحسابية من حيث التصريف compilation السريع وسهولة البرمجة والتنفيذ الفعّال. تعتبر جو لغة بسيطة جدًا من ناحية القواعد، فعدد الكلمات المفتاحية بها والأنواع الأساسية فيها ضئيل مقارنة بباقي اللغات، كما أنها تقلل كثيرًا من فكرة وجود طرق متعددة لتنفيذ مهمة ما، حتى أنها لا تحتوي على حلقة while وتقتصر فقط على حلقة for مما يجعل هذه اللغة سهلة التعلم ومناسبة للمبرمجين الجدد والخبراء ويميّزها عن باقي اللغات. تعالج جو عمليات التزامن بشكل مبتكر، بالإضافة إلى توفير الأدوات اللازمة لبناء ثنائيات محلية native binaries (برامج تنفيذية executables أو مكتبات shared libraries) لاستخدامها في منصات وأماكن أخرى. جو هي لغة برمجة متعددة الاستخدامات يمكن استخدامها في العديد من مشاريع البرمجة، إلا أنها مناسبة بشكل خاص لبرامج الشبكات والأنظمة الموزعة، ومن هذا المُنطلق اكتسبت لقب "لغة السحابة". تركز لغة جو على مساعدة المبرمجين من خلال تقديم مجموعة مميزة من الأدوات وجعل التنسيق جزءًا من مواصفات اللغة وتسهيل النشر عن طريق تحويل البرنامج إلى ملف تنفيذي. ستتعلم في هذا المقال كيفية تثبيت جو على حاسب يعمل بنظام ماك وإعداد مساحة عمل برمجية خاصة بك من خلال سطر الأوامر لبدء العمل مع جو. المتطلبات ستحتاج إلى حاسب يعمل بنظام ماك macOS مع إمكانية وصول إدارية administrative access واتصال بالإنترنت. الخطوة 1 - فتح الطرفية Terminal سننجز عملية التثبيت والإعداد من خلال سطر الأوامر command line وهو معروف أيضًا باسم الصدَفة shell وهو وسيلة تخاطب مع الحاسوب عبر كتابة الأوامر له والذي يُمكّنك من تعديل وأتمتة العديد من المهام التي تقوم بها على جهاز الحاسوب كل يوم وهو أداة أساسية لمطورِي البرامج. تُعَدّ طرفية نظام ماك تطبيقًا يمكنك استخدامه للوصول إلى واجهة سطر الأوامر، ومثل أي تطبيق آخر يمكنك العثور عليه بالذهاب إلى Finder ثم الانتقال إلى مجلد التطبيقات Applications ثم إلى مجلد الأدوات المساعدة Utilities، وانقر بعد ذلك نقرًا مزدوجًا فوق أيقونة الطرفية. يمكنك أيضًا العثور على الطرفية من خلال فتح Spotlight عن طريق الضغط باستمرار على مفتاحَي CMD + SPACE وكتابتها في المربع الذي يظهر. هناك العديد من الأوامر الخاصة بالطرفية والتي يمكنك تعلّمها من مقال مدخل إلى طرفيّة لينكس Linux Terminal، وبعد فتح تطبيق الطرفية يمكنك تحميل حزمة أدوات المطورXcode وتثبيتها، إذ ستحتاجها لتثبيت جو. الخطوة 2 - تثبيت Xcode تُعَدّ Xcode بيئة تطوير متكاملة integrated development environment أو IDE اختصارًا، وتحتوي على أدوات تطوير البرامج لنظام ماك، كما يمكنك التحقق مما إذا كان Xcode مثبتًا بالفعل عن طريق كتابة ما يلي في الطرفية: $ xcode-select -p يعني الخرج التالي أنّ Xcode مُثبّت: /Library/Developer/CommandLineTools إذا تلقيت خطأً ما، فثبّت Xcode من متجر App Store واضغط على زر قبول الخيارات الافتراضية. عُد إلى نافذة الطرفية بعد تثبيت Xcode، وبعد ذلك ستحتاج إلى تثبيت تطبيق أدوات سطر الأوامر Command Line Tools الذي يخص Xcode عن طريق كتابة الأمر التالي: $ xcode-select --install إلى هنا تكون قد ثبّت كل من Xcode وتطبيق Command Line Tools -أدوات سطر الأوامر الخاص به بالكامل، ويمكنك الآن تثبيت مدير الحزم Homebrew. الخطوة 3 - تثبيت وإعداد Homebrew على الرغم من احتواء طرفية نظام ماك على الكثير من الوظائف المفيدة مثل تلك الموجودة في أنظمة لينكس ويونكس، إلا أنها لا تحتوي على مدير حزم الذي يُعَدّ مجموعةً من الأدوات البرمجية التي تعمل على أتمتة عمليات التثبيت بما في ذلك التثبيت الأولي للبرامج وترقيتها وضبطها وإزالتها حسب الحاجة، كما يحتفظ بالحزم المثبَّتة في موقع مركزي وحسب التنسيقات الشائعة. يزوِّد Homebrew نظام ماك بنظام إدارة حزمة برمجيات مجانية ومفتوحة المصدر يعمل على تبسيط عملية تثبيت الحزم على نظام ماك، كما يمكنك تثبيته من خلال تنفيذ الأمر التالي في الطرفية: $ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" كُتب Homebrew باستخدام لغة روبي Ruby، لذلك سيعدّل مسار Ruby على حاسبك، كما سيسحب الأمر curl برمجيةً أو سكربتًا من عنوان URL المحدد وسيطبع لك هذا السكربت رسالةً تشرح فيها ما الذي ستفعله وستطلب منك الإذن لتنفيذ ذلك، إذًا ستوفر لك تلك الرسائل إمكانية معرفة ما الذي ستنفّذه البرمجية وستمنحك الفرصة للتحقق والموافقة على التنفيذ. قد يتطلب تنفيذ الأمر إدخال كلمة المرور الخاصة بك، وفي هذه الحالة يجب أن تدرك أنّ ضغطات المفاتيح التي تُجرّبها لن تظهر في الطرفية (تُخفى أثناء كتابتها)، وبعد الانتهاء من كتابة كلمة المرور ما عليك سوى الضغط على مفتاح العودة، ففي حال لم تُطلَب منك كلمة المرور، فاضغط على المحرف y ( أي نعم yes) كلما طُلب منك ذلك لتأكيد عملية التثبيت. فيما يلي بعض الرايات flags المرتبطة بالأمر curl: الراية f- أو fail-- تُخبر الطرفية بعدم تقديم مستند HTML عند حدوث أخطاء في الخادم. الراية s- أو silent-- تُستخدَم لكتم الأمر curl، أي لن تظهر لك معلومات أثناء عملية التثبيت، وبالتالي لن تُظهِر لك مقياس التقدم، وعند دمج هذه الراية مع الراية S- أوshow-error --، فسيُظهر لك curl رسالة خطأ في حالة الفشل. الراية L- أو location curl-- ستُخبِر curl بأنه عليه إعادة طلب العنوان من المكان الجديد في حال أبلغ الخادم عن انتقال الصفحة المطلوبة إلى موقع مختلف. ضع مجلد Homebrew في قمة متغير البيئة PATH بعد اكتمال عملية التثبيت، وذلك لضمان استدعاء عمليات تثبيت Homebrew بدلًا من الأدوات التي قد يحددها نظام macOS تلقائيًا والتي يمكن أن تتعارض مع بيئة التطوير التي نقوم بإنشائها. يجب عليك إنشاء أو فتح ملف ‎~/.bash_profile‎ باستخدام محرر نصوص سطر الأوامر nano من خلال الأمر nano: $ nano ~/.bash_profile اكتب الأمر التالي بعد فتح الملف في الطرفية: export PATH=/usr/local/bin:$PATH اضغط الآن باستمرار على مفتاح CTRL + o لحفظ التغييرات، وعندما يُطلب منك ذلك اضغط على مفتاح RETURN، كما يمكنك الآن الخروج من nano بالضغط على مفتاحي CTRL + x. نشِّط هذه التغييرات عن طريق تنفيذ الأمر التالي: $ source ~/.bash_profile بذلك ستدخل التغييرات التي أجريتها على متغير البيئة PATH حيّز التنفيذ، كما يمكنك التأكد من تثبيت Homebrew بنجاح عن طريق كتابة ما يلي: $ brew doctor إذا لم تكن هناك حاجة إلى إجراء عمليات تحديث، فستحصل على الخرج التالي: Your system is ready to brew. بالنسبة لعمليات التحديث التي قد تُطالب بها، فربما تكون تحذيرًا لتشغيل أمر آخر مثل brew update، وذلك للتأكد من أنّ تثبيت Homebrew الخاص بك بدوره محدث. بعد تجهيز Homebrew يمكنك تثبيت جو. الخطوة 4 - تثبيت جو يمكنك البحث عن جميع الحزم المتاحة عن طريق Homebrew من خلال الأمر brew search، وهنا ستبحث عن الحزم أو الوحدات المتعلقة بجو: $ brew search golang ملاحظة: لم يُستخدم في هذا المقال بحث brew باستخدام كلمة go، أي أننا لم نكتب brew search go لأنه يُعيد عددًا كبيرًا جدًا من النتائج، فكلمة go عبارة عن كلمة صغيرة وتتطابق مع العديد من الحزم، وبالتالي أصبح من الشائع استخدام كلمة golang على أساس مصطلح بحث، كما تُعَدّ هذه ممارسة شائعةً عند البحث على الإنترنت عن مقالات متعلقة بجو أيضًا، وقد وُلِد مصطلح Golang من عنوان موقع اللغة الرسمي golang.org. سيكون الخرج قائمةً من الحزم والوحدات المتعلقة بلغة جو كما ذكرنا: golang golang-migrate يمكنك الآن تثبيت لغة جو عبر تنفيذ الأمر التالي: $ brew install golang ستعطيك الطرفية ملاحظات تتعلق بتثبيت جو، وقد يستغرق التثبيت بضع دقائق قبل اكتمال التثبيت. اكتب ما يلي للتحقق من إصدار جو الذي ثبّته: $ go version سيطبع الأمر السابق الإصدار المُثبت لديك من جو وسيكون الإصدار الحديث والمستقر. يمكنك لاحقًا تحديث جو من خلال تنفيذ الأوامر التالية لتحديث Homebrew ثم تحديث جو: $ brew update $ brew upgrade golang سيحدِّث الأمر الأول صيغة Homebrew نفسها، وبالتالي ضمان حصولك على أحدث المعلومات للحزم التي تريد تثبيتها؛ أما الأمر الثاني فسيُحدّث الحزمة golang إلى أحدث إصدار متوفر. من الممارسات الجيدة التأكد من أن إصدار جو المُثبت على جهازك مُحدّث أي لديك أحدث إصدار، وذلك من خلال الاطلاع على أحدث الإصدارات الجديدة وتحديثه بما يتوافق معها. بعد تثبيت جو أصبحت جاهزًا لإنشاء مساحة عمل لمشاريع جو الخاصة بك. الخطوة 5 - إنشاء مساحة العمل الخاصة بك لبناء مشاريع جو الآن يمكنك المتابعة وإنشاء مساحة عمل البرمجة الخاصة بك بعد أن ثبّتََ Xcode و Homebrew و Go. ستحتوي مساحة العمل على مجلدَين في جذرها: src: ستوضع فيه ملفات جو المصدرية، وهي الملفات التي تُكتَب وتُنشأ باستخدام لغة جو، كما يستخدِمها مُصرِّف جو لإنشاء ملفات قابلة للتنفيذ (ملفات ثنائية يمكن تشغيلها على نظامك لتنفيذ المهام التي تتضمنها). bin: ستوضع فيه الملفات القابلة للتنفيذ التي أنشئت وثبِّتت بواسطة أدوات جو، وبعبارة أخرى هي البرامج التي تم تصريفها بواسطة الشيفرة المصدرية الخاصة بك أو غيرها من الشيفرة المصدرية المرتبطة بجو والتي جرى تحميلها. من المحتمل أن يحتوي المجلد src على عدة مستودعات للتحكم في الإصدارات مثل Git و Mercurial و Bazaar، ويسمح لك هذا باستيراد أساسي canonical import للشفرة في مشروعك، إذ يُعَدّ الاستيراد الأساسي عملية استيراد تشير إلى حزمة مؤهلة وجاهزة بالكامل مثل github.com/digitalocean/godo. سترى مجلدات مثل github.com أو golang.org عندما يستورد برنامجك مكتبات خارجية، فإذا كنت تستخدم -أو لديك- شيفرات برمجية على إحدى المواقع مثل GitHub، فستضع أيضًا هذه المشاريع أو ملفات المصدر ضمن هذا المجلد وستتعرّف على ذلك بعد قليل. ستبدو مساحة العمل النموذجية كما يلي: . ├── bin │ ├── buffalo # أمر تنفيذي │ ├── dlv # أمر تنفيذي │ └── packr # أمر تنفيذي └── src └── github.com └── digitalocean └── godo ├── .git # البيانات الوصفية لمستودع جيت ├── account.go # ملف الحزمة ├── account_test.go # اختبار ملف الحزمة ├── ... ├── timestamp.go ├── timestamp_test.go └── util ├── droplet.go └── droplet_test.go بدءًأ من الإصدار 1.8 يُعَدّ المجلد الافتراضي لمساحة العمل في جو هو المجلد الرئيسي home directory للمستخدِم الذي يحتوي على مجلد فرعي باسم go أي HOME/go$، فإذا كنت تستخدِم إصدارًا أقدم من 1.8، فمن الأفضل الاستمرار في استخدام الموقع HOME/go$ لمساحة عملك. نفِّذ الأمر التالي لإنشاء بنية مجلد لمساحة العمل الخاصة بك في جو: $ mkdir -p $HOME/go/{bin,src} يطلب الخيار p- من mkdir إنشاء جميع العناصر الرئيسية parents في المجلد حتى لو لم تكن موجودة حاليًا، كما يؤدي استخدام {bin,src} إلى إنشاء مجموعة من الوسائط لـ mkdir وإخباره بإنشاء كل من مجلدَي bin و src. سيؤدي ذلك إلى إنشاء بنية المجلد التالية: └── $HOME └── go ├── bin └── src سابقًا أي قبل الإصدار 1.8 كان يجب عليك استخدام متغير بيئة محلي يسمى GOPATH$ من أجل تحديد المكان الذي يمكن للمترجم فيه العثور على الشيفرة المصدرية المطلوب استخدامها في مشروعك، سواءً كانت الشيفرة محلية أو على موقع استضافة خارجي، وتُعَدّ هذه الطريقة جيدةً أكثر كما أن بعض الأدوات مازالت تعتمد على استخدامه ولكن لم يعد يُطلب ذكر متغير البيئة ذاك صراحة. يمكن ضبط المتغير GOPATH$ الخاص بك من خلال إضافة المتغيرات العامة إلى bash_profile./~. أولًا، افتح bash_profile./~ باستخدام nano أو محرر النصوص المفضل لديك: $ nano ~/.bash_profile اضبط المتغير GOPATH$ الخاص بك من خلال إضافة ما يلي إلى الملف: export GOPATH=$HOME/go عندما يُصرّف ويثبّت جو الأدوات، فإنه سيضعها في المجلد GOPATH/bin$، ومن الشائع إضافة المجلد الفرعي bin/ الخاص بمساحة العمل إلى PATH في bash_profile./~: export PATH=$PATH:$GOPATH/bin أضف الآن ما يلي إلى ملف bash_profile./~: export GOPATH=$HOME/go export PATH=$PATH:$GOPATH/bin سيسمح لك ذلك بتشغيل أية برامج تصرفها أو تحملها عبر أدوات جو في أيّ مكان على نظامك. نفّذ الأمر التالي لتحميل المتغيرات العامة وتحديث الصدَفة: $ . ~/.bash_profile يمكنك يمكنك التحقق من تحديث المتغير PATH$ باستخدام الأمر echo وقراءة الخرج: $ echo $PATH ستشاهد GOPATH/bin$ الذي سيظهر في مجلد home، فإذا سجلت الدخول على أساس مستخدِم عادي وليكن sammy، فسترى ‎/Users/sammy/go/bin في المسار: /Users/sammy/go/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin الآن بعد أن أنشأت المجلد الجذر لمساحة العمل وضبطت مجموعة متغيرات البيئة GOPATH$ الخاصة بك، أصبح بإمكانك إنشاء مشاريعك باستخدام بنية المجلد التالية، كما يفترض هذا المثال أنك تستخدِم موقع Github لاستضافة مشروعك: $GOPATH/src/github.com/username/project إذا كنت تعمل على مشروع https://github.com/digitalocean/godo مثلًا، فستخزنه في المجلد التالي: $GOPATH/src/github.com/digitalocean/godo ستجعل بنية المشاريع هذه الوصول إلى هذه المشاريع متاحًا باستخدام أداة go get، كما أنها ستساعدك أيضًا في عمليات القراءة، إذ يمكنك الوصول مثلًا إلى مكتبة godo من خلال الأمر السابق كما يلي: go get github.com/digitalocean/godo يمكنك أيضًا التحقق من نجاح عملية التحميل من خلال عرض محتويات المجلد: ls -l $GOPATH/src/github.com/digitalocean/godo يجب أن تشاهد خرجًا يشبه الخرج التالي: Output -rw-r--r-- 1 sammy staff 2892 Apr 5 15:56 CHANGELOG.md -rw-r--r-- 1 sammy staff 1851 Apr 5 15:56 CONTRIBUTING.md . . . -rw-r--r-- 1 sammy staff 4893 Apr 5 15:56 vpcs.go -rw-r--r-- 1 sammy staff 4091 Apr 5 15:56 vpcs_test.go بذلك تكون أنشأت مساحة عمل خاصة بك وضبطت متغيرات البيئة اللازمة، وفي الخطوة التالية سنختبر مساحة العمل هذه من خلال كتابة شيفرة برنامج بسيط. الخطوة 6 - إنشاء برنامج بسيط ستنشئ برنامج "Hello, World!‎" بغية اختبار مساحة العمل والتعرف أكثر على جو، إذ ستنشئ هنا ملفًا مصدريًا واحد لجو وليس مشروعًا متكاملًا، لذا لا داعي لأن تكون ضمن مساحة العمل الخاصة بك لإنجاز ذلك. افتح محرر نصوص سطر الأوامر nano من المجلد الرئيسي وأنشئ ملفًا جديدًا: $ nano hello.go اكتب برنامجك في الملف الجديد: package main import "fmt" func main() { fmt.Println("Hello, World!") } ستستخدِم هذه الشيفرة حزمة fmt وستستدعي الدالة Println لطباعة عبارة Hello, World!‎ التي مُرِّرت إلى الدالة. اخرج الآن من المحرر nano بالضغط على مفتاحي CTRL+ x وعند مطالبتك بحفظ الملف اضغط على y ثم ENTER، وبمجرد الخروج من nano والعودة إلى الصدَفة شغّل برنامج hello.go الذي أنشأته: go run hello.go سترى الخرج التالي: Hello, World! يكون بذلك اختبار مساحة العمل الخاصة بك قد أكتمل. خاتمة تهانينا، لقد أنشأت مساحة عمل خاصة بك لكتابة الشيفرات البرمجية وإنشاء المشاريع بلغة جو على جهاز يعمل بنظام تشغيل ماك. ترجمة -وبتصرُّف- للمقال How To Install Go and Set Up a Local Programming Environment on macOS لصاحبه Gopher Guides. اقرأ أيضًا المقال السابق: تثبيت لغة جو وإعداد بيئة برمجة محلية على أبونتو فهم، تنصيب وتهيئة بيئة عمل لغة البرمجة Go كتابة أول برنامج (ومكتبة) لك باستخدام لغة البرمجة Go
  17. تُعَدّ جو Go لغة برمجة حديثة ذات قواعد syntax عالية المستوى على غرار لغات البرمجة النصية مثل بايثون وروبي وجافاسكربت، وقد طوّرتها شركة جوجل Google في عام 2007 لتكون ملائمةً لنوعية احتياجات جوجل الحسابية من حيث التصريف compilation السريع وسهولة البرمجة والتنفيذ الفعّال. تُعَدّ جو لغةً بسيطةً جدًا من ناحية القواعد، فعدد الكلمات المفتاحية بها والأنواع الأساسية فيها ضئيل مقارنة بباقي اللغات، كما أنها تقلل كثيرًا من فكرة وجود طرق متعددة لتنفيذ مهمة ما، حتى أنها لا تحتوي على حلقة while وتقتصر فقط على حلقة for، مما يجعل هذه اللغة سهلة التعلم ومناسبةً للمبرمجين الجدد والخبراء ويميّزها عن باقي اللغات، كما تعالِج جو عمليات التزامن بصورة مبتكرة، بالإضافة إلى توفير الأدوات اللازمة لبناء ملفات ثنائية أصيلة native binaries مثل برامج تنفيذية executables أو مكتبات مشتركة shared libraries لاستخدامها في منصات وأماكن أخرى. تُعَدّ جو لغة برمجة متعددة الاستخدامات يمكن استخدامها في العديد من مشاريع البرمجة، إلا أنها مناسبة بصورة خاصة لبرامج الشبكات والأنظمة الموزعة، ومن هذا المُنطلق اكتسبت لقب "لغة السحابة"، كما تركز لغة جو على مساعدة المبرمجين من خلال تقديم مجموعة مميزة من الأدوات وجعل التنسيق جزءًا من مواصفات اللغة وتسهيل النشر عن طريق تحويل البرنامج إلى ملف تنفيذي. المتطلبات حاسوب -أو آلة افتراضية- مثبت عليه نظام أبونتو 20.04 مع إمكانية وصول إدارية والاتصال بالانترنت. الخطوة 1- إعداد جو الخطوة الأولى هي تثبيت جو عن طريق تحميل الإصدار الحالي من جو من الصفحة الرسمية، لذا يجب أن تحصل على عنوان URL لآخر نسخة من ملف Tarball (أو tarfile؛ اسم المجموعة أو أرشيف الملفات المُصرّفة معًا باستخدام الأمر tar)، كما يجب عليك الانتباه إلى قيمة SHA256 المدرَجة بجوارها لأنك ستحتاجها للتحقق من الملف الذي حُمِّل. في وقت كتابة هذه المقالة كان أحدث إصدار go1.16.7. سننجز عملية التثبيت من خلال سطر الأوامر command line -ومعروف أيضًا باسم الصدفة shell أو الطرفية Terminal وهو وسيلة تخاطب مع الحاسوب عبر كتابة الأوامر له- الذي يُمكّنك من تعديل وأتمتة العديد من المهام التي تؤديها على جهاز الحاسوب كل يوم، وهو أداة أساسية لمطورِي البرامج. يمكنك العثور على تطبيق سطر الأوامر من خلال النقر على أيقونة أبونتو في الزاوية العلوية اليسرى من شاشتك وكتابة Terminal في شريط البحث ثم انقر على أيقونة تطبيق الطرفية لفتحه أو يمكنك الضغط على مفاتيح CTRL + ALT + T على لوحة المفاتيح في الوقت نفسه لفتح تطبيق الطرفية تلقائيًا. يمكنك تثبيت الملفات التنفيذية (الثنائية) binaries لجو مباشرةً بعد فتح الطرفية، إذ يمكنك استخدام مدير حزم مثل apt-get أو اتباع خطوات التثبيت اليدوي وهو المُستحسَن لتكون قادرًا على فهم وإجراء أيّة تعديلات مطلوب ضبطها في نظامك لكي يعمل جو بطريقة صحيحة. تأكد من أنك في المجلد home (~) قبل بدء تحميل جو: $ cd ~ استخدم الأمر curl للحصول على عنوان URL الخاص بالملف tarball الذي نسخته من الصفحة الرسمية لجو: $ curl -OL https://golang.org/dl/go1.16.7.linux-amd64.tar.gz استخدم التجزئة sha256sum للتحقق من صلاحية ملف tarball: $ sha256sum go1.16.7.linux-amd64.tar.gz يجب أن تتطابق التجزئة التي عُرضَت بعد تنفيذ الأمر السابق مع التجزئة الموجودة في صفحة التحميلات في الصفحة الرسمية لجو وإلا فهذا ليس ملفًا صالحًا ويجب عليك تحميل الملف مرةً أخرى. go1.16.7.linux-amd64.tar.gz 7fe7a73f55ba3e2285da36f8b085e5c0159e9564ef5f63ee0ed6b818ade8ef04 go1.16.7.linux-amd64.tar.gz استخرِج بعد ذلك الأرشيف الذي حمِّل وثبّته في الموقع المطلوب على النظام، ويوصى في المسار usr/local/. يتضمن هذا الأمر الراية C- التي ترشد tar إلى المجلد المحدد قبل تنفيذ أي عمليات أخرى. $ sudo tar -C /usr/local -xvf go1.16.7.linux-amd64.tar.gz أصبح لديك الآن مجلدًا باسم go في المسار usr/local/، وبذلك تكون قد حمّلت وثبّت جو على نظام أبونتو الخاص بك. الخطوة 2 - إنشاء مساحة العمل Workspace الخاصة بك يمكنك إنشاء مساحة العمل الخاصة بك بعد إكمال الخطوة الأولى، إذ ستحتوي على مجلدين في جذرها: src: مجلد ستوضع فيه ملفات جو المصدرية، وهي الملفات التي تُكتب وتُنشأ باستخدام لغة جو، إذ سيستخدِمها مُصرِّف جو لإنشاء ملفات قابلة للتنفيذ أي ملفات ثنائية يمكن تشغيلها على نظامك لتنفيذ المهام التي تتضمنها. bin: مجلد ستوضع فيه الملفات الثنائية التي أنشِئت وثُبِّتت بواسطة أدوات جو؛ بعبارة أخرى هي البرامج التي صُرِّفت من التعليمات البرمجية المصدرية الخاصة بك أو غيرها من التعليمات البرمجية المصدرية المرتبطة بجو والتي حمّلتها. من المحتمل أن يحتوي المجلد src على عدة مستودعات للتحكم في الإصدارات مثل Git و Mercurial و Bazaar، إذ سيسمح لك هذا باستيراد أساسي canonical import للشيفرة البرمجية في مشروعك، والاستيراد الأساسي هو عملية استيراد تشير إلى حزمة مؤهلة وجاهزة بالكامل مثل github.com/digitalocean/godo. سترى مجلدات مثل github.com أو golang.org أو غيرها عندما يستورد برنامجك مكتبات تابعة لجهات خارجية، فإذا كنت تستخدِم -أو لديك- شيفرات برمجية على إحدى المواقع مثل github.com، فستضع أيضًا هذه المشاريع أو ملفات المصدر ضمن هذا المجلد وستتعرّف على ذلك بعد قليل. تبدو مساحة العمل النموذجية كما يلي: . ├── bin │ ├── buffalo # أمر تنفيذي │ ├── dlv # أمر تنفيذي │ └── packr # أمر تنفيذي └── src └── github.com └── digitalocean └── godo ├── .git # البيانات الوصفية لمستودع جيت ├── account.go # ملف الحزمة ├── account_test.go # اختبار ملف الحزمة ├── ... ├── timestamp.go ├── timestamp_test.go └── util ├── droplet.go └── droplet_test.go يُعَدّ المجلد الافتراضي لمساحة العمل في جو بدءًأ من الإصدار 1.8 هو المجلد الرئيسي home للمستخدِم الذي يحتوي على مجلد فرعي باسم go أي HOME/go$، فإذا استخدَمت إصدارًا أقدم من 1.8، فمن الأفضل الاستمرار في استخدام الموقع HOME/go$ لمساحة عملك. نفّذ الأمر التالي لإنشاء بنية مجلد لمساحة العمل الخاصة بك في جو: $ mkdir -p $HOME/go/{bin,src} يطلب الخيار p- من mkdir إنشاء جميع العناصر الرئيسية parents في المجلد حتى لو لم تكن موجودة حاليًا، إذ يؤدي استخدام {bin، src} إلى إنشاء مجموعة من الوسائط لـ mkdir وإخباره بإنشاء كل من مجلد bin و src. سيؤدي ذلك إلى إنشاء بنية المجلد التالية: └── $HOME └── go ├── bin └── src سابقًا وقبل الإصدار 1.8 كان يجب عليك استخدام متغير بيئة محلي يسمى GOPATH$ من أجل تحديد المكان الذي يمكن للمُصرِّف فيه العثور على الشيفرة المصدرية المطلوب استخدامها في مشروعك، سواءً كانت الشيفرة محلية أو على موقع استضافة خارجي (عمومًا، تُعَدّ هذه الطريقة جيدةً أكثر كما أن بعض الأدوات مازالت تعتمد على استخدامه). يمكن ضبط المتغير GOPATH$ الخاص بك من خلال إضافة المتغيرات العامة إلى ‎~/.profile‎‎ وربما تحتاج أيضًا إلى إضافته إلى ملف zshrc. أو bashrc. تبعًا لتهيئة الصدَفة shell الخاصة بك. أولًا، افتح ‎~/.profile‎‎ باستخدام nano أو محرر النصوص المفضل لديك: $ nano ~/.profile حدِّد المتغير GOPATH$ الخاص بك من خلال إضافة ما يلي إلى الملف: export GOPATH=$HOME/go عندما يُصرّف جو الأدوات ويثبّتها، فسيضعها في المجلد GOPATH/bin$، ومن الشائع إضافة المجلد الفرعي bin/ الخاص بمساحة العمل إلى PATH في ‎~/.profileكما يلي: export PATH=$PATH:$GOPATH/bin سيسمح لك ذلك بتشغيل أيّ برامج مُصرَّفة بواسطة جو أو محمّلة عبر أدوات جو من أيّ مكان على نظامك. أخيرًا، ستحتاج إلى إضافة المجلد bin إلى المسار PATH من خلال إضافة المسار usr/local/go/bin/ في نهاية السطر كما يلي: export PATH=$PATH:$GOPATH/bin:/usr/local/go/bin أصبح بإمكانك الآن الوصول إلى جميع أدوات جو من أيّ مكان على نظامك. نفّذ الأمر التالي لتحميل المتغيرات العامة وتحديث الصدَفة: . ~/.profile يمكنك التحقق من تحديث المتغير PATH$ باستخدام الأمر echo وقراءة الخرج: $ echo $PATH ستشاهد GOPATH/bin$ الخاص بك والذي سيظهر في مجلد home، فإذا سجّلت الدخول على أساس جذر، فسترى root/go/bin/ في المسار. /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/root/go/bin:/usr/local/go/bin ستشاهد أيضًا المسار الخاص بأدوات جو ضمن المجلد usr/local/go/bin/: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/root/go/bin:/usr/local/go/bin تحقق الآن من التثبيت عن طريق التحقق من الإصدار الحالي من جو: $ go version سيظهر لك خرج يشبه التالي: go version go1.12.1 linux/amd64 الآن بعد أن أنشأتَ المجلد الجذر لمساحة العمل وضبطت مجموعة متغيرات البيئة GOPATH$ الخاصة بك، أصبح بإمكانك إنشاء مشاريعك باستخدام بنية المجلد التالية، وسيفترض هذا المثال أنك تستخدِم موقع github.com لاستضافة مشروعك: $GOPATH/src/github.com/username/project إذا كنت تعمل على مشروع https://github.com/digitalocean/godo على سبيل المثال، فسيُخزَّن في المجلد التالي: $GOPATH/src/github.com/digitalocean/godo ستجعل هذه البنية المشاريع متاحةً باستخدام أداة go get، كما أنها ستساعدك أيضًا في عمليات القراءة، كما يمكنك الوصول إلى مكتبة godo من خلال الأمر السابق كما يلي: $ go get github.com/digitalocean/godo سيؤدي ذلك إلى تحميل محتويات مكتبة godo وإنشاء المجلد GOPATH/src/github.com/digitalocean/godo$ على جهازك. يمكنك أيضًا التحقق من نجاح عملية تحميل حزمة godo من خلال سرد محتويات المجلد: $ ll $GOPATH/src/github.com/digitalocean/godo يجب أن تشاهد خرجًا يشبه الخرج التالي: drwxr-xr-x 4 root root 4096 Apr 5 00:43 ./ drwxr-xr-x 3 root root 4096 Apr 5 00:43 ../ drwxr-xr-x 8 root root 4096 Apr 5 00:43 .git/ -rwxr-xr-x 1 root root 8 Apr 5 00:43 .gitignore* -rw-r--r-- 1 root root 61 Apr 5 00:43 .travis.yml -rw-r--r-- 1 root root 2808 Apr 5 00:43 CHANGELOG.md -rw-r--r-- 1 root root 1851 Apr 5 00:43 CONTRIBUTING.md . . . -rw-r--r-- 1 root root 4893 Apr 5 00:43 vpcs.go -rw-r--r-- 1 root root 4091 Apr 5 00:43 vpcs_test.go بذلك تكون قد أنشأت مساحة عمل خاصة بك وهيأت متغيرات البيئة اللازمة، وسنختبر في الخطوة التالية مساحة العمل هذه من خلال كتابة برنامج بسيط. الخطوة 3 - إنشاء برنامج بسيط في جو ستنشئ برنامج “Hello, World!” بغية اختبار مساحة العمل والتعرف أكثر على جو. ستنشئ هنا ملف مصدري واحد لجو وليس مشروعًا فعليًا، لذا لا داعي لأن تكون ضمن مساحة العمل الخاصة بك لإنجاز ذلك. افتح محرر نصوص سطر الأوامر nano من المجلد الرئيسي وأنشئ ملفًا جديدًا: $ nano hello.go اكتب برنامجك في الملف الجديد: package main import "fmt" func main() { fmt.Println("Hello, World!") } ستستخدِم هذه الشيفرة حزمة fmt وستستدعي الدالة Println لطباعة Hello, World!‎ التي تم مرِّرت على أساس وسيط إلى الدالة. اخرج الآن من المحرر nano بالضغط على مفتاحَي CTRL+ X، وعند مطالبتك بحفظ الملف، اضغط على Y ثم ENTER. شغِّل برنامج hello.go الذي أنشأته عند الخروج من nano والعودة إلى الصدَفة: go run hello.go سترى الخرج التالي: Hello, World! بذلك يكون اختبار مساحة عملك قد أكتمل. خاتمة تهانينا، لقد أنشأت مساحة عمل خاصة بك لكتابة الشيفرات البرمجية وإنشاء المشاريع بلغة جو على جهاز يعمل بنظام تشغيل أبونتو. ترجمة -وبتصرُّف- للمقال How To Install Go on Ubuntu 20.04 لصاحبه Gopher Guides. اقرأ أيضًا فهم، تنصيب وتهيئة بيئة عمل لغة البرمجة Go كتابة أول برنامج (ومكتبة) لك باستخدام لغة البرمجة Go
  18. تعلمت في المقالات السابقة كيفية إنشاء تطبيق جانغو Django (تطبيق المدونة) وكيفية السماح للمستخدمين الذين لديهم الصلاحيات الإدارية إضافة التعليقات والمنشورات باستخدام لوحة التحكم في واجهة مدير جانغو Django admin interface. ستتعلم في هذا المقال إنشاء عروض جانغو views تُمكّن تطبيق الويب الخاص بك من التعامل مع طلبات الويب بالطريقة الصحيحة وارسال استجابات الويب ردًا على الطلبيات المرسلة، ويمكن أن تكون الاستجابة محتوى HTML لصفحة ويب معينة أو إعادة توجيه أو خطأ HTTP (مثل خطأ 404). العروض في جانغو هي صفحة ويب في تطبيقك تؤدي وظائف معينة وترتبط بقالب Template معين، فعلى سبيل المثال إن كان التطبيق الذي نعمل عليه عبارة عن مدونة، فمن الممكن أن يتضمن العروض التالية: الصفحة الرئيسية للمدونة، تعرض المقالات التي أضيفت مؤخرًا. صفحة المقالة، تعرض نص المقالة وتوفّر الرابط الدائم لها. أرشيف المدونة حسب السنوات، تعرض المقالات المنشورة في سنة معينة. أرشيف المدونة حسب الأشهر، تعرض المقالات المنشورة في شهر معين. أرشيف المدونة حسب الأيام، تعرض جميع المقالات المنشورة في يوم معين. حدث التعليق على المقالة، ويتحكم في عملية إضافة التعليقات على مقالة معينة. نرى مما سبق أن العروض تقوم بوظائف متعددة، فهناك عروض مسؤولة عن عرض المقالات إما باختيار المقالة المطلوبة من قبل المستخدم أو البحث عنها من خلال الأرشيف، وهناك عرض يتولى مسؤولية التحكم بعملية إضافة التعليقات في المدونة. المتطلبات الأساسية هذا المقال جزء من سلسلة مقالات قصيرة حول كيفية إنشاء تطبيق ويب ليكون بمثابة مدونة وإليك فهرس كامل السلسلة: البدء مع إطار العمل جانغو لإنشاء تطبيق ويب إنشاء تطبيق جانغو وتوصيله بقاعدة بيانات إنشاء نماذج جانغو Django Models وربطها بقاعدة البيانات تنشيط واجهة مدير جانغو والاتصال بها معالجة طلبات الويب عبر العروض views في تطبيق جانغو فإذا لم تقرأ المقالات السابقة، فيجب أن تعلم أننا نفترض ما يلي: لديك نسخة جانغو 3 أو أحدث. وصلت تطبيقك بقاعدة بيانات (نحن نستخدم MySQL). أنك تعمل على نظام تشغيل مبني على يونيكس Unix. يُفضل أن يكون خادمًا سحابيًّا أبونتو 20.04 Ubuntu، لأنه النظام الذي تم إجراء الاختبار عليه. إذا كنت تريد العمل على بيئة مشابهة، فيجب عليك إعداد جانغو عليها. أعددت واجهة مُدير جانغو الخاصة بك. هذا المقال يتعامل مع عروض جانغو، وبالتالي قد تتمكن من اتباع هذا الدرس، حتى لو كان لديك إعداد مختلف. الخطوة الأولى - إنشاء دوال العروض يجب أن تنتقل في البداية إلى مجلد مشروعك وتنشيط بيئة بايثون الخاصة بك من خلال اتباع الأوامر التالية. $ cd ~/my_blog_app $ .env/bin/activate انتقل بعد ذلك إلى المجلد blogsite لكي نفتح بعد ذلك ملف العروض وننشئ أول عرض: (env) sammy@ubuntu:$ cd ~/my_blog_app/blog/blogsite افتح ملف العروض views.py باستخدام محرر النصوص الذي تفضله: (env) sammy@ubuntu:$ nano views.py بعد فتح الملف يجب أن تضع فيه الشيفرة التالية: from django.shortcuts import render # Create your views here. السطر الأول الذي يستورد دالة العرض ()render سنتركه كما هو، حيث تتيح لنا هذه الدالة الجمع بين القالب والسياق context حتى تتمكن من إرجاع كائن HttpResponse المناسب. ضع ذلك في ذهنك، فمع كل عرض تُنشئه، يجب عليك إنشاء نُسخة HttpResponse وملئها وإرجاعها. سنضيف الآن العرض الأول الذي سيرحب بالمستخدمين في صفحة الفهرس. لذا سنستورد الدالة ()HttpResponse من المكتبة http، وسنمرر لهذه الدالة نصًا ليتم عرضه عند طلب صفحة الويب. from django.shortcuts import render from django.http import HttpResponse def index(request): return HttpResponse('Hello, welcome to the index page.') بعد ذلك سنضيف دالة أخرى لعرض منشور محدد. ... def individual_post(request): return HttpResponse('Hi, this is where an individual post will be.') الآن تكون قد انتهيت من تعديل ملف العروض views.py سيبدو كما يلي: from django.http import HttpResponse from django.shortcuts import render def index(request): return HttpResponse('Hello, welcome to the index page.') def individual_post(request): return HttpResponse('Hi, this is where an individual post will be.') بعد الانتهاء احفظ الملف واغلقه. إذا كنت تستخدم المحرر nano، اضغط على CTRL+X ثم Y ثم ENTER. حتى الآن لم يتم ربط عنوان URL مع هذه الدوال، لذا يجب عليك إضافة ذلك إلى أنماط العناوين urlpatterns في ملف العناوين urls.py. الخطوة الثانية - ربط العناوين بالعروض يمكنك إنشاء عناوين URLs الخاصة بك في جانغو لاستخدامها في تطبيقك، ويتم ذلك من خلال ملف تهيئة العناوين URLconf. تُعرَض صفحة الويب بعد أن يحدد جانغو موقع الوحدة URLconf لكي يستخدمها، إذ يُبحث عن أنماط عناوين url المُخزنة في القائمة urlpatterns ويمر على العناوين فيها واحدًا تلو الآخر حتى يعثر على أول عنوان مُتطابق، وبالتالي يكون جانغو قد عثر على العرض المُرتبط بالعنوان، ثم تتلقى دالة العرض هذه البيانات المتعلقة بعنوان url وكائن HttpRequest. إذا فشلت أي خطوة من الخطوات السابقة، فسيتم استخدام العرض error-handling المخصص لمعالجة الأخطاء وعرضها. ستعمل في هذا القسم مع ملفي عناوين مُختلفين وفي مجلدين مختلفين في تطبيقك. الآن، من مجلد ‎~/my_blog_app/blog/blogsite افتح الملف urls.py (الذي يسمى أيضًا "URLconf") لكي تُعدله: (env) sammy@ubuntu:$ nano urls.py عدّل الملف الموجود لديك بحيث يصبح كما يلي، ثم احفظه واغلقه: from django.urls import path from . import views urlpatterns = [ path('', views.index, name='index'), path('post/', views.individual_post, name='individual_post') ] بعد تحديث ملف URLconf الخاص بمجلد blogsite، ويجب عليك تضمينه في ملف URLconf الخاص بمجلد المُدونة، وإلا فلن يتم التعرّف عليه، وتحتاج ذلك لأنه تم تحديده على أنه ROOT_URLCONF في ملف الإعدادات الخاص بك. هذا يعني أن جانغو يبحث في ملف URLconf الخاص بمجلد المدونة blog عندما يحتاج إلى مُطابقة أنماط عناوين urlpatterns. لإنجاز ذلك انتقل إلى مجلد المدونة: (env) sammy@ubuntu:$ cd ~/my_blog_app/blog/blog افتح ملف العناوين لتعديله: (env) sammy@ubuntu:$ nano urls.py لإنجاز عملية التضمين، يجب إضافة الأسطر التالية إلى هذا الملف، ثم احفظ الملف واغلقه: from django.contrib import admin from django.urls import include, path urlpatterns = [ path('admin/', admin.site.urls), path('', include('blogsite.urls')) ] نفتح الآن متصفح الويب للانتقال إلى عناوين URL التي أنشأناها والتحقق من أنها تستعرض النص الذي حددناه في العرض. انتقل إلى المجلد الرئيسي للوصول إلى ملف الإدارة manager.py الذي يُخدّم تطبيقك. (env) sammy@ubuntu:$ cd .. نفّذ الأمر التالي (استبدل 0.0.0.0 بعنوان IP الخاص بك): (env) sammy@ubuntu:$ python manage.py runserver 0.0.0.0:8000 انتقل إلى عنوان IP الخاص بك والمنفذ 8000 في متصفحك: your-server-ip:8000 ستظهر لك صفحة ويب كما يلي: انتقل الآن إلى العنوان التالي: your-server-ip:8000/post/ يجب أن تظهر الصفحة التالية: بهذا تكون قد تحققت من عمل ملفي urls.py بنجاح. الخطوة الثالثة - إضافة منشور في المدونة سنضيف الآن منشورًا في المدونة ونعرضه على صفحة الويب بدلًا من النص الذي عرضناه في الخطوة السابقة والذي عرّفناه ضمن ملفات المشروع. سننشئ المنشور من خلال صفحة المُدير التي أنشأناها سابقًا. افتح المتصفح وانتقل إلى صفحة المُدير الأساسي لموقع المدونة من خلال الخادم الذي يُخدّم تطبيقك: your-server-ip:8000/admin/blogsite/ بعد أن تظهر لك واجهة المُدير، اضغط على الزر "‎+ Add" الموجودة في السطر الثاني (سطر المنشورات Posts) لإضافة منشور ووضعه في قاعدة البيانات (بالنسبة للزر الآخر "change" فستحتاجه في حال أردت تعديل المنشور لاحقًا). عند النقر على الرابط، ستتلقى نموذجًا للإدخال كالتالي: النموذج يحتوي على الحقول التالية: العنوان Title: تضع هنا عنوان المنشور، مثلًا My First Blog Post. عنوان فرعي Slug: كلمات رئيسية مقروءة، تُشتق من عنوان الصفحة، لذلك في هذه الحالة يمكننا استخدام my-first-blog-post. المحتوى Content: المحتوى النصي للمنشور. المؤلف author: الشخص الذي كتب المنشور. بعد ذلك اضغط على زر الحفظ "SAVE". سنتأكد في الخطوة التالية من إضافة سطر جديد إلى قاعدة بيانات MySQL يحتوي على البيانات التي أدخلناها. الخطوة الرابعة - عرض محتويات قاعدة البيانات يجب أن ننتقل الآن إلى قاعدة بيانات MySQL، لذا أوقف تشغيل الخادم من خلال الأمر CTRL+C، ثم افتح مُفسّر MySQL interpreter مع تحديد المُستحدم djangouser الذي أنشأته سابقًا. (env) sammy@ubuntu:$ mysql -u djangouser انتقل إلى قاعدة البيانات blog_data التي أنشأتها سابقًا: Mysql> use blog_data; اعرض محتويات الجدول blogsite_post: Mysql> select * from blogsite_post; يجب أن يكون الخرج مُشابهًا لما يلي. يجب أن يُعرض لك معلومات المنشور الذي أضفته في الخطوة السابقة: +----+--------------------+--------------------+---------------+----------------------------+--------+ | id | title | slug | content | created_on | author | +----+--------------------+--------------------+---------------+----------------------------+--------+ | 1 | My First Blog Post | my-first-blog-post | Hello, World! | 2020-05-14 00:30:03.186564 | Sammy | +----+--------------------+--------------------+---------------+----------------------------+--------+ 1 row in set (0.00 sec) كما تلاحظ في الخرج، هناك سطر يحتوي على بيانات المنشور الذي أضفته. سنشير الآن إلى هذه البيانات في دالة العرض الخاصة بالمنشورات. استخدم الأمر CTRL+D للخروج من المُفسّر. انتقل إلى الملف views.py الموجود في المجلد blogsite: (env) sammy@ubuntu:$ cd ~/my_blog_app/blog/blogsite افتح الملف الآن باستخدام المحرر الذي يناسبك لكي تضيف البيانات اللازمة: (env) sammy@ubuntu:$ nano views.py عدّل ملفك بحيث يصبح كما يلي: from django.shortcuts import render from django.http import HttpResponse from .models import Post def index(request): return HttpResponse('Hello, welcome to the index page.') def individual_post(request): recent_post = Post.objects.get(id__exact=1) return HttpResponse(recent_post.title + ': ' + recent_post.content) لاحظ أنه تمت إضافة تعليمة جديدة لاستيراد Post، وتم حذف السلسلة النصية من HttpResponse واستبدالها ببيانات منشور المدونة. للإشارة إلى البيانات الخاصة بكائن معين، يتم استخدام مُعرّف ID المنشور المرتبط بالكائن الذي ترغب في عرضه، وخزّن هذا المُعرّف في المتغير recent_post. يمكنك بعدها الحصول على محتويات حقول معينة لهذا الكائن من خلال وضع نقطة ثم اسم الحقل. انتقل إلى ملف الإدارة manage.py بعد إغلاق وحفظ الملف لتشغيل التطبيق: (env) sammy@ubuntu:$ cd ~/my_blog_app/blog (env) sammy@ubuntu:$ python manage.py runserver 0.0.0.0:8000 انتقل من خلال المتصفح إلى الموقع التالي: your-server-ip:8000/post/ سترى هنا التغييرات التي أجريتها؛ سترى النص الذي أضفته إلى المنشور. يمكنك الآن إيقاف تشغيل الخادم بالضغط على CTRL+C ليتم نقلك بعدها إلى البيئة البرمجية الخاصة بك، واستخدم الأمر التالي عندما تريد الخروج من البيئة لإلغاء تنشيطها ونقلك إلى الموقع الافتراضي في الطرفية: (env) sammy@ubuntu: $ deactivate خاتمة تعلّمت في هذه المقالة كيفية إنشاء عروض جانغو وربطها بأنماط URL معينة وعرض نص مُخزّن في قاعدة بيانات المنشورات الخاصة بتطبيق المدونة على صفحة ويب. ترجمة -وبتصرف- للمقال How To Create Views for Django Web Development لصاحبه Jeremy Morris. اقرأ أيضًا مدخل إلى إطار العمل Django إنشاء تطبيق الاقتراعات وكتابة العرض الأول على Django العروض والقوالب في Django - الجزء الأول
  19. هذا المقال هو جزء من سلسلة مقالات سابقة، حيث تعلمت في المقالات السابقة كيفية إنشاء تطبيق جانغو وربطه بقاعدة بيانات MySQL وإنشاء نماذج للمنشورات والتعليقات داخل تطبيق الويب، وستتعلم في مقال اليوم كيفية الاتصال بموقع مُدير جانغو Django admin site وتنشيطه لكي تتمكن من إدارة تطبيق جانغو الخاص بك على الويب (المُدونة التي أنشأتها في المقالات السابقة). موقع مُدير جانغو يمتلك واجهة تُسمى واجهة مُدير جانغو Django admin interface تُسهل عليك العمل وتمنحك القدرة على إدارة موقعك أنت وأي مستخدم آخر لديه الصلاحيات في ذلك. المتطلبات الأساسية هذا المقال جزء من سلسلة مقالات قصيرة حول كيفية إنشاء تطبيق ويب ليكون بمثابة مدونة وإليك فهرس كامل السلسلة: البدء مع إطار العمل جانغو لإنشاء تطبيق ويب إنشاء تطبيق جانغو وتوصيله بقاعدة بيانات إنشاء نماذج جانغو Django Models وربطها بقاعدة البيانات تنشيط واجهة مدير جانغو والاتصال بها معالجة طلبات الويب عبر العروض views في تطبيق جانغو إذا لم تقرأ المقالات السابقة، فيجب أن تعلم أننا نفترض ما يلي: لديك نسخة جانغو 3 أو أحدث. وصلت تطبيقك بقاعدة بيانات (نحن نستخدم MySQL). أنك تعمل على نظام تشغيل مبني على يونيكس Unix. يُفضل أن يكون خادمًا سحابيًّا أبونتو Ubuntu، لأنه النظام الذي تم إجراء الاختبار عليه. إذا كنت تريد العمل على بيئة مشابهة، فيجب عليك إعداد جانغو عليها. يتعامل هذا المقال مع واجهة مُدير جانغو، وبالتالي قد تتمكن من اتباع هذا الدرس، حتى لو كان لديك إعداد مختلف. الخطوة الأولى - تنشيط المدير Admin كما في المقالات السابقة؛ عليك أولًا تنشيط بيئة بايثون الخاصة بك والانتقال إلى المجلد الجذر للتطبيق:‏ $ cd ~/my_blog_app $ . env/bin/activate يجب عليك الآن التأكد من أن تطبيقك موجود في القائمة INSTALLED_APPS في ملف الإعدادات settings.py، لذا انتقل إلى المجلد الذي يحتوي على هذا الملف: (env) sammy@ubuntu: $ cd ~/my_blog_app/blog/blog/ افتح ملف الإعدادات بواسطة أي محرر تريده (سنستخدم هنا المحرر nano): (env) sammy@ubuntu: $ nano settings.py إذا لم تجد تطبيقك في القائمة، أضفه من خلال django.contrib.admin. بعد تنفيذ الأمر السابق يجب أن يكون قسم INSTALLED_APPS من الملف يشبه الملف التالي، حيث أن blogsite يمثّل اسم التطبيق الذي أنشأناه في المقالات السابقة. ... # Application definition INSTALLED_APPS = [ 'blogsite', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ] ... في حال أجريت أيّة تعديلات، فيجب عليك حفظ الملف وإغلاقه (إذا كنت تستخدم المحرر nano، اضغط على CTRL+X ثم Y ثم ENTER). افتح الآن ملف العناوين urls.py باستخدام محرر النصوص الذي تستخدمه: (env) sammy@ubuntu: $ nano urls.py يجب أن يكون الملف يشبه التالي: … """ from django.contrib import admin from django.urls import path urlpatterns = [ path('admin/', admin.site.urls), ] إذا كان الملف عندك يختلف عن الملف السابق، فانسخ أسطر هذا الملف من هنا، ولصقها في ملف العناوين عندك. بذلك تكون قد تأكدت من أن مشروعك يحتوي على الشيفرات المناسبة في ملف الإعدادات وملف العناوين، وبالتالي سيتمكن تطبيقك من الوصول إلى النماذج وواجهة مُدير جانغو. الخطوة الثانية - تنشيط تطبيق المدير يجب أن يتم الآن تهجير النماذج إلى قاعدة البيانات، لكي تتعرّف على نماذج المُدير التي تمت إضافتها. انتقل إلى المجلد الذي يوجد فيه ملف الإدارة manager.py: (env) sammy@ubuntu: $ python manage.py createsuperuser تذكر أنّه يتوجب عليك دائمًا تنفيذ أمر التهجير migrate عندما تُجري أي تعديلات على النماذج: (env) sammy@ubuntu: $python manage.py migrate يجب أن تحصل على خرج مشابه للخرج التالي عند تنفيذ أمر التهجير في حال لم تٌجري تعديلات الملفات السابقة: Operations to perform: Apply all migrations: admin, auth, blogsite, contenttypes, sessions Running migrations: No migrations to apply. أما لو كنت قد أجريت تعديلات على النماذج، فسيخبرك بأنه نفذ عمليات التهجير اللازمة. شغّل الخادم الآن من خلال الأمر التالي (استبدال 0.0.0.0 بعنوان IP الخاص بك): (env) sammy@ubuntu: $python manage.py runserver 0.0.0.0:8000 ثم انتقل إلى عنوان URL الخاص بلوحة التحكم في المتصفح الذي تستخدمه (تأكد من ادخال عنوان IP الخاص بخادمك). http://your-server-ip:8000/admin/ ستظهر لك شاشة تسجيل الدخول التالية: بذلك نكون نجحنا في تنشيط التطبيق أو تطبيق المٌدير admin app، لكن يجب أن يكون لدينا حساب مُدير لكي نتمكن من الدخول. إذا لم يكن لديك حساب فتابع الخطوة التالية. الخطوة الثالثة - إنشاء حساب مُدير أساسي Admin Super-User افتح نافذة جديدة للطرفية للاتصال بالخادم، أو أوقف تطبيق جانغو بالضغط على CTRL+C لكي تتمكن من العمل ضمن البيئة الخاصة بك. افتح ملف الإدارة manager.py: (env) sammy@ubuntu: $ python manage.py createsuperuser بعد ذلك سيطلب منك تحديد معلومات المستخدم، مثل اسم المستخدم والبريد الإلكتروني وكلمة المرور. هنا سنسميه admin_user وسيكون البريد sammy@example.com وكلمة المرور admin123. Username (leave blank to use 'root'): admin_user Email address: sammy@example.com بعد ذلك سيطلب منك إدخال كلمة المرور مرتين (للتأكيد). لذا ادخل الكلمة الأولى ثم اضغط ENTER ثم أعد كتابتها واضغط ENTER. Password: Password (again): الآن أصبح لديك حساب مُدير أساسي، وأصبح بإمكانك تسجيل الدخول. بعد تسجيل الدخول بنجاح ستظهر لك الصورة التالية: بعد ذلك تحتاج إلى ربط تطبيقك بلوحة الإدارة admin panel. الخطوة الرابعة - إنشاء أنماط عناوين للنشر والتعليق حتى الآن لازالت لوحة الإدارة لا تحتوي على تطبيقك (تطبيق المدونة)، لذا يجب أن تضيفها وتسجلها مع النماذج المرتبطة بها (Comment و Post). لإنجاز ذلك، أنشئ ملفًا فارغًا يُسمى urls.py في المجلد blogsite: (env) sammy@ubuntu: $ touch ~/my_blog_app/blog/blogsite/urls.py أضف في هذا الملف نمط عنوان URL لتطبيقك، لكي تتمكن من الوصول إليه عبر واجهة المٌدير. انتقل إلى المجلد الذي يحتوي على ملف العناوين urls.py الذي أنشأته: (env) sammy@ubuntu: $ cd ~/my_blog_app/blog/blogsite/ ثم افتح الملف باستخدام محرر النصوص: (env) sammy@ubuntu: $ nano urls.py أضف التعليمات البرمجية التالية إليه: from django.urls import path from . import views urlpatterns = [ path('$/', views.posts, name='posts'), path('$/', views.comments, name='comments'), ] بذلك نكون انتهينا من إضافة أنماط العناوين اللازمة ليتمكن التطبيق من الوصول إلى العروض views (لم نتحدث عنها في المقالات السابقة، لكن سنغطيها لاحقًا) والمنشورات Posts والتعليقات Comments. الخطوة الخامسة - ربط تطبيق المدونة بحساب المدير ستتمكن من رؤية روابط كل المنشورات والتعليقات من داخل لوحة التحكم عند ربط المدونة بواجهة المُدير. في الوقت الحالي لا توجد تعليقات أو منشورات في مدونتك، لذا لن ترى إلا روابط للمجموعات Groups والمستخدمين Users. لربط المنشورات والتعليقات بحساب المُدير، يجب عليك تسجيل النماذج الخاصة بكل منهما داخل ملف المُدير لموقعك في المجلد blogsite. انتقل إلى المجلد: (env) sammy@ubuntu: $ cd ~/my_blog_app/blog/blogsite افتح بعد ذلك ملف المُدير admin.py باستخدام محرر النصوص الذي تفضله: (env) sammy@ubuntu: $ nano admin.py سيكون بهذا الشكل: from django.contrib import admin # Register your models here. الآن أضف إليه التعليمات البرمجية اللازمة لتسجيلهم كما يلي: from django.contrib import admin from blogsite.models import Post from blogsite.models import Comment admin.site.register(Post) admin.site.register(Comment) احفظ الملف واغلقه عندما تنتهي، وبذلك تكون قد سجلت النموذجين داخل لوحة التحكم. الخطوة السادسة - تحقق من أن عملية الربط تمت بنجاح بعد إضافة الشيفرة البرمجية اللازمة لتسجيل النماذج في ملف المُدير، شغّل الخادم مرة أخرى من خلال: http://your-server-ip:8000/admin ثم سجل الدخول في التطبيق من حساب المُدير الذي أنشأناه، يُفترض أن يتم نقلك بعد ذلك إلى صفحة الويب التالية (إذا لم تظهر فقد تحتاج إلى تحديث متصفحك). هذا يؤكد أن عملية الربط تمت بنجاح. يمكنك الآن إيقاف تشغيل الخادم بالضغط على CTRL+C ليتم نقلك بعدها إلى البيئة البرمجية الخاصة بك. عندما تريد الخروج من البيئة، استخدم الأمر التالي، لإلغاء تنشيطها ونقلك إلى الموقع الافتراضي في الطرفية: (env) sammy@ubuntu: $ deactivate خاتمة تعلمت في هذه المقالة كيفية تنشيط واجهة مُدير جانغو، وإنشاء حساب مُدير أساسي وتسجيل الدخول إلى الواجهة من خلاله، وتسجيل نماذج النشر والتعليق وربطها بحساب المُدير. لكي تتمكن لاحقًا من إنشاء منشورات ومراقبة التعليقات من خلال لوحة التحكم. ترجمة -وبتصرف- للمقال How To Enable and Connect the Django Admin Interface لصاحبه Jeremy Morris. اقرأ أيضًا مدخل إلى إطار العمل Django تثبيت إطار العمل جانغو على أوبنتو
  20. تعلمت في المقال السابق كيفية إنشاء قاعدة بيانات MySQL وإنشاء تطبيق جانغو Django وربطه بها وتشغيله. في هذا المقال سننشئ نماذج models في جانغو التي تُعرّف الحقول والسلوكيات الخاصة ببيانات تطبيقك (تطبيق المُدونة الذي بدأنا به في المقال السابق)، إذ تربط هذه النماذج البيانات من تطبيقك إلى قاعدة البيانات، ويستخدمها جانغو لإنشاء جداول قاعدة البيانات من خلال واجهة برمجة التطبيقات ORM (اختصار للعبارة Object Relational Mapping أي "ربط الكائنات العِلاقيَّة") وهو عبارة عن طريقة لربط الكائنات الخاصة بتطبيق ما بجداول في نظام إدارة قواعد بيانات علائقية. ويمكن تعريف النماذج بشكل مبسط على أنها وصف للبيانات الموجودة في قاعدة البيانات، وبمعنى آخر تمثّل النماذج في جانغو بنية قاعدة البيانات، أي ما ستحصل عليه من إجراء الأمر CREATE TABLE، لكن بلغة بايثون بدلًا من SQL. المتطلبات الأساسية هذا المقال جزء من سلسلة مقالات قصيرة حول كيفية إنشاء تطبيق ويب ليكون بمثابة مدونة وإليك فهرس كامل السلسلة: البدء مع إطار العمل جانغو لإنشاء تطبيق ويب إنشاء تطبيق جانغو وتوصيله بقاعدة بيانات إنشاء نماذج جانغو Django Models وربطها بقاعدة البيانات تنشيط واجهة مدير جانغو والاتصال بها معالجة طلبات الويب عبر العروض views في تطبيق جانغو فإذا لم تكن قد قرأت المقالات السابقة وطبقتها، فيجب أن تعلم أننا نفترض ما يلي: لديك نسخة جانغو 3 أو أحدث. وصلت تطبيقك بقاعدة بيانات (نحن نستخدم MySQL). أنك تعمل على نظام تشغيل مبني على يونيكس Unix. يُفضل أن يكون خادمًا سحابيًّا أبونتو Ubuntu، لأنه النظام الذي تم إجراء الاختبار عليه. إذا كنت تريد العمل على بيئة مشابهة، فيجب عليك إعداد جانغو عليها (يمكنك العودة إلى المقال الأول في السلسلة). هذا المقال يتعامل مع نماذج جانغو، وبالتالي قد تتمكن من اتباع هذا الدرس، حتى لو كان لديك إعداد مختلف. الخطوة الأولى - إنشاء تطبيق جانغو لكي تعمل وفق النهج العام المُتبع في جانغو، يجب عليك إنشاء تطبيق جانغو ضمن المشروع، ويحتوي على جميع الملفات اللازمة لإنشاء موقع المدونة. عندما تريد معاودة العمل على مشروعك في جانغو، عليك أولًا تنشيط بيئة بايثون الخاصة بك والتي أنشأتها لأجل هذا الغرض، ثم الانتقال إلى المجلد الجذر للتطبيق. يمكنك إنجاز ذلك كما يلي: $ cd ~/my_blog_app $ . env/bin/activate $ cd blog بعد الانتقال إلى المشروع، نفّذ الأمر التالي: (env) sammy@ubuntu:$ python manage.py startapp blogsite يؤدي ذلك إلى إنشاء تطبيقك، بجانب مجلد مشروع المدونة، وستصبح بنية المجلد لديك في هذه المرحلة كما يلي: my_blog_app/ └── blog ├── blog │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-38.pyc │ │ ├── settings.cpython-38.pyc │ │ ├── urls.cpython-38.pyc │ │ └── wsgi.cpython-38.pyc │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── blogsite │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── tests.py │ └── views.py └── manage.py سنركز في هذا المقال على الملف models.py الموجود في المجلد blogsite. الخطوة الثانية - إنشاء نموذج المنشورات Posts Model يجب علينا أولًا أن نفتح ملف model.py وأن نحرره بحيث يحتوي على الشيفرة الخاصة بإنشاء نموذج النشر، وهو نموذج يتضمن حقول قاعدة البيانات التالية: title: عنوان المنشور على المدونة. slug: يتم فيها تخزين عناوين URL الصالحة وإنشاءها لصفحات الويب. content: المحتوى النصي لمنشور المدونة. Creat_on: تاريخ إنشاء المنشور. author: الشخص الذي كتب المنشور. انتقل الآن إلى المجلد الذي يحتوي الملف model.py: (env) sammy@ubuntu:$ cd ~/my_blog_app/blog/blogsite استخدم الأمر cat لإظهار محتويات الملف في الطرفية terminal: (env) sammy@ubuntu:$ cat models.py يجب أن يحتوي الملف على الشيفرة التالية، حيث ستجد فيه تعليمة استيراد النماذج import models، جنبًا إلى جنب مع تعليق يصف ما سيتم وضعه في ملف model.py: from django.db import models # Create your models here. أضف الشيفرة التالية إلى ملف model.py باستخدام أحد محررات النصوص (هنا سيتم استخدام المحرر nano): (env) sammy@ubuntu:$ nano models.py نضع الآن داخل هذا الملف تعليمات استيراد الوحدات التالية: from django.db import models from django.template.defaultfilters import slugify from django.contrib.auth.models import User from django.urls import reverse حيث نستورد الوحدة slugify لتوليد العناوين الفرعية slugs من السلاسل strings، ونستخدم الوحدة User للاستيثاق authentication، ونستخدم reverse لتوفير مرونة أكبر في إنشاء عناوين URL. أضف بعد ذلك تابع لصنف class method إلى صنف النموذج model class والتي سنسميها Post، مع إضافة الحقول التالية أيضًا إلى قاعدة البيانات: ... class Post(models.Model): title = models.CharField(max_length=255) slug = models.SlugField(unique=True, max_length=255) content = models.TextField() created_on = models.DateTimeField(auto_now_add=True) author = models.TextField() سنضيف بعد ذلك دالة لإنشاء عنوان URL، ودالة لحفظ المنشور، وهذا أمر مهم جدًا لأنه يُنشئ رابطًا فريدًا لكل منشور في المدونة. ... def get_absolute_url(self): return reverse('blog_post_detail', args=[self.slug]) def save(self, *args, **kwargs): if not self.slug: self.slug = slugify(self.title) super(Post, self).save(*args, **kwargs) نحتاج الآن إلى إخبار النموذج بكيفية ترتيب المنشورات وعرضها على صفحة الويب، إذ يضاف النهج اللازم لإنجاز ذلك إلى الصنف الداخلي Meta الذي يحتوي أيضًا على نموذج مهم آخر لا يرتبط بتعريف حقل قاعدة البيانات. ... class Meta: ordering = ['created_on'] def __unicode__(self): return self.title تبقى إضافة نموذج التعليق Comment إلى هذا الملف، وهذا يعني أنك بحاجة إلى إضافة صنف جديد يسمى Comment، يحتوي على الحقول التالية: الاسم: اسم الشخص الذي يقوم بنشر التعليق. البريد الإلكتروني: عنوان بريده الإلكتروني. النص: نص التعليق. المنشور: المنشور الذي تم التعليق عليه. ... class Comment(models.Model): name = models.CharField(max_length=42) email = models.EmailField(max_length=75) website = models.URLField(max_length=200, null=True, blank=True) content = models.TextField() post = models.ForeignKey(Post, on_delete=models.CASCADE) created_on = models.DateTimeField(auto_now_add=True) انتهيت الآن ولكن تأكد من أن ملفك يحتوي على يُطابق الملف التالي: from django.db import models from django.template.defaultfilters import slugify from django.contrib.auth.models import User from django.urls import reverse class Post(models.Model): title = models.CharField(max_length=255) slug = models.SlugField(unique=True, max_length=255) content = models.TextField() created_on = models.DateTimeField(auto_now_add=True) author = models.TextField() def get_absolute_url(self): return reverse('blog_post_detail', args=[self.slug]) def save(self, *args, **kwargs): if not self.slug: self.slug = slugify(self.title) super(Post, self).save(*args, **kwargs) class Meta: ordering = ['created_on'] def __unicode__(self): return self.title class Comment(models.Model): name = models.CharField(max_length=42) email = models.EmailField(max_length=75) website = models.URLField(max_length=200, null=True, blank=True) content = models.TextField() post = models.ForeignKey(Post, on_delete=models.CASCADE) created_on = models.DateTimeField(auto_now_add=True) بعد ذلك احفظ الملف واغلقه (إذا كنت تستخدم المحرر nano اضغط CTRL+X ثم Y ثم ENTER). بعد الانتهاء من إعداد ملف models.py، يمكنك الانتقال إلى ملف settings.py لتحديثه. الخطوة الثالثة - تحديث الإعدادات بعد الانتهاء من إضافة النماذج إلى التطبيق، يجب أن تُخبر المشروع أن التطبيق blogsite الذي أضفناه منذ قليل موجود. لإنجاز ذلك، عليك بإضافته إلى قسم INSTALLED_APPS في ملف الإعدادات settings.py. انتقل إلى المجلد الذي يحتوي ملف الإعدادات: (env) sammy@ubuntu:$ cd ~/my_blog_app/blog/blog افتح الآن ملف settings.py باستخدام محرر النصوص: $ nano settings.py أضف الآن التطبيق blogsite إلى القائمة INSTALLED_APPS: # Application definition INSTALLED_APPS = [ 'blogsite', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ] الخطوة الرابعة - عمليات التهجير بعد إضافة النموذج Comment والنموذج Post، يجب عليك تطبيق هذه التغييرات، لكي يتعرف مخطط قاعدة بيانات MySQL عليها وينشئ الجداول اللازمة. الآن لو انتقلنا إلى المجلد ‎~/my_blog_app/blog/blogsite/migrations ونفذنا الأمر ls، ستلاحظ وجود ملف واحد هو ‎__init__.py، لكن ذلك سيتغير بعد التهجير. توجّه إلى مجلد المشروع عن طريق سطر الأوامر ونفّذ الأمر التالي للانتقال إلى المجلد blog: (env) sammy@ubuntu:$ cd ~/my_blog_app/blog ثم نفذ الأمر makemigrations على الملف manage.py: (env) sammy@ubuntu:$ python manage.py makemigrations وظيفة الأمر makemigrations هي إخبار جانغو بأنّك قد أجريت بعض التعديلات على النماذج وأنّك ترغب في حفظ هذه التعديلات على هيئة ملف تهجير يُحفظ على القرص الصلب كملف بايثون في مجلد migrations، تحت اسم ‎0001_initial.py و pycache وهي من ضمن ملفات تُنشَأ تلقائيًّا في كل مرة تنفذ هذا الأمر: Migrations for 'blogsite': blogsite/migrations/0001_initial.py - Create model Post - Create model Comment تذكر عندما انتقلنا إلى ‎~/my_blog_app/blog/blogsite/migrations كان يحتوي فقط على ملف ‎__init__.py. الآن لو رجعت إلى هذا المجلد، ستلاحظ وجود ملفين هما ‎0001_initial.py و pycache، ويمكنك تنفيذ الأمر التالي لرؤية محتويات هذا الملف: less 0001_initial.py انتقل الآن إلى المجلد ‎~/my_blog_app/blog: $cd ~/my_blog_app/blog بما أنه تم إنشاء ملف تهجير، يجب تطبيق التغييرات التي تحددها هذه الملفات على قاعدة البيانات باستخدام أمر التهجير migrate لكن بدايةً تحقق من عمليات التهجير الموجودة حاليًّا باستخدام الأمر showmigrations. (env) sammy@ubuntu:$ python manage.py showmigrations سيكون الخرج: admin [X] 0001_initial [X] 0002_logentry_remove_auto_add [X] 0003_logentry_add_action_flag_choices auth [X] 0001_initial [X] 0002_alter_permission_name_max_length [X] 0003_alter_user_email_max_length [X] 0004_alter_user_username_opts [X] 0005_alter_user_last_login_null [X] 0006_require_contenttypes_0002 [X] 0007_alter_validators_add_error_messages [X] 0008_alter_user_username_max_length [X] 0009_alter_user_last_name_max_length [X] 0010_alter_group_name_max_length [X] 0011_update_proxy_permissions blogsite [ ] 0001_initial contenttypes [X] 0001_initial [X] 0002_remove_content_type_name sessions [X] 0001_initial ستلاحظ أنه تم التحقق من جميع عمليات التهجير باستثناء التهجير الخاص بالملف ‎0001_initial.py الذي أنشأناه منذ قليل. تحقق الآن من تعليمات SQL التي يتم تنفيذها عند إجراء عمليات التهجير من خلال الأمر التالي (يأخذ هذا الأمر اسم التهجير والتهجير كوسطاء): (env) sammy@ubuntu:$ python manage.py sqlmigrate blogsite 0001_initial ستلاحظ الخرج التالي الذي يوضح تعليمات SQL التي تم تنفيذها في الخلفية. -- -- Create model Post -- CREATE TABLE `blogsite_post` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `title` varchar(255) NOT NULL, `slug` varchar(255) NOT NULL UNIQUE, `content` longtext NOT NULL, `created_on` datetime(6) NOT NULL, `author` longtext NOT NULL); -- -- Create model Comment -- CREATE TABLE `blogsite_comment` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `name` varchar(42) NOT NULL, `email` varchar(75) NOT NULL, `website` varchar(200) NULL, `content` longtext NOT NULL, `created_on` datetime(6) NOT NULL, `post_id` integer NOT NULL); ALTER TABLE `blogsite_comment` ADD CONSTRAINT `blogsite_comment_post_id_de248bfe_fk_blogsite_post_id` FOREIGN KEY (`post_id`) REFERENCES `blogsite_post` (`id`); نفّذ الآن أمر التهجير لكي يتم تطبيق التغييرات على قاعدة البيانات: (env) sammy@ubuntu:$ python manage.py migrate ستحصل على الخرج التالي: Operations to perform: Apply all migrations: admin, auth, blogsite, contenttypes, sessions Running migrations: Applying blogsite.0001_initial... OK بذلك تكون قد انتهيت من إنجاز عمليات التهجير. هناك ثلاث ملاحظات يجب الانتباه لها عند إجراء عمليات التهجير: إذا لم تكتمل عملية التهجير بنجاح، يتعين عليك إلغاء التغييرات التي أجريتها يدويًّا قبل معاودة المحاولة (إجراء محاولة تهجير أخرى)، لأن دعم هذا النوع من عمليات التعديل على المخطط ضعيفة. معظم عمليات التعديل على مخطط قاعدة البيانات تؤدي إلى إعادة كتابة الجداول بالكامل، وبالتالي قد يؤدي إلى بطء في التنفيذ. في MySQL هناك حدود معينة لطول أسماء الأعمدة والجداول والفهارس. من أجل كل قاعدة بيانات تفكر في استخدامها مع جانغو، حبذا لو تقارن بين مزايا وعيوب كل قاعدة بيانات. الخطوة الخامسة - تحقق من مخطط قاعدة البيانات يجب بعد الانتهاء من عمليات التهجير أن نتأكد من نجاح توليد الجداول في قاعدة البيانات، والتي أنشأناها من خلال نماذج جانغو. لإنجاز ذلك سجل الدخول إلى قاعدة بيانات MySQL، سنستخدم حساب المستخدم djangouser الذي أنشأناه سابقًا. (env) sammy@ubuntu:$ mysql blog_data -u djangouser حدد الآن قاعدة البيانات blog_data. إذا كنت لا تتذكرها، فيمكنك استخدام الأمر SHOW DATABASES;‎ لإظهار جميع قواعد البيانات الموجودة. mysql> USE blog_data; ثم اكتب الأمر التالي لعرض الجداول: mysql> SHOW TABLES; يجب أن تحصل على الخرج التالي: +----------------------------+ | Tables_in_blog_data | +----------------------------+ | auth_group | | auth_group_permissions | | auth_permission | | auth_user | | auth_user_groups | | auth_user_user_permissions | | blogsite_comment | | blogsite_post | | django_admin_log | | django_content_type | | django_migrations | | django_session | +----------------------------+ 12 rows in set (0.01 sec) الجدولين blogsite_comment و blogsite_post هما الجداول التي تمثل النماذج التي أنشأنها. للتحقق من أنها تحتوي على الحقول التي عرفناها: mysql> DESCRIBE blogsite_comment; الخرج: +------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | id | int | NO | PRI | NULL | auto_increment | | name | varchar(42) | NO | | NULL | | | email | varchar(75) | NO | | NULL | | | website | varchar(200) | YES | | NULL | | | content | longtext | NO | | NULL | | | created_on | datetime(6) | NO | | NULL | | | post_id | int | NO | MUL | NULL | | +------------+--------------+------+-----+---------+----------------+ 7 rows in set (0.00 sec) والأمر نفسه بالنسبة للجدول blogsite_post: mysql> DESCRIBE blogsite_post; الخرج: +------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | id | int | NO | PRI | NULL | auto_increment | | title | varchar(255) | NO | | NULL | | | slug | varchar(255) | NO | UNI | NULL | | | content | longtext | NO | | NULL | | | created_on | datetime(6) | NO | | NULL | | | author | longtext | NO | | NULL | | +------------+--------------+------+-----+---------+----------------+ 6 rows in set (0.00 sec) يمكنك الآن إغلاق MySQL باستخدام CTRL+D، بعد ذلك يمكنك مغادرة بيئة بايثون الخاصة بك من خلال تنفيذ أمر إلغاء التنشيط، وبالتالي الانتقال إلى الموقع الافتراضي في الطرفية: (env) sammy@ubuntu:$ deactivate خاتمة تعلمت في هذا المقال إضافة نماذج للوظائف الأساسية في مشروعك وتعلمت كتابة الشيفرة البرمجية اللازمة لتعريف النماذج وكيفية إجراء عمليات التهجير إلى جدول قاعدة بيانات MySQL. ترجمة -وبتصرف- للمقال How To Create Django Models لصاحبه Jeremy Morris. اقرأ أيضًا مدخل إلى إطار العمل Django إنشاء تطبيق الاقتراعات وكتابة العرض الأول على Django مقدمة عن قواعد البيانات
  21. تحدثنا في المقالات السابقة عن كيفية التحكم في الإصدار من خلال جيت بالنسبة للملفات النصية فقط، لكن ماذا عن الملفات الثنائية؟ جيت لديها بعض الإضافات التي تمكنها من التعامل مع هذا النوع من الملفات، وهذا هو موضوع المقال الأخير من هذه السلسلة. تعامل جيت git مع الكائنات الثنائية المصدرية Binary Blobs جميع المستخدمين يتفقون على أن جيت أداة محدودة القدرة في التعامل مع الكائنات الثنائية المصدرية، ولا سيما الكبيرة منها، ولقد أشرنا إلى ذلك في المقال الأول. تجدر الملاحظة إلى أنه بإمكانك استخدام جيت مع الملفات النصية الكبيرة جدًا دون مشاكل، لكن مع ملف ثنائي فالأمر مختلف، فجيت في هذه الحالة لا تستطيع معاملته إلا كصندوق أسود كبيرة وتحفظه كما هو. لنفترض أن لديك نموذجًا معقدًا ثلاثي الأبعاد يمثل لعبة ألغاز جديدة تصنعها، وحفظته بصيغة ثنائية ونتج ملف بسعة 1 جيجابايت، ثم نفذت عملية إيداع للملف، أي أنك أضفت 1 جيجابايت كاملة إلى سجل مستودعك. لاحقًا قررت إجراء بعض التعديلات على هذا النموذج، وبالفعل قمت بتعديل لون شعر النموذج وتريد أن تقوم بتنفيذ عملية إيداع مرة أخرى؛ وهنا لا يمكن لجيت تمييز اللون ولا حتى معرفة فيما إذا غيرت لون الشعر فقط أو أنك غيرت لون كامل النموذج، وهذه مشكلة، لأن جيت في هذه الحالة سيخصص غيغابايت جديدة بالكامل لهذا الإيداع، وربما تقرر لاحقًا تغيير لون عينه أو شكل رأسه، ومع كل مرة ننفذ عملية إيداع نستهلك جيجابايت جديدة بالرغم من أن التعديلات طفيفة للغاية، وهذه مشكلة خطية. بينما لو قارنت ذلك بملف نصي مهما كان تنسيقه، فستجد أن الأمر مختلف تمامًا، فجيت في حالة الملفات النصية يستطيع فهم التعديلات، وبدل أن يقوم بحفظ كامل الملف مرة أخرى بعد كل عملية إيداع تُجريها، فإنه يقوم بالتعديل على النسخة السابقة فقط. عمومًا، هناك حاجة كبيرة لاستخدام الملفات الثنائية عند العديد من المستخدمين، لذا ظهرت العديد من الحلول. يعد Git Large File Storage (اختصارًا LFS) مشروعًا مفتوح المصدر من جيت هاب بدأ كفرع من Git-media، إذ Git-media و git-annex هما إضافات لجيت يهدفان إلى إدارة الملفات الكبيرة، وكل منهما له طريقته الخاصة وميزاته التي يتفرد بها، والتالي يمثل بعضًا منها: Git-annex هو نظام مزامنة ملفات موزع يسمح لك بإدارة الملفات الكبيرة، حيث تُنشئ أنت والمستخدمين مستودعاتكم الخاصة ويكون لكل مستودع مجلد محلي ‎.git/annex يتم فيه تخزين الملفات الكبيرة. تتم مزامنة كل شيء بانتظام وبالتالي كل البيانات اللازمة تكون متاحة لجميع المستخدمين. افتراضيًا يفضل git-annex التخزين المحلي قبل التخزين خارج الموقع، لكن يمكنك تغيير ذلك من خلال annex-cost. Git-portal هو أيضًا نظام مزامنة ملفات موزع، وكما هو الحال في git-annex لديها خيار المزامنة مع موقع مركزي، ويستخدم أدوات مساعدة شائعة، مثل باش Bash وجيت وبرنامج rsync. Git-LFS هو نموذج مركزي، ومستودع للملفات والبيانات المشتركة. أنت تخبر Git-LFS أين هو المكان الذي يتم فيه تخزين ملفاتك الكبيرة، سواء كان على قرص صلب أو مخدم أو خدمة تخزين سحابية، ويتعامل كل مستخدم في مشروعك مع هذا المكان باعتباره الموقع الرئيسي المركزي للملفات الكبيرة. نموذج git-portal يؤمن Git-portal لجيت إمكانية إدارة الكائنات الثنائية باستخدام أدوات يونكس الأساسية مثل باش وجيت نفسها وبرنامج rsync اختياريًا. ينسخ Git-portal الملفات الثنائية الكبيرة إلى وحدة تخزين محلية أو خارجية (بعيدة)، ويعطيك روابط لينة symlinks يمكنك إيداعها جنبًا إلى جنب مع بقية ملفات مشروعك. إنه أداة بسيطة عمومًا، ويتطلب تنفيذ إجراءات يدويًا أحيانًا، مثلًا لا تحتوي على جامع مهملات (إجرائية لتتبع البيانات غير المستخدمة والتي تستهلك الموارد مثل الذاكرة)، وبالتالي يجب عليك القيام بذلك يدويًا، وهو أداة مثالية للمستخدمين الذين يحتاجون إلى إدارة الملفات الكبيرة والتي من الصعب أو غير الممكن إداراتها من خلال جيت، وهي لا تختلف عن جيت إلا ببعض الأمور البسيطة جدًا، لذا فتعلمه لن يكون عائقًا على الإطلاق. يمكنك تثبيت Git-portal من صفحة المشروع الخاصة به على جيت لاب. كل أوامر هذه الأداة تعكس الأوامر المستخدمة في جيت، فمثلًا لاستخدام Git-portal في مشروع: $ git-portal init لإضافة ملف وليكن مثلًا bigfile.png وهو صورة كبيرة الحجم، ننفذ الأمر التالي: $ git-portal add bigfile.png بمجرد إرسال الملف من خلال الأمر السابق، تكون باقي العمليات التي قد تحتاج إلى إجرائها هي ذاتها التي تستخدمها في جيت، وهنا تضيف ملفات كالمعتاد، إلا أنك تكون غافل نسبيًا عن حقيقة أن بعضها عبارة عن روابط لينة سريّة للمجلد ‎portal_‎. كل شيء موجود في المجلد ‎portal‎ (والذي يتجاهله جيت تمامًا) يمكن نسخه احتياطيًا إلى أي وحدة تخزين تريدها سواء كانت قرص صلب أو خادم بعيد. بما أن Git-portal يوفر استخدام الخطافات (برامج يتم تشغيلها قبل أو بعد أحداث معينة، مثل الدفع أو السحب أو الإيداع) بالتالي يمكنك إن أحببت بناء إعداد خاص لمزامنة المجلد ‎portal‎ الخاص بك تلقائيًا مع موقع بعيد: $ git remote add _portal alice@myserver.com:/home/alice/umbrella.git/_portal يتميز Git-portal بكونه نظامًا بسيطًا ومبتكرًا يعتمد على نظام لينكس، ويمكّنك من إدارة مشروعك ومشاركته مع الآخرين من خلال مجموعة صغيرة من الأدوات والأوامر، وقد تم استخدامه في العديد من المشاريع التي تتضمن الوسائط وألعاب الفيديو ومدونات الألعاب لإدارة كل شيء بدءًا من الصور البسيطة إلى ملفات PDF الكبيرة وحتى النماذج ثلاثية الأبعاد. نموذج git-annex يمتلك git-annex مسار عمل مختلف قليلًا، لكن الأفكار الأساسية هي نفسها، ويعتبر نظام مزامنة ملفات موزع يهدف إلى حل مشكلة إدارة ومشاركة ومزامنة الملفات الكبيرة دون الحاجة إلى خدمة تجارية أو حتى خادم مركزي، فهو يجعلك قادرًا على إدارة الملفات الكبيرة على جيت من دون تخزين محتوياتها في جيت. يجب أن تكون قادرًا على تثبيت git-annex من مستودع البرامج software repo، أو يمكنك الحصول عليه من موقعهم على الويب. كما هو الحال مع git-media، يجب على أي شخص يستخدم git-annex تثبيته على جهازه. الإعداد الأولي أبسط من git-media. لإنشاء مستودع مجرد bare repository على خادمك، نفّذ هذا الأمر مع استبدال المسار الظاهر بالمسار الخاص بك: $ git init --bare --shared /opt/jupiter.git ثم انسخه على حاسوبك المحلي، وميّزه كموقع git-annex خاص: $ git clone seth@example.com:/opt/jupiter.clone Cloning into 'jupiter.clone'... warning: You appear to have cloned an empty repository. Checking connectivity... done. $ git annex init "seth workstation" init seth workstation ok بدلًا من استخدام المرشحات filters لتحديد أماكن وجود ملفات الوسائط أو الملفات الكبيرة، يمكنك استخدام الأمر التالي لإضافة الملفات إلى git annex وهو تلقائيًّا يحديد فيما إذا كانت كبيرة أم لا: $ git annex add bigblobfile.flac add bigblobfile.flac (checksum) ok (Recording state in Git...) الآن تنفيذ عملية الإيداع كالمعتاد بدون اختلاف يذكر: $ git commit -m 'added flac source for sound fx' لكن عملية الدفع مختلفة، لأن git-annex تستخدم فرعها الخاص لتتبع الملفات، لذلك عند تنفيذ عملية دفع لأول مرة ربما تحتاج لإضافة الخيار u-، وذلك اعتمادًا على كيفية إدارتك لمستودعك: $ git push -u origin master git-annex To seth@example.com:/opt/jupiter.git * [new branch] master -> master * [new branch] git-annex -> git-annex كما هو الحال مع git-media، فإن عملية الدفع العادية لا تنسخ ملفاتك إلى الخادم وإنما ترسل فقط معلومات تتعلق بالوسائط. أخيرًا عندما تكون جاهزًا لمشاركة الملفات مع باقي أعضاء الفريق، نفّذ أمر المزامنة sync: $ git annex sync --content إذا شارك شخص آخر الملفات مع الخادم واحتجت إلى سحبها، فإن الأمر git annex sync سيسحب الملفات غير الموجودة على جهازك والموجودة على الخادم. يعتبر Git Annex حلًا مضبوطًا بدقة لإدارة الملفات الكبيرة وهو مرن وسهل الاستخدام ومتيّن (قليل الأخطاء) وتم اختباره جيدًا. نموذج git-lfs كُتِب git-lfs بلغة Go، ويمكنك تثبيته من الشيفرة المصدر أو كملف ثنائي يتم تنزيله وتثبيته على جهازك، وكافة تعليمات التثبيت موجودة على الموقع، وهو برنامج متعدد المنصات cross-platform لذا لن تواجه مشاكل في عمله وتثبيته على مختلف أنواع الأنظمة. بعد تثبيته يمكنك تحديد أنواع الملفات التي تريد أن يتجاهلها جيت ويديرها Git-LFS، مثلًا لكي يتتبع Git-LFS جميع الملفات التي تحمل الامتداد png. نكتب: $ git lfs track "*.png" في كل مرة تضيف فيها نوع جديد من الملفات لكي يتتبعها Git-LFS، يجب عليك إضافة ثم إيداع الملف gitattributes. كما يلي: $ git add .gitattributes $ git commit -m "LFS track *.png" عندما تغير حالة ملف من هذه الأنواع ليصبح ملف مرحلي (مُدرج)، يُنسَخ الملف إلى git/lfs.. Git-LFS هو مشروع لشركة جيت هاب وهو مرتبط كثيرًا ببنيتها، وإذا كنت ترغب في تشغيل خادم جيت يسمح بدمج Git-LFS، فيمكنك الاطلاع على المثال الموجود في: lfs-test-server من github. يتميز git-portal و git-annex بالمرونة ويمكنهما استخدام المستودعات المحلية بدلًا من الخادم، وهذا مفيد لإدارة المشاريع المحلية الخاصة. الملفات الكبيرة وجيت بالرغم من أن جيت مخصص للعمل مع الملفات النصية، فهذا لا يعني أنه لا يمكنك استخدامه مع الأنواع الأخرى من الملفات، حيث توجد الكثير من الحلول لمساعدتك في إدارة كافة أنواع الملفات، لذا اذهب وجرب جيت بدءًا من اليوم! ترجمة -وبتصرف- للمقال How to manage binary blobs with Git لصاحبه Seth Kenlon. اقرأ أيضًا المقال السابق: كيفية بناء خادم جيت لـ Git بدء العمل مع نظام إدارة الإصدارات جيت Git إنشاء أول مستودع لك من خلال جيت Git الدليل المرجعي للعمل على نظام غيت Git التعامل مع كائن البيانات الثنائية Blob في جافاسكربت
  22. جانغو Django هو إطار عمل Framework مجاني ومفتوح المصدر، كُتِب بلغة بايثون، يوفر لنا ميزات قابلية التوسع وإعادة الاستخدام والتطوير السريع. سنتحدث في هذا المقال عن كيفية تهيئة وإكمال العمليات الأساسية لبناء موقع ويب لمدونة، ووصلها بقاعدة بيانات MySQL. يتضمن ذلك إنشاء البنية الهيكلية لتطبيق الويب الخاص بمدونة باستخدام django-admin وإنشاء قاعدة بيانات MySQL ووصل تطبيق الويب بها. يوفر لك جانغو بيئة تطوير للعمل على تطبيق الويب الخاص بمدونتك، لكن ستحتاج إلى اتخاذ المزيد من الخطوات لنشر مدونتك على الإنترنت. هذا المقال جزء من سلسلة مقالات قصيرة حول كيفية إنشاء تطبيق ويب ليكون بمثابة مدونة وإليك فهرس كامل السلسلة: البدء مع إطار العمل جانغو لإنشاء تطبيق ويب إنشاء تطبيق جانغو وتوصيله بقاعدة بيانات إنشاء نماذج جانغو Django Models وربطها بقاعدة البيانات تنشيط واجهة مدير جانغو والاتصال بها معالجة طلبات الويب عبر العروض views في تطبيق جانغو المتطلبات الأساسية ستحتاج في هذا المقال إلى: خادم أبونتو Ubuntu، مع صلاحيات مستخدم عادي (أي ليس جذر root) وجدار حماية firewall. انظر مقال التهيئة الأولية لخادم أوبونتو قاعدة بيانات MySQL مثبتة التي تمثل خادم قاعدة البيانات، انظر مقال تعلم أساسيات MySQL. تثبيت بايثون 3، وإعداد بيئتها البرمجية، انظر مقال كيفية تثبيت بايثون 3 وإعداد بيئته البرمجية على خادم أوبنتو.. بعد تثبيت وتجهيز ما تم ذكره، يمكنك الانتقال إلى الخطوة الأولى. الخطوة الأولى - إنشاء قاعدة البيانات يمكن لجانغو العمل مع عدة أنواع مختلفة من نظم إدارة قواعد البيانات، لكن في هذا المقال سنتعامل مع MySQL و سنربط جانغو معها. بدايةً ستحتاج إلى إنشاء قاعدة بيانات باستخدام MySQL، إضافةً إلى ملف تعريف مستخدم لكي يستخدمه جانغو للاتصال بقاعدة البيانات. لإنجاز ذلك، اتصل بقاعدة بيانات MySQL كمستخدم جذر، باستخدام الأمر التالي: $ sudo mysql بعد ذلك سيتغير رمز سطر الأوامر ليصبح هكذا: mysql> يمكنك استعراض قواعد البيانات الحالية باستخدام الأمر التالي: mysql> SHOW DATABASES; ستحصل على خرج يشبه الخرج التالي (بافتراض أنك لم تنشئ أي قاعدة بيانات حتى الآن): +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | +--------------------+ 4 rows in set (0.00 sec) هناك 4 قواعد بيانات يتم إنشاؤها افتراضيًّا، موضحة في الخرج السابق، ولن تحتاج إلى التعامل معها، فهي تحتوي على معلومات خاصة بخادم MySQL. الآن، لإنشاء قاعدة بيانات MySQL تحتفظ ببيانات مدونتك، نفذ الأمر التالي: mysql> CREATE DATABASE blog_data; عند إنشاء قاعدة البيانات بنجاح، ستحصل على الخرج التالي: Query OK, 1 row affected (0.00 sec) انتبه فهناك احتمال أن تتلقى الخطأ التالي: ERROR 1007 (HY000): Can't create database blog_data; database exists يشير ذلك إلى أن قاعدة البيانات التي أسميناها blog_data أصبحت موجودة. إذا تلقيت خطأ MySQL التالي، فهذا يعني أن هناك خطأ قواعدي في كتابة أمر MySQL. لذا تأكد من أنك كتبت الأمر كما هو تمامًا: ERROR 1064 (42000): You have an error in your SQL syntax; تأكد الآن من وجود قاعدة البيانات من خلال استعراض قواعد البيانات الحالية: $ SHOW DATABASES; الآن يجب أن تظهر قاعدة البيانات blog_data ضمن الخرج. +--------------------+ | Database | +--------------------+ | information_schema | | blog_data | | mysql | | performance_schema | | sys | +--------------------+ 5 rows in set (0.00 sec) أنشئ الآن مستخدمًا على MySQL لكي يستخدمه جانغو لتشغيل قاعدة البيانات التي أنشأتها. إن إنشاء قواعد بيانات خاصة وحسابات محددة يمنحك المزيد من الأمان والتحكم والقدرة على الإدارة. سنسمي المستخدم djangouser (يمكنك اختيار الاسم الذي تريده)، كما سنضع كلمة مرور للحساب وسنعطي صلاحية الوصول إلى قاعدة البيانات التي أنشأتها. أولًا، أنشئ المستخدم وحدد كلمة المرور عن طريق الأمر التالي (حدد كلمة مرور قوية -استبدل "password" بكلمة المرور التي تريدها-): mysql> CREATE USER 'djangouser'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password'; الآن، يجب أن تعطي المستخدم djangouser صلاحيات الوصول الكامل إلى قاعدة البيانات التي هيأتها: mysql> GRANT ALL ON blog_data.* TO 'djangouser'@'localhost'; لديك الآن قاعدة بيانات وحساب مستخدم، كل منهما مصمم خصيصًا لجانغو. نفذ الآن الأمر التالي حتى يعرف MySQL التغييرات الأخيرة التي أجريتها: mysql> FLUSH PRIVILEGES; الأمر السابق ضروري لإخبار الخادم أن يُعيد تحميل جداول الصلاحيات grant tables. بعد الانتهاء من ذلك، يمكنك الخروج من خادم MySQL بكتابة الأمر EXIT؛ أو بالضغط على CTRL + D. الخطوة الثانية - إنشاء ملف ضبط MySQL بدلاً من تحديد تفاصيل عملية الاتصال مع قاعدة بيانات MySQL في ملف الضبط الخاص بجانغو Django configuration file، يمكنك تخزينها في ملف الضبط option file، حيث يمكن للعديد من برامج MySQL قراءة هذا الملف للحصول على معلومات، مثل خيارات بدء التشغيل أو تفاصيل الاتصال. غالبًا ما يكون ذلك أسهل، حيث لا يتعين عليك سوى تخزين بيانات اعتماد تسجيل الدخول إلى قاعدة البيانات في مكان واحد (بيانات الاعتماد هي سجل يحتوي على معلومات المصادقة/بيانات الاعتماد للاتصال بمورد ما خارج مخدم MySQL). افتح ملف الضبط my.cnf باستخدام محرر النصوص المفضل لديك لتحديث بيانات اعتماد MySQL (هنا سنستخدم محرر النصوص nano): $ sudo nano /etc/mysql/my.cnf أضف الأسطر التالية مع المعلومات المطلوبة ضمن ملف ‎/etc/mysql/my.cnf: … [client] database = blog_data user = djangouser password = your_actual_password default-character-set = utf8 ستلاحظ أنه تم تعيين الترميز utf8 كترميز افتراضي، لأنها الطريقة الشائعة لترميز بيانات Unicode في MySQL. عندما تتأكد من صحة التفاصيل الخاصة بك، احفظ الملف واغلقه. في حال استخدمت المحرر نانو nano لتحرير الملف، فيمكنك القيام بذلك عن طريق الضغط على CTRL + X ثم Y لتأكيد التغييرات. بعد الانتهاء من تعديل الملف، ستحتاج إلى إعادة تشغيل MySQL لتصبح التغييرات سارية المفعول: $ sudo systemctl daemon-reload $ sudo systemctl restart mysql إن إعادة تشغيل MySQL تستغرق بضع ثوانٍ، لذا يرجى التحلي بالصبر. الخطوة الثالثة - إنشاء البنية الأولية لمشروع جانغو ستضع في هذه الخطوة اللبنة الأساسية لتطبيقك عن طريق إنشاء الهيكل الأساسي للمشروع باستخدام الأمر django-admin. انتقل أولًا إلى المجلد الذي ترغب أن تضع مجلد مشروعك فيه، ثم أنشئ مجلد مشروعك واعطه اسمًا مناسبًا، مثل my_blog_app: $ mkdir my_blog_app انتقل الآن إلى المجلد الذي أنشأته: $ cd my_blog_app انتقل بعد ذلك إلى بيئة البرمجة التي ترغب في استخدامها للعمل مع جانغو (يمكنك استخدام بيئة موجودة أو إنشاء واحدة جديدة). سوف نسميها env، لكن يُفضل استخدام اسم له معنى بالنسبة لك: $ python3 -m venv env بعد إنشاء البيئة، يجب أن تنشطها: $ . env/bin/activate ثبت الآن جانغو داخل البيئة: (env) sammy@ubuntu:$ pip install django نفذ الأمر التالي داخل مجلد my_blog_app، لإنشاء مشروع بداخله: (env) sammy@ubuntu:$ django-admin startproject blog تأكد من أنه يعمل من خلال الانتقال إلى المجلد blog/: (env) sammy@ubuntu:$ cd blog ثم نفذ الأمر ls للتأكد من إنشاء الملفات والمجلدات الضرورية داخل مجلد المشروع: (env) sammy@ubuntu:$ ls عند تنفيذ هذا الأمر، ستلاحظ في الخرج ظهور مجلد blog وملف الإدارة manage.py: blog manage.py بعد الانتهاء من إنشاء مجلد المشروع والتأكد من أن الملفات الأساسية تم إنشاءها بنجاح، يمكنك الانتقال إلى الخطوة الرابعة. الخطوة الرابعة - تثبيت موصل قاعدة البيانات MySQL Database Connector لكي تتمكن من استخدام قاعدة بيانات MySQL التي أنشأتها مع مشروعك، ستحتاج إلى تثبيت إحدى المكتبات التي تمكّنك من توصيل قاعدة البيانات بتطبيق جانغو (يجب أن تكون المكتبة متوافقة مع جانغو أيضًا)، سنستخدم لهذا الغرض مكتبة mysqlclient. ثبت أولًا بعض المكتبات الضرورية في MySQL: (env) sammy@ubuntu:$ sudo apt install libmysqlclient-dev default-libmysqlclient-dev ثبت بعد ذلك حزمة wheel باستخدام مدير الحزم pip. وهي حزمة تستخدم في بايثون لتثبيت الوحدات modules من فهرس حزم بايثون Python Package Index. إن تثبيت برامج بايثون من خلال حزمة wheel يكون أسرع وأكثر كفاءة في استخدام الموارد من تثبيتها عن طريق بناء الحزم من الشيفرة المصدر. لتثبيت حزمة wheel، نفذ الأمر التالي: (env) sammy@ubuntu:$ pip install wheel بعد ذلك ثبت mysqlclient: (env) sammy@ubuntu:$ pip install mysqlclient بعد ذلك يجب أن تحصل على خرج مشابه للتالي: ... Successfully installed mysqlclient-2.1.0 بذلك تكون نجحت في تثبيت mysqlclient. الخطوة الخامسة - تعديل الإعدادات عندما نفذت الأمر django-admin سابقًا أدى ذلك إلى إنشاء ملف ضبط لجانغو يُسمى ملف الإعدادات settings.py. تحتاج إلى تغيير بعض الإعدادات الافتراضية فيه لكي تسير الأمور بنجاح. افتح الملف لتعديله من خلال محرر النصوص الذي تريده (هنا كالعادة المحرر nano): (env) sammy@ubuntu:$ nano ~/my_blog_app/blog/blog/settings.py يمكنك أيضًا تعديل ملف الإعدادات، بحيث تجعله يستخدم توقيت منطقتك الزمنية إذا أردت أن يكون توقيت الساعة في مدونتك مُقترن بالوقت في منطقتك. يمكنك استخدام قائمة المناطق الزمنية هذه كمرجع. مثلًا، هنا سوف نستخدم توقيت أمريكا / نيويورك واستخدم التوقيت الذي تريد. لإنجاز ذلك، انتقل إلى الحقل TIME_ZONE، والمتواجد ضمن ملف الإعدادات في القسم السفلي ‎~/my_blog_app/blog/blog/settings.py: ... # Internationalization # https://docs.djangoproject.com/en/2.0/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True ... عدّل TIME_ZONE بحيث يتم ضبطه على منطقتك الزمنية الحالية. سنستخدم المنطقة الزمنية لنيويورك في هذا المثال: ... # Internationalization # https://docs.djangoproject.com/en/2.0/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'America/New_York' USE_I18N = True ... ستحتاج بعد ذلك إلى إضافة مسار لملفاتك الثابتة static files، لذا لا تغلق ملف الإعدادات الآن. يُقصد بالملفات الثابتة، الملفات المُتعلقة بتطبيقك في جانغو، وقد تكون هذه الملفات أي ملفات ضرورية لعرض صفحة الويب، مثل ملفات JavaScript و CSS والصور ..إلخ. انتقل إلى نهاية ملف settings.py وأضف STATIC_ROOT: ... # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/2.0/howto/static-files/ STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, 'static') الآن بعد أن أضفت المنطقة الزمنية ومسار الملفات الثابتة، أضف عنوان IP الخاص بك إلى قائمة ALLOWED_HOSTS الموجودة في القسم العلوي من الملف، وهناك أضف فيها عنوان IP لخادمك، محاطًا بعلامتي اقتباس. ... # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True ALLOWED_HOSTS = ['your_server_IP_address'] # Application definition ... أضف بعد ذلك وحدة نظام التشغيل OS، التي توفّر وظائف متنوعة للمجلدات. هذه الوحدة ضرورية، فبدونها ستتلقى خطأ عند إنشاء مستخدم مُدير administrative user لكي تتمكن من استخدام واجهة جانغو Django interface من خلاله. لإنجاز ذلك عليك باستيراد وحدة OS التي ستعمل على نظام التشغيل الخاص بك. أضف سطر الاستيراد import os في أعلى ملف الإعدادات: ... import os from pathlib import Path # Build paths inside the project like this: BASE_DIR / 'subdir'. ... إلى هنا تكون قد أجريت عدة تعديلات على ملف الإعدادات. تبقى لديك إضافة بيانات اعتماد الاتصال بقاعدة البيانات، لتوصيل المدونة التي أنشأناها من خلال جانغو بقاعدة بيانات MySQL. لإنجاز ذلك، عليك بالبحث عن DATABASES داخل ملف الإعدادات. عندما تجده، سيبدو هكذا: ... # Database # https://docs.djangoproject.com/en/3.2/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', } } ... استبدل خياري ENGINE و NAME في قاموس DATABASES بالأسطر التالية: ... # Database # https://docs.djangoproject.com/en/3.0/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'OPTIONS': { 'read_default_file': '/etc/mysql/my.cnf', }, } } ... يُقصد بالسطر "ENGINE": "django.db.backends.mysql" إخبار جانغو أن يَستخدم الواجهة الخلفية لقاعدة بيانات MySQL المدمجة بينما يشير خيارread_default_file إلى ‎/etc/mysql/my.cnf، وهو ملف خيارات MySQL الذي عدلناه سابقًا، وهذا يخبر جانغو أين يمكن العثور على تفاصيل الاتصال اللازمة للاتصال بقاعدة بيانات MySQL التي أنشأتها في الخطوة الأولى. لاحظ أن جانغو يقرأ إعدادات الاتصال بقاعدة البيانات بالترتيب التالي: الخيارات OPTIONS الاسم، المستخدم، كلمة المرور، المضيف HOST، المنفذ PORT ملفات الضبط MySQL بناءً على الترتيب السابق، وبما أنك وضعت ملف خيارات MySQL ضمن الحقل OPTIONS، فسيكون لها الأولوية في التنفيذ على الإعدادات الموجودة في الحقل NAME، وذلك لأن الأولوية تكون للإعدادات الموجودة في الحقل OPTIONS، وبعد ذلك NAME، بينما لو وضعت ملف الضبط في مكان آخر، ستكون الأولوية للإعدادات التي تم تحديدها في الحقل NAME. يمكنك الآن حفظ وإغلاق الملف. بعد ذلك، تحقق من تغييرات التهجير migration عن طريق تشغيل ما يلي: (env) sammy@ubuntu:$ python manage.py makemigrations بعد ذلك نفّذ أمر التهجيرmigrate لضمان تنفيذ التغييرات: (env) sammy@ubuntu:$ python manage.py migrate الآن بعد أن تم تهجير التغييرات، يمكنك إنشاء مستخدم مُدير لكي تتمكن من استخدام واجهة مُدير جانغو. أنجز ذلك من خلال الأمر Createsuperuser: (env) sammy@ubuntu:$ python manage.py createsuperuser سوف يطلب منك اسم مستخدم وعنوان بريد إلكتروني وكلمة مرور للمستخدم الخاص بك. بعد إكمال هذه المعلومات، يمكنك الانتقال إلى الخطوة السادسة. الخطوة 6 - ضبط إعدادات جدار الحماية قبل أن تبدأ باختبار تطبيقك، يجب أن تُنجز بعضًا من عمليات الضبط في إعدادات جدار الحماية الخاص بك. ابدأ بتغيير إعدادات جدار الحماية عبر UFW للسماح بالوصول إلى المنفذ 8000 على الخادم: (env) sammy@ubuntu:$ sudo ufw allow 8000 للتأكد من أنه أعطيت صلاحيات الوصول إلى المنفذ بنجاح، نفّذ الأمر status: (env) sammy@ubuntu:$ sudo ufw status سيكون الخرج: Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere 8000 ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) 8000 (v6) ALLOW Anywhere (v6) كما تلاحظ في الخرج، فإن الصلاحيات تم منحها بنجاح. بهذا تكون قد انتهيت من تعديلات جدار الحماية. الخطوة السابعة - اختبار اتصال قاعدة بيانات MySQL بتطبيق جانغو يمكنك الآن أن تختبر فيما إذا كانت إعدادات الضبط التي أجريتها في جانغو تنجح في تحقيق الاتصال مع خادم MySQL. يمكنك إنجاز ذلك من خلال تشغيل الخادم، فإذا فشل تشغيله، فهذا يعني أن الاتصال لا يعمل بنجاح، وإلا فإن الاتصال نجح. انتقل أولًا إلى المجلد التالي: (env) sammy@ubuntu:$ cd ~/my_blog_app/blog/ نفّذ بعد ذلك الأمر التالي: (env) sammy@ubuntu:$ python manage.py runserver your-server-ip:8000 سيكون الخرج مُشابهًا للتالي: Performing system checks... System check identified no issues (0 silenced). October 25, 2021 - 19:50:58 Django version 3.2.9, using settings 'blog.settings' Starting development server at http://your-server-ip:8000/ Quit the server with CONTROL-C. ستلاحظ أن لديك عمليات تهجير غير مطبقة في الخرج. لا تقلق، فهذا لا يؤثر على الإعداد الأولي لتطبيقك، ويمكنك المتابعة. اتبع التعليمات الواردة في الخرج واتبع الرابط المُقترح http://your-server-ip:8000، لعرض تطبيق الويب الخاص بك والتحقق من أنه يعمل بشكل صحيح. إذا كانت صفحتك تشبه لقطة الشاشة أعلاه، فهذا يعني أن تطبيق جانغو الخاص بك يعمل بنجاح. عند الانتهاء من اختبار تطبيقك، اضغط على CTRL + C لإيقاف تشغيل الخادم والعودة إلى بيئة البرمجة الخاصة بك. للخروج بعد ذلك من بيئة بايثون الخاصة بك، يجب أن تنفّذ أمر إلغاء تنشيط البيئة: (env) sammy@ubuntu:$ deactivate ستُنقل بعد ذلك إلى الموقع الافتراضي في سطر الأوامر. خاتمة تعلمت في هذا المقال بناء الهيكل الأولي لمدونتك عن طريق جانغو؛ أكملت عملية تثبيت وتهيئة وتوصيل قاعدة بيانات MySQL مع تطبيق جانغو، وأضفت بعض المعلومات المهمة إلى ملف الإعدادات settings.py الخاص بتطبيقك، مثل توقيت منطقتك TIME_ZONE وتعديل قائمة ALLOWED_HOSTS واستيراد وحدة نظام التشغيل OS وبيانات اعتماد قاعدة البيانات لربط تطبيق جانغو بقاعدة بيانات MySQL، كما ضبطت إعدادات جدار الحماية لضمان إجراء الاختبار بنجاح. أصبح بإمكانك الآن البدء في تطوير النماذج وتطبيق عمليات التهجير في تطبيق جانغو الخاص بك وهذا ما سنتحدث عنه في المقال التالي. ترجمة -وبتصرف- للمقال How To Create a Django App and Connect it to a Database لصاحبه Jeremy Morris. اقرأ أيضًا مدخل إلى إطار العمل Django إنشاء تطبيق الاقتراعات وكتابة العرض الأول على Django مقدمة عن قواعد البيانات
  23. جانغو Django هو إطار عمل يُستعمَل في تطوير مواقع الويب كُتبَ بلغة بايثون، وهو مجاني ومفتوح المصدر، ويتسم بقابلية التوسع وإعادة الاستخدام والتطوير السريع واستقلالية المكونات، إذ يركز على تحليل التصميم إلى مكونات وظيفية أو منطقية مُفردة (استقلالية المكونات) مما يجعل التطبيقات أكثر مرونة وقابلية للتوسع والنمو وإعادة الاستخدام كما أنه يتسم بسرعة التطوير المعززة بميزات أمان مُدمجة. يعتمد جانغو على النمط البنائي للبرمجيات نموذج-قالب-عرض Model-Template-View -تختصر إلى MTV- والمُستمد من النمط البنائي نموذج-عرض-متحكم model–view–controller -تختصر إلى MVC- . يتم تعريف النموذج Model على أنه مصدر مفرد ومحدد من البيانات، والعرض View على أنه عبارة عن البيانات التي يتم إظهارها للمستخدم، والقالب Template على أنه عبارة عن الآلية التي يستخدمها جانغو لتوليد صفحات HTML. إن اعتماد جانغو على بنية نموذج-قالب-عرض تشجع على مبدأ عدم التكرار DRY programming وهو مبدأ يهدف إلى الحد من تكرار المعلومات من جميع الأنواع، وينص على أن "أي جزء في النظام ينبغي أن يكون معرّفاً في مكان واحد واضح مسؤول عن هذا الجزء". سنتحدث في هذه المقالة عن تثبيت جانغو وكيفية تهيئة بيئته البرمجية على خادم أبنتو Ubuntu، لاستخدامها لاحقًا في تطوير مواقع وتطبيقات الويب. بالنسبة لمواقع الويب الحيّة، سيكون لدينا بعض الأمور الإضافية، مثل الاتصال بقاعدة البيانات وإعداد اسم النطاق domain وإضافة مستويات أو طبقات أمنية. هذا المقال جزء من سلسلة مقالات قصيرة حول كيفية إنشاء تطبيق ويب ليكون بمثابة مدونة وإليك فهرس كامل السلسلة: البدء مع إطار العمل جانغو لإنشاء تطبيق ويب إنشاء تطبيق جانغو وتوصيله بقاعدة بيانات إنشاء نماذج جانغو Django Models وربطها بقاعدة البيانات تنشيط واجهة مدير جانغو والاتصال بها معالجة طلبات الويب عبر العروض views في تطبيق جانغو المتطلبات الأساسية قبل البدء بعمليات التثبيت والتهيئة، سوف تحتاج إلى: حساب مستخدم عادي مع صلاحيات sudo، مُهيّأ مسبقًا على خادم أبونتو 20.04، انظر مقال التهيئة الأولية لخادم أوبونتو. تثبيت بايثون 3، مع بيئة برمجة افتراضية، انظر مقال كيفية تثبيت بايثون 3 وإعداد بيئته البرمجية على خادم أوبنتو. الخطوة الأولى - تثبيت جانغو هناك عدة طرق لتثبيت جانغو، ومدير حزم بايثون pip داخل بيئة افتراضية، إذ البيئة الافتراضية virtualenv هي عبارة عن بيئة تطوير برمجية معزولة عما حولها، والتي تسمح لنا بتثبيت البرامج وحزم بايثون بداخلها، وبالتالي تمنع تفاعل هذه البرامج والحزم مع البيئة العامة للخاد سننشئ الآن المجلد الذي سيحتوي على تطبيق جانغو بداخل المجلد الرئيسي للخادم، وذلك من خلال الأمر mkdir، وسنعطيه اسمًا (يمكنك وضع اسم آخر)، ثم سننتقل إليه من خلال الأمر cd: $ mkdir django-apps $ cd django-apps الآن، بعد أن تنتقل إلى المجلد الذي أنشأته django-apps، أنشئ بيئتك الافتراضية، وهنا سنسميها البيئة العامة env (الاسم اختياري، لكن يُفضل أن يكون ذو معنى). $ virtualenv env إن لم تكن أداة virtualenv مثبتة لديك، فثبتها باتباع توثيق خطوات التثبيت من الموقع الرسمي. الآن، نشّط البيئة الافتراضية باستخدام الأمر التالي: $ . env/bin/activate في حال تغيرت البادئة في سطر الأوامر إلى (env)، فهذا يعني أن بيئتك تم تنشيطها، وستظهر لك في سطر الأوامر مشابهةً لما يلي: (env) sammy@ubuntu:$ بعد أن أصبحنا في داخل البيئة، نُثبت حزمة جانغو من خلال مُدير الحزم pip: (env) sammy@ubuntu:$ pip install django تحقق الآن من نجاح التثبيت: (env) sammy@ubuntu:$ django-admin --version يجب أن تحصل على خرج مُشابه للخرج التالي: 3.0.6 بعد الانتهاء من تثبيت جانغو على خادمك، يمكنك البدء بإنشاء مشروع كتجربة لكي تتأكد من أن كل شيء يعمل بنجاح. الخطوة الثانية - ضبط إعدادات جدار الحماية إذا كان لديك خادم تمت تهيئته أو كان لديك جدار حماية firewall يعمل على خادمك، فسنحتاج إلى فتح المنفذ الذي سنستخدمه في جدار الحماية الخاص بخادمنا. بالنسبة لجدار حماية UFW، يمكنك فتح المنفذ بالأمر التالي: (env) sammy@ubuntu:$ sudo ufw allow 8000 لمزيد من التفاصيل، انظر مقال أساسيات UFW: قواعد وأوامر شائعة للجدار الناري. إذا كنت تستخدم جدران حماية DigitalOcean، فيمكنك اختيار بروتوكول HTTP من قواعد جدار الحماية الداخلي Inbound firewall rules (تحدد قواعد جدار الحماية الداخلي حركة المرور المسموح بها للخادم على أي منافذ ومن أي مصادر). الخطوة الثالثة - بدء المشروع بإمكانك الآن إنشاء تطبيق باستخدام مُدير-جانغو django-admin وهو أمر يُستخدَم لإنجاز المهام الإدارية في بايثون، ثم يمكنك استخدام الأمر startproject لإنشاء بنية مجلد المشروع من أجل موقع الويب الذي سنُنشئه. نفّذ الأمر التالي (اسم المشروع testsite اختياري) داخل مجلد django-apps: (env) sammy@ubuntu:$ django-admin startproject testsite سيؤدي تشغيل الأمر السابق إلى تسمية مجلد المشروع وحزمة المشروع بالاسم المحدد (أي في حالتنا السابقة سيكون testsite)، وسيتم إنشاء المشروع في المجلد الذي تم تنفيذ الأمر فيه. وفي حال تم تحديد مسار مجلد الوجهة، سوف يعتبره جانغو مجلد المشروع، وسيُنشئ ملف الإدارة manager.py وحزمة المشروع بداخله. بعد ذلك يمكنك الإطلاع على ملفات المشروع التي تم إنشاؤها من خلال الانتقال إلى مجلد المشروع testsite، ثم تنفيذ الأمر ls لعرض قائمة الملفات الموجودة فيه: (env) sammy@ubuntu:$ cd testsite (env) sammy@ubuntu:$ ls الخرج: manage.py testsite ستلاحظ أن المجلد يحتوي على ملف الإدارة manage.py، والثاني هو مجلد باسم testsite يشبه ملف الإدارة ملف مُدير- جانغو، إذ أنه يضع حزمة المشروع في متغير البيئة sys.path. يؤدي ذلك أيضًا إلى تحديد متغير البيئة DJANGO_SETTINGS_MODULE للإشارة إلى ملف الإعدادات settings.py الخاص بالمشروع. يمكنك استعراض محتويات ملف الإدارة في الطرفية terminal عن طريق استخدام الأمر less: (env) sammy@ubuntu:$ less manage.py عندما تنتهي من الاطلاع عليه، اضغظ على المفتاح q لإنهاء عرض الملف. بعد ذلك انتقل إلى مجلد testsite لرؤية الملفات التي تم إنشاؤها: (env) sammy@ubuntu:$ cd testsite/ نفذ الآن الأمر ls لعرض قائمة الملفات الموجودة في المجلد الحالي: (env) sammy@ubuntu:$ ls سترى أربعة ملفات: __init__.py asgi.py settings.py urls.py wsgi.py سنتحدث الآن عن كل ملف من هذه الملفات: ملف التهيئة ‎init.py: تمثل نقطة الدخول لمشروع بايثون الخاص بك. ملف asgi.py: يحتوي على إعدادات التهيئة للنشر الاختياري optional deployment لواجهة بوابة الخادم غير المتزامن Asynchronous Server Gateway Interface (تختصر إلى ASGI)، ويعتبر معيارًا للتطبيقات التي تكون متزامنة أو غير متزامنة. ملف الإعدادات settings.py: يحتوي على جميع قيم التهيئة التي يحتاجها تطبيق الويب الخاص بك لكي يعمل، مثل إعدادات قاعدة البيانات، وإعدادات التسجيل logging، ومكان العثور على الملفات الثابتة static files، ومفاتيح واجهة برمجة التطبيقات API إذا كنت تعمل مع إحداها …إلخ. ويتيح لجانغو معرفة هذه الإعدادات. ملف العناوين urls.py: يمكن تشبيه هذا الملف بدفتر عناوين لموقع الويب الخاص بك، حيث يخزن كل عناوين الويب لموقعك، ويربطها بعروض views أو أي ملف urls-conf آخر لتطبيق معين. ملف wsgi.py: يحتوي على تهيئة واجهة بوابة خادم الويب Web Server Gateway Interface (تختصر إلى WSGI)، والذي يعتبر معيارًا لتطبيقات بايثون المتزامنة. الآن، يمكنك استخدام أمر التهجير migrate مع ملف manage.py لتهجير قاعدة البيانات (في هذا المثال نستخدم SQLite)، إذ يُطبق التهجير أي تغييرات أجريتها في نماذج جانغو على مخطط قاعدة البيانات: (my_env) $ python manage.py migrate الخطوة الرابعة - ضبط إعدادات جانغو يمكنك الآن تشغيل الخادم وعرض موقع الويب على مضيف معين ومنفذ من خلال تنفيذ الأمر runserver. ستحتاج إلى إضافة عنوان IP للخادم الخاص بك إلى قائمة ALLOWED_HOSTS في ملف الإعدادات settings.py. إن ALLOWED_HOSTS عبارة عن قائمة تحتوي على سلاسل نصيّة strings، وكل سلسلة من هذه السلاسل يمثل اسم مضيف أو نطاق يمكن لموقع جانغو أن يُخدّمه، وهو إجراء أمني لمنع هجمات حقن ترويسة HTTP أو كما تسمى "HTTP Host header attacks". يمكنك استخدام أي محرر نصوص تُفضله لإضافة عنوان IP الخاص بك. مثلًا، إذا كنت تستخدم المحرر نانو nano، يمكنك تنفيذ الأمر التالي: (env) sammy@ubuntu:$ nano ~/django-apps/testsite/testsite/settings.py بعد تنفيذ الأمر، ستحتاج إلى الانتقال إلى قائمة المُضيفين المسموح بهم Allowed Hosts في الملف، وإضافة عنوان IP الخاص بخادمك ضمن قائمة ALLOWED_HOSTS، ولا تنس وضع العنوان ضمن علامتي اقتباس. """ Django settings for testsite project. Generated by 'django-admin startproject' using Django 2.0. ... """ ... # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True # Edit the line below with your server IP address ALLOWED_HOSTS = ['your-server-ip'] ... يمكنك حفظ التغيير والخروج من المحرر nano بالضغط مع الاستمرار على الاختصار CTRL + x ثم الضغط على الزر y. بعد ذلك، سنتمكن لاحقًا من الوصول إلى تطبيق الويب الخاص بنا عبر المتصفح. الآن، سننشئ مُستخدمًا بصفة مُدير (مسؤول) administrative user، لكي تتمكن من استخدام واجهة المُدير admin interface وسننجز ذلك من خلال الأمر createuperuser: (my_env) $ python manage.py createsuperuser سيُطلب منك بعدها تحديد اسم مستخدم وعنوان بريد إلكتروني وكلمة مرور للمستخدم الذي أنشأته. الخطوة الخامسة - الوصول إلى تطبيق الويب بعد الانتهاء من التهيئة، انتقل إلى المجلد الذي يوجد فيه ملف الإدارة manager.py: (env) sammy@ubuntu:$ cd ~/django-apps/testsite/ بعد ذلك، نفذ الأمر التالي (استبدل "server-ip text" بعنوان IP الخادم الخاص بك): (env) sammy@ubuntu:$ python manage.py runserver your-server-ip:8000 بعد ذلك، يمكنك الانتقال إلى الرابط التالي لمعرفة الشكل الذي يبدو عليه موقعك (لا تنسى استبدال "server-ip text" بعنوان IP الخادم الخاص بك). http://your-server-ip:8000/ وإن كنت تعمل محليًا على حاسوبك، فيمكنك تشغيل الخادم للعمل محليًا بتمرير رقم المنفذ فقط بالشكل: (my_env)$ python manage.py runserver 8000 وبذلك، يمكنك الانتقال إلى العنوان localhost:8000 أو http://127.0.0.1:8000 للوصول للتطبيق من أي متصفح على حاسوبك. بعد تحميل الصفحة، سترى ما يلي: هذا يؤكد أنه تم تثبيت جانغو بنجاح وأن مشروع الاختبار لدينا يعمل بنجاح. للوصول إلى واجهة المُدير admin interface، أضف /admin/ إلى نهاية عنوان URL الخاص بك: http://your_server_ip:8000/admin/ أو http://127.0.0.1:8000/admin/ بالتالي سيتم نقلك إلى شاشة تسجيل الدخول: إذا أدخلت اسم المستخدم وكلمة المرور الخاصين بالمدير admin اللذين أنشأتهما مُسبقًا، فسيكون لديك صلاحية الوصول إلى قسم المُدير الرئيسي في الموقع: عند الانتهاء من اختبار التطبيق، يمكنك الضغط على CTRL + C لإيقاف تنفيذ الأمر runserver. وأخيرًا للخروج من بيئة بايثون التي أنشأتها، يجب عليك إلغاء تنشيطها من خلال أمر deactivate. (env) sammy@ubuntu:$ deactivate سيؤدي إلغاء تنشيط البيئة إلى إعادتك إلى الموقع الافتراضي في الطرفية. خاتمة تعلمت في هذه المقالة تثبيت جانغو وإعداد بيئة تطوير لبدء العمل على تطبيق جانغو الخاص بك، وبالتالي أصبح لديك الأساس اللازم للبدء في إنشاء تطبيقات ويب باستخدام جانغو. ترجمة -وبتصرف- للمقال How To Install Django and Set Up a Development Environment on Ubuntu 20.04 لصاحبه Lisa Tagliaferri. اقرأ أيضًا مدخل إلى إطار العمل Django تخصيص لوحة التحكم المرفقة مع Django تثبيت إطار العمل جانغو على أوبنتو
  24. سنتعلم في هذا المقال كيفية إنشاء خادم جيت Git، وكيفية كتابة خطّافات جيت Git hooks مخصصة لتشغيل إجراءات معينة (مثل الإشعارات) قبل أو بعد أحداث محددة، إضافةً إلى نشر شيفراتك البرمجية على موقع ويب. لحد هذه اللحظة كان حديثنا في السلسلة عن جيت كمستخدمين، أما الآن ستتم مناقشة إدارة جيت وتصميم بنية تحتية مرنة لجيت. قد تعتقد أن الأمر متقدم أو يحتاج إلى خبرة متقدمة، ولكن في الواقع لا يتطلب معرفة متقدمة أو أي تدريب خاص يتجاوز الفهم المتوسط لكيفية عمل جيت، والقليل من المعرفة حول لينكس. خادم جيت المشترك إن إنشاء خادم جيت مشترك خاص بك يعد أمرًا بسيطًا للغاية، وفي كثير من الحالات يستحق العناء، فهو لا يضمن فقط إمكانية الوصول إلى شيفرتك البرمجية دائمًا، بل تفتح أيضًا الأبواب لتوسيع مدى وصول جيت بامتدادات مثل خطافات جيت الخاصة، وتخزين غير محدود للبيانات، والدمج والنشر المستمر. إذا كان لديك معرفة حول كيفية استخدام جيت والتعامل مع خدمة SSH، فأنت تعرف من حيث لا تدري كيفية إنشاء خادم جيت. عندما تُنشئ مستودع أو عندما تنسخه من أحد المصادر، فإنك تكون قد أعددت عمليًّا نصف الخادم. بعد إعداد المستودع يجب تمكين الاتصال من خلال خدمة SSH مع المستودع، وبعدها يمكن لأي شخص لديه حق الوصول أن يستخدم المستودع كأساس لنسخة جديدة. عمومًا، تمثل هذه الطريقة واحدة من الطرق المتبعة لإنشاء خادم جيت git server، حيث هناك طرق أخرى تمكنك من إنشاء خادم جيت مصمم جيدًا وتقريبًا بنفس القدر من الجهد ومع قابلية تطوير أفضل. بدايةً يجب عليك تحديد المستخدمين الحاليين والمستقبليين، أما إذا كنت المستخدم الوحيد فلا داعي لإجراء أي تغييرات، ولكن إذا كنت تنوي إشراك مساهمين، فلا بد من تحديدهم. بفرض كان لديك خادم متاح (ليست مشكلة إذا لم يكن لديك خادم، حيث أن جيت يمكنها أن تساعدك في حل هذه المشكلة، كما أنه بإمكانك استخدام حاسوب راسبيري باي على نظام CentOS كمخدم في البداية)، فإن الخطوة الأولى هي تمكين عمليات تسجيل الدخول عبر خدمة SSH باستخدام ترخيص مفتاح SSH فقط، ويعد هذا أقوى بكثير من عمليات تسجيل الدخول باستخدام كلمة المرور لأنه محصن ضد هجمات القوة الغاشمة brute-force (طرق الاختراق التي تعتمد على تجريب كافة الاحتمالات الممكنة) كما أنه يمكن تعطيل المستخدم ببساطة من خلال حذف مفتاحه. بمجرد تمكين المصادقة من خلال مفتاح SSH أنشئ مستخدم جيت gituser، وهو عبارة عن مستخدم مشترك لجميع المستخدمين المُصرّح لهم: $ su -c 'adduser gituser' ثم قم بالتبديل إلى هذا المستخدم، وأنشئ إطار عمل ‎~/.ssh مع الأذونات المناسبة، وهذا مهم من أجل حمايتك، فإن لم تضع الأذونات اللازمة ستفشل فكرة استخدام مفتاح SSH للحماية. $ su - gituser $ mkdir .ssh && chmod 700 .ssh $ touch .ssh/authorized_keys $ chmod 600 .ssh/authorized_keys يحتوي ملف authorized_keys على مفاتيح SSH العامة لجميع المطورين الذين تمنحهم الإذن للعمل في مشروعك على جيت، وينبغي من كل مطوريك إنشاء أزواج من مفاتيح SSH الخاصة بهم وإرسال مفاتيحهم العامة إليك، وأنت ينبغي عليك نسخ المفاتيح العامة في ملف authorized_keys الخاص بمستخدم جيت (انظر مقال العمل مع خواديم SSH: العملاء والمفاتيح)، على سبيل المثال بالنسبة لمطور يسمى Bob، قم بتشغيل هذه الأوامر: $ cat ~/path/to/id_rsa.bob.pub >> \ /home/gituser/.ssh/authorized_keys طالما أن المطور Bob مثلًا لديه المفتاح الخاص الذي يطابق المفتاح العام الذي أرسله إليك، يمكن للمطور Bob الوصول إلى الخادم باعتباره مستخدم جيت. عمومًا، قد لا ترغب في منح مطوريك حق الوصول إلى خادمك، حتى لو كان الوصول كمستخدم جيت فقط، وتريد فقط منحهم حق الوصول إلى مستودع جيت، لهذا السبب يوفر جيت صدفة shell تسمى git-shell. نفّذ هذه الأوامر (كمستخدم جذر root) لإضافة git-shell إلى نظامك، ثم اجعلها الصدفة الافتراضية لمستخدم جيت: # grep git-shell /etc/shells || su -c \ "echo `which git-shell` >> /etc/shells" # su -c 'usermod -s git-shell gituser' الآن يمكن لمستخدم جيت استخدام مفتاح SSH فقط لدفع وسحب مستودعات جيت، ولا يمكنه الوصول إلى قشرة تسجيل الدخول. ينبغي عليك أيضًا أن تُضف نفسك إلى المجموعة المقابلة لـمستخدم جيت، والتي في مثالنا يمثلها الخادم الذي يعتبر أيضًا مستخدم جيت. فمثلًا: # usermod -a -G gituser seth الخطوة الوحيدة المتبقية هي إنشاء مستودع جيت، ونظرًا لأن لا أحد سيتفاعل معه مباشرة على الخادم (أي أنك لن تذهب إلى SSH الخاص بالخادم وتعمل مباشرة في هذا المستودع)، اجعله مستودعًا خاليًا، وإذا كنت ترغب في استخدام المستودع على الخادم لإنجاز العمل، فانسخه من هناك واعمل عليه في المجلد الرئيسي الخاص بك. في الحقيقة، ليس عليك فعليًّا أن تجعل هذا المستودع فارغًا؛ بإمكانه العمل كمستودع عادي، لكن يجب أن تعلم أن المستودع المجرد bare repository لا يحتوي على شجرة عمل working tree، أي لا توجد فيه فروع للتنقل بينها من خلال أمر checkout، وهذا مهم (أن يكون مجردًا) لأنه لا يُسمح للمستخدمين البعيدين بالانتقال إلى فرع نشط (أي يتم العمل عليه حاليًّا)، فمن المؤكد أنك لن تكون سعيدًا في حال كنت تعمل على فرع ما وليكن "Dev" وفجأة يأتي شخص ويدفع تعديلاته ضمن عملك! يمكنك وضع هذا المستودع في أي مكان تريده، طالما أن المستخدمين والمجموعات الذين تريد منحهم إذنًا للوصول إليه يمكنهم فعل ذلك. إن لم ترد وضع المجلد في المجلد الرئيسي، مثلًا لأن الأذونات فيه حازمة ودقيقة للغاية، وتريد تخزينه في موقع آخر مثل ‎/opt أو /usr/local/share، فأنشئ مستودعًا مجردًا كمستخدم جذر: # git init --bare /opt/jupiter.git # chown -R gituser:gituser /opt/jupiter.git # chmod -R 770 /opt/jupiter.git الآن يمكن لأي مستخدم تمت مصادقته على أنه مستخدم جيت أو موجود في مجموعة مستخدم جيت أن ينفذ عمليات القراءة من مستودع jupiter.git والكتابة عليه. يمكنك تجريبه على جهازك كالتالي: $ git clone gituser@example.com:/opt/jupiter.git jupiter.clone Cloning into 'jupiter.clone'... Warning: you appear to have cloned an empty repository. تذكر أنه يجب على المطورين إدخال مفتاح SSH العام الخاص بهم في ملف authorized_keys الخاص بمستخدم جيت، أو إذا كان لديهم حسابات على الخادم مثلك، فيجب أن يكونوا أعضاء في مجموعة مستخدم جيت. خطافات جيت git hooks إحدى الميزات الرائعة لاستخدام خادم جيت خاص بك هو أنه يتيح لك استخدام الخطافات، وهي برامج يتم تنفيذها قبل أو بعد أحداث محددة كالإيداع والسحب والدفع …إلخ. وبمزيد من الدقة هو ملف تنفيذي يتم وضعه في مجلد ‎.git/hooks واعتمادًا على مخطط تسمية قياسي يتم تنفيذه في الوقت المحدد، ويمكنك كتابة الشيفرة البرمجية التي ينفذها الخطاف بأي لغة تريدها، أي أنك غير مجبر على استخدام لغة محددة. أحيانًا توفر خدمات استضافة جيت واجهة تشبه الخطاف، لكنها لا تمنحك روابط جيت حقيقية ولا حتى إمكانية الوصول إلى نظام الملفات، وسنرى الآن مثالًا لاستخدام الخطافات، وهذا يتطلب منك إنشاء مستودع جيت إذا لم يكن لديك واحد بالفعل: $ mkdir jupiter $ cd jupiter $ git init ثم أنشئ خطاف جيت يعرض الرسالة "hello world": $ echo "#\!/bin/tcsh" > .git/hooks/post-commit $ echo "echo 'POST-COMMIT SCRIPT TRIGGERED'" >> \ ~/jupiter/.git/hooks/post-commit $ chmod +x ~/jupiter/.git/hooks/post-commit والآن اختبره: $ echo "hello world" > foo.txt $ git add foo.txt $ git commit -m 'first commit' ! POST-COMMIT SCRIPT TRIGGERED [master (root-commit) c8678e0] first commit 1 file changed, 1 insertion(+) create mode 100644 foo.txt والآن أصبح لدينا خطاف جاهز ونشط. خطاف الدفع إلى الويب الاستخدام الشائع لخطافات جيت هو دفع التعديلات تلقائيًا إلى المجلد الموجود على خادم ويب إنتاجي، حيث أنها تعتبر طريقة رائعة للتخلي عن بروتوكول نقل الملفات FTP، والاحتفاظ بكامل التحكم في الإصدار لما هو قيد الإنتاج، ودمج ونشر المحتوى تلقائيًا. إذا تم إنجازه بطريقة صحيحة، فإنه سيعمل بروعة، وفعليًّا هكذا يجب أن تتم عمليات النشر على الويب. متغيرات جيت يتم تخصيص مجموعة مختلفة من المتغيرات المتعلقة بالإجراء الذي يتم تنفيذه لكل خطاف، وربما تحتاج أو لا تحتاج إلى استخدام هذه المتغيرات، حيث يعتمد ذلك على ما تكتبه، فإذا كان كل ما تريده هو رسالة بريد إلكتروني عامة تنبهك إلى أن شخصًا ما نفّذ عملية دفع، فأنت لست بحاجة إلى تفاصيل، وربما قد لا تحتاج حتى إلى كتابة البرنامج، أما إذا كنت تريد رؤية رسالة الإيداع ومؤلف الإيداع في هذا البريد الإلكتروني، فلا بد من البرنامج آنذاك. لا يتم تشغيل خطافات جيت من خلال المستخدم مباشرةً، لذا قد تكون معرفة كيفية جمع المعلومات المهمة أمرًا محيرًا. حقيقةً، يشبه خطاف جيت أي نص برمجي آخر، حيث يستلم المعطيات من مجرى الدخل القياسي stdin بنفس طريقة باش BASH وبايثون Python وسي بلس بلس C++‎ وأي لغة أخرى. الفرق هو أننا لا نقدم هذه المدخلات بأنفسنا، لذا لاستخدامها عليك أن تعرف ما يمكن توقعه. قبل إنشاء خطاف جيت، انظر إلى العينات التي يوفرها جيت في مجلد ‎.git/hooks‎ الخاص بمشروعك مثل ملف pre-push.sample، وانظر إلى ما ينصّه في قسم التعليقات: # $1 -- اسم المستودع البعيد الذي يتم إجراء عملية دفع إليه # $2 – للمستودع البعيد URL عنوان # إذا تمت عملية الدفع من دون استخدام اسم المستودع البعيد، فإن هذه المعطيات ستكون متساوية # يتم توفير معلومات تتعلق بالإيداع كما يلي # <local ref> <local sha1> <remote ref> <remote sha1> في الحقيقة ليست كل العينات واضحة إلى هذه الدرجة كما في العينة السابقة، ولا يزال توثيق مجموعة المتغيرات التي يتم تمريرها كمعطيات إلى الخطافات قليلًا (بإمكانك قراءة الشيفرة المصدرية لجيت لمعرفتها، لكن لا أعتقد أنك سترغب في ذلك). مثال عن الخطافات التي تنجز مهام محددة بناءً على الفرع المُتأثر يُعتبر الخطاف الذي يُنفذ إجراءات معينة ضمن فرع محدد، أحد المتطلبات الشائعة في بعض الأنظمة البرمجية، وفيما يلي مثال على كيفية التعامل مع مثل هذه المهمة. قبل كل شيء يجب أن تعلم أن جيت لا تتبع الخطافات الخاصة بها لأن الخطاف يعد جزءًا من جيت وليس جزءًا من مستودعك، ولهذا السبب خطافات جيت التي تشرف على عمليات الإيداع والدفع ربما يكون من المنطقي أكثر بقاءها في المستودع المجرد على الخادم، بدلاً من أن تكون جزءًا من مستودعاتك المحلية. سنكتب الآن خطافًا يتم تنفيذه بعد استلام الإيداع، الخطوة الأولى هي تحديد اسم الفرع: #!/bin/tcsh foreach arg ( $< ) set argv = ( $arg ) set refname = $1 end تقرأ حلقة for-loop هذه المُعطى الأول $1، ثم تعيد التكرار من أجل استبداله بالمُعطى الثاني ‎$2، ثم مرة أخرى من أجل المعطى الثالث ‎$3. هناك طريقة أفضل للقيام بذلك في باش Bash، عن طريق استخدام الأمر read ووضع القيم في مصفوفة. عندما يكون لدينا اسم المرجع refname للشيء الذي يتم إيداعه، يمكننا استخدام جيت لاكتشاف اسم الفرع المقروء: set branch = `git rev-parse --symbolic --abbrev-ref $refname` echo $branch #DEBUG بعد ذلك وازن اسم الفرع بالكلمات المفتاحية التي نريد أن نبني الإجراء عليها: if ( "$branch" == "master" ) then echo "Branch detected: master" git \ --work-tree=/path/to/where/you/want/to/copy/stuff/to \ checkout -f $branch || echo "master fail" else if ( "$branch" == "dev" ) then echo "Branch detected: dev" Git \ --work-tree=/path/to/where/you/want/to/copy/stuff/to \ checkout -f $branch || echo "dev fail" else echo "Your push was successful." echo "Private branch detected. No action triggered." endif الآن نحوّل الشيفرة البرمجية إلى ملف تنفيذي: $ chmod +x ~/jupiter/.git/hooks/post-receive الآن عندما ينفذ المستخدم إيداعًا ضمن الفرع الرئيسي للخادم، يتم نسخ الشيفرة البرمجية إلى مجلد العمل، والإيداع ضمن الفرع dev يتم نسخه في مكان آخر، ولا يحدث أي إجراء في الفروع الأخرى. من السهل جدًا إنشاء برنامج للإيداع المسبق، مثلًا يتحقق فيما إذا كان شخص ما يحاول الدفع إلى فرع لا ينبغي أن يتم الدفع إليه، أو لتحليل رسائل الإيداع وما إلى ذلك. يمكن أن تكون خطافات جيت معقدة، ويمكن أن تكون مربكة بسبب مستوى التجريد الذي يفرضه العمل من خلال جيت، لكنها نظام قوي يسمح لك بتصميم جميع أنواع الإجراءات في البنية التحتية لجيت، لذلك فهي تستحق أن تتقنها. سوف نتعلم في المقال التالي والأخير من هذه السلسلة كيفية استخدام جيت لإدارة الكائنات الثنائية غير النصية، مثل ملفات الصوت والرسومات. ترجمة -وبتصرف- للمقال How to build your own Git server لصاحبه Seth Kenlon. اقرأ أيضًا المقال التالي: كيفية إدارة الكائنات الثنائية Binary Blobs باستخدام جيت Git المقال السابق: أدوات رسومية للأداة سطر الأوامر جيت git بدء العمل مع نظام إدارة الإصدارات جيت Git إنشاء أول مستودع لك من خلال جيت Git الدليل المرجعي للعمل على نظام غيت Git
  25. جانغو Django هو إطار عمل ويب في بايثون مجاني ومفتوح المصدر ويستخدم في تطوير مواقع الويب أُصدرَ في شهر تموز من عام 2005، وهو مشهور ببُنيته المُعتمدة على المكونات، إذ تُركز على تحليل التصميم إلى مكونات وظيفية أو منطقية مُفردة (استقلالية المكونات) مما يجعل التطبيقات أكثر مرونة وقابلية للتوسع والنمو وإعادة الاستخدام كما أنه يتسم بسرعة التطوير المعززة بميزات أمان مُدمجة. يعتمد جانغو على النمط البنائي للبرمجيات نموذج-قالب-عرض Model-Template-View -تختصر إلى MTV- والمُستمد من النمط البنائي نموذج-عرض-متحكم model–view–controller -تختصر إلى MVC- . يتم تعريف النموذج Model على أنه مصدر مفرد ومحدد من البيانات، والعرض View على أنه عبارة عن البيانات التي يتم إظهارها للمستخدم، والقالب Template على أنه عبارة عن الآلية التي يستخدمها جانغو لتوليد صفحات HTML. إن اعتماد جانغو على بنية نموذج-قالب-عرض تشجع على مبدأ عدم التكرار DRY programming وهو مبدأ يهدف إلى الحد من تكرار المعلومات من جميع الأنواع، وينص على أن "أي جزء في النظام ينبغي أن يكون معرّفاً في مكان واحد واضح مسؤول عن هذا الجزء". ستتعلم في هذه المقالة تثبيت جانغو وتشغيله على خادم أبونتو Ubuntu وستتعلم إنشاء مشروع جديد لاستخدامه كأساس لموقعك. المتطلبات الأساسية حساب مستخدم عادي بصلاحيات sudo مُهيّأ مسبقًا على خادم أبونتو 20.04. تثبيت جانغو بإمكانك تثبيت جانغو بطرق مختلفة وفقًا لاحتياجاتك والطريقة التي تريد بها تهيئة بيئة التطوير. 1. تثبيت عام من خلال الحزم مستودعات أبونتو الرسمية تحتوي على حزم جانغو التي يمكن تثبيتها باستخدام أداة الحزم المتقدمة APT package manager. تعتبر هذه الطريقة بسيطة، لكنها غير مرنة كباقي الطرق، كما أن الإصدار الموجود في المستودعات ربما يكون مختلفًا عن الإصدارات الرسمية المتوفرة. الآن، سنتحدث عن كيفية تثبيت جانغو باستخدام هذه الطريقة. أولاً، يجب تحديث فهرس الحزمة المحليّة لديك local package index باستخدام apt: $ sudo apt update الآن تحقق من إصدار بايثون الذي ثبَّته، مع ملاحظة أن الإصدار 3.8 من بايثون يكون افتراضيًا متوفرًا في الإصدار 20.04 من أبونتو وما فوق. عمومًا، يمكنك التحقق من إصدار بايثون المُثبت على جهازك عن طريق كتابة الأمر التالي: $ python -V يجب أن يكون الخرج مُشابه للخرج التالي: Python 3.8.2 الآن نثبت جانغو: $ sudo apt install python3-django نفذ الأمر التالي للتحقق من إصدار جانغو الذي ثبّتناه للتو، وضمان أن عملية التثبيت تمت بنجاح: $ django-admin --version يجب أن يكون الخرج مُشابهًا للخرج التالي: 2.2.12 هذا يعني أن عملية التثبيت تمت بنجاح، وربما تلاحظ أيضًا أن إصدار جانغو الذي حصلت عليه ليس أحدث إصدار مستقر stable version. 2. تثبيت جانغو باستخدام مدير حزم بايثون pip ضمن بيئة افتراضية تُعتبر هذه الطريقة مرنة وعملية أكثر ويوصى باستخدامها. يمكنك إنشاء بيئة مخصصة لمشاريعك self-contained، باستخدام أدوات مثل venv و vertualenv، أو يمكنك استخدام البيئة الافتراضية التي تسمح لك بتثبيت جانغو في مجلد المشروع بأمان، إلى جانب التخصيصات والحزم الأخرى اللازمة لكل مشروع. سنبيّن الآن كيفية تثبيت جانغو ضمن بيئة افتراضية سننشئها باستخدام الأداة venv وهي أداة تأتي مثبتة افتراضيًّا مع حزمة بايثون. تمكنك هذه الأداة من إنشاء بيئات بايثون افتراضية، وتثبيت حزم بايثون دون التأثير على باقي أجزاء النظام (بأمان)، لذلك يمكنك اختيار حزم بايثون بإصدارات محددة لكل مشروع، بصرف النظر عن التعارضات التي قد تحدث مع متطلبات المشاريع الأخرى. أولاً، يجب تحديث فهرس الحزمة المحليّة لديك local package index باستخدام apt: $ sudo apt update الآن يمكنك التحقق من إصدار بايثون المُثبت على جهازك عن طريق كتابة الأمر التالي: $ python -V يجب أن يكون الخرج مُشابه للخرج التالي: Python 3.8.2 بعد ذلك، نثبت pip و venv من مستودعات أبونتو: $ sudo apt install python3-pip python3-venv الآن، عندما تبدأ مشروعًا جديدًا، يمكنك إنشاء بيئة افتراضية له. ابدأ بإنشاء مجلد للمشروع الجديد وانتقل إليه: $ mkdir ~/newproject $ cd ~/newproject بعد ذلك، أنشئ بيئة افتراضية داخل مجلد المشروع باستخدام أمر بايثون المتوافق مع اصدار بايثون المُثبت لديك. سنطلق على بيئتنا الافتراضية اسم my_env، ويُفضل دومًا أن تسميها اسمًا يَصِفَها: $ python -m venv my_env بعد ذلك، سيتم تثبيت إصدارات مستقلة من بايثون ومدير الحزم pip ضمن بنية مجلد معزولة isolated directory structure (طريقة لإظهار الملفات بشكل معين، وتظهر الملفات بشكل شجري هرمي) داخل مجلد مشروعك. سيتم إنشاء مجلد بالاسم الذي تحدده، والذي يحتوي على التسلسل الهرمي للملفات في المكان الذي سيتم فيه تثبيت الحزم الخاصة بك. لتثبيت الحزم ضمن البيئة المعزولة التي أنشأناها، يجب تنشيطها عن طريق كتابة الأمر التالي: $ source my_env/bin/activate يُفترض آنذاك أن يتغير موجه سطر الأوامر لديك ليشير إلى بيئتك الافتراضية، أي يجب أن يكون مشابه لهذا: (my_env)username@hostname:~/newproject$ بعد أن انتقلت إلى بيئتك الافتراضية، يمكنك استخدام pip لتثبيت جانغو. لا يجب أن تستخدم pip لتثبيت جانغو قبل أن تكمل الخطوة السابقة (الانتقال إلى بيئتك الافتراضية)، أيضًا أنت لست بحاجة إلى استخدام sudo، لأنك تُثبته محليًّا. (my_env) $ pip install Django يمكنك التحقق من أن عملية التثبيت تمت بنجاح، كالتالي: (my_env) $ django-admin --version 3.0.8 تجدر الإشارة هنا إلى أن الأمر السابق يُثبت لك أحدث نسخة من جانغو، وفي وقت كتابة هذا المقال كانت أحدث نسخة هي النسخة 3.0.8، لذا عند قراءتك المقال وتثبيتك لجانغو، ربما تكون نسختك مختلفة (أحدث). أخيرًا لمغادرة البيئة الافتراضية، يجب أن تُلغي تنشيط البيئة الافتراضية: (my_env) $ deactivate بعد ذلك سيعود سطر الأوامر إلى الموقع الافتراضي. إذا أردت العودة لاحقًا إلى بيئتك لمتابعة العمل على مشروعك، انتقل إلى مجلد المشروع ونشّط بيئتك الافتراضية. $ cd ~/newproject $ source my_env/bin/activate 3. تثبيت أحدث إصدار من جانغو من خلال جيت git يمكنك استخدام هذه الطريقة في حال كنت ترغب بتثبيت آخر إصدار تم تطويره development version بدلًا من الإصدار المستقر stable version، حيث يمكنك الحصول على الشيفرة المصدر من مستودع جيت الخاص به، وهذه الطريقة ضرورية للحصول على آخر الميزات والإصلاحات، كما يمكنك إتمام ذلك من خلال البيئة الافتراضية التي لديك. عمومًا، لا بد من التنويه إلى أن الإصدار المستقر هو الإصدار الذي تم تجريبه واختباره وضمان أنه خالٍ من الأخطاء، أما الإصدار الذي يتم تطويره فهو ليس كذلك، فربما يحتوي بعض الأخطاء أو المشاكل. الآن سنعرض كيفية إنجاز هذه المهمة داخل البيئة الافتراضية. أولاً، نُحدث فهرس الحزمة المحلي: $ sudo apt update تحقق الآن من إصدار بايثون المُثبَّت: $ python -V يجب أن يكون الخرج مُشابه للخرج التالي: Python 3.8.2 ثم ثبّت pip و venv من المستودعات الرسمية: $ sudo apt install python3-pip python3-venv الخطوة التالية هي نسخ مستودع جانغو، وبعد ذلك ستحصل على الإصدار الأحدث الذي يتم تطويره والذي يتمتع بالميزات الجديدة وتصحيحات الأخطاء السابقة …إلخ. يمكنك نسخ المستودع إلى مجلد يُسمى ‎~/django-dev داخل المجلد الرئيسي home، كالتالي: $git clone git://github.com/django/django ~/django-dev الآن انتقل إلى هذا المجلد: $ cd ~/django-dev أنشئ بيئة افتراضية باستخدام أمر بايثون المتوافق مع إصدار بايثون المثبَّت لديك: $ python3 -m venv my_env ثم نشطها بالأمر التالي: $ source my_env/bin/activate الآن، يمكنك تثبيت المستودع باستخدام pip، وكما تلاحظ استخدمنا الراية e-، لكي تتم عملية التثبيت مع صلاحية قابلية التعديل editable، وهذا ضروري عندما نُنجز عملية التثبيت من جيت: (my_env)$ pip install -e ~/django-dev كما هي العادة، تحقق من نجاح التثبيت: $ django-admin --version 3.2 إنشاء أول مشروع لك بعد تثبيت جانغو، يمكنك بناء مشروعك، فسنتحدث في هذا القسم عن كيفية إنشاء مشروع واختباره على خادم تطوير development server باستخدام بيئة افتراضية. بدايًة، أنشئ مجلد مشروعك، وانتقل إليه. $mkdir ~/django-test $cd ~/django-test ثم أنشئ بيئتك الافتراضية: $ python3 -m venv my_env ونشطها بالأمر التالي: $ source my_env/bin/activate ثبت جانغو: (my_env)$ pip install django الآن، يمكنك استخدام django-admin لبناء مشروعك مع استخدام الأمر startproject، سنسمي المشروع djangoproject، لكن يمكنك اختيار أي اسم تريده. سيُنشئ الأمر startproject مجلدً داخل مجلد العمل الحالي لديك، والذي يتضمن: ملف الإدارة manage.py، الذي يُمكّنك من إدارة العديد من المهام المتعلقة بجانغو. مجلد يتضمن شيفرة مشروعك، ويكون اسمه مُطابقًا لاسم المشروع. لتجنب وجود عدد كبير جدًا من المجلدات المتداخلة، يمكنك أن تجعل جانغو يضع سكربت الإدارة والمجلد الداخلي في المجلد الحالي (لاحظ وجود نقطة في نهاية الأمر): (my _env)$ django-admin startproject djangoproject . الآن، يمكنك استخدام أمر التهجير migrate مع ملف manage.py لتهجير قاعدة البيانات (في هذا المثال نستخدم SQLite)، إذ يُطبق التهجير أي تغييرات أجريتها في نماذج جانغو على مخطط قاعدة البيانات: (my_env) $ python manage.py migrate ستشاهد خرجًا يشبه الخرج التالي: Operations to perform: Apply all migrations: admin, auth, contenttypes, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying admin.0003_logentry_add_action_flag_choices... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying sessions.0001_initial... OK وأخيرًا، نُنشئ مُستخدم مدير (مسؤول) administrative user لتتمكن من استخدام واجهة مدير جانغو Django admin interface، من خلال الأمر createsuperuser: (my_env)$ python manage.py createsuperuser سيُطلب منك أن تحدد اسم مستخدم وعنوان بريد إلكتروني وكلمة مرور للمستخدم الذي تريد إنشاءه. تعديل قائمة ALLOWED_HOSTS في ملف إعدادات جانغو لاختبار تطبيقك بنجاح، ستحتاج إلى تعديل أحد التوجيهات directives في إعدادات جانغو. افتح ملف الإعدادات من خلال الأمر التالي: (my_env) $ nano ~/django-test/djangoproject/settings.py الآن، حدد توجيه ALLOWED_HOSTS الذي يُمكِّنك من تحديد قائمة من العناوين أو أسماء النطاقات التي قد تُستخدم للاتصال بجانغو، وبالتالي فإن وصول أي طلب Request مع ترويسة مُضيف Host header (رأس المضيف هو الجزء الثالث من المعلومات الذي يمكنك استخدامه بالإضافة إلى عنوان IP ورقم المنفذ لتعريف نطاق الويب بشكل فريد) غير موجود في هذه القائمة إلى ظهور استثناء. إنَّ إنجاز هذه العملية ضروري في جانغو لتجنب بعض أنواع الثغرات الأمنية. إذًا ضمن القائمة ALLOWED_HOSTS حدِّد عناوين IP أو أسماء النطاقات المرتبطة مع خادم جانغو الخاص بك، وضع كل واحدٍ منهم ضمن علامتي اقتباس، وافصل بين كل واحدة بفاصلة. أخيرًا، إذا كنت تريد السماح بطلبات لنطاق بأكمله أو لأي نطاق جزئي، فأضف نقطة في بدايته. تذكر أن ALLOWED_HOST موجود ضمن الملف settings.py وفي مثالنا هو موجود في المسار: ALLOWED_HOSTS = ['your_server_ip_or_domain', 'your_second_ip_or_domain', . . .] عندما تنتهي احفظ الملف وأغلق المحرر. اختبار خادم التطوير يكفي أن يكون لديك حساب مستخدم، حتى تتمكن من تشغيل خادم تطوير جانغو development server لترى كيف تعمل الأمور في مشروعك، كما يجب أن تدرك أن استخدامه يجب أن يكون فقط لأغراض التطوير. أخيرًا، عندما تكون جاهزًا لنشر مشروعك، تأكد من اتباع إرشادات جانغو من توثيقه الرسمي، وذلك لضمان نشره بطريقة سليمة. قبل استخدام خادم التطوير، تأكد من فتح المنفذ المناسب في جدار الحماية firewall الخاص بك. إذا اتبعت دليل إعداد الخادم الأولي وكنت تستخدم UFW، فيمكنك فتح المنفذ 8000 من خلال الأمر التالي: (my_env) $ sudo ufw allow 8000 لمزيد من التفاصيل انظر مقال أساسيات UFW: قواعد وأوامر شائعة للجدار الناري. شغّل خادم التطوير: (my_env)$ python manage.py runserver your_server_ip:8000 الآن، ضمن متصفح الويب، حاول الانتقال إلى الخادم الخاص بك من خلال عنوان IP المربوط به، متبوعًا بالمنفذ 8000. http://your_server_ip:8000 إن كنت تعمل محليًا على حاسوبك، فيمكنك تشغيل الخادم للعمل محليًا بتمرير رقم المنفذ فقط بالشكل: (my_env)$ python manage.py runserver 8000 وبذلك، يمكنك الانتقال إلى العنوان localhost:8000 أو http://127.0.0.1:8000. يجب أن ترى شيئًا يشبه هذا: للوصول إلى واجهة المُدير admin interface، أضف /admin/ إلى نهاية عنوان URL الخاص بك. http://your_server_ip:8000/admin/ أو http://127.0.0.1:8000/admin/ سينقلك ذلك إلى شاشة تسجيل الدخول: إذا أدخلت اسم المستخدم وكلمة المرور الخاصين بالمدير admin اللذين أنشأتهما منذ قليل، فستتمكن من الوصول إلى قسم المُدير الأساسي في الموقع: عندما تنتهي من الاطلاع على الموقع الافتراضي، يمكنك إيقاف خادم التطوير من خلال الضغط على الاختصار CTRL-C في الطرفية terminal. إن مشروع جانغو الذي أنشأته، يوفر الأساس الهيكلي لتصميم موقع أكثر تعقيدًا وتكاملًا. يمكنك الاطلاع على توثيق جانغو للحصول على المزيد من المعلومات المتعلقة بإنشاء التطبيقات وتخصيص المواقع. خاتمة في نهاية هذه المقالة يجب أن يكون جانغو مثبتًا على خادم أبونتو الخاص بك، وبالتالي تمتلك أداةً مميزةً توفر لك الأدوات الرئيسية التي تحتاجها لإنشاء تطبيقات ويب قوية. يجب أن تكون قادرًا أيضًا على بدء مشروع جديد وتشغيل خادم المُطور. إن وجود إطار عمل متكامل مثل جانغو يمكن أن يساعد في جعل عملية التطوير أسرع، مما يسمح لك بالتركيز أكثر على الجوانب المهمة في تطبيقك. ترجمة -وبتصرف- للمقال How To Install the Django Web Framework on Ubuntu 20.04 لصاحبه Brian Boucheron. اقرأ أيضًا تنصيب إطار العمل Django وتهيئة بيئته البرمجية على Ubuntu 16.04 مدخل إلى إطار العمل Django حزم بايثون الثمانية التي تسهل تعاملك مع Django
×
×
  • أضف...