파이썬으로 나만의 간단한 계산기를 만들어 보며 함수와 예외 처리의 핵심 개념을 실전으로 익혀보는 시간입니다. 사용자에게 편리하고 안정적인 계산 기능을 제공하는 프로그램을 함께 구현해 보겠습니다. 이 과정을 통해 여러분의 코딩 실력이 한 단계 성장하는 경험을 하실 수 있을 것입니다.
핵심 요약
- 목표 설정: 사용자 입력 기반의 사칙연산을 수행하고 오류를 안전하게 처리하는 계산기를 만듭니다.
- 함수 활용: 각 연산(더하기, 빼기, 곱하기, 나누기)을 독립된 함수로 구현하여 코드의 재사용성을 높입니다.
- 입력 처리: 사용자로부터 숫자와 연산자를 입력받고, `float()`을 사용해 숫자형으로 변환합니다.
- 예외 처리: `try-except` 구문을 활용하여 숫자 변환 오류(`ValueError`)와 0으로 나누는 오류(`ZeroDivisionError`)를 안정적으로 처리합니다.
- 반복 실행: 계산기가 종료될 때까지 지속적으로 연산을 수행할 수 있도록 `while` 반복문을 사용합니다.
간단한 계산기 프로젝트의 목표는 무엇인가요?
계산기 프로젝트의 목표는 사용자 입력을 받아 기본적인 사칙연산을 수행하고, 발생할 수 있는 오류를 안전하게 처리하는 것입니다. 저는 취미로 코딩을 시작했던 10년 전, 처음으로 계산기를 만들며 파이썬의 기본적인 문법들이 실제 어떻게 유기적으로 작동하는지 깨달았습니다. 단순히 결과만 출력하는 것을 넘어, 사용자가 잘못된 값을 입력했을 때 프로그램이 멈추지 않고 적절한 안내를 제공하는 것이 중요합니다. 이 프로젝트는 함수 정의와 호출, 예외 처리 같은 핵심 개념들을 통합하여 실용적인 프로그램을 만드는 좋은 예제가 됩니다.
계산기의 핵심 기능, 어떻게 함수로 구현할까요?
사칙연산을 각각의 독립적인 함수로 정의하여 코드의 재사용성과 가독성을 높일 수 있습니다. 각 함수는 두 개의 숫자를 매개변수로 받아 해당 연산을 수행하고 그 결과를 반환합니다. 이렇게 모듈화하면 나중에 기능을 추가하거나 수정할 때도 훨씬 효율적입니다. 저는 GUI 개발을 할 때도 이런 작은 기능 단위를 함수로 만들어서 사용하는 습관을 가지고 있습니다. 실제 Tkinter로 GUI 계산기를 만들 때도 이 함수들을 그대로 재사용하여 시간을 절약할 수 있었습니다.
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):
# 0으로 나누는 예외는 나중에 처리합니다.
return x / y
이 코드는 기본적인 사칙연산을 수행하는 4개의 함수를 정의합니다. 각 함수는 두 숫자를 받아 해당하는 산술 연산자를 사용하여 결과를 돌려줍니다.
사용자 입력은 어떻게 받고 숫자로 변환할까요?
`input()` 함수로 문자열을 받고, `float()` 함수로 숫자로 변환하며, 이 과정에서 발생할 수 있는 `ValueError`를 처리해야 합니다. 사용자로부터 입력을 받는 것은 모든 인터랙티브 프로그램의 시작입니다. 파이썬의 `input()` 함수는 사용자로부터 입력받은 모든 것을 문자열로 처리합니다. 따라서 계산에 사용하려면 `int()`나 `float()` 함수를 이용해 숫자형으로 변환해야 합니다. 만약 사용자가 숫자가 아닌 다른 문자를 입력하면 `ValueError`가 발생할 수 있습니다. 이런 상황을 대비하는 것이 안정적인 프로그램을 만드는 첫걸음입니다.
num1_str = input("첫 번째 숫자를 입력하세요: ")
num2_str = input("두 번째 숫자를 입력하세요: ")
operator = input("연산자를 입력하세요(+, -, *, /): ")
사용자에게 첫 번째 숫자, 두 번째 숫자, 그리고 연산자를 각각 입력받습니다. 이 값들은 현재 문자열 형태입니다.
계산 과정에서 발생할 수 있는 오류는 어떻게 처리해야 할까요?
예외 처리는 프로그램이 예기치 않은 상황에서도 중단 없이 실행될 수 있도록 `try-except` 블록을 활용하여 오류를 미리 방지하는 필수적인 기법입니다. 제가 현업에서 자동화 스크립트를 작성할 때, 파일 경로 오류나 데이터 형식 오류 때문에 프로그램이 갑자기 멈추는 상황을 수없이 겪었습니다. 그때마다 `try-except` 블록으로 안전하게 오류를 처리하는 것이 얼마나 중요한지 깨달았습니다. 계산기에서는 주로 숫자가 아닌 입력으로 인한 `ValueError`와 0으로 나누는 `ZeroDivisionError`가 발생할 수 있습니다.
try:
num1 = float(num1_str)
num2 = float(num2_str)
except ValueError:
print("오류: 유효한 숫자를 입력해주세요.")
# 프로그램 종료 또는 다시 입력받기 등의 처리
return # 함수 내에서 예외 발생 시 더 이상 진행하지 않음
if operator == '/':
try:
result = divide(num1, num2)
except ZeroDivisionError:
print("오류: 0으로 나눌 수 없습니다.")
return
위 코드는 숫자를 변환하는 과정에서 `ValueError`가 발생하거나, 나누기 연산 시 `ZeroDivisionError`가 발생했을 때 적절한 오류 메시지를 출력하고 프로그램이 비정상적으로 종료되는 것을 방지합니다. 다양한 예외 유형과 처리 방법을 미리 학습해두면 이런 상황에 유연하게 대처할 수 있습니다.
계산기 전체 프로그램은 어떻게 구성해야 할까요?
사용자에게 지속적으로 연산을 제공하기 위해 반복문을 사용하고, 종료 조건을 명확히 설정하여 프로그램의 흐름을 제어합니다. `while` 반복문과 `if-elif-else` 조건문을 조합하여 사용자가 원하는 연산을 선택하고, ‘exit’ 같은 특정 명령을 입력하면 프로그램이 종료되도록 만들 수 있습니다. 이렇게 하면 한 번 계산하고 끝나는 것이 아니라, 여러 번 연산을 반복할 수 있는 편리한 계산기가 됩니다. 저는 이런 루프 구조를 데이터 분석 스크립트에서도 자주 사용합니다. 예를 들어, 특정 조건이 만족될 때까지 데이터를 계속 처리하는 경우에 유용하죠.
def run_calculator():
while True:
print("\n파이썬 계산기 (종료: 'exit')")
num1_str = input("첫 번째 숫자를 입력하세요: ")
if num1_str.lower() == 'exit':
print("계산기를 종료합니다.")
break
operator = input("연산자를 입력하세요(+, -, *, /): ")
if operator.lower() == 'exit':
print("계산기를 종료합니다.")
break
num2_str = input("두 번째 숫자를 입력하세요: ")
if num2_str.lower() == 'exit':
print("계산기를 종료합니다.")
break
try:
num1 = float(num1_str)
num2 = float(num2_str)
except ValueError:
print("오류: 유효한 숫자를 입력해주세요. 다시 시도하세요.")
continue # 다음 반복으로 넘어감
if operator == '+':
result = add(num1, num2)
elif operator == '-':
result = subtract(num1, num2)
elif operator == '*':
result = multiply(num1, num2)
elif operator == '/':
try:
result = divide(num1, num2)
except ZeroDivisionError:
print("오류: 0으로 나눌 수 없습니다. 다시 시도하세요.
")
continue
else:
print("오류: 지원하지 않는 연산자입니다. 다시 시도하세요.")
continue # 다음 반복으로 넘어감
print(f"결과: {num1} {operator} {num2} = {result}")
# 계산기 실행
if __name__ == "__main__":
run_calculator()
이 코드는 사용자가 ‘exit’를 입력하기 전까지 `while True` 반복문을 통해 계속해서 계산을 수행합니다. 각 입력 단계에서 ‘exit’를 확인할 뿐만 아니라, 숫자 변환 실패나 잘못된 연산자 입력, 0으로 나누는 오류가 발생하면 친절하게 메시지를 출력하고 다음 연산으로 넘어갈 수 있도록 `continue` 키워드를 사용합니다.
완성된 간단한 계산기 코드 살펴보기
지금까지 배운 함수 정의, 사용자 입력 처리, 그리고 예외 처리 기법을 통합하여 실제 동작하는 계산기 프로그램을 완성합니다. 아래 코드는 앞에서 설명한 모든 요소를 결합한 최종 버전입니다. 이 코드를 `calculator.py` 파일로 저장하고 직접 실행해보세요. 제가 처음으로 기능을 통합해서 프로그램을 완성했을 때의 뿌듯함은 지금도 잊을 수 없습니다. 여러분도 이 코드를 통해 그 느낌을 공유하시길 바랍니다.
# calculator.py
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):
"""두 숫자를 나눕니다. 0으로 나누면 ZeroDivisionError를 발생시킵니다."""
if y == 0:
raise ZeroDivisionError("0으로 나눌 수 없습니다.")
return x / y
def run_calculator():
"""사용자로부터 입력을 받아 계산을 수행하는 메인 함수"""
print("""환영합니다! 파이썬 간단 계산기입니다.
종료하려면 언제든지 'exit'를 입력하세요.""")
while True:
try:
num1_str = input("첫 번째 숫자를 입력하세요: ")
if num1_str.lower() == 'exit':
print("계산기를 종료합니다.")
break
num1 = float(num1_str)
operator = input("연산자를 입력하세요(+, -, *, /): ")
if operator.lower() == 'exit':
print("계산기를 종료합니다.")
break
num2_str = input("두 번째 숫자를 입력하세요: ")
if num2_str.lower() == 'exit':
print("계산기를 종료합니다.")
break
num2 = float(num2_str)
result = None # 결과 변수 초기화
if operator == '+':
result = add(num1, num2)
elif operator == '-':
result = subtract(num1, num2)
elif operator == '*':
result = multiply(num1, num2)
elif operator == '/':
result = divide(num1, num2)
else:
print("오류: 지원하지 않는 연산자입니다. 다시 시도해주세요.")
continue # 잘못된 연산자 입력 시 다음 반복으로
print(f"결과: {num1} {operator} {num2} = {result}")
except ValueError:
print("오류: 유효한 숫자를 입력해주세요. 다시 시도해주세요.")
except ZeroDivisionError as e:
print(f"오류: {e} 다시 시도해주세요.")
except Exception as e:
# 예상치 못한 다른 오류를 잡기 위한 일반 예외 처리
print(f"예상치 못한 오류가 발생했습니다: {e} 다시 시도해주세요.")
# 스크립트가 직접 실행될 때만 run_calculator() 함수를 호출합니다.
if __name__ == "__main__":
run_calculator()
흔히 겪는 오류와 해결 팁
사용자 입력 관련 오류(`ValueError`)와 0으로 나누는 오류(`ZeroDivisionError`)는 계산기 프로그램에서 가장 흔하게 발생하는 문제이므로, `try-except` 블록으로 반드시 처리해야 합니다. 제가 수년간 파이썬 코드를 작성하면서 초보 개발자들이 가장 많이 겪는 문제 중 80% 이상이 데이터 타입 불일치나 예상치 못한 입력 값 처리에서 온다고 생각합니다. 이를 방지하기 위한 몇 가지 팁을 드립니다.
- 숫자 입력 오류 (`ValueError`): 사용자가 숫자 대신 ‘a’, ‘hello’ 등을 입력하면 `float()` 변환 시 `ValueError`가 발생합니다. 반드시 `try-except ValueError:`로 감싸서 “유효한 숫자를 입력해주세요.”와 같은 안내 메시지를 보여주는 것이 좋습니다.
- 0으로 나누기 오류 (`ZeroDivisionError`): 어떤 숫자를 0으로 나누려고 할 때 발생합니다. `try-except ZeroDivisionError:`로 처리하여 “0으로 나눌 수 없습니다.”라는 메시지를 표시하고 프로그램이 멈추지 않도록 해야 합니다.
- 잘못된 연산자 입력: ‘+’, ‘-‘, ‘*’, ‘/’ 이외의 문자를 입력했을 때 `if-elif-else` 문의 `else` 블록에서 처리하여 “지원하지 않는 연산자입니다.”라고 안내할 수 있습니다.
이러한 오류들을 미리 예측하고 처리하는 습관은 견고한 프로그램을 만드는 데 필수적입니다.
마치며
이번 챕터에서는 파이썬의 핵심 요소인 함수와 예외 처리를 통합하여 간단하지만 실용적인 계산기 프로그램을 만들어 보았습니다. 단순히 문법을 아는 것을 넘어, 실제 프로그램을 구성하고 사용자의 입력을 처리하며 발생할 수 있는 오류에 대처하는 방법을 익히셨을 겁니다. 이 경험은 앞으로 더 복잡한 프로그램을 개발하는 데 중요한 밑거름이 될 것입니다. 다음 챕터에서는 프로젝트를 마무리하는 과정과 디버깅, 코드 최적화에 대한 팁을 알아보며 여러분의 개발 실력을 더욱 단단하게 만들겠습니다.
자주 묻는 질문 (FAQ)
Q1: `float()` 대신 `int()`를 사용해도 되나요?
A1: 네, 정수만 다루는 계산기를 만들려면 `int()`를 사용해도 됩니다. 하지만 `float()`는 정수와 실수 모두를 처리할 수 있어 더 유연합니다. 예를 들어, ‘5’를 입력해도 `5.0`으로 처리하고, ‘5.5’를 입력해도 오류 없이 처리할 수 있습니다.
Q2: `if __name__ == “__main__”:` 구문은 왜 사용하나요?
A2: 이 구문은 해당 파이썬 스크립트가 직접 실행될 때만 `run_calculator()` 함수를 호출하도록 합니다. 만약 다른 파일에서 이 스크립트를 모듈처럼 불러와 사용할 때는 `run_calculator()`가 자동으로 실행되지 않도록 방지하는 역할을 합니다. 이는 파이썬 코드의 모듈성을 높이는 일반적인 관례입니다.
Q3: 계산기를 계속 반복 실행하려면 어떻게 해야 하나요?
A3: 본문에서 설명한 것처럼 `while True:` 반복문 안에 계산기의 모든 로직을 넣고, 사용자가 특정 키워드(‘exit’ 등)를 입력했을 때 `break` 문을 사용하여 반복문을 빠져나가도록 구현하면 됩니다. 이를 통해 사용자가 원할 때까지 계속 계산기를 사용할 수 있습니다.
Q4: 더 많은 연산자를 추가하려면 어떻게 해야 하나요?
A4: `%` (나머지), `**` (거듭제곱) 등 다른 산술 연산자를 추가하려면, 먼저 해당 연산을 수행하는 새로운 함수를 정의합니다. 그리고 `run_calculator` 함수 내의 `if-elif-else` 조건문에 해당 연산자를 처리하는 `elif` 블록을 추가하여 새로 만든 함수를 호출하도록 구현하면 됩니다.
참고 자료
- [1] Python 공식 튜토리얼 — 오류와 예외 — https://docs.python.org/ko/3/tutorial/errors.html
- [2] Python 공식 튜토리얼 — 제어 흐름 도구와 함수 정의 — https://docs.python.org/ko/3/tutorial/controlflow.html
