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:]
    formas = []
    i = 0
    if len(argumentos) == 0:
        print("No se proporcionó forma a pintar")
        exit()
    elif len(argumentos) < 4:
        print(
            "Tienes que dar al menos 4 argumentos de la forma: "
            "<tipo> <x> <y> <lado|ancho> <alto> <color>"
        )
        exit()
    else:
        while i < len(argumentos):
            tipo = argumentos[i]
            if tipo == "cuad":
                if i + 3 > len(argumentos):
                    print("Error: Faltan argumentos para el cuadrado")
                    exit()
                x = int(argumentos[i + 1])
                y = int(argumentos[i + 2])
                lado = int(argumentos[i + 3])
                forma = {"tipo": "cuadrado", "x": x, "y": y, "lado": lado}
                if i + 4 < len(argumentos):
                    forma["color"] = argumentos[i + 4]
                    i += 5
                else:
                    i += 4
                formas.append(forma)
            elif tipo == "rect":
                if i + 4 > len(argumentos):
                    print("Error: Faltan argumentos para el rectángulo")
                    exit()
                x = int(argumentos[i + 1])
                y = int(argumentos[i + 2])
                ancho = int(argumentos[i + 3])
                alto = int(argumentos[i + 4])
                forma = {
                    "tipo": "rectángulo",
                    "x": x,
                    "y": y,
                    "ancho": ancho,
                    "alto": alto,
                }
                if i + 5 < len(argumentos):
                    forma["color"] = argumentos[i + 5]
                    i += 6
                else:
                    i += 5
                formas.append(forma)
            else:
                print(f"Error: Tipo de figura desconocido: {argumentos[i]}")
                exit()

    return formas


def dibuja_cuadrado(x, y, lado, color="black"):
    """Dibuja un cuadrado en el lienzo.

    Args:
        x: Coordenada x de la esquina superior izquierda
        y: Coordenada y de la esquina superior izquierda
        lado: Tamaño del lado del cuadrado
        color: Color del cuadrado (opcional, negro por defecto)

    Returns:
        True si el cuadrado se pudo pintar completamente,
        False si se sale del lienzo.
    """
    ancho_lienzo, alto_lienzo = tam_lienzo()

    if (
        x < 0
        or y < 0
        or x + lado > ancho_lienzo
        or y + lado > alto_lienzo
        or lado <= 0
    ):
        return False

    for i in range(x, x + lado):
        for j in range(y, y + lado):
            pinta(i, j, color)
    return True


def dibuja_rectangulo(x, y, ancho, alto, color="black"):
    """Dibuja un rectángulo (solo su contorno) en el lienzo.

    Args:
        x: Coordenada x de la esquina superior izquierda
        y: Coordenada y de la esquina superior izquierda
        ancho: Tamaño del ancho del rectángulo
        alto: Tamaño del alto del rectángulo
        color: Color del rectángulo (opcional, negro por defecto)

    Returns:
        True si el rectángulo se pudo pintar completamente,
        False si se sale del lienzo.
    """
    ancho_lienzo, alto_lienzo = tam_lienzo()

    if (
        x < 0
        or y < 0
        or x + ancho > ancho_lienzo
        or y + alto > alto_lienzo
        or ancho <= 0
        or alto <= 0
    ):
        return False

    # Dibuja solo el borde del rectángulo
    for i in range(x, x + ancho):
        pinta(i, y, color)  # borde superior
        pinta(i, y + alto - 1, color)  # borde inferior
    for j in range(y, y + alto):
        pinta(x, j, color)  # borde izquierdo
        pinta(x + ancho - 1, j, color)  # borde derecho
    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.

  • En lee_formas(), las validaciones de argumentos son incorrectas. Por ejemplo, para un cuadrado se verifica i + 3 > len(argumentos), pero debería ser i + 3 >= len(argumentos) para evitar IndexError. Si faltan argumentos (ej.: cuad 2 3), el programa intenta acceder a índices fuera de rango en lugar de mostrar el mensaje de error.
  • En dibuja_rectangulo(), el enunciado especifica que la figura debe "cubrir todos los pixels" (como el cuadrado), pero el código solo dibuja el borde del rectángulo (no lo rellena). Esto contradice el ejemplo del cuadrado y el comportamiento esperado.

Es fácil de leer y entender

El código es mayormente comprensible para principiantes:

  • Usa nombres de variables y funciones en español acordes al enunciado (dibuja_cuadrado, lee_formas).
  • Incluye comentarios explicativos en las funciones.
  • Pero la lógica de validación en lee_formas() es confusa debido a los errores en las comparaciones de índices, lo que podría generar dudas en alumnos novatos.

Sigue buenas prácticas de programación

Presenta errores críticos en validaciones:

  • No maneja correctamente los límites de los argumentos en lee_formas(), lo que causa fallos en tiempo de ejecución ante entradas incompletas.
  • La función dibuja_rectangulo() no sigue la especificación del enunciado (debe rellenar la figura, no solo dibujar bordes).
  • Aunque el código está estructurado con funciones claras, falta verificar los valores de retorno de dibuja_cuadrado() y dibuja_rectangulo() en main(), como sugiere el enunciado (ej.: notificar si una figura no cabe en el lienzo).

Recomendaciones de mejora

  1. Corrige las validaciones en lee_formas():

    • Para cuad, cambia i + 3 > len(argumentos) por i + 3 >= len(argumentos).
    • Para rect, usa i + 4 >= len(argumentos). Esto evitará IndexError y mostrará el mensaje de error adecuado.
  2. Rellena el rectángulo en dibuja_rectangulo():

    • Sigue el mismo patrón que dibuja_cuadrado() (bucle anidado para pintar todos los píxeles internos), no solo los bordes. El enunciado exige que "cubra todos los pixels" entre las coordenadas.
  3. Verifica los resultados de las funciones de dibujo en main():

    • Añade una comprobación como if not dibuja_cuadrado(...): print("Error: Figura fuera del lienzo") para cumplir con la especificación de devolver True/False.
  4. Simplifica la lógica de color en lee_formas():

    • Usa forma["color"] = argumentos[i + 4] if i + 4 < len(argumentos) else "black" para evitar repetir el incremento de i en dos bloques.