전체 글 (15)

나약한 공대생. 공대생 맞나? 공대생 아닌 것 같음.

━━━━ ◇ ━━━━
따라하며 배우는 파이썬과 데이터 과학/PART 1. 파이썬 기초체력 다지기

Chapter 06. 함수로 일처리를 짜임새있게 하자

이번 시간의 목차

1. 프로그램에서의 함수란?

2. 함수를 만들어보자!

3. 함수에게 값을 주고 돌려받자!

4. 함수 속 변수는 밖에서도 계속 쓰일 수 있을까?

5. 여러 종류의 인자

6. 나를 불러 줘! 재귀함수

7. 함수를 저장하고 싶다면 모듈을 만들자!

8. 마무리

 

 

자, 가자! 파이썬의 세계로!


 

프로그램에서의 함수란?

 

 함수(Function)은 우리가 반복적으로 사용하는 코드를 묶은 것으로, 코드 덩어리라고도 볼 수 있다. 우리가 앞 장에서 만든 코드보다 더 큰 프로그램을 만들 때, 이 함수를 쓰지 않고 일일이 동일한 코드를 여러 줄 반복하게 된다면 어떨까? 늘 그렇지만 프로그램은 간결할 수록 좋다. 당연히 길어지면 쓰는 사람도 읽는 사람도 힘들어질 수밖에 없다. 

 

 함수 말고도 프로그램을 작게 쪼개는 방법이 2가지 더 있다. 

  • 객체(Object): 코드 중에서 독립적인 단위로 분리할 수 있는 조각
  • 모듈(Module): 프로그램의 일부를 가지고 있는 독립적인 파일

 이번 장에서는 우선 함수에 대해서 먼저 알아보려고 한다. 

함수라는 이름 자체는 이미 많이 들어봤을 것이다. 현재 중학교 2학년 1학기 즘이면 수학에서 '일차 함수' 단원을 배운다. 

 

 

 이렇게 함수는 입력을 받아서 출력을 내보내는 것으로 생각할 수 있다. 함수 속 식(코드)는 바뀌지 않고, 입력 받는 값과 출력 값만 바꾸는 것이다. 

 

 


 

함수를 만들어보자!

 

 함수를 만들려면 파이썬의 키워드 중 def를 사용하면 된다. 아이엠그라운드 게임의 대사로 예시를 살펴보자. 

 첫째 줄 def Iamground() : 에서 def 키워드를 이용하여 함수를 정의한다. def의 뒤로는 함수의 이름을 적고, 소괄호()와 콜론 :을 붙인다. 이때 소괄호 속에 들어가는 것은 매개변수(Parameter)로, 이해하기 쉽게 설명하자면 수학 함수 f(x)에서 x와 같은 역할이다. 위의 Iamground() 함수에서는 매개변수를 사용하지 않지만, 매개변수를 x로 두고 x에 관한 코드를 짜 놓으면, 나중에 사용할 때 매개변수 자리에 넣은 값, 즉 인자(Argument)가 x에 관한 코드 속 x에 들어가서 해당 값에 대한 출력값을 출력하게 된다. 콜론은 앞 장에서 설명해서 알겠지만, 한 블록이 시작된다는 뜻을 가진다. 블록이 시작되면 항상 같은 깊이만큼 들여쓰기를 해야 한다. 키보드의 Tab 버튼을 이용하면 동일한 깊이만큼 들여쓰기가 되니 되도록이면 Tab을 이용한 들여쓰기를 하자. 

 

 그럼 이렇게 함수를 정의하기만 하면 실행이 되는 것일까? 

아니, 함수 속 코드를 실행하려면 함수를 호출해야 한다. 함수 호출(Function Call)은 간단하다. 위에서 설정한 함수이름(인자)를 적어주면 된다.

 

 그런데 Iamground() 속 여섯 문장은 그냥 print() 함수로도 충분히 출력할 수 있지 않나?

물론 그렇게 할 수도 있지만, 함수를 한 번 정의해 놓으면 언제든지 필요할 때마다 함수를 불러 일을 시킬 수 있기 때문에 일일이 print()로 출력하는 것보다 더욱 편리해진다. 

 

 조금 전에는 매개변수와 인자를 사용하지 않은 함수를 예시로 들어보았다. 그러면 이제는 매개변수와 인자를 한 번 써 보자. 

위의 Iamground() 함수에서는 아이엠그라운드 게임 참가자들의 과일 이름이 정해져있었다. 매개변수와 인자를 사용하면 내 차례에 올 과일만 바꿔서 출력할 수 있을 것이다.

 

>>> def Iamground(fruit) :    #매개변수는 fruit이다.
    print('아이엠그라운드 자기소개 하기')
    print('나는 사과')
    print('나는 딸기')
    print('나는 포도')
    print('나는', fruit)
    print('아이엠 그라운드 지금부터 시작')
 
    
>>> Iamground('귤')           #인자로 '귤'을 넣었다.
아이엠그라운드 자기소개 하기
나는 사과
나는 딸기
나는 포도
나는 귤                       #fruit 자리에 '귤'이 들어간다.
아이엠 그라운드 지금부터 시작
cs

 

 매개변수를 fruit로 두고 인자를 '귤'로 넣었더니 내 차례에 귤이 들어온 것을 볼 수 있다. 


 

함수에게 값을 주고 돌려받자!

 

 함수에 값을 주면 우리에게 결과를 보내주기도 한다. 이때 함수가 돌려주는 값을 반환 값(Return Value)이라고 한다. 함수 속에서 만들어진 값을 돌려 받으려면 return 키워드를 사용하면 된다. 원의 반지름을 넣으면 원의 넓이를 구해주는 함수를 만들어 보자.

 

>>> def circle_area(radius) :
    area = 3.14 * radius * radius
    return area
 
>>> c1_area = circle_area(6)
>>> c1_area
113.03999999999999
 
>>> area_sum = circle_area(6+ circle_area(4)
>>> area_sum
163.28
cs

 

 위의 circle_area(radius) 함수는 radius를 매개변수로 두고 인자로 받은 6을 radius 자리에 넣어서 원의 넓이를 구해서 반환해준다. 이 반환 값은 변수에 저장할 수 있다. 변수에 저장할 수 있으므로 이 반환 값 또한 데이터다. 이 함수가 수행한 결과를 더할 수도 있다. 

 

 동시 할당문을 기억하고 있는가? 한 번에 여러 변수에 여러 값을 넘겨주는 할당문인데, 이 함수에서도 인자로 한 번에 여러 값을 넘겨줄 수 있다. 이때 인자의 개수와 매개변수의 개수가 같아야 한다. 다르면 오류가 발생하게 된다. 

 

 또 함수로는 여러 개의 값을 돌려받을 수 있다. 

 

>>> def sort_num(x, y) :
    if x > y :
        return x, y
    else :
        return y, x
 
    
>>> print(sort_num(518), sort_num(2516))
(185) (2516)
cs

 

 이렇게 조건에 따라 각각 값을 받을 수도 있고, 

 

>>> def calculate(x, y) :
    return x + y, x - y, x * y, x / y #사칙연산 결과를 반환
 
>>> x, y = 350210
>>> a1, a2, a3, a4 = calculate(x, y)
>>> print(x, '+', y, '=', a1)
350 + 210 = 560
>>> print(x, '-', y, '=', a2)
350 - 210 = 140
>>> print(x, '*', y, '=', a3)
350 * 210 = 73500
>>> print(x, '/', y, '=', a4)
350 / 210 = 1.6666666666666667
cs

 

 동시 할당문을 이용해 한 번에 여러 값을 넘겨줄 수도 있다. 


 

함수 속 변수는 밖에서도 계속 쓰일 수 있을까?

 

우리는 앞에서 변수에 대해서 다룬 적이 있다. 변수는 어디에서나 쓰이는 만큼 함수 속에서도 쓰이는데, 그렇다면 한 가지 의문이 들 것이다. '함수 속에서 선언한 변수는 함수 밖에서도 적용이 되는가?'  궁금하면 직접 해 보는 것이 답이다. 한 번 해보자.

 

>>> def my_age() :
    age = 19
    print('age =', age)
 
    
>>> age = 20
>>> my_age()
age = 19
>>> print(age)
20
cs

 

 my_age() 함수에서 age라는 변수에 19라는 값을 저장해둔 뒤에 바깥에 있는 age 변수에 20이라는 값을 담았다. 

my_age() 함수를 출력할 때는 age가 19로 나오지만, 정작 age만 출력해 보면 따로 설정한 20이라는 값이 나온다. 이렇게 함수 속에서 선언한 변수가 밖에서도 적용되지 않는 것은 함수 속 변수가 지역변수(Local Variable)로, 밖에서 전체적으로 사용하는 변수 전역변수와는 별개의 메모리에 존재하기 때문이다. 지역변수는 함수가 종료되면 그대로 사라지는 변수다. 

 

 그렇다면 함수 속에서 선언한 변수를 밖에서도 계속 쓸 수는 없을까? 

왜 안 될까? 당연히 할 수 있다! global이라는 키워드를 사용하면 된다. 

def my_age() :
    global age
    age = 19
    print('age =', age)
 
age = 20
my_age()
print(age)
 
= RESTART: ................. 
age = 19
19
cs

 

 'global age' 는 함수 바깥의 전역변수 age를 사용하겠다는 선언이다. 그래서 위처럼 age = 20이라고 선언한 뒤 함수를 실행하면 age = 20이 age = 19로 덮어씌워지기 때문에 my_age()의 age도 19이고, age를 출력해도 19로 출력된다. 

 

 전역변수를 사용하면 함수가 끝나고 사라진 변수를 다시 선언할 필요가 없어지긴 하지만, 전역변수를 많이 사용하면 프로그램의 어느 부분에서 오류가 발생하였는가를 추적하기가 매우 어려워지기 때문에 전역 변수의 사용은 최소로 하는 것이 좋다. 

 


 

여러 종류의 인자

 

매개변수 자리에 인자를 하나하나 넣기 힘들 때는 함수의 매개변수에 기본값을 주면 된다. 이 기본값을 디폴트 인자(Default Argument)라고 한다. 예시로 햄버거 가게에서 주문을 받는다고 해 보자.

 

def burger(num, coke, fries) :
    print('햄버거 {}개 - 콜라 {}, 감자튀김 {}'.format(num, coke, fries))
 
burger(1TrueFalse)
 
= RESTART: ................. 
햄버거 1개 - 콜라 True, 감자튀김 False
cs

 

 이때 인자로 num, coke, fries에 해당하는 값을 넘겨주지 않으면 오류가 발생한다.  

 

>>> burger(1)
Traceback (most recent call last):
  File "<pyshell#63>", line 1in <module>
    burger(1)
TypeError: burger() missing 2 required positional arguments: 'coke' and 'fries'
cs

 

 하지만 매번 콜라와 감자튀김을 선택할지를 선택한다면 번거로울 것이다. 그러면 선택하지 않을 때만 따로 설정하도록 하면 어떨까? 키오스크를 조작해봤다면 쉽게 이해할 수 있을 것이다. 햄버거 세트 메뉴를 주문시키면 기본으로 햄버거 하나와 스몰 사이즈 콜라, 스몰 사이즈 감자튀김이 선택되고, 빼고 싶을 때만 따로 설정을 해주면 된다. 

 

 그렇다면 디폴트 인자를 활용해서 기본값으로 True를 넣어줄 수 있을 것이다. 

 

def burger(num, coke = True, fries = True) :
    print('햄버거 {}개 - 콜라 {}, 감자튀김 {}'.format(num, coke, fries))
 
burger(1)
burger(1, coke = False, fries = True)
 
= RESTART: ................. 
햄버거 1개 - 콜라 True, 감자튀김 True
햄버거 1개 - 콜라 False, 감자튀김 True
cs

 

 burger(1)에서 coke와 fries의 인자를 넣어주지 않았는데도 True로 나오는 것을 볼 수 있다. 

 

 이때 coke = False, fries = True라고 각각 매개변수와 인자를 매치시켜 두었는데, 이렇게 인자 앞에 키워드를 붙인 인자를 키워드 인자(Keyword Argument)라고 한다. 함수를 호출할 때 인자의 이름을 명시적으로 지정해서 전달하는 것이다. 이렇게 키워드 인자를 설정하면 인자가 많을 때 인자의 의미를 헷갈릴 일을 줄인다. 또, 키워드 인자를 사용하면 인자의 순서를 바꿔 넣어도 알아서 매개변수와 인자를 맞추어 출력한다. 

 

def burger(num, coke = True, fries = True) :
    print('햄버거 {}개 - 콜라 {}, 감자튀김 {}'.format(num, coke, fries))
 
burger(coke = True, num = 3)
burger(True1False)
 
= RESTART: ................. 
햄버거 3개 - 콜라 True, 감자튀김 True
햄버거 True개 - 콜라 1, 감자튀김 False
cs

 

 burger(coke = True, num = 3)에서는 num과 coke의 자리를 바꾸고 fries에 대한 인자를 생략했다. 그런데도 햄버거는 3개, 콜라는 포함하고, 감자튀김도 포함해서 출력된다. 

 

 그런데 키워드를 설정하지 않고 그냥 입력하면 def burger(num, coke, fries): 에서 설정한 num, coke, fries 순서대로 인자가 부여되기 때문에 맞지 않는 출력이 나온다. 이런 인자 전달 방식을 위치 인자(Positional Argument)라고 한다. 주의해야 할 점이 하나 있다. 키워드 인자 뒤로 위치 인자가 나올 수는 없다. 이는 파이썬의 문법 중 하나이므로 키워드 인자 뒤로 위치 인자를 넣어 버리면 오류가 난다. 

 

>>> burger(coke = False3)
SyntaxError: positional argument follows keyword argument
cs

 


 

나를 불러 줘! 재귀함수

 

 재귀함수(Recursion)란 함수 내부에서 자기 자신을 호출하는 함수를 말한다. 자기 자신을 불러 오면 뭐가 좋은가 싶을 수도 있지만, 재귀는 잘만 활용하면 매우 유용한 문제 해결 기법으로 처리 단계를 전부 기술하기 어려운 문제를 직관적이고 간단하게 해결할 수 있다. 

 

1! = 1
2! = 2 * 1
3! = 3 * 2 * 1
...
n! = n * (n-1* (n-2* ... * 2 * 1
----------------------------------------
def factorial(n) :                   #재귀함수를 이용한 팩토리얼 계산
    if n <= 1 :                      #종료 조건(1이 되면 곱을 멈춘다.)
        return 1
    else :                           #n이 1이 아닐 경우 
        return n * factorial(n-1)    #n에 (n-1)!을 곱한다. 
 
print('5! =', factorial(5))
----------------------------------------
5! = 120
cs

 

 재귀함수에서는 이 프로그램이 언제 종료되는가가 중요하다. 

위의 팩토리얼 예시에서는 n이 1 이하일 경우에는 팩토리얼을 정의할 필요가 없으므로 if 조건문에서 n이 1이하일 때 1을 반환하고 종료하게 된다. 이 조건문이 없으면... 프로그램은 무한 루프로 빠지게 될 것이다. 아래는 위의 factorial(5)의 재귀 절차를 그림으로 나타낸 것이다.

 

 


 

함수를 저장하고 싶다면 모듈을 만들자!

 

 프로그램이 간단한 경우에는 직접 함수를 호출하고 조합하는 것만으로 코딩할 수 있겠지만 복잡하고 길어지는 순간 그렇게 일일이 불러오고 조합하기 힘들어질 것이다. 좀 더 편안하고 간단한 코딩을 위해서 우리는 모듈(Module)을 활용할 필요가 있다. 

 

 우리는 이미 1장에서 모듈에 대해 간략하게 배운 적 있다. 복습 차 다시 설명하자면, 모듈은 파이썬 함수나 변수, 또는 클래스들을 모아 놓은 스크립트 파일을 말한다. 파이썬을 설치하면 기본적으로 제공되는 모듈을 파이썬 표준 라이브러리(Python Standard Library)라 한다. 이 외에도 여러 기관과 개발자들에 의해서 이미 많은 모듈이 만들어져 있고, 이 모듈을 활용하면 효과적으로 소프트웨어를 개발할 수 있다. 

 

 예시로 datetime 모듈을 한 번 불러와 보자. 

 

>>> import datetime
>>> datetime.datetime.now()
datetime.datetime(202161313459970593)
cs

 모듈을 불러오려면 import (모듈 이름)을 입력하면 된다. 여러 모듈을 불러오고 싶으면 쉼표 , 를 붙이고 모듈 이름을 더 써 주면 된다. 이때 datetime.datetime.now() 에서 맨 앞 datetime은 모듈 이름, 두 번째 datetime은 클래스, now()는 메소드이다. datetime이라는 모듈에 datetime이라는 클래스가 있어서 now()라는 기능(메소드)를 제공하는 것이다. 클래스와 메소드에 접근하려면 마침표 .를 붙여주면 된다.

 

 우리도 모듈을 한 번 만들어 보자.

 

#파일 이름은 Allsum.py 이다.
 
def Sum(num) :              #1부터 num까지의 수를 더하는 함수
    if num <= 1 :
        return 1
    else :
        return num + Sum(num - 1)
---------------------------------
 
>>> import Allsum as As     #as를 통해 모듈을 별명으로 부를 수 있다.
>>> As.Sum(100)
5050
 
---------------------------------
 
>>> from Allsum import Sum  #함수만 바로 불러올 수도 있다. 
>>> Sum(100)
5050
 
---------------------------------
 
>>> from Allsum import *    # *을 import하면 모든 함수를 불러올 수 있다.
>>> Sum(100)
5050 
cs

 

 예시로 1부터 num까지의 수의 합을 반환하는 함수를 만들어보았다. 

이 코드가 모듈로 활용되려면 저장을 해야 한다. 저장할 때 파일 이름이 곧 모듈 이름이 된다. 그러니 파일 이름도 무슨 기능들을 담은 것인지 한 눈에 알 수 있는 이름으로 설정하는 것이 좋다. 

 

 Allsum이라는 모듈 속 Sum(num) 함수를 사용하려면 Allsum.Sum(num) 형태로 호출하면 된다. 

모듈 이름이 너무 길거나 복잡할 때는 별명(Alias)를 지정하여 사용할 수도 있다. 별명을 지으려면 import할 때 모듈 이름 뒤로 as (별명)을 붙여주면 된다. 예시로는 import Allsum 뒤로 as As를 붙여 별명을 'As'로 지었다. 

 

 모듈 전체가 아닌 함수 각각을 가지고 오고 싶다면 from (모듈 이름) import (함수 이름)을 사용하면 된다. 이때 함수 이름 자리에 * 를 입력하면 모듈 내 모든 함수를 사용할 수 있게 된다. 

 


 

마무리

 이번 시간에는 함수를 만들고 이를 모듈로서 활용하는 법에 대해 알아보았다. 

마지막으로 심화문제 6.4와 6.6, 6.8을 풀어보고 마치도록 하자. 접은글 속의 해답 코드는 참고만 하자.

 

6.4 : n1, n2, n3이라는 이름의 매개변수를 3개 입력받아서 이 값들중에서 가장 큰 값과 작은 값, 두 개를 반환하는 max_and_min(n1, n2, n3) 함수를 구현하시오. 사용자로부터 임의의 정수 3개를 입력으로 받아서 이 함수를 호출하여 다음과 같은 출력을 내 보이도록 하라. 

 

3 수를 입력하시오 : 34 66 20
가장 큰 수 : 66
가장 작은 수 : 20
cs
더보기
n1, n2, n3 = map(int, input("3 수를 입력하시오 : ").split())  #세 수를 받고 한 번에 공백 단위로 분리한다.
 
def max_and_min(n1, n2, n3) :
    if n1 > n2 and n1 > n3 :   #n1이 가장 클 때
        if n2 > n3 :           #n2와 n3을 비교하여 최솟값을 찾는다. 
            return n1, n3
        else :
            return n1, n2
 
    elif n2 > n1 and n2 > n3 : #n2이 가장 클 때도 마찬가지
        if n1 > n3 :
            return n2, n3
        else :
            return n2, n1
 
    else :                     #n3이 가장 클 때도 마찬가지
        if n1 > n2 :
            return n3, n2
        else :
            return n3, n1
 
Max, Min = max_and_min(n1, n2, n3)  #최대/최솟값을 각각 변수에 담는다.
print("가장 큰 수 : ", Max)
print("가장 작은 수 : ", Min)
 
cs

 

 

6.6 : 임의의 수를 입력으로 받은 다음 이 수가 소수인지 아닌지를 판단하는 함수 is_prime(n)을 작성하여라. 만일 n이 소수이면 True, 그렇지 않으면 False를 반환하도록 하여라. (힌트: 소수는 1과 자기 자신 이외에는 약수를 가지지 않는다. 따라서 어떤 수 n을 2에서 n-1까지의 수로 나누어 보다 중간에 나누어 떨어지는 수가 있으면 이 수는 소수가 아닐 것이다.)

 

소수 검사를 할 정수를 입력하시오: 9677
소수인가요? : True
소수 검사를 할 정수를 입력하시오: 13
소수인가요? : True
소수 검사를 할 정수를 입력하시오: 4
소수인가요? : False
소수 검사를 할 정수를 입력하시오: 12347987345345
소수인가요? : False
 
 
cs
더보기
def is_prime(x) :
    for i in range(2, x) :      #2부터 x-1까지 아래를 반복한다. 
        if num % i == 0 :       #2부터 x-1까지 나누었을 때 나머지가 0이면 False를 반환
            return False
 
        else :                  #아니면 반복을 계속한다.
            continue
 
    return True                 #나머지가 0이 되는 수가 없으면 True를 반환한다.
 
num = int(input('소수 검사를 할 정수를 입력하시오 : '))
print('소수인가요? :', is_prime(num))
 
cs

 

 

6.8: 사용자로부터 x1, y1, x2, y2의 값을 받아들인 다음 (x1, y1)좌표에서 (x2, y2) 좌표를 잇는 직선의 거리를 출력하고자 한다. distance(x1, y1, x2, y2)를 구현하고 이 함수를 호출하여 다음과 같이 화면에 직선과 거리를 출력하도록 하여라. 

x1 : 4
y1 : 2
x2 : 2
y2 : 1
(4.02.0)과 (2.01.0) 사이의 거리는 2.23606797749979
cs
더보기
def distance(x1, y1, x2, y2) :
    distance = ((x1 - x2) ** 2 + (y1 - y2) ** 2** (1/2)
    return distance
 
x1 = float(input('x1 : '))
y1 = float(input('y1 : '))
x2 = float(input('x2 : '))
y2 = float(input('y2 : '))
 
= (x1, y1)
= (x2, y2)
print(A, '과', B, '사이의 거리는', distance(x1, y1, x2, y2))
 
cs
COMMENT
━━━━ ◇ ━━━━
따라하며 배우는 파이썬과 데이터 과학/PART 1. 파이썬 기초체력 다지기

Chapter 05. 여러 번 반복하는 일을 하자

이번 시간의 목차

1. 반복문이 뭐길래?

2. 정해진 횟수만큼 반복하자! for문

3. for문과 range() 함수는 천생연분!

4. 조건에 따라 반복하자! while문

5. 무한 루프를 제어해 보자, break와 continue!

6. 들쭉날쭉한 글씨는 포매팅으로 다듬자!

7. 마무리

 

 

자, 가자! 파이썬의 세계로!


 

반복문이 뭐길래?

 

 반복문이란 어떤 단계를 반복하게 하는 것으로, 반복문이 없다면 똑같은 문장을 여러 번 출력하고 싶을 때 Ctrl+c 후 Ctrl+v를 많이 써야 하는 불편함이 있고, 그렇게 똑같은 문장을 여러 번 쓰다 보면 보기에도 깔끔하지 않다. 반면, 반복 구조를 사용하면 반복적으로 수행하는 번거로운 작업을 간결하게 만들어 준다. 따라서반복문은 매우 중요한 제어문으로 쓰인다. 

 

 파이썬에는 두 가지 종류의 반복문이 있다. 

  • 횟수 제어 반복(for 문) : 횟수를 정해 놓고 반복한다.
  • 조건 제어 반복(while 문) : 특정한 조건이 만족되면 계속 반복한다.

 

 

 횟수 제어 반복은 반복할 횟수를 미리 아는 경우에 사용한다. 횟수는 꼭 숫자로만 이루어질 필요는 없고, 시퀀스(Sequence)를 가져와서 반복할 수도 있다. 시퀀스 자료형에는 리스트, 튜플, range, 문자열 등 값이 연속적으로 이어진 자료형이다. 시퀀스에 항목이 더 이상 없으면 반복이 종료된다. 예시로 든 range(5)라는 함수는 0, 1, 2, 3, 4의 숫자 시퀀스를 생성하는 함수로, for i in range(5)는 0에서 4까지의 숫자를 반환하는 작업을 끝낼 때까지 반복 실행된다. 

 

 조건 제어 반복은 조건에 따라 반복할 경우에 사용한다. 조건식은 이전 시간에 다루었듯이 최종적으로 True 또는 False 값을 가지는 문장이면 된다. 오른쪽에서 예시로 든 i = 0과 i < 5, i = i + 1은 i가 0으로 시작해서 블록을 반복할 때마다 'Hello Python!!'을 출력하고 i가 1씩 늘어나, 결국 i가 5 이상이 되면 반복을 멈추게 된다. 

 

 이런 반복을 프로그래밍에서는 흔히 동그란 고리를 의미하는 루프(Loop)라고도 한다. 프로그램이 반복해서 이전 단계로 돌아가는 모습이 동그라미를 그리는 것 같기 때문이다. 이 고리를 빠져나오지 않고 계속해서 반복하면 무한루프(Infinite Loop)라고 한다. 

 


 

정해진 횟수만큼 반복하자! for문

 

 for 루프는 반복할 횟수를 정해 두고, 이 횟수가 만족될 때까지 같은 동작을 반복한다. 우선 for 루프의 시퀀스로 리스트를 이용해 보자. 리스트는 대괄호 [...] 로 둘러싸인 값들인데, 이것은 7장에서 더 자세히 다룰 것이다. 지금은 고등학교 수학 시간에 배우는 집합과 비슷한 것이라고 이해하고 넘어가자. 

 

>>> for i in [12345] :
    print('즐거운 파이썬!')
 
    
즐거운 파이썬!
즐거운 파이썬!
즐거운 파이썬!
즐거운 파이썬!
즐거운 파이썬!
cs

 

 반복문의 끝에는 if문과 마찬가지로 콜론이 있어야 하고, 한 블록 안에는 무조건 들여쓰기가 똑같은 공백 수만큼 되어 있어야 한다. 위 코드에서 print('즐거운 파이썬!') 문장은 리스트에 있는 데이터의 개수만큼 반복된다. 반복되는 상황을 좀 더 자세히 볼까? 이번에는 print() 함수로 변수 i의 값도 확인해 보자.

 

>>> for i in [12345] :
    print('지금은', i, '가 반복할 차례!')
 
    
지금은 1 가 반복할 차례!
지금은 2 가 반복할 차례!
지금은 3 가 반복할 차례!
지금은 4 가 반복할 차례!
지금은 5 가 반복할 차례!
cs

 이렇게 시퀀스에 든 모든 항목의 차례가 지나면 반복이 종료된다. 

이번에는 시퀀스에 리스트가 아닌 문자열을 넣어보자. 

 

>>> for i in 'Apple' :
    print('지금은', i, '가 반복할 차례!')
 
    
지금은 A 가 반복할 차례!
지금은 p 가 반복할 차례!
지금은 p 가 반복할 차례!
지금은 l 가 반복할 차례!
지금은 e 가 반복할 차례!
cs

 똑같이 시퀀스에 든 모든 항목의 차례가 지나면 반복이 끝난다. 

조금 더 응용하면 이렇게 구구단도 만들 수 있다. 

 

>>> for i in [12345] :
    print('9 *', i, '='9 * i)
 
    
9 * 1 = 9
9 * 2 = 18
9 * 3 = 27
9 * 4 = 36
9 * 5 = 45
cs

 

for문과 range() 함수는 천생연분!

 

  방금은 리스트에 정수를 저장해두고 하나씩 꺼내 썼지만, 반복 횟수가 많아진다면 일일이 저장하고 꺼내 쓸 수 없다. 이런 때에는 range() 함수를 사용하면 편하다. 앞서 설명했듯, range(start, stop, step)은 start에서 시작하여 (stop - 1)까지 step 간격으로 정수들이 생성된다. start와 step 값은 생략할 수 있고, 생략할 경우 start는 0, step은 1로 간주된다. stop 값은 반드시 지정해야 한다.

 

 이해가 잘 되지 않으면 실제로 한 번 해 보자.

 

>>> for i in range(5) :    #0부터 4까지의 range
    print(i, end = ' ')    #end = ' '는 줄바꿈 대신 공백을 넣는다.
 
    
0 1 2 3 4 
>>> for i in range(18) : #1부터 7까지의 range
    print(i, end = ' ')
 
    
1 2 3 4 5 6 7 
>>> for i in range (0112) : #0부터 10까지 2씩 건너 뛴 range
    print(i, end = ' ')
 
    
0 2 4 6 8 10 
cs

 

 만약 10에서부터 1까지 1씩 감소하며 반복하고 싶다면 range(10, 0, -1)을 써 주면 된다.

 

>>> for i in range(100-1) :
    print(i, end = ' ')
 
    
10 9 8 7 6 5 4 3 2 1 
cs

 


 

조건에 따라 반복하자! while문

 

  조건 제어 반복은 어떤 조건이 만족되는 동안 반복하기 때문에 붙여진 이름이다. 반복되는 횟수를 알 수 없거나, 특별한 조건이 필요할 때에 쓰인다. 예시로 컴퓨터 사용을 위해 패스워드를 입력해야 한다고 하자. 입력한 패스워드가 미리 설정해둔 값과 일치하지 않는다면 일치할 때까지 입력을 요구해야 할 것이다. 

 

password = ''
while password == 'mycomputer' :
    password = input('암호를 입력하시오: ')
 
print('환영합니다.')
 
 
cs

 if문과 마찬가지로 while문에도 콜론이 붙고, 한 블록에는 동일한 공백 수만큼의 들여쓰기가 들어간다. 

 

 횟수 제어 반복문이 있다고 해서 while에는 횟수를 써먹을 수 없는 걸까? 아니다. 횟수를 알고 있는 경우에도 while 루프를 사용할 수 있다. 예를 들어 1부터 10까지의 합을 계산하는 코드를 while 루프로 작성해보자. 1부터 10까지 늘어나는 변수 count를 1로 초기화하여 만들고 합을 저장할 변수 s를 0으로 초기화하자. 

 

count = 1
= 0                  #1부터 10까지의 합은 여기에 저장된다. 
while count <= 10 : 
    s = s + count      #매번 count 값을 s에 저장해 더한다.
    count = count + 1  #count 값을 1 늘린다. 
 
print('합계는', s)
cs

 

이 코드의 count와 s값의 변화, 그리고 count <= 10 조건문의 반환값은 아래와 같다. 

count s count <= 10 반복 여부
1 1 True 반복
2 1 + 2 True 반복
3 1 + 2 + 3 True 반복
4 1 + 2 + 3 + 4 True 반복
5 1 + 2 + 3 + 4 + 5 True 반복
6 1 + 2 + 3 + 4 + 5 + 6 True 반복
7 1 + 2 + 3 + 4 + 5 + 6 + 7 True 반복
8 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 True 반복
9 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 True 반복
10 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 True 반복
11 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 False 반복 중단

 

 count가 11이 되면 count <= 10 이라는 조건에 어긋나므로 반복이 중단되는 것을 볼 수 있다. 


 

무한 루프를 제어해 보자, break와 continue!

 

  조건 제어 루프에서 프로그램이 무한히 반복하는 일을 무한 루프라고 이미 소개한 바 있다. 이 무한 루프는 말 그대로 빠져 나올 수 없기 때문에 어떤 때에는 문제라면 문제가 된다. 

 

 이런 무한 루프에서 빠져나오려면 이 키워드를 꼭 기억해야 한다. break. 루프를 강제적으로 빠져나올 때 사용하는 문장이다. 사용법의 간단한 예를 들자면 아래와 같다.

 

while True :
    light = input('신호등 색상을 입력하시오: ')
    if light == 'green' :
        break
 
print('전진!')
cs
신호등 색상을 입력하시오 : red
신호등 색상을 입력하시오 : yellow
신호등 색상을 입력하시오 : green
전진!!
cs

 

 이 코드에서는 '신호등 색상을 입력하시오: '를 출력하고 사용자의 입력을 기다린다. while True : 로 설정하면 항상 참이기 때문에 무한 반복이 이루어진다. 사용자가 'green'을 입력하면 break 문장을 실행해서 루프를 빠져나가고 '전진!!' 이 출력되는 것이다. 

 

 continue는 루프를 빠져나오지 않고 아래의 문장만을 건너뛰는 역할을 한다. 즉 반복문이 종료되는 것은 조건이 거짓일 때에만 해당된다. continue도 간단한 예시를 통해 사용법을 알아보자.

 

>>> st = 'I love Python Programming'
>>> for ch in st :
        if ch in ['a','e','i','o','u''A','E','I','O','U'] :
            continue
        print(ch, end='')
 
    
 lv Pythn Prgrmmng
cs

 

 'I love Python Programming'이라는 문자열 내에서 반복하여 모음이 반복할 차례가 오면 continue를 통해 아래 문장을 생략하고 다음 반복으로 넘어가서 자음이나 공백이 출력된다. 

 

 continue와 break는 잘 활용하면 편리한 프로그램을 만들 수 있겠지만, 너무 많이 쓰면 제어의 흐름에 일관성이 없어지기 때문에 코드를 읽기 어려워진다. 따라서 continue와 break는 필요한 경우에만 제한적으로 쓰는 것이 좋다. 

 


 

들쭉날쭉한 글씨는 포매팅으로 다듬자!

 

  지금까지 print()를 이용하여 다양한 출력을 해 보았는데, 출력을 다듬지 않아 출력 메세지의 간격이 들쭉날쭉했다. 

문자열을 가지런하게 정리하려면 format() 메소드를 사용하면 된다. 플레이스홀더 {}로 format() 메소드의 인자로 들어오는 값이 출력될 위치를 지정한다. 

 

>>> '{} Pyhon!'.format('Hello')
'Hello Pyhon!'
>>> 'I like {0} and {1}'.format('Python''Java')
'I like Python and Java'
>>> 'I like {0} and {0}'.format('Python''Java')
'I like Python and Python'
cs

 

 format() 메소드의 인자에 부여된 0, 1과 같은 인덱스를 이용하여 인자값을 지정할 수도 있다. 인덱스에 대해서는 7장 리스트 부분에서 자세하게 설명한다.

 

 부동소수점(Floating Point)을 이용하면 소숫점 아래 n번째 숫자를 출력할 수도 있다. 부동소수점으로는 f를 사용한다. 

 

>>> '소수점 아래 두자리 정밀도 : {0:.2f}, 세자리 정밀도 {0:.3f}'.format(1/3)
'소수점 아래 두자리 정밀도 : 0.33, 세자리 정밀도 0.333'
>>> '전체 10칸을 차지하는 실수 : {0:10.2f}, {0:10.3f}'.format(3.1415926)
'전체 10칸을 차지하는 실수 :       3.14,      3.142'
cs

 

 여기서 {0:.nf}는 format() 메소드의 인자를 소숫점 아래 n자리까지 표시해주고, {0:m.nf}는 전체 m칸을 차지하는 데에서 소숫점 n자리만큼을 채워 출력해준다. 예로 사용된 {0:10.2f}는 전체 10칸에서 소숫점 2자리까지를 포함하여 가장 오른쪽에 소수를 써 주고, 앞의 남은 6칸은 공백으로 채운다.

 

 또 정수를 깔끔하게 써주려면 {i:nd}의 형태로 포매팅을 해 주면 된다.

 

>>> for i in range(2112) :
    print('{0:3d} {1:4d} {2:5d}'.format(i, i*i, i*i*i))
 
    
  2    4     8
  4   16    64
  6   36   216
  8   64   512
 10  100  1000
cs

 

 이때 i에는 format() 메소드의 인자의 인덱스, n에는 전체 몇 칸이 사용될지를 써 준다.


 

마무리

 

  이번 시간에는 횟수 또는 조건에 따라 프로그램을 반복해서 수행시키는 for문과 while문에 대해 알아보았다.

마지막으로 도전문제 5.7, 5.8-(3), 5.12, 심화문제 5.2, 5.5, 5.8을 풀어보고 마치도록 하자. 접은글 속의 해답 코드는 참고만 하자.

 

도전문제

 

5.7: 구구단의 1단부터 9단까지를 모두 출력하도록 아래의 코드를 수정해보자.

dan = int(input('원하는 단은: '))
= 1
 
while i <= 9 :
    print('{} * {} = {}'.format(dan, i, dan * i))
    i = i + 1
cs
더보기
for n in range (110) :
    i = 1
    while i <= 9 : 
        print('{} * {} = {}'.format(n, i, n * i))
        i = i + 1
cs

 

 

5.8-(3): 아래의 코드를 이용하여 그림과 같은 별모양을 그려 봐라. 한 각은 그림을 참고하여라.

import turtle
= turtle.Turtle()
t.shape('turtle')
= 0
while i < 5:
    t.forward(50)
    t.right(144)
    i = i + 1
cs
더보기
import turtle
= turtle.Turtle()
t.shape("turtle")
= 1   #변의 개수 
= 1   #별의 팔 개수 
 
while i <= 10:
    t.forward(50)
    if i == d * 2 - 1 :  #홀수 번째 변을 그리고 나서 왼쪽으로 72도 돈다. 
        t.left(72)
        i = i + 1
 
    elif i == d * 2 :    #짝수 번째 변을 그리고 나서 오른쪽으로 144도 돈다.
        t.right(144)
        i = i + 1
        d = d + 1
 
cs

 

 

5.12: 사용자로부터 하나의 단어를 입력받은 다음 이 단어에서 모음이 나타나기 전까지의 모든 자음을 출력하는 프로그램을 작성하여라. 예를 들어 다음과 같이 'programming'이 입력되면 'o'가 나타나기 이전인 pr만 출력하도록 하여라. 

단어를 입력하세요 : programming
pr
cs
더보기
word = input('단어를 입력하세요 : ')
= ['a''e''i''o''u''A''E''I''O''U'#모음 리스트
 
for i in word :
    if i in W :   # in은 앞의 데이터가 뒤의 시퀀스에 들어 있는지 참/거짓으로 판단한다.
        break
    print(i, end = ''#들어있지 않으면 출력
 
cs

 

 

 

심화문제

 

5.2: 반복문을 활용하여 특정 구간의 수의 합을 구할 수 있다. 

1) for 반복문과 while 반복문을 사용하여 1에서 100까지의 정수 중에서 홀수의 합을 출력하는 프로그램을 작성하여라.

1에서 100까지의 수 중에서 홀수의 합 : 2500
cs
더보기
= 0      #숫자의 합을 저장할 변수를 선언한다. 
for i in range (11012) : 
    S = S + i  #1에서 2씩 건너뛰어 100까지의 홀수를 더해나간다.
 
print('1에서 100까지의 수 중에서 홀수의 합 : ', S)
cs

 

2) for 반복문과 while 반복문을 사용하여 1에서 100까지의 정수 중에서 짝수의 합을 출력하는 프로그램을 작성하여라.

1에서 100까지의 수 중에서 짝수의 합 : 2550
cs
더보기
= 0
for i in range(01012) :
    S = S + i
 
print('1에서 100까지의 수 중에서 짝수의 합 : ', S)
cs

 

3) 사용자로부터 시작 정수와 끝 정수를 입력으로 받은 다음 시작 정수 값에서 끝 값까지의 합을 구하여 다음과 같이 출력하는 프로그램을 작성하여라. 

시작 정수를 입력하세요 : 2
끝 정수를 입력하세요 : 6
2 에서 6 까지 정수의 합 : 20
cs
더보기
start = int(input('시작 정수를 입력하세요 : '))
end = int(input('끝 정수를 입력하세요 : '))
= 0
 
for i in range(start, end + 1) :
    S = S + i
 
print(start, '에서', end, '까지 정수의 합 : ', S)
 
cs

 

 

5.5 : 깊이가 30 미터인 우물이 있다. 이 우물에 사는 달팽이는 하루 종일 기어서 올라가면 7미터를 올라갈 수 있다. 그러나 밤이 되어 휴식을 취하는 동안 5 미터를 미끄러져 내려간다. 이 우물을 벗어나는데 며칠의 시간이 걸릴까? while문을 이용하여 매일 저녁 달팽이의 위치를 다음과 같이 구하시오. 출력 시 format() 메소드를 이용하여 숫자들이 오른쪽 정렬되도록 하자. (주의! 하루에 7 - 5 = 2미터를 올라갈 것이라고 단순 계산하면 안 된다. 이 경우 15일 되는 날 탈출하는 것으로 계산되지만 실제로는 13일이면 된다.) 

day :   1 달팽이의 위치 :   7 미터
day :   2 달팽이의 위치 :   9 미터
day :   3 달팽이의 위치 :  11 미터
day :   4 달팽이의 위치 :  13 미터
day :   5 달팽이의 위치 :  15 미터
day :   6 달팽이의 위치 :  17 미터
day :   7 달팽이의 위치 :  19 미터
day :   8 달팽이의 위치 :  21 미터
day :   9 달팽이의 위치 :  23 미터
day :  10 달팽이의 위치 :  25 미터
day :  11 달팽이의 위치 :  27 미터
day :  12 달팽이의 위치 :  29 미터
day :  13 달팽이의 위치 :  31 미터
축하합니다. 우물을 탈출하였습니다.
우물을 탈출하는 데 걸린 날은  13 일 입니다.
cs
더보기
day = 0
Posit = 0
 
while Posit <= 30 :      #위치가 30m 이하이면 아래가 반복된다. 
    day = day + 1        #하루가 시작되고 
    Posit = Posit + 7    #현재 위치에서 7m를 올라간다.
    print('day :''{0:3d}'.format(day), '달팽이의 위치 :''{0:3d}'.format(Posit), '미터')
 
    if Posit <= 30 :       #7m를 올라가도 30m 이하라면 
        Posit = Posit - 5  #저녁동안 5m 내려간다. 
 
    elif Posit >= 30 :
        print("축하합니다. 우물을 탈출하였습니다.")
        print("우물을 탈출하는 데 걸린 날은 ", day, "일 입니다.")
 
cs

 

 

5.8 : 거꾸로 정수는 121이나 3443과 같이 거꾸로 나열해도 그 값이 원래의 값과 같은 정수를 말한다. 사용자로부터 임의의 양의 정수를 입력받아 이 수가 거꾸로 정수인지 아닌지를 판단하는 다음과 같은 프로그램을 작성하시오. 입력을 받을 때 -99가 들어올 경우 더 이상 입력을 받지 않는다.

정수를 입력하시오 : 3443
3443 은(는) 거꾸로 정수입니다.
정수를 입력하시오 : 324
324 은(는) 거꾸로 정수가 아닙니다.
정수를 입력하시오 : -99
프로그램을 종료합니다.
cs
더보기
n1 = 0     #루프 돌입 전 입력 받을 정수를 초기화시킨다. 
 
while n1 != -99 :   #-99가 입력될 때까지 반복한다. 
    n1 = int(input("정수를 입력하시오 : "))
    n = n1
    N = 0           #입력받은 정수를 뒤집은 것이 들어갈 변수 초기화 
    
    while n > 0 :
        N = N * 10 + n % 10  
        n = n // 10
 
#위 블록을 343으로 예를 들어보자.
#루프 돌입 전 : n = 343, N = 0
#루프 1회 : n = 343 // 10 = 34, N = 0 + 3 = 3
#루프 2회 : n = 34 // 10 = 3, N = 3 * 10 + 34 % 10 = 34
#루프 3회 : n = 3 // 10 = 0, N = 34 * 10 + 3 % 10 = 343
#n < 0이므로 루프를 종료. N은 n1을 뒤집은 수가 된다. 
    
    if n1 == N :
        print(n1, "은(는) 거꾸로 정수입니다.")
 
    elif n1 == -99 :
        break
 
    elif n1 != N :
        print(n1, "은(는) 거꾸로 정수가 아닙니다.")
 
 
print("프로그램을 종료합니다.")
 
cs
COMMENT
━━━━ ◇ ━━━━
따라하며 배우는 파이썬과 데이터 과학/PART 1. 파이썬 기초체력 다지기

Chapter 04. 조건을 따져 실행해보자

이번 시간의 목차

1. 프로그램의 기본 제어 구조

2. 조건을 걸고 싶으면 if 를 써 보자

3. 배타적 조건, if - else문

4. 조건이 거짓일 때 또 검사하기, elif문

5. 마무리

 

 

 

자, 가자! 파이썬의 세계로!


 

프로그램의 기본 제어 구조

 

 하나의 프로그램 중의 제어 흐름을 논리식의 값에 따라 분기시키는 선택 구조를 제어 구조(Control Structure)라고 한다. 기본적인 제어 구조로는 세 가지가 있다.

  • 순차 구조(sequence) : 여러 명령이 순차적으로 실행되는 구조이다.
  • 선택 구조(selection) : 여러 개 중 하나의 명령문을 선택하여 실행하는 구조이다.
  • 반복 구조(iteration) : 동일한 명령이 반복되면서 실행되는 구조이다.

 위는 순차 구조, 선택 구조, 반복 구조를 순서도(Flowchart)로 나타낸 것이다. 

 

 

 

 이번에는 제어 구조 중에서도 선택 구조에 대해 알아보려 한다. 

선택 구조는 질문을 한 후에 결정하는 것이다. 우리의 삶에서도 수많은 선택을 해야 하고, 이는 프로그램에서도 마찬가지이다. 프로그램의 어떤 단계에서는 진행할 수 있는 경로가 하나 이상인 경우가 있는데, 이때 우리는 어떤 경로를 선택할 것인지 결정해야 한다. 그래야 상황에 따라 반응하는 유연한 프로그램이 될 것이다. 

 

 프로그램에서 선택 구조가 필요한 경우의 예로 '성적이 60점 이상이면 합격인 시험'을 들어서 if 조건식을 살펴보자.

 


 

조건을 걸고 싶으면 if 를 써 보자

 

 60점 이상이면 합격, 이라고 한다면 성적의 데이터가 60 이상인지 아닌지 판단해야 한다. 이렇게 어떤 조건(Condition)을 만족하는지 그렇지 않은지 판단할 때 쓰는 식을 조건식(Condition Expression) 이라고 한다. 이 조건식은 참 또는 거짓의 값을 갖는 부울형으로 평가된다.

 

 조건식에는 어떤 수식을 쓸 수 있을까? 이전에 배운 관계 연산자나 논리 연산자 등 최종적으로 참 또는 거짓의 값을 갖는 수식이라면 조건식이 될 수 있다. 논리 연산이나 관계 연산자를 사용하면 여러 조건이 걸린 복합 조건식을 만들 수도 있을 것이다.

 

 if문은 다음과 같이 사용하면 된다.

 

if 조건식 : 
    실행할 내용
    실행할 내용 
cs

 

 위의 방식대로 코딩하면 조건식을 평가한 결과가 True 라면 실행할 내용이 실제로 실행이 되고, 그렇지 않으면 실행할 내용을 선택하지 않고 건너 뛰어 버린다. 

 

 그럼 실제로 성적 데이터를 받아서 60 이상인지 아닌지 판단하여 합격 여부를 따져보자. 

 

score = int(input('점수를 입력하시오 : '))
if score >= 60 :
    print('합격입니다.')
cs

 

이렇게 짜고 나서 실행을 시켜 보면 

 

점수를 입력하시오 : 65
합격입니다. 
>>>
점수를 입력하시오 : 30
>>>
cs

 

 score 변수에 저장된 데이터에 따라 '합격입니다.' 문자열이 출력되거나 출력되지 않는 것을 볼 수 있다. 첫 번째 실행에서 score 변수에 저장된 데이터가 65로 score >= 60이 True를 반환하므로 print('합격입니다.') 가 실행되었고, 두 번째 실행에서는 score 변수에 저장된 데이터가 30이므로 score >= 60이 False를 반환하고 조건식 아래의 실행할 내용이 생략된다. 

 

 if로 조건문을 만들 때에 주의해야 할 점이 있다. 

if 뒤에 조건식이 이어진 다음 : (콜론) 이 보인다. 콜론 아래의 줄은 반드시 들여쓰기를 해 줘야 한다. 또 실행할 내용이 2개 이상일 경우 그 내용들은 모두 동일한 개수의 공백만큼 들여쓰기 해야 한다. 동일한 블록(Block)에 속해 있기 때문이다. 하나의 블록에 속하는 문장들은 모두 같이 실행된다. 보통 블록에 있는 문장들은 그 위에 있는 문장과 비교해봤을 때 문장의 맨 앞에 4칸의 들여쓰기 공백을 두고 시작한다. 동일한 블록에 있는데도 공백 수에 약간이라도 차이가 나면 오류가 발생한다. 

 

score = int(input('점수를 입력하시오 : '))
if score >= 60 :
    print('합격입니다.')
      print('장학금 대상자입니다.')
 
cs

 

 만약 이렇게 들여쓰기 공백 수가 차이 나면 

 

>>> score = int(input('점수를 입력하시오 : '))
점수를 입력하시오 : 89
>>> if score >= 60 :
    print('합격입니다.')
     print('장학금 대상자입니다.')
     
SyntaxError: unexpected indent
cs

 

 위와 같이 오류가 나게 된다. 

 


 

배타적 조건, if - else문 

 

 60점 이상이라면 합격이라는 문구를 출력하는 것은 좋은데, 60 미만일 때 불합격도 알려줘야 하지 않을까? 

이럴 때는 if 조건식 블록 다음으로 else 블록을 달아주면 된다. if - else문은 if의 조건이 참이면 if 블록을 실행하고, 아니면 else 블록을 실행하라는 뜻이다. 

 

score = int(input('점수를 입력하시오 : '))
if score >= 60 :            #60점 이상일 경우 실행되는 블록
    print('합격입니다.')
 
else :                      #60점 미만일 경우 실행되는 블록
    print('불합격입니다.')
cs

 

 이렇게 60점을 기준으로 이상이면 합격, 미만이면 불합격이 될 때 0에서 100까지의 점수가 입력될 경우 합격점이면서 동시에 불합격점이 될 수 없으므로 이 조건은 배타적 조건(Exclusive Condition)이 된다. 

 

 이제 본격적으로 if-else문을 활용해 보자.

우리는 지난 시간에 입력 받은 어떤 정수를 나머지 연산자를 통해 짝수인지 홀수인지 구분해내는 법을 배웠다. 이제는 조건에 맞추어 홀수인지 짝수인지 출력할 수도 있을 것이다.

 

number = int(input('양의 정수를 입력하세요 : '))
if number % 2 == 0 :
    print('짝수입니다.')
else : 
    print('홀수입니다.')
cs

 

 만약 임의의 정수를 받고 나서 이 검사를 0 이상인 수에 대해서만 하고, 이 정수가 음수인 경우에는 '음수입니다'를 출력하는 좀 더 복잡한 조건을 설정하려면 어떻게 해야 할까? 간단하다. if-else문 속에 또 if-else문을 붙여주면 된다. 이런 조건문 내의 조건문을 내부 조건문이라고도 한다. 

 

number = int(input('양의 정수를 입력하세요 : '))
if number < 0 :
    print('음수입니다.')
 
else :
    print('양수입니다.')
    if number % 2 == 0 :
        print('짝수입니다.')
    else :
        print('홀수입니다.')
cs

 

 특히 위의 예시처럼 else 블록이 아닌 if 블록에 또다른 if문이 들어가면 중첩 if문이라고 한다. 

number = int(input('양의 정수를 입력하세요 : '))
if number >= 0 :
    if number == 0 : 
        print('0입니다.')
    else :
        print('양수입니다.')
 
else :
    print('음수입니다.')
cs

 

 

하지만 조건을 덧붙이고 싶을 때마다 이렇게 중첩 if문만을 쓰다 보면 가독성에 문제가 생길 때도 있다. 이럴 때엔 elif라는 키워드를 쓰면 된다.


 

조건이 거짓일 때 또 검사하기, elif문

 

  elif는 'else if'를 줄인 말로, if-else문에서 if 조건이 거짓일 때 elif로 넘어가 다른 조건을 검사하게 된다. 

좀 전에 봤던 양수/음수 구분 코드를 조금 고쳐 보자. 

 

number = int(input('양의 정수를 입력하세요 : '))
if number >= 0 :
    if number == 0 : 
        print('0입니다.')
    else :
        print('양수입니다.')
 
else :
    print('음수입니다.')
cs

 

 if문에 걸려있는 number >= 0을 number > 0 과 number == 0 으로 구분해서 if-elif-else 문으로 구현할 수 있을 것이다.

 

number = int(input('양의 정수를 입력하세요 : '))
if number > 0 :
    print('양수입니다.')
 
elif number == 0 :
    pirnt('0입니다.')
 
else :
    print('음수입니다.')
cs

 


 

마무리

 

 이번 시간에는 조건에 따라 코드를 실행하는 조건식과 if-elif-else문에 대해 알아보았다. 

마지막으로 4장의 도전문제 4.4, 4.9, 4.12, 심화문제 4.5, 4.8을 풀어보고 마치도록 하자. 접은글 속의 해답 코드는 참고만 하도록 하자. 

 

도전문제 

 

4.4: 사용자로부터 2개의 정수를 연속하여 입력받도록 아래의 코드를 수정하여라. 이때 두 정수는 모두 0이 아니라고 가정하자. 두 정수를 각각 x, y라 할 때 두 정수의 부호가 모두 양수이면 1사분면(100, 100) 좌표로, x가 음수이고 y가 양수이면 2사분면 (-100, 100) 좌표로, 두 수 모두 음수이면 3사분면 (-100, -100) 좌표로, x가 양수이고 y가 음수이면 4사분면 (100, -100) 좌표로 거북이를 이동시키는 프로그램을 작성해 보자. (Tip: 터틀 그래픽의 다양한 함수는 이쪽에서 더 자세히 볼 수 있다. → https://docs.python.org/3/library/turtle.html)

import turtle
= turtle.Turtle()
t.shape('turtle')
 
t.penup()        #펜을 올려 그림이 그려지지 않게 한다.
t.goto(100100#거북이를 (x, y)로 이동시키는 함수.
t.write('거북이가 여기로 오면 양수입니다.')
t.goto(1000)
t.write('거북이가 여기로 오면 0입니다.')
t.goto(100-100)
t.write('거북이가 여기로 오면 음수입니다.')
t.goto(00)     #거북이를 원위치로 놓고
t.pendown()      #펜을 내려 그림이 그려지게 한다. 
 
= turtle.textinput('''숫자를 입력하시오: ')
= int(s)
 
if n > 0 :
    t.goto(100100)
 
elif n == 0 :
    t.goto(1000)
 
else :
    t.goto(100-100)
 
turtle.done()
cs
더보기
import turtle
= turtle.Turtle()
t.shape('turtle')
 
t.penup()
t.goto(100100)
t.write('두 수 모두 양수.')
t.goto(100-100)
t.write('첫 번째 수만 양수.')
t.goto(-100-100)
t.write('두 수 모두 음수.')
t.goto(-100100)
t.write('첫 번째 수만 음수.')
t.goto(00)
t.pendown()
 
= turtle.textinput('''x를 입력하시오: ')
= int(x)
= turtle.textinput('''y를 입력하시오: ')
= int(y)
 
if x > 0 :
    if y > 0 :
        t.goto(100100)
 
    else :
        t.goto(100-100)
 
else :
    if y > 0 :
        t.goto(-100100)
 
    else :
        t.goto(-100-100)
 
cs

 

4.9 : 주사위 던지기 게임을 만들어보자. random.randint(1, 6)을 사용하면 1에서 6까지의 정수를 랜덤하게 생성할 수 있다. 입력으로 '홍길동', '홍길순'과 같은 사용자의 이름을 받아서 홍길동의 주사위 번호, 홍길순의 주사위 번호를 출력한 후 이들을 비교하여 다음과 같이 출력하여라. 결과는 '홍길동이 이겼습니다.', '홍길순이 이겼습니다.', '비겼습니다.' 가운데 하나가 나타나도록 하여라. 

Player1의 이름 : 홍길동
Player2의 이름 : 홍길순
......주사위를 굴립니다......
홍길동의 주사위 번호는 3
홍길순의 주사위번호는 4
홍길순이 이겼습니다.
cs
더보기
import random
player1 = input('Player1의 이름 : ')
player2 = input('Player2의 이름 : ')
n1 = random.randint(16)
n2 = random.randint(16)
print('......주사위를 굴립니다......')
print(player1, '의 주사위 번호는 ', n1)
print(player2, '의 주사위 번호는 ', n2)
 
if n1 > n2 : 
    print(player1, '이 이겼습니다.')
elif n1 < n2 :
    print(player2, '이 이겼습니다.')
else :
    print('비겼습니다.')    
cs

 

4.12 : 컴퓨터와 승부차기 게임을 만들어보자. options = ['왼쪽', '중앙', '오른쪽'] 리스트를 생성하자. 다음으로 random 모듈을 사용하여 computer_choice = random.choice(options)와 같이하여 리스트에서 임의의 문자열을 추출하는 방식으로 다시 작성해 보자. 리스트에 대한 상세한 설명은 6장에서 다룰 것이다. 

어디를 공격하시겠습니까?(왼쪽, 중앙, 오른쪽) : 왼쪽
축하합니다!! 공격에 성공하였습니다.
컴퓨터의 수비위치 : 오른쪽 
cs
더보기
import random
attack = input('어디를 공격하시겠습니까?(왼쪽, 중앙, 오른쪽) : ')
options = ['왼쪽''중앙''오른쪽']
defence = random.choice(options)
 
if attack == defence :
    print('공격에 실패하셨습니다.')
 
else :
    print('축하합니다! 공격에 성공하였습니다.')
 
print('컴퓨터의 수비위치 : ', defence)
cs

 

 

 

심화문제

 

4.5 : random.randint(0, 9)를 이용하여 0에서 9사이의 복권번호 3개를 생성하도록 하자. 이들 중에서 3개의 숫자를 모두 맞히면 '1억원', 2개를 맞히면 '1천만원', 1개를 맞히면 '1만원', 모두 틀리면 '다음 기회에...'를 출력하는 복권 시스템이 있다고 가정하자. 사용자로부터 3개의 정수를 받은 다음 상금을 알려주는 프로그램을 다음과 같이 작성하시오. (예시는 랜덤하게 생성한 복권 당첨 번호가 2, 3, 9라고 가정한다.)  

(Tip. 공백으로 구분된 숫자는 n1, n2, n3 = map(int, input('세 복권번호를 입력하시오 : ').split())으로 한 번에 할당시킬 수 있다. map(x, y)는 y자리에 들어온 여러 데이터에 x라는 함수를 적용해주고, split()은 앞의 문자열을 괄호 속 단위로 문자열을 끊어 리스트로 만들어준다.)

세 복권번호를 입력하시오 : 157
다음 기회에...
 
세 복권번호를 입력하시오 : 129
상금 1천만원
cs
더보기
import random 
n1, n2, n3 = map(int, input('세 복권번호를 입력하시오: ').split())
= random.randint(09)
= random.randint(09)
= random.randint(09)
 
if n1 == x :
    if n2 == y :
        if n3 == z :
            print('상금 1억원')
        else : 
            print('상금 1천만원')
    else :
        if n3 == z :
            print('상금 1천만원')
        else : 
            print('상금 1만원')
 
else : 
    if n2 == y :
        if n3 == z : 
            print('상금 1천만원')
        else : 
            print('상금 1만원')
    else : 
        if n3 == z : 
            print('상금 1만원')
        else : 
            print('다음 기회에...')
cs

 

 

4.8: 덧셈, 뺄셈, 곱셈, 나눗셈을 수행해주는 프로그램을 작성하려 한다. 원하는 연산의 번호(1: 덧셈, 2:뺄셈, 3:곱셈, 4:나눗셈)을 입력 후, 두 개의 양의 정수를 입력하면 연산 결과를 출력해준다. 이때 연산의 번호에서 1, 2, 3, 4가 아닌 다른 값이 입력되면 '잘못 입력하였습니다.'를 출력한다. 또한, 각 연산에 배정된 숫자가 아닌 다른 숫자를 입력하면 잘못 입력하였다는 정보를 출력해야 한다.

1)덧셈 2)뺄셈 3)곱셈 4)나눗셈
어떤 연산을 원하는지 번호를 입력하세요: 4
연산을 원하는 숫자 두 개를 입력하세요 : 3 4
3 / 4 = 0.75
cs
더보기
print('1)덧셈 2)뺄셈 3)곱셈 4)나눗셈')
cal = int(input('어떤 연산을 원하는지 번호를 입력하세요: '))
n1, n2 = map(int, input('연산을 원하는 숫자 두 개를 입력하세요: ').split())
 
if cal == 1 :
    print(n1, '+', n2, '=', n1 + n2)
 
elif cal == 2 :
    print(n1, '-', n2, '=', n1 - n2)
 
elif cal == 3 :
    print(n1, '*', n2, '=', n1 * n2)
 
elif cal == 4 :
    print(n1, '/', n2, '=', n1 / n2)
 
else :
    print('잘못 입력하였습니다.')
cs
COMMENT
━━━━ ◇ ━━━━
따라하며 배우는 파이썬과 데이터 과학/PART 1. 파이썬 기초체력 다지기

Chapter 03. 연산자로 계산을 해 보자

이번 시간의 목차

1. 파이썬에서의 수식이란

2. 연산자 그 첫 번째, 산술 연산자

3. 연산자 그 두 번째, 할당 연산자

4. 연산자 그 세 번째, 비교 연산자

5. 연산자 그 네 번째, 논리 연산자

6. 연산자 그 다섯 번째, 비트 연산자

7. 연산자에도 우선순위가 있다!

8. random 모듈과 math 모듈

9. 마무리

 

 

 

자, 가자! 파이썬의 세계로!


 

파이썬에서의 수식이란

 

  우리는 그동안 살면서 수많은 수식을 접했을 것이다. 당장 수학책을 펼치기만 해도 수식이 없는 페이지가 없고, 더 나아가 물리학에서 어떤 운동이나 일에 대한 방정식, 경제학에서 수요 함수 등… 없는 곳이 없다고 할 정도이다. 

 

 물론 파이썬에도 수식은 존재한다. 하지만 수학에서의 수식과는 조금 다른 개념이다. 컴퓨터 과학 분야에서의 수식(Expression)하나의 값으로 평가될 수 있는 표현을 의미한다. 좀 더 정확하게 말하자면 피연산자들과 연산자의 조합이다. 이때 연산자(Operator)는 어떤 연산을 나타내는 기호를 의미하고, 피연산자(Operand) 연산의 대상이 되는 숫자나 변수를 의미한다. 

 

 

 연산자는 이전 시간에서도 보았듯 계산, 즉 산술을 위한 것만 있는 것은 아니다. 이번 시간에는 다양한 연산자에 대해서 알아보도록 하자. 

 


 

연산자 그 첫 번째, 산술 연산자

 

 우선 가장 익숙할 산술 연산자에 대해 알아보자. 

크게 어려운 건 없다. 덧셈, 뺄셈, 곱셈, 나눗셈과 나머지 및 지수 연산을 실행하는 연산자가 있다. 

 

연산자 기호 사용 예시 결과값 
덧셈 + 11 + 2 13
뺄셈 - 11 - 2 9
곱셈 * 11 * 2 22
나눗셈(실수) / 11 / 2 5.5
나눗셈(정수 나눗셈의 몫) // 11 // 2 5
나머지 % 11 % 2 1
지수(거듭제곱) ** 11 ** 2 121

 

 이때 나눗셈 연산자 / 와  // 를 잘 구분해서 써야 한다. / 는 소수점 아래, 즉 실수 범위까지 나눗셈을 하지만 // 는 나머지를 버리고 정수 몫만을 반환해준다. 

 

 사칙연산은 그렇다 쳐도, 나머지 연산자(%)와 지수 연산자(**)는 생소할지도 모른다. 

나머지 연산자는 생각보다 컴퓨터 과학에서 중요하게 쓰이는 연산자이다. 잘만 이용하면 짝수나 홀수도 쉽게 구분할 뿐만 아니라 소수(약수가 1과 자신 뿐인 수)도 구분할 수 있고, 단위 변환도 쉽게 이뤄낼 수 있다. 짧은 예시로 정수의 홀짝을 구분해보자. 어떤 수를 2로 나누어서 나머지가 0이라면 짝수일 것이고, 나머지가 1이라면 홀수가 될 것이다. 따라서 아래처럼 코드를 작성하면 홀수인지 짝수인지 쉽게 알 수 있을 것이다. 

 

number = int(input('정수를 입력하시오: '))
print(number % 2)       #0을 출력하면 짝수, 1을 출력하면 홀수가 된다.
 
정수를 입력하시오 : 28
0
cs

 

 지수 연산자는 앞의 수를 밑으로, 뒤의 숫자를 지수로 올려 계산해준다. 지수 연산자는 곱셈이나 나눗셈 연산자보다 우선순위가 높다. 또, 다른 연산자들과 달리 오른쪽에서 왼쪽으로 계산되기 때문에 지수 연산자를 쓸 때는 이 두 점을 주의해야 한다. 

 

>>> 2 ** 5       #2의 5
32 
>>> 10 * 2 ** 3  #10 * 2 * 2 * 2
80
>>> 2 ** 2 ** 4  #2의 16제곱 
65536
cs

 

 또 지수로는 실수도 올릴 수 있기 때문에 제곱근도 쉽계 계산할 수 있다. 

피타고라스 정리(c² = a² + b²)를 조금 손봐주면 c = (a² + b²) ^ ½ 를 얻을 수 있다. 간단한 예시로 사용자로부터 밑변과 높이 값을 받아서 그 삼각형의 빗변을 구하는 프로그램을 써 보자. 

 

= float(input('밑변의 길이는: '))
= float(input('높이의 길이는: '))
= (a * b) ** (1/2)
print('빗변의 길이는', c, '입니다.')
cs

 

 이때 지수로 2분의 1을 주고 싶다면 꼭 괄호 속에 넣어서 입력하도록 하자. / 는 나눗셈 연산자이므로 ** 보다 우선순위가 낮아 괄호를 써 주지 않으면 지수로 1이 올라가 버린다. 2분의 1 대신 0.5를 넣으면 괄호를 쓸 필요는 없다. 어쨌든, 위의 코드를 실행시키면 아래와 같은 결과가 나온다. 

 

밑변의 길이는: 3
높이의 길이는: 4
빗변의 길이는 5.0 입니다.
cs

 


 

연산자 그 두 번째, 할당 연산자

 

 할당 연산자? 어디서 많이 들어본 이름이 아닌가? 

그렇다. 우리는 이미 할당 연산자를 하나 알고 있다. 변수를 선언할 때 쓰는 = 가 바로 그 할당 연산자(Assignment Operator)이다. 명심하자. 프로그래밍의 세계에서 = 는 '같다' 라는 뜻이 아니라 왼쪽에 오른쪽 데이터를 저장한다는 뜻이다. 왼쪽은 항상 값을 저장할 수 있는 변수여야 하고, 오른쪽은 값을 표현하는 숫자나 문자, 변수, 혹은 수식이 와야 한다. 만약 이게 거꾸로 오게 된다면…

 

>>> 10 = x + y
SyntaxError: cannot assign to literal
cs

 

이렇게 오류를 일으킨다. 

 

 이미 2장에서 설명했듯, 한 번에 여러 변수를 선언해서 동시에 여러 값을 줄 수도 있다. 이때 쓰이는 할당문을 동시 할당문(Simultaneous Assignment)이라 하고, 한 번에 여러 변수를 선언해서 동일한 값을 주는 건 다중 할당문(Multiple Assignment)이라 한다. 

 

>>> x = y = 10      #같은 값을 주면 다중 할당문
>>> x, y
(1010)
>>> x, y = 2030   #동시에 다른 값을 주면 동시 할당문
>>> x, y
(2030)
cs

 

 그렇다면 할당 연산자는 이것 뿐인가? 

아니! 앞에서 설명한 산술 연산자와 결합해서 쓰이는 복합 할당 연산자라는 할당 연산자가 또 존재한다. 

 

연산자 사용 방법 의미
+= a += 10 a = a + 10
-= a -= 10 a = a - 10
*= a *= 10 a = a * 10
/=  a /= 10 a = a / 10
//= a //= 10 a = a // 10
%=  a %= 10 a = a % 10
**=  a **= 10 a = a ** 10

 

 당연하겠지만 복합 할당 연산자를 쓰기 전에는 a 자리에 들어갈 변수를 선언해 두어야 한다. 

꼭 이런 복합 할당 연산자를 쓰지 않아도 산술 연산자와 할당 연산자를 써서 코딩할 수 있지만, 의미 정도는 알아 두어야 다른 사람의 코드를 문제 없이 읽을 수 있으니 알아두도록 하자. 

 


 

연산자 그 세 번째, 비교 연산자

 

 비교 연산자(Comparison Operator)는 수치 데이터를 담고 있는 두 개의 피연산자를 대상으로 '크다'와 '작다' 같은 크기 관계를 살피고 그 결과로 True 또는 False를 반환한다. True와 False는 2장에서 이미 한 번 언급했는데, 부울형(Bool)이라는 자료형이다. 

 

연산자 설명 a = 100 이고 b = 200일 때
== 두 피연산자의 값이 같으면 True를 반환 a == b는 False
!= 두 피연산자의 값이 다르면 True를 반환 a != b는 True
> 왼쪽 피연산자가 오른쪽 피연산자보다 클 때 True를 반환 a > b는 False
< 왼쪽 피연산자가 오른쪽 피연산자보다 작을 때 True를 반환 a < b는 True
>= 왼쪽 피연산자가 오른쪽 피연산자보다 크거나 같을 때 True를 반환 a >= b는 False
<= 왼쪽 피연산자가 오른쪽 피연산자보다 작거나 같을 때 True를 반환 a <= b는 True

 

p>>> a, b = 100200
>>> a >= b
False
>>> a => b
SyntaxError: invalid syntax
>>> a > = b
SyntaxError: invalid syntax
cs

 

 앞에서 = 는 '같다' 라는 뜻이 아니라는 것은 이미 설명했다. 이제 진짜 '같다' 라는 의미를 가진 연산자가 나왔다. 간단하게 =를 연속해서 두 번, ==로 써 주면 된다. 이때 이 연산자 사이에 공백을 넣어서는 안 된다. 이는 != 나 >=, <= 도 마찬가지이다. 이 묶음 자체가 하나의 연산자이기 때문에 공백이 포함되어선 안 되고, 두 문자의 순서가 바뀌어도 안 된다

 


 

연산자 그 네 번째, 논리 연산자

 

 논리 연산자(Logical Operator)는 and, or, not 연산을 통해 True 또는 False 중 하나의 값을 갖는 부울 값을 반환한다. 부울 자료형 자체는 True나 False가 끝이라 단순하지만, 다른 자료형도 부울 자료형이 될 수 있음을 알아 두어야 한다. 숫자 자료형의 경우 0은 False, 0을 제외한 다른 모든 수는 True로 바꿀 수 있다. 문자열의 경우에는 빈 문자열은 False, 빈 문자열을 제외한 모든 문자열은 True로 간주된다.

 

>>> 10 > 20       #10은 20보다 작으므로 거짓임.
False
>>> 100 < 200     #100은 200보다 작으므로 참임.
True
>>> bool(10)      #0이 아닌 값이므로 True
True
>>> bool(-1)
True
>>> bool(0)       #0은 False
False
>>> bool(None)    #값이 없어도 False
False
>>> bool('')      #빈 문자열도 False
False
>>> bool('bool')
True
cs

 

 중간에 있는 'None' 은 값이 없다는 뜻을 지닌 키워드이다. 이처럼 0과 None, 그리고 빈 문자열에 대해서 False를 반환하는 것을 보니 0이나 비어 있는 것은 False, 0이 아닌 값이나 무언가가 들어있는 것은 True로 간주된다는 것을 알 수 있다. 

 

 이런 부울 자료형에 대해 적용할 수 있는 것이 논리 연산이다. 

 

연산자 의미
and y x와 y중 거짓(False)이 하나라도 있으면 거짓이 되며 모두 참(True)인 경우에만 참이다.
or y x나 y중에서 하나라도 참이면 참이 되며, 모두 거짓일 때만 거짓이 된다. 
not x x가 참이면 거짓, x가 거짓이면 참이 된다.

 

 x와 y에 대한 논리 연산 결과를 간략하게 정리해보면 아래와 같다. 

 

 


 

연산자 그 다섯 번째, 비트 연산자

 

  연산자에는 산술 연산자와 논리 연산자처럼 연산의 대상이 되는 데이터 값을 가지고 처리하는 연산자 뿐만 아니라 정보의 비트(Bit) 단위로 처리가 이루어지는 연산도 있다. 

 

 비트는 0과 1로 구성된 2진수의 한자리를 말하는데, 파이썬에서 정수 데이터형에 대해서 비트 단위로 조작이 가능하다. 이때 쓰는 연산자를 비트 연산자(Bit Operator) 또는 비트 단위 연산자(Bitwise Operator)라고 한다. 

 

연산자 의미 설명
& 비트 단위 AND 두 개의 피연산자의 해당 비트가 모두 1이면 1, 아니면 0
| 비트 단위 OR 두 피연산자의 해당 비트 중 하나라도 1이면 1, 아니면 0
^ 비트 단위 XOR 두 개의 피연산자의 해당 비트 값이 같으면 0, 아니면 1
~ 비트 단위 NOT 0은 1로 만들고, 1은 0으로 만든다.
<< 비트 단위 왼쪽으로 이동 지정된 개수만큼 모든 비트를 왼쪽으로 이동시킨다.
>> 비트 단위 오른쪽으로 이동 지정된 개수만큼 모든 비트를 오른쪽으로 이동시킨다.

 

 비트 연산자는 위와 같은 것들이 있다. 

어떤 정수의 이진수 값을 확인하고 싶으면 bin() 함수를 사용하면 된다. 한 번 연습해보자. 

 

>>> bin(9)      #9(10)의 2진수 형식(00001001)
'0b1001'
>>> bin(10)     #10(10)의 2진수 형식(00001010)
'0b1010'
>>> bin(9 & 10#두 2진수를 비교해서 모두 1이면 1, 아니면 0
'0b1000'
>>> bin(9 | 10#두 2진수를 비교해서 하나라도 1이면 1, 아니면 0
'0b1011'
>>> bin(~9)     #모든 비트를 바꾸면 2의 보수에 의해 -10(10)이다.
'-0b1010'
 
>>> 9 ^ 10      #비트를 비교해서 같으면 0, 아니면 1. 결과는 3
3
>>> bin (9 ^ 10#3의 2진수값은 (00000011)
'0b11'
>>> 9 << 1      #9(10)의 2진수 형식을 왼쪽으로 한 비트 이동
18
>>> bin(9 << 1#00001001을 왼쪽으로 한 비트 밀었으므로 
'0b10010'
>>> 9 >> 2      #오른쪽으로 두 비트 
2
>>> bin(9 >> 2)
'0b10'
cs

 

 ^ 연산자는 해당 비트의 값이 같으면 0, 아니면 1을 반환하는 XOR 연산을 비트 단위로 수행한다. 지금은 이를 활용하는 방법에 익숙하지 않겠지만, 이 연산은 데이터 교환이나 특정 부분을 제거할 때 유용하게 사용된다. 

 

 또, << 연산자와 >> 연산자는 지정된 수만큼 모든 비트를 왼쪽 또는 오른쪽으로 이동시킨다. 이때 이동시키고 남은 자리에는 0을 넣게 된다. 비트가 한 칸 왼쪽으로 이동하면 정수는 2배의 값을 가지게 되고, 한 칸 오른쪽으로 이동하면 // 2 연산을 한 결과가 될 것이다. 이런 연산을 쉬프트(Shift) 연산이라 한다.

 

 이 연산자는 복합 할당 연산자로서 사용할 수도 있다. 

 

연산자 사용 예시 의미
&= a &= 10 a = a & 10
|=  a |= 10 a = a | 10
^= a ^= 10 a = a ^ 10
<<= a <<= 10 a = a << 10
>>= a >>= 10 a = a >> 10

 

연산자에도 우선순위가 있다!

 

 좀 뜬금없지만 2 + 2 * 2 를 계산하면 몇이 나오는가? 무심코 8이라고 대답하기 쉽지만, 사칙연산에서는 곱하기와 나누기를 먼저 해야 하기 때문에 답은 6이 된다. 이렇게 우선순위(Precedence)가 있기 때문에 연산할 때에는 순서를 조심해야 한다. 

 

 이때까지 살펴본 연산자에도 우선순위가 존재한다. 산술 연산자의 우선순위로만 따지면 아래와 같다. 간단하게 사칙연산의 우선순위에 지수가 추가되었다고 생각하면 된다.

 

 

우선순위대로 연산하지 않고 다른 순서로 하고 싶은 경우에는 수학처럼 먼저 하고 싶은 연산에 괄호를 써 주면 된다. 

 

 아래는 파이썬에서 사용되는 중요한 연산자에 대한 우선순위를 정리한 표이다. 이 모든 걸 일일이 기억하기는 힘드니, 우선순위가 헷갈릴 때에는 먼저 하고 싶은 연산에 괄호를 씌워주는 것도 좋다. 

연산자 설명
** 지수 연산자
~, +(단항), -(단항) 단항 연산자
*, /, //, % 곱셈, 나눗셈, 나머지 연산자
+, - 덧셈, 뺄셈
>>, << 비트 이동 연산자
& 비트 AND 연산자
^, | 비트 XOR 연산자, 비트 OR 연산자
<=, <, >, >= 비교 연산자
==, != 동등 연산자
=, %=, /=, //=, -=, +=, *=, **= 할당 연산자, 복합 할당 연산자
is, is not 아이덴티티 연산자
in, not in 소속 연산자
not, or, and 논리 연산자 

 

random 모듈과 math 모듈

 

 파이썬에는 개발자들이 프로그램을 쉽게 작성할 수 있도록 다양한 내장함수가 제공된다. 앞서 살펴봤던 print(), imput(), int(), str() 등을 포함해서 70여 가지 이상이 있다. 이 뿐만 아니라 표준 라이브러리에서 터틀 그래픽, 난수 생성기와 다양한 수학 함수 등의 기능을 제공한다. 이번에는 그 난수 생성기인 random 모듈과 수학 함수를 제공하는 math 모듈에 대해 간단하게 알아보자. 

 

 random 모듈은 임의의 수를 생성하거나, 어떤 리스트나 튜플 내의 요소를 무작위로 섞거나 선택하는 함수를 포함한다. 이 중 대표적인 함수 몇 가지를 써 보자. 

 

>>> import random                    #random 모듈을 불러온다.
>>> random.random()                  #0 이상 1 미만의 임의의 실수 생성
0.5636551720885258
>>> random.random()                  #매번 다른 실수를 생성해준다.
0.14049721316673058
>>> random.randint(17)             #1 이상 7 이하의 임의의 정수 생성
2
>>> random.randrange(7)              #0 이상 7 미만의 임의의 정수 생성
4
>>> random.randrange(0102)       #0 이상 10 미만의 수에서 
2                                    #2씩 건너뛴 수 중 임의의 정수 생성
>>> Alist = [1020304050]     #여러 값을 가지는 리스트
>>> random.shuffle(Alist)            #Alist의 순서를 섞는다.
>>> Alist
[2040305010]                 #섞였다! 
>>> random.choice(Alist)             #Alist의 원소 중 무작위로 하나를 고른다.
40
cs

 

math 모듈은 원주율 π, 자연상수 e 등 상수 값과 실수의 절대값, sin(), cos() 등의 다양한 수학 함수를 포함하고 있다. 역시 대표적인 예시 몇 가지를 살펴보도록 하자.

 

>>> import math                 #math 모듈을 불러온다.
>>> math.pow(23)              #2의 3제곱
8.0
>>> math.fabs(-99)              #-99의 실수 절대값
99.0
>>> math.log(e)                 #자연 상수 e를 부를 때는 
Traceback (most recent call last):
  File "<pyshell#23>", line 1in <module>
    math.log(e)
NameError: name 'e' is not defined
>>> math.log(math.e)            #math.e 로 불러오자.
1.0                             #log(x)는 밑이 e, 진수가 x다.
>>> math.log(10010)           #log(x, y)는 밑이 y, 진수가 x다.
2.0
>>> math.pi                     #마찬가지로 원주율 파이는
3.141592653589793               #math.pi 로 불러오자.
>>> math.sin(math.pi / 2.0)
cs

 

 이보다 더 많은 함수가 있으니, 잘 쓰면 다양한 문제 풀이의 열쇠로 작용할 것이다. 


 

마무리

 

 이번 시간에는 수식과 다양한 연산자, 우선순위, 그리고 random 모듈과 math 모듈에 대해 알아보았다. 

마지막으로 3장의 심화 문제 3.4, 3.6, 3.7, 3.9, 3.10을 풀어보고 마치도록 하자. 해답 코드는 접은글에 적어두었다. 늘 그렇지만 코딩에는 정답이 없기 때문에 접은글 속의 해답은 참고만 하도록 하자. 

 

3.4: 사용자로부터 입력받은 정수 값 n이 0에서 100의 범위 안에 있는 짝수인지 그렇지 않으지를 판단하는 코드를 작성하여 다음과 같은 결과가 나타나도록 하시오.

정수를 입력하세요 : 120
입력된 정수는 0에서 100의 범위 안에 있는 짝수인가요? False
정수를 입력하세요 : 88
입력된 정수는 0에서 100의 범위 안에 있는 짝수인가요? True
cs
더보기
number = int(input('정수를 입력하세요 : '))
print('입력된 정수는 0에서 100의 범위 안에 있는 짝수인가요?'
      number % 2 == 0 and 0 <= number <= 100)
cs

 

 

3.6: 사용자로부터 2개의 정수 a와 b를 입력으로 받은 다음 a를 b로 나눈 몫과 나머지를 다음과 같이 출력하시오.

정수 a를 입력하시오 : 202
정수 b를 입력하시오 : 50
/ b 의 몫 : 4
/ b 의 나머지 : 2
cs
더보기
= int(input('정수 a를 입력하시오 : '))
= int(input('정수 b를 입력하시오 : '))
print('a / b 의 몫 : ', a // b)
print('a / b 의 나머지 : ', a % b)
cs

 

 

3.7: 사용자로부터 세 자리 정수를 입력으로 받으시오. 이때 입력받은 정수 n에 대한 백의 자리, 십의 자리, 일의 자리 십진수 값을 다음과 같이 출력하시오. (힌트: // 연산자와 % 연산자를 사용하시오. 예를 들어 백의 자리는 n // 100을 통해서 구할 수 있다.)

세 자리 정수를 입력하시오 : 349
백의 자리 : 3
십의 자리 : 4
일의 자리 : 9
cs
더보기
number = int(input('세 자리 정수를 입력하시오 : '))
first = number // 100
second = number % 100 // 10
third = number % 10
print('백의 자리 : ', first)
print('십의 자리 : ', second)
print('일의 자리 : ', third)
cs

 

 

3.9: 이동 거리 구하기; 평균 시속과 이동 시간을 입력으로 받아 다음과 같이 이동 시간은 시간, 분, 초 단위로 출력하고, 이동한 거리를 계산하여 출력하시오.

평균 시속(km/h)을 입력하세요 : 46.5
이동 시간(h)을 입력하세요 : 12.342
평균 시속 : 46.5 km/h
이동 시간 : 12 시간 20 분 31 초
이동 거리 : 573.903 km
cs
더보기
= float(input('평균 시속(km/h)을 입력하세요 : '))
hour = float(input('이동 시간(h)을 입력하세요 : '))
minute = (hour - int(hour)) * 60     #float형에 int()를 쓰면 정수값만 남는다.
second = (minute - int(minute)) * 60
 
print('평균 시속 : ', v, 'km/h')
print('이동 시간 : ', hour, '시간', minute, '분', second, '초')
print('이동 거리 : ', v * hour, 'km')
cs

 

 

3.10: 다음과 같이 사용자로부터 두 점의 좌표 (x1, y1), (x2, y2)를 입력받아 두 점 사이의 거리를 출력하시오.

x1 좌표를 입력하시오 : 0
y1 좌표를 입력하시오 : 0
x2 좌표를 입력하시오 : 3
y2 좌표를 입력하시오 : 4
두 점의 거리 : 5.0
cs
더보기
x1 = int(input('x1 좌표를 입력하시오 : '))
y1 = int(input('y1 좌표를 입력하시오 : '))
x2 = int(input('x2 좌표를 입력하시오 : '))
y2 = int(input('y2 좌표를 입력하시오 : '))
distance = ((x2 - x1) ** 2 + (y2 - y1) ** 2** (1/2)
print('두 점의 거리 : ', distance)
cs
COMMENT
━━━━ ◇ ━━━━
따라하며 배우는 파이썬과 데이터 과학/PART 1. 파이썬 기초체력 다지기

Chapter 02. 값을 담아 다루어 보자

이번 시간의 목차

1. 데이터를 저장하고 싶다면 변수를 만들자!

2. 변수의 이름은 막 지어도 되는 걸까?

3. 변수를 쓰면 좋은 점이 뭘까?

4. 자료형이 무엇일까?

5. 문자열의 세계로

6. 자료형을 바꾸고 싶어!

7. 네 정보를 알려 줘! input() 함수

8. 컴퓨터가 만능인 건 아니구나?

9. 마무리

 

 

 

자, 가자! 파이썬의 세계로!


 

데이터를 저장하고 싶다면 변수를 만들자!

 

 1장에서 설명했듯, 세상에는 다양하고 방대한 데이터가 존재한다. 이러한 데이터를 쉽고 빠르게 처리하려면 데이터를 저장해서 필요할 때마다 꺼내서 사용해야 한다. 파이썬에서는 변수(Variable)에 데이터를 저장한다. 컴퓨터의 메모리(Memory) 공간에 이름을 붙여서 정수, 실수, 문자열 등의 자료값을 저장할 수 있다. 꺼내는 건 간단하다. 그냥 변수의 이름을 적어주면 된다. 한 변수에 든 자료값을 바꾸고 싶으면 언제든 정정하면 쉽게 바꿀 수 있기 때문에 하는 라는 이름이 붙었다. 

 

 예를 들어 10 km/h로 도로를 달리는 사람의 속력을 v라는 이름의 변수에 저장한다고 하자. 다음과 같이 입력하면 변수가 저장된다.

 

>>> v - 10
>>> v
10
cs

 

이렇게 v라는 변수에 10이라는 데이터가 저장되었다. 

 이때 등호(=)는 할당연산자 혹은 대입연산자라고 부르고, 좌변과 우변이 같다는 의미가 아닌 우변의 값을 좌변에 있는 v라는 변수에 저장하라는 의미를 갖는다. 

 

 변수의 값을 바꾸고 싶을 때에는 똑같이 등호를 사용하여 변수를 정정해주면 된다. 

 
>>> v - 10
>>> v = 30
>>> v 
30
cs

 

 처음에는 v에 10이라는 값을 넣어줬지만, v = 30으로 정정해주니 v에 30이라는 값이 저장되었다. 

 

 한 번에 여러 변수를 선언해서 동시에 값을 줄 수도 있다. 이때 사용된 문장은 동시 할당문이라 한다. 이렇게 설정된 변수끼리는 아래와 같이 덧셈이나 뺄셈 연산도 가능하다. 

>>> x = 150
>>> y = 180
>>> x, y
(150180)
>>> x, y = 160200     #동시에 여러 변수를 선언하고 할당할 수 있다.
>>> x, y
(160200)              #x와 y에 160과 200이라는 값이 저장된다. 
>>> z = x + y           #정수값이 저장된 변수끼리는 연산도 할 수 있다.
>>> z
360
cs

 

 

 지금까지는 변수에 숫자 데이터만 담아 봤지만, 이제는 문자열도 한 번 넣어보자. 

1장에서 언급했듯, 큰 따옴표 또는 작은따옴표로 싸인 문장은 문자열이 된다. 파이썬에서는 문자열 데이터를 객체라는 용어로 부르고, 문자열을 넣은 변수는 객체를 지칭하는 꼬리표가 되는 셈이다. 

 

>>> s1 = 'Hello Everyone!'
>>> s1
'Hello Everyone!'
>>> len(s1)                  #s1 문자열의 길이를 알려주는 함수.
15
>>> s2 = 'Hello'
>>> s3 = "Everyone!"
>>> s2 + s3                  #문자열에 + 연산자를 쓰면 두 문자열을 이어준다.
'HelloEveryone!'
>>> s4 = '100'
>>> s5 = '200'
>>> s4 + s5
'100200'                     #s4와 s5는 문자열 데이터다!
cs

 

변수의 이름은 막 지어도 되는 걸까?

 

 

 
>>> x = 2000         #오락실에서 게임을 2판 했다.
>>> y = 8500         #저녁으로 햄버거를 사 먹었다.
>>> z = 5400         #후식으로 음료를 사 마셨다.
>>> w = (x + y + z)  #이건 오늘의 지출.
>>> w
15900
cs

 

 “데이터를 저장하는 것이 변수라는 것은 이제 알겠어. 그렇다면 변수의 이름은 짓고 싶은대로 지으면 되는 거지?”

 

 아니! 그 전에 식별자(Identifier)에 대해서 먼저 알아야 한다. 변수의 이름은 식별자의 일종으로, 변수와 변수들을 구분하는 역할을 한다. 그러므로 변수의 이름을 지을 때에는 변수의 역할을 가장 잘 설명하는 이름으로 지어야 한다. 막 짓고 나서 나중에 돌아보면 코드를 짠 사람도 이해 못하는 경우가 종종 생기기 마련이다. 

 

 이때, 식별자는 다음의 규칙을 따른다. 

 

  • 식별자는 문자와 숫자, 밑줄 문자(_)로 이루어지며, 이 외의 특수문자는 쓸 수 없다.
  • 식별자의 첫 글자는 숫자가 될 수 없으며, 중간에 공백을 포함해서는 안 된다.
  • 대소문자는 구별된다. (첫 장에서 예를 들었듯, print와 PRINT는 서로 다르게 취급된다.)
  • 파이썬의 예약어(키워드)는 식별자로 쓸 수 없다

 

예약어의 종류는 아래의 31개가 있다. 

 

and as assert break class continue def del
elif  else except exec finally for from global
if import in is lambda not or pass
print raise return try while with yield  

 

위에서 설명한 규칙과 주의사항을 잘 생각해서 맨 위에서 설정한 변수를 바꾸면 아래와 같이 나타낼 수 있다.

 

>>> play = 2000               #오락실에서 게임을 2판 했다.
>>> dinner = 8500             #저녁으로 햄버거를 사 먹었다.
>>> dessert = 5400            #후식으로 음료를 사 마셨다.
>>> total = (play + dinner + dessert)  #이건 오늘의 지출.
>>> total
15900
cs

 

 


 

변수를 쓰면 좋은 점이 뭘까?

 

 변수를 쓸 때의 장점은 크게 두 가지로 나누어 볼 수 있다. 

 

  1. 이해하기 쉬우며 수정하기 쉽다.
  2. 데이터가 변경되어도 일의 방법은 바꿀 필요 없다. 

 

 BMI 계산으로 예를 들어보자. BMI는 kg 단위로 측정한 몸무게를 m 단위로 측정한 키의 제곱으로 나누면 구할 수 있다. 어떤 사람의 키가 180 cm, 78.2 kg라고 했을 때의 BMI는 이렇게 나타낼 수 있겠다. 

 

>>> 78.2 / 1.80 ** 2    #지수는 ** 연산자를 통해 나타낼 수 있다.
24.1358024691358
cs

 

 하지만 이렇게 나타내면 이 사람의 키나 몸무게가 늘고 줄었을 때 새로 BMI를 구하기가 번거롭다. 값을 일일이 바꿔 줘야하는 것은 물론이며, 지금은 간단한 계산이지만 복잡한 코드를 짤 때 어느 부분을 고쳐야 할지 헤매는 일이 생길 수 있다. 

대신 몸무게와 키, 그리고 BMI를 변수로 저장해 둔다면 어떨까?

 

>>> weight = 78.2
>>> height = 1.80
>>> BMI = weight / height ** 2
>>> BMI
24.1358024691358
 
>>> weight = 80    #몸무게와 키를 바꿔 봤다.
>>> height = 1.85
>>> BMI = weight / height ** 2
>>> BMI
23.37472607742878
cs

 

 이처럼 변수를 사용하면 가독성이 늘 뿐만 아니라 이 코드의 목적이 무엇인지 파악하기도 쉽다. 또, 몸무게와 키는 바뀌어도 BMI를 계산하는 방법은 바뀌지 않기 때문에 스크립트를 다시 실행해주기만 하면 변경된 데이터로 새 BMI를 계산해낼 수 있다.


 

자료형이 무엇일까?

 

>>> number = 10
>>> word = 'words'
>>> number + word 
cs

 

 number에는 정수 10을, word에는 문자열 'word'를 저장해봤다. 위의 코드를 입력하면 어떤 결과가 나올까?  

 

>>> number = 10
>>> word = 'words'
>>> number + word 
Traceback (most recent call last):
  File "<pyshell#27>", line 1in <module>
    10 + 'word'
TypeError: unsupported operand type(s) for +'int' and 'str'
cs

 

 어쩌면 당연하게도 오류 문구가 뜬다. 

오류 문구에서 type과 int, str에 주목하자. 두 변수끼리 + 연산자를 쓸 수 없는 이유는 바로 두 변수의 자료형(Data Type)이다르기 때문이다. 자료형은 프로그램에서 사용할 수 있는 데이터를 말하는데, 파이썬에서 다루는 가장 단순한 기본 자료형은 아래의 4가지가 있다. 

 

자료형 설명 예시
정수(int) 정수로 된 숫자. -2, -14, 0, 25, 100…
실수(float) 실수로 된 숫자. 3.14, 0.00009, 1.414…
문자열(str) 따옴표로 싸인 문자 'word', "Hello World!", '1.414', '자료형'
부울형(bool) 참과 거짓 True, False

 

 이 외에도 리스트, 튜플, 딕셔너리, 집합 등의 다양한 자료형이 있지만 후에 상세하게 다룰 것이니 지금은 생략한다. 더 자세히 알고 싶다면 이쪽(https://www.w3schools.com/python/python_datatypes.asp)을 참고하자. 

 

 다른 언어에서는 변수를 선언할 때 따로 자료형을 지정해줘야 하지만 파이썬에서는 따로 지정할 필요 없이 다양한 자료형을 저장 및 수정할 수 있다. 파이썬은 프로그램이 시작한 이후 변수에 값을 넣을 때 자료형이 정해지는 동적 형결정(Dynamic Typing)을 쓰기 때문이다. 앞에서 말했듯 자료형을 지정해주는 번거로움이 없지만, 위의 예시처럼 정수와 문자열끼리 +연산자를 사용하는 등 옳지 않은 연산을 할 경우 오류가 발생할 수 있으니 주의해야 한다. 

 

 자료형을 알고 싶다면 type() 함수를 사용하면 된다. 위의 예시에 나왔던 number와 word의 자료형을 확인해보자.

 

>>> number = 10
>>> word = 'words'
>>> type(number)
<class 'int'>    #int는 정수를 의미한다.
>>> type(word)
<class 'str'>    #str은 문자열을 의미한다.
cs

 

 이렇게 자료형을 바로바로 반환해주는 것을 볼 수 있다. 

 

 그런데, 자료형이 다른 게 무슨 의미가 있는 걸까? 아래의 예시를 잠시 살펴보자.

 

>>> print(100 + 200)
300
>>> print('100' + '200')
100200
cs

 

 정수로 된 100과 200에 + 연산자를 사용했을 때와 문자열 '100'과 '200'에 + 연산자를 사용했을 때의 결과가 다르다. 이렇게 자료형이 다르면 각종 연산의 의미가 완전히 달라지기 때문에 변수의 자료형을 잘 구분하여 사용할 필요가 있다. 

 


 

문자열의 세계로

 

 컴퓨터에서는 물론 숫자도 중요하지만, 컴퓨터를 조작하는 인간은 주로 텍스트를 사용하여 정보를 다루기 때문에 프로그래밍을 할 때 텍스트 처리도 중요한 사항 중 하나이다. 앞서 말했지만, 이 텍스트를 프로그래밍 언어로는 문자열이라고 한다. 문자열에는 'b', 'word', '안녕하십니까', '365' 등 숫자나 알파벳 등 뿐만 아니라 우리 눈에 보이지 않는 공백이나 탭(Tab), 줄바꿈 등도 문자열의 일부가 된다. 

 

 파이썬에서는 이 문자열을 아주 간단하고 직관적으로 다룰 수 있다. 이 역시도 후에 자세하게 배우게 될 테니, 우선은 문자열의 기초부터 알아보도록 하자. 

 

>>> 'Today is May 26th.'
'Today is May 26th.'
>>> now = 'Today is May 26th.'
>>> now
'Today is May 26th.'
>>> print(now)
Today is May 26th.
>>> 'Today is May 26th."
SyntaxError: EOL while scanning string literal
cs

 

 앞에서 간간이 해 봐서 알겠지만, 큰 따옴표나 작은따옴표로 감싸면 문자열로 취급한다. 문자열은 변수에 저장될 수 있으며, 저장된 문자열은 변수 이름 또는 print(변수 이름)으로 불러올 수 있다. 

 

 이때 문자열의 양 끝에 작은따옴표와 큰 따옴표를 섞어서 붙이면 위처럼 오류가 발생한다. 오류 문구 중 EOL은 End Of Line의 약자로, 'Today is May 26th."라는 문장을 작은따옴표로 시작했으므로 문자열을 끝내는 작은 따옴표를 찾아봤으나, 줄의 끝까지 찾아도 없었다는 뜻이다. 즉, 작은따옴표로 시작한 문장을 큰 따옴표로 끝낼 수 없다. 

 

 

“그런데, 이렇게 헷갈릴 거면 작은 따옴표 하나만 쓰면 안 되나?”

 

 

 분명 이런 의문이 들 테다. 그렇다면 예시를 들어보자. 

 

 

>>> myself = Hello
Traceback (most recent call last):
  File "<pyshell#49>", line 1in <module>
    myself = Hello
NameError: name 'Hello' is not defined
>>> myself = 'Hello! I'm studying Python. I'm enjoying now!'
SyntaxError: invalid syntax
cs

 

 첫 줄처럼 따옴표를 쓰지 않으면 Hello라는 이름이 정의되지 않았다는 문법 오류가 발생한다. 파이썬에서는 따옴표가 붙지 않은 단어를 변수로 취급하기 때문에 Hello라는 이름의 변수가 없다고 받아들이고 위와 같은 오류 문구를 보내는 것이다. 

 

 그래서 따옴표를 붙이긴 해야 하는데, 만약 큰 따옴표 없이 두 번째 문장처럼 작은따옴표만 사용해서 문자열을 정의하게 되면 작은따옴표로 시작해서 다음 작은따옴표가 나오는 곳까지를 문자열로 인식해서 문자열(초록 글씨) 사이의 m studying Python. I는 알 수 없는 명령어 또는 변수로 인식한다. 

 

 

>>> myself = "Hello! I'm studying Python. I'm enjoying now!"       #큰 따옴표와 작은따옴표를 번갈아 쓰면 오류가 나지 않는다.
>>> myself 
"Hello! I'm studying Python. I'm enjoying now!"
>>> print(myself)
Hello! I'm studying Python. I'm enjoying now!
>>> print('Hello! I\'m studying Python. I\'m enjoying now!')       #또는 작은따옴표 앞에 역슬래시(\)를 붙여도 된다.
Hello! I'm studying Python. I'm enjoying now!
>>> print('Hello! I\'m studying Python. \t I\'m enjoying now!')    #\t는 탭 문자를 표시한다.
Hello! I'm studying Python.      I'm enjoying now!
>>> print('Hello! I\'m studying Python. \n I\'m enjoying now!')    #\n은 줄바꿈을 표시한다.
Hello! I'm studying Python.
I'm enjoying now!
cs

 

 이를 피하려면 큰 따옴표와 작은따옴표를 번갈아가며 쓰거나, 시작한 따옴표와 같은 따옴표 앞에 역슬래시(\)를 붙여주면 오류가 나지 않는다. 역슬래시는 특수한 문자를 표기하는 데에 사용된다. 특히 \t는 탭 문자를, \n은 줄바꿈을 표시해준다. 역슬래시를 출력하려면 2개를 연속해서 써 주면 된다. 

 


 

자료형을 바꾸고 싶어!

 

 잠시 조금 전 봤던 number와 word 사이의 + 연산자 사용으로 돌아가보자.

 

>>> number = 10
>>> word = 'words'
>>> number + word
Traceback (most recent call last):
  File "<pyshell#57>", line 1in <module>
    number + word
TypeError: unsupported operand type(s) for +'int' and 'str'
cs

 

 우리는 이제 이 명령이 왜 오류를 내는지 알고 있다. 'words'를 숫자로 바꿀 수는 없으니 10을 문자열로 바꾸면 될 것 같은데… 어떻게 하면 바꿀 수 있을까? 간단하다. str() 함수를 사용하면 된다. 

 

 

>>> number_str = str(number)
>>> type(number_str)
<class 'str'>
cs

 

 str() 함수는 괄호 속에 있는 데이터(여기서는 number라는 변수에 저장된 10이다.)를 문자열로 바꿔서 반환한다. 실제로 str(number)라는 데이터를 저장한 number_str이라는 변수의 자료형을 type() 함수로 확인해 보니 'str', 즉 문자열로 바뀌어 있다. 

 

 문자열을 정수 또는 실수로 바꾸고 싶다면 int(), 그리고 float() 함수를 사용하면 된다. 아래처럼 int()는 정수로, float()는 실수로 바꿔주는 역할을 한다. 

 

>>> n1 = '1024'
>>> n2, n3 = int(n1), float(n1)
>>> print(n2, n3)
1024 1024.0
cs

 

네 정보를 알려 줘! input() 함수

 

 이때까지 다양한 변수에 데이터를 담고 연산을 해 봤는데, 계속 변수에 직접 프로그램을 짜는 사람이 값을 집어 넣으면 많은 문제가 생길 것이다. 그렇다면 필요한 값을 사용자에게 직접 물어 입력하도록 하면 어떨까? 이럴 때에 쓰는 함수가 바로 input() 함수이다. 

 

input_string = input(output_string)
cs

 

 위처럼 입력하고 실행하면 괄호 속 output_string에 담긴 문자열이 출력되고 사용자의 입력을 기다리게 된다. 입력하고 싶은 것을 입력하고 엔터키를 누르면 입력받은 문자를 하나의 문자열로 만들어 input_string에 저장하게 된다. 

 

 간단하게 예시를 들어보자. 

 

>>> name = input('당신의 이름은 무엇인가요? : ')
당신의 이름은 무엇인가요? : 손오공
>>> name
'손오공'
cs

 

 이렇게 name에 '손오공'이라는 이름이 저장되는 것을 볼 수 있다. 

조금 더 응용해서 입력받은 문자열을 정수로 바꿔 연산까지 해 보자. 

 

= int(input('첫 번째 정수를 입력하시오: '))
= int(input('두 번째 정수를 입력하시오: '))
= x + y
print(x, '과', y, '의 합은', z, '입니다.')
cs

 

입력받은 문자열을 정수로 바꾸려면 아까 배웠던 int() 함수로 input(~)을 감싸주면 된다. 실수 값으로 바꾸고 싶다면 float()로 감싸면 된다. 

 


 

컴퓨터가 만능인 건 아니구나?

 

 척 보면 컴퓨터는 사람이 손으로 일일이 계산할 시간에 일반 계산기로도 해낼 수 없는 계산을 한 번에 해내기도 한다. 하지만 이런 컴퓨터에게도 한계가 있다. 예를 들어볼까? 기약 분수 중에서도 1/3 같이 분모의 인수에 2와 5가 포함되지 않은 분수의 경우 소수로 나타낼 시 무한 소수로 나타낼 수 있다. 그렇다면 컴퓨터도 1/3을 0.33333333333… 같은 무한 소수로 나타내는 걸까? 

 

>>> 1/3
0.3333333333333333
cs

 

 답은 '아니오'이다. 컴퓨터의 저장공간은 유한하기 때문에 무한을 표현할 수는 없다. 대신 0.33333333333… 이라는 값과 비슷한 0.3333333333333333이라는 근사치를 표현한다. 한마디로 컴퓨터에서 미세한 수치오류는 불가피한 것이다. 

 

 그래서 여러가지 계산을 하다 보면 아래와 같은 황당한 상황이 일어나기도 한다. 이런 상황이 일어날 것을 항상 염두에 두고 프로그램을 작성해야 한다.

 

>>> 0.1 + 0.1 == 0.2       #이때 == 연산자는 양변을 비교하여
True                       #같으면 True, 다르면 False를 반환한다.
>>> 0.1 + 0.1 + 0.1 == 0.3
False
>>> 0.1 + 0.1 + 0.1        #우리가 아는 값과 다른 값이 나온다! 
0.30000000000000004
cs

 

 이런 오류가 있기는 하지만, 파이썬은 시스템의 메모리가 허용하는 한도 내라면 얼마든지 큰 수를 표현할 수 있다는 장점도 갖고 있다. 10의 100제곱은 손으로 쓰려면 0을 100번이나 적어야 하는 큰 수이지만, 파이썬은 이까지도 표현할 수 있다. 

 

>>> 10 ** 100  #이때 ** 연산자는 뒷 숫자를 앞  지수로 올려준다. 
1000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
cs

 

 


 

마무리

 

  이번 시간에는 변수라는 개념과 다양한 자료형에 대해 알아보았다. 

마지막으로 2장의 심화 문제 2.4, 2.5, 2.8, 2.9를 풀어보고 마치도록 하자. 해답 코드는 접은글에 적어두었다. 저번 시간에도 얘기했지만, 정답이 정해져 있는 것은 아니니, 해답 코드는 참고만 하도록 하자. 

 

2.4: width와 height라는 변수에 각각 40, 20 값을 할당한 후 이 두 변수를 이용하여 곱셈 연산자를 정용한 후 다음과 같이 삼각형의 면적(area)을 구하는 프로그램을 작성하시오. 

삼각형의 면적 : 400.0
cs

 

더보기
width, height = 4020           #동시 할당문을 사용하면 편리할 것이다.
area = width * height * 0.5      #1/2를 곱하고 싶다면 0.5 대신 (1/2)를 써도 좋다.
print('삼각형의 면적 : ', area)
cs

 

 

2.5 정사각형의 면적을 구하기 위하여 사용자로부터 밑변의 길이를 정수로 입력받아서 다음과 같이 출력하시오. (힌트: 정수값 입력을 받기 위하여 int(input('정사각형의 밑변을 입력하시오 : '))를 사용함.)

정사각형의 밑변을 입력하시오 : 40
정사각형의 면적 :  1600
cs

 

더보기
under = int(input('정사각형의 밑변을 입력하시오 : '))
area = under * under   #또는 under ** 2 도 좋다. 
print('정사각형의 면적 : ', area)
cs

 

 

2.8 섭씨온도(celsius)를 화씨온도(fahrenheit)로 변환하는 식은 다음과 같다. 

farenheit = (9/5* celsius + 32
cs

이 식을 바탕으로 섭씨온도를 0도에서 50도까지 10도 단위로 증가시키면서 이에 해당하는 화씨온도를 다음과 같이 출력하는 프로그램 cel2fah.py를 작성하시오. 

섭씨  화씨
0 32.0
10 50.0
20 68.0
30 86.0
40 104.0
50 122.0
cs
더보기
 
print('섭씨 ''화씨')
 
celsius = 0
fahrenheit = (9/5* celsius + 32
print(celsius, fahrenheit)
 
celsius = 10
fahrenheit = (9/5* celsius + 32
print(celsius, fahrenheit)
 
celsius = 20
fahrenheit = (9/5* celsius + 32
print(celsius, fahrenheit)
 
celsius = 30
fahrenheit = (9/5* celsius + 32
print(celsius, fahrenheit)
 
celsius = 40
fahrenheit = (9/5* celsius + 32
print(celsius, fahrenheit)
 
celsius = 50
fahrenheit = (9/5* celsius + 32
print(celsius, fahrenheit)
cs

 

 

2.9: 앞서 다룬 섭씨온도를 화씨온도로 변환하는 식을 바탕으로 사용자로부터 섭씨온도를 입력받아서 다음과 같이 화씨온도로 출력하시오.

섭씨온도를 입력하세요 : 30
섭씨 30 도는 화씨 86.0 도 입니다. 
cs

 

더보기
celsius = int(input('섭씨온도를 입력하세요 : '))
fahrenheit = (9/5* celsius + 32
print('섭씨 ', celsius, '도는 화씨 ', fahrenheit, '도 입니다.')
cs
COMMENT
━━━━ ◇ ━━━━
따라하며 배우는 파이썬과 데이터 과학/PART 1. 파이썬 기초체력 다지기

Chapter 01. 데이터 과학과 파이썬의 세계로

이번 시간의 목차

1. 이 많은 데이터를 어떻게 처리하는 걸까?

2. 프로그래밍에 대해 먼저 알아보자!

3. Life is too short, You need Python

4. 본격적으로 파이썬을 활용해 보자!

5. 파이썬 개발 도구란?

6. 문자열과 숫자?

7. 이것 덕분에 파이썬이 편리해졌지!

8. 모듈을 써 보자!

9. 빨간 줄글, 혹시 이게 오류?

10. 마무리

 

 

 

자, 가자! 파이썬의 세계로!


 

이 많은 데이터를 어떻게 처리하는 걸까? 

 

 세상은 데이터로 가득하다. 인구, 교통, 날씨, 시청 기록, 매출 자료, 댓글 등… 우리 생활에서는 수많은 데이터가 쏟아져 나오고, 이 양은 셀 수 없을 정도로 방대하다. 이 데이터를 어떻게 가공해야 의미 있는 정보를 추출할 수 있을까?

 

 이를 위해 우리가 응용할 수 있는 학문 중 하나가 바로 데이터 과학(Data Science)이다. 데이터 과학이란 과학적 방법으로 정보나 지식을 추출하는 학문이고, 통계학, 컴퓨터 과학, 그리고 데이터가 발생하는 영역과 관련된 학문 분야의 이론과 기술을 융합적으로 사용해야 한다. 따라서 데이터 과학은 대표적인 학제 연구 분야라고 할 수 있다. 

 

 데이터 과학에서 데이터를 가공하는 과정을 크게 구분하면 아래의 다섯 가지 단계가 된다. 

교재 p.22의 그림을 참고했다.

 각 단계마다 전문성을 가지고 해당 업무에 종사하는 사람들이 존재한다. 

  • 데이터 엔지니어 : 데이터 수집과 정제에 전문적 역량을 가진 사람들을 통칭하여 부른다.
  • 데이터 분석가 : 데이터의 정제 작업부터 분석까지의 작업에 종사한다. 
  • 기계 학습 엔지니어 : 데이터를 이용하여 기계를 학습시키기 위한 학습 모델을 구축하고 이를 배포하는 일을 한다. 

 그리고 이 세 분야에 해당하는 역량을 모두 갖추고 다양한 문제를 해결하는 사람이 바로 데이터 과학자이다. 

 


 프로그래밍에 대해 먼저 알아보자!

 

 한편, 프로그래밍(Programming)이란 무엇일까? 

 그 전에 프로그래밍의 어원인 프로그램(Program)에 대해 먼저 알아보자. 프로그램이란 컴퓨터가 해야 할 일을 미리 기록해 놓은 작업 지시서 같은 것이다. 예로 들자면 우리가 많이 사용하는 파워포인트나 카카오톡, 크롬 등이 있다. 이런 프로그램을 작성하는 일을 프로그래밍이라고 하고, 이 일을 하는 사람을 프로그래머(Programmer)라고 한다. 

 

 전기 신호에 의해서 동작하는 컴퓨터는 0과 1, OFF와 ON의 이진(Binary) 값만을 이해한다. 프로그램 안에는 '무엇을 어떤 식으로 해라'와 같은 형태의 명령어(Instruction)가 존재하는데, 이 명령어 역시 0000100100001111… 과 같은 이진수 값으로 되어 있다. 이렇게 기계가 이해할 수 있는 명령어를 기계어(Machine Code)라고 한다. 

 

 하지만 기계어 명령은 사람이 이해하기는 너무 어렵다. 그래서 실제로 개발을 할 때에는 사람이 이해할 수 있는 언어를 사용해서 명령을 나타내고, 이렇게 만들어진 명령어를 기계어로 번역하여 프로그램을 만든다. 이렇게 프로그램을 작성하기 위해 사람이 이해할 수 있도록 만든 언어를 프로그래밍 언어(Programming Language)라고 하며, 이 언어를 이용해서 사용자가 원하는 일을 작성한 것을 소스 코드(Source Code)라 한다. 프로그래밍 언어는 컴퓨터가 이해할 수 있도록 기계어로 번역되어야 하기 때문에 엄격하게 약속된 문법을 따른다. 

 

 그렇다면 우리는 왜 프로그래밍에 대해 알아야 하는 걸까?

 인간과 컴퓨터는 상호 보완적인 특징을 가지고 있고, 인간의 부족한 점을 컴퓨터가 쉽게 메울 수 있다. 앞서 말했듯 방대한 데이터를 예시로 들어 보자. 사람이 그 데이터를 일일이 분류한다면 적어도 몇 시간은 걸릴 테지만, 컴퓨터는 명령만 주어지면 몇 분, 혹은 몇 초 안에 끝낼 수 있다. 이처럼 지루하고 반복되는 일을 컴퓨터한테 시키려면 우리가 컴퓨터 언어를 배워서 컴퓨터와 대화할 수 있어야 한다. 그를 위해서는 프로그래밍을 필수적으로 배워야 한다. 

 


 

Life is too short, You need Python
인생은 너무 짧으니 파이썬이 필요하다.

 

TIOBE에서 선정한 2021년 5월의 프로그래밍 언어 그래프. 파이썬(검은 선)이 현재 2위를 차지하고 있다.

 

세상에는 다양한 프로그래밍 언어가 존재한다. 모든 언어가 각자 고유의 문법 체계를 가지고 있고, 프로그래머들은 각자에게 맞는 언어를 골라 사용한다. 대표적인 언어로는 'C', 'C++', 'JavaScript', 그리고 우리가 앞으로 다룰 'Python' 등이 있다. 

 

 파이썬(Python)은 귀도 반 로섬이 1991년에 개발한 대화형 프로그래밍 언어로, '인생은 너무 짧으니 파이썬이 필요하다' 라는 말이 있을 정도로 생산성과 효율성이 뛰어나다. 무엇보다도 파이썬은 인터프리터를 통하여 작성한 문장의 결과를 바로바로 확인할 수 있는 인터프리터 언어이기 때문에 간편하게 실행을 살펴볼 수 있다. 덕분에 간결하면서도 효율적인 프로그램을 빠르게 작성할 수 있어 초보자의 프로그래밍 입문에도 적합하다. 

 


본격적으로 파이썬을 활용해 보자!

 

 파이썬을 활용하기 위해서는 우선 파이썬 인터프리터와 기본 라이브러리, 그리고 개발도구를 설치해야 한다. 이는 파이썬 소프트웨어 재단에서 관리하고 있으며, 홈페이지는 아래의 링크를 통해 접속할 수 있다. 

 

 

http://www.python.org/

다운로드 전 사용 중인 운영체제를 꼭 확인하자. 

  다운받은 후 실행하면 아래와 같은 화면이 나타날 것이다. 

 

②Install Now를 클릭하면 바로 설치가 시작되지만, ①의 체크박스를 잠시 확인해 보자.

  • Install launcher for all users : 선택할 시 이 컴퓨터를 사용하는 모든 사용자가 파이썬을 이용할 수 있는 설정이다. 
  • Add Python 3.9 to PATH : 명령 프롬프트 (흔히 cmd라고도 한다.)에서도 파이썬 셸로 접근할 수 있게 해주는 설정이다. 

 두 설정 모두 체크해 두면 편리하다. 물론 지금 선택해두지 않아도 언제든지 설치 프로그램을 다시 실행해서 체크박스를 선택하고 활성화할 수 있다. 

 

 

 이제 본격적으로 파이썬을 활용해 보자. 

아래 화면은 Python을 실행하면 나타나는 창, 인터프리터(Interpreter)이다. 

 

 

  1. 첫 줄에서는 현재 사용중인 파이썬의 버전 등의 정보를 알려주고 있고, 다음 줄에는 다른 정보를 위한 명령을 나타내고 있다.
  2. >>> 로 키보드 입력을 받으려 대기하고 있는 곳을 나타내고 있다. 이를 프롬프트(Prompt)라고 한다. 
  3. 프롬프트에 명령을 입력한다. 이때 print()는 파이썬의 내장 함수(Built-in Function)로, 괄호 속 값을 출력해주는 역할을 한다. 
  4. 프롬프트에 입력된 명령을 수행하여 출력해주고 있다. print() 함수를 통해 Hello Python!!이라는 문자열(String)이 나타내진다. 

※ 이때 print() 속의 문자열에는 반드시 작은따옴표나 큰 따옴표를 붙여주자. 문자열은 따옴표가 없으면 컴퓨터가 받아들이지 못한다. 작은따옴표의 끝에는 작은따옴표, 큰 따옴표의 끝에는 큰 따옴표. 

 


파이썬 개발 도구란?

 

 위에서 사용한 인터프리터로 코딩을 하다보면 몇 가지 문제가 생긴다. 한 번 입력하고 엔터를 눌러버리면 끝이기 때문에 수정이 어렵고, 한 번 수행한 일을 다음에 다시 시키기가 어렵다. 이를 피하려면 명령어들을 모아서 소스 코드를 만들어 하나의 파일로 저장해 두어야 한다. 우리는 이 작업을 파이썬의 통합 개발 도구인 IDLE(Integrated Development and Learning Environment)에서 진행할 것이다. 

 

인터프리터에서 실행한 명령을 그대로 IDLE에서 수행해보았다.

 

 소스 코드를 저장하려면 IDLE 프로그램의 File-New File 메뉴로 새 파일을 만들어 편집하거나, Ctrl+n 버튼으로 새 파일을 만들어 편집해야 한다. 위 이미지는 새 파일에 명령을 입력하고 '1-9'라는 이름으로 저장 후 실행하여 인터프리터 창에 결과가 나타난 화면이다. 

 

 잠시 붉은색으로 표시된 # 이하의 문장을 살펴보자. 

이 문장은 주석(Comment)으로, 쉽게 말하자면 컴퓨터가 아닌 프로그램을 읽는 사람을 위한 설명글이다.

 

#이렇게 주석을 달 수도 있고
'''이렇게 주석을 달 수도 있고'''
"""
또는 이렇게
할 수도 있다.
""" 
cs

 

 파이썬에서는 보통 #으로 시작하는 문장을 주석으로 취급하여 실제로 프로그램을 실행하면 주석을 무시하고 나머지 코드를 읽어 실행한다. 또는 작은따옴표나 큰 따옴표를 3개 사용해서 주석으로 달 수도 있다. 

 

 


문자열과 숫자?

 

 이제는 print() 함수를 써 보자. 

 

>>> 'Hello'                         #문자열 'Hello'
'Hello'
>>> "Hello"                         #작은 따옴표, 큰 따옴표 상관 없이 똑같은 문자열.
'Hello'
>>> print('Hello')                  #print()로 문자열을 출력하면 따옴표가 안 나온다.
Hello
>>> print("배가 " + "고픈데 뭐 먹지"#텍스트끼리 연결해서 출력할 수도 있다.
배가 고픈데 뭐 먹지 
>>> print('재밌다!' * 5)             #*연산자는 문자열을 n번 반복해서 출력해준다. 
재밌다! 재밌다! 재밌다! 재밌다! 재밌다! 
 
cs
 
 " " 나 ' '로 싸이면 텍스트 정보를 담은 문자열이 된다.
문자열끼리 + 연산자를 사용하면 해당 문자열을 이어 붙여준다. 
또 문자열에 * (횟수)를 붙여주면 해당 문자열을 (횟수)만큼 반복해서 출력해준다. 
 참, 이때 명령을 한 줄 입력하고 엔터키를 눌러 실행하고 바로 결과가 나오는 모드를 대화형 모드(Interpreter mode)라고 한다. 이 대화형 모드가 있어서 초보자에게 아주 편리하다.
 
 파이썬으로는 문자 뿐만 아니라 숫자도 다룰 수 있다.
컴퓨터는 기본적으로 계산하는 기계(Computer의 'Compute'가 '계산하다'라는 뜻이다.)인 만큼 계산에 매우 강력하다. 
 
>>> 2 + 8
10
>>> print(2 + 8)
10
>>> print(3 - 7)
-4
>>> print(3 * 7)
21
>>> print(21 / 3)
7
cs

 이렇게 간단한 계산은 물론,

 

>>> print(1048 * 23542 - 100000)
24572016
cs
 

 

계산기로 계산해야 하는 복잡한 계산이나,

 

>>> print(21352350128350 * 12304982305)
262740290499511228846750
cs

 

계산기도 하기 힘든 큰 수끼리의 계산도 해낼 수 있다. 

 

 

 이때 우리는 문자열로 나타내진 숫자와 말 그대로 숫자로 사용되는 수를 구분하여 사용해야 한다. 

 

>>> print(120 + 523)      #숫자 120과 523의 합을 구하여 출력한다.
643
>>> print('120' + '523')  #문자열 120과 523을 이어서 출력한다. 
120523
 
cs

 

 보이는 것처럼 문자열로 나타내진 숫자와 숫자로 사용되는 수에 똑같은 연산자를 적용했을 때의 결과가 다르다. 

잠시 연습해 보고 넘어가자. 아래는 교재 p.39 심화문제 1.3을 약간 수정하여 옮겨놓은 것이다. 해답은 접은글에 적어두었다.

 

print(100)
print(100 + 200)
print('100 + 200')
print(100200)
print('100''200')
print('100''200')
print('Hello Python!')
print('Hello''Python''!')
print('Hello' + 'Python' + '!')
print('Hello''Python''!')
print('**********')
print('*' * 10)
cs
더보기
>>> print(100)
100
>>> print(100 + 200)
300
>>> print('100 + 200')
100 + 200
>>> print(100200)
100 200
>>> print('100''200')
100 200
>>> print('100''200')
100200
>>> print('Hello Python!')
Hello Python!
>>> print('Hello''Python''!')
Hello Python !
>>> print('Hello' + 'Python' + '!')
HelloPython!
>>> print('Hello''Python''!')
HelloPython!
>>> print('**********')
**********
>>> print('*' * 10)
**********
cs

 

 


이것 덕분에 파이썬이 편리해졌지!

 

  함수나 변수, 클래스 등을 스크립트 파일로 만든 것을 모듈(Module)이라 하고, 파이썬을 설치하면 기본적으로 제공되는 모듈을 표준 라이브러리(Standard Library)라 한다. 파이썬으로 여러 문제를 해결하려면 이 표준 라이브러리뿐만 아니라 이미 만들어진 프로그램 코드를 활용해야 한다. 많은 라이브러리 중에서 파이썬 커뮤니티에서 공식적으로 인증한 라이브러리나 검증된 라이브러리를 패키지(Package)라고 부른다. 

 

 그럼 우선 우리가 앞으로 사용할 패키지를 불러와 보자. 아래의 두 과정을 거치면 된다. 

  1. 파이썬 시스템에 pip라는 프로그램을 이용하여 패키지를 설치한다.
  2. 설치된 패키지를 활용을 위해 불러온다.

 이때 pip는 파이썬의 패키지 관리 소프트웨어로, 파이썬 표준 라이브러리에 포함되지 않은 외부 라이브러리를 설치할 수 있도록 돕는 도구이다. pip를 쓸 때는 명령 프롬프트를 실행시켜 아래와 같은 명령을 입력해야 한다. 

 

pip install (패키지 이름)

 

예시로 missingno 패키지를 설치해 보았다. 

 성공적으로 설치가 되었다면 위처럼 'Successfully installed (패키지 이름)'이라는 문구가 뜬다. 아래 노란 문구는 pip를 업데이트 시키라는 알림 문구이니 무시해도 좋다. (그래도 업데이트는 제때 해 주자.) 

 

 우리가 앞으로 써야 할 모듈은 numpy, pandas, matplotlib, scikit-learn, opencv-python, seaborn으로 총 6가지이다. 한 번에 설치할 때는 쉼표를 쓰지 않고 pip install numpy pandas matplotlib scikit-learn opencv-python seaborn을 입력해주면 된다. 

 

 설치된 패키지를 불러오려면 아래처럼 import와 함께 모듈 이름을 써 주면 된다. 

 

import module-name
module-name.func()
cs

 

 위를 참고하여 가상의 모듈 'module-name'을 불러와서 모듈에 있는 'func'라는 기능을 사용할 수 있다.


모듈을 써 보자!

 

 기껏 모듈에 대해서도 알아봤겠다, 이제 파이썬에서 지원해주는 모듈을 하나 써 보자. 

터틀 그래픽(Turtle Graphic)은 2차원 화면에 놓인 로봇 거북이에게 명령을 내려 그림을 그리는 기능이다. 캔버스를 불러오려면 아래의 절차를 따른다. 

 

import turtle            #turtle 모듈을 불러온다.
= turtle.Turtle()      #turtle 모듈에 있는 Turtle 클래스 객체를 t로 설정.
t.shape('turtle')        #Turtle 클래스 객체인 t의 모양을 거북이로 바꾼다. 
cs

위의 코드를 실행시키면 이런 캔버스가 생긴다. 

 

 거북이를 움직이는 명령어에는 forward(), backward(), left(), right() 등이 있다. 이때 forward()와 backward()의 괄호에는 앞 또는 뒤로 몇 픽셀 움직일지가 들어가고, left(), right()의 괄호에는 왼쪽 또는 오른쪽으로 몇 도 회전할지가 들어간다. 

 이를 활용해서 한 변이 100 픽셀인 정사각형, 정삼각형, 직각 이등변 삼각형, 마름모꼴+짧은 대각선을 그려보자. 해답 코드는 접은글에 적어두었다. 


더보기
import turtle            #turtle 모듈을 불러온다.
= turtle.Turtle()      #turtle 모듈에 있는 Turtle 클래스 객체를 t로 설정.
t.shape('turtle')        #Turtle 클래스 객체인 t의 모양을 거북이로 바꾼다. 
 
#정사각형
>>> t.forward(100)
>>> t.left(90)
>>> t.forward(100)
>>> t.left(90)
>>> t.forward(100)
>>> t.left(90)
>>> t.forward(100)
 
#정삼각형
>>> t.left(90)
>>> t.forward(100)
>>> t.left(120)
>>> t.forward(100)
>>> t.left(120)
>>> t.forward(100)
 
#직각 이등변 삼각형
>>> t.forward(100)
>>> t.left(135)
>>> t.forward(144)
>>> t.left(135)
>>> t.forward(100)
>>> t.left(90)
 
#마름모꼴
>>> t.forward(100)
>>> t.left(120)
>>> t.forward(100)
>>> t.left(120)
>>> t.forward(100)
>>> t.right(120)
>>> t.forward(100)
>>> t.right(120)
>>> t.forward(100)
 
cs
 

 


빨간 줄글, 혹시 이게 오류?

 

 혹시 여기까지 오면서 주어진 문제를 해결하다 빨간 줄글을 본 적이 있나? 분명 따옴표나 괄호 하나를 빼먹거나, 이미 정해진 이름을 잘못 입력해서 한 번쯤은 만난 적이 있을 것이다. 앞서 설명했듯, 컴퓨터는 정해진 문법만 이해하기 때문에 인간처럼 사소한 오타를 알아서 이해하지 못한다. 예를 들어 다음과 같이 입력해보자. 

빨간 줄글이 나타나도 놀라지는 말자.

 

 무언가를 출력하고 싶을 때에 쓰는 함수는 print()이다. PRINT()가 아니다. 이처럼 문법에 맞지 않는 문장을 입력하고 실행하면 오류(Error)를 출력한다. 파이썬은 대소문자를 구분하기 때문에 print가 아닌 PRINT가 오면 어떻게 처리해야 하는지 모른다. 

 

 이때는 놀라지 말고 침착하게 오류가 난 부분을 찾아 수정해주자. 위의 코드에서는 line 1, PRINT('Hello World')와 같이 어느 부분에서 오류가 났는지 나타내주고 있고, 맨 아래줄에는 NameError: name 'PRINT' is not defined라고 어떤 오류가 났는지 알려주고 있으니 그에 맞추어 코드를 수정해주면 된다. 

 

 아래는 흔히 볼 수 있는 오류 메세지들이다. 

 

  • SyntaxError: invalid syntax : 파이썬의 기본 문법을 지키지 않은 표현이 있음.
  • IndentationError: expected an indented block  : 들여쓰기를 해야 할 곳에 들여쓰기가 되지 않음.
  • IndentationError: unexpected indent : 들여쓰기를 하면 안 되는 곳에 들여쓰기가 되어 있음.
  • NameError: name x is not defined : 무언가의 변수가 정의되지 않았음. 
  • TypeError: unsupported operand type(s) for ... : 데이터의 종류가 다른 것들끼리 무언가가 일어났음. 

 


마무리

 

 지금까지 데이터 과학의 기초와 파이썬의 기본적인 기능에 대해 알아보았다. 

마지막으로 1장의 심화 문제 1.5, 1.9, 1.10을 풀어보고 마치도록 하자. 해답 코드는 접은글에 적어두었다. 하지만 코딩에는 정답이 없기 때문에 접은글 속의 해답처럼 풀지 않았다고 틀린 것은 아니다. 그러니 해답 코드는 참고만 하도록 하자.

 

1.5 : 'I love Python!!'을 5줄에 걸쳐 모두 5번 출력하는 코드를 만들어 보자. 이 코드를 포함한 파일을 welcome5.py라고 정하고 이 코드를 파이썬 인터프리터에서 수행시켜 보시오.

더보기
#심화 1.5
print('I love Python!!')
print('I love Python!!')
print('I love Python!!')
print('I love Python!!')
print('I love Python!!')
cs

 

 

1.9 : 파이썬 대화창을 이용하여 다음과 같은 수식 계산을 해 보도록 하자. 

더보기
 
#심화 1.9
>>> #1에서 10까지 정수의 합
>>> 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10
55
>>> #반지름의 길이가 5인 원의 둘레(이때 원주율 파이는 3.14로 두고 계산할 것)
>>> 2 * 5 * 3.14
31.400000000000002
>>> #한 변의 길이가 20인 정사각형의 둘레
>>> 4 * 20
80
>>> #한 변의 길이가 20인 정사각형의 면적
>>> 20 * 20
400
>>> #높이가 10이고 밑변이 30인 직사각형의 둘레
>>> 2 * (10 + 30)
80
>>> #높이가 10이고 밑변이 30인 직사각형의 면적
>>> 10 * 30
300
cs

 

1.10 : 파이썬 대화창을 이용하여 4!, 5!, 6!을 구하여 출력해 보자.

더보기
>>> #심화 1.10
>>> #4!
>>> 4 * 3 * 2 * 1
24
>>> #5!
>>> 5 * 4 * 3 * 2 * 1
120
>>> #6!
>>> 6 * 5 * 4 * 3 * 2 * 1
720
cs

 이때 대화창에서 Alt키와 p키를 같이 누르면 이전에 실행했던 명령을 그대로 가져온다. 이를 사용하면 좀 더 수월하게 이 문제를 풀 수 있을 것이다. 

COMMENT
1 2