KR_Function - somaz94/python-study GitHub Wiki

Python ํ•จ์ˆ˜(Function) ๊ฐœ๋… ์ •๋ฆฌ


1๏ธโƒฃ ํ•จ์ˆ˜(Function)๋ž€?

ํ•จ์ˆ˜๋Š” ํŠน์ • ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์ฝ”๋“œ์˜ ๋ธ”๋ก์œผ๋กœ, ์ฝ”๋“œ์˜ ์žฌ์‚ฌ์šฉ์„ฑ๊ณผ ๋ชจ๋“ˆํ™”๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉ๋œ๋‹ค.

# ๊ธฐ๋ณธ ํ•จ์ˆ˜ ๊ตฌ์กฐ
def ํ•จ์ˆ˜์ด๋ฆ„(๋งค๊ฐœ๋ณ€์ˆ˜):
    ์‹คํ–‰ํ• _์ฝ”๋“œ
    return ๋ฐ˜ํ™˜๊ฐ’

# ์˜ˆ์ œ
def greet(name):
    return f"Hello, {name}!"

2๏ธโƒฃ ํ•จ์ˆ˜์˜ ์ข…๋ฅ˜

1. ๋งค๊ฐœ๋ณ€์ˆ˜์™€ ๋ฐ˜ํ™˜๊ฐ’์— ๋”ฐ๋ฅธ ๋ถ„๋ฅ˜

# 1. ๋งค๊ฐœ๋ณ€์ˆ˜์™€ ๋ฐ˜ํ™˜๊ฐ’์ด ๋ชจ๋‘ ์žˆ๋Š” ํ•จ์ˆ˜
def add(a, b):
    return a + b

# 2. ๋งค๊ฐœ๋ณ€์ˆ˜๋งŒ ์žˆ๋Š” ํ•จ์ˆ˜
def print_info(name, age):
    print(f"์ด๋ฆ„: {name}, ๋‚˜์ด: {age}")

# 3. ๋ฐ˜ํ™˜๊ฐ’๋งŒ ์žˆ๋Š” ํ•จ์ˆ˜
def get_pi():
    return 3.14

# 4. ๋งค๊ฐœ๋ณ€์ˆ˜์™€ ๋ฐ˜ํ™˜๊ฐ’์ด ๋ชจ๋‘ ์—†๋Š” ํ•จ์ˆ˜
def say_hello():
    print("Hello!")

2. ๊ฐ€๋ณ€ ์ธ์ž ํ•จ์ˆ˜

# *args: ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์œ„์น˜ ์ธ์ž๋ฅผ ํŠœํ”Œ๋กœ ๋ฐ›์Œ
def sum_all(*args):
    return sum(args)

# **kwargs: ํ‚ค์›Œ๋“œ ์ธ์ž๋ฅผ ๋”•์…”๋„ˆ๋ฆฌ๋กœ ๋ฐ›์Œ
def print_kwargs(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

3๏ธโƒฃ ํ•จ์ˆ˜์˜ ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ

1. ๊ธฐ๋ณธ๊ฐ’ ๋งค๊ฐœ๋ณ€์ˆ˜

def greet(name, greeting="Hello"):
    return f"{greeting}, {name}!"

print(greet("Alice"))          # Hello, Alice!
print(greet("Bob", "Hi"))      # Hi, Bob!

2. Lambda ํ•จ์ˆ˜

# ์ผ๋ฐ˜ ํ•จ์ˆ˜
def add(a, b):
    return a + b

# ๋žŒ๋‹ค ํ•จ์ˆ˜
add = lambda a, b: a + b

# ํ™œ์šฉ ์˜ˆ์ œ
numbers = [1, 2, 3, 4, 5]
squares = list(map(lambda x: x**2, numbers))

4๏ธโƒฃ ์Šค์ฝ”ํ”„(Scope)

# ์ „์—ญ ๋ณ€์ˆ˜
global_var = 10

def function():
    # ์ง€์—ญ ๋ณ€์ˆ˜
    local_var = 20
    print(global_var)  # ์ „์—ญ ๋ณ€์ˆ˜ ์ ‘๊ทผ ๊ฐ€๋Šฅ
    
    # ์ „์—ญ ๋ณ€์ˆ˜ ์ˆ˜์ •
    global global_var
    global_var = 30

โœ… ํ•จ์ˆ˜ ์ž‘์„ฑ Tip:

  • ํ•จ์ˆ˜๋Š” ํ•œ ๊ฐ€์ง€ ์ž‘์—…๋งŒ ์ˆ˜ํ–‰ํ•˜๋„๋ก ์„ค๊ณ„
  • ํ•จ์ˆ˜ ์ด๋ฆ„์€ ๊ธฐ๋Šฅ์„ ๋ช…ํ™•ํžˆ ํ‘œํ˜„
  • ๋ฌธ์„œํ™” ๋ฌธ์ž์—ด(docstring) ์‚ฌ์šฉ
  • ์ ์ ˆํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜์™€ ๋ฐ˜ํ™˜๊ฐ’ ์„ค๊ณ„


5๏ธโƒฃ ๊ณ ๊ธ‰ ํ•จ์ˆ˜ ๊ฐœ๋…

1. ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ

ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ ํ•จ์ˆ˜๋ฅผ ์ผ๊ธ‰ ๊ฐ์ฒด๋กœ ์ทจ๊ธ‰ํ•˜๊ณ  ๋ถˆ๋ณ€์„ฑ๊ณผ ์ˆœ์ˆ˜ ํ•จ์ˆ˜๋ฅผ ์ค‘์š”์‹œํ•˜๋Š” ํŒจ๋Ÿฌ๋‹ค์ž„์ด๋‹ค.

# ์ˆœ์ˆ˜ ํ•จ์ˆ˜
def pure_add(a, b):
    return a + b  # ์™ธ๋ถ€ ์ƒํƒœ ๋ณ€๊ฒฝ ์—†์Œ, ๋™์ผ ์ž…๋ ฅ = ๋™์ผ ์ถœ๋ ฅ

# ๊ณ ์ฐจ ํ•จ์ˆ˜: ํ•จ์ˆ˜๋ฅผ ์ธ์ž๋กœ ๋ฐ›๊ฑฐ๋‚˜ ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜
def apply_operation(a, b, operation):
    return operation(a, b)

result = apply_operation(5, 3, lambda x, y: x + y)  # 8

# ํ•จ์ˆ˜ํ˜• ๋„๊ตฌ
from functools import reduce

# map: ๊ฐ ์š”์†Œ์— ํ•จ์ˆ˜ ์ ์šฉ
numbers = [1, 2, 3, 4, 5]
doubled = list(map(lambda x: x * 2, numbers))  # [2, 4, 6, 8, 10]

# filter: ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ์š”์†Œ๋งŒ ํ•„ํ„ฐ๋ง
evens = list(filter(lambda x: x % 2 == 0, numbers))  # [2, 4]

# reduce: ๋ˆ„์  ์ง‘๊ณ„
total = reduce(lambda acc, x: acc + x, numbers, 0)  # 15

2. ํด๋กœ์ €(Closure)

ํด๋กœ์ €๋Š” ์ž์‹ ์„ ๊ฐ์‹ธ๋Š” ์Šค์ฝ”ํ”„์˜ ๋ณ€์ˆ˜๋ฅผ ๊ธฐ์–ตํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.

def make_counter():
    count = 0  # ๋‚ด๋ถ€ ๋ณ€์ˆ˜
    
    def counter():
        nonlocal count  # ์™ธ๋ถ€ ํ•จ์ˆ˜์˜ ๋ณ€์ˆ˜ ์‚ฌ์šฉ
        count += 1
        return count
    
    return counter  # ๋‚ด๋ถ€ ํ•จ์ˆ˜ ๋ฐ˜ํ™˜

# ์‚ฌ์šฉ ์˜ˆ์‹œ
counter = make_counter()
print(counter())  # 1
print(counter())  # 2
print(counter())  # 3

# ํด๋กœ์ €๋กœ ํ•จ์ˆ˜ ํŒฉํ† ๋ฆฌ ๋งŒ๋“ค๊ธฐ
def power_factory(exponent):
    def power(base):
        return base ** exponent
    return power

square = power_factory(2)
cube = power_factory(3)

print(square(4))  # 16
print(cube(3))    # 27

3. ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ(Decorator)

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ๊ธฐ์กด ํ•จ์ˆ˜์˜ ๋™์ž‘์„ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ ํ™•์žฅํ•˜๋Š” ์„ค๊ณ„ ํŒจํ„ด์ด๋‹ค.

# ๊ธฐ๋ณธ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ
def log_decorator(func):
    def wrapper(*args, **kwargs):
        print(f"ํ•จ์ˆ˜ {func.__name__} ์‹คํ–‰ ์‹œ์ž‘")
        result = func(*args, **kwargs)
        print(f"ํ•จ์ˆ˜ {func.__name__} ์‹คํ–‰ ์™„๋ฃŒ")
        return result
    return wrapper

# ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์ ์šฉ
@log_decorator
def greet(name):
    return f"Hello, {name}!"

# ์œ„ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๋™์ผ:
# greet = log_decorator(greet)

print(greet("Alice"))  # ๋กœ๊ทธ ์ถœ๋ ฅ ํ›„ "Hello, Alice!" ๋ฐ˜ํ™˜

# ์ธ์ž๋ฅผ ๋ฐ›๋Š” ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ
def repeat(times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            results = []
            for _ in range(times):
                results.append(func(*args, **kwargs))
            return results
        return wrapper
    return decorator

@repeat(3)
def say_hi():
    return "Hi!"

print(say_hi())  # ["Hi!", "Hi!", "Hi!"] ๋ฐ˜ํ™˜

4. ์žฌ๊ท€ ํ•จ์ˆ˜(Recursive Function)

์žฌ๊ท€ ํ•จ์ˆ˜๋Š” ์ž๊ธฐ ์ž์‹ ์„ ํ˜ธ์ถœํ•˜๋Š” ํ•จ์ˆ˜๋กœ, ๋ณต์žกํ•œ ๋ฌธ์ œ๋ฅผ ๋‹จ์ˆœํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.

# ํŒฉํ† ๋ฆฌ์–ผ ๊ณ„์‚ฐ
def factorial(n):
    if n <= 1:  # ๊ธฐ์ € ์กฐ๊ฑด(base case)
        return 1
    return n * factorial(n - 1)  # ์žฌ๊ท€ ํ˜ธ์ถœ

print(factorial(5))  # 120

# ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)

print(fibonacci(6))  # 8

# ๊ผฌ๋ฆฌ ์žฌ๊ท€ ์ตœ์ ํ™”
def factorial_tail(n, acc=1):
    if n <= 1:
        return acc
    return factorial_tail(n - 1, n * acc)

print(factorial_tail(5))  # 120

5. ์ œ๋„ˆ๋ ˆ์ดํ„ฐ(Generator)

์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋Š” ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํ•จ์ˆ˜๋กœ, ๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์ ์ธ ๋ฐ์ดํ„ฐ ์ƒ์„ฑ์— ์œ ์šฉํ•˜๋‹ค.

# ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜
def count_up_to(max):
    count = 1
    while count <= max:
        yield count
        count += 1

# ์‚ฌ์šฉ
counter = count_up_to(5)
print(next(counter))  # 1
print(next(counter))  # 2

# for ๋ฃจํ”„์—์„œ ์‚ฌ์šฉ
for num in count_up_to(3):
    print(num)  # 1, 2, 3 ์ถœ๋ ฅ

# ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ‘œํ˜„์‹
squares = (x**2 for x in range(5))
print(list(squares))  # [0, 1, 4, 9, 16]

# ๋ฌดํ•œ ์‹œํ€€์Šค ์ƒ์„ฑ
def infinite_sequence():
    num = 0
    while True:
        yield num
        num += 1

counter = infinite_sequence()
for i in range(5):
    print(next(counter))  # 0, 1, 2, 3, 4 ์ถœ๋ ฅ


6๏ธโƒฃ ํƒ€์ž… ํžŒํŠธ์™€ ํ•จ์ˆ˜ ์–ด๋…ธํ…Œ์ด์…˜

Python 3.5๋ถ€ํ„ฐ ๋„์ž…๋œ ํƒ€์ž… ํžŒํŠธ๋ฅผ ํ†ตํ•ด ํ•จ์ˆ˜ ์ธ์ž์™€ ๋ฐ˜ํ™˜๊ฐ’์˜ ํƒ€์ž…์„ ๋ช…์‹œํ•  ์ˆ˜ ์žˆ๋‹ค.

# ๊ธฐ๋ณธ ํƒ€์ž… ํžŒํŠธ
def greeting(name: str) -> str:
    return f"Hello, {name}!"

# ๋ณตํ•ฉ ํƒ€์ž…
from typing import List, Dict, Tuple, Optional, Union, Callable

def process_items(items: List[int]) -> List[int]:
    return [item * 2 for item in items]

def merge_dicts(dict1: Dict[str, int], dict2: Dict[str, int]) -> Dict[str, int]:
    return {**dict1, **dict2}

# ์„ ํƒ์  ๋งค๊ฐœ๋ณ€์ˆ˜
def find_user(user_id: int, full_info: Optional[bool] = None) -> Dict[str, Union[str, int]]:
    user = {"id": user_id, "name": "John Doe"}
    if full_info:
        user["email"] = "[email protected]"
    return user

# ํ•จ์ˆ˜ ํƒ€์ž…
def apply_transformation(items: List[int], transform: Callable[[int], int]) -> List[int]:
    return [transform(item) for item in items]

result = apply_transformation([1, 2, 3], lambda x: x * x)


7๏ธโƒฃ ๋ถ€๋ถ„ ์ ์šฉ๊ณผ ์ปค๋ง(Currying)

๋ถ€๋ถ„ ์ ์šฉ๊ณผ ์ปค๋ง์€ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ํ•จ์ˆ˜์˜ ์ผ๋ถ€ ์ธ์ž๋ฅผ ๋ฏธ๋ฆฌ ์ฑ„์›Œ๋„ฃ๋Š” ๊ธฐ๋ฒ•์ด๋‹ค.

from functools import partial

# ๋ถ€๋ถ„ ์ ์šฉ
def multiply(a, b, c):
    return a * b * c

# ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋งŒ ๊ณ ์ •
double = partial(multiply, 2)
print(double(3, 4))  # 2 * 3 * 4 = 24

# ๋‘ ๋ฒˆ์งธ ์ธ์ž๊นŒ์ง€ ๊ณ ์ •
double_triple = partial(multiply, 2, 3)
print(double_triple(4))  # 2 * 3 * 4 = 24

# ์ปค๋ง ์ง์ ‘ ๊ตฌํ˜„
def curry(func):
    def curried(*args, **kwargs):
        if len(args) + len(kwargs) >= func.__code__.co_argcount:
            return func(*args, **kwargs)
        return lambda *more_args, **more_kwargs: curried(*(args + more_args), **{**kwargs, **more_kwargs})
    return curried

@curry
def add3(a, b, c):
    return a + b + c

add1 = add3(1)
add1_2 = add1(2)
print(add1_2(3))  # 1 + 2 + 3 = 6
print(add3(1)(2)(3))  # 1 + 2 + 3 = 6
print(add3(1, 2, 3))  # 1 + 2 + 3 = 6


8๏ธโƒฃ ์ปจํ…์ŠคํŠธ ๊ด€๋ฆฌ์ž์™€ ํ•จ์ˆ˜

ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ์ปจํ…์ŠคํŠธ ๊ด€๋ฆฌ์ž๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

from contextlib import contextmanager
import time

# ์ปจํ…์ŠคํŠธ ๊ด€๋ฆฌ์ž ํ•จ์ˆ˜
@contextmanager
def timer():
    start = time.time()
    try:
        yield  # ์ด ์ง€์ ์—์„œ with ๋ธ”๋ก ๋‚ด๋ถ€ ์ฝ”๋“œ ์‹คํ–‰
    finally:
        end = time.time()
        print(f"์‹คํ–‰ ์‹œ๊ฐ„: {end - start:.5f}์ดˆ")

# ์‚ฌ์šฉ ์˜ˆ์‹œ
with timer():
    # ์‹œ๊ฐ„์„ ์ธก์ •ํ•  ์ฝ”๋“œ
    result = sum(i**2 for i in range(10000))

# ๋ฆฌ์†Œ์Šค ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ ์ปจํ…์ŠคํŠธ ๊ด€๋ฆฌ์ž
@contextmanager
def open_file(filename, mode='r'):
    try:
        f = open(filename, mode)
        yield f
    finally:
        f.close()

# ์‚ฌ์šฉ ์˜ˆ์‹œ
with open_file('example.txt', 'w') as f:
    f.write('Hello, World!')


9๏ธโƒฃ ๋น„๋™๊ธฐ ํ•จ์ˆ˜(Async Function)

Python 3.5๋ถ€ํ„ฐ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์œ„ํ•œ async/await ๊ตฌ๋ฌธ์ด ๋„์ž…๋˜์—ˆ๋‹ค.

import asyncio

# ๋น„๋™๊ธฐ ํ•จ์ˆ˜ ์ •์˜
async def fetch_data(url):
    print(f"{url} ๋ฐ์ดํ„ฐ ์š”์ฒญ ์ค‘...")
    await asyncio.sleep(1)  # ๋น„๋™๊ธฐ ๋Œ€๊ธฐ (I/O ์ž‘์—… ์‹œ๋ฎฌ๋ ˆ์ด์…˜)
    return f"{url}์˜ ๋ฐ์ดํ„ฐ"

# ์—ฌ๋Ÿฌ ๋น„๋™๊ธฐ ์ž‘์—… ์‹คํ–‰
async def fetch_all():
    urls = [
        "https://example.com/api/1",
        "https://example.com/api/2",
        "https://example.com/api/3"
    ]
    
    # ๋™์‹œ ์‹คํ–‰
    tasks = [fetch_data(url) for url in urls]
    results = await asyncio.gather(*tasks)
    
    return results

# ๋น„๋™๊ธฐ ๋ฉ”์ธ ํ•จ์ˆ˜
async def main():
    results = await fetch_all()
    for result in results:
        print(result)

# ์‹คํ–‰
if __name__ == "__main__":
    asyncio.run(main())

# ๋น„๋™๊ธฐ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ
async def async_generator():
    for i in range(5):
        await asyncio.sleep(0.1)
        yield i

# ๋น„๋™๊ธฐ ์ดํ„ฐ๋ ˆ์ด์…˜
async def use_async_gen():
    async for value in async_generator():
        print(value)


๐Ÿ”Ÿ ํ•จ์ˆ˜ ์ตœ์ ํ™” ๊ธฐ๋ฒ•

ํ•จ์ˆ˜ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•˜๋Š” ๋‹ค์–‘ํ•œ ์ตœ์ ํ™” ๊ธฐ๋ฒ•์ด๋‹ค.

import time
import functools

# 1. ๋ฉ”๋ชจ์ด์ œ์ด์…˜(Memoization) - ์žฌ๊ท€ ํ•จ์ˆ˜ ์ตœ์ ํ™”
@functools.lru_cache(maxsize=None)
def fibonacci_memo(n):
    if n <= 1:
        return n
    return fibonacci_memo(n - 1) + fibonacci_memo(n - 2)

# ์„ฑ๋Šฅ ๋น„๊ต
def fibonacci_normal(n):
    if n <= 1:
        return n
    return fibonacci_normal(n - 1) + fibonacci_normal(n - 2)

start = time.time()
fibonacci_normal(30)
print(f"์ผ๋ฐ˜ ์žฌ๊ท€: {time.time() - start:.5f}์ดˆ")

start = time.time()
fibonacci_memo(30)
print(f"๋ฉ”๋ชจ์ด์ œ์ด์…˜: {time.time() - start:.5f}์ดˆ")

# 2. ์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•œ ๋ฉ”๋ชจ๋ฆฌ ์ตœ์ ํ™”
def read_large_file(file_path):
    with open(file_path, 'r') as file:
        for line in file:
            yield line.strip()
            
# 3. ์ง€์—ญ ๋ณ€์ˆ˜ ์ตœ์ ํ™”
def process_items_optimized(items):
    # ์ง€์—ญ ๋ณ€์ˆ˜์— ํ•จ์ˆ˜ ๋ฐ”์ธ๋”ฉ
    _len = len
    result = []
    _append = result.append
    
    for item in items:
        _append(_len(str(item)))
    
    return result

# 4. ์ธ๋ผ์ธ ํ•จ์ˆ˜ ํ˜ธ์ถœ ์ตœ์ ํ™”
def calculate_sum(numbers):
    # ํ•จ์ˆ˜ ํ˜ธ์ถœ ๋Œ€์‹  ์ธ๋ผ์ธ ๊ณ„์‚ฐ
    total = 0
    for num in numbers:
        total += num
    return total


1๏ธโƒฃ1๏ธโƒฃ ์‹ค์ „ ํ•จ์ˆ˜ ํŒจํ„ด

์‹ค๋ฌด์—์„œ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๋˜๋Š” ํ•จ์ˆ˜ ๋””์ž์ธ ํŒจํ„ด์ด๋‹ค.

1. ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜ ํŒจํ„ด

# ๊ฐ์ฒด ์ƒ์„ฑ์„ ์บก์Аํ™”ํ•˜๋Š” ํŒฉํ† ๋ฆฌ ํ•จ์ˆ˜
def create_person(name, age, profession=None):
    person = {
        'name': name,
        'age': age
    }
    
    if profession:
        person['profession'] = profession
        
    if age < 18:
        person['category'] = 'minor'
    else:
        person['category'] = 'adult'
        
    return person

# ์‚ฌ์šฉ ์˜ˆ์‹œ
student = create_person("Alice", 15)
developer = create_person("Bob", 28, "Software Developer")

2. ์ „๋žต ํ•จ์ˆ˜ ํŒจํ„ด

# ๋‹ค์–‘ํ•œ ์ „๋žต ํ•จ์ˆ˜
def discount_regular(order_total):
    return order_total * 0.05  # 5% ํ• ์ธ

def discount_premium(order_total):
    return order_total * 0.1   # 10% ํ• ์ธ

def discount_vip(order_total):
    return max(order_total * 0.15, 100)  # 15% ํ• ์ธ, ์ตœ์†Œ 100

# ์ „๋žต์„ ์ ์šฉํ•˜๋Š” ํ•จ์ˆ˜
def apply_discount(order_total, customer_type):
    discount_strategies = {
        'regular': discount_regular,
        'premium': discount_premium,
        'vip': discount_vip
    }
    
    discount_func = discount_strategies.get(customer_type, lambda x: 0)
    return discount_func(order_total)

# ์‚ฌ์šฉ ์˜ˆ์‹œ
print(apply_discount(1000, 'regular'))  # 50
print(apply_discount(1000, 'vip'))      # 150

3. ํŒŒ์ดํ”„๋ผ์ธ ํŒจํ„ด

# ๊ฐ ๋‹จ๊ณ„๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ํ•จ์ˆ˜๋“ค
def validate(data):
    if not isinstance(data, dict) or 'name' not in data:
        return None
    return data

def normalize(data):
    if data is None:
        return None
    
    result = data.copy()
    result['name'] = result['name'].strip().lower()
    return result

def process(data):
    if data is None:
        return None
    
    result = data.copy()
    result['processed'] = True
    return result

# ํŒŒ์ดํ”„๋ผ์ธ ๊ตฌํ˜„
def pipeline(*funcs):
    def pipe(data):
        result = data
        for func in funcs:
            result = func(result)
            if result is None:
                return None
        return result
    return pipe

# ์‚ฌ์šฉ ์˜ˆ์‹œ
process_data = pipeline(validate, normalize, process)
good_data = {'name': ' John Doe '}
bad_data = {'id': 123}

print(process_data(good_data))  # {'name': 'john doe', 'processed': True}
print(process_data(bad_data))   # None

4. ๋ช…๋ น-์ฟผ๋ฆฌ ๋ถ„๋ฆฌ ํŒจํ„ด

class UserRepository:
    def __init__(self):
        self.users = {}
        self.next_id = 1
    
    # ๋ช…๋ น ํ•จ์ˆ˜ (์ƒํƒœ ๋ณ€๊ฒฝ)
    def add_user(self, name, email):
        user_id = self.next_id
        self.users[user_id] = {
            'id': user_id,
            'name': name,
            'email': email
        }
        self.next_id += 1
        return user_id
    
    def update_email(self, user_id, new_email):
        if user_id not in self.users:
            return False
        self.users[user_id]['email'] = new_email
        return True
    
    # ์ฟผ๋ฆฌ ํ•จ์ˆ˜ (์ƒํƒœ ๋ณ€๊ฒฝ ์—†์Œ)
    def get_user(self, user_id):
        return self.users.get(user_id)
    
    def find_by_email(self, email):
        for user in self.users.values():
            if user['email'] == email:
                return user
        return None

# ์‚ฌ์šฉ ์˜ˆ์‹œ
repo = UserRepository()
user_id = repo.add_user("John Doe", "[email protected]")
print(repo.get_user(user_id))
repo.update_email(user_id, "[email protected]")
print(repo.find_by_email("[email protected]"))


โš ๏ธ **GitHub.com Fallback** โš ๏ธ