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

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

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

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

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

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

    2

كل منشورات العضو شرف الدين حفني

  1. Bootstrap و tailwind كلًا منهما مكاتب للcss ويمكن إستخدام أيًا منهما كبديلًا للاخر ولكن الفرق الجوهري بينهما يقع في النقطة التالية Bootstrap هي في الأساس موجهة لتصميم واجهات متناسبة لجميع الشاشات وتأتي أيضًا ببعض الcomponents المُعرفة سابقة ولكن سر قوتها في الأساس تصميم الواجهات المتناسبة لجميع الشاشات بينما على الجانب الأخر Tailwind css توفر للمطور العديد من الأصناف التي تساعد على التصميم حيث تحتوي على العديد من التصميمات والتنسيقات المُعرفة مسبقًا وهذا سر قوتها بينما React.js فهي مكتبة للجافاسكريبت تُستخدم بشكلٍ أساسي لبناء ما يُسمى بالSPA(Single page applications) أو تطبيقات الصفحة الواحدة, حيث أن في React يتم إستخدام صفحة html واحدة فقط ويتم عمل render لتلك الصفحة لحقن مكونات جافاسكريبت بداخلها ولكن في النهاية تكون صفحة html واحدة ويحدث هذا عبر ما يُسمى بالVirtual dom وهو تكنيك متبع من قِبل React من أجل تسريع عملية الrender حيث أن في العادي عند التلاعب بالDOM يتم عمل Render للصفحة كلها ولكن بإستخدام تقنية الVirtual dom يتم تغيير فقط العناصر التي نحتاج لتغييرها مما يحسن من أداء التطبيق بشكلٍ ملحوظ
  2. المشكلة لديك في أنك تقوم بتعريف السوكيت في بداية الكائن وبالتالي عندما يحدث أي عملية Re-render يتم تعريف الكائن مرة أخرى, لحل تلك المشكلة يمكنك تخزين السوكيت في state ومن ثم تعريف خطاف useEffect نقوم بداخله بتعريف السوكيت وفي نهاية الأمر يكون الشفرة البرمجية لديك على الهيئة التالية const [socket, setSocket] = useState() useEffect(()=>{ if(!socket) setSocket(io('أكتب هنا رابط خادم السوكيت لديك')) },[]) وفي الاجزاء التي تستخدم فيها السوكيت مثل الكائن app نقوم أولًا بالتأكد من أن السوكيت تم تعريفه عبر الشفرة التالية if(socket){ socket.on('اسم الحدث لديك') ////تعريف باقي الأحداث }
  3. بالإضافة إلى شرح وائل يمكنك التفكير في الفرق بين الخوارزميتين عبر المكدسstack والطابور queue حيث يمكننا تمثيل خوارزمية البحث بالعمق وكأنها على هيئة مكدس حيث تعمل بتقنية LIFO حيث لو اعتبرنا لدينا العقد التالية { a:[b,c], b:[d], d:[f], f:[] } حيث كل مفتاح في القائمة السابقة يمثل عقدة والمصفوفة المرافقة للمفتاح تُمثل العقد المُتصلة بتلك العقدة لو قمنا بتطبيق االبحث بعمق سنلاحظ أننا نقوم بالدخول إلى العقدة a, ثم ندخل بعدها العقدة b فيصبح شكل المكدس لدينا a,b وبما أن b في أعلى المكدس فنقوم بإستكمال العمليات على b فندخل إلى العقدة d فتصبح بالتالي d في قمة المكدس فندخل إلى f فتصبح في قمة المكدس فندخل إليها نجد نهاية فارغة فنرجع إلى العنصر السابق في المدس نجده a فنستكمل العمليات عليه وندخل إلى c فيصبح بالتالي ترتيب العناصر لدينا a,b,d,f,c بينما عند إستخدام البحث بالعرض يكون الأمر كأننا إستخدمنا طابور queue فنعمل بتقنية الFIFO أي أن العنصر الذي يدخل أولًا نقوم بإستكمال العمليات عليه ومن ثم نرى العنصر الذي دخل بعده في حالتنا هنا نقوم بالدخول إلى العنصر a ومن ثم نقوم بإدخال العنصر b إلى الطابور ولكن نستكمل العمليات على العنصر a فنقوم بإدخال العنصر c بعدها نقوم بالدخول إلى العنصر التالي في الطابور وهو العنصر b فنقوم بإدخال العنصر d في الطابور ولكن لا نقوم بعمليات عليه وإنما نقوم بالعمليات على العنصرc لأنه سابق الدور في الطابور فبإختصار في حالة البحث بعمق نقوم بالمرور على جميع العقد التي نقابلها على عكس البحث بعرض نقوم بالمرور على العقد بالترتيب
  4. أجل لابد من بناء الapi حتى تتمكن من ربط الواجهة الأمامية المصنوعة بReact.js بالواجهة الخلفية المصنوع بlaravel
  5. في تلك الحالة يكون الapi يتم بناؤه من خلال laravel ويقوم react بإرسال طلبات إلى لارافيل لاستقبال وتسجيل البيانات , من الممكن إرسال الطلبات بطرق عديدة ولكن أشهرها مكتبة axios والتي يتم إستخدامها بالشكل التالي نقوم أولًا بتثبيت المكتبة npm install axios ثم نقوم بإرسال الطلبات بالشكل التالي axios.get(`رابط السيرفر الخاص بلارافيل`) .then(res => { console.log(res.data) }) ولإرسال طلبات post نقوم حينئذ بإستخدام الدالة post ومن ثم وضع جسم post في مُعامل أخر axios.post(`https://jsonplaceholder.typicode.com/users`, data) .then(res => { console.log(res); console.log(res.data); })
  6. من الأمثلة على الإستثناء التي لم يتم التحقق منها (Runtime exception) محاولة القسمة على رقم صفر int num1 = scanner.nextInt(); int num2 = scanner.nextInt(); System.out.println(num1/num2); إن قام المُستخدم بإدخال رقم 0 في المرة الثانية سيتم وقتها حدوث خطأ القسمة على الصفر لأن هذا غير مقبول رياضيًا ومن الأمثلة الشائعة الأخرى أيضًا محاولة الإشارة إلى قيمة تساوي null , على سبيل المثال إن لدينا كائن قيمته null وحاولنا إجراء بعض العمليات على هذا الكائن سيتم وقتها إلقاء خطأ في وقت التشغيل بسبب عدم إمكانية إجراء العمليات على الكائنات ذات القيمة null , على سبيل المثال تلك الشفرة بالأدنى public class Main { static String s; public static void main(String[] args) { System.out.println(s.length()); System.out.println("Hello World"); } } حاولنا هنا الوصول إلى الدالة length الخاصة بالمتغير s ولكن لا يمكننا ذلك لأن المتغير s قيمته null حيث أنه لا يشير إلى أي مكان في الذاكرة حاليًا مما يؤدي إلى إلقاء خطأ nullPointerException
  7. بالإضافة إلى الإجابات بالأعلى يوجد طرق قعالة تُستخدم لتصفية العناصر المكررة في لغة جافا إن كنت تستخدمم الإصدار الثامن أو أعلى من لغة جافا يمكنك إستخدام الصنف Arrays الذي يوفر دالة stream التي تقوم بالعديد من العمليات الشائعة بشكلٍ جاهز, على سبيل المثال لتحقيق المطلوب من إزالة العناصر المتكررة يمكن كتابة الشفرة التالية Arrays.stream(arr).distinct().toArray(); يمكنك أيضًا إستغلال خصائص هيكل البيانات set والذي من خصائصه أن لا يمكن تكرار العناصر فيه حيث يمكنك تحويل المصفوفة إلى set ومن ثم إعادة تحويل الset إلى مصفوفة مرة أخرى بحيث يتم إزالة التكرار كما في الشفرة التالية Set<> tempSet = new HashSet<>(Arrays.asList(array)); int[] filteredArray = tempSet.toArray(new int[tempSet.size()]);
  8. من المفترض أن تكون الcharset خاصية مضمنة للوسم meta وهي تحدد نوع الترميز الذي يتم قراءة الملف به من قِبل المتصفح , والترميز المستخدم هنا هو ترميز utf-8 وهو ترميز standard (معياري) مستخدم من قِبل جميع المتصفحات, ويكون كتابة الوسم على الشاكلة الاتية <meta charset="UTF-8"> بالنسبة للخلفية تحتاج أن تعطيها التنسيقات التالية background-position: center; background-repeat: no-repeat; background-size: cover; التنسيق الأول يحدد أن تكون الصورة تظهر في المنتصف بمعنى أن لا تكون منحرف لليسار أو اليمين, التنسيق الثاني يحدد أن الصورة تظهر مرة واحدة لا يتم تكرارها, التنسيق الثالث يحدد أن الصورة يجب أن تغطي جميع أجزاء الصفحة
  9. أجل سيكون من المفيد البدأ بدورة علوم الحاسوب حتى يتطور لديك التفكير البرمجي ويكون ليك المبادئ والمفاهيم الأساسية عن حل المشكلات والحوسبة بوجهٍ عام ومن ثم يمكنك البدأ في تعلم واجهة المستخدم حتى يكون لديك أرض صلبة تبدأ رحلة تعلمك من خلالها
  10. بالإضافة إلى إجابة سامح يمكنك لتحسين الأداء إستخدام التابع find حيث أن التابع filter سيقوم بالبحث في المصفوفة كلها حتى بعد أن يعثر على الكتاب المرغوب, لكن إن كنت تريد البحث عبر خاصية نادرة للكتاب مثل Title يمكنك وقتها أن تقوم بإنهاء البحث بعد العثور على الكتاب لأنك تضمن وقتها عدم وجود كتاب أخر له نفس الخاصية , وطريقة عمل الدالة find أنها تأخذ شرطًا وعند تحقيق الشرط تقوم بإرجاع العنصر الذي تحقق فيه الشرط ومن ثم بعد ذاك تقوم بإنهاء عملية البحث كما يتضح في الشفرة التالية let books = [ [1,"Start with why","Simon Sinek",80.0,13], [2,"But how do it know","J. Clark Scott",59.9,22], [3,"Clean Code","Robert Cecil Martin",50.0,5], [4,"Zero to One","Peter Thiel",47,12], [5,"You don't know JS","Kyle Simpson",39.9,9] ]; const book = books.find(book => book[1] == "Zero to One");
  11. تعدد الأشكال(polymorphism) يعني أن يتم تعامل مع الكائن أو الموروثات منه ويتم إستخدامه في العديد من الdesign patterns فعلى سبيل المثال في لغة جافا يوجد كلا الصنفين bufferedInputStream و DataInputStream , كلاهما موروثان من الصنف FilterInputStream ولكن كلًا منهما له خصائص مختلفة فعلى سبيل المثال الصنف الأول يتم إستخدامه لكتابة النصوص بشكلٍ إفتراضي على عكس الصنف الثاني الذي بشكلٍ إفتراضي يتم إستخدامه لكتابة الأنواع البدائية من البيانات مثل Integer, byte إن أردنا إنشاء دالة تقوم بإستقبال أي صنف من الإثنين بدون عمل Overload يمكننا وقتها إستخدام خاصية تعدد الأشكال عبر تعريف الدالة أنها تستقبل الصنف الأب وبالتالي يمكن إستقبال أيًا من الأبناء كما في الشفرة التالية public void manibulateStream(FilterInputstream filter){ ///your code } FilterInputstream datain =new DataInputStream(); FilterInputstream bufferedin = new BufferedInputStream(); manibulateStream(datain); manibulateStream(bufferedin);
  12. كما أشار حسن فإن الstatic يتم تخزينها على مستوى الصنف وليس الكائن ويوجد أيضًا فرق هام يجب ملاحظته وهو أن الذاكرة تنقسم إلى نوعين stack memory وتلك يتم تخزين المتغيرات وترتيب تنفيذ الدوال وهي سريعة التنفيذ والوصول إليها heap memory وفيها يتم تخزين الكائنات وهي بطيئة الوصول إليها في الحقيقة أن الstatic variables يتم تخزينهم في النوع الثاني (heap memory) وهذا يعني أن الوصول إلى المتغيرات التي يتم إعلانها كstatic يكون أبطأ من غيرها مما قد يؤدي إلى مشاكل في الأداء لذا يجب إستخدام خاصية الstatic بعناية وحرص عندما نكون حقًا نحتاجها, على سبيل المثال إن كان لدينا متغير مكلف للموارد عند إنشاؤه ونحن لا نريد إلا نسخة واحدة منه, في تلك الحالة من المفيد إنشاؤه ك static variable حتى يتم إستخدامه من قِبل جميع الكائنات بما أنه على مستوى الصنف .
  13. بالإضافة إلى إجابة محمد فإن عند عمل تعديل على القائمة في الدالة ستلاحظ أن التعديل قد إحدث أيضًا على Linked list الأصلية بخارج الدالة وذلك لأن على الرغم أن من المفترض Java أنها دائمًا ما تقوم بالتمرير بالقيم (pass by value) ألا أن هناك مشكلة وهي أن تلك القيمة في حالة الكائنات تكون عبارة عن pointer وبالتالي أي تغيير يحدث يطول الكائن الأصلي, إن كنت تريد تمرير الLinked list دون المساس بالقائمة الأصلية يمكنك إذا بدلًا من تمريرها تمرير نسخةً منها عبر الدالة clone كما في الشفرة البرمجية التالية LinkedList temp_list = (LinkedList) list1.clone(); test(temp_list); بهذه الطريقة نضمن أن لا يتم حدوث أي تغيير على القائمة الأصلية
  14. يمكنك إستخدام heroku ورفع الصور على الfirebase عبر خدمة الstorage كما ورد في ذلك السؤال
  15. ﻻ يوجد طريقة موحدة لدعم اللغات المتعددة في الموقع ولكن أحد أشهر الطرق كالأتي نقوم أولًا بإنشاء ملفات الreact لكل لغة ملفٍ ونقوم بوضع param في نهاية كل route باسم lang نستقبله بالشكل التالي const [searchParams, setSearchParams] = useSearchParams(); searchParams.get("lang") ومن ثم بناءًا على قيمة الparam نقوم بتحديد الصفحة التي سيتم إرسالها للمستخدم const App = ()=>{ const [searchParams, setSearchParams] = useSearchParams(); return( {searchParams.get("lang")=='eng'?<EngComponent/>:<AraComponent/>} ) }
  16. هذا لأن عندما تزيل الشرط يتم اسنخدام reference المسمى ali والذي لا يشير إلى شئ بعد لأنه يتم الإشارة عند إنشاء Link فبالتالي أنت تحاول أن تقوم بتغيير قيمة Link عبر reference ali من قبل أن يتم عمل mount للLink فيReact أما عندما تقوم بوضع الشرط لا يتم تنفيذ العمليات على reference إلا عندما تكونcondition قيمتها true وبالتالي يكون تم بالفعل عمل mount لل Link
  17. مرحبًا, غالبًا الapi خاصتك تقوم بالإستماع إلى العنوان 127.0.0.1 (localhost) والذي لا يمكن الإرسال إليه إلا من نفس الحاسب, لنتمكن من إرسال طلبات إلى api من خارج الحاسب يجب جعل الapi تقوم بالإستماع إلى العنوان 0.0.0.0 لأن هذا العنوان يعني"الإستماع إلى جميع العناوين المتاحة للحاسب" فعلى سبيل المثال إن كان عنوان شبكتك 10.1.2.1 عالميًا, و 192.168.1.5 محليًا , حينها عند إستخدام العنوان 0.0.0.0 سيتم الإستماع إلى كلا العنوانين فيكون الapi يقوم بالإستماع إلى الطلبات المحلية والطلبات الخارجية المُرسلة من قِبل الhamachi
  18. بالإضافة إلى إجابة محمد فإن كلا من قواعد البيانات البيانية والعلائقية يمكن إستخدامهما لتمثيل نفس نوعية البيانات نظرًا لأن كلاهمة يصلح لتحديد علاقات many-to-many على عكس قواعد البيانات الdocument كالmongodb والتي لا تصلح لعلاقات الmany to one, ولكن على الرغم من ذلك يوجد فروق وإختلافات يجب معرفتها لتحديد أي نوع من النوعين يجب أن تختار, فروق مثل هل البيانات متصلة بشكلٍ كبير أم لا؟ حيث أن القواعد البيانية تعد خيارًا جيدًا عندما يكون هناك إتصال بين البيانات بشكلٍ كبير مثل شبكات التواصل الإجتماعي هل الإستعلام عن البيانات أهم من تخزينها؟ حيث أن القواعد العلائقية تعد إختيارًا جيدًا عند التخزين عكس نظيرتها البيانية التي تعد خيارًا مثاليًا عند إستقبال البيانات هل الdata model تتغير أم ثابتة؟ حيث أن القواعد البيانية لا تجبرك على إستخدام schema معينة عىل عكس القواعد العلائقية يمكنك التفكير في تلك الأسئلة قبل القيام بإختيار قاعدة البيانات حتى تتأكد أنك قمت بإختيار الخيار المناسب لك
  19. يمكنك بعد تنفيذ الحل المقترح من قِبل محمد أن تقوم بحذف الجدول من قاعدة البيانات ومن ثم إعادة تشغيل تطبيق الflask تى يتم إعادة تنفيذ السطر الخاص ب db.create_all() حيث أن sqlalchemy لا تقوم بتحديث الجداول وإنما تقوم بإنشاؤها إن كانت غير موجودة بالفعل
  20. يتم إستخدام الindexes عند إستخدام الlike ولكن المشكلة الحقيقية تكمن عند إستخدام الwildcard وهي علامة النسبة المئوية % بداخل الlike وهذا لأنها تعني "أي شئ" بمعنى عند كتابة %ahmed تعني أيًا كانت النتيجة المهم يكون في أخرها كلمة أحمد وهذا يطابق mohamed ahmed, hossam, ahmed ahmed% وتلك كالأعلى ولكن المهم يكون بدايتها كلمة أحمد في تلك الجملة لن يتم إستخدام الindex في الحالة الأولى ولكن يتم إستخدامها في الحالة الثانية والسبب أن الindex تكون مخژنة على هيئة binary search tree فعند البحث في الحالة الأولى يضطر للبحث في جميع السجلات حتى يعثر على سجل يكون في نهايته أحمد بغض النظر عن بدايته بينما في الحالة الثانية يقوم بالبحث بإستخدام خواص البحث والترتيب الخاصة ب binary search tree والتي تمكن بسهولة من الوصول إلى الحالة التي فيها كلمة أحمد فبالتالي يتم إستخدام الindex في حالة ما كانت علامة الwildcard على اليمين وليس على اليسار
  21. نفترض أن لدينا جدولين user posts العلاقة بينهما واحد للuser وكثير للposts, نقوم بوضع مفتاح أجنبي(foreign key) عند جدول الposts يُشير إلى المفتاح الأساسي primary key لجدول الuser كما بالشكل التالي user_id = Column(Integer, ForeignKey('user.id')) ومن ثم نذهب إلى جدول user ونقوم بتعريف العلاقة بينهما relationship كما بالشكل التالي posts = relationship("posts") وعند إرسال الرد في الapi نقوم بتحديد الresource fields التي يتم إرسالها كما بالشكل التالي resource_fields={ 'posts': fields.List(fields.Nested({ "title": fields.String, "content": fields.String, }))}
  22. الفرق الأساسي في أن الtemplate engine يتم إنشاء الصفحات بواسطتها من جهة السيرفر أي أنها server side rendered على عكس أطر عمل الجافاسكريبت مثل react js و angular التي يتم إنشاء صفحاتها عند المستخدم حيث يتم إرسال شفرة جافاسكريبت للمستخدم ويتم تنفيذها في المتصفح ويمكن أن نلخص الفروق بينهم بشكلٍ بارز كالتالي: أطر العمل الخاصة بجافاسكريبت موجهة بشكلٍ عام للمبرمجين حيث أنك تقوم بكتابة شفرة للجافاسكريبت بينما محركات التصميم template engine موجهة بشكلٍ أكبر لمصممي الويب حيث أنها توفر التعامل مع الشفرة كلها على هيئة شفرة html مما يزيد من سهولة التعامل معها من ناحية الأداء فإن الtemplate engines تتفوق في تلك النقطة وذلك بسبب أنها يتم إنشاؤها عند الخادم من ناحية قوة الإستخدام فإن أطر العمل تتفوق في تلك النقطة فكما قلنا فإن أطر العمل للمبرمجين يتم كتابة شفرة برمجية فيها على عكس الtemplate engine التي موجهة بشكلٍ أكبر للمصممين ويتم كتابتها بداخل الhtml مما يجعل من أطر العمل حل أفضل للتطبيقات ذات التفاعل الكبير مع المستخدم والتطبيقات التي فيها شيئًا من التعقيد
  23. يمكنك تنفيذ المطلوب عبر تغيير قيمة الinside ل false للكائن res كما بالشكل التالي res.inside = false ولكن ستقابلك مشكلة وهي أن الدالة order_by تقوم بإرجاع Query لا تقوم بإرجاع نتيجة الحل أن نقوم بإرجاع نتيجة عبر مناداة الدالة first ليكون الشفرة البرمجية خاصتك على الهيئة التالية res = vehicles_schedule.query.filter_by(vehicle_id = result.vid).order_by('entrydate').first() ومن ثم سيتم تغيير القيمة عند مناداة الsession.commit() بالتوفيق
  24. يوجد العديد من الإختيارات حيث أن أي لغة برمجة عامة الأغراض مثل جافا و سي شارب وبايثون يمكن إستخدامها لبرمجة تطبيقات سطح المكتب والتي تشمل تطبيقات المحاسبة ولكن أشهر الإختيارات كالتالي: لغة c# تعد من أشهر اللغات في هذا النوع من التطبيقات مع قاعدة بيانات sql server حيث أنها مدعومة بشكلٍ قوي من شركة ميكروسوفت ويتوفر لها العديد من الأدوات التي يمكن إستخدامها لتسهيل الأمر ولكن عيبها أن تطبيقاتها تعمل على نظام تشغيل ويندوز فقط لغة java من اللغات القوية والمدعومة بقوة أيضًا ولكن ليس كدعم ميكروسوفت ويمكنك إستخدامها مع إطار عمل javaFx أو javaswing ويمكنك تشغيلها على كافة أنظمة التشغيل ليس فقط نظام ويندوز حيث يمكن تشغيلها على ويندوز ولينكس وماك وأي نظام بوجهٍ عام لغة جافا سكريبت يمكنك برمجة تطبيقات سطح المكتب بها عبر إطار عمل electron , قد يكون دعمها أقل من اللغات السابقة بالنسبة لتطبيقات سطح المكتب ولكن تتوفر بها ميزة رائعة وهي أنك تقوم بإستخدام تقنيات الويب في البرمجة مما يعطيك ميزة أنك يمكن برمجة مواقع الويب وتطبيقات سطح المكتب بنفس اللغة
  25. غالبًا تلك المشكلة تحدث بسبب أن عند تنفيذ الشفرة البرمجية يقوم المُترجم(interpreter) بالبحث عن المسار النسبي(relative path) الذي هو upload/temp.jpg بالنسبة إلى نسخة الinterpreter وليس بالنسبة إلى مجلد المشروع نفسه يمكننا حل تلك المشكلة عبر وضع مسار المشروع بدلًا من المسار النسبي من الواضحُ أنكِ تستخدمين flask لذا يمكننا كتابة الشفرة التالية os.path.join(app.root_path, 'upload', 'temp.jpg') تلك الشفرة ستقوم بإرجاع المسار المطلق(absolute path) لتطبيق flask الذي في حالتك غالبًأ يكون الملف main وبالتالي سيتم العثور على المجلد upload والملف temp.jpg بالتوفيق.
×
×
  • أضف...