Skip to content

Commit 6088a7d

Browse files
authored
Create Web-based-calculator.py
1 parent c032776 commit 6088a7d

1 file changed

Lines changed: 215 additions & 0 deletions

File tree

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
import math
2+
import tkinter as tk
3+
import ttkbootstrap as tb
4+
from ttkbootstrap.constants import *
5+
from tkinter import filedialog
6+
7+
# ---------------- GLOBALS ---------------- #
8+
current_expression = ""
9+
history = []
10+
memory_value = 0.0
11+
use_degrees = True
12+
13+
SAFE_DICT = {
14+
"sin": lambda x: math.sin(math.radians(x)) if use_degrees else math.sin(x),
15+
"cos": lambda x: math.cos(math.radians(x)) if use_degrees else math.cos(x),
16+
"tan": lambda x: math.tan(math.radians(x)) if use_degrees else math.tan(x),
17+
"log": math.log10,
18+
"ln": math.log,
19+
"sqrt": math.sqrt,
20+
"pi": math.pi,
21+
"e": math.e,
22+
}
23+
24+
# ---------------- FUNCTIONS ---------------- #
25+
def append_char(char):
26+
global current_expression
27+
current_expression += str(char)
28+
display_var.set(current_expression)
29+
30+
def clear_expression():
31+
global current_expression
32+
current_expression = ""
33+
display_var.set("")
34+
35+
def backspace():
36+
global current_expression
37+
current_expression = current_expression[:-1]
38+
display_var.set(current_expression)
39+
40+
def calculate():
41+
global current_expression
42+
try:
43+
result = eval(current_expression, {"__builtins__": None}, SAFE_DICT)
44+
history.append(f"{current_expression} = {result}")
45+
update_history()
46+
current_expression = str(result)
47+
except Exception:
48+
current_expression = "Error"
49+
display_var.set(current_expression)
50+
51+
# -------- Scientific -------- #
52+
def scientific(func):
53+
global current_expression
54+
if func in ["sin", "cos", "tan", "log", "ln", "sqrt"]:
55+
current_expression += f"{func}("
56+
elif func == "x2":
57+
current_expression += "**2"
58+
display_var.set(current_expression)
59+
60+
# -------- History -------- #
61+
def update_history():
62+
history_box.delete(0, tk.END)
63+
for item in reversed(history[-50:]):
64+
history_box.insert(tk.END, item)
65+
66+
def insert_from_history(event):
67+
global current_expression
68+
selection = history_box.curselection()
69+
if selection:
70+
current_expression = history_box.get(selection[0]).split("=")[0].strip()
71+
display_var.set(current_expression)
72+
73+
def export_history():
74+
file = filedialog.asksaveasfilename(
75+
defaultextension=".txt",
76+
filetypes=[("Text File", "*.txt")]
77+
)
78+
if file:
79+
with open(file, "w") as f:
80+
for h in history:
81+
f.write(h + "\n")
82+
83+
# -------- Memory -------- #
84+
def memory_clear():
85+
global memory_value
86+
memory_value = 0.0
87+
88+
def memory_add():
89+
global memory_value
90+
try:
91+
memory_value += float(display_var.get())
92+
except:
93+
pass
94+
95+
def memory_recall():
96+
append_char(memory_value)
97+
98+
# -------- Degree / Radian -------- #
99+
def toggle_mode():
100+
global use_degrees
101+
use_degrees = bool(mode_var.get())
102+
mode_label.config(text="DEG" if use_degrees else "RAD")
103+
104+
# -------- Keyboard Support -------- #
105+
def key_input(event):
106+
if event.char.isdigit() or event.char in "+-*/().":
107+
append_char(event.char)
108+
elif event.keysym == "Return":
109+
calculate()
110+
elif event.keysym == "BackSpace":
111+
backspace()
112+
elif event.keysym == "Escape":
113+
clear_expression()
114+
115+
# ---------------- GUI ---------------- #
116+
app = tb.Window(
117+
themename="darkly",
118+
title="Advanced Web-Style Scientific Calculator",
119+
size=(1000, 600)
120+
)
121+
122+
app.bind("<Key>", key_input)
123+
124+
# ---------------- LEFT PANEL ---------------- #
125+
left_frame = tb.Frame(app)
126+
left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=10, pady=10)
127+
128+
display_var = tk.StringVar()
129+
display = tb.Entry(
130+
left_frame,
131+
textvariable=display_var,
132+
font=("Segoe UI", 24),
133+
justify=tk.RIGHT
134+
)
135+
display.pack(fill=tk.X, pady=10, ipady=10)
136+
137+
btn_frame = tb.Frame(left_frame)
138+
btn_frame.pack(fill=tk.BOTH, expand=True)
139+
140+
buttons = [
141+
["7", "8", "9", "/", "sin"],
142+
["4", "5", "6", "*", "cos"],
143+
["1", "2", "3", "-", "tan"],
144+
["0", ".", "(", ")", "+"],
145+
["pi", "e", "√", "x²", "="]
146+
]
147+
148+
for r, row in enumerate(buttons):
149+
for c, char in enumerate(row):
150+
if char == "=":
151+
cmd, style = calculate, "success"
152+
elif char in ["sin", "cos", "tan"]:
153+
cmd, style = lambda f=char: scientific(f), "info"
154+
elif char == "√":
155+
cmd, style = lambda: scientific("sqrt"), "info"
156+
elif char == "x²":
157+
cmd, style = lambda: scientific("x2"), "info"
158+
else:
159+
cmd, style = lambda v=char: append_char(v), "secondary"
160+
161+
tb.Button(btn_frame, text=char, bootstyle=style, command=cmd)\
162+
.grid(row=r, column=c, sticky="nsew", padx=5, pady=5)
163+
164+
for i in range(5):
165+
btn_frame.columnconfigure(i, weight=1)
166+
btn_frame.rowconfigure(i, weight=1)
167+
168+
# -------- Controls -------- #
169+
control = tb.Frame(left_frame)
170+
control.pack(fill=tk.X, pady=5)
171+
172+
tb.Button(control, text="C", bootstyle="danger", command=clear_expression)\
173+
.pack(side=tk.LEFT, expand=True, fill=tk.X, padx=5)
174+
tb.Button(control, text="⌫", bootstyle="warning", command=backspace)\
175+
.pack(side=tk.LEFT, expand=True, fill=tk.X, padx=5)
176+
177+
# -------- Memory -------- #
178+
mem = tb.Frame(left_frame)
179+
mem.pack(fill=tk.X)
180+
181+
tb.Button(mem, text="MC", command=memory_clear).pack(side=tk.LEFT, expand=True, fill=tk.X)
182+
tb.Button(mem, text="M+", command=memory_add).pack(side=tk.LEFT, expand=True, fill=tk.X)
183+
tb.Button(mem, text="MR", command=memory_recall).pack(side=tk.LEFT, expand=True, fill=tk.X)
184+
185+
# -------- Degree / Radian -------- #
186+
mode_var = tk.IntVar(value=1)
187+
mode_label = tb.Label(left_frame, text="DEG", font=("Segoe UI", 10, "bold"))
188+
mode_label.pack(pady=5)
189+
190+
tb.Checkbutton(
191+
left_frame,
192+
text="Degree Mode",
193+
variable=mode_var,
194+
bootstyle="info",
195+
command=toggle_mode
196+
).pack()
197+
198+
# ---------------- RIGHT PANEL (History) ---------------- #
199+
right_frame = tb.Frame(app)
200+
right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, padx=10, pady=10)
201+
202+
tb.Label(right_frame, text="History", font=("Segoe UI", 14, "bold")).pack()
203+
204+
history_box = tk.Listbox(right_frame, font=("Segoe UI", 10))
205+
history_box.pack(fill=tk.BOTH, expand=True)
206+
history_box.bind("<Double-1>", insert_from_history)
207+
208+
tb.Button(
209+
right_frame,
210+
text="Export History",
211+
bootstyle="primary",
212+
command=export_history
213+
).pack(fill=tk.X, pady=5)
214+
215+
app.mainloop()

0 commit comments

Comments
 (0)