Skip to content

Revisión automática de la práctica 03-imagen

Este es el resultado de una revisión automática de la prácica 03-imagen, tal y como la hemos recogido de este repositorio de entrega. Por favor, ten en cuenta que al ser una revisión automática, realizada en parte con la ayuda de un asistente de inteligencia artificial generativa, puede incluir errores, y ser incorrecta. Pero leela con atención, porque creemos que puede tener información útil. Si tienes cualquier duda, o crees que la revisión es errónea, por favor, consulta con los profesores de la asignatura.


Comprobación de archivos con extension '.py'

  • Archivos Python excluidos de la búsqueda: pixels.py, invert.py
  • Archivos Python encontrados (excluyendo esos): process.py

Correcto, se elige process.py como entrega.

Comprobación con ficheros de plantilla

Los archivos son diferentes de los de la plantilla.

Comprobación con ficheros de solución

Los archivos son diferentes de los de la solución.

Revisión automática de programa

Programa revisado:

#!/usr/bin/env python3
"""
Programa para procesar imágenes aplicando cambios de brillo y desplazamiento de colores.
"""

import sys
import pixels


def lee_argumentos() -> tuple[str, float, int]:     #Los argumentos que he puesto son [el GIF, el factor de l brillo
                                                    #y el desplazamiento de colores]
    """
    Lee los argumentos de la línea de comandos.
    
    Returns:
        tuple: (nombre_fichero, factor_brillo, desplazamiento)
    """
    if len(sys.argv) != 4:
        print("Uso: python3 process.py <imagen.gif> <factor_brillo> <desplazamiento>")
        sys.exit(1)
    
    try:
        nombre_fichero = sys.argv[1]
        if not nombre_fichero.lower().endswith('.gif'):
            print("Error: El archivo debe ser un GIF (.gif)")
            sys.exit(1)
            
        factor_brillo = float(sys.argv[2])
        if factor_brillo < 0:
            print("Error: El factor de brillo debe ser un número positivo")
            sys.exit(1)
            
        desplazamiento = int(sys.argv[3])
        
        return nombre_fichero, factor_brillo, desplazamiento
        
    except ValueError as e:
        print(f"Error en los argumentos: {e}")
        print("Uso: python3 process.py <imagen.gif> <factor_brillo> <desplazamiento>")
        print("  <factor_brillo>: número real positivo")
        print("  <desplazamiento>: número entero (positivo o negativo)")
        sys.exit(1)


def cambia_brillo(brillo: float) -> None:
    """
    Modifica el brillo de la imagen multiplicando cada componente RGB por el factor dado.
    
    Args:
        brillo (float): Factor de brillo a aplicar (ej: 1.5 para aumentar un 50% el brillo)
    """
    for x in range(pixels.ancho):
        for y in range(pixels.alto):
            r, g, b = pixels.lee(x, y)
            
            # Aplicar brillo a cada componente
            r_nuevo = min(255, int(r * brillo))
            g_nuevo = min(255, int(g * brillo))
            b_nuevo = min(255, int(b * brillo))
            
            pixels.pinta(x, y, (r_nuevo, g_nuevo, b_nuevo))


def cambia_desplazamiento(desplazamiento: int) -> None:
    """
    Desplaza los colores de la imagen sumando el valor de desplazamiento a cada componente RGB.
    
    Args:
        desplazamiento (int): Valor a sumar a cada componente de color (puede ser negativo)
    """
    def ajustar_valor(valor: int) -> int:
        """Ajusta un valor de color para que esté en el rango 0-255"""
        return max(0, min(255, valor))
    
    for x in range(pixels.ancho):
        for y in range(pixels.alto):
            r, g, b = pixels.lee(x, y)
            
            # Aplicar desplazamiento a cada componente
            r_nuevo = ajustar_valor(r + desplazamiento)
            g_nuevo = ajustar_valor(g + desplazamiento)
            b_nuevo = ajustar_valor(b + desplazamiento)
            
            pixels.pinta(x, y, (r_nuevo, g_nuevo, b_nuevo))


def main():
    """Función principal del programa"""
    imagen, brillo, desplazamiento = lee_argumentos()
    pixels.prepara(imagen)
    cambia_brillo(brillo)
    cambia_desplazamiento(desplazamiento)
    pixels.espera()


if __name__ == "__main__":
    main()

Análisis

Cumple con el enunciado

El programa cumple con los requisitos especificados:

  • Implementa correctamente las tres funciones requeridas (lee_argumentos, cambia_brillo, cambia_desplazamiento) con las signaturas indicadas.
  • Valida que el archivo tenga extensión .gif y que el factor de brillo sea un número positivo.
  • Aplica el cambio de brillo multiplicando cada componente RGB por el factor y limitando a 255.
  • Aplica el desplazamiento sumando el valor a cada componente RGB y ajustando al rango 0-255.
  • Incluye la función main() con la estructura exacta del enunciado.

Es fácil de leer y entender

El código es accesible para principiantes:

  • Usa comentarios claros y docstrings explicativos en cada función.
  • Las variables y funciones tienen nombres descriptivos en español.
  • La lógica de procesamiento de píxeles está bien estructurada con bucles anidados.
  • La función auxiliar ajustar_valor encapsula la lógica de validación de colores, simplificando el código principal.

Sigue buenas prácticas de programación

El programa muestra buenas prácticas:

  • Separa responsabilidades en funciones independientes.
  • Valida entradas y maneja errores de forma explícita.
  • Evita código duplicado mediante funciones auxiliares.
  • Usa if __name__ == "__main__": para ejecutar el programa principal.
  • Sin embargo, hay un detalle a mejorar: al aplicar el brillo, primero convierte a int y luego aplica min(255, ...), lo que podría truncar decimales en lugar de redondear (aunque el enunciado no especifica redondeo).

Recomendaciones de mejora

  1. Manejo de decimales en el brillo
    En cambia_brillo, el uso de int(r * brillo) trunca los decimales. Sería más preciso redondear:

    r_nuevo = min(255, round(r * brillo))
  2. Validación adicional de argumentos
    Aunque el enunciado no lo exige, se podría validar que el archivo exista antes de procesarlo:

    import os
    if not os.path.exists(nombre_fichero):
        print("Error: El archivo no existe")
        sys.exit(1)
  3. Reducción de líneas largas
    Algunas líneas (como los mensajes de error) superan las 79 columnas recomendadas por PEP8. Ejemplo de mejora:

    print("Uso: python3 process.py <imagen.gif> "
          "<factor_brillo> <desplazamiento>")
  4. Claridad en mensajes de error
    En lugar de "Error en los argumentos", sería más útil indicar qué argumento falló:

    print(f"Error: '{sys.argv[2]}' no es un factor de brillo válido")
  5. Uso de sys.exit() sin código explícito
    En algunos casos, sys.exit() podría usarse sin código de error (aunque sys.exit(1) es correcto):

    sys.exit("Error: El archivo debe ser un GIF (.gif)")
  6. Documentación de la función ajustar_valor
    Aunque es una función auxiliar, añadir un breve comentario sobre su propósito mejoraría la legibilidad:

    # Ajusta un valor de color para que esté entre 0 y 255
    def ajustar_valor(valor: int) -> int:
        return max(0, min(255, valor))