Hi All,
I record my dry fire and live fire par times with an android app called "Dry Fire Par Timer" found here -> https://play.google.com/store/apps/details?id=com.csl1911a1.dryfirepartimer&hl=en_US
I wanted a way to graph the par times for each drill over time and was also looking to learn python so I took this opportunity to write my first python application. To use it copy the the "Dry Fire Par Timer" apps database ( dryfire.db ) to your computer and open it with this python application. I tested it in Linux ( Fedora 29 ) and Windows 10. I'm sure there are some bugs and it's It's not great, just something I did with my spare time. Feel free to use to and provide any feed back or code changes / bug fixes.
#!/usr/bin/env python3
import os
import sqlite3
from tkinter import filedialog
from tkinter import *
import tkinter as tk
import matplotlib.pyplot as plt
from dateutil import parser
from matplotlib import style
style.use('fivethirtyeight')
def get_drills():
c.execute('SELECT _id,event_name FROM dry_fire_event order by event_name')
global data
data = c.fetchall()
def create_list():
my_label_frame = tk.Frame(root, bd=5)
my_label_frame.place(relx=0.5, rely=0.1, relwidth=0.75, relheight=0.1, anchor='n')
my_label = tk.Label(my_label_frame, text="Select a Drill")
my_label.pack(side='top')
global drill_number
global drill_name
my_drill_frame = tk.Frame(root, bd=5)
my_drill_frame.place(relx=0.5, rely=0.15, relwidth=0.75, relheight=100, anchor='n')
my_drill_listbox = tk.Listbox(root, bd=5)
my_drill_listbox.place(relx=0.5, rely=0.15, relwidth=0.75, relheight=0.75, anchor='n')
my_drill_listbox.bind('<<ListboxSelect>>', on_select)
scrollbar = Scrollbar(my_drill_listbox)
scrollbar.pack(side=RIGHT, fill=Y)
for drill_number, drill_name in data:
my_drill_listbox.insert(END, drill_name)
my_drill_listbox.config(yscrollcommand=scrollbar.set)
scrollbar.config(command=my_drill_listbox.yview)
def graph_data():
c.execute('SELECT par_time,date_add from dry_fire_history WHERE fk_event_id = ? order by date_add desc',
(graph_drill_number,))
data_graph = c.fetchall()
dates = []
par_times = []
for row in data_graph:
dates.append(parser.parse(row[1]))
par_times.append(row[0])
plt.figure('Dryfire Drills', figsize=(my_fig_width, my_fig_height), dpi=80)
plt.title(graph_drill_name, )
plt.ylabel('Par Time')
plt.xlabel('Date/Time')
plt.plot_date(dates, par_times, '-')
plt.show()
def open_db_button():
open_button_popup_filename = filedialog.askopenfilename(title="Select Database to Open",
initialdir=os.getcwd(),
filetypes=(("Database File", "*.db"), ("All Files", "*.*")))
global conn
global c
conn = sqlite3.connect(open_button_popup_filename)
c = conn.cursor()
get_drills()
create_drill_button()
create_list()
tk.Button.destroy(my_open_button)
def create_drill_button():
my_drill_button = tk.Button(my_button_frame, text="Graph Selected Drill", command=graph_data)
my_drill_button.pack(side='right')
def on_select(evt):
w = evt.widget
index = int(w.curselection()[0])
drill = data[index]
global graph_drill_number
global graph_drill_name
graph_drill_number = drill[0]
graph_drill_name = drill[1]
my_width = 900
my_height = 800
my_fig_width = 12
my_fig_height = 8
root = tk.Tk()
root.wm_title("Graph Drills")
my_canvas = tk.Canvas(root, height=my_height, width=my_width)
my_canvas.pack()
my_button_frame = tk.Frame(root, bd=5)
my_button_frame.place(relx=0.5, rely=0, relwidth=0.75, relheight=0.1, anchor='n')
my_open_button = tk.Button(my_button_frame, text="Open Drills Database", command=open_db_button)
my_open_button.pack(side='left')
root.mainloop()
c.close()
conn.close()
graph_dryfire_drills.py