Codigo para hacer una calculadora en python

Codigo para hacer una calculadora en python

Crear una calculadora en Python en 3
sencillos pasos no es tan difícil si se usa un código limpio, la mejor
forma es hacerla paso a paso para evitar los errores de sintaxis al
ejecutar el programa, el código que les compartiré es el más limpio que hay,
con limpio me refiero a que no incluye cosas extra como librerías
avanzadas que les impediría entender que hace cada parte del código,
además si al final quieren incluirle algo para personalizarlo pueden
hacerlo a gusto posteriormente, este código es la base para cualquier
calculadora en Python y funciona para cualquier IDE como Pycharm,
Sublimetext y Visual studio code, entre otros.






Geolocalización y Mapas con Python – Blog Europeanvalley

Importando la librería Tkinter



Para hacer la interfaz gráfica necesaria para la ventana, colocar los
botones y el campo donde visualizaremos los números vamos a usar
Tkinter, ya viene incluida en la instalación de Python(no importa el
IDE), para importarla solo necesitamos colocar en un documento nuevo lo
siguiente:




from tkinter import*




Tras esto ya podemos crear todo el código pero entendamos primero los pasos que haremos.




1 Crearemos una ventana.


2 Haremos todos los botones que contendrá la ventana incluyendo números,
botones con operadores como el de suma, resta, división, multiplicación
y el botón de igual para hacer el cálculo, en cada botón pasaremos un
comando para identificarlo.


3 Procesaremos los datos porque una cosa es hacer los botones y otra
cosa es darles funcionamiento, este tercer paso no es tan difícil como
parece se hace con una sola función llamada eval, ¡empecemos!.




Creando la ventana en Tkinter





La ventana se hace con la función TK() le tenemos que dar un nombre a la
variable de esta ventana y ningún nombre más clásico que ventana,
pueden ponerle el que gusten posteriormente pero por ahora recomiendo no
cambiar cosas porque luego puede no funcionarles si olvidan cambiarlo
en todos los sitios que aparece.




if __name__ == "__main__":

ventana = Tk()



ventana.configure(background="light green")

ventana.title("Codigazo calculator V1.0")

ventana.geometry("265x125")

ventana.mainloop()




Como pueden ver además de crear la ventana con la función tk incluí
varios parámetros extra llamados métodos, el primero es configure
donde le asigné un color al background esto es al fondo de la ventana,
pueden usar otros colores como gray, yellow, blue, red, green y asi
sucesivamente, con el método title como su nombre lo
indica coloqué entre comillas el nombre que tendrá la ventana, este es
el nombre visible de nuestro programa, el nombre también pueden
cambiarlo, y es que al final la parte grafica de los programas o
aplicaciones es muy importante
para que el usuario se sienta cómodo o perciba que está haciendo uso de
una aplicación seria, el método geometry básicamente sirve para dar el
tamaño en medida de pixeles a la ventana, tanto su altura como su
anchura, también pueden jugar con estos parámetros, al final le aplique a
la ventana una llamada a la funcion mainloop(), sin
esto el programa si se ejecutará pero se cerraría de inmediato tan
pronto como lee el código, como su nombre lo indica mainloop sirve para
crear un loop es decir un bucle que se repite una y otra vez pasando por
este código así evitaremos que nuestro programa se cierre hasta que
cerremos la ventana manualmente.




Agreguemos tres sencillas líneas de código mas que servirán para crear
un campo de tipo Entry, estos son campos donde se puede ver y escribir
texto.




    calculo = StringVar()

datos = Entry(ventana, textvariable=calculo)

datos.grid(columnspan=10, ipadx=50)




En el código anterior la primer línea crea una variable llamada calculo,
la segunda línea crea el campo llamado datos que es donde veremos los
números y las operaciones y la tercer línea le da una ubicación con su
anchura definida usando el método grid,¿fácil verdad?.




Creando los botones de la calculadora





Boton 1 para la calculadora




Se crea un controlador de tipo button yo le llamare al primero boton1 el
primer valor a pasar es el nombre de la ventana a la que pertenecerá,
¿recuerdan que le habíamos puesto el nombre ventana?, bien pues ese
usaremos, el segundo parámetro llamado text este incluirá el texto que
veremos en el botón como estamos haciendo el botón con el numero 1 ese
es el texto que incluimos, cuando hagamos el de igual incluiremos el
símbolo = y así con cada uno, el tercer parámetro llamado fg que
significa foreground sirve para colocar el color de frente
en otras palabras el del texto, en este caso será negro y bg significa
background para el color de fondo que será blanco, el siguiente
parámetro es importante en el command utilizaremos lambda que es un tipo
de expresión que nos permite pasar distintos parámetros a una sola
función, a la función le llamaré digito e incluirá el numero 1, para
finalizar height es la altura y width es la anchura en pixeles.




    boton1 = Button(ventana, text=' 1 ', fg='black', bg='white',

command=lambda: digito(1), height=1, width=7)




Espero que no intentaran todavía ejecutar lo anterior porque de ser así
aunque si verán la ventana les lanzara errores por cuanto no hemos
creado todavía la función digito(), pero si ya entendieron el código
anterior solo queda crear los otros botones repitiendo el código
anterior y se ve de la siguiente forma (todos los botones juntos).




    boton1 = Button(ventana, text=' 1 ', fg='black', bg='white',

command=lambda: digito(1), height=2, width=5)

boton1.grid(row=2, column=0)



boton2 = Button(ventana, text=' 2 ', fg='black', bg='white',

command=lambda: digito(2), height=2, width=5)

boton2.grid(row=2, column=1)



boton3 = Button(ventana, text=' 3 ', fg='black', bg='white',

command=lambda: digito(3), height=2, width=5)

boton3.grid(row=2, column=2)



boton4 = Button(ventana, text=' 4 ', fg='black', bg='white',

command=lambda: digito(4), height=2, width=5)

boton4.grid(row=3, column=0)



boton5 = Button(ventana, text=' 5 ', fg='black', bg='white',

command=lambda: digito(5), height=2, width=5)

boton5.grid(row=3, column=1)



boton6 = Button(ventana, text=' 6 ', fg='black', bg='white',

command=lambda: digito(6), height=2, width=5)

boton6.grid(row=3, column=2)



boton7 = Button(ventana, text=' 7 ', fg='black', bg='white',

command=lambda: digito(7), height=2, width=5)

boton7.grid(row=4, column=0)



boton8 = Button(ventana, text=' 8 ', fg='black', bg='white',

command=lambda: digito(8), height=2, width=5)

boton8.grid(row=4, column=1)



boton9 = Button(ventana, text=' 9 ', fg='black', bg='white',

command=lambda: digito(9), height=2, width=5)

boton9.grid(row=4, column=2)



boton0 = Button(ventana, text=' 0 ', fg='black', bg='white',

command=lambda: digito(0), height=2, width=5)

boton0.grid(row=5, column=0)



suma = Button(ventana, text=' + ', fg='black', bg='white',

command=lambda: digito("+"), height=2, width=5)

suma.grid(row=2, column=3)



resta = Button(ventana, text=' - ', fg='black', bg='white',

command=lambda: digito("-"), height=2, width=5)

resta.grid(row=3, column=3)



multiplica = Button(ventana, text=' * ', fg='black', bg='white',

command=lambda: digito("*"), height=2, width=5)

multiplica.grid(row=4, column=3)



divide = Button(ventana, text=' / ', fg='black', bg='white',

command=lambda: digito("/"), height=2, width=5)

divide.grid(row=5, column=3)



resultado = Button(ventana, text=' = ', fg='black', bg='white',

command=igual, height=2, width=5)

resultado.grid(row=5, column=2)



limpiar = Button(ventana, text='Limpiar', fg='black', bg='white',

command=limpiar, height=2, width=5)

limpiar.grid(row=5, column='1')




Funciones para la calculadora





Este es todo el código grafico ahora solo queda crear 3 funciones que
atienden al punto número 3 es decir el de procesamiento de datos, para
decirlo de otra forma es el código que se encarga de hacer las
operaciones típicas de una calculadora.




def digito(num):

global boton

boton = boton + str(num)

calculo.set(boton)

def igual():

try:

global boton

total = str(eval(boton))

calculo.set(total)

boton = ""

except:

calculo.set(" error ")

def limpiar():

calculo.set("")




La función digito sirve para guardar toda la expresión matemática por
ejemplo "8+4+5*20/2", digito lo guardará y de inmediato lo mostrara el
campo de datos que habíamos creado haciendo uso del método set en la
variable calculo, limpiar hace algo similar nada más que en lugar de
enviar dígitos reemplaza el texto existente por un valor vacío, y la
función igual procesa todo con la función matemática eval() como es de
esperar evaluando la expresión y mostrando el resultado.




Ahora si pueden ejecutarlo y verificar que todo esté en orden, ya tienen su primer calculadora en Python
y a partir de ahí pueden ampliarle funciones o cambiarle el diseño, que
de hecho a mi parecer este diseño no es muy bueno por lo básico que es,
a continuación va el código entero por si confundieron algún paso.




from tkinter import *



boton = ""





def digito(num):



global boton

boton = boton + str(num)

calculo.set(boton)





def igual():



try:

global boton

total = str(eval(boton))

calculo.set(total)

boton = ""



except:



calculo.set(" error ")



def limpiar():

calculo.set("")





if __name__ == "__main__":



ventana = Tk()





ventana.configure(background="light blue")

ventana.title("Codigazo Calculator")

ventana.geometry("195x183")





calculo = StringVar()

datos = Entry(ventana, textvariable=calculo)

datos.grid(columnspan=10, ipadx=50)









boton1 = Button(ventana, text=' 1 ', fg='black', bg='white',

command=lambda: digito(1), height=2, width=5)

boton1.grid(row=2, column=0)



boton2 = Button(ventana, text=' 2 ', fg='black', bg='white',

command=lambda: digito(2), height=2, width=5)

boton2.grid(row=2, column=1)



boton3 = Button(ventana, text=' 3 ', fg='black', bg='white',

command=lambda: digito(3), height=2, width=5)

boton3.grid(row=2, column=2)



boton4 = Button(ventana, text=' 4 ', fg='black', bg='white',

command=lambda: digito(4), height=2, width=5)

boton4.grid(row=3, column=0)



boton5 = Button(ventana, text=' 5 ', fg='black', bg='white',

command=lambda: digito(5), height=2, width=5)

boton5.grid(row=3, column=1)



boton6 = Button(ventana, text=' 6 ', fg='black', bg='white',

command=lambda: digito(6), height=2, width=5)

boton6.grid(row=3, column=2)



boton7 = Button(ventana, text=' 7 ', fg='black', bg='white',

command=lambda: digito(7), height=2, width=5)

boton7.grid(row=4, column=0)



boton8 = Button(ventana, text=' 8 ', fg='black', bg='white',

command=lambda: digito(8), height=2, width=5)

boton8.grid(row=4, column=1)



boton9 = Button(ventana, text=' 9 ', fg='black', bg='white',

command=lambda: digito(9), height=2, width=5)

boton9.grid(row=4, column=2)



boton0 = Button(ventana, text=' 0 ', fg='black', bg='white',

command=lambda: digito(0), height=2, width=5)

boton0.grid(row=5, column=0)



suma = Button(ventana, text=' + ', fg='black', bg='white',

command=lambda: digito("+"), height=2, width=5)

suma.grid(row=2, column=3)



resta = Button(ventana, text=' - ', fg='black', bg='white',

command=lambda: digito("-"), height=2, width=5)

resta.grid(row=3, column=3)



multiplica = Button(ventana, text=' * ', fg='black', bg='white',

command=lambda: digito("*"), height=2, width=5)

multiplica.grid(row=4, column=3)



divide = Button(ventana, text=' / ', fg='black', bg='white',

command=lambda: digito("/"), height=2, width=5)

divide.grid(row=5, column=3)



resultado = Button(ventana, text=' = ', fg='black', bg='white',

command=igual, height=2, width=5)

resultado.grid(row=5, column=2)



limpiar = Button(ventana, text='Limpiar', fg='black', bg='white',

command=limpiar, height=2, width=5)

limpiar.grid(row=5, column='1')





ventana.mainloop()




Capturar numeros desde el teclado





En la programación muy poco está hecho, la mayoría hay que ir
haciéndolo, con el código anterior pueden utilizar la calculadora pero
si presionan la tecla enter(intro) para obtener el resultado no
obtendrán esultado, además apenas abren la calculadora es necesario que
den click en el campo input para empezar a escribir los dígitos con el
teclado, porque si intentan digitar sin haber dado click en dicho campo
simplemente no captará los números, esto se debe a que en verdad la ventana entera ha de capturar los eventos del teclado,
con el siguiente código les enseño como capturar los eventos del
teclado para que sea el usuario quien decida como utilizará su
calculadora pues es muy molesto tener una calculadora donde es necesario
clickar el botón "=" en lugar de usar la tecla intro.




Debajo de la función limpiar y no dentro añadimos la siguiente función




def teclado(event):



digito(event.char)




La función la llamaremos teclado y capturará los eventos que se enviaran
desde la llamada, a su vez esta función hace una llamada a la función
digito(), y dentro de esta función enviamos los datos contenidos en
event.char,
char es el método que sirve para indicar que lo que queremos enviar es
el carácter del objeto event. Muy bien ahora hagamos la llamada a esta
función cada vez que se presione una tecla, esto con ayuda del método
bind contenido en el objeto de nuestra ventana agregando una línea de
código casi al final del código, justo antes de la última línea que dice
ventana.mainloop(), el código es este.




ventana.bind("<Key>",teclado)




Como iba diciendo bind es el objeto al cual le decimos que capture
"<Key>" es decir cualquier key(tecla), y que cuando lo haga añada
una llamada a la función que creamos anteriormente llamada "teclado",
con esto ya no es necesario clicar primero en el campo input antes de
digitar los números, pero todavía tenemos que ligar la tecla enter a la
función igual() que es para obtener el resultado y así nuestra tecla
enter será como clicar en "=", como ya la función igual() existe no
tenemos que crear más funciones solo tenemos que detectar cuando se
presione la tecla enter y llamar esta vez a la función teclado, la
siguiente línea de código nos permite hacer esto, solo asegúrese
incluirla justo antes de la sentencia anterior , es decir antes de
ventana.bind("<Key>",teclado)




ventana.bind("<Return>", (lambda event: igual()))




Comentarios y preguntas




felipe:


Si quisiera que la calculadora tuviera para colocarle paréntesis para
encerrar expresiones y un punto para señalar que el numero es un float
como lo hago?




Codigazo:


Para colocar un punto creamos otro botón definiendo su nombre y en el
campo "text" colocamos un punto, como en el siguiente código:



    punto = Button(ventana, text='.', fg='black', bg='white',



command=lambda: digito("."), height=2, width=5)



punto.grid(row=6, column=0)




Ese código podemos colocarlo debajo del botón limpiar pero pese a que
nuestra ventana tiene una altura máxima de 183px es obvio que para poder
ver el botón tendríamos que agrandar con el mouse la ventana de nuestra
calculadora y esto es muy feo así que agrandamos su tamaño modificando
la sentencia ventana.geometry("195x183") por
ventana.geometry("195x225").



Calculadora con punto para números decimales en Python



Con el tema de parentesis hacemos lo mismo:



    parentesis1 = Button(ventana, text='(', fg='black', bg='white',



command=lambda: digito("("), height=2, width=5)



parentesis1 .grid(row=6, column=1)



parentesis2 = Button(ventana, text=')', fg='black', bg='white',



command=lambda: digito(")"), height=2, width=5)



parentesis2 .grid(row=6, column=2)




Calculadora con paréntesis de agrupación hecha en Python



Y asi queda nuestro codigazo, cualquier otra duda con mucho gusto.




peter:


hola




Emmanuel :


Hola a mi me da el error en except eso me señala




Codigazo:


Hola Emmanuel, ¿error en exept?, me imagino que se refiere que le
aparece la palabra error al clicar el igual, de ser así esto se debía
que previamente a clicar el botón igual usted intentó presionando enter y
al ver que no salía el resultado dio click en "=", acabo de añadir un
código que permite capturar los números y otros eventos del teclado en
nuestra calculadora, lea esa parte final, actualice su código y verá que
ahora todo está bien.




Adri:


Hola, como podría evitar que en la calculadora se pueda dividir entre 0?




Codigazo:


Hola adri, de hecho con el código anterior no se puede dividir entre
cero, si lo intenta le lanzará un error, pero si gusta se puede
personalizar este mensaje de error para que nos aparezca un mensaje como
el de la calculadora de Windows que dice "No se puede dividir entre
cero".



Para lograr esto tenemos que buscar la expresión "/0" dentro del calculo
que ingresa el usuario por ejemplo "9/0" tiene "/0" así sabremos que se
intenta dividir entre cero, para hacer esta comparación de la cadena
con nuestra expresión necesitamos utilizar el módulo re, este suele
incluirse de forma automática, pero si por algún motivo tras utilizar el
código que viene a continuación le lanza un error, coloque en el inicio
del código la instrucción "import re", mas como acabo de mencionar no
debería de ser necesario.



Solo necesitamos hacer 1 modificación, busque ya mismo en el código la
función "def igual()" una vez la encuentre modifique el código:



def igual():

try:

global boton

total = str(eval(boton))

calculo.set(total)

boton = ""




Cambiándolo por el siguiente:



def igual():

try:

global boton

cero = re.search("/0", boton, )

if cero:

calculo.set(" No se puede dividir entre cero ")

else:

total = str(eval(boton))

calculo.set(total)

boton = ""




eliana:


Hola como hago para que la calculadora pueda manejar decimales?




Codigazo:


Hola Eliana, en verdad la calculadora ya puede utilizar decimales,
pruebe con el teclado numérico y comprobará que puede por ejemplo hacer
esto 8.5+1.2 le dará un resultado en decimales, esta es una de las
ventajas de Python que no tenemos que cambiar el tipo de datos de las
variables, sino que esto lo hace de forma automática el intérprete.



Si se refiere a que desea ver un botón de punto en la calculadora
entonces con 3 sencillas líneas puede crear este botón con el siguiente
código



punto = Button(ventana, text=' . ', fg='black', bg='white',

command=lambda: digito("."), height=2, width=5)

punto.grid(row=6, column=0)






El problema es que el tamaño de la ventana hace que tengamos que alargar
el borde inferior de la calculadora con el mouse para poder ver el
botón de punto, así es que para cambiar el tamaño de forma permanente
nos vamos arriba donde dice



 ventana.geometry("195x183")




y lo cambiamos por



 ventana.geometry("195x224")




Ya está todo hecho y se ve de la siguiente forma



Añadiendo decimales a nuestra calculadora



Aunque visualmente no se ve muy bien ese espacio vacío, ¿verdad?

mi propuesta es que al igual como se hace en muchas calculadoras físicas
hagamos también en esta calculadora virtual, alarguemos el botón de ”=”
, algunos alargan el número 0, entonces primero cambiemos la
localización del botón "." donde está el igual y bajemos la localización
del botón igual, para esto no es necesario cambiar de posición del
código, es necesario editar la posición de los botones buscando la línea




punto.grid(row=6, column=0)




Cambiarla por



punto.grid(row=5, column=2)




Así también buscar la sentencia



resultado.grid(row=6, column=0)




Para cambiarla por



resultado.grid(column=0, columnspan=4, ipadx=74)




Añadimos ahora punto o coma





katherine:


hola,como deja en logaritmos naturles y dejan sus todos resultados en notaciones cientificas.




Codigazo:


Hola katherine!, a la verdad me cuesta entender lo que escribió, ¿desea
que la calculadora sea capaz de calcular los algoritmos naturales de
algún numero?.



De ser así entonces, es sencillo calcular los logaritmos con ayuda de la
función log contenida dentro de la librería math empecemos importando
esta librería agregando arriba (apenas empieza el código) esta linea.



import math




Agregamos también una nueva función antes de la función igual con el siguiente código



def logaritmo():

try:

global boton

total = str(math.log(eval(boton)))

calculo.set(total)

boton = ""



except:

calculo.set(" error ")




Ahora solo queda cambiar alguna que otra linea, busque y reemplace en el código original, la linea:



punto.grid(row=6, column=0)




Reemplace por:



punto.grid(row=5, column=2)




Busque



resultado.grid(row=6, column=0)




Reemplace por



resultado.grid(column=0, columnspan=4, ipadx=74)




Tambien



ventana.geometry("195x183")




y reemplaza con



ventana.geometry("195x224")




Mauro:


seguramente que para realizar eso tengo que almacenar el resultado
obtenido en una variable pero una vez que lo tengo almacenado no se como
utilizarlo para seguir realizando calculos




Mauro:


hola como puedo agregarle el boton c de una calculadora normal es el que
resetea la pantalla porque la tecla limpiar me la resetea solo después
de apretar el igual y otra cosita se podrá de alguna manera almacenar el
valor en pantalla para después con el realizar otra operación por
ejemplo de una operación obtuve el resultado 5 si ahora le quiero restar
3 quisiera que con solo apretar resta 3 me lo reste. gracias




Codigazo:


hola Mauro, Si gusta le cambia la palabra Limpiar por C, en cuanto al
funcionamiento para que pueda borrar tanto si se ha presionado el igual o
si no se ha presionado lo que tenemos que hacer es añadir 2 líneas a la
función limpiar(), así es que busque esta función



def limpiar():

calculo.set("")




Y cambiela por



def limpiar():

global boton

calculo.set("")

boton = ''




Pasando a la parte de almacenar el resultado del cálculo, efectivamente
su modo de pensar que el cálculo ha de almacenarse en una variable es
correcto, pero de hecho ya se almacena en una, esta es la variable
total, para no complicar la explicación observe que en la función
igual() al final después de calcularse y mostrarse en el campo input la
operación que se ha añadido tras presionar cada número en la variable
botón se borra al utilizar esta sentencia



boton = ''




Si elimina esa sentencia podrá ver que ya puede sumar pero cada vez que
agrega un operador como "+,-,*..." volverá a ver toda la operación, así
es que para evitar esto haga lo siguiente



boton = total




Con eso queda tal y como lo desea, disculpe por haber tardado un poco más de lo habitual en responderle




felipe:


hola, como podria hacer que los resultadoslos de en notación cientifica?




Codigazo:


Hola felipe!, aunque tal emprendimiento parece muy difícil al utilizar
un par de palabras reservadas para formato se nos hace muy sencillo



Lo primero que ha de hacer es agrandar el tamaño de la ventana como en
la respuesta que le di a Eliana, luego de eso tendrá que crear un botón
puede ser con este código



    notacion = Button(ventana, text=' NC ', fg='black', bg='white',

command=notacionc, height=2, width=5)

notacion.grid(row=6, column=0)




Y para finalizar solo ha de crear la funcion llamada "notacionc"



def notacionc():



global boton

s='{:.2e}'.format(int(boton)).replace(".00e+", "*10^")

calculo.set(str(s))

boton = ""




Yo la he añadido justo debajo de la función limpiar compruebe por usted
mismo que todos los resultados quedan en notación científica al
presionar dicho botón, del tipo "500 000 000 000 000" quedará "5*10^14",
cualquier otra pregunta ¡quedo atento!.

Publicar un comentario

0 Comentarios