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

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

  1. سامح أشرف

    سامح أشرف

    الأعضاء


    • نقاط

      14

    • المساهمات

      2934


  2. إياد أحمد

    إياد أحمد

    الأعضاء


    • نقاط

      6

    • المساهمات

      92


  3. Mohssen A Mohssen

    Mohssen A Mohssen

    الأعضاء


    • نقاط

      4

    • المساهمات

      317


  4. شرف الدين حفني

    • نقاط

      3

    • المساهمات

      1690


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

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

  1. كيف يمكنني التحقق من وجود كلمة في جملة معينة بإستخدام لغة ++C، فعلى سبيل المثال لدي المتغيرين التاليين: std::string s1 = "Hello, world"; std::string s2 = "world"; كيف يمكنني التحقق برمجيًا من أن المتغير s1 يحتوي على قيمة المتغير s2؟ في لغات أخرى مثل Python يمكنني إستعمال المعامل in للتحقق من هذا الأمر، كيف أقوم بنفس الشيء في لغة ++C؟
    2 نقاط
  2. أقوم باستخراج بعض البيانات من إحدى صفحات الويب، وقد قمت بتحليل إحدى أكواد ال HTML بالشكل التالي: spage = bs(urlopen(URL)) b = spage.body.find('div', 'class'='badges') print(b) # حصلت على الخرج التالي: """ <span> <span title="9 gold badges"><span class="badge1"></span> <span class="badgecount">9</span></span> <span title="38 silver badges"><span class="badge2"></span> <span class="badgecount">38</span></span><span title="56 bronze badges"><span class="badge3"></span> <span class="badgecount">56</span></span></span> """ الآن أريد استخراج 56 bronze badges و 9 gold badges و 38 silver badges منها؟
    2 نقاط
  3. كتبت الكود التالي للحصول على البيانات من جدول ب ID محدد: from bs4 import BeautifulSoup hDoc = br.response() soup = BeautifulSoup(hDoc.read(),'html') table = soup.find(lambda tag: tag.name=='table' and tag.has_key('id') and tag['id']=="HistoryData1") rows = table.findAll(lambda tag: tag.name=='tr') وهذا هو المقطع من كود HTML: <table cellspacing="0" cellpadding="3" border="0" id="HistoryData1" style="width:100%;border-collapse:collapse;"> <tr class="gridHeader" valign="top"> <td class="titleGridRegNoB" align="center" valign="top"><span dir=RTL>ballov</span></td> <td class="titleGridReg" align="center" valign="top">Grand</td> <td class="titleGridReg" align="center" valign="top">andera</td> <td class="titleGridReg" align="center" valign="top">colofisiaky</td> <td class="titleGridReg" align="center" valign="top">tochy</td><td class="titleGridReg" align="center" valign="top"><span dir="rtl"> (laesd)</span></td> <td class="titleGridReg" align="center" valign="top">שער נעילה מתואם</td><td class="titleGridReg" align="center" valign="top">kagt</td> </tr> <tr onmouseover="this.style.backgroundColor='#FDF1D7'" onmouseout="this.style.backgroundColor='#ffffff'"> لكن عندما أحاول طباعة الجدول أحصل على None؟ print (table) # None
    2 نقاط
  4. في المستند التالي: <select> <option value="0">1999/9/5</option> <option value="1">2010/9/5</option> <option value="2">2017/9/5</option> <option value="3" selected>220/9/5</option> </select> أريد الحصول على ال option المُختارة فقط (selected). استخدمت الدالة findall لكنها تعيد كل الخيارات؟ .findAll('option',attrs={'selected':''})
    2 نقاط
  5. لديك مُشكلة في المُتغير form حيث إستخدمت الإسم form في تعريفك للمُتغير في الأعلى: const form = document.querySelector("form"); إستخدمت هنا الكلمة المحجوزة const لتعريف المتغير فأصبح ثابت لا يُمكن إستخدام نفس الإسم لتعريف مُتغير بنفس الإسم لذلك عند تعريفك للمُتغير مرة أخرى: var form = document.getElementById("feed-back"); أعطى خطأ وسبب المُشكلة. لحل المُشكلة قم بتغيير إسم المتغير في الأسفل إلى إسم آخر: var feedForm = document.getElementById("feed-back"); و إستعمال نفس الإسم: var feedForm = document.getElementById("feed-back"); async function handleSubmit(event) { event.preventDefault(); var status = document.getElementById("status"); var data = new FormData(event.target); fetch(event.target.action, { method: feedForm.method, body: data, headers: { 'Accept': 'application/json' } }).then(response => { status.classList.add('success'); status.innerHTML = "Thanks We will respond as soon as possible!"; feedForm.reset() }).catch(error => { status.classList.add('error'); status.innerHTML = "Oops! There was a problem submitting your form" }); } feedForm.addEventListener("submit", handleSubmit) أيضاً أنصحك بوضع الأكواد مع بعضهم في الأسفل و نضعهم بداخل: document.addEventListener("DOMContentLoaded", function (event) { }); الملف بعد التعديل: FeedBack.html
    2 نقاط
  6. لو سمحتم أنا الآن ادرس كورس الويب هنا على منصة حسوب باستخدام php laravel وهذا الكورس به 8 مشاريع ، انا أعلم انه من الأفضل أن أنهى الدورة كاملة بعدها أبحث عن عمل ، لكن سؤالى هنا محدد ، سؤالى هنا هل سيكون عندى المهارة الكافية لأستطيع أن أجد عمل فى أى شركة خاصة فى مصر بعد أن انهى مشروعين فقط أو 3 على أقصى تقدير منهم ، وهذا بالتأكيد بعد أن أقوم بانهاء php basics و laravel ، وهذه هى المشروعات التى أقصدها وهم بالترتيب 1- مشروع شبكة إجتماعية تشبه انستجرام , بعدها أدرس Restful API's 2- مشروع cms مشروع online book store
    1 نقطة
  7. كيف أطبع هادا شكل بواسطة دالة for * ** *** **** *****
    1 نقطة
  8. مثلا لدي جدول يحتوي علي عمودين الاسم ورقم الهاتف وفي المتحكم controller قمت بعمل متغير اسمه $ table data يساوي هذا المتغير جدول قاعده البيانات db: table اسم الجدول وقمت بتمرير هذا المتغير من خلال الداله compact كيف أعرض محتوي الجدول في صفحه العرض view .
    1 نقطة
  9. يحتوي النوع string على التابع find والتي يقوم بإرجاع فهرس النص الذي تبحث عنه: #include <iostream> #include <string> int main() { std::string s1 = "Hello, world"; std::string s2 = "world"; // التحقق من وجود قيمة المتغير s2 داخل قيمة المتغير s1 if (s1.find(s2) != std::string::npos) { std::cout << "found '" << s2 << "' in '" << s1 << "'" << '\n'; } return 0; } في حالة وجود النص s2 داخل قيمة المتغير s1 سوف يتم طباعة الجملة found 'world' in 'Hello, world'
    1 نقطة
  10. أنا قد أنهيت مبادئ البرمجه بلغة بايثون ماذا افعل بعد ذلك؟ لكن لا أريد حل اسئله باللغة الانجليزيه لأنني لست متقناً لها
    1 نقطة
  11. حاولت أن أقوم بكتابة أكثر من كود ++C وفي كل مرة يظهر لدي الخطأ التالي: fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add ‘#include "stdafx.h"’ to your source? لا أعرف سبب هذه المشكلة، قمت بتجربة كتابة أكثر من برنامج بسيط، وفي كل مرة يظهر لدي نفس الخطأ. كيف يمكنني حل هذه المشكلة؟ أنا أستعمل Visual Studio 2010
    1 نقطة
  12. أجابتك تعمل على نوع Edit text فقط ولا تتفعل اذا ارسلت القيمة الى Text view من الـ Edit text وكذلك نوع متغير text لديك خاطئ - الي عمل معي ونقلها الى الاديت تيكست هو هذا: String text = "<a href=\"http://www.google.com/\"> Google </a>";
    1 نقطة
  13. أريد أن أعرف المساحة التي يشغلها نوع معين (مثل int أو double) في الذاكرة، فعلى سبيل المثال: النوع int يستغل 4 bytes من الذاكرة. كيف يمكنني أن أتأكد من هذا الرقم؟ وكيف يمكنني معرفة حجم باقي الأنواع في ++C؟
    1 نقطة
  14. في صفحة html لدي كودين جافا سكربت منفصلين عن بعض واحد في الاعلى والاخر في الاسفل لكنهم لايعملو الا عند حذف كود جافا سكربت واحد، عندما احذف كود جافا سكربت الاول يعمل الثاني واذا حذفت الثاني يعمل الاول واذا لم احذف اي احد منهم جميعهم لايعملو.
    1 نقطة
  15. أنا الآن في صدد تطوير تطبيق هاتف، سؤالي عن أفضل طريقة لعمل تأكيد الهاتف النقال بحيث يدخل مستعمل التطبيق هاتفه ليصله كود التأكيد كرسالة قصيرة ماهي أفضل طريقة أو خدمة لعملها وكم سعرها وهل توجد مجانا ؟؟
    1 نقطة
  16. يمكنك استخدام خدمة الفايربيز من قوقل و يمكنك الاطلاع على التوثيق الخاص بها من هنا , و هذه الخدمة توفر لك عدة رسائل مجانية يومياً و بعد بلوغ الحد الأقصى يمكنك الاشتراك في الخطة المدفوعة لكي تستطيع زيادة هذه الرسائل يومياً , أو يمكنك استخدام احدى خدمات SMS Provider مثل nexmo , twillo يمكنك البحث عن هذه الخدمات و مقارنة أسعارها لتختار الأفضل لك.
    1 نقطة
  17. بالإضافة إلى إجابة وائل أردت توضيح بعض الأمثلة التي قد تساعدك على الفهم المقصود بخطأ غير متوقع الذي يرمز إليه الرمز 500 أن الخادم لم يكن مستعدًا لهذا الخطأ وإن كان إستعد له لكانت النتيجة مختلفة, فمثلًا إن أرسل العميل البيانات ناقصة وبالتالي أصبح يوجد بعض البيانات التي قيمتها بnull, في الحالة الطبيعية والصحيحة أن يتأكد الخادم من أنه لا يوجد قيم مخالفة وإن وجد بيانات ناقصة يقوم بإرسال رمز 422 والذي يعبر عن عدم توافق البيانات المُرسلة مع البيانات المطلوبة ولكن بما أن الخادم لم يتأكد من صحة البيانات فيوجد إحتمال كبير أن يحدث runtime error بسبب تلك القيم التي قيمتها null أو undefined وبالتالي يتم إرسال رمز 500 يوجد تشابه بين كلا الرمزين 501 not implemented والرمز 405 method not allowed الفرق يكمن كالتالي الرمز 501 يرمز إلى أن تلك الmethod تم تصميمها في الAPI-design ومن المُفترض دعمها في وقتٍ ما ولكنها في الوقت الراهن غير مدعومة الرمز 405 تعني أن تلك الmethod لم يتم وضعها في الAPI-design من الأساس
    1 نقطة
  18. بالإضافة إلى إجابة وائل أردت توضيح بعض النقاط التي قد تجدها متشابهة أو مُشوشة كلا الرمزين 200 و 201 يعبران عن نجاح العملية ولكن الرمز 200 يتم إستخدامه مع الطلب من النوع GET بينما الرمز 201 يتم إستعماله مع الطلب من النوع POST وذلك لأن الطلب من النوع POST يُستعمل في الأساس لإنشاء موارد جديدة والرمز 201 يُعبر عن نجاح إنشاء تلك الموارد الجديدة الرمز 203 يتم إستخدامه عندما يكون هنالك وسيط(proxy) بين العميل والخادم ويقوم ذلك الوسيط بتعديل الرد فيقوم حينذاك بإرسال ذلك الرمز حتى يعلم العميل أن الرد قد تم تعديله, وأنوه هنا من أنه عادةً لا يُفضل إستخدام ذلك الرمز حيث أنك لا تستطيع معرفة الحالة الأصلية التي أرسلها الخادم, وإنما الأفضل أن تقوم بإرسال رمز 200 مع إدراج warning header يوضح للعميل الرمز الأصلي الرمز 204 قد تلاحظ تشابه بينه وبين الرمز 404 حيث كلا الرمزين يعبران عن عدم توفر بيانات ولكن الفرق يكمن كالتالي: في الرمز 404 يفيد بأن المورد المطلوب غير موجود من الأساس, فمثلًا نبحث عن التعليقات التي قام بها المستخدم ذو المُعرف 5 , ولا يوجد لدينا مُستخدم بذلك المُعرف فحينذاك يتم إرسال 404 في الرمز 204 يفيد بأن المورد موجود ولكن لا يوجد بيانات حتى يتم إرسالها, فمثلًا نبحث عن التعليقات التي قام بها المستخدم ذو المُعرف 5, والمُستخدم ذو المُعرف 5 موجود لدينا بالفعل ولكنه لم يقم بأية تعليقات حتى الأن, في تلك الحالة نقوم بإرسال الرمز 204 الذي يُفيد بعد توفر بيانات لإرسالها ولكن لا يوجد مشكلة في الموارد
    1 نقطة
  19. يمكنك مراسلة مركز المساعدة من هنا ، ثم تفتح تذكرة تخبرهم بما تريد وسيعملون على حل مشكلتك بـ أسرع وقت ممكن .
    1 نقطة
  20. عندما تستخدم موجهة Preprocessor Directive مثل define لتعريف قيمة ثابته مثل MAX_STUDENTS_PER_CLASS فإن هذه القيمة يتم إسبدالها في كل مكان في الملف وستكون النتيجة كالتالي: int max_students { numClassrooms * 30 }; ولكن هذه الطريقة لها العديد من المشاكل، حيث أن الـ Preprocessor لا يفهم صيغة ++C على الإطلاق ويقوم بإستبدال الثابت MAX_STUDENTS_PER_CLASS بالقيمة 30 في كل مكان يجده في الملف بغض النظر عن أي مجال Scope تكون فيه، وبالتالي قد تجد أن القيمة 30 أصبحت في أماكن غير مرغوب فيها مما يسبب بعض الأخطاء أثناء عملية التصريف Compiling. وبما أن الثابت MAX_STUDENTS_PER_CLASS يتم إستبدال قيمته قبل عملية التصريف من قِبل الـ Preprocessor فلا يمكن تتبع هذه القيمة من خلال مصحح الأخطاء debugger الموجود في بيئة التطوير لديك، وبالتالي لا يفضل أن يتم إستعمال هذه الطريقة لأنها قد تعرضك إلى أخطاء منطقية Logical Errors والتي يصعب إكتشاف سببها وحلها. أيضًا قد يتعارض تعريف القيمة من خلال Preprocessor Directive مع الكود نفسه، فعلى سبيل المثال في الكود التالي سوف يتم إزالة كل كلمات beta وإستدالها بالقيمة 3: #define beta 3 #include <iostream> int main() { int beta{ 5 }; std::cout << beta; return 0; } سوف يقوم الـ Preprocessor بتحويل الكود السابق إلى التالي: #include <iostream> int main() { int 3{ 5 }; std::cout << 3; return 0; } لاحظ كيف تم تغير اسم المتغير beta في السطر 5 إلى القيمة 3، وفي بعض الأحيان قد يتم تعريف القيمة beta في ملف آخر مما يجعل من عملية إكتشاف سبب هذه المشكلة صعبًا. وبناءً على ما سبق يفضل إستعمال const أو contexpr بدلًا من define لتفادي الأخظاء السابقة.
    1 نقطة
  21. النوع الأول const عبارة عن ثابت يحمل قيمة من نوع معين، ويكتب على الصيغة التالية: // const const_name = value; cosnt age = 18; وهذا الثابت يتم جسابه وتخزين قيمته أثناء وقت التشغيل Run Time مثل المتغيرات العادية، ولكن لا يمكن تغير قيمته لاحقًا، وبالتالي إن حاولت تنفيذ الكود التالي سوف يظهر لديك خطأ: const int age{123}; age = 18; // Error: expression must be a modifiable lvalue بينما النوع الثاني constexpr هو ثابت أيضًا ولكن يتم حسابه وتخزينه أثناء عملية التصريف Compile Time ويجب أن تكون قيمته محددة بالفعل قبل تشغيل البرنامج حتى، وبالتالي يجب أن تكون قيمته معروفة من البداية، لذلك سوف يظهر لديك خطأ إن حاولت أن تقوم بتنفيذ الكود التالي: int age{}; std::cin >> age; const int myAge{ age }; int age2{}; std::cin >> age2; constexpr int myAge{ age2 }; // Error: age2 is a runtime constant, not a compile-time constant الجزء الأول من الكود سوف يعمل بدون مشكلة، بينما الجزء الثاني سوف تظهر فيه مشكلة تخبرك بأن age2 عبارة عن ثابت يتم حسابه أثناء عملية التنفيذ run time. لذلك نستنتج أنه: يجب التصريح عن أي متغير لا يمكن تعديله بعد التهيئة والذي تمت تهيئته في وقت التصريف على أنه constexpr. يجب التصريح عن أي متغير لا يمكن تعديله بعد التهيئة ومبدئه غير معروف في وقت التصريف على أنه const.
    1 نقطة
  22. تسمح لك تعليمات RUN بتثبيت التطبيقات والحزم المطلوبة وتنفذ الاوامر في طبقة عالية على الصورة المشأة و غالبًا ما ستجد تعليمات RUN متعددة في Dockerfile. تعليمات CMD تسمح لك بتعيين أمر افتراضي والذي سيتم تنفيذه فقط عند تشغيل الحاوية دون تحديد أم إذا تم تشغيل حاوية Docker بأمر فسيتم تجاهل الأمر الافتراضي إذا كان Dockerfile يحتوي على أكثر من تعليمة CMD فسيتم تجاهل تعليمات CMD. لذا الحل هو أن تستعمل run في هذه الحالة بدل cmd
    1 نقطة
  23. يتم تحديد دقة الرقم عند الطباعة حسب المصرّّف نفسه، في الغالب تكون دقة الأرقم 7 أرقام فقط، ويمكن أن تستخدم معالج الإخراج output manipulator المسمى std::setprecision لتعديل دقة الأرقام، في البداية تحتاج إلى إسندعاء ملف الترويسة iomanip لكي تستطيع إستعمال معالج الإخراج std::setprecision، يقبل معالج الإخراج هذا دقة الطباعة (عدد الأرقام التي سيتم طباعتها) كمعامل له. ويمكنك أن تستعمله كالتالي: #include <iostream> #include <iomanip> int main() { std::cout << std::setprecision(10); double x{ 1.234'567'89 }; std::cout << x << '\n'; // 1.23456789 double y{ 123'456'789 }; std::cout << y << '\n'; // 123456789 return 0; } ملاحظة: يفضل أن تفصل الأرقام الكبيرة بإستخدام علامة الإقتباس المفرد ' لتسهيل القراءة فقط، وسيتم معاملة الرقم 789'456'123 على أنه الرقم 123456789 بدون مشكلة.
    1 نقطة
  24. تعرَّف التعابير النمطية بأنها مجموعات من المحارف التي تصف مجموعةً أخرى من المحارف أكبر منها، وهي تصف نمط المحارف الذي نستطيع البحث عنه في متن نص ما، وهي تشبه مفهوم المحارف البديلة wildcards المستخدمة في تسمية الملفات على أغلب نظم التشغيل، حيث يمكن استخدام محرف النجمة * لتمثيل أي تسلسل من المحارف في اسم ملف، ولهذا فإن ‎*.py تعني أي ملف ينتهي بالامتداد ‎.py، بل إن المحارف البديلة ما هي إلا مجموعة فرعية صغيرة من التعابير النمطية. وتدعم أغلب لغات البرمجة الحديثة التعابير النمطية ضمنيًا، أو لديها مكتبات أو وحدات متاحة للاستخدام في البحث عن النصوص واستبدالها وفقًا لتعابير نمطية، وذلك بسبب الإمكانيات الكبيرة لهذه التعابير، لكن شرحها المفصل هو خارج نطاق حديثنا، وستجد مصادر أخرى تتحدث عنها بتوسع شديد، وننصحك هنا بمراجعة كتب مثل كتاب أورايلي في التعابير النمطية وهو باللغة الإنجليزية، إضافةً إلى المقالات الموجودة في أكاديمية حسوب. ولعل إحدى الخصائص المميزة للتعابير النمطية هي أنها تُظهر أوجه التشابه مع البرامج في البنية، فهي أنماط مبنية من وحدات أصغر منها، وتلك الوحدات هي: محارف منفردة. محارف بديلة. نطاقات أو مجموعات من المحارف، أو مجموعات محاطة بأقواس. وبما أن المجموعة نفسها ما هي إلا وحدة، فيمكن أن تكون لدينا مجموعات من المجموعات إلى أن نصل إلى مستوى تعقيد كبير، ونستطيع جمع تلك الوحدات بطرق تشبه استخدام التسلسلات أو التكرارات أو العوامل الشرطية في لغات البرمجة، وسننظر في كل منها في حينه، فإضافةً إلى شرح مفهوم التعابير النمطية، سنعرف كيف نستخدمها في برامج بايثون، وننظر كيف تدعمها لغتا VBScript وجافاسكربت، ولنستطيع تجربة الأمثلة هنا يجب أن نستورد وحدة re ونستخدم التوابع الخاصة بها، وسنفترض أنك استوردتها تلقائيًا دون ذكر ذلك في كل مرة. التسلسلات تسلسلات المحارف لا شك أن أبسط بنية برمجية يمكن تصورها هي تسلسل من المحارف، كما أن أبسط تعبير نمطي ما هو إلا تسلسل من المحارف كذلك: red وهذا سيطابق أو يبحث في سلسلة نصية عن أي حدوث لهذه الأحرف الثلاثة التي تتكون منها كلمة red على الترتيب، وبناءً على ذلك سيجد كلمات مثل red وlettered وcredible، لأنها تحتوي على كلمة red ضمنها. ولنتحكم أكثر في خرج المطابقات، فإننا نوفر بعض المحارف الخاصة التي تُعرف باسم المحارف الوصفية metacharacters للحد من نطاق البحث: 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; } التعبير المعنى مثال ‎^red في بداية السطر فقط red ribbons are good red$‎ في نهاية السطر فقط I love red ‎\Wred في بداية الكلمة فقط it's redirected by post ‎red\W‎ في نهاية الكلمة فقط you covered it already يُطلق على هذه المحارف اسم المرابط anchors لأنها تثبت موضع التعبير النمطي في جملة أو كلمة ما، وهناك عدة مرابط أخرى معرَّفة في توثيق وحدة re يمكنك الاطلاع عليها. المحارف البديلة قد تحتوي التسلسلات على محارف بديلة Wildcard Characters تحل محل أي محرف، والمحرف البديل هو نقطة . جرِّب الشيفرة التالية مثلًا: >>> import re >>> re.match('be.t', 'best') <_sre.SRE_Match object at 0x01365AA0> >>> re.match('be.t', 'bess') تخبرنا الرسالة التي في الأقواس السهمية أن التعبير النمطي 'be.t' -الممرَّر وسيطًا أول- يطابق السلسلة 'best' الممرَّرة وسيطًا ثانيًا، كما يطابق 'beat' و'bent' و'belt' وغيرها، لكن المثال الثاني لا يطابق لأن 'bess' لا تنتهي بحرف t، لذا لا يُنشئ MatchObject. يمكنك تجريب عدة مطابقات أخرى لتفهم كيفية عملها، ولاحظ أن match()‎ لا تطابق إلا في بداية السلسلة النصية، أما لمنتصفها فنستخدم search()‎ كما سنرى لاحقًا. المجالات أو الفئات يتكون المجال range (أو الفئة set) من تجميعة من المحارف المغلَّفة في أقواس مربعة، ويبحث التعبير النمطي عن أي محرف يكون داخل هذه الأقواس: >>> re.match('s[pwl]am', 'spam') <_sre.SRE_Match object at 0x01365AD8> فهذا سيطابق swam أو slam، لكن لن يطابق sham لأن h غير موجودة في فئة التعبير النمطي. أما إذا وضعنا محرف الإقحام ^ أول عنصر في المجموعة، فكأننا نقول أننا نريد البحث عن أي محرف عدا المحارف الموجودة في المجموعة: >>> re.match('[^f]ool', 'cool') <_sre.SRE_Match object at 0x01365AA0> >>> re.match('[^f]ool','fool') وبناءً على ذلك نستطيع مطابقة cool وpool، لكننا لن نطابق fool لأننا نبحث عن أي محرف عدا f في بداية النمط. المجموعات نستطيع جمع تسلسلات من المحارف أو الوحدات الأخرى معًا من خلال تغليفها بأقواس، وهي لا تقوم بدور العزل هنا، بل تفيدنا عند دمجها مع خصائص التكرار والشرطيات التي سنشرحها لاحقًا. التكرار يمكن إنشاء تعابير نمطية تطابق تسلسلات مكررةً من المحارف باستخدام بعض المحارف الوصفية الخاصة، ونستطيع البحث بها عن تكرار محرف واحد أو مجموعة محارف: التعبير المعنى مثال '?' محرف واحد على الأكثر من المحارف السابقة -أي عدد صفر أو واحد من المحارف-، انتبه إلى الجزء الصفري هنا لأنه قد يربكك. pythonl?y يطابق: pythony وpythonly '*' يبحث عن صفر محرف سابق أو أكثر. pythonl*y يطابق ما ذكر في السطر السابق بالإضافة إلى: pythonlly وpythonllly ... إلخ '+' يبحث عن محرف واحد أو أكثر من المحارف السابقة. pythonl+y يطابق: pythonly وpythonlly وpythonllly ...إلخ {n,m} يبحث عن نطاق من التكرارات من n إلى m من المحارف السابقة. { fo{1,2 يطابق : fo أو foo يمكن تطبيق جميع محارف التكرار هذه على مجموعات أخرى من المحارف، وبناءً عليه: >>> re.match('(.an){1,2}s', 'cans') <_sre.SRE_Match object at 0x013667E0> يكون النمط هنا ‎(.an){1,2}s الذي يقول إن لدينا مجموعةً تتكون من أي محرف متبوع بالحرفين an، ونريد أن نجد مجموعةً أو اثنتين متبوعتين بالحرف s، وسيطابق هذا النمط: cancans وpans وcanpans، لكن لن يطابق bananas لانعدام وجود حرف قبل مجموعة an الثانية فيها. جرب تعديل البحث ليطابق bananas. هناك مشكلة واحدة مع نمط التكرار {m,n}، وهو أنه لا يحد المطابقة لعدد n من الوحدات، وعلى ذلك سيطابق مثال {fo{1,2 الذي في الجدول السابق fooo لأنه يطابق foo في بداية fooo، وعليه فإذا أردنا الحد من عدد المحارف المطابَقة، فسنحتاج إلى أن نُتبع تعبير الضرب بمرساة أو نطاق نفي negated range. وفي حالتنا، فإن [fo{1,2}[^o سيمنع fooo من المطابقة بما أنه يقول طابق حرف o واحد أو حرفين متبوعين بأي شيء غير o، لكن يجب أن يكون متبوعًا بشيء ما، لذا فإن foo لم تَعُد مطابقةً الآن. يوضح هذا الطبيعة المتقلبة للتعابير النمطية، فقد يصعب ضبطها للحصول على الخرج الذي نريده، ويجب أن نضعها تحت اختبارات فاحصة لتجنب الأخطاء. أما النمط الفعلي المطلوب للسماح بمطابقة foo وfoobar مع استثناء fooo، فهو ‎'fo{1,2}[^o]*$'‎، وهذا يعني fo أو foo المتبوعين بعدد صفر أو أكثر من حروف o ونهاية السطر، وفي الواقع حتى هذا النمط ليس تامًا وخاليًا من الأخطاء -جرب fooboo مثلًا-، لكن نحتاج أن نشرح بعض العناصر الأخرى قبل أن نحسّنه ونعدل فيه. التعابير الجشعة يقال إن التعابير النمطية جشعة، أي أن دوال البحث والمطابقة ستطابق كل ما تستطيعه من السلسلة النصية، بدلًا من التوقف عند أول مطابقة تامة، وهذا لا يهم غالبًا، لكننا سنحصل على مطابقات أكثر من المطلوب عند جمع المحارف البديلة مع عوامل التكرار. لننظر في المثال التالي: إذا كان لدينا تعبير نمطي مثل a.*b الذي يقول إننا نريد إيجاد a متبوعًا بأي عدد من المحارف إلى أن نصل إلى حرف b، فستبحث دالة المطابقة من أول a إلى آخر b، مما يعني أنه إذا احتوت سلسلة البحث على أكثر من b فستُضمَّن جميعًا في الجزء‏ ‎*. من التعبير عدا آخر واحدة، وعليه: re.match('a.*b','abracadabra') فقد طابق MatchObject في هذا المثال كل abracadab وليس أول ab فقط، وسلوك المطابقة الجشع هذا هو أكثر الأخطاء التي يرتكبها المبرمج في بداية استخدامه للتعابير النمطية، ولمنع هذا السلوك الجشع نضيف '?' بعد محرف التكرار، كما يلي: re.match('a.*?b','abracadabra') مما سيطابق ab فقط. الشرطيات يتبقى لدينا الآن أن نجعل التعبير النمطي يبحث في عناصر اختيارية أو يختار نمطًا من بين عدة أنماط، وسننظر في كل منها على حدة. العناصر الاختيارية يمكن تحديد محرف ما ليكون اختياريًا باستخدام عدد صفر أو أكثر من محارف التكرار الوصفية: >>> re.match('computer?d?', 'computer') <re.MatchObject instance at 864890> هذا سيطابق compute وcomputer وcomputed، كما سيطابق computerd، لكننا لا نريد هذه الأخيرة، لذا سنضيق النطاق الذي نريده كما يلي: >>> re.match('compute[rd]$','computer') <re.MatchObject instance at 874390> وهذا سيختار computer وcomputed فقط، ويرفض computerd، وإذا أضفنا ? بعد هذا النطاق فسنسمح باختيار compute مع تجنب computerd أيضًا. التعابير الاختيارية بالإضافة إلى خيارات المطابقة من قائمة محارف السابقة الذكر، يمكن المطابقة بناءً على اختيار من تعابير فرعية، فقد ذكرنا سابقًا أننا نستطيع جمع تسلسلات من المحارف في أقواس، لكن الواقع أننا نستطيع جمع أي تعبير نمطي عشوائي بين أقواس ومعاملته مثل وحدة، وسنستخدم الصيغة (RE) أثناء شرح التركيب اللغوي هنا للإشارة إلى أي تجميع لتعابير نمطية، والحالة التي نريد دراستها هنا هي مطابقة تعبير نمطي يحتوي على ‎(RE)xxxx أو ‎(RE)yyyy حيث تكون xxxx وyyyy أنماطًا مختلفةً، وبناءً عليه فإذا أردنا مطابقة premature وpreventative فسنفعل هذا بواسطة محرف الاختيار الوصفي |: >>> regexp = 'pre(mature|ventative)' >>> re.match(regexp,'premature') <re.MatchObject instance at 864890> >>> re.match(regexp,'preventative') <re.MatchObject instance at 864890> >>> re.match(regexp,'prelude') نلاحظ أنه عند تعريف التعبير النمطي تعين علينا أن ندرج النص الكامل لكلا الخيارين داخل أقواس بدلًا من (e|v)، ولو لم نفعل لاقتصر الخيار على prematureentative وprematurventative فقط، أي كان الحرفان فقط هما اللذان سيمثلان الخيارات المتاحة، وليس المجموعات كلها. نستطيع الآن باستخدام هذه التقنية أن نعود إلى المثال أعلاه الذي أردنا فيه التقاط fo أو foo وتجنب التقاط fooo إضافةً إلى أي شيء يأتي بعدها، وقد تركناها مع تعبير نمطي يتكون من fo{1,2}[^o]*$‎، والمشكلة هنا أن التطابق سيفشل إذا احتوت السلسلة النصية التالية لـ fo أو foo على o، لكن يمكن الالتفاف على ذلك باستخدام عدة خيارات من التعبيرات، ونريد أن ينجح التطابق سواء كان النمط في نهاية السطر أو متبوعًا بأي حرف سوى o، وسيبدو ذلك كما يلي: fo{1,2}($|[^o]) والذي سيعطينا أخيرًا ما نريده، تجدر الإشارة إلى أنه يجب تنفيذ اختبارات كافية عند استخدام التعابير النمطية، لضمان عدم التقاط أي شيء غير مرغوب فيه، وأننا نلتقط كل ما نريد التقاطه. المزيد من الملاحظات حول التعابير النمطية تحتوي وحدة re على مزايا كثيرة لم نذكرها هنا، يجدر النظر فيها ودراستها من توثيق الوحدة نفسها، لكننا نريد تسليط الضوء على مجموعة من الرايات flags التي يمكن استخدامها عند تصريف التعبيرات مع دالة re.compile()‎، والتي تتحكم في أمور مثل مطابقة النمط في الأسطر المختلفة، أو تجاهله لحالة الأحرف، أو غير ذلك. ومن المهم استخدام أداة تختبر التعابير النمطية للتحقق من نتائجها، وتوجد أدوات عديدة منها على الويب، لكن نخص بالذكر منها أداة regex101، حيث نكتب فيها تعبيرًا نمطيًا وسلسلة اختبار، ثم نرى الأجزاء التي طابقها التعبير من السلسلة النصية، وهذه الأداة تحديدًا تعطينا وصفًا مفيدًا عما يفعله التعبير النمطي، وتسمح لنا باختيار أصناف فرعية للمطابَقات الناتجة، وغيرها من المزايا المفيدة. استخدام التعابير النمطية في بايثون رأينا في السطور السابقة شيئًا يسيرًا من التعابير النمطية، ونريد أن نطبق ذلك في بايثون، حيث نستطيع استخدامها أداة بحث قويةً جدًا في النصوص، إذ يمكن البحث عن صور كثيرة مختلفة لسلاسل نصية في عملية واحدة، بل يمكن البحث عن المحارف التي لا تُطبع مثل الأسطر الفارغة باستخدام بعض المحارف الوصفية المتاحة، كما يمكن استبدال هذه الأنماط باستخدام التوابع والدوال الخاصة بوحدة re، كما رأينا في دالة match()‎ أعلاه، وفيما يلي بعض الدوال الأخرى المتاحة: الدالة - التابع التأثير (match(RE,string يعيد كائن مطابقة إذا طابق التعبير النمطي بداية السلسلة. (search(RE,string يعيد كائن مطابقة إذا وُجد تعبير نمطي في أي مكان في السلسلة النصية. (split(RE, string مثل string.split()‎ لكن يستخدم تعبيرًا نمطيًا مثل فاصل. (sub(RE, replace, string تعيد سلسلةً نصيةً أُنتجت عن طريق استبدال لـ re في أول مطابقة للتعبير النمطي، وهذه الدالة لها مزايا أخرى إضافية، انظر توثيقها للمزيد. (findall(RE, string تبحث عن جميع مرات حدوث التعبير النمطي في سلسلة نصية، وتعيد سلسلةً من كائنات المطابقة. (compile(RE تنتج كائن تعبير نمطي يمكن إعادة استخدامه لعدة عمليات مع نفس التعبير النمطي، ويكون للكائن جميع التوابع أعلاه لكن مع re مضمَّنة، ويكون أكثر كفاءةً من النسخ الخاصة بالدالة. لا شك أن هذه القائمة لا تحتوي جميع توابع re ودوالها، كما أن التوابع التي ذكرناها في الجدول لها معامِلات اختيارية لتوسيع استخدامها، واخترناها لأنها أكثر العمليات استخدامًا، ومناسبةً لاحتياجاتنا. مثال عملي على التعابير النمطية لننشئ برنامجًا يبحث في ملف HTML عن وسم IMG ليس له قسم ALT، فإذا وجدنا واحدًا فسنضيف رسالةً إلى المالك ليكتب ملفات HTML أفضل في المستقبل. import re # لنسمح بصفر مسافة أو أكثر بين img أو IMG التقط # < و I img = '< *[iI][mM][gG] ' # alt أو ALT السماح بأي عدد من المحارف حتى before > alt = img + '.*[aA][lL][tT].*>' # افتح الملف واقرأه في قائمة filename = input('Enter a filename to search ') inf = open(filename,'r') lines = inf.readlines() # ALT بدون IMG إذا احتوى السطر على وسم # HTML فأضف رسالتنا كتعليق for index,line in enumerate(lines): if ( re.search(img,line) and not re.search(alt,line) ): lines[index] += '<!-- PROVIDE ALT TAGS ON IMAGES! -->\n' # والآن اكتب الملف المعدَّل. inf.close() outf = open(filename,'w') outf.writelines(lines) outf.close() لدينا ملاحظتان على الشيفرة أعلاه نريد الإشارة إليهما، الأولى أننا استخدمنا re.search بدلًا من re.match، لأن الأولى تبحث عن الأنماط في أي مكان داخل السلسلة النصية، بينما تبحث الثانية في بداية السلسلة فقط، أما الملاحظة الثانية فهي أننا وضعنا زوجًا خارجيًا من الأقواس حول الاختبارين، وهو أمر غير ضروري لكنه يسمح لنا بتقسيم الاختبار إلى سطرين، مما يجعله أسهل في القراءة خاصةً إذا كنا سندمج تعبيرات كثيرةً. وهذه الشيفرة ليست مثاليةً لأنها لا تأخذ في الحسبان الحالة التي يكون وسم img فيها مقسمًا على عدة أسطر، لكنها تكفي لشرح التقنية عمومًا، على أنه يُفضل تجنب هذا "التخريب" الذي قمنا به في ملف HTML، لكن الذي ينسى وسوم alt يستحق جزاءه. نأتي لأمر أخير، وهو حدود كفاءة التعابير النمطية، فلهياكل البيانات المعرَّفة بوضوح -مثل HTML- أدوات أخرى غير التعابير النمطية، تُعرف باسم المحلِّلات تكون أكثر كفاءةً وأسهل في الاستخدام دون أخطاء، وسنستخدم محلل HTML في جزئية لاحقة من هذه السلسلة، وتتجلى فائدة التعابير النمطية في عمليات البحث المعقدة في النصوص الحرة إذ تحل لنا مشاكل كثيرة، مع التأكيد مرةً أخرى على الاختبار المفصل لها، كما لا يجب استخدامها إلا عند الحاجة الضرورية إليها، أما إذا كنا نريد البحث عن سلسلة بسيطة فنستخدم التابع find، لتجنب مشاكل التعابير النمطية. وسنعود مرةً أخرى إلى التعابير النمطية في دراسة الحالة لعدّاد القواعد النحوية، لذا جرب استخدامها حتى ذلك الحين، وتفقد التوابع الأخرى الموجودة في وحدة re، فلم نشرح حتى الآن إلا قشور هذه الأدوات بالغة القوة في معالجة النصوص. التعابير النمطية في جافاسكربت تدعم جافاسكربت التعابير النمطية ضمنيًا وبقوة، بل إن عمليات البحث في السلاسل النصية التي استخدمناها من قبل ما هي إلا بحوث تعابير نمطية، فقد استخدمنا أبسط صورة لها "تسلسل بسيط من المحارف"، وتنطبق جميع القواعد التي ذكرناها في بايثون على جافاسكربت، عدا أن التعابير النمطية هنا تكون محاطةً بشرطة مائلة / بدلًا من علامات الاقتباس: <script type="text/javascript"> var str = "A lovely bunch of bananas"; document.write(str + "<BR>"); if (str.match(/^A/)) { document.write("Found string beginning with A<BR>"); } if (str.match(/b[au]/)) { document.write("Found substring with either ba or bu<BR>"); } if (!str.match(/zzz/)) { document.write("Didn't find substring zzz!<BR>"); } </script> ينجح التعبيران الأولان ويفشل الثالث، لذا حصلنا على الاختبار السلبي، لاحظ علامة التعجب في البداية. التعابير النمطية في VBScript لا تحتوي VBScript على دعم مضمّن للتعابير النمطية كما في جافاسكربت، لكن فيها كائن تعبير نمطي يمكن بدؤه واستخدامه للبحث وعمليات الاستبدال وغيرها، كما يمكن التحكم فيه لتجاهل حالة الأحرف وللبحث في جميع النسخ أو نسخة واحدة فقط: <script type="text/vbscript"> Dim regex, matches Set regex = New RegExp regex.Global = True regex.Pattern = "b[au]" Set matches = regex.Execute("A lovely bunch of bananas") If matches.Count > 0 Then MsgBox "Found " & matches.Count & " substrings" End If </script> نكون بهذا قد وصلنا إلى نهاية هذا المقال مكتفين بما ذكرناه فيه، لكن نعيد التأكيد على أن التعابير النمطية غنية بالتعقيدات الدقيقة التي لا يمكن تغطيتها في هذا المقال القصير، ويمكن الرجوع إلى المصادر الموجودة في الويب لمزيد من المعلومات عن استخدامها، إضافةً إلى كتاب أورايلي الذي أوردناه في بداية المقال. خاتمة بنهاية هذا المقال نود أن تكون قد تعلمت: التعابير النمطية هي أنماط نصية تستطيع تطوير قوة وكفاءة عمليات البحث النصية. يصعب التحكم بالتعابير النمطية، وقد تتسبب في زلات برمجية غريبة، لذا يجب التعامل معها بحرص. التعابير النمطية ليست الحل السهل لكل مشكلة، بل قد يكون الحل في منظور أكثر تعقيدًا، فإذا لم ينجح استخدام التعابير النمطية في حل مشكلة لثلاث محاولات متتالية، فيجب البحث عن حل آخر. ترجمة -بتصرف- للفصل السادس عشر: Regular Expressions من كتاب Learn To Program لصاحبه Alan Gauld. اقرأ أيضًا المقال التالي: البرمجة كائنية التوجه المقال السابق: فضاءات الأسماء في البرمجة ما هي البرمجة ومتطلبات تعلمها؟ تعلم البرمجة التعابير النمطية (regexp/PCRE) في PHP
    1 نقطة
  25. مكتبة Tkinter في بايثون مُعدة لإنشاء تطبيقات ذات واجهة رسومية GUI بسيطة وليس الغرض منها إنشاء الألعاب، حتى وإن كانت ألعاب ثنائية الأبعاد 2D، بالتأكيد يمكنك عمل ألعاب بسيطة للغاية مثل لغة تخمين الرقم الصحيح (يخبر البرنامج المستخدم بإختيار رقم من عشرة أرقام وإن كان إختياره صحيح يظهر رسالة بالفوز)، ولكن لا يُفضل إستخدام مكتبة لإنشاء الواجهات الرسومية في صناعة الألعاب، لأنك سوف تجد الكثير من المشاكل والصعوبات في هذا الأمر. بينما من الأفضل أن تستخدم مكتبات مُعدة لهذا الأمر في الأساس مثل Pygame أو Pyglet أو حتى Kivy، حيث توفر لك هذه المكتبات دعم كبير في صناعة الألعاب (خصوصًا الألعاب ثنائية الأبعاد 2D) إن كنت تريد مصادر لتعلم Tkinter يُمكنك الإطلاع على هذه الإجابة هنا:
    1 نقطة
  26. في مصر يمكنك أن تقوم بإستخراج بطاقة فيزا لإستخدامها على الإنترنت، وتسمى "فيزا مشتريات أونلاين" في أغلب البنوك مثل البنك الأهلي المصري وبنك مصر وبنك الإسكندرية وبنك QNB وغيرها، وخطوات إستخراج هذه البطاقة وتكلفتها والوقت المستغرق في هذه العملية يختلف من بنك لآخر، ويجب أن تقوم بسؤال أحد الموظفين في أي فرع للبنك الذي تريده وسوف يخبرك بتفاصيل إستخراج بطاقة مشتريات من البنك، وفي الغالب سوف تحصل عليها في نفس اليوم أو بعد أسبوع كحد أقصى من وقت طلبك للفيزا. عليك أيضًا أن تسأل إن كانت الفيزا تدعم ربطها مع PayPal وأغلب البنوك تدعم ذلك بدون مشكلة، وذلك لأن كل البنوك لديهم عدة أنواع من البطاقات الإئتمانية التي تدعم الشراء عبر الإنترنت، وتختلف هذه الأنواع ومميزاتها من ينك لآخر بالطبع. أيضًا يمكنك أن تستخرج بطاقة Easy Pay مسبقة الدفع من أي مكتب للبريد المصري وهي بطاقة تدعم الشراء عبر الإنترنت وكذلك ربطها مع PayPal بدون مشكلة، وتدعم السحب من أغلب ماكينات ATM كذلك، ويُمكن إستخراجها في نفس اليوم ببطاقة الرقم القومي فقط وبتكلفة 25 جنية مصري فقط، وبعد إستخراجها يجب أن تقوم بشحنها بقيمة 100 جنية مصري على الأقل لكي يتم تفعيلها (يتم إضافة المئة جنية على الفيزا كرصيد). خطوات ربط بطاقة الفيزا مع PayPal بعد تسجيلك في موقع PayPal ستحتاج إلى إضافة بطاقة إئتمانية تدعم الشراء عبر الإنترنت إلى حسابك، وسوف يقوم موقع PayPal بخصم 1 دولار أمريكي من الفيزا للتأكد من صلاحيتها (سوف يتم إرجاع هذه القيمة بعد أسبوع من سحبها إلى حساب PayPal الخاص بك)، ولكي يتمكن PayPal من سحب هذه القيمة يقوم بطلب إدخال "رقم تأكيد عملية الدفع لـ PayPal"، ويجب أن تقوم بالإتصال بخدمة عملاء البنك الخاص بك (أو البريد المصري في حالة بطاقة Easy Pay) وطلب منهم "رقم تأكيد عملية الدفع لـ PayPal" وسوف يخبرك به موظف الدعم الفني، وهذا الرقم سوف تقوم بكتابته في موقع PayPal. ملاحظة: إن لم تتمكن من ربط بطاقة فيزا الخاصة بك بـ PayPal يُمكنك طلب المساعدة من خدمة العملاء الخاصة بالبنك وسوف يقوم بمساعدتك وإرشادك إلى الخطوات والتفاصيل. ملاحظة: قد تتأخر عملية الحصول على "رقم تأكيد عملية الدفع لـ PayPal" إلى ما يصل لأسبوع، لذلك قد يكون عليك أن تقوم بالإتصال بخدمة عملاء البنك الخاص بك أكثر من مرة للتأكد من وصول الرقم لديهم لكي يخبرك به. طريقة شحن البطاقات الإتمانية مسبقة الدفع يُمكنك أن تقوم بشحن البطاقة من أي فرع للبنك الخاص بك (أو أي مكتب بريد مصري في حالة بطاقة Easy Pay) أو من ماكينات ATM التي تدعم الإيداع، ويمكنك أن تسأل البنك عن أماكن تواجد هذه الماكينات في المنطقة التي تسكن بها. ملاحظة: يُمكن شحن بطاقة Easy Pay أيضًا من ماكينات الإيداع الخاصة بأغلب البنوك بما فيها ماكينات البنك الأهلي المصري.
    1 نقطة
  27. يُمكنك أن تستعمل أي مسار للواجهة الخلفية Backend حيث أن كل المسارات المعروفة في الوقت الحالي تؤدي الغرض منها على أكمل وجهة حتى بالنسبة لأكبر الشركات والمواقع الضخمة، فعلى سبيل المثال اللغات مثل PHP و Python و Ruby وكذلك JavaScript (مع Node.js) يمكنها عمل أي نظام للواجهة الخلفية Backend لإدارة تطبيق أندرويد وعمل API كامل متعدد الإصدارات بدون مشكلة وبسهولة أيضًا، مع العلم أن كل هذه اللغات لها إطارات عمل ضخمة يتم إستخدامها في العديد من المواقع الكبيرة مثل Laravel و Django و Express.js و Ruby on rails، يمكنك الإطلاع على هذه الإجابة لمزيد من التفاصيل عن كل لغة وإطار العمل الخاص بها: وبالطبع نفس الأمر ينطبق على نظام قواعد البيانات حيث يمكنك أن تستعمل MySQL أو PostgreSQL أو MongoDB بدون مشكلة في أغلب المشاريع.
    1 نقطة
  28. ويندوز 11 جديد نسبيًا مقارنة بالإصدارات السابقة منه مثل Windows 10 أو Windows 8.1، لذلك قد يكون هناك الكثير من المشاكل -حتى ولو كانت صغيرة- التي لم يتم حلها بعد (أو لم يتم إكتشافها من الأساس)، وعلى سبيل المثال إن كان حاسوبك يعمل بمعالج من نوع AMD Ryzen فقد تواجهة مشكلة في تشغيل بعض الألعاب أو بطء عام في الجهاز بنسبة تصل إلى 15% من أداء الجهاز العادي، مع العلم أن Microsoft قد أعلنت أنها أصلحت هذه المشكلة في التحديث الأخير (تحديث رقم Build 22000.282)، وقد قامت شركة AMD بطرح تعريف Driver جديد لإصلاح المشكلة من جانبها أيضًا (الإصدار 3.10.08.506). هذا وقد تجد عدد من المشاكل الأخرى مثل الإتصال بالطابعات، أو طلب صلاحييات المدير في كل مرة يتم فيها إستخدام الطابعة، أو مشاكل عند إنشاء أو إستخدام نظام إفتراضي Virtual machines (VMs)، وغيرها من المشاكل الأخرى يمكنك الإطلاع على آخر المشكلات الموجودة حاليًا في النظام ومعرفة كيفية إصلاح المشكلة (إن كان لها حل في الوقت الحالي) من خلال Windows 11 known issues and notifications الرسمية. لذلك لا يُنصح بتجربة Windows 11 على حاسوب الشخصي وخصوصًا إن كان لديك ملفات مهمة أو تستخدمه بكثرة في الأعمال، لأنك قد تواجهة مشكلة من المشكلات السابقة أو حتى مشكلة جديدة لم يتم إصلاحها بعد، مما سيؤثر بالسلب على عملك أو وقتك، ويُفضل أن تنتظر عدة أسابيع أخرى قبل تجربة النظام لضمان أن أغلب المشكلات قد تم حلها بالفعل. كما أنك في الغالب لا تحتاج إلى تثبيت Windows 11 من الأساس، فإن كان حاسوبك على ما يرام بـ Windows 10 وكل البرامج التي لديك تعمل عليه، فلست بحاجة إلى المخاطرة وتجربة نظام جديد خصوصًا إن كنت تستعمل حاسوبك في أمور مهمة كالعمل أو الدراسة كما ذكرت سابقًا، أما إن كان ينتابك الفضول فقط وتريد تجربة النظام فمن الأفضل أن تقوم بتجربة على حاسوب آخر أو حتى كنظام وهمي Virtual machine مع العلم أن هذا الأمر قد يكون معقدًا قليلًا في الوقت الحالي بسبب متطلبات تشغيل windows 11.
    1 نقطة
  29. يمكنك أن تقوم بالإشتراك بالدورة مجانًا لمدة 7 أيام (فترة تجريبية)، او يمكنك أن تقوم بالتقديم إلى الدورة من خلال المساعدات المالية Financial aid، من خلال الضغط على كلمة "Financial aid available" بجانب زر Enroll for Free ثم ملئ البيانات وسيتم الرد على هذا الطلب خلال 15 يوم من تاريخ التسجيل. إن كنت لا تريد الإنتظار فيمكنك أن تقوم بمحاولة دراسة محتويات الشهادة بنفسك من خلال البحث عن كل موضوع يتم تدريسه خلال الدروس، تستطيع معرفة محتويات الشهادة عبر قسم "WHAT YOU WILL LEARN" في كل صفحة course على حدى من هنا (يوجد 7 دورات كل منها تحتوي على نفس القسم).
    1 نقطة
  30. إن كنت تستخدم حزمة next-i18next، فسيظهر لك هذا الخطأ عندما تقوم اللغة الإفتراضية defaultLanguage غير موجودة ضمن اللغات التي يدعمها المشروع، فعلى سبيل المثال في الكود التالي اللغة الإفتراضية هي ar: // i18n.js const NextI18Next = require('next-i18next').default module.exports = new NextI18Next({ defaultLanguage: 'ar', otherLanguages: ['tr',"en","ru"], // .... }) فيجب أن يحتوي المشروع على ملف common.js ضمن ملف باسم ar كالتالي: public/static/locales/ar/common.json يظهر هذا الخطأ في مرحلة الإنتاج production فقط.
    1 نقطة
  31. UI هي واجهة المستخدم (User Interface)، بينما UX هي تجربة الإستخدام (User Experience)، ولكل منهما العديد من التفاصيل والشروحات والأداوات التي يمكنك إستخدامها، ومصمم واجهة الاستخدام UI/UX Designer لا يقوم بكتابة الأكواد ولكن كتابة الأكواد هي عمل UI/UX Developer، فالمصمم هو من يقوم بعمل مخطط للتصميم ثم يقوم المختص بتحويلها الى كود فعلي. في الوقت الحالي لن تجد الكثير من المحتوى العربي الذي يتخصص في تصميم واجهة الاستخدام UI/UX Design (على الأقل مقارنة بالمحتوى الأجنبي)، يمكنك أن تحصل على دورة مقدمة من Google بخصوص تجربة الإستخدام User Experience وهي دورة مجانية لفترة تجريبية (للحصول على الشهادة يجب أن تقوم بدفع مبلغ مالي) تقوم بدراستها من خلال موقع Coursera، تقدم الدورة شرح للأساسيات مثل wireframing و prototyping مع أسخدام أدوات مثل Adobe X.D و Figma. كما أن أكاديمية حسوب تحتوي على العشرات من المقالات في التصميم بشكل عام وفي تصميم واجهة الاستخدام UI/UX Design بشكل خاص، وأنصحك بأن تبدأ بسلسلة مقدمة إلى UI لتعلم كل ما يخص واجهة المستخدم User Interface، بالإضافة إلى سلسلة مدخل إلى تجربة المستخدم لتعلم تجربة الإستخدام User Experience، وكلٌ من السلسلتين يُعد مدخل ممتاز يحتوي على شرح لكل ما ستحتاج تعلمه للبدأ في العمل في هذا المجال. ستتعلم من خلال دورة جوجل ومن خلال السلستين السابقتين العديد من المصطلحات مثل: User Interviewing - مقابلة المستخدمين Usability Testing - اختبار قابلية الاستخدام Human Computer Interaction - تفاعل الإنسان والحاسوب Strategy Design - تصميم الإستراتيجية وغيرها الكثير. أيضًا سوف تحتاج إلى التدرب على أشهر أدوات التصميم مثل Adobe X.D و Figma فالطبع لن تستطيع عمل تصميم ممتاز حتى وإن كانت لديك معرفة كبيرة بالمجال ما لم يكن لديك معرفة بالأدوات التي سوف تستعملها. عند إنتهائك من تعلم الدروس والأدوات السابقة أنصحك بالإطلاع على المقالات العامة في قسم التصميم لأنك سوف تحصل على معرفة ممتازة بأدوات وأشياء وقواعد لم تكن تعلمها من قبل مما سيؤدي بالنهاية إلى جعل تصاميمك أكثر إحترافية. بعد تعلم ما سبق سوف تجد أن الأمور أصبحت أكثر وضوحًا وستعرف تلقائيًا الخطوة التالية.
    1 نقطة
  32. يمكنك كتابة طريقة العرض الخاصة بك للـ API إذا كنت تريد تخصيصه، ولا تحتاج إلى استخدام العرض الموجود مسبقًا from rest_framework_simplejwt.tokens import RefreshToken def get_tokens_for_user(user): refresh = RefreshToken.for_user(user) return { 'refresh': str(refresh), 'access': str(refresh.access_token), } ستعيد الدالة get_tokens_for_user أعلاه serialized لرمز refresh token وaccess token للمستخدم المحدد (المدخل إلى الدالة). بشكل عام، يمكن إنشاء token لأي فئة فرعية subclass من rest_framework_simplejwt.tokens.Token بهذه الطريقة.
    1 نقطة
  33. يمكنك أن تستخدم الخاصية contains على النحو التالي: User.objects.filter(datetime_registred__contains=datetime.date(2021,9,12)) أو يمكنك تحديد السنة والشهر واليوم يدويًا، وبالتالي سيتم تحديد كل المستخدمين الذين سجلوا في الموقع في هذا اليوم فقط بغض النظر عن وقت التسجيل: User.objects.filter(datetime_published__year='2021', datetime_published__month='09', datetime_published__day='12') وإن كنت تستخدم الإصدار 1.9 أو احدث من جانغو Django فيمكنك أن تستخدم الخاصية date، كالتالي: User.objects.filter(datetime_registred__date=datetime.date(2021, 9, 12))
    1 نقطة
  34. يوفر جانغو Django طريقة للحصول على أسماء الحقول وقيمها أيضًا من خلال التابع get_fields والذي يقوم بإرجاع tuple من أسماء الحقول، ويمكنك إستخدامه كالتالي: from django.contrib.auth.models import User fields = User._meta.get_fields() for field in fields: print(field.name) وإن كنت تريد المرور على كل الكائنات في نموذج معين فيمكنك أن تستخدم serializers، على النحو التالي: from django.core import serializers users = serializers.serialize("python", User.objects.all()) ثم في القالب: {% for user in users %} {% for field, value in user.fields.items %} {{ field }}: {{ value }} {% endfor %} {% endfor %} وإن أردت عرض حقول معينة، فيمكنك إضافة الخاصية fields، كالتالي: from django.core import serializers users = serializers.serialize("python", User.objects.all(), fields=('name','email'))
    1 نقطة
×
×
  • أضف...