البرمجة بلغة بايثون (الفصل السابع)
- أبريل 12, 2023
- تم النشر بواسطة: كود خانة
- الفئة: البرمجة بلغة بايثون
انشاء الوظائف (Functions):
في بداية هذه الدورة تعلمنا كيفية استخدام الوظائف المبنية داخل بايثون مثل ()max وايضاً تعلمنا انه بأمكاننا استيراد المكتبات التي توفر لنا العديد من الوظائف المهمة مثل math ولكن في كثير من الاحيان نحتاج الى انشاء وظائفنا الخاصة بأنفسنا مثلا انشاء وظيفة تقوم بعدة مهام نحن نريدها لسبب ما مهما كان نوع هذه المهام وعلى سبيل المثال نريد انشاء وظيفة تأخذ مدخلين وتقوم بتربيع كل واحد منهم ثم تقوم بجمعهم معاً ثم تقسيمهم على اثنان ثم اضافة عشرة للناتج (الفكره هي اننا نستطيع انشاء وظيفه خاصه تؤدي مهمه خاصه نحن نحتاجها لسبب ما)
والامر المهم الاخر الذي يدعونا الى انشاء الوظائف داخل بايثون هو الاختصار وعدم اعادة كتابة الكود في البرنامج في كل مرة نحتاجه ولتوضيح ذلك تخيل انك تعمل على مشروع كبير يحتوي على مئات السطور البرمجية وفي هذا المشروع نحتاج الى كتابة كود يؤدي مهمة معينة تقوم بدور معين مثلا for loop يحتوي على عدة شروط داخلية وللقيام بهذه المهمة نحتاج الى كتابة مثلاً عشر سطور برمجية، هنا يأتي الدور الكبير للوظائف لانه من غير المعقول ان نقوم بكتابة هذه العشر سطور في كل مرة نحتاج فيها الى القيام بهذه المهمة داخل البرنامج ولكن بأمكاننا خلق وظيفة وتسميتها بأسم معين وكتابة هذه العشر سطور داخل هذه الوظيفة حيث لو احتجنا في البرنامج لاحقا الى القيام بهذه المهمة كل ماعلينا فعله هو كتابة اسم هذه الوظيفة وهذه الوظيفة ستقوم بهذه المهمة المعينة التي انشأت من اجلها
من اجل خلق وظيفة خاصة نحتاج الى سبعة اشياء بسيطة وهي:
1- من اجل تعريف الوظيفة نكتب def وهي مختصر لكلمة definition
2- ثم نكتب الاسم الذي نريده للوظيفة
3- المدخلات التي تأخذها هذه الوظيفة حيث من الممكن ان لا تأخذ اي مدخل ومن الممكن ان تأخذ مدخل واحد او عدة مدخلات (المدخلات قد تكون ارقام او نصوص او قوائم او اي نوع اخر من البيانات)
4- النقتطتين : وتأتي بعد اسم الوظيفة
5- ثم مسافة كما هو الحال في الشروط واللوب
6- ونكتب بلوك الكود حيث يحتوي على كود المهمة التي ستقوم بها هذه الوظيفة
7- كلمة return وتعني ارجع حيث تحتوي على القيمة التي سترجعها هذه الوظيفة عند ذكر هذه الوظيفة او عند طباعة هذه الوظيفة
لتوضيح كل ماتحدثنا عنه لنفترض اننا نريد انشاء وظيفة نريد تسميتها multiply تأخذ مدخلين a,b ونريد ان ترجع هذه الوظيفة حاصل ضرب المدخلين ببعضهما وكما في الصورة التالية
الان من اجل استخدام هذه الوظيفه كل ما علينا فعله هو نداء هذه الوظيفة بأسمها multiply ثم اعطاء مدخلات لهذه الوظيفه
مثلاً لنفترض اننا نريد ان نجعل مدخلات هذه الوظيفة 4 و 5 وسنلاحظ في الناتج اننا حصلنا على ناتج ضرب هذين الرقمين ببعضهما أي بمعنى قامت الوظيفه multiply بأداء دورها بشكل صحيح
1 2 3 4 5 6 |
# Create multiply function def multiply(a,b): c = a * b return c multiply(4,5) |
1 |
20 |
ايضاً نستطيع ان نقوم بأنشاء نفس الوظيفه ولكن بشكل مختصر كما في الكود التالي
1 2 |
def multiply(a,b): return a*b |
بالنسبه لوظيفة multiply التي قمنا بصناعتها كان دورها هو ضرب رقمين ببعضهما ولذلك ضع في بالك انه يجب ان يكون المدخلين عباره عن رقمين يعني لو كان المدخلين نص سنحصل في الناتج على خطأ Error
1 |
multiply('hi', 'python') |
1 |
TypeError |
تخيل لو كانت المهمة المطلوبة تحتاج الى عدة سطور برمجية حيث ستوفر لنا صناعة وظيفة خاصة الكثير من الوقت والجهد لأنه سنحتاج الى كتابة هذه السطور البرمجية التي تؤدي المهمة المطلوبة مرة واحدة من خلال كتابتها داخل وظيفة خاصة وتسميتها بأسم خاص ونستدعيها في اي مكان في البرنامج متى ما احتجنا لها دون الحاجة لأعادة كتابة السطور البرمجية التي تؤدي هذه المهمة مرة اخرى لان الوظيفة الخاصة تحتوي بداخلها اصلا على هذه السطور التي تؤدي هذه المهمة
ولأن الوظائف الخاصة مهمة جدا في لغة بايثون سنأخذ مثال اخر عليها من اجل استيعابها اكثر ولنفترض اننا نريد انشاء وظيفه اسمها my_abs تأخذ مدخل واحد عبارة عن رقم ثم تقوم هذه الوظيفة بأرجاع القيمة المطلقة لهذا الرقم يعني لو كان المدخل 6- سترجع لنا الوظيفة القيمة المطلقة له وهي 6 واذا كان المدخل اصلا موجب مثلا 4 سترجعه نفسه 4
1 2 3 4 5 |
def my_abs(num): if num < 0: return -num # to change from negative to positive else: return num |
الان لو قمنا بأستدعاء هذه الوظيفه مع رقم سالب سوف نحصل في الناتج على القيمه المطلقه لهذا الرقم
1 |
my_abs(-2) |
1 |
2 |
ولو قمنا بأستدعاء هذه الوظيفه مع رقم موجب سوف نحصل في الناتج على القيمه المطلقه لهذا الرقم
1 |
my_abs(9) |
1 |
9 |
ايضاً نستطيع خزن ناتج هذه الوظيفه في متغير ثم نستطيع طباعة قيمة هذا المتغير كما في الكود التالي
1 2 |
x = my_abs(-12) print(x) |
1 |
12 |
مساحة تجريبية:
تمرين برمجي (1):
في هذا التمرين المطلوب منك هو ان تنشئ وظيفة اسمها max_min_first_last تأخذ مدخل واحد عبارة عن قائمة تحتوي عدة ارقام وهي القائمة التالية
1 |
num_list = [10,50,30,12,6,8,100] |
وترجع لنا هذه الوظيفة عند استخدامها اربع قيم وهي اكبر رقم في القائمة واصغر رقم في القائمة واول رقم في القائمة واخر رقم في القائمة
num_list = [10,50,30,12,6,8,100]
def max_min_first_last(nlist):
____________________ # Maximum number
____________________ # Minimum number
____________________ # First number
____________________ # Last number
return _____________________________________
print( max_min_first_last(num_list) )
num_list = [10,50,30,12,6,8,100]
def max_min_first_last(nlist):
max_num = max(nlist) # Maximum number
min_num = min(nlist) # Minimum number
first_num = nlist[0] # First number
last_num = nlist[-1] # Last number
return max_num, min_num, first_num, last_num
print( max_min_first_last(num_list) )
Ex().has_equal_ast(exact=False)
success_msg("اجابة صحيحة، احسنت")
– من اجل استخراج اكبر قيمة في القائمة استخدم الوظيفة max مع القائمه
– من اجل استخراج اصغر قيمة في القائمة استخدم الوظيفة min مع القائمه
– من اجل استخراج اول قيمة في القائمة استخدم الاندكس الاول مع القائمه
– من اجل استخراج اخر قيمة في القائمة استخدم الاندكس العكسي مع القائمه
– اجعل الوظيفة max_min_first_last ترجع لنا اربعة قيم وهي max_num & min_num & first_num & last_num
المدخلات الافتراضية للوظائف:
في بعض الاحيان نحتاج الى اعطاء قيمة افتراضيه لمدخلات الوظيفة التي نريد صناعتها يعني في حال عدم ذكر قيمة هذا المدخل ستأخذ الوظيفة القيمة الافتراضية التي وضعناها لهذا المدخل عند انشاء الوظيفة
ومثال على ذلك لنفترض اننا نريد انشاء وظيفة تحسب لنا معدل الدرجات للطلبه اسمها student_avg حيث تأخذ هذه الوظيفة اربعة مدخلات وهي درجة الرياضيات والتاريخ واللغه الانجليزيه واللغه العربيه ونريد ان نجعل قيمة اللغه العربيه تساوي 100 افتراضياً يعني في حال عدم اعطاء قيمة لمادة اللغة العربية في الوظيفة ستأخذ مادة اللغه العربيه القيمه 100 اوتوماتيكياً اما في حال اعطاء قيمة لمادة اللغه العربيه فسوف يتم احتساب القيم المدخله الجديده وليس القيمه الافتراضيه وكما ذكرنا دور هذه الوظيفة هو حساب المعدل يعني مجموع المواد تقسيم عدد المواد
والكود التالي يوضح ذلك
1 2 |
def student_avg(mathematics, history, english, arabic=100): return (mathematics + history + english + arabic) / 4 |
مثلاً في الكود التالي سنقوم بأعطاء درجه للمواد الاربعه
1 |
student_avg(90, 80, 90, 50) |
1 |
77.5 |
اما في الكود التالي فسوف نقوم بأعطاء درجات للمواد الثلاث الاولى فقط اما اللغه العربيه فستكون قيمتها افتراضياً 100
1 |
student_avg(90, 80, 90) |
1 |
90.0 |
تمرين برمجي (2):
قم بكتابة وظيفة اجعل اسمها Tconverter تقوم بتحويل درجة الحرارة من سيلزية الى فهرنهايت حيث تأخذ هذه الوظيفة مدخل واحد وهو درجة الحرارة السيلزية وترجع لنا قيمة واحدة وهي درجة الحرارة بالفهرنهايت وللمساعدة حاول ان تستفاد من المعادله الرياضيه التاليه
1 |
celsius * 1.8 = fahrenheit - 32 |
ثم قم بتحويل درجة الحرارة السيلزية التالية celsius = 37.5 الى فهرنهايت بأستخدام الوظيفة الجديده Tconverter
celsius = 37.5
# Create Tconverter function
def Tconverter(celsius):
_________________________________
return __________
# Convert celsius = 37.5 to fahrenheit using Tconverter
print( Tconverter(celsius) )
celsius = 37.5
# Create Tconverter function
def Tconverter(celsius):
fahrenheit = (celsius * 1.8) + 32
return fahrenheit
# Convert celsius = 37.5 to fahrenheit using Tconverter
print( Tconverter(celsius) )
Ex().has_equal_ast(exact=False)
success_msg("اجابة صحيحة، احسنت")
– اجعل قيمة المتغير fahrenheit تساوي المعادله الرياضيه بعد التحويل (celsius * 1.8) + 32
– اجعل الوظيفه ترجع المتغير fahrenheit
انشاء الكلاس والاوبجكت (Class and Object):
لغة بايثون هي لغة كائنية التوجه Object Oriented Programming ومختصرها OOP حيث يعتبر كل شيء داخل لغة بايثون عبارة عن كائن وقد ذكرنا هذا في درس سابق فالارقام الصحيحة والكسرية والنصوص والقوائم وكل شيء اخر هو عبارة عن اوبجكت ولكل نوع من هذه الاوبجكت يوجد صفات وخصائص تميزه عن الانواع الاخرى ومن ميزات اللغات الكائنية التوجه انه بألامكان وراثة هذه الصفات والخصائص
في هذه الدورة لن نتعمق كثيراً في هذا الموضوع ولكن سنتعلم الاساس والاكثر اهمية حيث سنتعلم كيفية انشاء كلاس وثم كيف ننشئ اوبجكت من هذا الكلاس ثم كيف نستخدمه ونورث كل صفاته وخصائصه
- في البداية ماهو الكلاس؟ الكلاس هو اشبه بالصندوق الذي يحتوي على وظيفة او عدة وظائف بداخله حيث بأمكاننا استخدام اي وظيفة او اي شيء من داخل الكلاس ولكن بعد تحويله الى اوبجكت
- وفي دروس سابقة من هذه الدورة تعلمنا انه الوظائف والمثود هي متشابهة جدا حيث كلاهما عبارة عن كود يؤدي وظيفة ودور معين ولكن الفرق هو ان المثود عبارة عن وظائف داخلية تستدعى من داخل الاوبجكت مثلا لدينا الاوبجكت ‘s = ‘hello عبارة عن متغير نصي بأمكاننا استدعاء من داخله المثود ()s.upper التي تحول جميع حروف هذا المتغير الى كبيرة وايضا تعلمنا هناك وظائف منفصلة ليست داخلية مثل المثود بل خارجية والتي نستدعيها على الاوبجكت ، مثلا لدينا الاوبجكت [x = [1, 2, 5 عبارة عن قائمة وبأمكاننا استدعاء الوظيفة (max(x عليها والتي ستعطينا اكبر رقم في القائمة ، ايضا الوظائف التي تعلمناها في بدايه هذا الدرس تعتبر وظائف منفصلة بأمكاننا استدعائها على الاوبجكت
- في الكلاس سوف ننشئ وظائف داخل الكلاس ثم سوف نحول الكلاس لاحقاً الى اوبجكت ثم سوف نستدعي الوظائف التي انشأناها في داخل الكلاس من داخل الاوبجكت وبما اننا سنستدعي الوظائف من داخل الاوبجكت هذا يعني ان هذه الوظائف اصبحت مثود لانها داخلية وتم استدعائها من داخل الاوبجكت وسنشرح الان كل هذا بالتفصيل مع الامثلة
مثال: لنفترض اننا نريد انشاء كلاس يؤدي اربعة مهام (جمع وطرح وضرب وقسمه) وهذا الكلاس سوف نجعل اسمه sum_sub_mul_div وسنجعل هذا الكلاس يحتوي بداخله على اربعة وظائف مشابهة للتي تعلمناها في بداية هذا الدرس حيث الوظيفة الاولى للجمع تأخذ قيمتين وترجع ناتج جمعهما والثانيه للطرح والثالثه للضرب والرابعه للقسمه جميع هذه الوظائف سنقوم بأنشأها داخل كلاس واحد وكما ذكرنا في البدايه ( الكلاس كأنه صندوق يحتوي بداخله عدة وظائف ) وايضا من الممكن ان يحتوي على متغيرات بداخله مثل المتغير الذي سنقوم بأنشائه واسمه var
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
class sum_sub_mul_div: var = 'math' def sum(self, a, b): self.c = a + b return self.c def sub(self, a, b): self.s = a - b return self.s def mul(self, a, b): self.m = a * b return self.m def div(self, a, b): self.d = a / b return self.d |
بعدها حتى نستطيع استخدام وظائف هذا الكلاس يجب ان نحوله الى كائن او اوبجكت ونستطيع القيام بهذه المهمه بكل سهوله فقط من خلال خزن الكلاس في متغير وتسميته اي اسم
1 |
ssmd = sum_sub_mul_div() |
الان بعد ان حولناه الى اوبجكت بأمكاننا الان استخدام اي وظيفة (مثود) من داخله وبكل بساطه او استدعاء اي متغير موجود على مستوى الكلاس مثل var فمثلاً نستطيع استدعاء وظيفة الجمع sum من داخلا الاوبجكت ssmd لمعرفة ناتج جمع اي رقمين
1 2 |
# call sum function ssmd.sum(10,2) |
1 |
12 |
او نستطيع استدعاء وظيفة الطرح sub من داخلا الاوبجكت ssmd لمعرفة ناتج طرح اي رقمين
1 2 |
# call sub function ssmd.sub(10,2) |
1 |
8 |
او نستطيع استدعاء وظيفة الضرب mul من داخلا الاوبجكت ssmd لمعرفة ناتج ضرب اي رقمين
1 2 |
# call mul function ssmd.mul(10,2) |
1 |
20 |
او نستطيع استدعاء وظيفة القسمه div من داخلا الاوبجكت ssmd لمعرفة ناتج قسمة اي رقمين
1 2 |
# call sum function ssmd.div(10,2) |
1 |
5.0 |
وايضاً نستطيع استدعاء المتغير var من داخل الاوبجكت ssmd
1 2 |
# call variable ssmd.var |
1 |
'math' |
ومن المؤكد انك تتسائل الان ماهي self الموجوده كمدخل في كل وظيفه داخل الكلاس وموجوده قبل كل متغير ننشأه داخل الكلاس
self وظيفتها هي تهيئة مكان في الذاكره ولاتشغل بالك بها كثيرا ولكن تذكر دائما ان تستخدمها في داخل الكلاس اما خارج الكلاس في الوظائف المنفصله مثل التي تعلمناها في بداية هذا الدرس فنحن لانحتاج الى self ابداً فقط في داخل الكلاس
مراجعة:
- الكلاس عبارة عن صندوق نضع بداخله الوظائف والمتغيرات التي نحتاجها
- نخزن الكلاس في متغير من اجل تحويله الى اوبجكت
- نقوم بأستدعاء وظائف الكلاس التي نحتاجها من داخل الاوبجكت
تهيئة مدخلات الكلاس:
ملاحظة: في هذا الدرس سنتعمق اكثر في الكلاس والاوبجكت وقد تواجه بعض الصعوبة في فهم كل شيء من اول مرة ولكن لا تقلق لان الامور ستصبح اسهل بكثير بعد التكرار والممارسة
- تعلمنا قبل قليل كيف نقوم بأنشاء الكلاس sum_sub_mul_div
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
class sum_sub_mul_div: var = 'math' def sum(self, a, b): self.c = a + b return self.c def sub(self, a, b): self.s = a - b return self.s def mul(self, a, b): self.m = a * b return self.m def div(self, a, b): self.d = a / b return self.d |
- ثم قمنا بتحويل الكلاس الى اوبجكت من خلال خزنه في المتغير ssmd
1 |
ssmd = sum_sub_mul_div() |
- لكننا لم نجعل اي مدخلات لهذا الكلاس بل تركنا الاقواس فارغة وذلك لاننا لم ننشئ اي معاملات parameters ولم نقم بتهيئة الكلاس لاستقبال اي مدخل وقمنا بتهيئة الوظائف الداخلية (المثود) لاستقبال مدخلات مثلا a,b ولكن في حقيقة الامر نحتاج في اكثر الاوقات الى انشاء مدخلات للكلاس وتهيئة هذه المدخلات بالنسبة للكلاس
- للتوضيح اكثر افترض اننا نريد انشاء كلاس اسمه الموظف Employee ونريد الان اعطاء هذا الكلاس مدخلات ثلاثة وهي الاسم الاول والاسم الاخير والراتب. (يعني ليس كما في المثال السابق بدون مدخلات) وايضا نريد انشاء وظيفتين بسيطة بداخل الكلاس حيث ترجع الوظيفة الاولى الاسم الاول والاخير للموظف بشكل مرتب وترجع الوظيفة الثانية راتب الموظف بشكل مرتب
- في البداية من اجل تهيئة المدخلات لهذا الكلاس نحتاج اولاً الى تعريف وظيفه داخل هذا الكلاس اسمها __init__ وهي مختصر initialization ومن اسمها واضحه حيث غرضها تهيئة الكلاس لاستقبال هذه المدخلات وبالشكل التالي مع استخدام self لاننا داخل الكاس
1 2 3 4 5 6 7 |
class Employee: def __init__(self, first, last, pay): self.first = first self.last = last self.email = first + '.' + last + '@email.com' self.pay = pay |
- وكما هو وضاح في الكود ان الكلاس اصبح جاهز لأستقبال ثلاث مدخلات بالاضافة الى اننا انشأنا متغير اسمه ايميل من خلال الاسم الاول والاخير
- الان لو اردنا انشاء وظائف داخلية داخل هذا الكلاس بأمكاننا استخدام هذه المدخلات الثلاثة داخل هذه الوظائف مباشرة ومن دون اعطاء اي مدخل لهذه الوظائف ومثال على ذلك سوف نخلق الان وظيفتين داخل الكلاس (الوظيفة الاولى الاسم الكامل fullname والثانية الراتب salary ) هاتين الوظيفتين سوف تستخدمان المدخلات الموجودة في داخل الكلاس مباشرةً ومن دون ان تأخذ هذه الوظائف اي مدخل
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
class Employee: def __init__(self, first, last, pay): self.first = first self.last = last self.email = first + '.' + last + '@email.com' self.pay = pay # Create fullname function without inputs and we can use first and last directly def fullname(self): return 'The full name is: {} {}'.format(self.first, self.last) # Create salary function without inputs and we can use pay directly def salary(self): return 'The salary is: {}'.format(self.pay) |
والان حتى نقوم بتجربة الكلاس الذي قمنا بصناعته سوف نقوم بخلق كائنين الاول سوه نسميه emp_1 وسنعطيه ثلاث مدخلات (الاسم الاول والاخير والراتب) وبنفس الطريقه سوف نصنع متغير ثاني سوف نسميه emp_2
1 2 3 |
# Create 2 objects emp_1 = Employee('Ahmed', 'Talal', 50000) emp_2 = Employee('Yasser', 'Ali', 60000) |
الان نستطيع استخدام اي وظيفه موجوده داخل الاوبجكت emp_1 كما في الكود التالي
1 2 3 |
# Use fullname & salary methods without inputs print( emp_1.fullname() ) print( emp_1.salary() ) |
1 2 |
The full name is: Ahmed Talal The salary is: 50000 |
وكذلك الحال بالنسبة للاوبجكت الثاني emp_2
1 2 3 |
# Use fullname & salary methods without inputs print(emp_2.fullname()) print(emp_2.salary()) |
1 2 |
The full name is: Yasser Ali The salary is: 60000 |
تمرين برمجي (3):
لدينا الكلاس Vehicle الذي يتكون من وظيفتين ، الوظيفه الاولى هي وظيفة التهيئة __init__ وتأخذ ثلاث مدخلات وهي اسم العربه ولونها وسعرها والوظيفه الثانيه هي وظيفة الوصف description حيث تقوم هذه الوظيفه بأرجاع وصف العربه بشكل مرتب
1 2 3 4 5 6 7 8 9 |
class Vehicle: def __init__(self, name, color, price): self.name = name self.color = color self.price = price def description(self): return 'The name of car is: {} the color is: {} the price is: {}'.format(self.name, self.color, self.price) |
حاول ان تفهم هذا الكلاس البسيط وطريقة بنائه ثم قم بالتالي:
- انشئ اوبجكت من كلاس Vehicle سميه car1 تكون مدخلاته اسم السيارة BMW ولونها احمر Red وسعرها 40000 ثم اطبع وصف هذا الاوبجكت بأستخدام المثود description
- انشئ اوبجكت ثاني من كلاس Vehicle سميه car2 تكون مدخلاته اسم السيارة Mercedes ولونها ابيض White وسعرها 50000 ثم اطبع وصف هذا الاوبجكت بأستخدام المثود description
# define the Vehicle class
class Vehicle:
def __init__(self, name, color, price):
self.name = name
self.color = color
self.price = price
def description(self):
return 'Car name: {} Color: {} Price: {}'.format(self.name, self.color, self.price)
# Create car1 object and print out the description
___________________________________
___________________________________
# Create car2 object and print out the description
___________________________________
___________________________________
# define the Vehicle class
class Vehicle:
def __init__(self, name, color, price):
self.name = name
self.color = color
self.price = price
def description(self):
return 'Car name: {} Color: {} Price: {}'.format(self.name, self.color, self.price)
# Create car1 object and print out the description
car1 = Vehicle('BMW', 'Red', 40000)
print(car1.description())
# Create car2 object and print out the description
car2 = Vehicle('Mercedes', 'White', 50000)
print(car2.description())
Ex().has_equal_ast(exact=False)
success_msg("اجابة صحيحة، احسنت")