파이썬 기초 05 - 미니프로젝트/예외처리
유투버 '나도코딩'님 강의 참조
01 스타크래프트 미니 프로젝트
from random import *
class Unit: #클래스 선언
def __init__(self, name, hp, speed): #생성자
self.name = name
self.hp = hp
self.speed = speed
print("{0} is ready".format(name))
def move(self, location):
print("Unit is movig")
print("{0} : is heading to {1} [속도 {2}]".format(self.name, location, self.speed))
def damaged(self, damaged):
print("{0} is under attack [{1} damaged]".format(self.name, damaged))
self.hp -= damaged
print("{0} : HP:{1}".format(self.name, self.hp))
if self.hp <= 0:
print("{0} is dead".format(self.name))
class AttackUnit(Unit):
def __init__(self, name, hp, speed, damage): #생성자
Unit.__init__(self, name, hp, speed) #상속받는 클래스에서 파라미터를 받음
self.damage = damage
def attack(self, location):
print("{0} is attacking to {1} location. [Damege {2}]".format(self.name, location, self.damage))
class Marine(AttackUnit):
def __init__(self):
AttackUnit.__init__(self, "Marine", 40, 1, 5)
def stimpack(self):
if self.hp > 10:
self.hp -= 10
print("{0} : Stimpack! (Used 10 HP)".format(self.name))
else:
print("{0} : Not enough HP")
class Tank(AttackUnit):
seize_mode = False
def __init__(self):
AttackUnit.__init__(self,"Tank", 150, 1, 35)
self.seize_mode = False
def set_seize_mode(self):
if Tank.seize_mode == False:
return
if self.seize_mode == False:
print("{0} : on Seize-Mode".format(self.name))
self.damage *= 2
self.seize_mode = True
else:
print("{0} : back to normal".format(self.name))
self.damage /= 2
self.seize_mode = False
class Flyable:
def __init__(self, flying_speed):
self.flying_speed = flying_speed
def fly(self, name, location):
print("{0} is flying to {1}. [Speed {2}]".format(name, location, self.flying_speed))
class FlyableAttackUnit(AttackUnit, Flyable):
def __init__(self, name, hp, damage, flying_speed):
AttackUnit.__init__(self, name, hp, 0, damage)
Flyable.__init__(self, flying_speed)
def move(self, location):
print("Moving")
self.fly(self.name, location)
class Wraith(FlyableAttackUnit):
def __init__(self):
FlyableAttackUnit.__init__(self, "Wraith", 80, 20, 5)
self.clocked = False
def clocking(self):
if self.clocked == True:
print("{0} : back to normal".format(self.name))
self.clocked = False
else:
print("{0} : on Clocking".format(self.name))
self.clocked = True
- 메소드 써보기
def game_start():
print("Game is starting")
def game_over():
print("Player : GG")
print("[Player] left the game")
game_start()
m1 = Marine()
m2 = Marine()
t1 = Tank()
t2 = Tank()
w1 = Wraith()
#유닛 일괄 관리
attack_units = []
attack_units.append(m1)
attack_units.append(m2)
attack_units.append(t1)
attack_units.append(t2)
attack_units.append(w1)
#전군 이동
for unit in attack_units:
unit.move("South")
#시즈모드 개발
Tank.seize_mode = True
print("Seize-Mode upgraded")
#공격 모드
for unit in attack_units:
if isinstance(unit, Marine):
unit.stimpack()
elif isinstance(unit, Tank):
unit.set_seize_mode()
elif isinstance(unit, Wraith):
unit.clocking()
#전군 공격
for unit in attack_units:
unit.attack("South")
#전군 피해
for unit in attack_units:
unit.damaged(randint(5, 20))
#게임 종료
game_over()
Game is starting
Marine is ready
Marine is ready
Tank is ready
Tank is ready
Wraith is ready
Unit is movig
Marine : is heading to South [속도 1]
Unit is movig
Marine : is heading to South [속도 1]
Unit is movig
Tank : is heading to South [속도 1]
Unit is movig
Tank : is heading to South [속도 1]
Moving
Wraith is flying to South. [Speed 5]
Seize-Mode upgraded
Marine : Stimpack! (Used 10 HP)
Marine : Stimpack! (Used 10 HP)
Tank : on Seize-Mode
Tank : on Seize-Mode
Wraith : on Clocking
Marine is attacking to South location. [Damege 5]
Marine is attacking to South location. [Damege 5]
Tank is attacking to South location. [Damege 70]
Tank is attacking to South location. [Damege 70]
Wraith is attacking to South location. [Damege 20]
Marine is under attack [16 damaged]
Marine : HP:14
Marine is under attack [11 damaged]
Marine : HP:19
Tank is under attack [16 damaged]
Tank : HP:134
Tank is under attack [8 damaged]
Tank : HP:142
Wraith is under attack [18 damaged]
Wraith : HP:62
Player : GG
[Player] left the game
퀴즈)
class House:
def __init__(self, location, house_type, deal_type, price, completion_year):
self.location = location
self.house_type = house_type
self.deal_type = deal_type
self.price = price
self.completion_year = completion_year
def show_detail(self):
print(self.location, self.house_type, self.deal_type, self.price, self.completion_year)
houses = []
house1 = House("강남", "아파트", "매매", "10억", "2010년")
house2 = House("마포", "오피스텔", "전세", "5억", "2007년")
house3 = House("송파", "빌라", "월세", "500/50", "2000년")
houses.append(house1)
houses.append(house2)
houses.append(house3)
print("총 {0}대의 매물이 있습니다.".format(len(houses)))
for house in houses:
house.show_detail()
총 3대의 매물이 있습니다.
강남 아파트 매매 10억 2010년
마포 오피스텔 전세 5억 2007년
송파 빌라 월세 500/50 2000년
02 예외처리
- 프로그래밍상에서 에러가 떳을때 처리하는 방법
print("Only to devide")
num1 = int(input("Enter first number -> "))
num2 = int(input("Enter second number -> "))
print("{0} / {1} = {2}".format(num1, num2, int(num1/num2)))
*int(input())인데 스트링을 넣으면 아래와 같은 오류가 뜬다
- 이때 예외처리를 할 수 있다!
try:
print("Only to devide")
num1 = int(input("Enter first number -> "))
num2 = int(input("Enter second number -> "))
print("{0} / {1} = {2}".format(num1, num2, int(num1/num2)))
except ValueError:
print("That is not a correct input")
→ 즉 오류도 종류가 많은데 오류의 종류를 'except'와 함께 선언해주면 개발자가 직접 예외처리를 해 줄 수 있다.
- 0을 입력하면 오류의 종류가 다르다!
try:
print("Only to devide")
num1 = int(input("Enter first number -> "))
num2 = int(input("Enter second number -> "))
print("{0} / {1} = {2}".format(num1, num2, int(num1/num2)))
except ValueError:
print("That is not a correct input")
except ZeroDivisionError as err:
print(err)
- 한번에 모든 예외 처리도 가능하다
except: print("an Error occured")
03 예외 발생 시키기
- 'raise ...' 구문을 써서 어떠한 상황이면 raise 예외종류 를 써서 except로 바로 넘길 수 있다.
try:
print("Only one digit devide")
num1 = int(input("Enter first number -> "))
num2 = int(input("Enter second number -> "))
if num1 >= 10 or num2 >= 10:
raise ValueError
print("{0} / {1} = {2}".format(num1, num2, int(num1/num2)))
except ValueError:
print("Wrong value. Only one digit")
Only one digit devide
Enter first number -> 10
Enter second number -> 5
Wrong value. Only one digit
- 사용자 정의 예외 처리
class BigNumberError(Exception):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return self.msg
try:
print("Only one digit devide")
num1 = int(input("Enter first number -> "))
num2 = int(input("Enter second number -> "))
if num1 >= 10 or num2 >= 10:
raise BigNumberError("입력값 : {0}, {1}".format(num1, num2))
print("{0} / {1} = {2}".format(num1, num2, int(num1/num2)))
except ValueError:
print("Wrong value. Only one digit")
except BigNumberError as err:
print("An error occured. Only one Digit")
print(err)
An error occured. Only one Digit
입력값 : 10, 5
- finally - 예외와 상관없이 무조건 실행하도록 하는 구문 (finally를 쓰면 프로그램이 강제 종료되는것을 막을 수 있음)
finally: print("Thanks for using this!")
퀴즈
조건1) 1보다 작거나 숫자가 아니면 ValueError로 처리
조건2) 치킨이 모두 소준되면 사용자 정의 에러'SoldOutError' 발생 시키고 프로그램 종료
class SoldOutError(Exception):
pass
chicken = 10
waiting = 1
while(True):
try:
print("Left chicken : {0}".format(chicken))
order = int(input("How many chickens do you want -> "))
if order > chicken:
print("No more chickens")
elif order <= 0:
raise ValueError
else:
print("Waiting number [{0}]. {1} chicken(s) ordered.".format(waiting,order))
waiting += 1
chicken -= order
if chicken == 0:
raise SoldOutError
except ValueError:
print("Wrong order")
except SoldOutError:
print("No more chickens")
break