Seite 1 von 1
Schleifen abbruch nach gewisser Zeit
Verfasst: Dienstag 31. Januar 2017, 02:46
von 123GuteLaune
Hallo,
ich habe einen Code geschrieben der auf ein externes Programm zugreift. Leider entsteht bei dem externen Programm ab und zu ein Fehler. Dieser Fehler lässt python warten auf ein feedback. Diese Feedback wird niemals eintretten, sprich eine endlose Schleife.
Ich würde gerne in meine For If not schleife einen Art Timer einbauen, der nach Starten der Schleife und Aufbau der Verbindung zum externen Programm anfängt zu zählen. Falls ein es länger als 8 sec dauert soll er auf der Schleife springen den If else Befehl ausführen.
Derzeit hab ich einen Index geschrieben der bestimmte Zeilen ausschließt, die den Fehler verursachen, leider dauert es jedesmal lange bis er eine neue Zeile findet die falsch ist und die muss ich händisch eingeben und das ganze von vorne starten
Wie kann man sowas umsetzen? (Ich bin Anfänger)
Codeteil
Code: Alles auswählen
forbidden = [23975, 24733, 24735]
for index, ber in enumerate(bers):
if not(index in forbidden):
res.append(single_r_x13(ber,fc,r,index))
else:
res.append([np.nan] * fc)
print("---------%s sekunden fuer Arima %s ------" % (((time.time() - start_time)/ (index + 1)), index))
return res#np.array([single_r_x13(ber,fc,r) for ber in bers])
Re: Schleifen abbruch nach gewisser Zeit
Verfasst: Dienstag 31. Januar 2017, 07:20
von Sirius3
@123GuteLaune: Solange die Funktion single_r_x13 abgearbeitet wird, kann man nichts in der Schleife tun. Man müßte also beim Lesen vom externen Programm irgendwo in single_r_x13 einen Timeout einbauen.
Re: Schleifen abbruch nach gewisser Zeit
Verfasst: Dienstag 31. Januar 2017, 11:42
von 123GuteLaune
Ok also muss ich den Timer direkt in die Methode einbauen?
Die Methode greift auf ein Verfahren in R zurück das ich durch eine Schnittstelle in Python nutze
Leider weiß ich nicht wie man so einen Timer baut?
Code der Methode:
Code: Alles auswählen
def single_r_x13(ber,fc,r,c):
#print data
#r('library("seasonal")')
try:
print ber
r.assign("rdata%s" % c, ber)
#print(r("rdata%s" % c))
ts_str = "my_ts%s <- ts(rdata%s, start=c(2012, 1), end=c(2014,12), frequency=12)" % (c,c)
r(ts_str)
r("ar%s <- seas(my_ts%s, forecast.save = 'forecasts')" % (c,c))
r("res%s <- series(ar%s, 'forecast.forecasts')" % (c,c))
forecast = r.get('res%s' % c)[:, 0][:fc]
return forecast
except:# TypeError:
return [np.nan]*fc
Re: Schleifen abbruch nach gewisser Zeit
Verfasst: Dienstag 31. Januar 2017, 11:53
von BlackJack
@123GuteLaune: Ich denke damit verschiebt sich das Problem nach R. Was hängt denn dort und warum?
Re: Schleifen abbruch nach gewisser Zeit
Verfasst: Dienstag 31. Januar 2017, 13:58
von 123GuteLaune
In R rufe ich ein Zeitreihenprognoseprogramm auf. R nutzt dabei ein numpy array aus python.
Programmablauf: Python schickt ein array nach R, R führt eine spezielle Prognose aus, R gibt einen Array aus, Array wird zurück gegeben an Python, Python schreibt diesen Wert in mein Dict. und speichert dies dann als CSV datai
Da ich das ganze massenhaft mache, entsteht manchmal ein Fehler bei der Prognose und das Programm gibt mir einen Fehler zurück das es nicht funktioniert. Diese Problem hab ich gelöst mit dem Except-Part.
Es gibt aber anscheinend noch einen anderen Fehler der im Prognoseprogramm selber entsteht und das Programm einfriert, ich weiß nicht wieso diese Fehler entsteht...
Deswegen wollte ich beim Aufrufen des Programms einen Timer laufen lassen, wenn python kein Feedback nach 8 sec bekommt soll er diese Prognose Terminieren und denn except Schleife oder die IF else schleife durchlaufen...
Kann man sowas einbauen und wenn ja wie?
Re: Schleifen abbruch nach gewisser Zeit
Verfasst: Dienstag 31. Januar 2017, 14:32
von BlackJack
@123GuteLaune: Ich würde mal sagen das geht nicht wenn das nicht bereits in irgendeiner Weise vorgesehen ist.
Ein ”nacktes” ``except`` sollte man übrigens nicht verwenden, das behandelt *alle* Ausnahmen, und es gibt nicht viel sinnvolles was man für *alle* Ausnahmen machen kann.
Re: Schleifen abbruch nach gewisser Zeit
Verfasst: Dienstag 31. Januar 2017, 16:10
von 123GuteLaune
Shit ich dachte ich kann des irgendwie erzwingen,...
Des ist echt doof! :K
Der except Befehl ist gewollt, da alle fehlerhaften Prognose gleich 0 gesetzt werden.
Re: Schleifen abbruch nach gewisser Zeit
Verfasst: Dienstag 31. Januar 2017, 16:36
von BlackJack
@123GuteLaune: Aber der greift bei *allen* Ausnahmen, also zum Beispiel auch bei Programmierfehlern die Du gemacht hast, bei Speicherfehlern, bei allem womit Du nicht rechnest, die dann einfach ignoriert werden, beziehungsweise als NaN-Werte zurück gegeben werden. Das will man nicht. Man sollte immer nur die konkreten Ausnahmen behandeln die man auch erwartet, denn nur bei denen kann man auch sicher sagen das die Behandlung Sinn macht, und nicht die Fehlersuche erschwert oder verhindert.
Re: Schleifen abbruch nach gewisser Zeit
Verfasst: Mittwoch 1. Februar 2017, 14:16
von Nras
Moin,
man kann da meines Erachtens nach schon etwas machen. Ich würde die function einfach wrappen und mit dem @timeout-Dekorator von
dieser Stackoverflow Antwort versehen. Statt dem if-else Teil mit der händisch gepflegten Liste mit den indices, würdest du dann einen try-except Teil einbauen. Salopp ausgedrückt steht dann da: "Gib mir ein Ergebnis, vielleicht wirfst du einen TimeoutError, dann setze ich das Ergebnis selbst.
Das könnte dann ungefähr so aussehen:
Code: Alles auswählen
from functools import wraps
from datetime import datetime
import errno
import os
import signal
import time
import numpy as np
class TimeoutError(Exception):
pass
def timeout(seconds=10, error_message=os.strerror(errno.ETIME)):
def decorator(func):
def _handle_timeout(signum, frame):
raise TimeoutError(error_message)
def wrapper(*args, **kwargs):
signal.signal(signal.SIGALRM, _handle_timeout)
signal.alarm(seconds)
try:
result = func(*args, **kwargs)
finally:
signal.alarm(0)
return result
return wraps(func)(wrapper)
return decorator
@timeout(8)
def may_timeout_single_r_x13(ber, fc, r, index):
return single_r_x13(ber, fc, r, index)
def single_r_x13(ber, fc, r, index):
# irgendetwas wird diese Methode schon machen. Bei Index 2 und 3 braucht sie lange.
if index in [2, 3]:
time.sleep(20) # Dauert sehr lange
return [ber + r + index] * fc # anything
def main():
# irgendetwas fuer fc, r und bers setzen.
fc = 2
r = 5
bers = range(6)
res = []
for index, ber in enumerate(bers):
start_time = datetime.utcnow()
try:
result = may_timeout_single_r_x13(ber, fc, r, index)
except TimeoutError:
print(repr(e))
result = [np.nan] * fc
res.append(result)
print("---------%s sekunden fuer Arima %s ------" % (datetime.utcnow() - start_time, index))
print(res)
return
if __name__ == '__main__':
main()
Das Produziert bei mir folgenden output:
Code: Alles auswählen
---------0:00:00.000018 sekunden fuer Arima 0 ------
---------0:00:00.000014 sekunden fuer Arima 1 ------
TimeoutError('Timer expired',)
---------0:00:08.000142 sekunden fuer Arima 2 ------
TimeoutError('Timer expired',)
---------0:00:08.000195 sekunden fuer Arima 3 ------
---------0:00:00.000019 sekunden fuer Arima 4 ------
---------0:00:00.000012 sekunden fuer Arima 5 ------
[[5, 5], [7, 7], [nan, nan], [nan, nan], [13, 13], [15, 15]]
Re: Schleifen abbruch nach gewisser Zeit
Verfasst: Mittwoch 1. Februar 2017, 14:39
von BlackJack
@Nras: Von `signal`-Vodoo würde ich abraten. Das ist Unix-Systemprogrammierung die ein bis zwei Ebenen unter dem liegen was man mit Python üblicherweise macht. Es funktioniert nicht mit Threads und man muss sich darüber im klaren sein, dass das ein harter Ausstieg aus was immer gerade passiert ist. Da irgendwelche Garantien zu geben das alles in einem geordneten Zustand hinterlassen wird ist schwer. Im Falle des OP wahrscheinlich unmöglich, denn der Alarm kann ja mitten in einem Aufruf von R kommen. Wie soll man da sicherstellen, dass R und/oder die Python-Anbindung danach noch in einem ordentlichen Zustand sind? Der Code dort ist doch gar nicht darauf ausgelegt einfach so abgebrochen/unterbrochen zu werden.
Zumal das ``raise TimeoutError(error_message)`` nur greift wenn Python überhaupt die Kontrolle hat. Wenn das in R irgendwo hängt, kommt man da auch mit einer Python-Ausnahme nicht heraus.
Re: Schleifen abbruch nach gewisser Zeit
Verfasst: Mittwoch 1. Februar 2017, 19:12
von 123GuteLaune
Cool vielen Dank ich werde diese Methode mit dem Signal wrapper testen!
@BlackJack:
Du hast natürlich recht, das ich das eigentlich nicht machen sollte, aber da ich mehr als 1 Mio Zeitreihen prognostiziere, muss ich leider so agieren, da ich nicht alle Fehler ausmerzen kann!
Zudem scheint R auch kein Problem zu verursachen sondern das X13as (Statistik programm von US-Staat). Ich habe da mit den Leute wegen meinen Fehler gesprochen und die meint des Programm ist so heavy das kann keiner mehr so richtig greifen! Deswegen diese etwas harte und uncoole lösung!
Konkret teste ich, ob das Programm was taugt oder nicht wenn ich nur Prognose mit "nan" bekomme ist das Entscheidung gegen so einen Ansatz!
Re: Schleifen abbruch nach gewisser Zeit
Verfasst: Mittwoch 1. Februar 2017, 20:02
von BlackJack
@123GuteLaune: Das sollte man nicht nur *eigentlich* nicht machen, sondern das sollte man wirklich *nicht* machen. Selbst wenn es ”funktioniert” kannst Du nach dem ersten Timeout im Grunde keinen Ergebnissen mehr trauen, weil Du nicht weisst ob sich das alles noch in einem gültigen Zustand befindet.
Re: Schleifen abbruch nach gewisser Zeit
Verfasst: Mittwoch 1. Februar 2017, 21:53
von DasIch
Um BlackJack mal zu übersetzen: Dein Programm ist kaputt, da du das Signal nicht zuverlässig abfangen kannst. Wenn du eine mit timeout dekorierte Funktion aufrufst bekommst du nun entweder einen TimeoutError oder ein Ergebnis von dem du nicht ausgehen kannst dass es richtig ist.
Was du statt dessen machen könntest ist das externe Programm in einem eigenen Prozess laufen zu lassen. Du kannst dann problemlos auf ein Ergebnis warten oder ggfs. den Prozess killen. Das ist nicht wesentlich schwieriger, hat den gleichen Effekt und funktioniert garantiert.
Re: Schleifen abbruch nach gewisser Zeit
Verfasst: Mittwoch 1. Februar 2017, 22:14
von 123GuteLaune
Eigentlich wäre das auch mein Wunsch gewesen, leider weiß ich nicht wie das funktioniert zwei Prozesse laufen zu lassen.
Meine Vorstellung war:
Das ich sobald ich in meine Funktion in R Aufruf gleichzeitig eine Uhr in einem anderen Prozess starte, falls das Zeitlimit überschritten wird, soll der derzeitig Prozess abgebrochen werden also ganz normal ausgeschalten. Und bei Abbruch soll für meine Zeitreihe diese except Schleife laufen.
Könntest du mir sagen wo ich sowas nachlesen kann oder mir einen Beispielhaften Code geben?
Mein Programm code gesamt anbei!
Code: Alles auswählen
import numpy as np
import pyper as pr
import time
from csv_read import read_in
#path_folder = r'/Users/Backup/'
#data = read_in('X.csv',path_folder)[0]
#fc=18
def r_x13(bers, fc):
r = pr.R(RCMD='/usr/local/bin/R', use_numpy=True)
r('library("seasonal")')
if not (type(bers) is np.array):
bers = np.array(bers)
res = []
start_time = time.time()
forbidden = [23975, 24733, 24735]
for index, ber in enumerate(bers):
if not(index in forbidden):
res.append(single_r_x13(ber,fc,r,index))
else:
res.append([np.nan] * fc)
print("---------%s sekunden fuer Arima %s ------" % (((time.time() - start_time)/ (index + 1)), index))
return res#np.array([single_r_x13(ber,fc,r) for ber in bers])
def single_r_x13(ber,fc,r,c):
try:
print ber
r.assign("rdata%s" % c, ber)
ts_str = "my_ts%s <- ts(rdata%s, start=c(2012, 1), end=c(2014,12), frequency=12)" % (c,c)
r(ts_str)
r("ar%s <- seas(my_ts%s, forecast.save = 'forecasts')" % (c,c))
r("res%s <- series(ar%s, 'forecast.forecasts')" % (c,c))
forecast = r.get('res%s' % c)[:, 0][:fc]
return forecast
except:# TypeError:
return [np.nan]*fc
Re: Schleifen abbruch nach gewisser Zeit
Verfasst: Mittwoch 1. Februar 2017, 22:41
von Sirius3
@123GuteLaune: vielleicht hilft es schon die Dokumentation zu dem Modul zu lesen, das Du da benutzt:
Some errors in command strings sent to R can be fatal to PypeR!
For example, incomplete command strings, typically, missing quotes or parentheses, will lead to a dead waiting: R is waiting for more input from Python while Python is trying to getting output from R.
In Such cases, the user has to press "Ctrl - C" to break the pipe, and restart R again. So far I have no idea for a solution for this problem.
Da hilft es vielleicht schon, ein etwas ausgereifteres Paket zu benutzen, statt eins, das bald seit 3 Jahren nicht mehr weiter entwickelt wird. Was bietet denn diese csv_read mehr, was nicht numpy auch könnte?
Den Typ explizit zu prüfen, ist schlecht, da es der Objektorientierung widerspricht. In Deinem Fall ist der richtige Weg das Prüfen numpy.asanyarray zu überlassen.
Re: Schleifen abbruch nach gewisser Zeit
Verfasst: Mittwoch 1. Februar 2017, 23:21
von 123GuteLaune
Hi Sirius,
ich habe eine wissenschaftliche Abhandlungen über die gängisten R inferface gelesen und dabei hat diese Modul am besten abgeschnitten. Ich ruf ja auch nur eine Methode auf der R rest läuft ja dann in R.
ich habe meine Daten überprüft sie werden richtig übergeben und es hat für andere Datein super geklappt!
Sprich R und Python sind gut zu einander!
Das Problem ist das externe Prognoseprogramm, dass ich Aufrufe durch R! Anscheinend ist im Interface von R und diesem Programm ein Problem nicht abgedeckt und R warte auf Feedback das es an Python übergeben kann.
Mehr konnte ich bis jetzt noch nicht rausfinden... Es gibt auch ein Inferface von python direkt zu diesem Programm, aber des ist noch viel älter und weitaus langsamer, deswegen kommt der für mich nicht in Betracht
http://statsmodels.sourceforge.net/0.6. ... hlight=x13
Das csv.read ist nur meine Datei, wo ich meine Zeitreihen die ich gemacht habe einlese in die entsprechende Form das R und das Programm was anfangen kann! Wie gesagt ich habe schon 600.000 Prognosen berechnet so weit so gut nur fehlen mir noch 400.000 und diese Fehler tritt nur selten auf in 25.000 Prognose waren es 3 mal.
Re: Schleifen abbruch nach gewisser Zeit
Verfasst: Freitag 3. Februar 2017, 12:38
von Nras
Hallo,
BlackJack hat geschrieben:@123GuteLaune: Das sollte man nicht nur *eigentlich* nicht machen, sondern das sollte man wirklich *nicht* machen. Selbst wenn es ”funktioniert” kannst Du nach dem ersten Timeout im Grunde keinen Ergebnissen mehr trauen, weil Du nicht weisst ob sich das alles noch in einem gültigen Zustand befindet.
also ich benutze diesen timeout Dekorator für so einiges, mir ist nie aufgefallen, dass unplausible Werte geliefert werden, nachdem so ein TimeOut stattfand. Könnest du dafür ein simples Beispiel produzieren?
Gruß,
Nras.