본문 바로가기
dev/python

[python] 파이썬 디지털 숫자 그리기

by 최연탄 2020. 12. 10.
728x90
반응형

파이썬 콘솔에 디지털 숫자를 출력하기
- 7 Segment Display 스타일의 숫자 출력
- 출력할 영역의 크기 조절 가능
- 숫자의 크기 조절 가능
- 숫자의 모양에 대한 정의는 코드 주석에 설명

import math

#       #
#  ---  #   a
# |   | # f   b
#  ---  #   g
# |   | # e   c
#  ---  #   d
#       #

numbers = [
#   [a, b, c, d, e, f, g]
    [1, 1, 1, 1, 1, 1, 0],  # 0
    [0, 1, 1, 0, 0, 0, 0],  # 1
    [1, 1, 0, 1, 1, 0, 1],  # 2
    [1, 1, 1, 1, 0, 0, 1],  # 3
    [0, 1, 1, 0, 0, 1, 1],  # 4
    [1, 0, 1, 1, 0, 1, 1],  # 5
    [1, 0, 1, 1, 1, 1, 1],  # 6
    [1, 1, 1, 0, 0, 0, 0],  # 7
    [1, 1, 1, 1, 1, 1, 1],  # 8
    [1, 1, 1, 1, 0, 1, 1],  # 9
]


def input_int_from_stdin(prompt):
    try:
        return int(input(f'\n<<< {prompt}: '))
    except:
        print('\nXXXXX 숫자만 입력해 주세요 XXXXX\n')
        return input_int_from_stdin(prompt)


def get_number_width(size):
    return 1 + 1 + size + 1 + 1


def get_number_height(size):
    return 1 + 1 + size + 1 + size + 1 + 1


def get_paint_number_dot(isOn, isVertical):
    if isOn:
        return '|' if isVertical else '-'
    else:
        return ' '


def get_paint_number_base(number, row):
    data = numbers[int(number)]

    switcher = {
        0: [' ', ' ', ' ', ' ', ' '],
        1: [' ', ' ', get_paint_number_dot(data[0], False), ' ', ' '],
        2: [' ', get_paint_number_dot(data[5], True), ' ', get_paint_number_dot(data[1], True), ' '],
        3: [' ', ' ', get_paint_number_dot(data[6], False), ' ', ' '],
        4: [' ', get_paint_number_dot(data[4], True), ' ', get_paint_number_dot(data[2], True), ' '],
        5: [' ', ' ', get_paint_number_dot(data[3], False), ' ', ' '],
        6: [' ', ' ', ' ', ' ', ' ']
    }

    return switcher.get(row)


def apply_font_column(number, row, number_width):
    column_last = number_width - 1
    number_row = get_paint_number_base(number, row)
    sized_row = []
    sized_row.extend([number_row[0], number_row[1]])

    for column in range(2, column_last - 1):
        sized_row.append(number_row[2])

    sized_row.extend([number_row[3], number_row[4]])

    return sized_row


def apply_font(number, row, number_width, number_height):
    row_center = math.floor(number_height / 2)
    row_last = number_height - 1

    if row == 0 or row == 1:
        return apply_font_column(number, row, number_width)
    elif row == row_last - 1:
        return apply_font_column(number, 5, number_width)
    elif row == row_last:
        return apply_font_column(number, 6, number_width)
    elif row < row_center:
        return apply_font_column(number, 2, number_width)
    elif row == row_center:
        return apply_font_column(number, 3, number_width)
    elif row > row_center:
        return apply_font_column(number, 4, number_width)


def get_paint_number(number, number_width, number_height):
    canvas_number = []

    for row in range(number_height):
        canvas_number.append(apply_font(number, row, number_width, number_height))

    return canvas_number


def create_canvas(default_character, rows, cols):
    return [[default_character] * cols for i in range(rows)]


def copy_canvas(canvas_source, canvas_destnation, base_row, base_column):
    for index_row, row in enumerate(canvas_source):
        for index_column, data in enumerate(row):
            canvas_destnation[base_row + index_row][base_column + index_column] = data


def draw_numbers_to_canvas(canvas, list_number, number_width, number_height, screen_width):
    row = 0
    column = 0

    for number in list_number:
        if (number_width * column + number_width > screen_width):
            row += 1
            column = 0

        canvas_number = get_paint_number(number, number_width, number_height)
        copy_canvas(canvas_number, canvas, number_height * row, number_width * column)

        column += 1


def draw_canvas_to_stdout(canvas):
    for row in canvas:
        buffer = ''

        for column in row:
            buffer += column

        print(buffer)


def draw(list_number, font_size, screen_width):
    number_width = get_number_width(font_size)
    number_height = get_number_height(font_size)
    count_line = math.ceil((number_width * len(list_number)) / screen_width)

    canvas = create_canvas('X', number_height * count_line, screen_width)
    draw_numbers_to_canvas(canvas, list_number, number_width, number_height, screen_width)
    draw_canvas_to_stdout(canvas)


font_size = 5
screen_width = 80

print('screen_width:', screen_width, ', font_size:', font_size)
input_data = input_int_from_stdin('표시할 숫자를 입력해주세요')
draw(str(input_data), font_size, screen_width)

반응형

댓글