PDA

Ver la Versión Completa : [ CONSULTA ] Tarea que continua antes de finalizar un Loop (For End for)


dj_janker
22/04/16, 12:16:30
Hola,
tengo un pequeño problema con un bucle For-End For dentro de una tarea.
El caso es que el proceso del bucle contiene varias variables que se deben comprobar, comparar, calcular, y tarda un poco.
En función de los resultados de las variables, estas se van escribiendo dentro de un archivo .csv
Hasta aquí bien. El problema que observo es como si la terea no respetara el proceso lógico. Es decir, si la estructura de la tarea es:

A1
For
A2
A3
End For
A4

Yo entiendo que A4 no se debe ejecutar hasta que no se hayan finalizado los distintos loops, para A2 y A3, programados dentro del For-End For.
Pero esto no ocurre así, ya que por ejemplo tras el loop tengo puesto que se envíe el archivo generado por email, hay veces que me da fallo porque no encuentra el archivo, ya que aún no ha acabado de generarse...
No sé si me explico.
La solución fácil es meterle una tarea Esperar, con un tiempo de 1 min. por ejemplo, pero es una opción "tosca", ya que el tiempo de finalización de mi bucle es variable, en función del número de items que le indique al inicio del mismo. La mayoría de las veces sobra con 1 minuto, pero hay caso en los que es necesario más tiempo.
Seguro que hay alguna opción, que estoy obviando, que permite continuar la tarea tras el End For, justo cuando este acaba, pero ahora mismo no doy con ella.
A ver si me podéis ayudar, por favor.

Muchas gracias.

Saludos.

WillyWeb
22/04/16, 13:06:03
Te has explicado perfectamente. Sin ver el código no es fácil ver las posibles causas de ese comportamiento. Por lo que cuentas, parece que esa secuencia de escrituras hacia el archivo CSV se queden atascadas en "una especie de buffer". Desde luego es raro, y no tengo claro que Tasker/Android funcionen así. ¿Haces llamadas a otras tareas dentro del bucle? ... eso podría explicar la demora en la escritura.

Posibles soluciones ¿...?

Lo que yo hago, siempre que puedo, es componer el archivo en una variable y luego escribir el contenido de la variable de una tacada en el archivo de salida. Una única escritura sin demoras, ni buffers, ni nada de nada ... zas ... todo de un golpe. Además de evitar problemas como el que sufres ahora mejora el rendimiento al minimizar los accesos a dispositivos externos (no mucho, pero algo es algo).

Pon aquí la tarea y lo miramos con calma.

dj_janker
22/04/16, 13:12:07
Te has explicado perfectamente. Sin ver el código no es fácil ver las posibles causas de ese comportamiento. Por lo que cuentas, parece que esa secuencia de escrituras hacia el archivo CSV se queden atascadas en "una especie de buffer". Desde luego es raro, y no tengo claro que Tasker/Android funcionen así. ¿Haces llamadas a otras tareas dentro del bucle? ... eso podría explicar la demora en la escritura.

Posibles soluciones ¿...?

Lo que yo hago, siempre que puedo, es componer el archivo en una variable y luego escribir el contenido de la variable de una tacada en el archivo de salida. Una única escritura sin demoras, ni buffers, ni nada de nada ... zas ... todo de un golpe. Además de evitar problemas como el que sufres ahora mejora el rendimiento al minimizar los accesos a dispositivos externos (no mucho, pero algo es algo).

Pon aquí la tarea y lo miramos con calma.

Esta es la tarea:

Pyc (104)
A1: Establecer variable [ Nombre:%molinos A:5 Calcular:Apagado Añadir:Apagado ]
A2: Establecer variable [ Nombre:%numfilas A:5*%molinos Calcular:Encendido Añadir:Apagado ]
A3: Establecer variable [ Nombre:%Int A:5 Calcular:Apagado Añadir:Apagado ]
A4: Establecer variable [ Nombre:%Idr A:1000 Calcular:Apagado Añadir:Apagado ]
A5: Establecer variable [ Nombre:%Tseg A:2.9 Calcular:Apagado Añadir:Apagado ]
A6: Si (if) [ %Tseg < 0.9 ]
A7: Establecer variable [ Nombre:%Vca A:72/%Tseg Calcular:Encendido Añadir:Apagado ]
A8: Fin si (End if)
A9: Si (if) [ %Tseg > 0.9 & %Tseg < 3 ]
A10: Establecer variable [ Nombre:%Vca A:78.5/(%Tseg^0.18) Calcular:Encendido Añadir:Apagado ]
A11: Fin si (End if)
A12: Si (if) [ %Tseg < 5 & %Tseg > 3 ]
A13: Establecer variable [ Nombre:%Vca A:64 Calcular:Encendido Añadir:Apagado ]
A14: Fin si (End if)
A15: Si (if) [ %Tseg > 5 ]
A16: Establecer variable [ Nombre:%Vca A:50 Calcular:Encendido Añadir:Apagado ]
A17: Fin si (End if)
A18: Flash [ Texto:%Vca Largo:Apagado ]
A19: Establecer variable [ Nombre:%max A:20 Calcular:Apagado Añadir:Apagado ]
A20: Establecer variable [ Nombre:%min A:1 Calcular:Apagado Añadir:Apagado ]
A21: For [ Variable:%num Ítems:1:%numfilas ]
A22: Variable aleatoria [ Nombre:%Vmas Mín:%min Máx:%max ]
A23: Variable aleatoria [ Nombre:%Vmenos Mín:%min Máx:%max ]
A24: Variable aleatoria [ Nombre:%Vcero Mín:%min Máx:%max ]
A25: Flash [ Texto:%Vmas %Vmenos %Vcero Largo:Apagado ]
A26: Si (if) [ %Vmas ig 0 & %Vmenos ig 0 & %Vcero ig 0 ]
A27: Establecer variable [ Nombre:%Vmmv A:" " Calcular:Apagado Añadir:Apagado ]
A28: Fin si (End if)
A29: Establecer variable [ Nombre:%VoGrande A:((%Vmas^2)/2)+((%Vmenos^2)/2)-(%Vcero^2) Calcular:Encendido Añadir:Apagado ]
A30: Si (if) [ %VoGrande < 0 ]
A31: Establecer variable [ Nombre:%Vmmv A:Vo Grande Calcular:Apagado Añadir:Apagado ]
A32: Else
A33: Establecer variable [ Nombre:%Vmmv A:sqrt(%VoGrande) Calcular:Encendido Añadir:Apagado ]
A34: Fin si (End if)
A35: Flash [ Texto:%Vmmv Largo:Apagado ]
A36: Si (if) [ %Vmas ig 0 & %Vmenos ig 0 & %Vcero ig 0 ]
A37: Establecer variable [ Nombre:%V_v A:" " Calcular:Apagado Añadir:Apagado ]
A38: Fin si (End if)
A39: Si (if) [ %Vmmv ig Vo Grande ]
A40: Establecer variable [ Nombre:%V_v A:(%Vcero/1000)*(%Idr/%Int) Calcular:Encendido Añadir:Apagado ]
A41: Else
A42: Establecer variable [ Nombre:%V_v A:(%Vmmv/1000)*(%Idr/%Int) Calcular:Encendido Añadir:Apagado ]
A43: Fin si (End if)
A44: Flash [ Texto:%V_v Largo:Apagado ]
A45: Escribir archivo [ Archivo:Download/test.csv Texto:%Vmas; %Vmenos; %Vcero; %Vmmv; %V_v; " "; " "; %Idr; %Int; %Tseg; %Vca Añadir:Apagado Añadir Nueva Línea:Encendido ]
A46: End For
A47: Leer Archivo [ Archivo:Download/test.csv A la variable:%test ]
A48: Flash [ Texto:%test Largo:Apagado ]

A ver si ves algo raro...

Pd:Por cierto, la idea con esta tarea es que cuando la ejecutara pidiera en una ventana de texto los valores de las 4 variables iniciales, pero eso supongo que es con Escenas, verdad?.... ese es un tema que no he tocado jamás

WillyWeb
22/04/16, 13:31:14
Procura meter las tareas/perfiles entre etiquetas [CODE] para que sean más fáciles de leer. Selecciona el texto y pulsa el icono de la (#) en la barra del editor de mensajes.

En la acción A45 tienes "Añadir:Apagado". Eso hace que por muchas vueltas que de el bucle tu archivo de salida sólo tenga una línea. ¿Es eso lo que pretendías?

Y para pedir esos valores iniciales no es imprescindible crear tu propia escena. Mira la acción "Consulta de Variable".

dj_janker
22/04/16, 14:19:54
Procura meter las tareas/perfiles entre etiquetas [CODE] para que sean más fáciles de leer. Selecciona el texto y pulsa el icono de la (#) en la barra del editor de mensajes.

En la acción A45 tienes "Añadir:Apagado". Eso hace que por muchas vueltas que de el bucle tu archivo de salida sólo tenga una línea. ¿Es eso lo que pretendías?

Y para pedir esos valores iniciales no es imprescindible crear tu propia escena. Mira la acción "Consulta de Variable".

Si, lo raro es que para ese ejemplo me genera las 25 filas en el .csv
He probado todas las combinaciones y esta es la que me funciona.
He tenido que hacer una acción "Mover archivo" para generar un archivo nuevo cada vez, si no se me añadían otras 25 líneas en el .csv cada vez que ejecutaba la tarea.

De todos modos cambiando esa opción el problema es el mismo, ejecuta las tareas finales, antes de acabar el loop completo.:cry:

Es super extraño.
Como podría meter todo en una variable antes del fin del loop, para escribirlo de golpe en el archivo, como proponías en tu primera respuesta?

dj_janker
22/04/16, 16:45:26
Se me ha ocurrido que a partir de la acción A46 End For, puedo meter una Tarea Esperar condicionada con Si-Fin Si en función de la variable inicial %molinos, que en cierto modo es la que marca el tiempo de proceso del Loop For-End For.

Con esto creo que lo soluciono.

Saludos.

WillyWeb
22/04/16, 17:51:14
Si, lo raro es que para ese ejemplo me genera las 25 filas en el .csv

Eso no debería pasar. Borra esa acción y la pones de nuevo ... algo se ha quedado atascado :oh:

He tenido que hacer una acción "Mover archivo" para generar un archivo nuevo cada vez, si no se me añadían otras 25 líneas en el .csv cada vez que ejecutaba la tarea.

Si no te interesa conservar los datos de una ejecución a otra puedes eliminar el archivo antes de empezar. Tasker tiene una acción directa para hacerlo.

Como podría meter todo en una variable antes del fin del loop, para escribirlo de golpe en el archivo, como proponías en tu primera respuesta?

Saca la acción de escribir archivo del bucle y en su lugar pon una de establecer variable (digamos que la llamas %archivo). Marca "Añadir" y en "Texto" pones lo que quieres que se añada a %archivo (cada línea del CSV en tu caso). Ya fuera del bucle usa la acción de escribir archivo pero en vez de cada línea pones la variable %archivo.

Se me ha ocurrido que a partir de la acción A46 End For, puedo meter una Tarea Esperar condicionada...

Como decías al principio, esa solución es "tosca". Esto tiene que tener una solución más "refinada" :risitas:

Caravantes
23/04/16, 23:09:31
Esta es la tarea:
...
A ver si ves algo raro...

En A22-A24 estableces tres variables aleatorias cuyos valores están en el margen de 1 a 20.
Sin embargo, luego en A26 abres una condición para el caso de que esas tres variables sean cero, lo cual creo que no puede suceder en ningún caso porque siempre tendrán valores entre 1 y 20. En A36 vuelves a usar esta condición "imposible".

A22: Variable aleatoria [ Nombre:%Vmas Mín:%min Máx:%max ]
A23: Variable aleatoria [ Nombre:%Vmenos Mín:%min Máx:%max ]
A24: Variable aleatoria [ Nombre:%Vcero Mín:%min Máx:%max ]
A25: Flash [ Texto:%Vmas %Vmenos %Vcero Largo:Apagado ]
A26: Si (if) [ %Vmas ig 0 & %Vmenos ig 0 & %Vcero ig 0 ]
...
A36: Si (if) [ %Vmas ig 0 & %Vmenos ig 0 & %Vcero ig 0 ]

En la acción A31, en lugar de poner "%VoGrande" has escrito "Vo Grande". Creo que falta el símbolo de variable (%) y sobra el espacio. Tasker está tomando eso como un texto literal en lugar de tomarlo como un nombre de variable.

A31: Establecer variable [ Nombre:%Vmmv A:Vo Grande Calcular:Apagado Añadir:Apagado ]

En A45 tienes una acción ESCRIBIR ARCHIVO AÑADIENDO NUEVA LÍNEA... Eso hace que las diferentes vueltas del bucle añadan líneas al archivo. Pero quizá deberías poner una acción previa para borrar el archivo o vaciarlo, si quieres que cada ejecución de la tarea comience con un archivo "vacío".

A45: Escribir archivo [ Archivo:Download/test.csv Texto:%Vmas; %Vmenos; %Vcero; %Vmmv; %V_v; " "; " "; %Idr; %Int; %Tseg; %Vca Añadir:Apagado Añadir Nueva Línea:Encendido ]

Yo también considero preferible la estrategia sugerida por Willy: que el bucle vaya añadiendo datos a una variable, y al final de la tarea pasas la variable a un archivo, de una sola vez (sin bucle).

En tu primer mensaje decías que
tras el loop tengo puesto que se envíe el archivo generado por email, hay veces que me da fallo porque no encuentra el archivo, ya que aún no ha acabado de generarse...
En la tarea que has puesto ya no hay ese envío por email. En lugar de eso, la tarea lee el archivo y luego lo muestra en una accion Flash ¿Te sigue fallando la estructura For-EndFor igual que comentabas al principio? ¿Se sigue pareciendo que se ejecuta el Flash antes de haber procesado todo el bucle?

WillyWeb
24/04/16, 11:45:55
A ver si ves algo raro...

Ves como cambia la cosa al poner las tareas/perfiles entre etiquetas [CODE] :oh:

La primera vez que he visto tu tarea todo lo que ha visto Caravantes después se me ha pasado por alto. :facepalm:

Es fácil que después de solucionar esos pequeños "fallos" la tarea funcione correctamente.

dj_janker
24/04/16, 11:56:29
Jeje, con las prisas olvidé poner la descripción como código y metí una versión que no era la última (con el envió de email y demás).
Es cierto el tema de la comparación de variables aleatorias que el caso de que todas sean cero no se podía dar, ya que iniciaban en 1. Eso ya lo cambié, aunque no creo que fuera el fallo. La otra asignación que comentó Caravantes no era un error, en ese caso la variable debe asignar el valor literal Vo Grande como un texto ni como una variable.
Finalmente los cambios que han hecho que funcione es meter un eliminar archivo Download/test.CSV antes del For y la eliminación y su correspondiente reescritura del Escribir archivo y End For.
Con esos cambios todo funciona como debería. ;)
P.D. he usado lo que me comentabas de Consulta de variable, que no conocía, y es genial.
Ahora tengo la tarea que necesitaba.

Mil gracias a los 2 por vuestra gran ayuda: WillyWeb y Caravantes


Enviado desde mi JY-S3 mediante Tapatalk