programming

파이썬 임의의 숫자를 입력받아 * 별 출력하기와 사용자 입력 예외처리 하기


by Kitle · 2020. 07. 08.



입력 예시

임의의 숫자를 입력받아 5 이면

*

**

***

****

*****


4 면 

*

**

***

****

를 출력하라.

for문을 이용하여 출력하시오.


라는 문제는 프로그래밍 단골 퀴즈죠. 이를 한번 풀어보고 예외처리도 해보겠습니다.


우선 입력한 숫자 만큼 한줄씩 반복 출력을 해 봅시다.

for i in range(1, 6):
    print(i)


한줄에 한개씩은 출력할 수 있습니다.

그렇다면 첫줄에 *, 두번째 줄에 ** 면 어떻게 될까요?

결국 수학적으로 규칙을 찾으면 됩니다. 어떻게 보면 구구단과 매우 유사한 패턴임을 볼 수 있습니다.


파이썬의 장점 중 하나는 상상한대로 그냥 바로 해보는 게 잘 될 때도 있습니다. 그만큼 고급 프로그래밍 언어와 인간 친화적 언어에 가깝다는 뜻도 되겠지요.


즉 '*' 문자열만큼을 현재 행(1~5) 만큼 곱하면

첫재줄에는 *, 두번째 줄에는 ** 이 나오지 않겠습니까?


산술적으로 1*2 = 2가 가능합니다.

일반적인 프로그래밍 언어에서 사칙연산은 '숫자'에 한정되는 경우가 많고, 문자열에 *곱하기 연산등을 시도하려고 하면 에러가 나는 경우가 있습니다.

하지만 파이썬에서는 '*' 문자열에 곱하기 연산이 가능합니다. 

이점이 아주 유용하죠.


for i in range(1, 6):
    print(i * '*')


한번 출력해보세요.


-결과부분-
*
**
***
****
*****
Process finished with exit code 0


가 정상적으로 출력 되었을 겁니다.


이제 입력 부분을 추가해볼까요?


print('input : ', end="")
user_input = input()
for i in range(1, user_input+1):
    print(i * '*')


로 수정해 봅니다.

1부터 사용자가 입력한 숫자까지 출력해보겠습니다.


-결과 부분 에러 출력-
input : 1
Traceback (most recent call last):
  File "/Users/kiyeongjeong/Documents/KY/python/crawlingenv/src/print_star.py", line 3, in <module>
    for i in range(1, user_input+1):
TypeError: can only concatenate str (not "int") to str


하지만 에러가 출력되는 군요.

사용자 입력부분이 str 즉 문자열로 받아들여져 range 범위에 적용되지 못했습니다.

명시적으로 int 라고 알려줘 보겠습니다.


print('input : ', end="")
user_input = input()
for i in range(1, int(user_input)+1):
    print(i * '*')


을 실행하여 숫자 1을 입력해 보겠습니다.

와우 * 이 한개 잘 출력 되네요.

여기까지가 바로 Happy case 였습니다.


자 그럼 다음시간에 뵙겠... 잠깐!!!


사용자가 1이 아니라 'alskdjalksdj' 를 입력한다면...????

프로그램은 에러를 뿜고 종료될겁니다.


에이.. 숫자 입력하라고 분명 말했는데.. 백날 소용 없습니다.

우리의 사용자들은 시키는대로 행동하지 않습니다.


그렇기 때문에 올바르지 않은 사용자 입력 처리(에러처리)를 얼마나 잘 해두느냐가 퀄리티 있는 SW를 보장하는지가 달려있습니다.


처리방법은 여러가지가 있습니다. 나중에 UI를 입혀서 숫자를 선택하게 하는 방법.

입력 부에 숫자가 아닌 부분이 들어오면 자동으로 에러를 표시하게 하는 방법.

등 UI에서 처리할 수 있는 부분이 있고,

그렇다고 하더라도 프로그램 내부에서는 어떻게든 뚫고 잘못된 값이나 없는 값을 받는 경우도 생깁니다.

여기서는 코드에 대해서 처리를 해보겠습니다.


첫번째 사용자의 입력 범위를 숫자로 제한하기.

print('input : ', end="")
user_input = input()
if user_input.isdigit() is True:
    for i in range(1, int(user_input)+1):
        print(i * '*')
else:
    print('입력 조건이 맞지 않습니다. 숫자만 가능합니다.')

이렇게 입력된 문자열을 .isdigit() 로 검사하여 숫자만 있다면 진행, 아니면 진행하지 않을 수 있습니다.


여기서 끝... 났으면 좋겠지만..


숫자 0 또는 엄청나게 큰 수를 입력한다면 어떨까요? 당연히 에러가 나겠죠?


그래서 보통 범위 제한을 하는 경우가 있습니다.

1부터 100까지만 허용하도록 하지요.


print('input : ', end="")
user_input = input()
if user_input.isdigit() is True:
    if 0 < int(user_input) < 101:
        for i in range(1, int(user_input)+1):
            print(i * '*')
    else:
        print('입력 범위를 벗어났습니다. 1~100 가능합니다.')
else:
    print('입력 조건이 맞지 않습니다. 숫자만 가능합니다.')


if 문으로 범위를 넣어 할 수 있습니다. 코드가 벌써 지저분해졌네요.


사용자 입력 받는 부분은 사실 print 쓸필요 없이 input 의 파라메터로 처리 가능합니다. 간결한 문법을 모르면 이렇게 됩니다 ㅠ.ㅠ  다시 정리해보겠습니다.

user_input = input('Enter a number: ')
if user_input.isdigit():
    user_input_number = int(user_input)
    if 0 < user_input_number < 101:
        for i in range(1, user_input_number+1):
            print(i * '*')
    else:
        print('입력 범위를 벗어났습니다. 1~100 가능합니다.')
else:
    print('입력 조건이 맞지 않습니다. 숫자만 가능합니다.')


이제 마지막 수정을 해보겠습니다. 사용자 입력 오류를 최소화 하기 위해서는 가이드를 먼저 해주는 것이 좋습니다. 변경해볼게요.

user_input = input('숫자만 입력해주세요(1~100): ')
if user_input.isdigit():
    user_input_number = int(user_input)
    if 0 < user_input_number < 101:
        for i in range(1, user_input_number+1):
            print(i * '*')
    else:
        print('입력 범위를 벗어났습니다. 1~100 가능합니다.')
else:
    print('입력 조건이 맞지 않습니다. 숫자만 가능합니다.')

이제 좀 더 쓰기 편해졌네요.

if 문이 두개 이기 때문에 and 조건으로 묶으면 좋지 않겠냐 생각할 수도 있습니다.

그래도 상관은 없지만, 여기서는 숫자 범위가 벗어난 경우 안내와, 입력 조건의 안내를 따로따로 출력해주기 위해서 나누어 두었습니다.

상황에 맞게 사용하시기 바랍니다.