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

هشام رزق الله

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

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

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

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

    31

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

  1. هنالك عدّة طرق للحصول على قائمة المجلدات في مجلد معين في لغة روبي، فإذا أردت حل سريع وقصير وفي سطر واحد فيمكنك استخدام هذه الطريقة التي استخدمنا فيها عدة توابع مثل Dir.entries وfile.directory? وغيرها: Dir.entries('/your_dir').select {|entry| File.directory? File.join('/your_dir',entry) and !(entry =='.' || entry == '..') } كما يمكنك استخدام هذه الطريقة السهلة والبسيطة والتي استخدمنا فيها تابع glob، وتدعم هذه الطريقة جميع المجلدات حتى المخفية منها كما في المثال التالي: Dir.chdir('/destination_directory') Dir.glob('*').select {|f| File.directory? f} ملاحظة: الملفات المخفية هي التي تبدأ بنقطة (.)
  2. هنالك عدّة طرق لاستبدال سلسلة نصية بنمط من تعبير نصي في لغة روبي، فيمكنك على سبيل المثال استخدام دالة gsub() مع '\1' للاستبدال كما في المثال التالي: "foo".gsub(/(o+)/, '\1\1\1') #=> "foooooo" لاحظ أننا استخدمنا علامة الاقتباس مفردة وهذا الأمر مهم لأنه في حالة استخدامك لعلامة الاقتباس المزدوجة فيجب عليك في هذه الحالة تهريب رمز \. بما أنك مهتم بالمجموعات (كما يبدو في مثالك)، لاحظ أنه يمكنك استخدام التعابير النصية مع السلاسل النصية عن طريق index كما في المثال التالي: "foo"[/oo/] #=> "oo" "Z_123: foobar"[/^Z_.*(?=:)/] #=> "Z_123"
  3. نعم هنالك عدة طرق لإعادة تسمية مفتاح قاموس في لغة بايثون، وهذه الحلول تعتمد على نوع القاموس فإذا كان القاموس عاديا فيمكنك استخدام هذه الطريقة: mydict[new_key] = mydict.pop(old_key) أما بالنسبة للقاموس المرتب فيجب عليك في هذه الحالة إعادة بناء القاموس بالكامل كما في المثال التالي: >>> OrderedDict(zip('123', 'abc')) OrderedDict([('1', 'a'), ('2', 'b'), ('3', 'c')]) >>> oldkey, newkey = '2', 'potato' >>> OrderedDict((newkey if k == oldkey else k, v) for k, v in _.viewitems()) OrderedDict([('1', 'a'), ('potato', 'b'), ('3', 'c')]) إن تعديل المفتاح هو أمر غير شائع في لغة بايثون لأن المفاتيح في العادة هي كائنات غير قابلة للتغيير مثل الأرقام أو السلاسل النصية أو غيرها، لذلك بدلا من تعديل المفتاح، إن الطريقة الوحيدة في بايثون التي تُمكنك من تعديل المفتاح هي عن طريق إعادة تعيين قيمة للمفتاح ومن ثم حذف المفتاح القديم.
  4. هنالك عدّة طرق للتأكد من وجود عدة سلاسل نصية في سلسلة نصية أخرى في لغة بايثون، فيمكنك على سبيل المثال استخدام any في الجملة الشرطية كما في المثال التالي: if any(x in str for x in a): وفي حالة ما أردت التأكد من وجود جميع السلاسل النصية الموجودة في قائمة فيمكنك استخدام all بدلا من any. هنالك أيضا حل آخر بسيط وسهل الفهم لكنه أطول بكثير من المثال السابق والذي قمنا فيه باستخدام حلقة التكرار والجمل الشرطية: a = ['a', 'b', 'c'] str = "a123" found_a_string = FALSE for item in a: if item in str: found_a_string = TRUE if found_a_string: print "found a match" else: print "no match found"
  5. نعم، فيمكنك القيام بأي شيء عن طريق لغة بايثون تقريبا. المكتبة المسؤولة عن إرسال الرسائل في لغة بايثون تدعى بـ smtplib وتحتوي على عدد من الدوال التي تحتاجها في عملية إرسال الرسالة، لكن قبل ذلك، يجب عليك أن تحصل على جميع المعلومات التي تحتاجها في الإرسال مثل اسم المستخدم وكلمة المرور والخادم والبريد الإلكتروني للمرسل والمستقبل بالإضافة إلى عنوان الرسالة ومحتواها. هذا مثال بسيط لإرسال رسالة باستخدام مكتبة smtplib: import smtplib fromaddr = 'user_me@gmail.com' toaddrs = 'user_you@gmail.com' msg = 'Why,Oh why!' username = 'user_me@gmail.com' password = 'pwd' server = smtplib.SMTP('smtp.gmail.com:587') server.ehlo() server.starttls() server.login(username,password) server.sendmail(fromaddr, toaddrs, msg) server.quit() وبما أنك ذكرت أنك تريد إنشاء برنامج للإرسال، فيمكنك في هذه الحالة إنشاء دالة للإرسال كما في المثال التالي: def send_email(user, pwd, recipient, subject, body): import smtplib gmail_user = user gmail_pwd = pwd FROM = user TO = recipient if type(recipient) is list else [recipient] SUBJECT = subject TEXT = body # Prepare actual message message = """\From: %s\nTo: %s\nSubject: %s\n\n%s """ % (FROM, ", ".join(TO), SUBJECT, TEXT) try: server = smtplib.SMTP("smtp.gmail.com", 587) server.ehlo() server.starttls() server.login(gmail_user, gmail_pwd) server.sendmail(FROM, TO, message) server.close() print 'successfully sent the mail' except: print "failed to send mail"
  6. هنالك عدّة طرق لتعريف تابع في سطر واحد في روبي حسب محتوياته، فأسهل وأبسط الطرق هي كالتالي: def hello() :hello end أو مثلا يمكنك تطوير السطور السابقة قليلا وإنشاء تابع أفضل، كإنشاء تابع لجمع معاملين كما هنا: def add a,b; a+b end وهنالك طريقة أخرى تعمل في الإصدار 1.8 من روبي وقد تم الاستغناء عنها في إصدار 1.9 وهي عن طريق استخدام تابع define_method كما في المثال التالي: define_method(:add) {|a,b| a+b }
  7. هنالك عدّة طرق لتوليد ألوان ست عشرية في لغة روبي، وبما أنك تبحث عن تابع معين، فهنالك تابع في ريلز يقوم بتوليد الأرقام العشوائية وهو SecureRandom.hex ويمكنك استخدامه كما في المثال التالي: ActiveSupport::SecureRandom.hex(3) أما في لغة روبي فلا يوجد تابع لتوليد الألوان حسب علمي، لكن هنالك طرق لتوليد الأرقام عشوائيا فمثلا يمكنك استخدام هذه الطريقة: colour = "%06x" % (rand * 0xffffff) أو يمكنك توليد كل جزء من أجزاء اللون على حد ومن ثم دمجهم كما في المثال التالي: r = rand(255).to_s(16) g = rand(255).to_s(16) b = rand(255).to_s(16) r, g, b = [r, g, b].map { |s| if s.size == 1 then '0' + s else s end } color = r + g + b # => e.g. "09f5ab"
  8. هنالك طرق سهلة لدمج القواميس في لغة بايثون، منها استخدام دالة update حيث ستطبق هذه الدالة على القاموس الأول وتمرر لها القاموس الثاني كما في المثال التالي: orig.update(extra) أما لو لم ترد تغيير محتويات قاموس orig فيمكنك حينها عمل نسخة للقاموس ومن ثم تطبيق دالة update على النسخة كما في المثال التالي: dest = dict(orig) # or orig.copy() dest.update(extra) في حالة كان هنالك مفاتيح متشابهة فانه سيتم أخذ قيمة المفتاح من القاموس الثاني كما في هذا المثال: >>> d1 = {1: 1, 2: 2} >>> d2 = {2: 'ha!', 3: 3} >>> d1.update(d2) >>> d1 {1: 1, 2: 'ha!', 3: 3}
  9. أسهل طريقة للحصول على طول عدد صحيح أي عدد الأرقام التي يتكون منها هي عن طريق تحويل هذا العدد إلى سلسلة نصية ومن ثم استخدام دالة len() لحساب عدد الأحرف التي تتكون منها السلسلة النصية وهي في هذه الحالة العدد الذي تبحث عن طوله: len(str(123)) أما لو لم ترد تحويل الأرقام إلى سلاسل نصية فيمكنك حينها استخدام دوال مكتبة math كما في المثال التالي: import math digits = int(math.log10(n))+1 أما بالنسبة للأرقام السالبة فيمكنك استعمال شيفرة التالية: import math if n > 0: digits = int(math.log10(n))+1 elif n == 0: digits = 1 else: digits = int(math.log10(-n))+2 # +1 if you don't count the '-'
  10. في بايثون هناك عدة عوامل تشبه عامل "لا يساوي" في اللغات الأخرى، ويعتمد ذلك على استخدامك واحتياجك، فيمكنك مثلا استخدام العامل != وهو أكثر عامل "لا يساوي" ينصح به في لغة بايثون كما يوجد عامل آخر يقوم بنفس الوظيفة وهو عامل <> وقليلا ما تجده في الشيفرات البرمجية المكتوبة بلغة بايثون، وأما إذا أردت المقارنة بين الكائنات فيمكنك استخدام كلمة is وعكسها أي كلمة is not، لتفهم هذه الأوامر أكثر أنصحك بالاطلاع على هذا المثال: 1 == 1 # true 1 != 1 # false 1 <> 1 # false [] is [] # false (distinct objects) a = b = []; a is b # true (same object) المصدر
  11. هنالك عدّة خيارات للتحكم في طول السلسلة النصية التي يدخلها المستخدم مع إضافة خيار السماح بترك الحقل فارغ، فيمكنك مثلًا استخدام دوال التحقق كما في المثال التالي: validates :foo, length: {minimum: 5, maximum: 5}, allow_blank: trueحيث سيكون minimum هو أقل عدد من الحروف المسموح به وأما maximum فهو لأكبر عدد من الحروف كما قمنا بوضع true لخيار allow_blank للسماح بترك الحقل فارغ. أو يمكنك استخدام هذه الصياغة أيضا: validates :foo, length: {minimum: 5, maximum: 5}, allow_blank: true وفي حالة كان الحد الأقصى والأدنى للحروف نفسه (يجب طباعة عدد معين من الحروف فقط) فيمكنك استخدام هذه الصياغة: validates :foo, length: {is: 5}, allow_blank: true المصدر
  12. للأسف، لغة روبي لا تدعم التوابع المتداخلة كما في عدّة لغات أخرى، لكن هنالك طرق أخرى يمكنك استخدامها بدلا من استخدام طريقة التوابع، فمثلا يمكنك إنشاء صنف مشابه لهذا: class Test1 def meth1 def meth2 puts "Yay" end meth2 end end Test1.new.meth1قمنا في السطور السابقة بتعريف تابع بشكل حيوي، فعندما تُشغل meth1 فسيتم تنفيذ السطور البرمجية الموجودة داخل meth1 وبما أنه قمنا بتعريف تابع آخر داخل meth1 وهو meth2 سيتم تنفيذه عندما تستدعيه عن طريق كتابة meth2.
  13. هنالك بعض الفروقات البسيطة بين الدوال المختلفة للخروج في بايثون، فدالة quit تصدر استثناء (exception) من نوع SystemExit خلف الكواليس ولو قمت بطباعتها فسيظهر التالي: >>> print (quit) Use quit() or Ctrl-Z plus Return to exit >>> كما يبدو فإن هذه الميزة قد تم إضافتها لمساعدة الأشخاص الذين لا يملكون خبرة بلغة بايثون. وهنالك أيضا دالة exit وهي تشبه دالة quit وتعتبر كمثيل لها ولقد وُجدت في بايثون لتسهيل استخدام اللغة. عند طباعة الدالة السابقة يظهر التالي: >>> print (exit) Use exit() or Ctrl-Z plus Return to exit >>> وهو يشبه ما يظهر عندما نقوم بطباعة الدالة السابقة. أما بالنسبة لدالة sys.exit فهي أيضا تصدر استثناء SystemExit في الخلفية والفرق بينها وبين الدالتين السابقتين أنها أفضل عند البرمجة لأنها تعتمد على وحدة sys والتي يتم استدعاؤها في أغلب الأوقات. وفي النهاية توجد أيضا دالة os._exit وهي تُخرجك من البرنامج من دون استدعاء cleanup handlers و flushing stdio buffers ويتم استخدام هذه الطريقة للخروج في حالات خاصة وأشهر حالات الخروج هي في عمليات الأبناء الذين تم إنشاؤهم عن طريق os.fork المصادر 1 2
  14. تمتلك لغة بايثون مميزات كثيرة تجعلها حيوية وسهلة الاستخدام، فكما في لغة سي فإنه سيتم دمج السلاسل النصية الحرفية المتجاورة أثناء وقت تجميع الشيفرة البرمجية ويمكنك في هذه الحالة تقسيم السلسلة النصية عن طريق الرمز \ كما يظهر في المثال التالي: def fun(): print '{0} Here is a really long ' \ 'sentence with {1}'.format(3, 5) أو يمكنك تقسيمها بدون الرمز \ حيث ليس للبادئة أية أهمية كما تظهر في المثال التالي (لا تنسَ فتح وإغلاق الأقواس): >>> def fun(): return ('{0} Here is a really long' ' sentence with {1}').format(3, 5) والحل الأخير وضع السلسلة النصية في متغير واستدعاؤه في مكانه المناسب كما في المثال التالي: >>> def fun(): ... s = '{0} Here is a really long sentence with {1}' ... print s.format(3, 5) المصدر
  15. للحصول على الشيفرة البرمجية لدالة مكتوبة بلغة بايثون يمكنك استخدام دالة getsourcelines من وحدة inspect حيث أنها ستُرجع لك الشيفرة البرمجية على شكل سلسلة نصية واحدة بعد أن تمرر لها اسم الدالة المطلوبة. ملاحظة: حسب علمي إذا كانت الدالة قد تم تجميعها (compiled) من سلسلة نصية أو تم استدعاؤها من ملف تم تجميعه فإنك لن تستطيع الحصول على شيفرتها البرمجية. عندما تكون الشيفرة البرمجية غير موجودة يمكنك استخدام دالة dis من مكتبة dis للحصول على بعض معلومات هذه الدالة كالتالي: >>> import dis >>> def foo(arg1,arg2): ... #do something with args ... a = arg1 + arg2 ... return a ... >>> dis.dis(foo) 3 0 LOAD_FAST 0 (arg1) 3 LOAD_FAST 1 (arg2) 6 BINARY_ADD 7 STORE_FAST 2 (a) 4 10 LOAD_FAST 2 (a) 13 RETURN_VALUE
  16. هنالك عدّة طرق للتأكد من وجود عناصر معينة في قائمة، فيمكنك على سبيل المثال استخدام دالة any() والتي ستقوم بأمر معين (اخترنا أمر الطباعة print) لجميع العناصر التي يتحقق فيها الأمر الذي تم تمريره إليها كما في المثال التالي: print any(x in a for x in b) هنالك طرق أخرى للحل فمثلا يمكنك إنشاء قائمة للعناصر الموجودة في القائمة الأولى أو يمكنك إنشاء set لفعل نفس الشيء كما في الأمثلة التالية: >>> L1 = [2,3,4] >>> L2 = [1,2] >>> [i for i in L1 if i in L2] [2] >>> S1 = set(L1) >>> S2 = set(L2) >>> S1.intersection(S2) set([2])
  17. هنالك عدّة طرق لتنسيق شكل العملات في لغة بايثون، منها استخدام وحدة locale فهي المسؤولة عن تنسيق العملات (والوقت) حيث نستعمل دالة setlocale لتحديد موقعنا الجغرافي ومن ثم سنستخدم دالة currency لتنسيق العملة كما في المثال التالي: >>> import locale >>> locale.setlocale( locale.LC_ALL, '' ) 'English_United States.1252' >>> locale.currency( 188518982.18 ) '$188518982.18' >>> locale.currency( 188518982.18, grouping=True ) '$188,518,982.18' وإذا كنت تستخدم الإصدار 2.7 من بايثون فيمكنك التنسيق بسهولة عن طريق السطر التالي: >>> '{:20,.2f}'.format(18446744073709551616.0) '18,446,744,073,709,551,616.00' وهنالك طريقة أخرى للحل باستخدام حزمة babel مع دالة numbers.format_currency كما في المثال التالي: >>> import babel.numbers >>> import decimal >>> babel.numbers.format_currency( decimal.Decimal( "188518982.18" ), "GBP" ) £188,518,982.18 المصدر
  18. هنالك فرق بسيط بين $1 و \1، فالأولى هي متغيّر عالمي والذي يمكن أن يُستخدم في أماكن متعدّدة من الشيفرة البرمجية، فمثلا يمكنك استخدامه في الجمل الشرطية كما في المثال التالي: if "foobab" =~ /foo(.*)/ then puts "The matching word was #{$1}" end أما \1 فهي مرجع خلفي والتي ستعمل فقط في توابع sub أو gusb ولا يمكنك استخدامها في أماكن أخرى، كمثال لنفترض أنك تبحث عن الجزء الثاني من كلمة موجودة في سلسلة نصية معينة فسوف تقوم بشيء مشابه لهذا (لاحظ أننا كررنا الجزء الثاني مرتين): "foobar".sub(/foo(.*)/, '\1\1') # => "barbar"
  19. أعتقد أن الصياغة التي تبحث عنها هي هذه: lambda x: True if x % 2 == 0 else False لكنها تعتبر صياغة سيئة في بايثون ولا ينصح باستخدامها. المشكلة أنه لا يمكنك كتابة أي أمر في دالة lambda فمثلا لا يمكنك استخدام print أو raise فيها. طريقة أخرى للحل باستخدام lambda: f = lambda x: x == 2 and x or Noneالحل الآخر هو أن تقوم بعمل دالة كاملة بدل استخدام lambda وهذا الحل في رأيي هو الأفضل، وسيكون شكل الدالة الكاملة كالتالي: def f(x): if x == 2: print(x) else: raise ValueError
  20. للتعامل مع ملفات json في لغة روبي يمكنك استخدام مكتبة json فهي المكتبة صحيحة للتعامل معها. سنقوم ببعض التعديلات في شيفرتك البرمجية حتى تعمل بالشكل المطلوب، فسنعدل على أول سطر الكتابة وسنحول hash المطلوب إلى Json عن طريق تابع to_json ومن ثم سنرتب المتغيرات قليلا وسنضيف do |f| إلى سطر فتح الملف كما في المثال التالي: require 'json' tempHash = { "key_a" => "val_a", "key_b" => "val_b" } File.open("public/temp.json","w") do |f| f.write(tempHash.to_json) end وسيكون شكل الناتج كالتالي(محتويات الملف): {"key_a":"val_a","key_b":"val_b"} كما يمكنك استخدام تابع JSON.pretty_generate للحصول على ناتج بشكل أفضل كما في المثال التالي: { "key_a":"val_a", "key_b":"val_b" } المصدر
  21. ليس لهذه الكلمة الكثير من الاستخدامات، فاستخدامها الوحيد هو حينما تريد تغيير و إنشاء متغيرات عامة في محتوى محلي على الرغم من أن إنشاء متغيرات عالمية نادرا ما يعتبر حلا جيدا في البرمجة بلغة بايثون، مثال: def bob(): me = "locally defined" # Defined only in local context print me bob() print me # Asking for a global variableالسطر الأخير للشيفرة البرمجية سيسبب لك هذا الخطأ: locally defined Traceback (most recent call last): File "file.py", line 9, in <module> print me NameError: name 'me' is not defined هذا الخطأ بسبب أن me غير مُعرّفة، ولحل هذه المشكلة يجب عليك استخدام global حيث ستتمكن من استخدام المتغير خارج الدالة أي سيصبح متغيرا عالمي: def bob(): global me me = "locally defined" # Defined locally but declared as global print me bob() print me # Asking for a global variableوالسطور السابق سوف تُظهر لك: locally defined locally defined
  22. هنالك عدة طرق لفرز مفاتيح قاموس معين في بايثون لكن أغلب هذه الطرق تعتمد على دالة sorted() للفرز، فعلى سبيل المثال يمكنك استخدام هذه الدالة مع تمرير اسم القاموس كمعامل أول ومن ثم دالة lambda بداخلها خوارزمية الفرز كعامل ثاني كما يظهر في المثال التالي: >>> mydict = {'a':1,'b':3,'c':2} >>> sorted(mydict, key=lambda key: mydict[key]) ['a', 'c', 'b'] كما يمكنك استخدام هذه الطريقة المختصرة أيضا، إذ مررنا اسم القاموس في معامل الأول و key=d.get كمعامل ثاني: sorted(d, key=d.get) طريقة أخرى: my_list = sorted(dict.items(), key=lambda x: x[1])
  23. هنالك طرق مختلفة لتوليد مصفوفة من الأحرف والأرقام في لغة روبي، فإذا كنت تستخدم الإصدار 1.8 من روبي فيمكنك توليد المصفوفة عن طريق مجال الحروف والأرقام مع استعمال دالة to_a للتحويل إلى مصفوفة كما في المثال التالي: ('a'..'z').to_a + ('0'..'9').to_a # works in 1.8 and 1.9 أو يمكنك استخدام حلقة التكرار map مع دالة to_s لتحويل الأرقام إلى حروف كما في المثال التالي: (0...36).map{ |i| i.to_s 36} وهنالك أيضا حل آخر يعمل في الإصدار 1.9 من روبي كما يظهر في المثال التالي: [*('a'..'z'), *('0'..'9')] # doesn't work in Ruby 1.8
  24. هنالك طرق مختلفة لمعرفة وجود صنف معين في برنامج لغة روبي، فيمكنك على سبيل المثال استخدام Module.const_get للحصول على الثابت (constant) التي أشارت إليها السلسلة النصية، وعند استخدام تلك الدالة فسترجع لك ثابت (الأصناف في الغالب يتم الإشارة إليها عن طريق ثابت)، يمكنك بعد ذلك التأكد ما إذا كان الثابت صنف أم لا. مثال بسيط حول استخدام Module.const_get: def class_exists?(class_name) klass = Module.const_get(class_name) return klass.is_a?(Class) rescue NameError return false end كما يمكنك فعلك ذلك بطريقة أقصر كما تبدو في المثال التالي: if defined?(MyClassName) == 'constant' && MyClassName.class == Class puts "its a class" end
  25. يمكنك حذف المسافات الزائدة في السلاسل النصية في لغة بايثون بسهولة باستخدام دالتي join() وsplit واللتان ستمكنك من حذف أي فراغ زائدة في السلسلة النصية كما في المثال التالي: " ".join(foo.split()) كما يمكنك استخدام التعابير النصية لحذف الفراغات عن طريق دالة sub من وحدة re كما في المثال التالي: >>> import re >>> re.sub(' +',' ','The quick brown fox') 'The quick brown fox' طريقة أخرى للحل باستخدام التعابير النصية كما في المثال التالي: import re s = "The fox jumped over the log." re.sub("\s\s+" , " ", s) ويمكنك أيضا استخدم هذه الطريقة التي تدعم tabs بالإضافة إلى الفراغات: >>> import re >>> str = 'this is a string with multiple spaces and tabs' >>> str = re.sub('[ \t]+' , ' ', str) >>> print str this is a string with multiple spaces and tabs
×
×
  • أضف...