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

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

  1. Sam Ahw

    Sam Ahw

    الأعضاء


    • نقاط

      5

    • المساهمات

      1388


  2. Wael Aljamal

    Wael Aljamal

    الأعضاء


    • نقاط

      4

    • المساهمات

      6975


  3. Hoida Ahamed

    Hoida Ahamed

    الأعضاء


    • نقاط

      4

    • المساهمات

      86


  4. Ahmed Sharshar

    Ahmed Sharshar

    الأعضاء


    • نقاط

      4

    • المساهمات

      348


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

المحتوى الأعلى تقييمًا في 08/09/21 في كل الموقع

  1. هل الدروس منظمة من اساس الموضوع الى النهاية ام لا اتمنى الاجابة
    2 نقاط
  2. يُمكنك إستخدام التحميل الحثيث المتداخل بالشكل التالي: <?php Exam::with(['teacher', 'teacher.profile', 'subject']) ->where('level_id', $request->level) ->select('id', 'subject_id', 'teacher_id', 'created_at') ->get(); كما قد نرغب أحياناً في التحديد او عمل شروط معينة على العلاقة نفسها فنُمرر مصفوفة للتابع with حيث المفتاح هو إسم العلاقة والقيمة تكون عبارة عن closure نحدد فيها ما نرغب به بهذا الشكل مثلاً: <?php Exam::with(['teacher' => function ($query) { $query->with('profile'); }, 'subject']) ->where('level_id', $request->level) ->select('id', 'subject_id', 'teacher_id', 'created_at') ->get(); في هذه الحالة نرغب بتحميل العلاقة أيضاً لكن في حالات أخرى نكون بحاجة لعمل شروط على حقول العلاقة فالطريقة الثانية تساعد في مثل هذه الحالات.
    2 نقاط
  3. يمكن المقارنه بين بيانات من نوع String String x,y; if(x=="y"); S.O.P(10); هذه الطريقه خاطئه مامن طريقه اخرى
    2 نقاط
  4. سنتحدث في هذا المقال عن مفهوم العلاقات بين جداول قاعدة البيانات، وما أنواع هذه العلاقات وكيف تتمثل وما هو أثرها على العمل. ما هي العلاقات بين الجداول عند إنشاء جداول في قاعدة البيانات، فإن الظاهر لنا أننا نقوم ببناء جداول منفصلة وغير مترابطة، ولكننا في الواقع العملي نحتاج لربط هذه الكيانات المنفصلة بحيث تُبنَى علاقات تحكم البيانات الموجودة في هذه الجداول، وتحكم طريقة التعامل مع هذه البيانات. تنشَأ العلاقة بين جدوليْن عندما يُربط عمودان فيهما مع بعضهما عن طريق وجود قيود مطبقة على العمودين، بحيث يكون قيد المفتاح الرئيسي على عمود في الجدول “الأب” وقيد المفتاح الأجنبي على العمود في الجدول “الابن”، وعادة يكون اسم العمودين واحدًا في كلا الجدولين. مثلا، لحفظ عناوين الأشخاص نستطيع إنشاء جدول باسم Address ونربطه بجدول الأشخاص Persons بعلاقة تحكم البيانات الموجودة في الجدولين، بحيث يكون لكل شخص في الجدول Persons عنوان واحد مرتبط به في الجدول Address. يُربَط الجدولان عن طريق عمود باسم Person_Id في كلا الجدولين. مثال آخر، لو أردنا أن نتابع عملية استعارة الكتب في مكتبة، فإننا سننشئ جدولًا باسم Borrowed_Books (كُتُب مُعارة) ونربطها بالجدول Persons عن طريق العمود Person_Id. يستطيع الشخص الواحد - في هذا النوع من الربط - أن يستعير أكثر من كتاب. في هذا المثال، لو أننا حفظنا بيانات الأشخاص والكتب المستعارة في جدول واحد، ستظهر لنا مشكلة تكرار البيانات Data Redundancy لأننا سنكرّر بيانات الشخص لكل كتاب يستعيره. ماذا نستفيد من بناء العلاقات بين الجداول؟ التخلص من مشكلة تكرار البيانات عن طريق فصلها وحفظها في أكثر من جدول، فمشكلة تكرار البيانات هي عدو مستخدمي قواعد البيانات ومسؤوليها، لأنها تتسبب بزيادة حجم قاعدة البيانات بقدر كبير وبسرعة، وترفع السرعات المطلوبة لتنفيذ الاستعلامات، وتجعل من موضوع صيانة قاعدة البيانات كابوسا مقلقا. الحفاظ على دقة وسلامة البيانات في قاعدة البيانات، فمع وجود العلاقات بين الجداول، سوف تضمن مثلا عدم وجود كتاب مُعار ليس له شخص استعاره، أو عنوان وهمي ليس له صاحب، وقس على ذلك العديد من الأمثلة. استخراج البيانات من أكثر من جدول بكفاءة وسرعة عن طريق بناء جمل ربط استعلامية تطلب المعلومات من أعمدة مختلفة في جداول مختلفة، وإخراج النتيجة بطريقة مفيدة ومرتبة. أنواع العلاقات توجد أربعة أنواع من العلاقات بين الجداول كالتالي: علاقة واحد إلى واحد (One-to-One). علاقة واحد إلى كثير أو علاقة كثير إلى واحد (One-to-Many / Many-to-One). علاقة كثير إلى كثير (Many-to-Many). علاقة المرجعية الذاتية (Self Referencing). علاقة واحد إلى واحد لنفترض أن الجدول Persons لديه البنية والبيانات التالية: Person_ID First_Name Last_Name Age Address 101 Ibrahim Mohammed 31 12 Main St, Doha 102 Mohammed Khaled 25 Gaza, Middle Center نستطيع أن نضع بيانات العنوان في جدول منفصل ونسميه Address وتكون بنية الجدوليْن كالتالي. الجدول Persons: Person_ID First_Name Last_Name Age Address_Id 101 Ibrahim Mohammed 31 1 102 Mohammed Khaled 25 2 الجدول Address: Address_ID Address 1 12 Main St, Doha 2 Gaza, Middle Center لاحظ أنه أصبح لدينا عمود بنفس الاسم Address_Id في كلا الجدولين. لبناء العلاقة بين الجدولين، طبّقنا قيد المفتاح الأجنبي على العمود Address_Id في الجدول Persons بحيث يأخذ قيمه من العمود Address_Id في الجدول Address والمطبق عليه قيد المفتاح الرئيسي. أصبحت لدينا الآن علاقة بين الجدولين، وفي حال كان كل عنوان في الجدول Address يقترن فقط بشخص واحد في الجدول Persons فعندها نسمي هذه العلاقة واحدًا إلى واحد. يجب التنويه إلى أن هذا النوع من العلاقات غير مستخدم كثيرا، فالجدول الأول الذي يحتوي العنوان وبيانات الشخص يفي بالغرض في أغلب الأحيان. نستطيع تمثيل العلاقة بالشكل التالي: لاحظ أن وجود العلاقة اختياري، فمن الممكن أن يكون لدينا سجل في الجدول Persons دون عنوان له في الجدول Address وهذا مرتبط بعدم تطبيق قيد القيمة غير الفارغة على العمود Address_Id. في حال طُبِّق قيد غير القيمة غير الفارغة على العمود، فهنا تصبح العلاقة واجبة بين الجدولين، ولا يمكن أن نُنْشئ سجلًّا في الجدول Persons إلا بإدخال قيمة موجودة للعمود Address_Id وهو في مثالنا هذا غير منقطي نوعا ما. دورة علوم الحاسوب دورة تدريبية متكاملة تضعك على بوابة الاحتراف في تعلم أساسيات البرمجة وعلوم الحاسوب اشترك الآن علاقة واحد إلى كثير أو علاقة كثير إلى واحد هذا النوع من العلاقات هو الشائع بين أنواع العلاقات بين الجداول في قاعدة البيانات، لوجود تطبيقات كثيرة عليه، فمثلا: الطالب (واحد) يستطيع أن يدرس أكثر من مساق (كثير). الطبيب يعالج ويتابع حالة مريض واحد أو أكثر. طلبية الشراء تحتوي على أكثر من عنصر. الشخص يستعير أكثر من كتاب. وقس على ذلك العديد من الأمثلة. لنفترض وجود جدول للزبناء Customers بالهيكلية التالية: Customer_ID Customer_Name 1 Ibrahim Mohammed 2 Mohammed Ahmed نستطيع ربط جدول الزبناء السابق بجدولٍ للطلبيات Orders بعلاقة واحد إلى كثير، لتعبر العلاقة عن الطلبيات التي قام بها العملاء وقيمة كل طلبية وتاريخها. يمكن أن تكون هيكلية الجدول Orders كالتالي: Order_ID Customer_ID Order_Date Order_Value 997 101 1/5/2017 100 998 102 21/4/2016 150 999 101 21/4/2015 1500 تسمح هذه العلاقة للعميل بأن يطلُب طلبيةً أو أكثر، ويمكن ألا تكون له أية طلبية. ولكنّ كل طلبية في الجدول Orders ستكون تابعة لعميل واحد. ونستطيع تمثيل هذه العلاقة بالشكل التالي: علاقة كثير إلى كثير في علاقة كثير إلى واحد، تكون العلاقة مبنية على أن يكون أحد أطرافها “واحدًا”، مثل طالب واحد، عميل واحد، طلبية واحدة، وفي الطرف الثاني “كثير”. نحتاج أحيانا أن يكون طرفا العلاقة كثيرين. فمثلا، قد تكون لدينا طلبية تحتوي أكثر من عنصر، ونفس العنصر يكون متواجدًا في أكثر من طلبية. في هذه الحالة نحتاج لوجود جدول إضافي لبناء العلاقة، فمثلا تكون هيكلية جدول Orders كالتالي: Order_ID Customer_ID Order_Date Order_Value 997 101 1/5/2017 100 998 102 21/4/2016 150 999 101 21/4/2015 1500 وهيكلية جدول Items كالتالي: Item_Id Item_Name Item_Description 201 Hard Disk 1 1 Tera SSD Hard 202 Mouse Microsoft Optical Mouse 203 LCD 42 42” LCD نستطيع بناء علاقة كثير إلى كثير بين الجدولين السابقين بإضافة جدول ثالث يحلّ مكان الرابط وغرضه الوحيد هو بناء هذا النوع من العلاقات. نطلق عليه مثلا الاسم Orders_Items، ويكون بالهيكلية التالية: Order_Id Item_Id 997 201 997 202 999 201 999 202 999 203 998 203 يمثّل الشكل التالي علاقة كثير إلى كثير كما تظهر في الجدول Orders_Items: علاقة المرجعية الذاتية يُبنى هذا النوع من العلاقات عندما نريد أن نبني علاقة بين جدول ونفس الجدول، وأوضح مثال على هذا النوع من العلاقات هو جدول الموظفين الذي يحتوي على عمود رقم الموظف المسؤول، حيث يمكن ربط كل موظف بموظف آخر (مدير أو مسؤول) من نفس الجدول. فمثلا، لو كان لدينا جدول باسم Employees خاص بحفظ بيانات الموظفين، ستكون هيكليته على النحو التالي لتطبيق علاقة مرجعية ذاتية عليه: Employee_ID Employee_Name Manager_Id 100 Ibrahim Elbouhissi 101 Khaled Saber 100 102 Yasmeen Hadi 100 103 Duaa Yousef 101 104 Sami Saber بعلاقة المرجعية الذاتية، من الممكن أن يكون للموظف مسؤولًا أو لا يكون، ومن الممكن أن يكون الموظف مسؤولا عن موظف أو أكثر، ويمكن تمثيل العلاقة بالشكل التالي.
    1 نقطة
  5. مدخل إلى البيانات وأنواعها: أنواع البيانات الأساسية يحتاج أي عمل إبداعي إلى ثلاثة مكونات أساسية هي: الأدوات التي يُنجَز بها، والخامات التي يتكون منها، والأساليب والتقنيات التي تُستغل الأدوات والخامات بها لإنجاز ذلك العمل، فأدوات الرسم مثلًا هي الفرش والأقلام ولوحات الرسم، كما أن من أساليب الرسم الخلط والرش وغيرها، ثم تأتي الخامات التي هي الدهانات والأوراق والماء ونحو ذلك. وبصورة مماثلة نجد أن أدوات البرمجة هي لغات البرمجة ونظم التشغيل وعتاد الحواسيب التي ستعمل عليها البرامج؛ أما الأساليب والتقنيات فهي هياكل البرامج التي تحدثنا عنها في المقال السابق، والخامات هي البيانات التي نعدل فيها ونعالجها، وهي ما سننظر فيه في هذا المقال. هذا المقال طويل بسبب طبيعة البيانات نفسها، لكننا كتبناه بحيث لا تجب قراءته كله من أجل إدراك الفهم الكامل للبياناتوتستطيع البدء فيه من البداية التي نمر فيها على الأنواع البسيطة للبيانات. البيانات Data من المعلوم بالمشاهدة في عالم البرمجة أن البيانات هي أكثر المصطلحات المستخدمة حاليًا، رغم قلة من يفهمها على حقيقتها، وما يهمنا في هذه السلسلة في موضوع تعريف البيانات نفسها؛ هو أن تعلم أنها الحقائق أو الأرقام التي يمكن استخلاص النتائج والمعلومات المفيدة منها، ورغم أن هذا يكاد يكون تسطيحًا لمفهومها، إلا أنه يعطينا نقطةً نبدأ منها على الأقل، وسنرى فيما يلي إن كنا نستطيع توضيح ذلك بالنظر في كيفية استخدام البيانات في البرمجة. البيانات هي تلك المعلومات الخام التي يعدّل فيها البرنامج ويغيرها، فلا تستطيع البرامج تنفيذ أي وظيفة ولا مهمة ذات قيمة بغير تلك البيانات، وتتوقف أنواع التعديلات التي تجريها البرامج على البيانات على تلك الأنواع نفسها، فكل نوع له عدد من العمليات التي يمكن إجراؤها عليه، فقد رأينا مثلًا أننا نستطيع جمع الأعداد معًا، إذ تحدث عملية الجمع على النوع العددي من البيانات، مما يعني أن البيانات تأتي في عدة صور وأشكال، وسننظر في كل نوع من أشهر تلك الأنواع، إضافةً إلى العمليات المتاحة على ذلك النوع. المتغيرات Variables تخزَّن البيانات في ذاكرة الحواسيب، ويمكن تشبيه تلك الذاكرة بذاكرة مكاتب البريد القديمة، إذ توضع صناديق صغيرة على حوائط تلك المكاتب لتصنيف الرسائل البريدية، ويجب كتابة الوجهة التي تُرسَل إليها رسائل كل صندوق على الصندوق نفسه، إذ لا قيمة للرسائل من دون وجهة تُرسل إليها، وهنا نُسقط مثالنا على البرمجة، إذ إن المتغيرات هي العناوين التي تكتَب على الصناديق داخل ذاكرة الحاسوب. بهذا نكون قد عرفنا نوع البيانات الآن، لكننا لا نستطيع تعديلها قبل أن تكون لنا صلاحية الوصول إليها، وهذه هي وظيفة المتغيرات، فنحن ننشئ نسخًا من أنواع البيانات ونسندها إلى المتغيرات، والنسخة instance هي مجرد جزء من البيانات وليكن 3 أو 5 مثلًا، وهي نُسخ لأعداد؛ أما المتغير فهو إشارة إلى منطقة محددة في ذاكرة الحاسوب تحتوي على البيانات. قد تتطلب بعض لغات البرمجة أن يُصرَّح عن المتغير declared ليطابق نوع البيانات التي يشير إليها، فإذا حاولنا إسناد نوع خاطئ من البيانات إليه، فسنحصل على خطأ، ويفضل بعض المبرمجين ذلك النوع المسمى بالكتابة الثابتة static typing، لأنه يحول دون ارتكاب الزلات البرمجية bugs الدقيقة التي يصعب اكتشافها، على أن جميع اللغات التي نستخدمها هنا مرنة إلى الحد الذي نستطيع معه إسناد أي نوع من البيانات إلى المتغيرات، وهو ما يُعرف بالكتابة الديناميكية dynamic typing. تتبع أسماء المتغيرات قواعدًا محددةً تختلف باختلاف لغة البرمجة التي تستخدمها، فلكل لغة قواعدها للأحرف التي يُسمح أو لا يُسمح بها، كما تشترط بعض اللغات مثل جافاسكربت وبايثون أن ينتبه المبرمج إلى حالة الأحرف التي يكتبها، بحيث تختلف python عن Python مثلًا، كما توجد لغات أخرى مثل VBScript لا تهتم لهذا، لكن يفضل أن يُتبَّع أسلوب ثابت في تسمية المتغيرات لتجنب الأخطاء الشائعة عند الانتقال من لغة لأخرى، ومن الأساليب المستخدمة في تسمية المتغيرات هو بدء اسم المتغير بحرف صغير، ثم استخدام حرف كبير لبداية كل كلمة تالية في اسمه، كما يلي: aVeryLongVariableNameWithCapitalisedStyle لن نتحدث هنا عن القواعد التي تحكم المحارف المسموح بها في لغات البرمجة التي سنستخدمها، لكن إذا كنت تستخدم الأسلوب الذي في المثال؛ فستجنب نفسك كثيرًا من المشاكل في هذا الشأن. ومن الأساليب المستخدمة في تسمية المتغيرات أيضًا فصل الكلمات في اسم المتغير بشرطة سفلية، كما في another_variable_name؛ أما في لغة بايثون فيأخذ المتغير نوع البيانات المسندة إليه، ويحتفظ بهذا النوع ويحذرك إذا حاولت خلط البيانات بطرق تختلف عنه، كأن تحاول إضافة سلسلة نصية إلى عدد مثلًا، وهي نفس حالة المثال الذي عرض لنا رسالة الخطأ في المقال السابق، ويمكن تغيير نوع البيانات التي يشير إليها المتغير عن طريق إعادة الإسناد إلى المتغير reassigning. >>> q = 7 # عددًا الآن q صار >>> print( q ) 7 >>> q = "Seven" # ليكون سلسلة نصية q أعد إسناد >>> print( q ) Seven لاحظ أن المتغير q ضُبط ليشير إلى العدد 7 ابتداءً، وقد حافظ على تلك القيمة إلى أن جعلناه يشير إلى سلسلة المحارف "Seven"، وعلى هذا نستنتج أن متغيرات بايثون تحافظ على النوع الذي تشير إليه، لكننا نستطيع تغيير ذلك عن طريق إعادة الإسناد إلى المتغير، وتلك هي الكتابة الديناميكية التي ذكرناها قبل قليل. ويمكن التحقق من نوع المتغير باستخدام الدالة type()‎ كما يلي: >>> print( type(q) ) <class 'str'> تُفقد البيانات الأصلية عند إعادة الإسناد، وتمسحها بايثون من الذاكرة ما لم يكن ثمة متغير آخر يشير إليها، وهذا المحو يُعرف باسم جمع المهملات Garbage Collection، والذي يمكن تشبيهه بموظف غرفة البريد الذي يأتي مرةً واحدةً كل فترة ويزيل أي طرود في صناديق البريد لا توجد عليها ملصقات، فإذا لم يستطع العثور على مالك لها أو لم يوجد عنوان على الطرد؛ فسيرميها في المهملات. لننظر الآن في بعض الأمثلة على أنواع البيانات. متغيرات جافاسكربت و VBSCript تختلف جافاسكربت عن أختها VBScript قليلًا في طريقة استخدام المتغيرات، فكلاهما ترى وجوب التصريح عن المتغير قبل استخدامه، وهي خاصية تشترك فيها اللغات المصرَّفة compiled مع اللغات ذات الكتابة الثابتة statically typed، بل حتى في اللغات الديناميكية مثل تلك التي نستخدمها، حيث نستفيد من التصريح عن المتغيرات في حالة حدوث خطأ إملائي عند استخدام متغير، إذ سسيدرك المترجم أن متغيرًا غير معروف قد استُخدم، وسيرفع خطأً؛ أما عيب هذا الأسلوب فهو الحاجة إلى مزيد من الكتابة من قِبل المبرمج. VBScript يصرَّح عن المتغير في لغة VBScript باستخدام التعليمة Dim، وهي اختصار لكلمة Dimension أو بُعد، وهي إشارة إلى الجذور الأولى للغة VBScript في لغة BASIC ولغات التجميع من قبلها، حيث كان يجب علينا إخبار المجمِّع بكمية الذاكرة التي سيستخدمها المتغير -أو أبعاده-، وظل الاختصار موجودًا حتى الآن. ويبدو التصريح عن المتغير في VBScript كما يلي: Dim aVariable نستطيع بمجرد التصريح عن المتغير أن نعين قيمًا له كما فعلنا في بايثون، ويمكن التصريح عن عدة متغيرات في تعليمة Dim واحدة بسردها جميعًا مع فصلها بفواصل إنجليزية "," كما يلي: Dim aVariable, another, aThird ويبدو الإسناد بعدها كما يلي: aVariable = 42 another = "هذه جملة قصيرة." aThird = 3.14159 قد نرى كلمةً مفتاحيةً أخرى هي Let، وهي من جذور BASIC أيضًا، لكننا لن نراها إلا نادرًا لقلة الحاجة إليها، وهي تُستخدم كما يلي: Let aVariable = 22 ولن نستخدمها على أي حال في هذه السلسلة. جافاسكربت نستطيع التصريح عن المتغيرات مسبقًا في جافاسكربت باستخدام الكلمة var، كما يمكن التصريح عن عدة متغيرات كما في VBScript في تعليمة var واحدة: var aVariable, another, aThird; كما تسمح جافاسكربت بتهيئة -أو تعريف- المتغيرات مثل جزء من تعليمة var، كما يلي: var aVariable = 42; var another = "A short phrase", aThird = 3.14159; يوفر هذا قليلًا من وقت الكتابة، لكنه لا يختلف عن أسلوب VBScript مع المتغيرات والمكون من خطوتين. يمكن التصريح عن متغيرات جافاسكربت وتهيئتها من غير استخدام var، بنفس الطريقة المتبعة في بايثون: aVariable = 42; غير أن المتعصبين لجافاسكربت يرون أن استخدام var أفضل، لذا سيكون هذا أسلوبنا في هذه السلسلة أيضًا. نأمل أن تكون تلك النبذة المختصر عن متغيرات جافاسكربت وVBScript قد أوضحت الفرق بين التصريح عن المتغيرات وبين تعريفها، أما متغيرات بايثون، فتعريفها يعني ضمنيًا التصريح عنها كذلك. أنواع الكتابة: صارمة أم متغيرة أم ثابتة لقد أشرنا إلى الكتابة الثابتة والديناميكية فيما سبق من المقال، وتوجد أنواع أخرى من الكتابة مثل الكتابة الصارمة strict -أو القوية أحيانًا أخرى-، والكتابة الفضفاضة loose أو الضعيفة، وسنحاول هنا أن نوضح الاختلافات بينها. تُنشأ المتغيرات مثل أنواع بيانات مرنة أو ثابتة، ويقال أن النوع الثابت مكتوب كتابةً ثابتةً أي أنه لا يتغير أبدًا-، أما المتغير الذي قد يشير إلى عدة أنواع من البيانات فيُكتب ديناميكيًا، لذا تشير البيانات الثابتة والديناميكية إلى أنواع البيانات التي يمكن تخزينها داخل المتغير. ويمكن دمج المتغيرات في العمليات المختلفة عند البرمجة، حيث ستتطلب كل عملية احتواء متغيراتها على أنواع بعينها، مثل الأعداد أو المحارف، فإذا رفضت اللغة السماح لعملية ما باستخدام أنواع خاطئة؛ فسيقال أن هذا النوع من الكتابة كتابةٌ صارمة. تحاول بعض اللغات إجبار القيم على الأنواع الصالحة المسموح بها، بينما تسمح لغات أخرى بأي نوع ثم تفشل العملية وتخرِج خطأً، وتلك هي الكتابة الفضفاضة، وعلى هذا تشير كل من الكتابة الصارمة والفضفاضة إلى أسلوب التحقق من أنواع المتغيرات المستخدَمة في العمليات، وبالنسبة للغات التي سنستخدمها في هذه السلسلة، فجميعها تستخدم كتابةً ديناميكيةً قويةً. الأنواع الأساسية للبيانات تسمى أنواع البيانات الأساسية primitive data types بهذا الاسم لأنها أبسط أنواع البيانات التي يمكن معالجتها والتعامل معها، أما الأنواع الأعقد من البيانات فما هي في الواقع إلا تجميعات من الأنواع الأساسية، فهي اللبنات الأساسية التي تكوَّن منها جميع الأنواع الأخرى، وبناءً عليه تكون هي أساس الحوسبة كلها، وتشمل الأنواع الأساسية الأرقام والأحرف ونوعًا آخر اسمه النوع البولياني boolean type. سلاسل المحارف Strings لقد رأينا هذه السلاسل من قبل، وهي أي سلسلة من المحارف التي يمكن طباعتها على الشاشة، وقد توجد فيها محارف تحكم لا تُطبع ولا تُرى على الشاشة. تُعرض تلك السلاسل في صورة أحرف، لكن الحاسوب يخزنها في صورة تسلسلات من الأرقام، ويطلق على ربط تلك الأرقام بالمحارف اسم الترميز encoding، وتوجد العديد من الترميزات المختلفة، رغم أن المنتشر حاليًا منها هو واحد من ثلاثة ترميزات معرَّفة بواسطة معيار الترميز الموحد Unicode Standard، وسننظر في الترميز الموحد أو اليونيكود في مقال لاحق، لكن يجب أن تعلم أن غرضه توفير مخطط ترميز يمثل أي حرف من أي أبجدية في أي مكان في العالم، إضافةً إلى المحارف الخاصة التي تحتاجها الحواسيب مثل الأقواس والتحكم والتهريب وغيرها. لن نعير هذا الترميز كثير الانتباه أثناء العمل، لكن قد نحتاج إلى التحويل بين الرموز الرقمية والأحرف، كما في مشكلة الاقتباسات في مثال VBScript من المقال السابق. ويمكن تمثيل السلاسل النصية في بايثون بعدة طرق: باستخدام علامات اقتباس مفردة: 'هذه سلسلة نصية' أو باستخدام علامات اقتباس مزدوجة: "وهذه سلسلة نصية تشبهها" أو بعلامات اقتباس ثلاثية مزدوجة: """ أما هذه فسلسلة نصية أطول ونستطيع إطالتها وتقسيمها على ما نشاء من الأسطر وستحافظ بايثون على هذه الأسطر """ يُستخدم النوع الأخير في إنشاء توثيقات لدوال بايثون التي ننشئها بأنفسنا كما سنرى في مقال تال، ويمكن استخدام علامات اقتباس ثلاثية مفردة، لكننا لا ننصح بهذا، إذ قد يصعب تحديد ما إذا كانت العلامات ثلاثيةً مفردةً أم علامةً مزدوجةً داخل أخرى مفردة. نستطيع الوصول إلى المحارف المنفردة في السلسلة النصية بمعاملتها مثل مصفوفة من المحارف -انظر المصفوفات أدناه-، كما توجد بعض العمليات التي توفرها لغة البرمجة لتساعدنا في التعامل مع السلاسل، مثل العثور على سلسلة فرعية أو ربط سلسلتين معًا، ونسخ واحدة إلى أخرى، وهكذا. تجدر الإشارة إلى أن بعض اللغات فيها نوع منفصل للمحارف، أي لحرف واحد فقط، وفي تلك الحالة تكون السلاسل مجرد مجموعات من قيم تلك الأحرف، لكن بايثون -على نقيض هذا-ـ إذ تستخدم سلسلةً طولها وحدة واحدة لتخزين الحرف الواحد، ولا يلزم وجود صياغة خاصة. العوامل النصية String Operators توجد عدة عمليات يمكن إجراؤها على السلاسل النصية، وبعضها مضمّن مسبقًا في بايثون، لكن يمكن توفير عمليات إضافية باستخدام الوحدات المستورَدة كما فعلنا مع وحدة sys في المقال السابق حول التسلسلات البسيطة. 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; } العامل الوصف S1 + S2 ضم كل من S1 و S2 S1 * N تكرار قدره N من S1 يمكننا أن نرى ذلك في الأمثلة التالية: >>> print( 'Again and ' + 'again' ) # ضم السلسلة Again and again >>> print( 'Repeat ' * 3 ) # تكرار السلسلة Repeat Repeat Repeat >>> print( 'Again ' + ('and again ' * 3) ) # '*' جمع '+' و Again and again and again and again كما يمكن إسناد سلاسل أحرف إلى متغيرات: >>> s1 = 'Again ' >>> s2 = 'and again ' >>> print( s1 + (s2 * 3) ) Again and again and again and again لاحظ أن المثالين الأخيرين أنتجا نفس الخرج. هناك الكثير من الأمور التي يمكن تنفيذها باستخدام السلاسل النصية، وسننظر فيها بتفصيل في مقالات تالية بعد أن نكتسب خبرةً جيدةً في المواضيع التي تسبقها. ربما تجب ملاحظة أن السلاسل النصية في بايثون لا يمكن تعديلها، أي أننا نستطيع إنشاء سلسلة نصية جديدة مع تغيير بعض الأحرف، لكن لا يمكن تعديل أي حرف داخل سلسلة تعديلًا مباشرًا، ويُعرف نوع البيانات ذاك الذي لا يمكن تغييره باسم النوع غير القابل للتغير immutable. متغيرات السلاسل النصية في VBScript تسمى المتغيرات في VBScript باسم المتغايرات variants، لأنها قد تحتوي على أي نوع من البيانات، وتحاول VBScript أن تحولها إلى النوع المناسب وفق الحاجة، وعليه فقد نسند عددًا إلى متغير ما، لكن إذا استخدمناه مثل سلسلة نصية فستحاول VBScript أن تحوله نيابةً عنا، وهذا يشبه -من الناحية العملية- سلوك أمر print في بايثون، غير أنه هنا يمتد إلى أي أمر VBSCript. ويمكن إعطاء VBScript لإشارة على أننا نريد قيمةً عدديةً في صورة سلسلة نصية من خلال تغليفها بعلامتي اقتباس مزدوجتين: <script type="text/vbscript"> MyString = "42" MsgBox MyString </script> يمكن دمج سلاسل VBScript معًا في عملية تسمى بالضم concatenation، باستخدام العامل &: <script type="text/vbscript"> MyString = "Hello" & "World" MsgBox MyString </script> سلاسل جافاسكربت النصية تحاط سلاسل جافاسكربت النصية بعلامات اقتباس مفردة أو مزدوجة، ويجب أن نصرّح عن المتغيرات قبل استخدامها، وذلك بكلمة var المفتاحية. في المثال التالي سنصرح عن متغيري سلاسل نصية ونعرّفهما: <script type="text/javascript"> var aString, another; aString = "Hello "; another = "World"; document.write(aString + another); </script> كما تسمح لنا جافاسكربت بإنشاء كائنات سلاسل نصية، ويمكن القول بأنها سلاسل نصية مع بعض المزايا الإضافية، والاختلاف الرئيسي بينهما هو طريقة إنشائها، والتي هي بالشكل: <script type="text/javascript"> var aStringObj, anotherObj; aStringObj = String("Hello "); anotherObj = String("World"); document.write(aStringObj + anotherObj); </script> قد تكون تلك كتابةً كثيرةً قياسًا على المثال السابق مع أنهما ينجزان العمل نفسه -وهذا صحيح نوعًا ما-، غير أن كائنات السلاسل تعطينا مزايا في بعض المواقف تجعلنا نفضل استخدامها عما سواها، كما سنرى لاحقًا. الأعداد الصحيحة Integers الأعداد الصحيحة هي الأعداد الكاملة غير الكسرية، من أكبر قيمة سالبة إلى أكبر قيمة موجبة، وهذا التحديد لمجال القيم مهم في البرمجة على عكس الرياضيات، إذ لا نعير اهتمامًا لقيمة العدد غالبًا طالما ينتمي إلى مجموعة أساسية أو المجموعة التي نعمل عليها، أو لم يكن يؤثر في الناتج؛ أما في البرمجة فهناك حدود عظمى وحدود دنيا، ويعرَف الحد الأعلى باسم MAXINT، كما يعتمد على عدد البتات bits المستخدَمة في حاسوبك لتمثيل عدد ما. يكون في أغلب الحواسيب ولغات البرمجة الحالية العدد 64-بت في المعماريات الحديثة، لذا فإن قيمة الحد الأعلى هنا MAXINT تساوي 10 مرفوعة إلى الأس 19، وتستطيع بايثون إخبارنا بقيمة maxint باستخدام وحدة sys، فإذا كانت معمارية النظام 64-بت مثلًا فستكون قيمة sys.maxsize هي 9223372036854775807، وهو رقم كبير؛ أما في VBScript فتكون تلك القيمة محدودةً بـ (‎+/- 32000‎) لأسباب تاريخية. تُعرَف الأعداد التي تحمل إشارةً موجبةً أو سالبةً بالأعداد الصحيحة ذات الإشارة signed integers، ومن الممكن استخدام أعداد صحيحة لا إشارة لها، غير أن هذا مقصور على الأعداد الموجبة، بما في ذلك الصفر، وهذا يعني أن الأعداد الصحيحة التي لا إشارة لها ضعف عدد ذوات الإشارة، بما أننا سنستغل المساحة التي كانت مخصصةً للأعداد السالبة لضمها إلى الأعداد التي لا إشارة لها، مما يعني زيادة قيمة الحد الأقصى إلى الضعف أيضًا "‎2 * MAXINT"، ونظرًا لأن حجم الأعداد الصحيحة مقيد بقيمة MAXINT، فإذا جمعنا عددين صحيحين وكان ناتج الجمع أكبر من الحد الأقصى؛ فسنحصل على خطأ، لكن قد تعيد بعض الأنظمة واللغات تلك القيمة الخاطئة كما هي مع رفع راية سرية secret flag نستطيع التحقق من وجودها إذا كنا نشك في الإجابة، وفي مثل هذه الحالة يكون التحقق عادةً هو برفع حالة خطأ، فإما أن يكون البرنامج حينها قادرًا على معالجة ذلك الخطأ فيعالجه، أو ينهي البرنامج نفسه إذا لم يستطع. تحوّل كل من جافاسكربت وVBScript العدد إلى صيغة تستطيعان التعامل معها، ولا تهتمان بالدقة هنا، إذ قد تختلف الصيغة الجديدة اختلافًا طفيفًا؛ أما لغة بايثون فتستخدم شيئًا اسمه العدد الصحيح الطويل Long Integer، وهي ميزة خاصة لها تسمح بأعداد صحيحة غير محدودة الحجم. >>> import sys >>> x = sys.maxsize * 1000000 >>> print(x) 9223372036854775807000000 >>> print (type(x)) <class 'int'> كما نرى فالنتيجة أكبر بكثير من القيمة التي تتوقعها من الحاسوب في العادة، رغم احتسابها int، أما إذا استخدمنا شيفرةً مكافئةً لهذا المثال في جافاسكربت وVBScript؛ فسيخرج لنا العدد بصيغة تختلف عن العدد الصحيح الذي نتوقعه، وسنتعلم المزيد عن هذا في قسم الأعداد الحقيقية. <script type="text/vbscript"> Dim x x = 123456700 * 34567338738999 MsgBox CStr(x) </script> العمليات الحسابية رأينا معظم العمليات الحسابية التي نحتاج إليها في المقال السابق في التسلسلات البسيطة، ولكن للتلخيص نعيدها مرةً أخرىً: مثال العامل الوصف M + N جمع M و N M - N طرح N من M M * N ضرب M في N M / N قسمة M على N، سيكون الناتج عددًا حقيقيًا كما سنبين لاحقًا M // N القسمة الصحيحة لـ M على N، ستكون النتيجة عددًا صحيحًا M % N باقي القسمة: أوجد ما تبقى من قسمة M على N M**N الأس: M مرفوعًا إلى الأس N بما أننا لم نرى المتغير الأخير من قبل، فلننظر في مثال على إنشاء بعض متغيرات الأعداد الصحيحة ونستخدم عامل الأس: >>> i1 = 2 # i1 أنشئ عددًا صحيحًا وأسنده إلى >>> i2 = 4 >>> i3 = i1**i2 # i3 أسند نتيجة 2 إلى أس 4 إلى >>> print( i3 ) 16 >>> print( 2**4 ) # أكد النتيجة 16 تحتوي الوحدة math في بايثون على بعض الدوال الرياضية الشائعة مثل sin و cos وغيرهما. عوامل الاختصار إحدى العمليات الشائعة في البرمجة هي زيادة قيمة المتغير التدريجية، فإذا كان لدينا المتغير x الذي قيمته 42، ونريد زيادة تلك القيمة إلى 43، فسيكون ذلك كما يلي: >>> x = 42 >>> print( x ) >>> x = x + 1 >>> print( x ) لاحظ السطر التالي: x = x + 1 لا معنىً لهذا السطر من حيث المنطق الرياضي، لكنه في البرمجة يعني أن x الجديدة تساوي قيمة x السابقة مضافًا إليها 1، فإذا كنت معتادًا على المنطق الرياضي؛ فستستغرق بعض الوقت لتعتاد على هذا النمط الجديد، لكن الفكرة هنا أن علامة = تُقرأ "ستكون" وليست "تساوي"، وعليه فإن السطر يعني أن x ستصبح قيمتها الجديدة هي x+1، وهذا النوع من العمليات شائع جدًا في الممارسة العملية إلى حد أن بايثون وجافاسكربت توفران عاملًا مختصرًا له من أجل توفير الكتابة على المبرمج: >>> x += 1 >>> print( x ) وهذان العاملان مساويان تمامًا لتعليمة الإسناد السابقة لكنهما أقصر، توجد عوامل اختصار لباقي العمليات الحسابية بنفس المنطق السابق، نبينها في الجدول التالي: مثال العامل الوصف M += N M = M + N M -= N M = M - N M *= N M = M * N M /= N M = M / N M //= N M = M // N M %= N M = M % N الأعداد الصحيحة في VBScript لقد قلنا إن الأعداد الصحيحة في VBScript محدودة بقيمة عظمى أقل من بايثون وجافاسكربت، وهي تقابل 16-بت على خلاف 64-بت التي رأيناها من قبل، أي حوالي "‎+/- 32000"، فإذا احتجنا إلى عدد صحيح أكبر من هذا؛ فنستخدم العدد long الذي يساوي حجمه حجم العدد الصحيح من معمارية 32-بت (أي 2 مليار)، كذلك لدينا النوع byte الذي هو عدد ثماني البتات، وحجمه الأكبر يساوي 255، وسيتضح بالممارسة العملية أن النوع القياسي للعدد الصحيح كافٍ لأغلب العمليات، فإذا كانت نتيجة العملية أكبر من MAXINT؛ فستحول VBSCript النتيجة تلقائيًا إلى عدد ذي فاصلة عائمة أو حقيقي، كما سنبين لاحقًا. ورغم دعم VBScript لجميع العمليات الحسابية المعتادة، إلا أن عملية الباقي modulo تمثَّل تمثيلًا مختلفًا، باستخدام العامل MOD، وقد رأينا ذلك في فصل التسلسلات البسيطة، كذلك فإن تمثيل الأسس مختلف، إذ يُستخدم محرف الإقحام ^ بدلًا من ** في بايثون. أعداد جافاسكربت تحتوي جافاسكربت على نوع عددي في صورة كائن كما سنصفه فيما بعد، وهي تسميه Number، لكن أحيانًا قد يكون عدد جافاسكربت "ليس عددًا" أو Not a Number، ويشار إليه بـ NaN اختصارًا، وهو ما نحصل عليه أحيانًا كنتيجة لبعض العمليات المستحيلة رياضيًا، والهدف منه هو السماح لنا بالتحقق من أنواع أخطاء بعينها دون تعطيل البرنامج، كما تحوي لغة بايثون كذلك النوع NaN أيضًا. تحتوي جافاسكربت على نسخ عددية خاصة لتمثيل اللانهاية الموجبة والسالبة، وهي ميزة نادرة نسبيًا في لغات البرمجة، وقد تكون كائنات جافاسكربت العددية إما أعدادًا صحيحةً أو حقيقيةً كما سنرى لاحقًا، وتَستخدم جافاسكربت نفس العوامل التي تستخدمها بايثون، باستثناء الإجراءات الأسية التي تستخدم كائنًا خاصًا بها اسمه Math. الأعداد الحقيقية Real Numbers الأعداد الحقيقية هي نفسها الأعداد الصحيحة لكن مع إضافة الكسور، وقد تمثل أعدادًا أكبر من الحد الأقصى MAXINT لكن مع دقة أقل، وهذا يعني أننا قد نرى عددين حقيقيين على أنهما متطابقين، لكن الحاسوب يراهما غير متطابقين عندما يوازنهما معًا، لأنه ينظر في أدق التفاصيل بينهما، حيث يمكن تمثيل العدد 5.0 في الحاسوب بإحدى الصورتين 4.9999999 أو (‎5.000000…01) مثلًا، وهذه التقاربات مناسبة لأغلب الاستخدامات، لكن قد نحتاج أحيانًا إلى تلك الدقة، فتذكر هذا الأمر إذا حصلت على نتيجة غريبة لا تتوقعها عند استخدام الأعداد الحقيقية. كما تُعرَف الأعداد الحقيقية أيضًا باسم أعداد الفاصلة العائمة floating point numbers، ولها نفس العمليات الحسابية التي تطبّق على الأعداد الصحيحة، مع زيادة هنا وهي قدرتها على اقتطاع العدد ليكون قيمة صحيحة. تدعم لغات البرمجة الثلاث بايثون وجافاسكربت وVBScript الأعداد الحقيقية، وننشئها في بايثون بتخصيص عدد بعلامة عشرية فيه كما رأينا في المقال السابق للتسلسلات البسيطة؛ أما جافاسكربت وVBScript فلا يوجد تمييز واضح بين الأعداد الصحيحة والحقيقية، فما عليك إلا استخدامها وستتعامل اللغة مع ما تدخله إليها وفق المناسب. الأعداد المركبة أو التخيلية Complex numbers إذا كانت لديك خلفية رياضية فقد تتساءل أين الأعداد المركبة complex في هذا الشرح، والواقع أننا لا نحتاج إليها غالبًا في البرمجة، لكن على أي حال فبعض اللغات مثل بايثون توفر دعمًا مضمّنا فيها للأعداد المركبة، بينما توفر بعض اللغات الأخرى مكتبةً من الدوال التي تستطيع التعامل مع الأعداد المركبة، ونفس الأمر ينطبق على المصفوفات. يمثَّل العدد المركب في بايثون كما يلي: (real+imaginaryj) وبناءً عليه تبدو عملية جمع بسيطة لعدد مركب كما يلي: >>> M = (2+4j) >>> N = (7+6j) >>> print( M + N ) (9+10j) تنطبق جميع عمليات الأعداد الصحيحة على الأعداد المركبة كذلك، كما توجد وحدة cmath التي تحتوي بعض الدوال الرياضية الشائعة التي تعمل على قيم الأعداد المركبة، ولا توفِّر جافاسكربت وVBScript دعمًا للأعداد المركبة. القيم البوليانية - True و False سُمي هذا النوع من القيم بهذا الاسم نسبةً إلى عالم الرياضيات George Boole الذي كان يدرس المنطق في القرن التاسع عشر، ولا يحوي هذا النوع من البيانات إلا قيمتين فقط، هما True عند التحقق أو الصحة، و false عند عدم التحقق أو الخطأ، وتدعم بعض اللغات هذا النوع دعمًا مباشرًا، بينما تستخدم بعض اللغات الأخرى اصطلاحًا تمثل فيه قيمةً عدديةً القيمة false، وتكون تلك القيمة غالبًا هي الصفر؛ بينما تمثَّل القيمة true بالعدد (1) أو (‎-1)، وقد كان هذا سلوك بايثون حتى الإصدار 2.2، لكنها صارت تدعم القيم البوليانية مباشرةً بعد ذلك باستخدام القيمتين True و False، وهما كما ترى تبدآن بحرف كبير، فتذكر أن بايثون حساسة لحالة الأحرف. تعرَف القيم البوليانية أحيانًا باسم قيم الحقيقة لأنها تُستخدم للتحقق مما إذا كان شيء ما صحيحًا أم لا، فإذا كتبنا برنامجًا يأخذ نسخةً احتياطيةً من جميع الملفات في مجلد ما مثلًا، فنستطيع نسخ كل ملف على حدة ثم نطلب اسم الملف التالي من النظام، وإذا لم تتبق ملفات لنسخها، فسيعيد النظام سلسلةً نصيةً فارغةً، حيث سنتحقق هنا مما إذا كان الاسم هو سلسلةً فارغةً أم لا، ونخزن النتيجة مثل قيمة بوليانية تكون قيمتها True إذا كان الاسم سلسلةً فارغةً، و False إذا لم يكن كذلك، وسنرى كيفية استخدام تلك النتيجة لاحقًا في هذه السلسلة. العوامل البوليانية أو المنطقية العامل الوصف الأثر A and B الإضافة أو AND صحيح إذا كان كل من A و B صحيحًا أو متحققًا، وخطأ في الحالات الأخرى A or B الاختيار أو OR صحيح إذا كان أحدهما أو كلاهما صحيحًا، وخطأ إذا كان كل من A و B خاطئًا A == B التساوي صحيح إذا كان A يساوي B A != B عدم التساوي صحيح إذا كانت A لا تساوي B not B النفي صحيح إذا لم يكن B صحيحًا تدعم VBScript القيم البوليانية كما تفعل بايثون على الصورة True و False، أما جافاسكربت فتدعمها لكن على الصورة true و false -لاحظ حالة الأحرف الصغيرة هنا-. كما ستجد أسماءً مختلفةً لنوع البيانات البولياني أو المنطقي في كل لغة، ففي بايثون ستجدها باسم bool، أما في جافاسكربت وVBScript فاسمه Boolean، ولا تشغل بالك بهذا لأننا لن ننشئ متغيرات من هذا النوع، لكننا سنستخدم نتائجه في الاختبارات. الوقت والتاريخ يُعطى التاريخ والوقت في العادة أنواعًا خاصةً بهما في البرمجة، لكن قد يمثَّلان أحيانًا في صورة عدد كبير (عدد الثواني منذ وقت أو تاريخ قديم، مثل الوقت الذي كُتب فيه نظام التشغيل)، لكن قد يكون نوع البيانات في أحيان أخرى هو ما يُعرف بالنوع المعقد الذي سنذكره في الفصل التالي، وهو يسهل استخراج الشهر واليوم والساعة… سننظر في استخدام بايثون لوحدة time في مقال تالٍ، أما جافاسكربت وVBScript فلديهما آليات خاصة للتعامل مع الوقت، لكننا لن ندرسها. النوع الذي يعرفه المستخدم User Defined Type قد لا تكفي الأنواع التي ذكرناها سابقًا لاحتياجاتنا البرمجية حتى لو دمجناها معًا، فقد نريد جمع عدة أجزاء من البيانات معًا ثم نعاملها مثل عنصر واحد، كما في وصف العنوان مثلًا، حيث يكون على هيئة "رقم المنزل والشارع والمدينة ، ثم الرمز البريدي". تسمح أغلب اللغات بجمع مثل هذه المعلومات معًا في سجل أو هيكل بيانات أو في هيئة صنف Class، وهذا الأخير في البرمجة كائنية التوجه Object Oriented. VBScript تبدو تعريفات السجلات في VBScript كما يلي: Class Address Public HsNumber Public Street Public Town Public ZipCode End Class تعني الكلمة المفتاحية Public أن البرنامج يستطيع الوصول إلى البيانات، وعليه توجد كلمة Private التي يمكن استخدامها لجعل البيانات خاصةً ومقصورةً على أجزاء بعينها من البرنامج، كما سنرى لاحقا. بايثون يختلف الأمر قليلًا في بايثون: >>> class Address: ... def __init__(self, Hs, St, Town, Zip): ... self.HsNumber = Hs ... self.Street = St ... self.Town = Town ... self.ZipCode = Zip ... سنترك شرح معنى كل من self و def __init__(...)‎ إلى حين الحديث عن البرمجة كائنية التوجه، أما الآن فنريد ملاحظة أن هناك شرطتين سفليتين حول init، وهذا أسلوب متبع في بايثون. لاحظ كذلك ضرورة استخدام المسافات الموضحة أعلاه، ذلك أن بايثون دقيقة في تحديد المسافات. قد يواجه البعض مشاكل أثناء كتابة ما يتشابه مع هذا المثال في محث بايثون، وستجد في نهاية هذا المقال شرحًا مختصرًا لهذه المشكلة، ثم سنشرحها بالتفصيل في جزء تالٍ من هذه السلسلة، فإذا أردت كتابة المثال أعلاه في محث بايثون؛ فتأكد من نسخ المسافات البادئة لكل سطر. والأمر الذي نريد التوكيد عليه هنا هو أننا جمعنا عدة أجزاء من بيانات مرتبطة ببعضها بعضًا ثم وضعناها في هيكل واحد هو Address، كما فعلنا في VBScript قبل قليل. جافاسكربت توفر جافاسكربت اسمًا غريبًا لهيكل بيانات العنوان في حالتنا، وهو function، إذ ترتبط الدوال عادةً بالعمليات وليس تجميعات البيانات، غير أن دوال جافاسكربت تستطيع التعامل مع كليهما، فإذا أردنا إنشاء كائن العنوان في جافاسكربت؛ فسنكتب الآتي: function Address(Hs,St,Town,Zip) { this.HsNum = Hs; this.Street = St; this.Town = Town; this.ZipCode = Zip; } نريد مرةً أخرى تجاهل الصياغة واستخدام الكلمة this هنا، والنظر إلى النتيجة التي ستكون مجموعةً من عناصر البيانات التي نستطيع القول بأنها تصف عنوانًا، ويمكننا معاملته على أنه وحدة واحدة. والآن، كيف نصل إلى تلك البيانات بعد إنشاء هياكلها؟ الوصول إلى الأنواع التي يعرفها المستخدم من الممكن إسناد نوع بيانات معقد إلى متغير، لكن لا يمكن الوصول إلى الحقول المنفردة دون استخدام بعض آليات الوصول الخاصة التي تحددها اللغة، وتكون نقطة . في الغالب. VBScript إذا استخدمنا حالة صنف العنوان الذي عرّفناه أعلاه، فسنكتب ما يلي: Dim Addr Set Addr = New Address Addr.HsNumber = 7 Addr.Street = "High St" Addr.Town = "Anytown" Addr.ZipCode = "123 456" MsgBox Addr.HsNumber & " " & Addr.Street & " " & Addr.Town نحدد هنا بُعد متغير جديد هو Addr باستخدام Dim، ثم نستخدم الكلمتين Set و New لإنشاء نسخة جديدة من صنف Address، ثم نسند القيم إلى حقول نسخة العنوان الجديدة، ثم نطبع العنوان في صندوق رسالة. بايثون على فرض أننا كتبنا تعريف الصنف أعلاه: >>> Addr = Address(7,"High St","Anytown","123 456") >>> print( Addr.HsNumber, Addr.Street, Addr.Town ) 7 High St Anytown ينشئ هذا نسخةً من نوع Address ويسند إليه المتغير Addr، ونستطيع تمرير قيم الحقل إلى الكائن الجديد عند إنشائه في بايثون، ثم نطبع حقول HsNumber و Street للنسخة المنشأة حديثًا باستخدام عامل النقطة .. كما يمكن إنشاء نسخ عنوان متعددة لكل منها قيمه المستقلة لأرقام البيوت والشوارع وغيرها. جرب هذا بنفسك لتتدرب عليه، فهل تستطيع معرفة كيفية استخدام هذا في مثال دفتر العناوين؟ جافاسكربت تشبه آلية جافاسكربت هنا ما سبق ذكره لكن مع بعض التعديل، غير أن الآلية الأساسية بسيطة ومباشرة: var addr = new Address(7, "High St", "Anytown", "123 456"); document.write(addr.HsNum + " " + addr.Street + " " + addr.Town); إحدى الآليات التي يمكن استخدامها في جافاسكربت أيضًا هي معاملة الكائن مثل قاموس واستخدام اسم الحقل كمفتاح: document.write( addr['HsNum'] + " " + addr['Street'] + " " + addr['Town']); وما لم نُعط اسم الحقل في هيئة سلسلة نصية كما في حالة قراءة ملف أو إدخال مستخدم للبرنامج، فلا ننصح باستخدام هذا النموذج. العوامل التي يعرفها المستخدم يمكن للأنواع التي يعرِّفها المستخدم أن تكون لها عمليات معرفة لها كذلك، وذلك أساس ما يعرف بالبرمجة كائنية التوجه. الكائن هو عبارة عن تجميعة من عناصر البيانات والعمليات المرتبطة بتلك البيانات، وهي مغلفة جميعًا في وحدة واحدة، حيث تستخدم بايثون الكائنات على نطاق واسع في مكتبتها القياسية للوحدات، كما تسمح لنا كوننا مبرمجين بإنشاء أنواع الكائنات الخاصة بنا. يحصل الوصول إلى عمليات الكائنات بنفس الطريقة التي يمكن الوصول بها إلى أعضاء البيانات لنوع معرَّف من قِبل المستخدم، أي من خلال عامل النقطة؛ أما غير هذا فتكون أشبه بالدوال، وتسمى تلك الدوال الخاصة بالتوابع methods، وقد رأيناها في حالة العملية append()‎ في القوائم، أينما تذكر أنه من أجل استخدامها يجب أن نربط استدعاء الدالة باسم المتغير. >>> listObject = [] # قائمة فارغة >>> listObject.append(42) # استدعاء تابع لكائن القائمة >>> print( listObject ) [42] يجب استيراد الوحدة عند توفير نوع كائن - يُسمى صنفًا- في وحدة بايثون كما فعلنا في sys من قبل، ثم كتابة اسم الوحدة قبل اسم نوع الكائن عند إنشاء نسخة يمكن تخزينها في متغير مع استخدام الأقواس طبعًا، بعد ذلك نستطيع استخدام المتغير دون استخدام اسم الوحدة، ولتوضيح هذا لنَعُد إلى وحدة array التي ذكرناها من قبل، فهي توفر الصنف array، ولنستورد هذه الوحدة ثم ننشئ نسخةً من array، ونسند اسم myArray إليها، ثم نستخدم myArray فقط للوصول إلى عملياتها وبياناتها كما يلي: >>> import array >>> myArray = array.array('d') # array of reals(d), use module name >>> myArray.append(42) # use array operation >>> print( myArray[0]] ) # access array content 42.0 >>> print( myArray.typecode ) # access array attribute 'd' نستورد الوحدة array في السطر الأول إلى البرنامج، ثم نستخدم تلك الوحدة في السطر الثاني لإنشاء نسخة من صنف array باستدعائها مثل دالة، ونحتاج هنا إلى توفير سلسلة الرموز النوعية typecode string التي توضح نوع البيانات التي يجب تخزينها. تذكر أن المصفوفات الخالصة تخزن نوعًا واحدًا من البيانات، حيث سنصل في السطر الثالث إلى إحدى عمليات صنف المصفوفة، وهي append()‎ التي تعامل الكائن myArray كأنه وحدة وكأن العملية داخل الوحدة، ثم نستخدم الفهرسة لجلب البيانات التي أضفناها، نستطيع في الأخير الوصول إلى بعض البيانات الداخلية، إذ يخزن typecode النوع الذي مررناه عند إنشاء المصفوفة، من داخل كائن myArray صياغةً تشبه صياغة الوحدة. لا يوجد فرق كبير بين استخدام الكائنات التي توفرها الوحدات، وبين الدوال الموجودة في الوحدات، باستثناء الحاجة إلى إنشاء نسخة instance، ويمكن النظر إلى اسم الكائن على أنه عنوان يحفظ الدوال والمتغيرات المرتبطة به مجموعةً معًا. إحدى الطرق الأخرى التي ننظر بها للأمر هي أن الكائنات تمثل أشياء من العالم الحقيقي ونحن نستخدمها أو نفعل بها أمورًا تنفعنا، وهذا المنظور على بساطته إلا أنه الفكرة التي نشأت بسببها الكائنات في البرمجة، فنحن نكتب -برمجيًا- محاكاةً لمواقف في العالم الحقيقي. تستطيع كل من جافاسكربت وVBScript أن تتعامل مع الكائنات، وقد كان هذا ما استخدمناه في كل أمثلة العناوين أعلاه، فقد عرفّنا صنفًا ثم أنشأنا نسخةً أسندناها إلى متغير كي نستطيع الوصول إلى خصائص تلك النسخة، ولهذا ارجع إن شئت إلى ما سبق من الشرح عن الأصناف والكائنات، وانظر كيف توفر الأصناف آليات لإنشاء أنواع جديدة من البيانات في برامجنا من خلال الربط بين بيانات النوع الجديد وعملياته معًا. العوامل الخاصة ببايثون إنّ الهدف من هذه السلسلة هو تعليم البرمجة للمبتدئين، ورغم أننا نستخدم بايثون في الشرح؛ إلا أنك تستطيع قراءة لغة برمجة أخرى واستخدامها بدلًا منها، بل إن هذا هو عين ما نتوقعه منك، إذ أنه لا توجد لغة برمجة بما فيها بايثون، تستطيع تنفيذ جميع المهام وحل كل المشاكل التي تواجهك برمجيًا، وبسبب ذات الهدف لن نشرح جميع الخصائص الموجودة في بايثون، بل سنركز على تلك التي يمكن إيجادها في لغات البرمجة الأخرى كذلك، ولهذا سنهمل شرح بعض الخصائص بالغة القوة في بايثون، والتي تميزها عما سواها، مثل العوامل الخاصة special operators، ذلك أن أغلب لغات البرمجة تدعم عمليات بعينها لا تدعمها لغات أخرى، وتلك العوامل الفريدة هي التي تسبب ظهور لغات برمجة جديدة، وهي من العوامل المهمة في تحديد شهرة تلك اللغات من حيث الاستخدام فيما بعد. حيث تدعم بايثون مثلًا عمليات غير شائعة نسبيًا في لغات البرمجة الأخرى، مثل تشريح القائمة spam[X:Y]‎ (إلى شرائح) list slicing من أجل استخراج شريحة من وسط القائمة أو السلسلة النصية أو الصف tuple، كما تدعم إسناد الصف Tuple الذي يسمح لنا بإسناد عدة قيم متغيرات مرةً واحدةً: X, Y = (12, 34)‎. كما تسهل تنفيذ العمليات على كل عضو من أعضاء تجميعة ما باستخدام الدالة map()‎ التي سنشرحها في مقال لاحق من هذه السلسلة، إضافةً إلى الكثير من الخصائص التي جعلت بايثون تشتهر بأنها تأتي "مع البطارية" إشارةً إلى كثرة الملحقات والمزايا التي تأتي معها. ارجع إلى توثيق بايثون للمزيد عن تلك المزايا. تجدر أخيرًا الإشارة إلى أنه رغم قولنا بأن تلك العوامل خاصة ببايثون؛ إلا أن هذا لا يعني أنها لا توجد في لغات برمجة أخرى، بل أنها لن توجد مجتمعةً في كل لغة، فالعوامل التي نشرحها في هذه السلسلة تكون متاحةً بشكل أو بآخر في أغلب لغات البرمجة الحديثة. يلخص هذا نظرتنا على المواد الخام للبرمجة، وسننتقل الآن إلى موضوع آخر نرى فيه كيف نستغل تلك المواد الخام في البرمجة الحقيقية. شرح لمثال العناوين رغم قولنا أننا سنشرح تفاصيل هذا المثال لاحقًا، إلا أننا رأينا صعوبة تنفيذ مثال بايثون من بعض القراء، ولهذا سيشرح هذا القسم شيفرة بايثون سطرًا سطرًا. ستبدو شيفرة المثال كاملة كما يلي: >>> class Address: ... def __init__(self, Hs, St, Town, Zip): ... self.HsNumber = Hs ... self.Street = St ... self.Town = Town ... self.Zip_Code = Zip ... >>> addr = Address(7,"High St","Anytown","123 456") >>> print( addr.HsNumber, addr.Street ) وسنشرح الآن سطرًا سطرًا: >>> class Address: تخبر التعليمة class بايثون أننا على وشك تعريف نوع جديد اسمه Address في هذه الحالة، وتشير النقطتان الرأسيتان إلى أن أي أسطر مزاحة تالية ستكون جزءًا من تعريف الصنف، وينتهي التعريف عند أول سطر غير مزاح، فإذا كنت تستخدم IDLE؛ فسترى أن المحرر قد أزاح السطر التالي تلقائيًا، أما إذا كنت تعمل من محث بايثون في سطر أوامر DOS مثلًا، فسيكون عليك إزاحة الأسطر كما هو موضح أعلاه، ولا تهتم بايثون بمقدار الإزاحة طالما أنها نفسها لكل سطر. أما السطر الثاني: ... def __init__(self, Hs, St, Town, Zip): يطلق على العنصر الأول في الصنف الخاص بنا "تعريف التابع method definition"، ويجب أن يكون حول الاسم شرطتان سفليتان على كل ناحية منه، وهي طريقة بايثون للأسماء التي لها أهمية خاصة، ويسمى ذلك التابع __init__، وهو عملية خاصة تنفذها بايثون حين ننشئ نسخةً من الصنف الجديد الخاص بنا كما سنرى بعد قليل؛ أما النقطتان الرأسيتان فتخبران بايثون أن مجموعة الأسطر المزاحة التالية ستكون هي التعريف الحقيقي للتابع. والسطر الثالث: ... self.HsNumber = Hs يُسنِد هذا السطر -والأسطر الثلاثة التالية- قيمًا إلى الحقول الداخلية للكائن الخاص بنا، وهذه الأسطر مزاحة من تعليمة def لتخبر بايثون أنها تشكل التعريف الحقيقي لعملية __init__، أما السطر الفارغ، فيخبر مفسر بايثون بأن تعريف الصنف قد انتهى، لنعود مرةً أخرى إلى محث بايثون المعتاد ‎>>>‎. >>> addr = Address(7,"High St","Anytown","123 456") ينشئ هذا نسخةً جديدةً من النوع Address، وتستخدم بايثون عملية __init__ المعرَّفة أعلاه لإسناد القيم التي أعطيناها إلى الحقول الداخلية، وتسنَد النسخة إلى متغير addr كما تسنَد أي نسخة لأي نوع بيانات آخر. >>> print( addr.HsNumber, addr.Street ) نطبع الآن قيم حقلين من الحقول الداخلية مستخدمين عامل النقطة للوصول إليهما. خاتمة يُعَد هذا المقال دسمًا وغنيًا بالمعلومات النظرية التي تؤسس لتعلم البرمجة على أسس سليمة، وسنعود إلى ما فيه مرات كثيرة أثناء الشرح، بما أن البيانات وأنواعها هي اللبنات التي تُصنع منها البرامج، لكن نريد التذكير هنا بأن بايثون تسمح لنا بإنشاء أنواع البيانات التي نريدها بأنفسنا ونستخدمها مثل أي نوع مضمّن فيها، وأن المتغيرات تشير إلى بيانات، وقد نحتاج إلى التصريح عنها قبل تعريفها، وهي تأتي في أنواع شتى، ويتوقف نجاح العملية التي نجريها على نوع البيانات الذي نستخدمه. ومن أنواع البيانات البسيطة سلاسل المحارف والأعداد والقيم البوليانية أو قيم "الحقيقة"، كما تشمل أنوع البيانات المعقدة التجميعات والملفات والبيانات وأنواع البيانات المعرّفة من قِبل المستخدم. توجد أيضًا العديد من العوامل في كل لغة برمجة، وتيُعَد تعلّم تلك العوامل جزءًا من التعود على أنواع بياناتها وعلى العمليات المتاحة لتلك الأنواع، وقد يكون العامل الواحد متاحًا لعدة أنواع، غير أن النتيجة قد لا تكون هي نفسها في كل مرة، بل ربما تختلف اختلافًا كبيرًا. سنتابع مع المقال الموالي مع ذكر نوع أخر مهم من البيانات، وهو التجميعات Collections. ترجمة -بتصرف- للفصل الخامس: The Raw Materials من كتاب Learning To Program لصاحبه Alan Gauld. اقرأ أيضًا المقال التالي: مدخل إلى البيانات وأنواعها: التجميعات Collections المقال السابق: التسلسلات البسيطة في البرمجة مدخل إلى البيانات الوصفية (microdata) في HTML5 هياكل البيانات: الكائنات والمصفوفات في جافاسكريبت
    1 نقطة
  6. لقد قمت بإنشاء مشروع بسيط باستخدام node.js وإطار العمل express.js وحاولت نشره على heroku ولكن يظهر لي الخطأ التالي: heroku[router]: at=error code=H10 desc="App crashed" method=GET path=/ dyno= queue= wait= connect= service= status=503 bytes= وفي ملف package.json لدي: { "name": "test", "author": "", "description": "", "version": "0.0.1", "private": true, "scripts": { "start": "node app" }, "dependencies": { "express": "3.0.6", "jade": "*", }, "engines": { "node": "0.8.14" } } كيف يمكنني حل هذه المشكلة؟
    1 نقطة
  7. السلام عليكم اريد ان اجعل الايقونه في الصوره بجانب النص 2- ايضا" اريد ان اجعل هناك 3 خلفيات تنتقل بين بعضها ب timer وثلاث ازرار اسفل الصفحه للتحكم بهم كيف يمكنني فعلها templete 1 (2).zip
    1 نقطة
  8. السلام عليكم انا كنت عايز اعرف لو استخدمت الكمبيوتر في فترة الظهر اللي هو في الحر هيضر الكمبيوتر ولا لا ؟ علما أن الكيسة dell و الشاشة الكمبيوتر hp
    1 نقطة
  9. السلام عليكم. أريد جلب الإختبارات الموجودة بقاعدة البيانات ضمن شرط level_id فأستخدم الكود التالي Exam::where('level_id', $request->level) ->select('id', 'subject_id', 'teacher_id', 'created_at') ->get(); وأجلب معها relation ['teacher', 'subject'] فيصبح الكود كالتالي Exam::with(['teacher', 'subject']) ->where('level_id', $request->level) ->select('id', 'subject_id', 'teacher_id', 'created_at') ->get(); سؤالي هو أن علاقة الteacher المجلوبة ضمن collection exams تحتوي على علاقة profile فأريد جلب علاقة الprofile أيضا التي توجد داخل علاقة الteacher توضيح أكثر: كل exam له teacher وكل teacher له profile أريد جلب العلاقة profile ضمن العلاقة teacher ضمن exam يعني كالتالي @foreach($exams as $exam) {{ $exam->teacher->profile }} @endforeach فكيف أفعل هذا وشكرا. أستعمل لارافل 8
    1 نقطة
  10. أضف العلاقات التي تريدها مع with أي جرب التالي: Exam::with(['teacher.profile', 'subject']) ^^^^^^^^^^^^^^^^ الشكل العام لها: with('relation1.relation2.relation3')->get(); اجلب العلاقات المرتبطة الواحدة تلوَ الأخرى..
    1 نقطة
  11. <form method="get" action="http://example.com?first=1"> <input name="second"> <input type="submit" value="submit"> </form> كيف عند عمل submit للفورم يصبح الرابط كالتالي: http://example.com?first=1&second=text ?? استعمل لارافل 8 وشكرا
    1 نقطة
  12. أي أنك تريد تثبيت الوسيط first=1 يمكن وضع input مخفي <input type="hidden" name="first" value="1"> سيتم إضافته للرابط.. <form method="get" action="http://example.com"> <input type="hidden" name="first" value="1" /> <input name="second" /> <input type="submit" value="submit" /> </form> والتجريب: إدخال 5 في الحقل الظاهر في الصفحة يرسل الطلب للصفحة http://example.com/?first=1&second=5
    1 نقطة
  13. اريد مقالة او فيديوهات شرح لاضافة zoom الى لارافيل
    1 نقطة
  14. لإستعمال خدمات zoom في تطبيق لارافيل يجدر بك فتح حساب مطور في zoom لإستعمال الواجهة البرمجية الخاصة بهم بشكل طبيعي . يمكنك قراءة توثيق الواجهة البرمجية كاملا هنا . كما يمكنك إستعمال الـ sdk الخاص بـ zoom للاستفادة من كامل المميزات و الخدمات التي توفرها . يمكنك قراءة التوثيق كاملا هنا . كما يمكنك إستعمال هاته الحزمة للإستفادة من بعض الخدمات بشكل أبسط . كما يمكنك الاستزادة بقراءة هاته المقالات حول نفس الموضوع : كيفية إضافة zoom API إلى تطبيق لارافيل كيفية تضمين الـ embeded code الخاص بأي ملتقى zoom (مقالة). كيفية تضمين الـ embeded code الخاص بأي ملتقى zoom (نقاش في منتديات zoom). إدارة ملتقيات زوم عن طريق تطبيق لارافيل .
    1 نقطة
  15. حسناً سأقترح لك عدة طرق، بدايةً سأقوم بإنشاء تابع لك، تمرر له رقم العمود أو الأعمدة التي تريدها أن تظهر في المصفوفة الجديدة ويعطيك الخرج المطلوب (تمررها على شكل قائمة): import numpy as np arr = np.random.randint(5, size=(5,3)) print(arr) """ [[4 1 2] [3 2 3] [0 1 4] [4 3 3] [2 3 0]] """ # التابع def make(index,a): a=a.T b=a[index] return b.T # الآن بفرض أنك تريد مصفوفة جديدة من المصفوفة الأصلية مكونة من ثاني و ثالث عمود make([1,2],arr) # الخرج """ array([[1, 2], [2, 3], [1, 4], [3, 3], [3, 0]]) """ # إذا أردنا ثاني عمود فقط make([1],arr) """ array([[1], [2], [1], [3], [3]]) """ حيث اعتمدت على فكرة أخذ منقول المصفوفة ثم اختيار الأعمدة التي أريدها (التي أصبحت تشكل أسطر) ثم بعدها نأخذ المنقول مرة أخرى لتعطي الخرج. وبشكل أكثر سهولة يمكنك استخدام مفهوم الفهرسة والتقطيع في بايثون، بالشكل التالي: # إذا أردت ثاني عمود arr[:,[1]] """ array([[1], [2], [1], [3], [3]]) """ # ثاني وثالث عمود arr[:,[1,2]] """ array([[1, 2], [2, 3], [1, 4], [3, 3], [3, 0]]) """ وأخيراً، إذا أردت أسطر وأعمدة محددين: # ثاني وثالث عمود مع أول سطرين فقط arr[:2,1:3] """ array([[1, 2], [2, 3]]) """
    1 نقطة
  16. package Java; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in =new Scanner(System.in); System.out.println(" ادخل الرقم الروماني"); String x=in.next(); System.out.printf("Roman= %S",x); }
    1 نقطة
  17. عندي مشكلة اني كنت اعمل على مشروع و كان Prettier - Code formatter يعمل بشكل جيد لكن الان بدات ب مشروع جديد و Prettier - Code formatter توقف عن العمل ولا اعلم لماذا مع انه مثبت
    1 نقطة
  18. في الجزء السفلي من محرر الأكواد vs code تظهر تبويب بنفس لاحقة الملف، مثلا إن كان php يكتب php وهكذا لكل لغة (تأكد من تطابقهما) اضغط بالزر الأيمن ضمن الملف ثم اختر format with ثم تظهر قائمة منبثقة حدد منها Prettier - Code formatter تأكد من تحديث الإضافة (يوجد 2 بنفس الاسم واحد منهم توقف عملها deprecated)
    1 نقطة
  19. سأترك الحل ربما قد يحتاجه شخص ما مستقبلا ^-^ في صفحة العرض : {{-- for change currency --}} <form action="{{ route('currency') }}" method="POST"> @csrf <select class="form-select" aria-label="Default select example" name="currency"> @foreach ($currencies as $currency) <option value="{{ $currency['code'] }}" >{{ $currency['code'] }}</option> @endforeach </select> <input type="submit" name="" value="submit" id=""> </form> {{-- for test --}} {{currency()->getUserCurrency() . request()->session()->get('currency')}} في الكونترولر: public function changeCurrency(Request $request) { $params = [ 'currency' => $request->currency, ]; $request->query = new ParameterBag($params); return back(); }
    1 نقطة
  20. شكرا جزيلا لك اجابتك كانت مفيدة جدا شكرا اخي 💚💛💛
    1 نقطة
  21. في حال كانت هذه الشركات تستخدم هذه اللغة، لم لا؟ لا يمكنني أنا أن أحدد قبولك طبعاً، فكل شركة لها معايير يتم فيها قياس خبرة وكفاءة الموظفين وأيضاً ما المهام التي ترغب بأن يلم بها هذا الموظف ويستطيع تنفيذها بكفاءة بهذه اللغة. يمكنك الاطلاع على بعض عروض العمل الموجودة لمبرمجي c++ على الانترنت مثلاً لأخذ نظرة عن كيف يتم طلب مبرمجي هذه اللغة وما المسؤوليات التي يتم طلبها مع هذه اللغة. أما في حال كان توجّهك لشركة بغض النظر عن لغة البرمجة، يمكنك البحث عن لغات البرمجة أو التقنيات التي تستخدمها هذه الشركة، ثم تقوية نفسك بهذه اللغات أو التقنيات.
    1 نقطة
  22. سلام عليكم ما فائدة الخاصيه : method التي تستخدم معا وسم <form> ذهبت الى ويكي حسوب وا لكني لم افهم ما الفائده منها
    1 نقطة
  23. اذا اتى وقت الامتحان كيف سأرفق المشاريع؟ و هل يجب علي حفظ المعلومات او فهمها؟ برغم انني مشترك في دورة علوم الحاسوب لكن اشعر لا اعرف الكثير من معلومات برغم اكرر المقطع مرتين وانفذ تطبيقات العملية واستمع مايقولي المدرب
    1 نقطة
  24. سوف يتم خلال المسار تعلم كيفية التعامل مع github وهو موقع يسمح لنا بإنشاء مستودعات وحفظ مشاريعنا فيها, انه سهل لا تقلق, من خلال هذه المستودعات سوف يتم النظر ومراجعة المشاريع التي قمت بها, اما بالنسبة للمعلومات لن تحتاج الى حفظها حيث انك مع الممارسة الكثيرة سوف تفهمها جديا وسوف تجد نفسك حفظتها أيضا دون اي مجهود اضافي لحفظها, فقط تحتاج الى المزيد من الممارسة وكتابة الاكواد وفهمها جيدا, أما بالنسبة للمشاعر التي تشعر بها أثناء التعلم لا تقلق منها , نم الطبيعي ان تشعر أنك خائف وأنك لم تفهم الكود بعد, لأنه علم جديد بالنسبة لك ولم تمارسه او تطبقه كثيرا بعد, ولكن بعد مرور فترة من الزمن وممارسته جيدا سوف تجد نفسك انك فهمت الكود وتردي التطوير عليه , لأنك في البداية أرجو منك ان تتمتع بقليل من الصبر وأن تجتهد في فهم الاكواد
    1 نقطة
  25. لدي مساري توجيه ضمن إطار العمل express متشابهين: /posts/:slug/ /articles/:slug/ وقمت بتكرار نفس الكود إلى كل مسار: app.get('/posts/:slug', samecode) app.get('/articles/:slug', samecode) ولكن أرغب بدمج هذه المسارات بحيث يتم تنفيذ نفس الكود عند الوصول إلى أي منهما: app.get('/[posts|articles]/:slug', function(req, res, next) { .... }) فكيف يمكنني تحقيق ذلك بدلاً من تكرار الشيفرة البرمجية لكل مسار؟
    1 نقطة
  26. يجب عليك تحديد ماهو المسار الذي ستعمل ضمنه أو ماهي المشاريع التي ستعمل عليها، فلغات وتقنيات تطوير الويب مثلاً تختلف عن تطوير تطبيقات الجوال وهي أيضاً تختلف عن تطوير تطبيقات سطح المكتب وهكذا. وحتى ضمن هذه المسارات يوجد عدّة فروع ولكل منها يتم استخدام تقنية أو لغة برمجة معيّنة لأداء مهام معيّنة. فتعدد لغات البرمجة هو بسبب أن لكل منها إيجابيات وسلبيات فيما يتعلّق ببعض الخصائص، وبالتالي يلجأ المبرمج إلى استخدام لغات البرمجة التي تساعده على إكمال مشروعه. في حال كانت لغة البرمجة لديك قادرة على تنفيذ جميع الخصائص التي ستعمل عليها، نعم يمكنك استخدام لغة برمجة واحدة وكثيراً ما نجد شركات تطلب متخصّص في لغة برمجة معيّنة وحتى بمكتبة أو حزمة برمجية معيّنة. أما بالنسبة للغة الأكثر طلباً فذلك يعود إلى المسار الوظيفي، يمكنك البحث على الانترنت مثلاً عن لغات البرمجة الأكثر طلباً في تطوير الويب وستجد مثلاً PHP و python و جافاسكريبت وغيرها..، ولكن لا يمكنك مقارنة لغة أكثر طلباً في تطوير الويب مع لغة أخرى في مجال مختلف تماماً، لأن النتيجة لن تكون دقيقة عندها. وفي النهاية لغات البرمجة والتقنيات في تحديث مستمر، ويجب عليك تحديد غايتك من استخدام لغة البرمجة وما نوعية المشاريع التي تفضّل العمل عليها قبل تحديد لغة البرمجة. ثم البقاء على اطلاع على مايجري من تحديثات في اللغة التي تستخدمها وما التقنيات التي يتم استخدامها
    1 نقطة
  27. هل يمكن تحويل رقم روماني الي عشري دون استخدام if
    1 نقطة
  28. لقد حاولت إضافة ملفات تعريف الارتباط في إطار العمل express كما موجود في التوثيق من خلال: app.use(express.cookieParser('secretKey')); وأيضاً حاولت التالي: res.cookie('cookieKey', 'cookieValue', {signed: true}) ولكن لم ألاحظ أي فرق من طرف المستخدم فما زالت ملفات تعريف الارتباط تظهر دون تشفير، فما هو الفرق الحقيقي مع إضافة signed: true إلى ملفات تعريف الارتباط ؟
    1 نقطة
  29. إن res.send بالفعل تقوم بإرسال الرد response وإغلاق الاتصال HTTP ولكن لا تقوم بإجراء أي شيء إضافي إلى الكود الذي يتبعها، حيث يمكنك إجراء أي عمليات برمجية بعد هذا السطر دون أي تأثير. ولكن لن تتمكّن من إجراء أي عمليات على الغرض res لأن الطلب تم إنهائه وإرسال الرد إلى المستخدم وبالتالي لا يمكنك إضافة أي بيانات أو معالجتها بعد إرسال هذا الرد، كما لا يمكنك إضافة أي ترويسة أو خصائص إضافية للطلب، مثلاً: res.send(...); res.write('test'); // سيعطي خطأ وإن هذا النمط مختلف عن بقية أطر العمل مثل PHP و ASP.NET وغيرها من أطر العمل التي تقوم بتعيين مسلك thread لكل طلب HTTP وتقوم بإنهاء هذا المسلك عند انتهاء الطلب. فمثلاً في حال قمت باستدعاء التابع Response.End في ASP سيقوم بإيقاف المسلك الموافق لهذا الطلب وبالتالي سيتوقف الكود البرمجي عن المتابعة. أما في node.js فلا يوجد مسلك محدد لكل طلب وبالتالي لن يتم إيقاف تنفيذ الكود الذي يتبع إرسال الطلب وإنهائه أو أي عمليات قد تجري من بعده طالما ليست متعلّقة بالعرض req و res.
    1 نقطة
  30. إن الخطأ App crashed لا يعطي أي تفاصيل عن نوع الخطأ أو ما السبب الذي أدى إلى توقّف عمل الخادم. يجب عليك قراءة ملفات logs لديك لمشاهدة الأخطاء التي يتم إظهارها من قبل مشروعك وتحديد المشكلة بشكل أدق وإعادة تشغيل الخادم من خلال: heroku restart ولكن من بعض أسباب ظهور هذه المشكلة هو كتابة المنفذ port بشكل يدوي، لأن heroku يقوم بإضافة المنفذ من قبله بشكل أوتوماتيكي، ففي حال كنت قد كتبت رقّم معيّن يجب عليك استبداله بإضافة قيمة process.env.PORT بالشكل التالي: app.listen(process.env.PORT || 5000, function(){ console.log("server running.."); }); كما في بعض الأحيان قد تحدث هذه المشكلة نتيجة سوء توافق بين نسخ الحزم أو إصدارات node.js لذلك يجب عليك التأكد من أن لديك نسخة node.js محدّثة تتوافق مع النسخة التي تم استخدامها في مشروعك والموجودة على الاستضافة: node --version وأخيراً تأكد من قيم متغيّرات البيئة لديك في حال كنت تملك أكثر من قيم لبيئة التطوير وبيئة النشر، وأي أخطاء أخرى يمكنك أن تجدها ضمن سجلات logs.
    1 نقطة
  31. ملفات تعريف الارتباط الموقّعة أو (signed) ستبقى تظهر في طرف المستخدم، إلا أنها ستكون مرفقة بتوقيع لاكتشاف في حال حاول المستخدم التعديل عليها. حيث يتم إنشاء توقيع باستخدام HMAC لقيمة ملفات تعريف الارتباط cookie value الحالية وترميزها من خلال base64 وعندما يتم قرائتها يتم قراءة هذا التوقيع وحساب التوقيع الذي تم إنشائه لهذه القيمة في حال كانا غير متطابقين أي يوجد تعديلات على قيمتها يتم إعادة خطأ. أما في حال كنت ترغب بإخفاء محتوى ملفات تعريف الارتباط فيجب عليك إما تشفير محتوياتها أو تخزينها من طرف الخادم بدلاً من طرف المستخدم، ويوجد بعض الحزم والآليات التي يمكنك اتباعها لتحقيق ذلك في express.js مثل cookie-session الموجودة ضمن التوثيق الرسمي في إطار العمل express، حيث يمكنك تحميلها بالشكل التالي: npm install cookie-session ومثال عن استخدامها من التوثيق الرسمي: var cookieSession = require('cookie-session') var express = require('express') var app = express() app.use(cookieSession({ name: 'session', keys: [/* secret keys */], maxAge: 24 * 60 * 60 * 1000 })) لإنشاء ملفات تعريف الارتباط التي يتم ارفاقها مع التوقيع signed: res.cookie('key', 'value', {signed: true}) ويتم الحصول عليها وقرائتها من خلال الغرض sigendCookie الموجود ضمن الطلب req: req.signedCookies['key']
    1 نقطة
  32. شكرا اخي الفاضل لكن تتبقى المشكلة الأكبر وهي توقف الرسائل ( القائمة المنسدلة - الاشعارات - ظهور الرسائل في صندوق عرض الرسائل ) اذا اردت التجريب فكلمات السر هي 123456 للمستخدم ahmed و ali شكرا مرة اخرى واشكرك مرة اخرى
    1 نقطة
  33. يمكنك القيام بذلك بالشكل التالي في باندا: df = df.astype(object).where(pd.notnull(df),None) ويمكنك استبدال nan بـ None في مصفوفة numpy الخاصة بك من خلال استخدام التابع np.where حيث نمرر له كوسيط أول القيمة المعادة من تطبيق التابع np.isnan على المصفوفة الخاصة بك، ثم القيمة المراد الاستبدال بها، ثم المصفوفة: arr = np.array([4, np.nan]) arr = np.where(np.isnan(arr), None, arr) # [4.0 None] print type(arr[1]) #<type 'NoneType'> كما ويمكنك القيام بذلك بسهولة من خلال التابع replace في باندا: df = df.replace({np.nan: None}) وللتحويل من none ل nan: import numpy as np x = np.array([3,4,None,55]) x = np.array(x,dtype=float) x #array([ 3., 4., nan, 55.]) # أو x = np.array(x) x.astype(float) #array([ 3., 4., nan, 55.])
    1 نقطة
  34. اذا كانت شكل المصفوفة على هيئة numpy ، يمكنك استخدام الدالة التالية: numpy.nan_to_num(x, copy=True, nan=0.0, posinf=None, neginf=None) والتي تقوم باخذ مصفوفة بها قيم nan وتحويلها لاي قيم تريدها. اما عن تبديل القيم nan الي none فلا توجد طريقة مباشره من Numpy، فقط يجب عليك تحويلها الي dataframe وذلك لنستطيع استخدام المكتبة pandas. يمكن استخدام الدالة pandas.notnull(obj) للقيام بمثل تلك عملية التحويل، لفهم كيفية استخدامها انظر المثال التالي: >>> array = np.array([[1, np.nan, 3], [4, 5, np.nan]]) >>> array array([[ 1., nan, 3.], [ 4., 5., nan]]) >>>pd.notna(array) array([[ True, False, True], [ True, True, False]]) اما عن حالتك فيمكنك استخدام الدالة كالتالي: df1 = df.astype(object).replace(np.nan, 'None') أو استخدام الدالة التالية: >>> df1 = df.where(pd.notnull(df), None) >>> df1 0 0 1 1 None
    1 نقطة
  35. إن المشكلة بسبب التنسيقات، حيث أن جميع مكونات الصفحة في نفس المستوى العمودي (هي ليست فوق بعضها) بل أسفل بعضها.. وعندما يقوم المتصفح بتبديل الصورة تظهر فوق مكون آخر ثم تختفي .. هذا الوقت يقوم فيه المتصفح بإصلاح المشكلة بعد رسم الصفحة مرة أخرى.. الحل بايتخدام خاصية z-index التي تسمح لنا بتموضع العناصر فوق بعضها بالترتيب .. عليك وضع قيمة لكل من العنصرين: .header_table{ ... z-index: 10; } .navb_table{ ... z-index: 10; } ملحوظة : لايعمل التعليق الخاص ب HTML والذي هو : <!-- comment --> داخل الوسم style بل نستخدم التعليق الخاص ب CSS: <style type="text/css"> /* .header_table{ width:100%; .... } */ </style>
    1 نقطة
  36. يمكنك استخدام where، ومن الجدير بالذكر أنه يمكنك القيام بذلك في الباندا: df1 = df.where(pd.notnull(df), None) ملاحظة: يؤدي هذا إلى تغيير نوع dtype لجميع الأعمدة إلى النوع object. مثال: In [1]: df = pd.DataFrame([1, np.nan]) In [2]: df Out[2]: 0 0 1 1 NaN In [3]: df1 = df.where(pd.notnull(df), None) In [4]: df1 Out[4]: 0 0 1 1 None ملاحظة: ما لا يمكنك القيام به هو إعادة صياغة إطارات البيانات dtype للسماح لجميع أنواع البيانات ، باستخدام astype ، ثم دالة إطارالبيانات fillna : df1 = df.astype(object).replace(np.nan, 'None') لسوء الحظ ، لا يعمل هذا ، ولا يستخدم replace، مع None. من الجدير بالذكر أنه في معظم حالات الاستخدام لا تحتاج إلى استبدال NaN بـ None.
    1 نقطة
  37. نعم توجد اختلافات بينهم تجعل كل مكتبة فيهم مميزه في شئ ما، اختصارا هذة هي ممميزات كل مكتبة منهم: numpy : هي مكتبة تتعامل مع الاشكال الرياضية للمصفوفات والعمليات الحسابية عليها، لذلك فهي مهمة في عمليات الحسابات الكبيرة والتي تتضمن الكثير من الرياضيات وتكون مميزة خاصة في المصفوفات. pandas : مكتبة تعتبر تمثيلا قريبا لبرنامج excel على بايثون، حيث انها توفر اشكالا سهلة وبسيطة سواء للتعامل او للقراءه للبيانات وكذلك العمليات الرياضية البسيطة التي توضح معالجة للبيانات بشكل سهلة وواضح. كذلك فانها تعتمد على شكل dataframe والذي يجعل شكل البيانات سهلا وواضحا للقراءة، لذا فهي اكثر المكتبات استخداما في مجال تحليل البيانات. scipy: يحتوي SciPy على جميع الوظائف الجبرية التي يوجد بعضها في NumPy إلى حد ما وليس في شكل كامل. بصرف النظر عن ذلك ، هناك العديد من الخوارزميات العددية المتاحة غير الموجودة بشكل صحيح في NumPy.لذلك فهي تستخدم بشكل اكبر ليس في تنظيم البيانات وانما في العمليات الجبرية او الخوارزمية عليها، لذلك فهي تستخدم في الذكاء الاصطناعي لاحتوائها على دوال كثيرة تستخدم فيها مثل random forest.
    1 نقطة
  38. يؤدي تكرار مصفوفة كصف باستخدام NumPy إلى ظهور مصفوفة ثنائية الأبعاد جديدة بحيث يكون كل صف هو المصفوفة الأصلية. ينتج عن تكرار مصفوفة كعمود مصفوفة ثنائية الأبعاد جديدة بحيث يكون كل عمود هو المصفوفة الأصلية. أول طريقة لتنفيذ ماتطلبه هي استخدام دالة np.repeat بالشكل التالي، حيث نمرر لها المصفوفة والمحور الذي نريد التكرار عليه وعدد التكرارات: import numpy as np array_2d = np.array([[1,2,3]]) # سيتم تكرار عناصر المصفوفة على طول الصفوف أي إلى أسفل. np.repeat(array_2d,repeats=3,axis=0) """ array([[1, 2, 3], [1, 2, 3], [1, 2, 3]]) """ arr = np.array([[1],[2],[3]]) # ًفي هذه الحالة، إذا كنت ستستخدم المحور = 1 ، فسيتم تكرار العناصر مع الأعمدة أي أفقيا np.repeat(arr,repeats=3,axis=1) """ array([[1, 1, 1], [2, 2, 2], [3, 3, 3]]) """ يمكنك أيضاً استخدام الدالة numpy.tile حيث نمرر لها المصفوفة وعدد مرات التكرار ك tuple أي بالشكل (n, 1) حيث تمثل n عدد مرات التكرار. والنتيجة ستكون تكرار المصفوفة أحادية الأبعاد الممررة للدالة tile على المحور العمودي. (أي التكرار كأسطر). an_array = np.array([1,2,3]) # عدد مرات التكرار repeat = 3 np.tile(an_array, (repeat, 1)) """ array([[1, 1, 1], [2, 2, 2], [3, 3, 3]]) """ أما لو أردت التكرار كأعمدة كما في الحالة الثانية يمكنك استخدام numpy.transpose بالشكل التالي: an_array = np.array([[1],[2],[3]]) # عدد مرات التكرار repeat = 3 np.transpose([an_array] * repeat) """ array([[[1, 1, 1], [2, 2, 2], [3, 3, 3]]]) """ وأخيراً يمكنك استخدام التابع np.broadcast_to بحيث نمرر له المصفوفة والأبعاد الجديدة وهو سيتكفل بالتكرار كما في المثال التالي : an_array = np.array([[1],[2],[3]]) np.broadcast_to(an_array, (3, 3)) """ array([[1, 1, 1], [2, 2, 2], [3, 3, 3]]) """ an_array = np.array([1,2,3]) np.broadcast_to(an_array, (3, 3)) """ array([[1, 2, 3], [1, 2, 3], [1, 2, 3]]) """
    1 نقطة
  39. بوجة عام، لان شكل المصفوفة عندك ثنائية الابعاد، اي انها صفوف واعمدة فقط، فيمكنك استخلاص الاعمدة من 1 ل 3 كالتالي: X = data[:, [1, 3]] وبشكل عام، استخلاص اي حجم من الصفوف يتم على الشكل التالي: x = data [[#1:#last] , [#1,#last]] حيث أن اول array تمثل الصفوف التي تريد تقطيعها بينما ابثانية تمثل الاعمدة ، كذلك #1 هي اول صف او عمود تريد اخذه بينما #last هو اخر صف او عمود تريد اخذه. وتعني العلامة : الى اخذ كل الصفوف او الاعمدة على حسب المكان الذي توضع فيه.
    1 نقطة
  40. يمكنك ببساطة استخدام الدالة numpy.repeat من اجل تكرار عناصر معينة بالشكل الذي تريدة سواء كان افقيا او راسيا. انظر المثال التالي للتوضيح: >>> np.repeat(3, 4) array([3, 3, 3, 3]) >>> x = np.array([[1,2],[3,4]]) >>> np.repeat(x, 2) array([1, 1, 2, 2, 3, 3, 4, 4]) >>> np.repeat(x, 3, axis=1) array([[1, 1, 1, 2, 2, 2], [3, 3, 3, 4, 4, 4]]) >>> np.repeat(x, [1, 2], axis=0) array([[1, 2], [3, 4], [3, 4]]) حيث أن axis تمثل الاتجاة الراسي او الافقي بحيث x=0 تعني تكرارا في الاتجاة الراسي و axis =1 تعني تكرارا في الاتجاه الافقي. كذلك يمكنك استخدام طريقة ذكية كالتالي: >>> array([[1,2,3],]*3) array([[1, 2, 3], [1, 2, 3], [1, 2, 3]]) >>> array([[1,2,3],]*3).transpose() array([[1, 1, 1], [2, 2, 2], [3, 3, 3]])
    1 نقطة
  41. أفترض أنك أردت العمودين 1 و 3, لتحديد عدة أعمدة مرة واحدة ، استخدم X = data[:, [1, 3]] أما لتحديد واحد في كل مرة استخدم x, y = data[:, 1], data[:, 3] يمكنك فعل ذلك أيضا باستخدام الأسماء كالتالي data[:, ['Column Name1','Column Name2']] يمكنك الحصول على الأسماء من خلال data.dtype.names
    1 نقطة
  42. pandas: إنها مكتبة مفتوحة المصدر ومرخصة من BSD مكتوبة بلغة Python. توفر Pandas هياكل بيانات وأدوات تحليل بيانات عالية الأداء وسريعة وسهلة الاستخدام لمعالجة البيانات الرقمية والسلاسل الزمنية. تم إنشاء Pandas على مكتبة numpy ومكتوبة بلغات مثل Python و Cython و C. في الباندا ، يمكننا استيراد البيانات من تنسيقات ملفات مختلفة مثل JSON و SQL و Microsoft Excel وما إلى ذلك. مثال: # استيراد المكتبة import pandas as pd # تهيئة وإنشاء قائمة متداخلة age = [['Aman', 95.5, "Male"], ['Sunny', 65.7, "Female"], ['Monty', 85.1, "Male"], ['toni', 75.4, "Male"]] #DataFrame إنشاء df = pd.DataFrame(age, columns=['Name', 'Marks', 'Gender']) Numpy: إنها المكتبة الأساسية للبايثون، وتستخدم لتنفيذ عمليات الحوسبة العلمية. يوفر مصفوفات وأدوات متعددة الأبعاد عالية الأداء للتعامل معها. المصفوفة الرقمية هي شبكة من القيم (من نفس النوع) مفهرسة بواسطة مجموعة من الأعداد الصحيحة الموجبة، والمصفوفات غير المتقاربة سريعة وسهلة الفهم ، وتمنح المستخدمين الصلاحية في إجراء العمليات الحسابية عبر المصفوفات. ويعتمد عليها كثيرٌ من العلماء والباحثين في إجراء العمليات الحسابية الكبيرة والمعقدة على بياناتهم وفي اختباراتهم العلمية. مثال: # استيراد المكتبة import numpy as np # 3-D numpy array using np.array() org_array = np.array([[10, 1, 77], [5, 0, 4]]) عندما يتعين علينا العمل على البيانات الجدولية ، فإننا نفضل وحدة الباندا. عندما يتعين علينا العمل على البيانات العددية ، فإننا نفضل الوحدة النمطية numpy. أدوات الباندا القوية هي Dataframe و Series. في حين أن الأداة القوية لـ numpy هي Arrays. تستهلك الباندا المزيد من الذاكرة. نمباي أكثر فعالية في التعامل مع الذاكرة. تتمتع Pandas بأداء أفضل عندما يكون عدد الصفوف 500 ألف أو أكثر. يتمتع Numpy بأداء أفضل عندما يكون عدد الصفوف 50 ألفًا أو أقل. تعد فهرسة سلاسل الباندا بطيئة جداً مقارنةً بمصفوفات نمباي. تعد الفهرسة في مصفوفات نمباي سريعة جداً. تقدم Pandas كائنات تمثل جدول ثنائي الأبعاد يسمى DataFrame. Numpy قادر على توفير مصفوفات متعددة الأبعاد. نمباي تقدم لك عمليات سريعة وبكفاءة عالية عند التعامل مع المصفوفات، وإستخدام أمثل للمصادر عند المعالجة. وتعتمد عليها كثير من المكتبات الأخرى مثل Pandas و theanets وغيرهما. يوفر باندا وظائف كثيرة مثل: data alignment و NA-friendly statistics و groupby و merge و join والعديد من الأدوات الأخرى المريحة، التي أصبحت شائعة جداً في السنوات الأخيرة في التطبيقات المالية. وأيضاً في تعلم الآلة. وتقدم المكتبة ما يسمى ب إطار البيانات (Data Frame) والذي يسهل من إستيراد البيانات والتعامل معها بسهولة. و تسهل المكتبة عمليات (Data Preprocessing ) مثل تنظيف البيانات، ومعالجة القيم الفارغة فيها، وإجراء العمليات الإستكشافية على البيانات. وتسهل دمج البيانات ببعضها أو تجزيئها إلى إطارات متعددة. أما بالنسبة لمكتبة SciPy فبشكل مختصر مكتبة (SciPy) هي نفس مكتبة (NumPy) تقريباً وهي أيضاً من بين المكتبات الاساسية للحسابات العلمية وخوارزميات الرياضيات والدوال المعقدة. ولكنها مبنية كأمتداد لمكتبة (NumPy) مما يعني أنهما يستخدمان سوية في أغلب الاحيان. تأتي هذه المكتبة على رأس هرم مكتبات علم البيانات بالبايثون ، وتخدم جانب تحليل البيانات و تعليم الالة بشكل قوي، ولا تقتصر على ذلك، حيث تقدم إمكانات هائلة في مجال معالجة الإشارات ومعالجة الصور والعمليات الحسابية المعقدة. تتكون وتعتمد مكتبة Scipy على خليط من المكتبات المشهورة مثل Numpy, Pandas, Matplotlib, Sympy, IPython وغيرها. تُقدم المكتبة مجموعة واسعة من الخوارزميات والحزم العلمية التي لها علاقة بالأخص بالعمليات الرياضية، الدوال الإحصائية وتعليم الألة. ومن ميزاتها أنها تقدم دوال واسعة في مجال الاحتمالات والإحصاء عبر موديول stats. وتدعم عمليات الجبر الخطي و Fourier transform. وتقدم المكتبة مجموعة من الدوال الخاصة بمعالجة المصفوفات متعددة الأبعاد لمعالجة الصور. وإجراء التحليل المكاني (Spatial Analysis) عبر مجموعة من الخوارزميات المتخصصة الموجودة في موديول spatial.
    1 نقطة
  43. مرحبا عبد الله، انا إسماعيل متخرج من الأكادمية من دورة تطوير تطبيقات الويب بلغة php، الدورة مشروحة بلغة عربية فصحى و مفهومة كما يمكنك تسريع سرعة الصوت او تخفيضه إن لم تستوعب جزء ما. تبدأ الدورة بشرح الأساسيات في لغة php و إطار العمل لارافيل، ثم يوجد عدة مسارات في كل مسار يتم بناء مشروع و ما أعجبني أنه في كل مسار يتم الشرح مِن قبل أستاذ آخر فإذا لم تفهم أو لم تستوعب طريقة الشرح في مسار ما ستفهم في آخر. بالإضافة الى انه يوجد مدربين ذو خبرة و يمكنك سؤالهم عن أي شيئ سواء اسفل الدرس او القسم الخاص بالأسئلة. بالنسبة لسؤالك الثاني قد تختلف المدة من شخص لآخر و حسب قدرة كل شخص في الفهم، لكن ما أنصحك به أن لا تركز على الوقت بل ركز على فهم الأساسيات جيدا و البحث عن الحلول للمشاكل التي تواجهك بنفسك قبل سؤال المدربين مباشرة. ارجو لك التوفيق.
    1 نقطة
×
×
  • أضف...