MagicforestA 2022-09-04 12:44 采纳率: 100%
浏览 61
已结题

python简易计算器

一段用python写的简易计算器代码,然后对于其中一些代码的用处不是很理解,
请求协助解释一下,提问都在注释里

import tkinter as tk

ERROR = "Error!"

def string_to_double(s):
    try:
        val = float(s);#display_str.get()得到的是字符串,然后float(s)就可以直接转化成float type了?
        return val;
    except ValueError:#这里用except是不是有点多余,一般按的都是数字,也没法按字符串
        return None

def clear_if_error():
    s = display_str.get()
    if s == ERROR:
        display_str.set("0")

def double_to_string(v):
    s = str(v)
    if 'e' in s:
        return ERROR
    if '.' in s:
        while s[-1] == '0':
            s = s[0:-1]
    while len(s) > 10 and s[-1] != '.':#如果len(s)>10了,岂不是要出错了?这里用while的意义是什么
        s = s[0:-1]
    if s[-1] == '.':
        s = s[0:-1]
    if len(s) > 10:
        return ERROR
    return s

def do_clear():
    global accumulator, last_operation
    display_str.set("0")
    accumulator = 0.
    last_operation = ""


def do_digit_0():
    clear_if_error()
    s = display_str.get()
    if len(s) < 10 and s != "0":
        display_str.set(s + '0')


def do_digit_x(dig):
    clear_if_error()
    s = display_str.get()
    if len(s) < 10:
        if s == "0":
            display_str.set(dig)
        else:
            display_str.set(s + dig)


def do_dot():
    clear_if_error()
    s = display_str.get()
    if len(s) < 10 and "." not in s:
        display_str.set(s + ".")


def do_plus():
    global last_operation, accumulator
    clear_if_error()
    last_operation = "+"
    accumulator = string_to_double(display_str.get())
    display_str.set("0")


def do_minus():
    global last_operation, accumulator
    clear_if_error()
    last_operation = "-"
    accumulator = string_to_double(display_str.get())
    display_str.set("0")


def do_mult():
    global last_operation, accumulator
    clear_if_error()
    last_operation = "*"
    accumulator = string_to_double(display_str.get())
    display_str.set("0")


def do_divd():
    global last_operation, accumulator
    clear_if_error()
    last_operation = "/"
    accumulator = string_to_double(display_str.get())
    display_str.set("0")


def do_equal():
    global last_operation, accumulator
    clear_if_error()
    value = string_to_double(display_str.get())
    if last_operation == "+":
        accumulator += value#举个例子,如果运行3+4,是不是accumulator=3,value=4,然后accumulator=7,为什么accumulator会认定是3,value会认定是4?
    elif last_operation == "-":
        accumulator -= value
    elif last_operation == "*":
        accumulator *= value
    elif last_operation == "/":
        if value != 0:
            accumulator /= value
        else:
            display_str.set(ERROR);
            return;
    display_str.set(double_to_string(accumulator))#根据计算器运行,如果我按一个数字,譬如说7,然后直接按等号"=",然后entry里显示0,但在do_equal()这个函数里并没有表示有这么一个功能


def do_plusminus():
    clear_if_error()
    display_str.set(double_to_string(-string_to_double(display_str.get())))


window = tk.Tk()
window.title('Calc')
display_str = tk.StringVar()
display_str.set("0")
stick = tk.N + tk.S + tk.E + tk.W#这个上北下南左西右东的格局是用加号做布置的?
display = tk.Entry(window, width=10, font=("Courier New", "15", "bold"), textvariable=display_str, justify=tk.RIGHT)
display.grid(row=0, columnspan=5, sticky=stick)
digit7 = tk.Button(window, text="7", command=lambda: do_digit_x("7"))#为什么这里需要用到lambda?
digit7.grid(row=1, column=0, sticky=stick)
digit8 = tk.Button(window, text="8", command=lambda: do_digit_x("8"))
digit8.grid(row=1, column=1, sticky=stick)
digit9 = tk.Button(window, text="9", command=lambda: do_digit_x("9"))
digit9.grid(row=1, column=2, sticky=stick)
plus = tk.Button(window, text="+", command=do_plus)
plus.grid(row=1, column=4, sticky=stick)
digit4 = tk.Button(window, text="4", command=lambda: do_digit_x("4"))
digit4.grid(row=2, column=0, sticky=stick)
digit5 = tk.Button(window, text="5", command=lambda: do_digit_x("5"))
digit5.grid(row=2, column=1, sticky=stick)
digit6 = tk.Button(window, text="6", command=lambda: do_digit_x("6"))
digit6.grid(row=2, column=2, sticky=stick)
minus = tk.Button(window, text="-", command=do_minus)
minus.grid(row=2, column=4, sticky=stick)
digit1 = tk.Button(window, text="1", command=lambda: do_digit_x("1"))
digit1.grid(row=3, column=0, sticky=stick)
digit2 = tk.Button(window, text="2", command=lambda: do_digit_x("2"))
digit2.grid(row=3, column=1, sticky=stick)
digit3 = tk.Button(window, text="3", command=lambda: do_digit_x("3"))
digit3.grid(row=3, column=2, sticky=stick)
equal = tk.Button(window, text=" = ", command=do_equal)
equal.grid(row=3, column=3, sticky=stick)
mult = tk.Button(window, text="*", command=do_mult)
mult.grid(row=3, column=4, sticky=stick)
digit0 = tk.Button(window, text="0", command=do_digit_0)
digit0.grid(row=4, column=0, sticky=stick)
dot = tk.Button(window, text=" . ", command=do_dot)
dot.grid(row=4, column=2, sticky=stick)
clear = tk.Button(window, text="C", command=do_clear)
clear.grid(row=4, column=1, sticky=stick)
plusminus = tk.Button(window, text="+/-", command=do_plusminus)
plusminus.grid(row=4, column=3, sticky=stick)
divd = tk.Button(window, text="/", command=do_divd)
divd.grid(row=4, column=4, sticky=stick)
accumulator = 0.
last_operation = ""
window.mainloop()


  • 写回答

4条回答 默认 最新

  • CSDN专家-showbo 2022-09-04 15:13
    关注

    注释大概这样

    
    def string_to_double(s):
        try:
            val = float(s);#类型转换是这样的,转成int型则是 int(s)
            return val;
        #就目前这个代码通过按钮输入可以不需要,但是为了程序的健壮性还是加上比较好,防止逻辑没处理好传入其他非数字内容导致程序崩溃
        #也许到时整个工具库,用这个函数来转的话没发控制输入来源这样写就比较好
        except ValueError:
            return None
    
    
    def double_to_string(v):
        s = str(v)
        if 'e' in s:
            return ERROR
        if '.' in s:
            while s[-1] == '0':
                s = s[0:-1]
    
        #这块代码控制转换成字符串后,字符串最大长度为10,超过就删除最后一个数字直到长度为10
        #这个处理还是有bug,如果是123456789011.1,则处理后变为123456789011.,长度还是12超了,所以最后的len(s)>10返回了ERROR
        while len(s) > 10 and s[-1] != '.':#如果len(s)>10了,岂不是要出错了?这里用while的意义是什么
            s = s[0:-1]
            print(1,s)
        if s[-1] == '.':
            s = s[0:-1]
        if len(s) > 10:
            return ERROR
        return s
    
    
    def do_equal():
        global last_operation, accumulator
        clear_if_error()
        value = string_to_double(display_str.get())
    
        if last_operation == "+":
            #accumulator是按下操作符前输入的数字,3+4,所以accumulator=3,value=4,计算后将结果赋值给accumulator
            #accumulator += value实际就是accumulator = accumulator+value,只是简写了
            accumulator += value#举个例子,如果运行3+4,是不是accumulator=3,value=4,然后accumulator=7,为什么accumulator会认定是3,value会认定是4?
        elif last_operation == "-":
            accumulator -= value
        elif last_operation == "*":
            accumulator *= value
        elif last_operation == "/":
            if value != 0:
                accumulator /= value
            else:
                display_str.set(ERROR);
                return;
        #因为最下面accumulator默认为0,刚开始按下数字后,last_operation为空,上面的操作都没执行,这里直接就是将0转数字后赋值给输入框绑定的display_str变量了
        display_str.set(double_to_string(accumulator))
    
    
    
    window = tk.Tk()
    window.title('Calc')
    display_str = tk.StringVar()
    display_str.set("0")
    stick = tk.N + tk.S + tk.E + tk.W#是的N/S/E/W,分别代表上对齐/下对齐/左对齐/右对齐,多个方向对齐用+链接,ticky=N+S,意为顶端和低端都要对齐
    display = tk.Entry(window, width=10, font=("Courier New", "15", "bold"), textvariable=display_str, justify=tk.RIGHT)
    display.grid(row=0, columnspan=5, sticky=stick)
    digit7 = tk.Button(window, text="7", command=lambda: do_digit_x("7"))#command需要无参函数,要传递参数需要lambda。或者按照上个例子那样用Bind来绑定事件,通过事件获取按钮显示的text也行
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 9月12日
  • 已采纳回答 9月4日
  • 创建了问题 9月4日

悬赏问题

  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?