背景
TkDocs tutorial 里介绍了 ,其中有 A First (Real) Example 一文,这篇文章里有一个使用 生成图形化界面的简单例子。我想在那篇文章的基础上实战一下,于是想到可以写一个正整数 ➡️ 罗马数字(输入的正整数不能大于 )的简易转化工具。
正文
如何将正整数转化为罗马数字
转化规则可以参考 12. 整数转罗马数字 这道题目。以 为例,我们可以对每个数位进行转化
- 千位是 : 表示 , 表示
- 百位是 :不用转化
- 十位是 : 表示 , 表示
- 个位是 : 表示 , 表示 , 表示
合在一起,就是
程序可以这样写 ⬇️
def to_roman(value):
convert_result = ""
digit_base = 1
while value > 0:
remainder = value % (digit_base * 10)
convert_result = convert_one_digit_to_roman(remainder, digit_base) + convert_result
digit_base *= 10
value -= remainder
return convert_result
def convert_one_digit_to_roman(raw_value, digit_base):
candidates = "IVXLCDM"
index = 0
temp = digit_base
while temp > 1:
temp /= 10
index += 2
value = raw_value // digit_base
if value <= 3:
return candidates[index] * value
if value == 4:
return candidates[index] + candidates[index + 1]
if value <= 8:
return candidates[index + 1] + candidates[index] * (value - 5)
if value == 9:
return candidates[index] + candidates[index + 2]
raise ValueError("无效输入: " + str(raw_value))
完整的代码
A First (Real) Example 一文中有使用 生成图形化界面的简单例子。在它的基础上,可以写出以下 代码
from tkinter import *
from tkinter import ttk
def convert():
try:
value = num.get()
if (value <= 0) or (value > 3999):
result.set("无效输入")
return
result.set(to_roman(value))
except ValueError:
pass
def to_roman(value):
convert_result = ""
digit_base = 1
while value > 0:
remainder = value % (digit_base * 10)
convert_result = convert_one_digit_to_roman(remainder, digit_base) + convert_result
digit_base *= 10
value -= remainder
return convert_result
def convert_one_digit_to_roman(raw_value, digit_base):
candidates = "IVXLCDM"
index = 0
temp = digit_base
while temp > 1:
temp /= 10
index += 2
value = raw_value // digit_base
if value <= 3:
return candidates[index] * value
if value == 4:
return candidates[index] + candidates[index + 1]
if value <= 8:
return candidates[index + 1] + candidates[index] * (value - 5)
if value == 9:
return candidates[index] + candidates[index + 2]
raise ValueError("无效输入: " + str(raw_value))
root = Tk()
root.title("整数转罗马数字小工具")
mainframe = ttk.Frame(root, padding=(3, 3, 12, 12))
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
num = IntVar()
num_entry = ttk.Entry(mainframe, width=4, textvariable=num)
num_entry.grid(column=2, row=1, sticky=(W, E))
ttk.Button(mainframe, text="转化为罗马数字", command=convert).grid(column=1, row=2, sticky=W)
ttk.Label(mainframe, text="请输入一个正整数 (不要超过3999)").grid(column=1, row=1, sticky=W)
result = StringVar()
ttk.Label(mainframe, textvariable=result).grid(column=2, row=2, sticky=W)
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
mainframe.columnconfigure(2, weight=1)
for child in mainframe.winfo_children():
child.grid_configure(padx=5, pady=5)
num_entry.focus()
root.bind("<Return>", convert)
root.mainloop()
运行
请将上一小节展示的完整代码保存为 to_roman.py。使用如下命令可以运行 to_roman.py
python3 to_roman.py
运行效果如下
我们输入一个正数,例如当前年份 ,然后点击“转化为罗马数字”按钮,效果如下
再用其他数字验证一下(例如 )
运行结果符合预期