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

سامح أشرف

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

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

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

  • عدد الأيام التي تصدر بها

    56

كل منشورات العضو سامح أشرف

  1. يمكن تخزين معلومات المنتجات التي يريد المستخدم شرائها بطريقتين: عبر JavaScript في متصفح الويب يمكن تخزين بيانات المنتجات في localStorage عند الضغط على زر "إضافة إلى السلة"، بالشكل التالي: // بيانات المنتج الذي يريد المستخدم إضافته إلى سلة المشتريات const productDetails = { name: "Phone", price: 1234, // ... }; // نقوم بجلب أي منتجات موجودة بالفعل في سلة المشتريات const productsInCart = JSON.parse(localStorage.getItem("cart")) || []; // نجمع المنتجات الموجودة بالفعل مع المنتج الحالي في مصفوفة واحدة const allProductsAsString = JSON.stringify([...productsInCart, productDetails]); // نقوم بتخزين هذه البيانات في localStorage localStorage.setItem("cart", allProductsAsString); وفي صفحة سلة المشتريات، يمكن الحصول على كل المنتجات بالشكل التالي: // نقوم بجلب أي منتجات موجودة بالفعل في سلة المشتريات const productsInCart = JSON.parse(localStorage.getItem("cart")) || []; ميزات وعيوب هذه الطريقة لا تحتاج إلى قاعدة بيانات على الخادم لتخزين البيانات. سريعة للغاية، حيث أن كل المهمة تتم في المتصفح بدون الحاجة إلى إرسال أي طلبات إلى الخادم. لا تحتاج إلى تسجيل دخول، حيث يمكن للمستخدم إختيار المنتجات التي يريد شرائها ويضعها في سلة المشتريات حتى قبل أن يسجل في موقع من الأساس. تعمل في متصفح واحد فقط، أي أنه إذا قام المستخدم بتسجيل الدخول إلى متصفح آخر لن يجد أي منتجات في سلة المشتريات. عبر PHP في الواجهة الخلفية في البداية يجب عمل جدول في قاعدة البيانات لتخزين المنتجات التي يضعها أي مستخدم في سلة المشتريات، ويكون شكل الجدول على النحو التالي: id | user_id | product_id | quantity -------------------------------------- 1 | 123 | 789 | 1 2 | 165 | 124 | 4 3 | 785 | 543 | 1 4 | 956 | 876 | 3 إذا قام المستخدم بإضافة أي منتج إلى سلة المشتريات يجب أن يتم إضافته إلى هذا الجدول، وفي هذا الجدول نحتاج إلى user_id و product_id أي أن المستخدم يجب أن يكون مُسجل في الموقع حتى يتمكن من إستعمال هذه الميزة. هنا جملة SQL Query لإضافة منتج إلى الجدول cart السابق: INSERT INTO cart (user_id, product_id, quantity) VALUES (123, 789, 3); أما لعرض المنتجات التي وضعها المستخدم في سلة المشتريات، يمكننا إستعمال جملة SQL التالية: SELECT * FROM cart INNER JOIN products ON products.id = cart.product_id; ميزات وعيوب هذه الطريقة تحتاج إلى قاعدة بيانات على الخادم لتخزين البيانات. بطيئة نوعًا ما، حيث أن عملية إضافة أي منتج في سلة المشتريات تحتاج إلى إرسال طلب Request إلى الخادم. تحتاج إلى تسجيل دخول قبل إستعمالها، بما أننا نستعمل user_id في الجدول cart فيجب أن يسجل المستخدم في الموقع أولًا. تعمل في جهة الخادم، أي أنه إذا قام المستخدم بتسجيل الدخول إلى متصفح آخر أو حاسوب مختلف تمامًا فسوف يجد كل المنتجات في سلة المشتريات كما هي.
  2. يمكن إستعمال الدالة strpos كذلك بالشكل التالي: <?php $number = "05914370969 "; if (strpos($number, '059') === 0) { echo "number starts with 059"; } else { echo "number doesn't start with 059"; } الدالة strpos تعمل على جلب موضع نص معين ضمن نص آخر، يمكنك الإطلاع على توثيق هذه الدالة من خلال موسوعة حسوب من هنا، أو من خلال الإجابات هنا: كما يمكن إستعمال الدالة preg_match وإستخدام التعابير النمطية Regular Expression على النحو التالي: <?php $number = "05914370969 "; $result = preg_match('/^059/', $number); if ($result !== 0) { echo "number starts with 059"; } else { echo "number doesn't start with 059"; } توثيق الدالة preg_match في موسوعة حسوب، وتجد شرح للدالة preg_match في هذه المقالة أيضًا:
  3. للقيام بهذا الأمر يجب أن نقوم بعمل صنف Class يحتوي على التابع __init__ كما يلي: class Person: def __init__(self): pass الآن نضيف مدخل Parameter إلى التابع __init__ ويجب أن يكون هذا المدخل إختياريًا Optional أي له قيمة إفتراضية: class Person: def __init__(self, name="no name"): self.name = name person1 = Person() person2 = Person("Person2") print(person1.name) # no name print(person2.name) # Person2 الآن يمكننا عمل كائنين Two Objects من هذا الصنف: class Person: def __init__(self, name="no name"): self.name = name person1 = Person() # بدون أي مدخلات person2 = Person("Person2") # بمدخل واحد فقط، وهو اسم الشخص print(person1.name) # no name print(person2.name) # Person2
  4. مبادئ SOLID أو SOLID principles هي مجموعة من القواعد النظرية التي تهدف لجعل الكود أسهل في الكتابة والصيانة، وتساعدك على العمل في مشاريع كبيرة بدون بذل جهد كبير في عملية إصلاح الأخطاء، وهذه المبادئ مفيدة بصورة خاصّة في التصميم كائنيّ التوجّه object-oriented design، حيث تقدم هذه القواعد الأساسيات التي يجب إتباعها عند إنشاء الأصناف وربطها معًا. هذه المبادئ ليست ضرورية لتصميم البرمجيات ولكنها تساعد مطوّري البرمجيّات على تحقيق تصاميم برمجيّة عالية الجودة. كل حرف من أحرف كلمة SOLID عبارة عن أختصار لأحد المبادئ: مبدأ المسؤولية الواحدة Single Responsibility Principle (SRP) مبدأ الفتح والإغلاق Open/Closed Principle (OCP) مبدأ ليسكوف للاستبدال Liskov Substitution Principle (LSP) مبدأ فصل الواجهات Interface Segregation Principle (ISP) مبدأ عكس التابعيّة Dependency Inversion Principle (DIP) هنا شرح بسيط لكل مبدأ من مبادئ SOLID: مبدأ المسؤولية الواحدة Single Responsibility Principle (SRP) ينص هذا المبدأ على التالي: على سبيل المثال إن كان لديك الصنف User للتعامل مع بيانات المستخدم في قاعدة البيانات، وبفرض أن هذا الصنف مسؤول عن عرض البيانات في الصفحة الشخصية للمستخدم، فسيكون لدينا سببين للتعديل على هذا الصنف في المستقبل: عندما نُريد عمل تغير ما في بيانات المستخدم في قاعدة البيانات. عندما نريد تغير شكل البيانات التي يتم عرضها في الصفحة الشخصية للمستخدم وبالتالي يوجد أكثر من سبب يدفعنا للذهاب إلى هذا الصنف والتعديل عليه، أي أن هذا الصنف لا يُحقق مبدأ المسؤولية الواحدة Single Responsibility Principle، ويجب فصله إلى صنفين كلُ منهما مسؤول عن أمر واحد ومحدد. يمكنك القراءة أكثر عن هذا المبدأ من خلال هذه المقالة: مبدأ الفتح والإغلاق Open/Closed Principle (OCP) المبدأ الثاني ضمن مبادئ SOLID هو مبدأ الفتح والإغلاق Open/Closed Principle، وينص هذا المبدأ على التالي: الهدف من هذا المبدأ هو التفكير في المستقبل (البناء الآن، التخطيط للمستقبل) بحيث نصمم البرمجيات وجعلها لا تحتاج إلى تغيير الكود المكتوب مسبقًا عند إضافة ميزات ووظائف جديدة إليها. على سبيل المثال إن كان لديك صنف Shape يصف أي شكل مُضلع ثنائي البعد، وقمت بإضافة الخواص width و height و area و perimeter فيه، فهذا الصنف لا يُحقق مبدأ الفتح والإغلاق Open/Closed Principle، لأننا سنحتاج إلى تعديل هذا الصنف في حالة أردنا عمل مثلث أو شكل خماشي، حيث أن هذه الأشكال لديها مُحيط perimeter ومساحة area ولكن ليس لديها طول وعرض. يمكنك القراءة أكثر عن هذا المبدأ من خلال هذه المقالة: مبدأ ليسكوف للاستبدال Liskov Substitution Principle (LSP) سُمي هذا المبدأ باسم صاحبه البروفسور باربارا ليسكوف، الذي طرحته لأوّل الأمر عام 1987. يهدف هذا المبدأ إلى تحديد شكل عملية الوراثة inheritance بين الأصناف، ويمكننا صياغة هذا المبدأ بالشكل التالي: لفهم معنى هذا المبدأ، تخيل أن لدينا صنف Rectangle والذي يصف أي مستطيل، ويوجد في هذا الصنف تابع يقوم بتعيّن الطول setHeight وتابع يقوم بتعين العرض setWidth، حتى الآن لا يوجد مشكلة، ولكن عندما نريد عمل صنف Square ويرث من الصنف Rectangle (حيث أن المربع حالة خاصة من المستطيل (مستطيل طوله مساوي لعرضه))، فسنواجه مشكلة في هذا الأمر، لأن المربع لا يمكن أن يحتوي على طول مختلف عن العرض، ولهذا يجب عمل صنف مختلف تمامًا للمربع Square بدون أن يرث من Rectangle يمكنك القراءة أكثر عن هذا المبدأ من خلال هذه المقالة: مبدأ فصل الواجهات Interface Segregation Principle (ISP) هدف هذا المبدأ هو التفكير في المستقيل كذلك، ولكن بطريقة مختلفة عن مبدأ المسؤولية الوحيدة السابق ذكره، حيث ينص هذا المبدأ على التالي: لفهم نص هذا المبدأ، يجب أن تفهم الواجهات Interfaces في لغة PHP (أو في البرمجة بشكل عام)، هنا مقالة توفر شرح لهذا الأمر بالإضافة لبعض المفاهيم الأساسية الأخرى: الآن تخيل أن لدينا واجهة تصف الشخص الواحد بالشكل التالي: interface iHuman { public function work(); // الإنسان يمكنه العمل public function sleep($hours); // يمكن أن ينام لعدة ساعات public function eat(); // يمكنه أن يأكل } بعد ذلك نريد أن نقوم بعمل صنف لموظف employee وبالتأكيد سوف نستخدم الواجهة السابقة بالشكل التالي: class Employee implements iHuman { public function work() {} public function sleep($hours) {} public function eat() {} } حتى الآن لا يوجد مشكلة، لكن ماذا إذا أردنا عمل صنف يُعبر عن طفل رضيع صغير Baby (ليس لديه عمل Work)، لذلك سوف يتم إجبارنا على إضافة التابع work إلى الصنف Baby حتى وإن لم يكن له فائدة تُذكر، لذلك ظهر مبدأ فصل الواجهات والذي ينص على فصل الواجهات عن بعضها البعض، بالشكل التالي: interface iWorkable { public function work(); // الإنسان يمكنه العمل } interface iHuman { public function sleep($hours); // يمكن أن ينام لعدة ساعات public function eat(); // يمكنه أن يأكل } class Employee implements iHuman, iWorkable { public function work() {} public function sleep($hours) {} public function eat() {} } class Baby implements iHuman { public function sleep($hours) {} public function eat() {} } يمكنك القراءة أكثر عن هذا المبدأ من خلال هذه المقالة: مبدأ عكس التابعيّة Dependency Inversion Principle (DIP) هذا المبدأ هو آخر مبادئ التصميم الكائنيّ SOLID، قد يكون صعبًا قليلًا لكنه مفيد للغاية، خصوصًا في البرمجيات الكبيرة والتي تحتوي على أصناف كثيرة ومتعددة، وينص على التالي: تخيل أن لديك صنف Button وصنف Window وتقوم بإستخدام كائنات من الصنف Button في العديد من الأمكان داخل الصنف Window، تكمن المشكلة الآن في أن الصنف Window أصبح يعتمد بشكل أساسي عل ىالصنف Button، وإذا أردت إجراء بعض التعديلات على الصنف Button (تغير بعض التوابع أو حذفها أو نغير المعاملات التي تأخذها)، فيجب أن تقوم بالتعديل على الصنف Window في الأماكن التي تستعمل كائنات من نوع Button ليجاري هذه التغيرات ويعمل بشكل سليم. حل المشكلة هنا هو عمل واجهة interface تسمى iButton على سبيل المثال، يعتمد عليها كلُ من الصنفين Button و Window، وبالتالي لن يعتمد أحد الأصناف على صنف آخر. يمكنك القراءة أكثر عن هذا المبدأ من خلال هذه المقالة:
  5. وعليكم السلام ورحمة الله وبركاته يمكنك تحميل نسخة 32bit من برنامج VS Code من خلال الموقع الرسمي للبرنامج من هنا. عليك فقط أن تضغط على زر 32bit كما في الصورة: وسوف يبدأ تحميل البرنامج بدون مشكلة.
  6. ما هي لغة البرمجة التي تستعملها؟ وما المشكلة التي تواجهك عند كتابة الكود؟ هل يمكنك إرفاق الكود الذي تحدث فيه المشكلة كذلك؟
  7. يمكنك عمل الكثير من الأشياء لزيادة مستواك ولتعلم المزيد من التقنيات، هنا بعض منها: قم بتطوير مشاريعك السابقة حاول أن تقوم بفتح أحد مشاريعك السابقة، وقم بتطويره، مثلًا قمتَ بعمل تطبيق To-Do، ويمكن إضافة المهام فيه، حاول تعديله وأضف له بعض المميزات الأخرى مثل إمكانيه إضافة وقت محدد لإنهاء المهمة Deadline أو أضف إمكانيه تحديد نوع أهمية كل مهمة (مهم، عاجل، عادي، غير مهم .. إلخ) وإمكانية ترشيح (فلتره) المهام Filter للوصول إلى المهام التي تندرج تحت تصنيف معين أو لها درجة أهمية معينة (مهم، عاجل، عادي، غير مهم .. إلخ). أيضًا إن لم يكن المشروع متجاوب Responsive حاول تعديله ليصبح متجاوب على كل الشاشات. يوجد الكثير من الأمور التي يمكنك عملها في كل مشروع، فأي فكرة يمكن تطويرها لشيء أفضل. تقليد المواقع الشهيرة أو التي تستعملها بكثيرة أن كنت تستعمل مواقع التواصل بشكل كبيرة أو أي موقع آخر، فيمكنك محاولة تقليد واجهة الموقع، وبالتالي تتدرب على واجهة موقع حقيقي، وذلك سيحسن من مهارتك وسيجعلك تواجهة تحديات أكبر، وستواجهة مشاكل أثناء هذه العملية ويجب أن تبحث عن حلول لهذه المشاكل، وكنتيجة لهذا الأمر سوف تتعلم تقنيات جديدة وسوف ترى نقاط القوة ونقاط الضعف لديك،و يمكنك تحسينها بعد ذلك. حل التحديات البرمجية يوجد الكثير من المواقع التي تقدم تحديات ومسائل برمجية، وتتدرج هذه المشاكل في صعوبتها (سهل، متوسط، متقدم .. إلخ)، حل هذه المسائل سوف يزيد من قدرتك على تطوير مشاريع أكثر تعقيدًا وسوف تستطيع حل المشاكل التي تواجهك أثناء العمل على مشاريع بشكل أسرع وأسهل، كما أن هذه التمارين سوف تزيد من فهمك لغة البرمجة التي تستعملها مما يزيد من مهاراتك بشكل عام. قد يكون حل المشاكل صعبًا في البداية، ولكن مع كل مشكلة تقوم بحلها سوف تتعلم شيء جديد أو تتعرف على تقنية مختلفة، ومع مرور الوقت سوف يكون بإمكانك حل أغلب المشاكل بسهولة. أشهر المواقع التي تقدم عدد كبير من المسائل البرمجية هنا قائمة ببعض المواقع التي تقدم مسائل برمجية، بعض هذه المواقع يتطلب التسجيل فيها أولًا لتتمكن من الوصول إلى المسائل: Coderbyte Project Euler HackerRank CodeChef Codewars LeetCode
  8. الأصناف Classes في PHP يمكن أن تحتوي على خصائص أو توابع ساكنة static أو عادية (موروثة inherited)، ولكي يمكننا الوصول إلى الخصائص العادية من داخل التوابع نستعمل this$ بينما تُستعمل self للوصول إلى الخصائص الساكنة أي أنك يجب أن تستخدم this$ للإشارة إلى الكائن الحالي Current Object. واستخدم self للإشارة إلى الصنف الحالي Current Class. بمعنى آخر ، استخدم this->member$ للتوابع غير الساكنة non-static ، واستخدم self::$member للتوابع الساكنة static. مثال: <?php class MyClass { // Current Class public $normal_value = "non-static value"; static $static_value = "static value"; function __construct() { echo $this->normal_value // للوصول إلى تابع أو خاصية عادية . ' + ' . self::$static_value; // للوصول إلى تابع أو خاصية ساكنة Static } } $c = new MyClass(); // Current Object // Output: non-static value + static value وإذا حاولت إستخدام self مكان this$ سيظهر لك الخطأ التالي: Fatal error: Uncaught Error: Access to undeclared static property سوف يتضح الأمر أكثر عن محاولة وراثة صنف إلى صنف آخر: <?php class X { function foo() { echo 'X::foo()'; } function bar() { self::foo(); // تُشير إلى الصنف الحالي، حتى بعد الوراثة } } class Y extends X { function foo() { echo 'Y::foo()'; } } $x = new Y(); $x->bar(); // X::foo() السبب في هذه النتيجة هو أن self تُشير إلى الصنف بحد ذاته وليس الكائنات التي يتم إنشائها منه (أو حتى الأصناف التي ترث منه)، وبالتالي ستظل self في المثال السابق تُشير إلى الصنف X على الجانب الآخر عند إستعمال this$ سيتم الإشارة إلى الكائن Object نفسه وليس الصنف Class: <?php class X { function foo() { echo 'X::foo()'; } function bar() { $this->foo(); // تُشير إلى الكائن الذي سيتم إنشائه } } class Y extends X { function foo() { echo 'Y::foo()'; } } $x = new Y(); $x->bar(); // Y::foo() ملاحظة: يمكن إستخدام self للوصول إلى التوابع بدون مشكلة (مثل this$) تمامًا: <?php class Person { private $name; public function __construct($name) { $this->name = $name; } public function getName() { return $this->name; } public function sayGoodbye() { echo "Goodbye, " . self::getName() . "<br/>"; } } $p = new Person("Sameh"); $p->sayGoodbye(); // // Goodbye, Sameh
  9. تعريف كلًا من الدالة Function والتابع Method هذه مجرد مصطلحات لوصف جزء معين من الكود، وهنا تعريف بسيط لكلٍ منهما: الدالة Function: تسمى أيضًا "وظيفة"، هي كتلة من الكود (مجموعة من الأسطر البرمجية) لها اسم معين، ويمكن تمرير بعض المدخلات لها لتغير سلوك الدالة أو نتيجتها (تسمى هذه المدخلات بـ Parameters)، وأيضًا يمكن للدالة إرجاع قيمة return بشكل إختياري، ويمكن إنشائها ضمن أي مجال namespace. التابع Method: تسمى أيضًا "طريقة"، وهي كذلك كتلة من الأكواد لها اسم معين، ولكن يكون التابع موجودًا ضمن كائن Object معين، ولها نفس خواص الدالة من حيث المدخلات التي يمكن تمريرها إليها وإرجاع قيمة كذلك. في بعض اللغات مثل ++C يطلق على التوابع "دوال أعضاء Member Functions"، ويمكن فقط إنشائها ضمن أصناف Classes. بناءً على التعريف السابق، يمكننا القول أن كل التوابع Methods عبارة عن دوال functions، ولكن ليس كل الدوال functions عبارة عن توابع Methods. الإختلافات بين الدالة Function والتابع Method تكمن الإختلافات بين الدالة Function والتابع Method في أن التابع له بعض المميزات الإضافية، مثل: عند إستدعاء تابع Method يتم الإشارة صراحة إلى الكائن الذي يحتويه. يمكن للتابع أيضًا الوصول لخواص الكائن Object والتوابع الأخرى الموجودة فيه (أو أي خواص وتوابع موروثة من صنف أب). مثال بلغة JavaScript عن الفرق بين التابع Method والدالة Function: class User { // getFullName عبارة عن تابع لأنه ضمن صنف Class getFullName() { // ... } } // sum هنا عبارة عن دالة لأنها ضمن المجال العام وليست ضمن صنف معين function sum(x, y) { return x + y; } مثال بلغة PHP: <?php class User { // getFullName عبارة عن تابع لأنه ضمن صنف Class public function getFullName() { // ... } } // sum هنا عبارة عن دالة لأنها ضمن المجال العام وليست ضمن صنف معين function sum($x, $y) { return $x + $y; } ملاحظة: بعض اللغات مثل Java و#C لا تحتويان على دوال Functions لأن اللغة بأكملها تستعمل البرمجة الكائنية OOP، وبالتالي يمكن عمل توابع Methods فقط، على الجانب الآخر لغات مثل C لا تحتوي على أصناف Class وبالتالي لا يمكن عمل توابع Methods فيها وتحتوي فقط على دوال Functions.
  10. يمكن إزالة أي خاصية أو تابع من كائن Object بعدة طريق: إستخدام الكلمة المفتاحية delete // لا يوجد أي فرق بين الطرق التالية delete user.age; // أو delete user['age']; // أو var prop = "age"; delete user[prop]; إستخدام القيمة undefined عند محاولة الوصول إلى خاصية غير موجودة في أي كائن سوف يتم إرجاع undefined ، ويمكننا أن نستخدم هذا الأمر لمحاكاة حذف الخاصية أو التابع من الكائن خاصتنا: user.age = undefined; console.log(user); console.log(user.hasOwnProperty('age')); // true /* { age: undefined, email: 'emad@gmail.com', firstName: 'Emad', lastName: 'Saif', getFullName: ƒ } */ هذه الطريقة سوف تبقى الخاصية أو التابع موجودًا في الكائن لكن بقيمة undefined، بينما إستعمال الكلمة المفتاحية delete سوف يزل الخاصية أو التابع بشكل كامل: delete user.age; console.log(user); console.log(user.hasOwnProperty('age')); // false /* { email: 'emad@gmail.com', firstName: 'Emad', lastName: 'Saif', getFullName: ƒ } */ عمل كائن Object جديد يمكن عمل كائن Object جديد يحتوي على كل الخصائص والتوابع ما عدا التلك التي نريد حذفها: const {age, ...newUser} = user; console.log(newUser.age); // undefined console.log(user.age); // 19 ميزة هذه الطريقة أنها تُبقى على العنصر الأصلي كما هو بدون تغير وتقوم بإنشاء كائن جديد كليًا بالخصائص والتوابع التي نريدها فقط، لكن من عيوبها أنها تقوم بعمل متغيرات جديدة في المجال الحالي، ففي المثال السابق تم إنشاء متغير جديد باسم age بقيمة 19
  11. هذا الأمر مهم في كثير من الحالات، على سبيل المثال بفرض أن لدينا دالة تتحقق مما إذا كان المستخدم كبير كفاية لدخول الصفحة (عمره 18 أو أكبر): function userIsAdult(age) { // في حالة كتب المستخدم رقم أقل من 18 if (age < 18) { console.log("you can not access this page"); // إن لم يتم إيقاف الدالة هنا سوف تكمل العمل } // condition is true console.log("you are an adult"); } // عند تنفيذ الدالة السابقة برقم أقل من 18 userIsAdult(10); /* Output: you can not access this page you are an adult */ لاحظ أن الدالة في المثال السابق إن لم تتوقف في حالة كانت قيمة age أقل من 18 فسوف يتم طباعة كلا الجملتين لأن الدالة سوف تكمل العمل بغض النظر عما إذا كان الشرط مُحققًا أم لا، لذلك علينا إيقاف الدالة إن كان العمر أقل من 18: function userIsAdult(age) { // في حالة كتب المستخدم رقم أقل من 18 if (age < 18) { console.log("you can not access this page"); return; // نوقف الدالة عن العمل هنا في حالة توقف الشرط } // condition is true console.log("you are an adult"); } // عند تنفيذ الدالة السابقة برقم أقل من 18 userIsAdult(10); /* Output: you can not access this page */
  12. أي دالة في JavaScript يجب أن ترجع قيمة بشكل أو بآخر، وإن لم تحتوي الدالة على كلمة return أو لم ترجع قيمة محددة فسوف ترجع undefined بشكل إفتراضي: // الدالة التالية لا تحتوي على return // لذلك يتم إرجاع undefined function test() { } console.log(test()); // undefined والكلمة return يمكنها إرجاع أي قيمة، حتى أنه يمكن إستخدامها لإرجاع دالة جديدة كاملة، وفي حالة لم يتم إعطائها قيمة لإرجاعها، فسوف يتم إرجاع undefined بشكل إفتراضي كذلك: // الكلمة return ترجع undefined في حالة لم يتم تحديد قيمة معينة لإرجاعها function test() { return; } console.log(test()); // undefined ومن المتعارف عليه هو إستخدام return في مثل هذه الحالة لإيقاف الدالة فقط، وليس لإرجاع قيمة معينة.
  13. الكلمة المفتاحية return تستعمل لإرجاع قيمة من الدالة وإيقاف تشغيلها، مثال: // لدينا دالة تقوم بطباعة ضعف أي رقم مُمرر لها function double(num) { console.log(num * 2); } double(5); // سيتم طباعة 10 double(3); // سيتم طباعة 6 double(8); // سيتم طباعة 16 الدالة double السابقة تقوم بطباعة ضعف أي رقم مُدخل إليها (تضرب الرقم في 2 وتطبع الناتج)، لكن ماذا إذا أردنا أن نستخدم ناتج عملية الضرب هذه بدلًا من طباعتها؟ في هذه الحالة لا نستعمل console.log بل نستعمل الكلمة return : // لدينا دالة تقوم بطباعة ضعف أي رقم مُمرر لها function double(num) { return (num * 2); } var result = double(5); console.log("The result is:", result); // The result is: 10 الكلمة return تقوم بإرجاع قيمة وإيقاف تنفيذ الدالة، أي أن أي شيء يأتي بعدها لن يتم تنفيذه: // لدينا دالة تقوم بطباعة ضعف أي رقم مُمرر لها function double(num) { return (num * 2); console.log("Some Content"); // هذا السطر لن يتم تنفيذه لأنه جاء بعد كلمة return } var result = double(5); console.log("The result is:", result); // The result is: 10 لمزيد من المعلومات حول الكلمة المفتاحية return أقرأ فقرة "أرجاع قيمة"، في هذه المقالة: المقالة السابقة جزء من سلسلة "دليل تعلم جافاسكربت"، وهي سلسلة شاملة لكل أساسيات JavaScript وتحتوي على شرح لكثير من الأمور المتقدمة.
  14. الكائن localStorage يقوم بتخزين النصوص Strings فقط، ولكن ما تحاول أن تقوم به هو تخزين كائن Object، ولحل المشكل يجب أن تحول القيمة التي تريد تخزينها إلى نص String، ولذلك نستخدم التابع JSON.stringify للقيام بهذه المهمة: // نحول الكائن إلى نص var data = JSON.stringify({ name : 'mohammed', age : 14 }); console.log(data); // '{"name":"mohammed","age":14}' localStorage.setItem('user', data); ولكي نحول قيمة النص string إلى كائن مرة أخرى نستعمل التابع JSON.parse، على النحو التالي: var data = JSON.parse(localStorage.getItem('user')); console.log(data); /** * Output: { name: 'mohammed', age: 14 } */ لاحظ أنني إستعملت التوابع getItem و setItem ، ولذلك لأنهم أفضل من إضافة الخاصية user إلى الكائن localStorage مباشرة `localStorage.user` ، ومن الأفضل القيام بهذا الأمر دائمًا لكي لا يحدث تعارض مع خصائص الكائن localStorage الأصلية والخصائص التي تضيفها، مثال: // هنا أحاول تخزين خاصية length localStorage.length = "many items"; // الخاصية length من ضمن الخصائص الأصلية للكائن localStorage // وترجع عدد العناصر الموجودة في localStorage console.log(localStorage.length); // 8 على الجانب الآخر عند إستعمال التوابع getItem و setItem لا تحدث هذه المشكلة: localStorage.setItem('length', "many items"); console.log(localStorage.getItem('length')); // "many items"
  15. الشرط في الكود المرفق لا يوجد به أي مشكلة، فتكوين جملة if .. else مصمم ليكون بهذا الشكل تمامًا: if (condition) { // condition is true } else { // condition is false } إن كان ما تريد تنفيذه من هذا الشرط هو تعليمه بسيطة مثل تخزين قيمة في متغير فيمكنك إستعمال المعامل الثلاثي trinity operator كما يلي: // المعامل الثلاثي trinity operator // conditoin ? true : false; const age = 19; var msg = age > 18 ? "you are an adult" : "you are young"; console.log(msg); لكن هناك طرق يمكن تحسين الكود ليكون أفضل وأقل عرضة للأخطاء، على سبيل المثال الكود التالي يقوم بجلب عمر المستخدم من حقل input: <input id="age-input" type="number" /> <button id="submit">submit</button> var submitBtn = document.getElementById("submit"); submitBtn.addEventListener("click", function () { var age = parseInt(document.getElementById("age-input").value); if (age > 0) { // condition is true console.log("condition is true"); } else { // condition is false console.log("condition is false"); } }); إذا قام المستخدم بكتابة عمره فسوف يتم طباعة condition is true ولكن ماذا يحدث إذا كتب صفر 0 ، أو إن ترك المستخدم الحقل فارغًا، أو في حالة كتابة رقم أقل من صفر (رقم سالب)، في هذه الحالة يجب أن نحدد الشرط بشكل أدق: var submitBtn = document.getElementById("submit"); submitBtn.addEventListener("click", function () { var age = parseInt(document.getElementById("age-input").value); if (age > 0) { // condition is true console.log("condition is true"); } else { // condition is false console.log("condition is false"); } }); أيضًا بما أن الكود موجود في دالة function ونريد تنفيذ أما الكود الموجود في جملة if أو الكود الموجود في جملة else، فيمكننا الإستعانه بالكلمة المفتاحية return والإستغناء عن جملة else: var submitBtn = document.getElementById("submit"); submitBtn.addEventListener("click", function () { var age = parseInt(document.getElementById("age-input").value); if (age > 0) { // condition is true console.log("condition is true"); return; } // condition is false console.log("condition is false"); }); بهذا الشكل يكون الكود أوضح من السابق، وما زال بإمكاننا تحسينه أكثر، فمن الأفضل أن نجعل كل شروط التحقق في بداية الدالة، بحيث لا يتم تنفيذ الكود إلا عند تخطي كل الشروط، على النحو التالي: var submitBtn = document.getElementById("submit"); submitBtn.addEventListener("click", function () { var age = parseInt(document.getElementById("age-input").value); if (age <= 0) { // لاحظ الشرط // condition is false console.log("condition is false"); return; } // condition is true console.log("condition is true"); }); ويمكننا إضافة أكثر من شرط في بداية الدالة، مثلًا إذا لم يقم المستخدم بكتابة أي شيء في الحقل: var submitBtn = document.getElementById("submit"); submitBtn.addEventListener("click", function () { var age = parseInt(document.getElementById("age-input").value); // if age equal or is less than 0 if (age <= 0) { // condition is false console.log("condition is false"); return; } // if there is no `age` value if (age !== "") { // condition is false console.log("condition is false"); return; } // main functionality console.log("condition is true"); }); كل هذه المباديء تنتدرج تحت مصطلح الكود النظيف Clean Code ، ويمكنك قراءة المزيد عنه من خلال موسوعة حسوب من هنا، أو من خلال الأسئلة التالية:
  16. نسيان الأكواد والوسوم أمر طبيعي للغاية خصوصُا عندما تدرس لغة برمجة جديدة أو تقنية جديدة، فتجد أنك يمكنك قراءة الأكواد وفهمها بسهولة كبيرة ولكن لا تستطيع كتابتها من الصفر وحدك أو على الأقل بدون الحصول على مساعدة من شخص أو موقع خارجي. هذا الأمر طبيعي للغاية ويمر به أي شخص بدأ في تعلم البرمجة بشكل عام، لذلك لا تقلق فيوجد الكثير من الحلول لهذه المشكلة، وبمرور الوقت ومع كثرة المشاريع لن تنسى أهم الأكواد التي تستعملها بكثرة. حاول تقليد مواقع معروفة: عندما تبدأ بتعلم خصائص ووسوم جديدة حاول أن تستخدمها في عمل صفحات ويب جديدة وأستخدم فيها هذه الخصائص والوسوم الجديدة، على سبيل المثال إن كنت تتعلم عن Flexbox في CSS فحاول عمل الصفحة الرئيسية لموقع Google بإستخدام هذه الخصائص أو حاول عمل شريط تنقل Navbar مثل الموجود في أكاديمية حسوب، أو إن كنت تتعلم إستخدام خصائص Padding في CSS فحاول عمل أزرار Buttons بسيطة وأستخدم فيها هذه الخصائص الجديدة. هذا الأمر مفيد للغاية لأنك ستتدرب بشكل عملي وسيكون بإمكان رؤية نتيجة ما تعلمته. بما أنك تدرس HTML و CSS فحاول أن تقوم بالتلاعب في المواقع التي تستعملها بصورة يومية، على سبيل المثال إن كنت تستخدم Facebook بشكل كبير، فقم بتغير لون خلفية الموقع أو حاول تغير أحجام بعض العناصر أو الخط المستخدم في الموقع، أو حاول تكبير الصور عند المرور عليها بمؤشر الفأرة، هذا الأمر سيسمح لك بالإطلاع على أكواد كتبها أشخاص غيرك، وسيجعلك تعتاد على فهم عمل الأكواد ووظائفها حيث أنك تراها مطبقة بالفعل في مواقع حقيقة. أبحث عن مشاريع صغيرة أنشائها غيرك: حاول البحث عن مشاريع بسيطة قام بعملها مطورين آخرين وأقرأ الكود الخاص بها، وحاول تقليدها، مثلًا ستجد في موقع CodePen العديد من مشاريع HTML و CSS و JavaScript الإحترافية وسوف يذهلك ما ستراه من مشاريع. محاولة تقليد مثل هذه الأشياء سيعطيك القدرة على توظيف ما تتعلمه، وستتعلم تقنيات وخصائص جديدة، ويمكنك بناء معرض أعمال إحترافي مع مرور الوقت. حاول دائمًا البحث عن حل أي مشكلة بنفسك أولًا لكي تطور مهارة البحث لديك ولكي تتعلم أمور جديدة خلال بحثك، على سبيل المثال إن واجهتك مشكلة في توسيط النص في منتصف div فحاول البحث عن خصائص تقوم بهذا الأمر ستجد خاصية text-algin تقوم بهذا وستسمع عن Flexbox وستجد طرق عديدة للقيام بهذه المهمة، وبالتالي ستخرج من عملية البحث هذه بحصيلة من المعلومات مفيدة للغاية.
  17. تستخدم محددات الوصول للتحكم في مسار الكود ولسهولة تتبعه وفهم آليه عمله وبالتالي تكون صيانته وحمايته من الأخطاء أسهل، هنا شرح لمعنى كلٍ منهم: الكلمة المفتاحية public public تعني عام ويمكن الوصول لأي تابع عام public method من داخل جميع التوابع الأخرى الموجودة داخل نفس الصنف وفي حالة الوراثة أو من خلال الكائن المنشأ من هذا الصنف. <?php class User { public function SayHi() { // ... } public function Hello() { $this->SayHi(); // في حالة الوصول إلى التابع من داخل تابع آخر في نفس الصنف } } $user = new User(); // حالة إنشاء كائن من الصنف $user->SayHi(); class Admin extends User { public function Hello() { $this->sayHi(); // في حالة الوراثة } } الكلمة public هي إختيارية ويمكن عدم كتابتها كذلك بدون مشكلة، وأي تابع لم يتم تحديده (public أو private أو protected) فسوف يكون عام public بشكل إفتراضي، لكنها إجبارية في حالة الخواص properties الكلمة المفتاحية private private تعني خاص، فأي تابع يُعرف على أنه خاص لا يمكن إستخدامه إلا داخل الصنف class المعرف بها فقط فلا يمكن الوصول له من خلال كائن منشأ من هذا الصنف وأيضاً لا يمكن الوصول للمكونات الخاصة في حالة الوراثة. <?php class User { private function SayHi() { // ... } public function Hello() { $this->SayHi(); // في حالة الوصول إلى التابع من داخل تابع آخر في نفس الصنف } } $user = new User(); $user->SayHi(); //ERROR: حالة إنشاء كائن من الصنف class Admin extends User { public function Hello() { $this->sayHi(); //ERROR: في حالة الوراثة } } الكلمة المفتاحية protected protected تعني محمي، وهي أعم من الحالة السابقة فأي تابع يُعرف على أنه محمي protected يمكن إستخدامه داخل نفس الصنف وفي حالة الوراثة فقط ولكن لا يمكن الوصول لتوابع الصنف المحمية من خلال الكائن المنشأ من هذا الصنف: <?php class User { protected function SayHi() { // ... } public function Hello() { $this->SayHi(); // في حالة الوصول إلى التابع من داخل تابع آخر في نفس الصنف } } $user = new User(); $user->SayHi(); //ERROR: حالة إنشاء كائن من الصنف class Admin extends User { public function Hello() { $this->sayHi(); // في حالة الوراثة لا يوجد مشكلة } } يمكنك معرفة المزيد من خلال موسوعة حسوب: قابلية الرؤية في كائنات PHP
  18. حرف U هو إختصار لكلمة Untracked أي أن هذا الملف غير مسجل في Git ولن يتم تتبع أي تغيرات تجري عليه، بينما حرف M يعني Modified (أي مُعدل)، ولفهم ما تعنيه هذه الكلمات يجب دراسة Git وهو برنامج يستخدم لإدارة الملفات والمشاريع البرمجة، بحيث يمكن عمل أي تغيرات على الملفات وتسجيلها وإرجاع الملفات إلى الحالة التي كانت عليها قبل التعديلات، ويسمح كذلك بأن يكون أكثر من مبرمج بالعمل على المشروع في نفس الوقت (عبر إستخدام GitHub أو GitLab)، بالإضافة إلى عمل أكثر من فرع Branch (نسخة كاملة من المشروع) للعمل عليها (لأصلاح خطأ معين أو لإضافة ميزة جديدة) بشكل سهل للغاية. إن أردت إخفاء حرف U فعليك أن تقوم بتنفيذ الأمر التالي: git add <اسم الملف> مع تغير <اسم الملف> إلى اسم الملف، مثال: git add App.js الأمر السابق سوف يخبر Git بمراقبة الملف App.js وحفظ أي تغيرات تجري عليه. ملاحظة: يجب التأكد من أنك في مجلد المشروع الصحيح عند تنفيذ الأمر السابق لكي يعمل بشكل سليم. هنا فيديو يشرح أهل الأساسيات الخاصة بـ Git: ويمكنك كذلك الإطلاع على العديد من المقالات الخاصة بـ Git من هنا.
  19. مكتبة React تستعمل لتسهيل العمل على المشاريع الكبيرة من خلال تقسيم المشروع بالكامل إلى مكونات Components وبالتالي يمكن التعامل مع كل مكون على حدى، ويمكن أن يعمل أكثر من مبرمج على نفس المشروع في وقت واحد بشكل أسهل من التعامل مع المشروع في شكل صفحات، فتخيل أنك تقوم بإستعمال زر معين Button في أكثر من مكان وفي أكثر من صفحة، وبعد تطوير المشروع أردت أن تقوم بتغير هذا الزر أو ما يفعله، حيناها سيكون عليك أن تبحث عن كل مكان أستعملت فيه هذا الزر وتقوم بالتعديل عليه، أو على الأقل سوف تتنقل بين ملفات CSS و JavaScript، أما في حالة إستعمال React.js (أو أي مكتبة أو إطار عمل يستعمل نظام المكونات) فستقوم بالتوجه مباشرة إلى ملف معين والتعديل عليه وأنتهى الأمر، وبالتالي تصبح عملية التطوير أسهل وأسرع من ذي قبل. كما يوفر React الكثير من الأشياء التي تسهل عليك عملية التطوير مثل الخطافات Hooks والتي من خلال يمكنك عمل الكثير من الأمور بأسطر بسيطة بدلًا من كتابتها من الصفر، بالإضافة إلى أن React.js يُمكن المبرمد من إنشاء التطبيقات بدون التعامل مع DOM بشكل مباشر، حيث يقوم المبرمج بوصف شكل المكون وما يقوم به (عبر أكواد JavaScript و CSS) ويقوم React بالتعامل مع DOM مما يعطي أفضل أداء ممكن بدون الدخول في تعقيدات لا حاجة لها. هنا مدخل بسيط للتعرف على React.js: وتستطيع الإطلاع على المقالات موجودة في أكاديمية حسوب من هنا، أو قراءة توثيق React باللغة العربية في موسوعة حسوب من هنا.
  20. يمكن عمل توابع ساكنة في لغة JavaScript بأكثر من طريقة: إنشاء التوابع الساكنة Static Methods في الأصناف Classes يمكن إستخدام الكلمة المفتاحية static لعمل تابع ساكن Static Method بالشكل التالي: class User { static hello() { console.log("Hello"); } } User.hello(); // Hello كما يمكن إسناد قيمة جديدة للصنف نفسه بشكل مباشرة على النحو التالي: class User { } User.hello = function() { console.log("Hello"); }; User.hello(); // Hello يمكن الإطلاع على المقالة التالية التي تحتوي على شرح مفصل لهذا الأمر وكيف يتم إنشاء التوابع بإستخدام prototype خلف الكواليس: إنشاء التوابع الساكنة Static Methods في الدوال البانية Constructor Function يمكن عمل توابع ساكنة Static Methods بإستخدام prototype بالشكل التالي: function Foo() { // يمكن إضافة التوابع العادية هنا عبر الكلمة المفتاحية this } Foo.prototype = { staticMethod: function () { return 2 + 3; } }; ويتم إستخدام التابع كما يلي: var sum = Foo.prototype.staticMethod(); console.log(sum); لاحظ أنه يمكن إستخدام نفس الطريقة لعمل توابع عادية instance methods بدون مشكلة: function User() { this.age = 23; } User.prototype = { instanceMethod: function () { // instance method return this.age * 365; }, staticMethod: function () { // static method return 2 + 3; } }; ويتم إستخدامهم بالشكل التالي: var sum = User.prototype.staticMethod(); // 5 var ageInDays = User.prototype.instanceMethod(); // NaN (undefined * 365) var user = new User(); var ageInDays2 = user.instanceMethod(); // 8395 var sum2 = user.staticMethod(); // 5 يمكن عمل دالة لتبسيط هذه العملية وإضافة توابع بشكل مباشر: (function (fn) { fn.bar = function () { return 123; } ; fn.baz = function () { return 456; } ; })( Foo.prototype ); Foo.prototype.bar(); // 123
  21. الفرق بين التوابع الساكنة Static Methods والتوابع العادية التوابع العادية لا يمكن إستخدامها إلا من خلال إنشاء كائن Object (أو instance) من الصنف Class بالشكل التالي: <?php class User { public function SayHi() { echo "Hello World!"; } } $user = new User(); // يجب إنشاء كائن من الصنف $user->SayHi(); بينما التوابع الساكنة Static Methods يمكن إستدعائها مباشرة بدون الحاجة إلى إنشاء كائن جديد: <?php class User { static public function SayHi() { echo "Hello World!"; } } // لا يجب إنشاء نسخة كائن جديد من الصنف User User::SayHi(); // Hello World! لاحظ في الأمثلة السابقة يجب كتابة الكلمة المفتاحية static قبل تعريف التابع لعمل تابع ساكن Static Method، ولا يوجد مشكلة في كتابة كلمة static قبل أو بعد الكلمة المفتاحية public (الكلمة المفتاحية public في حد ذاتها إختيارية) لكن يجب كتابتها قبل الكلمة المفتاحية function، وبالتالي لا يوجد فرق بين أي من التوابع التالية: <?php class User { static public function SayHi() { echo "Hello World!"; } public static function SayHi2() { echo "Hello World!"; } static function SayHi3() { echo "Hello World!"; } } // لا يجب إنشاء نسخة كائن جديد من الصنف User User::SayHi(); // Hello World! User::SayHi2(); // Hello World! User::SayHi3(); // Hello World! أيضًا لاحظ أن التوابع الساكنة Static Methods يتم إستدعائها من خلال العلامة :: بينما التوابع العادية تستخدم <- على النحو التالي: <?php $user->sayHi(); User::sayHi(); ملاحظة: لا يمكن استخدام المتغير الزائف ‎$this داخل التوابع الساكنة وذلك لأنّ هذه التوابع قابلة للاستدعاء دون الحاجة إلى إنشاء نسخة من الكائن. إستعمال أكثر من نوع من التوابع معًا يمكن أن يحتوي الصنف الواحد على توابع عادية وتوابع ساكنة معًا بدون مشكلة: <?php class greeting { public static function welcome() { echo "Hello World!"; } public function __construct() { self::welcome(); } } new greeting(); // "Hello World!" أيضًا لاحظ أنه يمكن إستدعاء التوابع الساكنة Static Methods من داخل نفس الصنف (في توابع أخرى) من خلال الكلمة المفتاحية self كما في المثال السابق. أيضًا يمكن إستدعاء تابع ساكن Static Method موجود في صنف أب من داخل صنف ابن على النحو التالي: <?php class User { protected static function sayHi() { return "Hello, World!"; } } class Admin extends User { public $hello; public function __construct() { $this->hello = parent::sayHi(); } } $admin = new Admin(); echo $admin -> hello; في المثال السابق يوجد تابع ساكن موجود في الصنف User (الصنف الأب) بينما الصنف الابن Admin يستدعي التابع sayHi الموجود في الصنف الأب مباشرة عبر الكلمة المفتاحية parent. متى يتم إستعمال التوابع الساكنة Static Methods يتم إستعمال التوابع الساكنة في حالات قليلة، منها: يمكن عمل صنف واحد يحتوي فقط على توابع ساكنة تقوم بأداة مهام متشابهة (أو تختص بأمر معين مثل إدارة الملفات على سبيل المثال). وفي هذه الحالة يمكن إعتبار التوابع الساكنة مجرد دوال عادية لكن موجودة في Namespace معين (وهو الصنف Class). يمكن إستخدامها في عمل Service وهي طريقة لترشيد التعليمات البرمجية الخاصة بك. يسمى هذا النوع من الهندسة المعمارية SOA (بنية موجهة للخدمة). فتخيل أن لديك متجر إلكتروني ويجب عمل صنف SaleHandler والذي يحتوي على كل الدوال التي يجب إستخدامها في التلاعب ببيانات مبيعة معينة (في قاعدة البيانات مثلًا)، في هذه الحالة سيكون من الأفضل أن يحتوي الصنف SaleHandler على توابع ساكنة Static Methods إن كنت تستعمل إطار عمل Framework مثل لارافيل Laravel فستجد أنه يتم إستعمال التوابع الساكنة في أكثر من مكان مثل عمل المسارات Routes أو توابع التعامل مع النصوص String. يمكنك معرفة المزيد عن التوابع الساكنة Static Methods وفائدتها من خلال موسوعة حسوب من هنا.
  22. تأكد من أنك قمت بتنفيذ الأمر التالي: heroku git:remote -a yourapp أيضًا عندما تقوم بعمل push يجب أن تكون في مجلد المشروع الرئيسي (أي لا تقوم بالدخول إلى مجلدات فرعية عبر الأمر cd لأن هذا سيسبب خطأ). إن أستمرت المشكلة حاول تنفيذ الأمر التالي وتأكد من أن تكون النتيجة صحيحة: git remote get-url heroku // نتيجة تنفيذ الأمر السابق كالتالي https://git.heroku.com/app-name.git إن ظهر لك الخطأ error: No such remote 'heroku فقم بتنفيذ الأمر التالي: git remote add heroku https://git.heroku.com/app-name.git git push heroku main مع تغير قيمة app-name باسم المشروع الخاص بك.
  23. هذه مشكلة في موقع Heroku نفسه حاول أن تستخدم git مع heroku cli لرفع ملفات المشروع مباشرة إلى Heroku بدلًا من ربط مستودع GitHub، من خلال الخطوات التالية: في البداية قم بتحميل الأداة من هنا (أتبع إرشادات التثبيت الخاصة بنظام التشغيل خاصتك)، وبعد تحميل وتثبيت الأداة قم بتنفيذ الأمر التالية في مجلد المشروع: heroku login سيقوم الأمر التالي بفتح صفحة تسجيل الدخول في موقع Heroku في المتصفح، وبعد إتمام عملية تسجيل الدخول قم بتنفيذ الأوامر التالية في مجلد المشروع: heroku git:remote -a <app-name> git add . git commit -am "make it better" git push heroku main مع تغير <app-name> إلى اسم المشروع الخاص بك على Heroku وبعد عملية رفع الملفات سوف يقوم Heroku بتثبيت حزم المشروع وتشغيله بشكل مباشرة.
  24. وعليكم السلام ورحمة الله وبركاته من المعروف أن لغة Python لغة محبوبة لسهولة صيغة الكود الذي يكتبه المبرمج مما يقلل عدد الأخطاء ويزيد من الإنتاجية، ولذلك تُستعمل في كثير من المشاريع المختلفة الكبيرة، وفي نفس الوقت لغة JavaScript تُعتبر أكثر لغة غنية بالمكتبات والإضافات التي تُسهل على المبرمج عمله، كما أنها تعمل في كل مكان تقريبًا ( الواجهات الأمامية Frontend, الواجهات الخلفية Backend تطبيقات الجوال Mobile Apps , تطبيقات سطح المكتب Desktop Apps ... إلخ)، وكلا اللغتين مطلوبين بشدة في سوق العمل العالمي والعربي. بالنسبة للتشتت بين إستخدام Flask أو Node.js (مع أي مكتبة مثل Express.js) فستجد أن هناك الكثير من المفاهيم المشتركة بينهما مثل المسارات Routes، والبرمجيات الوسيطة Middleware وحتى في طريقة تقسيم المشروع، وفي كلا الإختيارين سوف تصل إلى نفس النتيجة، لكن مع ذلك يبقى الإختيار الأخير عليك، فأنت من سيعمل لفترات طويلة بإستخدام أحدهما، فإن لم تكن تحب إستخدام JavaScript فسوف تجد صعوبة في كتابة أكواد المشاريع، وبما أن لديك خبرة بالفعل في Flask و Python فمن الأفضل أن تكمل بهما، على الأقل حتى تتعلم كل الأساسيات الخاصة بالواجهات الخلفية Backend مثل إنشاء API والتعامل مع قواعد البيانات، وعمل نظام إستيثاق Authentication System وبمجرد إتقان هذه الأمور سوف يكون بمقدروك الإنتقال إلى أي تقنية مشابهة مثل Node.js+ Express.js أو Laravel + PHP أو غيرهم، وفي النهاية سوف يكون لديك خبرة في الواجهات الخلفية ومعرفة جيدة في أكثر من تقنية. أيضًا تعلم Flask وأساسيات الواجهات الخلفية سوف يؤهلك لتعمل إطار عمل أكبر مثل جانغو Django والذي يستخدم في عمل مواقع ضخمة مثل Instagram على سبيل المثال. أما بالنسبة لسوق العمل فيمكنك أن تقوم بتصفح مواقع العمل الحر مثل مستقل وخمسات وحاول قراءة مشاريع الواجهات الخلفية Backend أو مشاريع الويب عمومًا، لترى حجم الطلب على هذه التنقيات في سوق العمل الحر العربي، وبما أن اللغتين -Python - JavaScript - مطلوبتين في سوق العمل بشكل عام، فيمكنك أن تتطور مهاراتك فيهما لكي تزيد من قدرتك على المنافسة.
  25. يمكن القيام بتحويل ملف excel إلى PDF بعدة طرق Microsoft Office إن كنت تستخدم Microsoft Office فعليك الضغط على قائمة FIle، ثم Print وإختيار Microsoft Print to PDF كما في الصورة: بعد ذلك أضغط على زر Print (رقم 3 في الصورة السابقة) وأختر مكان واسم لحفظ الملف فيه. Google Sheets إن لم يكن لديك Microsoft Office أو تريد طريقة أخرة لتحويل الملف إلى PDF (حتى على الهاتف) فيمكنك أن تستخدم Google Sheets، كل ما عليك هو رفع الملف وفتحه ومن قائمة File أختر Download ثم PDF: وسيتم تحميل ملف بصيغة PDF
×
×
  • أضف...