[python] Mejora del programa de múltiplos y divisores

Pues nada, me he liado la manta a la cabeza y he seguido mejorando el programa para buscar n múltiplos o los divisores de un número y este es el resultado:

#!/usr/bin/python
# coding=utf-8
import argparse

parser = argparse.ArgumentParser(add_help=False)
group = parser.add_mutually_exclusive_group()
group.add_argument("-h", "--help", help="Muestra esta ayuda y finaliza", action="help")
group.add_argument("-m", "--multiplos", help="USO: mates_b -m n i (Calcula i múltiplos de n)", action="store_true")
group.add_argument("-d", "--divisores", help="USO: mates_b -d n (Calcula los divisores de n)", action="store_true")
parser.add_argument("numero", help="número con el que queremos trabajar", type=int)
parser.add_argument("nMultiplos", nargs='?', help="número de múltiplos que queremos", type=int)
args = parser.parse_args()

# Aquí procesamos lo que se tiene que hacer con cada argumento
if args.multiplos:
    try:
        n = args.numero
        m = args.nMultiplos
        #Desde 0 hasta el número de múltiplos solicitado...
        print ('Los', m, 'primeros múltiplos de', n, 'son: ', end='')
        for i in range (0, m):
            # Multiplicamos el número del que queremos los múltiplos por i
            print (n*i, ' ', end='')
        print()
    except:
        print("¡ERROR!: Los argumentos para el cálculo deben de ser en formato numerico")
if args.divisores:
    try:
        n = args.numero
        if n <= 0:
            #Error: El número que se ha introducido es 0 o menor
            print("¡ERROR!: ¡Te he pedido un número entero mayor que cero!")
        else:
            print('Los divisores de', n, 'son: ', end='')
            #Desde 1 hasta el número, si la división da de resto 0 es un divisor
            for i in range(1, n + 1):
                if n % i == 0:
                    print(i, ' ', end='')
            print()
    except:
        print("¡ERROR!: El argumento para el cálculo debe de ser en formato numerico")

Lo que he hecho ha sido introducir los parámetros por línea de comando mediante la librería argparse, y voy a aprovechar para contaros en detalle pero de forma "casual" cómo lo he hecho.

Lo primero que hacemos es importar la librería.
Tras esto debemos crear un parser donde ir introduciendo las opciones que queremos controlar y leer los argumentos.

import argparse
parser = argparse.ArgumentParser()
parser.parse_args()

Ahora al ejecutar ya tenemos disponible la opción -h o --help por defecto... pero en inglés.

rafolas:python rafolas$ python3 mates.py -h
usage: mates.py [-h]

optional arguments:
  -h, --help  show this help message and exit

Si queremos mostrar una ayuda personalizada o simplemente en castellano, lo que hacemos es, como se ve en el código inicial, indicar que no se añada la ayuda como parámetro para el parser y luego añadirla nosotros a mano. Esto también sería útil en caso de necesitar un parámetro -h distinto de la ayuda.

El resultado es este:

#!/usr/bin/python
# coding=utf-8
import argparse

parser = argparse.ArgumentParser(add_help=False)
group = parser.add_mutually_exclusive_group()
group.add_argument("-h", "--help", help="Muestra esta ayuda y finaliza", action="help")
args = parser.parse_args()

Como para nuestro programa necesitamos dos opciones (-d para divisores, -m para múltiplos) y cada una de estas opciones tiene un número de parámetros y condiciones, la configuración se complica un poco. Este es el resultado que paso a explicar:

parser = argparse.ArgumentParser(add_help=False)
group = parser.add_mutually_exclusive_group()
group.add_argument("-h", "--help", help="Muestra esta ayuda y finaliza", action="help")
group.add_argument("-m", "--multiplos", help="USO: mates -m n i (Calcula i múltiplos de n)", action="store_true")
group.add_argument("-d", "--divisores", help="USO: mates -d n (Calcula los divisores de n)", action="store_true")
parser.add_argument("numero", help="número con el que queremos trabajar", type=int)
parser.add_argument("nMultiplos", nargs='?', help="número de múltiplos que queremos", type=int)
args = parser.parse_args()

Y este sería el resultado:

rafolas:python rafolas$ python3 mates.py -h
usage: mates.py [-h | -m | -d] numero [nMultiplos]

positional arguments:
  numero           número con el que queremos trabajar
  nMultiplos       número de múltiplos que queremos

optional arguments:
  -h, --help       Muestra esta ayuda y finaliza
  -m, --multiplos  USO: mates -m n i (Calcula i múltiplos de n)
  -d, --divisores  USO: mates -d n (Calcula los divisores de n)

Lo que hacemos es crear un grupo que hace las opciones -h, -d y -m mutuamente excluyentes. Luego añadimos dos argumentos más (ver el código inicial). Y como el segundo no es necesario en caso de elegir la opción -d, lo creamos con el argumento nargs='?' que lo marca como optativo.

Antes de ver cómo controlamos si los parámetros son correctos, veamos cómo se aplican esos parámetros al código para ejecutar sólo la parte que hemos elegido. Básicamente tendremos una variable boleana formada por el parser (args en mi caso) y la opción "larga" especificada con el doble guión ("-m", "--multiplos"...) por ejemplo, pero sin el doble guión: args.multiplos, con lo que el código se queda así:

if args.multiplos:
    try:
        #Aquí ponemos el código para averiguar los i primeros múltiplos de n
    except:
        #control de errores

El resto del programa es sencillo:
- Un bucle para multiplicar n por i, tomando i valores desde 0 hasta el valor pedido -1
- Un bucle para dividir n por cada número desde n hasta 1 y sacarlo por pantalla sólo si el resto es 0.

Los siguientes pasos, números primos, mcd y mcm.

Deja una respuesta

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

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.