ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 파이썬 기초 05 - 미니프로젝트/예외처리
    파이썬/파이썬 기초 2021. 10. 30. 18:03

    유투버 '나도코딩'님 강의 참조

     

     

    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
Designed by Tistory.