[Python mini projects] 전역일 계산기 및 단축 군 복무일 계산기 만들기 / 그리고 웹 어플리케이션의 정보 수집에 대해
Category: Python programming / Data science
(아이디어에 대한 포스트 한 가운데에 프로그래밍 언어 파이썬이라니, 조금은 뜬금없을 수도 있다.)
파이썬 프로그래밍을 공부하면서 주로 개발보다는 Data analysis, Data science 쪽에 관심을 가져왔다. 아무래도 데이터 핸들링, 시각화나 분석을 위한 파이썬에 치중하다 보니 Python을 처음부터 꼼꼼하고 완벽히 공부하기보다는 기본 syntax를 익힌 후 데이터를 다루는 데 필요한 모듈을 활용하는 방법을 집중적으로 다루어왔다. 그러나 최근 더 폭넓은 범위에서 Python을 활용하기 위해서는 개발을 위한 언어로써의 Python을 더 확실히 공부할 필요성이 있음을 느꼈다. 또한 그러는 과정에서 Python을 활용해 진행할 수 있는 나름의 미니 프로젝트를 해 볼 생각이며, Idea의 구체화와 시너지가 좋다고 생각되는 프로젝트들을 이 블로그에 포스트할 예정이다. 가까운 미래에 목표하고 있는 프로젝트는 어느 블로그(https://blog.naver.com/kirokkk123/90194636915)에서 우연히 보게 된 "네이버 웹툰 네트워크"에서 아이디어를 활용하여, 웹 상의 네트워크와 허브를 분석하는 프로젝트를 진행해볼까 한다 .
***
오늘은 프로젝트까지는 아니지만 datetime 모듈은 이용해 짧은 시간동안 만든 군 복무 전역일 계산기를 포스트해보려고 한다. 그리고 포스트의 말미에, 코딩을 하며 웹 어플리케이션에 대해 든 생각을 짧게 남기려 한다. 어제, 그리고 오늘부로 군 복무 단축에 대한 뉴스가 세간을 뜨겁게 달궜다. 또한, 2016년 10월 기준으로 2주에 1일씩 단축이라는 구체적인 방안 역시 공개되었는데, 아직 확정된 것이 아니어서 그런지 웹 사이트에서 제공하는 군복무 계산기에는 반영이 되지 않아 단축된 복무기간을 알기 위해서는 달력을 꺼내고 직접 세야 한다. (셈이 빠르다면 할 말이 없지만...)
그래서 군종별 입대일을 입력하면 기존의 전역일과, 단축 시행 이후의 전역일을 계산해주는 프로그램을 짜 보자는 생각이 들어 급하게 Python을 꺼내들었다. 단축일 계산기는 사실 분석적 사고나 창의적인 아이디어를 요하는 코딩작업은 아니었지만 날짜를 계산하는 모듈을 이용하여 기본적인 수준의 프로그램을 짜는데에 좋은 연습이 된다고 생각한다. 또한, 이후에 애플리케이션 개발과 인터페이스를 손댈 수 있을정도로 파이썬에 숙달하게 되면 여타 웹 사이트에서 제공하는것과 같은 군복무 계산기 애플리케이션을 만들어보고싶다.
먼저 코드의 구조를 설계해보면 다음과 같다:
1. 입대 날짜를 입력하게 한다
- datetime 모듈을 import한다. (시간의 연산에 필요한 timedelta와 relativedelta모듈 역시 import한다)
- input 을 통해 입대한 년, 월, 일을 차례대로 입력하게 한 뒤 이들을 변수로 저장한다.
- 입대 년, 월, 일에 대해 각각 '숫자가 아닌'input을 입력했을 때의 예외처리를 한다.
- 이후 입대 년, 월, 일을 묶어 datetime형태로 만든다.
이 과정의 코드는 다음과 같다.
---
import datetime
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
while True:
year = input("Enter your starting year: ")
try:
year = int(year)
break
except ValueError as err:
print ("You should enter a number as a year")
while True:
month = input("Enter your starting month: ")
try:
month = int(month)
break
except ValueError as err:
print ("You should enter number as a month")
while True:
day = input("Enter your starting day: ")
try:
day = int(day)
break
except ValueError as err:
print ("You should enter number as a day")
starting = "{0}-{1}-{2}".format(year, month, day)
starting_ = datetime.strptime(starting, '%Y-%m-%d')
---
2. 군종을 입력하게 한다.
- 군종을 입력하게 한다. Input을 요구할 때 문자열을 통해 군종을 어떻게 입력해야 할지 예시를 보여준다. 영어로 코드를 짰기 때문에 Army/ Air force/Marine/Navy/Police/Social/Fire 로 군종의 이름을 통일했다.
- 입력한 군종이 예시로 준 stadard에 맞게 입력되었을 경우 군종을 변수로 받은 채 루프를 끝낸다. 만일 다른 것을 입력했다면 오류 메시지를 출력한다.
- 군종별 복무기간을 {군종: 기간}형태의 딕셔너리로 만들고, 입력한 군종을 딕셔너리의 키로 하여 찾을 값을 '기간'변수에 할당한다.
3. 전역일을 계산한다
- 복무 시작일에 해당 복무 기간을 더하여 전역날짜를 계산한다.
- 만일 전역일이 지났을 경우 : 오늘 날짜를 기준으로 전역일이 더 이전일 경우 이미 전역했다는 메시지를 띄우고, 전역한 날짜를 보여준다.
- 만일 전역일이 아직 지나지 않았을 경우, 계산된 전역일을 출력한다.
이 과정까지의 코드는 다음과 같다:
while True:
type_ = input("""What is your type of service?:
Army/
Air force/
Marine/
Navy/
Police/
Social/
Fire
(Type as exactly the same as above): """)
if type_ in ["Army", "Air force", "Marine", "Navy", \
"Police", "Social", "Fire"]:
break
else:
print ("You've got to type valid 'type'")
term_type = {"Army" : 21, "Air force" : 24, "Marine" : 21, \
"Navy": 23, "Police" : 21, "Social" : 24, "Fire" : 23}
term = term_type[type_]
original_end_date = starting_ + relativedelta(months = term)\
- timedelta(days = 1)
if original_end_date <=datetime.now():
print ("It seems like your service has already been completed!")
print ("Your service was over in :", original_end_date)
else: print("Your last day of service was \
(Before modification): ", original_end_date)
4. 아직 전역일이 남았을 경우에, 2018년 1월 15일자로 언론을 통해 보도된 군 복무 단축 계획을 바탕으로 단축된 전역일과 단축받게되는 날짜를 출력한다. 한 언론사 보도에 따르면 2016일 10월 4일 입대자를 기준으로 2주마다 하루씩 추가로 단축되는 방식이다.
if original_end_date >= datetime.now():
print ("Congratulations! I've got a news you'll get a discount on your terms of service!")
start_of_discount = datetime.strptime("2016-10-04", "%Y-%m-%d")
days_of_discount = 0
while start_of_discount <= starting_:
start_of_discount += timedelta(weeks = 2)
days_of_discount+=1
discounted_end = original_end_date - timedelta(days = days_of_discount)
print ("You are discounted: {} days".format(days_of_discount))
print ("Your service ends in : ", discounted_end)
마지막으로, 위 코드를 실행한 후 올바른 결과를 출력하는지 확인해보도록 하겠다.
만일2018년 1월 17일, 육군으로 입대한다면 군 복무 단축 적용 전의 전역일은 다음과 같다
코드를 실행하고 날짜를 입력한 후, Army로 군종을 입력하면 결과는 다음과 같다.
Before modification (단축 전) 날짜는 10월 16일로 출력되며 단축되는 일수는 34일임을 알 수 있다.그런데 여기서 한 가지 문제점이 발견된다. 언론에 보도된 바에 의하면 2주에 1일씩 단축하는 방안으로 2020년 입대자부터는 3개월 복무기간이 단축되는데, 위에 작성한 코드는 2020년 이후 입대자에 대해서도 계속하여 2주에 1일씩 복무 기간을 단축시키는 작업을 수행한다. 따라서 코드의 중간에 단축되는 날 수가 3개월 이상이 되면 단축 작업을 중단하는 코드를 넣도록 한다. 연산의 편의상 3개월을 90일로 정의하겠다. (line 70)
이렇게 하면 최종적인 코드는 다음과 같다
2022년 입대자의 기준으로 실행해본 결과 정확히 90일이 단축된 전역일을 출력한다.
또한, 숫자가 아닌 다른 것을 날짜에 입력하거나, type of service를 잘못 입력하였을 경우의 예외처리도 원만하게 진행된다. 100줄도 되지 않는 코드이지만 조건별 전역일 계산이라는 간단한 기능 수행을 수행해낸다.
***
여담이지만 '전역일 계산기'라는 웹 애플리케이션을 살펴보며 구글의 검색을 통한 트렌트 분석과 같이 웹 어플리케이션에서도 사용 로그를 데이터로 남긴다면 트렌트 분석에 큰 도움이 되지 않을까 하는 생각이 들었다. (어쩌면 구글이나 네이버와 같은 플랫폼 회사에서는 이미 그렇게 하고 있는지도 모르겠다.) 예를들어, 군 복무 계산기는 현역 군인들만이 사용하는 것이 아니다. 아직 입대하지 않은 입대 예정자들이나, 입대일이 아직 정해지지 않았지만 미래의 계획을 위해 미리 원하는 입대일과 그에따른 전역일을 조회해보는 이들도 상당히 많다. '군 복무 계산기' 라는 애플리케이션이 익명의 개인정보 수집 동의 하에 사용 로그를 수집해 데이터베이스를 구축하면, 구글 검색을 통한 트렌드가 그랬던것처럼 아직 군 복무가 시작하지 않았거나 확정되지 않은 사람들에 대한 잠정적 데이터를 얻을 수 있다. (감기에 걸리면 Flue라는 키워드로 검색을 하거나, 관심있는 후보에 대해 검색하는 것과 마찬가지다. )
댓글
댓글 쓰기