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

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

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

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

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

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

    2

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

  1. يوجد عدد من الخوارزميات التي يمكنك تطبيقها على تطبيق كهذا ويتمحورون غالبًا في نطاق الترتيب والبحث يمكنك توفير خاصية أن يتم ترتيب القائمة حسب الإسم أو التاريخ ويمكنك مرة تجربة الترتيب بخوارزمية الbubble sort ومرة أخرى بخوارزمية الinsertion sort يمكنك توفير خاصية البحث بالإسم أو بالتاريخ وتجربة عدة خوارزمية للبحث مثلًا لو كانت القائمة مرتبة يمكنك إستخدام خوارزمية ال binary search tree إن لم تكن مرتبة يمكنك إستخدام خوارزمية الlinear search
  2. هل بإمكانك إرفاق صورة للكود + صورة لمجلد المشروع؟
  3. بما أنك تستخدم flask فغالبًا أنت تستخدم sqlalchemy , للأسف sqlalchemy لا تدعم الauto increment إلا في المفتاح الرئيسي(primary key) ولكن يمكنك تحقيق المطلوب عبر جعل الحقل المُراد جعله يزداد تلقائيًا في قاعدة البيانات من النوع SERIAL وإن كان الحقل موجودًا بالفعل يمكنك تنفيذ الأمر التالي CREATE SEQUENCE tablename_columnname_seq; ALTER TABLE tablename ALTER COLUMN columnname SET DEFAULT nextval('tablename_columnname_seq'); هذا سينشئ جدول للزيادات في قاعدة البيانات وسيجعل الحقل يستمد قيمته من هذا الجدول
  4. بالإضافة إلى إجابة وائل إن كنت تريد حذف جميع بيانات الجدول يمكنك في هذا الموقف إستخدام التعليمة DELETE مع وضع الشرط WHERE ب1 حتى تكون التعليمة بشكلٍ كامل على الشاكلة التالية DELETE FROM users WHERE 1
  5. عندما تقوم بإستخدام الtoken يمكنك جعلها من النوع JWT وبالتالي تقوم بإضافة كلمة سر إلى التوكين عند توليده من جهة الخادم وبالتالي عندما يقوم العميل بإرساله يقوم الخادم بالتأكد من صحته عبر الدالة verify , على سبيل المثال إن كنت تستخدم كلمة سر secret يمكنك التحقق من أن التوكين لم يتم التلاعب بها بالnode js عبر الشفرة التالية JWT.verify(token,'secret') .then(()=>doSomething()) .catch(err=>handleError(err)) إن كان التوكين تم التلاعب به سيتم إلقاء error وإستدعاء الدالة catch
  6. ببساطة لا يمكنك الحصول عليه لماذا لا يمكن الحصول عليه؟ فلنحكي القصة من بداية إرسال الطلب من قِبل العميل يقوم العميل بإرسال الطلب إلى الخادم الخاص بك يتم إرسال الطلب من الجهاز على هيئة packet (مجموعة من البيانات تتضمن عنوان الشبكة الخاص بك والعنوان الخاص بالوجهة وبعض البيانات الأخرى من ضمنها الmac address الخاص بك) يقوم الموديم بإستقبال الpacket ويستخرج منها عنوان شبكتك وعنوان الوجهة وباقي المعلومات الأساسية ولكن يقوم بتبديل الmac address الخاص بك بالmac address الخاص به بعد ذلك تقوم الpackets بالمرور على العديد من المحطات hobs قبل الوصول إلى الوجهة النهائية, وكل محطة منهم تقوم بإستبدال الmac address السابق بالmac address الخاص بها في النهاية عند وصول الطلب إلى الوجهة المطلوبة يكون الmac address الموجود في الpacket هو الخاص بأخر محطة قد مرت بها الpacket فبالتالي لا يمكن الحصول على الmac address الخاص بالعميل لأنه يتم إستبداله عند مرور الpacket على كل محطة
  7. النتائج التي ترجع من الsqlalchemy query تكون من نوعية query والتي يمكنك إستخدام الدالة count التي تتوفر بها والتي تقوم بإرجاع عدد النتائج على سبيل المثال result = session.query(User) print(result.count()) تلك الشفرة تقوم بإرجاع عدد النتائج الموجودة بالإستعلامة
  8. بالإضافة إلى إجابة وائل فإن يوجد إختلاف مهم بين الvector(المتجه) والمصفوفة array في جافا وهو أن المتجه متزامن synchronized مما يعني أن لا يمكن لأكثر من thread أن يقومو بعمليات عل نفس المتجه وتلك الخاصية لها ميزتها وعيبها في ذات الوقت المميزات المميزات أنه يضمن لنا عدم حدوت تصادم في البيانات عند محاولة الكتابة على المتجه من قِبل أكثر من thread ويمكن توضيح المقصد من هذا الكلام عبر المثال التالي: نفترض أن لدينا ملف كبير الحجم نقوم بقرائته من قبل نسختين من الthread بشكل متقطع بحيث يقوم كل ثريد بقراءة 5 ميجا ومن ثم يتم كتابتها في هيكل بيانات ومن ثم يرجع يقرأ 5ميجا أخرى ومن ثم يقوم بكتابتهم في الهيكل وهكذا إن كنا نستخدم مصفوفة يوجد إحتمالية أن يكتب الthread الأول والثاني في الكتابة في الفهرس رقم 3 في نفس الوقت مما يؤدي إلى مسح بيانات أحدهم وبالتالي يكون لدينا فقد في البيانات, ولكن مع المتجه لن يستطيع أن يكتب إلا thread واحد فقط, بينما الthread الأخر سينتظر لحين إنتهاء الthread الأول من الكتابة ومن ثم يقوم بالكتابة في الفهرس القادم مما يضمن لنا عد حدوث أي فقدان في البيانات العيوب بما أنه كما قلنا متزامن ولا يسمح لأكثر من نسخة thread من الكتابة في نفس الوقت فهذا يسبب بطئ في الأداء فبالتالي إن كنا لا نحتاج إلى ضمان عدم فقدان البيانات ونتعامل مع أكثر من thread فبالتالي لن نحتاج التعامل مع المتجه لأنه سيؤدي إلى فقدان في الأداء مقابل ميزة لا نحتاجها بالإضافة إلى أن المتجه يأخذ مساحة أكبر في الذاكرة
  9. عند إرسال بيانات إلى جهاز حاسب عبر الشبكة يتم إرساله عبر عنوان الشبكة ip address, ومن ثم عند الوصول إلى الشبكة المحددة يتم البحث عن الحاسب عبر العنوان المادي physical address أو mac address ومن ثم يتم إرسال البيانات له السؤال هنا, كيف يتم تحديد أي برنامج سوف يستقبل تلك المعلومات؟ حيث أن لدينا مئات البرامج والخدمات التي تعمل على الحاسوب في نفس ذات الوقت فكيف نستطيع تحديد أي واحد منهم يقوم بإستقبال تلك المعلومات؟ الإجابة هي المنفذ Port حيث أن عنوان الشبكة يستخدم لتحديد أي شبكة تسمع الطلب, والعنوان المادي لتحديد أي جهاز داخل الشبكة يستمع إلى الطلب, بينما المنفذ لتحديد أي برنامج داخل الجهاز يستمع إلى الطلب, فإذًا في حالتنا تلك لن تقوم الmysql بالإستماع إلى أية طلبات إلا االطلبات التي يتم إرسالها إلى المنفذ 3306
  10. مرحبًا أحمد برجاء في المرة القادم كتابة الأسئلة باللغة العربية حتى يسهل فهمها ويسهل الإجابة عليها ويستفاد باقي الزوار من تلك الإجابات بالنسبة لسؤالك فإن الhooks هي في حد ذاتها دوال functions ولكنا دوال من نوع خاص ما هو الخاص فيها؟ الخطافات (hooks) بشكل أساسي يتم إستخدامها من أجل التعامل مع دورة حياة الوِحدة(component) سواء من حيث تغيير الحالة الخاصة بها أو تنفيذ فعل معين عند تغيير الحالة الخاصة بها ويتم تصميمها بحيث لا تعمل إلا في الfunctional react components لذا يمكننا القول أن أي خطاف دالة وليست كل دالة خطاف على سبيل المثال في الشكل التالي شفرة برمجية لcustom hook للتعامل مع النماذج const useForm = (initialState = {}) => { const [formData, setFormData] = React.useState(initialState); const handleInputChange = (e) => { setFormData({ ...formData, [e.target.name]: e.target.value }) } return { formData, handleInputChange }; } يتم إستخدامها بالشكل التالي function Form() { const [formData, setFormData] = React.useState({ username: "", password: "", }); const { username, password } = formData; const handleInputChange = (e) => { setFormData({ ...form, [e.target.name]: e.target.value }); }; const handleSubmit = (e) => { e.preventDefault(); console.dir(formData); } return ( <form onSubmit={handleSubmit}> <input type="text" name="username" value={username} onChange={handleInputChange} /> <input type="password" name="password" value={password} onChange={handleInputChange} /> <button type="submit">Submit</button> </form> كما تلاحظ هنا نحن إستخدمنا خطاف بسيط مثل الuseState وأضفنا إليه شفرتنا الخاصة حتى نصل إلى خطاف جديد يقوم بتخزين بيانات النموذج دون الحاجة إلى التعامل معها يدويًا من خلال النموذج نفسه
  11. البرمجة كائنية التوجه هامة في أي لغة برمجة وهي ضرورية لإستيعاب مفاهيم برمجية مثل أنماط التصميم بالإضافة إلى أن البرمجة كائنية التوجه لها حالات إستخدامها الخاصة التي تكون الأفضل فيها بالإضافة لوجود عدد من أطر البيانات في الجافاسكريبت المبنية على البرمجة كائنية التوجه مثل إطار عمل nest js المُستخدم في برمجة الواجهات الخلفية وأيضًا يوجد لغة typescript والتي تعد نسخة مطورة من الجافاسكريبت والتي تعتمد بشكلٍ أساسي على البرمجة كائنية التوجه ويمكنك إستخدامها في React وتعمل بشكل أساسي في أطر عمل أخرى مثل angular
  12. بالإضافة إلى إجابة حسن يمكنك أيضًا تغيير المعمارية(archticture) التي تستخدمها في بناء الكود بمعنى أن تجعل الشفرة البرمجية أكثر تنظيمًا حتى لا تتشوش ويمكنك الوصول إلى ذلك عبر فعل التالي إنشاء ملف خاص بالPersonContext حتى يتم فصل الطبقة الخاصة بالcontext عن الطبقة الخاصة بباقي التطبيق عمل export لكلٍ من الPersonContext وال PersonProvider حتى يصبح الشفرة البرمجية كالشكل التالي export const PersonContext= React.createContext() export const PersonContextProvider = ({children})=>{ const [people, setPeople] = useState() return ( <PersonContext.Provider value={[people, setPeople]}> {children} </PersonContext.Provider> ) } ومن ثم يمكنك بسهولة عندما تريد إستخدام تلك الcontext في أي مكان أن تقوم فقط بعمل import للPersonContextProvider وتضع بداخله الcomponents التي ستستخدمه, وبداخل تلك ال components تقوم بعمل import لل PersonContext ومن ثم وضعه بداخل الخُطاف useContext والذي سيقوم بإرجاع نسخة من الstate وال setPeople كما بالشكل التالي import {PersonContextProfider} from './context/PersonContext' import ChildComp from './childcomp' const Comp = ()=>( <PersonContextProvider> <ChildComp/> </PersonContextProvider> ) وبداخل الcomponent التي تدعى ChildComp يمكنك فعل التالي import {PersonContext} from './context/personcontext' const ChildComp = ()=>{ const [people, setPeople] = useContext(PersonContext) }
  13. بالطبع يوجد عديد من المكتبات التي تدعمها الreact والتي يمكنها عمل animation أحد أشهر تلك المكتبات هي مكتبة framer والتي يمكنك زيارة موقعها عبر الضغط هنا ومثال على تلك المكتبة : import { motion } from "framer-motion" export const MyComponent = () => ( <motion.div animate={{ scale: [1, 2, 2, 1, 1], rotate: [0, 0, 270, 270, 0], borderRadius: ["20%", "20%", "50%", "50%", "20%"], }} /> ) على سبيل المثال تلك الشفرة البرمجية تقوم بجعل مربع يتضاعف حجمه ثم يدور بزاوية 270 درجة ويتحول إلى دائرة ثم ينقص حجمه مرة أخرى ثم يدور إلى الخلف 270 درجة ثم يرجع إلى مربع مرة أخرى, ويمكنك تجربة ذلك المثال من خلال ذلك الرابط
  14. يمكنك تنفيذ المطلوب عبر تمرير الدالة المسؤلة عن تغيير الحالة من المُكون الأب إلى المُكون الإبن, يمكنك فهم ذلك بشكلٍ أفضل عبر المثال التالي const Parent = ()=>{ const [name, setName] = useState("") const changeName = (value)=>{ setName(value) } return( <Child changeName = {changeName}/> ) } const Child = ({changeName})=>{ return( <input type='text' onChange={e=>changeName(e.target.value)}/> ) } كما تلاحظ عند تغيير قيمة الinput في المكون الإبن يتم مناداة الدالة changeName التي بدورها تقوم بتغيير الstate الخاص بالمكون الأب
  15. أجل بالطبع يمكنك ذلك حيث في نهاية المطاف الجي كويري والreact يظلان مجرد مكتبات للجافاسكريبت, فبالتالي يمكنك إستخدامهم سويًا ويكون بالشكل التالي: خطوات تثبيت الجي كويري في تطبيق React.js تثبيت الجيكويري عبر مدير الحزم npm عن طريق إستعمال الأمر npm install jquery --save بعدها نقوم بعمل إستيراد للمعامل $ عبر الشفرة التالية import $ from 'jquery'; ومن ثم يمكنك إستخدامها كما تفعل في تطبيقات الجافاسكريبت بشكلٍ إعتيادي $("button").click(function(){ $.get("demo_test.asp", function(data, status){ alert("Data: " + data + "\nStatus: " + status); }); }); ولكن السؤال الحقيقي هل يجب عليك فعل هذا؟ عيوب إستخدام الجي كويري في الreact مبدأيًا دعنا نتعرف على أحد مبادئ هندسة البرمجيات وهو مبدأ المسؤلية الواحدة (single responsbility) والذي ينص على أن في أي نظام يجب أن يكون كل قطعة في النظام مسؤلة عن أمر واحد فقط , وبالمثل كل أمر يكون مسؤل عنه قطعة واحدة فقط ما علاقة هذا بإستخدام الجيكويري؟ حسنًا في الحقيقة أن الreact تقوم بعمليات معالجة الDOM ولكن عبر الخفاء بشكلٍ لا تراه نسبيًا, فكل ما عليك فعله فقط هو تعريف الstate ومن ثم تقوم الreact بمعالجة الDOM وفقًا لتغير ذلك الstate بشكلٍ تلقائي, بينما الجيكويري تقوم بمعالجة الDOM بشكلٍ يدوي حيث يجب عليك كتابة كل سطر من الشفرة البرمجية لتنفيذ أوامر المعالجة المطلوبة, المشكلة في ذلك أننا الأن أصبح لدينا قطعتين في النظام يقومون بنفس الوظيفة وبالتالي هذا يؤثر على الأداء بالإضافة إلى أنه يؤدي إلى نتائج غير متوقعة في كثيرٍ من الأحيان
  16. برجاء ارفاق الشفرة البرمجية لمعاينتها بشكلٍ جيد
  17. لأن الstate تقوم بتغيير البيانات في الdom وبالتالي يتم إعادة البيانات إلى حالتها الأصلية عند عمل refresh للصفحة إن كنت تريد تخزين البيانات بشكلٍ دائم يمكنك إستخدام localStorage والتي تحتوي على ثلاث دوال أساسيين getItem, setItem, removeItem والذين يعملون كما يظهر في المثال التالي localStorage.setItem("item1", "sharaf")/// هكذا تم تخزين قيمة sharaf في المفتاح item1 console.log(localStorage.getItem("item1")/// سيتم طباعة قيمة المفتاح item1 والذي هو sharaf localStorage.removeItem("item1") وكما تلاحظ فإن الlocalStorage تعمل على هيئة المفتاح والقيمة, حيث تخزن القيمة في مفتاح ما وتصل إلى القيمة عبر نفس المفتاح
  18. حسب ما فهمت انك تريد طباعة القراءة أولًا ومن ثم التعديل ولكن ما يحدث أن أحيانا يتم طباعة التعديل قبل القراءة, أليس فهمي صحيحًا؟
  19. أولًا يجب عليك إستيراد الملفين iostream المسؤلة عن عمليات الإدخال والإخراج في لغة c++ وifstream المسؤل عن التعامل مع الملفات #include <iostream> #include <fstream> ومن ثم يمكننا كتابة بيانات في الملف الذي لدينا مساره بإستخدام المتغير من نوع ofstream كما بالشكل التالي ofstream MyFile("filename.txt"); MyFile << "بسم الله الرحمن الرحيم"; MyFile.close(); ولقراءة محتويات الملف نقوم بإستخدام متغير من نوع ifstream string test; ifstream myfile("test.txt"); while (getline (myfile, test)) { cout << test; } myfile.close(); نلاحظ هنا أننا نقوم بعمل حلقة تكرارية من نوع while حيث نقوم بالمرور على محتويات الملف سطر سطر وفي كل سطر نقوم بوضعه بداخل المتغير test ومن ثم نقوم بطباعته حتى ننتهي من محتويات الملف وكما تلاحظ فإن في كلا عمليتي القراءة والكتابة قد قمنا بإغلاق الملف في النهاية وهذا أمر في غاية الأهمية حيث عند فتح الملف يتم تحميله إلى الذاكرة وبالتالي يجب إغلاقه حتى نقوم بتفريغ مكانه في الذاكرة حتى لا نستهلك من موارد الحاسب
  20. ﻻ نحتاج لذلك لأننا بالفعل قمنا بعمل العلاقة بين الغرف والنزلاء عبر جدول الطلب حيث يحتوي جدول الطلب على معرف النزيل ورقم الغرفة
  21. أعتقد أن تلك الشفرة كُتبت بواسطة لغة الجافا, وبالتالي يمكنك تحقيق الأغراض المطلوبة بواسطة التالي: بالنسبة إلى جمع الemp_add يمكن تحقيقه عبر إستخدام الصنف stream الذي تم تقديمه في الإصدار جافا8 والذي يقوم بأخذ المعطيات على هيئة قطع(chunks) ومعالجتها معطى تلو الأخر, وبالتحديد يمكننا إستخدام الدالة reduce والتي تقوم بتنفيذ عمليات متتالية على المعطيات وتخزينها في متغير يعبر عن الناتج ومن ثم يتم إعطاء هذا الناتج كمعطى للدالة في المرة القادمة كما يتضح من الشفرة التالية int total_emp_add = Geeks .stream() .reduce(0, (subtotal, element) -> subtotal + element.Emp_add); حيث تبدأ الدالة بقيمة إبتدائية لمتغير الsubtotal تساوي صفر, ومن ثم تقوم بجمعه مع متغير الemp_add للكائن الاول ومن ثم يتم تمرير ناتج الجمع إلى المتغير subtotal في اللفة الثانية فيتم جمع الناتتج مع الemp_add للكائن الثاني وهكذا حتى يتم الإنتهاء من القائمة فينتج لنا في النهاية ناتج جمع الemp_add يمكننا حذف العامل ببساطة عبر إستخدام الدالة removeIf والتي تقوم باللف على جميع عناصر القائمة حتى تجد عنصر يتحقق فيه الشرط الذي سنمرره فيتم حذفه Geeks.removeIf(g -> g.emp_id == id); في تلك الشفرة يتم حذف العامل الذي يكون الid الخاص به مساوي للمتغير id يمكننا هنا إستخدام ال Iterator وهو عبارة عن كائن يقوم باللف على جميع عناصر القائمة ونقوم بالتحقق في كل مرة أن العامل الذي لدينا يستوفي شروط العامل الذي نريد أن نقوم بتعديله, إن كانت الإجابة بنعم فنقوم حينئذ بتغيير قيمته عبر الدالة set كما يتضح لنا في الشفرة التالية ListIterator<Geek> iterator = Geeks.ListIterator() while (iteratir.hasNext()) { Geek next = iterator.next(); if (next.emp_id==id) { / iterator.set(New_Geek); } } وبالطبع يتم إستبدال الكائن New_Geek بالكائن الجديد الذي نريد إدراجه
  22. الكيان الضعيف(weak entity) هو عبارة عن جدول لا يمكن تمييزه بشكلٍ نادر عبر خصائصه, بل يتم تمييزه بخصائص جداول أخرى, في حالتنا هنا الطلب لا يمثل كيان ضعيف وهذا لأن بالفعل له حقلُُ نادر وهو "رقم الطلب" وبالتالي بما أن له حقلُ نادر يميزه فهو كيان قوي وليس ضعيف, بل إضافة إلى ذلك لا يمكن أيضًا تمييز جدول الطلب بواسطة حقول جدولي العميل والغرف حيث إن إفترضنا أننا سنميز الطلب بواسطة العميل ورقم الغرفة, فيمكن لنفس العميل حجز نفس الغرفة أكثر من مرة وبالتالي لا يصلح هذا لنميز به جدول الطلب, فلهذا يجب تمييزه برقم الطلب
  23. يوجد العديد من المشاريع التي بإمكانك تنفيذها بإستخدام لغة سي شارب قائمة المهام ( to do list) أي برنامج يمكنك إضافة فيه المهام التي تسعى لتحقيقها وفور تحقيقها يوجد زر تضغط عليه يقم بتعليم تلك المهمة أنها قد تم تنفيذها, يمكنك زيادة التعقيد بأن تقوم بتقسيم المهام بين مهام يومية, اسبوعية, شهرية ويتم تقسيمهم عبر حقل في قاعدة البيانات برنامج مذكرات (note app) تقوم فيه بكتابة الأشياء الهامة حتى تستطيع العودة إليها مرة أخرى لعبة إكس أو(x-o) ويمكنك إضافة بعض المميزات مثل إمكانية اللعبة على أكثر من جهاز بإستخدام الsockets برنامج إدارة مخازن يمكن إنشاء منبه ومذكر للمهام كتطور لبرنامج قائمة المهام
  24. هذا غالبًا يحدث بسبب أن عند تغيير الstate تقوم بإضافة أو حذف عناصر إلى المصفوفة, ولكن المصفوفة نفسها لم تتغير فبالتالي لا يتم عمل re-render يجب تمرير عناصر المصفوفة على هيئة مصفوفة جديدة حتى يحدث الre-render ويمكن تحقيق ذلك بسهولة عبر إستخدام الspread operator <div> <Users users={[...users]}/> </div>
  25. بما أن لا وجود للغرفة إلا في جدول "الغرفة" ولا يمكن تكرار المُعرف الخاص بالغرفة فبالتالي لن يظهر المُعرف الخاص بها أكثر من مرة مما يعني أن لا يمكن حجزها أكثر من مرة على عكس النزيل الذي يظهر المُعرف الخاص به أكثر من مرة على هيئة foreign_key في جدول الغرف مما يعني إ/كانية حجزه لعدد من الغرف
×
×
  • أضف...