Имеется структура-абстракция Array
и её отстортированный вариант SortedArray
. Чтобы проверить работу поддерживаемых этими структурами методов, хотелось бы видеть состояние массива на момент 'до' и 'после' выполнения определенной операции: количество элементов, остаток памяти и т.д.
Был написан декоратор, который переопределяет все открытые методы класса, добавляя к ним функцию логирования в файл/системный поток с отображением стека инкапсулированных подвызовов. Такой декоратор независим от класса-структуры, к которой применяется. Добавление поддержки логирования требует понимания способа декорирования, инспекции методов, областей видимости. Алгоритм поддерживает один подуровень: подвызовы подвызовов останутся на одном уровне, но этого достаточно. Стек вызовов записывается в очередь.
@enable_logging(stdout)
class SortedArray(Array):
def random_fill(self):
super(self.__class__, self).random_fill()
self.selection_sort()
# ...
arr = SortedArray(5)
arr.random_fill()
записывает следующие логи
→ Called <SortedArray>.random_fill()
Before: [None, None, None, None, None] top=0, size=5
After: [17, 19, 54, 76, 79] top=4, size=5
↳ Called <SortedArray>.random_fill(), base method of <Array>
Before: [None, None, None, None, None] top=0, size=5
After: [79, 19, 17, 54, 76] top=4, size=5
↳ Called <SortedArray>.selection_sort(), base method of <Array>
Before: [79, 19, 17, 54, 76] top=4, size=5
After: [17, 19, 54, 76, 79] top=4, size=5
Семантика Python: специальные методы, декорирование, инспектирование во время выполнения, области видимости.
Алгоритмы и структуры: абстракция Array, SortedArray и их методов, алгоритм сортировки, симуляция выделяемой памяти.
Необходимо воспользоваться динамическими атрибутами для обработки данных в формате JSON. Пусть имеется набор данных следующей структуры:
{ "Schedule": {
"events": [{
"serial": 33451,
"name": "Migrating to the Web Using Dart and Polymer - A Guide for Legacy OOP Developers",
"website_url": "http://oscon.com/oscon2014/public/schedule/detail/33451",
"speakers": [ 149868 ],
}],
"speakers": [{
"serial": 149868,
"name": "Faisal Abid",
}]
}}
JSON-объект с ключом Schedule
содержит отображение с ключами events
и speakers
, за каждым из которых находится ассоциированный список записей с уникальным идентификатором serial
. Каждая запись мероприятия содержит список докладчиков (их идентификаторы).
Мероприятия и докладчики десериализованы в объекты соответствующих классов Event
и Speaker
. Обращения к полям events
осуществляются через одноименные атрибуты объекта. Например для чтения адреса веб-страницы мероприятия вызывается <Event>.website_url
. Вызов атрибута <Event>.speakers
возвращает список объектов Speaker
для мероприятия.
col = DataCollection('text.json')
event: Event = col.events['event.33597']
speakers: list[Speaker] = event.speakers
print(f'Event: {event}, url: {event.website_url}\nSpeakers: {speakers}')
Event: <Event: Quantifying your Fitness>, url: http://oscon.com/oscon2014/public/schedule/detail/33597
Speakers: [<Speaker: Kirsten Hunter>, <Speaker: Kjerstin Williams>]
Асинхронный TCP сокет сервер asyncio.start_server()
, получающий сообщения от клиентов и записывающий их в файл.
Для каждого нового соединения вызывается callback, который принимает в качестве аргументов StreamReader
и StreamWriter
. Непрерывно считывает фрагменты поступающих байт с помощью <StreamReader>.readline()
, преобразует каждый фрагмент в строку и записывает его в файл, открывая для этого новый поток с помощью futures.ThreadPoolExecutor()
. При получении пустой строки закрывает соединение. В ответ на сообщение "LIST", считывает все записанные сообщения из файла и отправляет клиенту.
Обработка подключения к адресам ('192.168.56.1', 8088), ('192.168.0.150', 8088)
Открыл соединение для клиента ('192.168.0.150', 59795)
Сохранил сообщение "Message 1" от клиента ('192.168.0.150', 59795)
Сохранил сообщение "Message 2" от клиента ('192.168.0.150', 59795)
Открыл соединение для клиента ('192.168.0.150', 59805)
Сохранил сообщение "Message 3" от клиента ('192.168.0.150', 59805)
Сохранил сообщение "Message 4" от клиента ('192.168.0.150', 59795)
Отправил список сообщений клиенту ('192.168.0.150', 59795).
Закрыл соединение для клиента ('192.168.0.150', 59795)
На заметку: ThreadPoolExecutor
можно заменить на asyncio.to_thread()