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/_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()ydibuja_rectangulo()verifican los límites del lienzo antes de dibujar y devuelvenTrue/Falsesegún corresponda. - El ejemplo de ejecución
python3 formas.py rect 10 8 6 3 green cuad 5 5 4se procesa correctamente, dibujando ambas figuras con sus colores y dimensiones especificadas. - No se usan llamadas directas a
turtle, solo se emplea el módulopixels.pycomo 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.argvy 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 seacuad/rect. Por ejemplo, paracuad, si hay 4 argumentos después decuad(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, usarsys.exit(1)tras el primer error crítico podría ser útil, pero el enunciado no lo exige, así que es opcional.