map.py 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018
  1. from os import path
  2. import os
  3. import math
  4. import random
  5. import tkinter
  6. import tkinter.messagebox
  7. import logging
  8. import pandas
  9. from matplotlib import pyplot as plt
  10. from matplotlib import rcParams
  11. from funcsystem.controller import SheetFunc, ExpFunc
  12. from newtkinter import askopenfilename, asksaveasfilename
  13. from system import exception_catch, basicConfig, QueueController
  14. queue_controller = QueueController()
  15. logging.basicConfig(**basicConfig)
  16. func_logger = []
  17. fig = None
  18. func_str_list = []
  19. prompt_num = 0
  20. FONT = (fr"Font{os.sep}ZKST.ttf", 11) # 设置字体
  21. SCREEN = tkinter.Tk() # 设置屏幕
  22. bg_color = "#FFFAFA" # 主颜色
  23. SCREEN["bg"] = bg_color
  24. botton_color = "#FFFAFA" # 按钮颜色
  25. word_color = "#000000" # 文字颜色
  26. line_style = {
  27. "实线": "-",
  28. "短横线": "--",
  29. "点划线": "-,",
  30. "虚线": ":",
  31. "点标记": ".",
  32. "圆标记": "o",
  33. "倒三角": "v",
  34. "正三角": "^",
  35. "左三角": "&lt",
  36. "下箭头": "1",
  37. "上箭头": "2",
  38. "左箭头": "3",
  39. "右箭头": "4",
  40. "正方形": "s",
  41. "五边形": "p",
  42. "星形": "*",
  43. "六边形": "h",
  44. "六边形2": "H",
  45. "+号": "+",
  46. "X标记": "x",
  47. } # 函数样式翻译表
  48. point_style = ["g", "r", "c", "m", "y", "k"]
  49. csv_list = []
  50. gui_width = 13 # 标准宽度
  51. gui_height = 2
  52. class UIAPI:
  53. @staticmethod
  54. @exception_catch()
  55. def get_save_dir_gui():
  56. return asksaveasfilename(title="选择导出位置", filetypes=[("CSV", ".csv")])
  57. @staticmethod
  58. @exception_catch()
  59. def output_prompt_gui(news):
  60. global prompt_box, prompt_num
  61. prompt_num += 1
  62. news = str(news)
  63. prompt_box.insert(0, news + f"({prompt_num})")
  64. SCREEN.update()
  65. @staticmethod
  66. @exception_catch()
  67. def get_y_value_gradient_gui():
  68. parameters = y_value_gradient.get().split("#") # 拆解输入
  69. return parameters
  70. @staticmethod
  71. @exception_catch()
  72. def dichotomy_gui():
  73. y = y_value.get().split(",") # 拆解输入
  74. parameters = dicon_parameters.get().split("#") # 拆解输入
  75. return parameters, y
  76. @staticmethod
  77. @exception_catch()
  78. def get_func_exp_box_index_gui():
  79. return func_exp_box.curselection()[0]
  80. @staticmethod
  81. @exception_catch()
  82. def get_x_value_gui():
  83. return x_value.get().split(",")
  84. @staticmethod
  85. @exception_catch()
  86. def update_property_box_gui(answer):
  87. property_box.delete(0, tkinter.END)
  88. property_box.insert(tkinter.END, *answer)
  89. @staticmethod
  90. @exception_catch()
  91. def update_result_box_gui(answer):
  92. result_box.delete(0, tkinter.END)
  93. result_box.insert(tkinter.END, *answer)
  94. @staticmethod
  95. @exception_catch()
  96. def get_func_logger_gui():
  97. return func_logger[func_exp_box.curselection()[0]]
  98. @staticmethod
  99. @exception_catch()
  100. def add_func_gui():
  101. get = func_exp.get().replace(" ", "")
  102. definition = definition_domain.get().split(",")
  103. name = func_name.get().replace(" ", "")
  104. style_str = func_style.get().split("#")
  105. if not name:
  106. name = get
  107. try:
  108. if style_str[0] not in point_style:
  109. style_str[0] = "b"
  110. line_style_str = line_style.get(style_str[1], "-")
  111. except IndexError:
  112. style_str = ["", ""]
  113. style_str[0] = random.choice(point_style)
  114. line_style_str = "-"
  115. style = style_str[0] + line_style_str
  116. try:
  117. span_str = definition[2]
  118. if span_str.startswith("H"):
  119. named_domain = {
  120. "Pi": math.pi,
  121. "e": math.e,
  122. "log": math.log,
  123. "sin": math.sin,
  124. "cos": math.cos,
  125. "tan": math.tan,
  126. "cot": lambda x: 1 / math.tan(x),
  127. "csc": lambda x: 1 / math.sin(x),
  128. "sec": lambda x: 1 / math.cos(x),
  129. "sinh": math.sinh,
  130. "cosh": math.cosh,
  131. "tanh": math.tanh,
  132. "asin": math.asin,
  133. "acos": math.acos,
  134. "atan": math.atan,
  135. }
  136. definition[2] = eval(span_str[1:], named_domain)
  137. except BaseException as e:
  138. logging.warning(str(e))
  139. return get, [name, style] + definition
  140. @staticmethod
  141. @exception_catch()
  142. def update_func_exp_box_gui():
  143. func_exp_box.delete(0, tkinter.END)
  144. func_exp_box.insert(tkinter.END, *func_logger)
  145. @staticmethod
  146. @exception_catch()
  147. def read_csv_gui():
  148. file = askopenfilename(title="载入表格", filetypes=[("CSV", ".csv")])
  149. style_str = func_style.get().split("#")
  150. try:
  151. if style_str[0] not in point_style:
  152. style_str[0] = "b"
  153. line_style_str = line_style.get(style_str[1], "-")
  154. except IndexError:
  155. style_str = ["", ""]
  156. style_str[0] = random.choice(point_style)
  157. line_style_str = "-"
  158. style = style_str[0] + line_style_str
  159. name = path.basename(file)[0:-4].replace(" ", "")
  160. if not name:
  161. name = random.randint(1, 1000)
  162. name += "(In CSV)"
  163. return pandas.read_csv(file).tolist(), name, style
  164. class API(UIAPI):
  165. @staticmethod
  166. @exception_catch()
  167. def type_selection(iter_object, si=float, no_zero=True): # Float筛选系统
  168. x = []
  169. for i in iter_object:
  170. try:
  171. if si(i) == si(0) and no_zero:
  172. continue
  173. x.append(si(i))
  174. except ValueError:
  175. pass
  176. return x
  177. @staticmethod
  178. @exception_catch()
  179. def plot_func():
  180. global func_logger, definition_domain, fig, x_limit, y_limit, y_axis, x_axis
  181. # 画板创造
  182. API.output_prompt_gui("生成绘制取...")
  183. fig = plt.figure(num="CoTan函数") # 定义一个图像窗口
  184. plt.grid(True, ls="--") # 显示网格(不能放到后面,因为后面调整成为了笛卡尔坐标系)
  185. axis = plt.gca()
  186. axis.spines["right"].set_color("none")
  187. axis.spines["top"].set_color("none")
  188. axis.xaxis.set_ticks_position("bottom")
  189. axis.yaxis.set_ticks_position("left")
  190. axis.spines["bottom"].set_position(("data", 0)) # 设置x轴, y轴在(0, 0)的位置
  191. axis.spines["left"].set_position(("data", 0))
  192. # 检测x
  193. try:
  194. if x_axis.get()[0] == "c": # 如果输入函数cx#-10#10#1#1
  195. # 第一部分HS,第二部分S,第三部分E,第四部分KD,第五部分JD
  196. plot_parameter = x_axis.get()[1:].split("#")
  197. exp_parameter = ["x", -10, 10, 1, 2] # 保护系统
  198. try:
  199. exp_parameter[0] = plot_parameter[0]
  200. exp_parameter[1] = int(plot_parameter[1])
  201. exp_parameter[2] = int(plot_parameter[2])
  202. exp_parameter[3] = int(plot_parameter[3])
  203. exp_parameter[4] = int(plot_parameter[4])
  204. except BaseException as e:
  205. logging.warning(str(e))
  206. plot_parameter = exp_parameter
  207. x_exp_scale = API.type_selection(
  208. ExpFunc(
  209. plot_parameter[0],
  210. "x",
  211. "",
  212. plot_parameter[1],
  213. plot_parameter[2],
  214. plot_parameter[3],
  215. plot_parameter[4],
  216. ).data_packet()[1]
  217. ) # 取y
  218. axis.set_xticks(x_exp_scale)
  219. elif x_axis.get()[0] == "y": # 输入函数y
  220. x_exp_scale = abs(int(x_axis.get()[1:]))
  221. x_major_locator = plt.MultipleLocator(x_exp_scale)
  222. axis.xaxis.set_major_locator(x_major_locator)
  223. else: # 输入纯数字
  224. x_exp_scale = API.type_selection(x_axis.get().split(","))
  225. axis.set_xticks(x_exp_scale)
  226. except BaseException as e:
  227. logging.debug(str(e))
  228. x_major_locator = plt.MultipleLocator(2)
  229. axis.xaxis.set_major_locator(x_major_locator)
  230. # 检测y
  231. try: # 意外捕捉
  232. if y_axis.get()[0] == "c": # 如果输入函数cx#-10#10#1#1
  233. # 第一部分HS,第二部分S,第三部分E,第四部分KD,第五部分JD
  234. plot_parameter = y_axis.get()[1:].split("#")
  235. exp_parameter = ["x", -10, 10, 1, 2] # 保护系统
  236. try:
  237. exp_parameter[0] = plot_parameter[0]
  238. exp_parameter[1] = int(plot_parameter[1])
  239. exp_parameter[2] = int(plot_parameter[2])
  240. exp_parameter[3] = int(plot_parameter[3])
  241. exp_parameter[4] = int(plot_parameter[4])
  242. except BaseException as e:
  243. logging.warning(str(e))
  244. plot_parameter = exp_parameter
  245. y_exp_scale = API.type_selection(
  246. ExpFunc(
  247. plot_parameter[0],
  248. "y",
  249. "",
  250. plot_parameter[1],
  251. plot_parameter[2],
  252. plot_parameter[3],
  253. plot_parameter[4],
  254. ).data_packet()[1]
  255. ) # 取y
  256. axis.set_yticks(y_exp_scale)
  257. elif y_axis.get()[0] == "y": # 输入函数y
  258. y_exp_scale = abs(int(y_axis.get()[1:]))
  259. y_major_locator = plt.MultipleLocator(y_exp_scale)
  260. axis.yaxis.set_major_locator(y_major_locator)
  261. else:
  262. y_exp_scale = API.type_selection(y_axis.get().split(","))
  263. axis.set_yticks(y_exp_scale)
  264. except BaseException as e:
  265. logging.debug(str(e))
  266. y_major_locator = plt.MultipleLocator(2)
  267. axis.yaxis.set_major_locator(y_major_locator)
  268. # 极限
  269. _x_limit = [-10, 10]
  270. _y_limit = [-10, 10]
  271. try:
  272. _x_limit = API.type_selection(x_limit.get().split(","), si=int, no_zero=False)
  273. _y_limit = API.type_selection(y_limit.get().split(","), si=int, no_zero=False)
  274. try:
  275. _x_limit = [_x_limit[0], _x_limit[1]]
  276. except IndexError:
  277. _x_limit = [-10, 10]
  278. try:
  279. _y_limit = [_y_limit[0], _y_limit[1]]
  280. except IndexError:
  281. _y_limit = _x_limit
  282. except BaseException as e:
  283. logging.warning(str(e))
  284. _x_limit.sort()
  285. _y_limit.sort()
  286. plt.xlim(_x_limit)
  287. plt.ylim(_y_limit)
  288. # 函数绘图系统
  289. API.output_prompt_gui("图像绘制中...")
  290. if not func_logger:
  291. return False
  292. for Fucn in func_logger:
  293. get = Fucn.get_plot_data()
  294. plot_x = get[0]
  295. plot_y = get[1]
  296. func_label = get[2]
  297. exp_style = get[3]
  298. first = True
  299. for i in range(len(plot_x)):
  300. x_exp_scale = plot_x[i]
  301. y_exp_scale = plot_y[i]
  302. if first:
  303. plt.plot(
  304. x_exp_scale, y_exp_scale, exp_style, label=func_label
  305. ) # plot()画出曲线
  306. first = False
  307. else:
  308. plt.plot(x_exp_scale, y_exp_scale, exp_style)
  309. get = Fucn.get_memory()
  310. memory_x = get[0]
  311. memory_y = get[1]
  312. max_x, max_y, min_x, min_y = Fucn.best_value()
  313. plt.plot(
  314. memory_x, memory_y, exp_style[0] + "o", label=f"Point of {func_label}"
  315. ) # 画出一些点
  316. len_x = sorted(list(set(memory_x))) # 去除list重复项目
  317. extreme_points = max_x + min_x
  318. last_x = None
  319. for i in range(len(len_x)):
  320. if i in extreme_points:
  321. continue # 去除极值点
  322. now_x = len_x[i] # x
  323. if last_x is None or abs(now_x - last_x) >= 1: # 确保位置
  324. num = memory_x.index(now_x) # y的座位
  325. now_y = memory_y[num]
  326. plt.text(
  327. now_x,
  328. now_y,
  329. f"({now_x},{int(now_y)})",
  330. fontdict={"size": "10", "color": "b"},
  331. ) # 标出坐标
  332. last_x = now_x
  333. last_x = None
  334. plot_max = []
  335. for i in range(len(max_x)): # 画出最大值
  336. now_x = max_x[i]
  337. if last_x is None or abs(now_x - last_x) >= 1: # 确保位置
  338. plt.text(
  339. now_x - 1,
  340. max_y,
  341. f"max:({now_x},{int(max_y)})",
  342. fontdict={"size": "10", "color": "b"},
  343. ) # 标出坐标
  344. plot_max.append(now_x)
  345. last_x = now_x
  346. last_x = None
  347. plot_min = []
  348. for i in range(len(min_x)): # 画出最小值
  349. now_x = min_x[i]
  350. if last_x is None or abs(now_x - last_x) >= 1:
  351. plot_min.append(now_x)
  352. plt.text(
  353. now_x - 1,
  354. min_y,
  355. f"min:({now_x},{int(min_y)})",
  356. fontdict={"size": "10", "color": "b"},
  357. ) # 标出坐标
  358. last_x = now_x
  359. plt.plot(plot_min, [min_y] * len(plot_min), exp_style[0] + "o") # 画出一些点
  360. plt.plot(plot_max, [max_y] * len(plot_max), exp_style[0] + "o") # 画出一些点
  361. API.output_prompt_gui("绘制完毕")
  362. plt.legend() # 显示图示
  363. plt.show() # 显示图像
  364. return True
  365. @staticmethod
  366. @exception_catch()
  367. def add_from_csv(): # 添加函数
  368. file, name, style = API.read_csv_gui()
  369. try:
  370. API.output_prompt_gui("读取CSV")
  371. func_str_list.append(name)
  372. func_logger.append(SheetFunc(file, name, style))
  373. API.update_func_exp_box_gui()
  374. API.output_prompt_gui("读取完毕")
  375. except BaseException:
  376. API.output_prompt_gui("读取失败")
  377. raise
  378. @staticmethod
  379. @exception_catch()
  380. def add_func(): # 添加函数
  381. get, definition = API.add_func_gui()
  382. if get and get not in func_str_list:
  383. func_str_list.append(get)
  384. func_logger.append(ExpFunc(get, *definition))
  385. API.update_func_exp_box_gui()
  386. API.output_prompt_gui("函数生成完毕")
  387. else:
  388. API.output_prompt_gui("函数生成失败")
  389. @staticmethod
  390. @exception_catch()
  391. def clean_func_box(): # 添加函数
  392. global func_logger, func_str_list
  393. if API.show_askokcancel("是否清空所有函数?)"):
  394. func_str_list = []
  395. func_logger = []
  396. API.update_func_exp_box_gui()
  397. API.output_prompt_gui("函数清空完毕")
  398. @staticmethod
  399. @exception_catch()
  400. def func_to_sheet_gui(): # 显示xy
  401. try:
  402. func = API.get_func_logger_gui()
  403. sheet_box.delete(0, tkinter.END)
  404. sheet_box.insert(tkinter.END, *func.return_list())
  405. API.output_prompt_gui("表格创建成功")
  406. except BaseException:
  407. API.output_prompt_gui("无法创建表格")
  408. raise
  409. @staticmethod
  410. @exception_catch()
  411. def show_askokcancel(message):
  412. return tkinter.messagebox.askokcancel("提示", message)
  413. @staticmethod
  414. @exception_catch()
  415. def clean_func_memory():
  416. global x_value, func_exp_box, func_logger
  417. try:
  418. if API.show_askokcancel(f"确定删除{func_logger[func_exp_box.curselection()[0]]}的记忆吗?"):
  419. API.get_func_logger_gui().clean_memory()
  420. API.update_result_box_gui([])
  421. API.output_prompt_gui("删除完毕")
  422. else:
  423. API.output_prompt_gui("删除取消")
  424. except BaseException:
  425. API.output_prompt_gui("删除失败")
  426. raise
  427. @staticmethod
  428. @exception_catch()
  429. def hide_memory(): # 显示xy
  430. global func_logger, result_box
  431. try:
  432. API.get_func_logger_gui().hide_or_show()
  433. API.update_result_box_gui([])
  434. API.output_prompt_gui("已清空卡槽")
  435. except BaseException:
  436. API.output_prompt_gui("隐藏(显示)失败")
  437. raise
  438. @staticmethod
  439. @exception_catch()
  440. def show_memory(): # 显示xy
  441. global func_logger, result_box
  442. try:
  443. answer = []
  444. for i in zip(API.get_func_logger_gui().get_memory()):
  445. answer.append(f"x={i[0]} -> y={i[1]}")
  446. API.update_result_box_gui(answer)
  447. API.output_prompt_gui("输出完成")
  448. except BaseException:
  449. API.output_prompt_gui("操作失败")
  450. raise
  451. @staticmethod
  452. @exception_catch()
  453. def property_prediction():
  454. try:
  455. API.output_prompt_gui("预测过程程序可能无响应")
  456. answer = API.get_func_logger_gui().property_prediction(API.output_prompt_gui)
  457. API.update_property_box_gui(answer)
  458. API.output_prompt_gui("性质预测完成")
  459. except IndexError:
  460. API.output_prompt_gui("性质预测失败")
  461. @staticmethod
  462. @exception_catch()
  463. def calculate():
  464. global func_logger, result_box, x_value
  465. try:
  466. API.output_prompt_gui("计算过程程序可能无响应")
  467. answer = API.get_func_logger_gui().calculation(API.get_x_value_gui())
  468. API.update_result_box_gui(answer)
  469. API.output_prompt_gui("系统计算完毕")
  470. except IndexError:
  471. API.output_prompt_gui("计算失败")
  472. @staticmethod
  473. @exception_catch()
  474. def func_to_csv(): # 导出CSV
  475. global csv_list
  476. try:
  477. API.get_func_logger_gui().save_csv(API.get_save_dir_gui())
  478. API.output_prompt_gui("CSV导出成功")
  479. except BaseException:
  480. API.output_prompt_gui("CSV导出失败")
  481. raise
  482. @staticmethod
  483. @exception_catch()
  484. def del_func(): # 删除函数
  485. global func_logger, func_str_list, func_exp_box
  486. del_index = API.get_func_exp_box_index_gui()
  487. del func_logger[del_index]
  488. del func_str_list[del_index]
  489. API.update_func_exp_box_gui()
  490. API.output_prompt_gui("函数删除完毕")
  491. @staticmethod
  492. @exception_catch()
  493. def dichotomy():
  494. try:
  495. API.output_prompt_gui("计算过程程序可能无响应")
  496. parameters, y = API.dichotomy_gui()
  497. answer = []
  498. API.output_prompt_gui("系统运算中")
  499. for i in y:
  500. answer += API.get_func_logger_gui().dichotomy(float(i), *parameters)[0]
  501. if answer:
  502. API.output_prompt_gui("系统运算完成")
  503. else:
  504. API.output_prompt_gui("系统运算无结果")
  505. API.update_result_box_gui(answer)
  506. except BaseException:
  507. API.output_prompt_gui("系统运算失败")
  508. raise
  509. @staticmethod
  510. @exception_catch()
  511. def gradient_method_calculation():
  512. try:
  513. API.output_prompt_gui("计算过程程序可能无响应")
  514. API.output_prompt_gui("系统运算中")
  515. answer = API.get_func_logger_gui().gradient_calculation(*API.get_y_value_gradient_gui())
  516. if answer[1]:
  517. API.output_prompt_gui("系统运算完成")
  518. else:
  519. API.output_prompt_gui("系统运算无结果")
  520. API.update_result_box_gui(answer)
  521. except BaseException:
  522. API.output_prompt_gui("系统运算失败,请注意参数设置")
  523. raise
  524. @staticmethod
  525. @exception_catch()
  526. def func_differentiation():
  527. global func_logger, func_exp_box, property_box, func_str_list, func_name, line_style, point_style, func_style
  528. try:
  529. fucn = API.get_func_logger_gui()
  530. diff = fucn.derivatives
  531. if diff is not None and str(diff):
  532. get = str(diff)
  533. func_str_list.append(get)
  534. func_logger.append(
  535. ExpFunc(
  536. get,
  537. "(导)" + fucn.func_name + " Of ",
  538. fucn.style,
  539. fucn.start,
  540. fucn.end,
  541. fucn.span,
  542. fucn.accuracy,
  543. )
  544. )
  545. API.update_func_exp_box_gui()
  546. API.output_prompt_gui("函数生成完毕")
  547. else:
  548. raise Exception
  549. except BaseException:
  550. API.output_prompt_gui("导函数创建失败")
  551. raise
  552. def function_mapping(in_queue, out_queue):
  553. global SCREEN
  554. queue_controller.set_queue(in_queue, out_queue)
  555. queue_controller()
  556. SCREEN.mainloop()
  557. queue_controller.stop_process()
  558. SCREEN.title("CoTan函数实验室")
  559. SCREEN.resizable(width=False, height=False)
  560. SCREEN.geometry(f"+10+10")
  561. SCREEN.iconbitmap(bitmap=f'Pic{os.sep}favicon.ico', default=f'Pic{os.sep}favicon.ico')
  562. rcParams["font.family"] = "simhei"
  563. rcParams["axes.unicode_minus"] = False
  564. tkinter.Label(
  565. SCREEN,
  566. text="输入解析式:",
  567. font=FONT,
  568. width=gui_width,
  569. height=gui_height,
  570. bg=bg_color,
  571. fg=word_color,
  572. ).grid(
  573. column=0, row=0
  574. ) # 设置说明
  575. func_exp = tkinter.Entry(SCREEN, width=gui_width * 2)
  576. func_exp.grid(column=1, row=0, columnspan=2, sticky=tkinter.E + tkinter.W)
  577. # 设置定义域
  578. tkinter.Label(
  579. SCREEN,
  580. font=FONT,
  581. text="定义域:",
  582. width=gui_width,
  583. height=gui_height,
  584. bg=bg_color,
  585. fg=word_color,
  586. ).grid(
  587. column=0, row=1
  588. ) # 设置说明
  589. definition_domain = tkinter.Entry(SCREEN, width=gui_width * 2)
  590. definition_domain.grid(column=1, row=1, columnspan=2, sticky=tkinter.E + tkinter.W)
  591. # 设置函数名字
  592. tkinter.Label(
  593. SCREEN,
  594. font=FONT,
  595. text="函数名字:",
  596. width=gui_width,
  597. height=gui_height,
  598. bg=bg_color,
  599. fg=word_color,
  600. ).grid(
  601. column=0, row=2
  602. ) # 设置说明
  603. func_name = tkinter.Entry(SCREEN, width=gui_width * 2)
  604. func_name.grid(column=1, row=2, columnspan=2, sticky=tkinter.E + tkinter.W)
  605. # 设置函数图示
  606. tkinter.Label(
  607. SCREEN,
  608. font=FONT,
  609. text="函数样式:",
  610. width=gui_width,
  611. height=gui_height,
  612. bg=bg_color,
  613. fg=word_color,
  614. ).grid(
  615. column=0, row=3
  616. ) # 设置说明
  617. func_style = tkinter.Entry(SCREEN, width=gui_width * 2)
  618. func_style.grid(column=1, row=3, columnspan=2, sticky=tkinter.E + tkinter.W)
  619. a_y = 4 # 按钮统一纵坐标
  620. tkinter.Button(
  621. SCREEN,
  622. text="添加新函数",
  623. command=API.add_func,
  624. font=FONT,
  625. width=gui_width,
  626. height=gui_height,
  627. bg=bg_color,
  628. fg=word_color,
  629. ).grid(
  630. column=0, row=a_y
  631. ) # 添加函数
  632. tkinter.Button(
  633. SCREEN,
  634. text="删除选中函数",
  635. command=API.del_func,
  636. font=FONT,
  637. width=gui_width,
  638. height=gui_height,
  639. bg=bg_color,
  640. fg=word_color,
  641. ).grid(
  642. column=1, row=a_y
  643. ) # 删除函数
  644. tkinter.Button(
  645. SCREEN,
  646. text="清除函数",
  647. command=API.clean_func_box,
  648. font=FONT,
  649. width=gui_width,
  650. height=gui_height,
  651. bg=bg_color,
  652. fg=word_color,
  653. ).grid(
  654. column=2, row=a_y
  655. ) # 绘制函数
  656. a_y += 1
  657. # 显示函数
  658. func_exp_box = tkinter.Listbox(SCREEN, width=gui_width * 3 + 2) # 暂时不启用多选
  659. rowspan = 12
  660. func_exp_box.grid(
  661. column=0,
  662. row=a_y,
  663. columnspan=3,
  664. rowspan=rowspan,
  665. sticky=tkinter.S + tkinter.N + tkinter.E + tkinter.W,
  666. )
  667. # a_y += rowspan
  668. # tkinter.Label(
  669. # SCREEN, font=FONT, text="", width=gui_width, height=1, bg=bg_color, fg=word_color
  670. # ).grid(column=0, row=a_y)
  671. tkinter.Label(SCREEN, font=FONT, text="", width=1, bg=bg_color, fg=word_color).grid(
  672. column=4, row=0
  673. ) # 占用第四
  674. a_y = 0
  675. # 输入x函数求y值
  676. tkinter.Label(
  677. SCREEN,
  678. font=FONT,
  679. text="计算(y):",
  680. width=gui_width,
  681. height=gui_height,
  682. bg=bg_color,
  683. fg=word_color,
  684. ).grid(
  685. column=5, row=a_y
  686. ) # 设置说明
  687. x_value = tkinter.Entry(SCREEN, width=gui_width * 2)
  688. x_value.grid(column=6, row=a_y, columnspan=2, sticky=tkinter.E + tkinter.W)
  689. a_y += 1
  690. # 输入x函数求y值
  691. tkinter.Label(
  692. SCREEN,
  693. font=FONT,
  694. text="二分法计算(y):",
  695. width=gui_width,
  696. height=gui_height,
  697. bg=bg_color,
  698. fg=word_color,
  699. ).grid(
  700. column=5, row=a_y
  701. ) # 设置说明
  702. y_value = tkinter.Entry(SCREEN, width=gui_width * 2)
  703. y_value.grid(column=6, row=a_y, columnspan=2, sticky=tkinter.E + tkinter.W)
  704. a_y += 1
  705. tkinter.Label(
  706. SCREEN,
  707. font=FONT,
  708. text="二分法参数:",
  709. width=gui_width,
  710. height=gui_height,
  711. bg=bg_color,
  712. fg=word_color,
  713. ).grid(
  714. column=5, row=a_y
  715. ) # 设置说明
  716. dicon_parameters = tkinter.Entry(SCREEN, width=gui_width * 2)
  717. dicon_parameters.grid(column=6, row=a_y, columnspan=2, sticky=tkinter.E + tkinter.W)
  718. a_y += 1
  719. # 输入x函数求y值
  720. tkinter.Label(
  721. SCREEN,
  722. font=FONT,
  723. text="梯度法计算(y):",
  724. width=gui_width,
  725. height=gui_height,
  726. bg=bg_color,
  727. fg=word_color,
  728. ).grid(
  729. column=5, row=a_y
  730. ) # 设置说明
  731. y_value_gradient = tkinter.Entry(SCREEN, width=gui_width * 2)
  732. y_value_gradient.grid(column=6, row=a_y, columnspan=2, sticky=tkinter.E + tkinter.W)
  733. a_y += 1
  734. tkinter.Button(
  735. SCREEN,
  736. text="计算(y)",
  737. command=API.calculate,
  738. font=FONT,
  739. width=gui_width,
  740. height=gui_height,
  741. bg=bg_color,
  742. fg=word_color,
  743. ).grid(
  744. column=5, row=a_y
  745. ) # 设置说明
  746. tkinter.Button(
  747. SCREEN,
  748. text="二分法计算(x)",
  749. command=API.dichotomy,
  750. font=FONT,
  751. width=gui_width,
  752. height=gui_height,
  753. bg=bg_color,
  754. fg=word_color,
  755. ).grid(column=6, row=a_y)
  756. tkinter.Button(
  757. SCREEN,
  758. text="梯度法计算(x)",
  759. command=API.gradient_method_calculation,
  760. font=FONT,
  761. width=gui_width,
  762. height=gui_height,
  763. bg=bg_color,
  764. fg=word_color,
  765. ).grid(column=7, row=a_y)
  766. a_y += 1
  767. # 绘制函数坐标表格
  768. tkinter.Button(
  769. SCREEN,
  770. text="查看记忆",
  771. command=API.show_memory,
  772. font=FONT,
  773. width=gui_width,
  774. height=gui_height,
  775. bg=bg_color,
  776. fg=word_color,
  777. ).grid(column=5, row=a_y)
  778. tkinter.Button(
  779. SCREEN,
  780. text="隐藏记忆",
  781. command=API.hide_memory,
  782. font=FONT,
  783. width=gui_width,
  784. height=gui_height,
  785. bg=bg_color,
  786. fg=word_color,
  787. ).grid(column=6, row=a_y)
  788. tkinter.Button(
  789. SCREEN,
  790. text="清空记忆",
  791. command=API.clean_func_memory,
  792. font=FONT,
  793. width=gui_width,
  794. height=gui_height,
  795. bg=bg_color,
  796. fg=word_color,
  797. ).grid(column=7, row=a_y)
  798. a_y += 1
  799. # 显示函数
  800. result_box = tkinter.Listbox(SCREEN, width=gui_width * 3 + 2, height=8) # 暂时不启用多选
  801. result_box.grid(
  802. column=5, row=a_y, columnspan=3, sticky=tkinter.N + tkinter.E + tkinter.W
  803. )
  804. a_y += 1
  805. # 设置坐标系刻度
  806. tkinter.Label(
  807. SCREEN,
  808. font=FONT,
  809. text="X轴(函数):",
  810. width=gui_width,
  811. height=gui_height,
  812. bg=bg_color,
  813. fg=word_color,
  814. ).grid(
  815. column=5, row=a_y, sticky=tkinter.N
  816. ) # 设置说明
  817. x_axis = tkinter.Entry(SCREEN, width=gui_width * 2)
  818. x_axis.grid(column=6, row=a_y, columnspan=2, sticky=tkinter.N + tkinter.E + tkinter.W)
  819. a_y += 1
  820. # 设置坐标系刻度
  821. tkinter.Label(
  822. SCREEN,
  823. font=FONT,
  824. text="Y轴(函数):",
  825. width=gui_width,
  826. height=gui_height,
  827. bg=bg_color,
  828. fg=word_color,
  829. ).grid(
  830. column=5, row=a_y
  831. ) # 设置说明
  832. y_axis = tkinter.Entry(SCREEN, width=gui_width * 2)
  833. y_axis.grid(column=6, row=a_y, columnspan=2, sticky=tkinter.E + tkinter.W)
  834. a_y += 1
  835. # 设置坐标系刻度
  836. tkinter.Label(
  837. SCREEN,
  838. font=FONT,
  839. text="X轴极限:",
  840. width=gui_width,
  841. height=gui_height,
  842. bg=bg_color,
  843. fg=word_color,
  844. ).grid(
  845. column=5, row=a_y
  846. ) # 设置说明
  847. x_limit = tkinter.Entry(SCREEN, width=gui_width * 2)
  848. x_limit.grid(column=6, row=a_y, columnspan=2, sticky=tkinter.E + tkinter.W)
  849. a_y += 1
  850. # 设置坐标系刻度
  851. tkinter.Label(
  852. SCREEN,
  853. font=FONT,
  854. text="Y轴极限:",
  855. width=gui_width,
  856. height=gui_height,
  857. bg=bg_color,
  858. fg=word_color,
  859. ).grid(
  860. column=5, row=a_y
  861. ) # 设置说明
  862. y_limit = tkinter.Entry(SCREEN, width=gui_width * 2)
  863. y_limit.grid(column=6, row=a_y, columnspan=2, sticky=tkinter.E + tkinter.W)
  864. a_y += 1
  865. tkinter.Button(
  866. SCREEN,
  867. text="绘制函数",
  868. command=API.plot_func,
  869. font=FONT,
  870. width=gui_width,
  871. height=gui_height,
  872. bg=bg_color,
  873. fg=word_color,
  874. ).grid(
  875. column=5, row=a_y
  876. ) # 绘制函数
  877. tkinter.Button(
  878. SCREEN,
  879. text="计算性质",
  880. command=API.property_prediction,
  881. font=FONT,
  882. width=gui_width,
  883. height=gui_height,
  884. bg=bg_color,
  885. fg=word_color,
  886. ).grid(
  887. column=6, row=a_y
  888. ) # 绘制函数
  889. tkinter.Button(
  890. SCREEN,
  891. text="创建导函数",
  892. command=API.func_differentiation,
  893. font=FONT,
  894. width=gui_width,
  895. height=gui_height,
  896. bg=bg_color,
  897. fg=word_color,
  898. ).grid(
  899. column=7, row=a_y
  900. ) # 绘制函数
  901. a_y += 1
  902. property_box = tkinter.Listbox(SCREEN, width=gui_width * 3 + 2, height=10) # 暂时不启用多选
  903. property_box.grid(
  904. column=5, row=a_y, columnspan=3, sticky=tkinter.N + tkinter.E + tkinter.W
  905. )
  906. a_y += 1
  907. prompt_box = tkinter.Listbox(SCREEN, width=gui_width * 3 + 2, height=3) # 暂时不启用多选
  908. prompt_box.grid(
  909. column=5, row=a_y, columnspan=3, sticky=tkinter.N + tkinter.E + tkinter.W
  910. )
  911. tkinter.Label(SCREEN, font=FONT, text="", width=1, bg=bg_color, fg=word_color).grid(
  912. column=8, row=a_y
  913. ) # 占用第四
  914. a_y = 0
  915. # 绘制函数坐标表格
  916. tkinter.Button(
  917. SCREEN,
  918. text="导入表格",
  919. command=API.add_from_csv,
  920. font=FONT,
  921. width=gui_width,
  922. height=gui_height,
  923. bg=bg_color,
  924. fg=word_color,
  925. ).grid(column=9, row=a_y)
  926. tkinter.Button(
  927. SCREEN,
  928. text="生成表格",
  929. command=API.func_to_sheet_gui,
  930. font=FONT,
  931. width=gui_width,
  932. height=gui_height,
  933. bg=bg_color,
  934. fg=word_color,
  935. ).grid(column=10, row=a_y)
  936. tkinter.Button(
  937. SCREEN,
  938. text="导出表格",
  939. command=API.func_to_csv,
  940. font=FONT,
  941. width=gui_width,
  942. height=gui_height,
  943. bg=bg_color,
  944. fg=word_color,
  945. ).grid(column=11, row=a_y)
  946. a_y += 1
  947. # 显示函数的xy
  948. sheet_box = tkinter.Listbox(SCREEN, width=gui_width * 3 + 2) # 暂时不启用多选
  949. sheet_box.grid(
  950. column=9,
  951. row=a_y,
  952. columnspan=3,
  953. rowspan=rowspan + 4,
  954. sticky=tkinter.S + tkinter.N + tkinter.E + tkinter.W,
  955. )
  956. API.output_prompt_gui("加载完成,欢迎使用!")