배꼽파지 않도록 잘 개발해요

방송대 파이썬 프로그래밍 기초 - 11강. 모듈 본문

방송대 컴퓨터과학과/파이썬 프로그래밍 기초

방송대 파이썬 프로그래밍 기초 - 11강. 모듈

꼽파 2023. 5. 22. 10:52


  • 1. 모듈의 이해

  • 2. 유용한 모듈

  • 1. 모듈의 이해

    모듈의 개념

    모듈(Module)
    - 함수, 상수 또는 클래스를 모아 놓은 집합체
    - 목적 또는 주제 지향적인 묶음

    - 프로그램을 구성하는 작은 단위로써, 코드를 조직화하고 유지보수하기 쉽게 만들어줌.

    • 함수 : 특정 작업을 처리
    • 상수(변수) : 불변의 값 (매번 변수 생성을 하지 않아도 됨.)
    • 클래스 : 다른 모듈로의 확장

    모듈, 패키지, 라이브러리

    • 모듈 :
    - 클래스, 함수, 상수의 집합
    - 하나의 파이썬 파일로 되어 있음.


    • 패키지 :
    - 하위 패키지 및 모듈의 집합
    - 하나의 폴더 단위


    • 라이브러리 :
    - 패키지 및 모듈의 집합
    - 한 분야의 일을 할 수 있는 모듈과 패키지를 묶어 놓은 단위

    모듈의 등록

    import 문을 사용하여 모듈 가져오기 import문, 모듈에 별칭(Alias) 붙이기
    import math로 'math' 모듈을 프로그램에 추가함.
    math.sqrt() 함수를 사용하여 25의 제곱근을 계산함.
    'as m'을 붙여서 math 모듈을 m이라는 별칭으로 사용함.
    math.sqrt() 대신 m.sqrt() 함수를 호출하여 25의 제곱근을 계산함.

    - 모듈이름 또는 별칭.변수

    - 모듈이름 또는 별칭.함수()

    - 모듈이름 또는 별칭.클래스

    → 파이썬 모듈을 프로그램 내부에서 사용할 수 있게 네임스페이스에 추가하는 명령어

     

    from 모듈이름 import 메소드 from 모듈이름 import  *
    'math' 모듈에서 'sqrt()' 함수만 가져옴.
    → 'math.sqrt()' 대신에 sqrt() 함수를 직접 호출하여 25의 제곱근을 계산함.
    'math' 모듈의 모든 함수를 가져옴.
    → math.이나 모듈이름.을 붙이지 않고도 함수를 직접 호출할 수 있음.

    여러 메소드를 사용할 때는 옆에 나열하여 작성하면 됨.
    -

    변수

    함수()

    클래스

    → 모듈이름 없이 변수, 함수, 클래스를 사용


    모듈의 등록 확인

    모듈의 등록을 확인하고, 모듈의 도움말을 보려면 해당 모듈을 'import'하여 등록된 상태여야 함.

    dir 함수 help 함수
    네임스페이스에 등록되어 있는 모든 이름들을 리스트로 반환 대화형 도움말 시스템 호출 또는 클래스나 메소드의 사용방법 반환
    - 파라미터 O → 클래스나 메소드 사용 방법 반환
    - 파라미터 X → 대화형 도움말 시스템 호출
    import math

    # math 모듈의 속성 확인
    print(dir(math))

    # math 모듈의 도움말 출력
    help(math)
    import math

    # math 모듈의 속성 확인
    print(dir(math))

    # math 모듈의 도움말 출력
    help(math)

    dir()
    help() (파라미터 O)
    help() 파라미터 X

    대화형으로 도움받고 싶다면 파라미터 값을 비워두고 실행하기


    네임스페이스의 이해

    네임스페이스
    - 특정 객체를 이름에 따라 구분할 수 있는 범위
    - 네임 스페이스에 올라온 여러 식별자들이 겹칠 수 있기 떄문에 오류 발생 원인이 네임스페이스 상의 객체명의 중복일 수도 있음.

    • 지역 네임스페이스 : 함수 또는 메소드 내의 이름 공간 (스코프)
    • 전역 네임스페이스 : 모듈 전체에서 통용되는 이름 공간
    • 빌트인 네임스페이스 : 모든 코드 범위


    모듈의 제거

    네임스페이스 내 모듈의 멤버 식별자 제거

    간혹 오류 발생 시 해당 모듈을 네임스페이스에서 제거해 볼 수 있음.

    import math

    # math 모듈 사용
    result = math.sqrt(25)
    print(result)

    # math 모듈 제거
    del math

    # 제거된 math 모듈 사용 시 NameError 발생
    result = math.sqrt(25)

    원뿔 계산 프로그램 개선

    math 모듈을 활용한 원뿔 계산

    import math로 math 모듈을 불러온 후 기존 3.14를 'math.pi'로 치환하기


    2. 유용한 모듈

    math 모듈

    수학적 계산 문제를 해결하기 위한 수학 함수 및 상수의 집합

    C언어 표준에 정의된 수학적 계산 함수를 내장

    π, e와 같은 상수 제공

     

    math 모듈 멤버 [암기 X]

    멤버 설명 예시
    pi 원주율 math.pi 3.141592653589793
    e 자연로그 e math.e   2.718281828459045
    fabs(x) x의 절대값 math.fabs(-2.5)  2.5
    ceil(x) x의 가장 가까운 정수로 올림 math.ceil(3.2) 4
    floor(x) x의 가장 가까운 정수로 버림 math.floor(3.8) 3
    exp(x) x의 지수함수(e의 x제곱) 값 math.exp(2) 7.3890560989306495
    log(x) x의 자연로그 값 math.log(10) 2.302585092994046
    sqrt(x) x의 제곱근 math.sqrt(16) 4.0
    sin(x) x의 사인 값 math.sin(math.pi/2) 1.0
    asin(x) sin의 역함수에 대한 라디안 각도 math.asin(1) 1.5707963267948966
    cos(x) x의 코사인 값 math.cos(math.pi) -1.0
    tan(x) x의 탄젠트 값 math.tan(math.pi/4) 1.0
    degrees(x) 라디안 각도 x를 도 단위로 변환 math.degrees(math.pi/2) 90.0

    삼각형 넓이 계산 프로그램

    두 변의 길이 a, b와 끼인각 a인 삼각형의 넓이를 구하는 프로그램을 작성하시오.

    넓이 = 1/2 x a x b x sinα

    math.sin()함수는 인자로 각도가 아니라 라디안 값을 사용하여 삼각함수의 값을 계산함.
    → math.radians(60)을 사용하면 60도를 호도법으로 바꾼 값의 sin값 산출함.

     

    from math import sin을 쓰면 sin함수에 'math.'를 붙이지 않아도 사용할 수 있음.


    random 모듈

    난수(random number) : 특정한 배열 순서나 규칙적인 의미가 없는, 임의의 수를 의미

    난수 관련된 생성 기능을 제공하는 모듈

    → 특정 범위의 난수를 발생

    RNG (난수 발생기) : 번호들 사이에는 규칙이 없으나 프로그램을 실행할 때마다 동일한 값들이 도출되는 난수 발생

    → 같은 번호가 계속 나오면 시드(시작점)을 바꿔주면 됨.

     

    random 모듈 멤버

    멤버 설명
    random() 0~1 사이의 숫자 중 난수 발생
    randint(a, b) a부터 b 사이의 숫자 중 난수 발생
    randrange(a, b, c) a부터 b 사이의 c 간격으로 나열된 숫자 중 난수 발생
    choice(sequence) 주어진 항목을 랜덤하게 반환
    sample(sequence) 랜덤하게 여러 개의 원소를 선택
    shuffle(sequence) 시퀀스의 순서를 랜덤하게 섞음
    import random
    
    # random(): 0~1 사이의 숫자 중 난수 발생
    random_number = random.random()
    print(random_number) # → 0.6038077765541744
    
    # randint(a, b): a부터 b 사이의 숫자 중 난수 발생
    random_integer = random.randint(1, 10) # 1~10 중 한개
    print(random_integer) # → 1
    
    # randrange(a, b, c): a부터 b 사이의 c 간격으로 나열된 숫자 중 난수 발생
    random_range = random.randrange(0, 10, 2) # 10 포함 안 됨 (0, 2, 4, 6, 8)
    print(random_range) # → 8
    
    # choice(sequence): 주어진 항목을 랜덤하게 반환 (1개만만)
    items = ['apple', 'banana', 'orange']
    random_choice = random.choice(items)
    print(random_choice) # → orange
    
    # sample(sequence): 랜덤하게 여러 개의 원소를 선택 (2개 이상, 개수 지정 가능)
    numbers = [1, 2, 3, 4, 5]
    random_sample = random.sample(numbers, 3)
    print(random_sample) # → [4, 5, 2]
    
    # shuffle(sequence): 시퀀스의 순서를 랜덤하게 섞음
    cards = ['Spade', 'Heart', 'Diamond', 'Club']
    random.shuffle(cards)
    print(cards) # → ['Club', 'Diamond', 'Spade', 'Heart']

     

    가위바위보 게임에서의 활용

     

    import random

    options = ["가위", "바위","보"]

    user = input("가위, 바위, 보를 입력: ")

    com = random.choice(options) → options에 있는 가위, 바위, 보 중 하나를 무작위로 반환함.


    로또 추첨 프로그램

    1~45 숫자 6개를 입력 받아 당첨 숫자와 비교하는 프로그램을 작성하시오.

    import random
    
    guess_str = input("1~45 번호 6개를 쉼표로 분리하여 입력하세요: ").split(", ")
    
    guess_list = list() # 공백 리스트 생성
    
    for i in guess_str : # guess_str의 숫자로 된 문자열을 하나씩 읽은 후
        guess_list.append(int(i)) # guess_list에 정수형으로 변환하여 append(추가)
    
    lotto_list = random.sample(range(1, 46, 1), 6) # 1~45까지 6개 무작위 추출
    
    print("예상 번호는 ", guess_list, "입니다.")
    print("추첨 번호는 ", lotto_list, "입니다.")
    
    hit_count = 0;   # 전체 개수를 저장하는 변수
    
    for num in guess_list:
        if num in lotto_list:
            hit_count = hit_count + 1
    
    print("축하합니다. " + str(hit_count) + "개 맞혔습니다.")


    스무고개 프로그램

    20번의 기회 안에 1~100 사이의 숫자를 맞히는 스무고개 프로그램을 작성하시오.

    import random 
    
    # 1~100 중 한 가지 정수를 무작위 생성하여 hit_number에 넣기
    hit_number = random.randint(1, 101)
    
    # 1~20까지 들어있는 리스트를 생성하여 현재 몇 번쨰 시도인지를 출력
    guess_count_list = range(1, 21, 1) 
    
    passfail = False
    
    # 스무고개를 한번 할 때마다 guess_count가 올라감
    for guess_count in guess_count_list :
    
    # 사용자가 입력한 숫자를 guess에 넣음.
        guess = int(input("숫자를 맞혀보세요!: " + str(guess_count) + "번째 시도: "))
        
        # 무작위로 생성된 수 = 사용자가 입력한 수
        if hit_number == guess:
            passfail = True
            break
        
        # 무작위로 생성된 수 > 사용자가 입력한 수
        elif hit_number > guess:
            print(str(guess) + "보다 큽니다.", end="")
            
        # 무작위로 생성된 수 < 사용자가 입력한 수
        else:
            print(str(guess) + "보다 작습니다.", end="")
    
    if passfail == True:
        print("맞췄습니다. 축하합니다.")
        
    else:
        print("모든 기회를 다 사용하셨습니다. 다음에 다시 도전하세요.")


    time 모듈

    에포크 시간을 얻어 다양한 형식으로 표시하는 기능 제공

    출처 : 11강 강의록

    1970년이 유닉스 에포크의 기준점이 된 이유

    역사적인 이유
    - 1970년은 유닉스 운영체제가 처음 개발되기 시작한 시기임.
    - 유닉스는 이후 많은 컴퓨터 시스템에서 사용되는 기반이 되는 운영체제로 발전하게 되었고, 개발 초기에 타임 시스템을 구현하는 데에 1970년이 기준으로 선택됨.

    기술적인 편의성
    - 1970년은 컴퓨터에서 사용되는 32비트 정수형 변수로 시간을 표현하는 데에 적합한 범위임.
    - 에포크 이전과 이후의 시간을 음수와 양수로 나누어 표현할 수 있으며, 초 단위로 시간을 표현하기에도 충분한 범위를 제공함.


    time 모듈 멤버

    멤버 설명
    time() 1970.1.1 자정 이후로 누적된 초를 실수 단위로 반환
    gmtime() struct_time 형식으로 기준 시각 변환
    localtime(time) 입력된 초를 변환하여, 지방표준시 기준 시각으로 변환
    strftime(str, time) 지정된 형식으로 시각을 변환
    ctime() 현재 시간을 반환
    sleep(n) 현재 동작중인 프로세스를 주어진 n초만큼 멈춤
    # time() - 1970년 1월 1일 자정 이후로 누적된 초를 실수 단위로 반환
    import time
    current_time = time.time()
    print(current_time)  
    # → 1654928182.1234567
    
    # gmtime() - struct_time 형식으로 기준 시각 변환 (협정 세계시, UTC)
    import time
    gmt_time = time.gmtime()
    print(gmt_time)  
    # → time.struct_time(tm_year=2022, tm_mon=6, tm_mday=10, tm_hour=12, tm_min=30, tm_sec=0, tm_wday=4, tm_yday=161, tm_isdst=0)
    
    # localtime(time) - 입력된 초를 변환하여, 지방표준시 기준 시각으로 변환
    import time
    current_time = time.time()
    local_time = time.localtime(current_time)
    print(local_time)  
    # → time.struct_time(tm_year=2022, tm_mon=6, tm_mday=10, tm_hour=21, tm_min=30, tm_sec=0, tm_wday=4, tm_yday=161, tm_isdst=0)
    
    # strftime(str, time) - 지정된 형식으로 시각을 변환
    import time
    current_time = time.time()
    formatted_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(current_time))
    print(formatted_time)  
    # → 2022-06-10 21:30:00
    
    # ctime() - 현재 시간을 반환
    import time
    current_time = time.ctime()
    print(current_time)  
    # → Fri Jun 10 21:30:00 2022
    
    # sleep(n) - 현재 동작 중인 프로세스를 주어진 n초만큼 멈춤
    import time
    print("시작")
    time.sleep(3)  
    print("3초 후")
    # → 3초 동안 멈춘 후 '3초 후'가 출력됨.

    소수 찾기 프로그램

    1 ~ 1000 사이에 소수(prime number)를 찾고 실행 시간을 출력하는 프로그램을 작성하시오.

    import time
    
    # 프로그램이 시작하는 현재 시각을 'start_time'에 저장함.
    start_time = time.strftime("%a %b %d %H:%M:%S %Y", time.localtime())
    print("시작 시각은", start_time, "입니다.")
    
    start_time_minus = time.time()
    
    # 1. 소수 판별하는 함수
    # 주어진 숫자 x가 소수인지 판별하는 'is_prime()' 함수를 생성
    def is_prime(x):
        for i in range(2, x):
            # 주어진 수 x를 2부터 x-1까지의 수로 나눔
            # i로 나누었을 때 나누어 떨어지면(나머지가 0이면)
            if x % i == 0: 
                # 소수가 아니므로 False 반환
                return False
        # 나누어 떨어지는 경우 소수이므로 True 반환
        return True
    
    # 2. 소수를 출력하기
    # 횟수를 저장하는 변수 'prime count' 초기화
    prime_count = 0
    prime_numbers = []
    
    # for 반복문(2부터 1000까지)은 is_prime 함수의 파라미터로 들어감.
    for i in range(2, 1001):
        # i가 소수이면 반복 횟수 증가시키고, prime_numbers에 추가
        if is_prime(i): 
            prime_count += 1
            prime_numbers.append(str(i))
    
    # 소수 출력
    print("소수는", end=" ")
    print(", ".join(prime_numbers))
    
    # 프로그램이 종료되는 현재 시각을 'end_time'에 저장함.
    end_time = time.strftime("%a %b %d %H:%M:%S %Y", time.localtime())
    print("종료 시각은", end_time, "입니다.")
    
    end_time_minus = time.time()
    
    # 3. 출력
    print(end_time_minus - start_time_minus, "초 실행했습니다.")

     

    수업 내용과 다르게 수정한 점

     

    • prime_numbers를 리스트로 만들어서 join 연산자로 각 사이를 ,로 연결되게 함.
    → 1) '소수는' 다음에 한 칸 밑으로 오는 문제 해결
         2) 소수 사이만 콤마로 연결되게 함.

    • time.strftime("%a %b %d %H:%M:%S %Y", time.localtime())으로 지정 형식을 지켜줌.
    - %a: 약식 요일 이름 (예: "Mon", "Tue")
    - %b: 약식 월 이름 (예: "Jan", "Feb")
    - %d: 월 내 일(day) (01 ~ 31)
    - %H: 시간(24시간 형식) (00 ~ 23)
    - %M: 분 (00 ~ 59)
    - %S: 초 (00 ~ 59)
    - %Y: 연도 (예: 2023)

    • 종료시각과 시작시각의 연산을 위해 time()을 활용해서 연산을 위한 변수를 생성함.
    time.time()으로 출력된 자료형은 실수이므로 연산 가능함.

    728x90