Как-то давно, попался мне на просторах интернета, приаттаченный ниже Питоновский скрипт калькулятора. Заработал он лишь частично. Т.е. ГУИ - вроде, работает (и-то кривовато, нет раскраски, которая есть в скрипте), а вот с математикой - вообще беда. Работает одно сложение (+), причем тоже с небольшими странностями: кнопку равно (=) нужно нажимать два раза. И вот тоже исключительно "для образовательных целей и спортивного интереса" захотелось исправить скрипт и понять ход мыслей автора сего бреда. В принципе если нужно, я могу реализовать подобный скрипт калькулятора еще как минимум несколькими вариантами непохожими друг на друга. Но тут дело принципа - захотелось разобраться именно с этим вариантом, чтобы проверить знание Питона на практике. Но знаний не хватило, а спортивный интерес остался. Может кто поможет подправить скрипт - чисто из образовательных целей и спортивного интереса? Код (Python): from tkinter import * class Window: def __init__(self, width, height, title="FirstTK", resizable=(False, True), icon=None): self.root = Tk() # корневая переменная которая хранит с себе экземпляр класса Tk self.root.title(title) self.root.geometry(f"{width}x{height}+200+200") self.root.resizable(resizable[0], resizable[1]) if icon: self.root.iconbitmap(icon) self.label_out = Label(self.root, text='0', font=("Verdana", 10, "bold")) def run(self): self.draw_widgets() self.root.mainloop() def draw_widgets(self): self.draw_menu() self.label_out.place(x=30, y=10) Button(self.root, width=1, height=1, text='1', font=("Verdana", 10, "bold"), command=lambda: self.test_button('1')).place(x=30, y=30) Button(self.root, width=1, height=1, text='2', font=("Verdana", 10, "bold"), command=lambda: self.test_button('2')).place(x=60, y=30) Button(self.root, width=1, height=1, text='3', font=("Verdana", 10, "bold"), command=lambda: self.test_button('3')).place(x=90, y=30) Button(self.root, width=1, height=1, text='4', font=("Verdana", 10, "bold"), command=lambda: self.test_button('4')).place(x=30, y=60) Button(self.root, width=1, height=1, text='5', font=("Verdana", 10, "bold"), command=lambda: self.test_button('5')).place(x=60, y=60) Button(self.root, width=1, height=1, text='6', font=("Verdana", 10, "bold"), command=lambda: self.test_button('6')).place(x=90, y=60) Button(self.root, width=1, height=1, text='7', font=("Verdana", 10, "bold"), command=lambda: self.test_button('7')).place(x=30, y=90) Button(self.root, width=1, height=1, text='8', font=("Verdana", 10, "bold"), command=lambda: self.test_button('8')).place(x=60, y=90) Button(self.root, width=1, height=1, text='9', font=("Verdana", 10, "bold"), command=lambda: self.test_button('9')).place(x=90, y=90) Button(self.root, width=1, height=1, text='0', font=("Verdana", 10, "bold"), command=lambda: self.test_button('0')).place(x=30, y=120) Button(self.root, width=1, height=1, text='+', font=("Verdana", 10, "bold"), command=lambda: self.test_button('+')).place(x=60, y=120) Button(self.root, width=1, height=1, text='-', font=("Verdana", 10, "bold"), command=lambda: self.test_button('-')).place(x=90, y=120) Button(self.root, width=1, height=1, text='*', font=("Verdana", 10, "bold"), command=lambda: self.test_button('*')).place(x=30, y=150) Button(self.root, width=1, height=1, text='/', font=("Verdana", 10, "bold"), command=lambda: self.test_button('/')).place(x=60, y=150) Button(self.root, width=1, height=1, text='=', font=("Verdana", 10, "bold"), command=self.solve).place(x=90, y=150) def draw_menu(self): menu_bar = Menu(self.root) file_menu = Menu(menu_bar, tearoff=0) color_menu = Menu(file_menu, tearoff=0) color_menu.add_command(label='Зеленый', command=lambda: self.change_color('green')) color_menu.add_command(label='Красный', command=lambda: self.change_color('red')) color_menu.add_command(label='Сброс', command=lambda: self.change_color('white')) menu_bar.add_cascade(label='Настройки', menu=file_menu) file_menu.add_cascade(label='Цвет фона', menu=color_menu) self.root.configure(menu=menu_bar) def change_color(self, color): self.root.configure(bg=color) def test_button(self, val): if self.label_out.cget("text") in ('0', 'ERROR', 'ZERO DIVISION'): self.label_out.config(text=val) else: if (val == '+' and self.label_out.cget("text")[-1] == '+') or ( val == '-' and self.label_out.cget("text")[-2] == '-'): return else: old_label_val = self.label_out.cget("text") new_val = old_label_val + val self.label_out.config(text=new_val) def solve(self): try: str_ = self.label_out.cget("text") token_list = [] token = [] for i in range(len(str_)): if str_[i].isdigit(): token += [str_[i]] else: token_list += [token] token = [] token += [str_[i]] token_list += [token] token = [] if len(token): token_list += [token] result = list(filter(lambda a: a, map(lambda x: ''.join(x), token_list))) def to_number(x): return int(x) if x.isdigit() else x result2 = list(map(to_number, result)) print(result2) for i in range(len(result2)): if not isinstance(result2[i], int) and result2[i + 1] == '-': result2[i + 2] = ~result2[i + 2] + 1 result2[i + 1] = None final_result1 = list(filter(lambda x: x is not None, result2)) print(final_result1) # здесь вставить обработку первого минуса для выражений типа -765+64 test_null = False def insert_change(x): nonlocal test_null if final_result1[i] == 'x': if not final_result1[i + 1]: test_null = True return product = final_result1[i - 1] * final_result1[i + 1] if x == '*' else final_result1[i - 1] / \ final_result1[ i + 1] final_result1[i - 1] = None final_result1[i] = None final_result1[i + 1] = None final_result1.insert(i + 1, product) print( final_result1) print(test_null) for i in range(len(final_result1)): insert_change('*') insert_change('/') final_result2 = list(filter(lambda x: x is not None, final_result1)) print(final_result2) if test_null: self.label_out.config(text='ZERO DIVISION') else: solution = final_result2[0] for i in range(len(final_result2) - 1): if final_result2[i] == '+': solution += final_result2[i + 1] if final_result2[i] == '-': solution -= final_result2[i + 1] self.label_out.config(text=str(solution)) except IndexError: self.label_out.config(text='ERROR') except TypeError: self.label_out.config(text='ERROR') if __name__ == "__main__": window = Window(150, 200) window.run() Форумный редактор "исправил" скрипт сделав его, вообще, нерабочим, поэтому дополню пост зип-архивом.
Вот я и не люблю из-за этого питухон. Это скрипт просто так не запустишь, если питухон не установлен. А калькулятор можно и на делфи или даже на ассемблере написать, и по трудозатратам это будет легче. Питухон такой ПИТУХОН!!!
проблема с гуЁвиной не из-за питона - просто в лине есть два мейнстрима для гуЁвины (гном/жтк и кеды/кьюти), а в скрипте ТС вообще зло-2,72..ий ткинтер привязан.. теоретически он должен бесшовно пахать, но это лишь теоретически лучший вариант - на кьюти переписать, а если уж совсем хочется избавить себя от страданий - можно сделать консольную версию