Seite 1 von 2

auf input 30s lang warten und dann Programm von vorne starten

Verfasst: Donnerstag 28. Februar 2019, 16:07
von waldi
Hallo,
Ich bin noch neu bei Python und suche eine Möglichkeit um auf einen input zu warten und wenn keiner nach 30 s kommt, soll das Programm wieder neu starten.

Ich würde mich auf eine baldige Antwort freuen.
MFG waldi

Re: auf input 30s lang warten und dann Programm von vorne starten

Verfasst: Donnerstag 28. Februar 2019, 16:35
von __deets__
Wo findet der Input denn statt? In der Konsole? In einer GUI?

Re: auf input 30s lang warten und dann Programm von vorne starten

Verfasst: Donnerstag 28. Februar 2019, 19:08
von waldi
In der Konsole

Re: auf input 30s lang warten und dann Programm von vorne starten

Verfasst: Donnerstag 28. Februar 2019, 19:32
von __deets__
Dann musst du dir etwas zb mit dem ncurses Modul bauen. wenn du Windows nutzt muss du wohl das hier dazu installieren https://www.lfd.uci.edu/~gohlke/pythonlibs/#curses

Re: auf input 30s lang warten und dann Programm von vorne starten

Verfasst: Donnerstag 28. Februar 2019, 20:21
von waldi
vielen Dank für die schnelle Antwort werde es gleich mal austesten
LG waldi

Re: auf input 30s lang warten und dann Programm von vorne starten

Verfasst: Freitag 1. März 2019, 18:04
von waldi
Ich hab da noch einige Probleme mit curses das ist was ich soweit geschrieben haben aber das will noch nicht ganz so funktionieren wie ich mir das vorstelle.
Und bräuchte nochmal hilfe.

LG waldi

Code: Alles auswählen

k = 0
i=0 
stdscr = curses.initscr()
stdscr.clear()
stdscr.refresh()
while (i<2):
    k = stdscr.getch()
  
    if (k == ord('\n')):
       
        break
    else:
          time.sleep(1)
          i=i+1
print('Schleife Ende')

Re: auf input 30s lang warten und dann Programm von vorne starten

Verfasst: Freitag 1. März 2019, 18:07
von __deets__
Bitte code-tags benutzen. Und die Antwort auf deine Frage ist hier in der Dokumentation beschrieben:

https://docs.python.org/3/howto/curses.html#user-input

Du musst curses sagen, dass du nicht auf Eingaben warten willst, damit du deine Schleife zum Zeit-verstreichen-lassen laufen lassen kannst.

Re: auf input 30s lang warten und dann Programm von vorne starten

Verfasst: Freitag 1. März 2019, 18:47
von waldi
ok danke probier ich dann mal aus

Re: auf input 30s lang warten und dann Programm von vorne starten

Verfasst: Samstag 2. März 2019, 18:41
von darktrym
Timer geht wohl nicht?

Re: auf input 30s lang warten und dann Programm von vorne starten

Verfasst: Samstag 2. März 2019, 19:07
von __deets__
Welcher Timer denn? threading.Timer?

Re: auf input 30s lang warten und dann Programm von vorne starten

Verfasst: Samstag 2. März 2019, 23:52
von darktrym
Kennst du noch einen? Ja.

Re: auf input 30s lang warten und dann Programm von vorne starten

Verfasst: Sonntag 3. März 2019, 00:25
von __blackjack__
Dann würde ich sagen Timer geht wohl nicht.

Re: auf input 30s lang warten und dann Programm von vorne starten

Verfasst: Sonntag 3. März 2019, 01:21
von __deets__
darktrym hat geschrieben: Samstag 2. März 2019, 23:52 Kennst du noch einen? Ja.
Na ich bin gespannt, wie du den dazu bekommst, eine blockierende Eingabeoperation im Hauptthread zu unterbrechen. 🍺🍿

Re: auf input 30s lang warten und dann Programm von vorne starten

Verfasst: Sonntag 3. März 2019, 08:57
von darktrym
Spontan, Eingabe in einem Thread um die GUI von der Logik zu entkoppeln.
Die andere Lösung sieht für mich nach fürchterlichen Spaghetticode aus.

Re: auf input 30s lang warten und dann Programm von vorne starten

Verfasst: Sonntag 3. März 2019, 10:29
von __blackjack__
@darktrym: Der OP hat keine GUI sondern will das in der Konsole machen. Spaghetticode würde GOTOs beinhalten. Wenn auf „input warten“ auch tatsächlich ein `input()`-Aufruf gemeint sein darf, ginge es vielleicht tatsächlich mit einem `threading.Timer`, aber nicht alleine sondern man bräuchte noch Signale dazu. Es sieht aber halt so aus als wenn Du Deine Antwort nicht zuende durchdacht hattest, denn nur beim Timer fehlt halt noch der Teil wie man denn eine blockierende Eingabe abbrechen soll.

Mit `select` könnte man vielleicht auch eine Lösung basteln.

Aber wenn auf einzelne Tasten direkt reagiert werden soll, dann ist `curses` wahrscheinlich die einfachste Lösung bevor man anfängt selbst low-level Konsolencode zu schreiben.

Re: auf input 30s lang warten und dann Programm von vorne starten

Verfasst: Sonntag 3. März 2019, 11:04
von __deets__
Das Problem nicht überrissen haben, aber anderer Leute Lösung erstmal als Spaghetticode abkanzeln. 👍🏻

Online-Diskussion sind doch immer wieder Beste.

Re: auf input 30s lang warten und dann Programm von vorne starten

Verfasst: Mittwoch 6. März 2019, 16:10
von waldi
Ich hab eine Lösung gefunden
hab damit zwar anfangs noch ein paar Probleme gehabt aber es Funktioniert



Code: Alles auswählen

import time
from threading import Thread
from pynput.keyboard import Key, Controller




keyboard = Controller()
eingabe = None
def zeit():
    time.sleep(3)
    if eingabe != None:
        return
    keyboard.press(Key.enter)
    keyboard.release(Key.enter)
    print("Zu langsam")
        
        
Thread(target = zeit).start()
eingabe = input("eingabe: ")


print(eingabe)

Re: auf input 30s lang warten und dann Programm von vorne starten

Verfasst: Mittwoch 6. März 2019, 16:24
von __deets__
Puh. Loesung ist jetzt relativ. Wenn ich in Sekunde 29 anfange zu tippen und zur Haelfte durch bin, und dann ballerst du mir ein return rein, ist ja auch eher Mist. Und wenn ich angefangen habe etwas einzutippen wie "12345", aber dein return kommt bei "123", dann unterscheidest du das nicht von einer nicht-eingabe.

Re: auf input 30s lang warten und dann Programm von vorne starten

Verfasst: Mittwoch 6. März 2019, 16:34
von __blackjack__
Und dann hätten wir da noch globale Variablen und das auch noch in Verbindung mit Threads. Iiiiihhh.

Re: auf input 30s lang warten und dann Programm von vorne starten

Verfasst: Mittwoch 6. März 2019, 16:45
von __deets__

Code: Alles auswählen

import time
from curses import wrapper, error



def input_with_timeout(screen, text, timeout=30):
    then = time.monotonic() + timeout
    res = []
    while time.monotonic() < then:
        try:
            key = screen.getkey()
            if key == '\n':
                return ''.join(res)
        except error:
            pass
        else:
            res.append(key)
            then = time.monotonic() + timeout

def main(stdscr):
    # Clear screen
    stdscr.clear()
    stdscr.nodelay(True)
    while True:
        eingabe = input_with_timeout(stdscr, "Bitte eingabe:", 3)
        if eingabe is not None:
            print("Echte eingabe:", eingabe, end="\r\n")
        else:
            print("Timeout aufgetreten\r\n")

if __name__ == '__main__':
    wrapper(main)
Das kommt ohne Threads, externe Module und ohne komische Zwischenergebnisse aus. Jede Eingabe verlaengert wieder die Wartezeit.