V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
guanjinman2022
V2EX  ›  Python

用 ChatGPT 编写个 素数判断 的代码,怎么改不够完美?

  •  
  •   guanjinman2022 · 2023-03-21 07:09:08 +08:00 · 2298 次点击
    这是一个创建于 620 天前的主题,其中的信息可能已经有所发展或是发生改变。
    import math
    import time
    import tkinter as tk
    from tkinter import messagebox, ttk
    from concurrent.futures import ThreadPoolExecutor, Future
    from typing import List
    
    def is_prime(n):
        """
        判断一个数是否为素数
        """
        if n < 2:
            return False
        elif n == 2:
            return True
        elif n % 2 == 0:
            return False
        else:
            for i in range(3, int(math.sqrt(n))+1, 2):
                if n % i == 0:
                    return False
            return True
    
    def factorization(n):
        """
        分解质因数
        """
        factors = []
        for i in range(2, int(math.sqrt(n))+1):
            while n % i == 0:
                factors.append(i)
                n //= i
            if n == 1:
                break
        if n > 1:
            factors.append(n)
        return factors
    
    def calculate():
        try:
            n = int(entry.get())
        except ValueError:
            messagebox.showerror("错误", "请输入一个整数")
            return
        progress_bar['value'] = 0
        result.set("计算中,请稍候...")
        future = executor.submit(calculate_result, n)
        future.add_done_callback(on_calculate_done)
        # 启动进度条更新线程
        progress_future = executor.submit(progress_worker, future)
    
    def calculate_result(n):
        start_time = time.time()
        if is_prime(n):
            result_str = f"{n} 是素数"
        else:
            factors = factorization(n)
            result_str = f"{n} 不是素数,它可以分解为 {factors}"
        end_time = time.time()
        result_str += f" 用时 {end_time - start_time:.2f} 秒"
        return result_str
    
    def on_calculate_done(future: Future):
        result.set(future.result())
    
    def quit_program():
        root.quit()
    
    def update_progress(progress):
        progress_bar['value'] = progress
    
    def progress_worker(future: Future):
        start_time = time.time()
        while not future.done():
            elapsed_time = time.time() - start_time
            progress = elapsed_time / progress_bar_max_time * 100
            progress = min(progress, 100)
            update_progress(progress)
            time.sleep(0.1)
        update_progress(100)
    
    root = tk.Tk()
    root.title("素数判断")
    
    # 创建控件
    label = ttk.Label(root, text="请输入一个整数:")
    label.pack(pady=10)
    
    entry = ttk.Entry(root, width=40)
    entry.pack(pady=10)
    
    progress_bar = ttk.Progressbar(root, orient=tk.HORIZONTAL, length=400, mode='determinate')
    progress_bar.pack(pady=10)
    
    button = ttk.Button(root, text="判断", command=calculate)
    button.pack(pady=10)
    
    result = tk.StringVar()
    result.set("结果将显示在这里")
    result_label = ttk.Label(root, textvariable=result)
    result_label.pack(pady=10)
    
    quit_button = ttk.Button(root, text="退出", command=quit_program)
    quit_button.pack(pady=10)
    
    # 设置布局
    root.geometry("500x300")
    
    executor = ThreadPoolExecutor(max_workers=2) # 增加线程池大小为 2 ,用于同时执行计算和进度条更新任务
    
    progress_bar_max_time = 5  # 进度条走满需要的时间,单位为秒
    
    def calculate():
        try:
            n = int(entry.get())
        except ValueError:
            messagebox.showerror("错误", "请输入一个整数")
            return
        progress_bar['value'] = 0
        result.set("计算中,请稍候...")
        future = executor.submit(calculate_result, n)
        future.add_done_callback(on_calculate_done)
        progress_future = executor.submit(progress_worker, future)
    
    def on_calculate_done(future: Future):
        result.set(future.result())
        progress_bar['value'] = 100
        future.cancel()  # 计算完成,取消进度条更新任务
    
    def update_progress(progress):
        progress_bar['value'] = progress
    
    def progress_worker(future: Future):
        start_time = time.time()
        while not future.done():
            elapsed_time = time.time() - start_time
            progress = elapsed_time / progress_bar_max_time * 100
            progress = min(progress, 100)
            update_progress(progress)
            time.sleep(0.1)
        update_progress(100)
    
    
    root.mainloop()
    

    这个是让 ChatGPT 写的判断素数的代码,使用 Python 3.11.2 版本 执行,但是进度条不管怎么改都不完美。 之前 GUI 界面上没进度条的,命令行窗口里有,很准确,还有倒计时、百分比等信息, 移到 GUI 界面上就一直不完美,要么点了判断,进度条不走,出结果的时候一下子拉满;要么进度条走完了还在计算中,代码里用 progress_bar_max_time = 5 的固定值不咋地,弄个预估的动态值也行啊,ChatGPT 也知道我的意思,就是弄不出来。

    我要求就是点判断后进度条开始匀速走,走完了刚好出来结果,最好进度条右边放个动态百分比数字。 放进度条就是为了计算大一点数时直观感受到大概时间

    4 条回复    2023-03-21 16:34:02 +08:00
    Devilker
        1
    Devilker  
       2023-03-21 07:41:23 +08:00
    1999 除以 3 那个吗 哈哈哈哈
    Rever4433
        2
    Rever4433  
       2023-03-21 10:45:36 +08:00
    这种进度条确实很难完美实现,举个例子,2147483647000007 和 214748364700007 ,在我的 i5 7300hq 的笔记本上前者 5.48s ,后者 0.74s 。并且素数的计算时间要更快。这就使得对于任何一次输入,计算时间都是不确定的。
    guanjinman2022
        3
    guanjinman2022  
    OP
       2023-03-21 11:44:47 +08:00 via Android
    @Rever4433 我知道时间是不确定的。后来让 ChatGPT 引入预估时间函数,用这个预估时间替换那个 5 来赋值。结果还是不行,点判断后进度条不走,显示计算中,相当于先后台计算一遍,知道时间后,再走进度条,走完刚好出来时间,整个过程相当于 2 倍时间。
    lmshl
        4
    lmshl  
       2023-03-21 16:34:02 +08:00
    这属于问题定义不清,gpt 也帮不了你了
    让我做的话我可能会这样,告诉 gpt 用 Miller–Rabin 算法实现一个素性检验算法,设定一个足够大的阈值,比如实验 20 次以后就认定输入是素数,因为伪素数几率已经足够低到可以忽略了。
    然后画进度条不过就是试验次数这一固定数值,你甚至不需要进度条,眨眼就验证完了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2781 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 05:40 · PVG 13:40 · LAX 21:40 · JFK 00:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.