Skip to content

Commit 034e8e3

Browse files
authored
Create InsurePredict.py
1 parent 96e3314 commit 034e8e3

1 file changed

Lines changed: 255 additions & 0 deletions

File tree

Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
"""
2+
InsurePredict v1.0 - Enterprise Edition
3+
Insurance Cost Prediction & Analysis Tool
4+
AI-driven cost predictions with smooth GUI
5+
"""
6+
7+
import os, sys, threading
8+
import tkinter as tk
9+
from tkinter import filedialog, messagebox, ttk
10+
11+
import ttkbootstrap as tb
12+
from ttkbootstrap.constants import *
13+
14+
try:
15+
from tkinterdnd2 import TkinterDnD, DND_FILES
16+
DND_ENABLED = True
17+
except ImportError:
18+
DND_ENABLED = False
19+
print("Drag & Drop requires tkinterdnd2: pip install tkinterdnd2")
20+
21+
import pandas as pd
22+
from sklearn.linear_model import LinearRegression
23+
24+
# ---------------------- UTIL ----------------------
25+
def resource_path(file_name):
26+
base_path = getattr(sys, "_MEIPASS", os.path.dirname(os.path.abspath(__file__)))
27+
return os.path.join(base_path, file_name)
28+
29+
# ---------------------- PREDICTION WORKER ----------------------
30+
class PredictionWorker:
31+
def __init__(self, files, callbacks):
32+
self.files = files
33+
self.callbacks = callbacks
34+
self._running = True
35+
# Dummy regression model (for demonstration)
36+
self.model = LinearRegression()
37+
# Example training on synthetic data
38+
self.model.fit([[18,0],[25,1],[40,1],[60,0]], [2000,3000,4000,3500])
39+
40+
def stop(self):
41+
self._running = False
42+
43+
def run(self):
44+
results = []
45+
total_files = len(self.files)
46+
for i, file in enumerate(self.files):
47+
if not self._running:
48+
break
49+
try:
50+
df = pd.read_csv(file)
51+
# Expected columns: ["age", "smoker"] for simplicity
52+
if "age" in df.columns and "smoker" in df.columns:
53+
pred = self.model.predict(df[["age","smoker"]])
54+
results.append((file, pred.tolist()))
55+
else:
56+
results.append((file, "Missing required columns"))
57+
except Exception as e:
58+
results.append((file, f"Error: {e}"))
59+
60+
# Update progress
61+
if "progress" in self.callbacks:
62+
self.callbacks["progress"](int((i+1)/total_files*100))
63+
if "found" in self.callbacks:
64+
self.callbacks["found"](file, results[-1][1])
65+
66+
if "finished" in self.callbacks:
67+
self.callbacks["finished"]()
68+
69+
# ---------------------- MAIN APP ----------------------
70+
class InsurePredictApp:
71+
APP_NAME = "InsurePredict"
72+
APP_VERSION = "1.0"
73+
SUPPORTED_EXT = (".csv",)
74+
75+
def __init__(self):
76+
if DND_ENABLED:
77+
self.root = TkinterDnD.Tk()
78+
else:
79+
self.root = tb.Window(themename="darkly")
80+
81+
self.root.title(f"{self.APP_NAME} v{self.APP_VERSION}")
82+
self.root.minsize(1000, 600)
83+
84+
self.worker_obj = None
85+
self.smooth_value = 0
86+
self.target_progress = 0
87+
self.file_set = set()
88+
89+
self._build_ui()
90+
self._apply_styles()
91+
92+
# ---------------------- UI ----------------------
93+
def _build_ui(self):
94+
main = tb.Frame(self.root, padding=10)
95+
main.pack(fill=BOTH, expand=True)
96+
97+
tb.Label(main, text=f"💰 {self.APP_NAME} - Insurance Cost Predictor",
98+
font=("Segoe UI", 22, "bold")).pack(pady=(0,4))
99+
100+
tb.Label(main, text="Predict insurance cost from CSV data",
101+
font=("Segoe UI", 10, "italic"), foreground="#9ca3af").pack(pady=(0,20))
102+
103+
# Row 1: File Selection
104+
row1 = tb.Frame(main)
105+
row1.pack(fill=X, pady=(0,6))
106+
107+
self.path_input = tb.Entry(row1, width=80)
108+
self.path_input.pack(side=LEFT, fill=X, expand=True, padx=(0,6))
109+
self.path_input.insert(0, "Drag & drop CSV files here…")
110+
111+
browse_btn = tb.Button(row1, text="📂 Browse", bootstyle=INFO, command=self.browse)
112+
browse_btn.pack(side=LEFT, padx=3)
113+
114+
self.start_btn = tb.Button(row1, text="🚀 Predict", bootstyle=SUCCESS, command=self.start)
115+
self.start_btn.pack(side=LEFT, padx=3)
116+
117+
self.cancel_btn = tb.Button(row1, text="⏹ Cancel", bootstyle=DANGER, command=self.cancel)
118+
self.cancel_btn.pack(side=LEFT, padx=3)
119+
self.cancel_btn.config(state=DISABLED)
120+
121+
export_btn = tb.Button(row1, text="💾 Export Results", bootstyle=PRIMARY, command=self.export_results)
122+
export_btn.pack(side=LEFT, padx=3)
123+
124+
about_btn = tb.Button(row1, text="ℹ️ About", bootstyle=INFO, command=self.show_about)
125+
about_btn.pack(side=LEFT, padx=3)
126+
127+
# Progress
128+
self.progress = tb.Progressbar(main, bootstyle="success-striped", maximum=100)
129+
self.progress.pack(fill=X, pady=(0,6))
130+
131+
# Treeview
132+
columns = ("selected","filename","prediction")
133+
self.tree = ttk.Treeview(main, columns=columns, show="headings", selectmode="extended", height=20)
134+
self.tree.heading("selected", text="✅")
135+
self.tree.heading("filename", text="Filename", anchor=W)
136+
self.tree.heading("prediction", text="Prediction", anchor=W)
137+
self.tree.column("selected", width=50, anchor=CENTER)
138+
self.tree.column("filename", width=600)
139+
self.tree.column("prediction", width=300)
140+
self.tree.pack(fill=BOTH, expand=True, pady=(0,6))
141+
142+
# Timer
143+
self.root.after(15, self.animate_progress)
144+
145+
# Bind DnD if enabled
146+
if DND_ENABLED:
147+
self.tree.drop_target_register(DND_FILES)
148+
self.tree.dnd_bind("<<Drop>>", self.on_drop)
149+
150+
# ---------------------- File Handling ----------------------
151+
def browse(self):
152+
files = filedialog.askopenfilenames(title="Select CSV Files", filetypes=[("CSV Files","*.csv")])
153+
if files:
154+
self._insert_files_chunked(files)
155+
156+
def on_drop(self, event):
157+
dropped_paths = self.root.tk.splitlist(event.data)
158+
self._insert_files_chunked(dropped_paths)
159+
160+
def _insert_files_chunked(self, paths, chunk_size=500):
161+
if not paths:
162+
return
163+
chunk = paths[:chunk_size]
164+
remaining = paths[chunk_size:]
165+
for path in chunk:
166+
ext = os.path.splitext(path)[1].lower()
167+
if ext == ".csv" and path not in self.file_set:
168+
self.file_set.add(path)
169+
self.tree.insert("", END, values=("☑️", path, "Queued"))
170+
self.root.after(1, lambda: self._insert_files_chunked(remaining, chunk_size))
171+
172+
# ---------------------- Actions ----------------------
173+
def start(self):
174+
selected_files = [self.tree.item(i)['values'][1] for i in self.tree.get_children() if self.tree.item(i)['values'][0]=="☑️"]
175+
if not selected_files:
176+
messagebox.showwarning("No Selection", "Select CSV files before predicting.")
177+
return
178+
self.progress["value"] = 0
179+
self.smooth_value = 0
180+
self.target_progress = 0
181+
self.start_btn.config(state=DISABLED)
182+
self.cancel_btn.config(state=NORMAL)
183+
threading.Thread(target=self._run_worker, args=(selected_files,), daemon=True).start()
184+
185+
def _run_worker(self, files):
186+
self.worker_obj = PredictionWorker(files, callbacks={
187+
"found": self.add_prediction,
188+
"progress": self.set_target,
189+
"finished": self.finish
190+
})
191+
self.worker_obj.run()
192+
193+
def add_prediction(self, file, prediction):
194+
for i in self.tree.get_children():
195+
if self.tree.item(i)['values'][1] == file:
196+
self.tree.item(i, values=("☑️", file, str(prediction)))
197+
break
198+
199+
def set_target(self, v):
200+
self.target_progress = v
201+
202+
def animate_progress(self):
203+
if self.smooth_value < self.target_progress:
204+
self.smooth_value += 1
205+
self.progress["value"] = self.smooth_value
206+
self.root.after(15, self.animate_progress)
207+
208+
def cancel(self):
209+
if self.worker_obj:
210+
self.worker_obj.stop()
211+
self.finish()
212+
213+
def finish(self):
214+
self.start_btn.config(state=NORMAL)
215+
self.cancel_btn.config(state=DISABLED)
216+
self.progress["value"] = 100
217+
218+
# ---------------------- Export ----------------------
219+
def export_results(self):
220+
selected_files = [self.tree.item(i)['values'] for i in self.tree.get_children() if self.tree.item(i)['values'][0]=="☑️"]
221+
if not selected_files:
222+
messagebox.showwarning("Export", "No results to export")
223+
return
224+
path = filedialog.asksaveasfilename(defaultextension=".txt", filetypes=[("Text Files","*.txt")])
225+
if path:
226+
with open(path,"w",encoding="utf-8") as f:
227+
for s in selected_files:
228+
f.write(f"{s[1]} | {s[2]}\n")
229+
messagebox.showinfo("Export", "Export completed")
230+
231+
# ---------------------- About ----------------------
232+
def show_about(self):
233+
messagebox.showinfo(f"About {self.APP_NAME}",
234+
f"{self.APP_NAME} v{self.APP_VERSION}\n\n"
235+
"• Predict insurance cost from CSV files\n"
236+
"• Drag & drop support\n"
237+
"• Multi-file batch predictions\n"
238+
"• Export results to text\n\n"
239+
"🏢 Built by Mate Technologies\n"
240+
"🌐 https://matetools.gumroad.com"
241+
)
242+
243+
# ---------------------- Styles ----------------------
244+
def _apply_styles(self):
245+
self.root.style = tb.Style(theme="darkly")
246+
self.root.style.configure("TProgressbar", troughcolor="#1b1f3a", background="#7c3aed", thickness=14)
247+
248+
# ---------------------- Run ----------------------
249+
def run(self):
250+
self.root.mainloop()
251+
252+
# ---------------------- RUN ----------------------
253+
if __name__ == "__main__":
254+
app = InsurePredictApp()
255+
app.run()

0 commit comments

Comments
 (0)