[사전스터디] 저가 비행기 티켓 구하기 - 1

hyuckhoon.ko·2020년 5월 4일
0

What I learned in wecode

목록 보기
12/109

(제주 -> 김포) or (김포->제주행) 편도 티켓을 구하는 air_service 프로그램을 만들려고 한다.

1. 사용자 정보 입력받기
1) 출발지, 출발일자 입력받는다.
(출발지가 '김포'면 도착지는 자동으로 '제주'로,
출발지가 '제주'면 도차지는 자동으로 '김포'가 되게 한다.)
2) 출발일자의 경우, 20200920 과 같이 8자리의 수를 입력받게 한다.
- 조건
a) 현재 날짜를 기준으로 5개월 이후의 티켓은 입력할 수 없다.
b) 20201320, 20200020과 같이, 월(month)가 12를 넘거나 0이하일 수 없다.
c) 20201237, 20201200과 같이, 일(day)가 월별 최대일 수를 넘거나 0이하일 수 없다.
-> 윤달을 고려한 2월의 최대입력수를 제한했으며, 30일 혹은 31일로 끝나는 달 역시 입력 범위를 고려하여 코드를 작성했다.

2. Beautiful Soup 모듈 기반 웹크롤링으로 항공사별
(항공사명, 티켓비용, 이륙시간)을 파싱받기.

- 항공사는 대한한공, 아시아나항공, 티웨이항공, 이스타항공, 진에어, 제주에어 총 6곳이다.

3. 파싱받은 데이터를 이진트리 구조로 저장하기.
linked_list, 큐 등이 아닌 이진트리 알고리즘(BST)으로 구현하려는 이유는,
① 스스로 BST를 구현해보고 싶은 욕심이 있다. 남이 만든 코드를 사용은 해봤지, 한 번도 직접 만들어 본적은 없기에......

② 티켓수만큼의 Cost_node 객체가 생성될 건데,
Cost_node를 읽어들일 때마다 바로바로 데이터의 우선순위가 결정되게 하기 위함이다. 물론 다른 자료구조 방식도 이렇게 작동된다. 하지만, root보다 작은 값은(==우선순위 ↓) 왼쪽에 위치하므로, 전위순회 방식으로
빨리빨리 최저가 순으로 읽다가, 데이터 전체의 평균값보다 비싸게 되는 순간
읽기를 멈추게 하는 것을 구현해 보고 싶기 때문이다.
실제로, 구현해보고 BST의 장단점을 직접 몸으로 체득하고 작성하겠다.

======================================================

======================================================

1. 사용자 정보 입력받기의 코드 (프로세스 - 1)

MAIN 은 아래와 같다.

import airlines_bot as Bot

#
# 1. User 정보 입력 받는 단계

user_status = False

# object 선언
bot = Bot.Airlines_bot()
bot.hello2client()

# 단계 1. user에게 출발지, 출발일자 입력받는 반복문
user_where_reply = bot.ask_place()
while not user_status:
    if user_where_reply == False:
        bot.ask_place()
    user_when_reply = bot.ask_when()
    while not user_when_reply:
        user_when_reply = bot.ask_when()
    user_status = True

import한 airlines_URL.py의 코드는 아래와 같다.

# Library : Domestic airlines for low cost
import airlines_URL as URL
from datetime import datetime

# 현재 시간 구하는 object 선언
now = datetime.now()

# 5개월 이후의 항공편은 예약 불가
month_limit = 5

# 윤달 및 월별 최대 일수 체크 함수 - 메소드 안에서 함수 호출됨
def day_check(user_year, user_month, user_day):
    if user_month in [1, 3, 5, 7, 8, 10, 12] and user_day > 31 or user_day <= 0:
        return False

    elif user_month in [4, 6, 9, 11] and (user_day > 30 or user_day <= 0):
        return False

    if (user_year % 4 != 0 and user_month == 2) and user_day > 28:
        return False

    elif (user_year % 4 == 0 and user_month == 2) and user_day > 29:
        return False

    return True


def month_check(user_month):
    if user_month <= 0 or user_month > 12:
        print("월(month)을 잘못 입력했습니다.")
        return False
    if abs(user_month-now.month) > 11:
        print("월(month)을 잘못 입력했습니다.")
        return False
    if abs(user_month - now.month) > month_limit:
        print("5개월 이후의 항공편은 예약할 수 없습니다..")
        return False
    else:
        return True


def year_check(user_year):
    if user_year < now.year:
        return False
    else:
        return True


class Airlines_bot():
    from_where = ''
    to_go = ''
    year = ''
    month = ''
    day = ''

    def __init__(self):  # airlines_URL의 cost_weight값 초기화
        if URL.airlines_list:
            pass
        else:
            print("항공사 리스트가 비어있습니다. airlines_URL.py를 확인하십시오")

    def hello2client(self):
        print("| Airlines service입니다. |")
        print("        환영합니다.\n\n\n")

    # 출발지, 도착지 입력 section
    def ask_place(self):
        self.from_where = input("1. 출발지를 입력하십시오. (서울/제주) : ")
        if self.from_where == '서울' and not self.from_where.isdigit():
            self.from_where = '서울'
            self.to_go = '제주'
            reply = f'- 출발지 : {self.from_where}\n- 도착지 : {self.to_go}'
            print(reply)
            print("     (입력완료)")
            return True
        elif self.from_where == '제주' and not self.from_where.isdigit():
            self.from_where = '제주'
            self.to_go = '서울'
            reply = f'→ 출발지 : {self.from_where}, 도착지 : {self.to_go}'
            print(reply)
            print("     (입력완료)")
            return True

        else:
            print("출발지를 잘못입력하셨습니다. 다시 입력하십시오")
            return False

    # 출발일자, 도착일자 입력 section
    def ask_when(self):
        print("==============================")
        print("2. 출발일자 8자리를 입력하세요")
        print(" - Ex) 입력 예시 : 20200504 ")
        from_when = input("출발일자를 입력하세요.(yyyymmdd) : ")
        if from_when.isdigit():
            if len(from_when) != 8:
                print("8자리 숫자를 입력하세요")
                return False
        else:
            print("숫자만 입력해야합니다.")
            return False

        # 사용자 입력 데이터 추가검증
        user_year = int(from_when[0:4])
        user_month = int(from_when[4:6])
        user_day = int(from_when[6:8])

        # 년(yyyy, year) 검사
        if not year_check(user_year):
            print("이미 지난 항공편은 예약할 수 없습니다.")
            return False

        # 월(mm, month) 검사
        if not month_check(user_month):
            return False

        # 일자(dd, day) 검사 - 윤달 및 월별 최대 일수 체크
        if not day_check(user_year, user_month, user_day):
            print("일자(dd)를 잘못 입력했습니다.")
            return False
        self.year = user_year
        self.month = user_month
        self.day = user_day
        return True

======================================================

■ 오늘은 크게 3가지의 프로세스 중 첫 단계를 완료했다.
자기 전까지 BST 튜토리얼을 좀 더 연구해야 겠다.

■ 내일은 Beautiful Soup 모듈을 사용한 웹크롤링을 사용한다.
각 항공사 홈페이지에서 필요한 데이터 정보들만 파싱받는 것인데,
아직 해보지 않은 것은
1) 팝업창을 닫게 하는 방법과,
2) 내가 원하는 정보를 '자동입력'하게 하는 방법이다.

                                  - One step at a time - 

1개의 댓글

comment-user-thumbnail
2020년 5월 4일

엄청나네요.. 이번주도 기대하겠습니다

답글 달기