<개인공부>/[Python]

[python] 파이썬 로또 프로그램

BlockDMask 2019. 11. 26. 02:18
반응형

안녕하세요. BlockDMask 입니다.

요즘 파이썬 공부를 시작했는데, 책만 보다보니 조금 지겹더군요.

역시 프로그래밍 언어 공부는 무언가를 만들면서 해야지 실력과 흥미가 쑥쑥 오르는것 같습니다.

그래서 오늘은 간단하게 짬나는 시간에 (약속장소에 여친이 나타나기 전까지) 파이썬 프로그램을 한번 만들어보려합니다.

간단한 python 프로그램인 만큼 프로그램을 만들때 처음부터 어떤식으로 만들었는지 step 별로 작성을 해보겠습니다.

"프로그램을 만든다!" 했을때 바로 코드로 가지 않고 기획서(?) 어떤 규칙으로 프로그램을 만들지 정리를 한 후에 프로그램을 만드는것이 더 좋은 방법이라고 생각합니다.

여러분들도 이런 방법으로 하고계시죠?

자 그럼 간단한 로또 프로그램 파이썬 프로젝트 시작해보겠습니다.


<목차>

1. python 로또 프로그램

2. 파이썬 로또 프로그램 소스코드


1. 파이썬으로 로또 프로그램 만들기


 [STEP1] 로또 프로그램 규칙 정하기.

1) 1~45 번 까지 숫자를 중복없이 6개를 뽑아야합니다.

2) 6개를 뽑고 +1개 를 더 뽑습니다.

3) 처음뽑은 6개가 일치하면 1등

4) 처음 뽑은 6개중 5개가 일치하고 +1 개가 일치하면 2등

5) 1등과 2등만 계산하겠습니다. 3등 이하는 기분나쁘기 때문에. (하나 더맞으면 2등이고! 제대로 맞으면 1등인데!! 3등은 억울하지 않씁니꽈!!)

6) 기능1. 프로그램은 무작위로 6개 +1개의 숫자를 뽑아 줄 수 있습니다. (뽑은 당첨번호는 프로그램이 종료 될때 까지 or 새롭게 뽑기 전까지 유지됨)

7) 기능2. 프로그램은 사용자가 6개의 숫자를 넣게 되면, 아까 뽑은 당첨번호를 뽑아서 1등인지 2등인지 맞춰줍니다. 

8) 기능3. 새롭게 당첨번호 6개 + 1개를 뽑을 수 있습니다.


▶ [STEP2] 파이썬 로또 프로그램 규칙에서 조심해야할것 생각하기.

- 규칙1번, 2번에서 중복없이 6개 +1개를 뽑아야합니다. 어떤식으로 중복을 체크해야할까?

- 규칙3,4번에서 처음뽑은 6개와 그 다음에 뽑은 1개를 어떤식으로 구분해야할까?


▶ [STEP3로또 프로그램 규칙에서 생길만한 버그 생각해보기.

(유저가 발견해서 제보 하면 버그이고, 그전에 플머가 생각해서 하면 예외처리)

예상 버그1) 유저의 입력이 1~45 사이의 번호가 아닌 46번 이상의 숫자가 들어올때

예상 버그2) 유저가 6개 보다 적은 숫자를 입력했을 때

예상 버그3) 유저가 6개 보다 많은 숫자를 입력했을 때

예상 버그4) 유저가 숫자가 아닌 문자를 넣었을 때


▶ [STEP4로또 프로그램 설계(?) 어떤식으로 구현할지 생각해보기.

- 1~45 까지의 숫자 중에 랜덤하게 수를 뽑는다.             // 파이썬 random 모듈 이용.

- 랜덤한 수를 뽑을때 숫자를 어떤 형태로 저장해야할까? // 리스트?, 튜플?, 집합 set?

- 뽑은 숫자를 프로그램이 끝날때 까지 저장한다.          //클래스의 멤버변수로 다뤄야할까?

- 유저가 입력한 숫자랑 뽑은 숫자가 일치하는지 봐야한다. //클래스의 함수?

- 1,2등은 어떻게 구분해야할까?

 : 1,2,3,4,5,6 이 있고 추가로 7이 뽑혔다고 할때.

 : 1,2,3,4,5,6 중 6개가 다맞으면 1등.

 : 1,2,3,4,5,6 중 5개가 맞고 추가로 뽑은 7이랑 맞으면 2등.


▶ 자료형에 대한 고민 (리스트 vs 집합set)

리스트를 사용하게 되면 sort가 되기 때문에 숫자를 처음부터 넣을수는 있습니다.

하지만 중복제거를 따로 챙겨야하기 때문에 불편하다고 생각하였습니다.


집합 set으로 구현한다면 순서는 오락가락 하겠지만, 순서는 화면에 출력이 필요할때마다 리스트에 복사해서 sort 후 출력하는게 더 괜찮지 않을까 싶어서 그렇게 구현했습니다.

또한, 집합 set으로 구현하려고 결정한 이유 두가지는

- 중복제거가 스스로 된다는 점과

- 교집합으로 6개가 맞는지 5개가 맞는지 확인이 편리하다는 점 입니다.


결론적으로 set을 판단한 것에 정리를 하자면 그냥 리스트말고 집합 사용하고 싶었습니다........


(제 구현이 정답은 아닙니다. 저도 파이썬에 이제 입문한 초보 입니다. 또한, 프로그래밍에 정답은 없다는점. 미리 알려드리고 싶습니다.)


2. 로또 프로그램 실행 영상

바로가기 : https://youtu.be/QKE0rWpERVQ


3. 파이썬 프로그램 로또 소스코드


▶ 프로그램 소스코드. 


소스코드 : https://github.com/BlockDMask/Lotto


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Lottery.py
import random
 
 
class Lotto:
    # 생성자
    def __init__(self):
        self.win = set()  # 6개의 당첨번호 (중복불가)
        self.bonus = set()  # 1개의 2등 번호
        self.myNum = set()  # 내가 입력한 번호
 
    # 로또 숫자 초기화 함수
    def init(self):
        self.win.clear()  # set 초기화
        self.bonus.clear()  # set 초기화
        while len(self.win) < 6:
            self.win.add(random.randrange(146))  # 1~45 사이의 숫자를 중복 없이 입력.
            # 집합 자료형이므로 알아서 중복 제외.
 
        while True:
            n = random.randrange(146)
            if not (n in self.win):  # 이미 뽑은 6개의 당첨번호와 다른 +1 번호를 받아야함.
                self.bonus.add(n)
                break
 
cs

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
    # 로또 번호를 입력 받는 함수
    def insert(self):
        self.myNum.clear()
        while len(self.myNum) < 6:
            print(str([len(self.myNum) + 1]) + "번째 숫자를 입력하세요. (1~45) : ", end="")
            n = int(input())  # 입력받음.
            if (n <= 0or (n >= 46or (n in self.myNum):  # 1~45를 벗어나거나 중복된것 제외
                print("=> 중복된 번호를 넣었거나 잘못된 번호를 넣었습니다. 다시 입력해주세요.")
                continue
            self.myNum.add(n)  # 입력넣기
            print("현재까지 번호 : " + str(list(self.myNum)))
 
    # 로또 번호 매칭해보는 함수
    def match(self):
        if len(self.myNum) != 6:
            print("=> 2번을 눌러서, 내 번호를 입력해주세요.")
            return
 
        self.print()
        self.printMyNum()
        matchingNum = len(self.win.intersection(self.myNum))
        if matchingNum == 6:
            print("=> [1등] 6개가 다 맞았습니다!!!")
            print("=> 세금 떼고 10억 입니다. (물론 꿈이죠..)")
        elif matchingNum == 5 and self.myNum.intersection(self.bonus):
            print("=> [2등] 5개 + bonus 가 맞았습니다!!!")
            print("=> 세금 떼고 6000만원 입니다. (전세집도 못가요...)")
        else:
            print("=> 꽝입니다. 일확천금을 노리지 말고 우리 적금할까요?")
 
    # 내가 입력한 번호 출력
    def printMyNum(self):
        print("내 번호 : ", end="")
        tmp = list(self.myNum)
        tmp.sort()
        print(tmp)
 
    # 로또 번호 출력 함수
    def print(self):
        print("이번주 번호 : ", end="")
        arr = list(self.win)
        arr.sort()
 
        print(arr, end="")
        print(" +", list(self.bonus))
 
 
print("=> 로또 프로그램을 실행합니다...")
lotto = Lotto()
lotto.init()
while True:
    print("===========================")
    print("1. 이번주 로또 번호를 봅니다.")
    print("2. 내 로또 번호를 입력합니다.")
    print("3. 새로운 로또 번호를 받습니다.")
    print("4. 이번주 번호와 내 로또번호를 확인합니다.")
    print("5. 프로그램을 종료합니다.")
    print("by. BlockDMask ============")
    num = int(input())
    if num == 1:
        print("이번주 로또 번호를 봅니다...")
        lotto.print()
    elif num == 2:
        print("로또 번호 6자리를 입력해주세요...")
        lotto.insert()
        lotto.printMyNum()
    elif num == 3:
        print("새로운 로또 번호를 받습니다...")
        lotto.init()
        lotto.print()
    elif num == 4:
        print("과연, 1등일까요? 2등일까요? 꽝일까요...?")
        lotto.match()
    elif num == 5:
        print("프로그램을 종료합니다...")
        break
    print()
 
cs


이상, 파이썬으로 간단한 프로그램 로또 프로그램 만들기였습니다.감사합니다.

소스코드 : https://github.com/BlockDMask/Lotto

반응형