Soluciones a los ejercicios de funciones y módulos de Python

La semana pasada os dejaba dos ejercicios como parte del artículo de funciones y módulos de Python. Se trataba de hacer una calculadora de la siguiente forma: Programa una calculadora que funcione por línea de comandos para las operaciones de suma, resta, multiplicación y división, y para un máximo de 2 números enteros (sumar, restar, multiplicar y dividir dos números enteros). Debe reconocer los símbolos usuales de estas operaciones: “+”, “-“, “*” y “/”. Debes usar funciones, una para cada operación. Captura de pantalla 2015-07-11 19.23.00 Ten en cuenta, eso sí, dos cosas que no tienes por qué saber aún:

  • Los valores numéricos llegarán a tu programa a través de la línea de comandos como cadenas, siempre. Es decir, cuando pases como parámetro un 2, tu programa Python entenderá “2” y no 2. Para que tus operaciones aritméticas funcionen bien, fuerza una conversión a números con la función int(), a la que le pasarás como parámetro cada argumento que quieras que se interprete como un número entero.
  • Ésta ya la habrás podido notar en la imagen superior 🙂 En Linux y en Mac OS X, el asterisco “*” es un caracter especial para el Terminal y lo interpretará antes de pasárselo a tu programa Python. Para que llegue un asterisco a tu programa, cuando lo pruebes tendrás que escapar el asterisco usando una barra invertida, : ./calculadora.py 2 * 3. Esto no ocurrirá en Windows.

Posteriormente, había un segundo ejercicio que trataba de mejorar la calculadora anterior para que usase un módulo. Vamos con las soluciones Lo primero que tenemos que hacer es preparar un programa ejecutable capaz de procesar la línea de comandos, de forma que podamos pasarle la información necesaria: dos factores y una operación enmedio. Para eso, vamos a crear el siguiente esqueleto y grabarlo con un nombre significativo, como calculadora.py:

#!/usr/bin/python3 
import sys 
# Programa de cálculo básico con enteros 
exit(0)

 Para dejarlo todo listo, podemos ya otorgarle permisos de ejecución con chmod +x calculadora.py usando el Terminal en el directorio en el que lo hemos guardado. Recuerda que si estás usando Windows puedes omitir la línea #!/usr/bin/python3 y tampoco tienes por qué conceder permisos de ejecución al programa. Si estás en Mac OS X puedes usar la orden which python3 para localizar la ruta que poner en la línea que comienza por #/.

A continuación vamos a pasar a definir las cuatro funciones de cálculo básico a continuación del comentario y antes de la sentencia exit (0):

def suma (sumando1, sumando2): 
    "Devuelve la suma de dos números" 
    return sumando1 + sumando2 

def resta (minuendo, sustraendo): 
    "Devuelve la resta de dos números" 
    return minuendo - sustraendo 
    
def producto (multiplicando, multiplicador): 
    "Devuelve el producto de dos números" 
    return multiplicando * multiplicador 
    
def cociente (dividendo, divisor): 
    "Devuelve el cociente de dos números" 
    return dividendo / divisor 

En estas definiciones me he preocupado en ir al grano y no procesar cada argumento como cadena, tal y como avisaba en el enunciado, sino asumir que quien llame a la función lo hará con las debidas precauciones convirtiendo previamente los argumentos del programa a números. Esto no es arbitrario, y es importante explicar bien por qué. Si programamos funciones y módulos es porque queremos que éstos sean lo más reutilizables posibles: que se puedan usar en muchas situaciones y contextos distintos. Si metemos dentro de las funciones la conversión de cadena a entero estaremos rompiendo ese sencillo principio porque sólo servirán para aquellos programas y contextos en los que se manejen los datos como cadenas de texto. Por ejemplo y sin ir más lejos, ya no serían de utilidad desde idle. Es mucho mejor hacer que las funciones se preocupen de los problemas técnicos más cercanos a lo que quieren ejecutar, y nada más: en este caso, aritmética. Tras la definición de las funciones de cálculo podremos poner ya la condición principal, que detecta la operación e invoca la función correspondiente:

if sys.argv[2] == "+": 
    print (suma (int(sys.argv[1]), int(sys.argv[3]))) 
elif sys.argv[2] == "-": 
    print (resta (int(sys.argv[1]), int(sys.argv[3]))) 
elif sys.argv[2] == "*": 
    print (producto (int(sys.argv[1]), int(sys.argv[3]))) 
elif sys.argv[2]== "/": 
    print (cociente (int(sys.argv[1]), int(sys.argv[3]))) 
else: 
    print ("No se ha reconocido la operación "" + sys.argv[2] + "".") 
    exit (1)

Si os fijáis, hemos hecho siempre conversiones a enteros, pero podríamos haberla hecho a números naturales con otras funciones como float(). Probadlo si queréis. También podéis ver que cuando el usuario introduce una operación no reconocible, el programa devuelve un mensaje explicando que ha ocurrido un error y sale con un código distinto de 0: 1. Recordad que, para el sistema operativo, un 0 como código de salida indica que el programa ha tenido éxito en su misión, así que si algo no ha salido como queríamos deberemos devolver un código diferente a 0. Podemos asignar cualquier número, y debemos usar distintos números para errores de distinta naturaleza, y siempre deberíamos documentar nuestros códigos si nuestro programa va a ser usado como parte de un sistema mayor. El código completo quedaría de esta forma:

#!/usr/bin/python3
 
import sys
 
# Programa de cáculo básico con enteros.
 
def suma (sumando1, sumando2):
        "Devuelve la suma de dos números"
        return sumando1 + sumando2
 
def resta (minuendo, sustraendo):
        "Devuelve la resta de dos números"
        return minuendo - sustraendo
 
def producto (multiplicando, multiplicador):
        "Devuelve el producto de dos números"
        return multiplicando * multiplicador
 
def cociente (dividendo, divisor):
        "Devuelve el cociente de dos números"
        return dividendo / divisor
 
if sys.argv[2] == "+":
    print (suma (int(sys.argv[1]), int(sys.argv[3])))
elif sys.argv[2] == "-":
    print (resta (int(sys.argv[1]), int(sys.argv[3])))
elif sys.argv[2] == "*":
    print (producto (int(sys.argv[1]), int(sys.argv[3])))
elif sys.argv[2]== "/":
    print (cociente (int(sys.argv[1]), int(sys.argv[3])))
else:
    print ("No se ha reconocido la operación "" + sys.argv[2] + "".")
    exit (1)
 
exit (0)

Vamos ahora a mover las funciones de aritmética a un módulo llamado artimetica_basica.py. Recordad que tenemos que guardarlo en el directorio principal del usuario si estamos en Linux, pero si estamos en Mac OS X en el directorio de documentos; en el directorio de instalación de Python si estamos trabajando en Windows. La localización de los módulos en Python está determinada por la librería sys, en una variable que se llama sys.path, sobre la que trabajaremos en otro artículo. El módulo aritmetica.py debe quedar así:

def suma (sumando1, sumando2):
        "Devuelve la suma de dos números"
        return sumando1 + sumando2
 
def resta (minuendo, sustraendo):
        "Devuelve la resta de dos números"
        return minuendo - sustraendo
 
def producto (multiplicando, multiplicador):
        "Devuelve el producto de dos números"
        return multiplicando * multiplicador
 
def cociente (dividendo, divisor):
        "Devuelve el cociente de dos números"
        return dividendo / divisor

A continuación, editamos el programa calculadora.py para que use dicho módulo:

#!/usr/bin/python3
 
import sys
import aritmetica_basica
 
# Programa de cáculo básico con enteros.
 
if sys.argv[2] == "+":
    print (aritmetica_basica.suma (int(sys.argv[1]), int(sys.argv[3])))
elif sys.argv[2] == "-":
    print (aritmetica_basica.resta (int(sys.argv[1]), int(sys.argv[3])))
elif sys.argv[2] == "*":
    print (aritmetica_basica.producto (int(sys.argv[1]), int(sys.argv[3])))
elif sys.argv[2]== "/":
    print (aritmetica_basica.cociente (int(sys.argv[1]), int(sys.argv[3])))
else:
    print ("No se ha reconocido la operación "" + sys.argv[2] + "".")
    exit (1)
 
exit (0)

Y esto es todo. Recordad que podéis dejar cualquier comentario o duda en los comentarios de esta entrada o a través del formulario de contacto del blog.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *