Just a relatively simple calculator using the Tkinter GUI. It has a few nice features such as correcting division by an integer (for older Python versions), error trapping, to and from memory buttons, and an editable display. The editable display allows you to backspace mistakes, and also to enter things not on the key pad, like hexnumbers. For instance if you enter 0xFF and press equals, it will give you the decimal (denary) equivalent of 255

The program also has a guard against the bad guys that like to abuse the underlying eval() function to wipe out files.

I wrote the code in detail, so you can hopefully figure it out. You can fancy up the calculator quite a bit, just experiment with the code.

See also the updated version at ...
http://www.daniweb.com/software-development/python/code/467452/updated-tiny-tkinter-calculator-python

Edited 3 Years Ago by vegaseat

Comments
nice code
# a tiny/simple Tkinter calculator (improved v.1.1)
# if you enter a number with a leading zero it will be an octal number!
# eg. 012 would be a decimal 10  (0.12 will not be affected)
# used a more modern import to give Tkinter items a namespace
# tested with Python24     vegaseat     08dec2006

"""
calculator has a layout like this ...
<   display   >
7  8  9  *  C
4  5  6  /  M->
1  2  3  -  ->M
0  .  =  +  neg
"""

import Tkinter as tk

def click(key):
    global memory
    if key == '=':
        # avoid division by integer
        if '/' in entry.get() and '.' not in entry.get():
            entry.insert(tk.END, ".0")
        # guard against the bad guys abusing eval()
        str1 = "-+0123456789."
        if entry.get()[0] not in str1:
            entry.insert(tk.END, "first char not in " + str1)
        # here comes the calculation part
        try:
            result = eval(entry.get())
            entry.insert(tk.END, " = " + str(result))
        except:
            entry.insert(tk.END, "--> Error!")
    elif key == 'C':
        entry.delete(0, tk.END)  # clear entry
    elif key == '->M':
        memory = entry.get()
        # extract the result
        if '=' in memory:
            ix = memory.find('=')
            memory = memory[ix+2:]
        root.title('M=' + memory)
    elif key == 'M->':
        entry.insert(tk.END, memory)
    elif key == 'neg':
        if '=' in entry.get():
            entry.delete(0, tk.END)
        try:
            if entry.get()[0] == '-':
                entry.delete(0)
            else:
                entry.insert(0, '-')
        except IndexError:
            pass
    else:
        # previous calculation has been done, clear entry
        if '=' in entry.get():
            entry.delete(0, tk.END)
        entry.insert(tk.END, key)

root = tk.Tk()
root.title("Simple Calculator")

btn_list = [
'7',  '8',  '9',  '*',  'C',
'4',  '5',  '6',  '/',  'M->',
'1',  '2',  '3',  '-',  '->M',
'0',  '.',  '=',  '+',  'neg' ]

# create all buttons with a loop
r = 1
c = 0
for b in btn_list:
    rel = 'ridge'
    cmd = lambda x=b: click(x)
    tk.Button(root,text=b,width=5,relief=rel,command=cmd).grid(row=r,column=c)
    c += 1
    if c > 4:
        c = 0
        r += 1

# use Entry widget for an editable display
entry = tk.Entry(root, width=33, bg="yellow")
entry.grid(row=0, column=0, columnspan=5)

root.mainloop()

Simplified the code by creating all the buttons in a loop. Hope you can still follow the flow.

BTW, this is a tiny calculator using a small footprint and short code. You can add more features, but then it wouldn't be a tiny calculator any longer. So, go ahead and improve it and change it to a scientific calculator.

Edited 5 Years Ago by vegaseat: n/a

Would you know how to do that using the Tkinter buttons? Is using self a bad thing when dealing with the buttons.


Editor's note: Sorry, put that into the wrong post!
BTW, this is a tiny calculator using a small footprint and short code. You can add more features, but then it wouldn't be a tiny calculator any longer. So, go ahead and improve it and change it to a scientific calculator.

Edited 5 Years Ago by vegaseat: improve

Of course it could be considered user responsibility, but I do not personally like that the calculator does not allow to continue from result and saves formula to memory instead of evaluating the result automatically.

For example:
10/3 M-> = result: 3.333333
* M<- =
result: *10/3.0first char not in -+0123456789.--> Error!

1/3=*3
result: *3first char not in -+0123456789.--> Error!

Edited 6 Years Ago by pyTony: n/a

how would you insert square root calculation in this program? I am trying
elif key == 'sqrt':
a = eval(entry.get())
entry.insert(tk.END, "=" + str(math.sqrt(a))
but of cours it's not working. Any ideas, please?

Ah, the power of the eval() function. With this tiny calculator you can easily find the square-root as long as you remember that the square-root of x is simply x to the power 1/2.

So, to find the square-root of 2 simply enter 2**0.5=

Edited 5 Years Ago by vegaseat: n/a

elif key == 'sqrt':
result = math.sqrt(eval(entry.get()))
entry.insert(END,"√= "+str(result))
this is it. it works for sqrt.

import Tkinter as tk
from Tkinter import *
import tkMessageBox
root = Tk()
buttons = {}
signVal = ''
firstVal = 1
root.title('Calculator')
root.attributes("-toolwindow", 1)

def createNumbers():
    global buttons
    buttonNum = 0

    for b in range( 2 ):
        for b2 in range( 5 ):
            button = Button(frame2, text = buttonNum, font = "Courier 9", width = 5, bd = 3 )
            button.grid(row=b, column=b2)
            buttons[ button ] = buttonNum
            buttonNum += 1
            button.bind( "<Button-1>", makeChoice )


def operators():
    button = Button(frame2, text = '+', font = "Courier 9", width = 5, bd = 3, command = lambda : operation('+') )
    button.grid(row=2, column=0)
    button = Button(frame2, text = '-', font = "Courier 9", width = 5, bd = 3, command = lambda : operation('-') )
    button.grid(row=2, column=1)
    button = Button(frame2, text = '*', font = "Courier 9", width = 5, bd = 3, command = lambda : operation('*') )
    button.grid(row=2, column=2)
    button = Button(frame2, text = '/', font = "Courier 9", width = 5, bd = 3, command = lambda : operation('/') )
    button.grid(row=2, column=3)
    button = Button(frame2, text = '=', font = "Courier 9", width = 5, bd = 3, command = lambda : excutionPart('=') )
    button.grid(row=2, column=4)
    button = Button(frame2, text = 'Clear', font = "Courier 9", width = 5, bd = 3, command = lambda : clearAll('clear') )
    button.grid(row=3, column=0)

def makeChoice( event ):
    global buttons    
    if (v.get() is None) or (len(v.get()) == 0):
       v.set(buttons[ event.widget ])       
    else:
        v.set(str(v.get())+str(buttons[ event.widget ]))

def operation(value):
    try:        
        global signVal
        global firstVal
        signVal = value
        if not isinstance(v.get(), int):
            firstVal = int(v.get())
        else:
            tkMessageBox.showerror("Error","Wrong Formate")
        print "First Value :", firstVal
        v.set('')
    except TypeError:
        tkMessageBox.showerror("Error","Wrong Formate")


def excutionPart(ex):
    print "Second Value :", str(v.get())
    if signVal is '+':
        v.set(int(firstVal)+int(v.get()))
    elif signVal is '-':
        v.set(int(firstVal)-int(v.get()))
    elif signVal is '*':
        v.set(int(firstVal)*int(v.get()))
    elif signVal is '/':
        v.set(int(firstVal)/int(v.get()))
    else:
        v.set('')
    print "Result is :", str(v.get())

def clearAll(val):
    v.set('')


#Top Frame 
frame1 = Frame(root)
frame1.pack(side = TOP)

#Bottom Frame 
frame2 = Frame(root)
frame2.pack(side = BOTTOM)

v = StringVar()
e = Entry(frame1, textvariable=v, width = 30)
e.pack(side = LEFT)



createNumbers()
operators()

root.mainloop()

Heading Here

Python Calculator Program

If i wanted to change this so that when i click = on the calculator it displayed the result in the box like '1 + 1 = 2' how would i go about doing this?

is it possible to adjust something in the code so that it becomes a reverse polish notation calculator? Or does anyone know the coding for one of those?

Here is a simple reverse polish calculator ...

''' calculator_reverse_polish.py
a simple calculator using a switch/case approach and lambda
'''

def do_operation(op, a, b):
    """
    arguments are in reverse polish notation order
    a dictionary combined with the lambda inline 
    function acts like C switch/case
    """
    return {'+': lambda: a + b,
            '-': lambda: a - b,
            '*': lambda: a * b,
            '/': lambda: 1.0*a / b  # Python 2 compromise
           }[op]()


print(do_operation('+', 3, 6))  # 9
print(do_operation('/', 3, 6))  # 0.5
print(do_operation('*', 3, 6))  # 18
print(do_operation('-', 3, 6))  # -3

The eval() function wouldn't like the notation.

is it possible to have a same code of your python calculator? this is the 1st time i saw a situation like this

The article starter has earned a lot of community kudos, and such articles offer a bounty for quality replies.