PROBLEMA - saltar la funcion INPUT luego de X segundos

Buenas tardes a todos

Soy Ingeniero, de La Plata, Bs. As. y programo (a nivel bastante basico) en la mayoria de los casos por hobby, y alguna que otra vez, por cuestiones laborales o de estudio.

En esta oportunidad llegue hasta aca, por recomendacion de un docente, para ver si algun aficionado y habilidoso en Python, me puede ayudar con un pequeno problema.

Tratando de no extenderme, cuento brevemente lo que intento hacer, y el problema que me surgio. (adjunto imagen del codigo de ejemplo)

LO QUE INTENTO HACER: Es un programa, el cual realiza diversas acciones dentro de un bucle (“while True”), es decir el bucle se ejecuta indefinidamente mientras se realizan esas acciones. Entre esas cosas que realiza el programa, intento realizar lo siguiente: ingresar un “string” (o caracter), ingresandolo desde el teclado, y en el momento que yo desee, mientras se ejecuta el codigo dentro del bucle “while True” el cual realiza diversas acciones.

EL PROBLEMA: El problema surge al intentar ingresar el string por teclado en el momento en que yo desee.
Al problema lo abordé con la función input(). Esta función, al momento en que se llama, frena la ejecucion del código, esperando (INDEFINIDAMENTE) que desde el teclado se ingresen caracteres, seguido por la tecla “ENTER”. Una vez presionado el ENTER, la funcion input() lee los caracteres. Para solucionar el inconveniente de que la funcion input() frena la ejecucion del codigo indefinidamente, ésta se debe llamar indirectamente, mediante un metodo, llamado func_timeout. Este metodo requiere (minimamente) que se le pasen dos argumentos. El primero es un TIMEOUT, y el segundo, una funcion X. Lo que hace el metodo func_timeout es, llamar a la funcion X, y si esta no se termina de ejecutar antes de un tiempo TIMEOUT (n° de segundos), el metodo func_timeout sale de la funcion X y ejecuta una expcecion.
Entonces, lo que he hecho es llamar a la funcion input() mediante el metodo func_timeout y lo he intentado hacer funcionar en un ejemplo muy simple adjuntado al presente mensaje (antes de meterlo al codigo completo) pero tiene un inconveniente, que lo hace inutil. En el ejemplo adjuntado, el metodo func_timeout se encuentra en un bucle indefinido (while True). Entonces, por cada vez que se ejecuta el bucle, el metodo func_timeout llama a la funcion input(), y esta queda esperando a que se ingresen caracteres + tecla ENTER. Si el caracter se ingresa antes del TIMEOUT, la funcion input() los lee, y termina de ejecutarse, es decir, el metodo func_timeout no llama a la excepcion. En caso de que no se ingresen caracteres luego de un tiempo TIMEOUT, el metodo llama al excepcion y el resto de codigo que haya en el bucle “while True” se sigue ejecutando. ACA ESTA EL PROBLEMA EN PARTICULAR (y me ha costado darme cuenta de lo siguiente): Por cada vez que se ejecuta el bucle “while True”, y no se ingresan caracteres (es decir, se llama a la excepcion) si yo luego de N bucles (sin ingresar caracteres), quiero ingresan algun caracter, debo apretar N veces la tecla ENTER y recien ahi puedo ingresar los caracteres (+ tecla ENTER). Si yo no apreto N veces tecla ENTER, la funcion input() no me lee los caracteres.
Lo anteriormente explicado hace inutil al codigo, porque la idea de la funcionalidad es, simplemente escribir los caracteres que se deseen (+ tecla ENTER) y simplemente guardarlos en una variable por ejemplo, en el momento en que se desee.
Como intento de solucion, se me ocurrio agregar N saltos de linea (\n), mediante un contador que cuente el numero de veces que no se ingresan caracteres, pero lo que me hacia el codigo era simplemente imprimir en pantalla N saltos de linea, es decir no me simulaba “el apretar N veces la tecla ENTER”.

Espero haber sido claro, pero es complicado comentar un problema de un codigo por escrito.

Adjunto el codigo (explicado linea por linea) por si a algun aficionado, le gusta poner a prueba sus conocimientos, y superarse cada dia jaja (Yo llevo dos dias y no he podido)

Saludos, y que la fuerza los acompane

Parecería que el problema que tenés es que el input que estás ejecutando te queda tomando datos del standard input del sistema.

O sea, vos estás llamando a request con algo que lo ejecuta en otro thread y corta ese thread (*) si pasó demasiado tiempo, pero el input que se corrió adentro de ese thread queda “enganchado”.

Por eso es que tenés que darle “varios enters”, porque con cada uno “cerrás” el input que llamás en la linea 12.

Lamentablemente lo que tenés que usar es un “input no bloqueante”. Hay mucho sobre eso, escrito por todos lados; por ejemplo. Digo “lamentablemente” porque lidiar con un input no bloqueante no es muy sencillo (pasás a tomar letra por letra, tenés que considerar buffers vos mismo, etc.)

Es más, te diría que no te metas en ese bardo, sino que vayas directamente a un modelo donde hacés el input directamente en un thread aparte que manejás vos, y comunicás lo que leés del usuario por un queue al programa principal.

(*) “corta ese thread”: puedo estar equivocado, pero creo que “cortar threads” es imposible, al menos en todos los casos y de forma sana; estuve viendo el código de func-timeout y es una chanchada atrás de la otra para tratar de levantar la excepción esa desde adentro del thread…

trio es una biblioteca piola para manejar programación concurrente cooperativa. En algunos casos permite utilizar threads aunque trio actúa como wrapper. Para tu caso, trio incorpora cancellation y timeouts.