Испытание свойствами и методами
https://stepik.org/lesson/709885/step/1?unit=710450
Время первого испытания.

Представьте, что вы получили задание от заказчика. Вас просят реализовать простую имитацию локальной сети, состоящую из набора серверов, соединенных между собой через роутер.
Каждый сервер может отправлять пакет любому другому серверу сети. Для этого у каждого есть свой уникальный IP-адрес.
Для простоты - это просто целое (натуральное) число от 1 и до N, где N - общее число серверов. Алгоритм следующий.
Предположим, сервер с IP = 2 собирается отправить пакет информации серверу с IP = 3. Для этого, он сначала отправляет пакет роутеру, а уже тот, смотрит на IP-адрес и пересылает пакет нужному узлу (серверу).
Для реализации этой схемы программе предлагается объявить три класса:
Server - для описания работы серверов в сети;
Router - для описания работы роутеров в сети (в данной задаче полагается один роутер);
Data - для описания пакета информации.
Серверы будут создаваться командой:
sv = Server()
При этом, уникальный IP-адрес каждого сервера должен формироваться автоматически при создании нового экземпляра класса Server.
Далее, роутер должен создаваться аналогичной командой:
router = Router()
А, пакеты данных, командой:
data = Data(строка с данными, IP-адрес назначения)
Для формирования и функционирования локальной сети, в классе Router должны быть реализованы следующие методы:
link(server) - для присоединения сервера server (объекта класса Server) к роутеру (для простоты, каждый сервер соединен только с одним роутером);
unlink(server) - для отсоединения сервера server (объекта класса Server) от роутера;
send_data() - для отправки всех пакетов (объектов класса Data) из буфера роутера соответствующим серверам (после отправки буфер должен очищаться).
И одно обязательное локальное свойство (могут быть и другие свойства):
buffer - список для хранения принятых от серверов пакетов (объектов класса Data).
Класс Server должен содержать свой набор методов:
send_data(data) - для отправки информационного пакета data (объекта класса Data) с указанным IP-адресом получателя (пакет отправляется роутеру и сохраняется в его буфере - локальном свойстве buffer);
get_data() - возвращает список принятых пакетов (если ничего принято не было, то возвращается пустой список) и очищает входной буфер;
get_ip() - возвращает свой IP-адрес.
Соответственно в объектах класса Server должны быть локальные свойства:
buffer - список принятых пакетов (объекты класса Data, изначально пустой);
ip - IP-адрес текущего сервера.
Наконец, объекты класса Data должны содержать два следующих локальных свойства:
data - передаваемые данные (строка);
ip - IP-адрес назначения.
Пример использования этих классов (эти строчки в программе писать не нужно):
router = Router()
sv_from = Server()
sv_from2 = Server()
router.link(sv_from)
router.link(sv_from2)
router.link(Server())
router.link(Server())
sv_to = Server()
router.link(sv_to)
sv_from.send_data(Data("Hello", sv_to.get_ip()))
sv_from2.send_data(Data("Hello", sv_to.get_ip()))
sv_to.send_data(Data("Hi", sv_from.get_ip()))
router.send_data()
msg_lst_from = sv_from.get_data()
msg_lst_to = sv_to.get_data()
Ваша задача реализовать классы Router, Server и Data в соответствии с приведенным техническим заданием (ТЗ). Что-либо выводить на экран не нужно.
Моё решение
class Data:
def __init__(self, data: str, ip: int) -> None:
self.data = data
self.ip = ip
class Server:
SERVER_COUNT = 0
def __init__(self) -> None:
Server.SERVER_COUNT += 1
self.ip = Server.SERVER_COUNT
self.buffer = []
self.router = None
def _check_data(self, data: Data) -> None:
if not isinstance(data, Data):
raise Exception('Данные должны быть экземпляром класса Data')
def _check_router_link(self) -> None:
if self.router is None:
raise Exception('Роутер не подключен')
def send_data(self, data: Data) -> None:
self._check_data(data)
self._check_router_link()
self.router.add_data(data)
def receive_data(self, data: Data) -> None:
self._check_data(data)
self._check_router_link()
if data.ip != self.ip:
raise Exception('Неправильный IP-адрес')
self.buffer.append(data)
def get_data(self) -> list:
data = self.buffer
self.buffer = []
return data
def get_ip(self) -> int:
return self.ip
def set_router(self, router: 'Router') -> None:
if not isinstance(router, Router):
raise Exception('Роутер должен быть экземпляром класса Router')
self.router = router
def remove_router(self) -> None:
self.router = None
class Router:
def __init__(self) -> None:
self.servers = {}
self.buffer = []
def _check_server(self, server: Server) -> None:
if not isinstance(server, Server):
raise Exception('Сервер должен быть экземпляром класса Server')
def link(self, server: Server) -> None:
self._check_server(server)
server.set_router(self)
self.servers[server.get_ip()] = server
def unlink(self, server: Server) -> None:
self._check_server(server)
if server.get_ip() in self.servers:
server.remove_router()
del self.servers[server.get_ip()]
def send_data(self) -> None:
for data in self.buffer:
if data.ip in self.servers:
self.servers[data.ip].receive_data(data)
self.buffer = []
def add_data(self, data: Data) -> None:
if not isinstance(data, Data):
raise Exception('Данные должны быть экземпляром класса Data')
self.buffer.append(data)
Категория: Обучение | автор: root
Опубликовано: 19-01-2025 13:00 | Обновлено: 25-02-2025 10:49