LINUX.ORG.RU

Python. Аннотации типов

 , ,


0

1

Прошу помощи с решением задачи.

Дано:

Вы решили создать компьютерную игру, в которую будет играть весь мир. Но, как известно, путь в тысячу верст начинается с первого шага.

Для начала вы решили написать класс, содержащий информацию об игроке. А поскольку игроков будет много, класс должен быть хорошо спроектирован. Для повышения качества кода вы решили снабдить класс аннотациями типов.

Итак, ваша задача написать класс Player, содержащий информацию об игроке, и снабдить его аннотациями типов. Класс должен иметь следующие атрибуты:

  • id — уникальный идентификатор игрока, целое число;

  • name — имя игрока, строка;

  • scores — набранные очки, целое число;

  • games — список игр, в которые сыграл данный игрок (укажите просто тип list без уточнения типа содержимого).

Конструктор принимает только id и name, а атрибуты scores и games инициализируются 0 и пустым списком.

У класса должен быть реализован метод add_result, принимающий два аргумента:

  • game_id — id игры;

  • scores — набранные очки.

Метод add_result должен сохранить id игры в списке games и прибавить набранные очки к общей сумме.

Метод get_mean должен вернуть средний балл по всем сыгранным играм (для этого нужно просто поделить количество набранных очков на количество сыгранных игр).

Все методы также должны быть снабжены аннотациями типов. Не забудьте про аннотацию типа возвращаемого значения (для методов, которые ничего не возвращают, это должен быть None). Аргумент self снабжать аннотацией типа не нужно (во-первых, его тип и так очевиден, во-вторых, это не так просто сделать — можете попробовать и убедиться сами).

Пример работы программы:

p = Player(1, 'Bilbo')
print(p.id)              ⇒ 1
print(p.name)            ⇒ Bilbo
print(p.scores)          ⇒ 0
print(p.games)           ⇒ []
 
p.add_result(15, 10) 
p.add_result(21, 5)  
print(p.scores)          ⇒ 15
print(p.games)           ⇒ [15, 21]
print(p.get_mean())      ⇒ 7.5

Моё решение:

#!/usr/bin/env python3

class Player:

    def __init__(self, id: int, name: str) -> None:
        self.id: int = id
        self.name: str = name
        self.scores: int = 0
        self.games: list = []

    def add_result(self, game_id: int, scores: int) -> None:
        self.scores: int = self.scores + scores
        self.games.append(game_id)

    def get_mean(self) -> float:
        return (self.scores / len(self.games))

p= Player(1, 'Bilbo')
print(p.id)
print(p.name)
print(p.scores)
print(p.games)

p.add_result(15, 10)
p.add_result(21, 5)
print(p.scores)
print(p.games)
print(p.get_mean())

Моё определение класса не проходит автоматическую проверку. Прошу подсказки где я прокалываюсь?


Всё, решил. Надо было так:

#!/usr/bin/env python3

class Player:
    id: int
    name: str
    scores: int
    games: list

    def __init__(self, id: int, name: str) -> None:
        self.id: int = id
        self.name: str = name
        self.scores: int = 0
        self.games: list = []

    def add_result(self, game_id: int, scores: int) -> None:
        self.scores: int = self.scores + scores
        self.games.append(game_id)

    def get_mean(self) -> float:
        return (self.scores / len(self.games))

p= Player(1, 'Bilbo')
print(p.id)
print(p.name)
print(p.scores)
print(p.games)

p.add_result(15, 10)
p.add_result(21, 5)
print(p.scores)
print(p.games)
print(p.get_mean())
czan
() автор топика
    def __init__(self, id: int, name: str) -> None:
        self.id: int = id

ИМХО, это немного странно

Если есть поля класса, то их тип анонсируется прямо в классе. А не каждый раз, когда к ним идет обращение

router ★★★★★
()
Последнее исправление: router (всего исправлений: 1)
Ответ на: комментарий от router

Забавно, что выделил как раз верную сущность :)

Есть переменные класса, а есть переменные инстанса класса. В этом случае score и games можно вынести в переменные класса, а name и id оставить на месте.

А на аннотацию типов можно и вовсе не смотреть - это сахар для линтеров, не более.

В общем случае этот кусочек кода вполне валидный.

stave ★★★★★
()
Ответ на: комментарий от stave

Хм. Уверен, что у тебя больше опыта, т.к. я чаще читаю чужой код, чем пишу свой

Но тут у меня возникли сомнения. Либо я вообще не понял о чем речь, либо это ошибка:

В этом случае score и games можно вынести в переменные класса

Переменные класса это весьма специфическая вещь для специфических случаев. Если инициализию games вынести из метода в описание класса, это будет грубая ошибка и однозначно приведет к багам

score тоже в любом случае будет переменной инстанса, но т.к. это скаляр, то инициализация в описании класса не приведет к багам, хоть и будет некрасивым кодом

А на аннотацию типов можно и вовсе не смотреть - это сахар для линтеров, не более

Да, но аннотациям (без инициализации) вроде как раз место вне методом класса

router ★★★★★
()

Честно говоря шляпная задача и проверка шляпная. ИРЛ id должен быть не просто цельным числом, а уникальным значением и оттуда много-много вопросов возникает к организации класса игрок. Например приходит в голову что игрока руками делать нельзя, а делать его должен какой-то другой класс который будет уже этот id выдавать уникальный. Ну и сразу вопрос к тому а стоит ли проверять этот id в классе игрок или всё же вопросы к тому что такое этот id надо перекладывать на класс который создаёт этих игроков.

peregrine ★★★★★
()
Ответ на: комментарий от peregrine

Товарищи! Я понимаю что тут много косяков и можно сделать лучше. Но мне не нужно лучше. Мне нужно сдать задачу и забыть. Всё. Больше ничего не надо. Благодарю за ответы и замечания!

czan
() автор топика
Последнее исправление: czan (всего исправлений: 1)
Ответ на: комментарий от czan

МФТИ Аспирантура

Эм, то ли образование так деграднуло, то ли в приборостроительных институтах в мое время учили на порядок качественнее?

Я без претензий к автору темы, просто это же уже аспирантура, не второй курс.

Obezyan
()