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

لوحة المتصدرين

  1. ابراهيم الخليل سماني

    • نقاط

      5

    • المساهمات

      505


  2. معاذ قره محمد

    معاذ قره محمد

    الأعضاء


    • نقاط

      4

    • المساهمات

      364


  3. Adnane Kadri

    Adnane Kadri

    الأعضاء


    • نقاط

      4

    • المساهمات

      5196


  4. zzzzzi

    zzzzzi

    الأعضاء


    • نقاط

      3

    • المساهمات

      6


المحتوى الأكثر حصولًا على سمعة جيدة

المحتوى الأعلى تقييمًا في 09/12/22 في كل الموقع

  1. السلام عليكم الفورم دي عاوز أخد منها ال value اللي هيحددها ال user : <form id="sizePicker"> <input type="number" id="inputHeight" name="height" min="1" value="1"> Grid Width: <input type="number" id="inputWidth" name="width" min="1" value="1"> <input type="submit"> </form> دايما بيظهر لي ال default value
    2 نقاط
  2. السلام عليكم, أردت أن أعطي الصفحة خلفية عبارة عن صورة ولكن تكون فوق كل المحتوى مع شفافية تسمح بظهور ما خلفها قمت بالتالي : <body class="overflow-x-hidden before:bg-[url('http://127.0.0.1:8000/storage/logo.png')] before:h-screen before:w-screen before:fixed before:bg-contain before:bg-center before:opacity-10 before:bg-no-repeat before:z-[999] "> ... ... ... </body> ولكن المشكلة التي واجهتني هي لا استطيع النقر على اي عنصر داخل الصفحة وذلك لأن العنصر موزع على كل الصفحة مع z-index عالي, إذن كيف أظهر الصورة فوق الكل بدون التأثير على النقر هل من حل أم لايوجد ؟ استعمل tailwindCSS شكرا
    2 نقاط
  3. كم مدة الدورة وهل التعيم عن بعد وهل الشهادة معترف بها بالشركات الحكومية؟
    2 نقاط
  4. يهتم تصميم الخدمات بجعل الخدمة تلائم احتياجات المستخدم ومتطلبات العميل، ويمكن استخدامه لتحسين الخدمات الحالية أو لإنشاء خدمة جديدة من الصفر. يجب على مصمم تجربة المستخدم أن يفهم المبادئ الأساسية لتصميم الخدمات وأن يكون قادرًا على تطبيقها عمليًا ليصبح تصميم الخدمات أسهل عليه. سنتحدث عن مبادئ تصميمية مستمدّة من منظمة Design4Services، وهي منظمة تعنى بتطوير تصميم الخدمات والمساعدة على تغيير إستراتيجية المشاريع التجارية، وهي رائجة كثيرًا في القطاع التجاري. هناك أيضًا طرائق أخرى لتصميم الخدمات غير مستعمَلة على نطاق واسع، لكنها قد تغني مجموعة أدوات مصمم الخدمة. هذه عبارة عن خريطة تجربة العميل لخدمة عامة. يساهم تصميم الخدمة في تحسين تجارب العملاء. المبادئ العامة لتصميم الخدمة تتمثل المبادئ العامة لتصميم الخدمة بتركيز انتباه المصمم على المتطلبات العامة لجميع الخدمات، ويضاف إليها مبادئ متعلقة بتصميم العملية والتصميم المؤسساتي وتصميم المعلومات والتصميم التقني، وسنتحدث عنها واحدةً تلو أخرى. فيما يلي المبادئ العامة لتصميم الخدمة: يجب تصميم الخدمة اعتمادًا على الفهم الحقيقي للغرض منها والطلب عليها وقدرة مزود الخدمة على تقديمها. يجب تصميم الخدمة اعتمادًا على حاجات العملاء بدلًا من الحاجات الداخلية للمشروع التجاري. يجب تصميم الخدمة من خلال إنشاء نظام فعال موحَّد بدلًا من مكونات غير مترابطة تسبب إضعاف أداء الخدمة. يجب تصميم الخدمة على أساس توفير قيمة فعالة قدر الإمكان للمستخدمين والعملاء. يجب تصميم الخدمة على أساس التعامل مع الأحداث الخاصة (التي تحيد عن المسار العام للعمليات) بما يوازي الأحداث الشائعة، وتصميم عمليات ملائمة لها. يجب تصميم الخدمة دائمًا بوجود معطيات من مستخدمي هذه الخدمة. يجب إنشاء نماذج أولية للخدمة قبل تطويرها بصورة نهائية. يجب تصميم الخدمة في إطار وجود حالة ونموذج واضحَين للمشروع التجاري. يجب تطوير الخدمة بحدها الأدنى القابل للتطبيق ثم نشرها، ويمكن بعد ذلك إعادة العمل عليها وتحسينها وتعزيز قيمتها على ضوء آراء المستخدم والعميل. يجب تصميم الخدمة وتقديمها بالتعاون مع جميع الأطراف المعنية الداخلية والخارجية. مخطط الخدمة هو أحد المخرَجات النهائية لتصميم الخدمة، ويتضمن تفاصيل جميع التفاعلات مع العميل. تضمن مبادئ تصميم الخدمة أن تضيف هذه المخططات قيمةً للعميل عند إتمامها. مبادئ تصميم العمليات في تصميم الخدمة يمثل تصميم العمليات داخليًا وخارجيًا الجزء الأكبر من تصميم الخدمة، وفيما يلي مبادئ تصميم العمليات: يجب إزالة أو تقليل أي نشاط لا يضيف قيمة للعميل. يتمحور العمل دائمًا حول العمليات وليس حول التركيبات الداخلية مثل الوظائف والموقع الجغرافي والمنتج وغيرها. يجب عدم تجزئة العمل إلا للضرورة القصوى، لكي تقع المسؤولية وإمكانية الحاسبة على عاتق فرد واحد، وللحد من التأخير وإعادة العمل وما إلى ذلك. يشجع ذلك أيضًا على الإبداع والابتكار ويعزز الشعور بملكية العمل. يجب تبسيط العمليات قدر الإمكان، من خلال التركيز على تقليل الخطوات والتنقلات والقواعد والضوابط، ويجب أن يضبط مالك العملية سيرَ العمل كلما أمكن له ذلك. يجب أن تعكس العملية حاجات العميل، ومن المقبول إنشاء نسخ عديدة من العملية إذا اختلفت حاجات العملاء. يجب تقليل التباين في العملية إلى الحد الأدنى. يجب تقليل ملحقات العملية (العمليات الموازية) إلى الحد الأدنى. يجب أن تكون العملية داخلية بدلًا من كثرة التوزع والتشتت (مثلًا التدريب أفضل من تلقي توجيهات خارجية حول العمل). يجب تقليل التوقف والتأخر في العملية إلى الحد الأدنى. يجب تقليل التسويات والرقابة والتفتيش في العملية إلى الحد الأدنى. أن تقيس مؤشرات الأداء الرئيسية للعملية الأمورَ المهمة فقط. التصميم المؤسساتي في تصميم الخدمة البشر هم العنصر الأساسي في تقديم الخدمة، وتساعدهم بعض المبادئ الأساسية للمؤسسات على العمل بكامل طاقتهم الكامنة، وتتضمن هذه المبادئ: يجب تنظيم العمل الجماعي ليتوافق مع العمليات والكفاءات المطلوبة. يجب إعطاء العاملين بصورة فردية الاستقلالية الكافية لاتخاذ قرارات مفيدة. يجب توفير مكان يعزز العمل بكفاءة عالية. التصميم المؤسساتي مجال مستقل بحد ذاته، ويمكن أن يصبح معقدًا للغاية في بعض الأحيان، وهو عادةً عبارة عن عملية يديرها قسم الموارد البشرية، لكن ليس هناك ما يمنع من مساهمة مصممي تجربة المستخدم ومصممي الخدمات. مبادئ تصميم المعلومات في تصميم الخدمة التدفق السلس للمعلومات أمر ضروري لتقديم خدمات عالية الجودة، فإذا لم يعرف الناس المعلومات اللازمة وبالتوقيت المناسب فإن العملية ستعاني من الخلل. فيما يلي بعض المبادئ البسيطة في تصميم المعلومات ضمن عملية تصميم الخدمة: يجب توحيد البيانات بين المؤسسة وعملائها وضمن المؤسسة بحد ذاتها. يجب أن تكون المعلومات سهلة النقل وقابلة لإعادة الاستخدام ضمن المؤسسة ومع الأطراف المشاركة في العمل. يجب تجنب إدخال البيانات كتابةً قدر الإمكان، واللجوء بدلًا من ذلك إلى أدوات البحث عن البيانات واختيارها وتأكيدها. يجرى تصميم البيانات عادةً من قِبل مديري قواعد البيانات DBAs، لكن يجب أن يعمل مصممو تجربة المستخدم ومصممو الخدمة على إدخال قدر كبير من المعطيات لضمان الالتزام بالمبادئ التوجيهية. مبادئ التصميم التقني في تصميم الخدمة تفيد مبادئ التصميم التقني في تحسين تقديم الخدمة، وتتضمن: يجب دائمًا استخدام الجانب التقني لدعم الخدمة لا لتوجيهها. الجانب التقني هو الذي يتلاءم مع تصميم الخدمة وليس العكس. يجب أن يكون التصميم التقني مرنًا وقابلًا للتعديل بما فيه الكفاية لإتاحة إمكانية إجراء تغييرات في ظل تغير متطلبات العملاء. الخلاصة تساعد مبادئ تصميم الخدمة على تطوير خدمات تقدم للمستخدمين والعملاء تجارب عالية الجودة. تتشابه الكثير من هذه المبادئ مع مبادئ مطبقة مسبقًا في تصميم تجربة المستخدم، ويجب أن يكون مصمم تجربة المستخدم للمنتجات قادرًا على الانتقال بسهولة نسبيًا إلى تصميم تجربة المستخدم للخدمات. ترجمة -وبتصرّف- للمقال The Principles of Service Design Thinking - Building Better Services. اقرأ أيضًا العوامل المؤثرة في تجربة المستخدم تصميم تجربة مستخدم مبسطة لتحقيق ارتباط صحي بالهواتف الذكية الانحياز المعرفي الإيجابي والسلبي في تصميم المنتج مجموعة أمثلة تعليمية عن التصميم السيئ مقابل التصميم الجيد
    1 نقطة
  5. ظهر لدي خطأ فقدان أحد التوابع عندما نقلت جميع وظائف المسارات من web.php إلى المتحكم PostController بالرغم من تعريفي للمسارات بشكل صحيح، الخطأ مثل ما هو موضح بالصورة المرفقة
    1 نقطة
  6. إذا كان إستفسارك يتعلق بأحد دروس الدورة يُرجى طرحه في صفحة ذلك الدرس. بخصوص المشكلة التي تظهر لك، فواضح من نص الرسالة أن ملف العرض show.blade.php يستخدم متغير إسمه comments هذا المتغير لم تقم بتمريره من الحدث المسؤول عن عرض هذه الصفحة في المتحكم. يُفترض أن يكون إسم الحدث هو show في المتحكم PostController و بفرض وجود علاقة بين النموذج Post و النموذج Comment إسمها comments هي واحد لكثير أي يُمكن للمنشور أن يكون له عدة تعليقات تابعة له يُمكنك تمرير المتغير بالشكل التالي: public function(Post $post) { $comments = $post->comments; return view('posts.show', compact('post', 'comments')); }
    1 نقطة
  7. اريد التحكم الكامل في المتغيرات العامة في الموقع مثل icon و primary color ونوع الخط والكثير من الأشياء التي يجب ان تكون ديناميكية
    1 نقطة
  8. توجد مكتبة صغيرة اسمها Constance تقوم ب: بترحيل إعداداتك الثابتة بسهولة إلى الإعدادات الديناميكية. بتحرير الإعدادات الديناميكية في واجهة إدارة Django. تعد الواجهة الخلفية لقاعدة البيانات اختيارية وتخزن قيم التكوين في نموذج Django القياسي. يتطلب الحزمة django-picklefield لتخزين تلك القيم. تثبيته على هذا النحو: pip install django-constance[database] وفي ملف settings CONSTANCE_BACKEND = 'constance.backends.database.DatabaseBackend' INSTALLED_APPS = ( # .... 'constance.backends.database', ) ثم قم بترحيل قاعدة البيانات : python manage.py migrate database
    1 نقطة
  9. مو عارفه ليش مو جالس يطبع لي النص بالconsole على انو كنت امشي خطوة خطوة مثل الفيديو
    1 نقطة
  10. عفوا أخي عدنان أريده صورة شفافة ثابتة تظر كخلفية ولكن فوق كل العناصر الحل الذي قدمه الأخ معاذ جميل ولكن سأضطر إلى مضاعفة كل مايُنقر في الصفحة
    1 نقطة
  11. يحتمل ان هنالك اعدادا افتراضيا آخر عطل ظهور الفكرة لديك. جرب انشاء عنصر مستقل تماما وطبق عليه التنسيقات اللازمة: <body> <div class="bg"></div> .. .bg{ position:fixed; height:100%; width:100%; top:0; left:0; background-image:url(image) } ايضا تأكد من امتلاك العنصر body الخلفية الشفافة: body{ background-color: transparent; } ايضا تغاضى عن استعمال z-index لأنه سيتم وضع العنصر الثابت افتراضا وراء باقي العناصر مما لا يعطل الوصول اليه. يحتمل ان يحل هذا المشكل لديك.
    1 نقطة
  12. فكرتي أن تضع لمشروعك ثلاث طبقات، طبقة تكون تحت الصورة وهي العناصر الأساسية للمشروع، ثم تليها طبقة الصورة التي ستغطي كامل المحتوى، والطبقة الأخيرة عناصر غير مرئية تكون فوق الصورة بحيث يقابل كل عنصر منها العنصر الظاهر من الطبقة الأولى، كمثال على كلامي: <div> <!-- محتوى أسفل الصورة --> <button id="mainContent">انقر هنا</button> </div> <img id="up" src="url"/> <!-- ضع الستايل المناسب للصورة بحيث تعبّئ كامل الصفحة --> <div> <!-- محتوى فوق الصورة --> <button id="opacityNonContent" onclick="doSomeThing">انقر هنا</button> </div> الزر الأول سيكون ظاهر من أسفل الصورة لكن لا يمكنك ضغطه، الزر الثاني سيكون مخفي فوق الصورة لكن يمكنك ضغطه ووضعنا له الحدث onclick فعند النقر عليه سيقوم بتنفيذ الوظيفة doSomeThing وهكذا مع جميع المحتوى.
    1 نقطة
  13. أيوه تماما الشطر الثاني من كلامك أخي عدنان يوضح ما أردته بالضبط
    1 نقطة
  14. لم افهم المشكلة على نحو جيد. هل تحاول تعيين خلفية صورة بشفافية لعنصر body ام تحاول اضافة عنصر صورة شفافة ثابت يظهر كخلفية ثابتة على طول امتداد الصفحة؟
    1 نقطة
  15. الصورة تظهر ولكن لما انزل سكرول تبدا في الإختفاء وايضا لا يمكنني الضغط على العناصر التي اسفلها المشكلة منطقية ولكن هل يوجد حل يخدم مصلحتي ؟
    1 نقطة
  16. بما ان العنصر يمتلك ثابتة، حاول اعطاءه z-index بقيمة اقل من تلك التي يمتلكها body. z-20 before:z-10 هل يوثر ذلك في ظهورها؟
    1 نقطة
  17. لما تعطي العنصر before:: الوضعية الثابتة؟ سوف يؤثر على تموضعه فوق العناصر وبالتالي الوصول اليها. جرب اعطاءه الوضعية المطلقة before:absolute before:top-0 before:left-0 قد تحتاج في هذا التخلص نهائيا من before:z-[999] يمكنك ايضا القيام بذلك عن طريق CSS وحدها، يوجد الخاصية background التي تعبر عن تجميعة الخصائص التالية مرتبة: background-color background-image background-repeat background-attachment background-position لنعطيها تدرج لوني شفاف + صورة، يكون كـ: background: linear-gradient(rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.2)), url(image.jpg) سينشئ هذا طبقة بيضاء بشفافية نحددها فوق الصورة. سيعطي هذا نفس المقاربة. قد تحتاج ايضا اسناد هاته الخصائص لظهور كامل للخلفية دون اي مشاكل: relative bg-fixed bg-center bg-cover bg-no-repeat
    1 نقطة
  18. يوجد حلّ كأن تضع عناصر مع opacity:0 (غير مرئيين) في الموضع الذي تريد النقر فيه وتضع الوظائف التي تريدها على هذه العناصر غير المرئية. فيصبح لكل عنصر مرئي تحت الصورة عنصر غير مرئي فوقه يقوم بوظائفه.
    1 نقطة
  19. إن الخطأ هو في التابع الذي تقوم بتمريره إلى ال addEventListener حيث أنك تقوم باستدعاء التابع و ليس القيام بتمرير اسمه فقط. عليك فقط القيام بتمرير التابع. أي أننا في هذه الطريقة نقوم بتمرير اسم التابع حتى يعرف ما الذي يجب تنفيذه عند حدوث ال event و هو يقوم بتنفيذ التابع عند حدوثه و بالتالي تكون القيمة المناسبة موجودة في مكون ال html. بينما في حال استدعينا التابع فوراً فسيأخذ القيمة الافتراضية تلقائياً و لن يقوم بتحديث شيء.
    1 نقطة
  20. أخي كل ما عليك حذف الأقواس عند دالة makeGrid داخل الaddEventListener: sub.addEventListener("click", makeGrid) في حال وضعت الأقواس ستنفذ الطريقة لمرة واحدة فقط عند بدء البرنامج. لأن وضع الأقواس يكون لاستدعاء الطريقة وتنفيذها، أما هنا نحن نريد مرجع الطريقة في الذاكرة دون تنفيذها لأن التنفيذ سيتم عند النقر فقط.
    1 نقطة
  21. ما سبب هذا الايرور مع انه الاكواد صحيحه
    1 نقطة
  22. كنت أقوم بدراسة التوابع فظهر لي مثال لتابع داخل تابع و حاولت تقليده في المثال التالي: def f(name): def say_hello(): print(f'hello {name}') return say_hello g = f('ali') g() لكن لم أفهم تماماً لماذا قام بطباعة hello ali كيف عرف التابع say_hello قيمة name مع أننا لم نقم بتمريرها له.
    1 نقطة
  23. إن هذا المفهوم يدعى ال closure و هو عبارة عن فضاء اسماء يضاف إلى فضاء الأسماء المحلي الخاص بالتابع، عندما تقوم بكتابة تابع داخل تابع فإن التابع الداخلي يستطيع الوصول إلى كافة المتحولات المعرفة (و الممررة) في التابع الخارجي، و بالتالي هذه المتحولات ستكون ضمن فضاء الاسماء الخاص به. عند إرجاع هذا التابع فإن فضاء الأسماء الخاص به سيكون يحتوي على هذه المتحولات و بالتالي ستأخذ القيمة الصحيحة لها. بشكل دقيق هنا في مثالك هذا، فإن التابع say_hello هو تابع داخلي بينما التابع f هو تابع خارجي. التابع say_hello يستطيع الوصول إلى المتحول name بشكل طبيعي حيث أنه معرف داخل التابع f، و عند تمرير اسمك (أي قيمة محددة) للتابع f فإن هذا المتحول أخذ قيمة هي اسمك، و هذا القيمة أصبحت مرتبطة بالمتحول في فضاء الاسماء و بالتالي الأمر ذاته بالنسبة للتابع say_hello و عند إرجاع هذا التابع ستكون القيمة لا تزال في فضاء اسماءه و هذا ما ظهر من خلال المثال عندما قام بطباعة القيمة المطلوبة للمتحول name.
    1 نقطة
  24. وعليكم السلام جربت الكود الخاص بك، القيمة في الinput تتغير بشكل طبيعي، قم بإضاحة المشكلة بشكل أكبر لنستطيع مساعدتك
    1 نقطة
  25. هل يمكنك مشاركة الكود الذي تقوم عن طريقه بأخذ القيم من ال form؟
    1 نقطة
  26. احتاج الى مكتبة جافاسكريب javascript لاستعمال محرر النصوص word داخل تطبيق سطح المكتب Electron
    1 نقطة
  27. برنامج Office Word هو برنامج منفصل بحد ذاته، ولا يمكن دمجه في برامج أخرى للكثير من الأسباب، منها أنه مدفوع وليس مجاني، مغلق المصدر ولا يمكن لأحد التعديل عليه سوى شركة مايكروسوفت، واللغة المستعملة في إنشائه ليست JavaScript ... إلخ. ولكن كبديل يوجد العديد من المكتبات التي تسمح لك بإنشاء محرر نصوص بإستخدام HTML و JavaScript، منها: ckeditor tiny editorjs quilljs كل المحررات السابقة مبنية بإستخدام JavaScript ويمكن إستخدامها في تطبيقات Electron بدون مشكلة. كما أن كلًا منهم يوفر توثيق Documentation كامل لكيفية تثبيته وإستخدامه والتعديل عليه.
    1 نقطة
  28. && يقوم بعملية مقارنة منطقية في حين & يقوم بعملية مقارنة للأعداد الثنائية binary للعبارتين الفرق بين && و & هو :أن الـ compiler في حالة && يقوم باختبار العبارة الأولى إذا كانت خاطئة لايمر على العبارة الأخرى لأن الـ and يجب أن تكون كلتا العبارتين true فإذا كانت إحدى العبارتين false لاداعي لمرور الـ compiler للعبارة الأخرى. ولكن في حالة & يمر الـ compilerعلى العبارة الثانية حتى وإن كانت العبارة الأولى false ، لذلك من الأفضل استخدام && بدل &.
    1 نقطة
  29. الدالة (funtion) هي كتلة من التعليمات التي تنفِّذ إجراءً ما، ويمكن، بعد تعريفها، إعادة استخدامها في أكثر من موضع. تجعل الدوال الشيفرة تركيبية (modular)، مما يسمح باستخدام نفس الشفرة مرارًا وتكرارًا. تضم بايثون عددًا من الدوال المُضمّنة الشائعة، مثل: ‎print()‎: تطبع كائنًا في الطرفية. ‎int()‎: تحوّل أنواع البيانات النصية أو العددية إلى أعداد صحيحة. ‎len()‎: تعيد طول كائن، وغيرها من الدوال. تتضمن أسماء الدوال الأقواس، وقد تتضمن معاملات أيضًا. في هذا الدرس، سنتعلم كيفية تعريف الدوال، وكيفية استخدامها في البرامج. تعريف الدالة لنبدأ بتحويل البرنامج "مرحبًا بالعالم!" إلى دالة. أنشئ ملفًا نصيًا جديدًا، وافتحه في محرر النصوص المفضل عندك، ثم استدع البرنامج ‎hello.py‎. تُعرَّف الدالة باستخدام الكلمة المفتاحية ‎def‎، متبوعة باسم من اختيارك، متبوعًا بقوسين يمكن أن يَحتويا المعاملات التي ستأخذها الدالة، ثم ينتهي التعريف بنقطتين. في هذه الحالة، سنعرّف دالة باسم ‎hello()‎: def hello(): في الشفرة أعلاه، أعددنا السطر الأول من تعريف الدالة. بعد هذا، سنضيف سطرًا ثانيًا مُزاحًا بأربع مسافات بيضاء، وفيه سنكتب التعليمات التي ستنفّذها الدالة. في هذه الحالة، سنطبع العبارة مرحبا بالعالم في سطر الأوامر: def hello(): print("مرحبا بالعالم") لقد أتممنا تعريف دالتنا، غير أننا إن نَفَّذنا البرنامج الآن، فلن يحدث أيّ شيء، لأننا لم نستدع الدالة؛ لذلك، سنستدع الدالة عبر التعبير ‎hello()‎ خارج كتلة تعريف الدالة: def hello(): print("مرحبا بالعالم") hello() الآن، لننفّذ البرنامج: python hello.py يجب أن تحصل على المخرجات التالية: مرحبا بالعالم! بعض الدوال أكثر تعقيدًا بكثير من الدالة ‎hello()‎ التي عرّفناها أعلاه. على سبيل المثال، يمكننا استخدام for والتعليمات الشرطية، وغيرها داخل كتلة الدالة. على سبيل المثال، تستخدم الدالة المُعرّفة أدناه تعليمة شرطية للتحقق مما إذا كانت المدخلات الممرّرة إلى المتغير ‎name‎ تحتوي على حرف علة (vowel)، ثم تستخدم الحلقة ‎for‎ للمرور (iterate) على الحروف الموجودة في السلسلة النصية ‎name‎. # names() تعريف الدالة def names(): # وإحالة المدخلات عليه name إعداد المتغير name = str(input('أدخل اسمك:')) # يحتوي حرف علة name التحقق من أن if set('aeiou').intersection(name.lower()): print('اسمك يحوي حرف علة') else: print('اسمك لا يحوي حرف علة') # name المرور على حروف for letter in name: print(letter) # استدعاء الدالة names() تستخدم الدالة ‎names()‎ التي عرّفناها أعلاه تعليمة شرطية، وحلقة for، وهذا توضيح لكيفية تنظيم الشفرة البرمجية ضمن تعريف الدالة. يمكننا أيضًا جعل التعليمة الشرطية والحلقة ‎for‎ دالتين منفصلتين. إنّ تعريف الدوال داخل البرامج يجعل الشفرة البرمجية تركيبية (modular)، وقابلة لإعادة الاستخدام، وذلك سيتيح لنا استدعاء نفس الدالة دون إعادة كتابة شيفرتها كل مرة. المعاملات حتى الآن، عرّفنا دالة ذات قوسين فارغين لا تأخذ أيّ وسائط (arguments)، سنتعلم في هذا القسم كيفية تعريف المعاملات (parameters) وتمرير البيانات إلى الدوال. المعامل (parameter) هو كيان مُسمًّى يوضع في تعريف الدالة، ويعرّف وسيطًا (arguments) يمكن أن تقبله الدالة عند استدعائها. دعنا ننشئ برنامجًا صغيرًا يأخذ 3 معاملات ‎x‎ و ‎y‎ و ‎z‎. سننشئ دالة تجمع تلك المعاملات وفق عدة مجموعات ثم تطبع تلك حاصل جمعها. def add_numbers(x, y, z): a = x + y b = x + z c = y + z print(a, b, c) add_numbers(1, 2, 3) مرّرنا العدد ‎1‎ إلى المعامل ‎x‎، و ‎2‎ إلى المعامل ‎y‎، و ‎3‎ إلى المعامل ‎z‎. تتوافق هذه القيم مع المعاملات المقابلة لها في ترتيب الظهور. يُجرِي البرنامج العمليات الحسابية على المعاملات على النحو التالي: a = 1 + 2 b = 1 + 3 c = 2 + 3 تطبع الدالة أيضًا ‎a‎ و ‎b‎ و ‎c‎، وبناءً على العمليات الحسابية أعلاه، فإنّ قيمة ‎a‎ ستساوي العدد ‎3‎، و ‎b‎ ستساوي ‎4‎، و ‎c‎ ستساوي العدد ‎5‎. لننفّذ البرنامج: python add_numbers.py سنحصل على المخرجات التالية: 3 4 5 المعاملات هي وسائط يتم تعريفها عادة كمتغيرات ضمن تعريف الدالة. يمكن تعيين قيم إليها عند تنفيذ التابع بتمرير وسائط إلى الدالة. دورة تطوير التطبيقات باستخدام لغة Python احترف تطوير التطبيقات مع أكاديمية حسوب والتحق بسوق العمل فور انتهائك من الدورة اشترك الآن الوسائط المسمّاة تُستدعى المعاملات بحسب ترتيب ظهورها في تعريف الدالة، أما الوسائط المسماة (Keyword Arguments) فتُستخدَم بأسمائها في استدعاء الدالة. عند استخدام الوسائط المسمّاة، يمكنك استخدام المعاملات بأيّ ترتيب تريد، لأنّ مترجم بايثون سيستخدم الكلمات المفتاحية لمطابقة القيم مع المعاملات. سننشئ دالة تعرض معلومات الملف الشخصي للمستخدم، ونمرر إليها المُعامِلين ‎username‎ (سلسلة نصية)، و ‎followers‎ (عدد صحيح). # تعريف دالة ذات معاملات def profile_info(username, followers): print("Username: " + username) print("Followers: " + str(followers)) داخل تعريف الدالة، وضعنا ‎username‎ و ‎followers‎ بين قوسي الدالة ‎profile_info()‎ أثناء تعريفها. تطبع شفرة الدالة المعلومات الخاصة بالمستخدم على هيئة سلسلة نصية باستخدام المعاملين المُمرّرين. الآن، يمكننا استدعاء الدالة وتعيين المعاملات: def profile_info(username, followers): print("Username: " + username) print("Followers: " + str(followers)) # استدعاء الدالة مع تعيين المعاملات profile_info("sammyshark", 945) # استدعاء الدالة مع تمرير الوسائط المسماة إليها profile_info(username="AlexAnglerfish", followers=342) في الاستدعاء الأول للدالة، مرّرنا اسم المستخدم ‎sammyshark‎، وعدد المتابعين ‎945‎ بالترتيب الوارد في تعريف الدالة. أمّا في الاستدعاء الثاني للدالة، فقد استخدمنا الوسائط المسمّاة، وقمنا بتعيين قيم للوسائط ويمكن عكس الترتيب إن شئنا. لننفذ البرنامج: python profile.py سنحصل على المخرجات التالية: Username: sammyshark Followers: 945 Username: AlexAnglerfish Followers: 342 سنحصل في المخرجات على أسماء المستخدمين، وأعداد المتابعين لكلا المستخدمين. يمكننا تغيير ترتيب المعاملات، كما في المثال التالي: def profile_info(username, followers): print("Username: " + username) print("Followers: " + str(followers)) # تغيير ترتيب المعاملات profile_info(followers=820, username="cameron-catfish") عند تنفيذ البرنامج أعلاه، سنحصل على المخرجات التالية: Username: cameron-catfish Followers: 820 يحافظ تعريف الدالة على نفس ترتيب العبارات في ‎print()‎، لذلك يمكننا استخدام الوسائط المسمّاة بأيّ ترتيب نشاء. القيم الافتراضية للوسائط يمكننا إعطاء قيم افتراضية لواحد أو أكثر من المعاملات. في المثال أدناه، سنعطي للمعامل ‎followers‎ القيمة الافتراضية ‎1‎ لاستعمالها إن لم تُمرَّر هذه القيمة للدالة عند استدعائها: def profile_info(username, followers=1): print("Username: " + username) print("Followers: " + str(followers)) الآن، يمكننا استدعاء الدالة مع تعيين اسم المستخدم فقط، وسيُعيّن عدد المتابعين تلقائيًا ويأخذ القيمة 1. لكن يمكننا تغيير عدد المتابعين إن شئنا. def profile_info(username, followers=1): print("Username: " + username) print("Followers: " + str(followers)) profile_info(username="JOctopus") profile_info(username="sammyshark", followers=945) عندما ننفّذ البرنامج باستخدام الأمر ‎python profile.py‎، سنحصل على المخرجات التالية: Username: JOctopus Followers: 1 Username: sammyshark Followers: 945 تمرير قيم إلى المعاملات الافتراضية سيتخطى القيمة الافتراضية المعطاة في تعريف الدالة. إعادة قيمة كما يمكن تمرير قيم إلى الدالة، فيمكن كذلك أن تنتج الدالة قيمة وتعيدها لم استدعاها. يمكن أن تنتج الدالة قيمة، ويكونُ ذلك عبر استخدام التعليمة ‎return‎، هذه التعليمة اختيارية، وفي حال استخدامها، فستُنهِي الدالة مباشرةً عملها وتوقف تنفيذها، وتُمرَّر قيمة التعبير الذي يعقُبها إلى المُستدعي (caller). إذا لم يلي التعليمة ‎return‎ أي شيء، فستُعيد الدالة القيمةَ ‎None‎. حتى الآن، استخدمنا الدالة ‎print()‎ بدلاً من ‎return‎ في دوالنا لطباعة شيء بدلًا من إعادته. لننشئ برنامجًا يعيد متغيرًا بدلًا من طباعته الآن. في ملف نصي جديد يسمى ‎square.py‎، سننشئ برنامجًا يحسب مربع المعامل ‎x‎، ويُحيل الناتج إلى المتغير ‎y‎، ثم يعيده. سنطبع المتغير ‎result‎، والذي يساوي ناتج تنفيذ الدالة ‎square(3)‎. def square(x): y = x ** 2 return y result = square(3) print(result) لننفّذ البرنامج: python square.py سنحصل على المخرجات التالية: 9 مخرجات البرنامج هي العدد الصحيح ‎9‎ الذي أعادته الدالة وهو ما نتوقعه لو طلبنا من بايثون حساب مربع العدد 3. لفهم كيفية عمل التعليمة ‎return‎، يمكننا تعليق التعليمة ‎return‎: def square(x): y = x ** 2 # return y result = square(3) print(result) الآن، لننفّذ البرنامج مرة أخرى: python square.py سنحصل على الناتج التالي: None بدون استخدام التعليمة ‎return‎، لا يمكن للبرنامج إعادة أيّ قيمة، لذلك تُعاد القيمة الافتراضية ‎None‎. إليك مثال آخر، في برنامج ‎add_numbers.py‎ أعلاه، سنستبدل بالتعليمة ‎return‎ الدالة ‎print()‎. def add_numbers(x, y, z): a = x + y b = x + z c = y + z return a, b, c sums = add_numbers(1, 2, 3) print(sums) خارج الدالة، أحلنا إلى المتغير ‎sums‎ نتيجة استدعاء الدالة بالوسائط ‎1‎ و ‎2‎ و ‎3‎ كما فعلنا أعلاه ثم طبعنا قيمته. فلننفّذ البرنامج مرة أخرى: python add_numbers.py والناتج سيكون: (3, 4, 5) لقد حصلنا على الأعداد ‎3‎ و ‎4‎ و ‎5‎ وهي نفس المخرجات التي تلقيناها سابقًا عندما استخدمنا الدالة ‎print()‎ في الدالة. هذه المرة تمت إعادتها على هيئة صف لأنّ التعبير المرافق للتعليمة ‎return‎ يحتوي على فاصلة واحدة على الأقل. تُوقَف الدوال فورًا عندما تصل إلى التعليمة ‎return‎، سواء أعادت قيمة، أم لم تُعِد. def loop_five(): for x in range(0, 25): print(x) if x == 5: # x == 5 إيقاف الدالة عند return print("This line will not execute.") loop_five() يؤدي استخدام التعليمة ‎return‎ داخل الحلقة ‎for‎ إلى إنهاء الدالة، وبالتالي لن يتم تنفيذ السطر الموجود خارج الحلقة. لو استخدمنا بدلًا من ذلك break، فسيُنفّذ السطر ‎print()‎ الأخير من المثال السابق. نعيد التذكير أنَّ التعليمة ‎return‎ تنهي عمل الدالة، وقد تعيد قيمة إذا أعقبها تعبير. استخدام ‎main()‎ دالةً رغم أنه يمكنك في بايثون استدعاء الدالة في أسفل البرنامج، وسيتم تنفيذها (كما فعلنا في الأمثلة أعلاه)، فإنّ العديد من لغات البرمجة (مثل C++‎ و Java) تتطلب الدالة ‎main‎. إنّ تضمين دالة ‎main()‎، وإن لم يكن إلزاميًا، يمكن أن يهيكل برامج بيثون بطريقة منطقية، بحيث تضع أهم مكونات البرنامج في دالة واحدة. كما يمكن أن يجعل البرنامج أكثر مقروئية للمبرمجين غير البايثونيِّين. سنبدأ بإضافة دالة ‎main()‎ إلى برنامج ‎hello.py‎ أعلاه. سنحتفظ بالدالة ‎hello()‎، ثم نعرّف دالة ‎main()‎: def hello(): print("مرحبا بالعالم") def main(): ضمن الدالة ‎main()‎، سندرج الدالة ‎print()‎، والتي ستعُلِمنا بأننا في الدالة ‎main()‎. أيضًا سنستدعي الدالة ‎hello()‎ داخل ‎main()‎: def hello(): print("مرحبا بالعالم") def main(): print("هذه هي الدالة الرئيسية") hello() أخيرًا، في أسفل البرنامج، سنستدعي الدالة ‎main()‎: def hello(): print("مرحبا بالعالم") def main(): print("هذه هي الدالة الرئيسية.") hello() main() الآن يمكننا تنفيذ برنامجنا: python hello.py وسنحصل على المخرجات التالية: هذه هي الدالة الرئيسية. مرحبا بالعالم! لمّا استدعينا الدالة ‎hello()‎ داخل ‎main()‎، ثم نفّذنا الدالة ‎main()‎ وحدها، فقد طُبع النص مرحبا بالعالم مرة واحدة فقط، وذلك عقب السلسلة النصية التي أخبرتنا بأننا في الدالة الرئيسية. سنعمل الآن مع دوال مُتعدِّدة، لذلك من المستحسن أن تراجع نطاقات المتغيرات في المقالة: كيفية استخدام المتغيرات في بايثون. إذا عرّفت متغيرًا داخل دالة، فلا يمكنك أن تستخدم ذلك المتغير إلا ضمن تلك الدالة. لذا، إن أردت استخدام متغير ما في عدة دوال، فقد يكون من الأفضل الإعلان عنه متغيرًا عامًا (global variable). في بايثون، يعدُّ ‎'__main__'‎ اسم النطاق الذي ستُنفَّذ فيه الشيفرة العليا (top-level code). عند تنفيذ برنامج من الدخل القياسي (standard input)، أو من سكربت، أو من سطر الأوامر، سيتم ضبط ‎__name__‎ عند القيمة ‎'__main__'‎. لهذا السبب، اصطلح مطورو بايثون على استخدام الصياغة التالية: if __name__ == '__main__': # الشفرة التي ستُنفّذ لو كان هذا هو البرنامج الرئيسي هذه الصياغة تتيح استخدام ملفات بايثون إما: برامج رئيسية، مع تنفيذ ما يلي التعليمة ‎if‎، أو وحدات عادية، مع عدم تنفيذ ما يتبع التعليمة ‎if‎. سيتم تنفيذ الشفرة غير المُتضمّنة في العبارة if __name__ == '__main__'‎:‎ عند التنفيذ. إذا كنت تستخدم ملف بايثون كوحدة، فسيتم أيضًا تنفيذ الشفرة البرمجية غير المُتضمّنة في هذه العبارة عند استيراد ذلك الملف. دعنا نوسع البرنامج ‎names.py‎ أعلاه، سننشئ ملفا جديدًا يسمى ‎more_names.py‎. سنعلن في هذا البرنامج عن متغير عام، ونعدِّل الدالة ‎names()‎ الأصليَّة بشكل نقسِّم فيه التعليمات إلى دالّتين منفصلتين. ستتحقق الدالة الأولى ‎has_vowel()‎ مما إذا كانت السلسلة النصية ‎name‎ تحتوي على حرف علة (vowel). وتطبع الدالة الثانية ‎print_letters()‎ كل حرف من السلسلة النصية ‎name‎. # الإعلان عن متغير عام لاستخدامه في جميع الدوال name = str(input('أدخل اسمك:')) # يحتوي حرف علة name تعريف دالة للتحقق من أن def has_vowel(): if set('aeiou').intersection(name.lower()): print('اسمك يحتوي حرف علة') else: print('اسمك لا يحتوي حرف علة') # name المرور على حروف def print_letters(): for letter in name: print(letter) بعد ذلك، دعنا نعرّف الدالة ‎main()‎ التي سَتستدعي كلا الدّالتين ‎has_vowel()‎ و ‎print_letters()‎. # الإعلان عن متغير عام لاستخدامه في جميع الدوال name = str(input('أدخل اسمك:')) # يحتوي حرف علة name تعريف دالة للتحقق من أنّ def has_vowel(): if set('aeiou').intersection(name.lower()): print('اسمك يحتوي حرف علة') else: print('اسمك لا يحتوي حرف علة') # name المرور على حروف def print_letters(): for letter in name: print(letter) # التي ستستدعي بقية الدوال main تعريف الدالة def main(): has_vowel() print_letters() أخيرًا، سنضيف العبارة ‎if __name__ == '__main__':‎ في أسفل الملف. لقد وضعنا جميع الدوال التي نودّ تنفيذها في الدالة ‎main()‎، لذا سنستدعي الدالة ‎main()‎ بعد العبارة ‎if‎. # الإعلان عن متغير عام لاستخدامه في جميع الدوال name = str(input('أدخل اسمك:')) # يحتوي حرف علة name تعريف دالة للتحقق من أن def has_vowel(): if set('aeiou').intersection(name.lower()): print('اسمك يحتوي حرف علة') else: print('اسمك لا يحتوي حرف علة') # name المرور على حروف def print_letters(): for letter in name: print(letter) # التي ستستدعي بقية الدوال main تعريف الدالة def main(): has_vowel() print_letters() # main() تنفيذ الدالة if __name__ == '__main__': main() يمكننا الآن تنفيذ البرنامج: python more_names.py سيعرض هذا البرنامج نفس المخرجات التي عرضها البرنامج ‎names.py‎، بيْد أنّ الشفرة هنا أكثر تنظيمًا، ويمكن استخدامها بطريقة تركيبية (modular). إذا لم ترغب في الإعلان عن الدالة ‎main()‎، يمكنك بدلاً من ذلك إنهاء البرنامج كما يلي: ... if __name__ == '__main__': has_vowel() print_letters() يؤدي استخدام ‎main()‎ كدالة، واستخدام العبارة ‎if __name__ == '__main__':‎ إلى تنظيم الشيفرة البرمجية بطريقة منطقية، وجعلها أكثر مقروئية وتراكبية. خلاصة الدوال هي كتل من التعليمات البرمجية التي تُنفِّذ إجراءات معيّنة داخل البرنامج، كما تساعد على جعل الشفرة تركيبية، وقابلة لإعادة الاستخدام بالإضافة إلى أنها تنظمها وتسهل من قراءتها. لمعرفة المزيد حول كيفية جعل الشفرة تركيبية، يمكنك قراءة المقالة التالية: كيفية كتابة الوحدات في بايثون 3. هذه المقالة جزء من سلسة مقالات حول تعلم البرمجة في بايثون 3. ترجمة -وبتصرّف- للمقال How To Define Functions in Python 3 لصاحبته Lisa Tagliaferri اقرأ أيضا المقالة التالية: كيفية استخدام ‎args و ‎*kwargs في بايثون 3 المقالة السابقة: كيفية استخدام تعابير break و continue و pass عند التعامل مع حلقات التكرار في بايثون 3 المرجع الشامل إلى تعلم لغة بايثون كتاب البرمجة بلغة بايثون
    1 نقطة
×
×
  • أضف...