본문 바로가기
IT공부방

[PCCE] LV3 파이썬 완전정복: Part 6 함수 정의와 활용, 표준 라이브러리 (math, random)

by TechDayNote 2025. 5. 25.

2025.05.22 - [프로그래밍] - [PCCE] LV3 파이썬 완전정복: Part 1 PCCE 시험 개요와 LV3 등급 분석

2025.05.22 - [프로그래밍] - [PCCE] LV3 파이썬 완전정복: Part 2: 변수, 자료형, 연산자 – Python 기본 문법 ①

2025.05.23 - [프로그래밍] - [PCCE] LV3 파이썬 완전정복: Part 3 조건문 – 흐름 제어 기초

2025.05.24 - [프로그래밍] - [PCCE] LV3 파이썬 완전정복: Part 4 반복문 – while, for, 중첩 반복

2025.05.24 - [프로그래밍] - [PCCE] LV3 파이썬 완전정복: Part 5 리스트와 2차원 리스트 – 자료구조 입문

 

코드의 구조화 – 함수와 라이브러리의 힘

여러분이 프로그램을 많이 작성하다 보면, 자연스럽게 중복되는 코드논리적 단위로 묶어야 할 코드들이 보이기 시작합니다. 이때 사용하는 도구가 바로 **함수(function)**입니다. 함수를 만들어 두면 원하는 동작을 재사용하거나, 코드를 논리적으로 깔끔하게 분리할 수 있습니다. 또한 파이썬을 비롯한 대부분의 언어는 다양한 표준 라이브러리(standard library)를 제공해, 복잡한 기능도 손쉽게 사용할 수 있도록 합니다. PCCE 시험에서는 함수와 라이브러리 사용을 직접 묻기도 하고, 주어진 함수를 완성하거나 라이브러리 함수를 활용하는 문제도 있습니다. 이번 파트에서는 Python 기준으로 함수 정의/호출 방법과, PCCE 범위 내에서 유용한 math, random 등의 표준 라이브러리 기능을 살펴보겠습니다.

Python 함수와 라이브러리

1. 함수 정의와 호출: Python에서 함수를 정의하려면 def 키워드를 사용합니다. 기본 형태는:

# 코드 예시
def 함수이름(매개변수1, 매개변수2, ...):
    <함수 실행 코드>
    return 반환값

예를 들어 두 수를 더하는 함수를 만들어보면:

# 코드 예시
def add(a, b):
    result = a + b
    return result
 

이렇게 정의한 함수를 호출(call)할 때는 add(5, 3)처럼 함수이름에 괄호, 인자를 써서 호출합니다. 그러면 8이 반환되겠죠. return 문은 함수를 종료하며 값을 돌려주는 역할입니다. 만약 return이 없거나 반환값이 없다면, Python 함수는 자동으로 None을 반환합니다.

함수의 **매개변수(parameter)**와 인자(argument) 개념을 혼동하지 마세요: 정의할 때 a, b는 매개변수, 호출할 때 5, 3은 인자입니다. PCCE에서는 주어진 함수의 시그니처 (이름, 파라미터)대로 코드를 완성하는 문제가 나오기도 합니다. 예를 들어 "정수 n이 소수인지 판단하는 함수 is_prime(n)을 완성하시오." 같은 형태일 수 있습니다. 그럴 때 함수의 리턴값 타입이나 역할을 문제 설명에서 파악해, 올바르게 구현해야 합니다.

2. 변수의 범위 (스코프): 함수 내부에서 정의한 변수는 기본적으로 **지역 변수(local variable)**로, 함수 밖에서 접근할 수 없습니다. 또한 함수 내부에서는 외부의 변수 이름과 같은 이름을 써도 별개로 취급됩니다. 예를 들어:

# 코드 예시
x = 10
def f():
    x = 5   # 이 x는 지역변수
f()
print(x)   # 여전히 10 (함수 내부의 x 변경은 밖에 영향 없음)

이런 식입니다. 만약 함수 내부에서 전역 변수를 사용하려면 global x 선언을 해줘야 합니다:

# 코드 예시
x = 10
def g():
    global x
    x = 5   # 전역변수 x를 직접 변경
g()
print(x)   # 5 (함수에서 바뀐 값이 반영됨)
 

그러나 전역 변수 사용은 가급적 피하고, 함수에 매개변수와 반환값을 이용해 데이터를 주고받는 게 좋습니다. PCCE에서도 특별한 경우 아니면 global 키워드는 쓸 일 없을 것입니다. 중요한 점은, 함수 안팎의 동일 이름 변수 혼용으로 버그가 생길 수 있다는 것입니다. (예: 실수로 지역변수로 선언해버려 함수 밖 값에 영향 안 미치는 상황) 이런 건 디버깅 문제로 나올 수 있으니 기억해두세요.

3. 표준 라이브러리 활용: Python은 방대한 표준 라이브러리를 갖고 있지만, PCCE Lv3 준비에서는 그 중 자주 쓰는 몇 가지만 짚어보겠습니다 (실제로 기출 범위에도 math, random, time 정도가 언급돼 있습니다).

  • math 모듈: 수학 관련 여러 함수와 상수를 제공합니다.
    • math.sqrt(x): x의 제곱근 계산. (반환은 float)
    • math.pow(x, y): x^y 연산 (거듭제곱). 결과는 float. 사실 파이썬에서는 x**y 연산자로도 거듭제곱 가능합니다.
    • math.floor(x): x의 내림 (소수점 버림). math.ceil(x): 올림.
    • math.factorial(n): n! (팩토리얼) 계산.
    • math.gcd(a, b): 최대공약수 계산 (유클리드 알고리즘 내장).
    • math.pi, math.e: 원주율 파이와 자연상수 e 값.
    PCCE 기출 2번 피타고라스 문제에서 Java 코드 답안에 Math.pow와 (int) 캐스팅이 쓰였는데, Python으로 풀 경우 c**2 - a**2로 바로 계산하거나 math.pow(c,2) 쓰면 됩니다. sqrt도 유용하죠. 예를 들어 소수 판정에 sqrt(n)까지 루프 돌리면 효율이 올라갑니다. (Lv3에선 n 크기 크지 않아도, 팁으로 알아두면 좋음)
  • random 모듈: 난수(random number) 생성 관련 함수들.
    • random.random(): 0.0 이상 1.0 미만의 랜덤 실수(float) 반환. 균등 분포.
    • random.randint(a, b): a 이상 b 이하의 정수 난수 반환 (a,b 포함). 예: random.randint(1,6)은 주사위 눈 1~6 랜덤.
    • random.choice(seq): 시퀀스(seq)에서 랜덤하게 하나 뽑아줌.
    • random.shuffle(lst): 리스트 항목들을 랜덤 섞기 (원본 변경).
    PCCE에서는 random을 직접 써서 무언가 하게 하기보다는, 간단히 난수 활용하는 예제나 함수 작동 원리를 이해하는지 볼 수 있습니다. 예를 들어 "랜덤으로 1~100 숫자 발생시키는 코드" 정도? 또는 "숫자 추측 게임" 시나리오 등. random 사용 문제에서는 시드(seed) 개념도 알아두면 좋은데, random.seed(x)를 호출하면 난수 생성기가 고정된 x로 시드 초기화되어 이후 나오는 난수가 재현 가능해집니다. (이건 주로 테스트 자동화 위해 쓰는데, PCCE에선 언급 안 할 수도 있습니다.)
  • time 모듈: 시간 관련. PCCE 범위에 나왔으니 언급하면,
    • time.time(): 현재 시각을 Unix timestamp(1970 기준 초단위)로 반환 (float).
    • time.sleep(sec): sec 초 만큼 현재 프로그램 일시정지 (delay).
    게임 루프나 지연 효과 주기 위해 sleep을 쓸 수 있겠죠. 예를 들어 "3초 카운트다운 후 시작" 같은 프로그램. PCCE에서 이걸 직접 쓰게 할지는 모르겠습니다만, 알아두면 좋습니다.
  • 또 datetime 모듈로 현재 날짜, 시각을 구할 수 있지만, Level3에선 시각 차이 계산 같은 간단한 용도 외에는 안 다룰 듯합니다.
  • 기타 알아두면 좋은 것:
    • sys 모듈의 sys.stdin.readline(): 입력 빠르게 읽기 (Python input() 느릴 때). 큰 입력 다룰 땐 필요.
    • collections 모듈: deque (효율적 큐)나 Counter (빈도 세기) 등. Counter는 리스트 원소 개수 세줄 때 편합니다. 그러나 Lv3에서는 기본 리스트/딕셔너리로 풀 수 있으니 없어도 됩니다.
    • itertools 모듈: itertools.permutations, combinations 등 조합 관련. Level3 완전탐색에서 쓸 수 있는데, 스스로 구현할 수도 있어서 선택사항.
    • string 모듈: 문자열 관련 상수 (ascii_letters 등)와 함수들. (이건 많이 안 씀)

4. 라이브러리 사용시 주의: 라이브러리를 쓰려면 import가 필요합니다. import math처럼 하면 math.sqrt로 호출하고, from math import sqrt 하면 바로 sqrt로 쓰죠. PCCE에서는 문제에 따라 특정 라이브러리 사용을 금지할 수도 있습니다. (예: "라이브러리 사용 없이 구현하세요" 등) 그런 언급 없으면 자유롭게 써도 됩니다. 하지만 무턱대고 쓰면 실수할 수 있으니, 동작을 정확히 알고 쓰는 것이 중요합니다. 예를 들어 math.pow는 float 리턴이라 int 필요하면 int(math.pow(...)) 해야 하고, random.randint(a,b)는 b까지 포함이란 것도 기억해야 합니다. 모호하면 공식 문서나 도움말을 봐야 하는데, 시험 중엔 인터넷이 안 되니 외워가야죠.

5. 함수와 라이브러리 관련 PCCE 기출경향:

  • 함수 정의 문제: "절대값을 구하는 함수 구현", "문자열 뒤집는 함수 구현" 등 단순한 것이 나올 수 있고, 조금 심화로 "입력 받은 리스트를 정렬해서 반환하는 함수 완성" 같은 것도 가능. 문제의 요구사항대로 return을 적절히 해야 합니다. 가끔 return 빼먹는 실수가 있는데, 그러면 호출 쪽에서 None 받아서 오류나니 주의.
  • 디버깅 유형: 주어진 함수가 원하는 값을 못 반환하는 버그를 찾아 고치기. 예를 들어 return 위치가 잘못되었거나, 조건에 따라 return 안 되는 경우 등. PCCE 기출 7번 “가습기” 문제 풀이를 보면 여러 함수를 정의해서 모드별 동작을 구현했고, 마지막 solution에서 호출했습니다. 이런 구성을 이해하는 문제가 될 수도 있습니다.
  • 라이브러리 활용 문제: "random 모듈로 1부터 10까지 난수 5개 출력", "Math 라이브러리를 이용해 두 실수의 거리를 구하라 (sqrt(pow))", "현재 시간을 구해 특정 형식으로 출력" 등등이 생각됩니다. 또한 이미 나왔듯 Math.pow 같은 걸 코드 채우기 할 수도 있고요.
  • 시간 복잡도 감소: math.gcd 같은 함수는 직접 구현보다 빠르니 쓰라고 힌트 줄 수도 있습니다. (그러나 Lv3에선 성능 크게 신경 쓸 정도 입력은 거의 없을 듯합니다.)

실습 예제 코드: 함수와 라이브러리 활용

간단한 함수 작성과 라이브러리 사용 예제를 코드로 확인해보죠.

# 코드 예시
import math
import random
import time

# 1. 함수 정의와 호출 예제
def factorial(n):
    """주어진 정수 n의 팩토리얼을 계산하여 반환"""
    result = 1
    for i in range(1, n+1):
        result *= i
    return result

print("5! =", factorial(5))   # 출력: 5! = 120

# 2. 조건에 따른 함수 (짝수/홀수 판단)
def is_even(num):
    if num % 2 == 0:
        return True
    else:
        return False

# 위 함수는 return num % 2 == 0  로 한 줄로 쓸 수도 있음
test_num = 7
if is_even(test_num):
    print(test_num, "은 짝수")
else:
    print(test_num, "은 홀수")
# 출력: 7 은 홀수

# 3. math 라이브러리 활용
x = 16
print("sqrt(16) =", math.sqrt(x))          # 출력: sqrt(16) = 4.0
print("5^3 =", math.pow(5, 3))             # 출력: 5^3 = 125.0
print("5! =", math.factorial(5))           # 출력: 5! = 120
print("gcd(48,18) =", math.gcd(48, 18))    # 출력: gcd(48,18) = 6
print("floor(3.7) =", math.floor(3.7))     # 출력: floor(3.7) = 3

# 4. random 라이브러리 활용
random.seed(0)      # 시드 고정 -> 실행마다 같은 난수 나옴
print("0~1 사이 난수:", random.random())  # 출력: 0~1 사이 난수: 0.844421851525...
print("주사위 굴리기:", random.randint(1, 6))  # 1~6 정수 중 랜덤
choices = ["가위", "바위", "보"]
print("랜덤 선택:", random.choice(choices))   # 출력: 세 개 중 하나
lst = [1,2,3,4,5]
random.shuffle(lst)
print("섞인 리스트:", lst)   # 예: [3, 1, 5, 2, 4]

# 5. time 라이브러리 활용
print("현재 timestamp:", time.time())   #  현재 시각 (1970 이후 초)
print("잠시 멈췄다가 출력...")
time.sleep(1.5)                         # 1.5초 휴식
print("1.5초 후 출력 완료!")

설명:

  • 1번: factorial 함수를 직접 구현했습니다. math.factorial을 쓰면 한 줄이지만, 직접 for문으로 해본 거죠. 5! = 120 잘 나옵니다. PCCE에서는 이 정도 구현은 할 줄 알아야 합니다. (사실 factorial은 재귀로 구현하는 예도 많지만, 초보에게 재귀는 약간 난이도 있으니 반복문으로 충분) 함수 docstring """..."""도 써봤는데, 그것까지는 안 물을 듯합니다.
  • 2번: is_even 함수는 짝수 여부 반환. True/False 반환하는 함수입니다. 7을 넣어 False 나오니 else절이 실행되어 "7 은 홀수" 출력됐죠. 이런 간단한 판단 함수는 PCCE 시험에서도 유용합니다. 만약 *"짝수면 True 반환하는 함수 완성"*이라든가, "주어진 문자열이 팰린드롬이면 1 반환, 아니면 0 반환 함수" 등의 문제가 있겠죠. 이 경우 반환형/값을 요구대로 맞추는 게 중요합니다. True/False 대신 1/0을 원하면 그에 맞게 return해야 하고, 문자열 입력받으면 len/2까지 체크하는 로직 작성하는 식으로요.
  • 3번: math 함수들 시연했습니다. sqrt(16) 4.0 (float), pow(5,3) 125.0 (float), math.factorial(5) 120, gcd(48,18)=6, floor(3.7)=3. 각각 잘 동작. math 라이브러리 함수들은 정확히 어떤 타입을 받고 뱉는지 알아둘 필요가 있습니다. sqrt/pow 같은 건 float 반환이라 정수 연산 시 유의, gcd는 정수 반환, factorial은 큰 숫자도 잘 처리 (파이썬은 큰 정수도 자동 bigint).
  • 4번: random 사용. random.seed(0)으로 시드 고정해, random.random() 결과가 매번 같게 함. (0.844421851525... 이 값은 seed 0일 때 첫 난수) 난수 생성 시드는 PCCE에선 언급 없으면 안 설정해도 되지만, 단위테스트 할 때 결과 일정하게 하려면 종종 씁니다. randint(1,6)는 16 랜덤 정수, choice(choices) 바위보 중 하나, shuffle(lst) 섞기. 이런 기능은 게임이나 시뮬레이션 문제에도 활용 가능하죠. PCCE에 random 쓰는 문제 예로 "로또 번호 생성" 같은거 내볼 수도 있겠네요. (145 사이 난수 6개 출력, 중복 없이 -> shuffle이나 sample 쓰면 금방, 아니면 while 돌며 뽑기).
  • 5번: time 사용. time.time()은 1970이후 초, 시스템마다 다른 큰 값 나오겠죠. time.sleep(1.5)로 1.5초 지연. 출력 보면 "잠시 멈췄다가 출력..." 찍히고 1.5초 뒤 "1.5초 후 출력 완료!" 나옵니다. time 모듈은 성능측정 등에도 쓰이지만, Lv3에선 그냥 아 이런 게 있구나 정도입니다.

PCCE 출제 포인트 분석: 함수/라이브러리 분야

  • 함수 완성 문제: 어느 정도 정형화된 함수 구현을 묻습니다. 예를 들어 기출 문제로 *"문자열 내에 특정 단어가 몇 번 등장하는지 세는 함수 구현"*이 있었다고 합시다. 그러면 loop 돌며 count++하거나 Python이면 str.count(substring) 사용 가능하죠. 핵심은 요구 사항대로 입력/출력 처리하는 겁니다. 함수 이름, 파라미터, 리턴 형태를 틀리지 말고 구현하는 게 포인트입니다. 문제지에 "다음 함수를 완성하시오"라고 하면서 함수 헤더와 일부 코드 주어지고, ... 부분 채우는 형태일 수도 있습니다.
  • 함수 호출/동작 이해: 함수가 주어졌을 때, 호출 결과를 예측하는 문제도 나올 수 있습니다. 예를 들어 디버깅 문제에서, 함수가 잘못된 값을 리턴해서 전체 로직에 버그를 일으키는 경우 그 함수를 고치게 할 수 있습니다. 또는 "함수 f가 재귀적으로 정의되었다, f(3)의 반환값은?" 같은 간단한 사고 문제도 가능하죠. (재귀는 Lv3에서는 깊게 안 하지만, factorial 재귀 정의 등은 소개될 수 있음)
  • 표준 라이브러리 직접 사용 유도: PCCE 범위에 언급된 라이브러리는 사용 가능하다는 뜻일 겁니다. 그러니 math.sqrt나 random.randint를 쓰면 더 쉽게 풀리는 문제를 낼 수 있습니다. 예를 들어 "두 점 (x1,y1), (x2,y2) 거리 계산" 문제면, sqrt((dx)^2 + (dy)^2) 써야 하는데, sqrt와 pow를 math에서 쓰는 걸 기대할 수 있죠. 또는 "1~100중 랜덤 숫자 하나 뽑아서 출력" 같은건 그냥 random.randint 쓰면 끝입니다. 이런 문제라면 사실 어려운 건 없고 라이브러리 써봤냐 확인하는 수준일 겁니다.
  • 라이브러리 함수 디버깅: 잘못된 사용으로 인한 버그를 찾게 할 수도 있습니다. 예를 들어 math.pow 써서 double과 int 비교 문제 생겼다거나, random.randint(a,b)를 b 미포함으로 착각했다거나, time.sleep 단위 착각 (ms vs s) 같은 것들이 있죠. 이러한 부분을 사전에 알고가면 좋겠네요.
  • 성능/효율 측면: Lv3에서는 대개 작은 입력이지만, 혹시 좀 큰 N 다루는 문제라면 라이브러리 함수 써서 빨리 끝낼 수도 있습니다. 예: 최대공약수 gcd, 소수 판정 sqrt 최적화 등. 수험생 후기 보니 "모의고사보다 실전이 어려웠는데, 특히 디버깅 난이도가 높았다"고 한 분이 있었어요. Lv3 수준에서도 디버깅 문제가 만만찮을 수 있으니, 함수/라이브러리 쪽에서 엉뚱한 값 나오게 하는 사소한 실수 (예: return 위치 문제, float 정밀도 문제 등)도 챙겨야 합니다.

마무리 요약 및 꿀팁

함수는 프로그램을 구조화하고 재사용성을 높이는 데 필수적입니다. 라이브러리는 바퀴를 다시 발명하지 않아도 되게 해주는 고마운 도구입니다. PCCE 준비 과정에서 함수 구현 연습은 자신의 코드를 더 깔끔하게 만들고 오류를 줄이는 연습이기도 합니다. 또한 Python의 표준 라이브러리들, 특히 math와 random은 간단한 문제풀이에 자주 쓰이니 익숙해져두세요.

꿀팁:

  • 함수 단위 테스트: 함수를 작성했으면, 여러 입력으로 결과를 확인해보는 습관을 가지세요. 예를 들어 is_even을 만들었다면, 짝수, 홀수, 0, 음수 등 몇 가지를 넣어 True/False 제대로 나오는지 체크하면 신뢰도가 올라갑니다. 시험 전에 미리 연습하는 거죠. 시험 중에는 시간이 허용하는 한 간단한 경우를 손으로 시뮬레이션하거나, 제공된 예제로 테스트하면 됩니다.
  • 라이브러리 문서 읽기: 모듈의 함수들은 미묘한 동작 차이가 있을 수 있습니다. PCCE 범위 내에선 간단한 것들이지만, 그래도 공식 문서(파이썬 docs)나 튜토리얼에서 한 번씩 써보고 넘어가세요. 예를 들어 random 모듈 문서 보면 seed에 대한 설명이나, randint vs randrange 차이 등이 나와 있습니다. 사소하지만 이런 걸 알아두면 실수 확률이 줄어요.
  • 모범 코드 익히기: 같은 문제를 풀 때, 라이브러리를 쓰는 버전과 안 쓰는 버전을 둘 다 작성해보세요. 그러면 두 접근법을 다 알게 되고, 시험장에서 유연하게 대응 가능합니다. 예를 들어 "원의 넓이 구하기" 문제를 풀 때, math.pi * r*r로 할 수도 있지만 3.14159 상수를 쓸 수도 있죠. 만약 문제에서 "표준 상수 사용 금지"라고 하면 math.pi 못 쓰니, 직접 3.14 등으로 해야 합니다. 두 방법 모두 준비해두면 어떤 제약이 와도 당황하지 않겠죠.

추천 연습 문제

  • 함수 구현 연습: 코딩 사이트 문제가 아니더라도, 스스로 몇 개 만들어보세요. 예: is_prime(n) (소수 판별), reverse_string(s) (문자열 뒤집기), sum_of_list(lst) (리스트 합 구하기) 등. 직접 만든 후 Python 내장 (reversed나 sum)과 결과 비교도 해보면 좋습니다.
  • 백준 15596 정수 N개의 합 – 정수 N개가 주어졌을 때 그 합을 구하는 함수 구현 문제입니다. C 언어 스타일로 함수 틀을 주고 구현하게 하는데, 파이썬로도 연습해보세요 (문제는 함수 내용 자유 구현이므로).
  • 프로그래머스 Lv0: 세균 증식 – 시간마다 세포수가 2배 되는 것을 계산하는 문제. 이건 단순 수식이지만, pow 함수를 써볼 수 있습니다.
  • 프로그래머스 Lv0: 중복된 숫자 개수 – 리스트에서 특정 값 개수 찾기 문제로, 함수로 만들어보거나 count 메서드 활용해보세요.
  • 프로그래머스 Lv0: 직사각형 넓이 구하기 – 좌표평면의 두 점 좌표 네 개 주어졌을 때, 남은 한 점 찾아 직사각형 완성하는 문제. math 관련성은 없지만, set등 자료구조 활용이나 함수 decomposition 연습해볼 만합니다.
  • 랜덤 관련 자율 연습: 간단한 콘솔 가위바위보 게임 만들어보기 – random.choice로 컴퓨터 패 선택, input으로 사용자 입력 받아서 비교 후 결과 출력하는 스크립트. 이것도 함수 분리(판정 함수 등) 해보면 함수 실습+random 활용이 됩니다.

 

2025.05.22 - [프로그래밍] - [PCCE] LV3 파이썬 완전정복: Part 1 PCCE 시험 개요와 LV3 등급 분석

2025.05.22 - [프로그래밍] - [PCCE] LV3 파이썬 완전정복: Part 2: 변수, 자료형, 연산자 – Python 기본 문법 ①

2025.05.23 - [프로그래밍] - [PCCE] LV3 파이썬 완전정복: Part 3 조건문 – 흐름 제어 기초

2025.05.24 - [프로그래밍] - [PCCE] LV3 파이썬 완전정복: Part 4 반복문 – while, for, 중첩 반복

2025.05.24 - [프로그래밍] - [PCCE] LV3 파이썬 완전정복: Part 5 리스트와 2차원 리스트 – 자료구조 입문