Получи случайную криптовалюту за регистрацию!

Часть первая Подготовительные работы Итак, первое, что делае | Geeks

Часть первая

Подготовительные работы

Итак, первое, что делаем - пишем функцию, которая (внезапно) отдаёт нам случайное булевое значение:

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)
###
# #
###
###
# #