앞서 만든 계산기에 함수를 추가해서 계산이 가능하도록 하겠습니다.
각 버튼별 함수 만들기
함수는 총 3개입니다. (숫자입력 및 AC버튼(지우기) 처리함수, 사칙연산 처리함수, 이퀄버튼 처리함수)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | 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 으로 사용하도록 하겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | 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형으로 바꿔주도록 하겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | 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이면, 정수라는 판단하에, 정수로 변경해주도록 하겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | 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() |
여기까지 하면, 기본적인 계산은 문제없이 다 되는것 같습니다. 다음토픽에서는, 키보드로 숫자와 연산자를 입력받도록 코드를 좀 바꿔보도록 하겠습니다.