앞서 만든 계산기에 함수를 추가해서 계산이 가능하도록 하겠습니다.
각 버튼별 함수 만들기
함수는 총 3개입니다. (숫자입력 및 AC버튼(지우기) 처리함수, 사칙연산 처리함수, 이퀄버튼 처리함수)
from tkinter import * from tkinter import ttk operation = '' #연산자 저장 변수 temp_number = 0 #이전값 저장 변수 # 숫자버튼 처리 함수 def button_pressed(value): # 입력값이 'AC'일때 if value=='AC': number_entry.delete(0,'end') print("AC pressed") else: # 그외에 0부터 9까지 숫자일때 number_entry.insert("end",value) print(value,"pressed") # 사칙연산 처리 def math_button_pressed(value): global operation #함수 바깥의 글로벌 변수사용 global temp_number if not number_entry.get() == '': #기존에 입력한 숫자가 있을때만 연산버튼 인식 operation = value temp_number = int(number_entry.get()) #입력된 숫자를 임시변수로 옮기고, number_entry.delete(0,'end') #입력칸을 비우고, 다음숫자를 입력받을 준비. print(temp_number,operation) # 결과 버튼 처리 def equal_button_pressed(): global operation global temp_number #연산자나 숫자가 입력되지 않으면, 실행하지 않음. if not (operation =='' and number_entry.get()==''): number = int(number_entry.get()) if operation == '/': solution = temp_number/number elif operation == '*': solution = temp_number*number elif operation == '+': solution = temp_number+number else : solution = temp_number-number # 계산후, 숫자표시칸을 비우고, 계산결과를 표시. number_entry.delete(0,'end') number_entry.insert(0,solution) print(temp_number,operation,number,"=",solution) operation = '' temp_number = 0 root = Tk() root.title("Calculator") root.geometry("300x200") entry_value = StringVar(root, value='') number_entry = ttk.Entry(root, textvariable = entry_value, width=20) number_entry.grid(row=0, columnspan=3) button7 = ttk.Button(root, text="7", command = lambda:button_pressed('7')) button7.grid(row=1, column=0) button8 = ttk.Button(root, text="8", command = lambda:button_pressed('8')) button8.grid(row=1, column=1) button9 = ttk.Button(root, text="9", command = lambda:button_pressed('9')) button9.grid(row=1, column=2) button_div = ttk.Button(root, text="/", command = lambda:math_button_pressed('/')) button_div.grid(row=1, column=3) button4 = ttk.Button(root, text="4", command = lambda:button_pressed('4')) button4.grid(row=2, column=0) button5 = ttk.Button(root, text="5", command = lambda:button_pressed('5')) button5.grid(row=2, column=1) button6 = ttk.Button(root, text="6", command = lambda:button_pressed('6')) button6.grid(row=2, column=2) button_mult = ttk.Button(root, text="*", command = lambda:math_button_pressed('*')) button_mult.grid(row=2, column=3) button1 = ttk.Button(root, text="1", command = lambda:button_pressed('1')) button1.grid(row=3, column=0) button2 = ttk.Button(root, text="2", command = lambda:button_pressed('2')) button2.grid(row=3, column=1) button3 = ttk.Button(root, text="3", command = lambda:button_pressed('3')) button3.grid(row=3, column=2) button_add = ttk.Button(root, text="+", command = lambda:math_button_pressed('+')) button_add.grid(row=3, column=3) button_ac = ttk.Button(root, text="AC", command = lambda:button_pressed('AC')) button_ac.grid(row=4, column=0) button0 = ttk.Button(root, text="0", command = lambda:button_pressed('0')) button0.grid(row=4, column=1) button_equal = ttk.Button(root, text="=", command = lambda:equal_button_pressed()) button_equal.grid(row=4, column=2) button_sub = ttk.Button(root, text="-", command = lambda:math_button_pressed('-')) button_sub.grid(row=4, column=3) root.mainloop()
버그수정 #1 : 연속계산
한번 계산후에, 다른숫자를 입력하면, 기존결과를 지우고, 새로 계산하도록 하겠습니다.
이를 위해서, 결과출력 상태를 저장하는 answer_trigger 변수를 True/False 형태로 boolean 으로 사용하도록 하겠습니다.
from tkinter import * from tkinter import ttk operation = '' temp_number = 0 # 결과 출력 상태인지 상태저장. answer_trigger = False def button_pressed(value): global temp_number global answer_trigger if value=='AC': number_entry.delete(0,'end') operation = '' #AC버튼 누르면, trigger 변수도 초기화. answer_trigger = False print("AC pressed") else: #Trigger가 True이면, Entry 초기화후 새로입력. if answer_trigger: number_entry.delete(0,"end") answer_trigger = False number_entry.insert("end",value) print(value,"pressed") def math_button_pressed(value): global operation global temp_number global answer_trigger if not number_entry.get() == '': operation = value temp_number = int(number_entry.get()) number_entry.delete(0,'end') print(temp_number,operation) def equal_button_pressed(): global operation global temp_number global answer_trigger if not (operation =='' and number_entry.get()==''): number = int(number_entry.get()) if operation == '/': solution = temp_number/number elif operation == '*': solution = temp_number*number elif operation == '+': solution = temp_number+number else : solution = temp_number-number number_entry.delete(0,'end') number_entry.insert(0,solution) print(temp_number,operation,number,"=",solution) operation = '' temp_number = 0 # 계산 완료후, Trigger 변수 True로 변경. answer_trigger = True root = Tk() root.title("Calculator") root.geometry("300x200") entry_value = StringVar(root, value='') number_entry = ttk.Entry(root, textvariable = entry_value, width=20) number_entry.grid(row=0, columnspan=3) button7 = ttk.Button(root, text="7", command = lambda:button_pressed('7')) button7.grid(row=1, column=0) button8 = ttk.Button(root, text="8", command = lambda:button_pressed('8')) button8.grid(row=1, column=1) button9 = ttk.Button(root, text="9", command = lambda:button_pressed('9')) button9.grid(row=1, column=2) button_div = ttk.Button(root, text="/", command = lambda:math_button_pressed('/')) button_div.grid(row=1, column=3) button4 = ttk.Button(root, text="4", command = lambda:button_pressed('4')) button4.grid(row=2, column=0) button5 = ttk.Button(root, text="5", command = lambda:button_pressed('5')) button5.grid(row=2, column=1) button6 = ttk.Button(root, text="6", command = lambda:button_pressed('6')) button6.grid(row=2, column=2) button_mult = ttk.Button(root, text="*", command = lambda:math_button_pressed('*')) button_mult.grid(row=2, column=3) button1 = ttk.Button(root, text="1", command = lambda:button_pressed('1')) button1.grid(row=3, column=0) button2 = ttk.Button(root, text="2", command = lambda:button_pressed('2')) button2.grid(row=3, column=1) button3 = ttk.Button(root, text="3", command = lambda:button_pressed('3')) button3.grid(row=3, column=2) button_add = ttk.Button(root, text="+", command = lambda:math_button_pressed('+')) button_add.grid(row=3, column=3) button_ac = ttk.Button(root, text="AC", command = lambda:button_pressed('AC')) button_ac.grid(row=4, column=0) button0 = ttk.Button(root, text="0", command = lambda:button_pressed('0')) button0.grid(row=4, column=1) button_equal = ttk.Button(root, text="=", command = lambda:equal_button_pressed()) button_equal.grid(row=4, column=2) button_sub = ttk.Button(root, text="-", command = lambda:math_button_pressed('-')) button_sub.grid(row=4, column=3) root.mainloop()
버그수정 #2 : 소수점형태의 문자열을 int형으로 변환시 오류. 조건부로 float형으로 변환
나눗셈에서 소수점이 생긴후, 이 숫자를 다시 계산하고자 연산자를 입력하면, 소수점형태의 문자열을 int형 숫자로 바꾸는 과정을 거치게 되는데, 이때 오류가 발생합니다. 이때는, 간단한 float_filter()라는 함수를 만들어서, float형으로 바꿔주도록 하겠습니다.
from tkinter import * from tkinter import ttk operation = '' temp_number = 0 answer_trigger = False def button_pressed(value): global temp_number global answer_trigger if value=='AC': number_entry.delete(0,'end') operation = '' answer_trigger = False print("AC pressed") else: if answer_trigger: number_entry.delete(0,"end") answer_trigger = False number_entry.insert("end",value) print(value,"pressed") # 소수점으로 int형 변환시 에러가 날경우, float형으로 반환. def float_filter(value): try: int(value) return int(value) except ValueError: return float(value) def math_button_pressed(value): global operation global temp_number global answer_trigger if not number_entry.get() == '': operation = value #float_filter 함수 호출. temp_number = float_filter(number_entry.get()) number_entry.delete(0,'end') print(temp_number,operation) def equal_button_pressed(): global operation global temp_number global answer_trigger if not (operation =='' and number_entry.get()==''): number = int(number_entry.get()) if operation == '/': solution = temp_number/number elif operation == '*': solution = temp_number*number elif operation == '+': solution = temp_number+number else : solution = temp_number-number number_entry.delete(0,'end') number_entry.insert(0,solution) print(temp_number,operation,number,"=",solution) operation = '' temp_number = 0 answer_trigger = True root = Tk() root.title("Calculator") root.geometry("300x200") entry_value = StringVar(root, value='') number_entry = ttk.Entry(root, textvariable = entry_value, width=20) number_entry.grid(row=0, columnspan=3) button7 = ttk.Button(root, text="7", command = lambda:button_pressed('7')) button7.grid(row=1, column=0) button8 = ttk.Button(root, text="8", command = lambda:button_pressed('8')) button8.grid(row=1, column=1) button9 = ttk.Button(root, text="9", command = lambda:button_pressed('9')) button9.grid(row=1, column=2) button_div = ttk.Button(root, text="/", command = lambda:math_button_pressed('/')) button_div.grid(row=1, column=3) button4 = ttk.Button(root, text="4", command = lambda:button_pressed('4')) button4.grid(row=2, column=0) button5 = ttk.Button(root, text="5", command = lambda:button_pressed('5')) button5.grid(row=2, column=1) button6 = ttk.Button(root, text="6", command = lambda:button_pressed('6')) button6.grid(row=2, column=2) button_mult = ttk.Button(root, text="*", command = lambda:math_button_pressed('*')) button_mult.grid(row=2, column=3) button1 = ttk.Button(root, text="1", command = lambda:button_pressed('1')) button1.grid(row=3, column=0) button2 = ttk.Button(root, text="2", command = lambda:button_pressed('2')) button2.grid(row=3, column=1) button3 = ttk.Button(root, text="3", command = lambda:button_pressed('3')) button3.grid(row=3, column=2) button_add = ttk.Button(root, text="+", command = lambda:math_button_pressed('+')) button_add.grid(row=3, column=3) button_ac = ttk.Button(root, text="AC", command = lambda:button_pressed('AC')) button_ac.grid(row=4, column=0) button0 = ttk.Button(root, text="0", command = lambda:button_pressed('0')) button0.grid(row=4, column=1) button_equal = ttk.Button(root, text="=", command = lambda:equal_button_pressed()) button_equal.grid(row=4, column=2) button_sub = ttk.Button(root, text="-", command = lambda:math_button_pressed('-')) button_sub.grid(row=4, column=3) root.mainloop()
버그수정 #3 : 결과값 정수형으로 처리.
한번 float형으로 계산이 되기 시작하면, 오류는 앞에서 잡더라도, 2.0 처럼, 정수형으로 표현될수 있는 숫자까지도 모두 flaot형으로 출력이 됩니다. 이때는, int(number)==float(number) 가 true이면, 정수라는 판단하에, 정수로 변경해주도록 하겠습니다.
from tkinter import * from tkinter import ttk operation = '' temp_number = 0 answer_trigger = False def button_pressed(value): global temp_number global answer_trigger if value=='AC': number_entry.delete(0,'end') operation = '' answer_trigger = False print("AC pressed") else: if answer_trigger: number_entry.delete(0,"end") answer_trigger = False number_entry.insert("end",value) print(value,"pressed") def float_filter(value): try: int(value) return int(value) except ValueError: return float(value) # 두값이 같으면 정수로 표현가능.==> 정수값으로 반환. def int_changer(value): if int(value) == float(value): return int(value) else: return float(value) def math_button_pressed(value): global operation global temp_number global answer_trigger if not number_entry.get() == '': operation = value temp_number = float_filter(number_entry.get()) number_entry.delete(0,'end') print(temp_number,operation) def equal_button_pressed(): global operation global temp_number global answer_trigger if not (operation =='' and number_entry.get()==''): number = int(number_entry.get()) if operation == '/': solution = temp_number/number elif operation == '*': solution = temp_number*number elif operation == '+': solution = temp_number+number else : solution = temp_number-number #int_changer() 함수를 한번 거쳐서, 값저장. solution = int_changer(solution) number_entry.delete(0,'end') number_entry.insert(0,solution) print(temp_number,operation,number,"=",solution) operation = '' temp_number = 0 answer_trigger = True root = Tk() root.title("Calculator") root.geometry("300x200") entry_value = StringVar(root, value='') number_entry = ttk.Entry(root, textvariable = entry_value, width=20) number_entry.grid(row=0, columnspan=3) button7 = ttk.Button(root, text="7", command = lambda:button_pressed('7')) button7.grid(row=1, column=0) button8 = ttk.Button(root, text="8", command = lambda:button_pressed('8')) button8.grid(row=1, column=1) button9 = ttk.Button(root, text="9", command = lambda:button_pressed('9')) button9.grid(row=1, column=2) button_div = ttk.Button(root, text="/", command = lambda:math_button_pressed('/')) button_div.grid(row=1, column=3) button4 = ttk.Button(root, text="4", command = lambda:button_pressed('4')) button4.grid(row=2, column=0) button5 = ttk.Button(root, text="5", command = lambda:button_pressed('5')) button5.grid(row=2, column=1) button6 = ttk.Button(root, text="6", command = lambda:button_pressed('6')) button6.grid(row=2, column=2) button_mult = ttk.Button(root, text="*", command = lambda:math_button_pressed('*')) button_mult.grid(row=2, column=3) button1 = ttk.Button(root, text="1", command = lambda:button_pressed('1')) button1.grid(row=3, column=0) button2 = ttk.Button(root, text="2", command = lambda:button_pressed('2')) button2.grid(row=3, column=1) button3 = ttk.Button(root, text="3", command = lambda:button_pressed('3')) button3.grid(row=3, column=2) button_add = ttk.Button(root, text="+", command = lambda:math_button_pressed('+')) button_add.grid(row=3, column=3) button_ac = ttk.Button(root, text="AC", command = lambda:button_pressed('AC')) button_ac.grid(row=4, column=0) button0 = ttk.Button(root, text="0", command = lambda:button_pressed('0')) button0.grid(row=4, column=1) button_equal = ttk.Button(root, text="=", command = lambda:equal_button_pressed()) button_equal.grid(row=4, column=2) button_sub = ttk.Button(root, text="-", command = lambda:math_button_pressed('-')) button_sub.grid(row=4, column=3) root.mainloop()
여기까지 하면, 기본적인 계산은 문제없이 다 되는것 같습니다. 다음토픽에서는, 키보드로 숫자와 연산자를 입력받도록 코드를 좀 바꿔보도록 하겠습니다.