Треки
/
Python
Python
/
Вправи
/
Банківський рахунок
Банківський рахунок

Банківський рахунок

Середня

Вступ

Після років заповнення форм і очікування ми нарешті отримали банківську ліцензію. Це означає, що тепер ми офіційно маємо право відкрити власний банк, ура!

Наш перший пріоритет - запустити IT-системи й налагодити їхню роботу. Після дня наполегливої праці ми вже можемо відкривати і закривати рахунки, а також обробляти зняття коштів і поповнення рахунку.

Оскільки нам не хотілося писати тести, ми запрошуємо кількох друзів допомогти протестувати систему. Однак уже за пʼять хвилин один із наших друзів заявляє, що втратив гроші! Хоча ми впевнені, що наш код без помилок, ми починаємо гортати логи, щоб розібратися.

Атож, саме як ми й підозрювали, винен наш друг! Він поділився своїми тестовими обліковими даними з іншим другом, і разом вони змовилися робити депозити та знімати кошти з одного рахунку паралельно. Хто б таке зробив?

Поки ми доводимо, що фізично неможливо, щоб хтось отримав доступ до свого рахунку паралельно, наш друг самовдоволено повідомляє, що банківські правила вимагають від нас це підтримувати. Отже, без підтримки паралельної роботи з рахунками не буде й сигналу до запуску. Зітхнувши, ми подумки занотовуємо, що завтра над цим треба попрацювати. Це відсуне дату запуску ще щонайменше на один день, але що ж...

Вказівки

Реалізуйте банківські рахунки, які підтримують відкриття/закриття, зняття та внесення грошей.

Оскільки до банківських рахунків можна отримувати доступ багатьма різними способами (через інтернет, мобільні телефони, автоматичні списання), банківське програмне забезпечення має давати змогу безпечно отримувати доступ до рахунків з багатьох потоків/процесів (термінологія залежить від обраної мови програмування) паралельно. Наприклад, багато внесень і знять можуть відбуватися паралельно; забезпечте, щоб не було станів гонки між читанням балансу рахунку та встановленням нового балансу.

Має бути можливість закрити рахунок; операції із закритим рахунком мають завершуватися помилкою.

Note

Python не підтримує «справжню» конкурентність через глобальне блокування інтерпретатора. Хоча робота над підтримкою вільної багатопотоковості в Python триває, вона все ще експериментальна. Наявні рішення зі стандартної бібліотеки, як-от multiprocessing і threading, складно реалізувати з поточним інструментарієм треку.

Тож вимогу щодо конкурентності для цієї вправи знято. Операції з рахунком виконуються послідовно в одному потоці, і жодних тестів на конкурентність чи «стан гонитви» не запускається.

Якщо хочеться поекспериментувати з вільним багатопотоковим виконанням або тестами на конкурентність, просимо робити це локально. Щоб завантажити вправи й працювати з ними локально, радимо скористатися Exercism CLI.


Повідомлення про винятки

Іноді буває потрібно згенерувати виняток. Коли ми це робимо, варто завжди додати змістовне повідомлення про помилку, щоб указати, у чому джерело помилки. Це робить код зрозумілішим і значно полегшує налагодження. Якщо відомо, що джерело помилки має певний тип, можна згенерувати один із вбудованих типів помилок, але повідомлення все одно має бути змістовним.

У цій вправі потрібно використати інструкцію raise, щоб «кинути» ValueError тоді, коли рахунок відкритий або не відкритий, або коли суми зняття чи поповнення неправильні. Тести пройдуть лише тоді, коли ми і згенеруємо exception через raise, і додамо до нього повідомлення.

Щоб згенерувати 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')
Редагувати через GitHub Посилання відкривається в новому вікні або вкладці
Python Exercism

Час розпочати Банківський рахунок?

Зареєструйтеся на Exercism, щоб вивчати й опановувати Python, а також 17 концепцій146 вправ та справжнє наставництво від людей, і все це безкоштовно.