소개
이 랩에서는 Python 에서 간단한 함수의 정의를 검토하고 예외 처리 (exception handling) 를 탐구하는 방법을 배우게 됩니다. 함수는 코드를 재사용 가능한 세그먼트로 구조화할 수 있게 해주는 핵심 프로그래밍 개념입니다. 반면에 예외 처리는 프로그램에서 오류와 예상치 못한 상황을 처리하는 방법입니다.
이 랩의 주요 목표는 간단한 함수를 정의하는 과정을 검토하고 Python 에서 예외 처리에 대해 배우는 것입니다. 수정될 파일은 pcost.py입니다.
함수 정의하기
이 단계에서는 함수를 만드는 방법을 배우겠습니다. Python 에서 함수는 단일 관련 작업을 수행하는 데 사용되는, 구성되고 재사용 가능한 코드 블록입니다. 여기서는 함수가 파일에서 포트폴리오 데이터를 읽고 총 비용을 계산합니다. 이 함수가 있으면 다양한 포트폴리오 파일에 대해 여러 번 사용할 수 있으므로 동일한 코드를 반복해서 작성할 필요가 없으므로 유용합니다.
문제 이해하기
이전 랩에서 포트폴리오 데이터를 읽고 총 비용을 계산하는 코드를 작성했을 수 있습니다. 그러나 해당 코드는 쉽게 재사용할 수 없는 방식으로 작성되었을 것입니다. 이제 해당 코드를 재사용 가능한 함수로 변환할 것입니다.
포트폴리오 데이터 파일은 특정 형식을 가지고 있습니다. "Symbol Shares Price" 형식으로 정보를 포함합니다. 파일의 각 줄은 주식 보유를 나타냅니다. 예를 들어, portfolio.dat라는 파일에서 다음과 같은 줄을 볼 수 있습니다.
AA 100 32.20
IBM 50 91.10
...
여기서 첫 번째 부분 ("AA" 또는 "IBM"과 같은) 은 주식 기호 (stock symbol) 이며, 주식의 고유 식별자입니다. 두 번째 부분은 해당 주식의 보유 주식 수이고, 세 번째 부분은 주당 가격입니다.
함수 만들기
/home/labex/project 디렉토리에 pcost.py라는 Python 파일을 만들어 보겠습니다. 이 파일에는 함수가 포함됩니다. 다음은 pcost.py 파일에 넣을 코드입니다.
def portfolio_cost(filename):
"""
Computes the total cost (shares*price) of a portfolio file
Args:
filename: The name of the portfolio file
Returns:
The total cost of the portfolio as a float
"""
total_cost = 0.0
## Open the file and read through each line
with open(filename, 'r') as f:
for line in f:
fields = line.split()
## Extract the data (symbol, shares, price)
shares = int(fields[1])
price = float(fields[2])
## Add the cost to our running total
total_cost += shares * price
return total_cost
## Call the function with the portfolio.dat file
if __name__ == '__main__':
cost = portfolio_cost('/home/labex/project/portfolio.dat')
print(cost)
이 코드에서 먼저 filename을 인수로 사용하는 portfolio_cost라는 함수를 정의합니다. 함수 내부에서 total_cost 변수를 0.0 으로 초기화합니다. 그런 다음 읽기 모드 ('r') 로 open 함수를 사용하여 파일을 엽니다. for 루프를 사용하여 파일의 각 줄을 반복합니다. 각 줄에 대해 split() 메서드를 사용하여 필드로 분할합니다. 그런 다음 주식 수를 추출하여 정수로 변환하고 가격을 추출하여 부동 소수점으로 변환합니다. 주식 수에 가격을 곱하여 해당 주식 보유에 대한 비용을 계산하고 이를 total_cost에 추가합니다. 마지막으로 total_cost를 반환합니다.
if __name__ == '__main__': 부분은 스크립트가 직접 실행될 때 함수를 호출하는 데 사용됩니다. portfolio.dat 파일의 경로를 함수에 전달하고 결과를 출력합니다.
함수 테스트하기
이제 프로그램이 제대로 작동하는지 확인하기 위해 실행해 보겠습니다. pcost.py 파일이 있는 디렉토리로 이동한 다음 Python 스크립트를 실행해야 합니다. 다음은 그렇게 하기 위한 명령입니다.
cd /home/labex/project
python3 pcost.py
이러한 명령을 실행하면 다음 출력이 표시됩니다.
44671.15
이 출력은 포트폴리오의 모든 주식의 총 비용을 나타냅니다.
코드 이해하기
함수가 수행하는 작업을 단계별로 살펴보겠습니다.
filename을 입력 매개변수로 사용합니다. 이를 통해 다른 포트폴리오 파일로 함수를 사용할 수 있습니다.- 파일을 열고 줄 단위로 읽습니다. 이는
open함수와for루프를 사용하여 수행됩니다. - 각 줄에 대해
split()메서드를 사용하여 줄을 필드로 분할합니다. 이 메서드는 공백을 기준으로 줄을 문자열 목록으로 분할합니다. - 주식 수를 정수로 변환하고 가격을 부동 소수점으로 변환합니다. 파일에서 읽은 데이터가 문자열 형식이고 산술 연산을 수행해야 하므로 필요합니다.
- 각 주식 보유에 대한 비용 (주식 * 가격) 을 계산하고 이를 실행 중인 총계에 추가합니다. 이렇게 하면 포트폴리오의 총 비용이 계산됩니다.
- 최종 총 비용을 반환합니다. 이를 통해 필요한 경우 프로그램의 다른 부분에서 결과를 사용할 수 있습니다.
이 함수는 이제 재사용 가능합니다. 다른 포트폴리오 파일로 호출하여 비용을 계산할 수 있으므로 코드를 더 효율적으로 유지 관리할 수 있습니다.
오류 처리 추가하기
실제 데이터를 사용할 때는 불일치 또는 오류가 발생하는 경우가 매우 흔합니다. 예를 들어, 데이터에 누락된 값, 잘못된 형식 또는 기타 문제가 있을 수 있습니다. Python 은 이러한 상황을 적절하게 처리하기 위해 예외 처리 메커니즘을 제공합니다. 예외 처리를 사용하면 프로그램이 갑자기 중단되는 대신 오류가 발생하더라도 계속 실행될 수 있습니다.
문제 이해하기
portfolio3.dat 파일을 살펴보겠습니다. 이 파일에는 주식 기호, 주식 수, 주당 가격과 같은 포트폴리오에 대한 일부 데이터가 포함되어 있습니다. 이 파일의 내용을 보려면 다음 명령을 사용할 수 있습니다.
cat /home/labex/project/portfolio3.dat
이 명령을 실행하면 파일의 일부 줄에 주식 수 대신 대시 (-) 가 있는 것을 알 수 있습니다. 다음은 표시될 수 있는 예입니다.
AA 100 32.20
IBM 50 91.10
C - 53.08
...
이 파일에서 현재 코드를 실행하려고 하면 충돌이 발생합니다. 그 이유는 코드에서 주식 수를 정수로 변환하려고 하지만 대시 (-) 를 정수로 변환할 수 없기 때문입니다. 코드를 실행하고 어떤 일이 발생하는지 살펴보겠습니다.
python3 -c "import sys; sys.path.append('/home/labex/project'); from pcost import portfolio_cost; print(portfolio_cost('/home/labex/project/portfolio3.dat'))"
다음과 같은 오류 메시지가 표시됩니다.
ValueError: invalid literal for int() with base 10: '-'
이 오류는 Python 이 int(fields[1])을 실행하려고 할 때 - 문자를 정수로 변환할 수 없기 때문에 발생합니다.
예외 처리 소개
Python 의 예외 처리는 try 및 except 블록을 사용합니다. try 블록에는 예외를 발생시킬 수 있는 코드가 포함되어 있습니다. 예외는 프로그램 실행 중에 발생하는 오류입니다. except 블록에는 try 블록에서 예외가 발생할 경우 실행될 코드가 포함되어 있습니다.
try 및 except 블록이 작동하는 방식의 예는 다음과 같습니다.
try:
## Code that might raise an exception
result = risky_operation()
except ExceptionType as e:
## Code to handle the exception
print(f"An error occurred: {e}")
Python 이 try 블록의 코드를 실행할 때 예외가 발생하면 실행이 즉시 일치하는 except 블록으로 이동합니다. except 블록의 ExceptionType은 처리하려는 예외 유형을 지정합니다. 변수 e에는 오류 메시지와 같은 예외에 대한 정보가 포함되어 있습니다.
예외 처리를 사용하여 함수 수정하기
데이터의 오류를 처리하도록 pcost.py 파일을 업데이트해 보겠습니다. try 및 except 블록을 사용하여 잘못된 데이터가 있는 줄을 건너뛰고 경고 메시지를 표시합니다.
def portfolio_cost(filename):
"""
Computes the total cost (shares*price) of a portfolio file
Handles lines with bad data by skipping them and showing a warning.
Args:
filename: The name of the portfolio file
Returns:
The total cost of the portfolio as a float
"""
total_cost = 0.0
## Open the file and read through each line
with open(filename, 'r') as f:
for line in f:
fields = line.split()
try:
## Extract the data (symbol, shares, price)
shares = int(fields[1])
price = float(fields[2])
## Add the cost to our running total
total_cost += shares * price
except ValueError as e:
## Print a warning for lines that can't be parsed
print(f"Couldn't parse: '{line}'")
print(f"Reason: {e}")
return total_cost
## Call the function with the portfolio3.dat file
if __name__ == '__main__':
cost = portfolio_cost('/home/labex/project/portfolio3.dat')
print(cost)
이 업데이트된 코드에서는 먼저 파일을 열고 줄 단위로 읽습니다. 각 줄에 대해 필드로 분할합니다. 그런 다음 주식 수를 정수로, 가격을 부동 소수점으로 변환하려고 시도합니다. 이 변환이 실패하면 (즉, ValueError가 발생하면) 경고 메시지를 출력하고 해당 줄을 건너뜁니다. 그렇지 않으면 주식 비용을 계산하여 총 비용에 추가합니다.
업데이트된 함수 테스트하기
이제 문제가 있는 파일로 업데이트된 프로그램을 실행해 보겠습니다. 먼저 프로젝트 디렉토리로 이동한 다음 Python 스크립트를 실행할 수 있습니다.
cd /home/labex/project
python3 pcost.py
다음과 같은 출력이 표시됩니다.
Couldn't parse: 'C - 53.08
'
Reason: invalid literal for int() with base 10: '-'
Couldn't parse: 'DIS - 34.20
'
Reason: invalid literal for int() with base 10: '-'
44671.15
이제 프로그램은 다음을 수행합니다.
- 파일의 각 줄을 처리하려고 시도합니다.
- 줄에 잘못된 데이터가 포함된 경우
ValueError를 catch 합니다. - 문제에 대한 유용한 메시지를 출력합니다.
- 파일의 나머지 부분을 계속 처리합니다.
- 유효한 줄을 기반으로 총 비용을 반환합니다.
이 접근 방식을 사용하면 불완전한 데이터를 처리할 때 프로그램이 훨씬 더 강력해집니다. 오류를 적절하게 처리하고 여전히 유용한 결과를 제공할 수 있습니다.
대화형 실험
Python 은 코드를 즉시 실행할 수 있는 대화형 모드를 제공합니다. 이는 코드를 테스트하고 새로운 것을 시도하는 데 매우 유용합니다. 이 단계에서는 Python 인터프리터에서 직접 함수를 호출하는 방법을 배우겠습니다.
대화형 모드에서 Python 실행하기
Python 스크립트를 실행한 다음 대화형 모드로 들어가려면 -i 플래그를 사용할 수 있습니다. 이 플래그는 스크립트를 실행한 후 Python 이 대화형 상태를 유지하도록 지시합니다. 방법은 다음과 같습니다.
cd /home/labex/project
python3 -i pcost.py
이 명령이 수행하는 작업을 자세히 살펴보겠습니다.
- 먼저
cd /home/labex/project는 현재 디렉토리를/home/labex/project로 변경합니다. 여기는pcost.py스크립트가 있는 곳입니다. - 그런 다음
python3 -i pcost.py는pcost.py스크립트를 실행합니다. 스크립트 실행이 완료되면 Python 은 대화형 모드에 유지됩니다. - 대화형 모드에서는 Python 명령을 터미널에 직접 입력할 수 있습니다.
명령을 실행하면 pcost.py 스크립트의 출력이 표시되고 Python 프롬프트 (>>>) 가 표시됩니다. 이 프롬프트는 이제 Python 명령을 입력할 수 있음을 나타냅니다.
대화형으로 함수 호출하기
대화형 모드에 들어가면 다른 파일 이름으로 portfolio_cost() 함수를 호출할 수 있습니다. 이를 통해 다양한 입력에 대한 함수의 동작을 확인할 수 있습니다. 다음은 예입니다.
>>> portfolio_cost('/home/labex/project/portfolio.dat')
44671.15
>>> portfolio_cost('/home/labex/project/portfolio2.dat')
19908.75
>>> portfolio_cost('/home/labex/project/portfolio3.dat')
Couldn't parse: 'C - 53.08
'
Reason: invalid literal for int() with base 10: '-'
Couldn't parse: 'DIS - 34.20
'
Reason: invalid literal for int() with base 10: '-'
44671.15
이 대화형 방식을 사용하면 다음을 수행할 수 있습니다.
- 함수가 예상대로 작동하는지 확인하기 위해 다른 입력으로 함수를 테스트합니다.
- 다양한 조건에서 함수의 동작을 실험합니다.
- 함수 호출의 즉각적인 결과를 확인하여 즉석에서 코드를 디버깅합니다.
대화형 모드의 장점
대화형 모드에는 몇 가지 장점이 있습니다.
- 전체 스크립트를 매번 실행하지 않고도 다양한 시나리오를 빠르게 테스트할 수 있습니다.
- 변수 및 표현식 결과를 즉시 검사할 수 있으므로 코드에서 무슨 일이 일어나고 있는지 이해하는 데 도움이 됩니다.
- 전체 프로그램을 만들지 않고도 작은 코드 조각을 테스트할 수 있습니다. 이는 학습하고 새로운 아이디어를 시도하는 데 좋습니다.
- 즉각적인 피드백을 받기 때문에 Python 을 배우고 실험하는 훌륭한 방법입니다.
대화형 모드 종료하기
실험을 마치면 두 가지 방법으로 대화형 모드를 종료할 수 있습니다.
exit()를 입력하고 Enter 키를 누릅니다. 이는 대화형 세션을 종료하는 간단한 방법입니다.- Ctrl+D 를 누릅니다 (Unix/Linux 에서). 이는 대화형 모드를 종료하는 바로 가기이기도 합니다.
Python 프로그래밍 여정 전반에 걸쳐 함수를 정의하고 대화형으로 테스트하는 기술은 개발 및 디버깅에 매우 유용합니다. 이를 통해 코드를 빠르게 반복하고 문제를 찾아 수정할 수 있습니다.
요약
이 Lab 에서 몇 가지 주요 Python 프로그래밍 개념을 배웠습니다. 첫째, 코드를 재사용 가능하게 만드는 함수를 정의하고 사용하는 방법을 배웠습니다. 둘째, 예외 처리 (exception handling) 를 구현하여 프로그램의 견고성을 향상시키는 방법을 익혔습니다. 마지막으로, 테스트 및 실험을 위해 Python 을 대화형 모드 (interactive mode) 로 사용하는 방법을 배웠습니다.
이러한 기술은 안정적인 Python 프로그램을 작성하는 데 필수적입니다. 함수는 코드를 구성하고 재사용하는 데 도움이 되며, 예외 처리는 예상치 못한 상황을 적절하게 처리할 수 있게 해주고, 대화형 모드는 테스트 및 디버깅을 위한 강력한 환경을 제공합니다. Python 학습을 진행하면서 이러한 개념은 더 크고 복잡한 애플리케이션을 개발하는 데 점점 더 가치 있게 될 것입니다.