From d7a765166af5a553e8976c3a551a305e82107486 Mon Sep 17 00:00:00 2001 From: EvgrafovMichail Date: Fri, 18 Sep 2026 23:49:33 +0300 Subject: [PATCH 1/4] Add criteria for homeworks eval --- README.md | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/README.md b/README.md index 48f42e21..1db404d7 100644 --- a/README.md +++ b/README.md @@ -10,3 +10,54 @@ ## Задания - [Часть 1. Генератор идентификаторов Twitter Snowflake](src/part1/TASK.md) — нужно написать генератор 64-битных числовых идентификаторов, в которые упакованы метка времени, номер узла и счётчик последовательности. Такие идентификаторы уникальны и примерно упорядочены по времени, а из самого идентификатора можно узнать, когда и на каком узле он был создан. + +## Критерии оценивания + +Максимальный балл за каждое задание — **10**. Правильность решения проверяется закрытыми тестами. + +### Условия принятия работы + +Работа принимается к оцениванию, только если выполнены **все** условия: + +- код проходит проверки [ruff](https://docs.astral.sh/ruff/) и [MyPy](https://mypy-lang.org/) (запустить их можно [локально](manuals/local_checks.md)); +- работа сдана до дедлайна. + +Если хотя бы одно условие не выполнено, работа не принимается и оценивается в 0 баллов. + +### Как считается балл за правильность + +Тесты разбиты на функциональные блоки: каждый блок соответствует функции или классу из задания и имеет свой вес (более сложные блоки весят больше). Внутри блока тесты делятся на две группы: + +| Группа тестов | Доля веса блока | Что проверяет | +|---|---|---| +| Базовые (типичные входные данные) | 70% | Основная логика реализована верно | +| Граничные (пустой ввод, нулевые и предельные значения, повторы и т. п.) | 30% | Обработка особых случаев | + +Формулы: + +``` +балл_блока = 0.7 · доля_пройденных_базовых + 0.3 · доля_пройденных_граничных +балл_за_правильность = 10 · Σ(вес_блока · балл_блока) / Σ(вес_блока) +``` + +Дополнительные правила: + +- **Нереализованный функционал.** Блок, в котором функционал не реализован (заглушка, `pass`, `NotImplementedError`), получает 0 баллов. Остальные блоки оцениваются как обычно, дополнительного штрафа за нереализованное нет. +- **Ошибки выполнения.** Тест, в котором возникло необработанное исключение, считается проваленным. +- **Зависание.** У каждого теста есть ограничение по времени выполнения. Если решение не укладывается в него (например, из-за бесконечного цикла), тест считается проваленным. + +### Штраф за списывание + +Если работа подозревается в списывании, оценка снижается на **5 баллов**. Итоговая оценка при этом может стать отрицательной. + +К списыванию также относится подгонка решения под известные примеры из условия (например, `if x == 5: return 25`) вместо реализации общего алгоритма. + +### Итоговая оценка + +``` +итоговая_оценка = балл_за_правильность − 5 (если есть подозрение в списывании) +``` + +### Как оспорить оценку + +Если вы не согласны с оценкой, напишите преподавателю. Укажите, с каким блоком или с какой частью критериев вы не согласны, и приведите аргументы. Оценка пересматривается по тем же критериям, которые описаны выше. From d4638eb01e20576e476d6a1a9dcba85bbf7396fd Mon Sep 17 00:00:00 2001 From: EvgrafovMichail Date: Mon, 21 Sep 2026 18:56:28 +0300 Subject: [PATCH 2/4] Expand criteria --- README.md | 46 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1db404d7..3b1426bd 100644 --- a/README.md +++ b/README.md @@ -46,16 +46,56 @@ - **Ошибки выполнения.** Тест, в котором возникло необработанное исключение, считается проваленным. - **Зависание.** У каждого теста есть ограничение по времени выполнения. Если решение не укладывается в него (например, из-за бесконечного цикла), тест считается проваленным. +### Штрафы за оформление + +Кроме правильности, оценивается качество кода. За нарушения ниже из балла за правильность вычитаются штрафы. Каждое нарушение штрафуется **один раз**, сколько бы раз оно ни встретилось в работе. + +#### Серьёзные нарушения (−1 балл за каждое) + +| Нарушение | Что имеется в виду | +|---|---| +| Копипаста | Вместо вынесения повторяющейся логики в функцию, метод или цикл один и тот же (или почти тот же) код скопирован несколько раз | +| Большая вложенность | Более трёх уровней вложенности (`if`, `for`, `while`, `try`, `with`) внутри одной функции. Лечится ранним возвратом (`return`, `continue`) и выносом логики в отдельные функции | +| Мёртвый код | Код, который нигде не используется: неиспользуемые функции, классы, переменные, константы, импорты, недостижимые ветки. Сюда же относятся крупные куски закомментированного кода «на будущее» и оставленный отладочный `print` | +| Слишком длинные функции | Функция делает много разных вещей одновременно (вычисления, проверки, преобразования, форматирование в одном месте) и не читается целиком. Ориентир: более 30–40 строк или несколько несвязанных обязанностей | + +#### Средние нарушения (−0.5 балла за каждое) + +| Нарушение | Что имеется в виду | +|---|---| +| Магические значения | Числа и строки с неочевидным смыслом прописаны прямо в коде, а не вынесены в именованные константы | +| Неинформативные имена | Имена вроде `a`, `tmp`, `data2`, `x1`, а также имена, не отражающие суть, или не соответствующие PEP 8 (`camelCase` для функций и переменных) | +| Избыточные глобальные переменные | Изменяемое глобальное состояние там, где достаточно параметров, возвращаемых значений или атрибутов класса | +| Слишком широкий перехват исключений | Голый `except:` или `except Exception:` без необходимости; молча проглоченные ошибки (`except ...: pass`) | +| Изменение входных данных | Функция неожиданно мутирует переданные ей аргументы, хотя из названия и описания это не следует | + +#### Типовые нарушения хорошего тона (−0.25 балла за каждое) + +Примеры: + +- `else` или `elif` после `return`, `raise`, `continue` или `break`; +- явное приведение к `bool` в условиях (`if bool(x):`) и сравнение с `True` / `False` (`if x == True:`); +- сравнение с `None` через `==` / `!=` вместо `is` / `is not`; +- проверка пустоты коллекции через `len(x) == 0` вместо `if not x`; +- обход через `for i in range(len(items))`, когда индекс не нужен (вместо `for item in items` или `enumerate`); +- `if cond: return True else: return False` вместо `return cond`; +- изменяемое значение по умолчанию у аргумента (`def f(x=[])`); +- ручная конкатенация строк вместо f-строк; +- избыточные комментарии, пересказывающие очевидный код. + ### Штраф за списывание -Если работа подозревается в списывании, оценка снижается на **5 баллов**. Итоговая оценка при этом может стать отрицательной. +Если работа подозревается в списывании, студент получает **−5 баллов**. Эти баллы не вычитаются из оценки за правильность, а **заменяют** итоговую оценку: итоговой оценкой становится −5, независимо от результата тестов. -К списыванию также относится подгонка решения под известные примеры из условия (например, `if x == 5: return 25`) вместо реализации общего алгоритма. +Студент может оспорить этот балл на занятии, доказав, что не списывал, а написал код самостоятельно (например, объяснив решение и ответив на вопросы по нему). Если подозрение снимается, работа оценивается по обычным критериям. ### Итоговая оценка ``` -итоговая_оценка = балл_за_правильность − 5 (если есть подозрение в списывании) +если есть подозрение в списывании: + итоговая_оценка = −5 +иначе: + итоговая_оценка = max(0, балл_за_правильность − штрафы_за_оформление) ``` ### Как оспорить оценку From b786cf82f61843367e77c91327f4cefe5703c6f9 Mon Sep 17 00:00:00 2001 From: EvgrafovMichail Date: Mon, 21 Sep 2026 19:16:42 +0300 Subject: [PATCH 3/4] Fix criteria review comments --- README.md | 52 ++++++++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 3b1426bd..09ef585b 100644 --- a/README.md +++ b/README.md @@ -50,38 +50,40 @@ Кроме правильности, оценивается качество кода. За нарушения ниже из балла за правильность вычитаются штрафы. Каждое нарушение штрафуется **один раз**, сколько бы раз оно ни встретилось в работе. +У каждого нарушения есть уникальный код: `S` — серьёзные, `M` — средние, `T` — типовые. При проверке преподаватель указывает в комментарии к работе только коды (например, `S1, M2, T1`), а расшифровку и штраф можно найти в таблицах ниже. + #### Серьёзные нарушения (−1 балл за каждое) -| Нарушение | Что имеется в виду | -|---|---| -| Копипаста | Вместо вынесения повторяющейся логики в функцию, метод или цикл один и тот же (или почти тот же) код скопирован несколько раз | -| Большая вложенность | Более трёх уровней вложенности (`if`, `for`, `while`, `try`, `with`) внутри одной функции. Лечится ранним возвратом (`return`, `continue`) и выносом логики в отдельные функции | -| Мёртвый код | Код, который нигде не используется: неиспользуемые функции, классы, переменные, константы, импорты, недостижимые ветки. Сюда же относятся крупные куски закомментированного кода «на будущее» и оставленный отладочный `print` | -| Слишком длинные функции | Функция делает много разных вещей одновременно (вычисления, проверки, преобразования, форматирование в одном месте) и не читается целиком. Ориентир: более 30–40 строк или несколько несвязанных обязанностей | +| Код | Нарушение | Что имеется в виду | +|---|---|---| +| `S1` | Копипаста | Вместо вынесения повторяющейся логики в функцию, метод или цикл один и тот же (или почти тот же) код скопирован несколько раз | +| `S2` | Большая вложенность | Более трёх уровней вложенности (`if`, `for`, `while`, `try`, `with`) внутри одной функции. Лечится ранним возвратом (`return`, `continue`) и выносом логики в отдельные функции | +| `S3` | Мёртвый код | Код, который нигде не используется: неиспользуемые функции, классы, переменные, константы, импорты, недостижимые ветки. Сюда же относятся крупные куски закомментированного кода «на будущее» и оставленный отладочный `print` | +| `S4` | Слишком длинные функции | Функция делает много разных вещей одновременно (вычисления, проверки, преобразования, форматирование в одном месте) и не читается целиком. Ориентир: более 30–40 строк или несколько несвязанных обязанностей | #### Средние нарушения (−0.5 балла за каждое) -| Нарушение | Что имеется в виду | -|---|---| -| Магические значения | Числа и строки с неочевидным смыслом прописаны прямо в коде, а не вынесены в именованные константы | -| Неинформативные имена | Имена вроде `a`, `tmp`, `data2`, `x1`, а также имена, не отражающие суть, или не соответствующие PEP 8 (`camelCase` для функций и переменных) | -| Избыточные глобальные переменные | Изменяемое глобальное состояние там, где достаточно параметров, возвращаемых значений или атрибутов класса | -| Слишком широкий перехват исключений | Голый `except:` или `except Exception:` без необходимости; молча проглоченные ошибки (`except ...: pass`) | -| Изменение входных данных | Функция неожиданно мутирует переданные ей аргументы, хотя из названия и описания это не следует | +| Код | Нарушение | Что имеется в виду | +|---|---|---| +| `M1` | Магические значения | Числа и строки с неочевидным смыслом прописаны прямо в коде, а не вынесены в именованные константы | +| `M2` | Неинформативные имена | Имена вроде `a`, `tmp`, `data2`, `x1`, а также имена, не отражающие суть, или не соответствующие PEP 8 (например, `camelCase` для функций и переменных) | +| `M3` | Избыточные глобальные переменные | Изменяемое глобальное состояние там, где достаточно параметров, возвращаемых значений или атрибутов класса | +| `M4` | Слишком широкий перехват исключений | Голый `except:` или `except Exception:` без необходимости; молча проглоченные ошибки (`except ...: pass`) | +| `M5` | Изменение входных данных | Функция неожиданно изменяет переданные ей аргументы, хотя из названия и описания это не следует | #### Типовые нарушения хорошего тона (−0.25 балла за каждое) -Примеры: - -- `else` или `elif` после `return`, `raise`, `continue` или `break`; -- явное приведение к `bool` в условиях (`if bool(x):`) и сравнение с `True` / `False` (`if x == True:`); -- сравнение с `None` через `==` / `!=` вместо `is` / `is not`; -- проверка пустоты коллекции через `len(x) == 0` вместо `if not x`; -- обход через `for i in range(len(items))`, когда индекс не нужен (вместо `for item in items` или `enumerate`); -- `if cond: return True else: return False` вместо `return cond`; -- изменяемое значение по умолчанию у аргумента (`def f(x=[])`); -- ручная конкатенация строк вместо f-строк; -- избыточные комментарии, пересказывающие очевидный код. +| Код | Нарушение | +|---|---| +| `T1` | `else` или `elif` после `return`, `raise`, `continue` или `break` | +| `T2` | Явное приведение к `bool` в условиях (`if bool(x):`) и сравнение с `True` / `False` (`if x == True:`) | +| `T3` | Сравнение с синглтонами и членами enum'ов через `==` / `!=` вместо `is` / `is not` | +| `T4` | Проверка пустоты коллекции через `len(x) == 0` вместо `if not x` | +| `T5` | Обход через `for i in range(len(items))`, когда индекс не нужен (вместо `for item in items` или `enumerate`) | +| `T6` | `if cond: return True else: return False` вместо `return cond` | +| `T7` | Изменяемое значение по умолчанию у аргумента (`def f(x=[])`) | +| `T8` | Ручная конкатенация строк вместо f-строк | +| `T9` | Избыточные комментарии, пересказывающие очевидный код | ### Штраф за списывание @@ -98,6 +100,8 @@ итоговая_оценка = max(0, балл_за_правильность − штрафы_за_оформление) ``` +Итоговая оценка за домашнее задание округляется до ближайшего целого по правилам математики: дробная часть от 0.5 и выше округляется вверх, меньше 0.5 — вниз (например, 7.5 → 8, 7.4 → 7). + ### Как оспорить оценку Если вы не согласны с оценкой, напишите преподавателю. Укажите, с каким блоком или с какой частью критериев вы не согласны, и приведите аргументы. Оценка пересматривается по тем же критериям, которые описаны выше. From dc98f6ee949a57f8300883d403ebf380db336107 Mon Sep 17 00:00:00 2001 From: EvgrafovMichail Date: Mon, 21 Sep 2026 19:47:04 +0300 Subject: [PATCH 4/4] Rearange formating mistakes --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 09ef585b..6b8725a4 100644 --- a/README.md +++ b/README.md @@ -56,20 +56,20 @@ | Код | Нарушение | Что имеется в виду | |---|---|---| -| `S1` | Копипаста | Вместо вынесения повторяющейся логики в функцию, метод или цикл один и тот же (или почти тот же) код скопирован несколько раз | -| `S2` | Большая вложенность | Более трёх уровней вложенности (`if`, `for`, `while`, `try`, `with`) внутри одной функции. Лечится ранним возвратом (`return`, `continue`) и выносом логики в отдельные функции | -| `S3` | Мёртвый код | Код, который нигде не используется: неиспользуемые функции, классы, переменные, константы, импорты, недостижимые ветки. Сюда же относятся крупные куски закомментированного кода «на будущее» и оставленный отладочный `print` | -| `S4` | Слишком длинные функции | Функция делает много разных вещей одновременно (вычисления, проверки, преобразования, форматирование в одном месте) и не читается целиком. Ориентир: более 30–40 строк или несколько несвязанных обязанностей | +| `S1` | Копипаста | Вместо вынесения повторяющейся логики в функцию, метод или цикл один и тот же (или почти тот же) код скопирован несколько раз. Мешает расширяемости: любое изменение приходится вносить во все копии | +| `S2` | Слишком длинные функции | Функция делает много разных вещей одновременно (вычисления, проверки, преобразования, форматирование в одном месте) и не читается целиком. Ориентир: более 30–40 строк или несколько несвязанных обязанностей. Такой код тяжело читать и поддерживать | +| `S3` | Магические значения | Числа и строки с неочевидным смыслом прописаны прямо в коде, а не вынесены в именованные константы. Как и копипаста, мешает расширяемости: значение приходится искать и менять по всему коду | +| `S4` | Слишком широкий перехват исключений | Голый `except:` или `except Exception:` без необходимости; молча проглоченные ошибки (`except ...: pass`). Так можно пропустить что-то важное | +| `S5` | Изменение входных данных | Функция неожиданно изменяет переданные ей аргументы, хотя из названия и описания это не следует. Неожиданное поведение, источник серьёзных ошибок | #### Средние нарушения (−0.5 балла за каждое) | Код | Нарушение | Что имеется в виду | |---|---|---| -| `M1` | Магические значения | Числа и строки с неочевидным смыслом прописаны прямо в коде, а не вынесены в именованные константы | +| `M1` | Большая вложенность | Более трёх уровней вложенности (`if`, `for`, `while`, `try`, `with`) внутри одной функции. Лечится ранним возвратом (`return`, `continue`) и выносом логики в отдельные функции | | `M2` | Неинформативные имена | Имена вроде `a`, `tmp`, `data2`, `x1`, а также имена, не отражающие суть, или не соответствующие PEP 8 (например, `camelCase` для функций и переменных) | | `M3` | Избыточные глобальные переменные | Изменяемое глобальное состояние там, где достаточно параметров, возвращаемых значений или атрибутов класса | -| `M4` | Слишком широкий перехват исключений | Голый `except:` или `except Exception:` без необходимости; молча проглоченные ошибки (`except ...: pass`) | -| `M5` | Изменение входных данных | Функция неожиданно изменяет переданные ей аргументы, хотя из названия и описания это не следует | +| `M4` | Мёртвый код | Код, который нигде не используется: неиспользуемые функции, классы, переменные, константы, импорты, недостижимые ветки. Сюда же относятся крупные куски закомментированного кода «на будущее» и оставленный отладочный `print`. Затрудняет чтение, но на работу программы не влияет | #### Типовые нарушения хорошего тона (−0.25 балла за каждое)