본문 바로가기

Personal Study

멘토씨리즈 Python 예제풀이 / Ch9. 파이썬의 예외처리

 

 

Chapter 8. 파이썬의 예외처리

 

section17. 예외처리

 

기본예제1 

다음은 사용자가 입력한 키를 정수로 반올림하여 다시 저장하는 프로그램입니다. 

일부러 예외가 발생하도록 구현하였으니 어떤 부분에서 예외가 발생하는지 찾아보세요.

<실행 예>

키를 입력하세요 >>> 175.5

예외가 발생했습니다.


try:
    height = input('키를 입력하세요')
    height = round(height)
    print('입력하신 키는 {}cm로 처리됩니다.'.format(height))
except:
    print('예외가 발생했습니다.')
>> height = float(input('키를 입력하세요')) 로 수정해야 예외가 발생하지 않음



기본예제2

다음은 사용자가 입력한 파일을 읽어서 화면에 그대로 출력하는 프로그램입니다.

만약 사용자가 입력한 파일이 존재하지 않는다면 예외처리를 통해서 해당 파일이 존재하지 않는다는

예외 메시지를 화면에 출력합니다. 웹하드에서 sample.txt 파일을 다운로드 받은 뒤 실행합니다.
<실행 예>

열고자 하는 파일명을 입력하세요 >>> abc.txt

abc.txt파일이 존재하지 않습니다.

프로그램을 종료합니다.

=====================================

열고자 하는 파일명을 입력하세요 >>> sample.txt

Hello Python!

Nice to meet you!

프로그램을 종료합니다.


try:
    filename = input('열고자 하는 파일명을 입력하세요.')
    file = open(filename, 'rt')
except FileNotFoundError:
    print('{}파일이 존재하지 않습니다.'.format(filename))
else:
    buffer = file.read()
    print(buffer, end="")
    print()
    file.close()
finally:
    print('프로그램을 종료합니다.')

 

기본예제3

사용자의 점수를 0부터 100사이로 입력받아서 점수가 80점 이상이면 '합격', 아니면 '불합격'을 출력하는

프로그램입니다. 입력된 점수가 0~100사이의 유효값이 아니라면 예외를 발생시키고,

'점수는 0~100사이입니다'라는 예외 메시지를 출력합니다.
<실행 예>

점수를 입력하세요 >>> -5

점수는 0~100 사이입니다.

====================================

점수를 입력하세요 >>> 85

85점은 합격입니다.


try:
    score = int(input('점수를 입력하세요'))
    if score <0 or score > 100:
        raise Exception('점수는 0에서 100사이입니다.')
except Exception as e:
    print(e)
else:
    if score >= 80:
        print('합격')
    else:
        print('불합격')



기본예제4

입력받은 이름이 2~6자가 아니면 NameError 예외를 발생시키고 '이름은 2~6자 사이로 입력해주세요'라는

예외 메시지를 출력하는 프로그램입니다.
<실행 예>

이름을 입력하세요 >>> 나

이름은 2~6자 사이로 입력해 주세요.

================================

이름을 입력하세요 >>> 이정숙

입력된 이름은 이정숙입니다.


class NameError(Exception):
    def __init__(self, message):
        super().__init__(message)
try:
    name = input('이름을 입력해주세요')
    if len(name)<=1 or len(name)>=7:
        raise NameError('이름은 2~6자로 입력해주세요')
except NameError as e:
    print(e)
else:
    print('입력된 이름은 {}입니다.'.format(name))

 

응용예제1

다음 지시사항을 읽고 우리나라의 모든 도를 맞히는 퀴즈를 진행할 수 있는 Quiz 클래스를 구현하세요.
  지시사항:
  1. Quiz 클래스는 다음과 같은 클래스 변수를 갖고있습니다.
      answer = ['경기도', '강원도', '충청남도', '충청북도', '전라남도', '전라북도', '경상남도', '경상북도', '제주특별자치도']
  2. challenge() 메소드는 사용자의 입력을 처리하고 일치하는 정답이 있으면 '정답입니다'를 출력한 뒤 해당 정답을 answer에서 제거함. 그리고 다시 challenge() 메소드를 호출합니다.
  3. challenge() 메소드는 사용자의 입력이 틀린경우 '틀렸습니다'라는 예외 메시지를 출력할 수 있도록 예외를 발생시킴.
  4. Quiz 클래스의 동작은 다음과 같은 코드로 진행합니다.(아래 참고)
  5. 정답을 모두 맞히면 다음과 같은 메시지를 출력합니다.
<실행 예>

우리나라의 9개 모든 도를 맞히는 퀴즈입니다. 하나씩 대답하세요.

정답은? >>> 경기도

정답입니다.

정답은? >>> 울릉도

틀렸습니다.


answer = ['경기도', '강원도', '충청남도', '충청북도', '전라남도', '전라북도', '경상남도', '경상북도', '제주특별자치도']
class Quiz(Exception):
    def __init__(self, message):
        super().__init__(message)
try:
    while True:
        name = input('도를 입력하세요')
        if name in answer:
            print('정답입니다.')
            answer.remove(name)
            continue
        elif name not in answer:
            raise Quiz('틀렸습니다.')
        elif len(answer) == 0: 
            break
except Quiz as e:
    print(e)
else:
    print('모든 도를 맞혔습니다. 성공입니다.')



응용예제2

다음 지시사항을 읽고 컴퓨터가 생성한 난수를 맞히는 UpDown 게임을 실행하는 UpDown 클래스를

구현하세요.
  지시사항:
  1. UpDown 클래스의 인스턴스를 생성하면 1~100사이의 난수가 인스턴스 변수 answer에 저장됩니다. 인스턴스 생성 후에는 play() 메소드만 호출합니다.
  2. challenge() 메소드는 사용자의 입력을 처리합니다. 유효하지 않은 정숫값을 입력하면 예외를 발생시키고 '1~100 사이만 입력하세요'라는 예외 메시지를 출력합니다.
  3. challenge() 메소드가 호출될때마다 인스턴스 변수 count가 1씩 증가합니다. 최종적으로 count 변숫값으로 몇번의 시도 끝에 성공했는지 알 수 있습니다.
  4. 생성된 난수를 맞히기 전에는 프로그램이 종료되지 않습니다.
  5. 정수 대신 다른 자료형의 값은 입력되지 않는다고 가정합니다.
<실행 예>

입력(1~100) >>> 200

1~100 사이만 입력하세요.

입력(1~100) >>> 50

Down!

입력(1~100) >>> 25

Down!

입력(1~100) >>> 12

Up!

입력(1~100) >>> 20

Down!

입력(1~100) >>> 15

Up!

입력(1~100) >>> 18

Down!

입력(1~100) >>> 16

8번 만의 정답입니다.


import random
class UpDown(Exception):
    def __init__(self, message):
        super().__init__(message)
try:
    count=0
    answer = random.randint(1,100)
    while True:
        number = int(input('입력(1~100)'))
        if number < 1 or number > 100:
            raise UpDown('1~100 사이의 숫자만 입력하세요')
        if answer > number:
            print('Up!')
            count += 1
            continue
        elif answer < number:
            print('Down!')
            count += 1
            continue
        elif answer == number:
            print('정답입니다.')
            count += 1
            print('{}번 만의 정답입니다.'.format(count))
            break
except UpDown as e:
    print(e)
else:
    print('예외가 발생하지 않았습니다.')



응용예제3

다음 지시사항을 읽고 입금, 출금, 이체, 조회 기능이 있는 BankAccount 클래스를 구현하고, 

추가로 예외상황을 처리할 수 있는 BankError 예외 클래스를 구현하세요.
  지시사항:
  1. BankAccount 클래스
      1. 인스턴스 변수: 계좌번호 acc_no, 통장 잔액 balance
      2. 생성자: 매개변수 acc_no, balance 
      3. 입금기능: 메소드명 deposit, 매개변수 money, 반환값 없음, 예외상황 0원이하를 입금하려할때
      4. 출금기능: 메소드명 withdraw, 매개변수 money, 반환값 실제로출금된금액, 예외상황 0원이하를 출금하려고 할때 및 통장잔액보다 큰 금액을 출금하려 할 때
      5. 이체기능: 메소드명 transfer, 매개변수 your_acc money, 반환값 없음
      6. 조회기능: 메소드명 inquiry, 매개변수 없음, 반환값 없음, 기능 계좌번호와 통장잔액을 화면에 출력
  예외사항:
  1. 마이너스 금액 입금
  2. 마이너스 금액 출금
  3. 통장잔액보다 큰 금액 출금
  정상상황:
  입금, 출금을 모두 확인할 수 있는 정상이체


class BankError(Exception):
    def __init__(self, message):
        super().__init__(message)
class BankAccount(BankError):
    balance = 0
    def __init__(self, acc_no, balance):
        self.acc_no = acc_no
        self.balance = balance
    def deposit(self, money):
        try:
            if money <= 0:
                raise BankError('0원 이하는 입금되지 않습니다.')
            self.balance += money
        except BankError as e:
            print(e)
    def withdraw(self, money):
        try:
            if money <= 0:
                raise BankError('0원 이하는 출금되지 않습니다.')
            if money > self.balance:
                raise BankError('통장 잔액보다 큰 금액을 출금할 수 없습니다.')
            self.balance -= money
        except BankError as e:
            print(e)
    def transfer(self, your_acc, money):
        try:
            if money <= 0:
                raise BankError('0원 이하는 이체되지 않습니다.')
            if money > self.balance:
                raise BankError('통장 잔액보다 큰 금액을 이체할 수 없습니다.')
            self.balance -= money
            your_acc.balance += money
        except BankError as e:
            print(e)
    def inquiry(self):
        print('계좌번호:{}, 통장잔액:{}'.format(self.acc_no, self.balance))