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'
- Comprobación con ficheros de plantilla
- Comprobación con ficheros de solución
- Revisión automática de programa
- Análisis
- Recomendaciones de mejora
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:
import sys
import pixels
def lee_argumentos() -> tuple[str, float, int]:
if len(sys.argv) != 4:
print(f"Uso: python3 {sys.argv[0]} <imagen.gif> <brillo> <desplazamiento>",
file=sys.stderr)
sys.exit(1)
try:
imagen = sys.argv[1]
brillo = float(sys.argv[2])
desplazamiento = int(sys.argv[3])
except ValueError:
print("Error: El brillo debe ser un número real (float) "
"y el desplazamiento un número entero (int).", file=sys.stderr)
sys.exit(1)
return imagen, brillo, desplazamiento
def _clamp_color(valor: int) -> int:
return min(255, max(0, valor))
def cambia_brillo(brillo: float):
ancho = pixels.get_width()
alto = pixels.get_height()
for y in range(alto):
for x in range(ancho):
r, g, b = pixels.get_color(x, y)
nuevo_r = int(r * brillo)
nuevo_g = int(g * brillo)
nuevo_b = int(b * brillo)
pixels.set_color(x, y, (
_clamp_color(nuevo_r),
_clamp_color(nuevo_g),
_clamp_color(nuevo_b)
))
def cambia_desplazamiento(desplazamiento: int):
ancho = pixels.get_width()
alto = pixels.get_height()
for y in range(alto):
for x in range(ancho):
r, g, b = pixels.get_color(x, y)
nuevo_r = r + desplazamiento
nuevo_g = g + desplazamiento
nuevo_b = b + desplazamiento
pixels.set_color(x, y, (
_clamp_color(nuevo_r),
_clamp_color(nuevo_g),
_clamp_color(nuevo_b)
))
def main():
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
- Lee correctamente los tres argumentos de línea de comandos (imagen, brillo y desplazamiento)
- Aplica el cambio de brillo multiplicando cada componente RGB por el factor y limitando valores entre 0-255
- Aplica el desplazamiento sumando el mismo valor entero a cada componente RGB y limitando valores entre 0-255
- Tiene la estructura de
main()exactamente como se especifica en el enunciado - Incluye la protección
if __name__ == "__main__"para ejecución independiente
Es fácil de leer y entender
- Usa funciones bien separadas con nombres claros en español
- Incluye un helper
_clamp_colorque encapsula la lógica de limitación de valores - Tiene una estructura lógica de procesamiento: lectura de argumentos → preparar imagen → aplicar brillo → aplicar desplazamiento → esperar
- Utiliza variables con nombres significativos (r, g, b para componentes RGB)
Sigue buenas prácticas de programación
- Usa funciones para separar responsabilidades
- Incluye manejo de errores para argumentos inválidos
- El helper
_clamp_colorevita repetición de código - No hay comentarios ni docstrings que expliquen el propósito de cada función
- La línea de error en
lee_argumentossupera los 79 caracteres recomendados por PEP8
Recomendaciones de mejora
-
Añadir docstrings a todas las funciones
Ejemplo paracambia_brillo:def cambia_brillo(brillo: float): """Modifica cada pixel multiplicando sus componentes RGB por el factor de brillo. Los valores resultantes se limitan entre 0 y 255.""" -
Mejorar formato PEP8 en líneas largas
Reformatear el mensaje de error para que no supere los 79 caracteres:print("Error: El brillo debe ser un número real (float) " "y el desplazamiento un número entero (int).", file=sys.stderr) -
Considerar redondeo en cambio de brillo
Actualmente se trunca el valor al convertir a int. Para brillo, podría ser más preciso:nuevo_r = int(round(r * brillo)) -
Optimizar bucles con
rangedirecto
En vez de:ancho = pixels.get_width() alto = pixels.get_height() for y in range(alto): for x in range(ancho):Podría simplificarse a:
for y in range(pixels.get_height()): for x in range(pixels.get_width()): -
Evitar procesamiento redundante
Actualmente se recorre toda la imagen dos veces (una para brillo y otra para desplazamiento). Para optimizar:def procesa_imagen(brillo: float, desplazamiento: int): """Aplica brillo y desplazamiento en un solo recorrido de la imagen""" for y in range(pixels.get_height()): for x in range(pixels.get_width()): r, g, b = pixels.get_color(x, y) # Aplicar ambos efectos en un solo paso nuevo_r = _clamp_color(int(r * brillo) + desplazamiento) # ...similar para g y b... pixels.set_color(x, y, (nuevo_r, nuevo_g, nuevo_b)) -
Añadir validación de rango para desplazamiento
Aunque el enunciado permite cualquier entero, podría mejorar con:if not (-255 <= desplazamiento <= 255): print("Advertencia: El desplazamiento podría causar saturación de colores", file=sys.stderr) -
Considerar manejo de tipos en parámetros
Aunque el enunciado no lo requiere, podría verificar que el archivo tenga extensión .gif:if not imagen.lower().endswith('.gif'): print("Error: El archivo debe ser de tipo GIF", file=sys.stderr) sys.exit(1)