Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 44 additions & 17 deletions src/part3/TASK.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ CRUD-операции над ним. Корзина (`cart.py`) в этой ча
реализуйте это так, как вы делали в своём решении части 2 (см.
[описание части 2](../part2/TASK.md)).

> **Важно.** Тексты, которые функции печатают в stdout или возвращают как
> строку (сообщения об ошибках, таблица хранилища, ответы консоли), в тестах
> проверяются **дословно**: лишний пробел, другой регистр, пропущенная точка или
> перевод строки считаются ошибкой. Берите тексты из описания и примеров как
> есть.

---

## Модуль `utils.py`
Expand Down Expand Up @@ -77,22 +83,22 @@ CRUD-операции над ним. Корзина (`cart.py`) в этой ча

### `get_storage_str_representation(storage: list[Product]) -> str`

Отрисовывает всё хранилище одной многострочной строкой — выровненной таблицей,
Отрисовывает всё хранилище одной мультистрокой — выровненной таблицей,
пригодной для печати в терминал.

«Выровненная» значит, что при печати моноширинным шрифтом все строки таблицы
имеют одинаковую длину, а разделители `|` стоят строго друг под другом:
значения в каждом столбце начинаются с одной и той же позиции, а ширина столбца
подбирается под самое длинное из его значений. Сравните: так выглядит вывод
хранилища, если просто напечатать значения через пробел, —
хранилища, если просто напечатать значения через пробел:

```
ID name price quantity
10 compressor 1299.99 3
2 nail 2.50 500
```

— а так он выглядит после выравнивания:
А так он выглядит после выравнивания:

```
| ID | name | price | quantity |
Expand All @@ -104,7 +110,7 @@ ID name price quantity
Точные правила выравнивания приведены в разделе «Формат» ниже.

- **Вход:** `storage` — хранилище товаров.
- **Выход:** многострочная строка (строки соединены `"\n"`, завершающего
- **Выход:** мультистрока (строки соединены `"\n"`, завершающего
перевода строки нет):

1. строка заголовков — значения из `TABLE_HEADERS`;
Expand Down Expand Up @@ -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`. Дальше везде —
Expand All @@ -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`.

**Примеры.** Каждый пример — отдельный фрагмент скрипта, который начинается с
пустого хранилища. В комментариях указано, что функция возвращает или печатает.
Expand Down Expand Up @@ -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. Если нормализованное имя пустое — печатается сообщение
Expand Down Expand Up @@ -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)]
```

Товара с таким идентификатором нет, а пустое имя отвергается раньше, чем
Expand Down Expand Up @@ -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 <name...> <price> <quantity> add a product, print its new id
read <id> print the product with that id
update <id> <name...> <price> <quantity> overwrite that product's fields
delete <id> 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.
```

### Разбор команд

Команда определяется по строке, разбитой по пробельным символам.
Expand All @@ -352,10 +378,11 @@ admin> exit
| `update <id> <имя...> <цена> <количество>` | перезаписать поля товара; `<имя...>` — одно или больше слов |
| `delete <id>` | удалить товар |

Для `create` и `update` два последних слова строки — это цена и количество, а
всё между глаголом (и, для `update`, идентификатором) и этими двумя словами
склеивается через один пробел в имя товара. Имя обязано быть непустым: `create`
и `update` вообще без слов имени (`create 89.90 12`) командой не считаются.
`<имя...>` может состоять из произвольного количества слов (но не меньше
одного), разделённых пробелами; слова склеиваются через один пробел в имя
товара. Все остальные параметры команд (`<id>`, `<цена>`, `<количество>`) — ровно
по одному слову. Поэтому `create` и `update` без слов имени (`create 89.90 12`)
командой не считаются.

Разобранные аргументы приводятся к типам: `<id>` и `<количество>` — через
`int(...)` (десятичное целое), `<цена>` — через `Decimal(...)`. Получившийся
Expand Down Expand Up @@ -386,8 +413,8 @@ admin> exit
- `create`, `read`, `update`, `delete` — выполняется соответствующая
CRUD-операция с разобранными аргументами, её результат выводится на экран
(если операция ничего не вернула, не выводится ничего); цикл продолжается;
- строка, которая не подошла ни под одну форму — неизвестный глагол
(`frobnicate ...`) либо известный глагол с неверным числом аргументов
- строка, которая не подошла ни под одну форму — неизвестная команда
(`frobnicate ...`) либо известная команда с неверным числом аргументов
(`read 1 2 3`) — печатается сообщение `'<строка>' is not a command`;
хранилище не меняется; вернуть `True`.

Expand Down Expand Up @@ -424,7 +451,7 @@ python -m src.part3.run_admin
```

После запуска появится приглашение `admin> `. Введите `help`, чтобы увидеть
список команд (после того как вы реализуете `HELP_TEXT`), и `exit`, чтобы
список команд (после того как вы реализуете `show_help()`), и `exit`, чтобы
выйти. Хранилище живёт только пока работает программа: при следующем запуске оно
снова пустое.

Expand Down
Loading