repl.it
@PySimpleGUI/

Lottery - Code Jam Entry Submitted

Tkinter

Code jam entry

fork
loading
Files
  • main.py
  • Lottery_Mega_Millions_Winning_Numbers__Beginning_2002.csv
  • nohup.out
  • Packager files
  • requirements.txt
main.py
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
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
import PySimpleGUI as sg
import csv
import sys
import matplotlib.pyplot as plt
import numpy as np

"""
     Lottery Code Jam - 05/05/2019
     My FIRST Code Jam Ever!

     Long Live PySimpleGUI!
"""

# The fields in the CSV file are:
# Draw Date	Winning Numbers	Mega Ball	Multiplier
# 5/3/2019	08 16 22 66 68	    11      	2
CSV_FILE = r'Lottery_Mega_Millions_Winning_Numbers__Beginning_2002.csv'


# class representing a single lotto winning entry
class LottoEntry:
    def __init__(self, date, numbers, mega, multiplier):
        self.date = date
        self.raw_numbers = numbers
        self.text_numbers = numbers.split(' ')
        self.numbers = [int(i) for i in self.text_numbers]
        self.mega = int(mega)
        self.mega_text = mega
        self.multiplier = int(multiplier) if multiplier != '' else 1
        self.multiplier_text = multiplier


# the entire lotto database, essentially a list of LottoEntry objects
class LottoDatabase:
    def __init__(self, filename):
        self.data = None
        self.headers = None
        self.filename = filename
        self.entries = []  # type: list[LottoEntry]
        self.load(filename)

    def load(self, filename):
        with open(filename, "r") as infile:
            reader = csv.reader(infile)
            self.headers = next(reader)
            try:
                self.data = list(reader)  # read everything else into a list of rows
            except:
                sg.PopupError('Error reading file')
                sys.exit(69)
        self.entries = []
        for row in self.data:
            self.entries.append(LottoEntry(row[0], row[1], row[2], row[3]))


# ---------------------------- Matplotlib helper code ----------------------------
import matplotlib

matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasAgg
import matplotlib.backends.tkagg as tkagg
import tkinter as Tk


def draw_figure(canvas, figure, loc=(0, 0)):
    """ Draw a matplotlib figure onto a Tk canvas

    loc: location of top-left corner of figure on canvas in pixels.

    Inspired by matplotlib source: lib/matplotlib/backends/backend_tkagg.py
    """
    figure_canvas_agg = FigureCanvasAgg(figure)
    figure_canvas_agg.draw()
    figure_x, figure_y, figure_w, figure_h = figure.bbox.bounds
    figure_w, figure_h = int(figure_w), int(figure_h)
    photo = Tk.PhotoImage(master=canvas, width=figure_w, height=figure_h)
    canvas.create_image(loc[0] + figure_w / 2, loc[1] + figure_h / 2, image=photo)
    tkagg.blit(photo, figure_canvas_agg.get_renderer()._renderer, colormode=2)
    return photo


# -------------------------- This program's specific Matplotlib code ----------------------

# Was pressed for time so an inefficient copy and paste of these functions was performed.  One for each graph. 

def plot_multipliers():
    labels = list(range(1, 6))
    multipliers = [e.multiplier for e in lotto_data.entries]
    totals = []
    for l in labels:
        totals.append(multipliers.count(l))
    index = np.arange(len(totals))
    plt.figure(figsize=(5, 4))
    plt.bar(index, totals)
    plt.xlabel('Multiplier', fontsize=12)
    plt.ylabel('Num Times Appeared', fontsize=12)
    plt.xticks(index, labels, fontsize=10, rotation=0)
    plt.title('Multiplier Number Distribution')
    fig = plt.gcf()  # if using Pyplot then get the figure from the plot
    figure_x, figure_y, figure_w, figure_h = fig.bbox.bounds
    return fig, figure_x, figure_y, figure_w, figure_h


def plot_mega():
    megas = [e.mega for e in lotto_data.entries]
    labels = list(range(min(megas), max(megas) + 1))
    totals = []
    for l in labels:
        totals.append(megas.count(l))
    index = np.arange(len(totals))
    plt.figure(figsize=(5, 4))
    plt.bar(index, totals)
    plt.xlabel('Ball Number', fontsize=12)
    plt.ylabel('Num Times Appeared', fontsize=12)
    plt.xticks(index, labels, fontsize=5, rotation=0)
    plt.title('Number of Times Ball Number Was Mega')
    fig = plt.gcf()  # if using Pyplot then get the figure from the plot
    figure_x, figure_y, figure_w, figure_h = fig.bbox.bounds
    return fig, figure_x, figure_y, figure_w, figure_h


def plot_drawn_balls():
    all_nums = []
    for e in lotto_data.entries:
        all_nums += e.numbers
    labels = list(range(min(all_nums), max(all_nums) + 1))
    totals = []
    for l in labels:
        totals.append(all_nums.count(l))
    index = np.arange(len(totals))
    plt.figure(figsize=(5, 4))
    plt.bar(index, totals, .8)
    plt.xlabel('Ball Number', fontsize=12)
    plt.ylabel('Num Times Appeared', fontsize=10)
    plt.xticks(index, labels, fontsize=5, rotation=0)
    plt.title('Frequency Ball in Winning Numbers')
    fig = plt.gcf()  # if using Pyplot then get the figure from the plot
    figure_x, figure_y, figure_w, figure_h = fig.bbox.bounds
    return fig, figure_x, figure_y, figure_w, figure_h


# ------------------------------- Beginning of GUI CODE -------------------------------
sg.ChangeLookAndFeel('GreenTan')

# create a wab give one of those graph functions
def make_tab(title, func):
    fig, x, y, w, h = func()
    tab = sg.Tab(title, [[sg.Canvas(size=(w + 20, h + 20), key=title)]], background_color='#F7F3EC')
    return tab, fig

lotto_data = LottoDatabase(CSV_FILE)

count_mega_in_numbers = 0
for entry in lotto_data.entries:
    if entry.mega in entry.numbers:
        count_mega_in_numbers += 1
#--------- Make tabs and the figures to be drawn later
tab1, fig1 = make_tab('Drawn', plot_drawn_balls)
tab2, fig2 = make_tab('Mega', plot_mega)
tab3, fig3 = make_tab('Multipliers', plot_multipliers)
# This tab is just a table of the data
tab4 = sg.Tab('Raw Data', [
    [sg.Table(lotto_data.data, lotto_data.headers, num_rows=20, alternating_row_color='#F7F3EC', font='ANY 12')]],
              background_color='#F7F3EC')

tab5_layout = [
    [sg.Text(f'Number times Mega was in winning numbers {count_mega_in_numbers}', background_color='#F7F3EC')],
    [sg.T('Check your favorite numbers to see if they were winners', background_color='#F7F3EC')],
    [sg.Slider((0, 75), key=f'_S{i}_', enable_events=True, font='ANY 10') for i in range(5)] +
    [sg.Listbox([], size=(35, 10), key='_LIST_', font='Courier 10')],
    [sg.T('Mega', background_color='#F7F3EC', size=(5, 1)),
     sg.Slider((0, 75), size=(15, 20), orientation='h', enable_events=True, key='_SMEGA_', font='ANY 10'),
     sg.T('', size=(25, 1), background_color='#F7F3EC', key='_TOUT_', text_color='red')],
    [sg.T('Mult', background_color='#F7F3EC', size=(5, 1)),
     sg.Slider((0, 5), size=(15, 20), orientation='h', enable_events=True, key='_SMULT_', font='ANY 10')],
]
tab5 = sg.Tab('Searching', tab5_layout, background_color='#F7F3EC')
# define the window layout
layout = [[sg.Text('Lottery Royal - Data Analysis', font='Any 18'),
           sg.Text(f'{len(lotto_data.data)} Total Draws', text_color='Red', font='Any 16')],
          [sg.TabGroup([[tab1, tab2, tab3, tab4, tab5]])],
          # [sg.Canvas(size=(w, h), key='canvas')],
          [sg.Exit(size=(4, 1))]]

# create the form and show it without the plot
window = sg.Window('Lottery Royal', layout, resizable=True, font='Helvetica 15').Finalize()

# add the plot to the window
fig_photo1 = draw_figure(window.FindElement('Drawn').TKCanvas, fig1)
fig_photo2 = draw_figure(window.FindElement('Mega').TKCanvas, fig2)
fig_photo3 = draw_figure(window.FindElement('Multipliers').TKCanvas, fig3)

# The PySimpleGUI Event Loop
while True:
    event, values = window.Read()
    if event in ('Exit', None):
        break
    if event.startswith('_S'):
        numbers = set([int(values[f'_S{i}_']) for i in range(5)])
        num_matches = 0
        winning_list = []
        for winner in lotto_data.entries:
            found = 0
            all_found = True
            for num in numbers:
                if num == 0:
                    continue
                if num not in winner.numbers:
                    all_found = False
                    break
            if all_found:
                if int(values['_SMEGA_']) and int(values['_SMEGA_']) != winner.mega:
                    continue
                if int(values['_SMULT_']) and int(values['_SMULT_']) != winner.multiplier:
                    continue
                winning_list.append(f'{winner.date} {winner.raw_numbers}  {winner.mega_text}  {winner.multiplier_text} ')
                num_matches += 1

        window.Element('_LIST_').Update(winning_list)
        window.Element('_TOUT_').Update(f'{len(winning_list)} total matching winners')
window.Close()
Fetching token
?