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

هشام رزق الله

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

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

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

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

    31

كل منشورات العضو هشام رزق الله

  1. يمكنك استخدام دالة str لتحويل عدد صحيح (integer) إلى سلسلة نصية (string) كما في المثال التالي: >>> str(10) '10' ويمكنك أيضا تحويل متغير يحتوي على عدد صحيح إلى سلسلة نصية بطرقتين الأولى عبر استخدام دالة str() الثانية عبر استخدام __str__()، كما في المثال التالي: a.__str__()كما يمكنك أيضا القيام بعكس هذه العملية أي ان تقوم بتحويل سلسلة نصية تحتوي على عدد إلى عدد صحيح عن طريق دالة int() كما في هذا المثال: >>> int('10') 10المصدر 1 2
  2. الإعلان declaration يُعرف الشيء ويصف نوعه سواء كان كائن أو دالة، فالإعلان هو ما يحتاجه المترجم (compiler) للإشارة لذلك الشيء المعلن، أي أنه ببساطة في الإعلان يتم حجز مكان لكائن أو دالة. أمثلة على الإعلانات: extern int ba; extern int g(int, int); double f(int, double); // extern can be omitted for function declarations class foo; // no extern allowed for type declarations أما التعريف definition فهو الكائن أو الدالة نفسها، أي أنه تعريف القيمة بالنسبة للمتغيرات والتعليمات البرمجية بالنسبة للدوال، وهذا ما يحتاجه الرابط (linker) لربط المراجع للكيانات. هذه هي التعريفات الموافقة للإعلانات المذكورة أعلاه: int ba; int g(int lhs, int rhs) {return lhs*rhs;} double f(int i, double d) {return i+d;} class foo {}; يذكر أنه يمكنك استخدام التعريف في مكان الإعلان.
  3. الموضع معقدا نوعا ما ولن يفهمه سوى المتوسطين والمتقدمين باللغة. std::string هي عبارة عن basic_string على قالب char وأما std::wstring فهي على قالب wchar_t. من المفترض أن يحمل char حرف بحجم 1 بايت أما wchar_t فهو من المفترض أن يحمل حرف واسع (wide character) وهنا يوجد بعض الفروقات على حسب الأنظمة ففي لينكس يبلغ حجمه wchar_t 4 بايت أما في نظام ويندوز فيبلغ حجمه 2 بايت فقط ! وأما عن سؤالك حول دعم المجمعات (compilers) فأغلب المجمعات الشهيرة تدعم النوعين.
  4. كالعادة في الروبي، توجد دائما عدة طرق للقيام بنفس الوظيفة، فمثلا يمكنك إنشاء سلسلة نصية تتكون من حروف عشوائية بطول 8 أحرف عن طريق الشيفرة البرمجية التالية: (0...8).map { (65 + rand(26)).chr }.joinويمكنك التعديل عليها كما تريد مثلا إذا أردت استبدال 8 أحرف بـ 50 حرف فيمكنك فعل هذا بكل سهولة عن طريق هذه الشيفرة (لاحظ أننا قمنا أيضا بتسهيل القراءة للشيفرة): (0...50).map { ('a'..'z').to_a[rand(26)] }.joinويمكنك أيضا استخدام دالة hex من وحدة SecureRandom كما في المثال التالي، والتي ستقوم بإنشاء سلسلة نصية عشوائية متكونة من 32 أرقام وأحرف (من a إلى f): require 'securerandom' random_string = SecureRandom.hex # outputs: 5b5cd0da3121fc53b4bc84d0c8af2e81 (i.e. 32 chars of 0..9, a..f)أو يمكنك ببساطة استخدام rand لإنشاء السلسلة النصية العشوائية كما في المثال التالي: rand(36**8).to_s(36)المصدر
  5. هنالك طريقتين لكتابة تعليقات طويلة على عدة أسطر في الروبي، الأولى عن طريق استخدام =begin/=end حيث يتم كتابة التعليق بين =begin و =end وسيقوم الروبي بتجاوز هذه التعليقات عند تشغيل البرنامج كما في المثال التالي: =begin My multiline comment here =endوعلى الرغم من وجود =begin و =end، فإن الطريقة الصحيحة والأصح لوضع التعليقات هي عن طريق استخدام # في كل سطر من التعليقات، فإذا قرأت الشيفرة المصدرية (سورس كود) لأي مكتبة في الروبي، فسوف تجد أنه استخدام # في أغلب التعليقات ذات السطر الواحد والمتعددة الأسطر. مثال لاستخدام # لأسطر متعددة: # This code # on multiple lines # is commented outالمصدر
  6. يمكنك استخدام دالة ord() التي سوف تعطيك العدد الصحيح من أي حرف أو رمز، وفي حالة ما إذا أردت أن تعيد العدد إلى حرف مرة أخرى يمكنك استخدام دالة chr() كما في المثال التالي: >>> ord('a') 97 >>> chr(97) 'a' >>> chr(ord('a') + 3) 'd' >>>ملاحظة: تقوم دالة ord() بإعطائك عدد الصحيح ليس فقط بالآسكي فمثلا لو كتبت حرف بنظام تشفير آخر فسوف تعطيك العدد الصحيح المقابل له أيضا. وفي حالة ما أردت الحصول على unicode لأي حرف أو رمز آخر يمكنك استخدام دالة unichr كما في المثال التالي: >>> unichr(97) u'a' >>> unichr(1234) u'\u04d2' المصدر
  7. يمكنك استخدام include? ، فـ include? تقوم بإرجاع true إذا كانت المصفوفة تحتوي على هذه القيمة، وخلافا لذلك فسوف تقوم بإرجاع false كما في المثال التالي: a = [ "a", "b", "c" ] a.include?("b") #=> true a.include?("z") #=> false وإذا لم ترغب باستخدام include? يمكنك أيضا استخدام any? كما في المثال التالي: ['cat','dog','horse'].select{ |x| x == 'dog' }.any?أو يمكنك استخدامه على هذا الشكل: ['cat','dog','horse'].any? { |x| x == 'dog' }كما يمكنك أيضا استخدام count التي لن تخبرك فقط بوجود القيمة في المصفوفة بل أيضا بعدد مرات التكرار كما في المثال التالي: a = ['Cat', 'Dog', 'Bird'] a.count("Dog") #=> 1 ويمكنك أيضا استخدام index في جملة شرطية للتأكد من وجود قيمة في السلسلة النصية كما في المثال التالي: a = ['cat','dog','horse'] if a.index('dog') puts "dog exists in the array" end للمزيد أنصحك بقراءة التوثيق الرسمي
  8. في الروبي هنالك عدة دوال للتحكم في تحويل حروف السلاسل النصية، فمثلا إذا أردت تحويل السلسلة النصية إلى الحروف الصغيرة، يمكنك استخدام downcase كما في المثال التالي: "hello James!".downcase #=> "hello james!"كما يمكنك استخدام upcase لتحويل جميع الأحرف الموجودة في السلسلة النصية إلى الأحرف الكبير كما في المثال التالي: "hello James!".upcase #=> "HELLO JAMES!"ويمكنك أيضا استخدام capitalize لتحويل أول حرف في السلسلة النصية إلى حرف كبيرة أما بقية الحروف فسيتم تحويلها إلى حروف صغيرة كما في المثال التالي: "hello James!".capitalize #=> "Hello james!" كما يمكنك أيضا تحويل حالة الحروف في السلاسل النصية الموجودة في المتغيرات كما في المثال التالي: string = "hello James!" string.downcase string #=> "hello james!" التوثيق الرسمي للسلاسل النصية
  9. هنالك عدة طريق لإنشاء أرقام عشوائية عن طريق لغة الروبي، من أن أشهر هذه الطرق استخدام تابع (method) rand. يجب على المعاملات التي يتم تمريرها إلى rand أن تكون من نوع integer أو range، وسيتم إرجاع رقم بين هذا المدى كما في المثال التالي: rand(9) # this generates a number between 0 to 8 rand(0 .. 9) # this generates a number between 0 to 9 rand(1 .. 50) # this generates a number between 1 to 50 #rand(m .. n) # m is the start of the number range, n is the end of number rangeكما يمكنك أيضا الحصول على أرقام float عن طريق إضافة المدى بالفاصل كما في المثال التالي: > rand(1.0..1.5) => 1.1835169281972568كما يمكنك إنشاء أرقام عشوائية عن طريق وحدة securerandom فيكفي أن تكتب أقصى عدد ممكن وسيتم إنشاء أرقام عشوائية بين 0 والرقم الأقصى كما في المثال التالي: require 'securerandom' p SecureRandom.random_number(100) #=> 15p SecureRandom.random_number(100) #=> 88 p SecureRandom.random_number #=> 0.596506046187744 p SecureRandom.random_number #=> 0.350621695741409 المصدر
  10. سوف نحتاج في الكثير من الأحيان إلى التعامل مع نظام التشغيل أو تشغيل أوامر شيل shell من خلال الروبي، وهذه اللغة توفر لنا العديد من الطرق لتنفيذ أوامر لينكس من خلالها. ومن أسهل هذه الطرق استخدام exec والذي يقوم باستبدال العملية الحالية (process) بتشغيل الأمر المقدم كما في المثال التالي: $ irb >> exec 'echo "hello $HOSTNAME"' hello nate.local $ لاحظ أن exec يقوم بإنهاء الروبي بعد تنفيذه الأمر. أما الطريقة الثانية وهي باستخدام exec الذي يقوم بتنفيذ الأمر من دون أن يقوم بإنهاء الروبي كما في المثال التالي: $ irb >> system 'echo "hello $HOSTNAME"' hello nate.local => true >> system 'false' => false >> puts $? 256 => nil >>توجد عدة طرق آخر، لكن هاتين أشهر وأسهل الطرق وإذا أردت معرفة المزيد عن هذه الطرق أنصحك بقراءة هذا المقال.
  11. هنالك عدة طرق لاستخراج الامتداد من ملف، فيمكنك استخدام دالة path.splitext من مكتبة os لاستخراج الاسم و الامتداد بشكل منفصل كما في المثال التالي: >>> import os >>> filename, file_extension = os.path.splitext('/path/to/somefile.ext') >>> filename '/path/to/somefile' >>> file_extension '.ext'أو بشكل مختصر يمكنك استخدام هذه الدالة كالتالي: import os.path extension = os.path.splitext(filename)[1]ويمكنك أيضا استخدام هذه الشيفرة البرمجية لاستخراج الامتداد فقط(دون النقطة): import os.path extension = os.path.splitext(filename)[1][1:] أو يمكنك استخدام هذه الشيفرة لفصل الملف إلى جزئين حسب النقطة: >>> filename = "example.jpeg" >>> filename.split(".")[-1]' jpeg'حيث لن تحصل بهذه الطريقة على رسالة خطأ لو كان الملف بدون امتداد كما في المثال التالي: >>> "filename".split(".")[-1] 'filename'ولو كنت في نظام لينكس ستجد أن جميع الشيفرات السابقة تضع سطر جديد في نهاية السلسلة النصية للامتداد، ويمكنك إضافة دالةstrip() إلى نهاية الملف لحل هذه المشكلة: import os.path extension = os.path.splitext(filename)[1][1:].strip()المصدر
  12. هنالك عدة طرق سهلة لتحويل متغير صحيح (int) إلى متغير من نوع سلسلة نصية (string)، ففي الإصدار 11 من السي بلس بلس تم إضافة دالة std::to_string التي تقوم بتحويل المتغيرات إلى سلسلة نصية كما في المثال التالي: int a = 20; std::string s = to_string(a);وأعتقد أن هذه هي أسهل طريقة لتحويل متغير صحيح (int) إلى متغير من نوع سلسلة نصية. كما يمكنك إنشاء دالة صغيرة للتحويل، ففي المثال التالي قمنا باستخدام مكتبة sstream لتحويل متغير من نوع int إلى string: #include <sstream> string IntToString (int a) { ostringstream temp; temp<<a; return temp.str(); }
  13. الفرق في المكان الذي يجب على المعالج الأولي (preprocessor) أن يقوم بالبحث فيه عندما يقوم بإرفاق الملفات (include). عند كتابة #include "filename" سيقوم المعالج الأولي بالبحث في نفس المجلد الذي يحتوي البرنامج. في الغالب تُستخدم هذه الطريقة من قِبل المبرمج لتعريف ملفات header قام بكتابتها. أما بالنسبة لـ #include <filename> فسيقوم المعالج الأولي بالبحث في المجلدات التي تم تعريفها للمترجم (compiler) أو IDE، وهذه الطريقة تُستخدم في الغالب لإرفاق ملفات المكتبات القياسية. للمزيد أنصحك بقراءة هذا المقال
  14. في الحقيقة لا ينصح باستخدام "using namespace std;” عمومًا، إلا أنه يمكنك استخدامها حسب الظروف والاحتياجات. هذه العبارة لا ينصح باستخدامها لتسببها بمشاكل عند تشابه أسماء المتغيرات وغيرها، لذلك قد تحدث مشاكل – خاصة للمبتدئين – عند تشغيل البرنامج، ولكن على الرغم من ذلك يمكنك استخدامها كما تريد أيضًا (تقريبا)، لأن أهمية عبارة "using namespace std;” تكمن في أنها تمنعك من تكرار “std::” وهذا التكرار المزعج هو الآخر سيئ. للمزيد من المعلومات حول Namespaces في لغة السي بلس بلس أنصحك بقراءة هذا المقال
  15. في الحقيقة إن "-->” ليس عامل حسابي واحد بل يتكون من عاملين منفصلين هما - - و > . فالعامل الحسابي - - يقوم بخفض قيمة المتغير x بمقدار 1 وأما > فيقوم بمقارنة x مع قيمة المتغير x، وبما أننا قد وضعنا حلقة التكرارية while فإن البرنامج سيقوم في كل مرة بخفض قيمة x بمقدار 1 و يقوم بالمقارنة ثم يطبع النتيجة على الشاشة ولذلك ستجد أن البرنامج قد قام بكتابة جميع الأرقام من 10 إلى 0 تنازليا. لفهم الدالة بشكل أفضل، يمكنك كتابة سطر الحلقة التكرارية كالتالي: while( (x--) > 0 )
  16. أولا يجب عليك أن تقوم بتثبيت حزمة python-mysqldb عن طريق الأمر: sudo apt-get install python-mysqldb وبعد تثبيت الحزمة قُم بإعادة تشغيل الحاسوب، لتجنب الكثير من المشاكل التي تحدث بسبب عدم إعادة تشغيل الحاسوب. بعد ذلك يمكنك استدعاء مكتبة MySQLdb إلى برنامجك كما في المثال التالي: #!/usr/bin/python import MySQLdb db = MySQLdb.connect(host="localhost", # your host, usually localhost user="john", # your username passwd="megajonhy", # your password db="jonhydb") # name of the data base # you must create a Cursor object. It will let # you execute all the queries you need cur = db.cursor() # Use all the SQL you like cur.execute("SELECT * FROM YOUR_TABLE_NAME") # print all the first cell of all the rows for row in cur.fetchall() : print row[0]ملاحظة: لا تنس تغيير بيانات الاتصال بقاعدة البيانات. لاحظ أننا قمنا بتنفيذ الأمر SELECT * FROM YOUR_TABLE_NAME حيث يمكنك استبدال هذا الأمر بأي أمر آخر تريده. كما يمكنك استخدام مخطط الكائن العلائقي (ORM) لتجنب كتابة أوامر SQL بشكل يدوي، ومن أشهر ORM في مجتمع البايثون هو SQLAlchemy . المصدر
  17. إن ملفات __init__.py تُستخدم لتمييز المجلدات كمسارات لحزمة البايثون، فإذا كان لديك الملفات التالية: mydir/spam/__init__.py mydir/spam/module.py وكان mydir هو المسار الخاص بك، يمكنك استدعاء هذه الملفات في الشيفرة البرمجية كما يلي: import spam.moduleأو عن طريق هذا السطر: from spam import module فلو قمت بحذف ملف __init__.py فلن ينظر البايثون إلى الوحدات في المجلدات الأخرى، لذلك عند قيامك باستدعاء الملف ستحصل على خطأ عدم إيجاد الملف. بالإضافة إلى ذلك، هذا هو أول ملف يتم تحميله في الملف، فيمكنك استخدامه لتشغيل شيفرة برمجية التي تريدها أن تعمل في كل مرة يتم تحميل الوحدة فيها، أو تحديد الوحدات الفرعية التي تريد أن تقوم تصديرها. للمزيد من المعلومات أنصحك بقراءة التوثيق الرسمي
  18. في هذه الحالة سوف تحتاج إلى فتح الملف بوضعية الإضافة، بإضافة "a” أو "ab” كوضع، (وليست w للكتابة حيث تقوم الأخيرة بحذف النصوص والبيانات السابقة). عندما تقوم بفتح الملف بوضعية "a”، سوف تكون الإضافة دائما في نهاية الملف ، ويمكنك إضافة "a+” حتى تسمح بالقراءة إلى جانب الإضافة (وستبقى الإضافة كالعادة إلى نهاية النص). هذا مثال قصير وسريع حول دالة open: >>> with open('test1','wb') as f: f.write('test') >>> with open('test1','ab') as f: f.write('koko') >>> with open('test1','rb') as f: f.read() 'testkoko' لاحظ أننا قمنا بفتح الملف بسطر واحد للشرح فقط فهذه الطريقة لا ينصح بها في البرامج حيث يجب أن تقوم بإغلاق الملف بعد فتحه عن طريق دالة close()، كما في المثال التالي: f = open('filename.txt', 'a') f.write("stuff") f.close()للمزيد من المعلومات ستجد التوثيق الرسمي في المصدر. المصدر
  19. في العادة، سوف تجد في مشاريع البايثون ملفات __init__.py والتي ستتكفل بمسارات الوحدات والمكتبات داخل المشروع، وأنصحك بهذه الطريقة لو كنت ستقوم بعمل مشروع برمجي متوسط أو كبير، أما لو أردت طريقة سهلة لمشروع برمجي صغير فيمكنك الاستعانة بدالة path.append من مكتبة sys التي ستقوم بإضافة مسار الوحدة ومن ثم القيام باستدعاء هذه الوحدة كما تستدعي أية مكتبة أخرى كما في المثال التالي: import sys sys.path.append( <path to dirFoo> ) import Bap حيث ستقوم بتغيير <path to dirFoo> بمسار الوحدة التي سوق تحتاجها. للمزيد من المعلومات حول الوحدات يمكنك قراءة التوثيق الرسمي
  20. هنالك عدة طرق يمكنك بها تحديد جميع الملفات ذات امتداد معين في البايثون والتي من أهمها وأشهرها هي عن طريق استخدام دالة glob من مكتبة glob حيث ستقوم هذه الدالة بإرجاع قائمة بأسماء الملفات كما في المثال التالي: >>> import glob >>> glob.glob('./[0-9].*') ['./1.gif', './2.txt'] >>> glob.glob('*.gif') ['1.gif', 'card.gif'] >>> glob.glob('?.gif') ['1.gif']وفي حالة ما كانت الملفات في مجلد آخر غير المجلد الحالي فيمكنك تغيير المجلد عن طريق استدعاء دالة os ومن ثم إضافة هذا السطر قبل استخدام دالة glob: os.chdir("/mydir") كما يمكنك استخدام دالة listdir من مكتبة os لعرض هذه الملفات: import os for file in os.listdir("/mydir"): if file.endswith(".txt"): print(file)للمزيد من المعلومات حول هذه الدوال أنصحك بمراجعة التوثيق الرسمي الموجود في المصدر المصدر 1 2
  21. هنالك عدة طرق، فالطريقة العامة هي عن طريق استخدام stdout حيث يقوم بالطباعة بدون أي يترك فراغ (مسافة) أو سطر جديد كما في السي والسي بلس بلس: import sys sys.stdout.write('.') أو يمكنك في البايثون 2 استخدام فاصلة (فارزة) بعد print لتجنب السطر الجديد (لكن يضع مسافة): print('.'), # this will still print a space, but not a newlineوفي البايثون 3، تم تحويل print إلى دالة، فالمثال السابق لن يعمل، ويمكنك تغيير نهاية السطر حتى لا يطبع سطر جديد أو مسافة كما في المثال: print('.', end="")المصدر
  22. أسهل طريقة للحصول على آخر عنصر من القائمة هي عن طريق استخدام هذه الطريقة: some_list[-1]في الحقيقة، يمكنك القيام بالكثير مع هذه الصياغة، فهذه الصياغة some_list[-n] تقوم بإرجاع العنصر في المرتبة التي تريد بدءا من الأخيرة، فمثلا لو قمت بكتابة some_list[-1] فسوف تحصل على العنصر الأخير، أما لو كتبت some_list[-2] فستحصل على العنصر ما قبل الأخير وهكذا. كما يمكنك تغيير قيمة إحدى العناصر بهذه الطريقة كما في المثال التالي: >>> some_list = [1, 2, 3] >>> some_list[-1] = 5 # Set the last element >>> some_list[-2] = 3 # Set the second to last element >>> some_list [1, 3, 5]المصدر
  23. للحصول على نوع الكائن يمكنك استخدام دالة type() المدمجة (أي الموجود في البايثون بشكل افتراضي)، فيكفي أن تقوم بتمرير كائن كمعامل وحيد وسوف تقوم هذه الدالة بإرجاع نوع الكائن، كما في المثال التالي: >>> type([]) is list True >>> type({}) is dict True >>> type('') is str True >>> type(0) is int True >>> type({}) <type 'dict'> >>> type([]) <type 'list'> كما يمكنك أيضا استخدام دالة isinstance وهذه الدالة مدمجة أيضا في البايثون، وتفيد خاصة في حالات الكشف عن أنواع الدالات الموروثة كما في المثال التالي: >>> class Test1 (object): pass >>> class Test2 (Test1): pass >>> a = Test1() >>> b = Test2() >>> type(a) is Test1 True >>> type(b) is Test2 True >>> isinstance(b, Test1) True >>> isinstance(b, Test2) True >>> isinstance(a, Test1) True >>> isinstance(a, Test2) False >>> isinstance([], list) True >>> isinstance({}, dict) Trueكما أن المعامل الثاني لدالة isinstance() تقبل مجموعة من الأنواع على شكل tuple، فإذا أردت مثلا التأكد من مجموع أنواع في المرة الواحد، فستقوم isinstance() بإرجاع true إذا كان الكائن أحد هذه الأنواع: >>> isinstance([], (tuple, list, set)) Trueالمصادر: 1 2
  24. هنالك العديد من الطرق لدمج القوائم في البايثون، بعضها بسيط والبعض الآخر اكثر تعقيدا، ومن أبسط الطرق لدمج قائمتين معا هي عن طريق إضافة القائمة الثانية إلى القائمة الأولى عن طريق =+ كما في المثال التالي: listone += listtwoأو يمكنك إنشاء متغير آخر تقوم بوضع القوائم به لتصبح قائمة واحدة كما في هذا المثال: mergedlist = listone + listtwoكما يمكنك ببساطة إنشاء قائمة جديدة ثم تقوم بإضافة القائمتين الأخريين إليها عن طريق استخدام دالة extend() كما في المثال التالي: listone = [1,2,3] listtwo = [4,5,6] mergedlist = [] mergedlist.extend(listone) mergedlist.extend(listtwo) المصدر
  25. الفرق أن **name تستقبل قاموس يحتوي على جميع مفاتيح المعاملات بينما *name تستقبل tuple يحتوي على المعاملات، فمثلا لنفترض أن لدينا الدالة التالية: def cheeseshop(kind, *arguments, **keywords): print("-- Do you have any", kind, "?") print("-- I'm sorry, we're all out of", kind) for arg in arguments: print(arg) print("-" * 40) keys = sorted(keywords.keys()) for kw in keys: print(kw, ":", keywords[kw])وقمنا باستدعائها على الشكل التالي: cheeseshop("Limburger", "It's very runny, sir.", "It's really very, VERY runny, sir.", shopkeeper="Michael Palin", client="John Cleese", sketch="Cheese Shop Sketch")فسوف تقوم بطباعة التالي: -- Do you have any Limburger ?-- I'm sorry, we're all out of Limburger It's very runny, sir. It's really very, VERY runny, sir. ---------------------------------------- client : John Cleese shopkeeper : Michael Palin sketch : Cheese Shop Sketch لاحظ أننا قد قمنا بفرز القاموس عن طريق sorted وإذا لم تقم بهذا فسوف تنتج مشاكل في الترتيب ولاحظ أيضا أنه يجب وضع *name قبل **name. للمزيد من المعلومات أنصحك بزيارة التوثيق الرسمي
×
×
  • أضف...