Python-求和附介面(節約版)

AZ26發表於2024-08-20
import tkinter as tk
from tkinter.scrolledtext import ScrolledText
from tqdm import tqdm
import itertools


class MainWidget:
    def __init__(self):
        # 新建窗體
        self.win = tk.Tk()
        self.win.title("計算求和")
        self.win.geometry('660x420')
        # 建立標籤
        agg_label = tk.Label(self.win, text="和")
        agg_label.place(relx=0.1, rely=0, relheight=0.1, relwidth=0.4)
        division_label = tk.Label(self.win, text="求和項")
        division_label.place(relx=0.5, rely=0, relheight=0.1, relwidth=0.4)
        # 建立輸入窗體
        self.agg_entry = ScrolledText()
        self.agg_entry.place(relx=0.1, rely=0.1, relheight=0.4, relwidth=0.4)
        self.division_entry = ScrolledText()
        self.division_entry.place(relx=0.5, rely=0.1, relheight=0.4, relwidth=0.4)
        # 建立結果區域
        result_label = tk.Label(self.win, text="求和結果")
        result_label.place(relx=0.1, rely=0.5, relheight=0.05, relwidth=0.8)
        self.result_entry = ScrolledText()
        self.result_entry.place(relx=0.1, rely=0.55, relheight=0.2, relwidth=0.8)
        # 建立執行按鈕
        exec_btn = tk.Button(self.win, text='執行計算', command=self.execute)
        exec_btn.place(relx=0.4, rely=0.75, relheight=0.1, relwidth=0.2)
        self.win.mainloop()

    def get_result(self,hope, list_input):
        """
        :param hope: # 期望相加所得引數
        :param list_input: # 所有數值
        :param used: # 已使用過列表,起始資料為空
        :return:
        """

        def generate_combination(items, length):
            for combination in itertools.combinations(items, length):
                result_generate = list(combination)
                # print(result)
                yield result_generate

        # 容差值,避免float計算過小
        epsilon = 0.001
        # 剔除大於目標值部分的列表內容不進行計算
        step_1_list = [i for i in list_input if i < hope]
        # 根據初步判斷後的step_1_list,迭代每一種資料長度的可能性
        result = []
        for i in tqdm(range(1, len(step_1_list) + 1)):
            print('當前組合長度:' + str(i))
            # 用迭代器  按照每種長度  生成每種可能
            calculate = generate_combination(items=step_1_list, length=i)
            # 迴圈迭代結果
            for x in calculate:
                self.win.update()
                # 對迭代器中每個元組求和
                if abs(sum(x) - hope) <= epsilon:
                    result = x
                    print('計算出', hope, ',組合是', result)
                    break  # 如果計算出結果,則終止對迭代結果迴圈
            else:
                # print('無結果')
                continue  # 未計算出結果,繼續對迭代結果迴圈
            break  # if True 則終止對所有長度可能的迴圈
        return hope, result

    # 獲取內容
    def execute(self):
        sums = self.agg_entry.get(0.0, tk.END)
        divisions = self.division_entry.get(0.0, tk.END)
        # sum_nums = [float(i) for i in re.findall(pattern=num_pattern, string=sums)]
        # division_nums = [float(i) for i in re.findall(pattern=num_pattern, string=divisions)]
        sum_nums = [float(i) for i in sums.split()]
        division_nums = [float(i) for i in divisions.split()]
        print(sum_nums, division_nums)
        # self.division_entry.tag_add('1', 0.0, 3.0)
        # self.division_entry.tag_config('1',background="blue")
        for i in sum_nums:
            hope = self.get_result(i, division_nums)[0]
            result = self.get_result(i, division_nums)[1]
            self.result_entry.insert(tk.END, hope)
            self.result_entry.insert(tk.END, "     ")
            self.result_entry.insert(tk.END, str(result))
            self.result_entry.insert(tk.END, '\n')
            self.win.update()


MainWidget()

相關文章