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:

***ERROR:***
 Error 1
Mensaje de error:
.F
======================================================================
FAIL: test_main_rect (test_formas.TestCreacionFormas.test_main_rect)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python3.13/unittest/mock.py", line 1426, in patched
    return func(*newargs, **newkeywargs)
  File "/tmp/_tempwc0rzdy0/test_formas.py", line 43, in test_main_rect
    self.assertEqual(white, color_pos(x, y))
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: Tuples differ: (255, 255, 255) != (0, 0, 255)

First differing element 0:
255
0

- (255, 255, 255)
+ (0, 0, 255)

----------------------------------------------------------------------
Ran 2 tests in 1.655s

FAILED (failures=1)



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

***ERROR:***
 Error 1
Mensaje de error:
.F
======================================================================
FAIL: test_dibuja_rectangulo (test_funciones.TestFuncionesFormas.test_dibuja_rectangulo)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/_tempfzh80l6y/test_funciones.py", line 32, in test_dibuja_rectangulo
    self.assertEqual(white, color_pos(x, y))
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: Tuples differ: (255, 255, 255) != (0, 0, 255)

First differing element 0:
255
0

- (255, 255, 255)
+ (0, 0, 255)

----------------------------------------------------------------------
Ran 2 tests in 1.635s

FAILED (failures=1)



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:]
    i = 0
    formas = []

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

        # --- CUADRADO ---
        if tipo == "cuad":
            # formato: cuad x y lado [color]
            x = int(argumentos[i + 1])
            y = int(argumentos[i + 2])
            lado = int(argumentos[i + 3])
            # color opcional
            if i + 4 < len(argumentos) and argumentos[i + 4] not in ("cuad", "rect"):
                color = argumentos[i + 4]
                i += 5
            else:
                color = "black"
                i += 4

            formas.append({
                "tipo": "cuadrado",
                "x": x,
                "y": y,
                "lado": lado,
                "color": color
            })

        # --- RECTÁNGULO ---
        elif tipo == "rect":
            # formato: rect x y ancho alto [color]
            x = int(argumentos[i + 1])
            y = int(argumentos[i + 2])
            ancho = int(argumentos[i + 3])
            alto = int(argumentos[i + 4])
            # color opcional
            if i + 5 < len(argumentos) and argumentos[i + 5] not in ("cuad", "rect"):
                color = argumentos[i + 5]
                i += 6
            else:
                color = "black"
                i += 5

            formas.append({
                "tipo": "rectángulo",
                "x": x,
                "y": y,
                "ancho": ancho,
                "alto": alto,
                "color": color
            })

        else:
            print(f"Tipo de figura desconocido: {tipo}")
            break

    return formas


def dibuja_cuadrado(x, y, lado, color="black"):
    """Dibuja un cuadrado en el lienzo.
    Devuelve True si se pintó correctamente, False si se sale del lienzo."""
    ancho_lienzo, alto_lienzo = tam_lienzo()

    # Verificar que no se salga del lienzo
    if x < 0 or y < 0 or x + lado > ancho_lienzo or y + lado > alto_lienzo:
        print(f"⚠️ El cuadrado en ({x},{y}) de lado {lado} se sale del lienzo.")
        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 en el lienzo.
    Devuelve True si se pintó correctamente, False si se sale del lienzo."""
    ancho_lienzo, alto_lienzo = tam_lienzo()

    # Verificar que no se salga del lienzo
    if x < 0 or y < 0 or x + ancho > ancho_lienzo or y + alto > alto_lienzo:
        print(f"⚠️ El rectángulo en ({x},{y}) de {ancho}x{alto} se sale del lienzo.")
        return False

    for i in range(x, x + ancho):
        for j in range(y, y + alto):
            pinta(i, 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 cumple completamente con el enunciado.

  • La función lee_formas() procesa correctamente los argumentos de línea de comandos, identificando cuadrados (cuad) y rectángulos (rect), manejando el color opcional y construyendo diccionarios con los parámetros requeridos.
  • Las funciones dibuja_cuadrado() y dibuja_rectangulo() verifican los límites del lienzo antes de dibujar y devuelven True/False según corresponda.
  • El ejemplo de ejecución python3 formas.py rect 10 8 6 3 green cuad 5 5 4 se procesa correctamente, dibujando ambas figuras con sus colores y dimensiones especificadas.
  • No se usan llamadas directas a turtle, cumpliendo con la restricción de usar solo pixels.py.

Es fácil de leer y entender

El código es claro para estudiantes principiantes:

  • Los nombres de variables y funciones son descriptivos (ej.: lado, ancho, alto).
  • Los comentarios explican el propósito de cada bloque sin sobrecargar la lectura.
  • La estructura de lee_formas() con if-elif para procesar cada figura es intuitiva y sigue el flujo lógico del enunciado.
  • Los bucles anidados en las funciones de dibujo reflejan directamente la idea de "pintar píxeles en un rango".

Sigue buenas prácticas de programación

El programa aplica buenas prácticas básicas:

  • Modularización: Cada función tiene una responsabilidad clara (leer argumentos, dibujar figuras).
  • Validación de límites: Se comprueba que las figuras no excedan el lienzo antes de dibujar.
  • Valores por defecto: El color negro se asigna correctamente cuando no se especifica.
  • Mensajes de error útiles: Se notifica explícitamente cuándo una figura se sale del lienzo.
  • Uso adecuado de diccionarios: Los parámetros de cada figura se organizan de forma estructurada y accesible.

Recomendaciones de mejora

  1. Validar tipos numéricos en lee_formas():
    Actualmente, si el usuario ingresa un valor no numérico (ej.: cuad a b 5), el programa fallará al convertir a entero. Para principiantes, sería útil añadir una verificación sencilla con str.isdigit() antes de int(), aunque el enunciado no lo exija explícitamente.

  2. Mejorar el manejo de errores en parámetros:
    Si faltan parámetros obligatorios (ej.: cuad 2 3 sin el lado), el programa intentará acceder a índices fuera de rango. Podrías añadir una comprobación como if i + 3 >= len(argumentos) para cuadrados, mostrando un mensaje de error amigable.

  3. Simplificar la lógica de detección de color:
    En lugar de verificar argumentos[i + 4] not in ("cuad", "rect"), podrías asumir que cualquier valor después de los parámetros obligatorios es un color hasta el próximo comando. Esto evita problemas si un color tuviera el nombre cuad (poco probable, pero más robusto). Ejemplo:

    color = "black"
    if i + 4 < len(argumentos) and argumentos[i + 4] not in ["cuad", "rect"]:
        color = argumentos[i + 4]
        i += 1  # Solo avanzar 1 posición adicional