(엔지니어를 위한) 파이썬 시작하기[4]
내용 : 입력, 출력 input, 형변환, print, 포맷팅
https://docs.python.org/ko/3/tutorial/inputoutput.html
0.시작하며
지금까지 만들어본 파이썬 코드는 입력을 하드코딩했다. 즉 코드 안에 값을 넣어서 프로그램을 만들었다. 예를 들어 어떤 숫자 두개의 합을 구하는 기능을 만들었다면 숫자 두개를 코드 안에 직접 넣어 놓으면 다른 숫자에 대해서 프로그램을 실행시키려면 코드를 열어서 소스를 고쳐야 한다. 프로그램의 수정 없이 상황에 따라서 다른 값들을 입력하고 그에 대한 결과를 받아볼 수 있도록 프로그램을 만들어야 재사용성이 높아진다. 프로그램을 만들 때 재사용성을 높게 하는 것은 효율적 측면에서 매우 중요하다.
사실 프로그램은 입력 → 계산 → 출력 이렇게 이루어진다. 프로그램에 어떤 값을 입력해주는 방법은 다양하다. 그래픽 화면을 이용해서 입력해줄 수도 있고(사실 윈도우 프로그램은 대부분 이방법을 쓴다고 봐야한다) 텍스트화면 환경에서 입력을 해줄 수도 있고, 입력데이터를 파일에다 넣어서 입력해줄 수도 있다(입력사항이 많을 때는 이 방법이 편할 것이다).
출력도 마찬가지다. 그래픽화면에 계산결과를 출력할 수도 있고, 텍스트화면으로 출력할 수도 있고, 계산 결과를 파일로 저장할 수도 있다.
그래픽 화면에서 입력을 받고 결과를 출력하는 방법, 파일로 입출력하는 방법은 나중에 따로 다루기로 하고 오늘은 텍스트 화면에서 입력받고 출력하는 방법에 대해서 다루고자 한다.
※점프투 파이썬에서는 4장에서 함수를 다루었는데 함수는 나중에 따로 다루기로 하겠다.
1. input문
텍스트 화면상에서 어떤 값 2개를 입력하면 더한 결과를 출력해주는 프로그램을 만들어보자.
텍스트편집기를 열고(필자는 notepad++를 썼다) 아래와 같이 입력하고 input_test.py라는 이름으로 저장하다. 필자는 d:\dev\python이라는 디렉터리에 저장했다.
# input_test.py
a = input("Enter a: ")
b = input("Enter b: ")
print(a+b)
첫번째 줄의 #는 comment처리하라는 뜻이다. 즉 #뒤쪽은 무시된다. 프로그램 실행에 영향을 미치지 않고 프로그램 만드는 사람이 설명 등을 기입할 때 쓴다.
input문이 두번 쓰인 걸 볼 수 있다. a=input(“Enter a: “) ← 이 문장은 화면에 “a: “를 표시하면서 입력받을 준비를 한다. 사용자가 값을 입력하고 엔터키를 누르면 그 값을 a라는 변수에 넣는다. b도 마찬가지다. 그리고 print(a+b)는 a+b의 결과를 출력하는 문장이다.
우리가 원하는대로 작동하는지 실행해보자. 실행은 input_test.py가 있는 디렉터리에서 python input_test.py라고 입력하면 된다. 실행하면 Enter a: 라는 문구를 볼수 있다. 이때 10을 입력해보자. 그러면 Enter b: 가 보일 것이다. 20을 입력해보자. 이렇게 두 값을 입력하면 바로 1020이 출력된다.
(base) D:\dev\python>python input_test.py
Enter a: 10
Enter b: 20
1020
(base) D:\dev\python>
이건 뭔가? 우리는 30을 기대했다. 10+20=30 아닌가? 1020은 뭔가?
이렇게 된 이유는 파이썬에서 input()으로 입력받는 결과는 문자로 인식된다는 것이다. 그래서 문자 ‘10’과 문자 ‘20’을 더한(연결한) 결과인 ‘1020’이 출력되는 것이다.
input문을 쓸 때 꼭 기억해야 할 것은 입력받는 것은 문자로 인식된다는 것이다.
(엔지니어를 위한) 파이썬 시작하기[2]편에서 숫자와 문자의 차이를 설명한바 있다. 문자 ‘10’은 숫자 10과 다르다. 그래서 우리가 원하는대로 프로그램이 작동하도록 하려면 형변환을 해야 한다. 형변환은 형을 바꾼다는 것이다.
형변환
형변환은 프로그래밍에서 중요한 기능이다. 여기서는 형변환 함수 중 몇개만 소개하겠다.
int(‘10’) : 문자를 정수로 변환한다. 소수점 이하가 없다.
float(‘10’) : 문자를 실수로 변환한다. 소수점 이하가 있다.
str(10.123) : 숫자를 문자열로 변환한다.
bool(1) : 참,거짓으로 변환한다.
형변환을 테스트해보기 위해서 python 인터프리트 환경을 실행시키고 다양하게 테스트해보자.
(base) D:\dev\python>python
Python 3.9.7 (default, Sep 16 2021, 16:59:28) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> int('10')
10
>>> int('10.1')
Traceback (most recent call last):
File "", line 1, in
ValueError: invalid literal for int() with base 10: '10.1'
정수로 변환하는 int()함수에 ‘10.1’이라는 문자열을 넣었더니 에러가 발생했다. 소수점 이하가 있기 때문에 정수가 아니라는 것이다.
>>> float('10.1')
10.1
>>> float('10')
10.0
>>>
정수로 변환해주는 float()함수는 소수점 이하가 없는 ‘10’을 입력해도 10.0이라는 결과를 돌려준다.
>>> str(10.1)
'10.1'
>>> str(10.112345)
'10.112345'
>>> str(10.11234534567890)
'10.1123453456789'
>>> str(10)
'10'
>>> str(10.0)
'10.0'
>>>
숫자를 문자열로 바꿔주는 str()함수를 테스트해보자. 입력한 수자 값 그대로 문자열로 변환되는 것 알 수 있다.
자 이제 input()문으로 입력 받는 값을 더하는 프로그램을 수정해보자.
첫번째 방법은 입력받은 a와 b를 그대로 두었다. a와 b는 여전히 문자열 형식이다. 그리고 int()함수를 적용해서 정수로 변환된 값은 aa, bb에 각각 할당했다. 그리고 print()문도 aa와 bb를 더한 결과를 출력하도록 했다.
# input_test0.py
a = input("a: ")
b = input("b: ")
aa = int(a)
bb = int(b)
print(aa+bb)
수정을 마치고 input_test0.py라는 이름으로 저장한 다음 실행한 후 10과 20을 입력하면 30이 제대로 출력되는 것을 확인할 수 있다.
(base) D:\dev\python>python input_test0.py
a: 10
b: 20
30
(base) D:\dev\python>
프로그램이 2줄 추가되었는데 aa와 bb를 따로 만들지 않고 입력한 결과를 직접 정수형으로 변환하기 위해서 아래와 같이 코딩할 수도 있다. 수학에서와 마찬가지로 프로그램에서도 가장 안쪽의 괄호 먼저 실행된다고 생각하면 된다. int()함수가 실행되기 전에 그 안쪽에 있는 input()함수가 먼저 실행된다. input()함수의 결과(사용자가 입력한 문자열)에 대해서 int()함수가 실행된다. 같은 기능이지만 구현하는 방법은 여러가지다. 마음에 드는 방법을 적용하면 된다.
# input_test1.py
a = int(input("a: "))
b = int(input("b: "))
print(a+b)
2. print문
이전 편들에서도 print문을 써왔었다. 문자나 값을 출력하는 용도로 써왔다. 이제 print문에 대해서 조금더 깊이 들어가보자. 파이썬 인터프리터 상태에서 다양한 print문을 시도해보자.
(base) D:\dev\python>python
Python 3.9.7 (default, Sep 16 2021, 16:59:28) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> print('a' 'b' 'c')
abc
>>> a=1
>>> b=2
>>> c=3
>>> print( a b c)
File "", line 1
print( a b c)
^
SyntaxError: invalid syntax
>>> print( a, b, c)
1 2 3
>>> print( 'a:',a, b, c)
a: 1 2 3
>>> print( 'a=', a, 'b=', b, 'c=', c)
a= 1 b= 2 c= 3
>>>
문자열들을 공백으로 구분해서 나열하면 열결되서 출력된다.
그렇다면 a,b,c 변수에 값을 할당하고 공백으로 구분해서 출력하면 어떻게 될까?
>>> a=1
>>> b=2
>>> c=3
>>> print( a b c)
File "", line 1
print( a b c)
^
SyntaxError: invalid syntax
문법에러가 발생한다. 변수들은 값들이기 때문에 연결될 수가 없다. 그래서 아래와 같이 ,로 구분해서 출력해야 한다.
>>> print( a, b, c)
1 2 3
1,2,3이라고만 출력되는 것보다 a=1. b=2. c=3이라고 출력되도록 하고 싶다면 어떻게 할까? a,b,c 각각의 앞에 ‘a=’, ‘b=’, ‘c=’이라는 문자열을 넣고 ,로 구분하면 된다.
>>> print( 'a=', a, 'b=', b, 'c=', c)
a= 1 b= 2 c= 3
a,b,c를 각각 다른 줄에 쓰고 싶다면 문자열 안에 ‘\n’를 입력한다. 문자열 안의 ‘\n’는 new line을 뜻한다. 이 표시를 만나면 다음줄로 이동한다고 보면 된다.
>>> print( 'a:',a, '\nb:',b, '\nc:',c)
a: 1
b: 2
c: 3
>>>
문자열 포맷팅(formating)
프로그램의 출력은 최종 결과를 사용자에게 보여주는 것이기 때문에 입맛에 맞게 조정할 수 있어야 한다. 그래서 파이썬에서는 문자열 포맷팅이라는 기능을 지원한다.
아래와 같이 nm와 ag, th라는 세개의 변수에 각각 문자열과 정수,실수가 들어있다고 하자.
nm='HongGilDong'
ag = 20
ht = 178.5
%포맷팅
문자열 안에 %표시를 이용해서 변수값을 대입해주는 기능이다.
위의 3개에 들어있는 변수의 값들을 포맷에 맞게 출력하기 위해서 %포맷팅을 적용해보자.
>>> print('name: %20s age: %10i height: %10.3f' % (nm, ag,ht))
name: HongGilDong age: 20 height: 176.500
형식은 이렇습니다.
문자열 % (변수들)
문자열안에는 %로시작하는 자료형이 들어간다. 자료형은 정수(%i 또는 %d), 실수(%f), 문자열(%s) 등을 사용할 수 있다. %자료형과 뒤에 나오는 변수들의 갯수는 일치해야 한다. 그리고 형식도 일치해야 한다. 변수들이 순서대로 문자열 안의 %자료형에 대입되어 출력된다.
%20s 는 폭 20에 문자열을 출력하라.
%10i 는 폭 10에 정수를 출력하라.
%10.3f 는 폭 10에 소수점 이하 3자리의 실수를 출력하라. 폭 값이 실제 폭보다 작은 경우 무시된다.
format함수를 이용한 포맷팅
%를 이용한 포맷팅과 큰 차이는 없다. 문자열 안에 %대신 {}를 쓰는 것과 문자열과 변수들 사이에 %대신 .format이라는 함수명(메소드명)을 써주는 것만 차이가 있다.
>>> print('name: {} age: {} height: {}'.format(nm, ag,tl))
name: HongGilDong age: 20 height: 176.5
변수의 형을 지정하려면 (문자열):s, (정수):d, (실수):f를 써준다.
>>> print('name: {:s} age: {:d} height: {:f}'.format(nm, ag,tl))
name: HongGilDong age: 20 height: 176.500000
tl변수가 176.500000로 나온 것을 볼 수 있습니다. 소수점 자리수를 지정하기 위해서 %포맷팅에서와 같이 .뒤에 자리수를 써준다.
>>> print('name: {:s} age: {:d} height: {:.3f}'.format(nm, ag,tl))
name: HongGilDong age: 20 height: 176.500
%와 마찬가지로 차지하는 폭을 지정할 수 있습니다. s,d,f 문자 앞에 자리수를 써준다.
>>> print('name: {:10s} age: {:6d} height: {:10.3f}'.format(nm, ag,tl))
name: HongGilDong age: 20 height: 176.500
format()함수를 이용한 포맷팅에서는 순서를 바꾸거나 이름을 줄 수 있는 장점이 있다.
>>> print('name: {1} age: {0} height: {2}'.format(ag,nm,tl))
name: HongGilDong age: 20 height: 176.5
format(ag,nm,tl)인 점을 주목하자. 순서가 두번째가 nm이다. 즉 이름이 들어있다. 그래서 문자열에 {1}라고 썼다. 1은 두번째 즉 nm이 대입되는 것을 뜻한다.
변수명과 다른 이름을 줘서 대입할 수도 있다. 순서를 신경쓰지 않고 포맷팅을 할 수 있을 것이다.
>>> print('name: {name} age: {age} height: {height}'.format(height=tl,age=ag,name=nm))
name: HongGilDong age: 20 height: 176.5
format()안을 주목하자. height=tl,age=ag, name=nm 이렇게 각 변수마다 별도의 키워드를 지정했다. 그리고 그 이름이 들어가야 할 곳에 {name}, {age}, {height}로 지정했다. 순서는 관계가 없어서 편하다.
f-string을 이용한 포맷팅
앞의 포맷팅보다 나중에 나온 방법으로 가장 진보된 방법으로 볼 수 있다. 앞의 방법과 다른 점은 문자열 안에 직접 변수명을 쓸 수 있다는 것이다. 앞의 내용을 f-string포맷팅으로 처리해보자.
print(f'name: {nm} age: {ag} height: {tl}')
name: HongGilDong age: 20 height: 176.5
기본적인 형식은 f’문자열’이다. 그리고 문자열 안에 { }안에 변수명을 직접 쓸 수 있다. 자리수를 주는 방법과 형식을 지정하는 방법은 이전의 %포맷팅이나 format()함수를 이용한 포맷팅 방법과 동일하다.
>>> print(f'name: {nm:10} age: {ag:6d} height: {tl:10.3f}')
name: HongGilDong age: 20 height: 176.500
사실 input문은 실제 프로그램에서 쓸 일이 그렇게 많지 않다. 하지만 print문은 최종 성과물을 만드는 것이라서 포맷팅 방법에 대한 것들을 잘 알아두는 것이 좋다. 이번에는 화면에 출력하는 것만 예를 들었지만 파일에 쓸 때도 열을 맞추거나 소수점 자리수를 정해서 출력해야할 때도 포맷팅은 유용하다.
다음 시간에는 파일 입력과 출력에 대해서 공부하겠다.