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

Mustafa Suleiman

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

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

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

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

    403

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

  1. بمنظور عام، أولآً عليك إنشاء فئة أو كلاس أساسي للنظام، باسم SecurityDevice ويتضمن سمات وسلوكيات مشتركة لكل الأجهزة الأمنية. ثم أضف به سمات properties مثل state و location و sensitivity التي تمثل حالة الجهاز وموقعه وحساسيته. ثم إضافة ميثودز مثل activate و deactivate و alert التي تمثل تفعيل وإلغاء تفعيل الجهاز وإرسال تنبيهات. بعد ذلك، عليك إنشاء كلاسات فرعية منه لكل نوع من الأجهزة الأمنية، مثل Camera و Alarm و MotionSensor، أي نقوم بالوراثة من الكلاس الأساسي SecurityDevice. ثم أضف سمات وسلوكيات (ميثودز) إضافية لكل فئة محددة، مثلاً: في كلاس Camera: أضف سمة resolution تمثل دقة الفيديو. Alarm: أضف سمة loudness تمثل شدة الصوت. MotionSensor: أضف سمة sensitivity تمثل حساسية الاستشعار. ثم تطبيق مبدأ الـ Polymorphism أي تعدد الأشكال وهو مفهوم أساسي في البرمجة الموجهة للكائنات (OOP) يسمح لك بتنفيذ نفس السلوك بطرق مختلفة اعتمادًا على نوع الكائن. وذلك عن طريق تجاوز الأساليب Method Overriding في الفئات (الكلاسات) المشتقة Derived Classes. للتوضيح لدينا ثلاث فئات: Camera، Alarm، MotionSensor. كل فئة تمثل نوعًا مختلفًا من الجهاز. Camera: لديها ميثود alert() التي ترسل تنبيهًا يحتوي على صورة من الكاميرا. Alarm: لديها ميثود alert() التي ترسل تنبيهًا يحتوي على صوت عالٍ. MotionSensor: لديها ميثود alert() التي ترسل تنبيهًا يحتوي على إشعار بحركة. سيتم الأمر كالتالي: نحدد فئة أساسية Base Class وهي SecurityDevice. ثم نحدد ميثود alert() في الفئة الأساسية. في كل فئة مشتقة (Camera، Alarm، MotionSensor)، نقوم بتجاوز طريقة alert() لتنفيذ سلوك مختلف. وعند استخدام كائن من نوع SecurityDevice، سيتم تنفيذ طريقة alert() المحددة في الفئة المشتقة التي ينتمي إليها الكائن. مثلاً من خلال بايثون نقوم بالتالي: class Device: def alert(self): print("تنبيه عام") class Camera(Device): def alert(self): print("تنبيه يحتوي على صورة من الكاميرا") class Alarm(Device): def alert(self): print("تنبيه يحتوي على صوت عالٍ") class MotionSensor(Device): def alert(self): print("تنبيه يحتوي على إشعار بحركة") camera = Camera() alarm = Alarm() motion_sensor = MotionSensor() # استخدام تعدد الأشكال camera.alert() alarm.alert() motion_sensor.alert()
  2. عند إنشاء قاعدة بيانات على Render ستحصل على روابط مختلفة للإتصال بها وهما internal للإتصال بقاعدة البيانات من داخل الاستضافة نفسها أي عند نشر المشروع عليها نستخدمه. بينما لو أردنا الإتصال من الخارج والقيام بعمليات التهجير من خلال منفذ الأوامر على نظامك كما تفعل بشكل عادي فنستخدم رابط تحت اسم External. وضعه في ملف .env في متغير باسم: DATABASE_URL = 'الرابط هنا'
  3. سأوضح لك بمثال وحاول تطبيقه على مشروعك، لكن للعلم ستوفر على نفسك الكثير لو تعلمت جافاسكريبت فهي اللغة البرمجية الخاصة بالويب وبدونها لن تتمكن من أن تصبح مطور للواجهة الأمامية Front-End حيث ستقوم ببناء مواقع ثابتة بدون أي تفاعل حقيقي. أولاً عند إنشاء كروت السور في صفحة الرئيسية، أضف سمة data-sura-name لكل كرت، واحفظ فيها اسم السورة. <div class="sura-card" data-sura-name="الفاتحة"> <h2>الفاتحة</h2> <button class="listen-button">استماع</button> </div> بعد ذلك علينا معالجة النقر على زر استماع من خلال جافاسكريبت كالتالي: إضافة حدث onclick لزر استماع في كل كرت. عند النقر، نحصل على اسم السورة من سمة data-sura-name للكرت. نستخدم window.location.href لتحويل المستخدم إلى صفحة القرآن مع تمرير اسم السورة كمعامل في عنوان URL. const listenButtons = document.querySelectorAll('.listen-button'); listenButtons.forEach(button => { button.addEventListener('click', () => { const suraName = button.parentElement.getAttribute('data-sura-name'); window.location.href = `quran.html?sura=${suraName}`; }); }); الآن علينا معالجة اسم السورة في صفحة القرآن من خلال القيام بالتالي بجافاسكريبت أيضًا: استخدم URLSearchParams للحصول على اسم السورة من عنوان URL. حدد اسم السورة في عنصر select باستخدام value. ثم نشغل الصوت تلقائيًا باستخدام JavaScript. const urlParams = new URLSearchParams(window.location.search); const suraName = urlParams.get('sura'); const suraSelect = document.getElementById('sura-select'); suraSelect.value = suraName; // شغل الصوت تلقائيًا من خلال إنشاء دالة خاصة بذلك وتمرير اسم السورة إليها) playAudio(suraName); لاحظ getElementById('sura-select') نحصل من خلالها على العنصر select لتغيير قيمة السورة به. لذا عليك تعديل أسماء الكلاسات بما يتناسب مع كود HTML لديك، بالتالي يجب إمتلاك أساسيات جافاسكريبت على الأقل.
  4. في ملف src\Pages\Dashboard\Users.js قم بكتابة دالة مباشرًة داخل useEffect وذلك غير صحيح، ما نقوم به هو التالي أرجو مراجعته: const getUsers = async () => { try { const response = await axios.get(`${Api.baseURL}/${Api.USERS}`, { headers: { Authorization: `Bearer ${cookie.get('e-commerce')}`, }, }); return response.data; } catch (error) { console.error(error); throw error; } }; useEffect(() => { getUsers(); }, []); نكتب الدالة بالخارج في حال تعود بوعد promise نستخدم async ثم نستدعي تلك الدالة في useEffect ونقوم بتشغيله مرة واحدة من خلال مصفوفة إعتماديات فارغة []
  5. Google Developer عباةر عن برنامج مجاني يقدم مجموعة من الأدوات والموارد لمن يرغبون في إنشاء تطبيقات وخدمات على منصة Google، أي للمطورين. ويوفر التالي: مجموعة واسعة من الأدوات مثل Android Studio، Firebase، Google Cloud Platform، و Google Maps APIs. دروسًا، وثائق، ودورات تدريبية لمساعدة المطورين على تعلم كيفية استخدام أدوات Google. دعمًا تقنيًا للمطورين من خلال المنتديات، وشبكات التواصل الاجتماعي، ووثائق الدعم. فرصًا للمطورين لعرض تطبيقاتهم على متجر Google Play، والحصول على شهادة Google Developer، والمشاركة في برامج Google Developer Groups. بإمكانك الانضمام إلى برنامج Google Developer مجانًا من خلال موقع Google Developer.
  6. أنت تستخدم طريقة المدى الربيعي (IQR) للكشف عن البيانات الشاذة، وهي طريقة مستخدمة بكثرة وفعالة. وهناك طرق مختلفة لما تريده، أولها الفهرس المنطقي Boolean Indexing diabetes = diabetes[(diabetes['Insulin'] >= lower_bound) & (diabetes['Insulin'] <= upper_bound)] سيتم إنشاء مجموعة بيانات جديدة تسمى diabetes تستبعد الصفوف التي تحتوي على قيم "Insulin" شاذة. الطريقة الثانية هي باستخدام طريقة drop: outlier_indices = diabetes[(diabetes['Insulin'] < lower_bound) | (diabetes['Insulin'] > upper_bound)].index diabetes.drop(outlier_indices, inplace=True) ستحذف الصفوف التي تحتوي على قيم شاذة من مجموعة البيانات الأصلية diabetes. الطريقة الثالثة هي من خلال loc: diabetes.loc[~((diabetes['Insulin'] < lower_bound) | (diabetes['Insulin'] > upper_bound)), :] ستنشئ مجموعة بيانات جديدة تحتوي فقط على الصفوف التي لا تحتوي على قيم شاذة.
  7. الـ Outlier عبارة عن قيمة بيانات تقع بعيدًا عن بقية البيانات في مجموعة البيانات. وأحيانًا يكون سببها خطأ في القياس أو بيانات غير متوقعة، وتؤثر على متوسط المجموعة، والانحراف المعياري، والارتباطات. وتستطيع إزالتها أو تحويلها أو استخدام تقنيات إحصائية مقاومة. مثلاً في مجموعة بيانات لدرجات الطلاب، يكون هناك طالب حصل على درجة 95 بينما حصل بقية الطلاب على درجات بين 70 و 85. بينما الـ Extreme Outlier هي قيمة بيانات تقع بعيدًا جدًا عن بقية البيانات في مجموعة البيانات، بشكل أكبر من outlier العادي، وذلك يعرف أيضًا باسم gross error. وغالبًا ما يكون سببها خطأ في القياس أو بيانات غير متوقعة بشكل كبير، وتؤثر بشكل كبير على متوسط المجموعة، والانحراف المعياري، والارتباطات، وتؤثر على تحليل البيانات بشكل كبير مقارنًة بالـ Outlier. ويجب التعامل معها بحذر شديد، فمن الضروري إزالتها أو تحويلها، ولكن يجب التحقق من سبب وجودها أولاً. مثلاً في نفس مجموعة البيانات، هناك طالب حصل على درجة 150 بينما حصل بقية الطلاب على درجات بين 70 و 85.
  8. تحتاج إلى تعديل التالي في ملف settings.gradle في السطر 3: def localProperties = Properties() لتصبح: def localProperties = new Properties() أي بوضع كلمة new. إن لم تجد ما سبق فقم بوضع كلمة new قبل السطر الذي يسبب المشكلة مثلاً كالتالي: if (keystorePropertiesFile.exists()) { keystoreProperties.load( new FileInputStream(keystorePropertiesFile))}
  9. ستجد أسفل فيديو الدرس في نهاية الصفحة صندوق تعليقات كما هنا، أرجو طرح الأسئلة أسفل الدرس وليس هنا في قسم الأسئلة البرمجة حيث نطرح الأسئلة العامة الغير متعلقة بمحتوى الدورة أو الدرس، وذلك لمساعدتك بشكل أفضل.
  10. ستجد أسفل فيديو الدرس في نهاية الصفحة صندوق تعليقات كما هنا، أرجو طرح الأسئلة أسفل الدرس وليس هنا في قسم الأسئلة البرمجة حيث نطرح الأسئلة العامة الغير متعلقة بمحتوى الدورة أو الدرس، وذلك لمساعدتك بشكل أفضل.
  11. طالما ذكرت سوق العمل الحر فتوجه مباشرًة إلى PHP ولارافل ثم تعلم ووردبريس، لكن لا تستمع إلى أحد، تفقد مواقع العمل الحر التي تنوي العمل عليها ونوعية المشروع المعروضة والمهارات الخاصة بها، ثم اتخذ قرارك بناءًا على ذلك. وفي كلا الأحوال سيتعين عليك تعلم جافاسكريبت فهي لغة الويب للواجهة الأمامية وبدونها ستحتاج إلى استخدام مكتبة مثل alpine للإلتفاف حول عدم تعلم اللغة، وذلك لا أنصحك به، قم بتعلم الأساسيات التي تمكنك من فهم سطور اللغة على الأقل ثم تستطيع استخدام مكتبة مثل alpine وبعد ذلك تستطيع التعمق في تعلم جافاسكريبت بعد فترة. ابحث عن Tall stack وتعلم التقنيات الخاص به بعد القيام بالبحث في الخطوة الأولى وإتخاذ قرارك.
  12. بخصوص شرح لمكتبة Turtle فلا يوجد على وجه الخصوص، هناك نقاشات حول تلك المكتبة هنا: بينما ستجد هنا شرح لمكتبة pygame وتطبيقات عملية على المكتبة ففي المقال التالي يوجد مرجع لكافة المقالات حول pygame في الأكاديمية: بالطبع على اليوتيوب يوجد شروحات عملية لكلاهما
  13. من الطرق السهلة لفعل ذلك هي Permutation Feature Importance أو أهمية ميزة الإزاحة، وستجدها بالعديد من مكتبات التعلم الآلي، مثل scikit-learn، حيث توفر وظائف مدمجة لحسابها. وتلك الطريقة توفر تصنيفًا واضحًا لأهمية الميزة، الأمر الذي يسهل فهم النتائج وتفسيرها، وتستطيع تطبيق أهمية ميزة الإزاحة على أي نموذج تعلم آلي، بما في ذلك النماذج الخطية وغير الخطية، دون الحاجة إلى تعديلات كبيرة على النموذج أو معاملاته الفائقة. أيضًا مقاومة للارتباطات بين الميزات، وهو أمر شائع في العديد من مجموعات البيانات، وبإمكانك حساب أهمية ميزة الإزاحة بسرعة نسبية، خاصة عند مقارنتها بطرق أخرى مثل إزالة الميزة التكرارية (RFE). للتوضيح: from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import train_test_split from sklearn.inspection import permutation_importance X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) rf = RandomForestClassifier(n_estimators=100, random_state=42) rf.fit(X_train, y_train) importances = permutation_importance(rf, X_test, y_test, n_repeats=10, random_state=42) # الحصول على درجات أهمية الميزة importance_scores = importances.importances_mean # فرز الميزات حسب الأهمية sorted_features = np.argsort(importance_scores)[::-1] # تحديد أفضل 3 ميزات top_3_features = sorted_features[:3] print("Best 3:", X.columns[top_3_features])
  14. أقصد النتيجة التي حصلنا عليها من خلال اختبارنا الإحصائي ليست نتيجة عشوائية، بل هي نتيجة ذات احتمال ضئيل جدًا للحدوث إن كانت الفرضية الصفرية صحيحة. أي أن هناك احتمالًا ضئيلًا جدًا لأن يكون ذلك الفرق نتيجة للصدفة. للتوضيح: الفرضية الصفرية: لا يوجد فرق بين متوسطي العينتين. الفرضية البديلة: يوجد فرق بين متوسطي العينتين. في حال قيمة p أقل من مستوى الدلالة (عادةً 0.05)، فإننا نرفض الفرضية الصفرية ونستنتج أن هناك فرقًا "ذو دلالة إحصائية" بين متوسطي العينتين.
  15. عليك تحديد ما هو استخدامك هل للبرمجة فقط أم هناك استخدامات أخرى وما هي الميزانية، وهل تستخدم الحاسوب خارج المنزل أم داخل المنزل أغلب الوقت؟ عامًة للبرمجة أنت لست بحاجة إلى مواصفات مرتفعة يكفي حاسوب بمواصفات متوسطة والأهم وجود 16 جيجابايت من الذاكرة العشوائية و هارد SSD للنظام.
  16. الغرض منها إجراء اختبار t للعينات المستقلة وهو اختبار إحصائي لمقارنة متوسطين لعينتين مستقلتين. وذلك عندما تريد معرفة هل هناك فرق ذو دلالة إحصائية بين متوسطين لعينتين مستقلتين. حيث تُجري ttest_ind اختبار t للعينات المستقلة وتُعيد قيمتين: القيمة p: وهي احتمال الحصول على الفرق المُلاحظ بين متوسطي العينتين إن لم يكن هناك فرق حقيقي بينهما. إحصائية t: وهي قياس الفرق بين متوسطي العينتين مُقسّمًا على خطأ المعياري. وتستقبل المعلمات التالية: a: مصفوفة NumPy تحتوي على البيانات للعينة الأولى. b: مصفوفة NumPy تحتوي على البيانات للعينة الثانية. axis: المحور الذي يتم حساب الاختبار عليه (افتراضيًا 0). equal_var: قيمة منطقية تُشير إلى ما إن كان يُفترض أن يكون التباين متساويًا بين العينتين (افتراضيًا True). nan_policy: كيفية التعامل مع القيم المفقودة (افتراضيًا "propagate"). للتوضيح: import scipy.stats as stats import numpy as np data1 = np.array([1, 2, 3, 4, 5]) data2 = np.array([6, 7, 8, 9, 10]) result = stats.ttest_ind(data1, data2) print(" p:", result.pvalue) print(" t:", result.statistic) لاحظ في حال كانت القيمة p أقل من مستوى الدلالة (عادةً 0.05)، فإننا نرفض الفرضية الصفرية ونستنتج أن هناك فرقًا ذو دلالة إحصائية بين متوسطي العينتين. أما لو القيمة p أكبر من مستوى الدلالة، فإننا لا نرفض الفرضية الصفرية ونستنتج أنه لا يوجد فرق ذو دلالة إحصائية بين متوسطي العينتين.
  17. في حال لديك أسئلة تتعلق بمحتوى الدروس في الدورة نقوم بالتعليق أسفل الدرس المتعلق بالسؤال أي العنوان الخاص به والمحتوى متعلق بالسؤال. إن كان السؤال غير متعلق بمحتوى الدورة أي خارج محتوى الدرس نقوم بطرح السؤال في قسم أسئلة البرمجة هنا على العام. بما أنّ السؤال لديك متعلق بمراجعة المشروع بشكل عام لذا تستطيع التعليق على الدروس الخاصة بالخاتمة.
  18. من الممكن ذلك بالطبع، وKaggle منصة ممتازة لتعلم مهارات تحليل البيانات والتعلم الآلي لأنها تُقدم مسابقاتها ببيانات حقيقية. لكن لا تُحاول المشاركة في مسابقات متقدمة في البداية، ابدأ بمسابقات خاصة بالمبتدئين لتعلم الأساسيات. ويجب إبراز ما قمت به بشكل سهل القراءة وبالرسوم البيانية وليس مجرد نص فقط، مثلاً كالتالي لكن أضف بعض الصور: https://github.com/tiannaparris/Data-Analysis-Portfolio ستجد تفصيل هنا بخصوص المهارات اللازمة للعمل على تعلمها أيضًا:
  19. ستحتاجين إلى استخدام إطار العمل JUnit الخاص بإختبارات الوحدة وهو الأكثر استخدامًا بخصوص جافا. أيضًا استخدام Mockito وهي إطار عمل لتنفيذ Mocking وتساعدك على اختبار الكود الذي يعتمد على كائنات أخرى، بمعنى إنشاء كائنات مزيفة mock objects في اختبارات الوحدة، وذلك إختياري لتحسين اختبارات الوحدة التي تقومين بها. لنقم بإضافة إطار العمل JUnit بإضافة التبعية التالية في ملف build.gradle: dependencies { testImplementation 'junit:junit:4.13.2' } ثم إنشاء فئة جديدة في src/test/java بامتداد .java. وتلك الفئة ستحتوي على اختبارات الوحدة. ثم كتابة اختبارات الوحدة باستخدام إطار العمل JUnit وسيبدوا كالتالي بدون Mockito: import org.junit.Before; import org.junit.Test; public class ExampleTest { private ExampleClass exampleClass; @Before public void setup() { exampleClass = new ExampleClass(); } @Test public void testExampleMethod() { // كتابة اختبار الوحدة هنا assertEquals("النتيجة المتوقعة", exampleClass.exampleMethod()); } } ثم تشغيل الاختبارات باستخدام Android Studio، وتستطيعي تشغيل الاختبارات الفردية أو جميع الاختبارات في الفئة. الآن عليكِ تمكين مكتبة Mockito في مشروعك عن طريق إضافة التبعية التالية في ملف build.gradle: dependencies { testImplementation 'org.mockito:mockito-core:4.0.0' } ثم إنشاء كائنات مزيفة باستخدام مكتبة Mockito أي نقوم بالكتابة في نفس ملف إختبار الوحدة، ليصبح بالشكل التالي: import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; import static org.junit.Assert.assertEquals; public class MyActivityTest { @RunWith(MockitoJUnitRunner.class) public class MyActivityTest { @Test public void testCalculateSum() { MyActivity myActivity = new MyActivity(); int result = myActivity.calculateSum(2, 3); assertEquals(5, result); } @Test public void testCalculateSumWithMock() { MyDependency dependency = Mockito.mock(MyDependency.class); Mockito.when(dependency.getValue()).thenReturn(5); MyActivity myActivity = new MyActivity(dependency); int result = myActivity.calculateSumWithDependency(); assertEquals(10, result); Mockito.verify(dependency, Mockito.times(1)).getValue(); } } } لاحظي: @Test لإضافة اختبارات جديدة وهو خاص بـ Junit Mockito.mock() لإنشاء كائنات mock objects. Mockito.when() لإرجاع قيم محددة من mock objects. Mockito.verify() للتأكد من استدعاء الطرق المطلوبة. استخدم assertEquals() للتأكد من أن النتيجة تساوي القيمة المتوقعة. بعد ذلك تشغيل الاختبارات باستخدام Android Studio. والإختبار هنا من أجل التأكد هل تُرجع دالة calculateSumWithDependency القيمة الصحيحة عندما تُرجع دالة getValue() في الكائن المزيف القيمة 5؟ وهل تُستدعى دالة getValue() في الكائن المزيف مرة واحدة فقط؟ وبالطبع لا يجب كتابة اسم الكلاس بالضرورة MyActivityTest، بإمكانك اختيار أي اسم تريدينه، لكن من المهم أن يكون اسمًا وصفيًا يعكس وظيفة الكلاس، أي مثلاً تسميته MyActivityCalculatorTest أو MyActivityDependencyTest لإبراز ما يتم اختباره.
  20. الدومين ستحتاج إلى شرائه فهو غير مجاني ولديك منصة مثل Namecheap توفر ذلك، وبعد شرائه تستطيع ربطه على الاستضافة حتى لو مجانية. حيث أنّ الاستضافة المجانية توفر لك دومين فرعي subdomain مثلاً على netlify ستحصل على دومين فرعي مشابه للتالي: portfolio-project.netlify.app
  21. أحيانًا يتم إرسال مثل تلك الرسائل بشكل تلقائي من خلال أداة معينة وليس على وجه الخصوص لملفك، أي يتم تحديد كلمات مفتاحية معينة وإختيار بلد محددة وإرسال الرسائل. منصة outlier.ai منصة معروفة وبها عدد كبير من الموظفين وذلك هو حسابها على لينكدإن: https://www.linkedin.com/company/try-outlier/ والهدف منها هو تدريب نماذج الذكاء الاصطناعي والدفع لك مقابل ذلك.
  22. سيتم ذلك لا تقلق محمد، أرجو الإنتظار لحين مراجعة مشاريعك في حال قمت بتسليمها وسيتم الرد عليك عند الإنتهاء، في حال لم تقم بتسليمها من الأفضل توفير الروابط الخاصة بها على github
  23. لأنها أكثر الخوارزميات كفاءة في البحث في مصفوفات مرتبة، وتعمل بزمن تشغيل O(log n) ، حيث n هو عدد العناصر في المصفوفة، أي أن زمن البحث يقل بشكل كبير مع زيادة عدد العناصر. وتستخدم في العديد من التطبيقات المختلفة، مثل قواعد البيانات، والبحث في الملفات، وإدارة الذاكرة، وغيرها. وتتمثل الفكرة الأساسية في تقسيم المصفوفة إلى نصفين، ثم تحديد النصف الذي يحتوي على العنصر المطلوب. مثلاً لو لدينا مصفوفة مرتبة تحتوي على الأرقام 1، 2، 3، 4، 5، 6، 7، 8، 9، وتبحث عن الرقم 5، فستقوم خوارزمية البحث الثنائي بتقسيم المصفوفة إلى نصفين: النصف الأول: 1، 2، 3، 4 النصف الثاني: 5، 6، 7، 8، 9 ثم ستقوم بتحديد النصف الذي يحتوي على الرقم 5، وهو النصف الثاني، ثم تقسيم النصف الثاني إلى نصفين مرة أخرى: النصف الأول: 5، 6 النصف الثاني: 7، 8، 9 ثم ستقوم بتحديد النصف الذي يحتوي على الرقم 5، وهو النصف الأول، ثم ستقوم بتحديد الرقم 5 في النصف الأول. أي تخيل أنك تبحث عن رقم معين في قائمة مرتبة من الأرقام، تبدأ بالبحث في النقطة الوسطى للقائمة، وفي حال كان الرقم الذي تبحث عنه أكبر من الرقم في النقطة الوسطى، فإنك تركز على النصف العلوي من القائمة، وفي حال الرقم الذي تبحث عنه أصغر من الرقم في النقطة الوسطى، فإنك تركز على النصف السفلي من القائمة، وتكرر تلك العملية حتى تجد الرقم الذي تبحث عنه. ولا يمكن استخدام خوارزمية البحث الثنائي مع البيانات غير مرتبة، وأحيانًا لا تُعطي تلك الخوارزمية النتيجة الصحيحة عند وجود بيانات متكررة. بالتالي هي ليست دائمًا الأفضل في كل الحالات، فهناك خوارزميات أخرى أفضل في بعض الحالات، ومنها: خوارزمية البحث الخطي: أفضل في حالات البحث في مصفوفات صغيرة أو غير مرتبة. خوارزمية البحث الثنائي المتكرر: أفضل في حالات البحث في مصفوفات مرتبة بشكل خاص. خوارزمية البحث الحشوي: أفضل في حالات البحث في مصفوفات كبيرة ومرتبة بشكل خاص.
  24. لو قمت بإنشاء مصفوفة من 3x3 من الأعداد الصحيحة، فإن NumPy ستقوم بتخصيص 9 عناصر في الذاكرة، وستحدد الشكل على أنه (3, 3)، والنوع على أنه int64، والخطوات على أنها (1, 3) و (3, 1). أي أن كل عنصر في المصفوفة يتم تخزينه في الذاكرة بشكل متوالي، مع استخدام الخطوات لتحديد مواقع العناصر المجاورة في المصفوفة. وتلك بنية بيانات تسمى مصفوفة متجانسةhomogeneous array، وهي تُخزن جميع العناصر من نفس نوع البيانات في منطقة متجاورة في الذاكرة. بالتالي تسمح للمكتبة بالتعامل مع البيانات بشكل فعال ومتوافق مع الذاكرة، مما يجعلها مناسبة للعمليات الحسابية الكبيرة. للتوضيح أكثر لو قمت بإنشاء مصفوفة NumPy من نوع int تحتوي على 5 عناصر: import numpy as np arr = np.array([1, 2, 3, 4, 5]) فسيتم تخصيص مساحة في الذاكرة لـ 5 عناصر من نوع int كالتالي: عنوان قيمة 0x1000 1 0x1008 2 0x1010 3 0x1018 4 0x1020 5 وتستخدم مؤشرات pointers الذاكرة للوصول إلى العناصر بشكل مباشر.
  25. أتفهم التشتت الذي يحدث في البداية، لكن بشكل واقعي مجال البرمجة ليس بالسهل ولا يوجد به إختصارات تؤدي لنفس النتيجة التي سيحصل عليها شخص بذل مجهود أكبر. تستطيع مشاهدة بعض المسارات والإكتفاء بذلك، لكن لن تصل للمستوى الذي سيصل إليه الشخص الأول، وأيضًا سيصبح مستواك ضعيف ولن تتمكن من حل المشاكل التي ستواجهك وستحتاج إلى الإعتماد على الآخرين. مجال الواجهة الخلفية Back-End على وجه الخصوص أصعب من الواجهة الأمامية وبحاجة إلى التعلم بشكل مُعمق وليس بشكل سطحي فالأمر يمر بدون مشكلة نسبيًا لو تخصصت في الواجهة الأمامية. لذا ستحتاج إلى دراسة كامل دورة علوم الحاسوب لتتأسس بشكل جيد في البرمجة ويصبح لديك نظرة عامة شاملة، وهناك بعض المسارات مثل الخوارزميات وهياكل البيانات وأنماط التصميم ستواجه صعوبة في فهمها في البداية حاول استيعابها بنسبة 50 إلى 70% وفيما بعد عند التخصص وتنفيذ مشاريع ستتفهم الأمر وتستطيع العودة إليها لاستيعابها بشكل أوضح. أي لا يوجد مسار في الدورة ليس مهم طالما أنك تدرس الدورة بدون خبرة سابقة في البرمجة.
×
×
  • أضف...