Python+ tkinter实现小学整数乘法和除法竖式演算式(修改)
整数的乘法与除法是小学数学中的重要内容,它们是数学运算中的基础部分。 本文将使用python 和Python 的标准 GUI(图形用户界面)包tkinter,实现整数乘法与除法的竖式演示。
一、小学整数乘法竖式演算式
界面上有两个整数输入框,单击“计算”按钮,显示小学生整数演示竖式,效果图:
源码如下:
import tkinter as tk
from tkinter import messagebox
def multiply(factor1, factor2):
"""执行竖式乘法并生成格式化计算过程字符串"""
# 转换为整数计算最终结果
num1 = int(factor1)
num2 = int(factor2)
product = num1 * num2
product_str = str(product)
# 确定所有元素的对齐基准(最终结果的长度)
max_length = len(product_str)
len1, len2 = len(factor1), len(factor2)
lines = [] # 存储每行显示内容的列表
# 添加前两行因数(右对齐)
lines.append(f"{factor1.rjust(max_length)}\n") # 第一个因数右对齐
lines.append(f"x{factor2.rjust(max_length - 1)}\n") # 第二个因数右对齐(考虑x符号占位)
lines.append("-" * max_length + "\n") # 分隔线
# 核心计算逻辑:从右到左遍历乘数的每一位(个位→高位)
for j in range(len2-1, -1, -1):
line = "" # 当前位的乘积结果
carry = 0 # 进位值
# 计算单个位数的乘积(从右到左遍历被乘数)
for i in range(len1-1, -1, -1):
# 计算当前位的乘积并加上进位
product_step = int(factor1[i]) * int(factor2[j]) + carry
carry = product_step // 10 # 计算进位
line = str(product_step % 10) + line # 将个位添加到当前行开头
# 处理最后的进位
if carry > 0:
line = str(carry) + line
# 补零逻辑:根据位权补对应数量的零
# 个位补0个,十位补1个,百位补2个...(len2-1 - j 实现)
zeros = "0" * (len2-1 - j)
line += zeros
# 将当前行右对齐并添加到结果列表
lines.append(line.rjust(max_length) + "\n")
# 添加最终结果部分
lines.append("-" * max_length + "\n")
lines.append(product_str.rjust(max_length) + "\n")
return "".join(lines) # 将列表转换为字符串
def calculate():
"""处理计算按钮点击事件"""
# 获取输入并去除前后空格
factor1 = entry_factor1.get().strip()
factor2 = entry_factor2.get().strip()
# 空输入检查
if not factor1 or not factor2:
messagebox.showwarning("输入错误", "请输入两个因数!")
return
try:
# 双重验证:纯数字且可以转换为整数
if not factor1.isdigit() or not factor2.isdigit():
raise ValueError
int(factor1) # 二次验证确保可以转换为整数
int(factor2)
# 生成计算过程并显示
result = multiply(factor1, factor2)
result_text.delete(1.0, tk.END) # 清空文本框
result_text.insert(tk.END, result) # 插入新内容
except ValueError:
messagebox.showwarning("输入错误", "请输入有效的整数!")
# GUI界面初始化
root = tk.Tk()
root.title("整数乘法竖式算式")
root.geometry("400x500")
root.configure(bg="#4682B4") # 设置背景颜色
# 创建容器框架
container = tk.Frame(root, bg="#4682B4")
container.pack(pady=20) # 添加垂直间距
# 标题标签
label_title = tk.Label(
container,
text="整数乘法竖式算式",
font=("Courier New", 18), # 使用等宽字体
bg="#4682B4", # 背景色与容器一致
fg="#dbc5c5" # 浅灰色文字
)
label_title.pack()
# 第一个因数输入框
entry_factor1 = tk.Entry(
container,
font=("Courier New", 18), # 保持等宽字体
width=20,
justify="right", # 输入右对齐
bd=0, # 去除边框
bg="white" # 白色背景
)
entry_factor1.pack(pady=10)
# 第二个因数输入框
entry_factor2 = tk.Entry(
container,
font=("Courier New", 18),
width=20,
justify="right",
bd=0,
bg="white"
)
entry_factor2.pack(pady=10)
# 计算按钮
button_calculate = tk.Button(
container,
text="计算",
font=("Courier New", 18),
bg="#98FB98", # 浅绿色背景
fg="#4682B4", # 文字颜色与主背景一致
bd=0, # 去除边框
command=calculate # 绑定点击事件
)
button_calculate.pack(pady=10)
# 结果显示文本框
result_text = tk.Text(
container,
font=("Courier New", 14), # 稍小字号
width=30,
height=15,
bd=0,
bg="white", # 白色背景
fg="#4682B4" # 文字颜色与主题色一致
)
result_text.pack(pady=10)
# 启动主事件循环
root.mainloop()
二、小学整数除法竖式演算式
界面上有两个整数输入框每次单击“计算”按钮,要显示小学数学整数整除竖式效果。效果图:
源码如下:
import tkinter as tk
from tkinter import messagebox
def division_steps(dividend, divisor):
steps = []
dividend_str = str(dividend)
dividend_len = len(dividend_str)
temp_dividend = 0
current_position = 0
result_started = False # 标记是否已经开始有效计算
while current_position < dividend_len:
temp_dividend = temp_dividend * 10 + int(dividend_str[current_position])
current_position += 1
# 如果当前部分不足以进行除法,则跳过该步骤
if temp_dividend < divisor:
continue
# 标记已经开始有效计算
result_started = True
quotient_digit = temp_dividend // divisor
subtrahend = divisor * quotient_digit
remainder = temp_dividend - subtrahend
# 计算缩进
# 缩进 = 除数长度 + 3(用于“ ) ”) + 当前被除数部分的偏移量 - 1(对齐被除数的第一个有效数字)
indent = len(str(divisor)) + 3 + (current_position - len(str(subtrahend)) - 1)
# 特殊处理第一步:避免显示多余的被减数和减法内容
if len(steps) == 0: # 第一条竖式步骤
step_str = f"{' ' * indent}-{subtrahend}\n" # 减去的值
step_str += f"{' ' * indent}{'-' * len(str(subtrahend))}\n" # 减号线条
else: # 后续步骤正常缩进
# step_str = f"{' ' * (indent + 1)}{temp_dividend}\n" # 当前部分被减数,此处需要(indent + 1)?
if len(str(temp_dividend))<= len(str(subtrahend)):
step_str = f"{' ' * (indent + 1)}{temp_dividend}\n" # 当前部分被减数,此处需要 + 1
else:
step_str = f"{' ' * (indent)}{temp_dividend}\n" # 当前部分被减数
step_str += f"{' ' * indent}-{subtrahend}\n" # 减去的值
step_str += f"{' ' * indent}{'-' * len(str(subtrahend))}\n" # 减号线条
steps.append(step_str)
temp_dividend = remainder
return steps, temp_dividend # 返回步骤和最终的余数
def calculate():
result_text.delete(1.0, tk.END) # 清空结果文本框
dividend = dividend_entry.get() # 获取被除数输入
divisor = divisor_entry.get() # 获取除数输入
try:
dividend = int(dividend) # 将被除数转换为整数
divisor = int(divisor) # 将除数转换为整数
if divisor == 0:
raise ValueError("除数不能为零") # 除数为零时抛出异常
except ValueError:
messagebox.showwarning("输入错误", "请输入有效的整数,且除数不能为零") # 弹出警告对话框
return
steps, remainder = division_steps(dividend, divisor) # 计算除法步骤和余数
dividend_str = str(dividend) # 被除数字符串
divisor_str = str(divisor) # 除数字符串
quotient = dividend // divisor # 计算商
quotient_str = str(quotient) # 商的字符串表示
result_text.config(state=tk.NORMAL) # 设置文本框为可编辑状态
# 计算商的对齐位置
# 商的第一位应该与被除数的第一个有效数字对齐
# 除数长度 + 3(用于“ ) ”) + 被除数长度 - 商长度
indent_quotient = len(divisor_str) + 3 + (len(dividend_str) - len(quotient_str))
result_text.insert(tk.END, f"{' ' * indent_quotient}{quotient_str}\n")
# 显示除数和被除数的格式化表示
result_text.insert(tk.END, f"{divisor_str} ) {dividend_str}\n")
# 显示除法步骤,格式化输出
for step in steps:
result_text.insert(tk.END, step)
# 显示竖式的余数
#result_text.insert(tk.END, f" {remainder}\n")
# 计算余数的缩进,使其与商的末尾对齐
# 余数的缩进 = 商的对齐缩进 + 商的长度 - 余数的长度
indent_remainder = indent_quotient + len(quotient_str) - len(str(remainder))
result_text.insert(tk.END, f"{' ' * indent_remainder}{remainder}\n")
# 显示最终的商和余数
result_text.insert(tk.END, f"商: {quotient}, 余数: {remainder}\n")
#result_text.config(state=tk.DISABLED) # 设置文本框为只读状态
# 创建主窗口
root = tk.Tk()
root.title("整数除法竖式演算")
root.geometry("450x500")
root.configure(bg="#4682B4") # 设置背景颜色
# 创建框架,用于容纳其他控件
frame = tk.Frame(root, bg="#4682B4")
frame.pack(pady=20)
# 被除数标签和输入框
dividend_label = tk.Label(frame, text="被除数:", bg="#4682B4", fg="white", font=("Courier", 14))
dividend_label.grid(row=0, column=0, padx=10, pady=5)
dividend_entry = tk.Entry(frame, width=15, justify="right", font=("Courier", 14))
dividend_entry.grid(row=0, column=1, padx=10, pady=5)
# 除数标签和输入框
divisor_label = tk.Label(frame, text="除数:", bg="#4682B4", fg="white", font=("Courier", 14))
divisor_label.grid(row=1, column=0, padx=10, pady=5)
divisor_entry = tk.Entry(frame, width=15, justify="right", font=("Courier", 14))
divisor_entry.grid(row=1, column=1, padx=10, pady=5)
# 计算按钮
calculate_button = tk.Button(frame, text="计算", command=calculate, bg="#98FB98", fg="#4682B4", font=("Courier", 14))
calculate_button.grid(row=2, column=0, columnspan=2, pady=10)
# 结果文本框
result_text = tk.Text(frame, width=40, height=20, font=("Courier", 12), wrap=tk.NONE)
result_text.grid(row=4, column=0, columnspan=2)
root.mainloop() # 进入主事件循环
OK!