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

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
waldi
User
Beiträge: 6
Registriert: Donnerstag 28. Februar 2019, 15:52

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
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wo findet der Input denn statt? In der Konsole? In einer GUI?
waldi
User
Beiträge: 6
Registriert: Donnerstag 28. Februar 2019, 15:52

In der Konsole
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

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
waldi
User
Beiträge: 6
Registriert: Donnerstag 28. Februar 2019, 15:52

vielen Dank für die schnelle Antwort werde es gleich mal austesten
LG waldi
waldi
User
Beiträge: 6
Registriert: Donnerstag 28. Februar 2019, 15:52

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')
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

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.
waldi
User
Beiträge: 6
Registriert: Donnerstag 28. Februar 2019, 15:52

ok danke probier ich dann mal aus
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Timer geht wohl nicht?
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Welcher Timer denn? threading.Timer?
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Kennst du noch einen? Ja.
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
Benutzeravatar
__blackjack__
User
Beiträge: 13533
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Dann würde ich sagen Timer geht wohl nicht.

Code: Alles auswählen

- (void)countSheep {
    unsigned int sheep = 0;
    while ( ! [self isAsleep]) { ++sheep; }
}
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

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. 🍺🍿
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

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.
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
Benutzeravatar
__blackjack__
User
Beiträge: 13533
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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.

Code: Alles auswählen

- (void)countSheep {
    unsigned int sheep = 0;
    while ( ! [self isAsleep]) { ++sheep; }
}
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das Problem nicht überrissen haben, aber anderer Leute Lösung erstmal als Spaghetticode abkanzeln. 👍🏻

Online-Diskussion sind doch immer wieder Beste.
waldi
User
Beiträge: 6
Registriert: Donnerstag 28. Februar 2019, 15:52

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)
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

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.
Benutzeravatar
__blackjack__
User
Beiträge: 13533
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Und dann hätten wir da noch globale Variablen und das auch noch in Verbindung mit Threads. Iiiiihhh.

Code: Alles auswählen

- (void)countSheep {
    unsigned int sheep = 0;
    while ( ! [self isAsleep]) { ++sheep; }
}
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

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.
Antworten