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:
OK
Pruebas realizadas por 04-formas/tests/test_funciones.py:
OK
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:]
if len(argumentos) < 4:
print("Se requieren al menos 4 argumentos para dibujar una "
"figura.")
return []
formas = []
i = 0
while i < len(argumentos):
if argumentos[i] == "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]
# Si existe un quinto argumento y no es el nombre de otra
# figura, asumimos que va a ser el color.
i += 5
else:
color = "black"
i += 4
# Si había color, se han usado 5 argumentos para esta forma:
# ["cuad", x, y, lado, color]
# Suma 5 a la variable i para saltar los cinco argumentos ya
# leídos y continuar leyendo desde el siguiente elemento no
# procesado.
# Si no había color solo se han usado 4 argumentos:
# ["cuad", x, y, lado] y suma 4 a la variable i
formas.append({"tipo": "cuadrado", "x": x, "y": y,
"lado": lado, "color": color})
elif argumentos[i] == "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]
# Si existe un sexto argumento y no es el nombre de otra
# figura, asumimos que va a ser el color
i += 6
else:
color = "black"
i += 5
formas.append({"tipo": "rectángulo", "x": x, "y": y,
"ancho": ancho, "alto": alto, "color": color})
return formas
def dibuja_cuadrado(x, y, lado, color="black"):
"""Dibuja el borde de un cuadrado en el lienzo."""
ancho_lienzo, alto_lienzo = tam_lienzo()
if x < 0 or y < 0 or x + lado - 1 >= ancho_lienzo or \
y + lado - 1 >= alto_lienzo:
# Comprueba si el cuadrado cabe en el lienzo, si x o y son
# negativos estamos fuera del lienzo,
# si la coordenada máxima (x + lado - 1, y + lado - 1) excede o
# iguala el tamaño del lienzo estamos fuera del lienzo
# Si no cabe, devuelve False y no pinta nada. (la resta -1 se
# usa porque se consideran píxeles índices enteros desde 0).
return False
# Dibuja solo el borde: lados superior e inferior
for i in range(lado):
pinta(x + i, y, color) # Lado superior
pinta(x + i, y + lado - 1, color) # Lado inferior
# Dibuja lados izquierdo y derecho (excluyendo las esquinas ya pintadas)
for j in range(1, lado - 1):
pinta(x, y + j, color) # Lado izquierdo
pinta(x + lado - 1, y + j, color) # Lado derecho
return True
def dibuja_rectangulo(x, y, ancho, alto, color="black"):
"""Dibuja el borde de un rectángulo en el lienzo."""
ancho_lienzo, alto_lienzo = tam_lienzo()
if x < 0 or y < 0 or x + ancho - 1 >= ancho_lienzo or \
y + alto - 1 >= alto_lienzo:
return False
# Dibuja solo el borde: lados superior e inferior
for i in range(ancho):
pinta(x + i, y, color) # Lado superior
pinta(x + i, y + alto - 1, color) # Lado inferior
# Dibuja lados izquierdo y derecho (excluyendo las esquinas ya pintadas)
for j in range(1, alto - 1):
pinta(x, y + j, color) # Lado izquierdo
pinta(x + ancho - 1, y + j, color) # Lado derecho
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 no cumple completamente con el enunciado. Aunque implementa las funciones requeridas y sigue la lógica básica de dibujo, presenta dos problemas críticos:
-
Error en el análisis de argumentos: En
lee_formas(), al detectar el color, se asume que cualquier argumento después de los obligatorios que no sea"cuad"o"rect"es un color. Esto falla si el color se llama"cuad"o"rect"(ej:python3 formas.py cuad 1 1 2 cuad), interpretándolo erróneamente como inicio de una nueva figura y causando errores de índice. -
Falta validación de parámetros mínimos por figura: Si se proporcionan argumentos incompletos para una figura (ej:
cuad 1 2sin el lado), el programa intentará acceder a índices fuera de rango enargumentos, generando unIndexErrorno controlado.
Es fácil de leer y entender
El código es medianamente comprensible para principiantes:
- Los nombres de variables y funciones son descriptivos (ej:
dibuja_cuadrado,lado). - Los comentarios explican la lógica de los bucles de dibujo, útil para entender cómo se pinta el borde.
-
Pero la lógica de
lee_formas()es compleja para principiantes: el uso dei += 5/i += 4y las condiciones anidadas para detectar el color dificultan su comprensión, especialmente al mezclar el control de índice con la detección de tipos de figura.
Sigue buenas prácticas de programación
No sigue buenas prácticas básicas:
-
Falta validación robusta: No se verifica que haya suficientes argumentos para cada figura antes de acceder a ellos (ej: para
cuadse necesitan al menos 4 argumentos después del tipo). -
Lógica frágil en
lee_formas(): La detección del color depende de que los nombres de colores no coincidan con"cuad"/"rect", lo cual es un supuesto peligroso. -
No se usa el valor de retorno de las funciones de dibujo: Aunque el enunciado pide que devuelvan
True/False,main()ignora estos valores, perdiendo oportunidad de notificar errores al usuario.
Recomendaciones de mejora
-
Valida parámetros por figura en
lee_formas():- Antes de procesar cada figura, verifica que haya suficientes argumentos restantes (ej: para
cuadnecesitas al menos 3 argumentos después del tipo). Si no, muestra un mensaje de error específico y termina.
- Antes de procesar cada figura, verifica que haya suficientes argumentos restantes (ej: para
-
Simplifica la detección del color:
- En lugar de depender de que el color no sea
"cuad"/"rect", define que el color siempre será el quinto argumento paracuad(si existe) y el sexto pararect(si existe), sin importar su valor. Ejemplo:# Para cuad if i + 4 < len(argumentos): color = argumentos[i + 4] i += 5 else: color = "black" i += 4
- En lugar de depender de que el color no sea
-
Usa el valor de retorno de las funciones de dibujo:
- En
main(), verifica sidibuja_cuadrado()/dibuja_rectangulo()devuelvenFalsee imprime un mensaje como"Error: Figura fuera del lienzo".
- En
-
Mejora los mensajes de error:
- En
lee_formas(), si faltan parámetros para una figura, indica cuál figura tiene el problema (ej:"Error: 'cuad' requiere 3 parámetros (x, y, lado)").
- En