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

سمير عبود

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

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

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

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

    34

كل منشورات العضو سمير عبود

  1. لم أفهم لماذا تستخدم حلقة foreach بداخل الخاصية class فهذا سيؤدي إلى تطبيق عدة كلاسات قد يكون الشرط تحقق في أول دورة للحلقة فتم تطبيق الصنف badge-success و في الدورة الثانية لم يتحقق فتم تطبيق badge-warning و هكذا في بقية الدورات إلى أن يتشكل لك عنصر: <div class="badge-success badge-success badge-warning" إذا قمت بتوضيح ما الذي تريد فعله يُمكن أن نساعدك,
  2. هما نفس الشيء يخدمان التحميل الحثيث لكن load تستخدم لتحميل العلاقة بعد تحميل النموذج الأب و تستخدم لفصل الإستعلامين مثلاً قد نحتاج لتحميل بيانات العلاقة في حال تحقق شرط ما: $posts = App\Models\Post::all(); if (some_condition) { $posts->load('relation1', 'relation2'); }
  3. عند الوصول لعلاقات Eloquent كخاصيات يتم تحميل بيانات تلك العلاقات بشكل كسول، أي بشكل لحظي سيتم تنفيذ الإستعلام عند الوصول لجلب بيانات العلاقة، و هذا الأمر يُسبب خلل في أداء التطبيق حيث أن كثرة الإستعلامات تُؤدي إلى بطئ التطبيق في الإستجابة حيث أن هذا الأمر يُسبب مشكل مشهورة في لارافل إسمها مشكلة N + 1، لكن يُمكن في Eloquent تحميل بيانات العلاقة بشكل حثيث أي مُسبق و هذا هو حل تلك المُشكلة و يتم إستخدام كل من التابع load او التابع with. مثال لنفترض أنه لدينا النموذج Category و النموذج Post حيث أن كل مقال ينتمي إلى قسم و كل قسم به عدة مقالات: <?php namespace App\Models; use Illuminate\Database\Eloquent\Model; class Post extends Model { /** * ... */ public function category() { return $this->belongsTo(Category::class); } } لنجلب الآن كل المقالات و نحاول طباعة القسم: $posts = App\Models\Post::all(); foreach ($posts as $post) { echo $post->category->name; } سينفّذ هذا التكرار استعلام واحد لاسترداد كل المقالات و من أجل كل مقال سيتم تنفيذ إستعلام آخر لجلب بيانات القسم التابع له. فرضاً أنه لدينا 20 مقال فإنه سيتم تنفيذ إستعلام واحد لجلب كل المقالات و 20 إستعلام آخر لجلب القسم لكل مقال أي إجمالي 21 مقال، و هذا ما يُسمى بالتحميل الكسول، فإذا كان عدد المقالات N فإن عدد الإستعلامات التي ستُنفذ هو N + 1 و من هنا جاءت تسمية المشكلة. لحُسن الحظ أنه يمكن إستخدام التحميل الحثيث الذي يسمح لنا بتقليل الإستعلامات إلى إستعلامين فقط و يُمكن تحديد العلاقة التي نريد تحميلها بشكل حثيث بإستخدام التابع with او load: $posts = App\Models\Post::with('category')->get(); foreach ($posts as $post) { echo $post->category->name; } و هذا الشكل يؤدي إلى تنفيذ إستعلامين فقط: select * from posts select * from categories where id in (1, 2, 3, 4, 5, ...) قد نُريد تحميل أكثر من علاقة بشكل حثيث فنُمررها في مصفوفة: $posts = App\Models\Post::with(['category', 'auther'])->get(); قد نُريد تحميل حقول محددة فقط: $posts = App\Models\Post::with('category:id,name')->get(); و هناك عدة نقاط و مفاهيم أخرى يُمكنك الإطلاع على التوثيق الرسمي لمعلومات أكثر.
  4. هناك عدة طرق للقيام بالأمر: إستخدام التعابير النمطية: import re x = "hello, world! Hi! hello!" count = len(re.findall("hello", x)) print(count) # 2 طريقة أخرى بإستخدام التعابير النمطية: import re x = "hello, world! Hi! hello!" word = "hello" count = sum(1 for _ in re.finditer(r'\b%s\b' % re.escape(word), x)) print(count) # 2 إستخدام split لتحويل النص إلى قائمة كلمات ثم إستخدام التابع count للقوائم: import re x = "hello, world! Hi! hello!" word = "hello" count = re.split(r'\W', x).count(word) print(count) # 2
  5. a or b: يتم إرجاع a إذا كان a يحمل قيمة صواب (True) و إلا سيقوم بإرجاع b و هذا ما يُفسر المثال الأول لك حيث تم إرجاع قيمة len(args) a and b يتم إرجاع b إذا كان a يحمل قيمة صواب (True) و إلا سيقوم بإرجاع a و هذا ما يُفسر المثال الثاني لك حيث تم إرجاع قيمة max(args)-min(args)
  6. هنالك 3 حالات للملفات على git: ملفات تم إيداعها committed: المقصود بالإيداع commit هو حفظ البيانات بشكل آمن في قاعدة البيانات المحلية. ملفات أجريت تعديلات عليها modified: هي التي تم إدخال تغييرات عليها لكنه لم يتم حفظ تلك التغييرات إلى قاعدة البيانات المحلية بعد. ملفات تم إدراجها staged: الإدراج فهو تعليم الملفات التي تم تعديلها في حالتها الحالية ليتم تضمينها في الإيداع القادم. و هذه الحالات تُقسم مشاريع Git إلى ثلاثة أقسام: حيث مجلد Git يُعتبر قاعدة بيانات مشروعك، مجلد العمل يُعتبر النُسخة الحالية و الأحدث من المشروع. منطقة الإدراج عبارة عن ملف واحد يتم الاحتفاظ به عادة داخل مُجلد Git والذي يحفظ معلومات حول المُحتوى الذي سيتم إرساله في الإيداع القادم. حيث أن سير العمل في Git يمر على المراحل التالية: التعديل على الملفات في مجلد العمل إضافة الملفات إلى منطقة الإدراج إيداع الملفات commit و الذي كما قلنا أنه يعني إلتقاط صورة عن الملفات و تخزين البيانات في مجلد Git. إذا كان الملف بداخل المجلد Git فهذا الملف تم إيداعه Commited، أما إن تم إجراء تعديلات عليه و هو في منطقة الإيداع و لم يتم حفظ تلك التعديلات بعد فيُعتبر مُدرج Staged، أما إذا تم إحداث تعديلات على الملف و لم يتم نقله إلى منطقة الإدراج فيُعتبر مٌعدل Modified
  7. origin هي إختصار لرابط المُستودع البعيد و يتم تخزينه عند تنفيذ الأمر: git remote add origin https://... كما يُمكن تعديل الرابط إنطلاقاً من الأمر التالي: git remote set-url origin new.git.url/here يٌعتبر master فرع من الفروع في المستودع. لمعرفة الفروع الموجودة في المستودع: git branch #local branches git branch -r #remote branches git branch -a #all branches لإنشاء فرع و تغيير المُؤشر نحوه: git checkout -b <branch-name> # Create a new branch and check it out كما بالإمكان إنشاء فرع دون تغيير المُؤشر أي البقاء في الفرع الحالي: git branch new_branch و لتغيير المؤشر لفرع ما نستخدم: git checkout <branch-name> لدفع التغييرات على الملفات من فرع محلي إلى فرع في المستودع نستخدم: git push <remote-name> <branch-name> حيث يكون <remote-name> هو origin و <branch-name> إسم الفرع المحلي. حيث أن صيغة الأمر هي بالشكل التالي: git push <remote-name> <local-branch-name>:<remote-branch-name> إذا لم تُحدد إسم الفرع البعيد فسيتم إعتبار إسم الفرع البعيد هو نفس الفرع المحلي وإن لم يكن موجود سيتم إنشاؤه.
  8. تستطيع إستخدام مكتبة mongoose أو mongodb نفسها للتحقق من أن المعرف id صالح. استيراد ObjectId من حزم mongodb أو mongoose: باستخدام Mongodb: const ObjectId = require('mongodb').ObjectId; // or const mongodb, {ObjectId} = require('mongodb'); باستخدام Mongoose: const ObjectId = require('mongoose').Types.ObjectId; ومع ذلك ، يقوم (id)ObjectId.isValid بإرجاع true حتى بالنسبة للسلاسل غير الصالحة ذات الطول 12. لمنع مثل هذه الحالات ، يمكن إضافة فحص آخر بعد التحقق الافتراضي الذي سيعيد صواب أو خطأ بناءً على الشرط: (String)(new ObjectId(id)) === id إنشاء دالة بهذا الشرط: const mongoose = require('mongoose'), ObjectId = mongoose.Types.ObjectId; // Validator function function isValidId(id){ if(ObjectId.isValid(id)){ if((String)(new ObjectId(id)) === id) return true; return false; } return false; } console.log(ObjectId.isValid("barbarbarbar")) // true console.log(isValidId("barbarbarbar")) // false console.log(isValidId("594ced02ed345b2b049222c5")) // true أيضاً إبتداءً من Mongoose > 5.7.12 تم إضافة دالة تقوم بعمل نفس الشيء: isValidObjectId: mongoose.isValidObjectId(string); /* true or false */
  9. يدعم fileinput بالفعل التحرير الداخلي. و يقوم بإعادة توجيه stdout إلى الملف في هذه الحالة يُمكنك إستخدامه بهذا الشكل: import fileinput with fileinput.FileInput("file.txt", inplace=True) as file: for line in file: print(line.replace("foo", "bar"), end='') لاحظ أننا حددنا المعامل inplace ب True حتى نستطيع التعديل.
  10. إذا كنت تقصد أنه إنطلاقاً من قائمة تحتوي على مفاتيح: ["b", "y", "z"] تُريد الوصول إلى قيمة في القاموس المُعطى. يُمكنك إنشاء دالة للمرور على القائمة و جلب القيمة في كل مرة بالشكل التالي: dataDict = { "a":{ "x": 1, "y": 2, "z": 3 }, "b":{ "x": 1, "y": { "x": 1, "y": 2, "z": 3 }, "z": 3 } } def nested_get(dic, keys): for key in keys: dic = dic[key] return dic print(nested_get(dataDict, ["b", "y", "z"])) # 3 كما بالإمكان إستخدام functools.reduce بالشكل التالي: from functools import reduce import operator def nested_get(dataDict, mapList): return reduce(operator.getitem, mapList, dataDict) dataDict = { "a":{ "x": 1, "y": 2, "z": 3 }, "b":{ "x": 1, "y": { "x": 1, "y": 2, "z": 3 }, "z": 3 } } print(nested_get(dataDict, ["b", "y", "z"])) # 3
  11. بإمكانك إستخدام التعابير النمطية لحذف كل الحروف المتحركة (aeiou): import re def removeVowel(text): result = re.sub(r'[AEIOU]', '', text, flags=re.IGNORECASE) return result text = "Hellooo, world! Words!" print(removeVowel(text)) # Hll, wrld! Wrds! أو تعكس الأمر فبدل ما تحذف تضيف تعمل حلقة للدوران على كل الحروف و إذا لم يكن الحرف ينتمي إلى الحروف aeiou تُضيفه إلى سلسلة نصية تكون مُهيئة ب "" مثال: def removeVowel(text): return ''.join([l for l in text if l not in "aeiouAEIOU"]); text = "HeElloooOOO, world! WoOrds!" print(removeVowel(text)) # Hll, wrld! Wrds!
  12. بإمكانك إنشاء دالة تعمل في صفوف إطار البيانات الخاص بك كما يلي: def f(row): if row['Set'] == "A": val = "Group 1" else: val = "Group 2" return val ثم تطبيق الدالة عند إنشاء العمود الثالث: df['New'] = df.apply(f, axis=1) و هذا المثال ككل: import pandas as pd data = {'Type': ['A', 'B', 'O', 'B'], 'Set': ['A', 'B', 'B', 'A']} df = pd.DataFrame(data, index =[1, 2, 3, 4]) def f(row): if row['Set'] == "A": val = "Group 1" else: val = "Group 2" return val df['New'] = df.apply(f, axis=1) print(df) و هذا الخرج: Type Set New 1 A A Group 1 2 B B Group 2 3 O B Group 2 4 B A Group 1 أيضاً يُمكنك إستخدام مكتبة numpy: تضع الشروط و الخيارات: conditions = [df.Set.eq("A"), df.Set.eq("B")] choices = ["Group 1", "Group 2"] ثم تُنشئ العمود و تُطبق الشروط و الخيارات: df['New'] = np.select(conditions, choices) و هذا المثال ككل: import pandas as pd import numpy as np data = {'Type': ['A', 'B', 'O', 'B'], 'Set': ['A', 'B', 'B', 'A']} df = pd.DataFrame(data, index =[1, 2, 3, 4]) conditions = [df.Set.eq("A"), df.Set.eq("B")] choices = ["Group 1", "Group 2"] df['New'] = np.select(conditions, choices) print(df) و ستحصل على نفس النتائج.
  13. تستطيع إعادة تعريف التابع __str__ من خلال الصنف وسيتم تنفيذ محتواه عند إستخدام طباعة كائن من ذلك الصنف: class Foo: def __str__(self): return "instance of foo" foo = Foo() print(foo) # instance of foo و تستطيع إعادة تعريف التابع __repr__ الذي سيتم تنفيذه في حالة إستدعاء الدالة ()repr او إستدعاء الكائن مباشرة من الواجهة التفاعلية لبايثون: >>> class Foo: ... def __repr__(self): ... return "Foo" ... def __str__(self): ... return "instance of foo" ... >>> foo = Foo() >>> print(foo) instance of foo >>> repr(foo) 'Foo' >>> foo Foo
  14. نعم هذا هو الأمر، لكن توضيح أخير فقط اول اوبشن تستخدم لتنبيه المستخدم و يرفق معها نص كالرجاء الإختيار او اي شيء توضيحي نضع لها الخاصية disabled حتى لا يتم اختيارها و لا نضع لها قيمة في الخاصية value و من باقي الخيارات نحدد التي نريد جعلها selected و ستجد انني وضعت شرط بداخل الحلقة في حالة ما إذا كان الخيار الحالي هو الموجود في قاعدة البيانات قم بتحديده. بالتوفيق
  15. هذا ما فهمته من المشكلة وهذا الحل حسب فهمي بفرض ان القيمة قبل التعديل تكون مخزنة في user['fibersID']$ <select class="form-control fiber-thread" name="fiber-thread"> <option disabled value="">Choose here</option> <?php $result = $conn->query("SELECT * FROM fibers"); while ($row = $result->fetch_assoc()) { if($row['id'] == $user['fibersID']) { echo '<option selected value="' . $row['id'] . '">' . $row['name'] . '</option>'; } else { echo '<option value="' . $row['id'] . '">' . $row['name'] . '</option>'; } } ?> </select> و في ملف ال php تقوم بنفس الفكرة: $id = $_POST['id']; $name = $_POST['name']; $fiber = $_POST['fiber']; $num = $_POST['num']; $color = $_POST['color']; $pantone = $_POST['pantone']; $height = $_POST['height']; $weight = $_POST['weight']; $factory = $_POST['factory']; $tprice = $_POST['tprice']; $mprice = $_POST['mprice']; $q = "UPDATE `thread` SET `name`='$name',`num`='$num',`color`='$color',`pantone`='$pantone',`height`='$height',`weight`='$weight',`factory`='$factory',`tPrice`='$tprice',`mPrice`='$mprice'"; if (isset($fiber) && !empty($fiber)) { $q .= ",`fiber`='$fiber'"; } if (isset($_FILES['image']['name'])) { // rename and upload image $q .= ",`image`='$image'"; } $q .= " WHERE thread.id =".$id.";"; $result = $conn->query($q); if ($result) { echo "done"; }
  16. هل قمت بحذف جزء التعديل الخاص بحقل fiber من الإستعلام لأني أظن أنك نسيته بنفس فكرة الصورة مسحناها من الإستعلام الأول و أضفناها في حال تحقق الشرط. بخصوص القائمة لماذا تضع له value وتقوم بتحديده؟
  17. طيب لأن القيمة 0 ليست null لذلك الشرط يتحقق في كل الأحوال if (isset($fiber) && !empty($fiber)) {
  18. قيمة المتغير fiber ماذا تكون في حالة لم تُعدل على القائمة؟
  19. لاحظ الإستعلام: $q = "UPDATE `thread` SET `name`='$name',`fiber`='$fiber',`num`='$num',`color`='$color',`pantone`='$pantone',`height`='$height',`weight`='$weight',`factory`='$factory',`tPrice`='$tprice',`mPrice`='$mprice',`image`='$image' WHERE thread.id =".$id.";"; في حالة عدم تحقق الشرط: if (isset($_FILES['image']['name'])) { فإن المُتغير image لن يتم تعريفه لذلك أعطاك ذلك الخطأ. و الحل إنشاء الإستعلام على أساس الصورة إن كانت موجودة فإن الإستعلام سيتضمن حقل الصورة إن لم تكن الصورة موجودة في الطلب فلا تقم بتضمين حقل الصورة في الإستعلام. يعني ببساطة بهذا الشكل: $id = $_POST['id']; $name = $_POST['name']; $fiber = $_POST['fiber']; $num = $_POST['num']; $color = $_POST['color']; $pantone = $_POST['pantone']; $height = $_POST['height']; $weight = $_POST['weight']; $factory = $_POST['factory']; $tprice = $_POST['tprice']; $mprice = $_POST['mprice']; $q = "UPDATE `thread` SET `name`='$name',`fiber`='$fiber',`num`='$num',`color`='$color',`pantone`='$pantone',`height`='$height',`weight`='$weight',`factory`='$factory',`tPrice`='$tprice',`mPrice`='$mprice'"; if (isset($_FILES['image']['name'])) { // rename and upload image $q .= ",`image`='$image'"; } $q .= " WHERE thread.id =".$id.";"; $result = $conn->query($q); if ($result) { echo "done"; } تقسيم الإستعلام و إنشاؤه بحيث يتضمن حقل الصورة إن كانت هناك صورة جديدة إن لم تكن هناك صورة جديدة لا نضيف الحقل للإستعلام. أعتقد أن المُشكلة الأولى نفس الفكرة.
  20. يقوم المعامل unwind بتفكيك حقل المصفوفة من مستندات الإدخال لإخراج مستند لكل عُنصر من هذه المصفوفة تطابق هذه المستندات مُستند الإدخال غير أن خاصية المصفوفة ستأخذ عُنصر واحد في كل مرة: مثال فرضاً أنه لديك المستند التالي: [ { title: "this is my title", author: "foo", posted: new Date(), pageViews: 6, tags: [ "foo", "bar", "baz" ] } ] عند إستخدام unwind بهذا الشكل: db.collection.aggregate({ $project: { author: 1, title: 1, tags: 1 } }, { $unwind: "$tags" }) ستكون النتيجة بهذا الشكل: [ { "_id": ObjectId("5a934e000102030405000000"), "author": "foo", "tags": "foo", "title": "this is my title" }, { "_id": ObjectId("5a934e000102030405000000"), "author": "foo", "tags": "bar", "title": "this is my title" }, { "_id": ObjectId("5a934e000102030405000000"), "author": "foo", "tags": "baz", "title": "this is my title" } ] يُمكنك تجربة المثال من: هنا، كان في المصفوفة ثلاث عناصر فأصبح لدينا 3 مستندات و توزعت عناصر المصفوفة على كل مستند في الخاصية tags
  21. إبتداءً من الإصدار 3.6 اصبح بالإمكان التعديل على عدة عناصر بداخل مصفوفة بحيث يُمكنك إستخدام positional identifier بالشكل التالي: db.collection.update({}, { $unset: { "address.localAddresses.$[].street": true } }) $[] تقوم بحذف كل الخاصيات street من المصفوفة localAddresses، يعمل كعنصر نائب لتحديث جميع العناصر في المصفوفة. بإمكانك تجربة المثال من: هنا إن أردت الحذف المتعدد من عدة مستندات إستخدم multi: true بالشكل التالي: db.collection.update({}, { $unset: { "address.localAddresses.$[].street": true } }, { multi: true })
  22. هل بإمكانك التوضيح أي برامج تقصد، هل تقصد برامج تحتاجها في الدورة أم ماذا؟ إذا كنت تقصد دورة تطوير واجهة المُستخدم فقط تابع الدروس و تابع مع المُدرب و إن احتجت لتحميل برنامج سيدلك في الدرس على ماهي البرامج التي ستحتاجها و رابط تنزيلها و كيفية تنزيلها كما أنه سيقوم بتثبيتها على جهازه حتى تتعلم منه طريقة تثبيتها على جهازك و إن حصلت لك مُشكلة ما فستجد في أسفل الدرس صندوق للتعليقات بإمكانك مشاركة المُشكلة معنا من خلاله و سنعمل على مُساعدتك. روابط للمواضيع الشائعة على الأكاديمية: كيف تستفيد من أكاديمية حسوب كيف أصل للدورات التي اشتركت بها كيف أتواصل مع المدرّبين الامتحان والحصول على الشهادة
  23. الأسئلة التي تُراودك طبيعية و قد تم طرحها من قبل العديد من المستقلين قبلك كما أن أجوبة هذه الأسئلة ليست حقيقة ثابتة لذلك يعمل فريق مستقل دائماً على كتابة عدة مقالات في هذا الجانب و تطوير المستقلين فيه على مُدونة مُستقل فأنصحك بالإطلاع على تلك المقالات من خلال هذا الرابط: دليل المستقلين و ستجد غايتك فيه. كما بإمكانك الإطلاع على بعض الكتب و المقالات أيضاً التي نشرتها الأكاديمية هنا على المنصة: مقالات العمل الحر كتب العمل الحر
  24. التابع .sort() في pymongo يأخذ مُعاملين key و direction لذا ، إذا كنت تريد الترتيب حسب المعرف _id ، فعليك الترتيب بهذا الشكل: .sort("_id", 1) أو: .sort("_id", pymongo.ASCENDING) // أو .sort("_id", pymongo.DESCENDING) إن كنت تريد الترتيب حسب عدة حقول فيُمكنك: .sort([("field1", pymongo.ASCENDING), ("field2", pymongo.DESCENDING)])
  25. يُقدم الصنف JPanel ثلاث دوال بانية هي الباني الإفتراضي و الباني الذي يقبل وسيط بولياني و الباني الذي يقبل كائن من الكلاسات التي تُطبق الواجهة LayoutManager حيث يتم استخدام LayoutManagers لترتيب المكونات بطريقة معينة. و LayoutManager هي واجهة يتم تنفيذها بواسطة جميع فئات مديري التخطيط. هناك الفئات التالية التي تمثل مديري التخطيط: BorderLayout FlowLayout و هو الإفتراضي GridLayout CardLayout GridBagLayout BoxLayout GroupLayout ScrollPaneLayout SpringLayout و غيرها حيث لكل صنف من هذه الأصناف طريقته في التخطيط. مثال عن إستخدام الباني الثاني و إستخدام مدير التخطيط BorderLayout: import java.awt.BorderLayout; import javax.swing.*; public class Main { public static void main(String args[]) { // إستخدام الباني الإفتراضي JPanel configurePanel = new JPanel(); configurePanel.add(new JButton("Config")); // إستخدام الباني الإفتراضي JPanel okCancelPanel = new JPanel(); okCancelPanel.add(new JButton("Ok")); okCancelPanel.add(new JButton("Cancel")); // إستخدام باني التخطيط JPanel buttonPanel = new JPanel(new BorderLayout()); buttonPanel.add(configurePanel, BorderLayout.WEST); buttonPanel.add(okCancelPanel, BorderLayout.EAST); // العرض JFrame t = new JFrame("Button Layout Demo"); t.setContentPane(buttonPanel); t.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); t.setSize(400, 65); t.setVisible(true); } } و هذه النتيجة: حيث إستخدمنا الباني الإفتراضي لإنشاء لوحتين (panels) واحدة أضفنا لها زر و الثانية أضفنا لها زرين. ثم أنشأنا لوحة ثالثة بإستخدام الباني الذي يقبل وسيط يحدد مدير التخطيط و حددنا النوع على أنه BorderLayout حتى نضيف اللوحتين وفق تخطيط نُحدده فجعلنا اللوحة التي تملك زر وحيد ناحية الغرب ( west ) و اللوحة التي تملك زرين ناحية الشرق (east) و هناك عدة ثوابت يُمكن إستخدامها في مدير التصميم BorderLayout و مديري التخطيط الأخرى لتوزيع العناصر.
×
×
  • أضف...