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

هشام رزق الله

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

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

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

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

    31

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

  1. هذا العامل الشرطي يُستخدم بكثرة في السكربتات المكتوبة بلغة روبي وهو يعمل بنفس الطريقة في لغة السي (الأقواس غير ضرورية)، والصياغة العامة لهذا التعبير (تعبير العامل الشرطي) كالتالي: if_this_is_a_true_value ? then_the_result_is_this : else_it_is_this حيث يكون الشرط في البداية (القيمة المراد التأكد من صحتها -true-) ومن ثم نضع علامة الاستفهام ? وبعد ذلك نكتب نتيجة هذا الشرط إذا كان صحيحا (إذا تحقق الشرط) -true- ونضع نقطتين : ونكتب نتيجة هذا الشرط إذا لم يكن صحيح. كما يمكنك استخدام تعبير if بسطر واحد كما في المثال التالي: if a then b else c end ويقابل هذا السطر باستخدام العامل الشرطي: a ? b : c
  2. من الأفضل استخدام دالة exit() عند استخدام الصدفة التفاعلية (the interactive shell) فهي مشابهة لدالة quit() ووظيفتها الخروج من السكربت (أو من الصدفة التفاعلية) مع إمكانية عرض رسالة عند الإغلاق، وهذه الرسالة يمكنك تمريرها وسوف تظهر عند الإغلاق. أما بالنسبة إلى دالة exit() التابعة لمكتبة sys فيُنصح باستخدامها في التطبيقات والبرامج ويمكنك أيضا تمرير رسالة لعرضها عند إغلاق البرنامج. كلا الدالتين تقومان بالخروج بنفس الطريقة وهي عن طريق SystemExit. يُذكر أن دالة sys.exit() مكتوبة بلغة السي وأما exit() فهي مكتوبة بلغة بايثون. المصادر 1 2
  3. أي ملف بايثون يعتبر كوحدة، وستكون اسمها نفس اسم الملف لكن بدون امتداد .py، أما بالنسبة إلى الحزمة فهي مجموعة من وحدات بايثون، في حين أن الوحدة هي ملف بايثون واحد فقط. يحتوي مجلد حزمة بايثون على ملف إضافي وهو ملف __init__.py لتمييزه من المجلدات التي تحتوي على مجموعة من سكربتات بايثون، ويمكن لمجلد الحزمة أن يتداخل وأن يحتوي على مجلدات داخله وخارجه ويجب أن يحتوي كل مجلد على ملف __init__.py الخاص به. مثال على استدعاء وحدة: import my_moduleمثال على استدعاء وحدة داخل حزمة: from my_package.timing.danger.internets import function_of_loveالمصدر
  4. هنالك عدة طرق سهلة وقصيرة لمعرفة هل المتغير المطلوب موجود أو لا، يمكنك مثلا استخدام طريقة try except وسنبحث عن خطأ NameError والذي سيخبرنا إن كان اسم المتغير المطلو موجود أم لا وبعد ذلك يمكننا وضع التعليمات البرمجية التي نريدها في حالة ما إذا كان المتغير المطلوب موجودا وأيضا في حالة عدم وجوده كما في المثال التالي: try: thevariable except NameError: print "well, it WASN'T defined after all!" else: print "sure, it was defined." كما يمكننا التأكد من وجود المتغير في vars() أو حتى في globals() حتى نعرف هل قمنا بتعريفه من قبل أو لا كما في المثال التالي: 'a' in vars() or 'a' in globals()
  5. السلاسل النصية في بايثون غير قابلة للتغيير، وبسبب هذا فإن تأثير هذه التعليمة line.replace(...) محدود وسيكون بإنشاء سلسلة نصية جديدة بدلا من تغيير السلسلة القديمة، يجب عليك في هذه الحالة إلى إعادة تعيين القيمة إلى line حتى تتمكن من جعل المتغير يحصل على القيمة الجديدة بدون الأحرف المحذوفة. بالإضافة إلى ذلك فإن الطريقة التي اقترحتها تعتبر بطيئة نوعا ما، لذ أنصحك باستخدام دالة translate كما في المثال التالي: line = line.translate(None, '!@#$') أو يمكنك استخدام التعابير النمطية كما في هذا المثال: import re line = re.sub('[!@#$]', '', line) المصدر
  6. لا يوجد في روبي كائن boolean، يمكنك فقط مقارنة الكائن مع true وfalse أو أن تقوم بمقارنة صنف الكائن مع TrueClass وfalseClass. ورغم أنني لا أعرف هدفك من هذه المقارنة إلا أنه يمكنك استخدام هذه الشيفرات البرمجية التي يمكنها أن تساعدك: module Boolean; end class TrueClass; include Boolean; end class FalseClass; include Boolean; end true.is_a?(Boolean) #=> true false.is_a?(Boolean) #=> true module Boolean; end class TrueClass; include Boolean; end class FalseClass; include Boolean; end true.is_a?(Boolean) #=> true false.is_a?(Boolean) #=> trueإذا كنت تستخدم ريلز أو ActiveSupport فيمكنك استخدام تابع ?in كما في المثال التالي: foo.in? [true, false] أو يمكنك استخدام هذه الطريقة أيضا في روبي فهي بسيطة وسهلة القراءة: [true, false].include? fooالمصدر
  7. لقد حدثت تغييرات عديدة في الإصدار الجديد من بايثون، منها تحول تعليمة الطباعة print إلى دالة مع إمكانية إضافة عوامل لتحل محل معظم الصياغات الخاصة لتعليمة الطباعة. هذا هو شكل الدالة الجديد: print("Hello World") لكن إذا قمت بكتابة هذا السطر وقام أحدهم باستخدام إصدار قديم للبايثون لتشغيل برنامج فسيحصل على رسالة خطأ ولتجنب هذه الرسالة من أفضل أن تقوم باستدعاء print_function من مكتبة __future__ وسوف يعمل تطبيقك في الإصدارين القديم والجديد للبايثون. بعض من أهم الفروقات بين إصداري 2 و3 للبايثون: Old: print "The answer is", 2*2 New: print("The answer is", 2*2) Old: print x, # Trailing comma suppresses newline New: print(x, end=" ") # Appends a space instead of a newline Old: print # Prints a newline New: print() # You must call the function! Old: print >>sys.stderr, "fatal error" New: print("fatal error", file=sys.stderr) Old: print (x, y) # prints repr((x, y)) New: print((x, y)) # Not the same as print(x, y)!المصدر
  8. في الحقيقة نادرا ما تُستخدم هذه العلامة في تطبيقات بايثون، فمعنى هذه العلامة أنك أنشأت قائمة لانهائية متداخلة مع نفسها، وفي هذه الحالة لا يمكنك طباعتها، فالمتغير p يحتوي على متغير p آخر والذي يحتوى علىp ...وهكذا. فالعلامة […] تخبرك بأنك قد قمت بإنشاء قائمة لا نهائية ولا يمكن عرضها. صورة توضيحية: أما بالنسبة لاستخدامات القائمة اللانهائية فهي في الغالب تُستخدم لإنشاء الرسوم البيانية حيث تحتاج إلى إنشاء نوع من الحلقات اللانهائية.
  9. يمكنك استخدام هذا السطر الذي سيُزيل محتويات القائمة القديمة بدلا من استبدال القديمة بأخرى جديدة: del l[:] جرب هذا المثال لتفهم ما الذي أقصده بعدم الاستبدال: l1 = [1, 2, 3] l2 = l1 del l1[:] print(l2) كما يمكنك استخدام السطر التالي: alist[:] = [] حيث استخدمنا في المثال عامل الشريحة (the slice operator) لتقسيم العناصر وحذفها. أما لو كنت تستخدم إصدارات بايثون الحديثة (إصدار 3.3 أو أحدث) فيمكنك حينها استخدام التابع المدمج alist.clear() لإفراغ قائمة alist وسيكون هذا السطر معادل لـ del alist[:] في إصدارات بايثون القديمة. المصدر
  10. يمكنك استخدام دالة rename() من مكتبة os أو دالة move() من مكتبة shutil فكلاهما لديه نفس الوظيفة ونفس الصياغة: os.rename("path/to/current/file.foo", "path/to/new/desination/for/file.foo") shutil.move("path/to/current/file.foo", "path/to/new/destination/for/file.foo") تُمرر أولا المسار القديم للملف ومن ثم تُمرر المسار الجديد الذي تريد نقل الملف إليه. يجب في الحالتين أن يكون المسار الجديد موجودا بالفعل أي أن المجلدات التي تريد نقل الملف إليها قد تم إنشاءها قبل تنفيذ الأمر، ويجب عليك في المسارين المحافظة على اسم الملف (القديم والجديد) وإلا فسوف يتم تغيير اسم الملف مع النقل. المصدر
  11. الحل سهل لغاية فما عليك سوى أن تقوم بترميز سكربت بايثون utf-8 عن طريق إضافة سطر الترميز في بداية السكربت بعد مسار مفسر بايثون كتعليق كما يظهر في المثال التالي: #!/usr/bin/env python # -*- coding: utf-8 -*- وبعد ذلك يمكنك استخدام ترميز utf-8 في السلاسل النصية بدون مشاكل كما في المثال التالي: u = 'idzie wąż wąską dróżką' uu = u.decode('utf8') s = uu.encode('cp1250') print(s) لا تنسى أن تتأكد من أن المحرر الذي تستخدمه يُرمّز شيفرتك المصدرية بـ utf-8 وإلا سوف تحصل على حروف غير مرئية لم يتم ترميزها كـ utf-8.
  12. بشكل افتراضي لا يمكنك استدعاء الملفات الموجودة في مجلدات مختلفة عن المجلد الحالي، فالبايثون يقوم بالبحث فقط في المجلد الحالي الذي يعمل فيه السكربت لكن يمكنك استخدام دالة path من مكتبة sys التي ستقوم بإضافة مسارات جديدة للسكربت حيث يقوم بايثون بالبحث فيها عند الاستدعاء، مثال على استخدام هذه الدالة: # some_file.py import sys sys.path.insert(0, '/path/to/application/app/folder') import fileكما يمكنك استخدام هذه السطر: from application.app.folder.file import func_name فقط تأكد من أن folder يحتوي على ملف __init__.py، فهو سيسمح لك بإرفاقه كحزمة. المصدر
  13. بما أنك تستخدم ريلز فيمكنك استخدام تابع simple_format الذي سيقوم بما تريده، فهذا التابع يُحوّل النصوص إلى نصوص مع وسوم HTML، أي أنه سيحول جميع الأسطر الجديدة إلى وسم <br> كما سيقوم بإضافة وسوم الفقرة. مثال على استخدام التابع: simple_format(mystring)أو إذا كنت تستخدم روبي دون ريلز فيمكنك في هذه الحالة استخدام تابع gsub لتحويل أي رمز n\ إلى رمز HTML المقابل له كما في المثال التالي: mystring.gsub(/(?:\n\r?|\r\n?)/, '<br>')المصدر
  14. هنالك عدة طرق لتغيير القيم الموجود في hash معين في روبي، فإذا كنت ترغب تغيير نفس السلسلة النصية دون أن تحصل على سلسلة نصية جديدة فيمكنك في هذه الحالة استخدام توابع مثل gsub! أو replace كما في المثال التالي (أي سطر من السطرين يفي بالغرض): # Two ways to achieve the same result (any Ruby version) my_hash.each{ |_,str| str.gsub! /^|$/, '%' } my_hash.each{ |_,str| str.replace "%#{str}%" } أما لو أردت تغيير السلاسل النصية فيمكنك الاستعانة بهذه الشيفرة البرمجية (كما في المثال الأول؛ أي سطر من السطرين يفي بالغرض): # Two ways to achieve the same result (any Ruby version) my_hash.each{ |key,str| my_hash[key] = "%#{str}%" } my_hash.inject(my_hash){ |h,(k,str)| h[k]="%#{str}%"; h } أما لو أردت الحصول على hash جديد بالتغييرات الجديدة فيمكنك استخدام هذه الشيفرة: # Ruby 1.8.6+ new_hash = Hash[*my_hash.map{|k,str| [k,"%#{str}%"] }.flatten] # Ruby 1.8.7+ new_hash = Hash[my_hash.map{|k,str| [k,"%#{str}%"] } ]
  15. يمكننا فعل ذلك بعدة طرق باستخدام روبي أو ريلز، فمثلا يمكننا استعمال حلقة التكرار لتكرار جميع القيم الموجودة ومن ثم استخدام عدّة توابع مثل instance_variable_get و to_s وdelete للتحويل إلى hash كما في المثال التالي: class Gift def to_hash hash = {} instance_variables.each {|var| hash[var.to_s.delete("@")] = instance_variable_get(var) } hash end end h = Gift.new("Book", 19).to_hashكما يمكنك استخدام هذه الطريقة التي استعملنا فيها توابع متنوعة مثل to_sym وinstance_variable_get حيث استخدمنا حلقة التكرار map لنتمكن من التعامل مع كل عنصر وفي النهاية استخدمنا التابع to_h للتحويل إلى hash: class Gift def to_hash instance_variables.map do |var| [var[1..-1].to_sym, instance_variable_get(var)] end.to_h end end
  16. هنالك عدة طرق لفعل ذلك في لغة روبي وفي ريلز، فيمكنك على سبيل المثال الحصول على hash من السلسلة لنصية التي قمت بتمريريها عن طريق وحدة cgi كما في المثال التالي: require 'cgi' CGI::parse('param1=value1&param2=value2&param3=value3')وسوف تحصل على: {"param1"=>["value1"], "param2"=>["value2"], "param3"=>["value3"]} كما يمكنك استخدام تابع parse_nested_query الذي يقوم بنفس الوظيفة السابقة كما في هذا المثال: Rack::Utils.parse_nested_query 'param1=value1&param2=value2&param3=value3' # => {"param1"=>"value1", "param2"=>"value2", "param3"=>"value3"} وفي النهاية، يمكنك استخدام تابع parse_query حيث تمرّر رابط الموقع كاملًا بينما يُرجع التابع قيم المعاملات فقط، كما في هذا المثال: Rack::Utils.parse_query URI("http://example.com?par=hello&par2=bye").query وسوف تحصل على التالي: { "par" => "hello", "par2" => "bye" }المصدر
  17. هنالك عدة طرق لحساب الفرق بين تاريخين في روبي، وفي حالتك هذه، بما أنك استخدمت أصناف Date (أو حتى DateTime) فإنه يمكنك استخدام العملية البسيطة (end_date – start_date).to_i للحصول على الفرق. أما لو افترضنا أن end_dt وstart_dt صنفان من نوع ActiveSupport::TimeWithZone فإنه سنقوم أولا بتحويلهما إلى تاريخ صالح للحساب عن طريق تابع to_date قبل أن نقوم بالعملية الحسابية لحساب الفرق. وفي النهاية يمكنك استخدام مساعدي ريلز المدمجين كما في المثال التالي: <% start_time = "2012-03-02 14:46:21 +0100" %> <% end_time = "2012-04-02 14:46:21 +0200" %> <%= distance_of_time_in_words(start_time, end_time) %> "about 1 month"المصدر
  18. لم تشرح لنا ماذا ستفعل بهذا الملف؟ أي ما سبب حاجتك لكتابة قائمة في ملف، فهل هذا الملف موجود لقراءته من قبل أشخاص أو برامج أخرى تحتاج إلى بيانات واضح؟ أم أنك تحاول فقط حفظ القائمة في الجهاز لاستخدامها بواسطة نفس تطبيق بايثون، فإذا كنت تحتاج كتابة قائمة في ملف للحالة الأولى فإن الشيفرة البرمجية التالية تفي بالغرض: for item in thelist: thefile.write("%s\n" % item) أما لو كنت تريد حفظ قائمة لاستخدامها لاحقا فأنصحك باستخدام دالة pickle كما في المثال التالي: import pickle pickle.dump(itemlist, outfile)ولقراءة البيانات: itemlist = pickle.load(infile) المصدر
  19. أهم فرق بين النوعين أن tuples حجمها محدد بينما القوائم ديناميكية، أي بكلمات أخرى إن tuples غير قابلة للتغيير على عكس القوائم التي يمكنك التحكم بها كما تريد من إضافة وحذف و...إلخ. أهم الفروقات بين tuples والقوائم: لا يمكنك إضافة عناصر إلى tuples فهي لا تملك توابع للإضافة.لا يمكنك حذف عناصر من tuples فهي لا تملك توابع للحذف أو للإقصاء.يمكنك إيجاد العناصر بسهولة في tuples بما أنها لا تتغير.يمكنك في tuples استخدام العامل in للتأكد من وجود عنصر معين.المصدر
  20. إن الفرق الرئيسي بين دالتي __getattr__ و __getattribute__ هو أن الأولى تُستخدم فقط في حالة لم يتم إيجاد السمة (attribute) بالطرق العادية، أي أنها تعتبر كأنها خطة احتياطية لإيجاد السمات المفقودة. أما بالنسبة إلى __getattribute__ فهي تُستدعى قبل النظر إلى السمات الحالية الموجودة في الكائن. تُشتق أصناف النمط الجديد من الكائن على عكس أصناف النمط القديم الموجودة في الإصدار الثاني من بايثون التي لا تملك صنف قاعدة واضح. ولن يكون الفرق بين النمط القديم والجديد شيء أساسي لاختيار دالة بين __getattr__ و __getattribute__ أي أنه لا أهمية له في اختيار استخدامك. المصدر
  21. يمكنك الحصول على طول السلسلة النصية بطريقتين في بايثون، الأول هي عن طريق استخدام تابع السلاسل النصية __len__() الذي سوف يعطيك طول السلسلة بدون أن تقوم بتمرير أي شيء كما في المثال التالي: >>> a.__len__() 23 ويمكنك أيضا استخدام دالة len() التي تشبه تابع __len__() فهي تقوم بإرجاع طول السلسلة النصية لكن الفرق أن len هي دالة وليست تابع لسلسلة النصية النصية ويمكنك استخدامها مع أنواع بيانات أخرى مثل القوائم … مثال على استخدام دالة len: len(s)
  22. في الحقيقة طريقة الحصول على الحرف الأول من سلسلة نصية معينة تختلف من إصدار روبي لآخر، فلكل إصدار طريقته الخاصة، فلو كنت تستخدم إصدار جديد من روبي (الإصدار 1.9.0+) فيمكنك الحصول على الحرف الأول من السلسلة النصية بسهولة عن طريق السطر التالي: 'Smith'[0] # => 'S' ويمكنك استخدام هذه شيفرة برمجية لو أردت أن تعمل شيفرتك على الإصدار 1.8.7+: 'Smith'.chars.first # => 'S' أما لو كنت تستخدم إصدار روبي أقدم من الإصدار 1.8.7 ففي هذه الحالة أنصحك باستخدام التابعين المدمجين split و first كما في المثال التالي: 'Smith'.split(//).first # => 'S'
  23. يمكنك فعل ذلك عن طريق استخدام طريقة الشرائح في روبي، فلو افترضنا أنك تريد الحصول على أول حرف من نص معين فيمكنك فعل ذلك عن طريق الأمر التالي(افترضنا أن النص موجود في متغير a): a[0] أما لو أردت الحصول على أول 10 حروف من النص فيجب عليك كتابة الأمر التالي: a[0..9] لاحظ أننا بدأنا من الحرف الذي رتبته 0 وهو الحرف الأول وانتهينا في الحرف الذي رتبته 9 وهو الحرف العاشر. مثال آخر، لو أردنا الحصول على الحروف من الرتبة 20 إلى 30 فيمكنك فعل ذلك عن طريق الأمر التالي: a[19..29] المصدر
  24. من الأفضل أن تكون الاستدعاءات في أعلى الملف، بالضبط بعد التعليقات وسلاسل التوثيق النصية(docstrings) وقبل تعريف المتغيرات والثوابت. على الرغم من أنه يمكنك استدعاء وحدة أو مكتبة معينة من خلال دالة في منتصف البرنامج إلا أنني لا أنصح بذلك. وذلك لأن الاستدعاءات تتطلب بعض الوقت حتى تتم، لذا يُفضل أن تدفع ثمن الاستدعاء (وقت الانتظار) مرة واحدة أثناء تشغيل البرنامج بدلا من وضعها في دالة ومن ثم يستغرق استدعاء مكتبة معينة وقت أطول. لذلك ولأجل لكفاءة يُوصى بوضع الاستدعاءات في بداية الملف. المصدر
  25. في جزء JSON، متغير data هو عبارة عن قاموس ولم يتم ترميزه كبيانات JSON مما تسبب في ظهور رسالة الخطأ، وهنالك حلين لهذه المشكلة حسب إصدار بايثون المثبت على جهازك، فإذا كنت تستخدم الإصدار الثاني من بايثون فسنقوم باستخدام ترميز utf-8 بالإضافة إلى المكتبتين json وio كما في المثال التالي: import io, json with io.open('data.txt', 'w', encoding='utf-8') as f: f.write(unicode(json.dumps(data, ensure_ascii=False))) أما لو كنت تستخدم الإصدار الجديد من بايثون (الإصدار الثالث) فسيكون الأمر أسهل، فلن نستخدم سوى دالة dump من مكتبة json مع الدالة المدمجة open كما في المثال التالي: import json with open('data.txt', 'w') as f: json.dump(data, f, ensure_ascii=False) المصدر
×
×
  • أضف...