SW/면접

프로그래밍에서 자주 저지르는 실수와 그 해결 방법

얇은생각 2024. 11. 16. 07:30
반응형

프로그래밍을 처음 시작하거나 어느 정도의 경험이 있는 개발자들조차도 흔히 저지르는 실수들이 있습니다. 이러한 실수들은 코드를 더욱 복잡하게 만들고, 유지 보수를 어렵게 하며, 성능에 영향을 줄 수 있습니다. 이 글에서는 대표적인 프로그래밍 실수들을 살펴보고, 이를 어떻게 개선할 수 있는지에 대해 이야기해보겠습니다. 이 글을 통해 여러분의 코드를 더 효율적이고 가독성 있게 작성할 수 있는 방법을 배울 수 있기를 바랍니다.

 

프로그래밍에서 자주 저지르는 실수와 그 해결 방법

 

1. 조건문 복잡도 줄이기

프로그래밍에서 조건문(특히 if문)을 작성하다 보면 여러 가지 조건을 동시에 검사해야 하는 상황이 자주 발생합니다. 이런 경우 조건이 복잡해지고 코드의 가독성이 떨어질 수 있습니다. 예를 들어, 사용자가 관리자 또는 에디터인지 확인하고, 사용자의 계정 상태가 활성화되어 있는지, 최근 로그인 기록이 있는지 등을 확인해야 한다고 가정해봅시다. 이러한 조건들을 한 줄의 if문으로 모두 나열한다면, 코드가 매우 길고 복잡해지며 이해하기 어려워집니다.

 

개선 방법

복잡한 조건문을 개선하기 위해 각 조건을 변수에 할당하는 방법을 사용할 수 있습니다. 예를 들어, is_authenticated, is_active, has_valid_login 등의 변수를 사용하여 각각의 조건을 의미하는 이름을 붙이면 가독성이 크게 향상됩니다. 이렇게 하면 코드가 자동으로 주석을 다는 것처럼 이해하기 쉽게 됩니다. 더 나아가 이러한 조건들을 하나의 함수로 분리하면 코드의 가독성과 유지보수성이 더욱 좋아집니다.

 

예시

  • 잘못된 코드: 복잡한 조건을 한 줄로 나열
if user.is_authenticated and (user.role == 'admin' or user.role == 'editor') and user.account_status == 'active' and user.age >= 18 and user.age <= 35:
    # 작업 수행
  • 개선된 코드: 조건을 의미 있는 변수로 분리
is_authenticated = user.is_authenticated
has_proper_role = user.role in ['admin', 'editor']
is_active = user.account_status == 'active'
is_valid_age = 18 <= user.age <= 35

if is_authenticated and has_proper_role and is_active and is_valid_age:
    # 작업 수행

 

이렇게 조건들을 변수에 분리하면 코드를 읽는 사람이 조건 하나하나의 의미를 쉽게 파악할 수 있어 가독성이 크게 향상됩니다.

 

 

2. 중첩된 블록 제거하기

다음으로 자주 발생하는 실수는 코드의 중첩입니다. 특히 여러 개의 조건문을 중첩하여 작성하다 보면 코드가 계단 모양으로 내려가며 복잡도가 급격히 증가합니다. 중첩이 많아질수록 코드의 가독성은 떨어지며, 유지보수가 매우 어려워집니다.

 

개선 방법

이러한 중첩을 줄이기 위해 조건이 맞지 않는 경우를 먼저 처리하고, 맞지 않을 경우 빠르게 continuereturn을 사용하여 흐름을 단순화하는 방식이 좋습니다. 이를 통해 코드의 중첩도를 줄이고 각 조건을 독립적으로 다루는 방식으로 개선할 수 있습니다.

 

예시

  • 잘못된 코드: 중첩된 조건문 사용
for number in numbers:
    if number is not None:
        if number > 0:
            if number % 2 == 0:
                if number < 100:
                    results.append(number)
  • 개선된 코드: 중첩 제거 및 조건 분리
for number in numbers:
    if number is None:
        continue
    if number <= 0 or number % 2 != 0 or number >= 100:
        continue
    results.append(number)

 

이렇게 작성하면 코드가 훨씬 간결해지며, 각 조건을 독립적으로 처리할 수 있어 가독성이 좋아집니다.

 

 

3. 반복적인 if-elif 구조 줄이기

많은 초보 개발자들이 특정 값을 확인하기 위해 여러 개의 if-elif 문을 사용하는 경우가 있습니다. 예를 들어, 요일을 숫자로 입력받아 해당 요일의 이름을 출력하는 프로그램을 작성한다고 가정해 봅시다. 이때 각 숫자마다 if-elif를 사용하는 것은 비효율적입니다.

 

개선 방법

대신 딕셔너리나 리스트를 사용하여 값들을 매핑하는 방법이 있습니다. 딕셔너리를 사용하면 키-값 쌍을 쉽게 매핑할 수 있어 코드의 길이를 줄이고 가독성을 높일 수 있습니다.

 

예시

  • 잘못된 코드: 반복적인 if-elif 사용
def get_day_name(day_number):
    if day_number == 1:
        return "Monday"
    elif day_number == 2:
        return "Tuesday"
    elif day_number == 3:
        return "Wednesday"
    # 계속 반복...
  • 개선된 코드: 딕셔너리 사용
def get_day_name(day_number):
    days = {
        1: "Monday",
        2: "Tuesday",
        3: "Wednesday",
        4: "Thursday",
        5: "Friday",
        6: "Saturday",
        7: "Sunday"
    }
    return days.get(day_number, "Invalid day number")

 

이렇게 딕셔너리를 사용하면 새로운 요일을 추가하거나 수정할 때 간단히 딕셔너리에 항목을 추가하거나 변경하면 됩니다.

 

4. 지나치게 큰 함수 만들기

또 다른 흔한 실수는 하나의 함수가 너무 많은 일을 처리하도록 만드는 것입니다. 이런 함수는 이해하기 어렵고, 수정이 필요할 때 많은 시간이 소요될 수 있습니다. 이러한 문제를 해결하기 위해 함수는 단일 책임 원칙(Single Responsibility Principle)을 따르는 것이 좋습니다.

 

개선 방법

하나의 큰 함수를 여러 개의 작은 함수로 나누어 각 함수가 하나의 작업만 처리하도록 합니다. 이렇게 하면 코드를 읽는 사람이 각 함수가 무슨 일을 하는지 쉽게 파악할 수 있으며, 유지보수도 간편해집니다.

 

예시

  • 잘못된 코드: 지나치게 큰 함수
def process_order(order):
    if not isinstance(order, dict):
        raise ValueError("Invalid order format")
    if 'items' not in order or 'customer' not in order:
        raise ValueError("Missing required fields")
    # 총 가격 계산, 할인 적용, 결제 처리 등...
  • 개선된 코드: 작은 함수로 분리
def process_order(order):
    validate_order(order)
    total_price = calculate_total_price(order)
    apply_discount(order)
    process_payment(order)
    send_confirmation_email(order)

def validate_order(order):
    # 주문 유효성 검사 코드

def calculate_total_price(order):
    # 총 가격 계산 코드

def apply_discount(order):
    # 할인 적용 코드

이렇게 각 작업을 작은 함수로 분리하면 코드의 가독성이 높아지고, 특정 기능을 수정할 때도 해당 함수만 수정하면 되므로 유지보수가 쉬워집니다.

 

 

5. 엣지 케이스 처리하지 않기

마지막으로, 많은 개발자들이 놓치는 부분은 엣지 케이스에 대한 처리를 하지 않는 것입니다. 예를 들어, 빈 리스트에 대해 평균을 구하려고 할 때 발생할 수 있는 오류를 고려하지 않는 경우가 있습니다.

 

개선 방법

코드를 작성할 때 항상 예상치 못한 입력이나 상황에 대해 미리 검토하고 처리하는 로직을 추가해야 합니다. 이렇게 하면 코드가 더 견고해지고 예외 상황에 대해 잘 대처할 수 있습니다.

 

예시

  • 잘못된 코드: 엣지 케이스 미처리
def calculate_average(numbers):
    return sum(numbers) / len(numbers)

 

  • 개선된 코드: 엣지 케이스 처리
def calculate_average(numbers):
    if not isinstance(numbers, list):
        raise TypeError("Input must be a list")
    if len(numbers) == 0:
        return 0
    valid_numbers = [num for num in numbers if isinstance(num, (int, float))]
    if len(valid_numbers) == 0:
        return 0
    return sum(valid_numbers) / len(valid_numbers)

이렇게 엣지 케이스를 처리하면 예기치 않은 상황에서도 코드가 오류 없이 동작하도록 할 수 있습니다.

 


 

이와 같이 프로그래밍에서 자주 발생하는 실수들을 고치면 코드의 가독성, 유지보수성, 성능을 크게 향상시킬 수 있습니다. 개발자는 코드 작성 시 항상 가독성을 염두에 두어야 하며, 가능한 한 단순하고 명확하게 코드를 작성하는 것이 좋습니다. 이를 통해 코드를 읽는 다른 사람들뿐만 아니라 미래의 자신에게도 도움이 되는 코드를 작성할 수 있을 것입니다. 프로그래밍에서 작은 실수들이 쌓여 큰 문제로 발전할 수 있기 때문에, 오늘 소개한 개선 방법들을 실천해 보시길 바랍니다.

반응형