-
المساهمات
1068 -
تاريخ الانضمام
-
تاريخ آخر زيارة
-
عدد الأيام التي تصدر بها
43
إجابات الأسئلة
-
إجابة Ali Haidar Ahmad سؤال في تشغيل ملف بايثون من الشل Python shell كانت الإجابة المقبولة
يمكنك استخدام التعليمة python file.py لتشغيل ملف بايثون من الطرفية Terminal، لكن تشغيله من خلال IDLE python shell يكون مختلفًا.
لتشغيل الملف في IDLE python shell ، نستخدم الدالة exec بالشكل التالي:
exec(open("path/script_name.py").read()) طبعًا استبدل path و script_name بمسار واسم الملف الخاص بك.
لكن في حال كنت قد فتحت ال shell في نفس المكان الذي يوجد فيه الملف، فيمكنك الاكتفاء باسم الملف:
exec(open("script_name.py").read())
-
إجابة Ali Haidar Ahmad سؤال في تضمين دالة محددة func من وحدة ما module بايثون كانت الإجابة المقبولة
يمكنك استخدام الدالة getattr، حيث تعيد الدّالة getattr() قيمة الخاصيّة المُعطاة من الكائن المُعطى، ويتم صياغتها بالشكل التالي:
getattr(object, name[, default]) حيث يمثل الوسيط الأول الكائن المراد الحصول على قيمة خاصيّته.
أما name فتمثل سلسلة نصيّة تُمثّل اسم الخاصيّة المرغوب الوصول إلى قيمتها.
default مُعامل اختياريّ. القيمة الافتراضيّة التي ستُعاد إن لم تكن الخاصيّة موجودة.
ولمزيد من التفاصيل عن هذه الدالة يمكنك الانتقال إلى هذا الرابط في موسوعة حسوب.
- الآن بالنسبة لمثالك، وعلى فرض أنه لدينا الوحدة mod، والدالة func، فإننا نكتب:
# استيراد الوحدة import mod # نمرر اسم الدالة كوسيط ثاني والوحدة كوسيط أول methodToCall = getattr(mod, 'func') result = methodToCall() واختصاراً يمكن كتابة:
result = getattr(mod, 'func')()
-
إجابة Ali Haidar Ahmad سؤال في الكلمة المفتاحية yield في بايثون كانت الإجابة المقبولة
أولاً: ما هي yield.
yield عبارة عن كلمة مفتاحية في Python تُستخدم للعودة من الدالة بدون تدمير حالة المتغيرات المحلية "local variable" الخاص بها وعندما يتم استدعاء الدالة، يبدأ التنفيذ من حيث توقفت الدالة في المرة الأخيرة عندما صادفت الكلمة المفتاحية yield. أي دالة تحتوي على الكلمة المفتاحية yield تسمى مولد "generator". وبالتالي، فإن yield هو الذي يتم من خلاله صنع المولد. هذه الكلمة المفتاحية قليلة الشهرة في بايثون ومع ذلك لها فائدة أكثر مما قد تتوقعينه.
ثانياً:أمثلة لتوضيح عمله.
مثال 1:
# generator to print even numbers # مولّد لطباعة الأعداد الفردية def printOdd(numbers) : for i in numbers: if i % 2 != 0: yield i # تحديد مجموعة من الأرقام numbers = [1, 2, 5, 4, 9] # طباعة الأعداد الفردية print ("The even numbers in list are : ", end = " ") for j in printOdd(numbers): print (j, end = " ") # الخرج: # The even numbers in list are : 1 5 9 كما ذكرت فإن أي دالة تحتوي على هذه الكلمة المفتاحية يكون اسمها مولّد، وهذا ما يؤكده الاستدعاء التالي:
printOdd(numbers) # <generator object printOdd at 0x00000216842B4DC8> لاحظ أيضاً في المثال السابق أن j تقوم بالمرور على عناصر هذا المولد، وفي كل استدعاء له يقوم بالتنفيذ من حيثما توقف بدلاً من العودة للبداية.
مثال 2:
# برنامج لتوليد مربعات الأعداد من 1 ل 50 # سنعرّف الآن دالة توليد لانهائية تقوم بتوليد مربعات الأعداد بدءاً من 1 def nextSquare(): i = 1 # حلقة لانهائية لتوليد مربعات الأعداد while True: yield i*i i += 1 # الاستدعاء التالي للدالة سيتم فيها بدء التنفيذ من هنا # استدعاء الدالة لتحقيق المطلوب for num in nextSquare(): if num > 50: break print(num) لاحظ أن التنفيذ بعد كل استدعاء يبدأ من التعليمة التي تلي yield، ففي أول استدعاء يبدأ التنفيذ من بداية الدالة، لكن في الاستدعاءات التالي يتم التنفيذ بدءاً من السطر الذي أشرت إليه في الكود.
-
إجابة Ali Haidar Ahmad سؤال في أبونتو-بايثون كانت الإجابة المقبولة
الطريقة الأولى
اتبع الخطوات التالية:
- الخطوة 1: تحديث قوائم المستودعات وتحديثها.
افتح التيرمنل، وأدخل ما يلي:
sudo apt update - الخطوة 2: تثبيت برمجيات الدعم.
تمنحك الحزمة المشتركة لخصائص البرامج "software-properties-common package" تحكم أفضل في مدير الحزم الخاص بك عن طريق السماح لك بإضافة مستودعات PPA (أرشيف الحزمة الشخصية).
sudo apt install software-properties-common - الخطوة 3: إضافة Deadsnakes PPA.
وهو عبارة عن PPA بإصدارات أحدث من مستودعات Ubuntu الافتراضية.
sudo add-apt-repository ppa:deadsnakes/ppa سيطالبك النظام بالضغط على Enter للمتابعة. افعل ذلك واتركه حتى ينتهي، ثم قم بتحديث قوائم الحزم مرة أخرى:
sudo apt update - الخطوة 4: تثبيت Python 3
يمكنك الآن بدء تثبيت Python 3 من خلال الأمر:
sudo apt install python3.8
الطريقة الثانية
تثبيته من خلال الشيفرة المصدر باتباع الخطوات التالية:
- الخطوة 1: تحديث قوائم المستودعات وتحديثها.
افتح التيرمنل، وأدخل ما يلي:
sudo apt update - الخطوة 2: تثبيت برمجيات الدعم.
ترجمة الحزمة من الشيفرة المصدر تتطلب برمجيات إضافية، لذا قم بتنفيذ الأمر التالي لتثبيتها:
sudo apt install build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev wget - الخطوة 3: تحميل آخر نسخة من الشيفرة المصدر لبايثون Python Source Code.
انتقل إلى الدليل tmp/ واستخدم الأمر wget:
cd /tmp wget https://www.python.org/ftp/python/3.7.5/Python-3.7.5.tgz - الخطوة 4: استخراج الملف المضغوط.
من خلال الأمر:
tar -xf Python-3.8.3.tgz - الخطوة 5: اختبار النظام وتحسين Python.
يُفضل قبل التثبيت، التأكد من اختبار النظام وتحسين Python، حيث أن هذه العملية تؤدي إلى إعداد وتجهيز بايثون للعمل على جهازك، ويؤدي استخدام خيار --optimization إلى تسريع تنفيذ التعليمات البرمجية بنسبة 10-20٪ :
cd python-3.8.3 ./configure --enable-optimizations ملاحظة: هذه العملية قد تستغرق حوالي 30 دقيقة.
- الخطوة 6: تثبيت مثيل ثانٍ من Python.
لإنشاء تثبيت ثانٍ لـ Python ، بالإضافة إلى تثبيت Python الحالي نفذ الأمر:
sudo make altinstall
-
إجابة Ali Haidar Ahmad سؤال في أخذ مدخلات متعددة من المستخدم في بايثون كانت الإجابة المقبولة
السؤال غير محدد جيدًا، ولكن سأغطي كل الاحتمالات التي قد تتم مصادفتها أثناء الإدخال.
من المعروف في بايثون أننا نستخدم الدالة input لكافة أنواع المدخلات، حيث تستقبل المدخلات مهما كان صنفها على شكل سلسلة String، ثم نحوّلها إلى الصنف المطلوب، فمثلاً لإدخال سلسلة نكتب:
s=input() لإدخال عدد صحيح نكتب:
s=input() myIntegerNumber=int(s) # أو اختصاراً myIntegerNumber=int(input()) لكن في حال الحاجة إلى أن يكون الدخل من المستخدم على شكل قيم أو مدخلات متعددة أو إدخال في سطر واحد، في لغات مثل السي و السي++ يمكن القيام بذلك من خلال دالة scanf لكن في بايثون يمكن القيام بذلك من خلال إحدى الطرق التالية:
من خلال الدالة: input().split(separator, maxsplit) فبما أن الدخل يكون على شكل String، فهذا يعني قدرتنا على استخدام الدالة split على خرج الدالة.
مثال: في حالتك، وبما أن المدخلات هما قيمتين دفعة واحدة فيمكننا إدخالهما بالشكل التالي.
x, y = input().split() أخذ 3 مدخلات:
x, y, z = input().split() أخذ عدة مدخلات دفعة واحدة (أعداد صحيحة)، ووضع المدخلات ضمن قائمة:
myList = list(map(int, input().split()))
من خلال مفهوم "اشتمال قائمة" list comprehension، حيث يمكننا استخدامه لأخذ مدخلات متعددة كما يلي.
إدخال عددين صحيحين:
x, y = [int(x) for x in input().split()] أخذ عدة مدخلات دفعة واحدة:
myList = [int(x) for x in input().split()]
-
إجابة Ali Haidar Ahmad سؤال في كيفية الحصول على معرف صفحة من خلال URL في فلاسك Flask؟ كانت الإجابة المقبولة
ربما بإمكانك استخدام التعابير المنتظمة regex للقيام بذلك، مثلاً:
from flask import Flask from werkzeug.routing import BaseConverter class RegexConverter(BaseConverter): def __init__(self, url_map, *items): super().__init__(url_map) self.regex = items[0] app = Flask(__name__) app.url_map.converters['regex'] = RegexConverter @app.route('/page<regex("\d+"):page_id>/') def page(page_id): return f"Page ID: {page_id}" if __name__ == '__main__': app.run()
-
إجابة Ali Haidar Ahmad سؤال في التنعيم Regularaization باستخدام L1-Lasso و L2-Ridge كانت الإجابة المقبولة
كلاهما يستخدم لمحاربة (أو معالجة) مشكلة الضبط الزائد Overfitting.
L1 ( L1 lasso or norm):
يقوم بمحاربة ال OF عن طريق تصغير قيم الأوزان المرتبطة بالميزات feature الأقل أهمية باتجاه ال 0، مما يجعل تأثير بعض ال feature مهمل لأنه يجعل قيم بعض الأوزان صفرية تماماً، ويمكن اعتبار ذلك نوعاً من أنواع اختيار الميزات feature selection، ويعتمد على إضافة حد جديد الى تابع الكلفة (يُسمى معاقبة penalty) يمثل مجموع القيم المطلقة للأوزان مضروباً بمعامل تحكم لمدا (زيادتها تؤدي إلى زيادة تأثير هذه العملية وتصغيرها يؤدي إلى العكس، وهي قيمة بين ال 0 وال 1 وتعتبر من المعاملات العليا HyperParameter التي يجب ضبطها).
المعادلة المعبرة عنه:
أي أنها تعتمد على إضافة مجموع القيم المطلقة للأوزان مضروباً بمعامل تحكم (لمدا)، إلى تابع الكلفة المستخدم.
L2 (L2 ridge):
يقوم بمحاربة ال OF عن طريق تصغير قيم الأوزان ولكن لا يجعلها صفرية، ويعتمد على إضافة حد جديد إلى تابع الكلفة يمثل مجموع مربعات الاوزان مضروبا بمعامل تحكم لمدا.
المعادلة المعبرة عنه:
أي أنها تعتمد على إضافة مجموع مربعات للأوزان مضروباً بمعامل تحكم (لمدا)، إلى تابع الكلفة المستخدم.
هناك فروق أخرى يمكن استنتاجها من هذا الكلام ،مثل أن L1 أكثر متانة من L2 بسبب قدرته على التعامل مع القيم الشاذة، في حين أن L2 يعاني من مشكلة القيم الشاذة (أو المتطرفة).
أيضاً L1 يقوم ضمنيّاً بعملية feature selection، وهذا قد يكون له أثر سلبي لبعض المهام، بينما L2 لا يقوم بذلك أبداً.
يعتبر أيضاً L1 تمثيل متناثر Sparse لأن عدد الأصفار يزداد نتيجة تصفير بعض الأوزان على عكس L2 الذي يعتبر كثيف Dense.
-
إجابة Ali Haidar Ahmad سؤال في كيفية الحصول على اسم النموذج model في جانغو Django؟ كانت الإجابة المقبولة
استخدم:
Article.__name__ نماذج Django ترث من ModelBase، حيث أنه يمثل صنف علوي "Metaclass" لجميع النماذج.
-
إجابة Ali Haidar Ahmad سؤال في إيجاد طول سلسلة في C++ كانت الإجابة المقبولة
الإجابة بسيطة، تتطلب منك معرفة الأساسيات فقط. سأكتب لك كافة الطرق، وأنت نظمها وأكمل حسب المطلوب:
في لغة السي يمكنك إيجاد طول السلسلة بالشكل التالي:
#include <stdio.h> #include <string.h> int main() { // نقوم بتعريف مصفوفة من المحارف لتخزين السلسلة الناتجة فيها char myStr[100]; // تعريف متغير سنستخدمه داخل الحلقة // القيمة النهائية لهذا المتغير ستمثل طول السلسلة أيضاً int i; // لإدخال السلسلة scanf نستخدم الدالة scanf("%s", myStr); // i نقوم بتعريف حلقة فارغة تقوم بزيادة قيمة المتغير // myStr وتتوقف عندما تجد المحرف الذي يدل على نهاية السلسلة في المصفوفة for (i = 0; myStr[i] != '\0'; ++i); // أخيراً نطبع طول السلسلة printf("Length of Str is %d", i); return 0; } لإيجاد طول سلسلة في c++ فالأمر مشابه لكن أبسط:
#include <iostream> #include <string.h> using namespace std; int main() { string str = "Hi"; int i = 0; for (i = 0; str[i]; i++); cout << i << endl; return 0; } هناك دوال جاهزة أيضاً لإتمام الأمر مثل length و size، أعرف أنك لاتحتاج لطريقة جاهزة لكن سأضعها للآخرين:
#include <iostream> using namespace std; int main() { string str = "C++ Programming"; // str.length() يمكنك أيضاً استخدام cout << "String Length = " << str.size(); return 0; } طريقة أخرى بأسلوب C-style من خلال استخدام الدالة strlen:
#include <iostream> #include <cstring> using namespace std; int main() { char str[] = "C++ Programming"; cout << "String Length = " << strlen(str); return 0; }
-
إجابة Ali Haidar Ahmad سؤال في ما هو المقصود بالاستثناءات exceptions في لغة جافا؟ كانت الإجابة المقبولة
بالنسبة للسؤال الأول المذكور في العنوان "ما هو المقصود بالاستثناءات Exception"؟
الاستثناء هو حدث غير مرغوب فيه أو غير متوقع، يحدث أثناء تنفيذ البرنامج أي في وقت التشغيل run time أو في وقت الترجمة compile time، مما يعطل التدفق الطبيعي لتعليمات البرنامج.
ملاحظة: هناك فرق بين الخطأ Error والاستثناء، فالخطأ هو مشكلة تحدث بشكل رئيسي بسبب نقص موارد النظام lack of system resources في وقت التشغيل، ولا يمكن التقاطه أو معالجته.
أمثلة على هذه الأخطاء هي OutOfMemoryError و LinkageError و AssertionError، إلخ.. وهي جميعاً تمثل صفوفاً فرعية subclasses من الصف Error.
لكن يشترك الخطأ والاستثناء في أنهما صفوف فرعية من الصف Java Throwable التي تنتمي إلى حزمة java.lang.
لن أدخل أكثر في تفاصيل الفروق بينهما لكي لانبتعد عن السؤال الأساسي.
بالنسبة للسؤال الثاني "ما هي انواع الاستثناءات في لغة جافا"؟
فهناك نوعين من الاستثناءات:
Checked Exceptions: تعني خطأ برمجي يحدث أثناء ترجمة البرنامج، وهي استثناءات يجب أن يتم التقاطها ومعالجتها من خلال كتلة catch أو من خلال جملة throws وإلا ستتسبب في إنهاء البرنامج وطباعة رسالة تتبع المكدس stack trace (تقرير عن إطارات المكدس النشطة في نقطة معينة من الوقت أثناء تنفيذ برنامج).
أمثلة على هذه الاستثناءات هي SQLException و IOException و File Not Found Exception و No Such Field Exception و Interrupted Exception و No Such Method Exception و Class Not Found Exception إلخ..
مثال برمجي: public class Main { public static void main(String[] args) { int s; s = "'s' should be String"; } } رسالة الخطأ:
Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - incompatible types: java.lang.String cannot be converted to int هذا الخطأ يعني أن هناك مشكلة في النوع المستخدم لتخزين البيانات.
ثم أخبرنا بسبب المشكلة و هي أنه لا يمكن تحويل الـString ل int , أي لا يمكن تخزين قيمة نوعها String في متغير نوعه int.
Unchecked Exception: تعني خطأ منطقي يحدث أثناء تشغيل البرنامج run time، وهذا النوع من الاستثناءات لايجب معالجته أو التقاطه أبداً، ولايقوم المترجم بالكشف عن هكذا استثناءات (أي على عكس النوع السابق)، حيث تقع على عاتق المبرمج مسؤولية التأكد من عدم حدوث هذه الأخطاء.
أمثلة على هذه الاستثناءات No Such Element Exception و Undeclared Throwable Exception و Empty Stack Exception و Arithmetic Exception و Null Pointer Exception و Array Index Out of Bounds Exception و Security Exception و ArrayIndexOutOfBoundException.
مثال برمجي: public class Main { public static void main(String[] args) { int[] arr = { 4, 5 }; System.out.println( arr[6] ); } } Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 6 هذا الخطأ يعني أن العنصر ليس موجود في المصفوفة، ثم أخبرنا بسبب المشكلة و هي أنه لم يجد عنصر يحمل الـ index رقم 6.
-
إجابة Ali Haidar Ahmad سؤال في كيفية الحصول على قيمة الأسكي Ascii لحرف في لغة البايثون كانت الإجابة المقبولة
يمكنك استخدام الدالة ()ord، حيث نمرر لهذه الدالة محرفاً وتُرجع لنا عدداً صحيحاً يمثل قيمة الآسكي المقابلة لهذا المحرف.
مثال:
ord('a') الخرج:
97 وللتحويل المعاكس (أي من عدد صحيح إلى المحرف الذي يقابله حسب ترميزالآسكي):
char(97) والخرج:
'a' تحتوي الأكاديمية على العديد من المقالات عن لغة بايثون، يمكنك الاطلاع عليها من هنا.
-
إجابة Ali Haidar Ahmad سؤال في تنسرفلو كانت الإجابة المقبولة
الهدف منه أنه في كل مرة يتم فيها تنفيذ الكود نحصل على نفس النتائج، لأن تقسيم الداتاسيت يكون عشوائي وبذلك تكون قدد ضمنت أن تقسيم الداتاسيت سيكون نفسه، أي بمعنى آخر، ستحصل على نفس التقسيم للداتاسيت في كل مرة تقوم بها بتنفيذ الكود.
هذا الأمر مهم جداً ولاسيما في الحالات التي تريد فيها مقارنة أداء عدة خوارزميات على نفس الداتاسيت أو حتى أثناء القيام بعملية ضبط المعاملات العليا للنموذج (Hyper-Parameters)، فعلى فرض تريد تجريب أداء خوارزمية SVM و LR على هذه البيانات فمن المفترض أن يتم القياس على أساس نفس الداتاسيت ونفس التقسيم، لأن اختلاف تقسيم البيانات يؤدي إلى نتائج مختلفة.
نقول أن الهدف من ذلك هو Reliability أي الموثوقية.
الموثوقية في الإحصاء والقياسات النفسية هي التطابق العام للقياس. يُقال إن المقياس يتمتع بموثوقية عالية في حال نتج عنه نتائج مماثلة في ظل ظروف ثابتة.
-
إجابة Ali Haidar Ahmad سؤال في شرح كود بايثون كانت الإجابة المقبولة
تم تمرير المُعطىs1 للوسيط s الذي يعبر عن حجم نقاط البيانات، حيث تعطى مصفوفة تحوي حجم كل نقطة، وبناءان على ذلك ستأخذ أول نقطة (1,2) حجم 100، في حين تأخذ النقطة الثانية (2,3) حجم 200 وهذا يظهر جلياً عند تنفيذك الكود حيث تكون أحجام النقط مختلفة.
على الجانب الآخر c1 أعطيت ل c وهي لكي لا تأخذ كل نقطة نفس اللون أي لكي يكون لدينا ألوان مختلفة فلو كان مثلاً لدينا:
c1=[1, 1, 3, 4, 5] ونفذنا الكود:
import matplotlib.pyplot as plt import numpy as np x=[1,2,3,4,5] y=[2,3,1,10,12] s1=[100,200,50,400,600] c1=[1, 1, 3, 4, 5] plt.scatter(x, y, c=c1, s=s1) plt.colorbar()
سوف تكون لون النقطة الأولى نفس لون النقطة الثانية لأنهما تأخذان قيمة واحدة، على عكس باقي النقاط، حيث تأخذ كل نقطة لون لأنه يوجد 3,4,5 قيم مختلفة.
-
إجابة Ali Haidar Ahmad سؤال في أيهما أفضل؟ تطبيق البرنامج باستخدام مكتبات جاهزة أم باستخدام لغة بايثون فقط كانت الإجابة المقبولة
بالتأكيد أفضل، ولاسيما إذا كنت مبتدءاً أو متوسط الخبرة، لا داع لإعادة اختراع العجلة إذا كانت موجودة ومن مصادر موثوقة مثل Sklearn أو Orange أو Keras أو أي إطار عمل آخر.
أُطر العمل هذه (المكتبات) يتم بناؤها من قبل فرق بحثية لديها خبرة طويلة في المجال وهي مُدققة ومُجربة ومُحسنة وخالية من الأخطاء.
الحالة الوحيدة التي اقترح عليك فيها بناء الخوارزمية بمفردك (وأشجع على ذلك) هي في حال كنت تريد التعلم (فهم كيف تعمل هذه الخوارزميات).
على سبيل المثال، في بداية تعلمي قمت ببرمجة خوازمية التصنيف اللوجستي و خوارزمية التوقع الخطي وبناء شبكات عصبونية بنوعيها (Deep&Shallow) وحتى شبكات من نوع RNN ثم بدأت أضيف لهذه الأكواد المزيد من الخصائص و المزيد من ال Optimization method، وكانت غايتي فقط التعلم.
أما الآن فأنا استخدم أُطر العمل الجاهزة لإنجاز المهام، وهذا مايقوم به جميع المبرمجين، فكل مايهمك هو معرفة ماتقوم به الخورازمية وكيف تتعامل معها.
الكلام المذكور أعلاه يؤكد عليه الدكتور جايسون براونلي.
-
إجابة Ali Haidar Ahmad سؤال في كيفية تخزين الملفات الثابتة من أكثر من مجلد في فلاسك Flask؟ كانت الإجابة المقبولة
اعتقد أنه يمكنك القيام بذلك من خلال نهج مشابه للنهج التالي، حيث أن CUSTOM_STATIC_PATH هو متغير يتم تعريفه ضمن التكوين (configuration) الخاص بك.
@app.route('/cdn/<path:filename>') def custom_static(filename): x=send_from_directory(app.config['CUSTOM_STATIC_PATH'], filename) return x وضمن القالب:
{{ url_for('custom_static', filename='foo') }}
-
إجابة Ali Haidar Ahmad سؤال في كيفية حذف الجلسة session الحالية في فلاسك Flask؟ كانت الإجابة المقبولة
يمكنك حذف الجلسة كالتالي:
from flask import session session.clear() حل آخر وجدته من الخلال المرور على session واستدعاء الدالة () session.pop على كل مفتاح في ال session:
for key in list(session.keys()): session.pop(key) // تقوم بحذف المتغير من الجلسة pop
-
إجابة Ali Haidar Ahmad سؤال في ما هو التغليف Encapsulation في لغة جافا؟ كانت الإجابة المقبولة
- التغليف هو أشبه بكبسولة الدواء التي تحتوي داخلها خليطاً من المواد الطبية.
- يعتبر التغليف أحد المفاهيم الأساسية في البرمجة الشيئية (OOP).
- إليك عدة تعاريف لمفهوم التغليف (Encapsulation):
هو العملية التي نقوم من خلالها بتغطية الكود والبيانات مع بعضها ضمن وحدة واحدة. هو فكرة مضمونها تجميع البيانات والطرق التي تعمل على تلك البيانات في وحدة واحدة، على سبيل المثال ، Class في Java. هو عبارة عن أسلوب يمكن اتباعه لإخفاء البيانات الأساسية في الكلاس, أي لإخفاء الخصائص الموجودة فيه ( Global Variables ), و جعل الكلاسات الأخرى قادرة على التعامل مع هذه الخصائص فقط من خلال دوال يقوم بإنشائها المبرمج الأساسي للكلاس. - من الناحية العملية، فإنه في التغليف، يتم إخفاء المتغيرات أو البيانات الخاصة بالكلاس عن أي كلاء آخر ولا يمكن الوصول إليها إلا من خلال دالة عضو من نفس الكلاس.
- يتم تحقيق مبدأ التغليف عن طريق التصريح عن جميع المتغيرات في الكلاس كمتغيرات خاصة (private) وكتابة طرق (دوال) عامة (public) في الكلاس لتعيين قيم المتغيرات والحصول عليها.
- فوائد التغليف:
من خلال توفير طريقة (دالة) setter أو getter فقط، يمكنك جعل الكلاس للقراءة فقط أو للكتابة فقط (زيادة المرونة) على سبيل المثال، إذا أردنا جعل الكلاس قابل للقراءة فقط "class read-only" نقوم بحذف دوال الضبط setter، وفي حال أردنا جعله للكتابة فقط نقوم بحذف دوال ال getter. يوفر لك التحكم في البيانات. طريقة لتحقيق إخفاء البيانات في Java. لن يكون لدى المستخدم أي فكرة عن التنفيذ الداخلي للكلاس، حيث لن يكون مرئياً للمستخدم كيف يخزن الكلاس القيم في المتغيرات. سيعرف المستخدم فقط أننا نقوم بتمرير القيم إلى طريقة الضبط setter ويتم تهيئة المتغيرات بهذه القيمة الممررة. قابلية إعادة الاستخدام: يحسن التغليف أيضاً من قابلية إعادة الاستخدام ويسهل تغييره مع المتطلبات الجديدة. مثال:
سنعطي الآن مثالاً بسيطاً للتغليف، حيث سنقوم بتعريف كلاس يحقق مبدأ التغليف و يحتوي على حقل واحد فقط مع دالة setter ودالة getter.
package com.javaproject; public class Student{ // private هنا قمنا بتعريف متغير يمثل اسم الطالب وحددنا الوصول إليه ك private String studentName; // هنا قمنا بتعريف متغير للحصول على هذا المتغير // getter أي أننا عرفنا دالة public String getName(){ return studentName; } // هنا قمنا بتعريف دالة لضبط قيمة هذا المتغير // أي قمنا بتعريف دالة تقوم بتحديد اسم الطالب // setter أي أننا عرفنا دالة public void setName(String studentName){ this.studentName=studentName; } } الآن سنقوم باختبار الكلاس السابق الذي قمنا بتغليفه:
package com.javatproject; class Test{ public static void main(String[] args){ // إنشاء كائن من الكلاس السابق // أو بمعنى آخر تعريف طالب Student stu=new Student(); // تحديد اسم لهذا الطالب stu.setName(Ali"); // طباعة اسم هذا الطالب System.out.println(stu.getName()); } }
-
إجابة Ali Haidar Ahmad سؤال في ما هو مفهوم تعدد الأشكال Polymorphism في لغة جافا؟ كانت الإجابة المقبولة
تُستخدم هذه الكلمة في سياقات مختلفة لتصف الحالات التي يكون فيها شيء ما في عدة أشكال مختلفة. غالباً يمكننا القول أنه شكل واحد رئيسي وينبثق منه أشكال فرعية يسهل التعامل معها،على سبيل المثال بناء دالة تنفذ أوامر مختلفة على حسب الكائن الذي نمرره لها عند إستدعاءها.
في العادة تعدد الأشكال يكون مربتط بشكل أساسي بالأصناف و الوراثة حيث تكون الدالة مبنية على أساس الصنف الأب، و لكننا عند إستدعاءها نمرر لها كائن من إحدى الأصناف التي ترث منه والتي تحتوي نفس الدوال لكن بتعريفات خاصة كما سنرى في المثال بعد قليل، لكن بصورة عامة فإن تعددية الأشكال مفهوم غير محصور فقط بالأصناف والوراثة وسأعطي الآن أمثلة على حالات مختلفة ومنوعة من تعددية الأشكال وبلغات برمجية مختلفة.
على سبيل المثال في لغة بايثون هناك الدالة len التي تحقق مبدأ تعددية الأشكال:
# len هنا قمنا بتمرير سلسلة نصية للدالة print(len("ali")) # len للدالة list بينما هنا قمنا بتمرير قائمة print(len([20, 30])) خرج البرنامج:
3 2 حيث قمنا بتمرير سلسلة نصية في البداية لهذه الدالة فأعطتنا طولها (عدد الأحرف)، ثم في المرة الثانية قمنا بتمرير قائمة، فأعطتنا عدد عناصرها، هذا مثال لتعددية الأشكال، حيث أن الدالة len تسلك سلوكاً مختلفاً بناءان على معطياتها.
مثال آخر لتعددية الأشكال:
def add(a, b, c = 0): return a + b+c print(add(10, 33)) print(add(20, 2, 5)) حيث قمنا بتعريف دالة add يمكنها جمع عددين أو 3 أعداد (الوسيط c يأخذ القيمة 0 بشكل افتراضي (أي في حال لم تمرر لها قيمة) وهي قيمة محايدة لعملية الجمع)، ثم قمنا باستدعاء الدالة مرتين، الأولى لجمع عددين والثانية لجمع 3 أعداد، هذا مثال آخر بسيط لتعددية الأشكال.
مثال آخر لتعددية الأشكال لكن هذه المرة مع الأصناف:
# تعرف صنف يمثل بلد class Syria(): def capital(self): print("Damascus") def language(self): print("Arabic") # تعريف صنف يمثل بلد آخر class England(): def capital(self): print("London") def language(self): print("English") # إنشاء كائن يمثل البلد الأول obj_sy = Syria() # إنشاء غرض ثاني يمثل البلد الثاني obj_eng = England() # obj_eng ومرة إلى الكائن obj_sy يشير مرةً إلى الكائن country الآن سنجعل متغير الحلقة # وفي كل مرة سيستدعي نفس الدوال # وهذه صورة أخرى من أشكال تعددية الأشكال for country in (obj_sy, obj_eng): country.capital() country.language()
- الآن سنعطي مثالاً آخر لتعددية الأشكال لكن هذه المرة مع الوراثة ومع لغة أخرى هي الجافا، حيث أن أحد الاستخدامات الشائعة لمفهوم تعددية الأشكال يحدث عندما يكون لدينا مرجع من صف أب (نسميه مقبض)يشير إلى كائن من صف ابن.
لنفرض مثلاً لدينا شاحنة ونريد نقل مجموعة سيارات بحيث كل شاحنة تتسع ل 10 سيارات ، وتنقل نوع واحد من السيارات ( يمكن تشبيه الشاحنة بمصفوفة تضم عناصر من نمط واحد ).
لنفرض لدينا نوعين من السيارات نريد أن ننقلهم 4:BMW و 4:AUDI
حسب الشروط المفروضة سنحتاج شاحنتين في كل واحدة سنضع 4 من نفس النوع ..
الفكرة أن الشاحنة الواحدة (مصفوفة ) لا تحمل نوعين لكنها تتسع للعدد الكلي ، أي أننا قمنا بعملية نقل صحيحة لكنها مكلفة ( حجزنا شاحنة ويوجد أماكن فارغة بالأولى + ماذا لو كان لدينا أكثر من نوعين .. )
الحل : يجب أن نبحث عن شاحنة ( مصفوفة) تحمل النوعين، ونعلم أن المصفوفة لا تحمل الا نوع واحد، ما العمل؟
هنا تأتي " تعددية الأشكال" بأن نعرف صف أب للصفين السابقين وليكن Carونرث منه الصفين BMW و AUDI ونأخذ مصفوفة مقابض من Car ( نمط واحد ) وكل عنصر (مقبض) نجعله يشير الى الكائن المطلوب ( BMW أو AUDI ).
وهكذا نكون قد حللنا المشكلة و خزنا كائنات من صفوف مختلفة بمصفوفة واحدة
مثال : (يمكن نسخ الكود وتنفيذه لملاحظة النتائج):
package javaapplication29; class Car { void type () { System.out.println("car");} } class BMW extends Car { @Override void type () { System.out.println("BMW");} } class AUDI extends Car { @Override void type () { System.out.println("AUDI");} } public class JavaApplication29 { public static void main(String[]args ){ Car[]c =new Car[8]; //نعبئ أربع سيارات BMW for( int i=0; i<4 ; ++i ) c[i] = new BMW(); //نعبئ أربع سيارات AUDI for( int i=4; i<8 ; ++i ) c[i] = new AUDI(); //تعليمة طباعة للتأكد من أنه تم تعبئة النوعين for( int i=0; i<8 ; ++i ) c[i].type(); } } مثال آخر:
// الفئة الأم (الأشكال) class Shapes { public void area() { System.out.println("The formula for area of "); } } // فئة المثلثات class Triangle extends Shapes { public void area() { System.out.println("Triangle is ½ * base * height "); } } // فئة الدوائر class Circle extends Shapes { public void area() { System.out.println("Circle is 3.14 * radius * radius "); } } class Main { public static void main(String[] args) { Shapes myShape = new Shapes(); // إنشاء كائن الأشكال Shapes myTriangle = new Triangle(); // إنشاء كائن المثلثات Shapes myCircle = new Circle(); // إنشاء كائن الدوائر myShape.area(); myTriangle.area(); myShape.area(); myCircle.area(); } نلاحظ أنه في كل كائن نستعمل الدالة ()area بشكل مختلف حسب طبيعة الكائن و هذا ما يسمى ب polymorphism.
- الآن سأعطي مثالاً آخر لتعددية الأشكال لكن بلغة برمجية أخرى هي لغة الأسس (مشابهة جداً للغة ال C):
لتحقيق مبدأ تعددية الأشكال مع الأصناف في هذه اللغة يجب أن نقوم بتعريف الدوال كمؤشرات، وهذا يتم من خلال إضافة الكلمة المفتاحية as_ptr للأمر handler (بشكل مشابه للكلمة المفتاحية virtual في c++).
فلنفترض أن لدينا الصنف التالي:
class A { handler this.set(i: Int) as_ptr { ... } } في التعريف أعلاه، سيضيف المترجم إلى الصنف A مؤشراً على الدالة set. وهذا يُمكّن الكائنات المشتقة من A (التي تقوم بوراثتها) من تخصيص الدالة عبر تغيير قيمة المتغير. مثلاً:
class B { @injection def a: A; handler this.set(i: Int) set_ptr { ... } } في هذا التعريف الصنف B يشتق من الصنف A ثم يغير مؤشر الدالة set (باستخدام الكلمة المفتاحية set_ptr) لتعريف خاص ب B.
الآن لو كان هناك دالة تستلم سنداً أو مؤشراً على A فيمكنك إعطاؤها سنداً ل B وستراه الدالة على أنه صنف A مع دالة set خاصة ب B.
قد تكون الأمور غامضة قليلاً، لكنها ستتضح في المثال التالي...
قمنا بتعريف صنف اسمه Country يحوي 3 دوال لم يحدد متنها (body).
بعدها قمنا بتعريف صنف اسمه Canda و صنف اسمه Syria يرثان من الصنف Country و كل منهما يحتوي تعريفاً خاصاً لنفس الدوال الموجودة في الصنف الأب Country.
بعدها قمنا بإنشاء دالة اسمها printCountryInfo مهمتها استدعاء جميع الدوال الموجودة في الكائن الذي نمرره لها بشرط أن يكون هذا الكائن قد تم إنشاؤه من صنف يرث من الصنف Country، حيث أن هذه الدالة تستلم سنداً من الصنف الأب.
في النهاية قمنا بإنشاء كائن من الصنف Canda و كائن من الصنف Syria و تمرير كل كائن منهما للدالة printCountryInfo.
import "Srl/Console.alusus" use Srl.Console; // تعريف صنف يمثل بلد class Country { // دالة سنستخدمها لطباعة اسم البلد handler this.name() as_ptr; // دالة سنستخدمها لطباعة العاصمة handler this.capital() as_ptr; // دالة سنستخدمها لطباعة اللغة handler this.language() as_ptr; } // تعريف صنف يمثل بلد محدد هو كندا class Canda { // country سنقوم الآن بوراثة الصنف @injection def country: Country; // تعريفاً مخصصاً Country الآن سنقوم بتعريف الدوال الموجودة في الصنف handler (this:Country).name() set_ptr{ print("Country: Canda\n") } handler (this:Country).capital() set_ptr{ print("Capital: Ottawa\n") } handler (this:Country).language() set_ptr{ print("Language: English\n") } } // تعريف صنف آخر يمثل بلد محدد هو سوريا class Syria { @injection def country: Country; handler (this:Country).name() set_ptr{ print("Country: Syria\n") } handler (this:Country).capital() set_ptr{ print("Capital: Damascus\n") } handler (this:Country).language() set_ptr{ print("Language: Arabic\n") } } // Country دالة تقوم باستلام سند من الصنف // ثم في متن هذه الدالة سنقوم باستخدام السند للوصول إلى الدوال function printCountryInfo(re:ref[Country]){ re.name() // تؤدي إلى طباعة اسم بلد re.capital() // العاصمة re.language() // اللغة print("\n********************\n") } // Canda إنشاء كائن من الصنف def obj1: Canda; // لطباعة معلومات هذا البلد printCountryInfo سنقوم الآن بتمريره إلى الدالة printCountryInfo(obj1) // Syria سنكرر الآن نفس الأمر لكن مع كائن من الصنف def obj2: Syria; printCountryInfo(obj2) /* Country: Canda Capital: Ottawa Language: English ******************** Country: Syria Capital: Damascus Language: Arabic ******************** */ هكذا نكون قد كتبنا دالة بسيطة تحقق مبدأ تعددية الأشكال.
مقال ذات صلة:
سؤال ذات صلة:
-
إجابة Ali Haidar Ahmad سؤال في ماهي elbow method و wcss ؟ كانت الإجابة المقبولة
غالباً ما تكون البيانات التي ستعمل عليها أبعاد متعددة مما يجعل من الصعب عرضها بيانياً أو تخيلها. وبالتالي لايكون العدد الأمثل للمجموعات واضحاً. لكن لحسن الحظ هناك طريقة لتحديد ذلك رياضياً وهي elbow method:
elbow method هي طريقة لإيجاد عدد العناقيد (ال ـClusters) في خوارزمية K-Means، أو بمعنى آخر هي طريقة لإيجاد قيمة K في خوارزمية K-Means.
نقوم برسم بياني يعبر عن العلاقة بين WCSS (Within Cluster Sum of Squares) و عدد العناقيد (ـClusters)، ثم نختار عدد العناقيد number of clusters عندما يبدأ التغيير في WCSS في الاستقرار.
بالنسبة ل WCSS فهي مجموع مربعات الفرق بين كل عضو في ال Cluster ومركزها.
الرسم البياني يعبر عن هذا الكلام حيث أن قيم K من 1 إلى 10 ويتم حساب قيمة WCSS المقابل لكل منها، كلما زاد عدد المجموعات ، ستبدأ قيمة WCSS في الانخفاض. تكون قيمة WCSS أكبر عندما تكون K = 1. عندما نحلل الرسم البياني ، يمكننا أن نرى أن الرسم البياني سيتغير بسرعة عند نقطة ما ، وبالتالي إنشاء شكل مرفق أو كوع (Elbow). من هذه النقطة ، يبدأ الرسم البياني في التحرك بشكل موازٍ للمحور السيني تقريباً (استقرار). قيمة K المقابلة لهذه النقطة هي قيمة K المثلى أو العدد الأمثل من المجموعات:
elbow method هي أفضل طريقة موجودة لإيجاد قيمة K.
لاتوجد مساوئ تذكر..
-
إجابة Ali Haidar Ahmad سؤال في تصحيح الجمل و الكلمات الخاطئة (بايثون) كانت الإجابة المقبولة
اقترح عليك استخدام مكتبة textblob حيث أنها تحتوي دالة تدعى correct تستخدم من أجل هذا الغرض، انظر إلى المثال التالي:
# استيراد المكتبة from textblob import TextBlob # TextBlob نقوم بتمرير الحملة إلى باني الصف tbObj = TextBlob("I amm goodd at speling mstake.") # tbObj من الكائن correct نقوم باستدعاء الدالة res = tbObj.correct() print(res) الخرج:
I am good at spelling mistake. بالنسبة لمثالك وكونه لديك قائمة من الجمل ستحتاجيه لإنشاء حلقة تكرارية للمرور عليها:
from textblob import TextBlob l=["Titanic is a 1997 Americn epic roance and diaster film dircted, writen, prodced, and co-edited by James Cameron.", "The Shawshank Redemption is a move produced by Niki Marvin and directed by Frank Darabont."] for sent in l: tbObj = TextBlob(sent) print(tbObj.correct()) """ Titanic is a 1997 American epic romance and disaster film directed, written, produced, and co-edited by James Cameron. The Shawshank Redemption is a move produced by Wiki Margin and directed by Rank Darabont. """
-
إجابة Ali Haidar Ahmad سؤال في انشاء dynamic 2D array to store products كانت الإجابة المقبولة
أنت تريد مصفوفة ديناميكية بلغة C++ لتخزين هذه المعلومات. إن عملية إنشاء مصفوفة ديناميكية في هذه اللغة منخفض المستوى قليلاً، سأعطيك الخطوات لذلك وسأعطيك بعدها رأس الخيط لحل مسألتك وأنت أكمل.
لتخصيص الذاكرة ديناميكياً نستخدام الدالة malloc أو calloc (وهاتين الدالتين أصلهما لغة السي) أو المؤثر new (وهذا ماسنستخدمه الآن لحجز الذاكرة -الخيار المستحسن-). الآن لإنشاء مصفوفة ديناميكية ثنائية البعد نقوم أولاً بالإعلان عن متغير مؤشر ل مؤشر أي بمعنى:
data type **pointer-variable; سنجعل صنف البيانات هو int وسيكون اسم المتغير arr إذاً سنكتب:
int** arr; الآن نقوم بحجز ذاكرة لصف أو سطر (row) سيحتفظ بمرجع للعمود column أي:
arr = new int*[row]; ثم نقوم بتخصيص مساحة للأعمدة باستخدام المؤثر new في كل خلية صف والتي ستحتوي على القيم الفعلية لعناصر المصفوفة أي بمعنى:
arr[i] = new int[col]; الكلام السابق يوضحه المخطط التالي:
والكود التالي هو تحقيق لما سبق:
#include <iostream> using namespace std; int main() { // نقوم بتعريف المؤشر للمؤشر int** array; // نقوم بتعريف متغيرين يمثلان عدد الأسطر والأعمدة المطلوبين int row, col, i, j; // نطلب إدخالهما من المستخدم cin >> row; cin >> col; // حجز ديناميكي للصف array = new int*[row]; // حجز ديناميكي للعمود for(i=0; i<row; i++){ array[i] = new int[col]; } //إدخال عناصر المصفوفة for(i=0; i<row; i++){ for(j=0; j<col; j++){ cin >> array[i][j]; } } // تحرير الذاكرة بعد الانتهاء من استخدام المصوفة delete [] array; } لطباعة عناصر المصفوفة يمكنك استخدام الدالة التالية:
void display(int** a, int r, int c){ for(int i=0; i<r; i++){ for(int j=0; j<c; j++){ cout << a[i][j] << ' '; } cout << endl; } } ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
الآن بالنسبة لمسألتك فيمكنك إتمامها من خلال تعريف مصفوفة ديناميكية كما في المثال السابق لكن يجب أن تكون عناصرها struct أو class يحتوي ال Product information.
-
إجابة Ali Haidar Ahmad سؤال في تحويل كود بايثون الى ملف تنفيذي كانت الإجابة المقبولة
يمكنك القيام بذلك من خلال مكتبة pyinstaller، من خلال الخطوات التالية:
1. تحميل المكتبة:
pip install pyinstaller 2. اذهب إلى المجلد الذي يحتوي على ملف بايثون الخاص بك (يكون امتداده py. أو ipynb. في حال قمت بكتابته باستخدام jupyter notebook).
3.اضغط على زر shift وانقر بزر الماوس الأيمن في نفس الموقع. سوف تحصل على المربع أدناه.
ثم انقر على "Open PowerShell window here".
ستحصل على نافذة كالتالي:
اكتب الأمر التالي في التيرمنل:
pyinstaller --onefile -w 'filename.py' حيث أن filename هو اسم الملف و py. هو امتداده (في حالتنا اسم الملف هو "1"). لذا سنكتب:
pyinstaller --onefile -w '1.py' بعد ذلك سيقوم بتحويله إلى ملف exe ووضعه ضمن مجلد جديد باسم dist ضمن نفس المسار والاسم لكن بامتداد exe.
-------------------------------------------------------------------------------------------------------------------------------------------------
هناك طريقة أخرى من خلال استخدام auto-py-to-exe وهي أكثر سهولة:
1. قم يتثبيت الأداة:
pip install auto-py-to-exe 2. بعد ذلك اضغط على القائمة ابدأ واكتب في مربع البحث:
auto-py-to-exe أو من خلال التيرمنل اكتب ونفذ الأمر التالي:
auto-py-to-exe ستظهر لك أيقونة الأداة، اضغط عليها فتظهر بالشكل:
كل ماعليك فعله الآن هو الضغط على زر Browse وتحديد ملف بايثون المطلوب.
لمزيد من التفاصيل حول هذه الأداة يمكنك زيارة التوثيق هنا.
-
إجابة Ali Haidar Ahmad سؤال في مكتبة fuzzy_expert لاتعمل كانت الإجابة المقبولة
هل قمت بتثبيت المكتبة fuzzy_expert؟
في حال لم تقم بتثبيتها، يجب عليك تثبيتها من خلال فتح التيرمنل وتنفيذ الأمر التالي:
pip install fuzzy_expert أو في حال كنت تستخدم google colab:
!pip install fuzzy_expert في حال قمت بتثبيتها واستمرت المشكلة، قم بتنفيذ الأمر التالي في التيرمنل فغالباً ستكون المكتبات الأساسية الموجودة لديك قديمة:
python -m pip install --user numpy scipy matplotlib ipython jupyter pandas sympy nose ولا اعتقد ستحتاج لشيء آخر..
-
إجابة Ali Haidar Ahmad سؤال في ما المقصود بالرمز d% في بايثون؟ كانت الإجابة المقبولة
هذا الرمز تجده في لغة السي++ أيضاً وأصله لغة السي وتحديداً الدالة printf فيها.
ويُسمى "placeholder" أو عنصر نائب أو بمعنى آخر هو رمز "symbol" يتم تضمينه ضمن سلسلة نصية أو تعبير رياضي للدلالة على أن هناك تعبيراً نصياً أو قيمة ستحل محله (للدلالة على شيء أو كمية مفقودة).
في بايثون نستخدم الرمز d% كعنصر نائب لتحديد قيم عدد صحيح أو أرقام عشرية أو أرقام. يسمح لنا بطباعة الأرقام داخل سلاسل أو قيم أخرى. يتم وضع الرمز d% حيثما نريد وضع العدد (يتم تحويل أرقام الفاصلة العائمة تلقائياً إلى قيم عشرية).
مثال:
# الإعلان عن متغير يمثل عدد صحيح num = 2021 الآن نريد أن نطبع هذا المتغير ضمن سلسلة نصية، لذا كل ماعلينا فعله هو وضع هذا العنصر ضمن السلسلة لينوب عن المتغير:
print("%d is here!!" % num) حيث نقوم بوضع السلسلة النصية المطلوب إظهارها ضمن علامتي اقتباس " " ونقوم بكتابة النص المطلوب إظهاره ضمنها إضافةً إلى العنصر النائب، ثم نكتب بعد علامتي الاقتباس الرمز % متبوعاً باسم المتغير الذي سيحل محل العنصر الذي ينوب عنه (d%).
num = 2022 print("%d is here!!" % num) # الخرج: # 2022 is here!! لكن ماذا لو كان لدينا أكثر من متغير نريد وضعه ضمن السلسلة النصية كما في مثالك؟ هنا يجب أن نقوم بوضع عنصر نائب من أجل كل متغير ويجب أن نضع هذه المتغيرات ضمن قوسين، مثلاً:
year = 2022 month=1 day = 1 print("%d:%d:%d" % (year,month,day)) # الخرج: # 2022:1:1 اعتقد أن الأمر أصبح واضحاً. حيث استخدمناها في مثالك لطباعة المتغيرات مع بعضها وفصلها ب " : ".
الآن لنجرب استخدام هذا الرمز مع الأعداد العشرية و النسبية:
# الإعلان عن متغير نسبي frac_num = 8/3 # الآن سنحاول استخدام الطريقة السابقة معه print ("Rational number formatting using %d") print("%d is equal to 8/3 using this operator." % frac_num) # الإعلان عن عدد عشري لنجرب علييها أيضاً dec_num = 10.9785 print ("Decimal number formatting using %d") print("%d is equal to 10.9785 using this operator." % dec_num) الخرج:
Rational number formatting using %d 2 is equal to 8/3 using this operator. Decimal number formatting using %d 10 is equal to 10.9785 using this operator. لاحظ من الخرج أنه يقوم بتحويلها إلى أعداد صحيحية.
-
إجابة Ali Haidar Ahmad سؤال في البحث عن الأسماء باستخدام Nltk في بايثون كانت الإجابة المقبولة
نعم في Nltk يمكنك استخدام Part-Of-Speech tagger (pos_tag)، حيث أن ماتطلبه ينتمي إلى فئة NNP.
# التي تقوم بتصنيف الكلمات pos_tag استيراد الوحدة from nltk.tag import pos_tag # تحديد الجملة sentence = "Ali Ahmed wishes to travel outside Syria in any way " # tokens نقوم الآن بتقسيم النص إلى وحدات tokens=sentence.split() # تصنيفها النحوي post = pos_tag(tokens) # [('Ali', 'NNP'), ('Ahmed', 'NNP'), ('wishes', 'VBZ'), ('to', 'TO'), ('travel', 'VB'),('outside', 'JJ'), ('Syria', 'NNP'), ('in', 'IN'), ('any', 'DT'), ('way', 'NN')] # NNP استخلالص ال pnouns = [word for word,pos in post if pos == 'NNP'] # ['Ali', 'Ahmed', 'Syria'] لإيجاد ال Possessive Nouns سنأخذ فقط الأسماء التي تنتهي ب " 's " أو " s' " وهنا يمكننا أن نستخدم الدالتين:
str.endswith("'s") str.endswith("s'") أي:
# التي تقوم بتصنيف الكلمات pos_tag استيراد الوحدة from nltk.tag import pos_tag # تحديد الجملة sentence = "Ali Ahmed wishes to travel outside Syria in any way " # tokens نقوم الآن بتقسيم النص إلى وحدات tokens=sentence.split() # تصنيفها النحوي post = pos_tag(tokens) # [('Ali', 'NNP'), ('Ahmed', 'NNP'), ('wishes', 'VBZ'), ('to', 'TO'), ('travel', 'VB'),('outside', 'JJ'), ('Syria', 'NNP'), ('in', 'IN'), ('any', 'DT'), ('way', 'NN')] # NNP استخلالص ال pnouns = [word for word,pos in post if pos == 'NNP'] # ['Ali', 'Ahmed', 'Syria'] sentence = "Ali took Daniel Jackson's hamburger and Agnes' fries" possessives = [word for word in sentence.split() if word.endswith("'s") or word.endswith("s'")] possessives # ["Jackson's", "Agnes'"]