¿De qué va este proyecto?
Este proyecto final va a ser complicado; sé que para quienes están aprendiendo programación será una tarea ardua. Sin embargo, es necesario que salgas de tu zona de confort. Está muy bien conocer todos los elementos básicos de programación, pero debes saber utilizarlos en proyectos prácticos que se acerquen más al desarrollo real de software. Si te resulta muy denso para resolver de una sola vez, ve haciéndolo en diferentes días.
Espacio publicitario
¿Cómo está estructurado el proyecto?
El proyecto final estará dividido en varias secciones con múltiples apartados, con el fin de que sea más sencillo completarlo. En cada fase o sección, construiremos una parte del programa final. Siempre intenta resolver cada parte por tu cuenta. No te rindas fácilmente, pero si no puedes completarla, consulta la solución. A partir de ella, podrás comenzar con la siguiente parte y habrás aprendido algo nuevo.
Para completar todas las secciones de este proyecto, deberás demostrar que has adquirido todos los conocimientos enseñados a lo largo del curso y que sabes utilizarlos cuando se te solicita.
¿De qué trata el proyecto exactamente?
El proyecto consistirá en crear una calculadora con las cuatro operaciones aritméticas básicas y algunas más. Esta calculadora será de consola, ya que aún no has aprendido a crear interfaces gráficas (programas de ventana). Aunque esta calculadora funcione en consola, la lógica de programación es la misma. Más adelante, podrás aprender a manejar una biblioteca como Tkinter o PyQt5 para migrarla a una ventana con botones, si eso es lo que deseas.
A pesar de no tener una interfaz gráfica, esta calculadora tendrá un menú de opciones en la consola, similar a los programas antiguos que ofrecían opciones en modo texto.
Libertad y creatividad ante todo
En general, cada apartado es libre en cuanto a la forma de
completarlo. Si no te indico algo específico, puedes
resolver las fases como prefieras. Por ejemplo, puede que
yo utilice un condicional match
en un
apartado, y tú hayas preferido hacerlo con un
if
.
Si tu código cumple los requisitos exigidos, da igual como lo hagas. No quiero que te fijes absolutamente en hacerlo lo más óptimo posible, si no, en que lo completes. La perfección irá llegando con la experiencia, no la busques todavía.
Esto lo indico porque en programación hay muchas posibles soluciones para un mismo problema. Hay unas más cortas que otras, unas más óptimas que otras, pero cuando empiezas a programar, lo primordial es aprender a hacer las cosas, ya habrá tiempo de mejorar tu técnica.
Sección 1: Creación de la interfaz
1.1 - Creando el menú de opciones estático
La primera parte del proyecto consiste en que crees una interfaz de usuario en la consola. Esta interfaz será un sencillo menú con todas las opciones de la calculadora. Lo que tienes que incluir en el menú, son las siguientes cosas:
- Título de la calculadora
-
Opciones:
- Suma
- Resta
- Multiplicación
- División
- Módulo
- Potencia
- Salir
- Aviso: Debes introducir una opción.
De momento, este menú será estático, es decir, una serie de texto mostrado en la consola, que no hará nada.
No te compliques, simplemente utiliza la función
print()
para mostrar todo esto en la consola.
Todavía no utilices la entrada de datos, esto será en la siguiente sección del proyecto.
La solución a esta parte del proyecto, es crear un
menú a base de print()
.
Con un elemento por línea, podemos definir cada una de las opciones que podrá elegir el usuario. De momento, son solo opciones informativas; aún no llevan la lógica para ejecutarlas.
# Título de la calculadora
print("Calculadora con Python")
# Menú de la calculadora
print("1. Suma")
print("2. Resta")
print("3. Multiplicación")
print("4. División")
print("5. Módulo")
print("6. Potencia")
print("7. Salir")
# Aviso para que se seleccione una opción
print("Seleccione una opción: ")
Calculadora con Python
1. Suma
2. Resta
3. Multiplicación
4. División
5. Módulo
6. Potencia
7. Salir
Seleccione una opción:
1.2 - Entrada de datos del usuario
Después de tener el menú creado, es el momento de añadir una entrada de datos en el programa. Esta entrada de datos, estará diseñada para que el usuario ponga una de las opciones del menú.
En el código, cambia esta parte del print()
,
por la entrada de datos:
# Aviso para que se seleccione una opción
print("Seleccione una opción: ")
La solución a este apartado es tan simple como
sustituir el print()
, que avisa para
introducir una opción, por un input()
,
que hace lo mismo, pero además permite introducir y
almacenar un valor en una variable:
# Título de la calculadora
print("Calculadora con Python")
# Menú de la calculadora
print("1. Suma")
print("2. Resta")
print("3. Multiplicación")
print("4. División")
print("5. Módulo")
print("6. Potencia")
print("7. Salir")
# Entrada de opción para el usuario
opcion = int(input("Seleccione una opción: "))
Calculadora con Python
1. Suma
2. Resta
3. Multiplicación
4. División
5. Módulo
6. Potencia
7. Salir
Seleccione una opción: (Aquí deja introducir un valor)
La entrada la he puesto con una conversión a
int()
. Esto es opcional, puesto que dependerá de cómo construyes el condicional del siguiente apartado, basándose en si este manejastr
oint
para las opciones.
1.3 - Condicional para llamar a las funciones
Lo siguiente que quiero que hagas es crear un condicional
if
o match
que evalúe las
posibles opciones puestas por el usuario. Cada opción de
este condicional llamará a la función correspondiente.
Cada función ejecutará el código necesario para hacer los
cálculos de la calculadora.
Por el momento, no quiero que añadas estas llamadas a las funciones, ya que todavía no las tenemos creadas. Solo quiero que apliques la condición necesaria para cada una de las opciones. Es decir, un bloque de código con una condición para cada opción del menú.
Piensa en contemplar una posible opción por si el usuario pone un número de opción inexistente, por ejemplo, opción 15.
En Python no se permite dejar estructuras con bloques de código vacíos. Mientras no tengamos nada que escribir en ellos (como es el caso de este ejercicio), tendrás que utilizar la palabra reservada
pass
.
A continuación tienes un ejemplo de uso en pseudocódigo. Tan solo, tendrás que saber aplicarla a lo que te pido en esta sección:
if condición:
pass
else:
pass
En el contexto de la programación Python, la palabra pass se puede traducir al español como “pasar” u “omitir”.
En este caso, es correcto utilizar un condicional
if-elif-else
o un condicional
match
.
Para este caso concreto, prefiero la segunda opción,
ya que las opciones de un menú, son algo bastante
repetitivo, y es más claro y conciso con un
condicional match
.
# Título de la calculadora
print("Calculadora con Python")
# Menú de la calculadora
print("1. Suma")
print("2. Resta")
print("3. Multiplicación")
print("4. División")
print("5. Módulo")
print("6. Potencia")
print("7. Salir")
# Entrada de opción para el usuario
opcion = int(input("Seleccione una opción: "))
# Condicional para llamar a cada función del menú
match opcion:
case 1:
# Suma
pass
case 2:
# Resta
pass
case 3:
# Multiplicación
pass
case 4:
# División
pass
case 5:
# Módulo
pass
case 6:
# Potencia
pass
case 7:
# Salir
pass
case _:
# Opción inválida
pass
Si has hecho este menú con el condicional
if
, será algo así:
if opcion == 1:
# Suma
pass
elif opcion == 2:
# Resta
pass
elif opcion == 3:
# Multiplicación
pass
elif opcion == 4:
# División
pass
elif opcion == 5:
# Módulo
pass
elif opcion == 6:
# Potencia
pass
elif opcion == 7:
# Salir
pass
else:
# Opción inválida
pass
Recuerda que para que coincidan los valores de cada opción, el valor del
input()
tiene que ajustarse a los datos en las expresiones condicionales.
En cada bloque del condicional se evalúa la opción
escogida por el usuario. Si la opción no está
contemplada, se ejecutará el bloque _
del
condicional match
, o el bloque
else
, si has utilizado
if
para el menú.
Es importante que hayas dejado el pass
en
cada bloque, así evitarás errores por dejar los
bloques de código vacíos.
1.4 - Menú infinito
Lo siguiente que tenemos que hacer, para ir terminando con esta primera parte del proyecto, es envolver la interfaz del usuario creada hasta ahora, con un bucle que repita el menú de forma indefinida.
Ahora mismo, si introduces cualquier valor en la consola, el programa finaliza. No queremos que ocurra eso. Lo que queremos es que si el usuario se equivoca, introduzca de nuevo otro valor. Si lo pone bien, que se llame a la función correspondiente (cuando las tengamos creadas) y luego, le deje utilizar cualquier otra opción, las veces que quiera.
La forma de salir de este bucle, será con la opción 7 (Salir). Deberás hacer funcional esa opción en este mismo ejercicio.
Recuerda que había una palabra especial para “romper” la ejecución del bucle, en un momento determinado.
La resolución de esta tarea, parece complicada en
exceso. Sin embargo, es tan fácil como añadir un bucle
while True
, que haga la ejecución del
código indeterminada (hasta que el usuario decida
salir).
# Interfaz de la calculadora
while True:
# Menú de la calculadora
print("Calculadora con Python")
print("1. Suma")
print("2. Resta")
print("3. Multiplicación")
print("4. División")
print("5. Módulo")
print("6. Potencia")
print("7. Salir")
# Entrada de opción para el usuario
opcion = int(input("Seleccione una opción: "))
# Condicional para llamar a cada función del menú
match opcion:
case 1:
# Suma
pass
case 2:
# Resta
pass
case 3:
# Multiplicación
pass
case 4:
# División
pass
case 5:
# Módulo
pass
case 6:
# Potencia
pass
case 7:
# Salir
break
case _:
# Opción inválida
pass
Con esto, no me malinterpretes, no quiero que pienses que realizar el apartado es fácil. Si no tenías en mente esta solución, puede que se te haya complicado. Es totalmente normal.
Sección 2: Creación de la lógica
Ahora que ya tenemos la interfaz de usuario preparada, ha llegado el momento de entrar en faena con la lógica de la calculadora. Para este proceso, crearemos una función para cada tipo de operación.
2.1 - Funciones para suma, resta, multiplicación y división
Puesto que la lógica de estas cuatro funciones es muy parecida, he decidido agruparla en un apartado.
Lo que tienes que hacer, concretamente, es crear cuatro funciones para estas cuatro operaciones básicas.
Para crear estas funciones, deberás seguir estas normas:
- Las funciones tendrán dos parámetros. Eso quiere decir, que las operaciones serán siempre con dos números.
- Deberás hacer que el resultado de la operación sea devuelto cuando se llame a la función correspondiente.
Por el momento, crea las cuatro funciones, sin llamarlas.
Las puedes colocar encima del código que llevamos hecho
hasta ahora. Antes del while True
.
Las funciones son muy parecidas, de forma que si has sabido hacer una, no habrás tenido dificultades con el resto.
Se trata de darles un par de parámetros para poder
pasarle dos valores, y calcular la operación con un
return
que devuelva el resultado.
Las funciones, las puedes colocar encima del código
anterior, antes del while True
:
# Lógica de la calculadora
# Función de suma
def suma(a, b):
return a + b
# Función de resta
def resta(a, b):
return a - b
# Función de multiplicación
def multiplicacion(a, b):
return a * b
# Función de división
def division(a, b):
return a / b
# Interfaz de la calculadora
while True:
. . .
2.2 - Funcionalidad de módulo
Ha llegado el momento de crear una función algo más difícil, la denominada “módulo”.
La función debe ser capaz de devolver el resto de una división entre dos números.
Esta es la función. Debes colocarla junto con las otras cuatro:
# Función de módulo
def modulo(a, b):
return a % b
2.3 - Funcionalidad de potencia
Ahora, crea la última función, la del cálculo de potencias.
Esta última función igual, colócala junto a las otras.
# Función de potencia
def potencia(a, b):
return a ** b
Sección 3: Asociar la lógica de las funciones a la interfaz de usuario
Ahora que ya tienes una parte en el programa con la lógica, y otra parte con la interfaz de usuario, es el momento de asociar la lógica a dicha interfaz.
Para este propósito, tan solo tienes que llamar a las funciones en cada opción del menú correspondiente.
El problema es que las llamadas deben llevar los dos valores que quiera el usuario, y todavía no tenemos la lógica creada para esto. Lo haremos más adelante. De momento, solo haz las llamadas y les das dos valores cualesquiera, tan solo, para que no te marque errores.
Las llamadas, con el fin de almacenar el resultado, deben estar en una variable. La puedes utilizar de forma general para todas las llamadas. Es decir, puede ser la misma variable para todas las operaciones, ya que solo se ejecutará una operación a la vez.
En cada bloque del condicional, vamos a realizar las
llamadas correspondientes, dentro de una variable
(quita ya los pass
).
Estas llamadas las pongo con un valor
0
en los argumentos, para que no me dé
error. Lo dejaremos así hasta implementar la entrada
de datos para los dos valores (operandos), por parte
del usuario.
# Condicional para llamar a cada función del menú
match opcion:
case 1:
# Suma
resultado = suma(0,0)
case 2:
# Resta
resultado = resta(0,0)
case 3:
# Multiplicación
resultado = multiplicacion(0,0)
case 4:
# División
resultado = division(0,0)
case 5:
# Módulo
resultado = modulo(0,0)
case 6:
# Potencia
resultado = potencia(0,0)
case 7:
# Salir
break
case _:
# Opción inválida
pass
Sección 4: Crea y asocia la lógica de entrada de datos
Probablemente, esta sea la parte más complicada del proyecto. Si no la consigues hacer, tómatelo con mucha calma. Es perfectamente normal. Mira la solución y analízala poco a poco, observando cada parte y reflexionando sobre cómo funciona.
4.1 - Condicional para pedir operandos
Ahora, si te pregunto en qué parte pondrías los
input()
, para pedirle al usuario los dos
números con los que quiere operar, en las llamadas de las
operaciones, ¿qué me responderías?
Este ejercicio trata de eso, de que pienses cómo y dónde colocar la solicitud para el usuario, de los dos valores numéricos para operar.
Puedes utilizar un condicional que contemple si la opción elegida por el usuario está entre 1 y 6. En ese caso, que solicite los números para realizar cualquier operación. De cualquier otra forma, que no se le pidan.
A continuación, tienes un fragmento con la parte modificada del código:
. . .
# Entrada de opción para el usuario
opcion = int(input("Seleccione una opción: "))
# Condicional para evaluar la opción elegida
if opcion >= 1 and opcion <= 6:
numero1 = int(input("Introduzca el primer número para operar:"))
numero2 = int(input("Introduzca el segundo número para operar:"))
match opcion:
case 1:
# Suma
resultado = suma(0,0)
print(resultado)
. . .
He colocado un condicional entre la entrada de opción
para el usuario y el condicional match
.
Primero se está evaluando la opción que ha introducido el usuario.
Con el condicional if
, se evalúa si está
entre el valor 1
y 6
. Si es
así, se le solicitan los datos para operar. En caso de
que sea otro el valor, no se le piden.
Esta acción se hace para evitar pedirle los operandos, si la opción seleccionada no es válida, o quiere salir directamente con la opción 7.
En resumen:
-
Opciones de la 1 a la 6: Se solicitan los
operandos. Luego, se pasa a calcular con ellos en la
operación correspondiente (gracias al
match
). -
Opción 7: No se solicitan los operandos,
porque no se ejecuta el condicional de solicitud de
operandos. Se sale directamente del bucle gracias al
match
, con ese break que tiene en la opción 7. -
Cualquier otro número de opción: No se
solicitan los operandos, porque no se ejecuta el
condicional de solicitud de operandos. Se pasa al
bloque
_
o bloqueelse
(dependiendo del condicional que hayas utilizado para las opciones), y nos avisará de que la opción es inválida (aún no hemos puesto este mensaje).
4.2 - Colocar los operandos en las llamadas
Ahora, tienes que pasar los dos operandos (variable
numero1
y numero2
), a cada
llamada de las funciones del menú.
El programa, después de hacer la llamada a una función, deberá responder en la consola con el resultado de la operación. Entonces, debes poner una frase parecida a esta:
El resultado de la operación es: x
Donde x, irá el resultado de la operación.
. . .
match opcion:
case 1:
# Suma
resultado = suma(numero1,numero2)
print(f"El resultado de la suma es: {resultado}")
case 2:
# Resta
resultado = resta(numero1,numero2)
print(f"El resultado de la resta es: {resultado}")
case 3:
# Multiplicación
resultado = multiplicacion(numero1,numero2)
print(f"El resultado de la multiplicación es: {resultado}")
case 4:
# División
resultado = division(numero1,numero2)
print(f"El resultado de la división es: {resultado}")
case 5:
# Módulo
resultado = modulo(numero1,numero2)
print(f"El resultado de la operación es: {resultado}")
case 6:
# Potencia
resultado = potencia(numero1,numero2)
print(f"El resultado de la operación es: {resultado}")
case 7:
# Salir
break
case _:
# Opción inválida
pass
Aquí tenías que pasar los operandos a las llamadas y formar una frase para mostrar el resultado en la consola.
4.3 - Posicionar las variables
Las variables numero1
y numero2
,
las colocaremos dentro del bucle (si no las tienes ya),
dado que solo se utilizan dentro de él. Así, lo tendremos
todo más organizado.
Colócalas aquí:
. . .
# Interfaz de la calculadora
while True:
# Menú de la calculadora
print("Calculadora con Python")
print("1. Suma")
print("2. Resta")
print("3. Multiplicación")
print("4. División")
print("5. Módulo")
print("6. Potencia")
print("7. Salir")
# Variables para los operandos
numero1 = 0
numero2 = 0
# Entrada de opción para el usuario
opcion = int(input("Seleccione una opción: "))
. . .
El valor 0
, es por poner cualquier valor.
Recuerda que en Python, no se pueden dejar variables sin
inicializar.
En este ejercicio no tienes que resolver nada por tu cuenta, solo sigue las instrucciones.
En este apartado tenías que seguir simplemente las instrucciones del enunciado. No hay nada que resolver.
Sección 5: Última pincelada y pruebas del programa.
5.1 - Mensaje de salida del programa
Como último detalle, quiero que le añadas a la opción de salir, un pequeño mensaje que avise al usuario de que se ha cerrado la calculadora, o una despedida. El mensaje es libre.
La solución es poner un sencillo mensaje en el bloque del condicional, destinado a finalizarlo (opción 7):
case 7:
# Salir
print("¡Hasta la próxima!")
break
Ten en cuenta, que para que salga el
print()
en la consola, debe estar antes
que el break
.
5.2 - Mensaje de opción inválida
También, añade un mensaje cualquiera a la opción inválida.
case _:
# Opción inválida
print("Opción inválida. Vuelva a intentarlo.")
He sustituido el pass
, por este
print()
.
5.3 - Pruebas del programa
Si no tienes quien pruebe los programas por ti, tendrás que aprender a hacerlo por tu cuenta. Parece tarea fácil, pero en programas complejos y grandes, tendrás que tener muchos flancos en cuenta.
Cuando pruebes un programa, deberás probar todo lo que se te ocurra. Las cosas que dejes sin probar, podrían tener fácilmente errores de lógica. Lo que se conoce comúnmente como “bugs”.
Para este apartado, no tendrás que solucionar nada, tan solo tienes que ir probando todo lo que te diga aquí mismo. Si te funciona como a mí, es que lo tienes perfecto.
Además, si se te ocurre alguna prueba extra que no comente, hazla, nunca está de más.
¿Por dónde empezamos?
Primero, ejecutaremos el programa y probaremos una opción numérica no válida:
Seleccione una opción: 15
Opción inválida. Vuelva a intentarlo.
Además, después de este mensaje debería cargarse el menú de nuevo.
Ahora, prueba cada una de las operaciones, de la 1 a la 6.
Si te funcionan todas, prueba también alguna de ellas con valores decimales, si no lo has hecho ya.
¡Vaya! Aparece un fallo. La calculadora no admite valores decimales:
Seleccione una opción: 1
Introduzca el primer número:10.3
ValueError: invalid literal for int() with base 10: '10.3'
Error de valor: literal inválido para la función int() con base 10: '10.3'
En este caso, si no lo has hecho antes, debes modificar la
conversión de tipos de la entrada de operandos, de
int()
, a float()
:
# Condicional para evaluar la opción elegida
if opcion >= 1 and opcion <= 6:
numero1 = float(input("Introduzca el primer número:"))
numero2 = float(input("Introduzca el segundo número:"))
Ahora, prueba de nuevo.
Finalmente, prueba la opción de salida (opción 7):
Seleccione una opción: 7
¡Hasta la próxima!
Esta vez, no se debería cargar el menú de la calculadora; el programa tiene que haber finalizado.
Si de momento vemos que funciona todo, que el bucle indeterminado nos deja ir eligiendo opciones infinitas del menú, y sale cuando queremos, está perfecto.
Los usuarios son impredecibles. No podemos esperar que no
vayan a hacer cosas inesperadas. ¿Qué ocurre si en lugar
de un número, pones una letra en la entrada de datos de
cualquier input()
?
Seleccione una opción: Q
ValueError: invalid literal for int() with base 10: 'Q'
Error de valor: literal no válido para int() con base 10: 'Q'
Este problema, no lo vamos a solucionar en este curso, ya que para hacerlo, tienes que saber controlar las excepciones; se trata de un tema algo más avanzado que daré en la siguiente entrega de la colección The Python Master (curso de Python avanzado).
Al final de las soluciones de este proyecto encontrarás el código completo, por si te has perdido por el camino. Así podrás hacer todas las pruebas que quieras y analizarlo parte por parte. Es importante que te fijes bien en las indentaciones. Suelen ser el motivo de muchos errores en Python.
Espero que hayas disfrutado haciendo el proyecto, y que haya servido para saciar un poco tus ganas de empezar a desarrollar programas completos.
Aquí no hay solución, tan solo debes seguir las indicaciones del apartado.
Te dejo el código completo del proyecto, por si has tenido problemas para seguir el hilo. Así podrás revisarlo mejor. Fíjate muy bien en las indentaciones. Será lo que seguramente te dé más problemas.
Si lo tienes muy diferente al mío, es normal. Como he indicado, hay muchos caminos diferentes en programación, para crear un mismo propósito.
Lo importante es que hayas cumplido con los requisitos que te he pedido, y que la calculadora funcione correctamente.
# Lógica de la calculadora
# Función de suma
def suma(a, b):
return a + b
# Función de resta
def resta(a, b):
return a - b
# Función de multiplicación
def multiplicacion(a, b):
return a * b
# Función de división
def division(a, b):
return a / b
# Función de módulo
def modulo(a, b):
return a % b
# Función de potencia
def potencia(a, b):
return a ** b
#----------------------------------------------------
# Interfaz de la calculadora
while True:
# Menú de la calculadora
print("Calculadora con Python")
print("1. Suma")
print("2. Resta")
print("3. Multiplicación")
print("4. División")
print("5. Módulo")
print("6. Potencia")
print("7. Salir")
# Variables para los operandos
numero1 = 0
numero2 = 0
# Entrada de opción para el usuario
opcion = int(input("Seleccione una opción: "))
# Condicional para evaluar la opción elegida
if opcion >= 1 and opcion <= 6:
numero1 = float(input("Introduzca el primer número:"))
numero2 = float(input("Introduzca el segundo número:"))
# Condicional para llamar a cada función del menú
match opcion:
case 1:
# Suma
resultado = suma(numero1,numero2)
print(f"El resultado de la suma es: {resultado}.")
case 2:
# Resta
resultado = resta(numero1,numero2)
print(f"El resultado de la resta es: {resultado}.")
case 3:
# Multiplicación
resultado = multiplicacion(numero1,numero2)
print(f"El resultado de multiplicación es: {resultado}.")
case 4:
# División
resultado = division(numero1,numero2)
print(f"El resultado de la división es: {resultado}.")
case 5:
# Módulo
resultado = modulo(numero1,numero2)
print(f"El resto de la división es: {resultado}.")
case 6:
# Potencia
resultado = potencia(numero1,numero2)
print(f"El resultado del cálculo es: {resultado}.")
case 7:
# Salir
print("¡Hasta la próxima!")
break
case _:
# Opción inválida
print("Opción inválida. Vuelva a intentarlo.")
Por cierto, si quieres puedes modificar todos los
espacios que aparecen en la consola, para que no salga
todo muy pegado. Recuerda que los saltos de línea se
aplican en los str
, con el símbolo
"\n"
. Por ejemplo:
print("\n")
Espacio publicitario
Espacio publicitario
Espacio publicitario