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

هشام رزق الله

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

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

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

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

    31

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

  1. هنالك عدة طرق في بايثون لفعل ذلك، فإذا كُنت تستخدم الإصدار الثاني من بايثون فيمكنك استخدام مكتبة urllib2 كما في المثال التالي: import urllib2 urllib2.urlopen("http://example.com/foo/bar").read() وإذا كنت تستخدم الإصدار الثالث فيمكنك في هذه الحالة استخدام مكتبة urllib.request كما في المثال التالي: import urllib.request urllib.request.urlopen("http://example.com/foo/bar").read() أو أنصحك باستخدام مكتبة httplib2 التي لديها ميزة ترتيب المحتوى والحالة وresponse headers كما في المثال التالي: import httplib2 resp, content = httplib2.Http().request("http://example.com/foo/bar")حيث سيحتوى متغير content على المحتوى بشكل سلسلة نصية أما resp فسيحتوى على بقية المعلومات الأخرى. المصدر
  2. هنالك طرق متنوعة لتحويل سلسلة نصية من نوع Unicode إلى سلسلة نصية عادية لكنك ستواجه بعض المشاكل البسيطة بسبب الرموز الخاصة. يمكنك تحويل سلسلة Unicode إلى ASCII (إذا كنت لا تحتاج إلى ترجمة الحروف التي ليست من نوع ASCII بطريقتين) الأولى عن طريق تجاهل الحروف non-ASCII (ليست من نوع ASCII) والثانية عن طريق استبدالها بعلامة استفهام كما في الأمثلة التالية: >>> a=u"aaaàçççñññ" >>> type(a) <type 'unicode'> >>> a.encode('ascii','ignore') 'aaa' >>> a.encode('ascii','replace') 'aaa???????' >>> كما يمكنك تحويل السلسلة النصية إلى ترميزات أخرى مثل utf8 أو utf16 كما في الأمثلة التالية: >>> s= u'£10' >>> s.encode('utf8') '\xc2\x9c10' >>> s.encode('utf16') '\xff\xfe\x9c\x001\x000\x00'
  3. هنالك عدة طرق لتعديل أسماء مجموعة من الملفات في البايثون، فلو افترضنا أنك موجود حاليا في المجلد الذي تريد تغيير أسماء فيه، وأن حالة أول 7 أحرف من الملفات لا تتغير(يمكنك تغيير طول عدد الأحرف حسب الحاجة 7 أو 8 أو 3 …) فيمكنك في هذه الحالة استخدام هذه الشيفرة البرمجية لتغيير أسماء الملفات: from glob import glob from os import rename for fname in glob('*.prj'): rename(fname, fname[8:]) أو يمكنك الاستعانة بدوال مكتبة os لتعديل أسماء الملفات كما في المثال التالي: $ ls cheese_cheese_type.bar cheese_cheese_type.foo $ python >>> import os >>> for filename in os.listdir("."): ... if filename.startswith("cheese_"): ... os.rename(filename, filename[7:]) ... >>> $ ls cheese_type.bar cheese_type.foo مثال آخر حيث سيتأكد من أن أسماء الملفات لا تحتوي على أكثر من كلمة cheese_: #!/usr/bin/env python from os import rename, listdir badprefix = "cheese_" fnames = listdir('.') for fname in fnames: if fname.startswith(badprefix*2): rename(fname, fname.replace(badprefix, '', 1))المصدر
  4. نعم توجد طرق أقصر وأفضل لمعرفة نوع المتغير سواء كان من نوع Hash أو مصفوفة (Array)، فعلى سبيل المثال يمكنك اختصار المثال الذي وضعته إلى هذا السطر: @some_var.class == Hash أو يمكنك اختصاره إلى هذا السطر أيضا: @some_var.is_a?(Hash) ومن الجدير بالذكر أن تابع is_a? يُرجع true إذا كان الصنف موجود في شجرة أصول الكائنات (the objects ancestry tree)، فعلى سبيل المثال: @some_var.is_a?(Object) # => true سيتم إرجاع true إذا كان @some_var مثيلا لـ hash أو أي صنف آخر ينبع(stems) من الكائن.
  5. أفضل طريقة بايثونية هي استخدام 4 فراغات لكل مستوى مسافة بادئة، وسيقوم مترجم البايثون بالتعرف على الفراغات ومسافات tabs بدون مشاكل، لكن يجب عليك أن لا تخلط بين الفراغات والمسافات في شيفرتك البرمجية أي أن تقوم باستخدام فراغات في سطر ومسافات في سطر آخر في نفس الشيفرة البرمجية لأنها ستحدث أخطاء كثيرة عند محاولة تشغيل البرنامج. أغلب مبرمجي البايثون يستخدمون الفراغات لذا أنصحك باستخدام الفراغات أيضا ما لم يكن لديك سبب لاستخدام مسافات tabs.
  6. هنالك عدة طرق لحذف المسافات وtabs في بايثون، فعلى سبيل المثال يمكنك استعمال دالة strip() للحذف من الجانبين كما في المثال التالي: s = " \t a string example\t " s = s.strip() أو يمكنك حذف المسافات من جانب واحد من السلسلة النصية، كما في الأمثلة التالية: الجانب الأيمن: s = s.rstrip() الجانب الأيسر: s = s.lstrip() الأمثلة السابقة ستحذف الفراغات والمسافات من جانبين، لكنها لا تقوم بحذف الفراغات الزائدة في وسط السلسلة النصية، لذلك أنصحك في مثل هذه الحالات باستخدام دالة sub من مكتبة re كما في الأمثلة التالية: import re print re.sub('[\s+]', '', s)
  7. يمكنك فعل ذلك بأكثر من طريقة، فعلى سبيل المثال إذا كنت تستخدم ريلز فيمكنك استعمال تابع camelize كما في المثالين التاليين: "active_record".camelize # => "ActiveRecord" "active_record".camelize(:lower) # => "activeRecord" وإذا أردت الحصول على صنف حقيقي فيجب عليك استخدام constantize بعد camelize كما في المثال التالي: "app_user".camelize.constantizeوإذا كنت تستخدم روبي بدون ريلز فيمكنك في هذه الحالة استخدام تابع classify كما في المثال التالي: "app_user".classify # => AppUser "user_links".classify # => UserLink كما يمكنك استخدام توابع مختلفة لحذف رمز _ ومن ثم دمج الكلمتين مع تغيير حالة الحرف الأول من كل كلمة إلى حرف كبير كما في المثال التالي: "hello_world".split('_').collect(&:capitalize).join #=> "HelloWorld"المصدر
  8. هنالك طرق عديدة لإيجاد التكرارات في مصفوفة معينة، فيمكنك على سبيل المثال استخدام select وcount كما في المثال التالي: a.select{|item| a.count(item) > 1}.uniq => ["A", "B"] شرح الشيفرة البرمجية: هنالك في الروبي توابع مفيدة جدا والتي من بينها تابع select ويُستعمل كالتالي: select {|item| block } → new_ary select → an_enumerator فهو يسمح لك بتحديد الكائنات التي اجتازت اختبار معين كما في المثال السابق. وقد استخدمنا تابع آخر في المثال السابق وهو تابع count لحساب التكرارات، فإذا ظهر عنصر معين أكثر من مرة واحدة في قائمة معينة فسيتم تحديده كما رأيناه في المثال النهائي. صيغة شرط التكرار: a.count(obj) > 1
  9. على الرغم من أنه يبدو أنه ليس هنالك أي فرق بين == و is إلا أن لكل واحد منهم وظيفة محددة، فمثلا == يستخدم للمقارنة بين القيم، فتُستخدم عندما تحتاج إلى معرفة ما إذا كان للكائنين نفس القيمة، أما is فهي تستخدم للمقارنة بين المراجع، فتُستخدم عندما تحتاج إلى معرفة إذا كان المرجعين يشيران إلى نفس الكائن أو لا. بشكل عام، إذا كنت تحتاج إلى مقارنة شيئين، ففي العادة سوف تستخدم == لأنك بحاجة إلى مقارنة بين قيمتين. مثال بسيط حول الفرق بينهم: >>> a = [1, 2, 3] >>> b = a >>> b is a True >>> b == a True >>> b = a[:] >>> b is a False >>> b == a True المصدر
  10. إن pyPDF يعمل بدون مشاكل (إذا افترضنا أنك تعمل على ملفات PDF جيّدة التكوين)، فإذا أردت أن تحصل على نص (مع الفراغات)، فكل ما يجب عليك فعله هو كتابة الشفرة البرمجية التالية: import pyPdf pdf = pyPdf.PdfFileReader(open(filename, "rb")) for page in pdf.pages: print page.extractText() ملاحظات حول استخراج النصوص عن طريق pyPDF: تقوم الشيفرات السابقة بتتبع تيار(stream) النص ومن ثم ستقوم بطباعته، وهذا الأمر سيعمل لبعض أنواع ملفات PDF ونادرا مع أنواع أخرى من ملفات PDF حسب المولد الذي تم استخدامه لإنشاء ملف PDF. يمكنك أيضا استخدام حزمة PDFMiner لاستخراج النصوص من ملف PDF وتحويلها إلى ملفات HTML أو SGML، وهذه الحزمة أفضل من سابقتها لكنها أكثر تعقيدا في الاستخدام.
  11. هنالك عدة طرق للحصول على اسم التابع الذي قام باستدعاء تابع آخر من داخله، فمثلا يُمكننا استعمال caller كما في المثال التالي: puts caller[0] ولتحسين الناتج يمكنك استخدام هذا السطر لحذف ما هو ليس ضروري في الناتج وإظهار اسم التابع التي قام بالاستدعاء فقط: puts caller[0][/`.*'/][1..-2] وإذا كنت تستخدم الإصدار الثاني من الروبي، فيمكنك في هذه الحالة اختصار السطر السابق كما يلي: caller_locations(1,1)[0].label هذه الطريقة أسرع بكثير من الطريقة السابقة. أو يمكنك استخدام ما يلي أيضا للحصول على اسم التابع: caller[0][/`([^']*)'/, 1]المصدر
  12. في الحقيقة لم أفهم بالضبط، إذا كنت تقصد أن الملف الذي قمت برفعه لا يظهر فهذه مشكلة في رفع الملف وليس لها علاقة بالبرمجة وأنصحك في هذه الحالة أن تتواصل مع شركة الاستضافة لحل هذه المشكلة.
  13. هنالك عدة طرق لوضع عنصر في بداية مصفوفة معينة لكن أشهرها هي عن طريق استخدام تابع unshift الذي يقوم بوضع العنصر الذي تريده في الموقع الأول في المصفوفة ويدفع بقية العناصر حيث سيصبح العنصر الثاني في الموقع الثالث وهكذا... كما في المثال التالي: irb>> a = [ 0, 1, 2] => [0, 1, 2] irb>> a.unshift('x') => ["x", 0, 1, 2] irb>> a.inspect => "["x", 0, 1, 2]" هنالك طريقة أخرى مشهورة وهي عن طريق استخدم تابع insert الذي سيمكنك من وضع أي عنصر في أي موقع من مواقع المصفوفة كما في المثال التالي: a = [1,2,3] a.insert(0,0) => [0,1,2,3]المصدر
  14. هنالك عدة طرق لحل هذه المشكلة، فيمكنك مثلا ببساطة القيام بتسطيح (flatten) القائمة المتداخلة أو يمكنك القيام بترشيح (فلترة) عناصر الموجودة في القائمتين كما في المثال التالي: c3 = [filter(lambda x: x in c1, sublist) for sublist in c2] يقوم filter بفحص جميع عناصر القائمة الثانية ويتأكد من أنها غير موجود في القائمة الأول. كما يمكنك أيضا استخدام intersection و set للحصول على العناصر المتكررة كما في المثال التالي: >>> b1 = [1,2,3,4,5,9,11,15] >>> b2 = [4,5,6,7,8] >>> set(b1).intersection(b2) set([4, 5]) ويمكنك أيضا عمل تغيير بسيط للسطر الأخير للمثال الذي وضعته وستحصل على ما تريد كما في المثال التالي: [[n for n in lst if n in c1set] for lst in c2]
  15. هنالك عدة طرق يمكنك استخدامها لتسطيح قائمة معينة في بايثون، فيمكنك ببساطة استخدام دالة flatten من وحدة compiler.ast كما في المثال التالي: >>> from compiler.ast import flatten >>> flatten([0, [1, 2], [3, 4, [5, 6]], 7]) [0, 1, 2, 3, 4, 5, 6, 7] كما يمكنك إنشاء دالة لتسطيح القائمة كما في هذا المثال: def flatten(x): if isinstance(x, collections.Iterable): return [a for i in x for a in flatten(i)] else: return [x] أو يمكنك إنشاء الدالة بطريقة أخرى إذا كنت تستخدم إصدار 2.6 من بايثون كما في المثال التالي: def flatten(l): for el in l: if isinstance(el, collections.Iterable) and not isinstance(el, basestring): for sub in flatten(el): yield sub else: yield el في الإصدار 3 من البايثون تم الاستغناء عن basestring لكن يمكنك استخدام هذا السطر بدلا عنها وسوف تحصل على نفس النتيجة: basestring = (str, bytes)المصدر
  16. توجد في بايثون أيضا دالة super كما في اللغات الأخرى وتعمل تقريبا بنفس الطريقة وصياغتها العامة كالتالي: super(type[, object-or-type]) هذه الدالة مفيدة جدا عند حاجتك إلى الوصول إلى توابع موروثة تم تجاوزها في الصنف. ترتيب البحث هو نفسه الذي تستخدمه دالة getattr() إلا أنه يتم تجاوز النوع. مثال بسيط على استخدام super: class Foo(Bar): def baz(self, arg): return super(Foo, self).baz(arg) ملاحظة: يمكنك استخدام الدالةsuper فقط في أصناف الأساليب الجديدة. كما أنصحك أيضا باستخدام CLASS.__bases__ كما في المثال التالي: class A: def __init__(self): print "I am Class %s"%self.__class__.__name__ for parentClass in self.__class__.__bases__: print " I am inherited from:",parentClass.__name__ #parentClass.foo(self) <- call parents function with self as first param class B(A):pass class C(B):pass a,b,c = A(),B(),C() المصدر
  17. بالنسبة لوحدات البايثون الأصلية فيمكنك الحصول على أماكن تواجد ملفاتها المصدرية عن طريق استخدام themodule.__file__، لكن هنالك بعض الوحدات لا يمكنك الإطلاع عليها مثل وحدة datetime لأنها مكتوبة بلغة السي، ولو حاولت اتباع الطريقة السابقة لمعرفة مكان تواجد الملف المصدري للوحدة فسيشير البايثون إلى ملف .so (لا يمكنك استخدام datetime.__file__ في نظام ويندوز) وبالتالي لا يمكنك رؤية شيفرتها المصدرية. يمكنك أيضا تنزيل الملف المصدري للبايثون وستحصل على الشيفرة المصدرية لجميع الوحدات في مجلد Modules.
  18. في الحقيقة يمكنك أن تقوم ببساطة بمقارنة السلسلة النصية مع ما تعتبره قيمة صحيحة حتى ترجع لك True كما في المثال التالي: s == 'True' أو يمكنك أيضا استخدام أكثر من قيمة في نفس الوقت عن طريق استخدام تعليمة in في قائمة من القيم التي تعتبرها صحيحة: s in ['true', '1', 't', 'y', 'yes', 'yeah', 'yup', 'certainly', 'uh-huh'] انتبه حين تستخدم bool فهي تقوم فقط بإرجاع true إذا كانت السلسلة النصية بها على الأقل حرف واحد (أو رمز أو رقم...)وتقوم بإرجاع false إذا كانت السلسلة النصية فارغة كما في هذا المثال: >>> bool("foo") True >>> bool("") False المصدر
  19. هنالك عدة طرق لمعرفة نوع نظام التشغيل الذي يتم تشغيل السكربت فيه، فمثلا يمكنك استخدام دالة name من مكتبة os لعرض نوع نظام التشغيل لكن هذه الدالة ليست دقيقة للغاية كما يبدو ذلك في المثال التالي: >>> import os >>> print os.name posix إذا أردت معلومات دقيقة حول نظام التشغيل فيمكنك في هذه الحالة استخدام دالة system من مكتبة platform لعرض اسم نظام التشغيل ويمكنك أيضا استخدام دالة release من نفس المكتبة لمعرفة إصدار نظام التشغيل كما في المثال التالي: >>> import platform >>> platform.system() 'Linux' >>> platform.release() '2.6.22-15-generic'المصدر
  20. هنالك طرق متنوعة لمعرفة ما إذا كانت سلسلة نصية معينة تبدأ بمجموعة أحرف موجودة في سلسلة نصية أخرى، فيمكنك على سبيل المثال استخدام تابع start_with? الذي سيقوم بإرجاع true إذا كانت السلسلة النصية الأولى تبدأ بالسلسلة النصية الثاني كما في المثال التالي: puts 'abcdefg'.start_with?('abc') #=> true كما يمكنك أيضا تمرير عدة سلاسل نصية في نفس الوقت والتي ستقوم بإرجاع true إذا كانت السلسلة النصية الأولى تبدأ بإحدى السلاسل النصية التي قمت بتمريرها كما في هذا المثال: 'abcdefg'.start_with?( 'xyz', 'opq', 'ab') كما يمكنك أيضا استخدام التعابير النمطية كما في المثال التالي: 'abcdefg' =~ /\Aabc/المصدر
  21. هنالك طريقتين شهيرتين في روبي للتعبير عن اللانهائية فيمكنك استخدام الثابت INFINITY بعد أن تضع نوعه كـ float كما في المثال التالي: >> Float::INFINITY #=> Infinityبعد ذلك يمكنك استخدام هذا الثابت في برنامجك كما تريد، فمثلا قمنا في هذا المثال بمقارنة اللانهائية مع 3(عملية 3 أصغر من اللانهائية): >> 3 < Float::INFINITY #=> true كما يمكنك إنشاء ثابت اللانهائية بنفسك في روبي 1.8.6+ كما في الأمثلة التالية: PositiveInfinity = +1.0/0.0 => Infinity NegativeInfinity = -1.0/0.0 => -Infinity CompleteInfinity = NegativeInfinity..PositiveInfinity => -Infinity..Infinityكما توجد طريقة أخرى للتعبير عن اللانهائية عن طريق استخدام BigDecimal كما في الأمثلة التالية: 1.9.3p429 :025 > BigDecimal('Infinity') => #<BigDecimal:7f8a6c548140,'Infinity',9(9)> 1.9.3p429 :026 > BigDecimal('-Infinity') => #<BigDecimal:7f8a6a0e3728,'-Infinity',9(9)> 1.9.3p429 :027 > 3 < BigDecimal('Infinity') => true 1.9.3p429 :028 > BigDecimal::INFINITY => #<BigDecimal:7f8a6ad046d8,'Infinity',9(9)>المصدر
  22. الحل لهذه المشكلة بسيط للغاية، فإذا كنت تستخدم الإصدار 2.7 من بايثون أو 3.1 فيمكنك استبدال تعليمة and بفاصلة (فارزة) كما في المثال التالي: with open('a', 'w') as a, open('b', 'w') as b: do_something() المشكلة لو كنت تستخدم الإصدارات القديمة لبايثون، ففي بعض الأحيان يمكنك استخدام دالة nested من مكتبة contextlib (لا ينصح بذلك)، لكن هذه الدالة لن تعمل بالطريقة التي تتوقعها لفتح مجموعة ملفات، وعلى الرغم من ذلك أنصحك بأن تقوم بمراجعة التوثيق الرسمي للمزيد من المعلومات.
  23. هنالك عدة طرق سهلة وبسيطة لمعرفة ما إذا كانت مصفوفة تحتوي على جميع القيم الموجودة في مصفوفة أخرى، فلو افترضنا أن لدينا المصفوفتين التاليتين: a = [5, 1, 6, 14, 2, 8] b = [2, 6, 15] فإذا طرحنا المصفوفة الأولى من الثانية فسنحصل على العناصر غير الموجودة في المصفوفة الثانية: a - b => [5, 1, 14, 8] لكن إذا طرحنا المصفوفة الثانية من الأولى فسنحصل على العناصر غير الموجودة في المصفوفة الأولى (وهذا ما أردناه): b - a => [15] لذلك ما علينا في هذه الحالة سوى أن نقوم بالتأكد من أن ناتج عملية b – a هي مصفوفة فارغة عن طريق تابع empty? والذي سيقوم بإرجاع true إذا كانت كذلك: (b - a).empty? => false المصدر
  24. من الأفضل أن تقوم بحفظ المعطيات كأعداد صحيحة ومن ثم تعويضها كما تريد عند الحاجة، فكل لغة برمجة طريقتها الخاصة لإضافة البادئة الصفرية، فمثلا في الروبي يمكنك استخدام دالة rjust التي تعمل مع السلاسل النصية لذلك يجب عليك أن أولًا تحويل المتغير الذي يحمل قيمة المعطيات إلى سلسلة نصية قبل أن تستخدم دالة rjust كما في المثال التالي: some_int = 5 some_int.to_s.rjust(2, '0') # => '05' some_int.to_s.rjust(5, '0') # => '00005' يجب الانتباه إلى أن دالة rjust ستضيف البادئة الصفرية حسب طول العدد وإذا كان رقم رتبة البادئة الصفرية أصغر من طول العدد فستقوم بإرجاع العدد دون إضافة بادئة صفرية كما في المثال التالي: another_int = 150 another_int.to_s.rjust(2, '0') # => '150' another_int.to_s.rjust(3, '0') # => '150' another_int.to_s.rjust(5, '0') # => '00150'المصدر
  25. هنالك عدة طرق للحصول على مسار واسم الملف الذي يعمل لكنها تختلف حسب طريق استدعاء الملفات. لذلك إذا افترضنا أن لديك ملفين وهما p1.py و p2.py وقد استدعيت الملف الثاني عن طريق دالة execfile كما في المثال التالي: محتويات ملف p1.py: execfile("p2.py")فيمكنك أن تقوم بمعرفة اسم ومسار الملف الثاني p2.py عن طريق دوال getfile و currentframe من مكتبة inspect أو عن طريق دوال من مكتبة os و inspect في نفس الوقت كما في المثال التالي: محتويات ملف p2.py: import inspect, os print inspect.getfile(inspect.currentframe()) # script filename (usually with path) print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # script directory
×
×
  • أضف...