AutoCad - Mi rutina Lisp se queda cargando

 
Vista:
sin imagen de perfil
Val: 4
Ha aumentado su posición en 3 puestos en AutoCad (en relación al último mes)
Gráfica de AutoCad

Mi rutina Lisp se queda cargando

Publicado por ErikaM (2 intervenciones) el 19/04/2021 11:35:06
Buen día. Me gustaría saber por qué mi rutina Lisp se queda cargando pero no ejecuta nada.
Soy nueva programando en AutoLisp, quizá se me esté pasando algun detalle
Es una rutina para que, a partir de un archivo csv, en cad se puedan insertar leaders con el ID, y las coordenadas x y y en su respectiva coordenada.
Ya intenté cargarlo a AutoCAD pero se queda cargando y no hace nada pero si oprimo esc en la ventana de comandos me aparece ; error: Function cancelled. No sé si sea muy pesada la rutina o sean demasiados procesos.
De antemano, muchas gracias

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
(defun c:INDIC3(/ arreglo ident dda darch letras x y id xt yt pt pt1 aii)
(setvar "cmdecho" 0)
(setq arreglo (list))
(setq ident "")
(setq aii 1)
(setq dda (getfiled "Selecciona un archivo" "" "" 4))
(setq darch ( open dda "r"))
(while (/= aii nil)
	(setq aii (read-char darch))
	(while (/= aii nil)
				(setq letras (chr aii))
				(if (/= letras "\n")
					(if ( = letras ",")
						(progn
							(setq arreglo(cons ident arreglo))
							(setq ident "")
						)
						(setq ident (strcat ident letras))
					)
					(progn
						(setq y (atof (car arreglo)))
						(setq x (atof (cadr arreglo)))
						(setq id (caddr arreglo))
						(setq xt (strcat "X = " (rtos x 2 2)))
						(setq yt (strcat "Y = " (rtos y 2 2)))
						(setq pt (list x y))
						(setq pt1 (list x (+ y 10)))
						(command "_leader" pt pt1 "" id xt yt "" )
						(setq arreglo (list))
					)
				)
	)
)
(close darch)
(princ)
(prompt "\nEventos cargados exitosamente")
(setvar "cmdecho" 0)
)
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
sin imagen de perfil
Val: 1.285
Oro
Ha mantenido su posición en AutoCad (en relación al último mes)
Gráfica de AutoCad

Mi rutina Lisp se queda cargando

Publicado por Gerardo (986 intervenciones) el 19/04/2021 21:39:12
Hola

Respondiendo a tu pregunta, el motivo por el cual se pega es porque tiene un bucle infinito.

Fijate que tienes un While anidado dentro de otro. En el mas externo no hay problema, porque en algun momento read-char devolverá nil y saldrá del bucle al terminar de recorrer el archivo, pero el while interno no tiene ninguna instrucción que cambie el valor de la variable aii, por lo que una vez que entra al leer la primera letra se quedará procesando el if permanentemente con el mismo valor de aii.

Ese tipo de proceso se resuelve con un solo while ya que estás leyendo secuencialmente caracter por caracter y procesando cada uno de ellos hasta el final del archivo. El segundo while jugaría por ejemplo si en el primero estuvieras leyendo palabras o lineas completas y dentro quisieras procesar cada línea, que en realidad es como yo lo resolvería. Leer linea por linea con la función Read-line y luego en un bucle interno localizar las comas para separar las coordenadas o "palabras" (eso solventa una restricción que tiene tu solución y es que el archivo de texto debe terminar con un y solo un salto de líena. Si no tiene ese salto la ultima linea no se procesa y si tiene más de uno dará error tratando de crear otro rótulo con datos nulos)

Mira esta versión de tu solución:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
(defun c:INDIC3 (/ arreglo ident dda darch letras x y id xt yt pt pt1 aii)
	(setvar "cmdecho" 0)
	(setq ident ""
			dda (getfiled "Selecciona un archivo" "" "" 4)
			darch (open dda "r")
	)
	(while (setq aii (read-char darch))
		(setq letras (chr aii))
		(if (/= letras "\n")
			(if (= letras ",")
				(setq arreglo (cons ident arreglo)
						ident ""
				)
				(setq ident (strcat ident letras))
			)
			(progn
				(setq y (atof (car arreglo))
						x (atof (cadr arreglo))
						xt (strcat "X = " (rtos x 2 2))
						yt (strcat "Y = " (rtos y 2 2))
						pt (list x y)
						pt1 (list x (+ y 10))
						arreglo nil
				)
				(command "_leader" pt pt1 "" ident xt yt "")
				(setq ident "")
			)
		)
	)
	(close darch)
	(prompt "\nEventos cargados exitosamente")
	(setvar "cmdecho" 0)
	(princ)
)

Además de lo del doble bucle fijate que esta linea (setq id (caddr arreglo)) no tiene sentido porque en ningun momento agregaste el id al arreglo. Esto debe hacerse en el caso de que se encuentre el salto de linea. Yo lo resumi colocando de una vez la variable ident (que es la que contiene el id despues de un "\n") en el command, pero si quieres hacer un par de pasos de más con tal de verlo más claro la lógica sería como esto:
1
2
3
4
5
6
7
8
9
10
11
12
13
(if (/= letras "\n")
			(if (= letras ",")
				(setq arreglo (cons ident arreglo)
						ident ""
				)
				(setq ident (strcat ident letras))
			)
			(progn
				(setq arreglo (cons ident arreglo)
						y	(atof (cadr arreglo))
						x	(atof (caddr arreglo))
						id	(car arreglo)
						xt	...
quedando id en el car y no en el caddr porque lo agregamos con cons de ultimo, por lo tanto el el primer elemento de la lista
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
2
Comentar
sin imagen de perfil
Val: 4
Ha aumentado su posición en 3 puestos en AutoCad (en relación al último mes)
Gráfica de AutoCad

Mi rutina Lisp se queda cargando

Publicado por Erika (2 intervenciones) el 20/04/2021 03:58:33
¡Muchísimas gracias! Me dedicaré a analizar más a detalle el código. El mío es algo largo y tedioso debido a que no llevo mucho tiempo programando en Lisp, espero mejorar con el tiempo, pero con tu respuesta ya me quedó más claro todo :)
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar