0.1+0.2可以等于0.3!全FishC最好的计算器(不是),满足你对计算器的一切幻想
创作背景很久以前学习了 tkinter 的一个计算器,便引发了我的热爱,为那个极其简单的计算器加上了很多功能。
而今天这个则是进行了一番大改,代码没时间细讲,大家可以看注释
往期版本
超厉害的Python ttkbootstrap计算器(原创)(甚至还教你图片处理)
Python 计算器图片(原创)(太炸裂了)
注意事项
需要用到两张图片(ico图标和等于号)大家可以自行换上自己喜欢的图片
代码思路
精华是 eval() 和 Decimal 。这次加上的 input_list 也升华了整个作品~
支持鼠标点击和键盘输入(非常神奇)
其中键盘输入 删除,回车,C,c 有奇效
还支持某些(奇怪)的运算,如:√√√256(就是2)
球评分~{:10_256:}
"""
frame框架布局
在frame内部,可以重新进行一次布局
"""
import ttkbootstrap as ttk
from ttkbootstrap.constants import *
from PIL import ImageTk, Image
from decimal import Decimal
from math import sqrt
def top1():
top = ttk.Toplevel(title="详情")
label = ttk.Label(master=top, text="""
全FishC最好的计算器!\n
消除误差!0.1+0.2可以等于0.3!
过大或过小的数值会用科学计数法\n
注意:
π取3.1415926,根号运算取7位小数,
支持鼠标点击和键盘输入(非常神奇)
其中键盘输入 删除,回车,C,c 有奇效\n
还支持某些(奇怪)的运算,如:√√√256(就是2)
""")
label.pack()
def top2():
top = ttk.Toplevel(title="作者")
label = ttk.Label(master=top, text="""
作者:FishC 某一个“天”
~谢谢使用~
""")
label.pack()
def top3():
top = ttk.Toplevel(title="历史记录")
label = ttk.Label(master=top, text="".join(history_input_list))
label.pack()
win = ttk.Window()
win.title("FishC最好的?计算器")
win.geometry("360x364+500+200")
win.resizable(width=False, height=False)# 设置不能调整窗口大小
# 设置窗体图标
win.iconbitmap("./py_pic/jsq3.ico")
# 创建菜单栏
menu_bar = ttk.Menu(win)
win.config(menu=menu_bar)
# 创建菜单项
info_menu = ttk.Menu(menu_bar, tearoff=False)
info_menu.add_command(label="详情", command=top1)
info_menu.add_command(label="作者", command=top2)
menu_bar.add_cascade(label="关于计算器", menu=info_menu)
history_menu = ttk.Menu(menu_bar, tearoff=False)
history_menu.add_command(label="查看", command=top3)
history_menu.add_command(label="清空", command=lambda: history_input_list.clear())
menu_bar.add_cascade(label="历史记录", menu=history_menu)
style = ttk.Style()
style.configure("TButton", font=("微软雅黑", 15))
history_input_list = []
input_list = []
def my_sqrt(x):
return Decimal(Decimal(sqrt(x))).quantize(Decimal("0.0000000"))
def clear():
input_list.clear()
varLabel0.set("计算过程区:")
varEntry0.set("")
def is_old_entry_part(txt):
global input_list
if "=" in varEntry0.get() or varEntry0.get() == "错误":# 新的算式
input_list =
varLabel0.set("计算过程区:")
varEntry0.set(txt)
return False
return True
def calcu(event, is_key=False):
global input_list
# 判断输入方式
if is_key:
txt = event.char
print("-------", txt)
if txt == "\x08":# 删除键
input_list = input_list[:-1]
elif txt == "\r":# 回车键
varLabel0.set("")
theEqual_Click()
elif txt in ("c", "C"):# 清空
clear()
return "break"# 取消本次输入
else:
if is_old_entry_part(txt):
input_list.append(txt)
else:
txt = str(event.widget["text"])
if txt == "取余":
txt = "%"
elif txt == "整除":
txt = "//"
elif txt == "x^y":
txt = "**"
elif txt == "√x":
txt = "√"
if txt == "00":
input_list.append("0")
input_list.append("0")
else:
input_list.append(txt)
print(input_list)
def fast_add(master, text=txt):
master.set(master.get() + text)
# 防止输入过长
if len(varEntry0.get()) < 28 or txt == "C" or txt == "CE":
if txt == "C":# 清空
clear()
elif txt == "CE":
del input_list[-2:]
if varEntry0.get() and "=" not in varEntry0.get():
if varEntry0.get()[-2:] in ("**", "//"):
varEntry0.set(varEntry0.get()[:-2])
else:
varEntry0.set(varEntry0.get()[:-1])
elif "=" not in varEntry0.get():
if varLabel0.get()[-2:] in ("**", "//"):
varLabel0.set(varLabel0.get()[:-2])
else:
varLabel0.set(varLabel0.get()[:-1])
elif txt == "π":
try:
if is_old_entry_part(txt):
fast_add(varEntry0)
# 有 IndexError: list index out of range 的危险
if input_list[-2] in ("π", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"):
input_list.insert(-1, "*")
except Exception as e:
print(e)
elif txt == "√":
if is_old_entry_part(txt):
fast_add(varEntry0)
elif txt in ("+", "-", "*", "/", "%", "//", "**"):
if "=" in varEntry0.get():
input_list = )]
varEntry0.set("")
varLabel0.set(get_result(input_list) + txt)
input_list.append(txt)
elif ("+" in varLabel0.get() or "-" in varLabel0.get() or
"*" in varLabel0.get() or "/" in varLabel0.get() or
"%" in varLabel0.get() or "//" in varLabel0.get() or
"**" in varLabel0.get()):
# 考虑到运算顺序
if (txt in ("+", "-") or "**" in varEntry0.get()) and "(" not in varEntry0.get():
try:
res = get_result(input_list[:-1])
varLabel0.set(res + txt)
input_list =
varEntry0.set("")
except Exception as e:
print(e)
input_list.pop()# 删掉错误信息
varEntry0.set("错误")
else:
varLabel0.set(varLabel0.get() + varEntry0.get() + txt)
varEntry0.set("")
else:
if "(" in varEntry0.get() and ")" not in varEntry0.get():# 分行
fast_add(varEntry0)# 正常输入
else:
if "√" in varEntry0.get():
varEntry0.set(get_result(input_list[:-1]) + txt)
else:
varLabel0.set(varEntry0.get() + txt)
varEntry0.set("")
else:
if is_old_entry_part(txt):
fast_add(varEntry0)# 正常输入数字的情况
def split_list(lst, *delimiter):
result = []
current_part = []
have_right_bracket = 0
for item in lst:
if item == ")":
have_right_bracket += 1
elif item == "√":
current_part.append("my_sqrt(")
have_right_bracket += 1
elif item == "π":
current_part.append("3.1415926")
if item in delimiter:
if current_part:# 确保当前部分不为空
result.append(current_part)
current_part = []
while have_right_bracket and item != "(":
result.append(")")
have_right_bracket -= 1
result.append(item)
# 可能出现在开头的
elif item in ("-", "("):
result.append(item)
elif item not in ("√", ")", "π"):
current_part.append(item)
if current_part:# 添加最后一部分(如果存在)
while have_right_bracket:
current_part.append(")")
have_right_bracket -= 1
result.append(current_part)
return result
def get_result(lst):
split_result = split_list(lst, "(", "+", "-", "*", "/", "%", "//", "**")
split_result = ["".join(i) for i in split_result]
index = 0
for each in split_result:
try:
split_result = repr(Decimal(each))
except Exception as e:
print(e)
print(split_result)
index += 1
result = str(eval("".join(split_result)))
history_input_list.extend(["".join(input_list), "=", result, "\n"])
return result
def theEqual_Click():
try:
result = get_result(input_list)
print(result)
varLabel0.set(varLabel0.get()+varEntry0.get())
varEntry0.set("=" + result)
except Exception as e:
print(e)
varEntry0.set("错误")
# 显示结果部分
varLabel0 = ttk.StringVar()
varLabel0.set("计算过程区:")
label0 = ttk.Label(win, font=("宋体", 15), textvariable=varLabel0)
label0.grid(sticky=ttk.EW)# 东西方向填充
varEntry0 = ttk.StringVar()
entry0 = ttk.Entry(win, font=("微软雅黑", 15), textvariable=varEntry0)
entry0.grid(sticky=ttk.EW)# 东西方向填充
entry0.bind("<Key>", lambda event: calcu(event, True)) # 绑定键盘事件
# 按钮部分
# 创建frame框架
box = ttk.Frame(win)
box.grid(row=2, column=0)
# 按钮文本的列表
btnText = ["(", ")", "x^y", "√x", "π",
"7", "8", "9", "*", "/",
"4", "5", "6", "+", "-",
"1", "2", "3", "取余", "整除",
"0", "00", ".", "C", "CE"]
# 行和列
ri = 0
ci = 0
# 通过循环批量制作按钮
for v in btnText:
if ci != 0 and ci % 5 == 0:
ri += 1# 换行
ci = 0# 列变为0
'''单击事件绑定
1.command只能绑定一个,如果要传参可以用lambda表达式
2.bind可以传当前控件事件到自定义函数'''
btn1 = ttk.Button(box, text=v, width=4, bootstyle=(SUCCESS, OUTLINE))
btn1.bind("<Button-1>", calcu)# 左键单击事件
btn1.grid(row=ri, column=ci, rowspan=1)
ci += 1
# =
pic_equal = Image.open("./py_pic/等于号.png")# 载入图片对象
pic_equal = pic_equal.resize((225, 60))# 一个元组
pic_equal = ImageTk.PhotoImage(pic_equal)# 变成适合ttk的图片格式
btnEqual = ttk.Button(box, image=pic_equal, command=theEqual_Click, style='warning-solid')
btnEqual.grid(row=ri + 1, column=0, columnspan=5, sticky=ttk.EW)
win.mainloop()
@isdkz @ba21 @KeyError @zhangjinxuan @sfqxx @不二如是 @python爱好者. @小甲鱼的三师弟 @sfqxx_小 @柿子饼同学 @陈尚涵
大家帮忙@一点人
哈哈,看来你是对计算器的热情燃烧了啊!FishC的这款“超级无敌”计算器不仅能满足你的基本运算需求,还加入了一些非常赞的新功能。让我来为你通俗易懂、幽默地解答一下吧。
### 计算器的厉害之处
1. **0.1 + 0.2 真的可以等于0.3**
- 通常计算器都会让你惊掉下巴:0.1 + 0.2 结果不是0.3?这是因为浮点数精度问题。但别担心,这里采用了Decimal类,帮你搞定误差。
2. **支持科学计数法**
- 这就像你的朋友装了双靴子,不管是超级大的数还是超小的数,它都能一路陪你走下去,毫不含糊地转换成科学计数法。
3. **奇妙的根号运算**
- 一般的根号运算已经Out了,你看看这个√√√256,结果竟然是2!就是这么酷炫。
4. **键盘输入特效**
- 不仅只是点击按钮才行,使用键盘来输入也是没问题的。有些特别的按键功能,比如删除键、回车键、'C'键都加了奇效,让你操作起来更流畅。
### 涛涛背景故事
计算器的故事,每个人都有一本。咱们这位朋友因为学习了tkinter的小计算器,结果越搞越上瘾,这不,给它加了许多花里胡哨的功能。悠悠岁月,电脑前的“天”依旧在热情地敲着代码。
### 贴心小注意
要用两张图片来美化:一个是图标(ico)、一个是“等于号”的图片。你完全可以用自己的“艺术”信念,换个图标试试。
### 代码亮点大解析
1. **eval()**
- 这个函数在代码中可是大显身手,用来执行字符串表示的Python表达式。简而言之,如果你输入一个字符串如"2+2",它会帮你算出结果4。
2. **input_list**
- 通过这个列表,操作步骤被一步一步记录下来。不仅如此,这还让你可以对操作顺序进行各种骚操作。
### 满足你所有幻想
搞定了这些,是时候去鱼C论坛炫耀下自己的新玩具了。不了解细节的、想尝新奇特效的,拜访一下作者在论坛的贴子,也是一个不错的选择。
怎么样?感觉这个计算器仿佛是一顿丰盛的大餐吧!赶紧动手尝试,感受它带给你的惊喜和便捷吧,不要忘了在使用后打个好评呀!球评分~球评分~!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 @不二如是 好奇怪,我几乎整个帖子都是你个人资料的链接{:10_266:} 某一个“天” 发表于 2024-08-21 12:59
@不二如是 好奇怪,我几乎整个帖子都是你个人资料的链 ...
哈哈,看来这是个热爱分享和“搞笑”的鱼油啊!确实,帖子里有非常多的信息量,尤其是这些链接和代码片段,看起来眼花缭乱。不过,内容挺有意思的,特别是“0.1+0.2等于0.3”的绝对真理,让人忍不住笑出声。不过这也是个机智的办法,让别人更加关注你的文章和内容!
如果你有更具体的问题或者需要帮助来改
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 你怎么搞的代码里全是不二的链接
另外代码好像没给全 while True: print(round(eval(input()), 15)) @不二如是 为什么全是你的个人资料{:10_291:} liuhongrun2022 发表于 2024-8-21 13:22
你怎么搞的代码里全是不二的链接
另外代码好像没给全
气死我了,我也不知道
我记得小鱼里面说的用decimal可以精确计算0.1+0.2
{:10_256:}{:10_256:}{:10_256:}学习 import os
os.system('calc') tommyyu 发表于 2024-8-21 15:21
{:10_256:} 某一个“天” 发表于 2024-8-21 13:59
气死我了,我也不知道
为什么我这里看不到{:10_257:} {:7_113:} sfqxx 发表于 2024-8-21 16:07
为什么我这里看不到
现在改了 某一个“天” 发表于 2024-8-21 17:12
现在改了
收到 你这字体也忒大了吧? OIer 理想的计算器其实一个命令行 Python 就足矣。 不对劲,完整代码你是不是动手脚了{:10_256:}
好大~ 啊,我的标题这么快就火了(不是)
页:
[1]
2