diff --git a/src/part3/TASK.md b/src/part3/TASK.md index 07c8fc60..e48ecdac 100644 --- a/src/part3/TASK.md +++ b/src/part3/TASK.md @@ -49,6 +49,12 @@ CRUD-операции над ним. Корзина (`cart.py`) в этой ча реализуйте это так, как вы делали в своём решении части 2 (см. [описание части 2](../part2/TASK.md)). +> **Важно.** Тексты, которые функции печатают в stdout или возвращают как +> строку (сообщения об ошибках, таблица хранилища, ответы консоли), в тестах +> проверяются **дословно**: лишний пробел, другой регистр, пропущенная точка или +> перевод строки считаются ошибкой. Берите тексты из описания и примеров как +> есть. + --- ## Модуль `utils.py` @@ -77,14 +83,14 @@ CRUD-операции над ним. Корзина (`cart.py`) в этой ча ### `get_storage_str_representation(storage: list[Product]) -> str` -Отрисовывает всё хранилище одной многострочной строкой — выровненной таблицей, +Отрисовывает всё хранилище одной мультистрокой — выровненной таблицей, пригодной для печати в терминал. «Выровненная» значит, что при печати моноширинным шрифтом все строки таблицы имеют одинаковую длину, а разделители `|` стоят строго друг под другом: значения в каждом столбце начинаются с одной и той же позиции, а ширина столбца подбирается под самое длинное из его значений. Сравните: так выглядит вывод -хранилища, если просто напечатать значения через пробел, — +хранилища, если просто напечатать значения через пробел: ``` ID name price quantity @@ -92,7 +98,7 @@ ID name price quantity 2 nail 2.50 500 ``` -— а так он выглядит после выравнивания: +А так он выглядит после выравнивания: ``` | ID | name | price | quantity | @@ -104,7 +110,7 @@ ID name price quantity Точные правила выравнивания приведены в разделе «Формат» ниже. - **Вход:** `storage` — хранилище товаров. -- **Выход:** многострочная строка (строки соединены `"\n"`, завершающего +- **Выход:** мультистрока (строки соединены `"\n"`, завершающего перевода строки нет): 1. строка заголовков — значения из `TABLE_HEADERS`; @@ -167,7 +173,7 @@ ID name price quantity ### `create_product(storage: list[Product], fields: tuple[str, Decimal, int]) -> int | None` -Порядок проверок (при первой же неудаче хранилище не меняется, печатается +Порядок действий (при первой же неудаче хранилище не меняется, печатается сообщение, возвращается `None`): 1. Имя из `fields` приводится через `normalize_product_name`. Дальше везде — @@ -180,10 +186,11 @@ ID name price quantity идёт по канонической форме, поэтому `" Cordless Drill "` (иной регистр, лишние пробелы по краям и между словами) конфликтует с уже сохранённым `"cordless drill"`. -4. Иначе — как в части 2: идентификатор через `generate_product_id`, цена через - `normalize_price`, кортеж `(идентификатор, нормализованное имя, +4. Иначе — как в части 2: кортеж вида `(идентификатор, нормализованное имя, нормализованная цена, количество)` добавляется в хранилище, возвращается - идентификатор. + идентификатор. Значение идентификатора должно быть сгенерировано + с помощью функции `generate_product_id`, цена нормализована с помощью + функции `normalize_price`. **Примеры.** Каждый пример — отдельный фрагмент скрипта, который начинается с пустого хранилища. В комментариях указано, что функция возвращает или печатает. @@ -231,7 +238,7 @@ print(storage) # [] ### `update_product(storage: list[Product], product_id: int, fields: tuple[str, Decimal, int]) -> Product | None` -Порядок проверок: +Порядок действий: 1. Имя из `fields` приводится через `normalize_product_name`. 2. Если нормализованное имя пустое — печатается сообщение @@ -286,7 +293,9 @@ result = update_product(storage, 1, (" Claw Hammer ", Decimal("85"), 10)) # печатает: product name 'claw hammer' is already taken print(result) # None -print(storage[0]) # (1, 'cordless drill', Decimal('90.00'), 12) +print(storage) +# [(1, 'cordless drill', Decimal('90.00'), 12), +# (2, 'claw hammer', Decimal('9.90'), 40)] ``` Товара с таким идентификатором нет, а пустое имя отвергается раньше, чем @@ -337,6 +346,23 @@ admin> exit количество — это два последних слова строки, а всё между ними — имя товара (поэтому имя может содержать пробелы и не требует кавычек). + Пример текста справки: + + ``` + Available commands: + help show this message + exit leave the console + show print the whole store as a table + create add a product, print its new id + read print the product with that id + update overwrite that product's fields + delete remove the product with that id + + For create and update the price and quantity are the last two words of the + line; everything before them is the product name, so it may contain spaces + (for example "Gibson SG Junior") and needs no quoting. + ``` + ### Разбор команд Команда определяется по строке, разбитой по пробельным символам. @@ -352,10 +378,11 @@ admin> exit | `update <имя...> <цена> <количество>` | перезаписать поля товара; `<имя...>` — одно или больше слов | | `delete ` | удалить товар | -Для `create` и `update` два последних слова строки — это цена и количество, а -всё между глаголом (и, для `update`, идентификатором) и этими двумя словами -склеивается через один пробел в имя товара. Имя обязано быть непустым: `create` -и `update` вообще без слов имени (`create 89.90 12`) командой не считаются. +`<имя...>` может состоять из произвольного количества слов (но не меньше +одного), разделённых пробелами; слова склеиваются через один пробел в имя +товара. Все остальные параметры команд (``, `<цена>`, `<количество>`) — ровно +по одному слову. Поэтому `create` и `update` без слов имени (`create 89.90 12`) +командой не считаются. Разобранные аргументы приводятся к типам: `` и `<количество>` — через `int(...)` (десятичное целое), `<цена>` — через `Decimal(...)`. Получившийся @@ -386,8 +413,8 @@ admin> exit - `create`, `read`, `update`, `delete` — выполняется соответствующая CRUD-операция с разобранными аргументами, её результат выводится на экран (если операция ничего не вернула, не выводится ничего); цикл продолжается; - - строка, которая не подошла ни под одну форму — неизвестный глагол - (`frobnicate ...`) либо известный глагол с неверным числом аргументов + - строка, которая не подошла ни под одну форму — неизвестная команда + (`frobnicate ...`) либо известная команда с неверным числом аргументов (`read 1 2 3`) — печатается сообщение `'<строка>' is not a command`; хранилище не меняется; вернуть `True`. @@ -424,7 +451,7 @@ python -m src.part3.run_admin ``` После запуска появится приглашение `admin> `. Введите `help`, чтобы увидеть -список команд (после того как вы реализуете `HELP_TEXT`), и `exit`, чтобы +список команд (после того как вы реализуете `show_help()`), и `exit`, чтобы выйти. Хранилище живёт только пока работает программа: при следующем запуске оно снова пустое.