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

Mustafa Suleiman

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

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

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

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

    356

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

  1. أرجو منك إضافة الأكواد بالنسخ واللصق، ضع كود HTML الخاص بالـ Footer و كود CSS أيضًا.
  2. يمكن أن يكون السبب في عدم تعيين ارتفاع الـ container الخاص بالـ footer بشكل صحيح، مما يؤدي إلى تغيير توزيع المحتوى. يمكن حل المشكلة عن طريق تحديد ارتفاع الـ container بشكل صحيح، ويمكن القيام بذلك باستخدام الخاصية "height" مع CSS، مثلاً: .footer { height: 100px; } ويمكن تعديل قيمة 100px وفقًا لاحتياجات التصميم. كما يجب التأكد من استخدام الأدوات المناسبة لتحليل التصميم والتأكد من تطابق النتائج مع التصميم الأصلي. بعض الأسباب الأخرى التي يمكن أن تؤدي إلى عدم توافق التصميم مع الواجهة النهائية على الموقع تشمل: استخدام العرض والارتفاع بنسبة مئوية بدلاً من القيم الثابتة. استخدام خصائص CSS مثل transform و rotate و translate بشكل غير صحيح. عدم تحديد وحدات القياس بشكل صحيح، مثل استخدام البكسل بدلاً من النسبة المئوية. استخدام العناصر المطلقة (absolute) بشكل غير صحيح، مما يؤدي إلى عدم وضوح الموقع على الشاشات المختلفة. استخدام القيم الافتراضية للخصائص في CSS دون تعديلها وفقًا لاحتياجات التصميم. ومن الصعب الجزم بسبب المشكلة، إلا بعض رؤية الكود الخاص بالـ Footer ويجب أن يكود كود HTML و CSS.
  3. قبل تعلم TailwindCSS عليك بمعرفة ماهى الميزات والقيود الخاص بتلك المكتبة وأيضًا مقارنتها بالبدائل مثل Bootstrap و StyledComponents، ومتى يتم استخدامها. Tailwind CSS تتميز مكتبة Tailwind CSS بالتالي: توفر مجموعة كبيرة ومتنوعة من الأنماط والألوان الرئيسية المعرفة مسبقًا. يمكنك تخصيص الأنماط بشكل كبير ومعرفة مسبقًا ما هي الفئات المتوفرة من خلال العرض الأساسي للمكتبة. تستخدم بنية "Atomic CSS" التي تسمح لك بإنشاء الأنماط بسرعة وسهولة عن طريق الجمع بين الفئات الأساسية المتوفرة لتشكيل تراكيب جديدة. تدعم ميزة "Dark Mode" التي تمكنك من تغيير الألوان تلقائيًا عندما تتغير الخلفية. تدعم RTL ولكن بشكل محدود وهناك إضافات خارجية لذلك. إليك بعض الأكواد البسيطة باستخدام Tailwind CSS: <div class="container mx-auto p-4"> <h1 class="text-4xl font-bold">مرحبًا بالعالم</h1> <p class="mt-4">أنا نص مثالي باستخدام Tailwind CSS</p> <button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded mt-4">اضغط هنا</button> </div> Bootstrap تتميز مكتبة Bootstrap بالتالي: توفر أنماط محددة مسبقًا لعدد كبير من العناصر والمكونات الشائعة، مما يجعل من السهل إنشاء واجهات المستخدم الجذابة. تحتوي على العديد من الإضافات والمكونات التي توفر العديد من الميزات، مثل معالجة النماذج والجداول وغيرها. تدعم RTL ولكن بشكل محدود. توفر Bootstrap مساعدات JavaScript مدمجة، مما يسمح بإضافة بعض التفاعلية إلى تطبيقات الويب. مثال: <div class="container p-4"> <h1 class="text-primary display-4">مرحبًا بالعالم</h1> <p class="mt-4">أنا نص مثالي باستخدام Bootstrap</p> <button class="btn btn-primary mt-4">اضغط هنا</button> </div> Styled Components تتميز مكتبة Styled Components بالتالي: توفر أسلوبًا مختلفًا للتعامل مع CSS وتستخدم قوة JavaScript لإنشاء عناصر UI. تسمح بتعريف المكونات باستخدام العلامات المشتقة باستخدام القوالب، مما يجعل من السهل إنشاء مكونات مخصصة وقابلة لإعادة الاستخدام. تسمح للمطورين بإنشاء ستايلات قابلة للتغيير والقابلة للتوسع بشكل سهل، مما يتيح إمكانية إجراء التعديلات بسهولة في جميع الأجزاء المتعلقة بالتصميم. تتميز بقدرتها على التعامل مع الحالات الحدودية وتسهيل التحويل بين المكونات. لا توفر الكثير من الميزات المدمجة مثل Bootstrap ولكن يمكن استخدام المكتبات الخارجية معها بسهولة. مثال: import styled from 'styled-components'; const Container = styled.div` padding: 1rem; `; const Title = styled.h1` font-size: 4rem; font-weight: bold; color: #0077ff; `; const Paragraph = styled.p` margin-top: 1rem; `; const Button = styled.button` background-color: #0077ff; color: #fff; font-weight: bold; padding: 0.5rem 1rem; border-radius: 0.25rem; margin-top: 1rem; &:hover { background-color: #0051a8; } `; function App() { return ( <Container> <Title>مرحبًا بالعالم</Title> <Paragraph>أنا نص مثالي باستخدام Styled Components</Paragraph> <Button>اضغط هنا</Button> </Container> ); } تلاحظ أن Styled Components تستخدم JavaScript لإنشاء المكونات في حين أن Bootstrap يستخدم الكلاسات لتحديد المظهر. ما الأفضل بينهم ومتى يكون من الأفضل استخدام أيًا منهم؟ لا يوجد إجابة صحيحة مطلقة على هذا السؤال، فذلك يعتمد على الحاجة والغرض من المشروع والتصميم المطلوب. إذا كنت تريد تطوير تطبيق ويب بسيط وسريع وقابل للتخصيص بشكل كبير، فقد يكون TailwindCSS هو الخيار الأفضل لأنه يوفر أسلوبًا سهلًا لتخصيص تصميم الموقع وتوفير الوقت والجهد. إذا كنت تبحث عن مكتبة تصميم تحتوي على العديد من المكونات الجاهزة، فقد يكون Bootstrap الخيار الأفضل لك. يتيح Bootstrap أنماطًا محددة مسبقًا ومكونات مثل النماذج والجداول وغيرها، مما يجعل من السهل تصميم واجهات المستخدم الجذابة والوظيفية، لكن لن يكون الموقع الخاص بك فريدًا بل يشبه أغلب المواقع التي تستخدم Bootstrap. Styled Components، بالمقابل، تعتمد على JavaScript وتقنية CSS-in-JS، مما يتيح للمطورين تصميم وتخصيص المكونات باستخدام JavaScript وCSS معًا، ويسمح للمستخدمين بتحسين أداء التطبيق والتحكم في الأنماط والأنماط الشخصية بشكل أفضل. لذا، يعتمد الاختيار بين TailwindCSS وBootstrap وStyled Components على الحاجة والغرض من المشروع والأولويات المطلوبة، فإذا كنت تحتاج إلى تسريع تطوير تطبيقات الويب الخاصة بك وتخصيصها بسهولة، فقد يكون TailwindCSS الخيار الأفضل. وإذا كنت تبحث عن مكتبة تصميم مكونات جاهزة ووظيفية، فقد يكون Bootstrap الخيار الأفضل، وإذا كنت تريد تصميم مكونات مخصصة باستخدام JavaScript و CSS معًا، فقد يكون Styled Components الخيار الأفضل.
  4. بالإضافة إلى ما تم ذكره، هناك أمر هام يجب معرفته وهو لماذا تم الاستغناء عن var وإعتماد let و const بدلاً منها: var: تم استخدام var في السابق لتعريف المتغيرات قبل إضافة let و const في ES6. يمكن استخدام var في أي مكان داخل النطاق الوظيفي الذي تم تعريفه فيه، وإذا تم استخدام var داخل الكتلة block، فإن نطاقه ينتهي عند نهاية الكتلة الحالية. يمكن إعادة تعريف المتغيرات المعرفة ب var داخل نفس النطاق، ويتم تعويض القيمة المخزنة في المتغيرات المعرفة ب var في حالة الارتفاع (hoisting)، وهو سلوك يؤدي إلى رفع تعريف المتغيرات إلى الجزء العلوي من النطاق الحالي. let: تم إضافة let في ES6 وهي تماثل var في كونها تستخدم لتعريف المتغيرات، ولكنها تتمتع بسلوك أفضل في بعض الحالات. يتم تعريف نطاق let داخل الكتلة، ولا يمكن إعادة تعريف المتغيرات المعرفة ب let داخل نفس النطاق، ولا يتم تعويض القيمة المخزنة في المتغيرات المعرفة ب let قبل تعريفها. يتم استخدام let بشكل أكبر في حالات تحتاج فيها إلى النطاق الحالي دون إعادة تعريف المتغيرات. const: تم إضافة const أيضًا في ES6 وهي تستخدم لتعريف المتغيرات ثابتة القيمة (constant)، أي أن القيمة المخزنة فيها لا يمكن تغييرها. يتم تعريف نطاق const داخل الكتلة، ويجب تعيين القيمة المخزنة في المتغيرات المعرفة ب const عند التعريف ولا يمكن تغييرها لاحقًا. يتم استخدام const عادة عندما يكون من الضروري تعريف قيم ثابتة وغير قابلة للتغيير، مثل القيم الثابتة مثل قيمة عدد ثابت مثل الرقم الثابت PI (3.14) أو قيمة ثابتة مثل عنوان URL الذي يستخدمه التطبيق. بشكل عام، يتم استخدام var عندما تكون هناك حاجة لتعريف متغيرات على مستوى الدالة أو الملف، ويتم استخدام let و const في حالة الحاجة إلى تعريف متغيرات على مستوى الكتلة. ويتم استخدام const في حالة الحاجة إلى تعريف متغيرات ثابتة القيمة. وتم استبدال var ب let و const في ES6 لتحسين توضيح ونطاق الحياة للمتغيرات. فباستخدام let و const، يتم تقييد نطاق المتغيرات بمدى الكتلة والتأكد من عدم تعريفها بشكل عشوائي في أي مكان آخر في البرنامج، بينما var يتم تعريف المتغيرات بمدى الدالة أو الملف، مما يمكن أحيانًا من تعريفها دون قصد في أي مكان في البرنامج. باختصار 1- متى يتم استخدام var و let: يتم استخدام var في حالات النطاق العام (global scope) أو النطاق الداخلي للدالة (function scope)، بينما يتم استخدام let في حالات النطاق الداخلي للكتل (block scope)، مثل اللوحات التالية: // نطاق العام (global scope) var a = 10; function myFunction() { // نطاق الدالة (function scope) var b = 20; if (true) { // نطاق الكتل (block scope) let c = 30; } } 2- لماذا تم استبدال var ب let و const: تم استبدال var بـ let و const لتفادي المشاكل التي قد تحدث بسبب نطاق الدالة العام وتبسيط العمل على المطورين. على سبيل المثال، قد يحدث خطأ في استخدام var عند تعريف متغير مرتين في نفس النطاق، حيث يتم تغيير قيمة المتغير الأول. ومن خلال استخدام let و const، يتم حل هذه المشكلة وتسهيل الكود. كما أن استخدام const يحد من خطأ البرمجة في تغيير قيمة المتغير عن طريق الخطأ. مثال: // مثال استخدام var var x = 5; var x = 10; console.log(x); // النتيجة 10 // مثال استخدام let let y = 5; y = 10; console.log(y); // النتيجة 10 // مثال استخدام const const z = 5; z = 10; // سيتم إلقاء خطأ في الكود console.log(z); https://io.hsoub.com/javascript/44681-المتغيرات-في-جافاسكربت-بعد-es6 https://io.hsoub.com/javascript/45102-رفع-المتغيرات-في-جافا-سكريبت-javascript-variables-hoisting
  5. بالإضافة إلى الخطوات التي أشار إليها Kais، يجب إصلاح الأخطاء في ملفات المشروع التي لديك لتجنب ظهور أخطاء أخرى. وأرجو منك إكمال بقية النقاش حول السؤال هنا لتجنب حل المشكلة من قبل أكثر من شخص، وفي المرات القادمة ضع السؤال أسفل الدرس. وإليك ملف app.py بعد التعديل وإصلاح الأخطاء التالية: استخدام Taskcontroller بدلاً من TaskController. إزالة المسافات الإضافية للوسيطات - مثل "title " بدلاً من " title". استخدام "type = str" لجميع الوسيطات، بدلاً من استخدام "type = str" لبعضها فقط. إضافة "action = 'store_true'" لخيار "--done" بدلاً من استخدام "type = str". تغيير الخيار "-a" إلى "--all" في الأمر "list". تغيير الخيار "-a" إلى "-n" في الأمر "remove". تحديد الخيار "task" كـ "type = int" في الأمر "check". from argparse import ArgumentParser from Taskcontroller import TaskController from argparse import Namespace def main(): controller = TaskController('tasks.txt') parser = ArgumentParser(description='Simple CLI Task Manager') subparsers = parser.add_subparsers() add_task = subparsers.add_parser('add', help='add the given task') add_task.add_argument('title', help='title of the task', type=str) add_task.add_argument('-d', '--description', help='short description of the task', type=str, default=None) add_task.add_argument('-s', '--start_date', help='date start of the task', type=str, default=None) add_task.add_argument('-e', '--end_date', help='date end of the task', type=str, default=None) add_task.add_argument('--done', help='check whether the task is done or not', action="store_true") add_task.set_defaults(func=controller.add_task) list_task = subparsers.add_parser("list", help='list of unfinished task') list_task.add_argument('-a', '--all', help='lists of all tasks', action="store_true") list_task.set_defaults(func=controller.display) check_task = subparsers.add_parser("check", help='check the given task') check_task.add_argument('-t', '--task', help='number of task to be done', type=int) check_task.set_defaults(func=controller.check_task) remove_task = subparsers.add_parser("remove", help='remove of task') remove_task.add_argument('-n', '--number', help='the task will be removed(numbers)', type=int) remove_task.set_defaults(func=controller.remove_task) reset_task = subparsers.add_parser("reset", help='remove all tasks') reset_task.set_defaults(func=controller.reset_task) args = parser.parse_args() args.func(args) if __name__ == '__main__': main() وهذا هو ملف Task.py بعد إصلاح الأخطاء التالية: تم تصحيح اسم الوسيط dsecription إلى description لكي يتوافق مع اسم المتغير المعرف في الدالة __init__، وتم إضافة مسافات بعد علامة فاصلة في دالة __str__ لتوضيح النص بشكل أفضل. class Task: def __init__(self, title, description=None, start_date=None, end_date=None, done=False): self.title = title self.description = description self.start_date = start_date self.end_date = end_date self.done = done def __str__(self): return f'{self.title}, {self.description}, {self.start_date}, {self.end_date}, {self.done}' ملف Taskcontroller.py بعد إصلاح الأخطاء التالية: استخدام متغيرات غير معرفة في الدوال: تم استخدام متغيرات غير معرفة في دالة list_alltasks()، والتي قام المبرمج بتسميتها بـ finished_tasks بدلاً من unfinished_tasks التي تم تعريفها في الدالة. خطأ في تعريف الدوال: تم تعريف دالة check_task() ولم يتم استخدام البارامتر args الموجود في تعريفها داخل الدالة، بل تم استخدام self.args بدلاً من ذلك. خطأ في اسم الدالة: تم تعريف دالة list_tasks() ولم يتم استخدام الاسم الصحيح للدالة، حيث استخدم اسم all_tasks بدلاً من unfinished_tasks الذي تم تعريفها. استخدام دالة غير موجودة: تم استخدام دالة list_all_tasks() بدلاً من list_alltasks() في الدالة remove_task(). استخدام self.args بدلاً من args: تم استخدام self.args بدلاً من args في الدالة check_task(). استخدام نوع البيانات الخاطئ: تم استخدام دالة date.fromisofromat() و date.formisoformat() بدلاً من date.fromisoformat() و date.isoformat() في الدالة due_date(). خطأ في استخدام الدالة print_table(): تم استخدام الدالة print_table() بدون استخدام البارامتر tasks في الدالة display(). استخدام tasks بدلاً من task: تم استخدام tasks بدلاً من task في الدالة remove_task()، والتي تم تعريفها كمتغير لحذف مهمة واحدة، وبالتالي أدت إلى القيام بحذف جميع المهام في الملف. عدم إدخال البيانات بالشكل الصحيح في الملف: تم حفظ البيانات في الملف في صورة سلسلة محولة، بدلاً من استخدام أي شكل من أشكال تخزين البيانات الهيكلية (على سبيل المثال، JSON أو CSV). عدم استخدام argparse بشكل صحيح: تم استخدام argparse للتعرف على المدخلات المستخدمة، ولكن تحديد الخيارات والوسائط التي تم استخدامها من خلال الأرقام الثابتة، وليس باستخدام الخيارات الاسمية. وهذا يعني أن أي تغيير في ترتيب الخيارات يؤثر على طريقة عمل البرنامج. عدم التحقق من صحة المدخلات: لم يتم التحقق من صحة المدخلات المستخدمة، مثل التحقق من تنسيق التاريخ المدخل أو القيم المدخلة للخيارات. تعقيد المنطق المستخدم في البرنامج: تم استخدام مجموعة متنوعة من الأساليب لإنجاز المهام المطلوبة، مما يصعب فهم كيفية عمل البرنامج وتصحيح الأخطاء في حالة وجودها. عدم استخدام معايير جيدة لتسمية المتغيرات: تم استخدام أسماء متغيرات غير واضحة، مما يصعب فهم دور كل متغير في البرنامج. الاعتماد على العوامل الخارجية: تم الاعتماد على وجود ملفات خارجية لتخزين البيانات، وهذا يعني أن أي تغييرات في تنسيق الملف يمكن أن تؤثر على طريقة عمل البرنامج. عدم وجود مستوى جيد من التعليقات: لم يتم إضافة تعليقات كافية لشرح وظيفة الأكواد المستخدمة، مما يجعل صعوبة فهم وتصحيح الأخطاء في البرنامج. from Task import Task from datetime import date from tabulate import tabulate from argparse import Namespace class TaskController: def __init__(self, file_name): self.file_name = file_name def add_task(self, args): # 1 start date if not args.start_date: now = date.today().isoformat() args.start_date = now # 2 define task task = (args.title, args.description, args.start_date, args.end_date, args.done) # 3 open file and save info with open(self.file_name, 'a') as file: file.write(", ".join(str(x) for x in task) + "\n") def list_tasks(self): unfinished_tasks = [] with open(self.file_name, 'r') as file: for line in file: title, description, start_date, end_date, done = line.strip().split(", ") end_date = None if end_date == 'None' else end_date done = False if done.strip() == 'False' else True if done: continue unfinished_tasks.append({'title': title, 'description': description, 'start_date': start_date, 'end_date': end_date}) return unfinished_tasks def list_all_tasks(self): all_tasks = [] with open(self.file_name, 'r') as file: for line in file: title, description, start_date, end_date, done = line.strip().split(", ") end_date = None if end_date == 'None' else end_date done = False if done.strip() == 'False' else True all_tasks.append({'title': title, 'description': description, 'start_date': start_date, 'end_date': end_date, 'done': done}) return all_tasks def due_date(self, start, end): start_date = date.fromisoformat(start) end_date = date.fromisoformat(end) due_date = end_date - start_date return f'{due_date.days} days left.' def print_table(self, tasks): formatted_tasks = [] for number, task in enumerate(tasks, 1): if task['start_date'] and task['end_date']: due_date = self.due_date(task['start_date'], task['end_date']) else: due_date = 'Open' formatted_tasks.append({'no.': number, **task, 'due_date': due_date}) print(tabulate(formatted_tasks, headers='keys')) def display(self, args): all_tasks = self.list_all_tasks() unfinished_tasks = self.list_tasks() if not all_tasks: print('There are no tasks. To add a task, use: add <task>') return if args.all: self.print_table(all_tasks) else: if unfinished_tasks: self.print_table(unfinished_tasks) else: print('All tasks have been completed!') def check_task(self, args): index = args.task tasks = self.list_all_tasks() if index <= 0 or index > len(tasks): print(f'Task number ({index}) does not exist!') return tasks[index - 1]['done'] = True with open(self.file_name, 'w') as file: for task in tasks: self.add_task(Namespace(**task)) def remove_task(self, args): tasks = self.list_alltasks() if args.task: index = args.task else: index = len(tasks) - 1 if index <= 0 or index > len(tasks): print(f'Task number ({index}) does not exist!') return tasks.pop(index - 1) with open(self.file_name, 'w') as file: for task in tasks: self.add_task(Namespace(**task)) def reset_task(self): with open(self.file_name, 'w') as file: file.write('') print('All tasks have been deleted!')
  6. يمكن اتباع الخطوات التالية لحل المشكلة: 1- لحل مشكلة [!] Android Studio (version 2022.1) ✗ Unable to find bundled Java version التي ظهرت في flutter doctor. أولاً السبب يعود إلى إصدار تحديثات لـ Flutter و Android Studio بشكل منتظم ، وتحديثات برمجية أخرى غير متوافقة يمكن أن تسبب مشاكل. تم توثيق هذه المشكلة في رابط المشكلة الحالية في Github: https://github.com/flutter/flutter/issues/118502. والحل البديل المؤقت هو إنشاء اختصار (symlink) لمجلد JRE الذي يأتي مع Android Studio. ويوضح الموضوع الآخر في Github (https://github.com/flutter/flutter/issues/106674) أنه تم إصدار تغيير معيب ، ولم يتم تضمينه بعد في الإصدار الثابت الحالي ، لذلك يجب استخدام حل المؤقت إلى حين تحديث Android Studio كالتالي: mklink /J "C:\Program Files\Android\Android Studio\jre" "C:\Program Files\Android\Android Studio\jbr" هذا الأمر يقوم بإنشاء رابط رمزي بإسم "jre" في مسار "C:\Program Files\Android\Android Studio" يشير إلى المجلد "jbr". يمكن تغيير المسار حسب مسار تثبيت برنامج Android Studio على جهاز الكمبيوتر الخاص بك. 2- إذا استمرت المشكلة قم بالتالي: التأكد من تثبيت Java Development Kit (JDK) بشكل صحيح وإضافتها إلى المتغيرات البيئية PATH، ولتجنب مشاكل java مع flutter يجب عليك تثبيت الإصدار Java 11. 2- تحديث Gradle إلى الإصدار الأحدث، يمكن القيام بذلك بتشغيل الأمر التالي: flutter upgrade --force 3- حذف مجلد .gradle الخاص بالمشروع وإعادة بناءه. يمكن القيام بذلك بتشغيل الأمر التالي: cd android: هذا الأمر يتيح لنا التنقل إلى مجلد android في مشروع Flutter الذي نعمل عليه. gradlew clean: هذا الأمر يستخدم لحذف أي ملفات مؤقتة أو ملفات بناء سابقة في مشروع Android. تمامًا كما تقوم بتنظيف الفضاء الخاص بالمشروع قبل إنشاء مشروع جديد في Android Studio. cd ..: هذا الأمر يسمح لنا بالعودة إلى الدليل الأعلى من مجلد android الذي قمنا بالتنقل إليه في الخطوة الأولى. flutter run: هذا الأمر يتيح لنا تشغيل تطبيق Flutter الخاص بنا. عند تنفيذ هذا الأمر، سيتم تشغيل تطبيق Flutter الخاص بك وتحميله على الهاتف المحمول أو المحاكي الذي يتم استخدامه في تطوير التطبيقات. cd android gradlew clean cd .. flutter run 4- ربما يوجد خطأ مع إصدار Gradle الحالي الذي يعمل عليه المشروع، يمكن تغيير الإصدار إلى إصدار أقدم أو أحدث بتحديث ملف android/build.gradle. يجب تغيير الإصدار في كل من build.gradle و gradle-wrapper.properties: buildscript { repositories { google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:4.1.0' // تغيير هذا الرقم إلى الإصدار المطلوب } } ... dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation 'com.android.support:multidex:1.0.3' } ... distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip // تغيير هذا الرقم إلى الإصدار المطلوب 5- بعد التعديل، قم بحفظ الملفات وإعادة بناء التطبيق بتشغيل الأمر التالي: flutter run
  7. إذا كانت المشكلة ليست في ذلك، ربما تكون المشكلة في اسم العرض الذي تحاولي الاستدعاء منه الـ autocomplete. يتعين عليك التحقق من الاسم الصحيح لعرض الـ autocomplete الخاص بالمركز والذي يجب استخدامه في تعريف URLconf لتوجيه الطلبات إليه. بالإضافة إلى ذلك، تأكدي من تضمين مسار URL الصحيح لـ autocomplete في ملفات تعريف URLconf الخاصة بتطبيق Django الخاص بك. يجب أن يحتوي هذا المسار على اسم العرض الصحيح وعلى وظيفة العرض التي ستعيد البيانات المطلوبة لـ autocomplete. على سبيل المثال، إذا كان اسم العرض الخاص بالـ autocomplete هو "center-autocomplete"، فإن المسار الخاص به في ملف URLconf يجب أن يكون مشابهًا للتالي: path('center-autocomplete/', views.CenterAutocomplete.as_view(), name='center-autocomplete'), وبعد ذلك، يمكنك استدعاء الـ autocomplete عن طريق تمرير اسم العرض الصحيح إلى الوسم الخاص بـ autocomplete في ملف HTML الخاص بك. على سبيل المثال: {% url 'center-autocomplete' %} هذا ينبغي أن يعيد اسم العرض الصحيح للـ autocomplete والذي يمكن استخدامه لإجراء طلبات autocomplete بشكل صحيح.
  8. إذا أردت إنشاء slider مماثل للصورة في سؤالك، يمكنك استخدام الكود التالي مه شرح التفاصيل الخاصة به. أولاً ، سنبدأ بإنشاء هيكل HTML للمتزلج. يجب علينا إنشاء عناصر HTML لكل شريحة من الشرائح وتجميعها داخل العنصر الرئيسي الذي سيحتوي على جميع الشرائح. سنستخدم عنصر div لتقسيم الصفحة إلى عناصر أصغر. الهيكل الأساسي للشريحة يجب أن يكون على هذا النحو: <div class="slider"> <div class="slide active"> <img src="image1.jpg" alt="Slide 1"> </div> <div class="slide"> <img src="image2.jpg" alt="Slide 2"> </div> <div class="slide"> <img src="image3.jpg" alt="Slide 3"> </div> <button class="prev-btn">Prev</button> <button class="next-btn">Next</button> </div> يجب علينا إنشاء عناصر div داخل عنصر الشريحة. العنصر الأول هو الصورة التي سيتم عرضها في الشريحة. يجب أن يكون لدينا أيضًا عنصر آخر يحتوي على عناصر نصية مثل العنوان والوصف. يمكنك تخصيص هذه العناصر بشكل كامل وفقًا لتصميمك. الآن ، يجب علينا استخدام CSS لتصميم الشرائح وإظهارها بشكل جيد. يمكننا استخدام position و display و z-index لإظهار الشرائح في المكان المناسب على الصفحة. .slider { position: relative; width: 100%; height: 500px; overflow: hidden; } .slide { position: absolute; width: 100%; height: 100%; opacity: 0; transition: opacity 0.5s ease-in-out; } .slide.active { opacity: 1; } .slide img { width: 100%; height: 100%; object-fit: cover; } .prev-btn, .next-btn { position: absolute; top: 50%; transform: translateY(-50%); width: 50px; height: 50px; background-color: #000; color: #fff; border: none; cursor: pointer; } .prev-btn { left: 20px; } .next-btn { right: 20px; } تم تعيين position: relative على العنصر الرئيسي للمتزلج لأننا سنستخدم position: absolute على العناصر الفرعية لتحديد مكانها. تم تعيين العرض والارتفاع على العنصر الرئيسي للتحكم في حجم المتزلج على الصفحة. تم تعيين position: absolute و top: 0 و left: 0 على الشرائح لأننا نريد عرضها في المكان الصحيح في المتزلج. تم تعيين opacity إلى 0 لكي يتم إخفاء جميع الشرائح غير النشطة. تم تعيين transition على opacity لإضافة تأثير تحويل عند تغيير الشريحة. تم تعيين z-index إلى -1 لجعل جميع الشرائح مخفية خلف العنصر النشط. عندما تصبح الشريحة نشطة ، يتم تعيين z-index إلى 1 لجعلها تظهر فوق الشرائح الأخرى. تم تعيين object-fit: cover على الصورة لجعلها تملأ المساحة المتاحة بالشريحة بشكل كامل. تم تعيين position: absolute و bottom: 0 و left: 0 و width: 100٪ على العنصر النصي لجعله يظهر في الجزء السفلي من الشريحة. تم تعيين خصائص النص (font-size و margin) لتخصيص النص وفقًا لتصميمك. أخيرًا ، سنستخدم JavaScript لتغيير الشريحة النشطة بعد فترة زمنية معينة. const slides = document.querySelectorAll('.slide'); const prevBtn = document.querySelector('.prev-btn'); const nextBtn = document.querySelector('.next-btn'); let currentSlide = 0; // Show the first slide slides[currentSlide].classList.add('active'); function prevSlide() { slides[currentSlide].classList.remove('active'); currentSlide = (currentSlide - 1 + slides.length) % slides.length; slides[currentSlide].classList.add('active'); } function nextSlide() { slides[currentSlide].classList.remove('active'); currentSlide = (currentSlide + 1) % slides.length; slides[currentSlide].classList.add('active'); } prevBtn.addEventListener('click', prevSlide); nextBtn.addEventListener('click', nextSlide); كود JavaScript، يقوم بتحديد الشرائح (slides) وأزرار التحكم (previous و next)، ثم يعطي الوظيفة (function) للزر السابق (previous) والتالي (next) للتحكم في الشرائح. في البداية، يتم تحديد الشرائح عن طريق استخدام document.querySelectorAll()، الذي يبحث عن جميع العناصر التي تحتوي على الكلاس (class) المعطى، في هذه الحالة هو .slide، ويتم حفظها في متغير slides باستخدام const. ثم يتم تحديد الأزرار عن طريق استخدام document.querySelector()، الذي يبحث عن أول عنصر يحتوي على الكلاس المعطى، في هذه الحالة هم .prev-btn و .next-btn، ويتم حفظهما في متغيرات prevBtn و nextBtn باستخدام const. ثم يتم تعيين الوظيفة (function) لكل زر بواسطة .addEventListener()، الذي يقوم بتحديد الحدث (event) الذي يتم الاستماع إليه، في هذه الحالة هو click، والوظيفة التي يتم تشغيلها عند حدوث هذا الحدث. لتحديد الشريحة الحالية وإظهارها، يتم تعيين متغير currentSlide إلى القيمة 0، ويتم إظهار الشريحة الأولى باستخدام .classList.add() وإضافة الكلاس active. لتبديل الشرائح بواسطة الأزرار، يتم إنشاء وظائف (functions) prevSlide() و nextSlide() التي تزيل الكلاس active من الشريحة الحالية وتحديد الشريحة التي ستظهر، بحيث يتم تطبيق العملية الحسابية (currentSlide - 1 + slides.length) % slides.length للحصول على الشريح
  9. لا يمكن استخدام النقطة في اسم المتغير في HTML. عادةً ما تستخدم النقطة للوصول إلى الخصائص أو الأساليب في Python. وبما أنه يتم استخدام النقطة "." للوصول إلى الخصائص في Python، فإن استخدامها في Django templates يؤدي إلى حدوث خطأ. لحل هذا المشكلة، يمكن استخدام قوسين مربعين [] brackets بدلاً من النقطة للوصول إلى قيمة مفتاح القاموس في Django template. يجب تحديد المفتاح الصحيح في القوسين المربعين. على سبيل المثال، إذا كان المفتاح المستخدم في النموذج هو "center_name"، يمكن استخدام الأمر التالي لاستدعاءه في قالب HTML: {{ appointment['center_name'] }} يمكن تغيير "center_name" إلى المفتاح الصحيح الذي تستخدمه في نموذج Django الخاص بك.
  10. يمكن لمستخدمي SQL Server الاتصال في نفس الوقت عن طريق واجهات الإدخال بشكل متزامن، والحد الأقصى لعدد المستخدمين المسموح لهم بالاتصال في الوقت نفسه يعتمد على عدة عوامل، مثل: 1- نوع الإصدار: يختلف الحد الأقصى لعدد المستخدمين المسموح لهم بالاتصال في الوقت نفسه حسب إصدار SQL Server. على سبيل المثال ، يمكن لإصدار SQL Server Express السماح بحد أقصى لـ 10 مستخدمين متزامنين ، بينما يمكن لإصدار SQL Server Enterprise السماح بعدد 32,767. يعني هذا أن SQL Server يسمح بأقصى عدد من الاتصالات المتزامنة للمستخدمين بقيمة 32,767 في الإصدارات القياسية والمعتادة من SQL Server. وهذا يشمل إصدارات SQL Server Standard وWeb وExpress وDeveloper. 2- الاستخدام المتوقع: يعتمد الحد الأقصى لعدد المستخدمين المسموح لهم بالاتصال في الوقت نفسه على الاستخدام المتوقع للنظام. إذا كان يتوقع استخدام النظام من قبل عدد كبير من المستخدمين المتزامنين ، فسيتم زيادة الحد الأقصى لعدد المستخدمين. نظرًا لأن عدد اتصالات المستخدمين هي خيار ديناميكي (يتكون ذاتيًا) دون تدخل منك، يقوم SQL Server بضبط الحد الأقصى لعدد اتصالات المستخدمين تلقائيًا حسب الحاجة، حتى الوصول للحد الأقصى المسموح به. على سبيل المثال ، إذا كان هناك 10 مستخدمين مسجلين الدخول فقط ، يتم تخصيص 10 كائنات اتصال مستخدم. في معظم الحالات، لا يتعين عليك تغيير قيمة هذا الخيار. القيمة الافتراضية هي 0 ، مما يعني أن الحد الأقصى (32،767) من اتصالات المستخدمين مسموح به. 3- قدرة الخادم: يمكن لقدرة الخادم أن تؤثر على الحد الأقصى لعدد المستخدمين المسموح لهم بالاتصال في الوقت نفسه. إذا كان لديك خادم بمواصفات عالية وذاكرة ومعالج قوية ، فسيتمكن الخادم من معالجة مزيد من الاتصالات المتزامنة. ومن المهم ملاحظة أن هذا الحد الأقصى هو لعدد الاتصالات المتزامنة فقط، ولا يشمل عدد المستخدمين الفعليين أو عدد الاستفسارات التي يقومون بها. وبما أن هذا العدد يعتمد على عدة عوامل، مثل حجم الذاكرة وسرعة المعالج وحجم قاعدة البيانات وحجم الاتصالات وغيرها من العوامل الفنية والأدائية، فإنه من المهم تقييم الموارد المتاحة واحتياجات النظام وحمولة العمل لتحديد الحد الأقصى الفعلي لعدد المستخدمين المتزامنين في الإصدار المستخدم من SQL Server. ولا يمكن تجاوز هذا الحد الأقصى لعدد المستخدمين في SQL Server. إذا تجاوزت الحد الأقصى لعدد الاتصالات المتزامنة، فسوف تتلقى رسالة خطأ ولن تتمكن من الاتصال حتى يتوفر اتصال آخر. ولكن هناك حلول بديلة للسماح لمزيد من المستخدمين بالإتصال. حيث يمكنك تثبيت المزيد من النسخ instances في الخادم. وكل نسخة تدعم SQL Server 32,767 اتصالًا، ويمكن تشغيل 50 نسخة لكل عقدة node، لذا يصبج الحد الأقصى لعدد اتصالات العميل لكل عقدة هو 32767 * 50. ويمكن أيضًا استخدام عدة خوادم SQL مرتبطة في ترتيب معين لتحديد عدد الاتصالات (حسب القسم أو الموقع) واستخدام تكرار المزامنة (MERGE replication) للحفاظ على جميع النسخ محدثة.
  11. عفوًا أخي أيمن، هذا النمط يبحث عن أي رقم يتكرر في أي مكان في الصفحة وليس فقط بجوار بعضهم البعض. يبدأ النمط بفتح الحدود \b ويحدد الرقم (\d) الذي نريد البحث عنه. ثم يستخدم (?:(?!\1)\d)+ لتحديد أي مجموعة من الأرقام التي لا يتم تكرار الرقم الأول بها. يستخدم (?!\1) للتأكد من أن الرقم الحالي لا يتطابق مع الرقم الذي تم العثور عليه في البداية (\1). وأخيرًا ، يتم استخدام \b مرة أخرى للحدود والتأكد من أن الرقم الأخير هو نفس الرقم الذي تم العثور عليه في البداية. \b(\d)(?:(?!\1)\d)+\1\b
  12. للبحث عن الأرقام المتكررة مرتين باستخدام regex ، يمكن استخدام النمط التالي: (\d)\1 هذا النمط يبحث عن أي رقم يتكرر مرتين بجوار بعضهم البعض. يتم استخدام الفاصلة العكسية \1 للإشارة إلى أننا نبحث عن نفس الرقم الذي تم العثور عليه في الفراغ السابق. للبحث عن الأرقام المتكررة ثلاث مرات باستخدام regex ، يمكن استخدام النمط التالي: (\d)\1\1 هذا النمط يبحث عن أي رقم يتكرر ثلاث مرات بجوار بعضهم البعض. يتم استخدام الفاصلة العكسية \1 مرتين للإشارة إلى أننا نبحث عن نفس الرقم الذي تم العثور عليه في الفراغين السابقين. ويمكنك استخدام الأداة التالية لكتابة ما تريده بالإنجليزية وسيتم تحويله إلى regex https://www.autoregex.xyz/
  13. الفرق بين console.log(hh.charAt(1)) و console.log(hh(4)) يتمثل في أن الأول يستخدم دالة charAt() لاسترداد حرف محدد في السلسلة، بينما الثاني يستخدم الدالة hh() التي لا توجد في لغة جافاسكريبت وسيتم رفضها من قبل المترجم عند تشغيل الكود إلا إذا قمت بكتابة تلك الدالة بنفسك أنت داخل ملف الكود الخاص بك حيث ستمرر لها القيمة 4. الدالة charAt() هي دالة جاهزة في جافاسكريبت تستخدم لاسترداد حرف محدد في السلسلة. وتأخذ هذه الدالة مؤشرًا على الفهرس الذي يتم استرداد الحرف منه كمعامل. في هذه الحالة ، يتم استخدام الفهرس 1 كمعامل ، مما يعني أن الحرف الثاني في السلسلة سيتم استرداده وكما تعلم الحرف الأول يمكن استخراجه من خلال كتابة 0 وليس 1. على الجانب الآخر ، لا يوجد دالة اسمها hh() في جافاسكريبت ، ولذلك سيقوم المترجم بإرجاع خطأ يفيد بعدم وجود الدالة. قد يكون هناك خطأ في تشغيل الكود الذي يستخدم هذه الدالة أو قد يتم استخدام دالة مخصصة بنفس الاسم من قبل المستخدم كما شرحت لك منذ قليل. بشكل عام ، من المهم فهم أن تفاصيل الدوال في جافاسكريبت تلعب دورًا هامًا في كيفية تنفيذ البرنامج. ولذلك ، يجب على المستخدمين التأكد من استخدام الدوال الصحيحة وفهم كيفية استخدامها بشكل صحيح لتجنب الأخطاء والأخطاء في البرامج. وهناك طريقة أخرى لاستخراج حرف من نص في جافاسكريبت بدون دالة في جافاسكريبت ، يمكن الوصول إلى حرف محدد في الكلمة باستخدام مؤشر الفهرس. على سبيل المثال ، إذا كانت الكلمة "Hello" ، يمكن استخدام word[0] لاسترداد حرف "H" الأول في الكلمة، علمًا بأن word هي اسم المتغير الذي قيمته 'Hello' ويتم ترقيم حروف الكلمة في جافاسكريبت بدءًا من الصفر كما أشرت. https://wiki.hsoub.com/JavaScript/String
  14. الخطأ الذي ظهر يشير إلى أن Gradle لم يتمكن من العثور على ملفات البناء اللازمة لبناء التطبيق Flutter الخاص بك في المسار المحدد C:\Users\aama6. ويعني ذلك أنه يفترض وجود ملفات settings.gradle و build.gradle في المسار المحدد. يحدث هذا في العادة عندما تقوم بتشغيل الأمر flutter run أو flutter build من داخل مجلد لا يحتوي على ملفات Gradle المطلوبة. لحل هذه المشكلة ، يمكنك اتباع الخطوات التالية: إذا لم تكن قد أنشأت مشروع Flutter جديدًا بعد ، فقد تحتاج إلى تشغيل الأمر flutter create لإنشاء ملفات البناء. قد يكون قد تم تشغيل أمر البناء من مجلد خاطئ. يجب عليك التأكد من أنك تشغل الأمر من داخل مجلد يحتوي على ملفات البناء اللازمة لتطبيق Flutter. تحقق من أنك تقوم بتشغيل الأمر flutter run أو flutter build من داخل مجلد يحتوي على ملفات البناء الخاصة بتطبيق Flutter. تحقق من أنه لديك ملف settings.gradle و / أو build.gradle في مجلد التطبيق. إذا كانت هذه الملفات مفقودة ، فأنت بحاجة إلى إنشاءها. إذا كنتي تعتقدي أنك قمت بترتيب ملفات البناء بشكل صحيح، فيمكن أن يكون هناك خطأ في Gradle. جرب تشغيل الأمر مرة أخرى مع إضافة --stacktrace للحصول على تقرير عن الخطأ الذي يتسبب في فشل البناء. يمكن أيضًا أن يكون هناك خطأ في ملفات Flutter الخاصة بك. جرب تشغيل الأمر flutter doctor للتحقق من أن كل شيء في حالة جيدة وأن Flutter مثبت بشكل صحيح على جهاز الكمبيوتر الخاص بك. قد يكون هناك مشكلة في إعدادات بيئة التطوير الخاصة بك. يجب عليك التأكد من أن Gradle مثبت بشكل صحيح ويمكن العثور عليه في مسار النظام الخاص بك. ويمكنك إلقاء نظرة على النقاشات التالية والنظر للحلول المقدمة.
  15. المشكلة أن الكود الخاص بك يعتمد على الحالة العامة isSelected في المكون الأساسي App.js للتحقق مما إذا كان المقعد المختار يجب أن يتغير إلى الحالة المحددة أم لا. وعند النقر على أي مقعد، تم تغيير الحالة العامة isSelected في App.js، مما يؤدي إلى تحديث كافة المقاعد في الصف بناءً على الحالة العامة الجديدة، وليس المقعد الذي تم النقر عليه فقط. لتجنب هذه المشكلة، تم تعديل الكود بالأسفل لإنشاء حالة جديدة في كل مكون فرعي Row.js للتحقق من ما إذا كان المقعد المختار يجب أن يتغير إلى الحالة المحددة أم لا، وبالتالي يمكن تحديث حالة مقعد واحد دون تحديث كافة المقاعد في الصف. يمكنك إضافة خاصية isSelected إلى عنصر النقر في مكانه لتحديد حالته، ثم استخدامها في تعيين الكلاس المناسب لهذا العنصر فقط. يمكن تحقيق ذلك من خلال تغيير الدالة handleClick في App.js على النحو التالي: const handleClick = (index) => { setSelectedIndex(index) } ثم في Row.js، يمكن تحديث الكلاس المستخدم بناءً على قيمة isSelected المستقبلة من الأب: function Row({id,isSelected,handleClick,selectedIndex}) { return ( <div className='row'> { [...Array(8)].map((_,index)=>( <div className={ (id===1 && index===3) || (id===1 && index===4) || (id===2 && index===6) || (id===2 && index===7) || (id===4 && index===3) || (id===4 && index===4) || (id===5 && index===4) || (id===5 && index===5) || (id===5 && index===6) ? 'seat occupied' : selectedIndex === index ? 'seat selected' : 'seat' } key={index} onClick={() => handleClick(index)} > <div></div> </div> )) } </div> ) }
  16. بالإضافة إلى ما ذكره عبد الباسط، هناك العديد من الكتب والموارد المتاحة على الإنترنت لتعلم PHP للمبتدئين، وأكثرها شيوعًا هو الكتاب الرسمي للغة PHP والذي يتم تحديثه باستمرار. يمكن الحصول على الكتاب الرسمي للغة PHP من خلال الموقع الرسمي للغة PHP على الإنترنت على العنوان التالي: http://www.php.net/manual/en/ كما يمكن الوصول إلى موقع W3Schools المتخصص في تعليم البرمجة والذي يوفر دروسًا وتمارين على PHP، ويمكن الوصول إليه على العنوان التالي: https://www.w3schools.com/php/ وإذا كنت ترغب في الحصول على كتاب مجاني لتعلم PHP للمبتدئين، يمكنك البحث عن كتب مفتوحة المصدر على الإنترنت مثل: "PHP: The Right Way" بقلم Josh Lockhart "PHP 7 Programming Cookbook" بقلم Doug Bierer "PHP 7: Real World Application Development" بقلم Chandan Kumar تذكر أن البحث على الإنترنت عن الموارد المجانية والكتب لتعلم PHP يمكن أن يكون مفيدًا، ولكن يجب أن تحرص على التحقق من مصدر المعلومات وجودتها قبل الاعتماد عليها. ولكن يجب الإنتباه إلى أنك تريد تعلم PHP 8 وليس PHP 7 . حيث يوجد فروق كبيرة بين PHP 7 و PHP 8، فلقد قامت الشركة المطورة للغة بإجراء تحسينات كبيرة وإضافة ميزات جديدة في الإصدار الأحدث. من بين أبرز التحسينات والميزات الجديدة في PHP 8: JIT (Just In Time) Compiler: وهي تقنية تتيح لمحرك PHP تحويل الكود إلى لغة الآلة عند التشغيل مباشرة مما يحسن من أداء اللغة بشكل كبير. Union Types: تتيح هذه الميزة تعريف نوعين أو أكثر من البيانات لنفس المتغير. Named Arguments: تتيح هذه الميزة تمرير الوسائط باستخدام اسم الوسيط بدلاً من الترتيب العادي. Attributes: تتيح هذه الميزة إضافة معلومات إضافية إلى الشفرة المصدرية. بالإضافة إلى ذلك، تم تحسين ميزات أخرى وتم تحسين أداء اللغة بشكل عام في PHP 8.
  17. لا يلزم تثبيت Python على جهاز الكمبيوتر إذا كان الهدف هو فقط فتح وتحرير ملف Python. ولكن إذا كنت تريد تشغيل وتنفيذ البرامج المكتوبة بلغة Python، فيجب تثبيت Python على الجهاز. يمكنك اتباع الخطوات التالية لفتح ملف Python والبدء في إنشاء صفحة ويب باستخدام إطار Django: تثبيت Python و Django: يجب تثبيت Python على جهاز الكمبيوتر الخاص بك. يمكن العثور على إصدار Python المناسب لنظام التشغيل الخاص بك على الموقع الرسمي للغة Python. بعد تثبيت Python، يجب تثبيت إطار Django باستخدام pip، وهو أداة إدارة حزم Python. يمكن تثبيت Django بالأمر التالي في سطر الأوامر command prompts: pip install django إنشاء مشروع Django جديد: يجب بدء العمل على مشروع Django جديد باستخدام الأمر التالي في سطر الأوامر: django-admin startproject myproject حيث myproject هو اسم المشروع الذي تريد إنشائه. إنشاء تطبيق Django جديد: بعد إنشاء المشروع، يجب إنشاء تطبيق Django جديد باستخدام الأمر التالي في سطر الأوامر: python manage.py startapp myapp حيث myapp هو اسم التطبيق الذي تريد إنشائه. إنشاء الملفات اللازمة لصفحة ويب: يمكنك الآن إنشاء الملفات اللازمة لصفحة ويب. على سبيل المثال، يمكن إنشاء ملف urls.py الذي يحتوي على الرابط المراد إنشاؤه وملف views.py الذي يحتوي على الدالة التي يتم استدعاؤها عند النقر على الرابط. فتح ملف Python والبدء في الكتابة: بعد إنشاء الملفات اللازمة، يمكنك فتح ملف Python باستخدام أي محرر Python مفضل لديك، مثل VScode أو Sublime Text أو PyCharm، والبدء في الكتابة. يمكن العثور على الأكواد المختلفة المتعلقة بإطار Django على الإنترنت، ويمكنك استخدامها للمساعدة في إنشاء صفحة ويب مخصصة باستخدام إطار Django.
  18. Rescript هي لغة برمجة جديدة وعالية الأداء تم إنشاؤها لتسهيل عملية كتابة البرامج وتحسين أدائها. تشبه Rescript لغة Typescript بالنسبة لمبادئ الكتابة، حيث تفرض بعض القيود على البرمجة بلغة الجافاسكريبت، والتي يمكن للكود الذي تم كتابته بهذه اللغة أن يتم تحويله إلى جافاسكريبت. تتميز Rescript بسرعة أداءها وقدرتها على تحسين أداء الكود المكتوب بها. كما أن لها نظام كتابة قوي يتيح للمبرمجين إمكانية كتابة التعليمات البرمجية بشكل أسرع وأكثر دقة. تختلف Rescript عن Typescript في بعض النواحي، حيث تغطي Typescript مجموعة كبيرة من ميزات جافاسكريبت، بينما تغطي Rescript فقط مجموعة منسقة منها. كما أن Rescript لا تسمح بحدوث أخطاء null/undefined، بينما يتعامل Typescript مع هذه الأخطاء. هذه بعض الأمثلة البسيطة للتعامل مع الأنواع في ReScript: لنفترض أن لدينا مصفوفة من الأرقام الصحيحة التي نريد أن نضيف إليها قيمة واحدة: let myArray = [|1, 2, 3|]; myArray->Array.map(x => x + 1); في هذا المثال ، نحن نستخدم عامل التدفق (|]) لإنشاء مصفوفة من الأرقام الصحيحة. ثم نستخدم دالة Array.map () لتحويل كل عنصر في المصفوفة إلى عنصر جديد يتم احتسابه بإضافة واحد إلى القيمة الحالية. هنا مثال آخر يستخدم السجلات: type person = { name: string, age: int, }; let myPerson = {name: "John Doe", age: 30}; let updatedPerson = {...myPerson, age: myPerson.age + 1}; في هذا المثال ، نحن نستخدم الكلمة الرئيسية "type" لتعريف نوع السجل "person" ، الذي يحتوي على اسم وعمر. ثم ننشئ متغير "myPerson" من نوع "person". بعد ذلك ، ننشئ متغيرًا آخر "updatedPerson" بتحديث قيمة "age" بإضافة واحد إلى القيمة الحالية. هذا مماثل لإعادة تعيين خاصية "age" في TypeScript. هذه بعض الأمثلة البسيطة لإظهار بعض التفاصيل حول كيفية عمل ReScript. يمكنك العثور على المزيد من الأمثلة والتفاصيل في الوثائق الرسمية لـ ReScript.
  19. لا داعي للذعر، الأمر بسيط عند فهم الطريقة وفهم الكود الذي يمكنك من تنفيذ ذلك، ففي البداية يجب عليك تقسيم المشكلة التي لديك إلى أجزاء وبدء العمل عليها تباعًا حتي تصلي لحل المشكلة، فلا تنظري أبدًا لمشكلة برمجية بكاملها بل قسميها إلى أجزاء. يمكن استخدام nested for loop في لغة السي++ لرسم الأشكال المختلفة. لهذا الغرض، يتم استخدام loop داخلي لتحديد الصفوف والأعمدة وloop خارجي لتحديد عدد الصفوف. في nested for loop ، يتم تضمين for loop داخل for loop آخر. يستخدم الـ for loop الخارجي لتكرار مرة أخرى داخليًا. بمعنى آخر، يتم تنفيذ الـ for loop الداخلي بأكمله مرة واحدة لكل تكرار من الـ for loop الخارجي. على سبيل المثال، إذا أردتي رسم مثلث، يمكن استخدام nested for loop كالتالي: #include <iostream> using namespace std; int main() { int rows = 7; for (int i = 1; i <= rows; ++i) { for (int j = 1; j <= i; ++j) { cout << "*"; } cout << endl; } return 0; } تم تعيين عدد الصفوف في هذا المثال إلى 7 باستخدام المتغير rows. يتم استخدام الـ loop الخارجي لتكرار العملية الداخلية بعدد الصفوف المحدد. الـ loop الداخلي يتحكم في عدد الأعمدة. في هذا المثال، يتم استخدام loop داخلي للتحكم في عدد النجوم المطلوب طباعتها في كل صف. إذا أردتي رسم مثلث مقلوب، يمكن تغيير اتجاه الطباعة بتغيير ترتيب الـ loop الداخلي والخارجي كالتالي: #include <iostream> using namespace std; int main() { int rows = 7; for (int i = rows; i >= 1; --i) { for (int j = 1; j <= i; ++j) { cout << "*"; } cout << endl; } return 0; } هذا المثال يستخدم الـ loop الخارجي للعد من الصفوف الأعلى إلى الأسفل، والـ loop الداخلي للعد من الأعمدة من الأعلى إلى الأسفل في كل صف. يمكن استخدام هذا النمط في الكثير من الرسومات الأخرى، ويمكن تعديل الشروط والمتغيرات المستخدمة في الـ loops للحصول على تأثيرات مختلفة. بالنسبة للأشكال المعقدة الفكرة تكمن في تقسيم الشكل إلى عدة أجزاء أصغر، واستخدام nested loops لرسم كل جزء من هذه الأجزاء. على سبيل المثال، إذا كنت تريد رسم شكل معقد يشبه شجرة، فيمكنك استخدام nested loops لرسم الشجرة كما يلي: 1- الجذع: يمكنك استخدام nested loop لرسم الجذع، حيث يتكون الجذع من عدة خطوط رأسية، يمكن رسمها باستخدام الدالة cout. 2- الأوراق: يمكنك استخدام nested loops آخر لرسم الأوراق، حيث يمكن استخدام loop خارجي لرسم الصفوف الأفقية للأوراق، وloop داخلي لرسم الأوراق في كل صف. يمكن استخدام الدالة cout لطباعة الرموز المستخدمة في الرسم، مثل "*" أو "-" أو "/" وغيرها. هذا مثال بسيط لرسم شجرة باستخدام nested loops في C++: #include <iostream> using namespace std; int main() { int height = 5; // Draw the trunk for(int i=1; i<=height; i++) { for(int j=1; j<=height-i; j++) { cout << " "; } for(int k=1; k<=2*i-1; k++) { cout << "*"; } cout << endl; } // Draw the leaves for(int i=1; i<=2; i++) { for(int j=1; j<=height-2; j++) { cout << " "; } cout << "***" << endl; } return 0; } يمكنك تعديل الأرقام المستخدمة في الدوال الداخلية للـ loop والرموز المستخدمة في الدالة cout للحصول على شكل مختلف للشجرة.
  20. بالنسبة للفكرة فقد شرحها لك أحمد وهي بسيطة، فهناك العديد من الأدوات المماثلة التي تؤدي نفس الغرض. مثل: https://haikei.app/ https://www.shapedivider.app/ وبالنسبة لتصميم الصورة التي قمت بإرفاقها يتم باستخدام HTML و CSS و JavaScript. يمكن استخدام العناصر الأساسية في HTML مثل divs و spans والاحتفاظ بها في مكان محدد على الصفحة باستخدام CSS. يمكنك استخدام grid و flexbox للحصول على التنسيق المطلوب كما في الصورة. إذا كنت بحاجة إلى مساعدة في البدء، يمكنك الاستعانة بمكتبات CSS الجاهزة مثل Bootstrap أو Materialize، والتي توفر العديد من الأدوات والنماذج الجاهزة التي يمكن استخدامها كأساس لتصميمك الخاص. وإليك مثال لاستخدام الأدوات التي تولد صور الـ SVG كما في التصميم وهما الـ Blob و الـ Wave. والكود يعتمد على أنك ستقوم بتحميل صور الـ SVG ووضعها في ملفات المشروع، وبإمكانك أيضًا استخدام كود SVG الذي توفره الأدوات بدلاً من تحميل الصورة حيث يتم وضعها داخل index.html في الجزء المراد عرضها به. <div class="background"> <div class="waves"></div> <div class="content"> <h1>عنوان التسجيل</h1> <button>الاشتراك</button> </div> </div> .background { background-image: url('blob-background.png'); height: 500px; position: relative; } .waves { background-image: url('wave.png'); background-repeat: repeat-x; height: 150px; position: absolute; bottom: 0; width: 100%; } .content { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; color: white; } h1 { font-size: 40px; margin-bottom: 30px; } button { background-color: #d4af37; border: none; color: white; padding: 15px 32px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; cursor: pointer; } يمكنك استخدام مواقع مثل https://www.freepik.com/ https://www.drawkit.com/ https://www.flaticon.com/ للحصول على الصور المطلوبة أو صور مشابهة لها.
  21. بالنسبة للمصادر فهناك العديد منها على يوتيوب، ولكن سأشرح لك كيفية البحث عما تريده. البحث عن مصدر موثوق: يجب عليك التأكد من مصدر المعلومات ومدى مصداقيته وجودة المحتوى، لذلك يفضل البحث في المصادر المعتمدة والموثوقة مثل YouTube و Udemy وغيرها من المواقع الشهيرة والمعروفة. استخدام كلمات البحث الصحيحة: يجب استخدام كلمات البحث الصحيحة للعثور على الفيديوهات المناسبة. على سبيل المثال، إذا كنت تريد تعليم شخص ما كيفية كتابة كود برمجي باستخدام Node.js، يمكنك استخدام "Node.js tutorial" ككلمة بحث أولية. التحقق من التعليقات والتقييمات: يمكنك قراءة التعليقات والتقييمات على الفيديوهات التعليمية لمعرفة ما إذا كانت مفيدة أم لا، وإذا كانت تحظى بتقييمات إيجابية من المستخدمين. التحقق من تاريخ الفيديو: يجب التأكد من أن تاريخ الفيديو حديث ومحدث، لأن تغييرات الإصدارات الجديدة قد تؤثر على كيفية كتابة الشفرة. اختيار الفيديو الصحيح: بعد البحث عن الفيديوهات المتاحة، يجب اختيار الفيديو الذي يتناسب مع مستوى الشخص المراد تعليمه والذي يشرح الخطوات بطريقة سهلة وواضحة. يمكن البحث في يوتيوب عن الفيديوهات التعليمية التي تشرح كيفية استخدام Node.js للاتصال بقاعدة البيانات SQLite واستخدامها لاستقبال إدخالات المستخدم وحفظها في القاعدة. يمكن استخدام عبارات البحث التالية: Node.js SQLite tutorial Node.js SQLite database tutorial Node.js SQLite input from user tutorial Node.js SQLite insert data tutorial وأنصحك بقراءة النقاش على السؤال التالي
  22. بالتأكيد يمكنك النجاح في البرمجة والعمل في هذا المجال، حتى لو لم تدرس في كلية الحاسوب أو تكنولوجيا المعلومات. لكن يجب أن تكون مستعدًا للاستمرار في تعلم البرمجة وتطوير مهاراتك باستمرار، لأن هذا المجال دائم التغيير والتطور، ويتطلب البحث والتعلم المستمر. وفي النهاية، يتطلب النجاح في البرمجة العمل الجاد والاهتمام بالتفاصيل والقدرة على حل المشاكل والتحديات التي قد تواجهك في العمل. بعد اكتساب الأساسيات في Python، يمكنك البدء في تعلم مفاهيم ومكتبات جديدة في اللغة، ومن ثم تطبيقها في مشاريع أكبر وأكثر تحديًا. لكن أنصحك وبشدة بتحديد المجال الذي تريده تعلمه والتخصص في البرمجة، هل هو تطوير مواقع الويب؟ أم تطبيقات الهاتف؟ وهكذا. وبعد تحديد المجال، يجب إلقاء نظرة على السوق المحلي لديك ومعرفة المهارات المطلوبة للمجال الذي تريده، بالنسبة للويب مثلاً هل المطلوب بكثرة لوظيفة junior هو إطار عمل React أم Angular وهل المطلوب بكثرة لغة مثل PHP؟ ونفس الأمر بالنسبة لمواقع العمل الحر إذا كنت تريد العمل كمستقل، يجب معرفة ما هي المهارات الأكثر طلبًا بالنسبة لمجال معين في البرمجة، من خلال تصفح الوظائف. بعد ذلك يمكنك البحث عن مصادر تعلم جديدة عبر الإنترنت، وفي المحتوى العربي لديك دورات أكاديمية حسوب في مختلف مجالات البرمجة. وأنصحك بقراءة النقاش المثمر التالي على سؤال مماثل. https://io.hsoub.com/webdev/143736-من-الصفر-الى-الاحتراف
  23. يتمثل الفرق الرئيسي بين Domain و Hosting في الوظائف التي يؤديانها والأغراض التي تستخدم فيها. الإستضافة خدمة تخزين وعرض المحتوى الإلكتروني على الإنترنت وتتمثل الخدمات التي تقدمها شركات الإستضافة في توفير مساحة تخزين على الخوادم الخاصة بها، وتوفير اتصال سريع بالإنترنت للوصول إلى المحتوى المخزن، وتوفير خدمة دعم فني للمستخدمين. أما بالنسبة لـ Domain فهو عنوان الموقع الإلكتروني الذي يتم استخدامه للوصول إلى الموقع على شبكة الإنترنت، ويتم شراء النطاق من شركات خاصة مثل GoDaddy، و Namecheap، وغيرها، ويتم تسجيل اسم النطاق بالإضافة إلى تعيين سجلات DNS للنطاق لإعادة توجيه الزوار إلى الخوادم التي تتحمل المسؤولية عن استضافة المحتوى. بشكل عام، يمكن اعتبار الإستضافة هي المكان الذي يتم فيه تخزين المحتوى، والنطاق هو العنوان الذي يستخدم للوصول إلى المحتوى المخزن على الإستضافة، وبالتالي يتم استخدام الإستضافة والنطاق معًا لإطلاق وعرض المواقع على الإنترنت. وبشكل أبسط في الأساس، الإستضافة والنطاق هما عبارة عن خدمتين تسمح للمواقع بالظهور على الإنترنت. يمكن أن تفكر في الإستضافة كـ "المكان" الذي يتم فيه حفظ الموقع على الإنترنت، حيث يتم تخزين ملفات الموقع (الصور والفيديو والصفحات وغيرها) على خوادم الإستضافة ويمكن للزوار الوصول إليها عن طريق الإنترنت. أما النطاق، فيمكن اعتباره كـ "عنوان الموقع"، حيث يتم استخدامه للوصول إلى الموقع على الإنترنت، على النحو التي نستخدمه في الحياة الواقعية عندما نسأل عن عنوان منزل أو مكتب. يتم شراء النطاق من شركات خاصة، ويمكن اختيار أي عنوان يريده المستخدم (طالما أنه غير مأخوذ بالفعل)، ومن ثم يتم توجيه النطاق إلى خوادم الإستضافة، حيث يتم عرض الموقع على الإنترنت. يتم تسجيل اسم النطاق بالإضافة إلى تعيين سجلات DNS للنطاق لإعادة توجيه الزوار إلى الخوادم التي تتحمل المسؤولية عن استضافة المحتوى. أي يمكن اعتبار الإستضافة والنطاق كـ "الأدوات" اللازمة لإطلاق وعرض المواقع على الإنترنت، ويمكن اختيار شركات مختلفة للإستضافة وشركات أخرى لشراء النطاقات، بناءً على احتياجات المستخدم وميزانيته.
  24. ربما قد اكون لم استوعب سؤالك بشكل صحيح في البداية، الأفضل لك هو تثبيت bootstrap من خلال الأمر التالي npm install bootstrap أو استخدامه عبر CDN من خلال وضع الروابط التالية بداخل عنصر head في ملف index.html <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script> بالنسبة لـ Popperjs هناك رابط CDN أيضًا والأفضل وضعه قبل رابط bootstrap داخل ملف index.html <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js" integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p" crossorigin="anonymous"></script> أو تثبيته من خلال npm npm i @popperjs/core
  25. للعمل محليًا يمكنك ذلك في 6 شهور دراسة مكثفة بمعدل 10 ساعات يوميًا، وربما تحتاج سنة. بينما العمل في الخارج يتطلب سنوات خبرة على أقل تقدير سنتان. بمعنى أنك طوال السنتان كنت تتعلم وتعمل على مشاريع واكتسبت الخبرة اللازمة، وأصبحت بمستوى Mid-level Developer ومن الممكن أن تصل إلى ذلك في 3 سنوات، تبعًا للوقت الذي تخصصه ومجهودك وتركيزك وخلفيتك السابقة عن البرمجة أو التقنية بشكل عام.
×
×
  • أضف...