[코딩 도전] 일본의 연호 계산_보수하기

지난 포스트에서 반영하지 못한 점을 반영하자!


윤년 반영하기

윤년을 반영하는 것은 생각보다 쉬웠다.

생각해보니 백준알고리즘에도 윤년을 구하는 문제가 있었다.

def leap_year(year):
    if year % 4 == 0:
        if year % 100 == 0:
            if year % 400 == 0:
                return True
            else:
                return False
        else:
            return True
    else:
        return False
  • 4의 배수가 아닌 경우 : 윤년이 아님.
  • 4의 배수이기만 한 경우 : 윤년임.
  • 4의 배수이고 100의 배수이며 400의 배수가 아닌 경우 : 윤년이 아님.
  • 4의 배수인 경우 : 윤년임.

위 논리를 적용해서 코드를 짜면 되는 것이었다.

30, 31일 반영하기

이것도 생각보다 쉬웠다.

input_year = random.randint(1900,2023)
input_month = random.randint(1, 13)

if input_month in [1, 3, 5, 7, 8, 10, 12]:
    input_day = random.randint(1, 32)

elif input_month in [4, 6, 9, 11]:
    input_day = random.randint(1, 31)

elif input_month == 2:
    if leap_year:
        input_day = random.randint(1, 30)
    else:
        input_day = random.randint(1, 29)

년도를 구하고 30일이 말일인 월, 31일이 말일인 월 끼리 리스트를 만들고 2월은 윤년 여부에 따라 날짜가 달라지니 위와 같이 논리를 적용하면 되는 것이었다.

1차 완성 코드

def leap_year(year):
    if year % 4 == 0:
        if year % 100 == 0:
            if year % 400 == 0:
                return True
            else:
                return False
        else:
            return True
    else:
        return False

def print_year(A, num):
    if A == 'M':
        B = '메이지'
    elif A == 'D':
        B = '다이쇼'
    elif A == 'S':
        B = '쇼와'
    elif A == 'H':
        B = '헤이세이'
    elif A == 'R':
        B = '레이와'
    
    if num == 1:
        C = '원'
    else:
        C = str(num)
    
    print(B, C+'년')
    
    return

from datetime import datetime
import random

input_year = random.randint(1900,2023)
input_month = random.randint(1, 13)

if input_month in [1, 3, 5, 7, 8, 10, 12]:
    input_day = random.randint(1, 32)

elif input_month in [4, 6, 9, 11]:
    input_day = random.randint(1, 31)

elif input_month == 2:
    if leap_year:
        input_day = random.randint(1, 30)
    else:
        input_day = random.randint(1, 29)


# input_Date = list(map(int, input().split()))

now = datetime.now()

now_YMD = [now.year, now.month, now.day, now.year - 2019 + 1]

data_to_compare = [input_year, input_month, input_day]
# data_to_compare = [input_Date[0], input_Date[1], input_Date[2]]

print(data_to_compare)

# 데이터 베이스 : [개막년, 개막월, 개막일, 년도], [종막년, 종막월, 종막일, 종막시 년도]
japan_years = { 
                'M':[[1900,1,1,33],[1912,7,29,45]],
                'D':[[1912,7,30,1],[1926,12,24,15]],
                'S':[[1926,12,25,1],[1989,1,7,64]],
                'H':[[1989,1,8,1],[2019,4,30,31]],
                'R':[[2019,5,1,1],now_YMD]
               }

japan_year_names = ['M', 'D', 'S', 'H', 'R']

# 년도 비교

for i in japan_year_names:
    
    # 년도가 경계 값에 포함되지 않을 경우
    if japan_years[i][0][0] <  data_to_compare[0] < japan_years[i][1][0]:
        print_year(i, data_to_compare[0] - japan_years[i][0][0] + 1)
    
    # 입력 값의 년도가 현재 년도와 같다면 레이와 시대이다.
    elif now_YMD[0] == data_to_compare[0]:
        print_year('R', now_YMD[-1])
        break
    
    # 년도가 경계 값에 포함될 경우 원년인지 아닌지 봐야한다. 월을 비교한다.
    elif japan_years[i][0][0] == data_to_compare[0]:

        # 경계 값 중 1900년이면 메이지 33년이다. 바로 출력하고 끝내면 된다.
        if data_to_compare[0] == 1900:
            print('메이지 33년')
            break
        
        # 월이 경계 값보다 클 경우 원년이다. 그대로 키 값을 반환하면 된다.
        elif data_to_compare[1] > japan_years[i][0][1]:
            print_year(i, 1)
            break
        
        # 월이 경계 값에 포함될 경우 일을 비교한다.
        elif japan_years[i][0][1] == data_to_compare[1]:
            
            # 일이 경계 값 보다 크면 원년이다.
            if data_to_compare[2] >= japan_years[i][0][2]:
                print_year(i, 1)
                break
            
            # 그렇지 않으면 이전 시대를 출력한다.
            else:
                print_year(japan_year_names[japan_year_names.index(i)-1],
                      japan_years[japan_year_names[japan_year_names.index(i)-1]][1][3])
                break
        # 월이 경계값보다 작으면 이전 시대를 출력한다.
        else:
            print_year(japan_year_names[japan_year_names.index(i)-1],
                  japan_years[japan_year_names[japan_year_names.index(i)-1]][1][3])
            break

난수를 돌려서 잘 적용하다가..

NameError: name 'input_day' is not defined

어떤 테스트 케이스에서 날짜가 정의되지 않는 오류가 발생한 것 같다.

오류 수정

elif input_month == 2:
    if leap_year:
        input_day = random.randint(1, 30)
    else:
        input_day = random.randint(1, 29)

앗.. 이 부분에서 실수했다.

leap_year가 년도를 입력변수로 받도록 해야했다.

elif input_month == 2:
    if leap_year(input_year):
        input_day = random.randint(1, 30)
    else:
        input_day = random.randint(1, 29)

위와 같이 수정했다.

그리고 굉장히 큰 실수를 한 것이 있었다.

random.randint(a, b)에서 난수 범위는 a이상 b이하인데,
a이상 b 미만으로 알고 있었다. range(a,b)처럼..

이 때문에 오류가 날 수 밖에 없었던 것이다.

오류 수정 후 코드

def leap_year(year):
    if year % 4 == 0:
        if year % 100 == 0:
            if year % 400 == 0:
                return True
            else:
                return False
        else:
            return True
    else:
        return False

def print_year(A, num):
    if A == 'M':
        B = '메이지'
    elif A == 'D':
        B = '다이쇼'
    elif A == 'S':
        B = '쇼와'
    elif A == 'H':
        B = '헤이세이'
    elif A == 'R':
        B = '레이와'
    
    if num == 1:
        C = '원'
    else:
        C = str(num)
    
    print(B, C+'년')
    
    return

from datetime import datetime
import random

input_year = random.randint(1900,2022)
input_month = random.randint(1, 12)

if input_month in [1, 3, 5, 7, 8, 10, 12]:
    input_day = random.randint(1, 31)

elif input_month in [4, 6, 9, 11]:
    input_day = random.randint(1, 30)

elif input_month == 2:
    if leap_year(input_year):
        input_day = random.randint(1, 29)
    else:
        input_day = random.randint(1, 28)


# input_Date = list(map(int, input().split()))

now = datetime.now()

now_YMD = [now.year, now.month, now.day, now.year - 2019 + 1]

data_to_compare = [input_year, input_month, input_day]
# data_to_compare = [input_Date[0], input_Date[1], input_Date[2]]

# print(data_to_compare)

# 데이터 베이스 : [개막년, 개막월, 개막일, 년도], [종막년, 종막월, 종막일, 종막시 년도]
japan_years = { 
                'M':[[1900,1,1,33],[1912,7,29,45]],
                'D':[[1912,7,30,1],[1926,12,24,15]],
                'S':[[1926,12,25,1],[1989,1,7,64]],
                'H':[[1989,1,8,1],[2019,4,30,31]],
                'R':[[2019,5,1,1],now_YMD]
               }

japan_year_names = ['M', 'D', 'S', 'H', 'R']

# 년도 비교

for i in japan_year_names:
    
    # 년도가 경계 값에 포함되지 않을 경우
    if japan_years[i][0][0] <  data_to_compare[0] < japan_years[i][1][0]:
        print_year(i, data_to_compare[0] - japan_years[i][0][0] + 1)
    
    # 입력 값의 년도가 현재 년도와 같다면 레이와 시대이다.
    elif now_YMD[0] == data_to_compare[0]:
        print_year('R', now_YMD[-1])
        break
    
    # 년도가 경계 값에 포함될 경우 원년인지 아닌지 봐야한다. 월을 비교한다.
    elif japan_years[i][0][0] == data_to_compare[0]:

        # 경계 값 중 1900년이면 메이지 33년이다. 바로 출력하고 끝내면 된다.
        if data_to_compare[0] == 1900:
            print('메이지 33년')
            break
        
        # 월이 경계 값보다 클 경우 원년이다. 그대로 키 값을 반환하면 된다.
        elif data_to_compare[1] > japan_years[i][0][1]:
            print_year(i, 1)
            break
        
        # 월이 경계 값에 포함될 경우 일을 비교한다.
        elif japan_years[i][0][1] == data_to_compare[1]:
            
            # 일이 경계 값 보다 크면 원년이다.
            if data_to_compare[2] >= japan_years[i][0][2]:
                print_year(i, 1)
                break
            
            # 그렇지 않으면 이전 시대를 출력한다.
            else:
                print_year(japan_year_names[japan_year_names.index(i)-1],
                      japan_years[japan_year_names[japan_year_names.index(i)-1]][1][3])
                break
        # 월이 경계값보다 작으면 이전 시대를 출력한다.
        else:
            print_year(japan_year_names[japan_year_names.index(i)-1],
                  japan_years[japan_year_names[japan_year_names.index(i)-1]][1][3])
            break

50회 돌려본 결과, 오류가 발생하지 않았다!

느낀 점


제일 중요한 것은 겁먹지 말자는 것이라고 생각하게 되었다.

논리구조, 코드를 처음 짜기 시작할 때 쉽지 않을 거라 겁이 나겠지만,
막상 몰입하다보면 생각보다 금방 답을 찾을 수 있을 것이라 생각하게 되었다.

그리고 너무 안풀리다 보면 잠깐만 뒤로 미루는 것도 한 방법이라고 생각한다.
머리를 식히고 정리하다보면 답이 떠오를 수도 있을테니.


© 2022.07. by Wookey_Kim

Powered by Hydejack v7.5.2