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'
- Comprobación con ficheros de solución
- Prueba automática del programa
- Revisión automática de programa
- Análisis
- Recomendaciones de mejora
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 devuelveTruedespués de dibujar correctamente (solo devuelveFalseen casos inválidos, pero en casos válidos retornaNonepor falta dereturn True). Esto incumple el requisito explícito de devolverTruecuando 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, encuad 5 5 4 rect 10 8 6 3, elrectse 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 deforma.get("color", "black")para manejar el color opcional. -
✅ Validación de límites del lienzo antes de dibujar (evita errores de segmentación). -
❌ Faltareturn Trueendibuja_cuadrado()tras dibujar, lo que rompe el contrato de la función. -
❌ Lógica defectuosa enlee_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 enlee_formas()imprime mensajes, pero no detiene la ejecución ante argumentos inválidos (puede generar resultados inesperados).
Recomendaciones de mejora
-
Corregir
dibuja_cuadrado():
Añadereturn Trueal final de la función, después de los bucles de dibujo, para cumplir con el requisito de devolverTruecuando el cuadrado se pinta correctamente. -
Mejorar
lee_formas():- En lugar de verificar si un argumento no es un número para detectar colores, comprueba si el siguiente argumento es
cuadorect(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
- En lugar de verificar si un argumento no es un número para detectar colores, comprueba si el siguiente argumento es
-
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 -
Validar tipos de figura en
main():
Aunque el enunciado no lo exige, añade una comprobación enmain()para ignorar figuras con tipos desconocidos (ej:if tipo not in ["cuadrado", "rectángulo"]: continue), evitando errores inesperados.