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.
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
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()))
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").
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)
Y asi queda nuestro codigazo, cualquier otra duda con mucho gusto.
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 = ""
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
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)
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")
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
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!.
0 Comentarios
Comenta lo que gustes y necesites, estare muy feliz de leerte, GRACIAS.