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 

  1. from tkinter import *
  2. import re

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:

Calculator in Python using tkinter package

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

  1. class Calculator(Frame):
  2. ....methods here
  3.  
  4. app = Calculator()
  5. app.mainloop()

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:

  1. def __init__(self, master=None):
  2. master = self.main_window()
  3. super().__init__(master)
  4. self.pack()
  5. self.create_widgets()
  6. self.render_widgets()

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()
  1. def main_window(self):
  2. root = Tk()
  3. root.title("Calculator developed by Ahmad Asjad using PYTHON")
  4. return root

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()

  1. def create_widgets(self):
  2. self.create_controls()
  3. self.create_digits()
  4.  
  5. #4 width widgets
  6. four_width = ['clear_all', 'clear', 'div', 'mult', 'min', 'plus', 'equal', 'seven', 'eight', 'nine', 'four',
  7. 'five', 'six', 'one', 'two', 'three', 'dot']
  8. self.set_width(four_width, 4)
  9.  
  10. #30 width widgets
  11. thirty_width = ['result', 'input']
  12. 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()
  1. def create_controls(self):
  2. self.result = Label(self, text='Result', bg='gray', height=2)
  3. self.input = Entry(self)
  4. self.clear_all = Button(self, bg='#393939', fg='white', text='C', height=2)
  5. self.clear = Button(self, bg='#393939', fg='white', text='X', height=2)
  6. self.div = Button(self, bg='#393939', fg='white', text='/', height=2, command=lambda : self.appent_input('/'))
  7. self.mult = Button(self, bg='#393939', fg='white', text='*', height=2, command=lambda : self.appent_input('*'))
  8. self.min = Button(self, bg='#393939', fg='white', text='-', height=2, command=lambda : self.appent_input('-'))
  9. self.plus = Button(self, bg='#393939', fg='white', text='+', height=2, command=lambda : self.appent_input('+'))
  10. 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()
  1. def create_digits(self):
  2. self.seven = Button(self, bg='#1f1f1f', fg='white', text='7', height=2, command=lambda : self.appent_input('7'))
  3. self.eight = Button(self, bg='#1f1f1f', fg='white', text='8', height=2, command=lambda : self.appent_input('8'))
  4. self.nine = Button(self, bg='#1f1f1f', fg='white', text='9', height=2, command=lambda : self.appent_input('9'))
  5.  
  6. self.four = Button(self, bg='#1f1f1f', fg='white', text='4', height=2, command=lambda : self.appent_input('4'))
  7. self.five = Button(self, bg='#1f1f1f', fg='white', text='5', height=2, command=lambda : self.appent_input('5'))
  8. self.six = Button(self, bg='#1f1f1f', fg='white', text='6', height=2, command=lambda : self.appent_input('6'))
  9.  
  10. self.one = Button(self, bg='#1f1f1f', fg='white', text='1', height=2, command=lambda : self.appent_input('1'))
  11. self.two = Button(self, bg='#1f1f1f', fg='white', text='2', height=2, command=lambda : self.appent_input('2'))
  12. self.three = Button(self, bg='#1f1f1f', fg='white', text='3', height=2, command=lambda : self.appent_input('3'))
  13.  
  14. self.zero = Button(self, bg='#1f1f1f', fg='white', text='0', width=12, height=2, command=lambda : self.appent_input('0'))
  15. 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()
  1. def appent_input(self, val):
  2. old_val = self.input.get()
  3. new_val = old_val + val
  4. self.input.delete(0, END)
  5. self.input.insert(0, self.validate_input(new_val))

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()
  1. def calculate(self):
  2. input_val = self.input.get()
  3. print(eval(input_val))
  4. self.result.config(text=input_val)
  5. self.input.delete(0, END)
  6. self.input.insert(0, eval(input_val))

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

 

validate_input()
  1. def validate_input(self, input):
  2. first_char = input[0]
  3. wront_char = re.match('[^0-9\-\+\(\)]', first_char)
  4. if(wront_char == None):
  5. return input
  6. elif(len(input) == 1):
  7. return ""
  8. else:
  9. 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:

  1. def render_widgets(self):
  2. self.result.grid(row=0, column=0, columnspan=4)
  3. self.input.grid(row=1, column=0, columnspan=4)
  4.  
  5. self.clear_all.grid(row=2, column=0)
  6. self.clear.grid(row=2, column=1)
  7. self.div.grid(row=2, column=2)
  8. self.mult.grid(row=2, column=3)
  9. self.min.grid(row=3, column=3)
  10. self.plus.grid(row=4, column=3)
  11. self.equal.grid(row=5, column=3, rowspan=2)
  12.  
  13. self.seven.grid(row=3, column=0)
  14. self.eight.grid(row=3, column=1)
  15. self.nine.grid(row=3, column=2)
  16.  
  17. self.four.grid(row=4, column=0)
  18. self.five.grid(row=4, column=1)
  19. self.six.grid(row=4, column=2)
  20.  
  21. self.one.grid(row=5, column=0)
  22. self.two.grid(row=5, column=1)
  23. self.three.grid(row=5, column=2)
  24.  
  25. self.zero.grid(row=6, column=0, columnspan=2)
  26. 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

 

 

 

Singleton pattern

Singleton pattern

is a creational pattern – one of the three basic design pattern.

As the name describes, it’s something which deals with a single value or it works as a unique thing.

In programming, it’s a class which have only one object in the entire execution process.

According to a programming language, you’ll have to set up the class in such a way that only one object will be created in the entire process.

Prerequisites:

  • Basic programming knowledge.
  • A basic oops concept like what is class, method, property, etc.
  • More understandable if you know PHP

In this, I’m going to use PHP as a programming language to implement the singleton pattern.

  • Make constructor – __contruct method – private.
  • Make __clone method private or keep it public, but let you always return $this variable.
  • Define a public static method to create an object of the same class.
  • Define a private static variable to check if the object created or not. Or keep the created object in that variable and return the same value if requested – I’m going to return the same object created in the previous call. I’ll create one if it’s called first time, and I’ll store it in the static variable.

 

  1. <?php
  2.  
  3. /**
  4.  * Description of SingletonPattern
  5.  *
  6.  * @author Ahmad Asjad <ahmadcimage@gmail.com>
  7.  */
  8. class SingletonPattern {
  9.  
  10. public $param1;
  11. public $param2;
  12. private static $selfInstance;
  13.  
  14. private function __construct($param1, $param2) {
  15. $this->param1 = $param1;
  16. $this->param2 = $param2;
  17. }
  18.  
  19. public function __clone() {
  20. return $this;
  21. }
  22.  
  23. /**
  24.   * @param string $param1
  25.   * @param string $param2
  26.   * @return SingletonPattern
  27.   */
  28. public static function getInstance($param1, $param2) {
  29. if (empty(self::$selfInstance)) {
  30. //Pass params to be passed to the constructor
  31. self::$selfInstance = new static($param1, $param2);
  32. }
  33. return self::$selfInstance;
  34. }
  35.  
  36. }

 

 

Run xdebug with quick setting

Many people have problems in enabling the xdebug module to debug their code. Let’s see how easy it’s to run xdebug with quick setting.

Steps to run xdebug

Step 1

Install xdebug if not already installed. after installation check whether it’s installed correctly or not (using phpinfo();)

Step 2

Edit php.ini and paste the sample of code:

If you are using Ubuntu, your php.ini path is something like /etc/php/7.1/apache2/php.ini

If you are using the console application of PHP, the path will differ: /etc/php/7.1/cli/php.ini

  1. ; Added for xdebug
  2. zend_extension="/usr/lib/php/20160303/xdebug.so"
  3. xdebug.remote_enable=1
  4. xdebug.remote_autostart = 1
  5. xdebug.remote_handler=dbgp
  6. xdebug.remote_mode=req
  7. xdebug.remote_host=localhost
  8. xdebug.remote_port=9000
  9. xdebug.profile_enable=1

change the above code according to your requirement

Step 3

Restart apache, if you want to use it instantly.

Now tell your editor to listen for xdebug.

How to enable PHP mail function on Ubuntu

Here are steps to follow:

First of all install packagephp-pear if it’s already not installed. apt-get install php-pear
Then install following PEAR packages

  • pear install mail
  • pear install Net_SMTP
  • pear install Auth_SASL
  • pear install mail_mime

Then install POSTFIX

apt-get install postfix

This command will bring dialogue step by step to setup mail server.

Select Internet Site

and choose domain mail to be sent from

Try to send mail using mail() function, and you’ll receive the one you sent.

Anonymous function example in PHP

 

  1. <?php
  2.  
  3. /**
  4. * An array function to work with its individual value whatever we want.
  5. * @param array $array
  6. * @param function $function
  7. */
  8. function anonymous_test($array, $function){
  9. foreach ($array as $single){
  10. $function($single);
  11. }
  12. }
  13. ?>

 

 

  1. <?php
  2. /**
  3. * Here we are writing a function which will print only if it's printable.
  4. */
  5. $arr = [1,2,3,['A','B'],4,5];
  6. anonymous_test($arr, function($value){
  7. if(!is_array($value) && !is_object($value)){
  8. echo $value;
  9. }
  10. });

1 of 812345678