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

كل الأنشطة

تحدث تلقائيًا

  1. الساعة الماضية
  2. في تحليل الأداء لنماذج الانحدار Regression Models، هناك عدة مقاييس بجانب متوسط مربع الخطأ Mean Squared Error - MSE لتقييم جودة النموذج. كل مقياس له مزاياه وعيوبه ويعتمد اختيار المقياس المناسب على السياق المحدد والتحليل المطلوب، مثلاً، MAPE غير مناسب في حال هناك قيم قريبة من الصفر في البيانات، حيث يؤدي ذلك إلى قيم غير معقولة. و RMSE و MAE يقدمان معلومات عن حجم الخطأ، لكن RMSE يعطي وزنًا أكبر للأخطاء الكبيرة بسبب التربيع، بالتالي مفيد في حال كانت الأخطاء الكبيرة غير مقبولة في مشروعك. ولو كانت الأخطاء تتبع توزيعًا طبيعيًا، فإن MSE و RMSE يكونا أكثر ملاءمة. أما إن كنت تهتم بالأخطاء النسبية أكثر من الأخطاء المطلقة، إذن MAPE أو MSLE أكثر ملاءمة. إليك كل مقياس: 1- Mean Absolute Error - MAE أو متوسط الخطأ المطلق: [ MAE = \frac{1}{n} \sum_{i=1}^n |y_i - \hat{y}_i| ] حيث ( y_i ) هو القيمة الحقيقية و ( \hat{y}_i ) هو التنبؤ من النموذج، ويقدم MAE فكرة عن حجم الخطأ المتوقع في التنبؤات. 2- جذر متوسط مربع الخطأ أو Root Mean Squared Error - RMSE: [ RMSE = \sqrt{\frac{1}{n} \sum_{i=1}^n (y_i - \hat{y}_i)^2} ] يعبر RMSE عن نفس المعلومات الموجودة في MSE ولكن في نفس وحدة القيم الأصلية مما يسهل فهمه في بعض الأحيان. 3- معامل التحديد (R-squared - (R^2)): [ R^2 = 1 - \frac{\sum_{i=1}^n (y_i - \hat{y}i)^2}{\sum{i=1}^n (y_i - \bar{y})^2} ] حيث ( \bar{y} ) هو المتوسط الحسابي للقيم الحقيقية. يعبر ( R^2 ) عن نسبة التباين في البيانات التي يمكن تفسيرها بواسطة النموذج، وقيمته تتراوح بين 0 و 1. 4- Mean Absolute Percentage Error - MAPE أو متوسط النسبة المطلقة للخطأ: [ MAPE = \frac{1}{n} \sum_{i=1}^n \left| \frac{y_i - \hat{y}_i}{y_i} \right| \times 100 ] يعطي MAPE فكرة عن حجم الخطأ الكلي كنسبة مئوية من القيم الحقيقية، وهو مفيد عند الرغبة في فهم الخطأ النسبي بدلاً من الخطأ المطلق. 5- متوسط اللوغاريتم المربع للخطأ Mean Squared Logarithmic Error - MSLE: [ MSLE = \frac{1}{n} \sum_{i=1}^n \left( \log(1 + y_i) - \log(1 + \hat{y}_i) \right)^2 ] يستخدم MSLE عندما تكون القيم الحقيقية والتنبؤات قد تأخذ قيمًا صغيرة جدًا أو كبيرة، ويعطي وزنًا أكبر للأخطاء النسبية الصغيرة. 6- إحصائية AIC (Akaike Information Criterion) و BIC (Bayesian Information Criterion): [ \text{AIC} = 2k - 2\ln(L) ] [ \text{BIC} = \ln(n)k - 2\ln(L) ] ( k ) هو عدد المعاملات في النموذج و ( L ) هو دالة الاحتمال الماكسيمالي للنموذج، وتلك الإحصائيات تأخذ في الاعتبار جودة النموذج وعدد المعاملات، ما يساعد في تجنب الإفراط في التكييف overfitting.
  3. أكيد هناك مقاييس أخرى يمكن استخدامها لتقييم النموذج بشكل أفضل حسب السياق والهدف من النموذج: متوسط الخطأ المطلق (Mean Absolute Error - MAE): يقيس هذا المقياس متوسط قيمة الفروق المطلقة بين القيم المتوقعة والقيم الفعلية. يعتبر MAE أقل تأثرا بالقيم الشاذة مقارنة بـ MSE. جذر متوسط مربع الأخطاء (Root Mean Squared Error - RMSE): هو الجذر التربيعي لمتوسط مربع الأخطاء، وهو يعطي نفس وحدة القياس للبيانات الأصلية. متوسط النسبة المئوية للخطأ المطلق (Mean Absolute Percentage Error - MAPE): يقيس هذا المقياس نسبة الخطأ المطلق إلى القيم الفعلية، ويعبر عنه كنسبة مئوية. معامل التحديد (Coefficient of Determination - R²): يقيس مدى تناسب النموذج مع البيانات. تتراوح قيمته بين 0 و 1، حيث تشير القيمة الأقرب إلى 1 إلى نموذج أفضل. لتحديد أي مقياس هو الأفضل للاستخدام، يعتمد ذلك على طبيعة البيانات والهدف من النموذج، حيث إذا كنت تحتاج إلى مقياس يتعامل بشكل جيد مع القيم الشاذة، يمكن أن يكون MAE أو MAPE أفضل من MSE، بينما إذا كان لديك اهتمام بالوحدات الأصلية للبيانات، فإن RMSE يمكن أن يكون أكثر ملائمة، أما إذا كنت تبحث عن فهم نسبة التباين المفسر بواسطة النموذج، فإن R² سيكون الخيار الأنسب. و يمكنك أن تطلع أكثر على الموضوع من خلال هذه الأسئلة:
  4. السلام عليكم في الReagression بيقيم الموذج بمعادل ال MSE فا كانت عاوز اعرف لها فيه معادله احسن من كده وازي اعرف ان فيها والا الا؟
  5. اليوم
  6. فعلان احنا بنقسم البيانات بيانات لتدريب وبيانات لاختبار حتي بنكون مقسم جدا علي kaggle بس تعلم العميق عكس كده صح يعني مع نزيدا اليبانات بيكون كويس جدا والعكس صحيح شكراا لحضرتكم جدا
  7. بدايةً، تحتاج إلى إنشاء قاعدة بيانات لتخزين معلومات القوالب، وليكن كالتالي: CREATE TABLE templates ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL, header TEXT, footer TEXT, content TEXT ); ولتتمكن من قراءة ملفات XML، تتوفر مكتبة SimpleXML المدمجة في PHP. فتقوم بقراءة ملف XML: function readXMLTemplate($filePath) { if (file_exists($filePath)) { $xml = simplexml_load_file($filePath); $template = [ 'header' => (string) $xml->header, 'footer' => (string) $xml->footer, 'content' => (string) $xml->content ]; return $template; } else { throw new Exception("File not found: $filePath"); } } وكتابة ملف XML: function writeXMLTemplate($filePath, $template) { $xml = new SimpleXMLElement('<template/>'); $xml->addChild('header', $template['header']); $xml->addChild('footer', $template['footer']); $xml->addChild('content', $template['content']); $xml->asXML($filePath); } بعد ذلك إنشاء وظائف لإضافة وتعديل القوالب في قاعدة البيانات. إضافة قالب: function addTemplate($name, $header, $footer, $content) { $conn = new mysqli('localhost', 'username', 'password', 'database'); $stmt = $conn->prepare("INSERT INTO templates (name, header, footer, content) VALUES (?, ?, ?, ?)"); $stmt->bind_param("ssss", $name, $header, $footer, $content); $stmt->execute(); $stmt->close(); $conn->close(); } تعديل قالب: function updateTemplate($id, $name, $header, $footer, $content) { $conn = new mysqli('localhost', 'username', 'password', 'database'); $stmt = $conn->prepare("UPDATE templates SET name = ?, header = ?, footer = ?, content = ? WHERE id = ?"); $stmt->bind_param("ssssi", $name, $header, $footer, $content, $id); $stmt->execute(); $stmt->close(); $conn->close(); } وباستطاعتك إنشاء واجهة مستخدم باستخدام HTML وPHP لإدارة القوالب من قبل المسؤول عن الموقع، مثل صفحة لعرض القوالب وصفحة لتعديلها. صفحة عرض القوالب: <?php $conn = new mysqli('localhost', 'username', 'password', 'database'); $result = $conn->query("SELECT * FROM templates"); ?> <!DOCTYPE html> <html> <head> <title>Manage Templates</title> </head> <body> <h1>Templates</h1> <ul> <?php while ($row = $result->fetch_assoc()): ?> <li> <a href="edit_template.php?id=<?php echo $row['id']; ?>"><?php echo $row['name']; ?></a> </li> <?php endwhile; ?> </ul> </body> </html> صفحة تعديل القالب: <?php $id = $_GET['id']; $conn = new mysqli('localhost', 'username', 'password', 'database'); $stmt = $conn->prepare("SELECT * FROM templates WHERE id = ?"); $stmt->bind_param("i", $id); $stmt->execute(); $result = $stmt->get_result(); $template = $result->fetch_assoc(); ?> <!DOCTYPE html> <html> <head> <title>Edit Template</title> </head> <body> <h1>Edit Template</h1> <form action="update_template.php" method="post"> <input type="hidden" name="id" value="<?php echo $template['id']; ?>"> <label>Name:</label> <input type="text" name="name" value="<?php echo $template['name']; ?>"><br> <label>Header:</label><br><textarea name="header"><?php echo $template['header']; ?></textarea><br> <label>Footer:</label><br><textarea name="footer
  8. لإتقان الأساسيات في البرمجة، يجب عليك أولا اختيار لغة برمجة واحدة للتركيز عليها، مثل Python أو JavaScript، لأنهما تعتبران من أسهل اللغات للمبتدئين، ثم تبدأ بتعلم المفاهيم الأساسية مثل المتغيرات (variables)، الحلقات (loops)، الشروط (conditionals)، والدوال (functions) وهذا الأمر سيساعدك على بناء أساس قوي. يمكنك أن تهمّ بقراءة وفهم أمثلة من الأكواد البرمجية المكتوبة بلغة البرمجة التي اخترتها، ثم كتابة أكواد برمجية مثل البرامج التي تنفذ عمليات حسابية بسيطة أو تلك التي تتعامل مع النصوص والبيانات وحاول دائما حل المشاكل البرمجية البسيطة في البداية، مثل تلك التي تتطلب منك حساب الأعداد الفردية أو الزوجية أو التحقق من صلاحية بيانات معينة. تذكر دائما، أنه من الضروري ممارسة البرمجة بانتظام من خلال أن تجعل لنفسك تحديات يومية أو أسبوعية مع تصفح وقراءة الأكواد المفتوحة المصدر على منصات مثل GitHub فيمكن تعطيك فكرة عن كيفية هيكلة البرامج الكبيرة وكتابة كود نظيف وفعال.
  9. حجم البيانات بلا شك له أهمية كبيرة، ولا يمكن حصرها، لكن مع ذلك صحيح، يمكن أن يؤثر وجود كمية كبيرة من البيانات سلبا على نماذج تعلم الآلة بسبب زيادة التعقيد الحسابي، وطول وقت التدريب مع صعوبة إدارة جودة البيانات، وتعقيد النماذج التي تعمل عليها، يمكنك تصفح هذه المقالة:
  10. الاستمرارية هي الحل، فإتقان الأساسيات يتطلب التزاما يوميا بالتعلم والممارسة، وعلى الأقل في حالة ما تعثرنا ولم نستمر يجب أن لا نوسّع الفوّهة وأن نعود لسكة التعلم في أقرب وقت، ومن الأفضل البدء بفهم عميق للمفاهيم الأساسية ثم الانتقال إلى التطبيق العملي من خلال مشاريع صغيرة. كما أن المراجعة الدورية للمواد التي تعلمتها تساعد في ترسيخ المعلومات. فالتعلم المستمر والممارسة الدائمة هما المفتاح لإتقان أي مهارة. يمكنك البحث عن المشاريع الصغيرة التي يمكنك العمل عليها لتطبيق ما تتعلمه، وقم بمراجعة ما تعلمته بانتظام يمكنك طرح أي سؤال أو استفسار أو صعوبة واجهتك أثناء التعلم في أسفل كل درس في صندوق التعليقات. بالنسبة للتمارين فالدروس نفسها فيها كمية من المسائل والتمارين والمشاريع الصغيرة والكبيرة التي ستساعد كثيرا في ترسيخ المفاهيم. والأكاديمية وفرت دليلا خاصا بتعلم البرمجة أنصحك بتصفحه ودراسته.
  11. نعم، يمكن أن يكون للبيانات الكبيرة تأثير سلبي على نماذج تعلم الآلة في بعض الأحيان. عند التعامل مع مجموعات بيانات ضخمة، يمكن أن تواجه عدة تحديات تتعلق بالقدرات الحاسوبية، وقت التدريب، وتعقيد النموذج. حقيقةـ صحيح يمكن أن تتجاوز البيانات الكبيرة قدرة الأجهزة الحاسوبية المتاحة فتدريب النماذج على بيانات ضخمة يتطلب ذاكرة كبيرة ومعالجات قوية وفي حال ما إذا كانت الموارد الحاسوبية محدودة، قد تواجه صعوبة في تحميل البيانات ومعالجتها بشكل فعال، مما يؤدي إلى بطء في الأداء أو حتى فشل عملية التدريب. لهذا قد تحتاج إلى تقنيات خاصة للتعامل مع هذه البيانات، مثل التجزئة أو التحليل الموزع، لتحسين الكفاءة. وقت التدريب هو الآخر يمكن أن يزداد بشكل كبير عند التعامل مع مجموعات بيانات كبيرة لأن تدريب نموذج تعلم الآلة على بيانات ضخمة يستغرق وقتا أطول بطبيعة الحال، مما يمكن أن يكون مشكلة إذا كنت بحاجة إلى نتائج سريعة أو تعمل في بيئة حيث الزمن عامل حاسم. للتغلب على ذلك، يمكن استخدام تقنيات مثل التعلم التدريجي أو النماذج الأولية للتدريب بشكل أسرع على أجزاء من البيانات قبل تدريب النموذج النهائي على المجموعة الكاملة. كما أنه يمكن أن يؤدي استخدام البيانات الكبيرة إلى تعقيد النموذج بشكل زائد فمع تزايد حجم البيانات، قد يتزايد أيضا عدد الميزات والأنماط التي يحتاج النموذج إلى تعلمهه وهذا ما قد يجعل النموذج أكثر تعقيدا وأقل قدرة على التعميم، مما يزيد من خطر التعلم الزائد حيث يتعلم النموذج تفاصيل غير ضرورية أو ضوضاء في البيانات لهذا فمن الضروري استخدام تقنيات مثل تنظيم النموذج أو التحقق المتقاطع لضمان أن النموذج يبقى قادرا على التعميم ويعمل بشكل جيد على البيانات الجديدة. وبينما يمكن للبيانات الكبيرة أن تكون مصدر قوة للنماذج، إلا أنها تتطلب إدارة دقيقة وموارد مناسبة للتأكد من أنها تساهم بشكل إيجابي في تحسين أداء النموذج بدلا من أن تكون عبئا.
  12. وعليكم السلام، على العموم، كلما كان لدينا بيانات أكثر كلما كان ذلك أحسن. حتى إذا كنا لن نستخدم معظم البيانات الكثيرة في تدريب النموذج، فسوف نتركها كبيانات اختبار ونستخدمها للتحقق من جودة تعلمه. لكن يجب عدم إغفال نقطة مهمة وهي توازن البيانات (Data balance)، أي أن البيانات يجب أن تكون موزعة بشكل شبه متساوي على مجال الاحتمالات الممكنة، إذا لم يكن ذلك هو الحال، فقد نقع في خطأ في تقدير جودة النموذج. فمثلا، لو كانت لدينا بيانات حول العمليات البنكية، بحيث أن 97% من العمليات قانونية و 3% فقط غير قانونية، فإذا قمنا بتدريب نموذج لاكتشاف العمليات غير القانونية، وكان هذا النموذج يجيب في كل الأحوال بأن العملية قانونية، فهنا النموذج سوف يكون صحيحا في 97% من الحالات، لكن في الواقع، هذا النموذج لا يقوم بفعل شيء! في هذه الأحوال، لا ينفع تكثير البيانات مع الاستمرار على هذا الحال، فلو كانت عندنا الملايين من هذه البيانات، وكانت دائما النسبة 97%-3%، فسوف نحصل على نفس الخطأ. إحدى الحلول في مثل هذه الحالة هي تقليل البيانات الزائدة حتى تصبح النسب متكافئة. فيمكن التقليل من البيانات التي تمثل العمليات القانونية حتى تصبح نسبتها إلى المجموع 50% فقط. وعندها يمكننا أن ندرب النموذج بشكل متوازن، بحيث تكون نصف البيانات التي رآها قانونية ونصفها الآخر عكس ذلك، وعندئذ سوف يتعلم بشكل صحيح.
  13. السلام عليكم هل لو البيانات كثير ممكن انها تثار سالب علي نماذج تعلم الاله ؟
  14. النصائح العامة لإتقان أساسيات البرمجة: التطبيق عبر كتابة الكود عند مشاهدة كل درس وعم الاكتفاء أبدا بالمشاهدة، فلا توجد معلومة يمكن أن تثبت بدون تطبيق. عدم نسخ الأكواد أو تحميل أكواد جاهزة عندما يكون الشخص مبتدئا، فهذا لا يساعد في التعلم مطلقا. بل يجب أن يقوم الطالب بكتابة الأكواد بنفسه. محاولة حل المشاكل التي يقع فيها الطالب بنفسه قبل طلب المساعدة، وحتى بعد الحصول على المساعدة، فيفترض بالطالب أن يفهم أين كان خطؤه، ولماذا يعمل التصحيح الذي اقترحه المدرب المساعد، وإذا لم يستطع، فيفترض أن يسأل المدرب المساعد ما الفرق بين حله وبين محاولة الطالب، حتى يستطيع التعلم بشكل صحيح. محاولة عدم استنساخ ما كتبه المدرس بشكل مطابق، بل يفترض أن يحاول الطالب التغيير قليلا على ما يكتبه المدرب ورؤية ما الذي يحصل عند التغيير. هذا سيوقع الطالب في أخطاء لا محالة، لكن الوقوع في الأخطاء وتصحيحها لاحقا هو من أحد أهم الطرق في التعلم. أما بالنسبة للتمارين، فعادة ما تكون مضمنة في نهاية الدرس أو أثنائه. ففي كثير من الأحيان يسأل المدرب سؤالا قبل أن يجيب عليه، فعندها يمكنك إيقاف الفيديو والتفكير والمحاولة فيه قبل مشاهدة الحل. كما يمكنك طلب المزيد من التمارين في قسم التعليقات الموجود أسفل كل درس، وسوف يقوم المدربون المساعدون باقتراح تمارين ومساعدتك في حلها. يمكنك الإطلاع على الأجوبة الموجودة هنا، لأن هذا السؤال متكرر وقد تمت الإجابة عليه من طرف مدربين آخرين عدة مرات، منها هنا:
  15. ما هي نصيحتك لي لإتقان الأساسيات وأين أجد تمارين لذلك
  16. البارحة
  17. السلام عليكوم ورحمة الله و بركاته من منا لا يعرف سكربت المنتديات الشهير vBulletin فانا بعد الانتهاء من برمجة سكربت متجر قلت ليه ماضيف نظام القوالب مثلة فانا اوريد ان اضيف صفحة في لوحة التحكم يوجد بها بعض القوالب و يمكن التعديل على الاكواد الخاصة بها بحيث ينقر المستخدم على تعديل source و ينتقل إلى صفحة يوجد بها حقول تحتوي على الاكواد مجزئة مثل الهيدر و الفوتر إلخ.. و يمكنة رفع قالب من جهازه و يتم تخزين محتويات القالب في قاعدة بيانات My SQL مثل اسم القالب و اكواد القالب إلخ..ا و بمعنا اصح اوريد برمجة نظام يشبة نظام قوالب بلوجر إلى حد قريب...
  18. @Mustafa Suleiman شكرا لك على الاجابة انا عندي مشروع يحتوى على الاف الصور اعتقد انه هذه الطريقة ستحتاج وقتا طويلا للبحث واستخراج الصور المشاببة
  19. أرجو النزول أسفل الفيديو لنهاية الصفحة وستجد صندوق تعليقات كما هنا.
  20. حسنا انا لا اجد زرا يسمح لي بسوال تحت الفديو هل اقتبس وارس اسال ام ابلغ ؟
  21. لا عليك تستطيع التعليق أسفل الفيديو وترك السؤال الحالي كما هو تستطيع تعديله وليس حذفه فلا داعي لأيهما.
  22. ستجد أسفل فيديو الدرس في نهاية الصفحة صندوق تعليقات كما هنا، أرجو طرح الأسئلة أسفل الدرس وليس هنا في قسم الأسئلة البرمجة حيث نطرح الأسئلة العامة الغير متعلقة بمحتوى الدورة أو الدرس وذلك لمساعدتك بشكل أفضل
  23. كيف افتح متصفح كروم لان كل ما أحاول افتح متصفح من البرنامج لأحصل على Output يفتح لي متصفح اخر
  24. نتحدث في هذا المقال عن مفهومي البرمجة المتزامنة synchronous وغير المتزامنة asynchronous، وفوائد استخدام التقنيات غير المتزامنة، كما نتحدث بإيجاز عن المشاكل التي تعلّقت تاريخيًا بتنفيذ الدوال غير المتزامنة في جافا سكريبت. تُعرّف البرمجة غير المتزامنة أنها تقنية تسمح لبرامجك بتنفيذ مهام مطوّلة تأخذ وقتًا طويلًا لتنفيذها، لكنها تبقى مع ذلك قادرة على الاستجابة للأحداث التي تقع أثناء تنفيذ هذه المهمة، بدلًا من الانتظار حتى تنتهي بالكامل. وستظهر نتيجة الاستجابة للحدث بمجرد انتهاء المهمة اﻷساسية وعرض نتيجة التنفيذ. على سبيل المثال معظم الدوّال المضمّنة في المتصفحات قد تستغرق وقتًا لذلك فهي تنفذ بطريقة غير متزامنة، نذكر منها على سبيل المثال: ()fetch: تستخدم لإحضار الموارد باستخدام طلبات HTTP. ()getUserMedia: تستخدم للوصول إلى كاميرا أو ميكروفون المستخدم. ()showOpenFilePicke: تستخدم لتطلب من المستخدم اختيار ملف. وقد لا تضطر كثيرًا لاستخدام دوال غير متزامنة خاصة بك، لكن إن احتجت إلى ذلك، لا بد من معرفة الطريقة الصحيحة لتنفيذها. سنبدأ هذا المقال بالنظر إلى ما تسببه الدوال المتزامنة التي تستغرق وقتًا طويلًا لتنفيذها، وضرورة استخدام البرمجة غير المتزامنة في هذه الحالات. البرمجة المتزامنة لنتأمل الشيفرة التالية: const name = "Muhammd"; const greeting = `Hello, my name is ${name}!`; console.log(greeting); // "Hello, my name is Muhammd!" في هذه الشيفرة: name: يصرّح عن نص. greeting: يصرّح عن نص آخر يستخدم المتغير name. تطبع الشيفرة بعد ذلك رسالة الترحيب على الطرفية. ينتقل المتصفح سطرًا سطرًا في الشيفرة السابقة وينفذها بهذا الترتيب. وينتظر المتصفح نهاية تنفيذ السطر اﻷول حتى ينتقل إلى السطر التالي، فكل سطر يعتمد على السطر الذي يسبقه. ندعو هذا البرنامج برنامجًا متزامنًا synchronous program، وسيبقى متزامنًا حتى لو استخدمنا دالة منفصلة كما في المثال التالي: function makeGreeting(name) { return `Hello, my name is ${name}!`; } const name = "Muhammd"; const greeting = makeGreeting(name); console.log(greeting); // "Hello, my name is Muhammd!" فالدالة ()makeGreating هي دالة متزامنة، لأن مُستدعيها سينتظر حتى تنهي الدالة عملها وتعيد القيمة المطلوبة ثم يستأنف تنفيذ الشيفرة البرمجية. دالة متزامنة تستغرق وقتًا في التنفيذ ماذا لو استغرقت الدالة المتزامنة وقتًا طويلًا في التنفيذ؟ سنعرض تاليًا برنامجًا يعتمد على خوارزمية ضعيفة وغير مجدية لتوليد أعداد أولية عندما ينقر المستخدم على زر "توليد أعداد أولية Generating Primes". وكلما كبر عدد اﻷعداد الأولية الذي يحدده المستخدم ستستغرق الدالة وقتًا أكبر ﻹيجاد النتيجة. إليك شيفرة HTML: <label for="quota">Number of primes:</label> <input type="text" id="quota" name="quota" value="1000000" /> <button id="generate">Generate primes</button> <button id="reload">Reload</button> <div id="output"></div> وشيفرة جافا سكريبت: const MAX_PRIME = 1000000; function isPrime(n) { for (let i = 2; i <= Math.sqrt(n); i++) { if (n % i === 0) { return false; } } return n > 1; } const random = (max) => Math.floor(Math.random() * max); function generatePrimes(quota) { const primes = []; while (primes.length < quota) { const candidate = random(MAX_PRIME); if (isPrime(candidate)) { primes.push(candidate); } } return primes; } const quota = document.querySelector("#quota"); const output = document.querySelector("#output"); document.querySelector("#generate").addEventListener("click", () => { const primes = generatePrimes(quota.value); output.textContent = `Finished generating ${quota.value} primes!`; }); document.querySelector("#reload").addEventListener("click", () => { document.location.reload(); }); وستكون نتيجة التنفيذ كالتالي: See the Pen frame_a_long-running_synchronous_function by Hsoub Academy (@HsoubAcademy) on CodePen. جرّب أن تنقر على الزر "Generate primes"، ستلاحظ أن الحاسوب سيتأخر عدة ثوان (وفقًا لسرعة حاسوبك) قبل أن يعرض رسالة الانتهاء "!Finished". مشاكل الدوال المتزامنة تشبه شيفرة المثال التالي ما تنفذه شيفرة المثال السابق باستثناء وجود مربع نص لتكتب فيه. جرّب أن تنقر اﻵن على الزر "Generate primes" ثم حاول أن تكتب مباشرةً شيئًا ما في مربع النص. ما ستلاحظه أن البرنامج سيفقد تجاوبه طالما أن الدالة ()generatePrimes قيد التنفيذ ولن تتمكن من الكتابة في مربع النص أو أن تنقر في أي مكان أو تفعل أي شيء. See the Pen Untitled by Hsoub Academy (@HsoubAcademy) on CodePen. يعود السبب في ذلك إلى أن برنامج جافا سكريبت ذو خيط معالجة وحيد single-threaded. وخيط المعالجة هو سلسلة من التعليمات يتبعها البرنامج. ولأن البرنامج وحيد الخيط، سينفذ التعليمات واحدة تلو اﻷخرى. لهذا استغرقت الدالة المتزامنة السابقة وقتًا حتى تعيد قيمتها وكان علينا الانتظار حتى تنتهي. وما نحتاجه عادة في برنامجنا طريقة لتنفيذ اﻵتي: البدء بتنفيذ مهمة طويلة باستدعاء دالتها. أن تكون الدالة قادرة على تنفيذ مهمتها والانتهاء مباشرة، حتى يبقى البرنامج متجاوبًا مع بقية اﻷحداث. أن تنفّذ الدالة مهامها دون أن تعيق خيط المعالجة الرئيسي، كأن تبدأ مثلًا خيط معالجة جديد. إبلاغنا بنتيجة عملياتها عندما تنتهي. هذه النقاط ما تقدمه بالفعل الدوال غير المتزامنة، وسنتابع في هذا المقال شرح كيفية إنجاز هذه الدوال في جافا سكريبت. معالجات اﻷحداث Event Handlers قد يذكرك شرحنا للداول غير المتزامنة بمعالجات اﻷحداث وستكون محقًا في ذلك. فمعالجات الأحداث هي نوع من البرمجة غير المتزامنة، إذ تزوّدنا بدالة (معالج الحدث) لن تُستدعى مباشرة بل بمجرّد وقوع الحدث الذي نترصّده. فإن كان الحدث هو إنهاء دالة غير المتزامنة لمهمتها، فقد يُستخدم حدث اﻹنهاء لتنبيه المستدعي بنتيجة استدعاء هذه الدالة. وقد استخدمت بعض الواجهات البرمجية غير المتزامنة في البدايات هذا اﻷسلوب، نذكر منها الواجهة البرمجية XMLHttpRequest التي تمكنك من إرسال طلبات HTTP إلى خادم واستقبالها باستخدام جافا سكريبت. فهذه العمليات قد تستغرق وقتًا، لهذا فهي غير المتزامنة. وتتلقى من خلال هذه الواجهة تنبيهًا عن تقدم الطلب وانتهائه عن طريق ربط مترصد أحداث Event Listener إلى الكائن XMLHttpRequest. نعرض في المثال التالي طريقة تنفيذ اﻷمر، فعندما تنقر على الزر "انقر ﻹرسال طلب Click to start request"، سننشئ كائن XMLHttpRequest جديد، ثم نترصد وقوع الحدث loadend (انتهاء التحميل). يطبع بعد ذلك معالج الحدث الرسالة "!Finished" إضافة إلى رمز الحالة Status Code. بعد إضاف معالج الحدث، نرسل الطلب. ولاحظ أنه بعد إرسال الطلب يمكننا طباعة العبارة "Started XHR request" أي يتابع برنامجنا تنفيذ تعليماته في الفترة التي يُعالج فيها الطلب، ثم يُستدعى معالج الحدث عند اكتمال الطلب. إليك شيفرة HTML: <button id="xhr">Click to start request</button> <button id="reload">Reload</button> <pre readonly class="event-log"></pre> وهذه شيفرة جافا سكريبت: const log = document.querySelector(".event-log"); document.querySelector("#xhr").addEventListener("click", () => { log.textContent = ""; const xhr = new XMLHttpRequest(); xhr.addEventListener("loadend", () => { log.textContent = `${log.textContent}Finished with status: ${xhr.status}`; }); xhr.open( "GET", "https://raw.githubusercontent.com/mdn/content/main/files/en-us/_wikihistory.json", ); xhr.send(); log.textContent = `${log.textContent}Started XHR request\n`; }); document.querySelector("#reload").addEventListener("click", () => { log.textContent = ""; document.location.reload(); }); وستكون نتيجة التنفيذ كالتالي: See the Pen frame_event_handlers by Hsoub Academy (@HsoubAcademy) on CodePen. يشبه اﻷمر ما شرحناه في مقال مدخل إلى اﻷحداث في جافا سكريبت، لكن بدل أن يكون الحدث الذي نترصده هو فعل ينفّذه المستخدم مثل النقر على زر، سيكون الحدث تغيّر حالة كائن ما. دوال رد النداء Callbacks تُعد معالجات الأحداث نوعًا خاصًا من دوال رد النداء، ودالة رد النداء هي دالة تُمرر إلى دالة أخرى، لكنها تُستدعى في الوقت المناسب. فدوال رد النداء هي الطريقة الرئيسية التي نُفّذت فيها الدوال غير المتزامنة في جافا سكريبت. لكن قد تصبح الشيفرة التي تعتمد على دوال رد النداء صعبة الفهم وخاصة عندما تستدعي تلك دوال رد النداء دوال رد النداء أخرى. ستواجه هذه الحالة كثيرًا إن احتجت لتنفيذ بعض العمليات المكونة من سلسلة من الدوال غير المتزامنة، إليك مثالًا: function doStep1(init) { return init + 1; } function doStep2(init) { return init + 2; } function doStep3(init) { return init + 3; } function doOperation() { let result = 0; result = doStep1(result); result = doStep2(result); result = doStep3(result); console.log(`result: ${result}`); } doOperation(); لدينا هنا عملية واحدة مقسّمة إلى ثلاث خطوات تتعلق كل واحدة بسابقتها. إذ تضيف الخطوة الأولى 1 إلى الدخل وتضيف الثانية العدد 2 والثالثة تُضيف العدد 3. فلو كان الدخل هو 0 ستكون النتيجة 6 (0+1+2+3). إن هذا البرنامج سهل ومباشر وفق أسلوب البرمجة المتزامنة، لكن إن نفذناه وفق أسلوب دوال رد النداء، سنجد: function doStep1(init, callback) { const result = init + 1; callback(result); } function doStep2(init, callback) { const result = init + 2; callback(result); } function doStep3(init, callback) { const result = init + 3; callback(result); } function doOperation() { doStep1(0, (result1) => { doStep2(result1, (result2) => { doStep3(result2, (result3) => { console.log(`result: ${result3}`); }); }); }); } doOperation(); ولأنه علينا استدعاء دوال رد النداء، ستكون النتيجة دالة ()doOperation متداخلة بشدة، ومن الصعب حينها قراءتها وتنقيحها. يُعرف هذا الأمر باسم "جحيم دوال رد النداء callback hell" أو "هرم الهلاك pyramid of doom" إذ تتخذ الدوال المتداخلة شكلًا هرميًا. وقد يصعب عليك جدًا التعامل مع الأخطاء إن تداخلت دوال رد النداء، إذ يتوجب عليك عندها معالجة الأخطاء في كل مستوىً من مستويات الهرم بدلًا من معالجتها مرة واحدة في قمة الهرم. لهذه اﻷسباب، لا تستخدم معظم الواجهات البرمجية غير المتزامنة دوال رد النداء حاليًا. وبدلًا من ذلك تبنت جافا سكريبت أساسًا جديدًا في البرمجة غير المتزامنة من خلال الوعد promise. وهذا ما سنتعرف عليه بالتفصيل في المقال التالي من السلسلة. ترجمة -وبتصرف- للمقال: Introducing asynchronous JavaScript اقرأ أيضًا المقال السابق: بناء تطبيق كرات مرتدة ملونة باستخدام الكائنات في جافا سكريبت -الجزء الثاني إرسال البيانات واستلامها عبر الشبكة في جافاسكربت البرمجة غير المتزامنة في جافاسكريبت طرق كتابة شيفرات غير متزامنة التنفيذ في Node.js
  25. هل قمتي بتشغيل unity كمسؤول administrator؟ أيضًا في حال كان اسم مجلد المشروع يحتوي على أية حروف خاصة عليك حذفها مثل ) أو - أو ' ، وأيضًا أسماء الملفات في المشروع وعدم استخدام أسماء عربية. أيضًا تأكدي من تثبيت NDK من خلال Unity Hub وتفقد المسار path الخاص به في Unity. وفي حال استمرار المشكلة عليك التعليق أسفل السؤال، وأيضًا مشاركة كامل رسالة الخطأ.
  1. عرض المزيد
×
×
  • أضف...