بعد سنوات من ملء الاستمارات والانتظار، حصلت أخيرًا على رخصتك المصرفية. هذا يعني أنك أصبحت الآن مؤهلًا رسميًا لفتح بنكك الخاص، هنيئًا لك!
أولويتك الأولى هي تشغيل أنظمة تقنية المعلومات. وبعد يوم من العمل الشاق، أصبحت قادرًا بالفعل على فتح الحسابات وإغلاقها، وعلى التعامل مع عمليات السحب والإيداع.
ولأنك لم ترغب في تكبّد عناء كتابة الاختبارات، دعوت بعض أصدقائك لمساعدتك في اختبار النظام. لكن بعد خمس دقائق فقط، ادّعى أحد أصدقائك أنه فقد المال! ورغم ثقتك بأن الكود الخاص بك خالٍ من الأخطاء، بدأت تتصفح السجلات للتحقيق.
آه أجل، كما توقعت تمامًا، صديقك هو المخطئ! فقد شارك بيانات اعتماده للاختبار مع صديق آخر، وتآمرا معًا على تنفيذ عمليات إيداع وسحب من الحساب نفسه على التوازي. ومن قد يفعل شيئًا كهذا؟
وبينما تجادل بأنه من المستحيل فعليًا أن يصل أحدهم إلى حسابه على التوازي، يخبرك صديقك بثقة متعالية أن قواعد العمل المصرفي تقتضي أن تدعم ذلك. إذن، لا دعم للعمليات المصرفية المتوازية، ولا إشارة انطلاق. فتُنهِد وتدوّن في ذهنك أن تعمل على هذا غدًا. سيؤخر ذلك تاريخ إطلاقك يومًا آخر على الأقل، ولكن حسنًا...
مهمتك هي تنفيذ حسابات بنكية تدعم الفتح والإغلاق والسحب والإيداع.
بما أن الحسابات البنكية يمكن الوصول إليها بطرق مختلفة (الإنترنت، والهواتف المحمولة، والخصومات التلقائية)، يجب أن يسمح برنامجك البنكي بالوصول إلى الحسابات بأمان من خيوط/عمليات متعددة (تختلف المصطلحات باختلاف لغة البرمجة لديك) في الوقت نفسه. على سبيل المثال، قد تحدث عمليات إيداع وسحب كثيرة في الوقت نفسه؛ عليك أن تضمن عدم وجود حالات تسابق بين قراءة رصيد الحساب وضبط الرصيد الجديد.
يجب أن يكون من الممكن إغلاق الحساب؛ فالعمليات على حساب مُغلق يجب أن تفشل.
لا يدعم Python التزامن "الحقيقي" بسبب قفل المفسّر العام. وبينما يجري العمل على دعم الخيوط الحرة في Python، فإنه لا يزال تجريبيًا. كما أن حلول المكتبة القياسية الحالية مثل multiprocessing وthreading يصعب تطبيقها بالأدوات الحالية للمسار.
نتيجة لذلك، تم استبعاد متطلب التزامن في هذا التمرين. عمليات الحساب تجري بالتتابع على خيط واحد، ولا تُشغَّل أي اختبارات للتزامن أو "لحالة التسابق".
إذا أردت أن تجرّب الخيوط الحرة أو اختبارات التزامن، فنرجو أن تفعل ذلك محليًا. وللمساعدة في تنزيل التمارين والعمل عليها محليًا، ننصح بـواجهة سطر الأوامر الخاصة بـ Exercism.
أحيانًا يلزمك رفع استثناء. وعندما تفعل ذلك، ينبغي أن تُضمّن دائمًا رسالة خطأ ذات معنى توضّح مصدر الخطأ. فهذا يجعل الكود أكثر وضوحًا ويساعد كثيرًا في تنقيح الأخطاء. وفي الحالات التي تعرف فيها أن مصدر الخطأ سيكون من نوع معيّن، يمكنك اختيار رفع أحد أنواع الأخطاء المدمجة، لكن ينبغي أن تُضمّن رسالة ذات معنى على أي حال.
يتطلب هذا التمرين تحديدًا أن تستخدم عبارة raise لـ"إطلاق" ValueError عندما يكون الحساب مفتوحًا أو غير مفتوح، أو عندما تكون مبالغ السحب أو الإيداع غير صحيحة. ولن تنجح الاختبارات إلا إذا نفّذت raise على exception وأرفقت معه رسالة.
ولرفع ValueError مع رسالة، اكتب الرسالة كوسيط لنوع exception:
# account is not open
raise ValueError('account not open')
# account is already open
raise ValueError('account already open')
# incorrect withdrawal/deposit amount
raise ValueError('amount must be greater than 0')
# withdrawal is too big
raise ValueError('amount must be less than balance')
سجّل في Exercism لتتعلّم وتتقن Python عبر 17 مفهومًا146 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.