whatisthis?

Phython. 파이썬 코딩 기초편-09 본문

WEB STUDY/PHYTHON | BACK-END

Phython. 파이썬 코딩 기초편-09

thisisyjin 2021. 9. 20. 16:23

<Quiz>

 

주어진 코드로 부동산 프로그램을 작성하시오.

 

출력 예시.

총 3대의 매물이 있습니다.

강남 아파트 매매 10억 2010년
마포 오피스텔 전세 5억 2007년
송파 빌라 월세 500/50 2000년
class House:

  # 매물 초기화
  def __init__(self, location, house_type, deal_type, price, year): 
       pass
       
  # 매물 정보 표시 
  def show_detail(self):
      pass

 

___ 내가 작성한 코드 ___

 

class House:
	def __init__(self, location, house_type, deal_type, price, year):
		self.location = location
		self.house_type = house_type
		self.deal_type = deal_type
		self.price = price
		self.year = year

	def show_detail(self):
		print(self.location, self.house_type, self.deal_type, self.price, self.year)

house = []
house1 = House("강남", "아파트", "매매", "10억", "2010년")
house2 = House("마포", "오피스텔", "전세", "5억", "2007년")
house3 = House("송파", "빌라", "월세", "500/50", "2000년")

house.append(house1)
house.append(house2)
house.append(house3)

print("총 {0}대의 매물이 있습니다.".format(len(house)))

for i in house:
	i.show_detail()

 

*** 클래스에 대한 이해가 부족한 것 같다.

 

len()함수

1. String 변수의 길이
2. 리스트 안에있는 개수 카운트

 

 


 

1. 예외처리 (try - except)

= 어떤 에러가 발생했을때 그것을 처리해주는 것.

 

print("나누기 전용 계산기")
num1 = int(input("첫번째 숫자를 입력하시오 : "))
num2 = int(input("두번째 숫자를 입력하시오 : "))
print("{0} / {1} = {2}".format(num1, num2, num1 / num2))
나누기 전용 계산기
첫번째 숫자를 입력하시오 : 30
두번째 숫자를 입력하시오 : 5
30 / 5 = 6.0

 

이때, num1과 num2는 int()형으로 입력받도록 되어있는데

만약 입력값을 string값인 '삼'으로 입력해보면

 

ValueError: invalid literal for int() with base 10: '삼'

 

다음과 같은 에러 문구가 발생한다.

 

 

이때 예외 처리를 이용하면 다음과 같다.

try:
    print("나누기 전용 계산기")
    num1 = int(input("첫번째 숫자를 입력하시오 : "))
    num2 = int(input("두번째 숫자를 입력하시오 : "))
    print("{0} / {1} = {2}".format(num1, num2, num1 / num2))
except ValueError:
    print("Error : 잘못된 값을 입력하였습니다.")

 

try :
   (에러가 나도 중지되지 않는 명령문)

except (에러명) :
   (에러 발생시 실행할 명령문)

 

 

** 추가로, 에러명을 직접 프린트 하고 싶을때는

except ZeroDivisionError as err:
    print(err)

다음과 같이

except (에러명) as err:

     print(err) 을 하면 된다.

 

여기서, err은 일종의 변수와 같이 사용된 것이므로 바꿔도 됨.

 

 

+) 리스트 이용시

 

try:
    print("나누기 전용 계산기")
    nums =[]
    nums.append(int(input("첫번째 숫자를 입력하시오 : ")))
    nums.append(int(input("두번째 숫자를 입력하시오 : ")))
    nums.append(int(nums[0] / nums[1]))

    print("{0} / {1} = {2}".format(nums[0], nums[1], nums[2]))

except ZeroDivisionError as err:
    print(err)

다음과 같이 nums라는 리스트에 첫번째 값과 두번째 값, 그리고 나눈 결과를 저장할 수 있다.

 

만약, 이때 나눈 값인 nums[2]를 까먹고 저장을 안했다면?

 

위와 같이 index 에러가 발생하게 한다.

(즉, 리스트에 없는 값을 참고하려 하므로 에러가 발생)

 

except:                                               

    print("알 수 없는 에러가 발생했습니다.")

 

 

다음과 같이 except만 적어준다면? 모든 종류의 에러에 똑같은 결과가 나온다.

(네임 에러든, value 에러든, zerodivision 에러든간에) 

 

만약, 어떤 에러인지 출력되도록 하려면 위에서와 같이 as 를 이용하면 된다.

 

except Exception as err:
    print(err)

여기서 exception은 예외라는 뜻이다.

** 예외(exception)란 코드를 실행하는 중에 발생한 모든 에러를 뜻합니다. 

 

 


2. 에러 발생시키기

 

의도적으로 에러를 발생시키고, 예외처리 ( try - except ) 로 처리해야 하는 경우에 사용.

 

try:
    print("한 자리 숫자 나누기 전용 계산기")
    num1 = int(input("첫번째 값 : "))
    num2 = int(input("두번째 값 : "))

    if num1 >= 10 or num2 >= 10:
        raise ValueError
    print("{0} / {1} = {2}".format(num1, num2, num1 / num2))

except ValueError:
    print("잘못된 값 입력함. 한자리만 가능.")

 

if문으로 조건을 설정한 후, raise (에러명) 과 같이 입력한다.

예 > raise ValueError

 

 

 


3. 사용자 정의 예외처리

class BigNumberError(Exception): # Exception이라는 클래스를 상속받음
    pass
    

try:
    print("한 자리 숫자 나누기 전용 계산기")
    num1 = int(input("첫번째 값 : "))
    num2 = int(input("두번째 값 : "))

    if num1 >= 10 or num2 >= 10:
        raise BigNumberError
    print("{0} / {1} = {2}".format(num1, num2, num1 / num2))

except ValueError:
    print("잘못된 값 입력함. 한자리만 가능.")

except BigNumberError:
    print("에러가 발생했습니다. 한자리만 입력하세요.")

 

위 예제와 같이  임의의 클래스를 선언한다.

(단, Exception이라는 클래스를 상속받도록)

 

class 클래스명(Exception):

   pass

 

if문에서 조건을 만족할때 raise BigNumberError 이 실행되므로

결과는 ValueError의 프린트문이 아닌

BigNumberError의 프린트문이 나오게 된다.

 

+) 클래스 자체에서 에러메시지가 나오도록 할 수 있다. 

class BigNumberError(Exception): # Exception이라는 클래스를 상속받음
    def __init__(self, msg):
        self.msg = msg

    def __str__(self):
        return self.msg

다음과 같이 init 함수에 msg변수를 추가하고

self.msg = msg로 선언해준다.

 

 

str 함수를 이용하여 return self.msg를 해준다.

 

** __str__함수는 __init__과 마찬가지로 메소드를 나타내며,

객체를 문자열로 표현한 것을 반환해주는 함수이다. 

 

<참고> 클래스 용어 총정리

클래스(class) = 똑같은 무엇인가를 계속해서 만들어낼 수 있는 설계, 틀과 같은 것.
객체(object) =  클래스에 의해서 만들어진 물건, 실체

언더바 2개로 정의된 함수 = 메서드 (method)
** 클래스 내부에 정의된 함수 = 메서드(method)

self = 인스턴스(=객체)를 생성해주기 위한 필수 요소
**인스턴스(객체) = 클래스("입력값")을 통해 만들어진 것.

___

+) 객체 vs 인스턴스
객체는 물건 하나를 , 인스턴스는 객체사이 관계에 초점을 맞출 때 씀. (같은 의미이긴 함)

___

그리고 나서 BigNumberError 클래스의 msg 값을 직접 입력해주면 된다.

 

raise BigNumberError("입력값 {0}, {1}".format(num1, num2))

 

 

 

 

** 주의

 

except문에서 as Err를 사용하여 print(err)를 해줘야만

클래스 내에서 str함수에 의해 msg에 해당하는 내용이 출력된다.

 

except BigNumberError as err:
    print("에러가 발생했습니다. 한자리만 입력하세요.")
    print(err)

 

 

 

즉, 원래 as err를 쓰면 나왔던 결과값은

except Exception as err:
    print(err)

미다음과 같이 무슨에러가 발생했는지였다.

 

그러나, 클래스의 msg를 대신 출력한 것과 같다.

 


4. Finally

try-except 문에서 에러 유무와 상관없이 맨 마지막에 실행되는 finally문.

 

구조> try - except - except … - finally

 

 

finally:
    print("계산기를 이용해주셔서 감사합니다.")

 

 

+) 참고로, 만약 except에서 valueError와 IndexError의 경우를 적어놨을 경우에,

except에 존재하지 않는 ZerodevisionError가 발생하더라도 finally문은 실행이된다!

 

 


 

<Quiz>

동네에 항상 대기손님이 있는 치킨집이 있다.

대기 손님의 요리시간을 줄이고자 자동 주문 시스템을 제작했다.

시스템 코드를 확인하고 적절한 예외처리 구문을 넣으시오.

 

 

<조건>

1.. 1보다 작거나 숫자가 아닌값이 들어올때에는 valueError 로 처리

- 출력 메시지 : 잘못된 값을 입력하였습니다.

 

2. 대기 손님이 주문할 수 있는 총 치킨량은 10마리로 한정

치킨 소진시 사용자 정의 에러 [SoldOutError]를 발생시키고 프로그램 종료

- 출력 메시지 : 재고가 소진되어 더이상 주문을 받지 않습니다.

 

[코드]

chicken = 10
waiting = 1 #대기번호 1부터 시작
while (True):
    print("[남은 치킨 : {0}]".format(chicken))
    order = int(input("치킨 몇마리 드릴까요?"))
    if order > chicken:
        print("재료가 부족합니다.")
    else:
        print("[대기번호 {0}] {1}마리 주문이 완료되었습니다.".format(waiting, order))
        waiting += 1
        chicken -= order