各位前辈给帮我看看这个代码有什么问题吗?
为什么下面的代码选择规则后,接收规则的变量selected_rules是空的呀!程序代码:
import pandas as pd import random import tkinter as tk from tkinter import filedialog root = tk.Tk() root.withdraw() # 文件选择框 file_path = filedialog.askopenfilename() # 读取表格数据 df = pd.read_excel(file_path) # 定义一个全局变量来保存用户选择的规则 selected_rules = [] # get_input()函数 def get_input(): x = num_entry.get() root.destroy() return int(x), selected_rules # 定义一个函数用于将被勾选的选项保存到一个列表中 def toggle_check(item, var): if var.get() == item[1] and item not in selected_rules: selected_rules.append(item) elif item in selected_rules: selected_rules.remove(item) update_selected_rules() # 弹出输入框和单选框,获取输入的数值和选择的规则 root = tk.Tk() tk.Label(root, text="请输入分配量(600/33=18):").grid(column=0, row=0, sticky='w') num_entry = tk.Entry(root) num_entry.grid(column=0, row=1) tk.Label(root, text="请选择分配规则:").grid(column=0, row=2, sticky='w') # 增加一个全选复选框 select_all_var = tk.IntVar() select_all_checkbox = tk.Checkbutton(root, text="全选", variable=select_all_var, anchor='w') select_all_checkbox.grid(column=0, row=3, sticky='w') rules = [("按平均数量分配", "quantity", 1), ("按平均金额分配", "amount", 2)] # 创建一个字典用来保存复选框 checkbox_dict = {} # 绑定全选复选框的选择事件 def select_all(): if select_all_var.get(): for mode in checkbox_dict: checkbox_dict[mode].select() selected_rules.clear() selected_rules.extend(rules) else: for mode in checkbox_dict: checkbox_dict[mode].deselect() selected_rules.clear() update_selected_rules() select_all_var.trace_add('write', lambda *args: select_all()) def update_selected_rules(): global selected_rules selected_rules = [] for item in rules: if checkbox_dict[item[1]].cget('selectcolor') == 'white': selected_rules.append(item) rule_var = tk.StringVar() rule_var.set("quantity") for i, (text, mode, order) in enumerate(rules): # 使用字典保存复选框 checkbox_dict[mode] = tk.Checkbutton(root, text=text, variable=rule_var, onvalue=mode, offvalue="", anchor='w', command=lambda item=(text, mode, order): toggle_check(item, rule_var)) checkbox_dict[mode].grid(column=0, row=i+4, sticky='w') button = tk.Button(root, text="确定", command=root.quit) button.grid(column=0, row=len(rules)+4) selected_rules = [] # 初始化选中的规则为空列表 root.mainloop() # 获取输入的数值和选择的规则并使用 num_accounts, selected_rules = get_input() print(num_accounts, selected_rules) # 输出输入的数值和选中的规则 # 抽取所有存在的账号名称 existing_accounts = df['账号'].dropna().astype(str) accounts = existing_accounts.value_counts().index.tolist() # 根据选择的规则计算每个账号需要分配的id数或金额 num_ids = len(df) if ("按平均数量分配", "quantity", 1) in selected_rules: average_amount = num_ids // num_accounts account_distribution = "按平均数量分配" print("662") else: total_amount = df['金额'].sum() average_amount = total_amount / num_accounts account_total_amounts = df.groupby('账号')['金额'].sum().to_dict() account_distribution = "按平均金额分配" print("66") # 根据平均金额计算每个账号需要分配的id数 num_ids_per_account = {} for account, total_amount in account_total_amounts.items(): num_ids_per_account[account] = int(total_amount / average_amount * num_ids / total_amount) total_ids = sum(num_ids_per_account.values()) if total_ids != num_ids: # 调整num_ids_per_account使得总和等于num_ids if total_ids > num_ids: excess_ids = total_ids - num_ids while excess_ids > 0: for account in list(num_ids_per_account.keys()): if num_ids_per_account[account] > 0: num_ids_per_account[account] -= 1 excess_ids -= 1 if excess_ids == 0: break else: remaining_ids = num_ids - total_ids while remaining_ids > 0: for account in list(num_ids_per_account.keys()): num_ids_per_account[account] += 1 remaining_ids -= 1 if remaining_ids == 0: break # 按金额排序 df_sorted = df.sort_values(by=['金额']) # 分配账号 assigned_accounts = [] account_id_counts = {} account_total_amounts = {} for i in range(num_ids): # 如果已分配该账号的id数量达到了上限,则在剩余账号中筛选 while True: if len(accounts) == 0: raise ValueError('账号数量不够,请减少分配量或添加更多账号') account = random.choice(accounts) if selected_rules == "quantity": if assigned_accounts.count(account) < num_ids_per_account: assigned_accounts.append(account) break else: if account not in account_total_amounts: assigned_accounts.append(account) account_id_counts[account] = 0 account_total_amounts[account] = 0 elif account_total_amounts[account] + df_sorted.loc[df_sorted.index[i], '金额'] > average_amount: accounts.remove(account) continue assigned_accounts.append(account) df_sorted.loc[df_sorted.index[i], '账号'] = account account_id_counts[account] += 1 account_total_amounts[account] += df_sorted.loc[df_sorted.index[i], '金额'] break #----------------------- # 对于按平均金额分配的规则,重新计算每个账号需要分配的id数 if selected_rules == "amount": num_accounts = len(accounts) total_amount = sum(account_total_amounts.values()) average_amount = total_amount / num_accounts # 分配订单 num_ids_per_account = {} total_ids = 0 for account in accounts: num_ids = int(account_total_amounts[account] / average_amount * num_ids / total_amount) num_ids_per_account[account] = num_ids total_ids += num_ids # 调整num_ids_per_account使得总和等于num_ids if total_ids != num_ids: if total_ids > num_ids: excess_ids = total_ids - num_ids for account in sorted(num_ids_per_account.keys(), key=num_ids_per_account.get, reverse=True): if num_ids_per_account[account] > 0: num_ids_per_account[account] -= 1 excess_ids -= 1 if excess_ids == 0: break else: remaining_ids = num_ids - total_ids for account in sorted(num_ids_per_account.keys(), key=num_ids_per_account.get): num_ids_per_account[account] += 1 remaining_ids -= 1 if remaining_ids == 0: break assigned_amounts = {account: num_ids_per_account[account] * average_amount for account in accounts} # 根据应分配金额分配订单 for account in account_total_amounts: assigned_accounts = [] excess_ids = df_sorted[df_sorted['账号'] == account] # 分配其它账号的订单,直到当前账号的订单数量达到应分配数量 while len(excess_ids) < assigned_amounts[account]: if len(accounts) <= 1: raise ValueError('账号数量不够,请减少分配量或添加更多账号') other_account = random.choice(accounts) if other_account != account: excess_ids_other = df_sorted[df_sorted['账号'] == other_account] excess_ids_to_assign = excess_ids_other.iloc[:assigned_amounts[account] - len(excess_ids)] # 判断是否需要在多个账号之间分配金额 if abs(excess_ids_to_assign['金额'].sum() - excess_ids['金额'].sum()) > 2000: diff = excess_ids_to_assign['金额'].sum() - excess_ids['金额'].sum() if diff > 0: excess_ids_to_assign = excess_ids_other.iloc[ :assigned_amounts[account] - len(excess_ids) + 1] excess_ids_to_assign['账号'] = account excess_ids = pd.concat([excess_ids, excess_ids_to_assign.iloc[:-1]]) excess_ids_other.drop(excess_ids_to_assign.iloc[:-1].index, inplace=True) else: excess_ids_to_assign = excess_ids_other.iloc[ :assigned_amounts[account] - len(excess_ids) - 1] other_account_ids = excess_ids[excess_ids['ID'].str.startswith(other_account)] excess_ids_to_assign.loc[other_account_ids.iloc[0].name, '金额'] += diff excess_ids_to_assign['账号'] = other_account excess_ids = pd.concat([excess_ids, excess_ids_to_assign]) excess_ids_other.drop(excess_ids_to_assign.index, inplace=True) else: excess_ids_to_assign['账号'] = account excess_ids = pd.concat([excess_ids, excess_ids_to_assign]) excess_ids_other.drop(excess_ids_to_assign.index, inplace=True) assigned_accounts.append(other_account) accounts.remove(other_account) if len(excess_ids) >= assigned_amounts[account]: break # 分配当前账号的订单 excess_ids = excess_ids.sample(frac=1) # 随机打乱顺序 excess_ids_to_assign = excess_ids.iloc[:assigned_amounts[account]] excess_ids_to_assign['账号'] = account excess_ids.drop(excess_ids_to_assign.index, inplace=True) account_id_counts[account] += len(excess_ids_to_assign) assigned_accounts.append(account) # 调整账户之间的总金额 while True: account_total_amounts = {account: df_sorted[df_sorted['账号'] == account]['金额'].sum() for account in accounts} max_amount_account = max(account_total_amounts, key=account_total_amounts.get) min_amount_account = min(account_total_amounts, key=account_total_amounts.get) diff = account_total_amounts[max_amount_account] - account_total_amounts[min_amount_account] if diff < 5000: break excess_ids = df_sorted[df_sorted['账号'] == max_amount_account] excess_ids_to_assign = excess_ids.sample(n=int(diff / 2)) excess_ids_to_assign['账号'] = min_amount_account excess_ids.drop(excess_ids_to_assign.index, inplace=True) account_id_counts[min_amount_account] += len(excess_ids_to_assign) if len(excess_ids) == 0: accounts.remove(max_amount_account) continue excess_ids = df_sorted[df_sorted['账号'] == min_amount_account] excess_ids_to_assign = excess_ids.sample(n=int(diff / 2)) excess_ids_to_assign['账号'] = max_amount_account excess_ids.drop(excess_ids_to_assign.index, inplace=True) account_id_counts[max_amount_account] += len(excess_ids_to_assign) # 剩余订单随机分配给其他账号 for i in range(len(excess_ids)): while True: if len(accounts) <= 1: raise ValueError('账号数量不够,请减少分配量或添加更多账号') other_account = random.choice(accounts) if other_account != account and assigned_accounts.count(other_account) < num_ids_per_account[ other_account]: excess_ids.loc[excess_ids.index[i], '账号'] = other_account excess_ids.drop(excess_ids.index[i], inplace=True) account_id_counts[other_account] += 1 assigned_accounts.append(other_account) accounts.remove(other_account) break df_sorted = df_sorted.sort_values(by=['账号', '金额']) # 输出表格和分配结果 save_path = filedialog.asksaveasfilename(defaultextension=".xlsx") if save_path: df_sorted.to_excel(save_path, index=False) print('文件保存成功!') print("账号分配结果:") for account, count in account_id_counts.items(): print("{}: {}个id ({:.2f}元)".format(account, count, account_total_amounts.get(account, 0))) print(account_distribution) else: print('未选择文件保存路径!')