파이썬 실전/로또 번호 생성기

파이썬 실전) 로또 번호 생성기 4. 연속 번호 제외

마리사라 2021. 2. 6. 20:53
반응형

이번 강의는 연속 번호 제외 기능을 추가해보도록 하겠습니다.


1. 연속 번호

여러 로또 사이트들에서는 연속 번호 제외 기능이 거의 100% 포함됩니다. 이것은 사람의 심리상 '11번이 나왔으니 다음에는 12번이 연속해서 나오지 않겠지'라는 막연한 기대에서 비롯됩니다. 하지만 과학적으로 모든 번호가 나올 확률은 동일하므로 11번이 나오고 12번이 나올 확률과 연속되지 않는 번호가 나올 확률이 같기 때문에 이 역시 과학적인 방법은 아닙니다.

 

동행 복권 연속 번호 출현 안내란

또한 결과적으로, 연속번호는 생각보다 많이 나오기 때문에 굳이 과학적으로 파고들지 않더라도 연속 번호를 제외하는 것은 의미가 없다는걸 알 수 있습니다.


2. 코드

로또 번호 사이트의 연속수 제거 기능은 2연속 제거, 3 연속 제거 등 연속의 개수를 지정해줄 수 있지만 이번에는 모든 연속을 제거하는 코드로 만들어 보겠습니다.

 

우선 연속수 제거를 체크하는 체크박스를 만들어 줍니다,

self.consecutive_number = wx.CheckBox(panel, id=9, pos=(10, 160), label="연속수 제거")

 

연속 번호를 제거하기 위해서는 연속 번호임을 파악할 수 있어야 하기 때문에 6개의 번호가 모두 나오고 list자료 형으로 바꾼 뒤, 순서대로 정렬한 이후부터 가능합니다.

while len(number) < 6:
    number.add(random.randint(1, 45))
        if len(number) == 6:
            number = list(number)
            number.sort()

그렇기 때문에 while문 뒤에 if문으로 번호가 6개 일 때 연속 번호를 삭제한다면 add로 다시 번호를 추가할 수 있을 것입니다.

 

이제부터 연속 번호 제거 코드입니다.

if self.consecutive_number.GetValue():
    for j in range(len(number) - 1):
        try:
            if number[j] + 1 == number[j + 1]:
                del number[j + 1]
        except:
            pass
    if not len(number) == 6:
        number = set(number)
        if self.fixed_number_check.GetValue():
            try:
                fixed_number_1 = int(self.fixed_number_1.GetValue())
                number.add(fixed_number_1)
            except:
                pass
            try:
                fixed_number_2 = int(self.fixed_number_2.GetValue())
                number.add(fixed_number_2)
            except:
                pass

if문은 연속 번호 제거 체크박스가 활성화되어 있을 경우에만 진행됩니다. 이후 for문을 통해 (현재 수 + 1)이다음 수와 같으면 연속 번호 이기 때문에 다음 수를 제거합니다. 이때 2개 이상 제거하면 리스트의 원소는 4개인데 5번째 원소를 호출하는 일이 발생할 수 있으므로 try/except문을 이용하여 에러를 무시하도록 합니다. 마지막으로 리스트의 원소의 개수가 6개가 되지 않는다면 번호를 다시 추가해 주어야 하기에 집합 자료형으로 바꾸어 줍니다. 마지막으로 고정수가 제거되었을 수도 있기 때문에 다시 추가해 줍니다. 이 부분은 여러 기능이 완성된 다음 모듈화 해 주도록 하겠습니다.

 

이제 결과 화면입니다.

좌 : 초기 화면 / 중 : 연속수 허용 / 우 : 연속수 제거

중앙의 사진에서 2번째를 보시면 4와 5로 연속된 숫자가 나왔습니다. 하지만 연속수 제거를 킨 오른쪽 사진에서는 연속수는 나오지 않습니다.


3. 마치며

이번 시간에는 연속수 제거 기능을 만들어 보았습니다. 앞서 말했듯 연속수 제거가 도움은 되지 않지만 로또 번호 사이트에서 사용하는 필터링이라서 만들었습니다.

import random
import wx


class Mainframe(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(300, 450))
        panel = wx.Panel(self)
        self.count = wx.TextCtrl(panel, id=1, pos=(5, 5))
        self.count.SetHint("시행 횟수 입력")
        self.generate_button = wx.Button(panel, id=2, label='생성', pos=(5, 50))
        self.output = wx.ListBox(panel, id=3, choices=[], pos=(120, 5), size=(150, 400))

        fixed_number_box = wx.StaticBox(panel, id=5, label="고정수", pos=(5, 100), size=(80, 50))
        self.fixed_number_1 = wx.TextCtrl(fixed_number_box, id=6, size=(30, 20), pos=(5, 20))
        self.fixed_number_2 = wx.TextCtrl(fixed_number_box, id=7, size=(30, 20), pos=(40, 20))
        self.fixed_number_check = wx.CheckBox(panel, id=8, pos=(100, 120))

        self.consecutive_number = wx.CheckBox(panel, id=9, pos=(10, 160), label="연속수 제거")

        self.Bind(wx.EVT_BUTTON, self.lotto, id=2)

    def lotto(self, event):
        for i in range(int(self.count.GetValue())):
            number = set()
            if self.fixed_number_check.GetValue():
                try:
                    fixed_number_1 = int(self.fixed_number_1.GetValue())
                    number.add(fixed_number_1)
                except:
                    pass
                try:
                    fixed_number_2 = int(self.fixed_number_2.GetValue())
                    number.add(fixed_number_2)
                except:
                    pass
            while len(number) < 6:
                number.add(random.randint(1, 45))
                if len(number) == 6:
                    number = list(number)
                    number.sort()
                    if self.consecutive_number.GetValue():
                        for j in range(len(number) - 1):
                            try:
                                if number[j] + 1 == number[j + 1]:
                                    del number[j + 1]
                            except:
                                pass
                        if not len(number) == 6:
                            number = set(number)
                            if self.fixed_number_check.GetValue():
                                try:
                                    fixed_number_1 = int(self.fixed_number_1.GetValue())
                                    number.add(fixed_number_1)
                                except:
                                    pass
                                try:
                                    fixed_number_2 = int(self.fixed_number_2.GetValue())
                                    number.add(fixed_number_2)
                                except:
                                    pass
            self.output.Append(str(number))


def run():
    app = wx.App()
    frame = Mainframe(None, -1, 'Lotto Number Generator')
    frame.Show()
    app.MainLoop()


run()
반응형