Tkinter文件名浮点数没有正确递增。

huangapple go评论75阅读模式
英文:

Tkinter filename float not incrementing correctly

问题

我正在尝试创建一个程序,通过按下按钮按数字顺序加载下一个文件。为了检查下一个文件是什么,我简单地运行一个 while 循环,以 .1 递增来检查文件名。例如,我有一个标有 1.1、1.3 和 1.4 的文件,我希望按钮按照这个顺序加载它们,跳过 1.2,因为它不存在。

出现的问题是,由于某种原因,它不仅递增了要检查的值 0.1,而且递增了某个随机的数,导致我无法正确地检查文件。

因为我知道现在至少文件名只会进入到十位的小数(例如 1.2),所以从文件号 1.0 开始,寻找下一个文件,输出的结果看起来像这样:

1.1
1.2000000000000002
1.3000000000000003
1.4000000000000004
1.5000000000000004
1.6000000000000005
1.7000000000000006
1.8000000000000007
1.9000000000000008
2.000000000000001
2.100000000000001
2.200000000000001
2.300000000000001
2.4000000000000012
2.5000000000000013
2.6000000000000014
2.7000000000000015
2.8000000000000016
2.9000000000000017
3.0000000000000018
3.100000000000002
3.200000000000002
3.300000000000002
3.400000000000002
3.500000000000002
3.6000000000000023
3.7000000000000024
3.8000000000000025
3.9000000000000026
4.000000000000003

在第一次迭代中,它似乎确实增加了 0.1,但之后就不受控制了。将帮助将如下代码中的浮点数从 float(cuename.get()) 更改为 int(cuename.get())

cued = int(cuename.get())

这将将输入解析为整数,而不是浮点数,从而防止出现精度问题。

英文:

I am trying to create a program that loads the next file numerically upon the press of a button. In order to check what the next file is I simply run a while loop checking for a file name in .1 increments. I.E, I have a file labeled 1.1, 1.3, and 1.4, I want the button to load them in that order, skipping 1.2 because it doesn't exist.

The problem arising is that for some reason instead of just incrementing the value that gets checked by .1, it is incrementing it by .10000000000(some random number here), making it so I can't check the files properly

import tkinter as tk
from tkinter import *

mainscreen = tk.Tk()

cuename = tk.Entry(mainscreen)


def loadnext_cue():
    cued = float(cuename.get())
    next_cue = cued + .1
    while os.path.exists("%s .txt" % str(next_cue)) == False:
        print(next_cue)
        next_cue += 0.1
        if next_cue >= 4:
            error = Label(mainscreen, text="No Higher Cue")
            error.pack(side=TOP)
            time.sleep(2)
            error.destroy()
            break
    if os.path.exists("%s .txt" % str(next_cue)):
        callup = next_cue
    
        with open("%s.txt" % str(callup), "r") as loadentry:
            quote = loadentry.read()
        T.delete("1.0", END)
        T.insert(END, quote)

Because of what I'm using the program for I know for now at least the file names will only go into the 10's place decimal (I.E. 1.2)

So, starting with file number 1.0, looking for the next file up, the output I'm getting looks something like this:

1.1
1.2000000000000002
1.3000000000000003
1.4000000000000004
1.5000000000000004
1.6000000000000005
1.7000000000000006
1.8000000000000007
1.9000000000000008
2.000000000000001
2.100000000000001
2.200000000000001
2.300000000000001
2.4000000000000012
2.5000000000000013
2.6000000000000014
2.7000000000000015
2.8000000000000016
2.9000000000000017
3.0000000000000018
3.100000000000002
3.200000000000002
3.300000000000002
3.400000000000002
3.500000000000002
3.6000000000000023
3.7000000000000024
3.8000000000000025
3.9000000000000026
4.000000000000003

It seems to go up by exactly .1 on the first iteration but then does whatever it wants after that. Any and all help would be appreciated

答案1

得分: 2

以下是您要翻译的内容:

"It may be due to the fact that they're floating point numbers. For example,

>>print(0.3+0.6)
0.8999999999

It prints 0.89999999 instead of 0.9. In your case,

num = 1
for _ in range(30):
    num+=0.1
    print(num)

Prints the output that you are getting. Instead what you could do is round them to the tens place so that you get the answer you are looking for.

import tkinter as tk
from tkinter import *

mainscreen = tk.Tk()

cuename = tk.Entry(mainscreen)

def loadnext_cue():
    cued = float(cuename.get())
    next_cue = cued + .1
    while os.path.exists("%s .txt" % str(next_cue)) == False:
        print(next_cue)
        next_cue += 0.1
        next_cue = round(next_cue, 1) # rounds it to the tenths place
        if next_cue >= 4:
            error = Label(mainscreen, text="No Higher Cue")
            error.pack(side=TOP)
            time.sleep(2)
            error.destroy()
            break
    if os.path.exists("%s .txt" % str(next_cue)):
        callup = next_cue

        with open("%s.txt" % str(callup), "r") as loadentry:
            quote = loadentry.read()
        T.delete("1.0", END)
        T.insert(END, quote)
```"

<details>
<summary>英文:</summary>

It may be due to the fact that they&#39;re floating point numbers. For example, 

>>print(0.3+0.6)
0.8999999999

It prints 0.89999999 instead of 0.9. In your case,

num = 1
for _ in range(30):
num+=0.1
print(num)

Prints the output that you are getting. Instead what you could do is round them to the tens place so that you gen the answer you are looking for.

import tkinter as tk
from tkinter import *

mainscreen = tk.Tk()

cuename = tk.Entry(mainscreen)

def loadnext_cue():
cued = float(cuename.get())
next_cue = cued + .1
while os.path.exists("%s .txt" % str(next_cue)) == False:
print(next_cue)
next_cue += 0.1
next_cue = round(next_cue, 1) # rounds it to the tenths place
if next_cue >= 4:
error = Label(mainscreen, text="No Higher Cue")
error.pack(side=TOP)
time.sleep(2)
error.destroy()
break
if os.path.exists("%s .txt" % str(next_cue)):
callup = next_cue

    with open(&quot;%s.txt&quot; % str(callup), &quot;r&quot;) as loadentry:
        quote = loadentry.read()
    T.delete(&quot;1.0&quot;, END)
    T.insert(END, quote)

</details>



# 答案2
**得分**: 1

你的文件名采用 x.y 的形式,其中 x 和 y 都是整数,但你正在使用 Python 浮点数来存储文件名。Python 中的浮点数表示带有有限精度的十进制数字,当进行算术运算时,可能会出现精度损失。这就是为什么当你执行 1.1 + 0.1 时,结果会有一个非常小的误差,即所谓的“随机数”。

我建议修改你的代码,将 x 和 y 部分分别存储在整数变量中。你可以根据需要分别递增这些部分,然后在需要时将它们组合成字符串文件名。

<details>
<summary>英文:</summary>

Your filenames are of the form x.y where x and y are both integers, but you are using a Python float to store the filename. Floats in Python represent decimal numbers with finite precision, and when you perform arithmetic you can experience a loss of precision. That is why when you perform 1.1 + 0.1 you get a very small error in the result -- the &#39;random number&#39;.

I suggest to modify your code to store the parts x and y in separate variables as integers. You can increment the parts separately according to your logic, and then compose them into the string filename when needed.

</details>



huangapple
  • 本文由 发表于 2023年2月18日 23:49:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/75494496.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定