Search code examples
python-3.xuser-interfacetkintercalculatornameerror

NameError: name 'f_num' is not defined in tkinter


I'm trying to program my calculator project to perform operations. It can perform addition and I want it to perform the remaining four (minus, multiplication, division, powers) But I'm stuck because of this error:

C:\Users\Admin\PycharmProjects\venv\Scripts\python.exe 
   "C:/Users/Admin/PycharmProjects/pythonProject/Calculator GUI v1.0.py"
   Exception in Tkinter callback
   Traceback (most recent call last):
    File "C:\Users\Admin\Python3.9\lib\tkinter\__init__.py", line 1892, in __call__
    return self.func(*args)
    File "C:\Users\Admin\PycharmProjects\pythonProject\Calculator GUI v1.0.py", line 32, in 
    button_subtract
     e.insert(0, f_num + int(second_number))
    NameError: name 'f_num' is not defined

   Process finished with exit code 0

My code:

import tkinter as Tk
from tkinter import *

root_var = Tk()
root_var.title("Calculator")

e = Entry(root_var, width=25, borderwidth=5)
e.grid(row=0, column=0, columnspan=3, padx=10, pady=10)

def button_click(number=None):

#e.delete(0, END)
current = e.get()
e.delete(0, END)
e.insert(0, str(current) + str(number) )

def button_clear():
e.delete(0, END)


def button_add():
first_number = e.get()
global f_num
f_num = int(first_number)
e.delete(0, END)


def button_subtract():
second_number = e.get()
e.delete(0, END)
e.insert(0, f_num + int(second_number))


def button_multiply():
third_number = e.get()
e.delete(0, END)
e.insert(0, f_num + int(third_number))



def button_divide():
fourth_number = e.get()
e.delete(0, END)
e.insert(0, f_num + int(fourth_number))



def button_exponents():
fifth_number = e.get()
e.delete(0, END)
e.insert(0, f_num + int(fifth_number))

def button_equal():
sixth_number = e.get()
e.delete(0, END)
e.insert(0, f_num + int(sixth_number))

 button_1 = Button(root_var, text="1", padx=50, pady=10, command=lambda: button_click(1))
 button_2 = Button(root_var, text="2", padx=50, pady=10, command=lambda: button_click(2))
 button_3 = Button(root_var, text="3", padx=50, pady=10, command=lambda: button_click(3))
 button_4 = Button(root_var, text="4", padx=50, pady=10, command=lambda: button_click(4))
 button_5 = Button(root_var, text="5", padx=50, pady=10, command=lambda: button_click(5))
 button_6 = Button(root_var, text="6", padx=50, pady=10, command=lambda: button_click(6))
 button_7 = Button(root_var, text="7", padx=50, pady=10, command=lambda: button_click(7))
 button_8 = Button(root_var, text="8", padx=50, pady=10, command=lambda: button_click(8))
 button_9 = Button(root_var, text="9", padx=50, pady=10, command=lambda: button_click(9))
 button_0 = Button(root_var, text="0", padx=50, pady=10, command=lambda: button_click(0))

 button_addition = Button(root_var, text="+", padx=50, pady=10, command=button_add)
 button_subtraction = Button(root_var, text="-", padx=50, pady=10, command=button_subtract)
 button_multiplication = Button(root_var, text="*", padx=50, pady=10, command=button_multiply)
 button_division = Button(root_var, text="/", padx=50, pady=10, command=button_divide)
 button_exponents = Button(root_var, text="^", padx=50, pady=10, command=button_exponents)

 button_equals = Button(root_var, text="=", padx=50, pady=10, command=button_equal)

 button_clear = Button(root_var, text="C", padx=50, pady=10, command=button_clear)

  button_1.grid(row=3, column=2)
  button_2.grid(row=3, column=1)
  button_3.grid(row=3, column=0)

  button_4.grid(row=2, column=2)
  button_5.grid(row=2, column=1)
  button_6.grid(row=2, column=0)

  button_7.grid(row=1, column=2)
  button_8.grid(row=1, column=1)
  button_9.grid(row=1, column=0)

  button_0.grid(row=4, column=0)
  button_addition.grid(row=4, column=1)
  button_subtraction.grid(row=4, column=2)

  button_multiplication.grid(row=5, column=0)
  button_division.grid(row=5, column=1)
  button_exponents.grid(row=5, column=2)

  button_equals.grid(row=6, column=0)
  button_clear.grid(row=6, column=1)


  root_var.mainloop()

The addition operation works. I want the other operations to also be able to perform their respective tasks.


Solution

  • When one of the operators is clicked, you need to save the current input number to f_num and the operator to another variable, for example opr.

    Then when = is clicked, do the calculation based on the saved opr, f_num and current input value.

    Below is an example based on your code:

    from tkinter import *
    
    root_var = Tk()
    root_var.title("Calculator")
    
    e = Entry(root_var, width=25, borderwidth=5)
    e.grid(row=0, column=0, columnspan=3, padx=10, pady=10)
    
    f_num = opr = None
    
    def button_click(number=None):
        current = e.get()
        e.delete(0, END)
        e.insert(0, current+str(number))
    
    def button_opr(op):
        global f_num, opr
        # save the first number and operator
        try:
            f_num = int(e.get())
            opr = op
            # clear the entry
            e.delete(0, END)
        except Exception as ex:
            print(ex)
    
    def button_clear():
        global f_num, opr
        e.delete(0, END)
        # reset first number and operator
        f_num = opr = None
    
    def button_equal():
        global f_num, opr
        if f_num and opr:
            try:
                current = int(e.get())
                e.delete(0, END)
                if opr == "+":
                    e.insert(0, f_num+current)
                elif opr == "-":
                    e.insert(0, f_num-current)
                elif opr == "*":
                    e.insert(0, f_num*current)
                elif opr == "/":
                    e.insert(0, f_num/current)
                elif opr == "^":
                    e.insert(0, f_num**current)
            except Exception as ex:
                print(ex)
        # reset first number and operator
        f_num = opr = None
    
    button_1 = Button(root_var, text="1", padx=50, pady=10, command=lambda: button_click(1))
    button_2 = Button(root_var, text="2", padx=50, pady=10, command=lambda: button_click(2))
    button_3 = Button(root_var, text="3", padx=50, pady=10, command=lambda: button_click(3))
    button_4 = Button(root_var, text="4", padx=50, pady=10, command=lambda: button_click(4))
    button_5 = Button(root_var, text="5", padx=50, pady=10, command=lambda: button_click(5))
    button_6 = Button(root_var, text="6", padx=50, pady=10, command=lambda: button_click(6))
    button_7 = Button(root_var, text="7", padx=50, pady=10, command=lambda: button_click(7))
    button_8 = Button(root_var, text="8", padx=50, pady=10, command=lambda: button_click(8))
    button_9 = Button(root_var, text="9", padx=50, pady=10, command=lambda: button_click(9))
    button_0 = Button(root_var, text="0", padx=50, pady=10, command=lambda: button_click(0))
    
    button_addition = Button(root_var, text="+", padx=50, pady=10, command=lambda: button_opr("+"))
    button_subtraction = Button(root_var, text="-", padx=50, pady=10, command=lambda: button_opr("-"))
    button_multiplication = Button(root_var, text="*", padx=50, pady=10, command=lambda: button_opr("*"))
    button_division = Button(root_var, text="/", padx=50, pady=10, command=lambda: button_opr("/"))
    button_exponents = Button(root_var, text="^", padx=50, pady=10, command=lambda: button_opr("^"))
    button_equals = Button(root_var, text="=", padx=50, pady=10, command=button_equal)
    button_clear = Button(root_var, text="C", padx=50, pady=10, command=button_clear)
    
    button_1.grid(row=3, column=2, sticky="ew")
    button_2.grid(row=3, column=1, sticky="ew")
    button_3.grid(row=3, column=0, sticky="ew")
    button_4.grid(row=2, column=2, sticky="ew")
    button_5.grid(row=2, column=1, sticky="ew")
    button_6.grid(row=2, column=0, sticky="ew")
    button_7.grid(row=1, column=2, sticky="ew")
    button_8.grid(row=1, column=1, sticky="ew")
    button_9.grid(row=1, column=0, sticky="ew")
    button_0.grid(row=4, column=0, sticky="ew")
    
    button_addition.grid(row=4, column=1, sticky="ew")
    button_subtraction.grid(row=4, column=2, sticky="ew")
    button_multiplication.grid(row=5, column=0, sticky="ew")
    button_division.grid(row=5, column=1, sticky="ew")
    button_exponents.grid(row=5, column=2, sticky="ew")
    button_equals.grid(row=6, column=0, sticky="ew")
    button_clear.grid(row=6, column=1, sticky="ew")
    
    root_var.mainloop()