AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Seltsames Verhalten einer Funktion

Ein Thema von Pytroxis · begonnen am 24. Apr 2019 · letzter Beitrag vom 28. Apr 2019
Antwort Antwort
Seite 1 von 2  1 2      
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.277 Beiträge
 
Delphi 10.4 Sydney
 
#1

AW: Seltsames Verhalten einer Funktion

  Alt 24. Apr 2019, 11:57
Hallo,
OK, für den schlechten Stil hast Du dich schon entschuldigt

Aber:
for i := 0 to round(zahlen[index][Length(zahlen[index])-1]-zahlen[index][0]) do
und
round(xWert + i * eineLaengenEinheit), getHeight[8

Wer soll das verstehen?
Bitte benutze eine lokale Variablen und F5/F7/F8 und Strg+F5.

Ich kenne dieses Boxplots erst mal gar nicht.
Und einen Datensatz habe ich auch nicht gefunden.
Woran erkennt man, dass die Boxplots einen gleichen/unterschiedlichen Datensatz haben?

Du hattest ja geschrieben, dass es in C++ bereits funktionierte.
Gehe doch den C++ und den Delphi-Code schrittweise durch und vergleiche die Variableninhalte.
Heiko

Geändert von hoika (24. Apr 2019 um 12:05 Uhr)
  Mit Zitat antworten Zitat
Pytroxis

Registriert seit: 12. Apr 2019
46 Beiträge
 
#2

AW: Seltsames Verhalten einer Funktion

  Alt 24. Apr 2019, 13:05
Wer soll das verstehen?
Bitte benutze eine lokale Variablen und F5/F7/F8 und Strg+F5.
Das Problem was ich hierbei habe ist, dass die Variablen in einer anderen Procedure verwendet werden müssen (-> Sortieren des Datensatzes, errechnen des medians, der Quartils etc.). Danach werden sie erst zum zeichnen verwendet (in einer anderen Funktion). Demnach wüsste ich nicht wie ich auf lokale Variablen setzen soll außer vielleicht der lokale Variable den Wert der globalen zuzuweisen (-> andere Möglichkeit sehe ich gerade nicht, korrigiere mich bitte falls ich falsch liege).

Ich kenne dieses Boxplots erst mal gar nicht.
Und einen Datensatz habe ich auch nicht gefunden.
Woran erkennt man, dass die Boxplots einen gleichen/unterschiedlichen Datensatz haben?
Ein Boxplots ist das was du im Anhang gesehen hast (-> grafische Darstellung einer Verteilung).
Die Datensätze sind in zahlen gespeichert und sie werden durch den Nutzer eingeben oben in meinem Fall waren die Datensätze:
Delphi-Quellcode:
zahlen[0] := [0,1,2,3,4,5]
zahlen[1] := [0,1,2,3,4,6]
Der unterschied war hierbei die 5 bzw. 6 sprich das Maximum.
Im oberen Bild sieht man, dass beide Boxplots richtig dargestellt werden sofern die Datensätze gleich sind aber bei unterschiedlichen Datensätzen der obere Boxplot "verkrüppelt" ist.

Du hattest ja geschrieben, dass es in C++ bereits funktionierte.
Gehe doch den C++ und den Delphi-Code schrittweise durch und vergleiche die Variableninhalte.
Witzige Geschichte, dass kann ich nicht machen. Das ursprüngliche Programm war fertig, korrekt, als ich dann mit umschreiben auf Delphi soweit fertig war, wollte mein Lehrer, dass ich noch das vergleichen hinzufüge und dabei gibt es jetzt halt die Probleme.

Du rundest Gleitkommawerte auf Ganzzahlen, da kann es schon mal passieren, dass zwei Werte, die in der Dezimaldarstelllung gleich aussehen und als Nachkommateil .5 haben in der Binärdarstellung leicht unterschiedlich sind, so das einer nach oben und einer nach unten gerundet wird. Vielleicht ist das dein Problem...
Probeweise habe ich mal alle round durch trunc ersetz, da somit dieser Fehler ja nicht mehr auftreten dürfte.
Allerdings tritt er immer noch auf und es hat sich nichts verändert. Aber prinzipiell ist die Idee mit trunc statt round gar nicht so schlecht.


Deine Methode ist viel zu lang und komplex. Mache mehrere kleinere daraus, z.B. trenne die Berechnung und das Malen.
Und dann wie hoika schon schrieb debugge.
Aber wie soll ich es denn weiter trennen? Die einzige Möglichkeit die ich sehe wären Arrays (-> Mit den Rechnungen etc.) und diesen dann an eine Funktion zum zeichnen weiterzugeben oder hast du eine bessere Idee?


Ohne den Source im Einzelnen angesehen zu haben, habe ich folgenden Verdacht:
Es gibt globale Variablen. Die Prozeduren gehören zu keinem Objekt und es wird in den Prozeduren auf die globalen Variablen zugegriffen. Bei jedem Repaint besteht die Gefahr, dass Werte aus den globalen Variablen verwendet werden, die zum anderen "Datensatz" gehören. Die Folge ist, dass mit falschen Werten gezeichnet wird.
Die Globalen Variablen werden eigentlich nur einmal verändert und zwar beim sortieren des Datensatzes.
In der Zeichnen Funktion werden ausschließlich lokale Variablen verwendet bzw. überschrieben, es werden nur aus den globalen Variablen gelesen, demnach dürften die globalen Variablen nicht verändert worden sein.


Ich habe die Datensätze auch mehrfach kontrolliert und getestet ob diese verändert werden o.ä. und das wurden sie nicht, daher wundert mich das ganze ja so sehr, dass die Darstellung einmal mit gleichen Datensätzen geht und das andere mal mit unterschiedlichen nicht mehr.
Werde jetzt mal debuggen und mich später nochmal melden
  Mit Zitat antworten Zitat
Pytroxis

Registriert seit: 12. Apr 2019
46 Beiträge
 
#3

AW: Seltsames Verhalten einer Funktion

  Alt 24. Apr 2019, 13:10
Ich habe jetzt noch nicht gedebuggt aber mir ist folgende aufgefallen:
Bisher waren die Datensätze immer
Delphi-Quellcode:
zahlen[0] := [1,2,3,4,5]
zahlen[1] := [1,2,3,4,6]
Dabei war dann der erste Boxplot verkrüppelt.
Nun habe ich die Datensätze einfach mal getauscht:
Delphi-Quellcode:
zahlen[0] := [1,2,3,4,6]
zahlen[1] := [1,2,3,4,5]
Und so werden beide ganz normal angezeigt.

Das wundert mich jetzt noch viel mehr

Edit:
Bitte benutze eine lokale Variablen und F5/F7/F8 und Strg+F5.
Das debuggen hat wirklich geholfen!
Habe meinen Fehler gefunden und jetzt fühle ich mich ziemlich dumm -_-
Habe vergessen die Variablen für Quartils und Median auch auf mehrere Boxplots auszulegen. Werde das jetzt mal ändern aber daran liegt es vermutlich.

Edit2:
Es lag tatsächlich an den Variablen, jetzt fühle ich mich wirklich dumm -_-

Geändert von Pytroxis (24. Apr 2019 um 14:13 Uhr)
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.277 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Seltsames Verhalten einer Funktion

  Alt 24. Apr 2019, 14:04
Hallo,
geht doch.

die Quartils und Median sahen für mich eh schon etwas komisch aus,
die hatte ich auch im Verdacht ...

Der Debugger ist Dein bester Freund.
Heiko

Geändert von hoika (24. Apr 2019 um 14:50 Uhr)
  Mit Zitat antworten Zitat
Pytroxis

Registriert seit: 12. Apr 2019
46 Beiträge
 
#5

AW: Seltsames Verhalten einer Funktion

  Alt 24. Apr 2019, 15:27
Hallo,
geht doch.

die Quartils und Median sahen für mich eh schon etwas komisch aus,
die hatte ich auch im Verdacht ...

Der Debugger ist Dein bester Freund.
Merk ich mir für die Zukunft


Nicht dumm! Klüger als vorher

Sherlock
JaJa
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#6

AW: Seltsames Verhalten einer Funktion

  Alt 24. Apr 2019, 15:39
Super. So was freut einem, wie das hier gelaufen ist. Großes Lob an den Threadersteller und an die Helfer.

Zusatzaufgabe: Jetzt noch etwas Refactoring und das ganze in eine Klasse packen. Dann kannst du beliebig viele Boxplots machen, weil jeder Boxplot ein unabhängiges Objekt mit der Klasse als Blaupause ist. Und wenn du das hier einmal kapiert und geschafft hast, fällt es beim nä htsen mal leichter; egal in welcher Programmiersprache.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Pytroxis

Registriert seit: 12. Apr 2019
46 Beiträge
 
#7

AW: Seltsames Verhalten einer Funktion

  Alt 24. Apr 2019, 16:00
Super. So was freut einem, wie das hier gelaufen ist. Großes Lob an den Threadersteller und an die Helfer.

Zusatzaufgabe: Jetzt noch etwas Refactoring und das ganze in eine Klasse packen. Dann kannst du beliebig viele Boxplots machen, weil jeder Boxplot ein unabhängiges Objekt mit der Klasse als Blaupause ist. Und wenn du das hier einmal kapiert und geschafft hast, fällt es beim nächstes mal leichter; egal in welcher Programmiersprache.
Habe das schon alles in eine extra Unit ausgelagert aber das mit der Klasse ist wirklich ne super Idee! Werde mich dann die nächsten Tage mal daran versuchen es umzuschreiben.
Theoretisch ist es ja nicht so schwierig, hoffe ich mal

Hatte bis jetzt immer eine schleife genutzt, welche die Funktion zeichnen aufruft (bei mehreren Boxplots).
Meinst du ich kann das so lassen oder sollte ich das, wenn ich es zu einer Klasse umschreibe, anders lösen?

Edit:
Oder wäre folgende Option besser -> Funktion in der Klasse die zeichnen aufruft (mit Schleife etc.). Und dann in Form2 (wo gezeichnet wird), lediglich diese Funktion statt zeichnen aufzurufen?

Geändert von Pytroxis (24. Apr 2019 um 16:24 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sherlock
Sherlock

Registriert seit: 10. Jan 2006
Ort: Offenbach
3.811 Beiträge
 
Delphi 12 Athens
 
#8

AW: Seltsames Verhalten einer Funktion

  Alt 24. Apr 2019, 14:31
Edit2:
Es lag tatsächlich an den Variablen, jetzt fühle ich mich wirklich dumm -_-
Nicht dumm! Klüger als vorher

Sherlock
Oliver
Geändert von Sherlock (Morgen um 16:78 Uhr) Grund: Weil ich es kann
  Mit Zitat antworten Zitat
Pytroxis

Registriert seit: 12. Apr 2019
46 Beiträge
 
#9

AW: Seltsames Verhalten einer Funktion

  Alt 28. Apr 2019, 14:10
Wer soll das verstehen?.
Hatte es nochmal überarbeitet und versucht übersichtlicher zu gestalten.
Meine Lösung ist nun:

Delphi-Quellcode:
procedure TBoxplot.zeichnen(Boxplot : real);
  var i, xWert, index: integer;
      eineLaengeneinheit : Double;
      getHeight : array[0..9] of integer;
      getWidth : array[0..3] of integer;
  begin
    if Length(FZahlen) > 0 then begin
      xWert := 50;
      index := trunc(Boxplot);

      eineLaengeneinheit := (FSize[1]-120) / (FZahlen[index][High(FZahlen[index])] - FZahlen[index][0]);


      getHeight[0] := round(FSize[0] * 0.31919 + FHeight * Boxplot);
      getHeight[1] := round(FSize[0] * 0.13214 + FHeight * Boxplot);
      getHeight[2] := round(FSize[0] * 0.18379 + FHeight * Boxplot);
      getHeight[3] := round(FSize[0] * 0.04839 + FHeight * Boxplot);
      getHeight[4] := round(FSize[0] * 0.09839 + FHeight * Boxplot);
      getHeight[5] := round(FSize[0] * 0.21839 + FHeight * Boxplot);
      getHeight[6] := round(FSize[0] * 0.15839 + FHeight * Boxplot);
      getHeight[7] := round(FSize[0] * 0.26839 + FHeight * Boxplot);
      getHeight[8] := round(FSize[0] * 0.28839 + FHeight * Boxplot);
      getHeight[9] := round(FSize[0] * 0.27742 + FHeight * Boxplot);

      getWidth[0] := round(xWert + (FQuartils[index][0] - FZahlen[index][0]) * eineLaengenEinheit);
      getWidth[1] := round(xWert + (FMedian[index] - FZahlen[index][0]) * eineLaengenEinheit);
      getWidth[2] := round(xWert-1 + (FQuartils[index][1] - FZahlen[index][0]) * eineLaengenEinheit);



      // Name des Boxplots
      FPaintBox.Canvas.TextOut(xWert-20, getHeight[3]-20, FNamen[index] + ':');

      // Einteilung/Markierung
        // Minimum
      FPaintBox.Canvas.TextOut(xWert-5, getHeight[0], FloatToStr(FZahlen[index][0]));
      drawLine(clRed, xWert, getHeight[1], xWert, getHeight[2]);

        // Maximum
      FPaintBox.Canvas.TextOut(FWidth-5, getHeight[0], FloatToStr(FZahlen[index][High(FZahlen[index])]));
      drawLine(clRed, FWidth, getHeight[1], FWidth, getHeight[2]);

        // unteres Quartil
      FPaintBox.Canvas.TextOut(getWidth[0]-5, getHeight[3], FloatToStr(FQuartils[index][0]));
      drawLine(clRed, getWidth[0], getHeight[4], getWidth[0], getHeight[5]);

        // FMedian[index]
      FPaintBox.Canvas.TextOut(getWidth[1]-5, getHeight[3], FloatToStr(FMedian[index]));
      drawLine(clRed, getWidth[1], getHeight[4], getWidth[1], getHeight[5]);

        // oberes Quartil
      FPaintBox.Canvas.TextOut(getWidth[2]-5, getHeight[3], FloatToStr(FQuartils[index][1]));
      drawLine(clRed, getWidth[2], getHeight[4], getWidth[2], getHeight[5]);

        //Boxplot an sich
      drawLine(clBlack, xWert, getHeight[6], getWidth[0], getHeight[6]);
      drawLine(clBlack, getWidth[0], getHeight[4], getWidth[2], getHeight[4]);
      drawLine(clBlack, getWidth[0], getHeight[5], getWidth[2], getHeight[5]);
      drawLine(clBlack, getWidth[2], getHeight[6], FWidth, getHeight[6]);

      //Skala
      for i := 0 to round(FZahlen[index][High(FZahlen[index])]-FZahlen[index][0]) do begin
        getWidth[3] := round(xWert + i * eineLaengenEinheit);
        drawLine(clBlack, getWidth[3], getHeight[7], getWidth[3], getHeight[8]);
      end;
      drawLine(clBlack, xWert, getHeight[9], FWidth, getHeight[9]);
    end;
  end;
Ist das so schon mal verständlicher?
Und habt Ihr noch Tipps es übersichtlicher/verständlicher zu schreiben?
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.780 Beiträge
 
Delphi 10.4 Sydney
 
#10

AW: Seltsames Verhalten einer Funktion

  Alt 28. Apr 2019, 14:23
..wo kommen denn diese "magischen" Werte her?

Delphi-Quellcode:
      getHeight[0] := round(FSize[0] * 0.31919 + FHeight * Boxplot);
      getHeight[1] := round(FSize[0] * 0.13214 + FHeight * Boxplot);
      getHeight[2] := round(FSize[0] * 0.18379 + FHeight * Boxplot);
      getHeight[3] := round(FSize[0] * 0.04839 + FHeight * Boxplot);
      getHeight[4] := round(FSize[0] * 0.09839 + FHeight * Boxplot);
      getHeight[5] := round(FSize[0] * 0.21839 + FHeight * Boxplot);
      getHeight[6] := round(FSize[0] * 0.15839 + FHeight * Boxplot);
      getHeight[7] := round(FSize[0] * 0.26839 + FHeight * Boxplot);
      getHeight[8] := round(FSize[0] * 0.28839 + FHeight * Boxplot);
      getHeight[9] := round(FSize[0] * 0.27742 + FHeight * Boxplot);
Um es lesbarer zu gestalten, vielleicht die Werte durch Konstante ersetzen.
Oder die Werte in ein Array stecken, mit den gleichen Indizes wie getHigh.
Dann könntest Du das alles in eine Schleife von 0 bis 9 abarbeiten.

Grüße
Klaus
Klaus
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:50 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz