Python

Flet을 이용한 로또 1등 번호 생성기

아짱이아빠 2024. 9. 24. 22:23
반응형
SMALL

다음은 Python Flet 라이브러리를 이용하여 만든 로또 1등 번호 생성기 프로그램에 대한 설명입니다.


 

 

개요

Flet은 파이썬을 사용하여 쉽게 UI를 만들 수 있게 해주는 라이브러리이다. 

이 Flet을 활용하면 파이썬으로 만든 프로그램을 안드로이드 앱으로도 만들 수 있다.

그래서 이전에 만들었던 머신러닝을 통한 로또 1등 번호 생성기를 핸드폰에서도 쉽게 실행시키기 위해 Flet 라이브러리를 이용하여 프로그램으로 만들었으나 결론적으로 안드로이드 앱으로 만드는 데까지는 실패하였다.

안드로이드에서 실행할 수  있는 apk 파일은 빌드하였으나, 이 프로그램에서 사용된 다양한 라이브러리, 예를 들면, Scikit-learn이나 Prophet, Pandas등이 모두 패키징 하는 데에 문제를 일으켰고 아직까지 해결하지 못했다.

이러한 문제들에 대해서는 나중에 얘기하고 코드에 대한 설명을 하겠다.


 

라이브러리 정의 

임포트를 해야 하는 라이브러리들은 아래와 같다.

import flet as ft
from time import sleep
import pandas as pd
import numpy as np
import requests
from sklearn.svm import SVR
from prophet import Prophet
from collections import Counter

 

맨 위에 있는 flet 임포트를 위해서는 먼저 flet 설치가 필요하다.

Flet의 설치는 커맨트 창에서 다음의 명령어로 설치할 수 있다.

 

pip install flet

 


 

프로그램 구조

전체적인 프로그램은 아래와 같이, ‘main’이라는 정의 내에 구성되며, 내부에 과거의 로또 1등 번호들을 추출하는 것과 이를 통해 다음을 예측하는 정의등으로 구성된다.

 

def main(page: ft.page):

 

     def 1등 로또 번호 6자리의 합

 

            def 과거 로또 번호 추출

 

     로또 번호 회차 입력창 정의

 

     def 로또 번호 예측

 

     예측 결과창 정의

 

이 프로그램은 사용자가 원하는 로또 회차를 입력하면, 1회차부터 입력된 회차까지의 1등 번호를 추출하고 1등의 각 6자리 숫자들의 합을 구한다.

이 합들을 RBF와 Prophet 이라는 학습 라이브러리를 이용하여 다음 회차의 1등 번호들의 합을 예측한다. 

그리고 이 합을 만족하는 6자리의 숫자는 이제 것 가장 많이 나왔던 숫자들의 순으로 조합을 만들고 또한 가장 적게 나왔던 숫자의 순으로도 조합을 만든다.

이에 대한 내용은 다음의 글에 좀 더 자세히 나와 있다.

 

 

Python Machine Learning을 이용한 Lotto 번호 생성 프로그램 - (1)

이번에 파이썬을 이용하여 Lotto 번호 6자리를 뽑아내는 프로그램을 만들어 보았다. 많은 사람들이 Lotto 번호를 만드는 프로그램을 만들었으며 대부분은 random() 함수를 이용하여 난수를 생성한다

superhky.tistory.com

 

 

Python Machine Learning을 이용한 Lotto 번호 생성 프로그램 - (2)(UPDATE )

1부에서 Machine Learning을 통해 다음 차수의 1등 Lotto 번호 총 합 예측을 하였다.2부에서는 예측된 합에서 6개의 Lotto 번호 조합을 찾아보도록 하겠다. 1부 처음에 얘기했듯이 Lotto 번호의 조합은 과

superhky.tistory.com

 

 

Machine Learning을 이용한 간단 주식 예측

이번에는 비교적 간단한 Machine Learning을 이용하여 주식의 종가를 예측하는 것을 알아보겠다. 파이썬 코드는 자주 보는 유튜브 동영상 강의를 참조하였다. 예측 알고리즘은 Radial Basis Function(RBF)

superhky.tistory.com

 

 

PROPHET 머신 러닝을 이용한 파이썬 로또 번호 생성

이번에 파이썬의 머신 러닝 중 PROPHET 알고리즘을 이용하여 로또 번호 6자리를 추출하는 프로그램에 대해 얘기해 보겠다. 내 블로그에는 아래처럼 이전에 파이썬 머신 러닝을 이용하여 다음번 로

superhky.tistory.com

 

로또 번호 생성기 & ChatGPT

이번에는 로또 번호 6자리 조합을 찾는 파이썬 코드에 대해 알아보겠다. 이는 이전 포스트에서 다뤘던 딥러닝을 통한 로또 번호 추출과 같은 연장선상에 있다. 딥러닝을 통해 다음 차수의 1등 로

superhky.tistory.com

 


 

코드 상세 설명

다음의 코드는 로또 1등 번호를 추출하고 1등 번호들의 합을 구하는 기능을 하는 코드이다.

def lotto_rounds_sum(e):
       
        def getLottoWinInfo(minDrwNo, maxDrwNo):
            drwtNo1 = []
            drwtNo2 = []
            drwtNo3 = []
            drwtNo4 = []
            drwtNo5 = []
            drwtNo6 = []
            bnusNo = []
            totSellamnt = []
            drwNoDate = []
            firstAccumamnt = []
            firstPrzwnerCo = []
            firstWinamnt = []
           
            #=======Progress Bar 입력===============================    
            pb_01 = ft.ProgressBar(width=400)
            page.add(ft.Column([ft.Text("Progressing..."), pb_01]))
            #=======================================================
           
            for i in range(minDrwNo, maxDrwNo+1, 1):
                req_url = "http://www.dhlottery.co.kr/common.do?method=getLottoNumber&drwNo=" + str(i)
                req_lotto = requests.get(req_url)
                lottoNo = req_lotto.json()
                drwtNo1.append(lottoNo['drwtNo1'])
                drwtNo2.append(lottoNo['drwtNo2'])
                drwtNo3.append(lottoNo['drwtNo3'])
                drwtNo4.append(lottoNo['drwtNo4'])
                drwtNo5.append(lottoNo['drwtNo5'])
                drwtNo6.append(lottoNo['drwtNo6'])
                bnusNo.append(lottoNo['bnusNo'])
                totSellamnt.append(lottoNo['totSellamnt'])
                drwNoDate.append(lottoNo['drwNoDate'])
                firstAccumamnt.append(lottoNo['firstAccumamnt'])
                firstPrzwnerCo.append(lottoNo['firstPrzwnerCo'])
                firstWinamnt.append(lottoNo['firstWinamnt'])


                lotto_dict = {"추첨일":drwNoDate, "Num1":drwtNo1, "Num2":drwtNo2, "Num3":drwtNo3, "Num4":drwtNo4, "Num5":drwtNo5,
                              "Num6":drwtNo6, "bnsNum":bnusNo, "총판매금액":totSellamnt, "총1등당첨금":firstAccumamnt,
                              "1등당첨인원":firstPrzwnerCo,"1등수령액":firstWinamnt}

                #====Progressbar update====
                pb_01.value = i/maxDrwNo
                sleep(0.1)
                page.update()
                #==========================


            df_lotto = pd.DataFrame(lotto_dict)
            return df_lotto
        #=========================================================================================================================
        lotto_df = getLottoWinInfo(1,int(lotto_rounds_input.value))
        data_sum = lotto_df["Num1"]+lotto_df["Num2"]+lotto_df["Num3"]+lotto_df["Num4"]+lotto_df["Num5"]+lotto_df["Num6"]
        num_list = list(lotto_df['Num1'])+list(lotto_df['Num2'])+list(lotto_df['Num3'])+list(lotto_df['Num4'])+list(lotto_df['Num5'])+list(lotto_df['Num6'])
        data_date = lotto_df['추첨일']


        #====번호를 많이 나온 순/적게 나온 순으로 정리=====
        count = Counter(num_list)
        common_num = count.most_common(45)
        i=1
        common_num_k =[]
        for i in range(45):
            common_num_i = common_num[i]
            common_num_i= common_num_i[:1]
            common_num_k.append(common_num_i)
            i = i+1
        i=0
        most = ()
        for i in range(45):
            most = most+common_num_k[i]
            i = i+1
       
        j=0
        least = ()
        for j in reversed(range(45)):
            least = least+common_num_k[j]
            j = j+1
        #============================================

        #=========마지막 회차 1등 번호의 합 출력 ==========================================================
        page.add(ft.Text('로또 '+str(lotto_rounds_input.value)+'회차의 합 :' + str(data_sum.values[-1])))
        #================================================================================================

        return data_sum.values, data_date, most, least

 

중간에 보이는 ‘Progressbar update’는 flet에서 제공하는 진행바(Progressbar)의 기능이다.

이제까지 1,100여 회차가 넘어가는 로또 번호들을 추출할 때에 시간이 좀 걸리기 때문에, 어느 정도 진행되는지를 확인하기 위해 작성하였다.

일반적으로는 처리가 진행되고 있음만 알려주지만 위의 코드에서와 같이 value에 for 문의 전체 횟수 중 i 번째 임을 정의해 주면 프로그램의 진행 과정을 확인할 수 있다.

 

Flet에서 텍스트의 추가는 “page.add(~~)”를 통해 할 수 있다.

 

다음은 UI 창의 타이틀과 로또 회차를 입력하는 창을 만들어 준다.

   page.title = "인공지능 로또번호 생성기"
   lotto_rounds = ft.Text('로또 회차 선택(30회 이상 입력 필요)')
   lotto_rounds_input = ft.TextField(hint_text='로또 회차를 넣으시오')
           
   row = ft.Row(controls=[
       lotto_rounds,
       lotto_rounds_input,
   ])
   page.add(row)

 

‘hint_text =~~’는 TextField라는 입력창에 어떤 입력값을 넣어야 하는지 힌트 문구를 보여주는 기능을 한다.

Text와 TextField는 하나의 행(row)으로 정의된 것을 볼 수 있고 따라서 화면에 한 줄로 표현된다.

Flet은 마지막에 보듯이 page.add(row)를 넣어주어야 화면에 시현된다.

 

다음은 로또 번호 합을 예측하고 이를 만족하는 6자리 숫자 조합을 만드는 기능을 하는 코드이다.

def Prediction(e):

        x = lotto_rounds_sum(e)
        
        #===========RBF 예측 ==============================
        counts=[]
        j=1
        for j in range(int(lotto_rounds_input.value)):
            counts.append([int(j+1)])
            j=j+1
        rbf_svr = SVR(kernel = 'rbf', C=1000, gamma=0.1)
        rbf_svr.fit(counts, x[0])
        count = [[len(counts)+1]]
        rbf_pred = rbf_svr.predict(count)
        rbf_pred_1 = rbf_pred[0]
        page.add(ft.Text('RBF 예측 결과 :'+ str(rbf_pred_1)))

        #===Prophet 예측 =================================
        new_values =[]
        new_values = pd.DataFrame(new_values)
        new_values['ds'] = x[1]
        new_values['y'] = x[0]
        data = new_values[['ds','y']]
        model = Prophet()
        model.fit(data)
        future = model.make_future_dataframe(periods=7)
        forecast = model.predict(future)
        forecast_1 = forecast['yhat'].values[len(forecast)-1]
        page.add(ft.Text('Prophet 예측 결과 :' + str(forecast_1)))

        #=========번호 조합 찾기================================================================
        #======많이 나온 순====================================================================
        cc=[]
        for i in range(len(x[2])):
            for j in range(i+1, len(x[2])):
                for k in range(j+1, len(x[2])):
                    for l in range(k+1, len(x[2])):
                        for m in range(l+1, len(x[2])):
                            for n in range(m+1,len(x[2])):
                                if x[2][i]+x[2][j]+x[2][k]+x[2][l]+x[2][m]+x[2][n] == round(rbf_pred_1):
                                   cc = [x[2][i],x[2][j],x[2][k],x[2][l],x[2][m],x[2][n]]
                                   page.add (ft.Text('RBF 결과(많이 나온 순)' + str(cc)))
                                   
                                   break
                            if cc != []:
                                break
                        if cc != []:
                            break
                    if cc != []:
                        break
                if cc != []:
                    break
            if cc != []:
                break
  
        ccc=[]
        for i in range(len(x[2])):
            for j in range(i+1, len(x[2])):
                for k in range(j+1, len(x[2])):
                    for l in range(k+1, len(x[2])):
                        for m in range(l+1, len(x[2])):
                            for n in range(m+1,len(x[2])):
                                if x[2][i]+x[2][j]+x[2][k]+x[2][l]+x[2][m]+x[2][n] == round(forecast_1):
                                   ccc = [x[2][i],x[2][j],x[2][k],x[2][l],x[2][m],x[2][n]]
                                   page.add (ft.Text('Prophet 결과(많이 나온 순)' + str(ccc)))
                                   
                                   break
                            if ccc != []:
                                break
                        if ccc != []:
                            break
                    if ccc != []:
                        break
                if ccc != []:
                    break
            if ccc != []:
                break
        # ==================적게 나온 순===============================================================
        ic=[]
        for i in range(len(x[3])):
            for j in range(i+1, len(x[3])):
                for k in range(j+1, len(x[3])):
                    for l in range(k+1, len(x[3])):
                        for m in range(l+1, len(x[3])):
                            for n in range(m+1,len(x[3])):
                                if x[3][i]+x[3][j]+x[3][k]+x[3][l]+x[3][m]+x[3][n] == round(rbf_pred_1):
                                   ic = [x[3][i],x[3][j],x[3][k],x[3][l],x[3][m],x[3][n]]
                                   page.add (ft.Text('RBF 결과(적게 나온 순)' + str(ic)))
                                   
                                   break
                            if ic != []:
                                break
                        if ic != []:
                            break
                    if ic != []:
                        break
                if ic != []:
                    break
            if ic != []:
                break
  
        icc=[]
        for i in range(len(x[3])):
            for j in range(i+1, len(x[3])):
                for k in range(j+1, len(x[3])):
                    for l in range(k+1, len(x[3])):
                        for m in range(l+1, len(x[3])):
                            for n in range(m+1,len(x[3])):
                                if x[3][i]+x[3][j]+x[3][k]+x[3][l]+x[3][m]+x[3][n] == round(forecast_1):
                                   icc = [x[3][i],x[3][j],x[3][k],x[3][l],x[3][m],x[3][n]]
                                   page.add (ft.Text('Prophet 결과(적게 나온 순)' + str(icc)))
                                   
                                   break
                            if icc != []:
                                break
                        if icc != []:
                            break
                    if icc != []:
                        break
                if icc != []:
                    break
            if icc != []:
                break


위의 코드는 Flet과는 관계가 없으므로 추가적인 설명은 하지 않도록 하겠다. 

다만 필자는 프로그램 전공자가 아니고 순전히 취미로 하는 것이기 때문에 효율적으로 프로그램을 구성했다고 할 수 없으니 이점은 참고하길 바란다.

위의 코드에서 가장 많이 나온 순으로 번호를 조합하는 부분은 며칠을 고민하면서 만들었었는데 ChatGPT가 1분도 안돼서 만드는 것을 보고 앞으로는 어렵게 고민고민하면서 코딩할 필요가 없다고 생각했던 기억이 난다.

반응형

마지막은 예측 결과를 출력하는 부분이다.

RBF_Pred = ft.Text('예측 시작')
RBF_btn = ft.IconButton(icon=ft.icons.PLAY_CIRCLE_FILL_OUTLINED, on_click=Prediction)
    
row = ft.Row(controls=[
    RBF_Pred,
    RBF_btn
])
page.add(row)
   
page.update()

 

위의 두 번째 코드는 flet에서 예측 프로그램 실행 버튼 만들며 버튼의 타입은 여러 가지를 제공한다.

여기서는 마우스를 갔다 놓으면 주변에 회색 원을 만들어주는 타입의 버튼을 사용하였다.

그리고 버튼을 클릭하면 ‘Prediction’ 이라는 정의를 실행하도록 한다.

Text와 버튼은 앞에서와 같이 한 행으로 정의하여 보여준다.

 


결과

다음은 프로그램을 실행하면 나오는 창이다.

로또 1등 번호 생성기 결과
(로또 1등 번호 생성기 결과)

 

앞에서 설명했듯이, "로또 회차를 넣으시오"란 입력 힌트에 맞춰 회차 번호를 입력하고 예측 시작 옆의 삼각형 버튼을 누르면 프로그램이 실행된다.

 

로또 1등 번호 생성기 실행 화면
(로또 1등 번호 생성기 실행 화면)

 

참고로 로또는 이전의 결과가 다음의 결과에 전혀 영향을 주지 않는다.

그러므로 사실 이러한 예측이란 건 있을 수 없다.

그렇기 때문에 로또 1등 번호를 예측하겠다는 것에 너무 많은 노력을 들일 필요는 없을 것 같다.

다만 파이썬 프로그램 공부 겸해서 했던 프로젝트 이므로 이를 소개할 뿐이다.

 

마지막으로 서두에도 얘기했듯이 Flet을 이용한 이유는 안드로이드 앱으로 만들기 위해서였는데, 아직 성공하지 못하고 있다.

안드로이드에서 실행할 수 있는 apk 파일로는 변환에 성공했지만 실제로 안드로이드 폰에서 실행해보면 다음과 같은 오류가 발생하고 이러한 문제들을 해결하지 못하고 있다.

혹시 이에 대한 조언을 해줄 수 있으면 댓글을 달아 주시기 바랍니다.

Flet으로 안드로이드 앱 빌드시 에러, No module named 'pandas'
(Flet으로 안드로이드 앱 빌드시 에러, No module named 'pandas')

 

Flet으로 안드로이드 앱 빌드시 에러, module 'os' has no attribute 'add_dll_directory'
(Flet으로 안드로이드 앱 빌드시 에러, module 'os' has no attribute 'add_dll_directory' )
Flet으로 안드로이드 앱 빌드시 에러, No module named 'umpy.core._multiarray_umath'
(Flet으로 안드로이드 앱 빌드시 에러, No module named 'umpy.core._multiarray_umath')
Flet으로 안드로이드 앱 빌드시 에러, No module named 'sklearn.__check_build._check_build'
(Flet으로 안드로이드 앱 빌드시 에러, No module named 'sklearn.__check_build._check_build')

 


 

반응형
LIST