map.py 29 KB

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