[Python] 함수, 클래스

seonyoung·2024년 7월 31일
0

📁 함수

  • 재귀 함수는 함수가 자기 자신을 호출하는 함수
    → 이는 문제가 더 이상 작아질 수 없을 때까지 문제를 반복적으로 나누고, 그 후에 작은 문제들의 해답을 모아서 원래 문제를 해결하는 방식

<함수란?>

  • 함수는 특정 작업을 수행하는 코드의 묶음
  • 입력값을 받아서 그 입력값을 처리한 후 결과값을 반환
  • ex) 수학에서 y = f(x) 라는 함수는 x라는 입력값을 받아 y라는 결과값을 반환하는 식

<함수를 사용하는 이유?>

  • 코드 재사용성
    • 프로그래밍을 하다 보면 똑같은 내용을 반복해서 작성하고 있는 자신을 발견할 때가 종종 있으며, 이때가 바로 함수가 필요한 때
    • 즉, 반복되는 부분이 있을 경우, ‘반복적으로 사용되는 가치 있는 부분’을 한 뭉치로 묶어 ‘어떤 입력값을 주었을 때 어떤 결괏값을 리턴해 준다’라는 식의 함수로 작성하는 것
  • 가독성 향상
    • 자신이 작성한 프로그램을 기능 단위의 함수로 분리해 놓으면 프로그램 흐름을 일목요연하게 볼 수 있기 때문
    • 마치 공장에서 원재료가 여러 공정을 거쳐 하나의 완제품이 되는 것처럼 프로그램에서도 입력한 값이 여러 함수를 거치면서 원하는 결괏값을 내는 것을 볼 수 있음
    • 이렇게 되면 프로그램 흐름도 잘 파악할 수 있고 오류가 어디에서 나는지도 쉽게 알아차릴 수 있음
  • 유지보수 용이 : 함수로 코드를 분리해 놓으면 특정 기능의 구현을 수정하거나 확장할 때 해당 함수만 수정하면 되므로 유지보수가 용이

<함수 사용 예제>

  • 기본 구조 : 함수는 def 키워드를 사용하여 정의하며, 입력값을 받아서 결괏값을 반환
def add(a, b): 
    return a + b

# 사용 예제
result = add(3, 5)
print(result)  # 출력: 8
  • 입력이 없는 구조: 입력값이 없는 함수는 고정된 결괏값이나 특정 동작을 수행할 수 있음
def say(): 
    return 'Hi'

# 사용 예제
greeting = say()
print(greeting)  # 출력: Hi
  • 리턴값이 없는 구조: 결괏값을 반환하지 않고, 내부에서 특정 동작을 수행하는 함수
def add(a, b): 
    print("%d, %d의 합은 %d입니다." % (a, b, a+b))

# 사용 예제
add(3, 5)  # 출력: 3, 5의 합은 8입니다.
  • 입력도 리턴값도 없는 구조: 입력값도 없고, 결괏값을 반환하지도 않는 함수
def say(): 
    print('Hi')

# 사용 예제
say()  # 출력: Hi
  • 여러 값을 리턴하는 구조: 함수는 여러 값을 한꺼번에 반환할 수 있음
def calculate(a, b):
    sum_value = a + b
    diff_value = a - b
    prod_value = a * b
    quot_value = a / b if b != 0 else None
    return sum_value, diff_value, prod_value, quot_value

# 사용 예제
sum_result, diff_result, prod_result, quot_result = calculate(10, 2)
print(f"합: {sum_result}, 차: {diff_result}, 곱: {prod_result}, 나눗셈: {quot_result}")
# 출력: 합: 12, 차: 8, 곱: 20, 나눗셈: 5.0

<재귀함수란?>

  • 함수가 자기 자신을 호출하는 함수

  • 이는 문제가 더 이상 작아질 수 없을 때까지 문제를 반복적으로 나누고, 그 후에 작은 문제들의 해답을 모아서 원래 문제를 해결하는 방식입니다

  • 팩토리얼 계산 예제

def factorial(n):
    if n == 1:
        return 1
    else:
        return n * factorial(n - 1)

# 사용 예제
result = factorial(5)
print(result)  # 출력: 120

→ 여기서 factorial 함수는 n이 1일 때 1을 반환하고, 그렇지 않을 경우 n * factorial(n - 1)을 호출
→ 이렇게 함으로써 n이 1이 될 때까지 계속해서 자신을 호출

📁 클래스

<클래스란?>

  • 객체를 만들어 내기 위한 설계도 또는 틀과 같은 의미
  • ex) 붕어빵 틀이 있다면 쉽게 동일한 모양의 다양한 맛의 붕어빵을 대량 생산이 가능
    • 클래스 : 붕어빵 틀
    • 객체 또는 인스턴스: 붕어

<계산기 클래스를 만들어 보자>

  • 먼저 연산을 하는 함수를 만들기
def add(x, y):
    return x + y

def subtract(x, y):
    return x - y

def multiply(x, y):
    return x * y

def divide(x, y):
    if y == 0:
        return "Division by zero error"
    return x / y
  • 이 기능들을 계산기 라는 걸로 묶어보자
class Calculator:
    def add(self, x, y):
        return x + y

    def subtract(self, x, y):
        return x - y

    def multiply(self, x, y):
        return x * y

    def divide(self, x, y):
        if y == 0:
            return "Division by zero error"
        return x / y
# 클래스 인스턴스 생성
calc = Calculator()

# 연산 예시
print(calc.add(10, 5))       # 결과: 15
print(calc.subtract(10, 5))  # 결과: 5
print(calc.multiply(10, 5))  # 결과: 50
print(calc.divide(10, 5))    # 결과: 2.0
print(calc.divide(10, 0))    # 결과: Division by zero error
  • 진짜 계산기는 계산 결과가 누적되니 계산기 안에 변수를 추가해보자
class AccumulatingCalculator:
    def __init__(self):
        self.total = 0  # 계산 결과를 누적하는 변수

    def add(self, x):
        self.total += x
        return self.total

    def subtract(self, x):
        self.total -= x
        return self.total

    def multiply(self, x):
        self.total *= x
        return self.total

    def divide(self, x):
        if x == 0:
            return "Division by zero error"
        self.total /= x
        return self.total
# 클래스 인스턴스 생성
acc_calc = AccumulatingCalculator()

# 연산 예시
print(acc_calc.add(10))       # 결과: 10 (0 + 10)
print(acc_calc.subtract(2))   # 결과: 8 (10 - 2)
print(acc_calc.multiply(5))   # 결과: 40 (8 * 5)
print(acc_calc.divide(2))     # 결과: 20 (40 / 2)
print(acc_calc.add(5))        # 결과: 25 (20 + 5)
  • 리셋 기능도 넣어볼까?
class AccumulatingCalculator:
    def __init__(self):
        self.total = 0  # 계산 결과를 누적하는 변수

    def add(self, x):
        self.total += x
        return self.total

    def subtract(self, x):
        self.total -= x
        return self.total

    def multiply(self, x):
        self.total *= x
        return self.total

    def divide(self, x):
        if x == 0:
            return "Division by zero error"
        self.total /= x
        return self.total

    def reset(self):
        self.total = 0
        return self.total
# 클래스 인스턴스 생성
acc_calc = AccumulatingCalculator()

# 연산 예시
print(acc_calc.add(10))       # 결과: 10 (0 + 10)
print(acc_calc.subtract(2))   # 결과: 8 (10 - 2)
print(acc_calc.multiply(5))   # 결과: 40 (8 * 5)
print(acc_calc.divide(2))     # 결과: 20 (40 / 2)
print(acc_calc.add(5))        # 결과: 25 (20 + 5)
print(acc_calc.reset())       # 결과: 0 (계산기 리셋)

<다량의 계산기를 만들어보자>

  • 이제 계산기 클래스는 만들 수 있어, 그런데 클래스는 여러개의 인스턴스를 생성하는 것이 장점이니 만들어보자
# 인스턴스 생성
calc1 = AccumulatingCalculator()
calc2 = AccumulatingCalculator()
calc3 = AccumulatingCalculator()

# 첫 번째 계산기 사용
calc1.add(50)
calc1.subtract(20)
print("Calc1 Total:", calc1.total)  # 결과: 30

# 두 번째 계산기 사용
calc2.add(100)
calc2.multiply(2)
print("Calc2 Total:", calc2.total)  # 결과: 200

# 세 번째 계산기 사용
calc3.add(25)
calc3.divide(5)
print("Calc3 Total:", calc3.total)  # 결과: 5

# 각 계산기는 독립적으로 작동합니다.
  • 근데 동일한 계산기야, 아직 뭐가 좋은지 모르겠어
class RegionalCalculator:
    def __init__(self, region):
        self.total = 0
        self.region = region

    def add(self, x):
        self.total += x
        return self._print_result()

    def subtract(self, x):
        self.total -= x
        return self._print_result()

    def multiply(self, x):
        self.total *= x
        return self._print_result()

    def divide(self, x):
        if x == 0:
            return "Division by zero error"
        self.total /= x
        return self._print_result()

    def reset(self):
        self.total = 0
        return self._print_result()

    def _print_result(self):
        if self.region == "경상도":
            return f"{self.total}이다 잉가, 바람이 분다!"
        elif self.region == "전라도":
            return f"{self.total}이제 노라, 그렇구마잉!"
        elif self.region == "충청도":
            return f"{self.total}여, 그러믄 되겠네!"
        else:
            return self.total
# 각 지역별 계산기 인스턴스 생성
calc_gyeongsang = RegionalCalculator("경상도")
calc_jeolla = RegionalCalculator("전라도")
calc_chungcheong = RegionalCalculator("충청도")

# 경상도 계산기 사용
print(calc_gyeongsang.add(10))        # 출력: 10이다 잉가, 바람이 분다!
print(calc_gyeongsang.subtract(3))    # 출력: 7이다 잉가, 바람이 분다!

# 전라도 계산기 사용
print(calc_jeolla.multiply(5))        # 출력: 0이제 노라, 그렇구마잉!
print(calc_jeolla.add(100))           # 출력: 100이제 노라, 그렇구마잉!

# 충청도 계산기 사용
print(calc_chungcheong.divide(4))     # 출력: 0.0여, 그러믄 되겠네!
print(calc_chungcheong.add(40))       # 출력: 40.0여, 그러믄 되겠네!
profile
원하는 바를 이루고 싶은 사람입니다.

0개의 댓글