Seite 3 von 4
Re: Durchlaufzeit von Funktionen rausfinden / Datum angeben
Verfasst: Samstag 10. Januar 2015, 20:20
von BlackJack
@Serpens66: Irgendwie scheinst Du nichts wirklich zu verstehen und Dir stattdessen alles aus Beispielen und wildem Durchprobieren von allem was Dir in den Sinn kommt, zusammenzuhacken. So funktioniert programmieren nicht. Die `submit()`-Methode nimmt als erstes Argument die Funktion, und als weitere Argumente beliebig viele Positions- und dann Schlüsselwortargumente. Da ist doch sogar ein Beispiel in der Dokumentation.
Die Klasse `TheTest` sieht in der Verwendung genau so komisch aus wie `Boerse2Rock` vorher. Wenn in der `__init__()` nichts steht und man jede ”Methode” ausführt in dem man ein Exemplar von dem Datentyp erstellt, die ”Methode” ausführt, und dann das Exemplar sofort wieder wegwirft, dann ist das keine Klasse und keine Methoden sondern eine umständliche Art Funktionen und deren Aufrufe zu schreiben.
Re: Durchlaufzeit von Funktionen rausfinden / Datum angeben
Verfasst: Samstag 10. Januar 2015, 20:33
von Serpens66
BlackJack hat geschrieben:@Serpens66: Irgendwie scheinst Du nichts wirklich zu verstehen und Dir stattdessen alles aus Beispielen und wildem Durchprobieren von allem was Dir in den Sinn kommt, zusammenzuhacken. So funktioniert programmieren nicht. Die `submit()`-Methode nimmt als erstes Argument die Funktion, und als weitere Argumente beliebig viele Positions- und dann Schlüsselwortargumente. Da ist doch sogar ein Beispiel in der Dokumentation.
Ja stimmt, ich bastel mir so lange was aus beispielen zusammen und probiere rum was passiert, bis ich es beim fünften mal basteln dann automatisch verstanden habe, wie es funktioniert

so macht das lernen wenigstens spaß

(aber bitte lass uns nicht wieder darüber diskutieren. Ich möchte so programmieren lernen, wie ich es für richtig halte)
Ach und natürlich habe ich auf diese Weise mittlerweile schon so einiges verstanden und gelernt, sonst würde ich ja garnicht vorwärts kommen
Allerdings ist das bei *args gerade nicht der Fall. Da habe ich es doch alles richtig und so wie du schreibst gemacht, oder nicht?
Das einzige Problem was ich bei args habe ist:
Wie rufe ich innerhalb einer Klasse eine Variable auf, die in einer Funktion einer anderen Klasse definiert wird.
(du wolltest doch, dass ich genau schreibe, was ich schon ausprobiert habe?

)
BlackJack hat geschrieben:
Die Klasse `TheTest` sieht in der Verwendung genau so komisch aus wie `Boerse2Rock` vorher. Wenn in der `__init__()` nichts steht und man jede ”Methode” ausführt in dem man ein Exemplar von dem Datentyp erstellt, die ”Methode” ausführt, und dann das Exemplar sofort wieder wegwirft, dann ist das keine Klasse und keine Methoden sondern eine umständliche Art Funktionen und deren Aufrufe zu schreiben.
Die Klasse `Boerse2Rock` kennst du doch garnicht =P Dort sind in der init Funktion der Klasse zahlreiche self.xxx Variablen definiert, welche dann innerhalb der ganzen funktionen in der Klasse verwendet werden. Dass ich das nun nicht alles in die Thetest() Klasse übernehme ist denke ich klar, es dient ja nur dem testen und muss daher nur die dinge enthalten, die ich testen will =P
Ich sehe den Sinn in Klassen so:
1. self.variablen sind in allen Funktionen übergreifend aufruf- und veränderbar.
2. ohne eine Klasse müssen die Funktionen in einer bestimmten Reihenfolge definiert werden, weil sie sonst evtl aufgerufen werden, bevor sie überhaupt definiert werden. Daher ist allein aus diesen Grund, selbst ohne self.varaiblen, eine Klasse sinnvoll.
Welche Gründe gibts noch?
Re: Durchlaufzeit von Funktionen rausfinden / Datum angeben
Verfasst: Samstag 10. Januar 2015, 20:46
von Sirius3
@Serpens66: Du suchst hier Hilfe und wir können nur an dem, was Du schreibst abschätzen, was die verstehst und wie Du Dinge umsetzt. Die Erfahrung zeigt, dass BlackJack auffallend oft richtig in dieser Einschätzung liegt. Was Argumente und Funktionen sind, solltest Du noch weiter üben, bevor Du Dich daran machst, diese parallel ausführen zu wollen. Da Funktionen nie auf Modulebene aufgerufen werden, ist es völlig egal, in welcher Reihenfolge sie definiert werden.
Re: Durchlaufzeit von Funktionen rausfinden / Datum angeben
Verfasst: Samstag 10. Januar 2015, 20:58
von Serpens66
Sirius3 hat geschrieben:@Serpens66: Du suchst hier Hilfe und wir können nur an dem, was Du schreibst abschätzen, was die verstehst und wie Du Dinge umsetzt. Die Erfahrung zeigt, dass BlackJack auffallend oft richtig in dieser Einschätzung liegt. Was Argumente und Funktionen sind, solltest Du noch weiter üben, bevor Du Dich daran machst, diese parallel ausführen zu wollen.
Könnt ihr mir dennoch meine Fragen beantworten? Also z.b wie das ganze nun ohne "eval()" und strings geht.
Klar habe ich hier und da bei den basics Schwächen. Aber diese lerne ich automatisch mit, wenn ich mein ziel verfolge.
Z.b die eben erwähnten Vorteile von Klassen habe ich auch beim Machen rausgefunden. Ich wusste nicht, warum ich Klassen überhaupt brauche. Aber dadurch dass ich gemerkt habe, dass es ohne eine Klasse etwas umständlich ist, verwende ich sie nun also.
Deswegen sehe ich kein Problem darin, weiterhin auf diese Art und Weise zu lernen. Man muss doch nicht alles immer nach Lehrbuch machen und stumpf ohne Spaß etwas auswendig lernen. Beim Programmieren ist ausprobieren doch das A und O um sich etwas einzuprägen, deswegen verstehe ich wirklich nicht, was ihr dagegen habt =(
Ich finde es ein wenig Schade, dass ihr so krass gegen meine Art zu lernen seid, da es mir auf diese Weise nicht nur sehr viel Spaß macht, sondern ich meinem Ziel in riesen Schritten viel näher komme. Die Alternative wäre ziemlich trostlos und stumpf ein Tutorial durchzuarbeiten und dabei keinerlei eigene Fortschritte zu erzielen. Das werde ich nicht tun. Aber natürlich verwende ich Tutorials gleichoft wie z.b die documentation. Denn in der Doku gibt es wenige Erklärungen, deshalb schaue ich dann nochmal in Tutorials rein. Das tue ich aber erst, wenn ich einen Befehl vor mir habe, von dem ich gerne wissen möchte wie er funktioniert.
Ich würde euch wirklich bitten nicht immer wieder so eine grundsatzdiskussion anzufangen, Ihr kennt meinen Standpunkt und ich hab euch auch geschrieben, wie ich so ticke und wie ich mich tatsächlich doch überreden lasse, etwas "stumpf" zu lernen.
Z.b. mir einfach schreiben "Du machst das und das falsch, schau dir doch bitte das und das hier nochmal an: [Link]"
Dann schaue ich mir das an, mache meine tests und lerne etwas von euch, ohne dass ihr euch damit rumschlagen müsst
Sirius3 hat geschrieben:Da Funktionen nie auf Modulebene aufgerufen werden, ist es völlig egal, in welcher Reihenfolge sie definiert werden.
was genau sagst du damit? Ich meinte folgendes:
Code: Alles auswählen
def rechne()
summe = blabla() + 1
print(summe)
def blabla():
zahl=1
return zahl
rechne()
In dem Fall kommt soweit meine Erfahrung war die Fehlermeldung, dass die Funktion blabla nicht definiert ist. Sobald ich die blabla() Funktion aber über die rechne() Funktion verschiebe, geht es.
Edit:
Ich bin aufjedenfall schon sehr stolz darauf, was ich mit meiner Lerntechnik und eurer Hilfe schon erreicht habe, großes Dankeschön! Würde ich nur stumpf ein Tutorial durcharbeiten hätte ich jetzt und auch noch in einem halben Jahr genau garnichts erreicht.. und vermutlich hätte ich nach ein paar Wochen dann doch aufgeben, weil mir diese Tutorials einfach zu trocken sind und ich keine Erfolgserlebnisse verzeichnen kann.
Re: Durchlaufzeit von Funktionen rausfinden / Datum angeben
Verfasst: Samstag 10. Januar 2015, 21:21
von Sirius3
@Serpens66: wenn Du schon Beispiele postest, wo etwas angeblich nicht tut, dann solltest Du die schon selbst mal ausprobiert haben.
Wie die Funktionsdefinition von submit ist, habe ich Dir gezeigt, und auch, wie man die übergeben Funktion dann auch aufrufen kann. Die "*" und "**" Syntax kann man übrigens im Tutorial nachlesen, wenn die einem unbekannt sein sollte. Die submit-Funktion von concurrent hast Du ja schon selbst benutzt, da gehe ich davon aus, dass Du den Aufruf auch verstanden hast.
Re: Durchlaufzeit von Funktionen rausfinden / Datum angeben
Verfasst: Samstag 10. Januar 2015, 21:24
von BlackJack
@Serperns66: Wenn etwas nach fünfmal herumprobieren funktioniert, heisst das nicht das Du es verstanden hast. Verstanden hat man erst etwas wenn man ohne herumprobieren und ohne einfaches übernehmen von einem Stück Quelltext ein ähnliches Problem lösen kann, in dem man den Code dafür von Grund aus selber schreibt und bei jedem Teilausdruck weiss was der bewirkt, welchen Wert und welchen Typ der hat und bei Anweisungen welchen Effekt die auf den Zustand und Ablauf des Programms haben. Den Eindruck vermittelst Du aber nicht. Von Dir kommen stattdessen Verständnisfragen, zum Beispiel zu Threads vs Futures, die nicht kommen würden wenn es verstanden worden wäre, und Fragen nach tabellarischen Gegenüberstellungen von Techniken, die man sich selber Aufstellen könnte, wenn man sich damit beschäftigt und sie versteht, und nicht zuletzt auch immer Fragen nach Beispielen, die Du dann hier und da veränderst, aber wie man an Folgefragen merkt, nicht wirklich durchdrungen hast. Das läuft auf Dauer darauf hinaus das Du immer weiter nach Beispiellösungen zu Deinen Problemen fragst und die dann irgendwie in Dein Programm bastelst.
Es spricht nichts gegen Ausprobieren und dabei lernen, nur sehe ich den letzten Teil nicht so wirklich. Ich bin nicht gegen Deine Art zu lernen weil das IMHO kein lernen ist, jedenfalls nicht selbstständig programmieren lernen.
Zum Beispiel hast Du jetzt wie es aussieht eine völlig falsche Vorstellung was Klassen sind, wofür die gut sind, und das basierend auf falschen Grundannahmen über die simpelsten Funktionsaufrufe auf Modulebene. Beides Sachen die man nach dem durcharbeiten eines guten Grundlagentutorials wohl nicht passiert wären. Dein Beispiel funktioniert nämlich problemlos wenn man bei der Definition von `rechne()` den fehlenden Doppelpunkt ergänzt. Warum sollte das auch nicht funktionieren‽ Wenn etwas nicht funktioniert muss man erklären können warum das so ist.
Ich kenne die Klasse `Boerse2Rock` nicht aber ich sehe Code wie Du die Methoden aufrufst und das sieht verdächtig falsch aus. Passt auch nicht zu Deiner Beschreibung denn der `__init__()` wird nichts übergeben, also was sollte dann in der `__init__()` an das Objekt gebunden werden? Und Du rufst auch nur eine ”Methode” auf, also wird das was in der `__init__()` definiert würde, ja auch gar nicht über mehrere Methodenaufrufe hinweg und/oder von verschiedenen Methoden verwendet. Eine Klasse fasst zusammengehörende Daten und Funktionen zu einer Einheit zusammen, oder im Extremfall auch mal nur Daten, aber eine Klasse ohne Daten macht keinen Sinn. Das wäre dann nämlich genau das selbe wie ein Modul mit Funktionen, nur eben mit zusätzlicher aber sinnfreier Syntax.
Re: Durchlaufzeit von Funktionen rausfinden / Datum angeben
Verfasst: Samstag 10. Januar 2015, 22:10
von Serpens66
Sirius3 hat geschrieben:@Serpens66: wenn Du schon Beispiele postest, wo etwas angeblich nicht tut, dann solltest Du die schon selbst mal ausprobiert haben.
du hast recht.. der Code funktioniert, abgesehen von dem fehleden doppelpunkt.. hmm.. es gab eine Konstruktion wo es so war, wie beschrieben, ich weiß aber grad nicht mehr wie das genau aussah, möglicherweise waren da noch andere anfängerfehler drin.
Sirius3 hat geschrieben:
Wie die Funktionsdefinition von submit ist, habe ich Dir gezeigt, und auch, wie man die übergeben Funktion dann auch aufrufen kann. Die "*" und "**" Syntax kann man übrigens im Tutorial nachlesen, wenn die einem unbekannt sein sollte. Die submit-Funktion von concurrent hast Du ja schon selbst benutzt, da gehe ich davon aus, dass Du den Aufruf auch verstanden hast.
Wie bereits geschrieben habe ich args und auch die * schreibweise bereits verstanden. Es gibt nur noch 2 Probleme, die ich eig oben recht deutlich gepostet habe, eines davon sogar in fettgedruckt. Das andere ist, dass ich die "eval()" funktion verwende, was ich ja nicht tun sollte. Leider fällt mir keine Alternative ein. Anhand der submit Funktion kann ich nicht erkennen, welchen Typ der Paramater hat, das als fn in submit reingegeben wird. Ich verwende ja einen String. Ich gehe davon aus, wenn ich keinen String verwende, dass die Funktion sonst direkt ausgeführt wird. Beim schreiben dieses Textes wäre meine Vermutung jetzt, dass ich als fn nicht z.b. get_balance(*args) übergeben muss, sondern lediglich get_balance. Ist das korrekt? Das ist alles was ich wissen woltle, wie ich die Funktion übergeben kann, ohne dass sie ausgeführt wird. Im nachhinein ist es wohl das, was du mir mit deinem hinweis hier
http://www.python-forum.de/viewtopic.ph ... 35#p269935 sagen wolltest. Ich habe es aber nicht gesehen, dass "fn" hier lediglich der Funktionsname ist, ohne klammer. Hätte man drauf kommen können, bin ich aber nicht... das war das missverständnis.
(bitte lest meine Posts niemals "aggressiv" innerlich vor, denn ich formuliere meine Texte innerlich immer sehr ruhig und argumentativ

)
So, falls ich mit obigen Folgerungen richtig liege, sollte das eval Problem sogar gelöst sein, bleibt nur noch der Aufruf der args Variablen.
Re: Durchlaufzeit von Funktionen rausfinden / Datum angeben
Verfasst: Samstag 10. Januar 2015, 22:30
von EyDu
Serpens66 hat geschrieben:Leider fällt mir keine Alternative ein. Anhand der submit Funktion kann ich nicht erkennen, welchen Typ der Paramater hat, das als fn in submit reingegeben wird. Ich verwende ja einen String. Ich gehe davon aus, wenn ich keinen String verwende, dass die Funktion sonst direkt ausgeführt wird.
Funktionen sind ganz normal Objekte, die kannst du auch ganz normal übergeben. In der Dokumentation wird zum Beispiel die pow-Funktion übergeben. Wenn du die () am Ende einer Funktion weg lässt, dann wird sich nicht aufgerufen.
Serpens66 hat geschrieben:(bitte lest meine Posts niemals "aggressiv" innerlich vor, denn ich formuliere meine Texte innerlich immer sehr ruhig und argumentativ

)
Deine Beiträge kamen jetzt nicht aggressiv rüber, bei textueller Kommunikation kann man die genaue Stimmung des Autors eh nie so genau erahnen. Die Antworten von uns sind ja auch eher sachlicher Natur, dass hat etwas trockene Materie manchmal so an sich. Gerade, wenn es schnell geschrieben wird.
Re: Durchlaufzeit von Funktionen rausfinden / Datum angeben
Verfasst: Samstag 10. Januar 2015, 22:36
von Serpens66
@ BlackJack:
ich danke euch für eure Geduld mit mir und hoffe dass ihr mich nicht aufgebt..
Du hast recht, dass man zumindest die Grundlagen beherrschen sollte und das auch nicht soo lange dauern sollte, diese zu lernen, wie dann die fortgeschrittenen Dinge.
BlackJack hat geschrieben:@Serperns66: Wenn etwas nach fünfmal herumprobieren funktioniert, heisst das nicht das Du es verstanden hast. Verstanden hat man erst etwas wenn man ohne herumprobieren und ohne einfaches übernehmen von einem Stück Quelltext ein ähnliches Problem lösen kann, in dem man den Code dafür von Grund aus selber schreibt und bei jedem Teilausdruck weiss was der bewirkt, welchen Wert und welchen Typ der hat und bei Anweisungen welchen Effekt die auf den Zustand und Ablauf des Programms haben. Den Eindruck vermittelst Du aber nicht. Von Dir kommen stattdessen Verständnisfragen, zum Beispiel zu Threads vs Futures, die nicht kommen würden wenn es verstanden worden wäre, und Fragen nach tabellarischen Gegenüberstellungen von Techniken, die man sich selber Aufstellen könnte, wenn man sich damit beschäftigt und sie versteht, und nicht zuletzt auch immer Fragen nach Beispielen, die Du dann hier und da veränderst, aber wie man an Folgefragen merkt, nicht wirklich durchdrungen hast. Das läuft auf Dauer darauf hinaus das Du immer weiter nach Beispiellösungen zu Deinen Problemen fragst und die dann irgendwie in Dein Programm bastelst.
Also ich sehe es wie folgt:
Ich habe die Sprache C4Skript von dem bereits erwähnten Spiel Clonk genau aufdieselbe Weise gelernt. Dort hatte ich allerdings deutlich leichteren Zugang zu tausenden Beispielen aller Art. Es hat tatsächlich recht lange gedauert, bis ich etwas wirklich verstanden habe. Ich habe hunderte Fragen gestellt, zu Anfang Dinge zu absoluten Basics. Ich habe Kostruktionen einfach nur abgewandelt um es für meine Zwecke zu gebrauchen, ohne wirklich zu verstehen, was da nun passiert. Ich wusste auch tagelang danach immernoch nicht, wie es nun eigentlich genau funktioniert und konnte es nicht selbst schreiben. Stattdessen habe ich immer wieder beim Beispiel nachgeschaut, wie das nochmal war. Aber ich habe trotzdem immer was dabei gelernt. Denn nach ca einem halben Jahr hatte ich nicht nur unglaublich viel Content selbst zusammengebastelt, sondern ich wusste auch, wie all die Dinge nun genau funktionieren, da ich dieselben Beispiele immer und immer wieder für eine neue Anwendung abwandeln musste.
Wenn ich mir heute meine Anfängerfragen im Clonkforum durchlese, denke ich mir auch:
"oh man, ein wunder dass ich überhaupt was auf die Reihe gekriegt habe, dass diese konstruktion so funktioniert ist nur ein glücklicher zufall!

"
Genauso wird es mit sicherheit auch bei Python sein. Es braucht seine Zeit bis ich die etwas komplexeren Dinge wirklich verstanden habe. Bis es soweit ist, schlage ich mich mit Beispielen durch und lerne dabei. Nicht von heute auf morgen, aber durch ständiges verwenden und abwandeln des Beispiels erkenne ich mit der Zeit alle möglichen Facetten.
BlackJack hat geschrieben:
Zum Beispiel hast Du jetzt wie es aussieht eine völlig falsche Vorstellung was Klassen sind, wofür die gut sind, und das basierend auf falschen Grundannahmen über die simpelsten Funktionsaufrufe auf Modulebene. Beides Sachen die man nach dem durcharbeiten eines guten Grundlagentutorials wohl nicht passiert wären. Dein Beispiel funktioniert nämlich problemlos wenn man bei der Definition von `rechne()` den fehlenden Doppelpunkt ergänzt. Warum sollte das auch nicht funktionieren‽ Wenn etwas nicht funktioniert muss man erklären können warum das so ist.
Ja stimmt, da habe ich einen Error erzeugt, etwas im Code geändert und falsche Schlussfolgerungen zu der Lösung gezogen.
Das passiert unweigerlich bei meiner Art zu lernen. Das meinte ich weiter oben mit "Ein wunder dass es überhaupt funktioniert", weil es natürlich häufiger vorkommt, dass ich dadurch falsche Annahmen habe. Aber früher oder später merke ich das entweder selbst, oder ihr weißt mich darauf hin. Oder ich lese den Hinweis zufällig beim durchstöbern eines Tutorials. Es ist ja nicht so, dass ich mit jeder kleinen Frage hier ankomme, ich versuche schon so gut ich kann meine Fragen selbst zu beantworten, sonst wäre das Forum echt überflutet mit meinen Fragen
BlackJack hat geschrieben:
Ich kenne die Klasse `Boerse2Rock` nicht aber ich sehe Code wie Du die Methoden aufrufst und das sieht verdächtig falsch aus. Passt auch nicht zu Deiner Beschreibung denn der `__init__()` wird nichts übergeben, also was sollte dann in der `__init__()` an das Objekt gebunden werden? Und Du rufst auch nur eine ”Methode” auf, also wird das was in der `__init__()` definiert würde, ja auch gar nicht über mehrere Methodenaufrufe hinweg und/oder von verschiedenen Methoden verwendet. Eine Klasse fasst zusammengehörende Daten und Funktionen zu einer Einheit zusammen, oder im Extremfall auch mal nur Daten, aber eine Klasse ohne Daten macht keinen Sinn. Das wäre dann nämlich genau das selbe wie ein Modul mit Funktionen, nur eben mit zusätzlicher aber sinnfreier Syntax.
Hm.. ich weiß gerade leider nicht, ob du recht hast und ich meinen Aufbau fälschlicherweise als gut ansehe, oder ob du dir meinen Aufbau einfach nur falsch vorstellst (was daran liegt, dass ich hier sehr selten wirklich fertigen Code schreibe, sondern immer nur stark vereinfachte test-skripte, die so natürlich nicht bei mir verwendet werden).
Daher hier mal meine Klassen init, wie sie zurzeit aussieht:
Code: Alles auswählen
class Boerse2Rock:
def __init__(self):
# lokale variablen definieren
# Anpassbare Werte (gebühren iwann noch abfragen)
self.fee_boerse2 = 0.3/100
self.fee_rock = 0.5/100
self.maxmenge = 0.1 # eine maximale Menge pro Trade, wenn keine maximalmenge, dann 0 eintragen
self.pairCode_boerse2 = "XXBTZEUR"
self.pairCode_rock = "BTCEUR"
self.mindest_profit_standard = 0.5 # mindestprofits bei 50:50 Verteilung auf den Börsen, mind. 0.1
self.MyBalanceBTC_boerse2 = None
self.MyBalanceEUR_boerse2 = None
self.MyBalanceBTC_rock = None
self.MyBalanceEUR_rock = None
self.MyBalanceBTCinEUR_boerse2 = None
self.MyBalanceBTCinEUR_rock = None
self.trademenge = None
So. innerhalb der zahlreichen Funktionen dieser Klasse, verwende ich diese Variablen, bzw. weise ihnen werte zu.
Auf diese Weise muss ich diese Variablen nicht ständig von Funktion zu Funktion weiterreichen.
Das ist doch der Sinn davon, oder nicht? Was ist daran nun falsch oder müsste man noch verbessern?
Re: Durchlaufzeit von Funktionen rausfinden / Datum angeben
Verfasst: Samstag 10. Januar 2015, 22:39
von Serpens66
EyDu hat geschrieben:
Funktionen sind ganz normal Objekte, die kannst du auch ganz normal übergeben. In der Dokumentation wird zum Beispiel die pow-Funktion übergeben. Wenn du die () am Ende einer Funktion weg lässt, dann wird sich nicht aufgerufen.
danke dir

das war das, was ich im letzten Post ja gemutmaßt habe und mir vorher nicht bewusst war, weshalb ich auf strings zurückgegriffen habe

Hab zwar natürlich das Beispiel mit pow gesehen, aber ich bin irgendwie trotzdem nicht drauf gekommen

sieht man den Wald vor lauter Bäumen nicht
EyDu hat geschrieben:
Deine Beiträge kamen jetzt nicht aggressiv rüber, bei textueller Kommunikation kann man die genaue Stimmung des Autors eh nie so genau erahnen. Die Antworten von uns sind ja auch eher sachlicher Natur, dass hat etwas trockene Materie manchmal so an sich. Gerade, wenn es schnell geschrieben wird.
Freut mich, dass sie nicht so rüberkommen, sollen sie ja auch nicht

(hatte nur die Befürchtung, dass sie evtl ziemlich unfreundlich rüberkommen könnten, wenn man sie in einem aggressiven Ton vorliest)
Re: Durchlaufzeit von Funktionen rausfinden / Datum angeben
Verfasst: Samstag 10. Januar 2015, 23:22
von Serpens66
Soooo, nun sieht es so aus:
Code: Alles auswählen
def machwas(self):
args1 = ["Boerse2","ZEUR"]
args2 = ["TheRock","EUR"]
args3 = ["TheRock","BTCEUR"]
args4 = ["Boerse2","XXBTZEUR",10]
args5 = ["TheRock","BTCEUR"]
args6 = ["Boerse2","XXBTZEUR"]
# nur hier so in der antwort:
self.parallel(
[self.get_balance,self.get_balance,
self.get_orderbook,self.get_orderbook,
self.get_ticker_exchangepair,self.get_ticker_exchangepair],
[args1,args2,args3,args4,args5,args6])
# wäre das auch im Skript so in der Form okay, oder ist es anders besser?
def parallel(self,aufgabenliste, argsliste): # aufgabenliste enthält funktionen, argsliste die argumente
print("Zeit bei parallelstart: {}".format(uhrzeit()))
threads = list(map(Multithread, aufgabenliste, argsliste))
for thread in threads:
thread.start()
for thread in threads:
thread.join()
print(list(thread.result for thread in threads))
print("Zeit bei Ende: {}".format(uhrzeit()))
class Multithread(threading.Thread):
def __init__(self, aufgabe,argumente):
threading.Thread.__init__(self)
self.aufgabe = aufgabe
self.argumente = argumente
self.result = None
def run(self):
result = self.aufgabe(*self.argumente)
self.result = result
TheTest().machwas()
Es funktioniert einwandfrei und ist glaube ich auch ganz okay geschrieben, oder?
Ich hab vorher noch ein wenig mit concurrent.futures rumexperimentiert, aber es noch nicht geschafft das spam, ham, eggs Beispiel umzusetzen. Eventuell beschäftige ich mich damit später nochmal, da meine Umsetzung natürlich deutlich Fehler anfälliger und sicherlich auch weniger effizient ist, als dieses fertige Modul. Das mache ich aber vermutlich erst in 3-4 wochen, wenn ich wieder etwas mehr Zeit habe.
Re: Durchlaufzeit von Funktionen rausfinden / Datum angeben
Verfasst: Samstag 10. Januar 2015, 23:38
von EyDu
Zeilen 2 bis 7 sind noch sehr unschön, da könntest du gleich eine Liste produzieren, statt sie so umständlich über Namen in Zeile 13 zusammenzusetzen. Das ist ja sehr viel unnötige Schreibarbeiten. Allerdings kannst du das gleich besser lösen: Zusammengehörende Daten sollten im Code auch immer zusammenstehen. Du hast aber zwei parallele Listen: Eine mit den Funktionen und eine mit den dazugehörigen Parametern. Stelle deinen Code mal so um, dass Funktionen und Parameter in einem Tupel gehören. Also
Code: Alles auswählen
def machwas(self):
modes = [
(self.get_balance, ("Boerse2", "ZEUR")),
(self.get_balance, ("TheRock", "EUR")),
...
Da musst du dann natürlich die parallel-Funktion noch umstellen.
Zeile 34 und 35 kannst du auch zusammenfassen, den Umweg über "result" brauchst du nicht. Das habe ich in meinem Beispiel nur eingefügt, damit die Ausgabe des Threads auch garantiert vor der Ausgabe der Summe kommt.
Re: Durchlaufzeit von Funktionen rausfinden / Datum angeben
Verfasst: Sonntag 11. Januar 2015, 00:18
von Serpens66
Vielen Dank EyDu
sieht dann jetzt so aus:
Code: Alles auswählen
def machwas(self):
modes = [
(self.get_balance, ("Boerse2", "ZEUR")),
(self.get_balance, ("TheRock", "EUR")),
(self.get_orderbook, ("TheRock","BTCEUR")),
(self.get_orderbook, ("Boerse2","XXBTZEUR",10)),
(self.get_ticker_exchangepair, ("TheRock","BTCEUR")),
(self.get_ticker_exchangepair, ("Boerse2","XXBTZEUR"))
]
#im richtigen Skript könnte man hier anstatt "XXBTZEUR" natürlich self.pairCode_boerse2 nehmen
self.parallel(modes)
def parallel(self,aufgabenliste):
print("Zeit bei parallelstart: {}".format(uhrzeit()))
threads = list(map(Multithread, aufgabenliste))
for thread in threads:
thread.start()
for thread in threads:
thread.join()
print(list(thread.result for thread in threads))
print("Zeit bei Ende: {}".format(uhrzeit()))
class Multithread(threading.Thread):
def __init__(self, aufgabe):
threading.Thread.__init__(self)
self.aufgabe = aufgabe[0] # ist das so vernünftig gelöst, oder gibt es da noch einen sinnvollereren Weg?
self.argumente = aufgabe[1]
self.result = None
def run(self):
self.result = self.aufgabe(*self.argumente)
Re: Durchlaufzeit von Funktionen rausfinden / Datum angeben
Verfasst: Sonntag 11. Januar 2015, 10:21
von Sirius3
@Serpens66: Du hast nicht verstanden, was objektorientierte Programmierung ist. Du hast anscheinend zwei Börsen und willst vin ihnen balance, order und exchangepair wissen. Eine Börse ist damit ein typisches Objekt, nach außen hin die selbe Information, dahinter stecken aber unterschiedliche URLs, Abfage-APIs, etc.
Du behandelst die Börsen aber nicht als Objekte, sondern baust sie in ein Überobjekt, das in Wirklichkeit nichts anderes ist als ein Modul mit Funktionen und globalen Variablen. Man kann auch globale Variablen erzeugen und sich die selben Probleme einhandeln, auch wenn man nicht explizit "global" schreiben muß.
get_balance bekommt als erste Argument "Boerse2" oder "TheRock", ist aber eine Funktion des Überobjekts. Bei OOP wäre get_balance eine Methode des jeweiligen Börsen-Objekts und wüßte damit implizit, welche Börse abzufragen wäre.
Futures sind für den Anfänger normalerweise einfacher zu verstehen, als Threads. Man startet die Funktion und fragt irgendwann später, wenn es gebraucht wird, das Ergebnis ab. Das erfordert normalerweise nur einen minimalen Eingriff in ein Programm, das bisher linear ablief. Was Du mit Deiner Multithreadedparellelklasse machst, ist, Dein ganzen Programm auf den Kopf zu stellen, nur damit ein paar Abfragen parallel ablaufen. Dazu steckst Du Dinge in eine Liste, die nicht zusammengehören (balance und orderbook) die Du später wieder mühsam trennen mußt. Die Komplexität verzehnfacht sich gegenüber Futures und die Fehleranfälligkeit verhundertfacht sich.
Re: Durchlaufzeit von Funktionen rausfinden / Datum angeben
Verfasst: Sonntag 11. Januar 2015, 14:08
von Serpens66
Sirius3 hat geschrieben:@Serpens66: Du hast nicht verstanden, was objektorientierte Programmierung ist. Du hast anscheinend zwei Börsen und willst vin ihnen balance, order und exchangepair wissen. Eine Börse ist damit ein typisches Objekt, nach außen hin die selbe Information, dahinter stecken aber unterschiedliche URLs, Abfage-APIs, etc.
Du behandelst die Börsen aber nicht als Objekte, sondern baust sie in ein Überobjekt, das in Wirklichkeit nichts anderes ist als ein Modul mit Funktionen und globalen Variablen. Man kann auch globale Variablen erzeugen und sich die selben Probleme einhandeln, auch wenn man nicht explizit "global" schreiben muß.
get_balance bekommt als erste Argument "Boerse2" oder "TheRock", ist aber eine Funktion des Überobjekts. Bei OOP wäre get_balance eine Methode des jeweiligen Börsen-Objekts und wüßte damit implizit, welche Börse abzufragen wäre.
Ich denke mal mit objektorientierter Programmierung meinst du das, was BlackJack letztens angesprochen hatte mit "die funktion die rechnet sollte garnicht wissen, woher die Werte kommen", richtig? Falls ja, hatte ich diesbezüglich ja bereits geschrieben, dass mein Skript quasi nur aus einer Funktion bestand, wo ich alles drin gemacht habe, was ich aber ändern möchte (
edit: siehe hier:
http://www.python-forum.de/viewtopic.ph ... 86#p269886 ) . Es ist noch lange nicht fertig, aber ich denke ich bin auf einem guten Weg. So habe ich deswegen nämlich diese Funktionen get_balance und Co eingeführt.
Die get_balance hat den Zweck, dass ich dort durch Eingabe des Börsennamen, bei jeder beliebigen Börse (die ich evtl noch einbaue), die Balance abfragen kann, ohne dass ich auf die objektspezifischen Dinge (z.b Argumente und wie die Ausgabe aussieht) achten muss.
Code: Alles auswählen
def get_balance(self,exchange,currency=0):
if exchange =="TheRock":
MyBalance = rock.GetBalance(currency)["result"][0]['trading_balance']
elif exchange == "Boerse2":
MyBalance = k.query_private("Balance")["result"] # in einer Anfrage werden alle balances abgefragt.
if currency: # ohne Angabe von currency erhält man also eine Liste mit allen currencies
MyBalance = MyBalance[currency]
else:
print("Ungültiger Exchange Name bei get_balance übergeben!")
return None
return MyBalance
# in meinem Skript ist noch ein try/except Aufbau um Fehler zu behandeln.
#Er ist noch nicht besonders schön und das weiß ich, deswegen lasse ich ihn hier erstmal weg,
#da es darum gerade nicht geht.
So. Nun habe ich ja glücklicherweise fast fertige Objekte zur datenausfrage bei den Exchanges gefunden. Auf diese Objekte, die vorher natürlich importiert werden, wird hier zugegriffen, um die Balance abzufragen. So greift rock.GetBalance(currency) auf folgende Funktion in einem anderen Skript zu:
Code: Alles auswählen
# get the balance for a certain currency (return None if not found)
def GetBalance(self, currency):
try:
url = 'https://www.therock.com/api/get_balance'
values = {
'username' : self.username,
'password' : self.password,
'api_key' : self.key,
'type_of_currency' : currency
}
Balance = requests.post('https://www.therock.com/api/get_balance', data=values).json()
return Balance
except: # dass das hier nicht gut gelöst ist, wissen wir ja, deswegen nochmal die eigene fehlerbehandlug
return None
Für Boerse2 gibt es eine ähnliche Funktion in einem anderen Skript, welches auch importiert ist und mit k. benannt ist.
Da für diese beiden Funktionen in den externen Skripten unterschiedliche Parameter gebraucht werden und die Ausgabe auch unterschiedlich zerlegt werden muss, bietet sich eine "get_balance" Funktion denke ich sehr an, oder etwa nicht?
Dennoch ist mein Aufbau natürlich noch lange nicht perfekt. So wäre es mir nicht ohne weiteres möglich mal eben eine dritte börse hinzuzufügen, was zum großen Teil aber auch an den Rechnungen liegt, die noch nur für 2 börsen ausgelegt sind.
Das ist mir aber auch bewusst. Es wird nun erstmal so fertiggestellt, wo ich so gut ich kann die aufgaben verteile, es aber nicht perfekt ist. Sobald das dann steht und auch funktioniert, kümmere ich mich dann darum, dass alles so ineinander greift, dass es kein Problem ist weitere Börsen hinzuzufügen, was ja auch in meinem Interesse liegt, dass das möglichst unkompliziert geht.
Sirius3 hat geschrieben:
Futures sind für den Anfänger normalerweise einfacher zu verstehen, als Threads. Man startet die Funktion und fragt irgendwann später, wenn es gebraucht wird, das Ergebnis ab. Das erfordert normalerweise nur einen minimalen Eingriff in ein Programm, das bisher linear ablief. Was Du mit Deiner Multithreadedparellelklasse machst, ist, Dein ganzen Programm auf den Kopf zu stellen, nur damit ein paar Abfragen parallel ablaufen. Dazu steckst Du Dinge in eine Liste, die nicht zusammengehören (balance und orderbook) die Du später wieder mühsam trennen mußt. Die Komplexität verzehnfacht sich gegenüber Futures und die Fehleranfälligkeit verhundertfacht sich.
wieso gehören balance und orderbook nicht zusammen? Sie gehören insofern zusammen, dass ich möchte, dass sie zeitgleich abgefragt werden und nicht nacheinander. Aber ja, natürlich ist das deutlich umständlicher und fehleranfälliger als mit futures, das hab ich ja in meinem letzten Post auch geschrieben. Dennoch habe ich so schonmal wieder ein wenig was gelernt, was ich allein mit der Verwendung von futures nicht gelernt hätte

(z.b wie man funktionen und beliebige anzahlan an argumenten weitergibt).
Ich werde mich also aufjedenfall in den Semesterferien nochmal mit futures beschäftigen und es dementsprechend wieder umschreiben.
Re: Durchlaufzeit von Funktionen rausfinden / Datum angeben
Verfasst: Freitag 4. August 2017, 10:44
von Serpens66
Hallo,
ich möchte diesen alten Thread nochmal ausbuddeln, weil ich eine Frage zu dem hier entwickelten Threading Code habe.
Code: Alles auswählen
def parallel(aufgabenliste):
threads = list(map(Multithread, aufgabenliste))
for thread in threads:
thread.start()
for thread in threads:
thread.join()
class Multithread(threading.Thread):
def __init__(self, aufgabe=0):
if aufgabe:
threading.Thread.__init__(self)
self.aufgabe = aufgabe[0] #ist ja ein Tupel aus funktion und argumenten
self.argumente = aufgabe[1]
self.result = None
return
def run(self):
self.result = self.aufgabe(*self.argumente)
return
Und zwar verwende ich Threads quasi verschachtelt.
Also ich starte bei Skript-start zb. 2 Threads die beide eine funktion mit einer "while True" Schleife aufrufen.
In dieser Schleife werden dann mit weiteren Threads Funktionen aufgerufen, die API Calls machen. Jede dieser Funkionen "return"ed nach kurzer Zeit was, sodass diese Threads eigentlich alle automatisch wieder geschlossen werden müssten, sodass die gesamtanzahl an Threads wieder bei 2 liegt.
Das ganze wiederholt sich jetzt hunderte male, solange bis ich manuell das Programm abbreche.
Irgendwann bekam ich aber mal eine Fehlermeldung, dass das Programm wegen zu vielen Threads abgebrochen wurde, weshalb ich mir nun in jedem Durchlauf die aktuelle anzahl an Threads ausgeben lasse. Dabei lässt sich leider feststellen, dass ca. alle 2 Minuten ein Thread nicht geschlossen wird. Dadurch wird die Gesamtanzahl an Threads immer höher und höher.
Ich dachte zuerst, dass mein Skript vllt nur zu schnell laufen würde und habe deshalb ein paar mehr sleep befehle in die 2 Haupt-threads eingebaut, in der Hoffnung dass die ganzen kleinen threads dann geschlossen werden, aber das passiert leider nicht. Sie bleiben offenbar unendlich lange offen.
Nur warum?
Könnt ihr mir vllt ohne genaueren Code sagen, was für Gründe es geben kann, dass obwohl die Funktion, die mit dem Thread aufgerufen wurde zuende ist, der Thread dennoch nicht geschlossen wird? Und warum passiert das nur ab und zu und nicht ständig?
Meine einzige Vermutung wäre aktuell, dass das vielleicht passiert, wenn die Funktion einen Fehler raised? Ab und zu gibts nen Fehler bei nen API Call. Das könnte erklären, warum es nur langsam ansteigt.
Übrigens könnte diese steigende Anzahl von Threads auch die Erklärung für das Memory Problem sein, worüber ich mal einen Thread gemacht hatte. Wenn zig Threads nicht geschlossen werden, blockieren sie natürlich weiterhin den Arbeitsspeicher...
Re: Durchlaufzeit von Funktionen rausfinden / Datum angeben
Verfasst: Freitag 4. August 2017, 11:24
von BlackJack
@Serpens66: Du wirst da irgendwo irgendwelche Threads nicht beenden. Du schreibst etwas von Endlosschleifen. Und falls API-Calls welche über das Netz meinen: So etwas kann ja auch mal hängenbleiben.
Das klingt insgesamt nach einer Anwendung die von Logging profitieren könnte.
Warum ist `aufgabe` mit dem Defaultwert 0 belegt wenn das doch ein Tupel sein soll? Als Wert für ”nichts” gibt es in Python den Wert `None`. Der ist als Wahrheitswert in Bedingungen auch `False`.
Wobei ein Defaultwert hier aber sowieso unsinnig ist. Du erzeugst doch keine Theads ohne Aufgabe. Die würde spätestens in `run()` dann sowieso einen `AttributeError` auslösen und zudem ist ein Thread ohne Aufgabe sinnlos.
Du rufst die `__init__` von `Thread` nicht auf. Ist ein Wunder das das so überhaupt funktioniert.
Und irgendwie klingt das als würdest Du `concurrent.futures` selbst implementieren — nur schlechter. So ein `Future` hat beispielsweise nicht nur ein Ergebnis, sondern kapselt auch Ausnahmen und stellt die zur Verfügung wenn man das Ergebnis abfragt. Und man kann die maximale Anzahl von Threads/Prozessen angeben die verwendet werden sollen.
Re: Durchlaufzeit von Funktionen rausfinden / Datum angeben
Verfasst: Samstag 5. August 2017, 02:40
von Serpens66
Ich danke dir für deine Antwort
Ich habe hier mal ein kleines Vorwort geschrieben (da es so lang geworden ist hab ichs in Offtopic gepackt):
viewtopic.php?f=5&t=41009
Jedenfalls möchte ich dir damit mein Verhalten erklären und warum ich, obwohl es direkt in einen der ersten Posts auch von dir vorgeschlagen wird, bisher nicht auf concurrent.futures gewechselt bin.
Ich habe mir jetzt die Posts nochmal angeguckt und ich habe damals wirklich ncihts von dem verstanden, was du versucht hast mir zu sagen.
Mir ist auch nicht aufgefallen, dass ich in dem Code ProcessPoolExecutor anstatt ThreadPoolExecutor verwendet habe, obwohl du darauf hingewiesen hast, dass ich gerade Prozesse mit Threads vergleiche. Beide Begriffe waren mir damals absolut neu und ich habe erst vor kurzem gelernt, was der Unterschied ist.
Zurück zum Thema:
Jedenfalls habe ich jetzt gemerkt, wie leicht die Anwendnung von concurrent.futures ist und ich werde dies nun anstelle der Threads verwenden, danke
Dennoch würde ich mich freuen, wenn du mir bei der Lösung der ursprünglichen Frage helfen könntest.
Der Thread Code verwendet ja "join()". Dh. eigentlich sollte immer so lange gewartet werden, bis alle Threads ihre Aufgabe abgeschlossen haben, erst dann geht es weiter. Danach sollte der thread doch eigentlich automtatisch geschlossen werden?
In meinem Programm geht alles normal weiter, dh. alle Threadaufgaben werden abgeschlossen, entweder durch return oder durch "raise errror". Und das Programm läuft danach auch porblemlos weiter, wird also nicht aufgehalten.
Dennoch steigt die Anzahl an Threads langsam immer weiter an, weil manche, obwohl die Aufgabe beendet ist, nicht geschlossen werden.
An sich könnte ich nun einfach auf concurrent.futures wechseln und hoffen, dass sich das Problem damit erledigt hat. Aber 1. würde ich es gerne verstehen und 2. wer weiß, ob es bei concurrent.futures nicht ein ähnliches Problem gibt? Und soweit ich gesehen habe, kann ich bei concurrenct.futures nicht nachgucken, wieviele Threads noch laufen, obwohl sie beendet sein müssten.
(Falls es aber einfach an dem Thread Code liegt, also daran, dass er so schlecht geschrieben ist, und im Normalfall dieses Problem nicht existiert, dann kannst du mir das auch so direkt sagen. Ich denke wir brauchen nun keinen voll funktionierenden Thread Code entwickeln, da wir ja stattdessen concurrent haben.)
Der Code den ich nun verwenden würde wäre sowas:
Code: Alles auswählen
pool = concurrent.futures.ThreadPoolExecutor(10)
futures = []
for count in range(10):
futures.append(pool.submit(DoSomething, count,"abc"))
concurrent.futures.wait(futures)
for future in futures:
print(future.result())
Re: Durchlaufzeit von Funktionen rausfinden / Datum angeben
Verfasst: Samstag 5. August 2017, 12:16
von BlackJack
@Serpens: Was verstehst Du denn unter dem „schliessen“ von Threads? Wenn Du mit `join()` auf das Ende eines Threads wartest, dann blockiert dieser Aufruf solange bis die `run()`-Methode des Threads am Ende angekommen ist. Egal aus welchen Gründen — also sowohl wenn der Programmfluss auf ”natürliche” Weise am Ende ankommt, als auch wenn eine Ausnahme dafür sorgt.
Falls also noch Threads in Deinem Programm laufen, dann wurde entweder nirgends auf deren Ende gewartet oder es gibt (mindestens) einen Thread der auch noch läuft und auf das Ende des anderen wartet.
Das Problem mit dem Speicherverbrauch ist davon nur teilweise abhängig, denn auch ein `Thread`-Objekt dessen `run()` bereits durchgelaufen ist, verbraucht solange es irgendwie per Code erreichbar ist, noch den Speicher den es selbst und seine Attribute verbrauchen. Also beispielsweise auch das Ergebnis vom `run()` wenn das als Attribut auf dem Objekt gespeichert wurde.
Was vielleicht noch sein könnte, ist dass die fehlende Initialisierung der Basisklasse `Thread` Probleme nach sich zieht. Du machst das ja nur wenn tatsächlich eine Aufgabe übergeben wurde, das ist aber etwas was man grundsätzlich machen sollte.
Ich habe ja auch Logging vorgeschlagen. Weil man so einfach(er) den Threads auf die Spur kommen könnte die dort alle zwei Minuten einfach weiterlaufen. Das ist bei solchen länger laufenden Prozessen eigentlich Standard, sowohl um die Fehlersuche zu erleichtern, als auch generell den Programmablauf nachvollziehen zu können.
An der Stelle wo Du Dir Die Anzahl der aktiven Threads ausgeben lässt, könntest Du auch die Threads selbst auflisten und Dir eventuell vorhandene `aufgabe`- und `argumente`-Attribute ausgeben lassen, vielleicht bringt das ja bereits ein Muster zum Vorschein das Rückschlüsse auf das Problem ermöglicht.
Falls das gleiche Problem bei `concurrent.Futures` existiert, wird das irgendwann blockieren wenn alle Workerthreads beschäftigt sind und in einer Endlosschleife hängen.
Zum Codebeispiel: Du müsstest wahrscheinlich in der letzten Schleife noch mit eventuellen Ausnahmen umgehen, wie auch immer Du damit umgehen möchtest wenn so ein `DoSomething`-Aufruf kein Ergebnis sondern eine Ausnahme zur Folge hatte.
Re: Durchlaufzeit von Funktionen rausfinden / Datum angeben
Verfasst: Samstag 5. August 2017, 13:18
von Serpens66
Vielen Dank
Bisher läuft concurrent.futures problemlos 5 Stunden (hängt also nichts irgendwie).
Allerdings hat die Zahl der Threads die mit threading.active_count() ausgegeben werden schon leicht zugenommen...
Aktuell verwende ich noch den alten Thread Code, um die Hauptthreads zu starten. Die die dann in while Schleife laufen. Da war ich mir nicht sicher, ob ich das auch mit concurrent machen kann, da die Anzahl der Threads die diese Hauptthreads starten, stark variieren kann und ich verhindern wollte, dass es durch Zuweisung von zu wenig Workers irgendwie hängen bleibt. (zwischen 20 und 100 pro durchlauf. Nach ~20 Stunden waren es bisher 1000 active threads, weshalb alleine diese schwankung also nicht die ursache sein kann). Oder sollte ich einfach die Hauptthreads mit einer worker Anzahl von zb 10000 starten, damit es niemals hängen bleibt? (ich dann aber den fehlerfreien concurrent Code, statt dem komischen Thread Code nehme)
Daher würde ich gerne deinen Vorschlag durchführen und gucken, welche Threads das sind. Doch wie mache ich das? Ich konnte in der Doku nichts finden, wie ich mir die aufgabe der noch aktiven Threads ausgeben lassen könnte https://docs.python.org/3.4/library/threading.html
Inwiefern kann futures.result() einen Fehler raisen ? Habe gerade testweise mal einen Assertionerror in einem thread geraised. Der Thread wurde abgebrochen und das Ergebnis war nicht in futures enthalten. Dh. das einzige was so schief gehen könnte, wäre dass ich bei 20 Threads 20 Ergebnisse erwarte, aber nur 15 bekomme, bweil 5 davon einen Fehler geraised haben. Das wäre schon ärgerlich, weil ich davon ausgehe, dass die Reihenfole wie ich sei reingegeben habe, auch die Reihenfolge ist, wie ich die ergebnisse bekomme... Allerdings hatte ich soweit ich weiß noch nie ein Problem mit der Reihenfolge und bei threading selbst sollte es doch auch so funktionieren, oder nicht? Meine Funktionen raisen in der Regel auch keinen error, sie fangen Fehler selbst ab, printen den und returnen stattdessen einen standardwert (außer es ist ein Schreibfehler im Abfang-Code)