Mit dbg debuggen
-
Hallo ihr Lieben,
nach langer Zeit melde ich mich wieder zu Wort. Ich habe den Klassiker, dass mein Programm sich festgefahren hat. Nun möchte ich von dem Vorgehen wegkommen in jede Zeit ein
cout << "Hier"
zu schreibe, bis ich den Fehler gefunden habe.Ich habe also angefangen mit
valgrind
unddbg
zu experimentieren.Valgrind
Für Valgrind habe ich meine einzelnen Programmteile mit der Option-g -O0
compiliert und anschließend gelinkt.
Schließlich habe ich das Programm wie im Quick-Tutorial angegeben mittelsvalgrind --leak-check=yes ./main
ausgeführt. Irgendwann hängt es fest und ich breche mittels
strg+c
ab und kriege am Ende die Meldung==9923== HEAP SUMMARY: ==9923== in use at exit: 6,616 bytes in 3 blocks ==9923== total heap usage: 3 allocs, 0 frees, 6,616 bytes allocated ==9923== ==9923== LEAK SUMMARY: ==9923== definitely lost: 0 bytes in 0 blocks ==9923== indirectly lost: 0 bytes in 0 blocks ==9923== possibly lost: 0 bytes in 0 blocks ==9923== still reachable: 6,616 bytes in 3 blocks ==9923== suppressed: 0 bytes in 0 blocks ==9923== Reachable blocks (those to which a pointer was found) are not shown. ==9923== To see them, rerun with: --leak-check=full --show-reachable=yes ==9923== ==9923== For counts of detected and suppressed errors, rerun with: -v ==9923== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
Da sieht doch eigentlich recht gut aus, oder nicht?
gdb
Als nächstes habe ich mich an
gdb
versucht und möchte mich an das Programm anhängen, während es läuft. Also starte ich das Programm, schaue mir in der Konsole mittelstop
die ID an, starte in der Konsole dann gdb und hänge mich mittelsattach <ID>
an das Programm.Dann sagt mir gdb zunächst
Attaching to process 9958 Reading symbols from /var/autofs/home/home/huthmacher/Korrespondenz/A.Marocchino/Cpp/main...done. Reading symbols from /usr/lib/libgsl.so.0...(no debugging symbols found)...done. Loaded symbols for /usr/lib/libgsl.so.0 Reading symbols from /usr/local/lib/libgslcblas.so.0...done. Loaded symbols for /usr/local/lib/libgslcblas.so.0 Reading symbols from /usr/lib/libstdc++.so.6...(no debugging symbols found)...done. Loaded symbols for /usr/lib/libstdc++.so.6 Reading symbols from /lib/libm.so.6...Reading symbols from /usr/lib/debug/lib/libm-2.11.3.so...done. (no debugging symbols found)...done. Loaded symbols for /lib/libm.so.6 Reading symbols from /lib/libgcc_s.so.1...(no debugging symbols found)...done. Loaded symbols for /lib/libgcc_s.so.1 Reading symbols from /lib/libc.so.6...Reading symbols from /usr/lib/debug/lib/libc-2.11.3.so...done. (no debugging symbols found)...done. Loaded symbols for /lib/libc.so.6 Reading symbols from /lib64/ld-linux-x86-64.so.2...Reading symbols from /usr/lib/debug/lib/ld-2.11.3.so...done. (no debugging symbols found)...done. Loaded symbols for /lib64/ld-linux-x86-64.so.2 0x00007fd78c89509f in __ieee754_log (x=2.4599721655249596e-05) at ../sysdeps/ieee754/dbl-64/e_log.c:160 160 ../sysdeps/ieee754/dbl-64/e_log.c: Datei oder Verzeichnis nicht gefunden. in ../sysdeps/ieee754/dbl-64/e_log.c
Nun, wie finde ich jetzt heraus, woran es hängt? Ich gebe z.B.
list
ein und kriege (immer wieder)155 in ../sysdeps/ieee754/dbl-64/e_log.c
Was sagt mir das? Dass sich das Programm gerade in
e_log.c
befindet? Wie komme ich da weiter, um herauszufinden woran es sprichwörtlich hängt?Viele Grüße,
-- Klaus.
-
Jetzt machst du noch
backtrace
. Damit siehst du den Callstack, d.h. du siehst, wo die momentane Funktion aufgerufen wurde, wo die Funktion, die die momentane Funktion aufgerufen hat aufgerufen wurde, usw.Du kannst mittels
frame
zwischen den Ebenen wechseln. Damit gehst du im Callstack hoch bis zu Code, den du selber geschrieben hast. Dieser code ist Teil deiner Endlosschleife und du kannst ihn nun genauer debuggen.Für sonstige Grundfunktionalität des gdb guckst du dir am besten ein Tutorial an, was so alles möglich ist. Am häufigsten brauchen wirst du Haltepunkte, Einzelschritt, Funktionsschritt und Anzeige von Ausdrücken (insbesondere von Variablen). Das sind bloß Grundlagen und leicht zu lernen, aber damit kommst du schon erstaunlich weit.
-
Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++ (auch C++0x und C++11) in das Forum Rund um die Programmierung verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
SeppJ schrieb:
Jetzt machst du noch
backtrace
. Damit siehst du den Callstack, d.h. du siehst, wo die momentane Funktion aufgerufen wurde, wo die Funktion, die die momentane Funktion aufgerufen hat aufgerufen wurde, usw.Ja sehr cool.
Ich habe mich nochmal an ein neues Programm drangehängt und kriege direkt
Loaded symbols for /lib64/ld-linux-x86-64.so.2 0x000000000040182f in boxmuller (mu=10, sigma=2, u=2.4599721655249596e-05, v=0.49092605197802186) at BoxMuller.cpp:7 7 rand_var = mu + sigma * sqrt(-log(u)) * cos(2*M_PI*v); Current language: auto The current source language is "auto; currently c++".
Mittel
backtrace
lande ich auch da(gdb) backtrace #0 0x000000000040182f in boxmuller (mu=10, sigma=2, u=2.4599721655249596e-05, v=0.49092605197802186) at BoxMuller.cpp:7 #1 0x000000000040125e in main () at main.cpp:30
Kann es sein, dass der Logarithmus Probleme mit sehr kleinen Zahlen hat? Die Funktionen get_uniform() liefert Zahlen in (0,1).
Aber eine Zahl in der Größenordnung e-5 bis e-6 ist doch für einedouble
noch nicht klein?Zumindest tritt der Fall in meiner for-Schleife auf und hängt bei 86%, d.h. es ist 43000 mal gut gegangen?
Natürlich muss das nichts heißen, aber wenn es nicht am Speicherüberlauf o.ä. hängt, dann verwundert es mich doch.
const double electron_number = 50000.0; for(unsigned int i = 0; i < electron_number; ++i) { double energy = 0; do{ energy = boxmuller(mean,sigma,rng.get_uniform(),rng.get_uniform()); } while( energy < 0 || energy > 2 * mean ); unsigned int counter = ( energy / delta ) + 0.5; ++energy_distr[counter]; std::cout << ( i / electron_number ) * 100.0 << " %" << std::endl; }
Gruß,
-- Klaus.
-
Kontext!
Du beschreibst gerade deine Symptome und Vermutungen wie für jemanden, der dein Programm in- und auswendig kennt. Hier versteht niemand, wovon du sprichst.
-
SeppJ schrieb:
Kontext!
Du beschreibst gerade deine Symptome und Vermutungen wie für jemanden, der dein Programm in- und auswendig kennt. Hier versteht niemand, wovon du sprichst.
Ja, sorry - ich hatte schon lange nicht mehr gepostet, da wurde aus präziser Fragestellung seichtes Labern.
Aber scheinbar hing es daran, dass die Zufallszahl zu klein war.
Also ich habe eine Funktion
get_uniform()
, welche mit Hilfe der GSL Zufallszahlen in (0,1) erzeugt. Diese habe ich wie folgt modifiziert und jetzt klappt es.double random_number_generator::get_uniform() { double u = 0; do{ u = gsl_rng_uniform(rng); } while( u < 0.001 || u > 0.999 ); return u; }
Mit Hilfe dieser Zufallszahlen möchte ich eine Gaussverteilung mit Hilfe der Box Muller Methode simulieren indem im Aufruf der Methode
u
undv
mittelsget_uniform()
ausgewertet werden.double boxmuller(double mu, double sigma, double u, double v) { double rand_var = 0; do{ rand_var = mu + sigma * sqrt(-log(u)) * cos(2*M_PI*v); } while ( rand_var < mu - 3 * sigma || rand_var > mu + 3 * sigma ); return rand_var; }
Und wenn ich die Informationen von
gdb
richtig deute, dann hing es daran, dass der Logarithmus in der boxmuller Methode nicht mit der kleinen (Zufalls- ) Zahl zurechtkam.Gruß,
-- Klaus.
-
Jain. Die Endlosschleife ist durchaus da, weil deine Funktion nicht mit kleinen Eingabewerten zurecht kommt (das hat übrigens nichts mit dem Logarithmus zu tun, der funktioniert tadellos). Der Grund ist jedoch, dass deine Box Muller Implementierung totaler Quatsch ist.
Wann soll denn die Schleife jemals abbrechen? Warum ist überhaupt die Prüfung da? Wieso bekommt die Methode Zufallszahlen, anstatt einem Zufallsgenerator? Kurz: Schlechtes Design + fehlerhafte Implementierung.
Ratschlag: Du möchtest ja anscheinend verhindern, dass deine Zufallszahlen zu groß werden. Dadurch verfälscht du aber die Gaussverteilung. Das ist sicher nicht gut für den Algorithmus, der die Zahlen benutzt. Ich rate aber einfach mal ganz frech, dass du gar keine Gaussverteilung brauchst, sondern bloß eine Verteilung mit den gleichen ersten beiden Momenten einer Gaussverteilung (-> zentraler Grenzwertsatz). Das heißt, du nimmst einfach eine entsprechend transformierte Gleichverteilung. Viel(!) performanter, viel einfacher zu implementieren, keine Designprobleme mehr, keine Probleme mehr mit Ausreißern.
P.S.: Da du im C++-Forum mit dem Thread angefangen hast: C++ kennt bereits allerlei Zufallszahlengeneratoren und Verteilungen. Das heißt, selbst wenn eine Gleichverteilung überraschenderweise nicht passen sollte, dann brauchst du das alles nicht selber zu implementieren*. Die Standardbibliothek ist viel besser getestet und designt als das eine Einzelperson in vertretbarer Zeit schaffen könnte. Und auch in C würdest du wohl besser zu einer bewährten Numerikbibliothek greifen, z.B. GSL.
*: Die transformierte Gleichverteilung implementierst du natürlich auch nicht selber, sondern nimmst die aus der Standardbibliothek.
-
SeppJ schrieb:
Wann soll denn die Schleife jemals abbrechen? Warum ist überhaupt die Prüfung da? Wieso bekommt die Methode Zufallszahlen, anstatt einem Zufallsgenerator? Kurz: Schlechtes Design + fehlerhafte Implementierung.
Meine Idee ist die Gaussverteilung zu simulieren. Da ich im Zuge der Monte Carlo (MC) Methode nur Zufallszahlen zur Verfügung habe, führt mich die Inversionsmethode zur Box Muller Methode.
Abstrakt gesehen ist das doch eine Funktion, welche mir für gegebenes und und zwei gleichverteilten Zufallszahlen in (0,1) die Gaussverteilung simuliert.
Was meinst du mit 'kriegt die Methode Zufallszahlen anstatt einen Zufallsgenerator' ?SeppJ schrieb:
Ratschlag: Du möchtest ja anscheinend verhindern, dass deine Zufallszahlen zu groß werden. Dadurch verfälscht du aber die Gaussverteilung.
Jain. Die Gaussverteilung ist von minus bis plus Unendlich ausgedehnt, allerdings 'reicht' das Intervall von , weil dann ca. 99% erfasst werden.
Aus diesem Grund verwerfe ich Zufallsvariablen, die nicht in diesem Intervall liegen.SeppJ schrieb:
P.S.: Da du im C++-Forum mit dem Thread angefangen hast: C++ kennt bereits allerlei Zufallszahlengeneratoren und Verteilungen. Das heißt, selbst wenn eine Gleichverteilung überraschenderweise nicht passen sollte, dann brauchst du das alles nicht selber zu implementieren*. Die Standardbibliothek ist viel besser getestet und designt als das eine Einzelperson in vertretbarer Zeit schaffen könnte. Und auch in C würdest du wohl besser zu einer bewährten Numerikbibliothek greifen, z.B. GSL.
*: Die transformierte Gleichverteilung implementierst du natürlich auch nicht selber, sondern nimmst die aus der Standardbibliothek.
Hä?
Ich verwende für die Erzeugung der Zufallszahlen schon die GSL. Ich habe die Klasse
random_number_generator
struct random_number_generator { random_number_generator(); ~random_number_generator(){ gsl_rng_free(rng); } gsl_rng * rng; unsigned int get_uniform_int(unsigned int n); double get_uniform(); };
Und dann eben für gleichverteilte Zufallszahlen in (0,1).
double random_number_generator::get_uniform() 5 { 6 double u = 0; 7 do{ 8 u = gsl_rng_uniform(rng); 9 } while( u < 0.001 || u > 0.999 ); 10 11 return u; 12 }
Diese Methode hat natürlich die 'Abfrage' für oben diskutierte vermeintliche Verhalten des Logarithmus.
-
Du machst dir die gewünschten Eigenschaften deiner Verteilungen kaputt, wenn du sie verfälscht.
Leider gehst du nicht auf die von mir als interessant empfundenen Punkte ein. Ich weiß nicht, wie ich dir weiter helfen soll, außer dass
1. es falsch ist.
2. es unnötig ist, da du nachmachst, was längst hundertfach existiert.
3. es unnötig ist, da du es wahrscheinlich gar nicht brauchst
4. deine Vermutungen über die Fehlerursache (Logarithmus) ebenfalls falsch sind.Detaillierte Erklärungen habe ich oben schon gegeben.
-
Mh,
also ich bin ja schon lange davon abgekommen das Rad neu zu erfinden und mehr anzuwenden was Leute mit viel mehr Expertise schon programmiert haben.
Ich war überrascht zu sehen, dass z.B. die GSL eine eigene Funktion extra für die Gaussverteilung besitzt [1].
Aber hey, dort steht z.B.
This function uses the Box-Muller algorithm which requires two calls to the random number generator r.
Also ich war zumindest auf dem richtigen Weg die Box Muller Methode zu verwenden!
Dann werde ich versuchen diese Methode zu implementieren.
Ist dies ein Beispiel dafür, dass du meintest ich solle mich mehr danach umschauen was schon vorhanden ist?
Viele Grüße,
-- Klaus.
-
Ja, das meinte ich. Und wenn du dir die Methode genau anguckst, wirst du auch sehen, dass sie einen Zufallsgenerator als Argument hat, keine Zufallszahl.
Was du dir noch unbedingt angucken solltest:
- Zufallszahlen mit C++. Dann wirst du die fette Abhängigkeit GSL los, falls du sie nur der Zufallszahlen wegen benutzt:
http://en.cppreference.com/w/cpp/numeric/random
- Nochmal nachdenken, ob du wirklich gaussverteilte Zahlen brauchst. Du sprichst von Monte Carlo Verfahren, das klingt nach Simulation von physikalischen Vorgängen. Da ist es oft unangenehm, gaussverteilte Zufallszahlen zu haben, wegen der möglichen sehr großen Werte. Die Algorithmen, die ich so kenne, brauchen eigentlich nur passendes erstes und zweites Moment um (langfristig) zu funktionieren. Das kann man rechentechnisch viel günstiger haben und ohne die Ausreißer, die zu unangenehmen "Zuckungen" führen können.
-
SeppJ schrieb:
Ja, das meinte ich. Und wenn du dir die Methode genau anguckst, wirst du auch sehen, dass sie einen Zufallsgenerator als Argument hat, keine Zufallszahl.
Bei allem Respekt, aber der Unterschied ist doch bestenfalls die Art der Implementierung und nicht die Art wie es funktioniert. Immerhin steht dabei
This function uses the Box-Muller algorithm which requires two calls to the random number generator r.
Also du hast recht, dass ein Zufallsgenerator übergeben wird, aber intern werden von diesem zwei Zufallszahlen benötigt.
Meine Variante sieht so aus:
double boxmuller(double mu, double sigma, double u, double v) { return = mu + sigma * sqrt(-log(u)) * cos(2*M_PI*v); }
Und was du meinst, würde in meinem Code z.B. so aussehen:
double boxmuller(double mu, double sigma, random_number_generator & rng) { double u = rng.get_uniform(); double v = rng.get_uniform(); return = mu + sigma * sqrt(-log(u)) * cos(2*M_PI*v); }
Natürlich lasse ich mich jetzt gerne überzeugen, warum es besser ist ganze Objekte zu übergeben (deine Variante), anstatt nur die Ausgaben deren (Klassen- ) Funktionen (meine Variante).
SeppJ schrieb:
- Nochmal nachdenken, ob du wirklich gaussverteilte Zahlen brauchst. Du sprichst von Monte Carlo Verfahren, das klingt nach Simulation von physikalischen Vorgängen. Da ist es oft unangenehm, gaussverteilte Zufallszahlen zu haben, wegen der möglichen sehr großen Werte. Die Algorithmen, die ich so kenne, brauchen eigentlich nur passendes erstes und zweites Moment um (langfristig) zu funktionieren. Das kann man rechentechnisch viel günstiger haben und ohne die Ausreißer, die zu unangenehmen "Zuckungen" führen können.
Ich denke wir meinen dasselbe.
Ich formuliere es mal so: Angenommen das Alter der Menschen wäre zwischen 0 und 100 Jahren gaussverteilt. Dann kann ich über die Box Muller Methode mittels zwei gleicherteilten Zufallszahlen in (0,1) das Alter als Zufallsvariable beschreiben, die gaussverteilt ist.
Dummerweise kann das Ergebnis aber auch -3 oder 107 Jahre sein. Aus diesem Grund hatte ich die Schleife eingebautdouble alter = 0; do{ alter = <Box-Muller-Method> } while(alter < 0 || alter > 100);
Wenn also das alter nicht in dem passenden Intervall liegt, wird eine neue Zufallsvariable erzeugt. Wenn ich das Intervall sehr groß wähle, relativ zur Standardabweichung, dann muss ich sehr selten wiederholen.
Ich verstehe nur nicht, warum dies eine Endlosschleife sein soll!Ich habe den Eindruck, dass du diese beschriebene Problematik genau damit beheben willst, dass du sagst Die Algorithmen, die ich so kenne, brauchen eigentlich nur passendes erstes und zweites Moment und führt mich z.B. zur Moment erzeugenden Funktion.
Habe ich langsam verstanden was du meinst?
Gruß,
-- Klaus.
-
Habe ich langsam verstanden was du meinst?
Leider nein, daher
Schluss mit den Hinweisen und Klartext:Klaus82 schrieb:
SeppJ schrieb:
Ja, das meinte ich. Und wenn du dir die Methode genau anguckst, wirst du auch sehen, dass sie einen Zufallsgenerator als Argument hat, keine Zufallszahl.
Bei allem Respekt, aber der Unterschied ist doch bestenfalls die Art der Implementierung und nicht die Art wie es funktioniert. Immerhin steht dabei
This function uses the Box-Muller algorithm which requires two calls to the random number generator r.
Also du hast recht, dass ein Zufallsgenerator übergeben wird, aber intern werden von diesem zwei Zufallszahlen benötigt.
Nö! Fällt dir denn nichts auf, wenn du das mit deinem eigenen Generator vergleichst? Der braucht nämlich viel mehr Zufallszahlen, wenn die Schleifenbedingung anschlägt. Bekommt er aber nicht. -> Endlosschleife.
Wenn du dir den GSL Box-Muller anguckst, wirst du sehen, dass dieser auch nicht nur zwei Zufallszahlen braucht, sondern eine andere Variante des Box-Muller Verfahrens benutzt. Wusstest du nicht? Klar wusstest du das nicht, denn du musstest es nicht wissen und der Funktionskopf hat dieses völlig unnötige Details vor dir verborgen. Denn das braucht der Benutzer gar nicht zu wissen. Er sollte es nicht wissen. Denn jetzt können sie einfach die Implementierung ändern, der Funktionskopf sieht immer noch genau gleich aus, da völlig egal ist, wie viele Zufallszahlen intern verbraucht werden.
Darum ist diese Variante vom Design her besser.
SeppJ schrieb:
- Nochmal nachdenken, ob du wirklich gaussverteilte Zahlen brauchst. Du sprichst von Monte Carlo Verfahren, das klingt nach Simulation von physikalischen Vorgängen. Da ist es oft unangenehm, gaussverteilte Zufallszahlen zu haben, wegen der möglichen sehr großen Werte. Die Algorithmen, die ich so kenne, brauchen eigentlich nur passendes erstes und zweites Moment um (langfristig) zu funktionieren. Das kann man rechentechnisch viel günstiger haben und ohne die Ausreißer, die zu unangenehmen "Zuckungen" führen können.
Ich denke wir meinen dasselbe.
Nein.
Ich formuliere es mal so: Angenommen das Alter der Menschen wäre zwischen 0 und 100 Jahren gaussverteilt. Dann kann ich über die Box Muller Methode mittels zwei gleicherteilten Zufallszahlen in (0,1) das Alter als Zufallsvariable beschreiben, die gaussverteilt ist.
Dann ist das Alter offensichtlich nicht gaussverteilt. Du samplest irgendeine andere Verteilung. Mit ganz anderen Eigenschaften. Mag sein, dass es für dich das richtige ist, ich weiß schließlich nicht, worum es geht. Ich kann dir nur sagen, mir kommt das verdächtig vor. Wenn du einen Betreuer oder ähnliches für deine Arbeit hast, würde ich dir dringend raten, diesen zu fragen, bevor du an Verteilungen rumspielst, die von einem Algorithmus vorausgesetzt werden.
Ich habe den Eindruck, dass du diese beschriebene Problematik genau damit beheben willst, dass du sagst Die Algorithmen, die ich so kenne, brauchen eigentlich nur passendes erstes und zweites Moment und führt mich z.B. zur Moment erzeugenden Funktion.
Ich fürchte, wir sind gar nicht auf einer Wellenlänge. Ich weiß nicht, was du überhaupt machst,du weißt nicht, wovon ich rede. Da brauchen wir bei diesem Nebenthema nicht weiter zu diskutieren. Aber es sollte bezüglich deiner Eingangsfrage nun klar sein, wieso die Endlosschleife auftritt und wieso das Design nicht so toll ist.
-
SeppJ schrieb:
Nö! Fällt dir denn nichts auf, wenn du das mit deinem eigenen Generator vergleichst? Der braucht nämlich viel mehr Zufallszahlen, wenn die Schleifenbedingung anschlägt. Bekommt er aber nicht. -> Endlosschleife.
Ja, eben habe ich es geschnallt. Stand echt auf dem Schlauch. Die while Bedingung bringt natürlich nichts, wenn die Zufallszahlen u und v übergeben werden, denn dann sind sie fix! D.h. die Zufallszahlen u und v müssen in jedem Durchlauf neu erzeugt werden!
Über den Rest muss ich nachdenken. Ich verstehe noch nicht so recht die Kritik daran, dass ich Ergebnisse wegwerfe.
Ich habe den Eindruck dir geht es darum, dass eine Methode, die aufgrund von gleichverteilten Zufallszahlen eine Verteilung simulieren soll nicht in die Verlegenheit kommen darf, dass ein Ergebnis verworfen wird. Denn sonst lässt die Methode Ergebnisse zu, die in der zu simulierenden Verteilung nicht vorkommen, ergo simuliert die Methode die Verteilung nicht eindeutig.Gruß,
-- Klaus.
-
Klaus82 schrieb:
Über den Rest muss ich nachdenken. Ich verstehe noch nicht so recht die Kritik daran, dass ich Ergebnisse wegwerfe.
Ich habe den Eindruck dir geht es darum, dass eine Methode, die aufgrund von gleichverteilten Zufallszahlen eine Verteilung simulieren soll nicht in die Verlegenheit kommen darf, dass ein Ergebnis verworfen wird. Denn sonst lässt die Methode Ergebnisse zu, die in der zu simulierenden Verteilung nicht vorkommen, ergo simuliert die Methode die Verteilung nicht eindeutig.Nein, das war nicht, was ich sagen wollte.
Lassen wir das einfach ruhen. Ich kann dir hier nicht die Welt der Zufallszahlen erklären. Wenn du mit Momenten und Verteilungen usw. nichts anfangen kannst, dann wird es wohl auch (hoffentlich) nicht so wichtig sein für dich. Behalt im Hinterkopf, dass dir mal jemand gesagt hat, dass an der Methode etwas faul sein könnte. Wenn du dich besser auskennst, dann guckst du dir nochmal an, ob das wirklich in Ordnung ist.