1
0

factory.py 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729
  1. from __future__ import division # 让/恢复为除法
  2. import random
  3. import tkinter
  4. import tkinter.messagebox
  5. import os
  6. import logging
  7. import sympy
  8. from matplotlib import pyplot as plt
  9. from matplotlib import rcParams
  10. from matplotlib.animation import FuncAnimation
  11. from funcsystem.controller import ExpFunc as ExpFunc
  12. from newtkinter import asksaveasfilename
  13. from system import exception_catch, basicConfig, QueueController
  14. queue_controller = QueueController()
  15. logging.basicConfig(**basicConfig)
  16. func = None
  17. fig = None
  18. prompt_num = 0
  19. line_style = {
  20. "实线": "-",
  21. "短横线": "--",
  22. "点划线": "-,",
  23. "虚线": ":",
  24. "点标记": ".",
  25. "圆标记": "o",
  26. "倒三角": "v",
  27. "正三角": "^",
  28. "左三角": "&lt",
  29. "下箭头": "1",
  30. "上箭头": "2",
  31. "左箭头": "3",
  32. "右箭头": "4",
  33. "正方形": "s",
  34. "五边形": "p",
  35. "星形": "*",
  36. "六边形": "h",
  37. "六边形2": "H",
  38. "+号": "+",
  39. "X标记": "x",
  40. } # 函数样式翻译表
  41. point_style = ["g", "r", "c", "m", "y", "k"]
  42. SCREEN = tkinter.Tk()
  43. bg_color = "#FFFAFA" # 主颜色
  44. botton_color = "#FFFAFA" # 按钮颜色
  45. word_color = "#000000" # 文字颜色
  46. gui_width = 13 # 标准宽度
  47. gui_height = 2
  48. row = 0
  49. column = 1
  50. class UIAPI:
  51. @staticmethod
  52. @exception_catch()
  53. def dichotomy_gui():
  54. parameters = [100, 0.0001, 0.1, 0.5, False, True, 1000, 0.1, 0.1, False, None]
  55. for i in range(11):
  56. try:
  57. if i in (4, 5, 9):
  58. a = dicon_parameters[i].get()
  59. else:
  60. a = float(dicon_parameters[i].get())
  61. parameters[i] = a
  62. except BaseException as e:
  63. logging.warning(str(e))
  64. return parameters
  65. @staticmethod
  66. @exception_catch()
  67. def output_prompt_gui(news):
  68. global prompt_box, prompt_num, SCREEN
  69. prompt_num += 1
  70. news = str(news)
  71. prompt_box.insert(0, news + f"({prompt_num})")
  72. SCREEN.update()
  73. @staticmethod
  74. @exception_catch()
  75. def set_func_gui():
  76. new_func = func_exp.get().replace(" ", "")
  77. if new_func == "":
  78. API.output_prompt_gui("应用失败")
  79. raise Exception
  80. default_value = [-10, 10, 0.1, 2, 1, -10, 10, 1]
  81. get = [
  82. start_definition,
  83. end_definition,
  84. span_definition,
  85. accuracy,
  86. default_a,
  87. start_a,
  88. end_a,
  89. span_a,
  90. ]
  91. # 参数的处理
  92. span = None
  93. try:
  94. span_str = span_definition.get().replace(" ", "")
  95. if span_str[0] == "H":
  96. domain = {
  97. "Pi": sympy.pi,
  98. "e": sympy.E,
  99. "log": sympy.log,
  100. "sin": sympy.sin,
  101. "cos": sympy.cos,
  102. "tan": sympy.tan,
  103. "cot": lambda x: 1 / sympy.tan(x),
  104. "csc": lambda x: 1 / sympy.sin(x),
  105. "sec": lambda x: 1 / sympy.cos(x),
  106. "sinh": sympy.sinh,
  107. "cosh": sympy.cosh,
  108. "tanh": sympy.tanh,
  109. "asin": sympy.asin,
  110. "acos": sympy.acos,
  111. "atan": sympy.atan,
  112. }
  113. span = eval(span_str[1:], domain)
  114. except BaseException as e:
  115. logging.warning(str(e))
  116. for i in range(8):
  117. try:
  118. default_value[i] = float(get[i].get())
  119. except BaseException as e:
  120. logging.warning(str(e))
  121. if span is not None:
  122. default_value[2] = span
  123. # View的处理
  124. style_str = func_style.get().split("#")
  125. try:
  126. if style_str[0] not in point_style:
  127. style_str[0] = "b"
  128. line_style_str = line_style.get(style_str[1], "-")
  129. except IndexError:
  130. style_str = ["", ""]
  131. style_str[0] = random.choice(point_style)
  132. line_style_str = "-"
  133. style = style_str[0] + line_style_str
  134. # Name的处理
  135. name = func_name.get().replace(" ", "")
  136. if name == "":
  137. name = new_func
  138. return [new_func, name, style]+default_value
  139. @staticmethod
  140. @exception_catch()
  141. def get_y_value_gui():
  142. return y_value.get().split(",")
  143. @staticmethod
  144. @exception_catch()
  145. def update_prediction_box_gui(*answer):
  146. prediction_box.delete(0, tkinter.END)
  147. prediction_box.insert(tkinter.END, *answer)
  148. @staticmethod
  149. @exception_catch()
  150. def get_projection_value_gui():
  151. return projection_value.get()
  152. @staticmethod
  153. @exception_catch()
  154. def get_proximity_accuracy_gui():
  155. return proximity_accuracy.get()
  156. @staticmethod
  157. @exception_catch()
  158. def get_x_value_derivation_gui():
  159. return x_value_derivation.get().split(",")
  160. @staticmethod
  161. @exception_catch()
  162. def get_y_value_symbol_gui():
  163. return y_value_symbol.get().split(",")
  164. @staticmethod
  165. @exception_catch()
  166. def get_x_value_gui():
  167. return x_value.get().split(",")
  168. @staticmethod
  169. @exception_catch()
  170. def update_result_box_gui(answer):
  171. result_box.delete(0, tkinter.END) # 清空
  172. result_box.insert(tkinter.END, *answer)
  173. @staticmethod
  174. @exception_catch()
  175. def get_y_value_gradient_gui():
  176. return y_value_gradient.get()
  177. @staticmethod
  178. @exception_catch()
  179. def askokcancel_gui(message):
  180. return tkinter.messagebox.askokcancel("提示", message)
  181. @staticmethod
  182. @exception_catch()
  183. def add_projection_box_gui(result):
  184. projection_box.insert(tkinter.END, result)
  185. @staticmethod
  186. @exception_catch()
  187. def update_sheet_box_gui(sheet):
  188. sheet_box.delete(0, tkinter.END)
  189. sheet_box.insert(tkinter.END, *sheet)
  190. @staticmethod
  191. @exception_catch()
  192. def get_save_dir_gui():
  193. return asksaveasfilename(title="选择导出位置", filetypes=[("CSV", ".csv")])
  194. class API(UIAPI):
  195. @staticmethod
  196. @exception_catch()
  197. def type_selection(sequence, type_=float, convert=True): # Float筛选系统
  198. x = []
  199. for i in sequence:
  200. try:
  201. if type_(i) == type_(0) and convert:
  202. continue
  203. x.append(type_(i))
  204. except ValueError:
  205. pass
  206. return x
  207. @staticmethod
  208. @exception_catch()
  209. def save_to_csv(): # 导出CSV
  210. try:
  211. if not func.save_csv(API.get_save_dir_gui()):
  212. raise Exception
  213. API.output_prompt_gui("CSV导出成功")
  214. except BaseException:
  215. API.output_prompt_gui("CSV导出失败")
  216. raise
  217. @staticmethod
  218. @exception_catch()
  219. def save_to_sheet(): # 生成表格
  220. try:
  221. API.update_sheet_box_gui(func.return_list())
  222. API.output_prompt_gui("表格创建成功")
  223. except BaseException:
  224. API.output_prompt_gui("无法创建表格")
  225. raise
  226. @staticmethod
  227. @exception_catch()
  228. def sympy_computing(exp_str) -> tuple:
  229. try:
  230. named_domain = {
  231. "Pi": sympy.pi,
  232. "e": sympy.E,
  233. "log": sympy.log,
  234. "sin": sympy.sin,
  235. "cos": sympy.cos,
  236. "tan": sympy.tan,
  237. "cot": lambda x: 1 / sympy.tan(x),
  238. "csc": lambda x: 1 / sympy.sin(x),
  239. "sec": lambda x: 1 / sympy.cos(x),
  240. "sinh": sympy.sinh,
  241. "cosh": sympy.cosh,
  242. "tanh": sympy.tanh,
  243. "asin": sympy.asin,
  244. "acos": sympy.acos,
  245. "atan": sympy.atan,
  246. }
  247. answer = eval(exp_str, named_domain)
  248. return answer, True
  249. except (SyntaxError, ZeroDivisionError, NameError, TypeError, ValueError):
  250. return None, False
  251. @staticmethod
  252. @exception_catch()
  253. def computing_gui():
  254. accuracy_, must = API.sympy_computing(prediction_accuracy.get())
  255. return accuracy_
  256. @staticmethod
  257. @exception_catch()
  258. def confirmation_expression(c):
  259. get = API.sympy_computing(c)
  260. if not get[1]:
  261. return c
  262. return get[0]
  263. @staticmethod
  264. @exception_catch()
  265. def check_center_of_symmetry():
  266. accuracy_ = API.computing_gui()
  267. try:
  268. result = func.check_symmetry_center(API.get_projection_value_gui(), API.output_prompt_gui, accuracy_)
  269. if result[0]:
  270. API.add_projection_box_gui(result[1])
  271. API.output_prompt_gui("预测完成")
  272. else:
  273. API.add_projection_box_gui(result[1])
  274. raise Exception
  275. except BaseException:
  276. API.output_prompt_gui("预测失败")
  277. raise
  278. @staticmethod
  279. @exception_catch()
  280. def check_symmetry_axis():
  281. accuracy_ = API.computing_gui()
  282. try:
  283. result = func.check_symmetry_axis(
  284. API.confirmation_expression(API.get_projection_value_gui()), API.output_prompt_gui, accuracy_
  285. )
  286. if result[0]:
  287. API.add_projection_box_gui(result[1])
  288. API.output_prompt_gui("预测完成")
  289. else:
  290. API.add_projection_box_gui(result[1])
  291. raise Exception
  292. except BaseException:
  293. API.output_prompt_gui("预测失败")
  294. raise # 给log捕捉
  295. @staticmethod
  296. @exception_catch()
  297. def check_periodic():
  298. accuracy_ = API.computing_gui()
  299. try:
  300. result = func.check_periodic(
  301. API.confirmation_expression(API.get_projection_value_gui()), API.output_prompt_gui, accuracy_
  302. )
  303. if result[0]:
  304. API.add_projection_box_gui(result[1])
  305. API.output_prompt_gui("预测完成")
  306. else:
  307. API.add_projection_box_gui(result[1])
  308. raise Exception
  309. except BaseException:
  310. API.output_prompt_gui("预测失败")
  311. raise
  312. @staticmethod
  313. @exception_catch()
  314. def check_monotonic():
  315. accuracy_ = API.computing_gui()
  316. try:
  317. result = func.check_monotonic(
  318. API.get_projection_value_gui(), API.output_prompt_gui, accuracy_
  319. )
  320. if result[1]:
  321. API.add_projection_box_gui(result[1])
  322. API.output_prompt_gui("预测完成")
  323. else:
  324. API.add_projection_box_gui(result[1])
  325. raise Exception
  326. except BaseException:
  327. API.output_prompt_gui("预测失败")
  328. raise
  329. @staticmethod
  330. @exception_catch()
  331. def clear_memory():
  332. try:
  333. if API.askokcancel_gui(f"确定删除{func}的记忆吗?"):
  334. API.update_result_box_gui([])
  335. func.clean_memory()
  336. API.output_prompt_gui("删除完毕")
  337. else:
  338. API.output_prompt_gui("删除取消")
  339. except BaseException:
  340. API.output_prompt_gui("删除失败")
  341. raise
  342. @staticmethod
  343. @exception_catch()
  344. def show_hidden_memory(): # 显示xy
  345. try:
  346. API.update_result_box_gui([])
  347. func.hide_or_show()
  348. API.output_prompt_gui("已清空卡槽")
  349. except BaseException:
  350. API.output_prompt_gui("隐藏(显示)失败")
  351. raise
  352. @staticmethod
  353. @exception_catch()
  354. def gradient_method_calculation():
  355. try:
  356. API.output_prompt_gui("计算过程程序可能无响应")
  357. parameters = []
  358. for i in gradient_parameters:
  359. parameters.append(i.get())
  360. API.output_prompt_gui("系统运算中")
  361. answer = func.gradient_calculation(API.get_y_value_gradient_gui(), *parameters)
  362. if answer[1] is not None:
  363. API.update_result_box_gui(answer[0])
  364. API.output_prompt_gui("系统运算完成")
  365. else:
  366. API.output_prompt_gui("系统运算无结果")
  367. except BaseException:
  368. API.output_prompt_gui("系统运算失败,请注意参数设置")
  369. raise
  370. @staticmethod
  371. @exception_catch()
  372. def calculate():
  373. try:
  374. API.output_prompt_gui("计算过程程序可能无响应")
  375. answer = func.calculation(API.get_x_value_gui())
  376. if answer:
  377. API.output_prompt_gui("系统运算完毕")
  378. else:
  379. API.output_prompt_gui("系统运算无结果")
  380. API.update_result_box_gui(answer)
  381. except BaseException:
  382. API.output_prompt_gui("计算失败")
  383. raise
  384. # raise
  385. @staticmethod
  386. @exception_catch()
  387. def sympy_calculation_x():
  388. try:
  389. API.output_prompt_gui("计算过程程序可能无响应")
  390. answer = []
  391. for i in API.get_y_value_symbol_gui():
  392. answer += func.sympy_calculation(i)[0]
  393. if answer:
  394. API.output_prompt_gui("系统运算完毕")
  395. else:
  396. API.output_prompt_gui("系统运算无结果")
  397. API.update_result_box_gui(answer)
  398. except BaseException:
  399. API.output_prompt_gui("计算失败")
  400. raise
  401. @staticmethod
  402. @exception_catch()
  403. def function_differentiation():
  404. try:
  405. API.output_prompt_gui("计算过程程序可能无响应")
  406. accuracy_ = API.get_proximity_accuracy_gui()
  407. answer = []
  408. for i in API.get_x_value_derivation_gui():
  409. get = func.derivative(i, accuracy_)[0]
  410. if get is not None:
  411. answer.append(get)
  412. if answer:
  413. API.output_prompt_gui("系统运算完毕")
  414. else:
  415. API.output_prompt_gui("系统运算无结果")
  416. API.update_result_box_gui(answer)
  417. except IndexError:
  418. API.output_prompt_gui("计算失败")
  419. @staticmethod
  420. @exception_catch()
  421. def approximation(): # 逼近法
  422. try:
  423. API.output_prompt_gui("计算过程程序可能无响应")
  424. accuracy_ = API.get_proximity_accuracy_gui()
  425. answer = []
  426. for i in API.get_x_value_derivation_gui():
  427. get = func.derivative(i, accuracy_, True)[0]
  428. if get is not None:
  429. answer.append(get)
  430. if answer:
  431. API.output_prompt_gui("系统运算完毕")
  432. else:
  433. API.output_prompt_gui("系统运算无结果")
  434. API.update_result_box_gui(answer)
  435. except IndexError:
  436. API.output_prompt_gui("计算失败")
  437. @staticmethod
  438. @exception_catch()
  439. def dichotomy(): # 二分法
  440. global dicon_parameters, func, result_box
  441. try:
  442. API.output_prompt_gui("计算过程程序可能无响应")
  443. answer = []
  444. API.output_prompt_gui("系统运算中")
  445. for i in API.get_y_value_gui():
  446. try:
  447. answer += func.dichotomy(float(i), *API.dichotomy_gui())[0]
  448. except BaseException as e:
  449. logging.warning(str(e))
  450. if answer:
  451. API.output_prompt_gui("系统运算完成")
  452. else:
  453. API.output_prompt_gui("系统运算无结果")
  454. API.update_result_box_gui(answer)
  455. except BaseException:
  456. API.output_prompt_gui("系统运算失败")
  457. raise
  458. @staticmethod
  459. @exception_catch()
  460. def property_prediction():
  461. try:
  462. accuracy_ = API.computing_gui()
  463. API.output_prompt_gui("预测过程程序可能无响应")
  464. answer = func.property_prediction(API.output_prompt_gui, True, accuracy_)
  465. API.update_prediction_box_gui(*answer)
  466. API.output_prompt_gui("性质预测完成")
  467. except IndexError:
  468. API.output_prompt_gui("性质预测失败")
  469. @staticmethod
  470. @exception_catch()
  471. def function_drawing():
  472. global x_scale, start_x_plot, start_x_polt, span_x_plot, y_scale, start_y_plot, end_y_plot, span_y_plot
  473. global start_x_limit, end_x_limit, start_y_limit, end_y_limit
  474. global func, fig, show_point, show_best_value, show_text, plot_type, frame_rate
  475. try:
  476. draw_type = plot_type.curselection()[0]
  477. except IndexError:
  478. draw_type = 0
  479. # 画板创造
  480. API.output_prompt_gui("生成绘制取...")
  481. fig = plt.figure(num="CoTan函数") # 定义一个图像窗口
  482. if draw_type in (0, 1, 2, 3, 8, 9):
  483. plt.grid(True, ls="--") # 显示网格(不能放到后面,因为后面调整成为了笛卡尔坐标系)
  484. axis = plt.gca()
  485. text_y = ""
  486. text_x = ""
  487. def init():
  488. nonlocal text_x, text_y
  489. if draw_type in (0, 2, 4, 6, 8):
  490. axis.spines["right"].set_color("none")
  491. axis.spines["top"].set_color("none")
  492. axis.xaxis.set_ticks_position("bottom")
  493. axis.yaxis.set_ticks_position("left")
  494. axis.spines["bottom"].set_position(("data", 0)) # 设置x轴, y轴在(0, 0)的位置
  495. axis.spines["left"].set_position(("data", 0))
  496. # 检测x
  497. try:
  498. if x_scale.get()[0] == "c": # 如果输入函数cx#-10#10#1#1
  499. plot_parameter = [
  500. x_scale.get()[1:],
  501. start_x_plot.get(),
  502. start_x_polt.get(),
  503. span_x_plot.get(),
  504. 2,
  505. ] # 第一部分HS,第二部分S,第三部分E,第四部分KD,第五部分JD
  506. exp_parameter = ["x", -10, 10, 1, 2] # 保护系统
  507. try:
  508. exp_parameter[0] = plot_parameter[0]
  509. exp_parameter[1] = int(plot_parameter[1])
  510. exp_parameter[2] = int(plot_parameter[2])
  511. exp_parameter[3] = int(plot_parameter[3])
  512. exp_parameter[4] = int(plot_parameter[4])
  513. except BaseException as e:
  514. logging.warning(str(e))
  515. plot_parameter = exp_parameter
  516. x_exp_scale = API.type_selection(
  517. ExpFunc(
  518. plot_parameter[0],
  519. "x",
  520. "",
  521. plot_parameter[1],
  522. plot_parameter[2],
  523. plot_parameter[3],
  524. plot_parameter[4],
  525. ).data_packet()[1]
  526. ) # 取y
  527. axis.set_xticks(x_exp_scale) # 输入表达式计算刻度
  528. elif x_scale.get()[0] == "y": # 输入函数y
  529. # 不错要错误捕捉,外围有个大的捕捉
  530. x_exp_scale = abs(int(start_x_plot.get()))
  531. x_major_locator = plt.MultipleLocator(x_exp_scale)
  532. axis.xaxis.set_major_locator(x_major_locator)
  533. else: # 输入纯数字
  534. x_exp_scale = API.type_selection(x_scale.get().split(","))
  535. axis.set_xticks(x_exp_scale)
  536. except BaseException as e:
  537. logging.debug(str(e))
  538. x_major_locator = plt.MultipleLocator(2)
  539. axis.xaxis.set_major_locator(x_major_locator)
  540. # 检测y
  541. try: # 意外捕捉
  542. if y_scale.get()[0] == "c": # 如果输入函数cx#-10#10#1#1
  543. plot_parameter = [
  544. y_scale.get()[1:],
  545. start_y_plot.get(),
  546. end_y_plot.get(),
  547. span_y_plot.get(),
  548. 2,
  549. ] # 第一部分HS,第二部分S,第三部分E,第四部分KD,第五部分JD
  550. exp_parameter = ["x", -10, 10, 1, 2] # 保护系统
  551. try:
  552. exp_parameter[0] = plot_parameter[0]
  553. exp_parameter[1] = int(plot_parameter[1])
  554. exp_parameter[2] = int(plot_parameter[2])
  555. exp_parameter[3] = int(plot_parameter[3])
  556. exp_parameter[4] = int(plot_parameter[4])
  557. except BaseException as e:
  558. logging.warning(str(e))
  559. plot_parameter = exp_parameter
  560. y_exp_scale = API.type_selection(
  561. ExpFunc(
  562. plot_parameter[0],
  563. "y",
  564. "",
  565. plot_parameter[1],
  566. plot_parameter[2],
  567. plot_parameter[3],
  568. plot_parameter[4],
  569. ).data_packet()[1]
  570. ) # 取y
  571. axis.set_yticks(y_exp_scale)
  572. elif y_scale.get()[0] == "y": # 输入函数y
  573. y_exp_scale = abs(int(start_y_plot.get()))
  574. y_major_locator = plt.MultipleLocator(y_exp_scale)
  575. axis.yaxis.set_major_locator(y_major_locator)
  576. else:
  577. y_exp_scale = API.type_selection(y_scale.get().split(","))
  578. axis.set_yticks(y_exp_scale)
  579. except BaseException as e:
  580. logging.debug(str(e))
  581. y_major_locator = plt.MultipleLocator(2)
  582. axis.yaxis.set_major_locator(y_major_locator)
  583. # 极限
  584. _x_limit = [-10, 10]
  585. _y_limit = [-10, 10]
  586. try:
  587. x_limit = API.type_selection(
  588. [start_x_limit.get(), end_x_limit.get()], type_=int, convert=False
  589. )
  590. y_limit = API.type_selection(
  591. [start_y_limit.get(), end_y_limit.get()], type_=int, convert=False
  592. )
  593. try:
  594. _x_limit = [x_limit[0], x_limit[1]]
  595. except IndexError:
  596. _x_limit = [-10, 10]
  597. try:
  598. _y_limit = [y_limit[0], y_limit[1]]
  599. except IndexError:
  600. _y_limit = _x_limit
  601. except BaseException as e:
  602. logging.warning(str(e))
  603. _x_limit.sort()
  604. _y_limit.sort()
  605. axis.set_xlim(_x_limit)
  606. axis.set_ylim(_y_limit)
  607. text_x = _x_limit[0] + abs(_x_limit[0]) * 0.01
  608. text_y = _y_limit[1] - abs(_y_limit[1]) * 0.01
  609. init()
  610. # 函数绘图系统
  611. API.output_prompt_gui("图像绘制中...")
  612. if func is None:
  613. return False
  614. if draw_type in (0, 1, 4, 5):
  615. # 绘制曲线
  616. get = func.get_plot_data()
  617. plot_x = get[0]
  618. plot_y = get[1]
  619. func_label = get[2]
  620. exp_style = get[3]
  621. first = True
  622. for i in range(len(plot_x)):
  623. plot_x = plot_x[i]
  624. plot_y = plot_y[i]
  625. if first:
  626. plt.plot(plot_x, plot_y, exp_style, label=func_label) # plot()画出曲线
  627. first = False
  628. else:
  629. plt.plot(plot_x, plot_y, exp_style)
  630. # 绘制记忆点
  631. get = func.get_memory()
  632. plot_memory_x = get[0]
  633. plot_memory_y = get[1]
  634. max_x, max_y, min_x, min_y = func.best_value()
  635. if show_point.get():
  636. plt.plot(
  637. plot_memory_x,
  638. plot_memory_y,
  639. exp_style[0] + "o",
  640. label=f"Point of {func_label}",
  641. ) # 画出一些点
  642. memory_x = sorted(list(set(plot_memory_x))) # 去除list重复项目
  643. extreme_points = max_x + min_x
  644. if show_text.get():
  645. last_x = None
  646. for i in range(len(memory_x)):
  647. if i in extreme_points:
  648. continue # 去除极值点
  649. now_x = memory_x[i] # x
  650. if last_x is None or abs(now_x - last_x) >= 1: # 确保位置
  651. num = plot_memory_x.index(now_x) # y的座位
  652. now_y = plot_memory_y[num]
  653. plt.text(
  654. now_x,
  655. now_y,
  656. f"({now_x},{int(now_y)})",
  657. fontdict={"size": "10", "color": "b"},
  658. ) # 标出坐标
  659. last_x = now_x
  660. if show_best_value.get():
  661. last_x = None
  662. plot_max = []
  663. for i in range(len(max_x)): # 画出最大值
  664. now_x = max_x[i]
  665. if last_x is None or abs(now_x - last_x) >= 1: # 确保位置
  666. if show_text.get():
  667. plt.text(
  668. now_x - 1,
  669. max_y,
  670. f"max:({now_x},{int(max_y)})",
  671. fontdict={"size": "10", "color": "b"},
  672. ) # 标出坐标
  673. plot_max.append(now_x)
  674. last_x = now_x
  675. last_x = None
  676. plot_min = []
  677. for i in range(len(min_x)): # 画出最小值
  678. now_x = min_x[i]
  679. if last_x is None or abs(now_x - last_x) >= 1:
  680. plot_min.append(now_x)
  681. if show_text.get():
  682. plt.text(
  683. now_x - 1,
  684. min_y,
  685. f"min:({now_x},{int(min_y)})",
  686. fontdict={"size": "10", "color": "b"},
  687. ) # 标出坐标
  688. last_x = now_x
  689. plt.plot(plot_min, [min_y] * len(plot_min), exp_style[0] + "o") # 画出一些点
  690. plt.plot(plot_max, [max_y] * len(plot_max), exp_style[0] + "o") # 画出一些点
  691. plt.legend() # 显示图示
  692. elif draw_type in (8, 9):
  693. get = func.data_packet()
  694. plot_x = get[0]
  695. plot_y = get[1]
  696. plot_x_len = len(plot_x)
  697. x_data = []
  698. y_data = []
  699. func_label = get[2]
  700. exp_style = get[3]
  701. plot_ln = axis.plot([], [], exp_style, label=func_label, animated=False)[0]
  702. text = plt.text(text_x, text_y, "", fontdict={"size": "10", "color": "b"})
  703. def _init():
  704. init()
  705. return plot_ln, text
  706. def update(n):
  707. nonlocal x_data, y_data
  708. if n == 0:
  709. x_data = []
  710. y_data = []
  711. x_data.append(plot_x[n])
  712. y_data.append(plot_y[n])
  713. text.set_text(f"x={plot_x[n]},y={plot_y[n]}")
  714. plot_ln.set_data(x_data, y_data)
  715. return plot_ln, text
  716. try: # 自定义帧率
  717. frame = int(frame_rate.get())
  718. except ValueError:
  719. frame = 100
  720. ani = FuncAnimation(
  721. fig,
  722. update,
  723. frames=plot_x_len,
  724. init_func=_init,
  725. interval=frame,
  726. blit=False,
  727. repeat_delay=3000,
  728. ) # 动态绘图
  729. elif draw_type in (2, 3, 6, 7):
  730. text = plt.text(text_x, text_y, "", fontdict={"size": "10", "color": "b"})
  731. all_func = func.return_son()
  732. func_cul_list = []
  733. plot_x_len = len(all_func)
  734. m = [] # 每个群组中fx分类的个数
  735. for i in all_func: # 预先生成函数
  736. API.output_prompt_gui(f"迭代计算中...(共{plot_x_len}次)")
  737. get = i.get_plot_data()
  738. m.append(len(get[0]))
  739. func_cul_list.append(get)
  740. func_cul_list += func_cul_list[::-1]
  741. ln_list = [text]
  742. for i in range(max(m)):
  743. ln_list.append(
  744. axis.plot([], [], func_cul_list[0][3], animated=False)[0]
  745. ) # 创建足够的i
  746. plot_x_len = len(func_cul_list)
  747. def _init():
  748. init()
  749. text.set_text("")
  750. return None
  751. def update(n):
  752. print('A')
  753. get_ = func_cul_list[n - 1]
  754. ln_list[0].set_text(get_[2])
  755. for i in range(max(m)):
  756. try:
  757. x = get_[0][i]
  758. y = get_[1][i]
  759. print(x)
  760. print(y)
  761. ln_list[i + 1].set_data(x, y)
  762. except IndexError:
  763. ln_list[i + 1].set_data([], [])
  764. return ln_list
  765. try: # 自定义帧率
  766. frame = int(frame_rate.get())
  767. except ValueError:
  768. frame = 100
  769. ani = FuncAnimation(
  770. fig, update, frames=plot_x_len, init_func=_init, interval=frame, blit=False
  771. ) # 动态绘图(请不要去除ani = ,原因不清楚)
  772. API.output_prompt_gui("绘制完毕")
  773. plt.show() # 显示图像
  774. return True
  775. @staticmethod
  776. @exception_catch()
  777. def set_function():
  778. global func
  779. default_value = API.set_func_gui()
  780. try:
  781. func = ExpFunc(*default_value, have_son=True)
  782. API.output_prompt_gui("应用成功")
  783. SCREEN.title(f"CoTan函数工厂 {func}")
  784. except BaseException:
  785. API.output_prompt_gui("应用失败2")
  786. raise
  787. def function_factory_main(in_queue, out_queue): # H_S-默认函数GF-关闭时询问返回函数
  788. global SCREEN
  789. API.output_prompt_gui("加载完毕")
  790. queue_controller.set_queue(in_queue, out_queue)
  791. queue_controller()
  792. SCREEN.mainloop()
  793. queue_controller.stop_process()
  794. SCREEN["bg"] = bg_color
  795. SCREEN.title("CoTan函数工厂")
  796. SCREEN.resizable(width=False, height=False)
  797. SCREEN.geometry("+10+10")
  798. SCREEN.iconbitmap(bitmap=f'Pic{os.sep}favicon.ico', default=f'Pic{os.sep}favicon.ico')
  799. FONT = (rf"Font{os.sep}ZKST.ttf", 11) # 设置字体
  800. rcParams["font.family"] = "simhei"
  801. rcParams["axes.unicode_minus"] = False
  802. tkinter.Label(
  803. SCREEN,
  804. text="输入解析式:",
  805. bg=bg_color,
  806. fg=word_color,
  807. font=FONT,
  808. width=gui_width,
  809. height=gui_height,
  810. ).grid(
  811. column=column, row=row
  812. ) # 设置说明
  813. func_exp = tkinter.Entry(SCREEN, width=gui_width * 2)
  814. func_exp.grid(column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W)
  815. row += 1
  816. tkinter.Label(
  817. SCREEN,
  818. text="定义域前端点:",
  819. bg=bg_color,
  820. fg=word_color,
  821. font=FONT,
  822. width=gui_width,
  823. height=gui_height,
  824. ).grid(
  825. column=column, row=row
  826. ) # 设置说明
  827. start_definition = tkinter.Entry(SCREEN, width=gui_width * 2)
  828. start_definition.grid(
  829. column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W
  830. )
  831. row += 1
  832. tkinter.Label(
  833. SCREEN,
  834. text="定义域后端点:",
  835. bg=bg_color,
  836. fg=word_color,
  837. font=FONT,
  838. width=gui_width,
  839. height=gui_height,
  840. ).grid(
  841. column=column, row=row
  842. ) # 设置说明
  843. end_definition = tkinter.Entry(SCREEN, width=gui_width * 2)
  844. end_definition.grid(
  845. column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W
  846. )
  847. row += 1
  848. tkinter.Label(
  849. SCREEN,
  850. text="函数绘制跨度:",
  851. bg=bg_color,
  852. fg=word_color,
  853. font=FONT,
  854. width=gui_width,
  855. height=gui_height,
  856. ).grid(
  857. column=column, row=row
  858. ) # 设置说明
  859. span_definition = tkinter.Entry(SCREEN, width=gui_width * 2)
  860. span_definition.grid(
  861. column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W
  862. )
  863. row += 1
  864. tkinter.Label(
  865. SCREEN,
  866. text="函数计算精度:",
  867. bg=bg_color,
  868. fg=word_color,
  869. font=FONT,
  870. width=gui_width,
  871. height=gui_height,
  872. ).grid(
  873. column=column, row=row
  874. ) # 设置说明
  875. accuracy = tkinter.Entry(SCREEN, width=gui_width * 2)
  876. accuracy.grid(column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W)
  877. row += 1
  878. tkinter.Label(
  879. SCREEN,
  880. text="函数名字:",
  881. bg=bg_color,
  882. fg=word_color,
  883. font=FONT,
  884. width=gui_width,
  885. height=gui_height,
  886. ).grid(
  887. column=column, row=row
  888. ) # 设置说明
  889. func_name = tkinter.Entry(SCREEN, width=gui_width * 2)
  890. func_name.grid(column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W)
  891. row += 1
  892. tkinter.Label(
  893. SCREEN,
  894. text="函数视图:",
  895. bg=bg_color,
  896. fg=word_color,
  897. font=FONT,
  898. width=gui_width,
  899. height=gui_height,
  900. ).grid(
  901. column=column, row=row
  902. ) # 设置说明
  903. func_style = tkinter.Entry(SCREEN, width=gui_width * 2)
  904. func_style.grid(column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W)
  905. row += 1
  906. tkinter.Label(
  907. SCREEN,
  908. text="常量a默认值:",
  909. bg=bg_color,
  910. fg=word_color,
  911. font=FONT,
  912. width=gui_width,
  913. height=gui_height,
  914. ).grid(
  915. column=column, row=row
  916. ) # 设置说明
  917. default_a = tkinter.Entry(SCREEN, width=gui_width * 2)
  918. default_a.grid(column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W)
  919. row += 1
  920. tkinter.Label(
  921. SCREEN,
  922. text="常量a起点:",
  923. bg=bg_color,
  924. fg=word_color,
  925. font=FONT,
  926. width=gui_width,
  927. height=gui_height,
  928. ).grid(
  929. column=column, row=row
  930. ) # 设置说明
  931. start_a = tkinter.Entry(SCREEN, width=gui_width * 2)
  932. start_a.grid(column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W)
  933. row += 1
  934. tkinter.Label(
  935. SCREEN,
  936. text="常量a终点:",
  937. bg=bg_color,
  938. fg=word_color,
  939. font=FONT,
  940. width=gui_width,
  941. height=gui_height,
  942. ).grid(
  943. column=column, row=row
  944. ) # 设置说明
  945. end_a = tkinter.Entry(SCREEN, width=gui_width * 2)
  946. end_a.grid(column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W)
  947. row += 1
  948. tkinter.Label(
  949. SCREEN,
  950. text="常量a跨度:",
  951. bg=bg_color,
  952. fg=word_color,
  953. font=FONT,
  954. width=gui_width,
  955. height=gui_height,
  956. ).grid(
  957. column=column, row=row
  958. ) # 设置说明
  959. span_a = tkinter.Entry(SCREEN, width=gui_width * 2)
  960. span_a.grid(column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W)
  961. row += 1
  962. tkinter.Button(
  963. SCREEN,
  964. bg=botton_color,
  965. fg=word_color,
  966. text="应用函数",
  967. command=API.set_function,
  968. font=FONT,
  969. width=gui_width,
  970. height=gui_height,
  971. ).grid(
  972. column=column, row=row, sticky=tkinter.E + tkinter.W
  973. ) # 添加函数
  974. tkinter.Button(
  975. SCREEN,
  976. bg=botton_color,
  977. fg=word_color,
  978. text="绘制图像",
  979. command=API.function_drawing,
  980. font=FONT,
  981. width=gui_width,
  982. height=gui_height,
  983. ).grid(column=column + 1, row=row, sticky=tkinter.E + tkinter.W)
  984. tkinter.Button(
  985. SCREEN,
  986. bg=botton_color,
  987. fg=word_color,
  988. text="性质预测",
  989. command=API.property_prediction,
  990. font=FONT,
  991. width=gui_width,
  992. height=gui_height,
  993. ).grid(
  994. column=column + 2, row=row, sticky=tkinter.E + tkinter.W
  995. ) # 添加函数
  996. row += 1
  997. tkinter.Label(
  998. SCREEN,
  999. text="预测精度:",
  1000. bg=bg_color,
  1001. fg=word_color,
  1002. font=FONT,
  1003. width=gui_width,
  1004. height=gui_height,
  1005. ).grid(
  1006. column=column, row=row
  1007. ) # 设置说明
  1008. prediction_accuracy = tkinter.Entry(SCREEN, width=gui_width * 2)
  1009. prediction_accuracy.grid(
  1010. column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W
  1011. )
  1012. row += 1
  1013. # 显示函数的xy
  1014. prediction_box = tkinter.Listbox(SCREEN, width=gui_width * 3, height=gui_height*5) # 暂时不启用多选
  1015. prediction_box.grid(
  1016. column=column,
  1017. row=row,
  1018. columnspan=3,
  1019. rowspan=5,
  1020. sticky=tkinter.S + tkinter.N + tkinter.E + tkinter.W,
  1021. )
  1022. column += 3
  1023. tkinter.Label(SCREEN, text="", bg=bg_color, fg=word_color, font=FONT, width=1).grid(
  1024. column=column, row=0
  1025. ) # 设置说明
  1026. # 第二排的开始
  1027. column += 1
  1028. row = 0
  1029. tkinter.Label(
  1030. SCREEN,
  1031. text="X轴刻度声明:",
  1032. bg=bg_color,
  1033. fg=word_color,
  1034. font=FONT,
  1035. width=gui_width,
  1036. height=gui_height,
  1037. ).grid(
  1038. column=column, row=row
  1039. ) # 设置说明
  1040. x_scale = tkinter.Entry(SCREEN, width=gui_width * 2)
  1041. x_scale.grid(column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W)
  1042. row += 1
  1043. tkinter.Label(
  1044. SCREEN,
  1045. text="X轴刻度起点:",
  1046. bg=bg_color,
  1047. fg=word_color,
  1048. font=FONT,
  1049. width=gui_width,
  1050. height=gui_height,
  1051. ).grid(
  1052. column=column, row=row
  1053. ) # 设置说明
  1054. start_x_plot = tkinter.Entry(SCREEN, width=gui_width * 2)
  1055. start_x_plot.grid(
  1056. column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W
  1057. )
  1058. row += 1
  1059. tkinter.Label(
  1060. SCREEN,
  1061. text="X轴刻度终点:",
  1062. bg=bg_color,
  1063. fg=word_color,
  1064. font=FONT,
  1065. width=gui_width,
  1066. height=gui_height,
  1067. ).grid(
  1068. column=column, row=row
  1069. ) # 设置说明
  1070. start_x_polt = tkinter.Entry(SCREEN, width=gui_width * 2)
  1071. start_x_polt.grid(
  1072. column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W
  1073. )
  1074. row += 1
  1075. tkinter.Label(
  1076. SCREEN,
  1077. text="X轴刻度间隔:",
  1078. bg=bg_color,
  1079. fg=word_color,
  1080. font=FONT,
  1081. width=gui_width,
  1082. height=gui_height,
  1083. ).grid(
  1084. column=column, row=row
  1085. ) # 设置说明
  1086. span_x_plot = tkinter.Entry(SCREEN, width=gui_width * 2)
  1087. span_x_plot.grid(column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W)
  1088. row += 1
  1089. tkinter.Label(
  1090. SCREEN,
  1091. text="Y轴刻度声明:",
  1092. bg=bg_color,
  1093. fg=word_color,
  1094. font=FONT,
  1095. width=gui_width,
  1096. height=gui_height,
  1097. ).grid(
  1098. column=column, row=row
  1099. ) # 设置说明
  1100. y_scale = tkinter.Entry(SCREEN, width=gui_width * 2)
  1101. y_scale.grid(column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W)
  1102. row += 1
  1103. tkinter.Label(
  1104. SCREEN,
  1105. text="Y轴刻度起点:",
  1106. bg=bg_color,
  1107. fg=word_color,
  1108. font=FONT,
  1109. width=gui_width,
  1110. height=gui_height,
  1111. ).grid(
  1112. column=column, row=row
  1113. ) # 设置说明
  1114. start_y_plot = tkinter.Entry(SCREEN, width=gui_width * 2)
  1115. start_y_plot.grid(
  1116. column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W
  1117. )
  1118. row += 1
  1119. tkinter.Label(
  1120. SCREEN,
  1121. text="Y轴刻度终点:",
  1122. bg=bg_color,
  1123. fg=word_color,
  1124. font=FONT,
  1125. width=gui_width,
  1126. height=gui_height,
  1127. ).grid(
  1128. column=column, row=row
  1129. ) # 设置说明
  1130. end_y_plot = tkinter.Entry(SCREEN, width=gui_width * 2)
  1131. end_y_plot.grid(column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W)
  1132. row += 1
  1133. tkinter.Label(
  1134. SCREEN,
  1135. text="Y轴刻度间隔:",
  1136. bg=bg_color,
  1137. fg=word_color,
  1138. font=FONT,
  1139. width=gui_width,
  1140. height=gui_height,
  1141. ).grid(
  1142. column=column, row=row
  1143. ) # 设置说明
  1144. span_y_plot = tkinter.Entry(SCREEN, width=gui_width * 2)
  1145. span_y_plot.grid(column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W)
  1146. row += 1
  1147. tkinter.Label(
  1148. SCREEN,
  1149. text="X轴显示起点:",
  1150. bg=bg_color,
  1151. fg=word_color,
  1152. font=FONT,
  1153. width=gui_width,
  1154. height=gui_height,
  1155. ).grid(
  1156. column=column, row=row
  1157. ) # 设置说明
  1158. start_x_limit = tkinter.Entry(SCREEN, width=gui_width * 2)
  1159. start_x_limit.grid(
  1160. column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W
  1161. )
  1162. row += 1
  1163. tkinter.Label(
  1164. SCREEN,
  1165. text="X轴显示终点:",
  1166. bg=bg_color,
  1167. fg=word_color,
  1168. font=FONT,
  1169. width=gui_width,
  1170. height=gui_height,
  1171. ).grid(
  1172. column=column, row=row
  1173. ) # 设置说明
  1174. end_x_limit = tkinter.Entry(SCREEN, width=gui_width * 2)
  1175. end_x_limit.grid(column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W)
  1176. row += 1
  1177. tkinter.Label(
  1178. SCREEN,
  1179. text="Y轴显示起点:",
  1180. bg=bg_color,
  1181. fg=word_color,
  1182. font=FONT,
  1183. width=gui_width,
  1184. height=gui_height,
  1185. ).grid(
  1186. column=column, row=row
  1187. ) # 设置说明
  1188. start_y_limit = tkinter.Entry(SCREEN, width=gui_width * 2)
  1189. start_y_limit.grid(
  1190. column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W
  1191. )
  1192. row += 1
  1193. tkinter.Label(
  1194. SCREEN,
  1195. text="Y轴显示终点:",
  1196. bg=bg_color,
  1197. fg=word_color,
  1198. font=FONT,
  1199. width=gui_width,
  1200. height=gui_height,
  1201. ).grid(
  1202. column=column, row=row
  1203. ) # 设置说明
  1204. end_y_limit = tkinter.Entry(SCREEN, width=gui_width * 2)
  1205. end_y_limit.grid(column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W)
  1206. row += 1
  1207. tkinter.Label(
  1208. SCREEN,
  1209. text="帧率(帧/ms):",
  1210. bg=bg_color,
  1211. fg=word_color,
  1212. font=FONT,
  1213. width=gui_width,
  1214. height=gui_height,
  1215. ).grid(
  1216. column=column, row=row
  1217. ) # 设置说明
  1218. frame_rate = tkinter.Entry(SCREEN, width=gui_width * 2)
  1219. frame_rate.grid(column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W)
  1220. row += 1
  1221. show_point = tkinter.IntVar()
  1222. show_best_value = tkinter.IntVar()
  1223. show_text = tkinter.IntVar()
  1224. tkinter.Checkbutton(
  1225. SCREEN,
  1226. bg=bg_color,
  1227. fg=word_color,
  1228. activebackground=bg_color,
  1229. activeforeground=word_color,
  1230. selectcolor=bg_color,
  1231. text="显示记忆点",
  1232. variable=show_point,
  1233. ).grid(column=column, row=row, sticky=tkinter.E + tkinter.W)
  1234. tkinter.Checkbutton(
  1235. SCREEN,
  1236. bg=bg_color,
  1237. fg=word_color,
  1238. activebackground=bg_color,
  1239. activeforeground=word_color,
  1240. selectcolor=bg_color,
  1241. text="显示最值",
  1242. variable=show_best_value,
  1243. ).grid(column=column + 1, row=row, sticky=tkinter.E + tkinter.W)
  1244. tkinter.Checkbutton(
  1245. SCREEN,
  1246. bg=bg_color,
  1247. fg=word_color,
  1248. activebackground=bg_color,
  1249. activeforeground=word_color,
  1250. selectcolor=bg_color,
  1251. text="显示文字",
  1252. variable=show_text,
  1253. ).grid(column=column + 2, row=row, sticky=tkinter.E + tkinter.W)
  1254. row += 1
  1255. # 显示函数的xy
  1256. plot_type = tkinter.Listbox(
  1257. SCREEN, width=gui_width * 3, height=gui_height * 4
  1258. ) # 暂时不启用多选
  1259. plot_type.grid(
  1260. column=column,
  1261. row=row,
  1262. columnspan=3,
  1263. rowspan=3,
  1264. sticky=tkinter.S + tkinter.N + tkinter.E + tkinter.W,
  1265. )
  1266. plot_type.insert(
  1267. tkinter.END,
  1268. *[
  1269. "笛卡尔坐标系静态图像(默认)",
  1270. "矩形坐标系静态图像",
  1271. "笛卡尔坐标系动态图像",
  1272. "矩形坐标系动态图像",
  1273. "笛卡尔坐标系静态图像(无线框)",
  1274. "矩形坐标系静态图像(无线框)",
  1275. "笛卡尔坐标系动态图像(无线框)",
  1276. "矩形坐标系动态图像(无线框)",
  1277. "笛卡尔坐标系动态画图",
  1278. "矩形坐标系动态画图",
  1279. ],
  1280. )
  1281. row += 3
  1282. # 显示函数的xy
  1283. prompt_box = tkinter.Listbox(
  1284. SCREEN, width=gui_width * 3, height=gui_height*1) # 暂时不启用多选
  1285. prompt_box.grid(
  1286. column=column,
  1287. row=row,
  1288. columnspan=3,
  1289. rowspan=1,
  1290. sticky=tkinter.S + tkinter.N + tkinter.E + tkinter.W,
  1291. )
  1292. column += 3
  1293. tkinter.Label(SCREEN, text="", bg=bg_color, fg=word_color, font=FONT, width=1).grid(
  1294. column=column, row=0
  1295. ) # 设置说明
  1296. column += 1
  1297. row = 0
  1298. tkinter.Label(
  1299. SCREEN,
  1300. text="计算(y):",
  1301. bg=bg_color,
  1302. fg=word_color,
  1303. font=FONT,
  1304. width=gui_width,
  1305. height=gui_height,
  1306. ).grid(
  1307. column=column, row=row
  1308. ) # 设置说明
  1309. x_value = tkinter.Entry(SCREEN, width=gui_width * 2)
  1310. x_value.grid(column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W)
  1311. row += 1
  1312. tkinter.Label(
  1313. SCREEN,
  1314. text="二分法计算(x):",
  1315. bg=bg_color,
  1316. fg=word_color,
  1317. font=FONT,
  1318. width=gui_width,
  1319. height=gui_height,
  1320. ).grid(
  1321. column=column, row=row
  1322. ) # 设置说明
  1323. y_value = tkinter.Entry(SCREEN, width=gui_width * 2)
  1324. y_value.grid(column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W)
  1325. dicon_parameters = [] # 二分法参数输入
  1326. name_list = [
  1327. "最大迭代数",
  1328. "计算精度",
  1329. "最值允许偏移量",
  1330. "零点最小间隔",
  1331. "减少计算",
  1332. "允许梯度计算",
  1333. "最大扩张深度",
  1334. "扩张限制",
  1335. "扩张偏移量",
  1336. "开启二级验证",
  1337. "二级验证程度",
  1338. ]
  1339. for i in range(11):
  1340. row += 1
  1341. dicon_parameters.append(tkinter.StringVar())
  1342. tkinter.Label(
  1343. SCREEN,
  1344. bg=bg_color,
  1345. fg=word_color,
  1346. text=name_list[i] + ":",
  1347. font=FONT,
  1348. width=gui_width,
  1349. height=gui_height,
  1350. ).grid(
  1351. column=column, row=row
  1352. ) # 设置说明
  1353. tkinter.Entry(SCREEN, width=gui_width * 2, textvariable=dicon_parameters[-1]).grid(
  1354. column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W
  1355. )
  1356. row += 1
  1357. tkinter.Label(
  1358. SCREEN,
  1359. text="梯度法计算(x):",
  1360. bg=bg_color,
  1361. fg=word_color,
  1362. font=FONT,
  1363. width=gui_width,
  1364. height=gui_height,
  1365. ).grid(
  1366. column=column, row=row
  1367. ) # 设置说明
  1368. y_value_gradient = tkinter.Entry(SCREEN, width=gui_width * 2)
  1369. y_value_gradient.grid(
  1370. column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W
  1371. )
  1372. gradient_parameters = [] # 梯度法法参数输入
  1373. name_list = ["梯度起点", "梯度终点", "计算深度", "计算精度"]
  1374. for i in range(4):
  1375. row += 1
  1376. gradient_parameters.append(tkinter.StringVar())
  1377. tkinter.Label(
  1378. SCREEN,
  1379. bg=bg_color,
  1380. fg=word_color,
  1381. text=name_list[i] + ":",
  1382. font=FONT,
  1383. width=gui_width,
  1384. height=gui_height,
  1385. ).grid(
  1386. column=column, row=row
  1387. ) # 设置说明
  1388. tkinter.Entry(
  1389. SCREEN, width=gui_width * 2, textvariable=gradient_parameters[-1]
  1390. ).grid(column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W)
  1391. column += 3
  1392. tkinter.Label(SCREEN, text="", bg=bg_color, fg=word_color, font=FONT, width=1).grid(
  1393. column=column, row=0
  1394. ) # 设置说明
  1395. column += 1
  1396. row = 0
  1397. tkinter.Label(
  1398. SCREEN,
  1399. text="代数法计算(x):",
  1400. bg=bg_color,
  1401. fg=word_color,
  1402. font=FONT,
  1403. width=gui_width,
  1404. height=gui_height,
  1405. ).grid(
  1406. column=column, row=row
  1407. ) # 设置说明
  1408. y_value_symbol = tkinter.Entry(SCREEN, width=gui_width * 2)
  1409. y_value_symbol.grid(
  1410. column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W
  1411. )
  1412. row += 1
  1413. tkinter.Label(
  1414. SCREEN,
  1415. text="求(x)导数:",
  1416. bg=bg_color,
  1417. fg=word_color,
  1418. font=FONT,
  1419. width=gui_width,
  1420. height=gui_height,
  1421. ).grid(
  1422. column=column, row=row
  1423. ) # 设置说明
  1424. x_value_derivation = tkinter.Entry(SCREEN, width=gui_width * 2)
  1425. x_value_derivation.grid(
  1426. column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W
  1427. )
  1428. row += 1
  1429. tkinter.Label(
  1430. SCREEN,
  1431. text="逼近求导精度:",
  1432. bg=bg_color,
  1433. fg=word_color,
  1434. font=FONT,
  1435. width=gui_width,
  1436. height=gui_height,
  1437. ).grid(
  1438. column=column, row=row
  1439. ) # 设置说明
  1440. proximity_accuracy = tkinter.Entry(SCREEN, width=gui_width * 2)
  1441. proximity_accuracy.grid(
  1442. column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W
  1443. )
  1444. row += 1
  1445. tkinter.Button(
  1446. SCREEN,
  1447. bg=botton_color,
  1448. fg=word_color,
  1449. text="计算(y)",
  1450. command=API.calculate,
  1451. font=FONT,
  1452. width=gui_width,
  1453. height=gui_height,
  1454. ).grid(
  1455. column=column, row=row
  1456. ) # 设置说明
  1457. tkinter.Button(
  1458. SCREEN,
  1459. bg=botton_color,
  1460. fg=word_color,
  1461. text="二分法计算(x)",
  1462. command=API.dichotomy,
  1463. font=FONT,
  1464. width=gui_width,
  1465. height=gui_height,
  1466. ).grid(column=column + 1, row=row)
  1467. tkinter.Button(
  1468. SCREEN,
  1469. bg=botton_color,
  1470. fg=word_color,
  1471. text="梯度法计算(x)",
  1472. command=API.gradient_method_calculation,
  1473. font=FONT,
  1474. width=gui_width,
  1475. height=gui_height,
  1476. ).grid(column=column + 2, row=row)
  1477. row += 1
  1478. tkinter.Button(
  1479. SCREEN,
  1480. bg=botton_color,
  1481. fg=word_color,
  1482. text="代数法计算",
  1483. command=API.sympy_calculation_x,
  1484. font=FONT,
  1485. width=gui_width,
  1486. height=gui_height,
  1487. ).grid(column=column, row=row, sticky=tkinter.N + tkinter.E + tkinter.W)
  1488. tkinter.Button(
  1489. SCREEN,
  1490. bg=botton_color,
  1491. fg=word_color,
  1492. text="逼近法导数计算",
  1493. command=API.approximation,
  1494. font=FONT,
  1495. width=gui_width,
  1496. height=gui_height,
  1497. ).grid(column=column + 1, row=row, sticky=tkinter.N + tkinter.E + tkinter.W)
  1498. tkinter.Button(
  1499. SCREEN,
  1500. bg=botton_color,
  1501. fg=word_color,
  1502. text="导数计算",
  1503. command=API.function_differentiation,
  1504. font=FONT,
  1505. width=gui_width,
  1506. height=gui_height,
  1507. ).grid(column=column + 2, row=row, sticky=tkinter.N + tkinter.E + tkinter.W)
  1508. row += 1
  1509. k = 5
  1510. result_box = tkinter.Listbox(SCREEN, height=gui_height * (k - 1)) # 暂时不启用多选
  1511. result_box.grid(
  1512. column=column,
  1513. row=row,
  1514. columnspan=3,
  1515. rowspan=k,
  1516. sticky=tkinter.N + tkinter.E + tkinter.W,
  1517. )
  1518. row += k - 1
  1519. tkinter.Label(
  1520. SCREEN,
  1521. text="性质预测值:",
  1522. bg=bg_color,
  1523. fg=word_color,
  1524. font=FONT,
  1525. width=gui_width,
  1526. height=gui_height,
  1527. ).grid(
  1528. column=column, row=row, sticky=tkinter.N + tkinter.S
  1529. ) # 设置说明
  1530. projection_value = tkinter.Entry(SCREEN, width=gui_width * 2)
  1531. projection_value.grid(
  1532. column=column + 1, row=row, columnspan=2, sticky=tkinter.E + tkinter.W
  1533. )
  1534. row += 1
  1535. tkinter.Button(
  1536. SCREEN,
  1537. bg=botton_color,
  1538. fg=word_color,
  1539. text="周期性",
  1540. command=API.check_periodic,
  1541. font=FONT,
  1542. width=gui_width,
  1543. height=gui_height,
  1544. ).grid(column=column, row=row, sticky=tkinter.N + tkinter.E + tkinter.W)
  1545. tkinter.Button(
  1546. SCREEN,
  1547. bg=botton_color,
  1548. fg=word_color,
  1549. text="对称轴",
  1550. command=API.check_symmetry_axis,
  1551. font=FONT,
  1552. width=gui_width,
  1553. height=gui_height,
  1554. ).grid(column=column + 1, row=row, sticky=tkinter.N + tkinter.E + tkinter.W)
  1555. tkinter.Button(
  1556. SCREEN,
  1557. bg=botton_color,
  1558. fg=word_color,
  1559. text="对称中心",
  1560. command=API.check_center_of_symmetry,
  1561. font=FONT,
  1562. width=gui_width,
  1563. height=gui_height,
  1564. ).grid(column=column + 2, row=row, sticky=tkinter.N + tkinter.E + tkinter.W)
  1565. row += 1
  1566. tkinter.Button(
  1567. SCREEN,
  1568. bg=botton_color,
  1569. fg=word_color,
  1570. text="单调性",
  1571. command=API.check_monotonic,
  1572. font=FONT,
  1573. width=gui_width,
  1574. height=gui_height,
  1575. ).grid(column=column, row=row, columnspan=3, sticky=tkinter.N + tkinter.E + tkinter.W)
  1576. row += 1
  1577. # 显示函数的xy
  1578. projection_box = tkinter.Listbox(
  1579. SCREEN, width=gui_width * 3, height=gui_height*6
  1580. ) # 暂时不启用多选
  1581. projection_box.grid(
  1582. column=column,
  1583. row=row,
  1584. columnspan=3,
  1585. rowspan=6,
  1586. sticky=tkinter.S + tkinter.N + tkinter.E + tkinter.W,
  1587. )
  1588. column += 3
  1589. tkinter.Label(SCREEN, text="", bg=bg_color, fg=word_color, font=FONT, width=1).grid(
  1590. column=column, row=0
  1591. ) # 设置说明
  1592. column += 1
  1593. row = 0
  1594. tkinter.Button(
  1595. SCREEN,
  1596. bg=botton_color,
  1597. fg=word_color,
  1598. text="生成表格",
  1599. command=API.save_to_sheet,
  1600. font=FONT,
  1601. width=gui_width * 2,
  1602. height=gui_height,
  1603. ).grid(column=column, row=row, columnspan=2)
  1604. tkinter.Button(
  1605. SCREEN,
  1606. bg=botton_color,
  1607. fg=word_color,
  1608. text="导出表格",
  1609. command=API.save_to_csv,
  1610. font=FONT,
  1611. width=gui_width,
  1612. height=gui_height,
  1613. ).grid(column=column + 2, row=row)
  1614. row += 1
  1615. # 显示函数的xy
  1616. sheet_box = tkinter.Listbox(SCREEN, width=gui_width * 3) # 暂时不启用多选
  1617. sheet_box.grid(
  1618. column=column,
  1619. row=row,
  1620. columnspan=3,
  1621. rowspan=17,
  1622. sticky=tkinter.S + tkinter.N + tkinter.E + tkinter.W,
  1623. )