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

Hassan Hedr

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

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

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

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

    38

كل منشورات العضو Hassan Hedr

  1. حاليا في الأكاديمية لا يوجد دورات بلغة بايثون، يمكنك الاطلاع على سلسلة مقالات Python101 المنشورة في الأكاديمية فهي شاملة لكل أساسيات اللغة
  2. يمكنك تشغيل تطبيقاتك في CPanel عبر NodeJS فقط إذا تم تنصيب الحزم التالية من قبل مدير الاستضافة (يجب سؤال الدعم الفني عن دعمها ل NodeJS) ea-ruby27-mod_passenger ea-apache24-mod_env ea-nodejs10 # أو أي نسخة أخرى قم بالدخول الى حسابك وفتح مدير الملفات والذهاب الى مسار مجلد المنزل home وفتح ملف bashrc. وإضافة السطر التالي وحفظ الملف (بحسب نسخة NodeJS المنصبة يختلف اسم المسار) export PATH=/opt/cpanel/ea-nodejs10/bin/:$PATH بعدها تقوم بالدخول من حسابك إلى terminal وتنفذ الأمر التالي (لتفعيل السطر السابق): source ~/.bashrc الآن أصبح بإمكانك استخدام الأمر node لتنفيذ البرامج، بافتراض انك قمت بنسخ ملفات مشروعك قم بتغيير المسار لملف مشروعك وتنفيذ البرنامج كالتالي: cd ~/path/to/project node index.js
  3. نفذ التابع قبل إظهار الخرج لا يمكن أن يحدث العكس يتم تنفيذ استدعاء تابع قراءة الملف أولا readFile('./content/first.txt', 'utf8', (err, result) => { ... }) ثم عند انتهاء قراءة الملف يتم استدعاء التابع الممرر للتابع السابق والذي يحوي السطر التالي console.log(result)
  4. المثال السابق يقوم بطباعة بعض السطور وقراءة ملف وطباعة محتوياته بالنسبة لترتيب تنفيذ هذه الأوامر فهو متعلق بطريقة عمل JavaScript و حلقة الأحداث Event Loop يمكن القراءة عنها في المقال التالي أولا ينفذ السطر console.log('started a first task') // started a first task بعدها ينفذ الأمر التالي والذي يبدأ عملية قراءة الملف والأهم تسجيل التابع الممرر ليتم استدعاءه لاحقا عند الانتهاء من القراءة، تنفيذ التابع سيأخذ دوره في حلقة الاحداث ولا يستدعى التابع حتى يحين دوره (لا خرج في تنفيذ هذه المرحلة) readFile('./content/first.txt', 'utf8', (err, result) => { ... }) // بعدها ينفذ السطر التالي console.log('starting next task') // starting next task لقد انتهت عملية تنفيذ جميع التعليمات في الملف، الان يتم اخذ التعليمات الموجودة في حلقة الأحداث Event Loop ويتم تنفيذها بالتتالي، إذا كانت الحلقة فارغة وليس هناك اجرائيات أبناء للاجرئية الحالية سيتم الانتهاء من التنفيذ والخروج فورا في حالتنا لا تزال عملية القراءة قائمة وعندما تنتهي ستقوم باستدعاء التابع الذي ممرته لها سابقا الذي سينتظر في حلقة الاحداث ليأتي دوره والآن دور حلقة الأحداث لذا ستنفذ محتويات التابع التالي (err, result) => { if (err) { console.log(err) return } console.log(result) console.log('completed first task') } // ... محتويات الملف ... // completed first task الغرض من تصميم التنفيذ بهذه الطريقة والذي يدعى Non-Blocking I/O هو عدم اشغال الاجرائية الحالية بعمليات القراءة والكتابة الخارجية، حيث يتم تنفيذ جميع التعليمات الآن وتأجيل التعليمات الغير متزامنة Asynchronous لوقت لاحق
  5. التعديلات في الحزم الخارجية يجب أن تكون داخل تطبيقك وليس بتعديل مباشر على الحزمة، هذا يقتضي أن توفر الحزمة طريقة لتغيير عملها مثلا عبر التحميل الزائد للتوابع الموروثة في حالتك يمكن التعديل على LoginController من داخل مشروعك والتحميل الزائد للتابع username المسؤول عن تحديد الحقل الخاص باسم المستخدم كالتالي: namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use Illuminate\Foundation\Auth\AuthenticatesUsers; class LoginController extends Controller { use AuthenticatesUsers; protected $redirectTo = '/home'; public function __construct() { $this->middleware('guest')->except('logout'); } public function username() { return 'username'; // تحدد اسم الحقل هنا } }
  6. وجود فراغ بين أي محددين في CSS يعني أن المحدد الثاني داخل أبناء المحدد الأول table .class في مثالك تستهدف أبناء الوسم table الحاوين على الصنف class table .class { ... } <table> <tr class="class" /> <!-- مستهدف --> <tr> <td> <div class="class">...</div><!-- مستهدف --> </td> </tr> </table> عدم وجود فراغ يعني أن العنصر المستهدف بالمحدد الأول يجب أن يحوي نفسه على المحدد الثاني table.class في مثالك تستهدف أي وسم table يحوي نفسه على الصنف class table .class { ... } <table class="class"> <!-- مستهدف --> ... </table>
  7. يمكنك إرسال إشارة إلى الإجرائية تعلمها برغبتك في انهاء عملها، وهي بدورها تقوم بالاعمال اللازمة والانهاء، أو أن تقوم بإنهائها قسرا عن طريق نظام التشغيل في لينكس تستخدم الأمر kill لإرسال الاشارات الى الاجرائيات ومنها اشارات انهاء العمل: SIGTERM اشارة للطلب من الاجرائية الخروج، سيتم تلقي الاشارة من الاجرائية والمباشرة بعمليات الانهاء kill -15 PID SIGKILL اشارة انهاء الاجرائية قسرا حيث يقوم نظام التشغيل بايقاف عمل الاجرائية فورا kill -9 PID حيث PID هو معرف الاجرائية يمكن الحصول عليه من خرج تنفيذ التعليمة التالية ps
  8. أن برنامج MYSQL Workbench هو اداة لخدمة MYSQL للتفريق بينهما نفذ الأمر التالي mysql إذا ظهر لك الخرج التالي فإن الخدمة تعمل mysql> وإلا قم بالذهاب إلى services وابحث عن الخدمة MySQL وقم ببدئها start service ثم حاول مجددا
  9. أداة MYSQL Workbench هي برنامج يحوي عدة أدوات تساعدك في استعراض وتعديل وتصميم وتهجير جداول البيانات، وهي تقوم بذلك بالتواصل مع خدمة MYSQL، أنت لن تتواصل مع الأداة بل مع الخدمة مباشرة يمكنك اتباع الخطوات التالية: تأكد من تشغيل خدمة MySQL على جهازك والتأكد من عنوان المنفذ Port التي تعمل عليه الخدمة (الافتراضي يكون 3306) تأكد من اسم المستخدم وكلمة المرور على الخدمة الذي تريد الدخول منه (الافتراضي هو المستخدم root وليس لديه كلمة سر) (اختياري) يمكنك الاتصال مباشرة بقاعدة بيانات معينة منشئة سابقة تأكد من اسمها قم بتمرير القيم السابقة لمعاملات تابع الاتصال createConnection، التالي طريقة القيام بالاتصال بالقيم الافتراضية: var con = mysql.createConnection({ host : 'localhost', // عنوان الخدمة port : 3306, // اختياري يمكن تجاهله في حال قيمته افتراضية user : 'root', // اسم المستخدم password : '', // كلمة سر المستخدم database : 'database_name' // اختياري اسم قاعدة البيانات });
  10. نعم عمليات القراءة تحسب بعدد المستندات Documents المقروءة استدعاء كامل المجموعة Collection سيكلفك عمليات قراءة بعدد المستندات داخلها عبر استدعاء فقط المستندات Documents التي تحتاجها (لتقليل عمليات القراءة) باستعلام واحد فقط (لتقليل السرعة)، مثلا باستخدام المعامل in سيجلب لك فقط المستندات بالمعرفات المحددة كالتالي: productsCollection.where('id', 'in', [ /* ... معرفات المنتجات المطلوبة */ ]) أو حتى تقليل عدد المستندات أكثر اذا كنت تريد استردادهم بغرض العرض بحيث فقط تطلب العدد الذي تحتاجه للعرض وتتصفح بين المجموعات باستخدام pagination كالتالي: productsCollection.where('id', 'in', [ /* ... */ ]) .startAt(21) // ترتيب أول منتج في الصفحة .limit(10) // عدد المنتجات المطلوبة
  11. المشكلة في حال طابق الطلب أي من المسارين "/" و "about/" سيتم إرسال رد للعميل، ولن ينتهي التنفيذ وسيتم محاولة ارسال الرد الموجود في نهاية التابع وهذا ينتج خطأ لأنه تم ارسال رد سابق للعميل وانتهى الاتصال الحل يكون بانهاء تنفيذ التابع (باستخدام return) عند أول إرسال لرد كالتالي: const server = http.createServer((req, res) => { if (req.url === '/') { return res.end('Welcome to our home page') } if (req.url === '/about') { return res.end('Here is our short history') } res.end(` <h1>Oops!</h1> <p>We can't seem to find the page you are looking for</p> <a href="/">back home</a> `) }) أو وضع الردود في سلسلة if else حيث تضمن تنفيذ رد واحد فقط كالتالي: const server = http.createServer((req, res) => { if (req.url === '/') { res.end('Welcome to our home page') } else if (req.url === '/about') { res.end('Here is our short history') } else { res.end(` <h1>Oops!</h1> <p>We can't seem to find the page you are looking for</p> <a href="/">back home</a> `) } })
  12. عند التعامل مع الملفات عن طريق الحزمة fs يمكنك تحديد عدة طرق تنوي التعامل فيها مع الملف المذكور عبر تمرير المعامل flag يوجد له عدة قيم بعدة معاني أمثلة: 'a' يتم فتح الملف المذكور للكتابة واضافة المحتوى لنهاية الملف، إذا لم يكن الملف موجودا فسيتم انشائه (هذا كما في المثال المذكور) 'w' يتم فتح الملف المذكور للكتابة وازالة محتوياته وكتابة المحتويات الممررة كما لو انك تنشئ ملف جديد، إذا لم يكن الملف موجودا فسيتم انشائه 'r' يتم فتح الملف المذكور للقراءة، وسيظهر خطأ في حال الملف لم يكن موجودا (لا يتم تمريرها للتابع writeFileSync بل للتابع open) في مثالك السابق في كل مرة ستنفذ البرنامج سيقوم بإضافة محتويات الملفين المذكورين إلى الملف content/result-sync.txt
  13. حاول انشاء Middleware وتسجيله ضمن النواة Kernel، تتحقق داخله من نوع المستخدم وبعدها تقوم بفصل الاتصال مع قاعدة البيانات، ثم تغيير الاعدادات ديناميكيًا، ثم إعادة الاتصال مجددا واكمال الطلب كالتالي class ChangeDatabaseForUser { public function handle(Request $request, Closure $next, ...$guards) { \DB::disconnect('mysql'); \Config::set('database.connections.mysql.database', auth()->user()->type == 0 ? 'db1' : 'db2'); \DB::reconnect(); return $next($request); } }
  14. الثلاث نقط تسمى صيغة النشر (Spread Syntax) ببساطة فكر بها أنها تنشر محتويات ما بعدها (بشرط أن يكون من النوع iterator) ...[1, 2, 3] // 1, 2, 3 .. [[1,2,3], {name: 'ahmed'}, 'abc'] // [1,2,3], {name: 'ahmed'}, 'abc' يستفاد منها عند تعريف مصفوفة، ونريد نشر عناصر مصفوفة داخلها const arr = [1, 2, 3] console.log([...arr, 4, 5, 6]) // [1, 2, 3, 4, 5, 6] كما نشر المصفوفات، يستفاد منها لنشر الأغراض أيضا عند تعريف غرض const obj = {name: 'Ahmed'}; console.log({ ...obj, age: 25 }) // { name: 'Ahmed', age: 25 } يستفاد منها عند تمرير معاملات لتابع، ولديك المعاملات في مصفوفة تقوم بنشرها ثم تمريرها كالتالي function sum(x, y, z) { return x + y + z; } const numbers = [1, 2, 3]; console.log(sum(...numbers)); // 6 // الاستدعاء السابق يكافئ الاستدعاء التالي console.log(sum(1, 2, 3)); // 6
  15. لديك أرضية جيدة في JavaScript وعدة مفاهيم متقدمة تجعلك قادرا على تنفيذ المشاريع، الخبرات التي ذكرتها كافية لبناء تطبيقات في NodeJS لا تعتمد على المسميات من Junior و Senior فهي نسبية حسب كل مؤسسة وما تتطلبه من مهارات، قد تلقبك مؤسسة بمطور متوسط، بينما مهاراتك تكفي حاجة مؤسسة أخرى ستدعوك مطور متقدم
  16. هل يمكن ارفاق صورة للإعدادات في قسم GitHub Pages في اعدادات المستودع تكون فيها قائمة اختيار المجلد مفتوحة من فضلك
  17. يمكنك تمرير المعزز كالتالي، ويمكنك أيضا الاستغناء عن تمرير preloadedState اذا كنت لا تستخدم حالة ابتدائية import { createStore } from 'redux'; ... const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(); const store = createStore(reducer, preloadedState, composeEnhancers));
  18. تأكد من تعزيز ال Middlewares في مشروعك بمحسن الاضافة ليتم الربط مع الإضافة، كالتالي import { createStore, applyMiddleware, compose } from 'redux'; const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; const store = createStore(reducer, preloadedState, composeEnhancers( applyMiddleware(...middleware /* مرر كل الـ middlewares التي تستخدمها هنا */) )); من فضلك أرفق الخطأ الذي يظهر لك إن لم تنجح بتنفيذ الربط
  19. المشكلة انك قمت برفع ملفات مشروعك كاملة (المصدر مع ملفات الموقع) والاعدادات التي قمت بها تقوم باستضافة المشروع باعتبار ان ملفات موقعك موجودة بالجذر مباشرة (هذا سبب الخطأ 404) لكن في مشروعك ملفات الموقع موجودة في المجلد app، قم بالدخول مجددا الى اعدادات GitHub Pages داخل مستودع المشروع ومن هناك يمكنك تغيير مجلد ملفات الموقع الى المجلد app (الافتراضي هو مجلد الجذر) كما في الصورة
  20. قم بإنشاء مستودع جديد على حسابك في Github قم برفع ملفات مشروعك (ملفات الموقع) الى المستودع الذي انشئته، أبسط طريقة عبر الرفع اليدوي عن طريق واجهة موقع Github داخل مستودعك قم بتفعيل Github Pages داخل مستودعك بالذهاب الى الاعدادات Settings، ثم النزول الى القسم Github Pages واختيار الفرع branch الذي يحتوي موقعك، ثم حفظ الاعدادات Save بعدها سيظهر لك رابط لصفحة مشروعك المستضاف يمكنك الدخول من خلاله
  21. الجلسات Session هي طريقة لتخزين البيانات يمكن تنفيذها بطريقتين تخزين البيانات على الخادم وتوليد معرف لها وارساله للعميل يبرزه عند كل طلب للخادم (تخزين البيانات وادارتها مكلف) تخزين البيانات لدى العميل والاعتماد عليه لابرازها في كل مرة مثل تخزين البيانات في Cookie (لا يمكن الوثوق بأمان البيانات من طرف العميل) JWT هي طريقة لتخزين البيانات بأمان داخل قيمة نصية، ولا يكون الحاجة للخادم ان يقوم بادارة تخزينها (لا كلفة لتخزين البيانات / وثوق عالي بمحتوى البيانات)
  22. الأمر التالي (الذي نفذته) يتحقق من الاعتماديات لتطوير تطبيقك، ونتيجته بالأسفل أن جميع الاعتماديات منصبة على جهازك بشكل سليم cordova requirements اذا كنت تقصد حفظ الخرج مع المدخلات على الطرفية لديك يمكنك (كل النص الذي تشاهده) يمكنك تحديده كما تحدد أي نص والضغط على Ctrl + C و Ctrl + V في أي محرر نصوص
  23. في c++ علامة الاقتباس المفردة" ' " تدل على النوع محرف char، وعلامة الاقتباس المزدوجة " " " تدل على نص الخطأ في المثال السابق هو عند محاولة جمع محرف و عدد int، بدل علامات الاقتباس للفراغات بعلامة مزدوجة كالتالي string findTrees(int arr[],int n){ string position; int a; if(arr[0]==arr[2]){ a=abs(arr[3]-arr[1]); position=abs(arr[0]-a) + " " + to_string(arr[1]) + " " + abs(arr[0]-a) + " " + arr[3]; }
  24. تعني تغيير مسار العمل الحالي (يكون مكتوبا على يسار المؤشر) إلى مسار القرص E لديك، بتنفيذ التعليمة التالية ستلاحظ تغير المسار الحالي إلى القرص E وهو المكان الذي تريد فيه انشاء مشروعك الجديد e: الأمر التالي ينشئ لك مشروع cordova جديد داخل المسار الحالي داخل مجلد جديد ستعطيه الاسم "cordova-hello-word" cordova create cordova-hello-word بعدها تكون انشأت مشروعا جديدا جاهزا لبدء التطوير ستجد ملفاته داخل الملف "cordova-hello-word" تغير مسار اعمل الى داخل المجلد بتنفيذ الامر التالي cd cordova-hello-word لاحقا يمكنك ذكر سؤالك في التعليقات تحت فيديو الدرس الذي تحاول الاستفسار عنه ليقوم المدربون بمساعدتك
  25. NextJS لا يدعم تمرير الاعدادات الى webpack مباشرة يمكنك بدل من ذلك تمرير الدالة webpack وتعديل اعدادات webpack داخل ملف اعداد next.config.js module.exports = { webpack(config, { buildId, dev, isServer, defaultLoaders, webpack }) { config.module.rules[3].oneOf.forEach((moduleLoader, i) => { Array.isArray(moduleLoader.use) && moduleLoader.use.forEach((l) => { if ( l.loader.includes("\\css-loader") && !l.loader.includes("postcss-loader") ) { const { getLocalIdent, ...others } = l.options.modules; l.options = { ...l.options, modules: { ...others, localIdentName: "[hash:base64:6]", // هنا يمكنك تخصيص الاسم }, }; } }); }); return config; }, };
×
×
  • أضف...