لوحة المتصدرين
المحتوى الأكثر حصولًا على سمعة جيدة
المحتوى الأعلى تقييمًا في 10/17/21 في كل الموقع
-
لدي مشروع عبارة عن موقع الكتروني مبني بلغة python بايثون وإطار عمل دجانغو، أريد شرح خطوات رفعه على الاستضافة وتشغيله1 نقطة
-
الإصدار 1.2.0
21011 تنزيل
انتشر مصطلح العمل الحر في الآونة الأخير انتشار النار في الهشيم، وسبب ذلك جائحة كوفيد-19 التي ضربت العالم فقلبت الموازين، فالآن وبعد إلزام الدول للشعوب بالبقاء في المنازل وفرض قيود على نمط الحياة وحتى أسلوب العمل من أجل الحد من انتشار الوباء، تعرّف أغلب الناس طوعًا أو كرهًا إلى أسلوب العمل المستقل والعمل عن بعد من المنزل، واضطر كثير منهم إلى دخول سوق الإنترنت ليقدموا خدماتهم بشكل مستقل بعد إنهاء عقودهم مع شركاتهم بسبب تقليل الشركات لنفقاتها، وحتى الذي استمروا في عملهم ووظيفتهم اضطروا إلى تبني أسلوب العمل من المنزل إذ رأينا الكثير من الشركات التي أغلقت مقراتها ونقلها إلى أسلوب العمل عن بعد وهنا وجد الموظفون أنفسهم أمام نمط عمل غريب لم يعتادوه من قبل! وبات الكثير يسأل عن كيفية الدخول إلى هذا سوق العمل الحر وكيفية تبني أسلوب العمل من المنزل ويسألنا عن تجاربنا ومن أين يبدؤون وماذا يفعلون، لذا وجب علينا تقديم المساعدة والإجابات الوافية ومدُّ يَد العون لتوفر مرجع شامل يهدي الوافدين إلى ويرشد السالكين على طريق العمل الحر ونمط العمل عن بعد من المنزل، فكان هذا الكتاب! يبدأ الكتاب في أول فصل له بشرح مفهوم ثقافة العمل الحر والعمل عن بعد من المنزل واختلافهما عن العمل التقليدي كما يعرض واقع العالم العربي من العمل المستقل، ثم ينتقل في الفصل الثاني إلى التحدث عن سوق العمل الحر وعرض مجالاته وكيفية الدخول إليه. ينتقل الكتاب بعدها في الفصول التالية إلى شرح المهارات الواجب على كل عامل مستقل أن يمتلكها حتى يصبح عاملًا مميزًا له مكانته المرموقة في السوق ليتهافت أصحاب المشاريع على تسليمه العمل كلما برز اسمه بين العاملين في السوق، فيعرِّج على التسويق الذاتي ثم ينتقل إلى شرح كيفية إدارة المشروع من الناحية الفنية والمالية والتعامل مع العملاء أصحاب المشاريع وكيفية حل أي خلافات قد تطرأ. لم ننسَ أهمية صحة العامل المستقل والعامل عن بعد من منزله، فخصَّصنا فصلين نتحدث في أولهما عن المواضيع المتعلقة بالصحة النفسية والجسدية على حد سواء، بالإضافة إلى عرض أهم التحديات التي قد تواجه العامل من المنزل مثل الإجازات وإدارة الوقت وكيفية التعامل معها. عرجَّنا بعد ذلك في الفصل الذي يليه على الأمور المتعلقة ببيئة العمل، تلك البيئة التي سيمضي العامل البعيد فيها جل وقته، فعرضنا كيفية بناء بيئة العمل المريحة المثلى وتنظيمها وكيفية فصل بيئة العمل عن بيئة المنزل والأهل الملاصقة لها. تحدثنا عن التعهيد الخارجي في فصل كامل وهو مفهوم قد يلزم العامل المستقل لاحقًا لتوسيع عمله أو إنجاز مهام خارج اختصاصه، ثم انتقلنا في الفصل الأخير إلى التحدث عن أهم منصات العمل الحر العربية بمختلف أنواعها وكيفية إنشاء حسابات عليها لتطبيق كل ما تعلمناه سابقًا في الكتاب ودخول السوق من أوسع مداخله. يمكنك قراءة فصول هذا الكتاب مباشرةً على شكل مقالات، الموسومة بوسم «دليل العامل المستقل»، وإليك العناوين: مدخل إلى ثقافة العمل الحر الدخول إلى سوق العمل الحر على الإنترنت كيفية التسويق الذاتي في العمل الحر الإدارة الفنية للمشروع للعامل المستقل فن التعامل مع العملاء في العمل المستقل العناية بالصحة الجسدية والنفسية للعامل المستقل العناية ببيئة عمل العامل المستقل الإدارة المالية في العمل الحر ما يلزم العامل المستقل معرفته عن التعهيد الخارجي تعرف على منصات العمل الحر والعمل عن بعد1 نقطة -
لا شك أن التعامل مع النصوص هو أكثر ما يفعله المبرمج في عمله لأنه يبرمج بلغات تتكون من كلمات ورموز، وهي نصوص في النهاية، لذلك توجد أدوات كثيرة جدًا في أغلب لغات البرمجة لتسهيل التعامل مع هذه النصوص، وسننظر في كيفية استخدام تلك الأدوات في تنفيذ المهام البرمجية المعتادة التي تشمل ما يلي: تقسيم الأسطر إلى مجموعات من المحارف. البحث عن سلاسل نصية داخل سلاسل أخرى. استبدال سلسلة نصية بأخرى. تغيير حالة الأحرف. سننظر في كيفية تنفيذ كل مهمة من هذه المهام باستخدام بايثون، ثم نمر عليها سريعًا في جافاسكربت وVBScript، وتُستخدم توابع السلاسل النصية في بايثون للتعامل مع السلاسل النصية، فلعلك تذكر من مقال البيانات وأنواعها أن التوابع تشبه الدوال المرتبطة ببيانات، ونستطيع الوصول إلى التوابع باستخدام نفس الترميز النقطي dot notation الذي نستخدمه للوصول إلى الدوال في الوحدات modules، لكننا سنستخدم البيانات نفسها بدلًا من استخدام اسم الوحدة. لننظر الآن في ذلك. تقسيم السلاسل النصية أولًا سنقسم سلسلةً نصيةً إلى عدة أجزاء، والذي نحتاج إليه عند معالجة الملفات لأننا نقرأ الملف سطرًا سطرًا، لكن قد يحتوي جزء من السطر فقط على البيانات المطلوبة. من أمثلة ذلك برنامج دليل جهات الاتصال الذي نعود إليه كل حين، فقد نرغب في الوصول إلى حقول بعينها من مدخل ما، دون الحاجة لطباعة المدخل كله، وسنستخدم لهذا الغرض التابع split() في بايثون كما يلي: >>> aString = "Here is a (short) String" >>> print( aString.split() ) ['Here', 'is', 'a', '(short)', 'String'] لاحظ كيف حصلنا على قائمة تحتوي الكلمات التي في aString مع حذف جميع المسافات، لأن الفاصل الافتراضي للدالة ''.split() هو المسافة البيضاء، سواءً كانت سطرًا جديدًا، أم مسافةً عادية، أم مسافة جدول tab. لنجرب الآن استخدامه مرةً أخرى بجعل الفاصل قوسًا افتتاحيًا: >>> print( aString.split('(') ) ['Here is a ', 'short) String'] يكمن الفرق هنا في أننا حصلنا على عنصرين فقط في القائمة، وقد حُذف القوس الافتتاحي من بداية 'short)'، وهذه ملاحظة مهمة حول ''.split()، وهي حذفه للمحارف الفاصلة، الذي نريده غالبًا مع استثناءات قليلة. كذلك لدينا التابع ''.join() الذي يأخذ قائمةً -أو أي نوع آخر- من التسلسلات النصية ويدمجها معًا، لكن له خاصية قد تسبب حيرةً عند استخدامه، وهو استخدامه السلسلة التي نستدعي التابع عليها محرفًا للدمج، كما يلي: >>> lst = ['here','is','a','list','of','words'] >>> print( '-+-'.join(lst) ) here-+-is-+-a-+-list-+-of-+-words >>> print( ' '.join(lst) ) here is a list of words رغم منطقية هذا السلوك، إلا أنه يبدو غريبًا عند رؤيته لأول مرة، كما أنه سلوك مناقض لما هو موجود في جافاسكربت التي تحوي تابع مصفوفة اسمه join، وتكون السلسلة الدامجة فيه معامِلًا. عد الكلمات سنعيد النظر مرةً أخرى في برنامج عد الكلمات الذي أوردناه في مقال البرمجة باستخدام الوحدات، الذي كانت الشيفرة الوهمية فيه كما يلي: def numwords(aString): list = split(aString) # قائمة بكل عنصر وكلمة return len(list) # تعيد عددًا من العناصر في القائمة for line in file: total = total + numwords(line) # accumulate totals for each line print( "File had %d words" % total ) لننظر إلى متن دالة numwords() بما أننا شرحنا كيفية جلب الأسطر من الملف، حيث نريد أن ننشئ قائمةً من الكلمات في سطر، وذلك باستخدام التابع ''.split() الافتراضي. وإذا نظرنا في توثيق بايثون فسنجد أن دالة len() المضمَّنة تعيد عدد العناصر في قائمة ما، ويجب أن يكون ذلك العدد في حالتنا عدد الكلمات في السلسلة النصية، وهو ما نريده بالضبط، وعلى ذلك تبدو الشيفرة النهائية كما يلي: def numwords(aString): lst = aString.split() # split() aString هو تابع كائن السلسلة return len(lst) # أعد عدد العناصر في القائمة with open("menu.txt","r") as inp: total = 0 # initialize to zero; also creates variable for line in inp: total += numwords(line) # راكم إجمالي كل سطر print( "File had %d words" % total ) لكن هذه الشيفرة تحسب محارفًا مثل & على أنها كلمات، وهذا ليس صحيحًا، كما أنه لا يمكن استخدامها إلا على ملف واحد فقط هو menu.txt، رغم إمكانية تحويلها لتقرأ اسم الملف من سطر الأوامر argv[1]، أو عبر input() كما رأينا في مقال كيفية قراءة البرامج لمدخلات المستخدم، وسنترك هذا تدريبًا للقارئ. البحث في النصوص ستكون العملية التالية التي ننظر فيها هي البحث عن سلسلة فرعية داخل سلسلة أكبر منها، وتدعم بايثون هذا من خلال تابع السلسلة ''.find() الخاص بها، وأبسط استخدامات هذا التابع تزويده بسلسلة للبحث، وتعيد بايثون فهرس أول محرف من السلسلة الفرعية إذا وجدتها داخل السلسلة الرئيسية، أما إذا لم تجدها فستعيد -1: >>> aString = "here is a long string with a substring inside it" >>> print( aString.find('long') ) 10 >>> print( aString.find('oxen') ) -1 >>> print( aString.find('string') ) 15 لقد كان المثالان الأولان واضحين ومباشرين، فالأول يعيد فهرس بداية 'long'، أما الثاني فيعيد -1، وذلك لأن 'oxen' غير موجودة داخل aString؛ بينما المثال الثالث ففيه أمر مثير للاهتمام، إذ لا تحدد find إلا الورود الأول لسلسلة البحث فقط، لكن ماذا لو كانت سلسلة البحث مكررةً أكثر من مرة في السلسلة الأصلية؟ من الممكن هنا أن نستخدم فهرس المرة الأولى لورود سلسلة البحث لنقسم السلسلة الأصلية إلى جزأين ونبحث مرةً أخرى، ونكرر ذلك إلى أن نحصل على النتيجة -1، كما يلي: aString = "Bow wow says the dog, how many ow's are in this string?" temp = aString[:] # استخدم التقسيم لصنع نسخة count = 0 index = temp.find('ow') while index != -1: count += 1 temp = temp[index + 1:] # استخدم التقسيم هنا. index = temp.find('ow') print( "We found %d occurrences of 'ow' in %s" % (count, aString) ) وهنا نكون قد عددنا مرات الحدوث فقط، لكن كان بإمكاننا جمع نتائج الفهرس في قائمة من أجل المعالجة لاحقًا. يستطيع التابع find() أن يسرّع من هذه العملية قليلًا باستخدام أحد المعامِلات الاختيارية الخاصة به، وهو موضع البداية في السلسلة الأصلية: aString = "Bow wow says the dog, how many ow's are in this string?" count = 0 index = aString.find('ow') # استخدم البدء الافتراضي while index != -1: count += 1 index = aString.find('ow', index+1) # اضبط بدءًا جديدًا print( "We found %d occurrences of 'ow' in %s" % (count, aString) ) يلغي هذا الحل الحاجة إلى إنشاء سلسلة نصية جديدة في كل مرة، وهو الأمر الذي قد يبطئ العملية إذا كانت السلسلة طويلةً، وإذا علمنا أن السلسلة الفرعية ستكون في بداية السلسلة الأصلية، أو لم نهتم لمرات الحدوث الأخرى، فمن الممكن أن نحدد قيمتي بداية ونهاية البحث، كما يلي: >>> # قصر البحث على أول 20 محرف >>> aString = "Bow wow says the dog, how many ow's are in the string?" >>> print( aString.find('the',0,20) ) توفر بايثون عدة توابع أخرى لمواقف البحث الشائعة، مثل ''.startswith() و''.endswith()، ونستطيع أن نخمن وظائف هذه التوابع بمجرد قراءة أسمائها، وهي تعيد إما True أو False بناءً على بدء السلسلة بسلسلة نصية معطاة أو انتهائها بها، كما يلي: >>> print( "Python rocks!".startswith("Perl") ) False >>> print( "Python rocks!".startswith('Python') ) True >>> print( "Python rocks!".endswith('sucks!') ) False >>> print( "Python rocks!".endswith('cks!') ) True لاحظ أنها تعطينا نتائج بوليانيةً، حيث سنعلم أين نبحث إذا كانت الإجابة True. كذلك لاحظ أن سلسلة البحث لا يجب أن تكون كلمةً كاملة، بل تكفي سلسلة نصية فرعية. يمكن تزويد موضعي البدء start والانتهاء stop داخل السلسلة النصية، تمامًا مثل ''.find()، لنتحقق من وجود سلسلة نصية فرعية في أي موضع معطىً داخل السلسلة النصية، ولا تستخدَم هذه الخاصية الأخيرة في البرمجة العملية كثيرًا. كما يمكن استخدام عامل in الخاص ببايثون لإجراء اختبار بسيط للتحقق من وجود سلسلة نصية فرعية في أي مكان داخل سلسلة أخرى: >>> if 'foo' in 'foobar': print( 'True' ) True >>> if 'baz' in 'foobar': print( 'True' ) >>> if 'bar' in 'foobar': print( 'True' ) True استبدال النصوص بما أننا عثرنا على النص الذي نريده، فلنغيره الآن إلى شيء آخر. توفر توابع السلاسل النصية في بايثون لهذا حلًا متمثلًا في التابع ''.replace() الذي يأخذ وسيطين، هما سلسلتا البحث والاستبدال، وتكون القيمة المعادة هي السلسلة الجديدة الناتجة عن الاستبدال. >>> aString = "Mary had a little lamb, its fleece was dirty!" >>> print( aString.replace('dirty','white') ) "Mary had a little lamb, its fleece was white!" إن الفرق الأساسي بين ''.find() و''.replace هو أن الأخير يستبدل جميع مرات الحدوث في سلسلة البحث، وليس المرة الأولى فقط، ويُستخدم الوسيط الاختياري count لتقييد عدد مرات الاستبدال، كما يلي: >>> aString = "Bow wow wow said the little dog" >>> print( aString.replace('ow','ark') ) Bark wark wark said the little dog >>> print( aString.replace('ow','ark',1) ) # واحد فقط Bark wow wow said the little dog من الممكن إجراء عمليات بحث واستبدال معقدة باستخدام ما يسمى بالتعبير النمطي regular expression، لكنها معقدة وسنتحدث عنها في مقال آخر لاحقًا. تغيير حالة الأحرف مما يجب مراعاته في النصوص هو كيفية التحويل من الحالة الصغرى للحروف إلى الحالة الكبرى، وإن كان هذا غير شائع، إلا أن بايثون توفر بعض التوابع المساعدة لذلك على أي حال: >>> print( "MIXed Case".lower() ) mixed case >>> print( "MIXed Case".upper() ) MIXED CASE >>> print( "MIXed Case".swapcase() ) mixED cASE >>> print( "MIXed Case".capitalize() ) Mixed case >>> print( 'MIXed Case'.title() ) Mixed Case >>> print( "TEST".isupper() ) True >>> print( "TEST".islower() ) False لاحظ أن التابع ''.capitalize() يغير حالة الأحرف إلى الحالة الكبرى للسلسلة النصية كلها، وليس لكل كلمة فيها؛ أما تغيير حالة كل كلمة فينفذها التابع title(). انتبه أيضًا إلى سلوك دالتي الاختبار ''.isupper() و''.islower()، إذ توفر بايثون دوالًا توكيديةً مثل هذه لاختبار السلاسل النصية، منها: ''.isdigit() و''.isalpha() و''.isspace()، وتتحقق الدالة الأخيرة من جميع أنواع المسافات البيضاء، لا محارف المسافة العادية فقط. وسنستخدم عدة توابع من هذا النمط، خاصةً في عد الكلمات. التعامل مع النصوص في VBScript تنحدر VBScript من لغة BASIC القديمة، لذا تحتوي على الكثير من دوال معالجة النصوص المدمجة فيها، وقد تجد 20 دالةً أو تابعًا في توثيقها، بالإضافة إلى الدوال الموجودة لمعالجة محارف اليونيكود، مما يعني أننا نستطيع فعل كل ما فعلناه في بايثون باستخدام VBScript، وسنمر عليها سريعًا فيما يلي: تقسيم النصوص نبدأ بدالة split: <script type="text/vbscript"> Dim s Dim lst s = "Here is a string of words" lst = Split(s) ' returns an array MsgBox lst(1) </script> كما في بايثون، نستطيع إضافة قيمة فاصلة إذا أردنا، غير فاصل المسافة البيضاء العادي، كذلك لدينا دالة Join لعكس هذه العملية. البحث عن النصوص واستبدالها نبحث باستخدام InStr، وهو اختصار لـ In String: <script type="text/vbscript"> Dim s,n s = "Here is a long string of text" n = InStr(s, "long") MsgBox "long is found at position: " & CStr(n) </script> القيمة المعادة هنا هي الموضع الذي تبدأ فيه السلسلة الفرعية داخل السلسلة الأصلية، فإذا لم توجد السلسلة الفرعية فستعيد صفرًا، وهذه ليست مشكلةً بما أن VBScript تبدأ فهارسها بواحد وليس صفر، لذا لا يُعَد الصفر هنا فهرسًا صالحًا؛ أما إذا كانت إحدى السلسلتين Null، فستعيد القيمة Null، مما يجعل عملية اختبار شروط الخطأ أكثر صعوبةً وتحتاج إلى عدة اختبارات معًا. يمكن تحديد نطاق فرعي من السلسلة الأصلية للبحث فيه باستخدام قيمة بادئة، كما فعلنا في بايثون، كما يلي: <script type="text/vbscript"> Dim s,n s = "Here is a long string of text" n = InStr(6, s, "long") ' start at position 6 If n = 0 or n = Null Then ' check for errors MsgBox "long was not found" Else MsgBox "long is found at position: " & CStr(n) End If </script> ونستطيع تحديد كون البحث حساسًا لحالة الأحرف أم لا، وهذا غير موجود في بايثون، والوضع الافتراضي للبحث هو أن يكون حساسًا لحالة الأحرف. تستبدَل النصوص باستخدام الدالة Replace كما يلي: <script type="text/vbscript"> Dim s s = "The quick yellow fox jumped over the log" MsgBox Replace(s, "yellow", "brown") </script> ونستطيع توفير وسيط اختياري ليحدد عدد مرات الحدوث في سلسلة البحث التي يجب استبدالها، والوضع الافتراضي هو استبدالها جميعًا، لكن يمكن تحديد موضع بدء كما في InStr أعلاه. تغيير الحالة تغيّر الحالة في VBScript بواسطة UCase وLCase، لكن لا يوجد فيها ما يكافئ التابعين capitalize وtitle الموجودين في بايثون: <script type="text/vbscript"> Dim s s = "MIXed Case" MsgBox LCase(s) MsgBox UCase(s) </script> وهذا ما سنغطيه من معالجة النصوص في VBScript، فإذا أردت المزيد فارجع إلى ملف مساعدة VBScript لترى القائمة الكاملة للدوال. التعامل مع النصوص في جافاسكربت تُعَد جافاسكربت أقل اللغات الثلاث تجهيزًا للتعامل مع النصوص، لكن العمليات الأساسية موجودة إلى حد ما، رغم افتقارها إلى العدد الكبير من التوابع والدوال الموجودة في بايثون وVBScript للتعامل مع النصوص، وهي تعوض ذلك بدعم قوي للتعابير النمطية، حيث تعوض بدائية الدوال الموجودة كثيرًا، لكن على حساب تعقيد التعابير النمطية، وهي تأخذ المنظور كائني التوجه، مثل بايثون في التعامل مع السلاسل النصية، حيث تُنفَّذ المهام باستخدام توابع الصنف String. تقسيم النصوص تقسَّم النصوص في جافاسكربت باستخدام التابع split: <script type="text/javascript"> var aList, aString = "Here is a short string"; aList = aString.split(" "); document.write(aList[1]); </script> لاحظ أن جافاسكربت تتطلب تزويدها بمحرف الفصل، فليس لديها قيمة افتراضية له، والفاصل هنا هو تعبير نمطي، مما يجعل عمليات الفصل المعقدة ممكنةً. وقد ذكرنا سابقًا أن النصوص تُدمج باستخدام تابع المصفوفة Join، لذا فإن عكس عملية التقسيم أعلاه سيكون كما يلي: aList.join(" ") // ادمج عناصر مفصولة بمسافات البحث في النصوص نبحث في النصوص في جافاسكربت باستخدام التابع search(): <script type="text/javascript"> var aString = "Round and Round the ragged rock ran a rascal"; document.write( "ragged is at position: " + aString.search("ragged")); </script> وهنا يكون وسيط سلسلة البحث تعبيرًا نمطيًا أيضًا كي نتمكن من إجراء عمليات بحث معقدة، لكن انتبه إلى عدم وجود طريقة لتقييد نطاق السلسلة الأصلية الذي يُبحث فيه، وذلك من خلال تمرير موضع بدء، رغم إمكانية محاكاة ذلك باستخدام التعابير النمطية على أي حال. استبدال النصوص يُستخدم التابع replace() لاستبدال النصوص كما يلي: <script type="text/javascript"> var aString = "Humpty Dumpty sat on a cat"; document.write(aString.replace("cat","wall")); </script> يمكن أن تكون سلسلة البحث تعبيرًا نمطيًا بحيث نرى هنا السلوك المتوقع، إذ تستبدل عملية الاستبدال جميع نسخ سلسلة البحث، ونستطيع القول أنه لا توجد طريقة تقيد عملية الاستبدال في جزء من السلسلة أو مرة حدوث واحدة دون تقسيم السلسلة أولًا ثم إعادة دمجها مرةً أخرى. تغيير الحالة تغيَّر حالة الأحرف في جافاسكربت باستخدام دالتين هما toLowerCase() وtoUpperCase(): <script type="text/javascript"> var aString = "This string has Mixed Case"; document.write(aString.toLowerCase()+ "<BR>"); document.write(aString.toUpperCase()+ "<BR>"); </script> تغني بساطة هذين التابعين عن شرحهما، والجدير فقط بالذكر هنا أن جافاسكربت على عكس اللغات الأخرى، توفر دوالًا كثيرةً لمعالجة HTML، لأنها لغة برمجة ويب بالأساس، ويمكن الرجوع إلى تلك الدوال في توثيق اللغة، إذ هي خارج مجال حديثنا. خاتمة مررنا على الدوال والتوابع المستخدمة للتعامل مع النصوص التي قد تراها في مشاريعك، ونود الإشارة هنا إلى وجوب النظر في التوثيق الرسمي للغة التي تعمل بها عند معالجة النصوص، إذ توجد أدوات قوية لمثل هذه العمليات والمهام الضرورية في البرمجة، وننصح بالبحث أولًا في التوثيقات المتوفرة في موسوعة حسوب، وهي توثيقات عربية مترجمة من التوثيقات الرسمية للغات أو من أمهات الكتب فيها، ونود أن تخرج من هذا المقال بما يلي: معالجة النصوص عملية شائعة لها دعم قوي مضمَّن في أغلب اللغات. أكثر المهام شيوعًا هي تقسيم النصوص والبحث فيها، واستبدالها، وتغيير حالة الأحرف فيها. توفر كل لغة مستويات مختلفة من الدعم، لكن العمليات الثلاث الأساسية متاحة دومًا. ترجمة -بتصرف- للفصل الثالث عشر: Manipulating Text من كتابة Learning To Program لصاحبه Alan Gauld. اقرأ أيضًا المقال التالي: كيفية التعامل مع الأخطاء البرمجية المقال السابق: التعامل مع الملفات في البرمجة تعلم البرمجة ما هي البرمجة ومتطلبات تعلمها؟1 نقطة
-
1 نقطة
-
لدي صورة تحوي بعض الضجيج الغاوصي عليها، وأريد التخفيف منه، كيف يمكنني استخدام التابع gussianBlur للقيام بالمهمة؟1 نقطة
-
لدي نقاط بيانات في عمودين منdataframe وأريد أن أقوم بتمثيلهما بيانيَاً؟1 نقطة
-
لدي 4 أطر بيانات مختلفة لكن لها نفس المقياس، كيف يمكنني رسمها على نفس ال figure؟1 نقطة
-
يُمكن إستخدام منصة Heroku كما وضح شرف الدين سابقًا أو يمكن حتى إستخدام أي سيرفر إفتراضي VPS من البداية من خلال الخطوات التالية: المتطلبات في البداية نحتاج إلى إنشاء الخادم وضبطه في السحابة من خلال أحد خدمات شركات الإستضافة مثل DigitalOcean أو CloudNode، يمكنك أن تشتري أي خادم ويب للتجربة، وسيتم محاسبتك بالساعة (حسب وقت إستعمالك للخادم منذ وقت الشراء)، وقد تتبع شركات إستضافة خطط أخرى غير المحاسبة بالساعة. ضبط بيئة Virtualenv جديدة نحتاج الآن إلى إعداد بيئة وهميّة virtualenv حيث سيتم تخزين ملفات المشروع وحزم Python أيضًا. إذا كنت لا تستخدم virtualenv ، فقم ببساطة بإنشاء المجلد الذي سيتم تخزين ملفات مشروع Django فيه وانتقل إلى الخطوة التالية. يمكنك تثبيت وإعداد Vitualenv من خلال الأوامر التالية: sudo apt-get install python-virtualenv virtualenv /opt/myproject الآن بعد تثبيت وإعداد بيئة وهميّة Vitualenv للمشروع نحتاج إلى تفعيلها لكي نتمكن من تثبيت المكتبات والحزم المستخدمة في المشروع، يوجد ملف باسم activate في مجلد bin في البيئة الوهميّة التي تم إنشائها سابقًا: source /opt/myproject/bin/activate يمكن الإطلاع على المزيد حول البيئة الوهمية Vitualenv من خلال هذه المقالة: كل المتبقي في هذه الخطوة هو تثبيت Django من خلال الأمر التالي: pip install django ملاحظة: يجب تنفيذ الأمر السابق بعد تفعيل البيئة الوهميّة مباشرة وليس في أي نافذة Terminal أخرى، لكي يتم تثبيت Django في البيئة الوهمية وليس بشكل عام على النظام. إنشاء قاعدة بيانات المشروع في الغالب يتم إستخدم PostgreSQL كخادم قاعدة بيانات. لإنشاء قاعدة بيانات باستخدام PostgreSQL، قم بتنفيذ الأمر التالي: sudo su - postgres الآن يمكن تنفيذ الأمر التالي لإنشاء قاعدة بيانات جديدة (يمكن إختيار أي اسم في هذه الخطوة): createdb mydb ولضمان حماية أكبر على قاعدة البيانات سوف نقوم بإنشاء مستخدم جديد وإعطائه صلاحيات التحكم في قاعدة البيانات التي قمنا بإنشائها: createuser -P psql GRANT ALL PRIVILEGES ON DATABASE mydb TO myuser; في الأمر الأول سوف يتم السؤال عن اسم المستخدم الجديد وكلمة السر الخاصة به وبعض المعلومات الأخرى، ثم سيتم إعطائه الصلاحيات اللازمة من خلال جملة SQL الأخيرة. إذا لم يكن المشروع يستخدم PostgreSQL كخادم قاعدة بيانات، فستحتاج إلى التحقق من الوثائق حول كيفية إنشاء قاعدة بيانات لخادم قاعدة البيانات الذي تختاره. ضبط خادم Nginx نحتاج إلى ضبط خادم Nginx لكي يتمكن من عرض موقعنا. وذلك عبر تشغيل الأمر التالي لإنشاء ملف configuration : sudo nano /etc/nginx/sites-available/myproject الأمر السابق سوف يقوم بإنشاء ملف جديد والبدء في تحريره عبر برنامج nano. الآن يجب كتابة التالي لكي يتمكن خادم Nginx من التعرف على مكان المشروع وكيفية تشغيله: server { server_name yourdomainorip.com; access_log off; location /static/ { alias /opt/myenv/static/; } location / { proxy_pass http://127.0.0.1:8001; proxy_set_header X-Forwarded-Host $server_name; proxy_set_header X-Real-IP $remote_addr; add_header P3P 'CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"'; } } يمكن الآن حفظ الملف عبر الضغط على Ctrl + O ثم إغلاق الملف عبر الضغط على Ctrl + X لكي يتعرف Nginx على الملف السابق الذي قمنا بإنشائه يجب تنفيذ الأوامر التالية: cd /etc/nginx/sites-enabled sudo ln -s ../sites-available/myproject sudo service nginx restart إن ظهر خطأ كالتالي: server_names_hash, you should increase server_names_hash_bucket_size: 32 لحل المشكلة يجب تعديل الملف /etc/nginx/nginx.conf وإلغاء التعليق عن السطر التالي: server_names_hash_bucket_size 64; حتى الآن تم إعداد الخادم بشكل سليم ويتبقى أن نرفع ملفات مشروع Django نفسه إلى الخادم، ويمكن إستخدام أي بروتوكول لنقل أو إدارة الإصدارات مثل FTP, SFTP, SCP, Git, SVN، ويفضل إستخدام Git نظرًا لأنه الأسرع والأسهل في التثبيت والإعداد والأسرع في نقل الملفات أيضًا، لذلك يجب رفع المشروع على مستودع في أحد المواقع مثل GitHub أو GitLab .. إلخ، والحصول على رابط المستودع حيث سنقوم بإستخدامه في الخطوة التالي: إذا لم يكن لديك Git مثبت مسبقًا، فيمكن تثبيته عبر الأمر التالي: sudo apt-get install git نحتاج الآن إلى إنشاء مجلد للمشروع في البيئة الوهمية التي قمنا بإنشائها في الخطوات الأولى وتحميل نسخة من ملفات المشروع إليه: cd /opt/myproject mkdir myproject cd myproject git clone https://github.com/path/to/repo . ملاحظة: يحتوي الأمر الأخير على نقطة . وهي تشير إلى المجلد الحالي الذي سيتم تنزيل الملفات إليه. تثبيت وإعداد خادم التطبيقات App Server نحتاج الآن إلى إستخدام اداة مثل gunicorn لكي تعمل كخادم HTTP وتدير الزيارات إلى المشروع، لذلك سجب تثبيتها وجعل هذا الخادم يستمع إلى الزيارات من المنفذ 8001 الذي قمنا بإعداده في خطوة إعداد Nginx السابقة: source /opt/myproject/bin/activate pip install gunicorn gunicorn_django --bind yourdomainorip.com:8001 يمكنك الآن الضغط على Ctrl + z ثم كتابة "bg" لكي يعمل المشروع في الخلفية. ضبط إعدادات المشروع الخطوة الأخيرة هي إعداد المشروع نفسه وتغير بعض الإعدادات الخاصة به لكي يتعمل بشكل سليم وبدون مشاكل. في البداية سوف نقوم بتعديل ملف settings.py من خلال الأمر التالي: sudo nano /opt/myproject/myproject/settings.py ويجب تعديل وضع التطوير Development Mode عبر تغير قيمة المتغير DEBUG إلى False: DEBUG = False أيضًا يجب إعداد قاعدة البيانات من خلال تعديل DATABASES: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.psycopg2', 'NAME': 'mydb', # database name. # The following settings are not used with sqlite3: 'USER': 'myuser', 'PASSWORD': 'password', 'HOST': '', # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP. 'PORT': '', # Set to empty string for default. } } كما يجب تعديل مسارات الملفات الثابتة Static Files من خلال تعديل المتغير STATIC_ROOT و STATIC_URL، كالتالي: STATIC_ROOT = '/opt/myproject/static/' STATIC_URL = '/static/' الآن يمكن حفظ المشروع والتوجه إلى المجلد الذي يحتوي الملف manage.py ثم تنفيذ الأمر التالي: python manage.py collectstatic سيجمع هذا الأمر جميع الملفات الثابتة Static Files في المجلد الذي قمنا بتعيينه في ملف settings.py أعلاه. هذا كل شيء، يمكن الآن زيارة الموقع عبر IP الخادم VPS أو ربطه بنطاق/مجال Domain معين. وفي هذه الحالة ستحتاج إلى شراء نطاق Domain لكي تتمكن من تشغيل مشروعك عبر الإنترنت، حيث أن شركات الإستضافة تمنحك الخادم فقط في أغلب الأحيان، لذلك يجب أن تقوم بشراء نطاق لموقعك بنفسك من خلال أحد شركات الإستضافة مثل namechape أو GoDaddy ..إلخ ، لذلك يجب أن يكون لديك مجال يشير إلى خادم الويب الذي تم إنشاؤه حديثًا.1 نقطة
-
لتحويل الصورة الملونة RGB إلى صورة أبيض وأسود، نقوم أولاً بتحويلها إلى صورة رمادية إما من خلال قراءتها مباشرةً كصورة رمادية في التابع imread أو من خلال استخدام كود التحويل COLOR_BGR2GRAY في التابع cvtColor، ثم تعتيبها بإحدى طرق التعتيب في OpenCV وهما التعتيب البسيط والتعتيب المتكيف (روابطهما في الأسفل): import cv2 import numpy as np # قراءة الصورة img = cv2.imread(r'/content/me.jpg') # Gray تحويل الصورة إلى gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # أو cv2.imread(r'/content/me.jpg',0) # تحويل الصورة إلى أبيض وأسود عن طريق التعتيب _,Black_white_img=cv2.threshold(gray_img,127,255,cv2.THRESH_BINARY) # عرض الصورة الناتجة cv2.imshow('res',Black_white_img) cv2.waitKey(0) cv2.destroyAllWindows() الخرج:1 نقطة
-
ممكن اي شخص منكم يصمم سوق إلكتروني بسيط بأسهل لغه اهم شي يكون شغال..عشان ارفعه على الانترنت...يحتوي على خمس صفحات على الاكثر..مع فيديو للشرح...وانا ادفع له مقابل بعد ما نتفق على القيمة.1 نقطة
-
يمكنك توظيف مستقل مختص لتنفيذ مشروعك عن طريق منصة مستقل بوضع توصيف لمشروعك والمطلوب وسيقدم المستقلون المهتمون عروض اسعارهم وتختار الانسب بعد الاتفاق1 نقطة
-
من الممكن القيام بمثل ذلك عبر منصة heroku , نبدأ أولاً بتثبيت heroku command line عبر الأمر التالي لمستخدمين ليونكس sudo snap install --classic heroku وعبر الرابط التالي لمستخدمي ويندوز https://cli-assets.heroku.com/heroku-x86.exe بعد ذلك نقوم بتسجيل الدخول الى حساب heroku الخاص بك عبر نافذة الأوامر بالشكل التالي heroku login Enter your Heroku credentials: Email: your_email.com Password: ********* قم بإنشاء ملف runtime.txt في مجلد المشروع وقم بتحديد اصدار البايثون فيه, على سبيل المثال python-2.7.12 نقوم بانشاء ملف الprocfile في مجلد المشروع لتحديد الأوامر المراد تنفيذها عند بدأ تشغيل المشروع على heroku touch Procfile ومن ثم نقوم بإضافة الأمر التالى في الملف والذي يحدد خادم الويب الذي سيُستخدم في تشغيل المشروع web: gunicorn djangoherokuapp.wsgi --log-file - ومن ثم نقوم بتعديل ملف الsettings.py ووضع الdependencies التالية بالشكل التالي INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'herokuapp', ] ومن ثم نقوم بتثبيت تلك الإعتماديات من أجل عمل المشروع بشكل صحيح على المنصة pip install gunicorn dj-database-url whitenoise psycopg2 ولنجعل heroku يعلم أن المشروع المُراد تثبيته هو مشروع python نقوم بإنشاء ملف requirements.txt pip freeze > requirements.txt ونقوم بتحديد الdependencies وإصداراتها في الملف dj-database-url==0.4.2 Django==1.11.7 gunicorn==19.7.1 psycopg2==2.7.3.2 pytz==2017.3 whitenoise==3.3.1 إن كان المشروع يحتوي على ملفات ثابتة(static files) مثل الhtml, css, javascript, images فإن للأسف heroku ﻻ يقوم بدعم التعامل مع تلك الملفات بشكل إفتراضي لذا سنقوم بإستخدام الwhitenoise الذي قمنا بتثبيته مسبقاً وكتابة الأوامر التالية في ملف الsettings.py PROJECT_ROOT = os.path.join(os.path.abspath(__file__)) STATIC_ROOT = os.path.join(PROJECT_ROOT, 'staticfiles') STATIC_URL = '/static/' STATICFILES_DIRS = ( os.path.join(PROJECT_ROOT, 'static'), ) STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage' ومن ثم نقوم بإضافة الخدمات الوسيطة(middle ware ) في ملف الsettings.py MIDDLEWARE = [ 'whitenoise.middleware.WhiteNoiseMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] نقوم بعد ذلك بإنشاء المشروع على heroku عبر الأمر التالي heroku create herokudjangoapp نقوم بعد ذلك بتهيئة مستودع git عبر الأمر التالي git init ومن ثم نحتاج لربط ذلك المشروع بالمشروع الذي لدينا على الحاسب heroku git:remote -a herokudjangoapp ومن ثم نقوم بتنفيذ الأوامر التالية من أجل رفع المشروع على heroku git add . git commit -m "first commit" git push heroku master سيستغرق ذلك بعضاً من الوقت ومن ثم ستجد المشروع قد تم رفعه بنجاح1 نقطة
-
يمكنك القيام بذلك من خلال الدالة add_gridspec: add_gridspec(nrows=1, ncols=1, **kwargs) # حيث أن الوسيط الأول هو عدد الأسطر في الشكبة # الوسيط الثاني هو عدد الأعمد # مع استخدام وسطاء إضافية مثل: # width_ratios لتحديد عرض كل رسم # height_ratios لتحديد ارتفاع كل رسم ثم إضافة ال subplots كما في المثال التوضيحي التالي: fig5 = plt.figure(constrained_layout=True) # subplot تحديد أبعاد كل widths = [2, 3, 1.5] heights = [1, 3, 2] # subplots تعريف مساحة الشبكة التي ستضم ال spec5 = fig5.add_gridspec(ncols=3, nrows=3, width_ratios=widths, height_ratios=heights) # GridSpec(3, 3, height_ratios=[1, 3, 2], width_ratios=[2, 3, 1.5]) # subplots إضافة for row in range(3): for col in range(3): # subplot إضافة ax = fig5.add_subplot(spec5[row, col]) # وضع معلومات ضمنه تمثل الطول والعرض label = 'Width: {}\nHeight: {}'.format(widths[col], heights[row]) ax.annotate(label, (0.1, 0.5), xycoords='axes fraction', va='center') الخرج: كما يمكنك استخدام الوسيط gridspec_kw في الدالة subplots لتحديد نسبة العرض والارتفاع مباشرةً كما في المثال التالي: import numpy as np import matplotlib.pyplot as plt # البيانات x = np.arange(0, 10, 0.2) y = np.sin(x) # رسمها f, (ax1, ax2) = plt.subplots(1, 2, gridspec_kw={'width_ratios': [3, 1]}) # رسم البيانات ax1.plot(x, y,color="w") ax1.set_facecolor('black') ax2.plot(y, x,color="w") ax2.set_facecolor('red') # plots لترك مسافة بين ال f.tight_layout() # إضافة خطوط شبكية ax1.grid(b = True, color ='w', linestyle ='-.', linewidth = 0.5, alpha = 0.6) ax2.grid(b = True, color ='black', linestyle ='-.', linewidth = 0.5, alpha = 0.6) والخرج: مثال آخر: import numpy as np import matplotlib.pyplot as plt # البيانات x = np.arange(0, 10, 0.2) y = np.sin(x) # رسمها f, (ax0, ax1, ax2) = plt.subplots(3, 1, gridspec_kw={'height_ratios': [1, 1, 3]}) ax0.plot(y, x,color="w") ax0.set_facecolor('b') ax1.plot(x, y,color="w") ax1.set_facecolor('black') ax2.plot(y, x,color="w") ax2.set_facecolor('red') f.tight_layout() ax0.grid(b = True, color ='b', linestyle ='-.', linewidth = 0.5, alpha = 0.6) ax1.grid(b = True, color ='w', linestyle ='-.', linewidth = 0.5, alpha = 0.6) ax2.grid(b = True, color ='black', linestyle ='-.', linewidth = 0.5, alpha = 0.6) الخرج:1 نقطة
-
السلام عليكم : أرجو المساعدة بشأن حل هذا السؤال : كتابة برنامج يقوم بحساب عدد مرات تكرار كل حرف كبير في سلسلة حروف يدخلها المستخدم. الدخل : THIS IS A BEAUTIFUL DAY الخرج: A 3 B 1 D 1 E 1 F 1 H 1 I 3 L 1 S 2 T 2 U 2 Y 1 نشكر جهودكم1 نقطة
-
import javax.swing.JOptionPane; class p1 { public static void main(String [ ] args) { System.out.println("string:\t MY HOMEWORK IS NOT DIFFICULT!?" ); String str=JOptionPane.showInputDialog("Input long string?)"); char [ ] mychar= new char [ 26] ; int [ ] c= new int [26]; for ( int i = 0 ; i< mychar.length; i++) { mychar=(char)(i+65); } for ( int i = 0 ; i<str.length; i++) { if ((int) str >=65&& (int)str<=90) { c[ (int)str -65]++; } } for ( int i = 0 ; i< mychar.length; i++) { if (c !=0) { System.out.println( mychar + " "+c ); } } } } وهي محاولتي يوجد فيها بعض الأخطاء ممكن المساعدة في تصحيحها ..... أرجو الرد و مشكورين1 نقطة