Skip to content

Revisión automática de la práctica 04-formas

Este es el resultado de una revisión automática de la prácica 04-formas, 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
  • Archivos Python encontrados (excluyendo esos): formas.py

Correcto, se elige formas.py como entrega.

Comprobación con ficheros de solución

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

Prueba automática del programa

Pruebas realizadas por 04-formas/tests/test_argumentos.py:

OK

Pruebas realizadas por 04-formas/tests/test_formas.py:

OK

Pruebas realizadas por 04-formas/tests/test_funciones.py:

OK

Revisión automática de programa

Programa revisado:

import sys
from pixels import tam_lienzo, pinta, espera


def lee_formas():
    """Lee los argumentos de línea de comandos y construye una lista de
    diccionarios que representan las formas."""
    argumentos = sys.argv[1:]
    if not argumentos:
        print("No hay formas a pintar.")
        exit()

    formas = []
    i = 0
    while i < len(argumentos):
        tipo = argumentos[i]

        if tipo == "cuad":
            if i + 3 >= len(argumentos):
                print("Formato incorrecto para cuadrado. Uso: cuad x y lado [color]")
                exit()
            x, y, lado = int(argumentos[i+1]), int(argumentos[i+2]), int(argumentos[i+3])
            color = argumentos[i+4] if (i+4 < len(argumentos) and argumentos[i+4] not in ("cuad", "rect")) else "black"
            formas.append({"tipo": "cuadrado", "x": x, "y": y, "lado": lado, "color": color})
            i += 5 if color != "black" else 4

        elif tipo == "rect":
            if i + 4 >= len(argumentos):
                print("Formato incorrecto para rectángulo. Uso: rect x y ancho alto [color]")
                exit()
            x, y, ancho, alto = int(argumentos[i+1]), int(argumentos[i+2]), int(argumentos[i+3]), int(argumentos[i+4])
            color = argumentos[i+5] if (i+5 < len(argumentos) and argumentos[i+5] not in ("cuad", "rect")) else "black"
            formas.append({"tipo": "rectángulo", "x": x, "y": y, "ancho": ancho, "alto": alto, "color": color})
            i += 6 if color != "black" else 5

        else:
            print("Tipo de figura no reconocido. Usa 'cuad' para cuadrado o 'rect' para rectángulo.")
            exit()

    return formas


def dibuja_cuadrado(x, y, lado, color="black"):
    """Dibuja un cuadrado en el lienzo."""
    ancho_lienzo, alto_lienzo = tam_lienzo()
    if x < 0 or y < 0 or x + lado > ancho_lienzo or y + lado > alto_lienzo:
        return False
    for i in range(lado):
        pinta(x + i, y, color)
        pinta(x + i, y + lado - 1, color)
        pinta(x, y + i, color)
        pinta(x + lado - 1, y + i, color)
    return True


def dibuja_rectangulo(x, y, ancho, alto, color="black"):
    """Dibuja un rectángulo en el lienzo."""
    ancho_lienzo, alto_lienzo = tam_lienzo()
    if x < 0 or y < 0 or x + ancho > ancho_lienzo or y + alto > alto_lienzo:
        return False
    for i in range(ancho):
        pinta(x + i, y, color)
        pinta(x + i, y + alto - 1, color)
    for j in range(alto):
        pinta(x, y + j, color)
        pinta(x + ancho - 1, y + j, color)
    return True


def main():
    """Programa principal"""
    (ancho, alto) = tam_lienzo()
    formas = lee_formas()

    for forma in formas:
        tipo = forma["tipo"]
        x = forma["x"]
        y = forma["y"]
        color = forma.get("color", "black")

        if tipo == "cuadrado":
            lado = forma["lado"]
            dibuja_cuadrado(x, y, lado, color)
        elif tipo == "rectángulo":
            ancho_forma = forma["ancho"]
            alto_forma = forma["alto"]
            dibuja_rectangulo(x, y, ancho_forma, alto_forma, color)

    espera()


if __name__ == "__main__":
    main()

Análisis

Cumple con el enunciado

El programa no cumple completamente con el enunciado. El enunciado especifica que las figuras deben "cubrir todos los pixels entre las coordenadas X e Y" (ejemplo: un cuadrado de lado 3 en (2,3) ocupa X=2-4 e Y=3-5). Sin embargo, las funciones dibuja_cuadrado() y dibuja_rectangulo() solo dibujan el perímetro de las figuras (bordes), no rellenan el área interior. Esto contradice el requisito explícito de que la figura "cubra todos los pixels" en el rango indicado. Además, el programa no verifica los valores de retorno de dibuja_cuadrado()/dibuja_rectangulo() en main(), aunque el enunciado no exige manejar estos valores, sí especifica que las funciones deben devolver True/False según si la figura cabe en el lienzo.

Es fácil de leer y entender

El código es relativamente fácil de entender para un principiante. Usa nombres de variables descriptivos (x, y, lado, ancho_lienzo), comentarios claros y una estructura lógica en lee_formas() con el bucle while. Sin embargo, la lógica para detectar el color opcional es compleja (verificación de i+4 < len(argumentos) and argumentos[i+4] not in ("cuad", "rect")), lo que podría confundir a estudiantes novatos. Además, la diferencia entre dibujar el perímetro vs. rellenar la figura no está documentada, lo que genera ambigüedad.

Sigue buenas prácticas de programación

Hay mejoras necesarias en buenas prácticas:

  • Diseño incorrecto: Las funciones de dibujo no cumplen su propósito (deben rellenar, no solo dibujar bordes).
  • Validación incompleta: No se verifica si las coordenadas iniciales son negativas en lee_formas() (ej: cuad -1 2 3).
  • Acoplamiento innecesario: En lee_formas(), se asume que los colores válidos no coinciden con "cuad" o "rect", lo que es frágil (ej: color "rectángulo" no funcionaría).
  • Falta de modularidad: La lógica de parsing en lee_formas() mezcla validación y construcción de diccionarios, dificultando su mantenimiento.

Recomendaciones de mejora

  1. Rellenar figuras, no solo bordes:
    Modifica dibuja_cuadrado() y dibuja_rectangulo() para que pinten todos los píxeles internos, no solo el perímetro. Por ejemplo, en el cuadrado:

    for i in range(lado):
        for j in range(lado):
            pinta(x + i, y + j, color)
  2. Simplifica el parsing de colores:
    En lee_formas(), usa un enfoque más robusto para detectar el color. Por ejemplo, procesa los argumentos en orden e ignora palabras clave solo al inicio de una nueva figura:

    if i + 3 < len(argumentos) and argumentos[i+3] not in ["cuad", "rect"]:
        color = argumentos[i+3]
        i += 1  # Avanza un argumento adicional
  3. Valida coordenadas negativas:
    Añade en lee_formas() comprobaciones para x e y negativos, mostrando un mensaje de error claro:

    if x < 0 or y < 0:
        print("Error: Coordenadas no pueden ser negativas.")
        exit()
  4. Documenta el comportamiento crítico:
    Añade comentarios en las funciones de dibujo explicando que ahora rellenan la figura, no solo dibujan bordes, para evitar confusiones. Ejemplo:

    # Pinta TODOS los píxeles dentro del cuadrado (no solo el perímetro)