-
المساهمات
13280 -
تاريخ الانضمام
-
تاريخ آخر زيارة
-
عدد الأيام التي تصدر بها
367
إجابات الأسئلة
-
إجابة Mustafa Suleiman سؤال في كيف أستخدم مكتبة Prism.js كانت الإجابة المقبولة
أولاً عليك باستيراد الملفات المطلوبة وهي:
prism.js prism.css prism-live.css prism-live.js ويمكنك استيرادها من خلال الروابط التالية:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism-tomorrow.min.css" /> <script src=" https://cdn.jsdelivr.net/npm/prismjs@1.29.0/prism.min.js "></script> <script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/autoloader/prism-autoloader.min.js"></script> ثم استيراد ملف prism-live.js كالتالي:
<script src="prism-live.js?load=css,html,javascript"></script> حيث أن prism-live.js تعتمد على prism.js وتسمح بتلوين الأكواد داخل عنصر <textarea>.
وبعد ذلك عليك بحقن الأكواد من خلال جافاسكريبت في iframe وضع له id وليكن باسم code كالتالي:
<iframe id="code"></iframe> وقد شرحت الأمر بالتفصيل في سؤال من قبل عن كيفية إنشاء محرر أكواد بسيط مثل CodePen هنا:
موقع محرر اكواد -
إجابة Mustafa Suleiman سؤال في تعلم البرمجة في الثانوية العامة كانت الإجابة المقبولة
أنت تُفكر بالأمر بشكل غير صحيح، عليك بتحديد العائد والهدف من وراء أي شيء تقوم بفعله، هل أنت بحاجة إلى شهادة الثانوية والحصول على درجة مرتفعة لدخول جامعة ذات مستقبل جيد؟
إذن عليك التركيز في الفترة القادمة على الدراسة من أجل ذلك، وتخصيص الوقت المتبقي لدراسة البرمجة أي ستصبح عملية تعلم البرمجة أمر ثانوي في وقت فراغك.
أما إن كانت تلك الشهادة والمجموع بدون عائد جيد لك أو مستقبل تراه مناسبًا، إذن عليك بتخصيص الجزء الأكبر من وقتك لتعلم البرمجة مع توفير وقت مناسب من أجل النجاح والحصول على شهادة الثانوية ودخول جامعة للحصول على شهادة جامعية فقط.
حيث أنك قد أخبرت بأن العمل يمثل أمر ضروري بعد الثانوية بالنسبة لك، لذلك الظروف الشخصية لديك هي التي ستحدد مستقبلك وعليك السعي وفقًا لذلك.
أما إن كان لديك الوقت والظروف المناسبة، فعليك بالتركيز على الدراسة ودخول جامعة متعلقة بالبرمجة مثلاً ثم بدء رحلة تعلم البرمجة وتستطيع بدء ذلك مبكرًا في العطل الصيفية من أجل دراسة الأساسيات.
لكن نصيحتي إليك هي ألا تنقطع عن تعلم البرمجة حاول تخصيص وقت ولو يسير من أجل كتابة الكود وتنفيذ مشروع بسيط من أجل تثبيت ما تعلمته ولكي لا تنسى وتضيع مجهودك وتعود لنقطة قريبة من البداية بعد مرحلة إنقطاع كبيرة.
-
إجابة Mustafa Suleiman سؤال في التسويق بالعمولة و منصة ووردبريس كانت الإجابة المقبولة
بالنسبة للمواقع التي ذكرتها فالأول يعتمد على Drupal وليس ووردبريس، والثاني يعتمد على ووردبريس ويستخدم قالب مخصص.
وبإمكانك أنت البحث عن قوالب خاصة بالـ coupons على المنصات التي توفر قوالب ووردبريس مثل موقع themeforest، وبالبحث عن coupons ستجد النتائج التالية:
https://themeforest.net/category/wordpress?term=coupons وبخصوص تنفيذ المشروع من خلال برمجة خاصة، فلا تعتمد على الشركات في ذلك حيث أن التكلفة ستكون مرتفعة كما ذكرت وذلك أمر طبيعي، والأفضل تعيين مبرمج جيد ذو سابقة أعمال من على مواقع العمل الحر مثل مستقل.
والتكلفة تعتمد على المميزات التي تريد توافرها بالموقع والتصميم وخلافه وأيضًا خبرة المبرمج.
وعن تحويل الموقع لتطبيق من خلال فلاتر، فالأمر بسيط إذا كنت تريد عرض الموقع كما هو من خلال تطبيق مع إضافة مزايا بسيطة، لكن تحويل الموقع بالكامل إلى تطبيق متعدد الصفحات مثلاً وبمزايا مختلفة فسترتفع التكلفة بلا شك.
-
إجابة Mustafa Suleiman سؤال في من اين ابدأ؟ كانت الإجابة المقبولة
أولاً دورة تطوير المنتجات موجهة لمن يريد أن يصبح مدير تطوير منتجات أو صاحب مشروع، لكنها مفيدة لك كمبرمج بالطبع حيث ستتعرف على عملية إدارة تطوير المنتج والمشروع من البداية قبل كتابة الكود فهي آخر خطوة، لكنها ليست مناسبة لك في البداية لن تشعر بفائدة إذا كنت تريد أن تصبح مبرمج فهي مفيدة بعد تعلم البرمجة وذلك واضح من الدورات الأخرى التي اخترتها.
والفيديو التالي سيوضح لك ماهية دورة تطوير المنتجات:
لذلك أنصحك أولاً بتعلم أساسيات البرمجة وعلوم الحاسوب من خلال دورة علوم الحاسوب وستجد نقاش حول فائدة تلك الدورة هنا:
وبعد الإنتهاء من دورة علوم الحاسوب، سيصبح لديك دراية ووعي بالمجالات البرمجية المختلفة والقدرة على الإختيار من بينها وأيضًا تعلم وإنتاجية أسرع عند تعلم الدورات الأخرى.
أنصحك بالإنتقال لدورة تطوير واجهات المستخدم فهى سهلة وستؤهلك لدخول مجال الويب، وتعلم اللغات الأساسيات الخاصة به وهي HTML, CSS, JS ومكتبة jQuery وBootstrap، وستحتاج تلك الللغات والمهارات في دورة بايثون لذلك رغم أنك ستتعلمها في تلك الدورة، لكن من الأفضل البدء بالترتيب الصحيح.
بعد ذلك تنتقل لدورة بايثون وستجد شرح حول تلك الدورة هنا:
وأنصحك بالإطلاع على النقاش التالي ستجد به الكثير من الإجابات على الأسئلة لديك:
-
إجابة Mustafa Suleiman سؤال في عقود العمل في العمل الحر وخصيصا في مجال البرمجه كانت الإجابة المقبولة
الأهم هو إحتواء العقد على النقاط التالية:
تحديد اسم وعنوان كل من صاحب العمل أو المتعاقد والمورد بشكل واضح. تفاصيل المشروع بدقة، بما في ذلك الغرض منه، والوظائف التي يجب تنفيذها، والجدول الزمني المتوقع للتسليم، والميزانية المحددة. طريقة الدفع، والمبلغ الإجمالي، والجدول الزمني للدفعات. المعايير التي سيتم من خلالها قبول المشروع، وكيفية تحديد أي عيوب أو أخطاء. المسؤوليات القانونية لكل طرف، بما في ذلك المسؤولية عن الأضرار الناتجة عن الإهمال أو الخطأ. سرية المعلومات. تسليم الكود المصدري. آلية حل النزاعات في حالة حدوث أي خلافات بين الطرفين. بالإضافة إلى العناصر الأساسية، تتضمن عقود العمل في مجال البرمججة أيضًا عناصر أخرى، مثل:
تحديد من سيمتلك حقوق الملكية الفكرية للمشروع. تحديد التزام كل طرف بعدم الكشف عن معلومات سرية للطرف الآخر. تحديد كيفية إجراء أي تغييرات في المشروع. كيفية التعامل مع أي ظروف طارئة قد تؤثر على المشروع. وبخصوص الصيغة أو قالب جاهز فابحث عن contract template for Software Development projects، أو ابحث عن "عقد برمجة موقع" وستجد نماذج يمكنك الإطلاع عليها.
ومن الأسهل استخدام موقع عمل حر مثل مستقل والإتفاق على شروط المشروع بالتفصيل وكتابتها في محادثة المشروع، وستضمن المنصة حقك وحق العميل، ولديك منصة مستقل.
-
إجابة Mustafa Suleiman سؤال في توزيع الأرباح فى الشركات الصغيرة - Part Time كانت الإجابة المقبولة
في حالة الشركات الصغيرة التي تعمل بنظام Part Time، يتم توزيع الأرباح بناءًا على المساهمة النسبية لكل شريك في نجاح الشركة، وبالتالي الشخص الأول هو صاحب رأس المال بنسبة 100%، أي يستحق الحصول على حصة أكبر من الأرباح، ولتكن بنسبة 60% أو 70%.
أما بالنسبة للشخص الثاني والثالث، فهما مسؤولان عن أقسام مهمة في الشركة، وبالتالي يستحقان الحصول على حصص متساوية، كنسبة 20% لكل منهما.
وبالتالي، فإن نسبة توزيع الأرباح ستكون على النحو:
الشخص الأول: 60% الشخص الثاني: 20% الشخص الثالث: 20% بالطبع، تلك مجرد نسبة تقريبية، ويمكن تعديلها حسب الاتفاق بين الشركاء، فإن كان الشخص الثاني مسؤولاً عن قسم فني مهم يساهم بشكل كبير في نجاح الشركة، فقد يستحق الحصول على حصة أكبر، ويجب أن يكون هناك اتفاق مكتوب بين الشركاء بشأن نسبة توزيع الأرباح.
من المهم أيضًا مراعاة العوامل التالية عند توزيع الأرباح:
حجم الشركة حجم الإيرادات حجم الأرباح المخاطر التي يتحملها كل شريك مساهمة كل شريك في نجاح الشركة -
إجابة Mustafa Suleiman سؤال في الفرق بين NPM و Yarn كانت الإجابة المقبولة
ببساطة وبدون تعقيد في البداية، كان "npm" هو أشهر أداة لإدارة المكتبات الخاصة بجافاسكريبت، وعندما تبدأ مشروعك، تقوم بكتابة أمر "npm init" لإنشاء ملف "package.json"، وذلك الملف يحوي قائمة بجميع المكتبات التي تحتاجها لمشروعك.
بعد ذلك، تستخدم أمر "npm install" لتحميل المكتبات المذكورة في ملف "package.json" إلى مجلد يسمى "node_modules".
وهناك ملف آخر يسمى "package-lock.json" يساعد على ضمان تثبيت نسخ محددة من المكتبات بشكل دقيق، لذا إذا كان مطور مشروع ما قد قام بتحديث مكتبة معينة إلى الإصدار 2 ثم 3، وآخر قام بتحديثها مباشرة إلى الإصدار 3، يمكن استخدام هذا الملف لضمان أن الإصدارات المثبتة متطابقة من خلال أمر npm ci.
ومع ذلك، كانت "npm" تعاني من مشاكل مثل التثبيت غير المتسق، وحالات أخرى مثل تغيير ملكية ملفات النظام عند تشغيلها على نظام لينكس.
لحل تلك المشاكل، قامت فيسبوك بإطلاق أداة جديدة تدعى "Yarn" في عام 2016 والتي تمتاز Yarn بأنها أسرع وأكثر أمانًا واستقرارًا من npm.
وبنفس الكيفية تستطيع استخدام "yarn init" لإنشاء ملف "package.json" مع Yarn، ثم "yarn install" لتحميل المكتبات. ومثلما هو الحال مع npm، تقوم Yarn بإنشاء مجلد "node_modules" وملف "yarn.lock" لتثبيت الإصدارات بشكل دقيق.
بإمكانك أيضًا التبديل من استخدام npm إلى Yarn بسهولة.
على الرغم من ذلك، عليك بمعرفة أن npm تم تحسينها أيضًا مع كل إصدار جديد، وهناك الكثير من المشاريع التي لا تزال تستخدم npm بدلاً من Yarn.
وفي الوقت الحالي أصبح لا يوجد فرق تقريبًا حيث تم تطوير npm لتمتلك نفس الخواص في yarn والتي منها package.json واستخدام أفضل لإتصالات الشبكة وملفات التخزين المؤقتة واستخدام checksums الخاصة بتفقد أمان وموثوقية الكود الذي تقوم بتحميله.
ولكن هناك ميزة مثل parallel installation متوفرة في yarn وتعني تحميل المكتبات بشكل متوازي مما يسرع من عملية التثبيت، وأيضًا ميزة Zero-Install وتتيح تجنب تثبيت المكتبات المكررة بين مشاريع مختلفة، أي عندما تكون هناك مكتبات مشتركة بين مشاريع مختلفة، فإن Yarn يقوم بمشاركتها دون الحاجة إلى تثبيت نسخة منها في كل مشروع على حدة مما يوفر مساحة على القرص ويقلل من استهلاك الشبكة والموارد.
الخلاصة
يعتبر Yarn أسرع من npm بسبب تنفيذه لعملية التثبيت المتوازي، حيث يمكنه تنزيل وتثبيت مكتبات مختلفة في وقت واحد، هذا يؤدي إلى اكتمال عمليات التثبيت بشكل أسرع، مما يوفر الوقت للمطورين أثناء إعداد مشاريعهم. تستفيد Yarn من مزايا أمان أكبر مقارنةً بـ npm. ذلك لأن Yarn تحتوي على آلية تحقق أفضل لتجنب الثغرات الأمنية والتحقق من صحة المكتبات التي يتم تثبيتها، مما يقلل من احتمالية وجود مشكلات أمنية في مشاريعك. Yarn يستهلك مساحة أكبر على القرص مقارنةً بـ npm، ذلك لأن Yarn يخزن البيانات إضافية مما يزيد من استهلاك المساحة، وقد يكون أمرًا مزعجًا إذا كنت تعمل على جهاز قرص صلب ذو مساحة محدودة. -
إجابة Mustafa Suleiman سؤال في خطأ no such table عند إضافة بيانات في جدول في قاعدة بيانات SQLite كانت الإجابة المقبولة
رسالة الخطأ تخبرك أنه لا يوجد جدول باسم STUDENTS هل لديك جدول بذلك الاسم؟
-
إجابة Mustafa Suleiman سؤال في اريد regular expression تقبل النصوص العربية والانجليزية والارقام والرموز وايضا ال emoji كانت الإجابة المقبولة
تستطيع الإعتماد على التعبير الحديث التالي:
/\p{Emoji}/u ففي الدعم الأحدث للتعبيرات العادية في البيئة المتصفحة (مثل Chrome، Firefox، Safari، إلخ)، التحسينات تسمح لك باستخدام تعبيرات عامة تعتمد على خصائص يونيكود للتعرف على مجموعات محددة من الأحرف، مثل الإيموجي.
خاصية \p{Emoji} escape تطابق أي حرف Unicode مصنف على أنه رمز تعبيري، والعلامة u تخبر محرك regular expression بتفسير النمط كسلسلة Unicode.
وكمثال الكود التالي سيكشف عن جميع الرموز التعبيرية في السلسلة "Hello 😀 😄":
const text = "Hello 😀 😄"; const regex = /\p{Emoji}/u; const matches = regex.exec(text); console.log(matches); // ['😀', '😄'] و هناك نطاق يمثل الأحرف العربية والإنجليزية والأرقام ويمكنك دمجه مع \p{Emoji}. النطاق المشترك للأحرف العربية والإنجليزية والأرقام هو \p{L}\p{N}.
إليك الكود مع تضمين الأحرف العربية والإنجليزية والأرقام:
const text = "Hello 😀 😄 مرحبا 123"; const regex = /[\p{L}\p{N}\p{Emoji}]+/gu; const matches = text.match(regex); console.log(matches); // ['Hello', '😀', '😄', 'مرحبا', '123'] اعتمدت على \p{L} للدلالة على الأحرف اللغوية (مثل العربية والإنجليزية) و\p{N} للأرقام، أما + تعني أنه يمكن أن يكون هناك تطابق لسلسلة من تلك الأحرف والأرقام، و u يشير إلى دعم اليونيكود.
واستخدام text.match(regex) بدلاً من regex.exec(text) لأنك تريد العثور على جميع التطابقات في النص، ليس فقط أول تطابق.
-
إجابة Mustafa Suleiman سؤال في كيفية فتح مرحلة ثانية في تطبيق Android بعد الانتهاء من المرحلة الأولى كانت الإجابة المقبولة
بالنسبة للسؤال الأول، لمنع فتح المرحلة الثانية حتى يتم الانتهاء من المرحلة الأولى، استخدمي الكود التالي:
// Check if the first level is completed if (firstLevelCompleted) { // Open the second level openLevelTwo(); } يمكنك أيضًا استخدام متغير لتحديد حالة المرحلة الحالية، مثلاً إنشاء متغير يسمى currentLevel وضبطه على 1 للمرحلة الأولى و2 للمرحلة الثانية. ثم، استخدام ذلك المتغير للتحقق مما إذا كان المستخدم قد وصل إلى المرحلة الثانية أم لا.
// Check the current level if (currentLevel == 2) { // Open the second level openLevelTwo(); } بالنسبة للسؤال الثاني، لفتح المرحلة الثانية عند النقر على الزر الموجود في نهاية الصفحة الأولى، نستخدم التالي:
// Click on the button to open the second level Button button = findViewById(R.id.button); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { openLevelTwo(); } }); بالنسبة للسؤال الثالث، لفتح المرحلة الثانية بعد جمع 20 نقطة، تستطيعي استخدام الكود التالي:
// Check the score int score = getScore(); if (score >= 20) { // Open the second level openLevelTwo(); } بإمكانك أيضًا استخدام متغير لتحديد النتيجة الحالية، وكمثال إنشاء متغير يسمى score وضبطه على عدد النقاط التي جمعها المستخدم ثم، استخدام هذا المتغير للتحقق مما إذا كان المستخدم قد جمع ما يكفي من النقاط للانتقال إلى المرحلة الثانية أم لا.
// Check the score int score = getScore(); if (score >= 20) { // Open the second level openLevelTwo(); }
-
إجابة Mustafa Suleiman سؤال في معالجة خطأ عند إستعمال redux كانت الإجابة المقبولة
بسبب أن createStore أصبحت غير مدعومة أي deprecated والكود سيعمل بدون مشكلة لكن كتحذير فقط ومن الأفضل استخدم Redux Toolkit بدلاً من Redux.
وإذا أردت استيراد createStore فعليك استيرادها بالشكل التالي:
import { legacy_createStore as createStore } from 'redux'; و Redux Toolkit هو نهج موصى به لكتابة منطق Redux حاليًا، بما في ذلك إعداد المخزن (store)، والمنشئين (reducers)، واسترجاع البيانات، والمزيد.
حيث أن Redux Toolkit يقدم واجهة برمجة التطبيق (API) تُسمى configureStore والتي هي النسخة المحسنة من createStore والتي تبسط عملية إعداد المخزن وتساعد في تجنب الأخطاء الشائعة، وconfigureStore تكون بمثابة غمد (wrapper) حول واجهة البرمجة الأساسية لـ Redux وهي createStore، وتتولى الكثير من عمليات إعداد المخزن تلقائيًا، كالتالي:
import { configureStore } from "@reduxjs/toolkit"; https://redux.js.org/tutorials/fundamentals/part-8-modern-redux#using-configurestore -
إجابة Mustafa Suleiman سؤال في مشكلة هامش أبيض في صورة مستخدمًا Intersection Observer في الواجهة، ما السبب وكيفية حله؟ كانت الإجابة المقبولة
قمت بتكبير وتصغير الشاشة فظهرت المشكلة بالفعل، لكن كان علي تفقد جميع العناصر بالصفحة لتفقد ما سبب المشكلة وتبين أنه القسم التالي في الصفحة:
ولحل المشكلة عليك باستخدام overflow: hidden على القسم section.works .gallary-work كالتالي:
section.works .gallary-work { background-image: url(../images/hero-bg/app.jpg); background-position: center; background-attachment: fixed; background-size: cover; margin-top: 120px; overflow: hidden; } وبخصوص التصميم هو جيد أحسنت، لكن بخصوص التأثيرات عند التمرير فعليك بتقليص الوقت بحيث لا يشعر بها المستخدم فلا يجب أن ينتظر المستخدم أن تظهر العناصر أي يجب تحقيق التوازن بين هذا وذاك.
-
إجابة Mustafa Suleiman سؤال في العودة إلى الاعدادات الافتراضية لمحرر الاكواد vs code كانت الإجابة المقبولة
عليك بتفقد الإضافات لديك وحذف أي إضافة متعلق بـ Twig ثم إعادة تشغيل المحرر، وفي حال استمرت المشكلة عليك بالتوجه إلى الإعدادات كما أخبرك عمر، ثم الضغط الأيقونة الخاصة بعرض ملف settings.json ثم البحث عن أي إعدادات خاصة بـ Twig ثم حذفها ثم الحفظ وإعادة تشغيل المحرر.
وفي حال استمرت المشكلة من الأفضل حذف VScode تمامًا ثم إعادة تثبيت آخر إصدار مرة أخرى، وبخصوص Twig عليك باستخدام الإضافة التالية حيث لا يوجد بها مشكلة التعليقات التي ظهرت لديك:
https://marketplace.visualstudio.com/items?itemName=mblode.twig-language-2 وأيضًأ تأكد من الأسفل في المحرر أنه تم إختيار الصيغة الصحيحة للملف وهي HTML كالتالي:
-
إجابة Mustafa Suleiman سؤال في معالجة الخطأ التالي [section] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment> في react-router-dom كانت الإجابة المقبولة
المشكلة بسبب وجود عنصر <section> كفرع مباشر لعنصر <Routes> داخل الكود، وفي React Router v6، يجب أن تحتوي عناصر <Routes> على عناصر <Route> فقط أو <React.Fragment> كعناصر داخلية أو كأطفال childrens.
لذلك عليك باستخدام <Route> للـ <section> أيضًا بدلاً من وضع <Routes> داخل <section>.
import { Route, Routes } from 'react-router-dom'; function App() { return ( <> <Navbar /> <Routes> <Route path="/" element={<Landing />} /> <Route path="/login" element={<Login />} /> <Route path="/register" element={<Register />} /> </Routes> </> ); } وبالتالي ولم يعد هناك <Routes> داخل <section> وتم وضع جميع الـ <Route> مباشرة داخل <Routes> الرئيسي، مما سيحل مشكلة الخطأ الذي كنت تواجهه.
https://reactrouter.com/en/6.15.0/upgrading/v5 -
إجابة Mustafa Suleiman سؤال في اقتراحات مواقع تساعدك في عمل موقع لشركتك وتخصيصها كمبرمج front end كانت الإجابة المقبولة
ما علاقة موقع سلة بالأمر، سلة هي منصة لإنشاء مواقع التجارة الإلكترونية وتوفر قوالب للتعديل عليها من خلال CSS وJS.
لا يوجد منصة توفر لك أنت ترفع موقعك الخاص وتوفير بوابة دفع لك، وإذا أردت يمكنك تطوير قالبك على متجر سلة وقد تم شرح الأمر هنا:
أفضل وأشهر بوابات الدفع أما إذا أردت إنشاء موقع من خلال HTML, CSS, JS فعليك برفعه على استضافة حتى لو مجانية، ثم استخدام أحد بوابات الدفع وقد تم شرح الأمر بالتفصيل هنا:
-
إجابة Mustafa Suleiman سؤال في تحريك جميع عناصر الشاشه في pygame كانت الإجابة المقبولة
باستطاعتك استخدام نفس الكود الذي قدمته في الاستجابة السابقة لتحريك الشاشة لتتبع شخصية اللعبة، ولكن بإضافة بعض الخطوات الإضافية لمنع اللاعب من الخروج من الشاشة.
أولاً، عليك إنشاء مصفوفة من القيم التي تمثل الحدود اليسرى واليمنى العلوية والسفلية للشاشة، ثم استخدام هذه المصفوفة لتحديد ما إذا كان اللاعب يتحرك خارج الشاشة أم لا.
ثانيًا، إضافة شرط إلى الحلقة الرئيسية للتحقق مما إذا كان اللاعب يتحرك خارج الشاشة، وإن كان اللاعب يتحرك خارج الشاشة، بإمكانك تحريك الشاشة بحيث يكون اللاعب دائمًا في المنتصف.
وإليك مثالاً:
import pygame # Initialize Pygame pygame.init() # Create a window screen = pygame.display.set_mode((640, 480)) # Create the player player = pygame.Rect(320, 240, 64, 64) # Load the background image background = pygame.image.load("background.png") # Create a list of the screen borders borders = [0, 0, 640, 480] # Draw the background image screen.blit(background, (0, 0)) # Draw the player screen.blit(player, player.center) # Update the display pygame.display.update() # Main loop while True: # Check for events for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() # Move the player if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: player.x -= 10 if event.key == pygame.K_RIGHT: player.x += 10 if event.key == pygame.K_UP: player.y -= 10 if event.key == pygame.K_DOWN: player.y += 10 # Check if the player is outside the screen if player.x < borders[0]: player.x = borders[0] if player.x > borders[2]: player.x = borders[2] if player.y < borders[1]: player.y = borders[1] if player.y > borders[3]: player.y = borders[3] # Draw the player screen.blit(player, player.center) # Update the display pygame.display.update() # Keep the game running pygame.time.delay(100)
-
إجابة Mustafa Suleiman سؤال في تفعيل تناوب اللعب بناءً على إجابة سؤال في لعبة XO باستخدام React.js و Node.js و socket.io كانت الإجابة المقبولة
const http = require('http'); const express = require('express'); const socketIO = require('socket.io'); const app = express(); const server = http.createServer(app); const io = socketIO(server); const questions = [ { question: 'ما هو عاصمة فرنسا؟', answer: 'باريس' }, { question: 'ما هو أكبر كوكب في النظام الشمسي؟', answer: 'المشتري' }, // قائمة الأسئلة والإجابات الأخرى ]; let currentPlayer = 0; // تحديد اللاعب الحالي io.on('connection', (socket) => { // عند اتصال لاعب جديد socket.emit('question', questions[currentPlayer].question); socket.on('answer', (playerAnswer) => { if (playerAnswer === questions[currentPlayer].answer) { // إذا كانت الإجابة صحيحة io.emit('correctAnswer', currentPlayer); currentPlayer = 1 - currentPlayer; // تبديل تناوب اللاعبين } }); }); server.listen(3000, () => { console.log('Server is running on port 3000'); });
-
إجابة Mustafa Suleiman سؤال في مشكلة عند استخدام مكتبة pafy كانت الإجابة المقبولة
خطأ "TypeError: unsupported operand type(s) for *: 'NoneType' and 'int'" يعني أنك تحاول ضرب كائن من نوع NoneType برقم صحيح، يحدث هذا إذا كانت وظيفة get_video_stream() تُرجع كائنًا من نوع NoneType.
تُستخدم وظيفة get_video_stream() بواسطة وظيفة playVideo() للحصول على قائمة بجميع تيارات الفيديو المتاحة لفيديو YouTube.
وتستخدم وظيفة get_video_stream() مكتبة pafy للحصول على معلومات حول فيديو YouTube.
تم تحديث مكتبة pafy مؤخرًا، ومن الممكن أن تكون وظيفة get_video_stream() غير متوافقة مع الإصدار الجديد من المكتبة.
ولإصلاح الخطأ، يمكنك محاولة تحديث مكتبة pafy، وأيضًا محاولة استخدام مكتبة مختلفة للحصول على معلومات حول مقاطع فيديو YouTube.
أولاً قم بتحديث مكتبة pafy عن طريق تشغيل الأمر التالي في موجه الأوامر:
pip install --upgrade pafy ثانيًا جرب استخدام مكتبة مختلفة للحصول على معلومات حول مقاطع فيديو YouTube، وهناك العديد من المكتبات المتاحة، مثل youtube-dl و pytube.
-
إجابة Mustafa Suleiman سؤال في كيف احفظ بيانات قادمه من backend node.js الي cookies frontend كانت الإجابة المقبولة
من خلال الإعتماد على middleware passport.session() لحفظ البيانات من backend إلى cookies في frontend تلقائيًا.، وذلك الوسيط middleware يستخدم مكتبة cookie-session لإنشاء وإدارة جلسات المستخدم.
وللاستخدام، أضف passport.session() إلى middleware chain الخاص بك:
app.use(passport.session()); ثم، يمكنك استخدام استراتيجية Passport الخاصة بك لحفظ البيانات في الجلسة، مثلا في حال كنت تستخدم استراتيجية passport.local()، تستطيع حفظ اسم المستخدم وكلمة المرور في الجلسة باستخدام الكود التالي:
passport.use(new LocalStrategy((username, password, done) => { // Check the username and password against the database if (username === 'kerlos' && password === 'secret') { // The user is authenticated done(null, user); } else { // The user is not authenticated done(new Error('Invalid username or password')); } })); بمجرد حفظ البيانات في الجلسة، سيتم إرجاعها إلى frontend تلقائيًا.
وبإمكانك الوصول إلى البيانات باستخدام middleware cookie-parser()، ومثلاً للحصول على على اسم المستخدم نستخدم التالي:
const username = req.cookies.username; وباستطاعتك أيضًا استخدام middleware cookie-parser() لإزالة البيانات من الجلسة، فلتسجيل خروج المستخدم، استخدم الكود التالي:
req.session.destroy(); وإليك مثال كامل:
const express = require('express'); const passport = require('passport'); const cookieSession = require('cookie-session'); // Create an Express app const app = express(); // Configure passport app.use(passport.initialize()); app.use(passport.session({ secret: 'secret', })); // Define a route that requires authentication app.get('/protected', passport.authenticate('local'), (req, res) => { // The user is authenticated res.send('Hello, ' + req.user.username); }); // Define a route that logs the user in app.post('/login', (req, res) => { // Check the username and password against the database if (req.body.username === 'johndoe' && req.body.password === 'secret') { // The user is authenticated passport.authenticate('local')(req, res, () => { res.redirect('/protected'); }); } else { // The user is not authenticated res.send('Invalid username or password'); } }); // Define a route that logs the user out app.get('/logout', (req, res) => { // Invalidate the user's session req.session.destroy(); res.redirect('/'); }); // Start the app app.listen(3000, () => { console.log('App listening on port 3000'); });
-
إجابة Mustafa Suleiman سؤال في كيفية حذف عنصر من قواعد البيانات مع العناصر المرتبطة بها في MongoDB؟ كانت الإجابة المقبولة
الطريقة الأولى لحل المشكلة هي باستخدام مفهوم الـ "حذف المتوالي" (Cascading Delete) في MongoDB، وعند حذف عنصر من Model Product، يمكنك تعيين خاصية تؤدي إلى حذف جميع العناصر المرتبطة به في Model Cart تلقائيًا.
والأمر يعتمد على كيفية تطبيقك للعلاقة بين Model Product و Model Cart في تطبيقك، فإذا كنت تستخدم مرجعًا يشير إلى عنصر في Model Product في Model Cart (مثل استخدام ObjectId)، فتستطيع الاستفادة من خاصية "onDelete" في واجهة العلاقة للقيام بذلك.
وإليك مثال على كيفية تحقيق حذف المتوالي بين Model Product و Model Cart باستخدام مكتبة Mongoose في Node.js، ولنفترض أن لديك مودل Product ومودل Cart مثل التالي:
// Product Model const mongoose = require('mongoose'); const productSchema = new mongoose.Schema({ name: String, // ... other product properties }); const Product = mongoose.model('Product', productSchema); module.exports = Product; مودل Cart:
// Cart Model const mongoose = require('mongoose'); const cartSchema = new mongoose.Schema({ products: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Product' }], // ... other cart properties }); const Cart = mongoose.model('Cart', cartSchema); module.exports = Cart; بإمكانك إضافة خاصية "onDelete" في علاقة Model Cart مع Model Product لتحقيق حذف المتوالي:
const cartSchema = new mongoose.Schema({ products: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Product', onDelete: 'CASCADE' }], // ... other cart properties }); وبذلك عندما يتم حذف عنصر من Model Product، سيقوم MongoDB تلقائيًا بحذف جميع العناصر المرتبطة به في Model Cart بفضل الخاصية "onDelete" التي تم تعيينها في واجهة العلاقة.
والخاصية "onDelete" ليست جزءًا من MongoDB نفسها، بل هي خاصية تقدمها مكتبة Mongoose لتسهيل التعامل مع قواعد البيانات. لذلك، ويجب التأكد من استخدام Mongoose أو أي مكتبة أخرى تقدم تلك الخاصية حتى تتمكن من الاستفادة من الحذف المتوالي.
الطريقة الثانية هي باستخدام طريقة deleteMany() مع استعلام يحدد كل العناصر التي تريد حذفها، وكمثال:
const productsCollection = db.collection('products'); const cartsCollection = db.collection('carts'); // Find all products that are in the cart const productsInCart = cartsCollection.find({ productId: { $in: productsCollection.distinct('id') } }); // Delete all products that are in the cart productsInCart.deleteMany(); سيعمل الكود السابق على حذف جميع المنتجات التي توجد في عربة التسوق، بالإضافة إلى إمكانية استخدام طريقة deleteOne() لحذف عنصر واحد فقط.
أي إن كنت تريد حذف المنتج الذي له معرف 1234567890, فالطريقة كالتالي:
const productsCollection = db.collection('products'); // Delete the product with id 1234567890 productsCollection.deleteOne({ id: 1234567890 }); والقرار بين استخدام "حذف المتوالي" باستخدام خاصية "onDelete" في واجهة العلاقة أو استخدام deleteMany() و deleteOne() يعتمد على حاجتك الفعلية وتصميم قاعدة البيانات والتطبيق الخاص بك، وسأوضح لك الفرق بالمقارنة بينهم:
استخدام حذف المتوالي (onDelete):
المزايا:
يقوم بالحفاظ على سلامة علاقات البيانات بطريقة أكثر تلقائية، وعند حذف عنصر من Model Product، ستتم إزالة العناصر المرتبطة به من Model Cart تلقائيًا دون الحاجة إلى كتابة الكود يدويًا. أكثر ملاءمة وسهولة للتطبيقات التي تعتمد بشكل كبير على العلاقات وتحتاج إلى تنظيم بياناتها بشكل جيد. العيوب:
يتطلب استخدام مكتبة معينة (مثل Mongoose) التي تدعم هذه الخاصية، وإذا قررت استخدام مكتبة أخرى قد لا تكون تلك الخاصية متاحة. استخدام deleteMany() و deleteOne():
المزايا:
تحكم أكبر بالعملية وأوضح للمطورين، وتستطيع كتابة الكود بشكل دقيق لحذف العناصر المطلوبة بناءًا على متطلبات تطبيقك. قابل للتطبيق دون الحاجة إلى مكتبة خاصة بـ "حذف المتوالي". العيوب:
أكثر تعقيداً في بعض الحالات، خاصة إذا كان لديك عدة نماذج مرتبطة بعلاقات معقدة. وببساطة إن كانت علاقاتك معقدة وتعتمد على عمليات حذف متعددة في عدة نماذج، فمن الأفضل استخدام deleteMany() و deleteOne() لتحكم أكبر في العملية، أما إذا كانت العلاقات بسيطة وترغب في تبسيط عملية الحذف، فالحذف المتوالي باستخدام "onDelete" هو الخيار الأمثل.
-
إجابة Mustafa Suleiman سؤال في أيهما أكثر أمانًا: User::find($id) أم User::findOrFail($id) في Laravel؟ كانت الإجابة المقبولة
استخدام findOrFail($id) بدلاً من find($id) يعتبر عملية جيدة في بعض الحالات وذلك لضمان أمان التطبيق والتعامل مع الأخطاء بشكل أفضل.
ولكن يجب توضيح الفرق بين الاثنين:
User::find($id)
تلك الطريقة تقوم بالبحث عن سجل في قاعدة البيانات باستخدام المفتاح الرئيسي للجدول (وغالبًا ما يكون الـ ID)، وإن وجد السجل، فيتم إرجاع السجل نفسه، وإذا لم يتم العثور عليه، فيتم إرجاع قيمة null.
User::findOrFail($id)
نفس عملية البحث السابق، ولكن في حالة عدم العثور على السجل، فيتم برفع استثناء من نوع ModelNotFoundException، وذلك يعني أنه إذا لم يتم العثور على السجل، يتم رمي استثناء وتوقف تنفيذ البرنامج، مما يتطلب التعامل مع الاستثناء في الكود.
السبب الرئيسي لاستخدام findOrFail($id) هو تجنب الحصول على قيمة null ومعالجة تلك القيمة في حالة عدم وجود السجل المطلوب في قاعدة البيانات، وعند استخدام findOrFail($id)، تستطيع ببساطة التعامل مع الاستثناء المرتبط في الكود، مما يسهل تحديد الأخطاء والتعامل معها بشكل أفضل.
إذا قمت بتعيين APP_DEBUG=true في ملف .env، فذلك سيساعدك في رؤية الأخطاء والاستثناءات التي تم رفعها، ولكن لا ينصح بالاعتماد على ذلك الإعداد في بيئة الإنتاج، حيث سيكشف عن معلومات حساسة.
أي بإختصار، سيتسبب استخدام User::find($id) في تلقي المستخدمين خطأً 500 ، مما قد يكشف عن بيانات غير مقصودة، وسيتسبب استخدام User::findOrFail($id) في تلقي المستخدمين خطأ 404 ، والذي يعد أكثر أمانًا.
بالإضافة إلى ذلك ، فإن استخدام User::findOrFail($id) سيساعد على منع الأخطاء التي قد تحدث إذا لم يكن المستخدم موجودًا، وإذا استخدمت User::find($id) ولم يكن المستخدم موجودًا ، فستتلقى خطأً 500.
مما يؤدي إلى توقف API الخاص بك عن العمل، وسيكون من الصعب تحديد سبب المشكلة، وسيتسبب استخدام User::findOrFail($id) في تلقي خطأ 404 ، مما سيسهل تحديد سبب المشكلة وإصلاحها.
-
إجابة Mustafa Suleiman سؤال في اين يتم تخزين الصور في المواقع كانت الإجابة المقبولة
من خلال الكود في موقعك، حيث تتعامل مع المجلد الخاص بتخزين الصور كما تتعامل معه في حاسوبك، عليك بالإشارة إلى مسار المجلد في الكود الخاص بك مع اسم الصور.
وأيضًأ تتيح الاستضافة لك إمكانية توليد رابط مباشر للصورة بعد تحميلها عبر FTP، ويمكنك العثور على الصورة داخل مجلدات الاستضافة الخاصة بك ومن ثم الحصول على الرابط الكامل الذي يؤدي إلى الصورة، مثال للرابط:
http://example.com/path/to/image.jpg
-
إجابة Mustafa Suleiman سؤال في كيف يمكنني تغيير جودة الفيديو إلى 360 بكسل في تطبيق أندرويد؟ كانت الإجابة المقبولة
عليك بإضافة مستودع JitPack إلى إلى قسم repositories في ملف build.gradle:
repositories { ... maven { url 'https://jitpack.io' } } ثم، تحتاج إلى إضافة تبعية FFmpegMediaMetadataRetriever إلى قسم dependencies في ملف build.gradle:
dependencies { implementation 'com.github.wseemann.FFmpegMediaMetadataRetriever:FFmpegMediaMetadataRetriever-core:v1.0.15' } وفي حال أردت إضافة أي مستودع لمكتبة أخرى نتوجه إلى موقع https://jitpack.io ثم ألصق رابط المستودع الخاص بالمكتبة على GitHub وستظهر لك الإصدارات المتاحة ونضغط على get it وستجد الرابط بالأسفل:
وتستطيع قراءة المستند الرسمي الخاص بالمكتبة في حال واجهتك مشكلة معينة:
https://github.com/wseemann/FFmpegMediaMetadataRetriever -
إجابة Mustafa Suleiman سؤال في مشاكل في بوابات الدفع - كيف يمكن التعامل مع المشاكل المحتملة وتجنب فقدان المبلغ؟ كانت الإجابة المقبولة
المشاكل المعروفة هي كالآتي:
فشل المعاملة لأسباب مختلفة ، مثل عدم وجود رصيد كافٍ في بطاقة الائتمان أو انتهاء صلاحية البطاقة أو إدخال بيانات غير صحيحة. استخدام بوابات الدفع لعمليات الاحتيال ، مثل سرقة بطاقات الائتمان أو استخدام بيانات بطاقة الائتمان المسروقة لإجراء عمليات شراء غير مصرح بها. اختراق بوابات الدفع ، مما يعرض بيانات بطاقات الائتمان للخطر. وعند إتمام عملية الدفع بنجاح، ستحصل عادة على استجابة (response) من بوابة الدفع، تتضمن:
حالة الدفع: مثل "ناجح" أو "فشل". رقم المعاملة: وهو رقم مرجعي فريد للمعاملة. الرد من البنك: رسالة من بوابة الدفع أو البنك تحتوي على تفاصيل الدفع الناجح أو الفشل. رمز الاستجابة: يوحد رموز للردود تشير إلى نتيجة الدفع (مثل رمز 200 للنجاح). بعد الحصول على تلك البيانات، تستطيع تسجيل بعض المعلومات الأساسية في قاعدة البيانات للتفريق بين الدفعات الناجحة والفاشلة وتتبع حالة الطلبات، ومنها:
رقم المعاملة. حالة الدفع (مثل "ناجح" أو "فشل"). المبلغ المدفوع. تاريخ ووقت الدفع. أخر 4 أرقام من البطاقة أو الحساب البنكي. معلومات المستخدم (اختياري، يعتمد على احتياجات موقعك). وإليك مثال للاستجابة من خلال بوابة دفع stripe:
{ "id": "ch_1234567890", "object": "charge", "created": 1582950736, "livemode": false, "currency": "usd", "amount": 1000, "description": "A test charge", "source": { "id": "src_1234567890", "object": "source", "type": "card", "last4": "1234", "exp_month": 12, "exp_year": 2023, "name": "John Doe", "address_line1": "123 Main Street", "address_line2": null, "city": "Anytown", "state": "CA", "country": "US", "zip": "91234", "cvc": "123" }, "destination": { "id": "cus_1234567890", "object": "customer" }, "status": "succeeded", "failure_message": null, "failure_code": null, "charge_back_id": null, "refunds": [ { "id": "re_1234567890", "object": "refund", "created": 1582950736, "amount": 1000, "currency": "usd", "reason": "customer_requested", "balance_transaction": "bal_1234567890" } ], "balance_transaction": { "id": "bal_1234567890", "object": "balance_transaction", "created": 1582950736, "amount": 1000, "currency": "usd", "description": "Charge succeeded", "type": "charge", "balance_delta": 1000, "available_on": 1582950736, "net_received": 1000, "fee": 0, "transfer_group": null }, "metadata": { "foo": "bar" } } وبالطبع تستطيع إجراء إختبارات على بوابة الدفع للتأكد من عملها بشكل سليم قبل نشر الموقع.
وأيضًا لمعلوماتك علميات الاسترجاع للأموال يتم معالجتها من قبل بوابة الدفع.
-
إجابة Mustafa Suleiman سؤال في كيفية تسجيل شاشة وكاميرا الهاتف أثناء الاختبار باستخدام Node.js و React؟ كانت الإجابة المقبولة
تسجيل شاشة الهاتف أثناء الاختبار
هناك مكتبة تُدعى react-screen-recorder تستطيع الإعتماد عليها لتسجيل الشاشة أثناء الاختبار، وتلك المكتبة تعمل مع React وتُتيح للمستخدمين تسجيل شاشة هاتفهم أثناء استخدام التطبيق، ولتثبيتها استخدم الأمر التالي:
npm install react-screen-recorder وستجد طريقة الاستخدام في المستودع الرسمي للمكتبة:
https://github.com/DeltaCircuit/react-media-recorder وإليك مثال:
import React, { useState } from 'react'; import { ScreenRecorder } from 'react-screen-recorder'; const ScreenRecorderComponent = () => { const [isRecording, setIsRecording] = useState(false); const handleRecording = (blob) => { // يمكنك إرسال الـ blob إلى المنصة الخاصة بك للمراجعة هنا console.log(blob); }; return ( <div> <h1>تسجيل شاشة الهاتف</h1> <ScreenRecorder onRecordingComplete={handleRecording} isRecording={isRecording}> {({ startRecording, stopRecording }) => ( <> {isRecording ? ( <button onClick={stopRecording}>إيقاف التسجيل</button> ) : ( <button onClick={startRecording}>بدء التسجيل</button> )} </> )} </ScreenRecorder> </div> ); }; export default ScreenRecorderComponent; ضع المكون في التطبيق وسيظهر زرًا يمكن للمستخدم النقر عليه لبدء تسجيل شاشة هاتفه، وبمجرد أن ينتهي المستخدم من تسجيل الشاشة، ستُستدعى وظيفة handleRecording وستُمرر لها blob الخاص بتسجيل الفيديو، هنا تستطيع إرسال الـ blob للواجهة الخلفية للمراجعة.
تسجيل فيديو من الكاميرا الأمامية أثناء الاختبار
وبالنسبة لتسجيل الفيديو من الكاميرا الأمامية، باستطاعتك استخدام تقنية التسجيل بواسطة MediaRecorder، والوصول إلى الكاميرا الأمامية باستخدام API "getUserMedia"، وهي API's متاحة من قبل المتصفح.
وإليك مثال:
async function startRecording() { const stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: 'user' }, audio: false }); const mediaRecorder = new MediaRecorder(stream); const chunks = []; mediaRecorder.ondataavailable = (e) => { if (e.data.size > 0) { chunks.push(e.data); } }; mediaRecorder.onstop = () => { const videoBlob = new Blob(chunks, { type: 'video/mp4' }); // قم بإرسال الـ videoBlob للمراجعة على المنصة الخاصة بك هنا }; mediaRecorder.start(); } function stopRecording() { mediaRecorder.stop(); } وعليك باستدعاء startRecording() عند بدء الاختبار و stopRecording() عند انتهائه.
تحميل الفيديوهات للمراجعة
وبمجرد انتهاء الاختبار، تستطيع إرسال الفيديوهات (شاشة الهاتف والكاميرا الأمامية) إلى المنصة الخاصة بك للمراجعة، باستخدام Node.js والمكتبات المناسبة لاستقبال الفيديوهات وتخزينها في الخادم أو قاعدة البيانات.
وبالطبع نستخدم Express.js كإطار عمل لبناء نظام السيرفر واستقبال طلبات الفيديوهات، والإعتماد على مكتبات أخرى مثل Multer لتحميل الفيديوهات على الخادم.
مثال:
const express = require('express'); const multer = require('multer'); const app = express(); const upload = multer({ dest: 'uploads/' }); app.post('/upload', upload.single('video'), (req, res) => { // يتم تخزين الفيديو هنا في قاعدة البيانات أو أي مكان آخر تفضله console.log(req.file); res.send('تم تحميل الفيديو بنجاح!'); }); app.listen(3000, () => { console.log('السيرفر يعمل على منفذ 3000'); }); وبإمكانك استدعاء API نقطة النهاية /upload عند انتهاء الاختبار لتحميل الفيديوهات.