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/_tempxh_uc1nl/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.670s

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/_temp2zd_utnu/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.654s

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]
        forma = {}
        
        if tipo == 'cuad':
            try:
                x = int(argumentos[i+1])
                y = int(argumentos[i+2])
                lado = int(argumentos[i+3])
                forma = {
                    'tipo': 'cuadrado',
                    'x': x,
                    'y': y,
                    'lado': lado
                }
                # Verificar si el siguiente argumento es un color
                if i + 4 < len(argumentos) and not argumentos[i+4].lstrip('-').isdigit():
                    forma['color'] = argumentos[i+4]
                    i += 5
                else:
                    i += 4
                formas.append(forma)
            except (IndexError, ValueError):
                print(f"Error: Faltan argumentos para el cuadrado en la posición {i}")
                i += 1
                
        elif tipo == 'rect':
            try:
                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 }
                # Verificar si el siguiente argumento es un color
                if i + 5 < len(argumentos) and not argumentos[i+5].lstrip('-').isdigit():
                    forma['color'] = argumentos[i+5]
                    i += 6
                else:
                    i += 5
                formas.append(forma)
            except (IndexError, ValueError):
                print(f"Error: Faltan argumentos para el rectángulo en la posición {i}")
                i += 1
        else:
            i += 1
            
    return formas


def dibuja_cuadrado(x, y, lado, color="black"):
     #Args: x, y: Coordenadas de inicio del cuadrado.
           # lado: Tamaño del lado del cuadrado.
           # color: Color del cuadrado (negro por defecto).

     # Returns:
           # bool: True si el cuadrado se pudo dibujar completamente, False si se sale del lienzo.

        (ancho_lienzo, alto_lienzo) = tam_lienzo()

        # Verificar si el cuadrado cabe en el lienzo
        if (x < 0 or y < 0 or
                x + lado > ancho_lienzo or
                y + lado > alto_lienzo or
                lado <= 0):
            return False

        # Dibujar el cuadrado
        for i in range(x, x + lado):
            for j in range(y, y + lado):
                pinta(i, j, color)


def dibuja_rectangulo(x, y, ancho, alto, color="black"):

    (ancho_lienzo, alto_lienzo) = tam_lienzo()

    # Verificar si el rectángulo cabe en el 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

    # Dibujar 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")  #aqui si no pòngo el .get daria un error si el color no existe
                                             #en vez de cogerse como predeterminado el 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.

  • dibuja_cuadrado() no devuelve True después de dibujar correctamente (solo devuelve False en casos inválidos, pero en casos válidos retorna None por falta de return True). Esto incumple el requisito explícito de devolver True cuando el cuadrado se pinta bien.
  • lee_formas() tiene un error grave al procesar múltiples figuras: interpreta el tipo de la siguiente figura (ej: rect) como un color si no se especifica uno, lo que provoca que se ignoren figuras subsiguientes. Por ejemplo, en cuad 5 5 4 rect 10 8 6 3, el rect se toma como color del cuadrado y el rectángulo nunca se procesa.
  • Aunque el dibujo de píxeles es correcto (usando pinta), la lógica de validación de bordes del lienzo está bien implementada en ambas funciones.

Es fácil de leer y entender

El código es moderadamente comprensible para principiantes:

  • Los nombres de variables y funciones están en español y son descriptivos (ej: x, y, lado, ancho_lienzo).
  • Los comentarios explican el propósito de cada bloque, lo que ayuda a entender la lógica.
  • Sin embargo, el error en lee_formas() (confundir tipos de figura con colores) es difícil de detectar para un principiante, ya que la lógica de verificación (not argumentos[i+4].lstrip('-').isdigit()) es compleja y no está bien justificada en los comentarios.

Sigue buenas prácticas de programación

Presenta algunas buenas prácticas, pero con fallos críticos:

  • Uso correcto de forma.get("color", "black") para manejar el color opcional.
  • Validación de límites del lienzo antes de dibujar (evita errores de segmentación).
  • Falta return True en dibuja_cuadrado() tras dibujar, lo que rompe el contrato de la función.
  • Lógica defectuosa en lee_formas() para identificar colores: verifica si un argumento no es un número, pero los tipos de figura (cuad, rect) también son cadenas no numéricas, generando conflictos.
  • Manejo de errores en lee_formas() imprime mensajes, pero no detiene la ejecución ante argumentos inválidos (puede generar resultados inesperados).

Recomendaciones de mejora

  1. Corregir dibuja_cuadrado():
    Añade return True al final de la función, después de los bucles de dibujo, para cumplir con el requisito de devolver True cuando el cuadrado se pinta correctamente.

  2. Mejorar lee_formas():

    • En lugar de verificar si un argumento no es un número para detectar colores, comprueba si el siguiente argumento es cuad o rect (tipos de figura válidos). Si lo es, no hay color; si no, es un color.
    • Ejemplo para cuad:
      if i + 4 < len(argumentos) and argumentos[i+4] not in ['cuad', 'rect']:
          forma['color'] = argumentos[i+4]
          i += 5
      else:
          i += 4
  3. Simplificar la lógica de parsing:
    Usa una lista de tipos válidos (tipos_validos = ['cuad', 'rect']) para evitar repeticiones y hacer el código más claro. Por ejemplo:

    if i < len(argumentos) and argumentos[i] in tipos_validos:
        tipo = argumentos[i]
        # ... procesar según tipo
  4. Validar tipos de figura en main():
    Aunque el enunciado no lo exige, añade una comprobación en main() para ignorar figuras con tipos desconocidos (ej: if tipo not in ["cuadrado", "rectángulo"]: continue), evitando errores inesperados.