Обложка канала

Geeks

11247 @g33ks

Канал от гиков для гиков. Новости технологий и ссылки на новые каналы ИТ и научной тематики.

Geeks

4 года назад
Открыть в
Часть первая Подготовительные работы Итак, первое, что делаем - пишем функцию, которая (внезапно) отдаёт нам случайное булевое значение: from random import random def random_bool() -> bool: return random() < 0.5 Пожалуй, на этой славной ноте и закончим подготовительные работы. Булево значение для нас будет индикатором того, закрашена ли точка на изображении или все-таки нет. Генерация необходимых данных Вторым шагом мы непременно должны создать список из булевых значений заданного размера, который у нас будет ответственен за ряд точек в изображении: def generate_row( cells_count: int, ) -> List[bool]: return [random_bool() for _ in range(cells_count)] Не то чтоб я каждую строку кода хочу выносить в отдельную функцию, но пока мне так больше нравится. Итак, шажок номер три, чтоб немного приблизиться к величию GitHub, нам необходимо генерировать три блока с данными, а затем склеивать их. Очевидно, что мы можем написать функцию, которая будет принимать целочисленное количество рядов в сетке значений и количество точек в этих рядах. Будем ожидать, что данная функция нам будет отдавать список из списков булевых значений: def generate_block( width: int, height: int, ) -> List[List[bool]]: return [generate_row(width) for _ in range(height)] Теперь мы можем создать левый и центральный блок. Для правого блока нам ничего нового не нужно, а достаточно просто отзеркалить левый блок. И вот, свет увидела еще одна функция в одну строчку: def reverse_block( block: List[List[bool]], ) -> List[List[bool]]: return [list(reversed(i)) for i in block] Теперь мы можем сгенерировать все три части изображения. Вот приблизительно как-то так: left = generate_block(width=cells_count // 2, height=cells_count) spacer = generate_block(width=cells_count % 2, height=cells_count) right = reverse_block(left) Очевидно, что нам надо как-то их соединить, и для этого мы напишем вот такую функцию: def concatenate_blocks( left: List[List[bool]], spacer: List[List[bool]], right: List[List[bool]], ) -> List[List[bool]]: result = list() for i, left_row in enumerate(left): right_row = right[i] spacer_row = spacer[i] line = [*left_row, *spacer_row, *right_row] result.append(line) return result И вуаля! def generate_data( cells_count: int = 5, ) -> List[List[bool]]: left = generate_block(width=cells_count // 2, height=cells_count) spacer = generate_block(width=cells_count % 2, height=cells_count) right = reverse_block(left) return concatenate_blocks(left, spacer, right) Можно запустить данную функцию и вывести результат каким-то таким образом: >>> from pprint import pprint >>> data = generate_data() >>> pprint(data) [[False, True, True, True, False], [False, True, False, True, False], [False, True, True, True, False], [False, True, True, True, False], [True, False, False, False, True]] Запускаем и любуемся на полученный результат из пяти списков. Во время просмотра результата работы скрипта задумываемся над тем, что нам нужна была картинка, а не вот это вот все, что есть на экране, и продолжаем писать код. Пока, в сугубо отладочных целях, напишем страшенную функцию для быстрой визуализации такого списка, один раз её прогоним и забудем её как страшный сон: >>> def data_to_str(data: List[List[bool]]) -> str: >>> return "\\n".join(list("".join(list(map(lambda x: "#" if x else " ", row))) for row in data)) >>> print(data) ### # # ### ### # #