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

Mustafa Suleiman

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

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

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

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

    340

كل منشورات العضو Mustafa Suleiman

  1. إذا أردت إختصار الأمر في سطر واحد، فسيصبح: بمعنى أنه هناك فرق كبير بين المبرمج الجيد والسيئ، ولا يتعلق الفرق فقط بقدرة المبرمج على كتابة الكود، ولكن أيضًا بالطريقة التي يفكر بها والحلول التي يقدمها. فالمبرمج الجيد يكون لديه فهم عميق لمبادئ البرمجة ويكتب الكود بطريقة مبتكرة وصحيحة، بينما المبرمج السيء يفتقر إلى الفهم العميق والتمرس في البرمجة، ولديه عادات سيئة مثل تجاهل مبادئ التصميم الجيدة وسوء إدارة الوقت وعدم اهتمامه بجودة الكود. ويسعى إلى تعلم التقنيات دونّ تعلم الأساسيات أولاً، مثلاً تعلم أساسيات جافاسكريبت فقط ثم الإنتقال سريعًا لتعلم مكتبة مبنية على اللغة مثل React، ويتجاهل أمور كثيرة في اللغة سيعاني من عدم فهمها لاحقًا وسيضطر للعودة ودراسة تلك الأمور وإلا لن يصل بعيدًا في مشواره الوظيفي كمبرمج. نفس الأمر بالنسبة للغة بايثون كالإنتقال لتعلم الإطارات والمكتبات سريعًا دون فهم جيد للغة والوصول لأريحية بالتعامل معها وتنفيذ مشاريع وحل مشاكل من خلالها. أيضًا تجاهل لأساسيات علوم الحاسوب، فهي مهمة وتجعلك مبرمج متفهم لآلية ما يدور في الخلفية وليس كتابة الكود فقط. وعلى ذكر الكود، الشركات الجيدة لا تريد شخص يكتب كود فقط من خلال لغة معينة فذلك أمر سهل، بل تريد شخص يفهم لما يكتب الكود، فمثلاً مبرمج الواجهة الخلفية يجب أن يكون على علم جيد بقواعد البيانات والمفاهيم الخاصة بالواجهة الخلفية وهكذا. والمبرمج الجيد يكتب المبرمج الجيد كودًا سهل الفهم والصيانة والاستخدام، سواء من قبل المستخدمين أو المبرمجين الآخرين، من خلال تعليقات واضحة على الأجزاء المهمة في الكود ولكي يتمكن من فهم الكود هو أيضًا فيما بعد، فهناك مقولة:
  2. لنتفق أولاً على المشكلة لديك وهي بالوصف التالي: تستخدم Blade لعرض تفاصيل المشروع من قاعدة البيانات. لديك جدول phone يحتوي على تفاصيل الهاتف وجدول phonecolor يحتوي على أربعة سلاسل لأربعة صور (image1, image2, image3, image4). في Blade، تعرض الألوان باستخدام foreach phone->phonecolor as color. عند النقر على أي لون، يتم عرض صور phonecolor (أي image1، image2، إلخ). يعمل Lightgallery بشكل صحيح عند النقر على لون لعرض الصور. ومع ذلك، عندما تقوم بالنقر على صورة واحدة (مثل image1 أو image2) لتكبيرها، لا يتم تحديث Lightgallery ولا يتم تكبير الصورة الصحيحة. Lightgallery لم تعد تتفاعل مع Livewire عند تحديث عدد الصور. فهل قمت بتحديث مكونات Livewire بشكل صحيح عند النقر على لون مختلف؟ حيث تستطيع ذلك بواسطة $refresh() أو إعادة توجيه المستخدم إلى نفس الصفحة باستخدام $goto() للتأكد من إعادة تحميل المكون وتحديث Lightgallery. أيضًا أضف الخاصية livewire:key إلى العناصر التي يتم تحديثها ديناميكيًا (مثل معرض Lightgallery). سيضمن ذلك إعادة تقديم العنصر بشكل صحيح عند تغير البيانات. <div x-data="{ selectedColor: 'black' }"> <button @click="selectedColor = 'black'">أسود</button> <button @click="selectedColor = 'white'">أبيض</button> <div x-show="selectedColor === 'black'" livewire:key="black-images"> </div> <div x-show="selectedColor === 'white'" livewire:key="white-images"> </div> </div> مع التأكد من أن كود JavaScript الخاص بك الذي يحاول تكبير الصور يعمل بشكل صحيح مع Livewire، فربما تحتاج إلى تعديل الكود لاستهداف العناصر الصحيحة بعد تحديث المكونات، أو التفكير في استخدام مكتبة أخرى مثل photoswipe أو swiper.
  3. هي للتأكد من أنّ الإتصال هو عن طريق شخص حقيقي وليس bot أي إتصال من خلال كود كتبه شخص، و قد لا تظهر اختبارات human verification في Cloudflare مثل حل لغز أو كتابة أرقام في صورة وخلافه، وبدلاً من ذلك يحدث اختبار اتصال بسيط. وتحدد Cloudflare مستوى المخاطر لكل زائر بناءً على سلوكه وتاريخه، وإن كان مستوى المخاطر منخفضًا، فقد لا يتم عرض أي اختبارات human verification، وتعتمد Cloudflare على معلومات مثل عنوان IP وجهاز المستخدم وسلوكه لتحديد ما إذا كان اختبار human verification ضروريًا، ولو كانت البيانات غير كافية، فقد لا يتم عرض اختبار.
  4. هل لديك صلاحية فتح برنامج Salfeld؟ حيث أنك لن تتمكن من تعطيله في حال لم تستطيع فتح البرنامج فغالبًا يوجد كلمة مرور له. أما إضافة Windscribe فهي VPN وسنقوم بتجربته لحل المشكلة. والـ VPN، أو الشبكة الخاصة الافتراضية ، هي خدمة تسمح لك بالاتصال بالإنترنت بأمان وخصوصية، وتعمل عن طريق إعادة توجيه حركة المرور على الإنترنت عبر خادم بعيد ، مما يخفي عنوان IP الخاص بك وموقعك، وذلك يجعل من الصعب على المتعقبين وموفري خدمة الإنترنت (ISPs) والحكومات تتبع نشاطك عبر الإنترنت. والإضافة تتطلب إنشاء حساب، وتستطيع استخدام الإضافة التالية إذا كنت لا تريد إنشاء حساب، حيث ستقوم بتثبيتها والإتصال مباشرةً بالضغط على الإضافة ثم زر الإتصال ثم تجربة تصفح الأكاديمية. https://chromewebstore.google.com/detail/vpn-free-betternet-unlimi/gjknjjomckknofjidppipffbpoekiipm
  5. ذلك طبيعي حيث يتم تفقد الإتصال الخاص بك من وقت لآخر أثناء تصفح الأكاديمية، لكن هناك تعارض بين Salfeld و ميزة human verification في cloudflare. حاول تجربة استخدام vpn من أجل تمكن الدخول للموقع ثم تعطيله بعد نجاح الدخول، وهناك إضافات على المتصفح مثل Windscribe. https://chrome.google.com/webstore/detail/hnmpcagpplmpfojmgmnngilcnanddlhb وإن أمكن تعطيل Salfeld أثناء تصفح الأكاديمية فسيحل ذلك المشكلة.
  6. المشكلة تحدث عند الإنتقال من زر all إلى photos وأيضًا videos، لكن لا تحدث عند الإنتقال من videos إلى photos أو العكس، لذا تفقد ما الخطأ في المنطق الخاص بذلك، ربما هناك كلاس لا يتم حذفه أو ما شابه.
  7. لا مشكلة لديك، قمت بإختبار المشروع سواء بشكل محلي أو رابط netlify لا يوجد مشكلة تفقد الفيديو: ربما المشكلة لديك هي في الكاش (الملفات المؤقتة) حاول إعادة تحديث الصفحة بالضغط على CTRL + F5 أيضًا حاول تحديث المتصفح. 2024-02-15_11-03-22.mp4
  8. إذا كان التعبير صحيحًا، فإن Not تجعله خاطئًا. إذا كان التعبير خاطئًا، فإن Not تجعله صحيحًا. أي عكس القيمة المنطقية لتعبيرات Boolean.
  9. المطلوب منك هو كتابة دالة تُرجع دائمًا True لأي عنصر في قائمة معينة، ولديك العنصر هو كلمة "flick"، أي يجب على الدالة تبديل السلوك لترجع دائمًا القيمة المنطقية المعاكسة. ولديك مشكلتان: 1- التكرار اللانهائي، حيث عندما تواجه حلقة for عنصرًا "flick" ، يتم تعيين boo إلى "False"، ثم يتم تعيين العنصر نفسه إلى boo. لكن بما أن boo الآن "False" ، فسيتم إعادة تعيين boo إلى "True" في التكرار التالي، سيستمر هذا التناوب إلى أجل غير مسمى ، مما يؤدي إلى حلقة لانهائية. 2- عدم معالجة عناصر غير السلسلة، افترض الكود أن جميع العناصر في القائمة هي سلاسل، فإذا واجهت عنصرًا غير سلسلة (مثل رقم أو قائمة فرعية) ، فسيتسبب ذلك في حدوث خطأ TypeError. لذا سيصبح الكود كالتالي وأضفت تعليقات لتفهم ما يحدث: def always_true(arr): """ تعديل القائمة المعطاة `arr` لترجع دائمًا True عند فحصها لمعرفة صحتها. إذا كان عنصر في `arr` هو كلمة "flick" ، فإن الدالة تقلب السلوك لترجع دائمًا القيمة المنطقية المعاكسة. ومع ذلك ، لا تعدل القائمة الأصلية مباشرة لتجنب التأثيرات الجانبية المحتملة. Args: arr: القائمة التي تريد تعديلها. Returns: None. تعدل الدالة القائمة المُدخلة مباشرة. Raises: TypeError: إذا لم يكن عنصر في `arr` سلسلة. """ truth_state = True for i in range(len(arr)): if arr[i] == 'flick': truth_state = not truth_state # تبديل حالة الصدق arr[i] = 'flicked' # تمييز العنصر لتجنب التكرار اللانهائي arr[i] = truth_state return None # غير ضروري ، لكن يمكن الاحتفاظ به للتناسق # مثال على الاستخدام arr = ['a', 'b', 'flick', 'c', 'flick', 'd'] always_true(arr) print(arr) # إخراج: ['True', 'True', 'flicked', 'True', 'flicked', 'True'] # مثال آخر arr2 = [0, 1, 'flick', True, False] always_true(arr2) print(arr2) # إخراج: [True, True, 'flicked', True, False]
  10. أولاً علينا فك ضغط المشروع ثم فتح المجلد في vscode من خلال سحب وإلقاء المجلد به أو بالضغط على file ثم open folder، وعند تحميل مشروع جافاسكريبت أي أقصد مشروع من خلال مكتبة أو إطار خاص بجافاسكريبت نبدأ أولاً بتحميل الحزم من خلال الأمر: npm i وإن واجهتنا مشكلة بتثبيت الحزم نقوم بتجاهل تعارض الحزم من خلال: npm i --legacy-peer-deps بعد ذلك نتوجه لملف package.json ونتقد السكربتات الخاصة بتشغيل المشروع مثل التالي في المشروع: "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }, ونقوم بتنفيذ أمر التشغيل وهو start من خلال التالي: npm start والأمر Start نستطيع كتابته بدون run في npm بينما الأوامر الأخرى يجب كتابة run مثل التالي: npm run build بعد تشغيل أمر: npm start سيتم تشغيل المشروع. والمشروع هو مشروع react وهي مكتبة جافاسكريبت خاصة بالواجهة الأمامية.
  11. أولاً عليك إضافة الدالة الصحيحة هنا: list_tasks.set_defaults(func = controller.check_task) لتصبح: list_tasks.set_defaults(func=controller.display) بعد ذلك عليك عدم وضع فواصل بين بيانات المهمة في ملف Task.py أي بدلاً من: return f'{self.title} , {self.description} , {self.start_date} , {self.end_date} , {self.done}' يصبح: return f'{self.title}, {self.description}, {self.start_date}, {self.end_date}, {self.done}' فهناك مسافة إضافية في نهاية السلسلة، والتي لا يمكن لـ "date.fromisoformat()" تحليلها. بعد ذلك احذف ملف taks.txt ثم أضف مهمة والتجربة مرة أخرى.
  12. بشكل بسيط، أثناء تطوير المشروع من الأسهل الإعتماد على قاعدة بيانات SQLiteفالتعامل معها سهل ويوفر الوقت ويجنب مشاكل قد تحدث أثناء التطوير، وبعد الإنتهاء تستطيع الإنتقال لقاعدة البيانات التي تريدها وذلك من خلال إطار Django أو Flask. بالطبع عليك تعلم قاعدة بيانات علائقية وهما mySQL وPostgreSQL، وفيما بعد تستطيع تعلم MongoDB وهي قاعدة بيانات NoSQL مناسبة لتخزين البيانات غير المنظمة أي غير علائقية. بالطبع يوجد أنواع أخرى لكن تلك أمور متقدمة وللمعرفة فقط في بدايات تعلمك: Redis: قاعدة بيانات NoSQL مناسبة لتخزين نتائج استعلامات قاعدة البيانات، أو صفحات الويب المُخزنة مؤقتًا، أو أي بيانات أخرى تتغير بشكل متكرر. Cassandra: قاعدة بيانات NoSQL تسمح بتخزين البيانات على العديد من الخوادم في مواقع مختلفة.
  13. تأكد من تمرير الوسائط كالتالي في ملف app.py في السطر 40 كما يشير الخطأ: args = parser.parse_args() if not args.func: return args.func(args) في حال استمرت المشكلة أرجو إرفاق مجلد المشروع بعد ضغطه بواسطة winRAR
  14. لأن دالة size() التي تستخدمها غير متوفرة في مكتبة C++ القياسية، وهناك وظائف مختلفة تسمى size() تعمل مع هياكل بيانات مختلفة، لكن تلك التي تستخدمها قد تكون خاصة بمكتبة معينة أو قد تكون وظيفة مخصصة لم تحددها. استخدام عامل sizeof() (للمصفوفات على غرار C) مثل numbers في الكود لديك، للحصول على عدد العناصر، ومع ذلك، لاحظ أن ذلك يرجع الحجم الكلي للمصفوفة بالبايتات، وليس عدد العناصر: #include <iostream> using namespace std; int main() { int numbers[] = {10, 20, 3, 30, 5, 7, 40}; int numssize = sizeof(numbers) / sizeof(numbers[0]); cout << numssize << endl; // Output: 7 return 0; } وإن كنت تستخدم عناصر من مكتبة Standard Template Library (STL) ، مثل المتجهات أو المصفوفات أو السلاسل، فتستطيع الإعتماد على دالة std::size(): #include <iostream> #include <vector> using namespace std; int main() { vector<int> numbers = {10, 20, 3, 30, 5, 7, 40}; int numssize = std::size(numbers); cout << numssize << endl; // Output: 7 return 0; } ولو لديك وظيفة مخصصة أو مكتبة تحدد دالة size() خصيصًا لحالة استخدامك، فتحتاج إلى التأكد من أن الوظيفة مرئية في نطاق وظيفتك main()، وتحقق من مكان تعريف الوظيفة وتضمين الرؤوس أو الملفات الضرورية لإحضارها إلى النطاق.
  15. أرجو التعليق أسفل فيديو الدورة لمساعدتك بشكل أفضل وطرح الأسئلة العامة هنا. بخصوص سؤالك في ملف app.py تأكد من وجود معلمة --task كالتالي: do_task = subparsers.add_parser('check', help='Check the given task') do_task.add_argument('-t', '--task', help='Number of the task to be done. If not specified, last task will be removed.', type=int) do_task.set_defaults(func=controller.do_task) لديك أنت قمت بتسمية الدالة باسم check_task لا مشكلة في ذلك.
  16. فهمت ما تريده، عليك استخدام الحدث الصحيح للنقر على الرابط وهو onclick: document.links[0].onclick = function (event) { console.log(event); event.preventDefault(); }; document.forms[0].onsubmit = function (e){ let userValid = false; let userAge = false; if (!userValid || !userAge ){ e.preventDefault(); console.log("النموذج غير صالح"); } }
  17. live server قيد التشغيل بالفعل ستجده بالأسفل على اليمين في vscode لديك منفذ 5500 اضغط عليه للإيقاف ثم انقر عليه مرة أخرى go live للتشغيل.
  18. أولاً حدث النموذج غير صحيح عليك تغيير onsubmitb إلى onsubmit في الوظيفة الثانية. ثم قم بتغيير الخطأ الإملائي fales إلى false ,و من الأفضل وضع true لـ userValid و userAge إذا كان يجب أن تكون صحيحة في البداية. أيضًأ تطبيق فحص مساواة صارم باستخدم === بدلاً من == لمقارنة صارمة. إليك الكود بعد التعديل مع تعليقات لتوضيح ما أقصده: document.forms.onsubmit = function (e) { // اسم الحدث تم تصحيحه let userValid = true; // بافتراض أن التحقق من صحة البيانات يبدأ صحيحًا let userAge = true; // بافتراض أن التحقق من صحة البيانات يبدأ صحيحًا // أضف منطق التحقق من صحة النموذج هنا (مثل التحقق من قيم الإدخال) // تحديث `userValid` و `userAge` بناءً على نتائج التحقق من الصحة if (!userValid || !userAge) { e.preventDefault(); } };
  19. لاحظ أنك لم تكتب علامة الـ $ من أجل تحديد طباعة المتغير فحاليًا تقوم بطباعة نص فقط باسم name. إليك مثال: <?php // تعريف المتغير $name = "باسم"; // طباعة المتغير باستخدام echo echo $name; ?> وأرجو طرح السؤال المتعلق بالدورة أسفل درس الدورة ستجد صندوق تعليقات، وطرح الأسئلة العامة هنا.
  20. على إفتراض أن هيكل قاعدة البيانات لديك هو حقل واحد لسجل العمل أي SPECIALIST_WORKED_BEFORE هو حقل VARCHAR/Text واحد يخزن جميع عناصر سجل العمل كسلسلة مفصولة بفواصل، وتريد تحرير تلك العناصر مباشرة داخل ListBox، سيكون الكود كالتالي: private void dataGridView1_SelectionChanged(object sender, EventArgs e) { if (dataGridView1.SelectedRows.Count > 0) { try { int id = int.Parse(dataGridView1.SelectedRows[0].Cells[0].Value.ToString()); var p = db.TBL_SPECIALIST.SingleOrDefault(x => x.SPECIALIST_ID == id); if (p != null) { string workHistoryString = p.SPECIALIST_WORKED_BEFORE; // تقسيمها إلى مجموعة من السلاسل لعرضها في ListBox lbx_work_history.Items.Clear(); lbx_work_history.Items.AddRange(workHistoryString.Split(',').Select(s => s.Trim()).ToArray()); // تمكين التحرير إذا لزم الأمر lbx_work_history.Enabled = true; // اختياري: إضافة زر "حفظ التغييرات" لكتابة العناصر التي تم تحريرها مرة أخرى إلى قاعدة البيانات } else { lbx_work_history.Items.Clear(); lbx_work_history.Enabled = false; // معالجة عدم العثور على أي متخصص } } catch (Exception ex) { } } } private void lbx_work_history_SelectedIndexChanged(object sender, EventArgs e) { if (lbx_work_history.SelectedIndex >= 0) { // معالجة تحرير أو حذف العنصر المحدد } } أو تنفيذ جدول سجل عمل منفصل، أي يوجد جدول منفصل (مثل TBL_WORK_HISTORY) مرتبط بـ TBL_SPECIALIST (مثل SPECIALIST_ID) لتخزين إدخالات سجل العمل الفردية، وعرض وتحرير تلك الإدخالات في شبكة/عرض بيانات. وكمثال لمخطط قاعدة البيانات: CREATE TABLE TBL_SPECIALIST ( SPECIALIST_ID INT PRIMARY KEY, ... (other specialist fields) ); CREATE TABLE TBL_WORK_HISTORY ( WORK_HISTORY_ID INT PRIMARY KEY, SPECIALIST_ID INT FOREIGN KEY REFERENCES TBL_SPECIALIST(SPECIALIST_ID), WORK_HISTORY_DESCRIPTION VARCHAR(255) ); ثم تنفيذ الكود: private void dataGridView1_SelectionChanged(object sender, EventArgs e) { if (dataGridView1.SelectedRows.Count > 0) { try { int id = int.Parse(dataGridView1.SelectedRows[0].Cells[0].Value.ToString()); var p = db.TBL_SPECIALIST.SingleOrDefault(x => x.SPECIALIST_ID == id); if (p != null) { // تحميل سجل العمل من جدول منفصل var workHistory = db.TBL_WORK_HISTORY.Where(x => x.SPECIALIST_ID == id).ToList(); // عرض سجل العمل في DataGridView dgv_work_history.DataSource = workHistory; // تكوين DataGridView حسب الحاجة (أعمدة، قابلية التحرير، إلخ) // تمكين التحرير إذا لزم الأمر dgv_work_history.Enabled = true; } else { // معالجة عدم العثور على أي متخصص } } catch (Exception ex) { } } } // معالجة حفظ التغييرات التي تم إجراؤها على سجل العمل (إضافة/تعديل/حذف) private void btn_save_work_history_Click(object sender, EventArgs e) { // استرداد التغييرات من DataGridView var workHistoryChanges = ... // استخدم آلية مناسبة لجمع التغييرات من DataGridView // تحديث قاعدة البيانات foreach (var change in workHistoryChanges) { // ... } // تحديث DataGridView لعرض التغييرات // ... } وعليك تكوين dgv_work_history بشكل صحيح لعرض سجل العمل (ربط البيانات، الأعمدة، إلخ)، حيث ستحتاج إلى آلية مناسبة لجمع التغييرات من dgv_work_history (مثل استخدام مجموعات البيانات المُدارة أو كائنات DTO).
  21. هل القالب هو قالب HTML, CSS فقط؟ إذن ستحتاج إلى شراء خدمة تعديل قالب من خلال منصة خمسات، وإن كانت التعديلات كثيرة من الأفضل إنشاء مشروع على منصة مستقل واستقبال العروض مع شرح تفاصيل ما تريده. والتكلفة تختلف من مستقل لآخر وتستطيع اختيار ما تريد، لكن اختر دائمًا من لديه معرض أعمال جيد ومنظم ومناسب لما تريده، أيضًا لمن يبدي احترافية في عرضه المقدم.
  22. إذا أردت النصيحة، فنعم عليك تعلم الأساسيات، لكن ذلك في حال أنك ستقوم بتطوير تطبيقات ويب من خلال Flask أو Django، وفي حال أنك ستتعامل مع كود بايثون فقط وليس مواقع الويب إذن لا حاجة إلى ذلك. وفي الدورة سيتم شرح بناء مواقع من خلال Flask وDjango، لذا إن أردت دراسة تلك المسارات عليك دراسة المسار الأول من دورة تطوير واجهات المستخدم بجانب المسار الأول من دورة تطوير التطبيقات من خلال جافاسكريبت، والمسارات الأولى من جميع الدورات متاحة لك بشكل مجاني.
  23. عليك إذن دراسة المسار الأول من دورة تطوير واجهة المستخدم لتتعلم HTML, CSS, JS. ثم تعود لدورة جافاسكريبت وتقوم بدراسة أساسيات JS بشكل معمق أكثر، ثم تقوم بدراسة أساسيات React، ثم أساسيات Node.js ثم React Native.
  24. صحيح، القصد هو أنه ليس لزامًا إتمام كامل الدورة للتقدم للإختبار والحصول على الشهادة، حيث تستطيع إنهاء 4 مسارات فقط وسيتم اختبارك بهم. لكن بالطبع لا أنصحك بذلك فإنهاء الدورة بالكامل سيحقق إفادة لك والشهادة في ذاتها لا معنى لها بدون فائدة تعود عليك، الغرض من ذلك هو أن البعض يريد دراسة مسارات معينة وليس بحاجة إلى باقي المسارات لأي سببٍ كان. يتم رفع المشاريع العملية الكاملة إلى منصة GitHub حيث ننشيء مستودع منفصل لكل مشروع، وهي بالفعل المشاريع التي قم بتنفيذها خلال الدورة.
  25. بالطبع لا، عليك تحديد ما تريده من الدورة تحديدًا، هل تريد أن تصبح مطور واجهة أمامية أم خلفية أم الاثنان معًا Full-stack. وطالما أنك لم تُحدد إذن عليك بالتجربة، صدقني قراءة 100 مقالة عن المجال المناسب لن تفيدك بقدر التجربة العملية، لذا لإختيار المسار البرمجي الذي ستبذل به أقصى جهدك، عليك بدراسة الدورة بالكامل لتفقد المجالات من واقع عملي. أيضًا هناك نقطة هامة ألا وهي إن كنت تنوي العمل بالشركات فعليك تفقد الوظائف في بلدك وما هي التنقيات المطلوبة وهل مجال الويب مطلوب أكثر أم مجال تطوير تطبيقات الهاتف وهل المطلوب Flutter أم React Native ألقي نظرة على الوظائف، وبالنسبة لمواقع العمل الحر عليك بتفقد المشاريع المعروضة في المنصة التي تنوي العمل عليها لتفقد التقنيات والمهارات المطلوبة بكثرة. وفي النهاية إن لم تستطع اتخاذ قرار، إذن من الأفضل تعلم مجال الواجهة الأمامية Font-End فهو سيفتح لك المجال لتعلم المجالات الأخرى ويعتبر أسهل نسبيًا والمفاهيم والمهارات التي ستتعلمها ستنتقل معك إلى المجالات الأخرى ويعتبر مجال جيد لدخول عالم البرمجة.
×
×
  • أضف...