관리 메뉴

승이네 반도체

8/23 (화) 김변수와 시작하는 코딩생활 with 파이썬 스터디 15일차(필수 파이썬 응용하기 / 가위바위보 게임) 본문

빅데이터 & 딥러닝 스터디/파이썬 스터디(김변수와 시작하는 코딩생활 3기)

8/23 (화) 김변수와 시작하는 코딩생활 with 파이썬 스터디 15일차(필수 파이썬 응용하기 / 가위바위보 게임)

승이네 2022. 8. 23. 00:10
반응형

 학습 내용 : 파트15. 파이썬 응용하기

 

 필수 과제 : 3-10. 가위바위보 게임

 

 

15. 파이썬 응용하기

 

 15-1. 모듈, 패키지, 라이브러리와 프레임워크

 

 프로그래밍을 하다보면 모듈, 패키지, 라이브러리, 프레임워크를 비슷하다고 생각할 것입니다.

(사실 저는 프로그래밍을 잘 몰라 라이브러리만 들어봤네요...ㅎㅎ)

이 4가지의 정의와 차이점을 간단히 알아보겠습니다.

 

모듈 : 함수, 변수, 클래스 등을 모아 놓은 파이썬 파일 1개

패키지 : 모듈 여러 개를 모아 관리하는 하나의 폴더

라이브러리 : 다른 사람들이 사용할 수 있도록 유용한 기능을 모듈이나 패키지로 만들어 놓은 것

프레임워크 : 목적(예 : 웹 개발)에 따라 코드를 쉽게 작성할 수 있도록 미리 만들어 놓은 뼈대

 

 자주 사용하는 코드를 모듈이나 패키지, 라이브러리, 프레임워크로 구현해 놓으면 코드를 여러 번 작성하는 수고를 덜 수 있습니다.

지금까지는 직접 모든 코드를 작성했지만 다른사람이 구현해 놓은 코드를 가져와 사용할 수도 있습니다.

 

 모듈을 사용하기 위해선 파일의 최상단에 import라는 코드를 적어야 합니다.

 

import 모듈 파일명

 

 모듈을 가져오는 방법을 배웠으니 이제 직접 생성하고 사용해 볼 것입니다.

 

 

구구단 2단을 출력하는 gugu2 함수를 정의한 gugudan 모듈을 직접 생성한 후 다른 파일에 불러온 것입니다.

 

같은 폴더에 있는 gugudan.py 파일
같은 폴더에 있는 practice.py 파일
practice.py 파일 실행 결과

 다음과 같이 모듈을 불러오는 파일은 그 모듈과 같은 폴더 안에 있는 파일이어야 합니다.

 

 여러 개의 모듈을 만들었다고 가정했을 때, 서로 연관된 모듈들을 모아 하나의 폴더에 넣어서 관라히게 됩니다.

이러한 폴더를 패키지라고 부르고, 여러 개의 패키지외 모듈의 집합을 라이브러리라고 부릅니다.

 

여기서는 파이썬에 기본적으로 포함된 라이브러리, 그 중에서도 자주 사용되는 random과 time 라이브러리를 예로 들어 라이브러리 사용법을 알아보겠습니다.

 

 

 15-2. 유용한 라이브러리

 

 이번에는 유용한 라이브러리를 불러와 사용해 보겠습니다.

파이썬에서 라이브러리를 사용하려면 직접 만든 모듈으 사용할 때와 같이 파일의 최상단에 import로 불러와야 합니다.

 

import 라이브러리명

 

 라이브러리를 사용할 때 거기에 어떤 함수가 들어 있는지 일일이 외워둘 필요는 없습니다.

해당 라이브러리를 설명해 놓은 문서나 웹사이트 등을 확인한 후 활용할 수 있으면 충분합니다.

 

1) random 라이브러리 - 임의의 수 생성

 

 random은 실행할 때마다 새로운 난수를 생성되도록 합니다. 그 임의의 수를 원하는 범위, 원하는 형식으로 생성할 수 있습니다.

random 라이브러리에는 random(), randint() 등의 함수가 포함되어 있습니다.

 

import로 random 라이브러리를 가져온 뒤에는 random.함수명()이라는 코드로 random 라이브러리에 속한 함수를 자유롭게 사용할 수 있습니다.

 

 이처럼 random의 실행 결과는 매번 다르게 나옵니다.

 

 randint() 함수를 사용해 1부터 100 사이의 임의의 정수를 출력하는 코드입니다.

 

 

2) 시간과 관련된 time 라이브러리

 

 time 라이브러리는 시간과 연관된 함수를 가지고 있습니다.

time 라이브러리에는 time(), ctime() 등의 함수가 포함되어 있습니다.

 

 time()은 UTC를 기준으로 한 시간을 실수 형태로 반환하는 함수입니다.

 

 ctime()은 현재 시각을 문자열로 반환하는 함수입니다.

 

 그 외 time 라이브러리에서 사용 빈도가 높은 함수 중 하나는 sleep() 함수입니다.

sleep() 함수를 사용화면 코드가 실행되는 중간에 일정한 시간 간격을 줄 수 있습니다.

위 코드를 실행시켜보면 "3초 뒤에 시작됩니다."가 출력되고 약 3초가 지나고 4초 시작될 때쯤? "hello wolrd"가 출력되었습니다.

위 코드처럼 time.sleep() 괄호 안에 숫자를 적으면 해당 숫자(초)만큼 기다리게 됩니다. 코드 내에서 시간 간격을 두고 싶을 때, 특히 반복문 내에서 일정한 시간간격을 두고 싶을 때 sleep()함수를 사용합니다.

 

 

 15-3. 오류의 종류

 

 파이썬 코드를 짜다가보면 오류가 어쩔 수 없이 생깁니다.

하지만 오류를 미리 알고 있다면 오류가 발생했을 때 해결하기 쉽습니다.

 

구문 오류 : 문법이 맞지 않아 발생하는 오류

런타임 오류 : 문법은 맞으나 명령어를 잘못 사용하여 발생하는 오류

논리 오류 : 실행은 되지만 프로그램의 논리가 맞지 않아 원하는 대로 결과가 나오지 않는 오류

 

1) 구문 오류(Syntax Error)

 

 구문 오류(Syntax Error)는 문법에 맞지 않는 경우, 쉽게 말해 오타가 있는 경우를 말합니다.

파이썬이 코드를 읽다가 문법이 잘못되면 이를 해석하지 못해 오류가 발생합니다.

이런 경우에는 'SyntaxError'라는 오류 문구가 출력됩니다.

 

 

 2) 런타임 오류(Runtime Error)

 

 런타임 오류(Runtime Error)는 코드를 실행하는 중에 발생하는 오류를 말합니다.

'SyntaxError'가 아닌 다른 오류 문구가 출력된다면 런타임 오류에 해당합니다.

 

 숫자를 0으로 나누거나, 정의하지 않은 변수 이름을 사용하거나, 모듈을 찾지 못하거나, 인덱싱이 잘못된 경우 등 다양한 종류의 런타임 오류가 있습니다.

 

 오류 상황은 굉장히 다양하기 때문에 모든 종류의 오류를 외우기는 어렵습니다.

그러나 오류 발생 상황에 조금 더 쉽게 대처하기 위해서 자주 발생하는 오류는 알아두는 것이 좋습니다.

 

NameError : 정의하지 않은 변수를 사용했을 때 발생하는 오류

ZeroDivisionError : 숫자를 0으로 나누었을 때 발생하는 오류

IndexError : 주로 리스트나 튜플에서 존재하지 않는 인덱스 위치로 인덱싱했을 때 발생하는 오류

KeyError : 주로 딕셔너리에서 존재하지 않는 key값으로 값을 가져오려 할 경우 발생하는 오류

AttributeError : 클래스와 라이브러리에서 존재하지 않는 속성이나 함수를 사용할 때 발생하는 오류

TypeError : 잘못된 타입이나 연산을 사용한 경우에 발생하는 오류. 특히 숫자 변수와 문자 변수를 연산하면서 가장 흔하게 발생.

 

 

 3) 논리 오류(Logic Error)

 

 논리 오류(Logic Error)는 구문 오류나 런타임 오류 없이 잘 실행 되었지만 원하는 대로 동작하지 않는 오류를 말합니다.

이것은 코드의 알고리즘을 잘못 구성하여 발생하는 버그로, 구문 오류나 런타임 오류 같이 별도의 오류 문구가 출력되지 않습니다.

따라서 직접 버그를 찾아야 합니다.

 

 위와 같이 10과 20을 더한 후 나누기 2를 해야하는데 원하는 값인 15가 나오지 않았습니다.

왜 그러냐면 avg = a + b / 2 부분에서 b / 2가 먼저되어 a + (b / 2) 이렇게 된 것입니다.

따라서 우리는 avg = (a + b) / 2로 작성해 주어야 합니다.

 

 

 15-4. 예외 처리

 

 구문 오류나 런타임 오류가 발생하면 프로그램이 비정상적으로 종료됩니다.

구문 오류의 경우에는 아예 코드를 읽을 수 없어 직접 오타를 찾아야 했지만, 런타임 오류는 예외처리라는 방법으로 오류 상황을 대비할 수 있습니다.

 

 예외 처리를 사용하면 런타임 오류가 생겼을 때 프로그램이 갑자기 꺼지거나 멈추는 것을 방치할 수 있습니다.

그렇기 때문에 적절한 예외 처리는 프로그램 성능 향상에 영향을 미치는 중요한 요소입니다.

 

 예외 처리문의 기본 구조는 다음과 같습니다.

 

try:

     코드

except:

     오류가 발생했을 때 실행문

 

 try에 속한 코드를 실행하는 도중 오류가 발생하면 except의 코드가 실행됩니다.

 

 첫 번째 결과 값은 오류 없이 잘 나왔지만, 두 번째 결과 값은 두 번째 숫자에 0을 넣어 에러가 발생하였습니다.

0으로 나눠서 발생하는 오류를 방지하기 위해 조건문을 이용할 수도 있겠지만, 예외 처리를 사용하면 조금 더 쉽게 오류를 처리할 수 있습니다.

 

 예외 처리문의 구조를 대입해 보면 다음과 같이 Error가 나왔을 때, 원하는 실행문을 추가할 수 있습니다.

 

 하지만 오류의 종류는 다양합니다.

만약 각각의 오류마다 다른 처리를 하고 싶다면 다음과 같이 except 옆에 오류의 종류를 적어 주면 됩니다.

 

try:

     코드

except 오류1:

     오류1이 발생했을 때 실행문

except 오류2:

     오류2가 발생했을 때 실행문

 

 실행 결과 1은 인덱스 오류가 발생한 경우입니다. 'IndexError: list index out of range'에서 IndexError가 오류의 이름입니다.

실행 결과 2는 나눗셈 오류가 발생한 경우입니다. 'ZeroDivisionError: division by zero'에서 ZeroDivisionError가 오류의 이름입니다.

 

 예외 처리문을 사용해 이러한 오류들을 각각 다르게 처리할 수 있습니다.

이번에는 except 옆에 오류의 이름을 적어서 오류별로 다른 메세지가 출력되도록 했습니다.

첫 번째 출력은 인덱스 오류(IndexError)일 경우에만 실행되고,

두 번째 출력은 나눗셈 오류(ZeroDivisionError)일 경우에만 실행됩니다.

 

 

15-5. 파이썬 내장 함수

 

 파이썬 내장 함수 중에서 자주 사용되는 내장 함수를 몇 가지 더 알아보겠습니다.

 

 1) enumerate()

 

enumerate(시퀀스형 데이터)

 

 enumerate()는 리스트로 for 반복문을 작성할 때 유용한 함수입니다. 리스트, 튜플, 문자열 자료형처럼 순서가 있는 시쿼스형 데이터를 enumerate 함수에 넣고, 그 모든 요소를 인덱스와 쌍으로 추출하는 데 활용됩니다.

 

 

 2) round()

 

 round(숫자, 반올림할 자릿수)

 

 round()는 숫자를 반올림하는 함수입니다.

만약 round()함수에 실수 하나만 넣으면 정수로 반올림된 값이 반환됩니다.

 

 숫자를 두 개 넣을 때 첫 번째 숫자는 반올림할 숫자이고, 두 번째 숫자는 반올림할 자릿수(소수점 아래 자릿수)를 나타내는 숫자입니다.

따라서 round(3.52, 1)은 소수점 아래 일의 자리까지 반올림해서 표시하므로 결과는 3.5가 됩니다.

 

 

 3) filter()

 

filter(함수, 시퀀스형 또는 딕셔너리형 데이터)

 

 filter()는 리스트, 함수, 튜플 등의 시퀀스형 데이터나 딕셔너리형 데이터에서 필터링한 결과를 반환하는 함수입니다.

filter() 함수에 전달인자로 어떤 데이터를 함께 넣습니다.

filter() 함수 내에서 자동으로 데이터를 순서대로 반복하며 함수를 실행하고, 함수의 반환값이 참인 데이터만 반환합니다.

사용 방법이 다른 함수와 조금 달리 조금 복잡합니다.

 

 filter() 함수에 isEven() 함수와 [1, 3, 4, 2, 5, 3, 4]을 인풋으로 넣습니다.

filter() 함수는 데이터를 순서대로 반복하며 isEven() 함수를 실행하고 그 반환값이 참인 데이터만 반환합니다.

그것을 리스트 형태로 만들기 위해 filter() 함수 전체를 list()로 감쌉니다.

 

 

 4) map()

 

map(함수, 시퀀스형 또는 딕셔너리형 데이터)

 

 map()은 리스트, 튜플 등의 시퀀스형 데이터나 딕셔너리형 데이터의 값을 자동으로 반복하며 함수에 전달인자로 넣고, 그 함수의 결과를 묶어 반환하는 함수입니다.

 

 사용 방법은 filter 함수와 비슷합니다. 함수와 데이터를 함께 넣으면 map() 함수 내에서 자동으로 데이터를 순서대로 반복하며 함수를 실행합니다.

 

 map() 함수에 multiply() 함수와 [1, 3, 4, 2, 5, 3, 4]을 인풋으로 넣습니다.

map() 함수는 데이터를 순서대로 반복하며 multiply() 함수를 실행하고 그 반환값을 모두 묶어 반환합니다.

그것을 리스트 형태로 만들기 위해 filter() 함수 전체를 list()로 감쌉니다.

 

 

 

 3-10. 가위바위보 게임

 

 컴퓨터와 가위바위보 게임을 할 수 있는 프로그램을 작성해 보세요.

 

조건1 : random 라이브러리를 사용합니다.

조건2 : 프로그램에서 '가위', '바위', '보' 중 하나를 입력하면 게임을 진행합니다.

조건3 : 함수를 2개 이상 사용합니다.

조건4 : 게임 결과(이김, 비김, 짐)를 출력합니다.

 

import random

def wingababo():
    print("축하합니다. 당신이 이겼습니다.")

def drawgababo():
    print("비겼습니다.")
    
def losegababo():
    print("졌습니다.")
        
result = random.randint(1, 3)
user = input("가위바위보 게임입니다. 무엇을 낼지 입력해 주세요. : ")

if result == 1:
    result = "가위"

if result == 2:
    result = "바위"

if result == 3:
    result = "보"

print(f"사용자 : {user}")
print(f"computer : {result}")

if user == "바위" and result == "가위" or user == "가위" and result == "보" or user == "보" and result == "주먹":
    wingababo()

elif user == "바위" and result == "보" or user == "가위" and result == "바위" or user == "보" and result == "가위":
    losegababo()

elif user == result:
    drawgababo()

else:
    print("잘못된 입력입니다.")

 원래 제일 처음에 Class를 사용하려 했지만 그냥 함수를 쓰는게 더 편할거 같아 Class를 지웠습니다.

랜덤 함수를 이런식으로 사용해보니 정말 재밌었습니다.

 예제는 입력 값이랑 랜덤 값이랑 빼서 차이를 통해 뺀 값이 0이 나오면 비기고 숫자 차이가 1 또는 -2일 때 이긴다고 되어있었는데 새로운 관점이었습니다.

 제가 짠 코드 같은 경우에는 각 경우의 수가 3개밖에 없어서 다 쳤는데 새로운 관점을 얻어간 것 같습니다.

반응형
Comments