반응형

심심풀이로 로또의 추첨결과 정보를 가져오는 프로그램을 작성하려고 한다.

 

로또복권 운영사인 동행복권 홈페이지에서는 별도의 API를 제공하지 않지만 홈페이지의 소스를 보다보면

 

아래와 같이 내부에서 결과 정보를 호출하는 구문이 있고, 쿼리 URL을 쉽게 찾을 수 있다.

로또 추첨결과의 회차별 정보를 가져오는 URL은 다음과 같다.

 

로또 추첨 결과 쿼리 URL: https://www.dhlottery.co.kr/common.do?method=getLottoNumber&drwNo=1119

쿼리의 "drwNo" 값이 회차 이다.

 

쿼리가 정상적으로 수행되었을때 수신되는 메시지(JSON)는 다음과 같다.

 

{
   "totSellamnt":111840714000,					//전체 당첨 상금 총액(1등~5등 모든 당첨금액)
   "returnValue":"success",						//요청결과(정상:success, 실패:fail)
   "drwNoDate":"2024-05-11",					//추첨일
   "firstWinamnt":1396028764,					//1등 추첨자의 당첨금액
   "drwtNo6":45,								//6번째 번호
   "drwtNo4":13,								//4번째 번호
   "firstPrzwnerCo":19,							//1등 당첨자 수
   "drwtNo5":20,								//5번째 번호
   "bnusNo":3,									//보너스번호 번호
   "firstAccumamnt":26524546516,				//1등 총 당첨금액(1등 당첨금액 * 1등 당첨자 수)
   "drwNo":1119,								//회차 번호
   "drwtNo2":9,									//2번째 번호
   "drwtNo3":12,								//3번째 번호
   "drwtNo1":1									//1번째 번호
}

 

JSON 구조로 쉽게 파싱하도록 되어있다.

아래의 당첨결과 상세페이지의 내용가 대조하면 쉬울 듯 하다.

 

추가로 최신 회차를 구하는 계산식 함수는 다음과 같다,

 

# 로또 1회차(2002-12-07)기준으로 오늘까지의 회차를 가져오는 함수
def get_last_rounds():
    start_date = datetime.date(2002, 12, 7) #1회 추첨일
    today = datetime.date.today()
    # 주차 계산
    weeks = (today - start_date).days // 7
    return weeks + 1

2002-12-07이 1회 추첨일이므로 이기준으로 오늘까지의 주차수(weeks)를 구하여 +1을 해준다.

반응형

리눅스 계열 OS에서 많이 사용되는 쉘스크립트의 형식(인덴트:indent 와 같은 줄맞춤?)을 자동으로 해주는 파이썬 라이브러리가 있어 스크랩한다.


쉘스크립트 경우 대부분 작성을 vim이나 notepad같은 별도의 IDE를 사용하지 않기때문에 여타  IDE처럼 인덴트를 자동으로 잡아주는 기능이 없다.


파이썬 파일로 아래 내용을 저장후 해당파일을 실행해주면 된다.


공식사이트는 https://arachnoid.com/python/beautify_bash_program.html 이며 라이센스는 GNU General Public License.



실행명령:

python beautify_bash.py file1.sh


파일:

beautify_bash.py


소스코드:

 
#!/usr/bin/env python
# -*- coding: utf-8 -*-

#**************************************************************************
#   Copyright (C) 2011, Paul Lutus                                        *
#                                                                         *
#   This program is free software; you can redistribute it and/or modify  *
#   it under the terms of the GNU General Public License as published by  *
#   the Free Software Foundation; either version 2 of the License, or     *
#   (at your option) any later version.                                   *
#                                                                         *
#   This program is distributed in the hope that it will be useful,       *
#   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
#   GNU General Public License for more details.                          *
#                                                                         *
#   You should have received a copy of the GNU General Public License     *
#   along with this program; if not, write to the                         *
#   Free Software Foundation, Inc.,                                       *
#   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
#**************************************************************************

import re, sys

PVERSION = '1.0'

class BeautifyBash:

  def __init__(self):
    self.tab_str = ' '
    self.tab_size = 2

  def read_file(self,fp):
    with open(fp) as f:
      return f.read()

  def write_file(self,fp,data):
    with open(fp,'w') as f:
      f.write(data)

  def beautify_string(self,data,path = ''):
    tab = 0
    case_stack = []
    in_here_doc = False
    defer_ext_quote = False
    in_ext_quote = False
    ext_quote_string = ''
    here_string = ''
    output = []
    line = 1
    for record in re.split('\n',data):
      record = record.rstrip()
      stripped_record = record.strip()
      
      # collapse multiple quotes between ' ... '
      test_record = re.sub(r'\'.*?\'','',stripped_record)
      # collapse multiple quotes between " ... "
      test_record = re.sub(r'".*?"','',test_record)
      # collapse multiple quotes between ` ... `
      test_record = re.sub(r'`.*?`','',test_record)
      # collapse multiple quotes between \` ... ' (weird case)
      test_record = re.sub(r'\\`.*?\'','',test_record)
      # strip out any escaped single characters
      test_record = re.sub(r'\\.','',test_record)
      # remove '#' comments
      test_record = re.sub(r'(\A|\s)(#.*)','',test_record,1)
      if(not in_here_doc):
        if(re.search('<<-?',test_record)):
          here_string = re.sub('.*<<-?\s*[\'|"]?([_|\w]+)[\'|"]?.*','\\1',stripped_record,1)
          in_here_doc = (len(here_string) > 0)
      if(in_here_doc): # pass on with no changes
        output.append(record)
        # now test for here-doc termination string
        if(re.search(here_string,test_record) and not re.search('<<',test_record)):
          in_here_doc = False
      else: # not in here doc
        if(in_ext_quote):
          if(re.search(ext_quote_string,test_record)):
            # provide line after quotes
            test_record = re.sub('.*%s(.*)' % ext_quote_string,'\\1',test_record,1)
            in_ext_quote = False
        else: # not in ext quote
          if(re.search(r'(\A|\s)(\'|")',test_record)):
            # apply only after this line has been processed
            defer_ext_quote = True
            ext_quote_string = re.sub('.*([\'"]).*','\\1',test_record,1)
            # provide line before quote
            test_record = re.sub('(.*)%s.*' % ext_quote_string,'\\1',test_record,1)
        if(in_ext_quote):
          # pass on unchanged
          output.append(record)
        else: # not in ext quote
          inc = len(re.findall('(\s|\A|;)(case|then|do)(;|\Z|\s)',test_record))
          inc += len(re.findall('(\{|\(|\[)',test_record))
          outc = len(re.findall('(\s|\A|;)(esac|fi|done|elif)(;|\)|\||\Z|\s)',test_record))
          outc += len(re.findall('(\}|\)|\])',test_record))
          if(re.search(r'\besac\b',test_record)):
            if(len(case_stack) == 0):
              sys.stderr.write(
                'File %s: error: "esac" before "case" in line %d.\n' % (path,line)
              )
            else:
              outc += case_stack.pop()
          # sepcial handling for bad syntax within case ... esac
          if(len(case_stack) > 0):
            if(re.search('\A[^(]*\)',test_record)):
              # avoid overcount
              outc -= 2
              case_stack[-1] += 1
            if(re.search(';;',test_record)):
              outc += 1
              case_stack[-1] -= 1
          # an ad-hoc solution for the "else" keyword
          else_case = (0,-1)[re.search('^(else)',test_record) != None]
          net = inc - outc
          tab += min(net,0)
          extab = tab + else_case
          extab = max(0,extab)
          output.append((self.tab_str * self.tab_size * extab) + stripped_record)
          tab += max(net,0)
        if(defer_ext_quote):
          in_ext_quote = True
          defer_ext_quote = False
        if(re.search(r'\bcase\b',test_record)):
          case_stack.append(0)
      line += 1
    error = (tab != 0)
    if(error):
      sys.stderr.write('File %s: error: indent/outdent mismatch: %d.\n' % (path,tab))
    return '\n'.join(output), error

  def beautify_file(self,path):
    error = False
    if(path == '-'):
      data = sys.stdin.read()
      result,error = self.beautify_string(data,'(stdin)')
      sys.stdout.write(result)
    else: # named file
      data = self.read_file(path)
      result,error = self.beautify_string(data,path)
      if(data != result):
        # make a backup copy
        self.write_file(path + '~',data)
        self.write_file(path,result)
    return error

  def main(self):
    error = False
    sys.argv.pop(0)
    if(len(sys.argv) < 1):
      sys.stderr.write('usage: shell script filenames or \"-\" for stdin.\n')
    else:
      for path in sys.argv:
        error |= self.beautify_file(path)
    sys.exit((0,1)[error])

# if not called as a module
if(__name__ == '__main__'):
  BeautifyBash().main()


반응형

python(파이썬) 주석이나 출력문중에 한글 내용이 있을때 인코딩을 별도로 선언하지 않고 실행시키면 오류가 뜬다.

그럴 경우에는 파일의 첫줄에 아래 내용을 추가시킨다.



# -*- coding: utf-8 -*-



+ Recent posts