La idea básica de este algoritmo es poder analizar información, generalmente provista mediante registros, agrupándolos según diversos criterios. Como precondición se incluye que la información debe estar ordenada según los mismos criterios por los que se la quiera agrupar. De modo que si varios registros tienen el mismo valor en uno de sus campos, se encuentren juntos, formando un grupo.

Se lo utiliza principalmente para realizar reportes que requieren subtotales, cantidades o promedios parciales u otros valores similares.

El algoritmo consiste en ir recorriendo la información, de modo que cada vez que se pro-duzca un cambio en alguno de los campos correspondiente a uno de los criterios, se ejecutan los pasos correspondientes a la finalización de un criterio y el comienzo del siguiente.

Ejemplo

Supongamos que en un archivo csv tenemos los datos de las ventas de una empresa a sus clientes y se necesita obtener las ventas por cliente, mes por mes, con un total por año, otro por cliente y uno de las ventas totales. El formato está especificado de la siguiente forma:

cliente,año,mes,día,venta

Para poder hacer el reporte como se solicita, el archivo debe estar ordenado en primer lugar por cliente, luego por año, y luego por mes.

Teniendo el archivo ordenado de esta manera, es posible recorrerlo e ir realizando los sub-totales correspondientes, a medida que se los va obteniendo.

# ventas.py: Recorre un archivo de ventas e imprime totales y subtotales

# encoding: latin1
import csv

def leer_datos(datos):
    """ Devuelve el siguiente registro o None si no hay más """
    try:
        return datos.next()
    except:
        return None

def ventas_clientes_mes(archivo_ventas):
    """ Recorre un archivo csv, con la información almacenada en el
        formato: cliente,an"o,mes,día,venta """
    # Inicialización
    ventas = open(archivo_ventas)
    ventas_csv = csv.reader(ventas)

    item = leer_datos(ventas_csv)
    total = 0

    while item:
        # Inicialización para el bucle de cliente
        cliente = item[0]
        total_cliente = 0
        print "Cliente %s" % cliente

        while item and item[0] == cliente:
            # Inicialización para el bucle de año
            anyo = item[1]
            total_anyo = 0
            print "\tAño: %s" % anyo

            while item and item[0] == cliente and item[1] == anyo:
                mes, monto = item[2], float(item[3])
                print "\t\tVentas del mes %s: %.2f" % (mes, monto)
                total_anyo += monto
                # Siguiente registro
                item = leer_datos(ventas_csv)

        # Final del bucle de año
        print "\tTotal para el año %s: %.2f" % (anyo, total_anyo)
        total_cliente += total_anyo

    # Final del bucle de cliente
    print "Total para el cliente %s: %.2f\n" % (cliente, total_cliente)
    total += total_cliente

# Final del bucle principal
print "Total general: %.2f" % total

# Cierre del archivo
ventas.close()

ventas_clientes_mes("ventas.csv")

Se puede ver que para resolver el problema es necesario contar con tres bucles anidados, que van incrementando la cantidad de condiciones a verificar.

Las soluciones de corte de control son siempre de estar forma: una serie de bucles anidados, que incluyen las condiciones del bucle padre y agregan su propia condición, y el movimiento hacia el siguiente registro se realiza en el bucle con mayor nivel de anidación.


Copyright (c) 2011-2014 Rosita Wachenchauzer, Margarita Manterola, Maximiliano Curia, Marcos Medrano, Nicolás Paez. La copia y redistribución de esta página se permite bajo los términos de la licencia Creative Commons Atribución - Compartir Obras Derivadas Igual 3.0 siempre que se conserve esta nota de copyright.