Home » LCD 패널 방식으로 숫자를 표시해보기 (파이썬)

LCD 패널 방식으로 숫자를 표시해보기 (파이썬)

LCD 처럼 숫자를 표시하는 코드를 만들어 보자

크기와 출력할 숫자를 입력받는다. 크기는 LCD 표시 요소 하나의 크기를 가리킨다. (크기는 1~10,  숫자는 0~99,999,999)  가로선은 -, 세로선은 | 문자를 통해서 표현하며, 사이즈만큼 길이가 길어진다. 따라서 하나의 문자를 표시하기 위해서는 가로는 size + 2, 세로는 size * 2 + 3 만큼의 공간이 필요하다.
예시 – 출력: 0123456789. size: 3

 ---         ---   ---         ---   ---   ---   ---   ---
|   |     |     |     | |   | |     |         | |   | |   |
|   |     |     |     | |   | |     |         | |   | |   |
|   |     |     |     | |   | |     |         | |   | |   |
             ---   ---   ---   ---   ---         ---   ---
|   |     | |         |     |     | |   |     | |   |     |
|   |     | |         |     |     | |   |     | |   |     |
|   |     | |         |     |     | |   |     | |   |     |
 ---         ---   ---         ---   ---         ---   ---

접근

왼쪽과 같이 LCD 숫자 하나를 표현하기 위해서는 총 7개의 패널이 필요하다. 각 패널의 번호를 왼쪽과 같이 지정한다고 하자. 어떤 숫자를 표현하고자 한다면 각 패널이 어떤 숫자에서는 켜질 것인지, 켜지지 않을 것인지를 구분해야 한다. 예를 들어 위쪽 가로 방향 패널인 0의 경우에는 1을 그려야 하는 시점에는 켤 필요가 없다. 하지만 0이나 2, 3 등을 그려야 하는 시점에서는 켜져야 한다.
즉 0번 패널이 켜져야 하는 숫자는 아래 그림에서 알 수 있듯이, 0, 2, 3, 4, 6, 7, 8, 9 가 된다.  같은 방식으로 각 패널마다 어떤 숫자에 켜져야 할 것인지를 미리 정해두도록 하자.

이렇게 각 패널마다 켜져야 하는 숫자들을 정리하는 것은 생각보다 간단하다. 위 그림을 이용해서 쉽게 리스트를 완성할 수 있다.

masks = ("02356789", "045689", "01234789", "2345689", "02689", "013456789", "0235689")

이제 숫자를 출력할 차례이다. 우선 한개의 숫자를 출력하는 과정을 생각해보자. 숫자를 출력하는 과정은 가로선을 표현하는 구간 3군데와 세로선을 표현하는 구간 2군데로 나뉜다.

가로선 표현

패널 1개의 크기가 S인 숫자의 폭은 S + 2 (양쪽의 1씩 세로선이 표시되어야 하므로)이다. 따라서 가로선의 경우 표시하려는 숫자의 해당 가로 패널이 켜지는 경우에는 (공백) + (-) * S + (공백)을 출력하게 된다. 만약 패널이 꺼져 있는 경우에는 (-) 대신에 공백이 출력될 것이다. 따라서 맨 위에 가로선을 표시하는 것은 출력하려는 숫자 d 에 따라서 다음과 같은 문자열을 만들게 된다.

' ' + ('-' if d in masks[0] else ' ') * s + ' '
## "#---#" 또는 "#####" 

세로선 표현

세로선을 표현할 때는 한 줄에 1번 2번 혹은 4번 5번 패널을 같이 판단해야 한다. 표시되는 문자의 상황은 가로선과 반대로 양끝에 패널이 있고 가운데는 크기 값 만큼의 공백이 들어온다. 따라서 사이즈 3일 때의 둘째줄은 다음과 같이 만들어진다.

('|' if d in masks[1] else ' ') + ' ' * s + ('|' if d in masks[2] else ' ')

그리고 이렇게 만들어지는 세로선은 사이즈 값만큼 반복하여 라인을 만들어야 한다. 사이즈 3인 경우에는 2,3,4 번 줄이 같은 내용을 반복 출력한다.
이후 가운데 가로선과, 다시 아래쪽 세로선, 마지막으로 바닥자리 가로선을 같은 식으로 표시한다.

정리

한 번에 한 글자에 대해서 한줄씩 문자열을 만드는 방법을 알아보았으니, 이번에는 여러 글자를 출력할 때 한줄은 어떻게 만드는지에 대해서 알아보자. 이미 모든 글자는 같은 규격으로 생성되며, 매번 줄을 만드는 방법을 알았다. 따라서 여러 글자의 경우에는 각 글자에서 해당줄의 문자열을 생성하고 공백으로 구분하여 하나로 합치면 된다. 이는 str.join() 을 이용하면 된다. 출력해야하는 숫자 문자열을 digits 라고 하면, 해당 코드는 리스트 축약을 통해서 손쉽게 표현할 수 있다.

## 가로줄
' '.join(
    [(' ' + ('-' if d in mask[0] else ' ') * s + ' ') for d in digits]
}
## 세로줄
' '.join(
    [('|' if d in mask[1] else ' ') + ' ' * s + ('|' if d in mask[2] else ' ')\
     for d in digits]
)

이렇게 각 줄을 생성하여 리스트에 담고 개행문자를 끼워서 하나로 합치면 출력해야하는 최종 문자열이 완성된다. 이제 코드를 정리해보자.

def make_presentation(digits, s=1):
  masks = ("02356789", "045689", "01234789", 
           "2345689", "02689", "013456789", "0235689")
  result = []  
  ## 윗줄
  result.append(' '.join([' '+('-' if d in masks[0] else '-') * s + ' '\
                          for d in digits]))
  ## 위쪽 세로줄
  for _ in range(s):
    result.append(' '.join([ ('|' if d in masks[1] else ' ') + ' ' * s +\
                             ('|' if d in masks[2] else ' ') + ' '\
                            for d in digits]))
  
  ## 가운데 가로줄
  result.append(' '.join([' '+('-' if d in masks[3] else '-') * s + ' '\
                          for d in digits]))
  ## 위쪽 세로줄
  for _ in range(s):
    result.append(' '.join([ ('|' if d in masks[4] else ' ') + ' ' * s +\
                             ('|' if d in masks[5] else ' ') + ' '\
                            for d in digits]))
  ## 바닥줄
  result.append(' '.join([' '+('-' if d in masks[6] else '-') * s + ' '\
                          for d in digits]))
  return '\n'.join(result)
def main():
  digits, size = input().split()[:2]
  size = int(size)
  print(make_presentation(digits, size))

정리

중복되는 복잡한 코드가 너무 많아서 이를 별도의 람다식으로 빼내었다.

댓글 남기기