ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 35.6 심사문제: 시간 클래스 만들기
    코딩도장 심사문제모음 2020. 11. 10. 00:34
    728x90

    표준 입력으로 시:분:초 형식의 시간이 입력됩니다. 다음 소스 코드에서 Time 클래스를 완성하여 시, 분, 초가 출력되게 만드세요. from_string은 문자열로 인스턴스를 만드는 메서드이며 is_time_valid는 문자열이 올바른 시간인지 검사하는 메서드입니다. 시간은 24시까지, 분은 59분까지, 초는 60초까지 있어야 합니다. 정답에 코드를 작성할 때는 class Time:에 맞춰서 들여쓰기를 해주세요.

    사용한 코드

    1. @classmethod (클래스 메서드)

    2. map

    3. int

    4. ### cls ###

    5. @staticmethod (정적 메서드)

    6. and (비교 연산자)

    첫 접근 방법

    크게 2가지 메서드를 만들면 해결이 가능한 문제다

    1. 문자열을 인스턴스로 만드는 메서드 (from_string)

    2. 문자열이 올바른지 검사하는 메서드  (is_time_valid)

    2번 의 경우 입력된 문자열이 올바른지 아닌지만 검사하면 되는 메서드로 클래스에 접근할 필요가 없어

         정적 메서드를 사용한다.

    문제는 1번 메서드인데

    아래 호출 함수로 보았을때 1번 2번 모두 인스턴스없이 클래스에서 직접 메서드를 호출 하고 있다.

    결국 클래스메서드 또는 정적 메서드라는 소리이며, __init__ 즉, 클래스의 속성에 접근해야하므로

    클래스 메서드를 사용하면 된다.

    TIL.32 클래스의 속성과 메서드

    < 문제에서의 메서드 호출>
    
    time_string = input()
     
    if Time.is_time_valid(time_string):
        t = Time.from_string(time_string)
        print(t.hour, t.minute, t.second)
    else:
        print('잘못된 시간 형식입니다.')

    ## 여기서 문제를 푸는데 제일 중요한 부분이 나오는데, 바로

    입력된 time_string을 문자열로 바꾼후 인스턴스를 생성해줘야한다.

    흔히 사용하던 james = Person() 이 아닌, 메서드 안에서 인스턴스를 생성해줘야한다는 것이다.

    이부분을 알지 못하면 풀수 없는 문제로 생각되며, 또 힌트를 봐야만했다.

    갈수록 어려워지고 있는데, 아주 좋다

    나머지는 풀이에서 알아보도록 하자

    풀이

    Time 클래스를 생성하고 hour, minute, second 는 인스턴스 속성으로 만들어져 있다.

    class Time:
        def __init__(self, hour, minute, second):
            self.hour = hour
            self.minute = minute
            self.second = second

    ## 사실 메서드의 순서가 크게 의미가 있느지는 모르겠지만 메서드 1, 2를 뒤바꿔도 결과는 같다 참고하자.

    ## 문제에서의 메서드 호출에 맞추어 정적 메서드부터 풀이해보자

    < 문제에서의 메서드 호출>
    
    time_string = input()
     
    if Time.is_time_valid(time_string):
        t = Time.from_string(time_string)
        print(t.hour, t.minute, t.second)
    else:
        print('잘못된 시간 형식입니다.')

     

    is_time_valid 라는 메서드는 앞서 말한바와 같이 정적 메서드로 만들어준다.(올바른지 검사하는 메서드)

    정적 메서드이므로 self 또는 cls로 받을 필요가없다 (클래스 속성 및 인스턴스 속성에 접근하지 않기 때문이다.)

    입력되는 23:35:59 라는 time_string을 매개변수로 받고 

    map 객체 언패킹을 이용해 각 함수에 값을 할당해준다.

    hour, minute, second = map(int, time_string.split(':'))
    ## 23:35:59 --> 23, 35, 59 --> map 객체 (리스트  x)

    앞서 연습문제에서 했던것 처럼 비교 연사자의 값을 이용해 True 인지 False인지 검사해주면 된다.

    여기서는 0을 포함해도 문제가 없으므로 최대값만 and 연산자를 이용해 조건을 걸어주었다.(모두 True 여야 True)

        @staticmethod     # 정적 메서드 
        def is_time_valid(time_string):
            hour, minute, second = map(int, time_string.split(':'))
            return hour < 25 and minute < 61 and second <61  # 결과에 따라 T, F

    이렇게 하면 아래의 if 문에서 True가 되어 아래 코드를 실행한다.

    < 문제에서의 메서드 호출>
    
    time_string = input()
     
    if Time.is_time_valid(time_string):
        t = Time.from_string(time_string)
        print(t.hour, t.minute, t.second)
    else:
        print('잘못된 시간 형식입니다.')

    ### 문제 풀이 핵심 구간 ###

    두번째 메서드

    from_string이라는 클래스메서드를 만들어줘여하는데,

    해당 메서드는 입력받은 문자열로 인스턴스를 만들어주는 메서드여야 한다.

    첫번째 매개변수는 반드시 cls , 입력되는 문자열 23:35:59는 매개변수로 받고,map을 이용한 언패킹으로 각 변수에 할당하면 된다.(이부분은 어렵지않다)

        @classmethod
        def from_string(cls, time_string):
            hour, minute, second = map(int, time_string.split(':'))
            
            ## 23:35:42 --> 23, 35, 59 --> map 객체임 (리스트 x)

    그럼 hour == 23, minute == 35, second == 59 각 변수에 할당이 된다.

    < 문제에서의 메서드 호출>
    
        t = Time.from_string(time_string)
        print(t.hour, t.minute, t.second)

    위에서 보면 Time 클래스from_string 메서드 time_string이라는 값을 넣었을때 반환되는 값을 

    t 라는 인스턴스를 생성하여 (인스턴스.속성) 형식으로 출력해야한다.

        t = Time.from_string(time_string)

     

    ## 여기서 ## 아래와 같이 메서드 안에서 클래스의 인스턴스를 만들 수 있다는 점을

        알지 못하면 풀 수 있을까? 하는 의문이 든다.

    ## 즉, cls() 를 이용하여 할당되어 있는 값들을 이용해 클래스의 인스턴스로 만들어줘야한다.###

    만들어준 인스턴스를 반환하여 위의 호출코드를 생각한다면

     time이라는 인스턴스를 t에 다시 재할당하는것이 아닐까 생각한다.

    t = Time 안의 from_string 안의 time ( map 객체 의 23, 35, 59)?

        @classmethod
        def from_string(cls, time_string):
            hour, minute, second = map(int, time_string.split(':'))
            time = cls(hour, minute, second) # cls == Time(클래스) 로 바꿔도 정상동작
            return time

    여기서 cls == 클래스 이므로, 클래스 Time을 넣어도 정상 동작 한다.

    class Time:
        def __init__(self, hour, minute, second):
            self.hour = hour
            self.minute = minute
            self.second = second
    
        @classmethod
        def from_string(cls, time_string):
            hour, minute, second = map(int, time_string.split(':'))
            time = cls(hour, minute, second)
            return time
    
        @staticmethod    
        def is_time_valid(time_string):
            hour, minute, second = map(int, time_string.split(':'))
            return hour < 25 and minute < 61 and second <61 
    
    
    time_string = input()
    
    
    if Time.is_time_valid(time_string):
        t = Time.from_string(time_string)
        print(t.hour, t.minute, t.second)
    else:
        print('잘못된 시간 형식입니다.')

    ### map 객체에서도 언패킹이 된다는 사실

    ### 메서드 안에서 클래스 인스턴스를 생성하는 cls이 있다는 사실

    ### return 값을 이용하여 불필요한 if문을 줄일 수 있다는 사실

    ### 해당 문제를 통해 각 메서드를 어떻게 출력하는지 if ~ else 구문도 꼭 참고하도록 하자

    ※ 실제 코딩 도장의 해법과 다를  수 있으며, 답은 여러가지가 존재합니다.

    코드 지적 정말 감사히 받겠습니다.

    728x90
Designed by Tistory.