## October 21, 2018 Calculator in Python

### Prerequisites

• Basic Python knowledge
• Basic oops concept

In this article, I’m going to describe to you how to make a calculator in Python using tkinter package. To make any desktop application in python, we need to import any desktop package like QT, tkinter, etc. Here I have selected the tkinter package.

## Calculator in Python using tkinter package

The `tkinter` package (“Tk interface”) is the standard Python interface to the Tk GUI toolkit

Now, we’ll have to assume some layout design for the calculator so that we can implement the same using tkinter package. Here I have chosen this design for that purpose: If you are new to tkinter, I’ll recommend you to go through this page: https://tkdocs.com/tutorial/firstexample.html

I have extended Frame class of the tkinter in my custom class `Calculator`

`mainloop` is a method of Frame class which starts the desktop widget. So, after playing our all logic, we’ll have to call this method to render the GUI widgets.

##### constructor

I have started rendering of widgets right from the constructor of the class:

For any desktop application, there is always a main window which contains other widgets like button, label, input field, etc. Here I have created the main window master = self.main_window() in the above snippet

##### main_window()

For more detail on Tk class visit https://docs.python.org/3.5/library/tkinter.html#tkinter.Tk

##### create_widgets()

Now moving to our one of main functionality part – design layout for the calculator calling `self.create_widgets()`

 Code Block      `def create_widgets(self):    self.create_controls()    self.create_digits()     #4 width widgets    four_width = ['clear_all', 'clear', 'div', 'mult', 'min', 'plus', 'equal', 'seven', 'eight', 'nine', 'four',                  'five', 'six', 'one', 'two', 'three', 'dot']    self.set_width(four_width, 4)     #30 width widgets    thirty_width = ['result', 'input']    self.set_width(thirty_width, 30)`

In this method, I have called two methods of the same class to create the input widgets. I have categorized all buttons into two parts one for controls like plus, minus, division, etc. and another for digits like one, two, three, etc. characters. Then I have grouped those buttons width wise so that we can set the width of each widget accordingly.

#### Creating widgets

Let’s have a look on booth method creating the controls and digit widgets:

##### create_controls()
 Code Block      `def create_controls(self):    self.result = Label(self, text='Result', bg='gray', height=2)    self.input = Entry(self)    self.clear_all = Button(self, bg='#393939', fg='white', text='C', height=2)    self.clear = Button(self, bg='#393939', fg='white', text='X', height=2)    self.div = Button(self, bg='#393939', fg='white', text='/', height=2, command=lambda : self.appent_input('/'))    self.mult = Button(self, bg='#393939', fg='white', text='*', height=2, command=lambda : self.appent_input('*'))    self.min = Button(self, bg='#393939', fg='white', text='-', height=2, command=lambda : self.appent_input('-'))    self.plus = Button(self, bg='#393939', fg='white', text='+', height=2, command=lambda : self.appent_input('+'))    self.equal = Button(self, bg='red', fg='white', text='=', height=5, command=self.calculate)`

In this, I have set up all control required for a basic calculator and set its background and foreground color according to the design layout we decided earlier in the image. Don’t forget to see the command param of Button widgets. We are passing a method to perform the work once this button is clicked. Except one of them, all are passed appent_input() method and unique one is passed calculate method. You’ll see these methods later what exactly they do.

##### create_digits()
 Code Block      `def create_digits(self):    self.seven = Button(self, bg='#1f1f1f', fg='white', text='7', height=2, command=lambda : self.appent_input('7'))    self.eight = Button(self, bg='#1f1f1f', fg='white', text='8', height=2, command=lambda : self.appent_input('8'))    self.nine = Button(self, bg='#1f1f1f', fg='white', text='9', height=2, command=lambda : self.appent_input('9'))     self.four = Button(self, bg='#1f1f1f', fg='white', text='4', height=2, command=lambda : self.appent_input('4'))    self.five = Button(self, bg='#1f1f1f', fg='white', text='5', height=2, command=lambda : self.appent_input('5'))    self.six = Button(self, bg='#1f1f1f', fg='white', text='6', height=2, command=lambda : self.appent_input('6'))     self.one = Button(self, bg='#1f1f1f', fg='white', text='1', height=2, command=lambda : self.appent_input('1'))    self.two = Button(self, bg='#1f1f1f', fg='white', text='2', height=2, command=lambda : self.appent_input('2'))    self.three = Button(self, bg='#1f1f1f', fg='white', text='3', height=2, command=lambda : self.appent_input('3'))     self.zero = Button(self, bg='#1f1f1f', fg='white', text='0', width=12, height=2, command=lambda : self.appent_input('0'))    self.dot = Button(self, bg='#1f1f1f', fg='white', text='.', height=2, command=lambda : self.appent_input('.'))`

Same as the above method except that this generates digit widgets whereas above method generates control widgets.

#### Command methods being used on click of any widget

##### appent_input()

What exactly it does is, after a minimal validation, it appends the particular character in the input field. You can add more validation according to the scenario, this is for descriptive purpose only.

##### calculate()

This is the main method of the class which solves the calculation problem.

##### validate_input()
 Code Block      `def validate_input(self, input):    first_char = input    wront_char = re.match('[^0-9\-\+\(\)]', first_char)    if(wront_char == None):        return input    elif(len(input) == 1):        return ""    else:        return self.validate_input(input[1:])`

To validate the clicked button input. Like in the expression what character is allowed and what not.

##### render_widgets()

Till now, we have created the widgets, but we didn’t tell the system where these digits to appear. Following method solves this problem:

 Code Block      `def render_widgets(self):    self.result.grid(row=0, column=0, columnspan=4)    self.input.grid(row=1, column=0, columnspan=4)     self.clear_all.grid(row=2, column=0)    self.clear.grid(row=2, column=1)    self.div.grid(row=2, column=2)    self.mult.grid(row=2, column=3)    self.min.grid(row=3, column=3)    self.plus.grid(row=4, column=3)    self.equal.grid(row=5, column=3, rowspan=2)     self.seven.grid(row=3, column=0)    self.eight.grid(row=3, column=1)    self.nine.grid(row=3, column=2)     self.four.grid(row=4, column=0)    self.five.grid(row=4, column=1)    self.six.grid(row=4, column=2)     self.one.grid(row=5, column=0)    self.two.grid(row=5, column=1)    self.three.grid(row=5, column=2)     self.zero.grid(row=6, column=0, columnspan=2)    self.dot.grid(row=6, column=2)`

Here we have told the system how and where those widgets to appear. I have used grid to align those widgets, you can use according to your choice from the available Tk’s geometry-management mechanisms like pack(), etc.

For the complete class file, visit GitHub gist:

https://gist.github.com/ahmadasjad/2d7deb37a5867efd6d07c862ee2238d7