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/_tempt8ipu7ak/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.651s

FAILED (failures=1)

Mensaje del test:
Cuadrado dibujado correctamente en (2, 3)
Rectángulo dibujado correctamente en (2, 3)


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/_tempx14649fi/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.662s

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:]
    formas = []
    i = 0
    while i < len(argumentos):
        tipo = argumentos[i]
        if tipo == 'cuad':
            x = int(argumentos[i+1])
            y = int(argumentos[i+2])
            lado = int(argumentos[i+3])
            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})
        elif tipo == 'rect':
            x = int(argumentos[i+1])
            y = int(argumentos[i+2])
            ancho = int(argumentos[i+3])
            alto = int(argumentos[i+4])
            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:
            i += 1
    return formas


def dibuja_cuadrado(x, y, lado, color="black"):
    """Dibuja un cuadrado en el lienzo.
    
    Args:
        x, y: Coordenadas de inicio del cuadrado
        lado: Tamaño del lado del cuadrado
        color: Color del cuadrado (opcional, por defecto 'black')
        
    Returns:
        bool: True si el cuadrado se pudo pintar completamente, False si se sale del lienzo
    """
    (ancho_lienzo, alto_lienzo) = tam_lienzo()
    
    # Verificar si el cuadrado se sale del lienzo
    if (x < 0 or y < 0 or 
        x + lado > ancho_lienzo or 
        y + lado > alto_lienzo):
        return False
        
    # Pintar el cuadrado
    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.
    
    Args:
        x, y: Coordenadas de inicio del rectángulo
        ancho: Ancho del rectángulo
        alto: Alto del rectángulo
        color: Color del rectángulo (opcional, por defecto 'black')
        
    Returns:
        bool: True si el rectángulo se pudo pintar completamente, False si se sale del lienzo
    """
    (ancho_lienzo, alto_lienzo) = tam_lienzo()
    
    # Verificar si el rectángulo se sale del lienzo
    if (x < 0 or y < 0 or 
        x + ancho > ancho_lienzo or 
        y + alto > alto_lienzo):
        return False
        
    # Pintar el rectángulo
    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")
        exito = False

        if tipo == "cuadrado":
            lado = forma["lado"]
            exito = dibuja_cuadrado(x, y, lado, color)
            if not exito:
                print(f"Error: El cuadrado en ({x}, {y}) con lado {lado} se sale del lienzo de {ancho}x{alto}", file=sys.stderr)
        elif tipo == "rectángulo":
            ancho_forma = forma["ancho"]
            alto_forma = forma["alto"]
            exito = dibuja_rectangulo(x, y, ancho_forma, alto_forma, color)
            if not exito:
                print(f"Error: El rectángulo en ({x}, {y}) con tamaño {ancho_forma}x{alto_forma} se sale del lienzo de {ancho}x{alto}", file=sys.stderr)
        
        if exito:
            print(f"{tipo.capitalize()} dibujado correctamente en ({x}, {y})")

    espera()


if __name__ == "__main__":
    main()

Análisis

Cumple con el enunciado

El programa cumple completamente con el enunciado.

  • 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 claves adecuadas (tipo, x, y, etc.).
  • 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, solo se emplea el módulo pixels.py como se exige.

Es fácil de leer y entender

El código es claro para estudiantes principiantes:

  • Los nombres de variables y funciones están en español (lado, ancho, alto), lo que facilita la comprensión.
  • Las funciones incluyen docstrings explicando parámetros y comportamiento.
  • La estructura lógica (bucles anidados para dibujar, verificación de límites) es sencilla y sigue el enunciado paso a paso.
  • El uso de sys.argv y el procesamiento secuencial de argumentos son apropiados para el nivel.

Sigue buenas prácticas de programación

  • Modularización adecuada: Cada función tiene una responsabilidad clara (leer, dibujar, ejecutar).
  • Manejo de errores: Se validan los límites del lienzo y se notifican errores con mensajes descriptivos.
  • Valores por defecto: El color negro se asigna correctamente cuando no se especifica.
  • Legibilidad: Los comentarios y la estructura ayudan a seguir la lógica sin confusiones.
  • Uso correcto de tipos: Se convierten explícitamente los argumentos a enteros (int(argumentos[...])).

Recomendaciones de mejora

  • En lee_formas(), al verificar el color, sería más robusto comprobar solo si quedan argumentos suficientes en lugar de depender de que el siguiente token no sea cuad/rect. Por ejemplo, para cuad, si hay 4 argumentos después de cuad (x, y, lado, color), tomar el color; si hay 3, usar negro. Esto evita asumir que los colores nunca coincidirán con nombres de figuras.
  • En las funciones de dibujo, podrías añadir una validación para coordenadas negativas en la verificación de límites (ya se hace, pero se podría destacar en comentarios para reforzar el concepto a los alumnos).
  • En main(), al imprimir errores, usar sys.exit(1) tras el primer error crítico podría ser útil, pero el enunciado no lo exige, así que es opcional.