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

هشام رزق الله

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

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

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

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

    31

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

  1. يمكنك كتابة حلقات تكرار معكوسة بعدة طرق ومنها استخدام تابع downto مع حلقة التكرار for كما في المثال التالي: for i in (10).downto(0) puts i end أو يمكنك ببساطة استخدم تابع downto مع التعليمة do كما يظهر في المثال التالي: index = 10 # any value index.downto(0) do |i| puts i end كما يمكنك استخدام عداد يعمل بطريقة عكسية مع وضع شرط في حلقة تكرار until كما في المثال التالي: i = index until i > 0 i -= 1 puts i end
  2. في لغة روبي لن تعمل طريقة Time.now + 10.hours لأن لأن هذه الطريقة تابعة لمكتبة ActiveSupport الموجودة في إطار ويب ريلز، وبالطبع فهو يملك أيضا توابع minutes وseconds. أما بالنسبة لإضافة الوقت إلى كائن Time في روبي فيمكنك استخدام العامل الحسابي + ومن ثم تكتب عدد الثواني التي تريد إضافتها إلى الوقت، وفي حالة ما أردت إضافة دقائق فاضرب عدد الدقائق في 60 ونفس الأمر بالنسبة للساعات والأيام وغيرها كما في المثال التالي: irb> t = Time.now #=> 2011-08-03 22:35:01 -0600 irb> t2 = t + 10 # 10 Seconds #=> 2011-08-03 22:35:11 -0600 irb> t3 = t + 10*60 # 10 minutes #=> 2011-08-03 22:45:01 -0600 irb> t4 = t + 10*60*60 # 10 hours #=> 2011-08-04 08:35:01 -0600
  3. هنالك عدة طرق في لغة بايثون لاستبدال حروف غير آسكي، لكني سأشرح وأُصلح الأمثلة التي ذكرتها في سؤالك. التعبير الذي وضعته في المثال الأول سيقوم بترشيح السلسلة النصية بدلا من الاستبدال، فهو سيحذف جميع حروف غير آسكي كما ذكرت، ولحل هذه المشكلة أنصحك باستخدام تعبير شرطي كما في المثال التالي: return ''.join([i if ord(i) < 128 else ' ' for i in text]) في المثال السابق سيتم التعامل مع كل حرف على حدة ومن ثم يستبدل الحروف المطلوبة. أما الخطأ في التعبير النمطي الذي وضعته فهو أنك نسيت وضع + في التعبير كما في المثال التالي حتى تتمكن من الاستبدال: re.sub(r'[^\x00-\x7F]+',' ', text)
  4. بشكل عام من ناحية التصرفات فإن جميع هذه الطرق للرجوع من تابع معين تتصرف بنفس التصرف ولا يوجد فرق بينها، فجميعها ستُرجع لك None عند انتهاء تنفيذ سطورها، لكن الفرق البسيط بين هذه الطرق هي وقت و مكان إرجاع None، وهنا يبرز فرق استخدامها فمثلا return None تعني إرجاع قيمة None لاستخدامها لاحقا وreturn تُستخدم بطريقة مشابهة لـ break في حلقات التكرار في حين أن عدم إرجاع شيء فهو يشبه return في دوال void في لغات السي بلس بلس والجافا.
  5. يمكنك جعل حلقة التكرار تدور حول كل عنصرين معا بدلا من عنصر واحد بطرق متعددة في لغة بايثون، فيمكنك مثلا إنشاء دوال للقيام بذلك مثال دالة pairwise() ومن ثم استخدامها للتكرار كما في المثال التالي: from itertools import izip def pairwise(iterable): "s -> (s0,s1), (s2,s3), (s4, s5), ..." a = iter(iterable) return izip(a, a) for x, y in pairwise(l): print "%d + %d = %d" % (x, y, x + y)أو يمكنك إنشاء دالة grouped() والتي تشبه كثيرا الدالة السابقة لكنها تختلف قليلا في آلية عملها كما تظهر في المثال التالي: from itertools import izip def grouped(iterable, n): "s -> (s0,s1,s2,...sn-1), (sn,sn+1,sn+2,...s2n-1), (s2n,s2n+1,s2n+2,...s3n-1), ..." return izip(*[iter(iterable)]*n) for x, y in grouped(l, 2): print "%d + %d = %d" % (x, y, x + y)ومن الطرق الأخرى أيضا للدوران حول كل عنصرين معا هي عن طريق إنشاء tuple يتكون من عنصرين كما في المثال التالي: data = [1,2,3,4,5,6] for i,k in zip(data[0::2], data[1::2]): print str(i), '+', str(k), '=', str(i+k)
  6. هنالك طرق عديدة في لغة روبي لإيجاد العنصر الأكثر تكرارا في مصفوفة معين، فيمكنك على سبيل المثال بناء hash يدور حول عناصر المصفوفة ويسجل مرات تكرارها كما في المثال التالي: arr = [1, 1, 1, 2, 3] freq = arr.inject(Hash.new(0)) { |h,v| h[v] += 1; h } #=> {1=>3, 2=>1, 3=>1}وبعد ذلك يمكنك البحث عن العنصر الذي يملك أكبر عدد من التكرارات كما في المثال التالي: arr.max_by { |v| freq[v] } #=> 1 ومن الطرق الأخرى لإيجاد التكرارات هي عن طريق ترتيب المصفوفة حسب مرات تكراراها ومن ثم نحصل على العنصر الأخير منها كما في المثال التالي: sort_by {|i| grep(i).length }.last كما يمكنك استخدام هذه الطريقة والتي تعتبر الأسرع مقارنة بالطريقتين السابقتين: freq = inject(Hash.new(0)) { |h,v| h[v] += 1; h } max = freq.values.max # we're only interested in the key(s) with the highest frequency freq.select { |k, f| f == max } # extract the keys that have the max frequency
  7. حسب التوثيق الرسمي للروبي فإن الفرق بين الإثنين هو التالي: ولزيادة الفهم، إذا كتبت a..b فكأنك كتبت مجالا يبدأ من a وينتهي في b وستكون a و b منتميتين إلى هذا المجال فكأنك قد كتبت a <= x <= b في حين أن a...b هي عكس الطريقة السابقة لأن كتابة المجال بثلاث نقاط يشبه كتابة a <= x < b. احذر الأخطاء التالية التي تتكرر بكثرة: (1..4).include?(4.5) #=> false (1...5).include?(4.5) #=> true (1..4).to_a == (1...5).to_a #=> true (1..4) == (1...5) #=> false
  8. هنالك عدة طرق في لغة بايثون لتشغيل ملف سكربت shell من داخل برنامجك، فيمكنك على سبيل المثال استخدام دالة system من مكتبة os ومن ثم تمرر لها أمر تنفيذ سكربت بايثون كما في المثال التالي: os.system(“./script.sh”) أو يمكنك ببساطة استخدام دالة call من وحدة subprocess لتشغيل أي سكربت كما في المثال التالي: >>> import subprocess >>> subprocess.call(['./test.sh']) # Thanks @Jim Dennis for suggesting the [] 0 >>> حيث أن test.sh هو سكربت shell بسيط وأما 0 فهي القيمة العائدة من التشغيل. في حالة ما رغبت بتمرير بعض المعاملات إلى السكربت فيمكنك في هذه الحالة الاستعانة بدالة split من وحدة shlex كما في المثال التالي: import subprocess import shlex subprocess.call(shlex.split('./test.sh param1 param2')) المصدر
  9. هنالك عدّة طرق في لغة بايثون لدمج القواميس وبما أنك ذكرت السرعة فأسرع طريقة للدمج هي عبر استخدام منشئ dict ومن ثم استخدام دالة update كما يظهر في المثال التالي: $ python -mtimeit -s'd1={1:2,3:4}; d2={5:6,7:9}; d3={10:8,13:22}' \ 'd4 = dict(d1, **d2); d4.update(d3)' 1000000 loops, best of 3: 1.88 usec per loopأو يمكنك استخدام هذه الطريقة التي استعملنا فيها دالة update مباشرة فهي كما تلاحظ أبطئ قليلا لكنها مقبولة: $ python -mtimeit -s'd1={1:2,3:4}; d2={5:6,7:9}; d3={10:8,13:22}' \ 'd4 = {}' 'for d in (d1, d2, d3): d4.update(d)' 100000 loops, best of 3: 2.67 usec per loopكما يمكنك دمج محتويات القواميس عن طريق استخدام دالة items() مع العامل الحسابي + كما في المثال التالي على الرغم من أنني لا أنصح بهذه الطريقة لأنها الأبطأ: $ python -mtimeit -s'd1={1:2,3:4}; d2={5:6,7:9}; d3={10:8,13:22}' \ 'd4 = dict(d1.items() + d2.items() + d3.items())' 100000 loops, best of 3: 4.93 usec per loop
  10. هنالك طرق عديدة في بايثون لتحويل سلسلة نصية إلى بايتات hex، ومن أبسط هذه الطرق هي إرسال سلسلتك النصية إلى منشئ الأعداد الصحيحة ثم تطبق تنسيق hex على جميع عناصرها وفي نهاية تفصل hex كل عنصر بنقطتين عن طريق الدالة المدمجة join كما في المثال التالي: >>> s = "Hello world !!" >>> ":".join("{:02x}".format(ord(c)) for c in s) '48:65:6c:6c:6f:20:77:6f:72:6c:64:20:21:21 أو في حالة استخدامك للإصدار الثاني من بايثون يمكنك استخدام هذا السطر: ':'.join(x.encode('hex') for x in 'Hello World!') في الإصدار الثالث لن يعمل لك المثال السابق لذا اكتب ما يلي: ':'.join(hex(ord(x))[2:] for x in 'Hello World!')
  11. حسب رأيي فإن أسهل طريقة في لغة الروبي لمطابق أسطر متعددة هي استخدام المُعدل (modifier) /m لتفعيل وضع الأسطر المتعدد (على سبيل المثال للسماح لـ . بمطابقة الأسطر الجديدة)، ويمكنك استخدام الرمز ؟ لتنفيذ تطابق من نوع (non-greedy). مثال على الشرح في الأعلى: message = <<-MSG Random Line 1 Random Line 2 From: person@example.com Date: 01-01-2011 To: friend@example.com Subject: This is the subject line Random Line 3 Random Line 4 MSG message.match(/(From:.*Subject.*?)\n/m)[1] => "From: person@example.com\nDate: 01-01-2011\nTo: friend@example.com\nSubject: This is the subject line"لمزيد من المعلومات حول التعابير النمطية أنصحك بقراءة التوثيق الرسمي لروبي. ومن الحلول الأخرى إذا ردت فقط مطابقة حسب رمز "العودة إلى السطر" فيمكنك مثلا تحويل جميع رموز العودة إلى رمز | (في حالة عدم وجوده في النص) عن طريق السطر التالي: aString.split("\n").join("|") وبعد ذلك يمكنك استخراج الجزء الذي تريده.
  12. هنالك عدّة طرق في لغة روبي لإلغاء تعريف المتغيرات في irb وأسهل هذه الطرق تنظيف سجلات المتغيرات المحلية عن طريق استدعاء "صدفة irb الفرعية" (irb subshell) كما في المثال التالي: $ irb irb(main):001:0> a = "a" => "a" irb(main):002:0> defined? a => "local-variable" irb(main):003:0> irb # step into subshell with its own locals irb#1(main):001:0> defined? a => nil irb#1(main):002:0> a NameError: undefined local variable or method `a' for main:Object from /Users/dean/.irbrc:108:in `method_missing' from (irb#1):2 irb#1(main):003:0> exit => #<IRB::Irb: @context=#<IRB::Context:0x1011b48b8>, @signal_status=:IN_EVAL, @scanner=#<RubyLex:0x1011b3df0>> irb(main):004:0> a # now we're back and a exists again => "a" أما في لغة روبي (كسكربت) يمكنك استخدام توابع مختلفة مثل remove_class_variable و remove_instance_variable و remove_const للمتغيرات العامة لكن في الوقت الحالي لا يوجد أي توابع لإلغاء تعريف قيم متغيرات محلية.
  13. على الرغم من أن القواميس هي كائنات غير مرتبة إلا أنه يمكنك استخدام عدة طرق لجعلها مرتبة كما عرّفتها أول مرة، مثلا استخدم دالة OrderedDict من وحدة collections والتي ظهرت في الإصدار 2.7 من بايثون، وذلك كما في المثال التالي: from collections import OrderedDict OrderedDict((word, True) for word in words) حيث سيحتوي القاموس على التالي: OrderedDict([('He', True), ('will', True), ('be', True), ('the', True), ('winner', True)])
  14. في الحقيقة إن استخدام cls ليس إلزاميا لذلك فهي تشبه self كثيرا لكن بعض المبرمجين يستخدمونها بدلا من self للتمييز بين معامل الأول لمثيل التوابع والأصناف. الفرق بينهما موجود في PEP 8: وكما قلنا سابقا إن استخدام cls هو نمط للكتابة وليس أمرا إجباريا لذلك تجد أن فقط القلة من المبرمجين من يستخدمونها (غالبًا المحترفين).
  15. لا تتوقع وجود خيارات كثيرة في حالة كانت أطوال الأسطر مختلفة، لذلك سوف تحتاج إلى التعامل مع نهايات الأسطر لتعرف عدد الأسطر وأماكنها وذلك عن طريق قراءة الملف على الأقل مرة واحدة باستخدام حلقة التكرار for كما في المثال التالي: # Read in the file once and build a list of line offsets line_offset = [] offset = 0 for line in file: line_offset.append(offset) offset += len(line) file.seek(0) # Now, to skip to line n (with the first line being line 0), just do file.seek(line_offset[n])كما يمكنك أيضا استخدام وحدة linecache والتي تسمح لك بالحصول على أي سطر من أي ملف لكنها للأسف كما قلنا سابقا تحتاج على الأقل لقراءة الملف مرة واحدة لذلك ستقوم هذه الوحدة بتحميل الملف في الذاكرة. مثال على استخدام الدالة: >>> import linecache >>> linecache.getline('/etc/passwd', 4) 'sys:x:3:3:sys:/dev:/bin/sh\n' المصدر
  16. هنالك طرق عديدة في لغة روبي لحذف عناصر محددة من المصفوفة، فيمكنك على سبيل المثال وضع العناصر التي تريد حذفها في مصفوفة ومن ثم استخدام حلقة تكرار each على عناصر المصفوفة كما يظهر في المثال التالي: a= [1,1,1,2,2,3] delete_list = [1,3] delete_list.each do |del| a.delete_at(a.index(del)) end أو يمكنك فعل ذالك بطريقة أخرى كما في المثال التالي: [1,3].inject([1,1,1,2,2,3]) do |memo,element| memo.tap do |memo| i = memo.find_index(e) memo.delete_at(i) if i end end أو يمكنك استخدام هذه الطريقة بسطر واحد: b = [1,1,3].each.with_object( a ) { |del| a.delete_at( a.index( del ) ) } ويمكنك أيضا استخدام lambda بوضع محتويات المثال السابق في دالة lambda كما في المثال التالي: subtract = lambda do |minuend, subtrahend| subtrahend.each.with_object( minuend ) { |del| minuend.delete_at( minuend.index( del ) ) } end ولاستدعاءها يمكنك كتابة السطر التالي: subtract.call a, [1,1,3]
  17. هنالك عدّة طرق في لغة روبي لتمرير كتل إلى التوابع، فيمكنك على سبيل المثال وضع الكتلة التي تريد تمريرها في متغير ومن ثم تمرير ذالك المتغير كما يظهر في المثال التالي: foo = Proc.new { |prompt| prompt.echo = false } new_pass = ask("Enter your new password: ", &foo) verify_pass = ask("Enter again to verify: ", &foo) أو يمكنك تمرير الكتلة بطرق أخرى فمثلا استخدمنا في هذا المثال تابع call لاستخدام المتغير foo الذي يحتوي على الكتلة التي تريد تمريرها كما يظهر ذلك هنا: foo = Proc.new { |prompt| prompt.echo = false } new_pass = ask("Enter your new password: ") {|x| foo.call(x)} verify_pass = ask("Enter again to verify: ") {|x| foo.call(x)}
  18. أعتقد أن أفضل طريقة موثوقة للتأكد ما إذا كان سكربت بايثون يعمل داخل virtualenv (هذه الطريقة تعمل بشكل في العادة داخل virtualenv و pip) هي عن طريق التأكد من وجودsys.real_prefix، فإذا كان موجود فهذا يعني أن السكربت يعمل داخل virtualenv. يمكن التأكد من وجوده عن طريق استخدام الأسطر التالية: import sys if hasattr(sys, 'real_prefix'): #...إن sys.prefix يشير إلى مجلد virtualenv وأما sys.real_prefix فتشير إلى البادئة الحقيقية لنظام بايثون (في الغالب تكون /usr أو /usr/local أو ما شابه). خارج virtualenv، يجب أن لا تكون sys.real_prefix موجودة.
  19. هنالك طرق كثيرة في بايثون 3 لطباعة معاملات مختلفة، فيمكنك على سبيل المثال تمرير المعاملات على شكل tuple كما في المثال التالي: print("Total score for %s is %s " % (name, score)) أو يمكنك استخدام نمط تنسيق السلاسل النصية الجديد كما في المثال التالي: print("Total score for {} is {}".format(name, score)) كما يمكنك تمرير القيم بمعاملات إلى دالة print كما يظهر في المثال التالي: print("Total score for", name, "is", score) وإذا لم ترغب بالمسافات التي يتم إضافتها بشكل تلقائي بواسطة دالة print فيمكنك في هذه الحالة تغيير قيمة معامل sep كما في المثال التالي: print("Total score for ", name, " is ", score, sep='') ملاحظة: إذا كنت تستخدم الإصدار الثاني من بايثون فيجب عليك استدعاء دالة print عن طريق مكتبة __future__ إذا أردت تجربة الأوامر السابقة: from __future__ import print_function
  20. باختصار، معناها أنه لا توجد أية قيود على استخدام الكائن، وهي تشبه أي كائن آخر. كائن من الدرجة الأولى هو شيء يمكنك التعامل معه بحيوية (dynamically) من ناحية الإنشاء والحذف والتمرير إلى دالة وإرجاعه كقيمة ولديه جميع المميزات التي تتمتع بها المتغيرات الأخرى في لغة البرمجة. بالنسبة للغة C++ فالدوال نفسها ليست كائنات صنف أول، وعلى الرغم من ذلك فإن مؤشرات الدالة هي من نوع صنف أول. المصدر
  21. يمكنك تجربة إضافة "S3Media LinkSafe” فهذه الإضافة المجانية تحمي روابط التحميل الموجودة في موقعك عن طريق إنشاء رابط جديد لكل عملية تحميل يبقى لمدة معينة فقط ومن ثم يتم حذفه وهذه العملية ستحمي روابط التحميل من السرقة واستهلاك المكثف لعرض الحزمة (bandwidth). بالإضافة إلى ذلك توفر لك هذه الإضافة عدة مميزات أخرى مثل إمكانية وضع كلمة سر للروابط وإمكانية التحكم في زمن بقاء الرابط وغيرها الكثير من المميزات الأخرى. الموقع الرسمي
  22. وعليكم السلام، أنصحك أولا بأن تُحدد هدفك ومجالك في البرمجة حتى تتمكن من اختيار لغة البرمجة الصحيحة لتعلمها، فهل تريد برمجة مواقع ويب؟(تتطلب تعلم لغات HTML و CSS وجافا سكربت...)؟ أم تريد برمجة تطبيقات الويب؟ (بالإضافة إلى لغات برمجة مواقع الويب تحتاج إلى تعلم إطار معين مثل "ريلز" في لغة روبي أو "دجانغو” في لغة بايثون...)؟ أم هل تريد برمجة برامج سطح المكتب؟ (لغات C++، بايثون...) أم هل تريد برمجة الألعاب؟ (لغات C, C++...). وبعد ذلك يمكنك البدء بتعلم البرمجة عن طريق البحث عن دورات وكتب في المجال الذي اخترته (تجد الكثير من الدروس في جزء "تعلم البرمجة" في أكاديمية حسوب). أهم نصية في البرمجة هي أنه كلما زدت قراءاتك للشيفرات البرمجية وكتابتك لها كلما تعلمت بشكل أسرع وأصبحت أكثر احترافية. بالنسبة لتصميم موقع أو مدونة فتحتاج إلى القليل من الصبر حتى تتمكن من تعلم أساسيات برمجة تطبيقات الويب قبل أن تتمكن من برمجة المواقع.
  23. يمكنك تغيير مفاتيح hash معيّن بمجموعة مفاتيح جديدة في روبي بسهولة وبطرق متنوعة، فمثلا يمكنك استخدام حلقة map للتكرار على جميع عناصر hash معين ومن ثم تغييرها بالمجموعة الجديدة التي ستُمررها له كما في المثال التالي: Hash[hsh.map {|k, v| [key_map[k], v] }] أو يمكنك فعل ذلك بإضافة مُدخل جديد للمفتاح ومن ثم حذف المفتاح القديم، فإذا افترضنا أن لديك hash باسم h والذي يحتوي على المفاتيح التي تريد تعديلها وhash آخر باسم new_keys والذي يحتوي على المفتاح الثاني فيمكنك في هذه الحالة استخدام الطريقة التالية: h.keys.each do |key| h[new_keys[key]] = h[key] # add entry for new key k.delete(key) # remove old key end
  24. هنالك خطأ بسيطة في الطريقة التي قمت بتجربتها ولم تنجح وبالضبط في متغيرات اليوم والشهر، فقُم بتغيير السطر الذي كتبته إلى هذا السطر وستُحل المشكلة: Date.strptime(updated, '%a, %d %b %Y %H:%M:%S %Z') على الرغم من ذلك هنالك طرق أخرى في ريلز لتحويل سلسلة نصية إلى كائن من نوع تاريخ، وأسهل هذه الطرق هي عن طريق استخدام تابع Date.parse مع تمرير اسم السلسلة النصية كما في المثال التالي: str = "Tue, 10 Aug 2010 01:20:19 -0400 (EDT)" date = Date.parse str => #<Date: 4910837/2,0,2299161> puts date 2010-08-10 كما يمكنك استخدام تابع to_date كما في المثال التالي: str = "Tue, 10 Aug 2010 01:20:19 -0400 (EDT)" str.to_date => Tue, 10 Aug 2010
  25. هنالك عدّة طرق سهلة وقصيرة في بايثون يمكنك من خلالها تغيير حالة الأحرف الموجودة لعناصر سلسلة معينة، فمثلا يمكنك فعل ذلك عن طريق "تفهيم القائمة" (list comprehensions) واستخدام دالة lower() لحالة الأحرف الصغيرة أو دالة upper() لحالة الأحرف الكبير مع حلقة التكرار for كما في المثال التالي: >>> [x.lower() for x in ["A","B","C"]] ['a', 'b', 'c'] >>> [x.upper() for x in ["a","b","c"]] ['A', 'B', 'C'] أو يمكنك فعل ذلك مع استخدام دالة map و دالة lambda مع دوال الأحرف الكبيرة والصغيرة والتي ذكرناها في الأعلى كما في المثال التالي: >>> map(lambda x:x.lower(),["A","B","C"]) ['a', 'b', 'c'] >>> map(lambda x:x.upper(),["a","b","c"]) ['A', 'B', 'C']
×
×
  • أضف...