ابحث في المدونة

الأربعاء، 18 مارس 2020

لنصمم برنامج لحساب المتوسط الحسابي بلغة البايثون

بسم الله الرحمن الرحيم.
السلام عليكم ورحمة الله وبركاته.
أعزاءنا الكرام في كل مكان .. أهلًا ومرحبًا بكم وأسعد الله أوقاتكم بكل خير.

ها أنا أعود إليكم مع فكرة جديدة لنطبقها سويًا بلغة البايثون.
وكما أشرت سابقًا ؛ فقد لا تكون البرامج التي نكتبها ذات فائدة كبيرة للمستخدم العادي , وإنما هي أفكار نجربها معًا لترسيخ المفاهيم الأساسية في البرمجة واكتساب مهارة حل المشكلات البرمجية.

فكرة البرنامج الذي سنعمل على كتابة أكواده اليوم هي عداد للمتوسط الحسابي لمجموعة من القيم الرقمية.
هذا البرنامج سيعمل بصورة لا نهائية , أي أنه سيأخذ رقم من المستخدم , ويجمعه مع الأرقام السابقة , ثم يعرض المتوسط الحسابي للأرقام المدخلة
بعد ذلك يعيد الكرة ويطلب من المستخدم إدخال رقمًأ آخر ويعرض له المتوسط الحسابي مع الرقم الجديد ... وهكذا إلى أن يقوم المستخدم بالخروج من البرنامج.
سنراعي في الكود الذي سنكتبه الأخطاء التي قد يرتكبها مستخدم البرنامج كأن يقوم بإدخال حروف عوضًأ عن الأرقام , أو أن لا يدخل أي قيمة.

الكود:


containor = []
while 1:
    txt = input("أدخل رقمًا: ")
    try:
        txt = int(txt)
        containor.append(txt)
    except ValueError:
        pass
    try:
        print("لقد أدخلت إلى الآن القيم التالية: {} \n المتوسط الحسابي لها هو : {}\n مجموع القيم المدخلة هي: {} \n إجمالي عدد القيم المدخلة هو: {}".format(", ".join([str(i) for i in containor]),sum(containor)/len(containor),sum(containor),len(containor)))
    except ZeroDivisionError:
        print("لا توجد أي قيم مدخلة أو أن القيمة ليست رقمًا")

الشرح:


كما تلاحظون ؛ فإن السطر الأول من الكود هو عبارة عن تعريف لمتغير جديد أُسندت إليه قائمة فارغة.
سنستخدم هذه القائمة لاحقًأ لحفظ القيم المدخلة من قبل المستخدم


السطر الثاني:
while 1:

هذا السطر يمثل كود لبدء الحلقة while , والجدير بالذكر أن استخدامنا للرقم 1 فقط بعد while يدل على أن هذه الحلقة غير محدودة وغير مقيدة بشرط , أي أنها حلقة لا نهائية , فكلما انتهى تنفيذ الأوامر التي بداخلها تعيد الكرة مرة أخرى بصفة غير نهائية.
السبب من استخدامنا لهذا الأسلوب هو أننا لا نعلم عدد القيم التي سيعمد المستخدم إلى إدخالها, لذلك ؛ تركنا له الفرصة مفتوحة ليدخل ما يشاء من أرقام.

السطر الثالث , وتحت جملة while 1 وضعنا 4 مسافات مراعاة لل indentation الذي تستدعيه الجملة while.
وهنا أنشأنا متغيرًًا باسم txt يأخذ الرقم الذي سيدخله المستخدم عبر لوحة المفاتيح , وقد استخدمنا الدالة input للقيام بذلك
لكن مهلًا:
أليست جميع القيم المدخلة عن طريق ال function input عبارة عن نصوص فقط؟
بَلا بَلا
إذًا كيف نحسب المتوسط الحسابي والبيانات التي عندنا هي عبارة عن نصوص
قد يقول قائل : ماذا إن أدخل المستخدم أرقامًا
الجواب : هي من وجهة نظرنا أرقام , لكن من وجهة نظر مفسر بايثون أنه طالما كان النص مدخلًا عن طريق الدالة input ؛ فهي عبارة عن نصوص وإن احتوت على أرقام بل وإن كانت كلها أرقام.

ما الحل إذًا ؟
الحل , وكما تلاحظونه مكتوبًًا عندكم في الكود , هو استخدام الجملة try , أي بمعنى جرب الأمر التالي
السطر الذي يليه يستوجب وضع 8 مسافات , 4 منها عبارة عن indentation للجملة while , والأربع الأخرى هي للجملة try
        txt = int(txt)
وهنا نحن نقول لبايثون أن يجرب تحويل النص المدخل إلى صيغة الآرقام integers ووضع تلك الأرقام في المتغير txt
        containor.append(txt)
بعدها طلبنا منه إدراج الرقم في القائمة التي أسميناها containor
كلا الأمرين السابقين يندرجان تحت جملة try الخاصة بالتجربة

    except ValueError:
الإخوة الكرام , الجملة السابقة هي عبارة عن جملة لاستثناء الخطأ الذي قد يحدث في حال لو فشلت عملية تحويل النص إلى رقم , وفي العادة يحدث ذلك الخطأ لو أن المستخدم قام بإدخال حروف عوضًا عن الأرقام أو أنه ضغط على زر الإدخال enter دون كتابة أي شيء.
وفي الحقيقة لو أننا لم نكتب جملة الاستثناء هذه لتوقف البرنامج وخرج من فوره في حال حدث ذلكم الخطأ المذكور.
انتبه عزيزي القارئ إلى أنه ينبغي كتابة أمر تحت جملة except ليقوم البرنامج بتنفيذه في حال حدوث الخطأ المحدد.

وقد كتبت الأمر pass كأمر يتم تنفيذه لو وقع الخطأ المذكور
تجدر الإشارة إلى أن الكلمة pass في بايثون تعني "لا تقم بأي شيء".

انتهينا الآن من إدراج الرقم إلى القائمة الحاوية containor , بقي الآن أن نكتب العمليات الحسابية وأمر الطباعة
ارتأيت أن أدمج الأمرين في كود واحد.



انتبه:
كما نعلم جميعًا أن المعادلة الرياضية المعروفة لحساب المتوسط الحسابي تقول:
المتوسط الحسابي = مجموع القيم / عدد القيم

هنا يوجد احتمال ظهور مشكلة من شأنها إيقاف برنامجنا عن العمل ,
وهي أن لا يقوم المستخدم بإدخال أي قيم , وبالتالي عندما نستخدم المعادلة الرياضية المذكورة فسيحدث خطأ رياضي فادح لا يمكن لبايثون أن يقبله
عزيزي القارئ, يعتَبر بايثون القسمة على 0 خطأًا يستوجب إيقاف البرنامج عن العمل.
لذلك , ومن أجل أن نتفادى وقوع هذا الخطأ, فسنستخدم جملة try مرة أخرى
    try:

        print("لقد أدخلت إلى الآن القيم التالية: {} \n المتوسط الحسابي لها هو : {}\n مجموع القيم المدخلة هي: {} \n إجمالي عدد القيم المدخلة هو: {}".format(", ".join([str(i) for i in containor]),sum(containor)/len(containor),sum(containor),len(containor)))
هذه هي دالة الطباعة على الشاشة التي نعرفها جميعًا, غير أن محتواها يبدو غريبًا بعض الشيء.
لا تقلقوا , فكل ذلك سيُشرَح بإذن الله.
لقد وضعنا داخل الدالة print علامة تنصيص تفيد ببداية محتوى نصي
أول ما كتبنا فيه الجملة التالية
لقد أدخلت إلى الآن القيم التالية:
بعد ذلك وضعنا قوسين متعرجين بهذا الشكل
{}

هذين القوسين إخوتي الكرام يمثل مساحة محجوزة لعرض محتوى غير معروف من قبل المبرمج , أي أنه سيتم التعويض عنه لاحقًا
بعد القوسين المتعرجين كتبنا التالي
\n
يوضَع الرمز السابق لفصل الجمل بحيث تكون الجملة التي قبلها في سطر والتي بعدها في سطر آخر

لقد كررنا هذه العملية 4 مرات ,
كتبنا جملة ووضعنا مكانًأ محجوزًا وأخذنا سطرًا جديدًاوأخيرًأ أغلقنا علامة التنصيص.
 لننتبه قليلًا من مسألة ترتيب الأقواس المتعرجة
القوس الأول عبارة عن مكان ستعوض فيه القيم المكتوبة من قبل المستخدم
الحيز الثاني سيعوض فيه ناتج المتوسط الحسابي
أما الحيز الثالث فسيعوض بمجموع القيم المدخلة
والحيز الأخير سيكتب مكانه عدد القيم المدخلة

كيف نقوم بالتعويض؟

تستخدم الدالة format للتعويض عن أماكن الأقواس المزخرفة داخل النصوص
حيث تكتب الدالة مفصولة عن النص المراد تنسيقه بعلامة النقطة , ثم تُكتَب القيم المراد تعويضها كمعاملات للدالة format بحيث يتم الفصل بين كل قيمة وأخرى بعلامة الفاصلة , وتراعى فيها مسألة ترتيب الأقواس.
في حالتنا هذه سنعوض عن المكان الأول بالقيم المدخلة
إذًا , المعامل الأول للدالة format سيكون الأمر التالي:

", ".join([str(i) for i in containor])
هذا الكود يقوم بتحويل القوائم في بايثون إلى نص عادي ويقوم بفصل كل عنصر وآخر بعلامة الفاصلة
ومنعًا للإطالة ؛ لن أفصل في شرح الكود.

المعامل الثاني هو المتوسط الحسابي , وقد حسبناه بهذه الطريقة
sum(containor)/len(containor)
كما تعلمون فإن جميع القيم المدخلة قد قمنا بتخزينها في القائمة containor
هناك دالة في بايثون تستخدم لجمع القيم العددية داخل القوائم
هذه الدالة اسمها sum
كتبنا الدالة sum ومررنا القائمة containor كمعامل لها
ثم قسمنا الناتج الذي أرجعته الدالة sum بدالة أخرى تسمى len  وأيضًا مررنا القائمة containor كمعامل للدالة
والحقيقة أن الدالة len تستخدم لحساب عدد العناصر داخل القائمة
إذًا نحن حققنا المعادلة الرياضية التي تقول أن المتوسط الحسابي = مجموع القيم sum(containor) / عدد القيم len(containor)

المعامل الثالث هو حساب المجموع فقط
sum(containor)
وقد علمنا سابقًا أن الدالة sum تستخدم لجمع العناصر الرقمية داخل القوائم , وهنا لم نحتج إلى تقسيم المجموع لأننا نريده هو بنفسه ولا نريد المتوسط

المعامل الأخير هو حساب عدد القيم الموجودة
len(containor)
وقد علمنا أيضًأ أن الدالة len تستخدم لإرجاع عدد قيم القائمة.

كل ما سبق بما فيه دالة format بمعاملاتها كان عبارة عن معامل لدالة الطباعة print
وبما أن جملة الطباعة اندرجة تحت جملة try فإذًا لا بد من وضع استثناء لخطأ ما قد يحصل
فسنكتب :
        except ZeroDivisionError:
لاستثناء احتمالية أن يكون عدد القيم 0
وأيضًا لا ننسى وضع أمر يُنفذ في حال وقوع الخطأ , والأمر هنا سيكون إظهار رسالة للمستخدم تعلمه بالخطأ الذي ارتكبه
        print("لا توجد أي قيم مدخلة أو أن القيمة ليست رقمًا")



انتهى الكود.
وانتهت معه مشاركة اليوم , آملًا أن أكون قد وفقت في تقديم المفيد.
مع خالص التحية.

وسائل التواصل



ليست هناك تعليقات:

إرسال تعليق

قل شيئًا