Scientific Calculator in Python using Tkinter

Scientific Calculator in Python

Introduction

We have created a Scientific Calculator in Python which is a fully functional graphical user interface system that contains everything that IT students and computer-related courses will require for their college projects. The project has the same symbols, operators, and numbers as a regular calculator, however, the user cannot enter a number using their keyboard. Python is a computer language that may be used to do mathematical and scientific calculations.

Scientific Calculator in Python using Tkinter: Project Overview

Project Name:Scientific Calculator in Python using Tkinter
AbstractIt’s a GUI-based project used with the tkinter module to organize all the elements that work under Scientific Calculator in Python.
Language/s Used:Python
IDEPyCharm and Thonny(Recommended)
Python version (Recommended):Python 3.x
Database:Not used
Type:Desktop Application
Recommended forBeginners in Python and intermediates of Tkinter

We will mostly understand our codes using comments. Now, let’s start.

Step.1: Importing Libraries and Designing The Buttons

import tkinter as tk
from math import *
 
# used to switch between units of rad, and deg
convert_constant = 1
inverse_convert_constant = 1
 
btn_params = {'padx': 16, 'pady': 1, 'bd': 4, 'fg': 'white', 'bg': 'black', 'font': ('arial', 18), 'width': 2, 'height': 2, 'relief': 'flat', 'activebackground': "black"}

In the above code sample, we imported the essential libraries, such as Tkinter, as well as all of the widget classes, including the message box module. This framework allows Python programmers to easily develop GUI components by utilizing the widgets included in the Tk toolkit. Math module for solving mathematical equations. I designed the buttons using the button function.

Step.2: Defining the Functions of the Calculator

#Functions for the buttons
def fsin(arg):
    return sin(arg * convert_constant)
 
 
def fcos(arg):
    return cos(arg * convert_constant)
 
 
def ftan(arg):
    return tan(arg * convert_constant)
 
 
def arcsin(arg):
    return inverse_convert_constant * (asin(arg))
 
 
def arccos(arg):
    return inverse_convert_constant * (acos(arg))
 
 
def arctan(arg):
    return inverse_convert_constant * (atan(arg))

Here we define some functions to implement the Sin, Cos, Tan, Sin-¹, Cos-¹, Tan-¹. To do that we use some predefine python functions such as Sin(), Cos(), Tan(), asin(), acos(), atan().

Step.3: Creating a Display of Calculator

# Here are the methods inside class for all the Buttons in the Scientific Calculator.
class Calculator:
    def __init__(self, master):
        # expression that will be displayed on screen
        self.expression = ""
        # be used to store data in memory
        self.recall = ""
        # self.answer
        self.sum_up = ""
        # create string for text input
        self.text_input = tk.StringVar()
        # assign instance to master
        self.master = master
        # set frame showing inputs and title
        top_frame = tk.Frame(master, width=650, height=10,
                             bd=10, relief='flat', bg='gray')
        top_frame.pack(side=tk.TOP)
        # set frame showing all buttons
        bottom_frame = tk.Frame(
            master, width=650, height=470, bd=2, relief='flat', bg='black')
        bottom_frame.pack(side=tk.BOTTOM)
       
        # Here is the code for Display of Calculator.
        # entry interface for inputs
        txt_display = tk.Entry(top_frame, font=('arial', 36), relief='flat', bg='black', fg='white', textvariable=self.text_input, width=60, bd=12, justify='right')
        txt_display.pack()
 
        # row 0
        # left bracket button
        self.btn_left_brack = tk.Button(
            bottom_frame, **btn_params, text="(", border=1, command=lambda: self.btn_click('('))
        self.btn_left_brack.grid(row=0, column=0)
        # right bracket button
        self.btn_right_brack = tk.Button(
            bottom_frame, **btn_params, text=")", command=lambda: self.btn_click(')'))
        self.btn_right_brack.grid(row=0, column=1)
        # takes e to some exponent that you insert into the function
        self.btn_exp = tk.Button(
            bottom_frame, **btn_params, text="exp", command=lambda: self.btn_click('exp('))
        self.btn_exp.grid(row=0, column=2)
        # constant pi
        self.btn_pi = tk.Button(
            bottom_frame, **btn_params, text="π", command=lambda: self.btn_click('pi'))
        self.btn_pi.grid(row=0, column=3)
        # square root
        self.btn_sqrt = tk.Button(
            bottom_frame, **btn_params, text="sqrt", command=lambda: self.btn_click('sqrt('))
        self.btn_sqrt.grid(row=0, column=4)
        # clears self.expression
        self.btn_clear = tk.Button(
            bottom_frame, **btn_params, text="C", command=self.btn_clear_all)
        self.btn_clear.grid(row=0, column=5)
        # deletes last string input
        self.btn_del = tk.Button(
            bottom_frame, **btn_params, text="AC", command=self.btn_clear1)
        self.btn_del.grid(row=0, column=6)
        # inputs a negative sign to the next entry
        self.btn_change_sign = tk.Button(
            bottom_frame, **btn_params, text="+/-", command=self.change_signs)
        self.btn_change_sign.grid(row=0, column=7)
        # division
        self.btn_div = tk.Button(
            bottom_frame, **btn_params, text="/", command=lambda: self.btn_click('/'))
        self.btn_div.grid(row=0, column=8)
 
        # row 1
        # changes trig function outputs to degrees
        self.btn_Deg = tk.Button(bottom_frame, **btn_params, activeforeground='gray', text="Deg", command=self.convert_deg)
        self.btn_Deg.grid(row=1, column=0)
        # changes trig function outputs to default back to radians
        self.btn_Rad = tk.Button(bottom_frame, **btn_params, foreground='white', activeforeground='Gray', text="Rad", command=self.convert_rad)
        self.btn_Rad.grid(row=1, column=1)
        # cubes a value
        self.cube = tk.Button(bottom_frame, **btn_params, text=u"x\u00B3", command=lambda: self.btn_click('**3'))
        self.cube.grid(row=1, column=2)
        # takes the absolute value of an expression
        self.btn_abs = tk.Button(
            bottom_frame, **btn_params, text="abs", command=lambda: self.btn_click('abs' + '('))
        self.btn_abs.grid(row=1, column=3)
        # 'memory clear' button. Wipes self.recall to an empty string
        self.btn_MC = tk.Button(
            bottom_frame, **btn_params, text="MC", command=self.memory_clear)
        self.btn_MC.grid(row=1, column=4)
        # seven
        self.btn_7 = tk.Button(bottom_frame, **btn_params, text="7", command=lambda: self.btn_click(7))
        self.btn_7.configure(activebackground="black", bg='black')
        self.btn_7.grid(row=1, column=5)
        # eight
        self.btn_8 = tk.Button(bottom_frame, **btn_params, text="8", command=lambda: self.btn_click(8))
        self.btn_8.configure(activebackground="black", bg='black')
        self.btn_8.grid(row=1, column=6)
        # nine
        self.btn_9 = tk.Button(bottom_frame, **btn_params, text="9", command=lambda: self.btn_click(9))
        self.btn_9.configure(activebackground="black", bg='black')
        self.btn_9.grid(row=1, column=7)
        # multiplication
        self.btn_mult = tk.Button(bottom_frame, **btn_params, text="x", command=lambda: self.btn_click('*'))
        self.btn_mult.grid(row=1, column=8)
 
        # row 2
        # sin function that returns value from -1 to 1 by default
        self.btn_sin = tk.Button(
            bottom_frame, **btn_params, text="sin", command=lambda: self.btn_click('fsin('))
        self.btn_sin.grid(row=2, column=0)
        # cos function that returns value from -1 to 1 by default
        self.btn_cos = tk.Button(
            bottom_frame, **btn_params, text="cos", command=lambda: self.btn_click('fcos('))
        self.btn_cos.grid(row=2, column=1)
        # tan function
        self.btn_tan = tk.Button(bottom_frame, **btn_params, text="tan", command=lambda: self.btn_click('ftan('))
        self.btn_tan.grid(row=2, column=2)
        #
        self.btn_log = tk.Button(bottom_frame, **btn_params, text="log", command=lambda: self.btn_click('log('))
        self.btn_log.grid(row=2, column=3)
        # outputs what is in self.recall
        self.btn_MR = tk.Button(bottom_frame, **btn_params, text="MR", command=self.memory_recall)
        self.btn_MR.grid(row=2, column=4)
        # four
        self.btn_4 = tk.Button(bottom_frame, **btn_params, text="4", command=lambda: self.btn_click(4))
        self.btn_4.configure(activebackground="black", bg='black')
        self.btn_4.grid(row=2, column=5)
        # five
        self.btn_5 = tk.Button(bottom_frame, **btn_params, text="5", command=lambda: self.btn_click(5))
        self.btn_5.configure(activebackground="black", bg='black')
        self.btn_5.grid(row=2, column=6)
        # six
        self.btn_6 = tk.Button(bottom_frame, **btn_params, text="6", command=lambda: self.btn_click(6))
        self.btn_6.configure(activebackground="black", bg='black')
        self.btn_6.grid(row=2, column=7)
        # subtraction
        self.btnSub = tk.Button(bottom_frame, **btn_params, text="-", command=lambda: self.btn_click('-'))
        self.btnSub.grid(row=2, column=8)
 
        # row 3
        # sin inverse function
        self.btn_sin_inverse = tk.Button(bottom_frame, **btn_params, text=u"sin-\u00B9", command=lambda: self.btn_click('arcsin('))
        self.btn_sin_inverse.grid(row=3, column=0)
        # cos inverse function
        self.btn_cos_inverse = tk.Button(bottom_frame, **btn_params, text=u"cos-\u00B9", command=lambda: self.btn_click('arccos('))
        self.btn_cos_inverse.grid(row=3, column=1)
        # tan inverse function
        self.btn_tan_inverse = tk.Button(bottom_frame, **btn_params, text=u"tan-\u00B9", command=lambda: self.btn_click('arctan('))
        self.btn_tan_inverse.grid(row=3, column=2)
        # takes the natural log
        self.btn_ln = tk.Button(bottom_frame, **btn_params, text="ln", command=lambda: self.btn_click('log1p('))
        self.btn_ln.grid(row=3, column=3)
        # adds current self.expression to self.recall string
        self.btn_M_plus = tk.Button(bottom_frame, **btn_params, text="M+", command=self.memory_add)
        self.btn_M_plus.grid(row=3, column=4)
        # one
        self.btn_1 = tk.Button(bottom_frame, **btn_params, text="1", command=lambda: self.btn_click(1))
        self.btn_1.configure(activebackground="black", bg='black')
        self.btn_1.grid(row=3, column=5)
        # two
        self.btn_2 = tk.Button(bottom_frame, **btn_params, text="2", command=lambda: self.btn_click(2))
        self.btn_2.configure(activebackground="black", bg='black')
        self.btn_2.grid(row=3, column=6)
        # three
        self.btn_3 = tk.Button(bottom_frame, **btn_params, text="3", command=lambda: self.btn_click(3))
        self.btn_3.configure(activebackground="black", bg='black')
        self.btn_3.grid(row=3, column=7)
        # addition
        self.btn_add = tk.Button(
            bottom_frame, **btn_params, text="+", command=lambda: self.btn_click('+'))
        self.btn_add.grid(row=3, column=8)
 
        # row 4
        # factorial function
        self.btn_fact = tk.Button(bottom_frame, **btn_params, text="n!", command=lambda: self.btn_click('factorial('))
        self.btn_fact.grid(row=4, column=0)
        # square function
        self.btn_sqr = tk.Button(bottom_frame, **btn_params, text=u"x\u00B2", command=lambda: self.btn_click('**2'))
        self.btn_sqr.grid(row=4, column=1)
        # to the power of function
        self.btn_power = tk.Button(bottom_frame, **btn_params, text="x^y", command=lambda: self.btn_click('**'))
        self.btn_power.grid(row=4, column=2)
        # stores previous expression as an answer value
        self.btn_ans = tk.Button(bottom_frame, **btn_params, text="ans", command=self.answer)
        self.btn_ans.grid(row=4, column=3)
        # comma to allow for more than one parameter!
        self.btn_comma = tk.Button(bottom_frame, **btn_params, text=",", command=lambda: self.btn_click(','))
        self.btn_comma.grid(row=4, column=4)
        # zero
        self.btn_0 = tk.Button(bottom_frame, **btn_params, text="0", command=lambda: self.btn_click(0))
        self.btn_0.configure(activebackground="black", bg='black', width=7, bd=5)
        self.btn_0.grid(row=4, column=5, columnspan=2)
        # equals button
        self.btn_eq = tk.Button(bottom_frame, **btn_params, text="=", command=self.btn_equal)
        self.btn_eq.configure(bg='Gray', activebackground='#009999')
        self.btn_eq.grid(row=4, column=7)
        # decimal to convert to float
        self.btn_dec = tk.Button(bottom_frame, **btn_params, text=".", command=lambda: self.btn_click('.'))
        self.btn_dec.grid(row=4, column=8)

We created a Calculator class with the following instance variables: ‘op’ (stores the current operator clicked by the user), ‘M’ (stores memory), ‘isTrue 2nd’ (stores True if ‘2nd’ is clicked and activates the second set of scientific functions like sin-1, 10x. ex, y x in place of sin, log, ln, xy), ‘is degree’ (True if ‘deg’ is on, takes radians for trigonometric operations when ‘deg’ is clicked to ‘rad’ and is degree = False) and ‘decimal clicked’ (turns True when user clicks ‘.’)

Step.4: Create functions for the buttons in Calculator 

    # allows button you click to be put into self.expression
 
    def btn_click(self, expression_val):
        if len(self.expression) >= 23:
            self.expression = self.expression
            self.text_input.set(self.expression)
        else:
            self.expression = self.expression + str(expression_val)
            self.text_input.set(self.expression)

 
    # clears last item in string
 
    def btn_clear1(self):
        self.expression = self.expression[:-1]
        self.text_input.set(self.expression)

    # adds in a negative sign
 
    def change_signs(self):
        self.expression = self.expression + '-'
        self.text_input.set(self.expression)

    # clears memory_recall
 
    def memory_clear(self):
        self.recall = ""
 

    # adds whatever is on the screen to self.recall
 
    def memory_add(self):
        self.recall = self.recall + '+' + self.expression

    # uses whatever is stored in memory_recall
 
    def answer(self):
        self.answer = self.sum_up
        self.expression = self.expression + self.answer
        self.text_input.set(self.expression)

    # uses whatever is stored in memory_recall
    def memory_recall(self):
        if self.expression == "":
            self.text_input.set('0' + self.expression + self.recall)
        else:
            self.text_input.set(self.expression + self.recall)

    # changes self.convert_constant to a string that allows degree conversion when button is clicked
    def convert_deg(self):
        global convert_constant
        global inverse_convert_constant
        convert_constant = pi / 180
        inverse_convert_constant = 180 / pi
        self.btn_Rad["foreground"] = 'White'
        self.btn_Deg["foreground"] = 'RED'

    def convert_rad(self):
        global convert_constant
        global inverse_convert_constant
        convert_constant = 1
        inverse_convert_constant = 1
        self.btn_Rad["foreground"] = 'RED'
        self.btn_Deg["foreground"] = 'white'

    # clears self.expression
 
    def btn_clear_all(self):
        self.expression = ""
        self.text_input.set("")

    # converts self.expression into a mathematical expression and evaluates it
 
    def btn_equal(self):
        self.sum_up = str(eval(self.expression))
        self.text_input.set(self.sum_up)
        self.expression = self.sum_up

Step.5: Making Tkinter Layout

# tkinter layout
root = tk.Tk()
b = Calculator(root)
root.title("Scientific Calculator!")
root.geometry("650x490+50+50")
root.resizable(False, False)
root.mainloop()

In the end, it is time to start designing the program’s graphical user interface for our Scientific Calculator in Python using Tkinter. We will begin by launching Tkinter and creating a window for the Scientific calculator. In this case, we set the window size to 650×490+50+50, and the window resizability to false.

Complete code for Scientific Calculator in Python using Tkinter

import tkinter as tk
from math import *
 
# used to switch between units of rad, and deg
convert_constant = 1
inverse_convert_constant = 1
 
btn_params = {'padx': 16, 'pady': 1, 'bd': 4, 'fg': 'white', 'bg': 'black', 'font': ('arial', 18),
              'width': 2, 'height': 2, 'relief': 'flat', 'activebackground': "black"}
 
#Functions for the buttons
def fsin(arg):
    return sin(arg * convert_constant)
 
 
def fcos(arg):
    return cos(arg * convert_constant)
 
 
def ftan(arg):
    return tan(arg * convert_constant)
 
 
def arcsin(arg):
    return inverse_convert_constant * (asin(arg))
 
 
def arccos(arg):
    return inverse_convert_constant * (acos(arg))
 
 
def arctan(arg):
    return inverse_convert_constant * (atan(arg))
 
 
# Here are the methods inside class for all the Buttons in the Scientific Calculator.
class Calculator:
    def __init__(self, master):
        # expression that will be displayed on screen
        self.expression = ""
        # be used to store data in memory
        self.recall = ""
        # self.answer
        self.sum_up = ""
        # create string for text input
        self.text_input = tk.StringVar()
        # assign instance to master
        self.master = master
        # set frame showing inputs and title
        top_frame = tk.Frame(master, width=650, height=10,
                             bd=10, relief='flat', bg='gray')
        top_frame.pack(side=tk.TOP)
        # set frame showing all buttons
        bottom_frame = tk.Frame(
            master, width=650, height=470, bd=2, relief='flat', bg='black')
        bottom_frame.pack(side=tk.BOTTOM)
       
        # Here is the code for Display of Calculator.
        # entry interface for inputs
        txt_display = tk.Entry(top_frame, font=('arial', 36), relief='flat', bg='black', fg='white', textvariable=self.text_input, width=60, bd=12, justify='right')
        txt_display.pack()
 
        # row 0
        # left bracket button
        self.btn_left_brack = tk.Button(
            bottom_frame, **btn_params, text="(", border=1, command=lambda: self.btn_click('('))
        self.btn_left_brack.grid(row=0, column=0)
        # right bracket button
        self.btn_right_brack = tk.Button(
            bottom_frame, **btn_params, text=")", command=lambda: self.btn_click(')'))
        self.btn_right_brack.grid(row=0, column=1)
        # takes e to some exponent that you insert into the function
        self.btn_exp = tk.Button(
            bottom_frame, **btn_params, text="exp", command=lambda: self.btn_click('exp('))
        self.btn_exp.grid(row=0, column=2)
        # constant pi
        self.btn_pi = tk.Button(
            bottom_frame, **btn_params, text="π", command=lambda: self.btn_click('pi'))
        self.btn_pi.grid(row=0, column=3)
        # square root
        self.btn_sqrt = tk.Button(
            bottom_frame, **btn_params, text="sqrt", command=lambda: self.btn_click('sqrt('))
        self.btn_sqrt.grid(row=0, column=4)
        # clears self.expression
        self.btn_clear = tk.Button(
            bottom_frame, **btn_params, text="C", command=self.btn_clear_all)
        self.btn_clear.grid(row=0, column=5)
        # deletes last string input
        self.btn_del = tk.Button(
            bottom_frame, **btn_params, text="AC", command=self.btn_clear1)
        self.btn_del.grid(row=0, column=6)
        # inputs a negative sign to the next entry
        self.btn_change_sign = tk.Button(
            bottom_frame, **btn_params, text="+/-", command=self.change_signs)
        self.btn_change_sign.grid(row=0, column=7)
        # division
        self.btn_div = tk.Button(
            bottom_frame, **btn_params, text="/", command=lambda: self.btn_click('/'))
        self.btn_div.grid(row=0, column=8)
 
        # row 1
        # changes trig function outputs to degrees
        self.btn_Deg = tk.Button(bottom_frame, **btn_params, activeforeground='gray', text="Deg", command=self.convert_deg)
        self.btn_Deg.grid(row=1, column=0)
        # changes trig function outputs to default back to radians
        self.btn_Rad = tk.Button(bottom_frame, **btn_params, foreground='white', activeforeground='Gray', text="Rad", command=self.convert_rad)
        self.btn_Rad.grid(row=1, column=1)
        # cubes a value
        self.cube = tk.Button(bottom_frame, **btn_params, text=u"x\u00B3", command=lambda: self.btn_click('**3'))
        self.cube.grid(row=1, column=2)
        # takes the absolute value of an expression
        self.btn_abs = tk.Button(
            bottom_frame, **btn_params, text="abs", command=lambda: self.btn_click('abs' + '('))
        self.btn_abs.grid(row=1, column=3)
        # 'memory clear' button. Wipes self.recall to an empty string
        self.btn_MC = tk.Button(
            bottom_frame, **btn_params, text="MC", command=self.memory_clear)
        self.btn_MC.grid(row=1, column=4)
        # seven
        self.btn_7 = tk.Button(bottom_frame, **btn_params, text="7", command=lambda: self.btn_click(7))
        self.btn_7.configure(activebackground="black", bg='black')
        self.btn_7.grid(row=1, column=5)
        # eight
        self.btn_8 = tk.Button(bottom_frame, **btn_params, text="8", command=lambda: self.btn_click(8))
        self.btn_8.configure(activebackground="black", bg='black')
        self.btn_8.grid(row=1, column=6)
        # nine
        self.btn_9 = tk.Button(bottom_frame, **btn_params, text="9", command=lambda: self.btn_click(9))
        self.btn_9.configure(activebackground="black", bg='black')
        self.btn_9.grid(row=1, column=7)
        # multiplication
        self.btn_mult = tk.Button(bottom_frame, **btn_params, text="x", command=lambda: self.btn_click('*'))
        self.btn_mult.grid(row=1, column=8)
 
        # row 2
        # sin function that returns value from -1 to 1 by default
        self.btn_sin = tk.Button(
            bottom_frame, **btn_params, text="sin", command=lambda: self.btn_click('fsin('))
        self.btn_sin.grid(row=2, column=0)
        # cos function that returns value from -1 to 1 by default
        self.btn_cos = tk.Button(
            bottom_frame, **btn_params, text="cos", command=lambda: self.btn_click('fcos('))
        self.btn_cos.grid(row=2, column=1)
        # tan function
        self.btn_tan = tk.Button(bottom_frame, **btn_params, text="tan", command=lambda: self.btn_click('ftan('))
        self.btn_tan.grid(row=2, column=2)
        #
        self.btn_log = tk.Button(bottom_frame, **btn_params, text="log", command=lambda: self.btn_click('log('))
        self.btn_log.grid(row=2, column=3)
        # outputs what is in self.recall
        self.btn_MR = tk.Button(bottom_frame, **btn_params, text="MR", command=self.memory_recall)
        self.btn_MR.grid(row=2, column=4)
        # four
        self.btn_4 = tk.Button(bottom_frame, **btn_params, text="4", command=lambda: self.btn_click(4))
        self.btn_4.configure(activebackground="black", bg='black')
        self.btn_4.grid(row=2, column=5)
        # five
        self.btn_5 = tk.Button(bottom_frame, **btn_params, text="5", command=lambda: self.btn_click(5))
        self.btn_5.configure(activebackground="black", bg='black')
        self.btn_5.grid(row=2, column=6)
        # six
        self.btn_6 = tk.Button(bottom_frame, **btn_params, text="6", command=lambda: self.btn_click(6))
        self.btn_6.configure(activebackground="black", bg='black')
        self.btn_6.grid(row=2, column=7)
        # subtraction
        self.btnSub = tk.Button(bottom_frame, **btn_params, text="-", command=lambda: self.btn_click('-'))
        self.btnSub.grid(row=2, column=8)
 
        # row 3
        # sin inverse function
        self.btn_sin_inverse = tk.Button(bottom_frame, **btn_params, text=u"sin-\u00B9", command=lambda: self.btn_click('arcsin('))
        self.btn_sin_inverse.grid(row=3, column=0)
        # cos inverse function
        self.btn_cos_inverse = tk.Button(bottom_frame, **btn_params, text=u"cos-\u00B9", command=lambda: self.btn_click('arccos('))
        self.btn_cos_inverse.grid(row=3, column=1)
        # tan inverse function
        self.btn_tan_inverse = tk.Button(bottom_frame, **btn_params, text=u"tan-\u00B9", command=lambda: self.btn_click('arctan('))
        self.btn_tan_inverse.grid(row=3, column=2)
        # takes the natural log
        self.btn_ln = tk.Button(bottom_frame, **btn_params, text="ln", command=lambda: self.btn_click('log1p('))
        self.btn_ln.grid(row=3, column=3)
        # adds current self.expression to self.recall string
        self.btn_M_plus = tk.Button(bottom_frame, **btn_params, text="M+", command=self.memory_add)
        self.btn_M_plus.grid(row=3, column=4)
        # one
        self.btn_1 = tk.Button(bottom_frame, **btn_params, text="1", command=lambda: self.btn_click(1))
        self.btn_1.configure(activebackground="black", bg='black')
        self.btn_1.grid(row=3, column=5)
        # two
        self.btn_2 = tk.Button(bottom_frame, **btn_params, text="2", command=lambda: self.btn_click(2))
        self.btn_2.configure(activebackground="black", bg='black')
        self.btn_2.grid(row=3, column=6)
        # three
        self.btn_3 = tk.Button(bottom_frame, **btn_params, text="3", command=lambda: self.btn_click(3))
        self.btn_3.configure(activebackground="black", bg='black')
        self.btn_3.grid(row=3, column=7)
        # addition
        self.btn_add = tk.Button(
            bottom_frame, **btn_params, text="+", command=lambda: self.btn_click('+'))
        self.btn_add.grid(row=3, column=8)
 
        # row 4
        # factorial function
        self.btn_fact = tk.Button(bottom_frame, **btn_params, text="n!", command=lambda: self.btn_click('factorial('))
        self.btn_fact.grid(row=4, column=0)
        # square function
        self.btn_sqr = tk.Button(bottom_frame, **btn_params, text=u"x\u00B2", command=lambda: self.btn_click('**2'))
        self.btn_sqr.grid(row=4, column=1)
        # to the power of function
        self.btn_power = tk.Button(bottom_frame, **btn_params, text="x^y", command=lambda: self.btn_click('**'))
        self.btn_power.grid(row=4, column=2)
        # stores previous expression as an answer value
        self.btn_ans = tk.Button(bottom_frame, **btn_params, text="ans", command=self.answer)
        self.btn_ans.grid(row=4, column=3)
        # comma to allow for more than one parameter!
        self.btn_comma = tk.Button(bottom_frame, **btn_params, text=",", command=lambda: self.btn_click(','))
        self.btn_comma.grid(row=4, column=4)
        # zero
        self.btn_0 = tk.Button(bottom_frame, **btn_params, text="0", command=lambda: self.btn_click(0))
        self.btn_0.configure(activebackground="black", bg='black', width=7, bd=5)
        self.btn_0.grid(row=4, column=5, columnspan=2)
        # equals button
        self.btn_eq = tk.Button(bottom_frame, **btn_params, text="=", command=self.btn_equal)
        self.btn_eq.configure(bg='Gray', activebackground='#009999')
        self.btn_eq.grid(row=4, column=7)
        # decimal to convert to float
        self.btn_dec = tk.Button(bottom_frame, **btn_params, text=".", command=lambda: self.btn_click('.'))
        self.btn_dec.grid(row=4, column=8)
 
    # functions
    # allows button you click to be put into self.expression
 
    def btn_click(self, expression_val):
        if len(self.expression) >= 23:
            self.expression = self.expression
            self.text_input.set(self.expression)
        else:
            self.expression = self.expression + str(expression_val)
            self.text_input.set(self.expression)
 
    # clears last item in string
 
    def btn_clear1(self):
        self.expression = self.expression[:-1]
        self.text_input.set(self.expression)
 
    # adds in a negative sign
 
    def change_signs(self):
        self.expression = self.expression + '-'
        self.text_input.set(self.expression)
 
    # clears memory_recall
 
    def memory_clear(self):
        self.recall = ""
 
    # adds whatever is on the screen to self.recall
 
    def memory_add(self):
        self.recall = self.recall + '+' + self.expression
 
    # uses whatever is stored in memory_recall
 
    def answer(self):
        self.answer = self.sum_up
        self.expression = self.expression + self.answer
        self.text_input.set(self.expression)
 
    # uses whatever is stored in memory_recall
 
    def memory_recall(self):
        if self.expression == "":
            self.text_input.set('0' + self.expression + self.recall)
        else:
            self.text_input.set(self.expression + self.recall)
 
    # changes self.convert_constant to a string that allows degree conversion when button is clicked
 
    def convert_deg(self):
        global convert_constant
        global inverse_convert_constant
        convert_constant = pi / 180
        inverse_convert_constant = 180 / pi
        self.btn_Rad["foreground"] = 'white'
        self.btn_Deg["foreground"] = 'RED'
 
    def convert_rad(self):
        global convert_constant
        global inverse_convert_constant
        convert_constant = 1
        inverse_convert_constant = 1
        self.btn_Rad["foreground"] = 'RED'
        self.btn_Deg["foreground"] = 'white'
 
    # clears self.expression
 
    def btn_clear_all(self):
        self.expression = ""
        self.text_input.set("")
 
    # converts self.expression into a mathematical expression and evaluates it
 
    def btn_equal(self):
        self.sum_up = str(eval(self.expression))
        self.text_input.set(self.sum_up)
        self.expression = self.sum_up
 
 
# tkinter layout
root = tk.Tk()
b = Calculator(root)
root.title("Scientific Calculator!")
root.geometry("650x490+50+50")
root.resizable(False, False)
root.mainloop()

Output:

Output for Scientific Calculator in Python using Tkinter

Conclusion

In this article, we built a Scientific Calculator in Python using Tkinter and defined what happens when a user interacts with a UI element. Using Frame widgets to create containers/windows in which to arrange UI components. Positioning Button widgets within a Frame widget using Tkinter’s Layout Manager. The grid layout manager was chosen for the Calculator application due to its precision compared to alternative layout techniques.


Also Read:

Share:

Author: Harsh Sheladiya