البحث في الموقع
المحتوى عن 'functions'.
-
يمكنك استخدام اكسل تماما كما تستخدم الحاسبة في إجراء العمليات الحسابية البسيطة والمعقدة. فهو يحتوي على مجموعة واسعة من الدوال functions الخاصة بمختلف المجالات يمكنك استخدامها لإجراء العمليات الحسابية المطولة في وقت قصير. الصيغ في اكسل هي عبارة عن مجموعة من المعاملات، الدوال والأرقام. يجب أن تبدأ أي صيغة بعلامة يساوي (=)، وسيتوضح المفهوم أكثر عن طريق الأمثلة في الفقرات التالية. الرياضيات الأساسية في اكسل تقوم معظم العمليات الحسابية المعقدة على أساس الرياضيات البسيطة؛ الجمع، الطرح، الضرب، والقسمة. لنتعلم كيفية القيام بهذه العمليات باستخدام المعاملات (+، -، *، /) أو الدوال (Sum، product، إلخ). افتح برنامج اكسل وقم بإنشاء جدول بيانات بسيط يحتوي على عدة أرقام لتطبيق العمليات الحسابية عليها. الجمع لكي تقوم بجمع رقمين أو عدد من الأرقام، حدّد الخلية التي تريد ظهور الناتج فيها ثم اكتب صيغة الجمع يدويا: =العدد الثاني + العدد الأول ثم اضغط Enter من لوحة المفاتيح. لكن هذه الطريقة ستصبح مطولة ومملة إذا كان عدد الأرقام التي تريد جمعها أكثر من 3. لذلك بدلا من كتابة الأرقام قم بتحديد الخلايا. أي اكتب علامة (=) ثم حدد الخلية الأولى بواسطة الفأرة، ثم علامة (+) ثم حدد الخلية الثانية، وهكذا. لاحظ أن البرنامج يقوم بتمييز الخلايا مع اسم الخلية في الصيغة بنفس اللون. هذه الطريقة مفيدة أكثر إذا كنت ستجري تغييرا على الجدول لاحقا، إذا سيتغير ناتج الجمع تلقائيا تبعا لتغير الأرقام في الخلايا المشمولة في الصيغة. أي إذا قمت بتغيير محتوى الخلية B5 من "3" إلى "5" ستتغير النتيجة إلى "14" تلقائيا. هل ترغب في الحصول على مستندات إكسل احترافية؟ وظّف محلل بيانات خبير لتحرير مستنداتك وتنسيقها من مستقل أضف مشروعك الآن الطرح لا تختلف عملية الطرح عن عملية الجمع سوى باستخدام المعامل (-) بدلا من (+). يمكنك طرح مجموعة من الخلايا المتجاورة أو غير المتجاورة بنفس طريقة عملية الجمع. الضرب والقسمة عمليتا الضرب والقسمة لا تختلفان عن الجمع والطرح. استخدم علامة النجمة (*) (وليس x) لعملية الضرب، وعلامة (/) لعملية القسمة. طريقة كتابة الصيغة هي كما في عمليتي الجمع والطرح. تذكر أن تكتب علامة = قبل بداية أي صيغة. استخدام الدوال Functions الدّوال هي عبارة عن صيغة معرفة مسبقا في البرنامج. تساعدك الدوال في اكسل على توفير الوقت حيث انها تختصر الكثير من الخطوات. دالة الجمع استخدم زر الجمع التلقائي لجمع نطاق من الخلايا "المتجاورة" بدلا من تحديد كل خلية على حدة. الصيغة العامة لدالة الجمع هي: SUM(number;number,…) ويمثل "number" رقم محدد أو اسم خلية. حدد الخلية التي تريد ظهور الناتج فيها، ويجب أن تكون بعد نطاق الخلايا المتجاورة. مثلا إذا أردت جمع الأرقام في العمود B يجب أن أقوم بتحديد خلية أسفل نطاق الخلايا ضمن العمود B. وإذا أردت جمع الأرقام في الصف 3، يجب أن أقوم بتحديد خلية على يمين نطاق الخلايا في الصف 3 (أو على يسار نطاق الخلايا إذا كان اتجاه الورقة من اليسار إلى اليمين) وهكذا. سأقوم بجمع الأرقام في العمود B، بتحديد الخلية B8، الذهاب إلى تبويب الصفحة الرئيسية، ثم النقر على زر الجمع التلقائي AutoSum. أو حدد الخلية واضغط على اختصار الجمع التلقائي Alt+ =. ستتحول حدود نطاق الخلايا إلى إطار متقطع متحرك، وستظهر صيغة الجمع (Sum(B3:B7= في الخلية التي سيظهر فيها الناتج. اضغط Enter لإتمام العملية. في المثال تمثل النقطتين (:) نطاق من الخلايا. وهذه هي الصيغة العامة لجمع أرقام في نطاق من الخلايا المتجاورة. سأقوم أيضا بجمع نطاق الخلايا في الصف 4 وبنفس الطريقة: لاحظ أنني حصلت على النتيجة "8" من عملية الجمع، وليس "18"، والسبب أنّ أمر الجمع التلقائي يُطبق على الخلايا المتجاورة فقط. يمكنك استخدام دالة الجمع (وليس زر الجمع التلقائي) إذا كانت الخلايا غير متجاورة أيضا. حدد أي خلية تريد ظهور النتيجة فيها، واكتب SUM=. اضغط على المفتاح Ctrl وقم بتحديد العدد الذي تريده من الخلايا (أو نطاق الخلايا) مع الاستمرار بالضغط، ثم أغلق القوس. لاحظ أيضا أنني قمت بتحديد الخليتين B3، B5 ونطاق الخلايا C5:C7. اضغط Enter للحصول على النتيجة. أو بطريقة أخرى، استخدم دالة الجمع واكتب أسماء الخلايا التي تريد جمع محتوياتها يدويًا، افصل بين اسم خلية وآخر بفارزة منقوطة (;). ملاحظة: لمشاهدة محتوى الخلية (أي الصيغة) انقر بشكل مزدوج على الخلية، أو قم بتحديد الخلية وشاهد الصيغة من شريط الصيغة. لا تمتلك عملية الطرح دالة معرفة كما في الجمع، والطريقة الوحيدة لتنفيذ عملية الطرح هي باستخدام المعامل (-). يمكنك أن تطرح ناتج دالة جمع من ناتج دالة جمع آخر: دالة الضرب دالة الضرب تشابه دالة الجمع من حيث طريقة العمل، فيما عدا أنها تقوم بضرب الأرقام بدلا من جمعها. وصيغة دالة الضرب هي: PRODUCT(number;number,…) ويمثل "number" رقم محدد أو اسم خلية. يمكنك استخدام دالة الضرب لإيجاد ناتج الضرب لمجموعة خلايا متجاورة أو غير متجاورة: أما عملية القسمة فحالها حال عملية الطرح لا تمتلك دالة معرفة، استخدم المعامل (/) لتنفيذ عملية القسمة. يمكنك قسمة ناتج دالة ضرب على ناتج دالة جمع مثلا: أدخل بياناتك وعالجها بصور وأساليب متعددة بالإكسل استعن بأفضل مقدمي خدمات الإكسل على خمسات اطلب خدمتك الآن تتابع العمليات الحسابية يستخدم اكسل التتابع المعروف لتنفيذ العمليات الحسابية، أي: الأقواس أولا، من الداخل إلى الخارج. الأسس. الضرب والقسمة من اليسار إلى اليمين. وأخيرا الجمع والطرح من اليسار إلى اليمين. أمثلة: =((25/5)+(2*3)) =5+6 =11 =45/9*5 (تنفذ العمليات من اليسار إلى اليمين، أي القسمة أولا ثم الضرب) =5*5 =25 =5-4+3 (تنفذ العمليات من اليسار إلى اليمين، أي الطرح أولا ثم الجمع) =1+3 =4 =2+(3*(1+5)^2)-6/3 =2+(3*36)-2 =2+108-2 =108 في هذا المثال: يتم إيجاد نتيجة القوس الداخلي (1+5) =6 ثم يرفع الناتج للأس (2) = 36 لأن الأسس تتبع الأقواس في تتابع العمليات ثم تضرب النتيجة بالعدد (3) = 108 ثم يتم إيجاد ناتج عملية القسمة (6/3) = 2 بعدها تصبح الصيغة كالتالي: 2-108+2= والنتيجة النهائية = 108. جرّب تطبيق هذه الصيغ وصيغ أخرى لتفهم تتابع العمليات الحسابية بشكل أفضل. صيغ متقدمة يمكن أن تصبح الصيغ أكثر تعقيدا حسب طبيعة البيانات التي تعمل عليها. ويوفر اكسل مجموعة كبيرة من الدوال المعرفة التي يمكنك استخدامها لتبسيط عملك، كالدوال الهندسية، الدوال المنطقية، دوال الوقت والتاريخ، إلخ. يمكنك استخدام الدوال التي تتناسب ومجالك. للوصول إلى مجموعة الدوال اذهب إلى تبويب صيغ Formulas. انقر على زر المزيد من الدوال More Functions إذا لم تجد ما تبحث عنه. لنأخذ المثال التالي لتوضيح المزيد من القواعد المتعلقة بالصيغ والدوال: الجدول عبارة عن درجات مجموعة من الطلاب لاختبارات الفصلين الأول والثاني والاختبار النهائي. والهدف هنا هو إيجاد النتيجة النهائية بضرب كل درجة بنسبة الفصل، وجمعها للحصول على الدرجة النهائية لكل طالب. سأقوم أولا بتحويل نسبة الفصل إلى نسبة مئوية بتحديد نطاق الخلايا، ثم من تبويب الصفحة الرئيسية Home، ومن خانة أرقام Numbers انقر على زر %. في الخلية H11 سأقوم بإيجاد النتيجة النهائية للطالب 1، بكتابة الصيغة كما في الصورة أدناه: أي سيتم ضرب الدرجة الأولى x 20%، والدرجة الثانية x 20%، والدرجة الثالثة x 60%، ثم تجمع نتائج الضرب الثلاث. سأستخدم خيار التعبئة التلقائية AutoFill (أي نسخ الصيغة) لتكرير نفس الخطوة تلقائيا بدلا من كتابة الصيغة يدويا. لعمل تعبئة تلقائية انقر على الخلية التي تريد نسخ صيغتها، ضع المؤشر على المربع الأخضر في حافة الخلية ليتحول شكله إلى (+) ثم انقر مع السحب إلى جهة اليسار. لكن لاحظ النتائج التي حصلت عليها: تفسير الخطأ الذي حدث هنا هو أنه يوجد نوعان من المراجع للخلايا؛ المراجع النسبية relative references والمراجع المطلقة absolute references. ويستخدم اكسل المراجع النسبية في الصيغة بشكل افتراضي. عندما اخترت الخلية H11 لإظهار النتيجة كانت الصيغة كالتالي: =(G8*H8)+(G9*H9)+(G10*H10) وعندما استخدمت التعبئة لإظهار النتيجة في الخلية التالية إلى اليسار (I11) انتقل اكسل أيضا بالصيغة خطوة إلى اليسار، وأصبحت الصيغة في الخلية I11 كالتالي: =(H8*I8)+(H9*I9)+(H10*I10) أي انتقل من G8 إلى H8، ومن H8 إلى I8، وهكذا. أي أن النسب في الخلايا G8، G9، وG10 تم تجاوزها ولم يتم استخدامها. بمعنى أنه تم استخدام الخلايا G8، G9، وG10 كمرجع نسبي. لذلك يجب التبديل من المراجع النسبية إلى المراجع المطلقة (أي تثبيت الخلايا G8، G9، وG10 في الصيغة واستخدامها كمرجع مطلق) باستخدام المفتاح F4 عند تحديد قيمة الخلية المراد تثبيتها. لاحظ كيف تتغير الصيغة في الصورة أدناه (علامة الدولار $ تستخدم للمراجع المطلقة): وعندما أقوم بالتعبئة التلقائية هذه المرة ستظهر النتائج الصحيحة: جمع الوقت أو طرحه يمكنك إضافة الوقت في جداول بيانات اكسل كأي نوع آخر من البيانات وتنسيقه. كما يمكنك إجراء عمليتي الجمع والطرح عليه أيضًا. يُعرض الوقت في اكسل بعدة تنسيقات كالساعات والدقائق، الساعات والدقائق والثواني، الوقت صباحا (AM)/مساء (PM)، إلخ. يمكنك الوصول إلى هذه التنسيقات عن طريق النقر بزر الفأرة الأيمن على الخلية التي تحتوي على بيانات بصيغة الوقت ثم اختيار تنسيق الخلايا Format Cells. جمع الوقت قد تحتاج إلى جمع الوقت إذا كان لديك مشروع مقسم إلى مهام وتريد معرفة الزمن الكلي الذي يستغرقه إنجاز المشروع، كما في المثال التالي: سأقوم بتحديد الخلية C6 لإظهار نتيجة الجمع فيها ثم استخدم دالة الجمع التلقائي (أو كتابة الصيغة يدويا): ثم سأستخدم التعبئة التلقائية لتطبيق نفس الصيغة على بقية المشاريع بدلا من تكرار عملية الجمع على كل مشروع: سأكون بذلك قد انتهيت من جمع الوقت لولا نتيجة المشروع 3 غير المنطقية على الرغم من كون الصيغة صحيحة، فمن المستحيل أن يكون النتائج 3:55 عند جمع 20:30 ساعة مع 7:25. وتفسير ذلك هو أن نتيجة الجمع أكبر من 24 ساعة، والخلية غير منسقة لتعرض الوقت أكبر من 24 ساعة. لحل المشكلة، سنقوم بتنسيق الخلية لتعرض الوقت أكبر من 24 ساعة: انقر على الخلية بزر الفأرة الأيمن واختر تنسيق الخلايا Format Cells من قسم مخصص Custom وفي خانة النوع Type اكتب h]:mm] تستخدم الأقواس المربعة لعرض الوقت أكبر من 24 ساعة، ويمثل حرف h الساعات، وmm الدقائق. بعد كتابة الصيغة انقر موافق OK وستظهر النتيجة الصحيحة. تستطيع استخدام الأقواس المربعة في كل الحالات لتجنب حدوث مثل هذه الأخطاء. يمكنك أيضا إضافة مدة معينة من الوقت إلى وقت محدد باستخدام دالة الوقت، مثلا إذا كنت ترغب في إضافة ثلاث ساعات وربع إلى الساعة الخامسة والنصف مساء اكتب الصيغة التالية واضغط Enter. يمثل الرقم 3 عدد الساعات، الرقم 15 عدد الدقائق، والرقم 0 عدد الثواني. طرح الوقت يمكنك طرح الوقت أيضا باستخدام اكسل بنفس طريقة طرح الأرقام العادية، فيما عدا أنه لا يظهر النتائج السالبة. وكذلك يجب أن تستخدم المعامل (-) لعدم وجود دالة معرفة لعملية الطرح. قد تحتاج إلى طرح الوقت لمعرفة الوقت المستغرق لعمل يبدأ في وقت محدد وينتهي في وقت محدد، كما في المثال التالي: في الخلية التي تريد إظهار النتيجة فيها قم بكتابة الصيغة التالية (طرح وقت البدء من وقت الانتهاء): بعدها قم بعمل تعبئة تلقائية لتطبيق الصيغة على بقية الخلايا. لاحظ النتائج التالية: النتيجة الأولى على شكل مربعات (#) لأنها سالبة، أي وقت الانتهاء أقل من وقت البدء، وهذا بسبب خطأ في الإدخال (يجب أن يكون وقت الانتهاء مساء وليس صباحا). النتيجة الثانية خاطئة لأن تنسيق الخلية لا يظهر الوقت أكبر من 24 ساعة، وسنقوم بتصحيح هذا الخطأ بالنقر بزر الفأرة الأيمن على الخلية، اختيار تنسيق الخلايا Format Cells، ثم اختيار التنسيق الذي قمنا بعمله سابقا لإظهار الوقت أكبر من 24 ساعة (h]:mm]). النتيجة الثالثة صحيحة. إذا كنت ترغب بإظهار النتائج بصيغة أرقام اعتيادية وليس بصيغة وقت (أي 8.5 بدلا من 8:30) اتبع الخطوات التالية: حدد الخلية التي تريد إظهار الناتج فيها واكتب الصيغة التالية: قمنا باستخدام الأقواس لنتأكد من أن عملية الطرح تنفذ قبل عملية الضرب. كما قمنا بالضرب بالرقم 24 لأن الوقت مخزون في اكسل كجزء من اليوم. أي 6 ساعات تعرف في اكسل بربع يوم (0.25)، و12 ساعة تعرف بنصف يوم (0.5) يوم. لذلك استخدمنا الرقم 24 للتحويل من الجزء من اليوم إلى ساعات. بعد تنفيذ الصيغة انقر بزر الفأرة الأيمن على النتيجة، اختر تنسيق الخلايا Format Cells، ثم اذهب إلى قسم رقم Number. حدد عدد المراتب العشرية التي تريد إظهارها بعد الفارزة ثم انقر موافق OK. سيتحول الناتج من صيغة وقت إلى أرقام عشرية. وكما في عملية جمع الوقت، يمكنك أيضا طرح مدة معينة من الوقت من وقت محدد باستخدام دالة الوقت، مثلا إذا كنت ترغب في طرح ساعتين و45 دقيقة من الساعة التاسعة والربع صباحا اكتب الصيغة التالية واضغط Enter. يمثل الرقم 2 الساعات، الرقم 45 الدقائق، والرقم 0 الثواني.
-
المُزخرفات من أعظم مميزات لغة بايثون، إذ تساعدك على بناء برنامجك باحترافية أكثر موفرة طريقة بسيطة لإضافة خاصيات جديدة للدالة. وهي ببساطة دوال تستطيع أن تعدل على دوال أخرى. تذكير ببعض المفاهيم الأساسية إذا لم تكن تعرف شيئا عن الدوال في لغة بايثون فيجب عليك العودة للدرس السابق الدوال في بايثون قبل أن تكمل قراءة هذا الدرس. تُعتبر الدوال في لغة بايثون كائنات من نوع الفئة الأولى أو First class objects. ما يعني أنّنا نستطيع القيام بالعديد من العمليات، وهي كالتالي: يُمكنك تعريف دالة داخل دالة أخرى يُمكنك أن تستدعي دالة داخل أخرى يُمكنك أن تقوم بتمرير دالة كمُعامل لدالة أخرى يُمكنك أن تُسند دالة لمُتغير يُمكنك إرجاع دالة داخل دالة أخرى بما أنّ المُزخرفات مُجرّد دوال فعلينا أن نبدأ من الأساس، لاحظ الدالة التالية: def say_hello(): print 'Hello!' عند استدعاء الدالة ستُطبع القيمة Hello على الشاشة، هذا ليس بالأمر المُعقد، الآن ماذا لو أردنا أن نعدل الدالة في جزء آخر من البرنامج لكي تطبع أشياء أخرى وتؤدي أغراضا أخرى قبل استدعاء الدالة أو بعد ذلك؟ يُمكن أن نعدّل الدالة مُباشرة، لكن هذا الأمر سيغير من طريقة سير البرنامج، إذ نريد أن نعدل الدالة في منطقة واحدة فقط من البرنامج وليس في كامل البرنامج، هذه المسألة تُحل بالمُزخرفات، وكما يدل اسمها فهي دوال تُزيّن وتُزخرف الدالة الأصلية، أي تُضيف عليها مهاما أخرى. سننشئ لهذه الدالة الآن مُزخرفا Decorator يقوم بطباعة Before قبل تنفيذ الدالة و After بعد تنفيذ الدالة، وذلك دون تعديل الدالة مُباشرة. انظر المثال التالي: def decorator(function): def function_decorator(): print 'Before' function() print 'After' return function_decorator الشيفرة أعلاه عبارة عن دالة تقبل دالة أخرى (الدالة التي نرغب بزَخرَفَتِها أو تزيينها) كمُعامل وبعدها نقوم بإنشاء دالة داخل هذه الدالة لطباعة القيمة Before ثم استدعاء الدالة الأصلية (المُعامل) بعدها طباعة After وأخيرا إرجاع الدالة الجديدة (وهي نُسخة مزخرفة من الدالة الأصلية). بعدها يُمكننا أن نستخدم هذا المُزخرف لزخرفة أي دالة مهما كانت، انظر المثال التالي: # -*- coding: utf-8 -*- def decorator(function): # إنشاء الدالة المسؤولة عن الزخرفة def function_decorator(): # إنشاء الدالة التي ستكون نسخة مزخرفة من الدالة المُمرّرة في كمُعامل print 'Before' # طباعة جملة قبل تنفيذ الدالة function() # استدعاء الدالة print 'After' return function_decorator # إرجاع الدالة مُزَخْرَفَةً def say_hello(): # إنشاء دالة عادية print 'Hello!' say_hello = decorator(say_hello) # زخرفة الدالة say_hello() # استدعاء النُسخة المُزخرفة من الدالة توفر لنا لغة بايثون طريقة أكثر مرونة لزخرفة الدوال، وهي بوضع اسم المُزخرف مسبوقا بالحرف @ قبل تعريف الدالة. أي أنّ السّطر التالي: def say_hello(): print 'Hello!' say_hello = decorator(say_hello) # زخرفة الدالة يُمكن أن يكون كالتالي: @decorator def say_hello(): # إنشاء دالة عادية print 'Hello!' وبالتالي سنتمكن من زخرفة أي دالة نرغب بزخرفتها كالتالي: @decorator def say_hello(): print 'Hello!' @decorator def say_hi(): print 'Hi!' @decorator def say_name(): print 'Abdelhadi!' say_hello() say_hi() say_name() عند تنفيذ الشيفرة أعلاه ستكون المخرجات كالتالي: Before Hello! After Before Hi! After Before Abdelhadi! After مُلاحظة: إذا كانت للدالة معاملات فما عليك إلا استخدام args* التي سبق وتحدثنا عنها في الدرس السابق. # -*- coding: utf-8 -*- def decorator(function): # إنشاء الدالة المسؤولة عن الزخرفة def function_decorator(*args): # إنشاء الدالة التي ستكون نسخة مزخرفة من الدالة المُمرّرة كمُعامل print 'Before' # طباعة جملة قبل تنفيذ الدالة function(*args) # استدعاء الدالة print 'After' return function_decorator # إرجاع الدالة مُزَخْرَفَةً لاحظ الدالتين function_decorator و function. أمثلة على المزخرفات في لغة بايثون إذا فهمت مبدأ المزخرفات فستستطيع أن تتعامل مع الدوال بمرونة عالية، وإليك بعض الأمثلة لاستخدام المُزخرفات لتأدية بعض المهام البسيطة: حساب مدة تنفيذ دالة إذا فهمت جيدا مبدأ المُزخرفات فستلاحظ بأنّك تستطيع تنفيذ مهام قبل تنفيذ الدالة ومهام بعد تنفيذها، ومما سبق نستنتج بأنّنا نستطيع أن نقوم بحفظ الوقت الحالي في مُتغير ثم تنفيذ الدالة وبعدها نقوم بحساب الفرق بين الوقت السابق والوقت الحالي، ما سيُرجع المُدة المُستغرقة لتنفيذ الدالة. البرنامج التالي مثال على مُزخرف لحساب مُدة دالة تطبع الجملة !Hello World مليون مرّة. # -*- coding: utf-8 -*- import time # جلب مكتبة الوقت لاستعمال دوال الوقت def function_time(function): def function_decorator(*args): start_time = time.time() # الحصول على وقت البداية function(*args) end_time = time.time() # الحصول على الوقت بعد نهاية التنفيذ # طباعة اسم الدالة والفرق بين وقت البداية ووقت النهاية print '%s function took %0.3f s' % (function.func_name, (end_time - start_time)) return function_decorator # إرجاع الدالة مُزَخْرَفَةً # زخرفة الدالة المسؤولة عن الطباعة مليون مرة @function_time def print_million_times(): for i in range(0, 1000000): print 'Hello World! 1,000,000 times!' print_million_times() البرنامج أعلاه سيطبع الجملة مليون مرة ثم يعرض الوقت المُستغرق لإنجاز العملية. الجملة الأخيرة ستكون شيئا كالتّالي: print_million_times function took 69.584 s ملاحظات: نستعمل التابع func_name للحصول على اسم الدالة المُمررة كمعامل، ويكون على شكل سلسلة نصية. نستعمل الجملة time.time للحصول على الوقت بالثواني، عدد الثواني الذي تنتجه الجملة هو عدد الثواني الذي مرّ منذ سنة 1970. يُمكنك استعمال هذا المُزخرف مع أي دالة تريد فقط اكتب اسم المُزخرف مسبوقا بالحرف @ ثم عرف الدالة بعده، وستحصل على الوقت المُستغرق لتنفيذ الدالة. حساب عدد مرات استدعاء دالة يُمكننا أن نستخدم المُزخرفات للحصول على عدد المرات التي استدعيت فيها دالة ما في برنامج مُعيّن، بحيث يحمل متغير قيمة العدد صفر، وفي كل مرة تستدعى فيها الدالة، فإن المُتغير يحمل القيمة مع زيادة بالعدد واحد، انظر المثال التالي. # -*- coding: utf-8 -*- # متغير العد n = 0 # المُزخرف def call_times(function): def decorated(): function() # استدعاء الدالة global n # جعل مُتغير العدّ عالميا n += 1 # زيادة قيمة المُتغير print 'Function was called', n, 'times' # طباعة قيمة المُتغير return decorated @call_times # زخرفة الدالة def func(): # إنشاء الدالة print 'Hello!' # استدعاء الدالة func() func() func() func() مُخرجات البرنامج أعلاه ستكون كالتالي: Hello! Function was called 1 times Hello! Function was called 2 times Hello! Function was called 3 times Hello! Function was called 4 times يُمكنك إصلاح الجمل من الناحية اللغوية بإضافة بعض العبارات الشرطية للبرنامج. إنشاء مزخرف لتنفيذ دالة عند تحقق شرط معين فقط يُمكنك أن تستعمل دالة تسجيل الدخول التي قُمنا بإنشائها كمُزخرف للدوال التي تحتاج لأن يكون المُستخدم مُسجلا دخوله. مثلا لنقل بأنّنا نريد أن نعرض على المُستخدم عدة خيارات بعضها يحتاج إلى تسجيل دخول المُستخدم وبعضها لا. الخيارات كالتّالي: تسجيل مُستخدم جديد (تسجيل الدخول غير مطلوب) طباعة جملة عشر مرات ( تسجيل الدخول غير مطلوب) الحصول على الوقت الحالي ( تسجيل الدخول غير مطلوب) طباعة اسم المُستخدم (تسجيل الدخول مطلوب) رؤية معلومات الحساب (تسجيل الدخول مطلوب) تعديل كلمة المرور (تسجيل الدخول مطلوب) مبدأ عمل البرنامج سيكون كالتالي: إنشاء الدوال المسؤولة عن الخيارات عرض الخيارات على المُستخدم زخرفة الدوال التي تطلب تسجيل المُستخدم بمُزخرف تسجيل الدخول المُزخرف سيتحقق من أنّ المُستخدم قد سجل دخوله، إذا كان الأمر كذلك، تنفّذ الدالة وإذا لم يتحقق الشرط فلا تنفذ. لنقل بأنّ اسم مُزخرف التحقق من تسجيل الدخول هو is_user_logged_in، ستكون الدوال التي تطلب تسجيل الدخول مُزَخْرَفَةً كالتالي: @if_user_logged_in def account_info(): print 'Username:', username, 'Password:', password تمارين تمرين 1 أنشئ دالة للجمع بين عددين، وبعدها أنشئ مُزخرفا يقوم بمُضاعفة النتيجة. تمرين 2 أنشئ دالة للحصول على قيم من المُستخدم وقم بزخرفة لطباعة جملة ترحيب قبل استدعاء الدالة وجملة توديع بعد استدعاءها. تمرين 3 أكمل البرنامج الخاص بالمثال الثالث (إنشاء مُزخرف لتنفيذ دالة عند تحقق شرط مُعين فقط). تفاصيل التمرين موجودة بالمثال.
- 4 تعليقات
-
- 5
-
- decorators
- مزخرفات
- (و 4 أكثر)
-
تعرّفنا في مقال سابق على ميزات جديدة في الإصدار ES6 من جافاسكريبت. سنتابع في هذا المقال الحديث عن الميزات الأكثر استخداما من هذا الإصدار وذلك بتناول الإضافات الجديدة التالية: المعاملات المبدئية التفكيك Destructuring. المعاملات المبدئية تتيح هذه الخاصيّة تحديد معاملات افتراضية عند تعريف الدوال. نأخذ مثالاً لتوضيح الفائدة التي نجنيها من هذا الأمر, سنفترض أننا نريد كتابة دالة تطبع اسم عضو في فريق لعبة. إن كتبنا الدالة حسب الطريقة القديمة - قبل الإصدار ES6 - فستكون شبيهة بالتالي: function announcePlayer (firstName, lastName, teamName) { console.log(firstName + ' ' + lastName + ', ' + teamName) } announcePlayer('Stephen', 'Curry', 'Golden State Warriors') // Stephen Curry, Golden State Warriors يبدو الأمر مناسبا للوهلة الأولى؛ لكن ماذا لو أردنا الإعلان عن اسم لاعب لا ينتمي لأي فريق؟ ستكون نتيجة تنفيذ الدالة أعلاه كالتالي: announcePlayer('Zell', 'Liew') // Zell Liew, undefined طبعا undefined ليس اسم فريق. سيكون من المناسب الإشعار بأن اللاعب غير منتمٍ (Unaffiliated) لأي فريق عند عدم تمرير المعامل للدالة: announcePlayer('Zell', 'Liew', 'unaffiliated') // Zell Liew, unaffiliated يمكننا تحسين الشفرة بالتحقق من تمرير المعامل إلى المتغيّر teamName بدلاً من تمرير القيمة unaffiliated في كلّ مرة: function announcePlayer (firstName, lastName, teamName) { if (!teamName) { teamName = 'unaffiliated' } console.log(firstName + ' ' + lastName + ', ' + teamName) } announcePlayer('Zell', 'Liew') // Zell Liew, unaffiliated announcePlayer('Stephen', 'Curry', 'Golden State Warriors') // Stephen Curry, Golden State Warriors يمكن تقليل الأسطُر باستخدام العوامل Ternary operators المنطقية الثلاثية ?: function announcePlayer (firstName, lastName, teamName) { var team = teamName ? teamName : 'unaffiliated' console.log(firstName + ' ' + lastName + ', ' + team) } يمكن بالاعتماد على ميزة المعاملات المبدئية في ES6 إضافة علامة = أمام اسم المعامل عند تعريف الدالة وسيأخذ المعامل تلقائية القيمة المُحدَّدة عند عدم تمرير قيمة له أثناء استدعاء الدالة. يصبح مثالنا السابق عند كتابته حسب صيغة ES6 كالتالي: const announcePlayer = (firstName, lastName, teamName = 'unaffiliated') => { console.log(firstName + ' ' + lastName + ', ' + teamName) } announcePlayer('Zell', 'Liew') // Zell Liew, unaffiliated announcePlayer('Stephen', 'Curry', 'Golden State Warriors') // Stephen Curry, Golden State Warriors لاحظ أن اسم الفريق يصبح unaffiliated عند عدم تمرير المعامل الأخير إلى الدالة. أمر أخير. يمكنك استخدام القيمة المبدئية للمعامل بتمرير undefined يدويا إلى الدالة. تفيد هذه الطريقة إذا كان المعامل الذي تريد استخدام قيمته المبدئية ليس الأخير في معطيات الدالة: announcePlayer('Zell', 'Liew', undefined) // Zell Liew, unaffiliated التفكيك يعدّ التفكيك طريقة مناسبة لاستخراج قيم من المصفوفات Arrays والكائنات Objects. توجد فروق طفيفة بين تفكيك المصفوفات وتفكيك الكائنات. تفكيك الكائنات فلنفترض أن لدينا الكائن التالي: const Zell = { firstName: 'Zell', lastName: 'Liew' } ستحتاج - للحصول على الاسم الشخصي (firstName) والاسم العائلي (lastName) من Zell إلى إنشاء متغيّريْن وإسناد كل قيمة إل متغيّر: let firstName = Zell.firstName // Zell let lastName = Zell.lastName // Liew يتيح تفكيك الكائن إنشاء هذين المتغيّرين وإسنادهما بسطر واحد: let { firstName, lastName } = Zell console.log(firstName) // Zell console.log(lastName) // Liew مالذي يحدُث هنا؟ تطلُب من جافاسكريبت عند إضافة القوسين المعكوفين على النحو الذي رأيناه أثناء تعريف المتغيّرات تطلُب إنشاء المتغيرات المذكورة وإسناد Zell.firstName إلى firstName وZell.lastName إلى lastName. تترجم جافاسكريبت - الإصدار ES6 - الشفرة التالية: let { firstName, lastName } = Zell إلى: let firstName = Zell.firstName let lastName = Zell.lastName إن سبق استخدام اسم المتغيّر فلن يكون باستطاعتنا تعريفه من جديد؛ خصوصا عند استخدام let أو const. الشفرة التالية غير صحيحة: let name = 'Zell Liew' let course = { name: 'JS Fundamentals for Frontend Developers' // ... other properties } // تتسبّب التعليمة التالية في الخطأ Uncaught SyntaxError: Identifier 'name' has already been declared let { name } = course يمكن تفادي الخطأ في الحالات السابقة بإعادة تسمية المتغيّر أثناء تفكيك الكائن باستخدام النقطتين العموديّتين : على النحو التالي: let { name: courseName } = course console.log(courseName) // JS Fundamentals for Frontend Developers يترجم مفسّر الإصدار ES6 التعليمة عند استخدام النقطتين على النحو التالي: let courseName = course.name أمر أخير بخصوص تفكيك الكائنات. عند استخراج خاصيّة غير موجودة في الكائن فإن المتغيّر يأخذ القيمة undefined: let course = { name: 'JS Fundamentals for Frontend Developers' } let { package } = course console.log(package) // undefined هل تذكر المعاملات المبدئية؟ يمكنك استخدامها لاستخراج المتغيّرات كذلك. الصياغة مطابقة لتلك المستخدمة عند تعريف الدوال: let course = { name: 'JS Fundamentals for Frontend Developers' } let { package = 'full course' } = course console.log(package) // full course يمكنك كذلك إعادة تسمية المتغيّرات مع تحديد قيم مبدئية لها: let course = { name: 'JS Fundamentals for Frontend Developers' } let { package: packageName = 'full course' } = course console.log(packageName) // full course تفكيك المصفوفات يشبه تفكيك المصفوفات تفكيك الكائنات. تُستخدَم الأقواس المُربَّعة [] بدلا من {} لاستخراج متغيّرات من المصفوفة. المتغيّر الأول بين الأقواس يأخذ قيمة العنصُر الأول في المصفوفة والمتغيّر الثاني قيمة العنصر الثاني وهكذا. let [one, two] = [1, 2, 3, 4, 5] console.log(one) // 1 console.log(two) // 2 إن حدّدت متغيرات أكثر من عناصر المصفوفة فإن المتغيرات الزائدة تأخذ القيمة undefined: let [one, two, three] = [1, 2] console.log(one) // 1 console.log(two) // 2 console.log(three) // undefined في الغالب نستخرج العناصر التي نحتاجها من المصفوفة فقط. يمكن استخدام الكلمة المفتاحية rest على النحو التالي لاستقبال بقية المصفوفة: let scores = ['98', '95', '93', '90', '87', '85'] let [first, second, third, ...rest] = scores console.log(first) // 98 console.log(second) // 95 console.log(third) // 93 console.log(rest) // [90, 87, 85] سنخصّص جزءًا من هذا المقال للحديث عن العامل rest، ولكن قبل ذلك سنتحدّث عن ميزة خاصّة عند تفكيك المصفوفات وهي مبادلة المتغيّرات Swapping variables. فلنفترض أن لدينا متغيّريْن a وb: let a = 2 let b = 3 نريد مبادلة هذين المتغيّرين بحيث تكون قيمة a تساوي 3 وقيمة b تساوي 2. نحتاج - في الإصدار ES5 - إلى استخدام متغيّر ظرفي لإكمال المبادلة: let a = 2 let b = 3 let temp // المبادلة temp = a // temp = 2 a = b // a = 3 b = temp // b = 2 فلنر الآن كيفية المبادلة في ES6 بتفكيك المصفوفات: let a = 2 let b = 3; // نحتاج لنقطة فاصلة هنا لأن السطر الموالي يبدأ بقوس معكوف مربَّع // المبادلة باستخدام ميزة تفكيك المصفوفات [a, b] = [b, a] console.log(a) // 3 console.log(b) // 2 تفكيك المصفوفات والكائنات في الدوال أروع ما في التفكيك إمكانيةُ استخدامه في أي مكان تريده. حتى إن بإمكانك تفكيك المصفوفات والكائنات في الدوال. فلنفترض أن لدينا دالة تأخذ مصفوفة من النتائج وتعيد كائنا بالنتائج الثلاث الأعلى. تشبه الدالة التالية ما فعلناه عند تفكيك المصفوفات السابقة: ملحوظة: ليس ضروريا استخدام الدوال السهمية للاستفادة من ميزات ES6 الأخرى. function topThree (scores) { let [first, second, third] = scores return { first: first, second: second, third: third } } توجد طريقة بديلة لكتابة الدالة أعلاه وهي تفكيك المصفوفة أثناء تعريف الدالة. سنقلّل عدد الأسطُر في هذه الحالة كما أننا نعرف أن المعطى المُمرَّر لنا مصفوفة. function topThree ([first, second, third]) { return { first: first, second: second, third: third } } سنرى الآن تفصيلا صغيرا. بما أننا نستطيع الجمع بين المعاملات المبدئية والتفكيك أثناء تعريف الدوال.. فما هي نتيجة الشفرة التالية: function sayMyName ({ firstName = 'Zell', lastName = 'Liew' } = {}) { console.log(firstName + ' ' + lastName) } الأمر معقَّد قليل إذ أننا جمعنا ميزات عدّة في آن. أولا؛ نرى أن الدالة تأخذ معطى واحدا، وهو كائن اختياري تكون قميته {} عند عدم تحديد قيمة. ثانيًّا، نحاول تفكيك الكائن واستخراج المتغيرين firstName وlastName منه واستخدامهما إن وُجدا. أخيرا؛ عندما لا يُعيَّن المتغيران firstName وlastName في الكائن المُمرَّر فإننا نحدّد قيمتيهما بـ Zell وLiew على التوالي. تعطي الدالة النتائج التالية: sayMyName() // Zell Liew sayMyName({firstName: 'Zell'}) // Zell Liew sayMyName({firstName: 'Vincy', lastName: 'Zhang'}) // Vincy Zhang سنتعرّف في مقال لاحق على ميزات أخرى جديدة في الإصدار ES6. ترجمة - بتصرّف - للمقال Introduction to commonly used ES6 features لصاحبه Zell.