# Problem mit Standardabweichung



## chrisl77 (3. Aug 2012)

Liebe Leute, 

ich habe ein Problem mit einer Standardabweichung. Ich möchte aus einem Textfile Daten zusammenfassen (ca. 3000 Werte/Stunde). Dabei möchte ich die Mittelwerte/h und Standardabweichungen ausgeben. Das Problem scheint zu sein, dass ich den Mittelwert von innerhalb einer if-Schleife für die Berechnung außerhalb brauche... oder unterliege ich hier einem Denkfehler? 
Außerdem stimmen die Mittelwerte nicht 100%ig mit excel überein, evtl. erste und letzte Zeile - Schleifen-Problem?
Ich sitze schon ziemlich lange daran, und bin für jede Hilfe dankbar. 

lg
chrisl 

Code


```
package auslesen_stu;

import java.io.*;


/*
 * @author c.brandstätter
 */
public class ZuluftStunden {

    static String strRead, secondentry;
    static String dlm = ",", dlm2 = " ", dlm3 = "/";
    static double d, stdev, ste, d2;
    static int counter, m, st, sec, ho, st2;
    static int counter2 = 0;
    static int counter3 = 1;
    static BufferedReader namesFile;
    static String strRead2, part1;
    static String strReadMinute, strReadStunde, strReadSekunde;
    static double summe = 0;
    static double summed = 0;
    static double aver2 = 0;
    static double mw = 0;
    static double mw2 = 0;
    static double mw3 = 0;
    static int mold = -1;
    static int stold = -1;
    static double abc = 0;
    static FileWriter writer;
    static File file;

    public static void main(String[] args) throws FileNotFoundException {


        namesFile = new BufferedReader(new FileReader("*"));

        try {

            file = new File("*");
            writer = new FileWriter(file, true);
            writer.write(namesFile.readLine());
            writer.write(System.getProperty("line.separator"));
            writer.write("Stunde " + " Mittelwert " + " Stabw " + " Standarderror ");
            writer.write(System.getProperty("line.separator"));
            while ((strRead = namesFile.readLine()) != null) {

                if (counter > 0) {

                    String splitarray[] = strRead.split(dlm);
                    part1 = splitarray[0]; //Zeit
                    String zeitteil[] = part1.split(dlm3);
                    strReadSekunde = zeitteil[2];
                    strReadMinute = zeitteil[1];
                    strReadStunde = zeitteil[0];
                    secondentry = splitarray[1]; //Messwert und Skala
                    String cutzwei[] = secondentry.split(dlm2);
                    strRead2 = cutzwei[1]; //Messwert
                    d = Double.parseDouble(strRead2);
                    d2 = (d*60)/1000;
                    m = Integer.parseInt(strReadMinute);
                    st = Integer.parseInt(strReadStunde);
                    sec = Integer.parseInt(strReadSekunde);

                    summe = summe + d2;
                    counter2++;
                    // System.out.println(d);


                    abc = abc + (summe-aver2)*(summe-aver2);//PROBLEM!!!

                   // System.out.println(abc);

                    if (st != stold) {
                        summed = summe + d2;
                        counter3 = counter2 - 1;
                        aver2 = (summed) / (counter2);
                        //mw = (summed-counter3*aver2)*(summed-counter3*aver2);
                        mw2 = Math.sqrt(abc / counter3);
                        ste = mw2 / Math.sqrt(counter3);
                        //ho = st - 1;
                        st2 = st - 1; //aktuelle stunde

                        if (st2 == -1) {
                            st2 = 23;
                        }

                        System.out.println("MittelW " + aver2 + " summe " + summed + " counter2 " + counter3 + " Messwert " + d2 + " SE " + ste + " stabw " + mw2 + " sekunde " + sec + " minute " + m + " stunde " + st2);
                        writer.write(st2 + " "  + aver2 + " " + mw2 + " " + ste + " "+counter3);
                        writer.write(System.getProperty("line.separator"));
                        stold = st;
                        counter2 = 0;
                        summe = 0;
                        mw2 = 0;
                        stdev = 0;
                        mw3 = 0;
                        abc = 0;



                    }



                } //break;
                counter++;
            }
            writer.flush();
            writer.close();

        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (namesFile != null) {
                    namesFile.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}
```

Ausgabe 
(die ersten und letzten beiden Zeilen; zusätzlich wird ein file generiert, in das er die Daten reinschreibt.)

MittelW -0.007871999824047089 summe -0.007871999824047089 counter2 0 Messwert -0.003935999912023544 SE Infinity stabw Infinity sekunde 17 minute 25 stunde 14
MittelW 0.8247612895651469 summe 1649.522579130294 counter2 1999 Messwert 1.258055971880257 SE 19.17678377986091 stabw 857.3974126640069 sekunde 6 minute 0 stunde 15


MittelW 0.5652572924944593 summe 1950.702916398379 counter2 3450 Messwert 0.9532799786925316 SE 17.165361168485276 stabw 1008.2366800278943 sekunde 6 minute 0 stunde 7
MittelW 0.8070397663090869 summe 2784.28719376635 counter2 3449 Messwert 0.757967983058095 SE 28.664106957959437 stabw 1683.3910462302338 sekunde 6 minute 0 stunde 8


----------



## chrisl77 (3. Aug 2012)

Hier ist noch ein Nachtrag mit Beispielen (Zeilen 1-10) aus den jeweiligen files, um das Ganze noch verständlicher zu machen.

lg
Chrisl

Input-File

13/7/2012 Nummer 1
15/25/16, -0.060399998649954795 ml(n)/min, 
15/25/17, -0.06559999853372574 ml(n)/min, 
15/25/18, -0.06639999851584434 ml(n)/min, 
15/25/19, -0.08079999819397926 ml(n)/min, 
15/25/20, -0.057999998703598975 ml(n)/min, 
15/25/21, -0.08079999819397926 ml(n)/min, 
15/25/22, -0.06719999849796295 ml(n)/min, 
15/25/23, -0.06479999855160713 ml(n)/min, 
15/25/24, -0.07999999821186066 ml(n)/min, 

Output-File

Stunde  Mittelwert  Stabw  Standarderror 
14 -0.007871999824047089 NaN NaN 0
15 0.8247612895651469 0.0 0.0 1999
16 1.0280523457168933 1648.936811509822 28.077434080381682 3449
17 1.0535972912328755 3546.2665292967267 60.384402854481166 3449
18 1.0028698332781139 3634.3836652552523 61.87585660662902 3450
19 0.8698543875137614 3460.4024687600595 58.92234410076536 3449
20 1.099245248473435 3000.5626782075706 51.0923767444346 3449
21 0.6679700163740643 3791.846444775635 64.56603907012925 3449
22 0.3574941583379817 2304.162450483776 39.22866667806792 3450


----------



## SlaterB (3. Aug 2012)

Verständnis ist ein gutes Stichwort, davon ist wirklich wenig da

diese unendlichen Mengen an Variablen und Einzelwerte können doch nicht alle unverzichtbar fürs Problem sein?
reduziere dich auf einen simplen Wert statt Datum, mit einfachen Zahlen 3, 5, 8,
reduziere dich auf 10 Werte statt tausende,

verzichte auf mehrere Datendurchgänge, bei denen von vorne angefangen werden muss,
verzichte auf Datei, arbeit mit Daten im Array in Programm eingetragen,
verzichte auf Standardabweichung, Schreiben in Datei, übersprungene erste Zeilen und was noch alles dabei ist

rechne den Durchschnitt von 3, 5, 8 usw. aus, dasselbe in Excel,
kommt dasselbe raus? nun, da kann man recht froh sein,
nun fange an, das Problem in einzelne Richtungen zu erweitern,
auf 3000 Werte zu kommen ist nicht ganz so leicht mit Quelltext, wenn auch nicht undenkbar,
lieber aber erst auf Datum wechseln, wenn das vielleicht in Excel nicht ganz so leicht nachvollziebar berechnet wird

überhaupt könntest du das Excel vielleicht hochladen, welche Daten welcher Spalte mit welchem Endergebnis ist dort der Durchschnitt, 
und was genau bekommst du in Java raus?


----------



## chrisl77 (3. Aug 2012)

Also, 

wenn ich exemplarisch die excel-Ausgabe für Stunde 0 (letzter Tag) verwende:

Excel: Summe: 1196,929125; Mittelwert: 0,346935978; Stabw: 0,000826493; Anzahl: 3450;
Programm: Summe: 1197.278253; Mittelwert: 0,347037; Stabw: 1194,12; Anzahl: 3449;

Das Problem ist, die Dateien sind einfach bei weitem zu groß (ca. 7-10mb) zum hochladen. 
Deswegen habe ich auch exemplarisch ein paar Zeilen angeführt. Das Datum steht nur in der ersten Zeile, deswegen die variable counter (>0). 

Das führt auch dazu, dass die Überprüfung mit excel eine Weile dauert. 
Das bedingt dann wohl auch, dass ich ein Programm benötige, welches mir die Abläufe automatisiert. 

Die erhaltenen Daten sind nicht Quelltext, sondern einfach in ein textfile eingetragen. Dazu wurde bereits ein Programm geschrieben. Ich erhalte pro Sekunde 25 Messwerte; die werden bereits gemittelt pro Sekunde. Diese Messwerte möchte ich nun mitteln auf Stunden, daher die ungefähr 3500 Werte. 

Was ich dann sowieso noch "per Hand" erledigen muss ist: erste und letzte Stunde eines files (auch zur Kontrolle); ich habe vier von diesen Messgeräten, also muss ich jedesmal das Programm umschreiben. Auch das Datum muss ich händisch eintragen, das lässt sich aber relativ leicht von einem auf vier kopieren. 

Mein Problem ist wie oben beschrieben lediglich die Standardabweichung. Ich hatte die Variable abc auch schon anders definiert, und bin bei weitem genauer dort gelandet, aber trotzdem falsch. 

Der Mittelwert wird von allen Werten einer Stunde gebildet (nach einer Stunde), aber die Variable abc wächst kontinuierlich... jetzt muss ich diese beiden zueinander in Bezug setzen. 

lg und danke für die rasche Antwort
Chrisl


----------



## SlaterB (3. Aug 2012)

die genannten Zahlen klingen nun nach Problemen mit Anzahl Nachkommastellen,
auf die 8. nach dem Komma wird es aber kaum ankommen, muss schon ziemlich weit vorne sein um in der Summe so eine Abweichung zu produzieren

----


ein Zugang zu undurchschaubaren Daten kann Intervallhalbierung bzw. sonstige Einteilung sein,
bilde Mittelwer der ersten 1500 und des Rests, in Excel genauso

falls bei beiden noch Abweichungen dann ist es egal, sonst mit der Hälfe weitermachen die Probleme hat,
weiter halbieren,
wenn irgendwann zwei Häften in Ordnung sind, in Summe aber nicht mehr, dann ist das schon eine Information

noch besser natürlich Reduktion auf 10 Werte, die Probleme machen

alles natürlich unter der Annahme, dass du sowieso schon die ersten 10 für sich getestet und dabei keine Probleme festgestellt hast

-----

auch nett: in Excel eine Summe der bisherigen Werte 
1. Zeile -> nur Summe der einen Zahl
2. Zeile -> vorherige Summe + den Wert der aktuellen Zeile
3. Zeile -> vorherige Summe + den Wert der aktuellen Zeile
ist eine einfache Formel, die man leicht über alle Zeilen kopieren kann, falls mit Formeln ein wenig Kenntnisse,

in Java genauso die 3500 Summen ausgeben, daneben Zeilennummer usw.,
und dann einfach durchscrollen, ab wann Unterschied,

oder nur die 3500 Werte ausgeben und in Excel als Spalte daneben einfügen, noch besser zu vergleichen


----------



## chrisl77 (3. Aug 2012)

Ja, das klingt nach einer guten Herangehensweise, um genauere Werte zu erhalten. 

Aber bei der Standardabweichung ist das kein Rundungsfehler, sondern da gibt es ein gröberes Problem. 
Was ich durch die Angabe zeigen wollte, die Stabw entspricht ungefähr der Summe - deswegen mein Problem: er zieht den Mittelwert offenbar nicht ab. Ob der Wert jetzt eine Zeile hinz nimmt oder nicht... da ist die Messgenauigkeit bei weitem weniger präzise als dieser kleine Rechenfehler bei, wie schon gesagt ca. 3500 Werten/h. 

Standardabweichung: Abzug des Mittelwerts von jedem Wert, dann quadrieren, durch Anzahl-1 dividieren, dann Wurzel. 

Offenbar zieht er mir den Mittelwert nicht ab. Deswegen zurück zum eingangs beklagten Problem: 
der Mittelwert wird in der if-schleife "stündlich" gebildet (!=stunde), er muss aber "sekündlich" abgezogen werden für die Standardabweichung. 

lg
und danke 
chrisl


----------



## SlaterB (3. Aug 2012)

ich sehe gerade 3449 zu 3450 Werte, das ist natürlich eine viel bessere Erklärung für die kleine Summenabweichung,
sollte doch recht schnell zu klären sein, wieviele Zeilen eingelesen werden, ob z.B. die erste und letzte mit verarbeitet wird?

der counter, der die erste Zeile überspringt, ist nicht zufällig Schuld?! was ist die erste Zeile der Datei? gib sie wenigens aus im else zum "if (counter > 0) {"

if-Schleife bitte nicht mehr schreiben
if-schleife.de


--------

wenn bei der Standardabweichung die Abweichung riesig ist, dann sind wiederum die Daten eigentlich auch schnell zu kürzen,
geht nicht irgendwie, auf 10 oder gar 1-2 Zeilen abzukürzen?

was ist die Excel-Formel, irgendwas fertiges oder sind Zwischenschritte nachzuvollziehen?
in Java kannst du doch alles ausgeben, Differenz zum Mittelwert usw.

ich kann mich jetzt elegant herausreden, dass mir just die Zeit fehlt, überhaupt nochmal nachzuschlagen, welcher Rechenweg geeignet ist, und welchen Code du eingebaut hast,
Wurzel scheint mir aber grob überblickt fragwürdig dabei
Standardabweichung ? Wikipedia

evtl. heute abend mehr, 
sofern sich sonst nichts tut, überlege bitte, was du bis dahin an Informationen bereitstellen kannst,

vielleicht ist es  sinnvoll, testweise doch noch einfache Zahlen a la 5, 7, 12 in Excel einzutippen, 
was kommt da als Standardabweichung heraus?
es wird sich dann schon eine Java-Formel finden lassen, die dieselbe Zahl produziert


----------



## andiv (3. Aug 2012)

chrisl77 hat gesagt.:


> Standardabweichung: Abzug des Mittelwerts von jedem Wert, dann quadrieren, durch Anzahl-1 dividieren, dann Wurzel.



Ich hab mir deinen Code jetzt nicht durchgelesen, weil er mir nicht sonderlich "übersichtlich" erscheint. Aber nur so als Tipp, es gibt auch eine alternative Berechnung der Standardabweichung für auflaufende Messwert bei der der Mittelwert nicht bekannt sein muss sondern "just-in-time" mitberechnet wird. Vielleicht ist diese Form ja besser für deine Implementierung geeignet.


----------



## pappawinni (4. Aug 2012)

Also, ich denk mal wieder und zwar:
Bei einem alten Taschenrechner hatte ich mal ne einfache Statistikfunktion. 
Da musste ich dann den Statistikspeicher erstmal löschen, wenn da nochwas drinnen war.
Dann konnte ich nacheinander Werte in den Speicher geben und danach immer den Mittelwert und die Standardabweichung abfragen. Der Rechner hat die Einzelwerte nicht gespeichert, 
sonst hätte man die wohl auch wieder abfragen, konnte man aber nicht.
Ich denke es wäre im Prinzip was du suchst und auch für eine Java Klasse gut geeignet.

Also wie könnte das im Taschenrechner funktioniert haben. Ich stell mir das so vor:

Mittelwert:
Der Rechner speichert die aktuelle Summe und die Zahl der eingegebenen Werte.
Kommt ein neuer Wert hinzu, dann rechnet er
Anzahl = Anzahl+1
Summe = Summe + Wert
Mittelwert = Summe/Anzahl

Im Fall des Reset werden Anzahl, Summe zurückgesetzt.

Standardabweichung:
Die Standardaweichung ist die Wurzel aus der Varianz.
Die Varianz kann auch mit Hilfe der Summe der qautrierten Werte berechnet werden.
Der Rechner könnte also zusätzlich die Summe der Quatrade speichern.
Wenn ein neuer Wert in den Statistikspeicher kommt, dann rechnet der Rechner also ausser dem Mittelwert noch

Quatradsumme = Quatradsumme + Wert^2
Wenn Anzahl < 2
:  nix machen, oder laut schreinen, wenn einer nach Varianz und Standardabweichung fragt, nicht definiert
sonst
*:  Varianz =  ( Quatradsumme - Summe^2/Anzahl )/(Anzahl-1)
:  Standardabweichung = Wurzel(Varianz)*
Im Resetfall muss mindestens die Quatradsumme, zurückgesetzt werden.

Zusammengefasst dann also die Operationen bei hinzufügen eines Wertes 

Anzahl = Anzahl+1
Summe = Summe + Wert
Mittelwert = Summe/Anzahl
Quatradsumme = Quatradsumme + Wert^2
Wenn Anzahl < 2
:  nix machen, oder laut schreinen, wenn einer nach Varianz und Standardabweichung fragt, nicht definiert
sonst
:  Varianz =  ( Quatradsumme - Summe^2/Anzahl )/(Anzahl-1)
:  Standardabweichung = Wurzel(Varianz)

Deine Variablen für die Summen könnten so aber ziemlich große Werte annehmen.
Grundsätzlich ginge es wohl auch so:

Anzahl = Anzahl + 1
Mittelwert = Mittelwert +  (Wert - Mittelwert)/Anzahl   
(Summe = Mittelwert * Anzahl)
NQSumme = NQSumme + (Wert^2-NQSumme)/Anzahl
(Quatradsumme = NQSumme * Anzahl)
Wenn Anzahl < 2
:  nix machen, oder laut schreinen, wenn einer nach Varianz und Standardabweichung fragt, nicht definiert
sonst
: Varianz = ( NQSumme - Mittelwert^2) * Anzahl / (Anzahl-1)
: Standardabweichung = Wurzel(Varianz)


----------



## pappawinni (4. Aug 2012)

Oh, ich hab mir das Programm mal geladen und auch mal n kleines Testfile angelegt.
Da stimmt , mein ich, in der Struktur noch mehr nicht.
Ich will das jetzt nicht im Detail zerlegen, aber zumindest läuft die while schleife bis Dateiende. Für die letzten Datensätze wird keine Statistik produziert.
Warum er mir für die erste Zeile ne Extra-Stastik macht, hab ich noch nicht wirklich erkannt. 
Ist auch wirklich nicht sehr übersichtlich.

Da bringt es auch nicht viel für das Programm , wenn ich versuch die Statistik auszulagern, aber ich habs mal probiert.
Damit lern ich ja veilleicht auch was.


```
import java.io.*;
 
/*
 * @author c.brandstätter
 */
public class ZuluftStunden {
 
    static String strRead, secondentry;
    static String dlm = ",", dlm2 = " ", dlm3 = "/";
    static double d, stdev, ste, d2;
    static int counter, m, st, sec, ho, st2;
    static int counter2 = 0;
    static int counter3 = 1;
    static BufferedReader namesFile;
    static String strRead2, part1;
    static String strReadMinute, strReadStunde, strReadSekunde;
    static double summe = 0;
    static double summed = 0;
    static double aver2 = 0;
    static double mw = 0;
    static double mw2 = 0;
    static double mw3 = 0;
    static int mold = -1;
    static int stold = -1;
    static double abc = 0;
    static FileWriter writer;
    static File file;
 
    public static void main(String[] args) throws FileNotFoundException {
 
        namesFile = new BufferedReader(new FileReader("C:/data/java/Zuluft.log"));

        /*-----------------------------*/
        
        MiniStat myStatistik = new MiniStat();
        
        /*-----------------------------*/
 
        try {
        	
            file = new File("C:/data/java/Zuluft.out");
            writer = new FileWriter(file, true);
            writer.write(namesFile.readLine());
            writer.write(System.getProperty("line.separator"));
            writer.write("Stunde " + " Mittelwert " + " Stabw " + " Standarderror ");
            writer.write(System.getProperty("line.separator"));
            while ((strRead = namesFile.readLine()) != null) {
 
                if (counter > 0) {
 
                    String splitarray[] = strRead.split(dlm);
                    part1 = splitarray[0]; //Zeit
                    String zeitteil[] = part1.split(dlm3);
                    strReadSekunde = zeitteil[2];
                    strReadMinute = zeitteil[1];
                    strReadStunde = zeitteil[0];
                    secondentry = splitarray[1]; //Messwert und Skala
                    String cutzwei[] = secondentry.split(dlm2);
                    strRead2 = cutzwei[1]; //Messwert
                    System.out.println(strRead2);
                    d = Double.parseDouble(strRead2);
                    d2 = (d*60)/1000;
                    m = Integer.parseInt(strReadMinute);
                    st = Integer.parseInt(strReadStunde);
                    sec = Integer.parseInt(strReadSekunde);

                    /*-----------------------------*/
                    myStatistik.wertHinzu(d2);
                    /*-----------------------------*/
                    
                    summe = summe + d2;
                    counter2++;
                    // System.out.println(d);
 
                    abc = abc + (summe-aver2)*(summe-aver2);//PROBLEM!!!
 
                   // System.out.println(abc);
 
                    if (st != stold) {
                        
                        summed = summe + d2;
                        counter3 = counter2 - 1;
                        aver2 = (summed) / (counter2);
                        //mw = (summed-counter3*aver2)*(summed-counter3*aver2);
                        mw2 = Math.sqrt(abc / counter3);
                        ste = mw2 / Math.sqrt(counter3);

                        
                        /*-----------------------------*/
                        aver2 = myStatistik.mittelwert();
                        summed = myStatistik.summe();
                        mw2 = myStatistik.varianz();
                        ste = myStatistik.standardabweichung();
                        counter3 = myStatistik.n();
                        /*-----------------------------*/
                        
                        //ho = st - 1;
                        st2 = st - 1; //aktuelle stunde
 
                        if (st2 == -1) {
                            st2 = 23;
                        }
                         
                        System.out.println("MittelW " + aver2 + " summe " + summed + " counter2 " + counter3 + " Messwert " + d2 + " SE " + ste + " stabw " + mw2 + " sekunde " + sec + " minute " + m + " stunde " + st2);
                        writer.write(st2 + " "  + aver2 + " " + mw2 + " " + ste + " "+counter3);
                        writer.write(System.getProperty("line.separator"));
                        stold = st;
                        counter2 = 0;
                        summe = 0;
                        mw2 = 0;
                        stdev = 0;
                        mw3 = 0;
                        abc = 0;
                        
                        /*-----------------------------*/
                        myStatistik.reset();
                        /*-----------------------------*/
 
                    }
 
                } //break;
                counter++;
            }
            writer.flush();
            writer.close();
 
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (namesFile != null) {
                    namesFile.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}
```

Und die Statistik-Klasse:


```
public class MiniStat {

	private double summe;
	private double nQsumme;
	private int anzahl;
	
	public void MiniStat() {
		this.summe=0;
		this.nQsumme=0;
		this.anzahl=0;
	}
	public void reset(){
		this.summe=0;
		this.nQsumme=0;
		this.anzahl=0;		
	}
	public double mittelwert(){
		return(summe/anzahl);
	}
	public double varianz(){
		if (anzahl <2) return(0);
	    return (nQsumme - mittelwert() * mittelwert()) * anzahl / (anzahl-1);
	}
	public double standardabweichung(){
		if (anzahl < 2) return(0);
		return(Math.sqrt(varianz()));
	}
    public void wertHinzu(double wert){
    	anzahl = anzahl + 1;
    	summe = summe + wert;
    	nQsumme = nQsumme + (wert*wert - nQsumme)/anzahl;    	
    }
	public double summe(){
		return(summe);
	}    
	public int n(){
		return(anzahl);
	}    
}
```


----------



## pappawinni (4. Aug 2012)

Ich weiss ja nicht, ob es das bringt, aber ich hab mal versucht den Knoten aus dem Ding heraus zu machen. 
So richtig sortiert schaut es trotzdem nicht aus. 
Hab den Eindruck, als hätte da wer nen Code für das Lesen und Schreiben von Files genommen und da relativ planlos irgendwie was dazwischen gewurschtelt.


```
import java.io.*;
 
/*
* ---------------------------- */
public class ZuluftStunden {
 
 
    public static void main(String[] args) throws FileNotFoundException {
        String strRead, secondentry;
        String dlm = ",", dlm2 = " ", dlm3 = "/";
        double d, ste, d2=0;
        int counter=1, m=0, st=0, sec=0, st2=0;
        int counter3 = 1;
        BufferedReader namesFile;
        String strRead2, part1;
        String strReadMinute, strReadStunde, strReadSekunde;
        double summed = 0;
        double aver2 = 0;
        double mw2 = 0;
        int stold = -1;
        FileWriter writer;
        File file;

    	
        namesFile = new BufferedReader(new FileReader("C:/data/java/Zuluft.log"));
        
        MiniStat myHourStat = new MiniStat();
        MiniStat myDayStat = new MiniStat();

        try {
        	
            file = new File("C:/data/java/Zuluft.out");
            writer = new FileWriter(file, true);
            writer.write(namesFile.readLine());
            writer.write(System.getProperty("line.separator"));
            writer.write("Stunde " + " Mittelwert " + " Stabw " + " Standarderror ");
            writer.write(System.getProperty("line.separator"));

            while ((strRead = namesFile.readLine()) != null) {

            	if (counter > 0) {
 
                    String splitarray[] = strRead.split(dlm);
                    part1 = splitarray[0]; //Zeit
                    String zeitteil[] = part1.split(dlm3);
                    strReadSekunde = zeitteil[2];
                    strReadMinute = zeitteil[1];
                    strReadStunde = zeitteil[0];
                    secondentry = splitarray[1]; //Messwert und Skala
                    String cutzwei[] = secondentry.split(dlm2);
                    strRead2 = cutzwei[1]; //Messwert                    
                    d = Double.parseDouble(strRead2);
                    d2 = (d*60)/1000;
                    m = Integer.parseInt(strReadMinute);
                    st = Integer.parseInt(strReadStunde);
                    st2 = st - 1; //aktuelle stunde                    
                    if (st2 == -1) {
                        st2 = 23;
                    }
                    sec = Integer.parseInt(strReadSekunde);
                     
                    if (st != stold && counter >1) {
                        
                        aver2 = myHourStat.mittelwert();
                        summed = myHourStat.summe();
                        mw2 = myHourStat.varianz();
                        ste = myHourStat.standardabweichung();
                        counter3 = myHourStat.n();                        
                         
                        System.out.println("MittelW " + aver2 
                        		         + " summe " + summed 
                        		         + " counter2 " + counter3 
                        		         + " Messwert " + d2 
                        		         + " SE " + ste 
                        		         + " stabw " + mw2 
                        		         + " Time " + st2 
                        		         + ":" + m 
                        		         + ":" + sec);
                        writer.write(st2 + " "  + aver2 + " " + mw2 + " " + ste + " "+counter3);
                        writer.write(System.getProperty("line.separator"));
                        myHourStat.reset();
                    }
                    myHourStat.wertHinzu(d2);
                    myDayStat.wertHinzu(d2);
                    stold = st;
                    counter++;                    
                } 
            
            }
            aver2 = myHourStat.mittelwert();
            summed = myHourStat.summe();
            mw2 = myHourStat.varianz();
            ste = myHourStat.standardabweichung();
            counter3 = myHourStat.n();

            writer.write(st2 + " "  + aver2 + " " + mw2 + " " + ste + " "+counter3);
            writer.write(System.getProperty("line.separator"));                
                        
            System.out.println("MittelW " + aver2 
   		         + " summe " + summed 
   		         + " counter2 " + counter3 
   		         + " Messwert " + d2 
   		         + " SE " + ste 
   		         + " stabw " + mw2 
   		         + " Time " + st2 
   		         + ":" + m 
   		         + ":" + sec);

            System.out.println("Tagesauswertung"); 
            System.out.println("MittelW " + myDayStat.mittelwert() 
      		         + " Summe " + myDayStat.summe()
      		         + " Stdabw " + myDayStat.standardabweichung() 
      		         + " Varianz " + myDayStat.varianz()
      		         + " N " + myDayStat.n());                         
            
            writer.flush();
            writer.close();
 
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (namesFile != null) {
                    namesFile.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}
```


----------



## pappawinni (5. Aug 2012)

Hab noch ein paar Ecken und Kanten gefunden.
Ich bin jetzt davon ausgegangen, das der Autor mit "Stabw" die Standardabweichung meinte.
Wofür das SE stand, ist mir nicht wirklich klar geworden. Ich hab da halt jetzt die Varianz ausgegeben.
Stunden, Minuten und Sekunden auslesen hab ich mir gespart, werden eh nur Stunden gebraucht.

Hier also meine "Final Variant"
Die dazu benötigte Klasse "MiniStat" ist unverändert, also weiter oben im Thread zu finden.


```
import java.io.*;
 
/*
 * revised by pappawinni [url=http://www.java-forum.org]Java programmieren aus Leidenschaft[/url]
 */
public class ZuluftStunden {
 
 
    public static void main(String[] args) throws FileNotFoundException {
        String strRead, line_separator=System.getProperty("line.separator");
        double d2=0;
        int counter = 1, st = 0, stold = 0;
        BufferedReader namesFile;
        FileWriter writer;
        File file;
    	
        namesFile = new BufferedReader(new FileReader("C:/data/java/Zuluft.log"));
        
        MiniStat myHourStat = new MiniStat();
        MiniStat myDayStat = new MiniStat();
 
        try {
        	
            file = new File("C:/data/java/Zuluft_stat.log");
            writer = new FileWriter(file, true);
            /* skip first line of input file */
            writer.write(namesFile.readLine());
            writer.write(line_separator);
            writer.write("Hour " + " Mean " + " Standard deviation " + " Variance " + " Count ");
            writer.write(line_separator);

            while ((strRead = namesFile.readLine()) != null) {
            	/* supposed line structure:
            	 * "HH/MM/JJ, -#.########## ml/(n)/min, "
            	 */
            	String splitarray[] = strRead.split(",");
                /* extract hour */
                stold = st;            	
                st = Integer.parseInt(splitarray[0].substring(0,2));
                /* extract measured value */
                d2 = (Double.parseDouble(splitarray[1].substring(0,splitarray[1].trim().indexOf(" "))) 
                     *60)/1000;
                /* hour change, then
                 * output of statistics for last hour */
                if (st != stold && counter >1) {
                                             
                    System.out.println("Mean " + myHourStat.mittelwert() 
                    		         + " Sum " + myHourStat.summe() 
                    		         + " Stderr " + myHourStat.standardabweichung() 
                    		         + " Variance " + myHourStat.varianz()
                    		         + " Count " + myHourStat.n() 
                    		         + " hour " + stold);
                    
                    writer.write(stold + " "  
                               + myHourStat.mittelwert() + " " 
                    		   + myHourStat.standardabweichung() + " " 
                               + myHourStat.varianz() + " "
                    		   + myHourStat.n());                        
                    writer.write(line_separator);
                    
                    myHourStat.reset();
                }
                myHourStat.wertHinzu(d2);
                myDayStat.wertHinzu(d2);
                counter++;                                
            }
            
            /* output statistics for last hour in file */
            
            writer.write(st + " "  
                 + myHourStat.mittelwert() + " " 
         		 + myHourStat.standardabweichung() + " " 
                 + myHourStat.varianz() + " "
         		 + myHourStat.n());
            writer.write(line_separator);                
            writer.flush();
            writer.close();

            System.out.println("Mean " + myHourStat.mittelwert() 
      		         + " Sum " + myHourStat.summe() 
      		         + " Stderr " + myHourStat.standardabweichung() 
      		         + " Variance " + myHourStat.varianz()
      		         + " Count " + myHourStat.n() 
      		         + " hour " + st);

            /* output over all analysis data */
            
            System.out.println("over all analysis"); 
            System.out.println("Mean " + myDayStat.mittelwert() 
      		         + " Sum " + myDayStat.summe()
      		         + " Count " + myDayStat.n()
      		         + " Variance " + myDayStat.varianz()
      		         + " Stderr " + myDayStat.standardabweichung());                                     
 
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (namesFile != null) {
                    namesFile.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}

/*
 * Test data - first line
 * 15/25/16, -0.060399998649954795 ml(n)/min,
 * 15/25/17, -0.06559999853372574 ml(n)/min, 
 * 15/25/18, -0.06639999851584434 ml(n)/min, 
 * 15/25/19, -0.08079999819397926 ml(n)/min,
 * 15/25/20, -0.057999998703598975 ml(n)/min,
 * 16/25/21, -0.08079999819397926 ml(n)/min, 
 * 16/25/22, -0.06719999849796295 ml(n)/min, 
 * 16/25/23, -0.06479999855160713 ml(n)/min, 
 * 16/25/24, -0.07999999821186066 ml(n)/min, 
 * --
 * File Output:
 * Hour  Mean  Standard deviation  Variance  Count 
 * 15 -0.003974399911165235 5.319669043741484E-4 2.829887873494144E-7 5
 * 16 -0.004391999901831147 5.026648870815248E-4 2.5267198870468203E-7 4
 * --
 */
```


----------



## pappawinni (5. Aug 2012)

Jetzt hab ich auch noch mal geschaut, ob ich das:

```
d2 = (Double.parseDouble(splitarray[1].substring(0,splitarray[1].trim().indexOf(" ")))..
```
nicht irgendwie kürzer bekomme und da fiel mir auf, dass das sogar eigentlich noch zu kurz ist und ich dadurch bei jedem Wert die letzte Stelle abschneide.

```
d2 = (Double.parseDouble(splitarray[1].trim().substring(0,splitarray[1].trim().indexOf(" ")))..
```
hätte es dann wohl korrigiert, aber wozu?

Wenn ich nämlich, und ich frag mich warum ich das nicht so gemacht habe, gleich den Split über Blanks mache, dann kann ich dann einfach 
	
	
	
	





```
d2 = (Double.parseDouble(splitarray[1]) * 60)/1000;
```
 schreiben.
Naja, wenn ich schon mal "Final Variant" schreib :shock:


----------



## pappawinni (5. Aug 2012)

Ich hab mich nun auch mal an einem "make it nice" versucht.
Die Dateinamen der Ein-und Ausgabedatei, die bislang fest im Programm codiert waren, 
müssen jetzt über eine Inputbox eingegeben werden.
Überprüft wird da aber wenig, z.B. ob jetzt evtl. Ein- Ausgabedatei womöglich gleich sind, was ja fatal wäre.
In dem Fall wird es dann sicherlich zu einem Programmabbruch kommen. 
Man könnte sich damit vielleicht auch irgendetwas überschreiben, wenn man da eine falschen Dateinamen eingibt.
Etwas besser abgesichert habe ich, dass die Inputdatei evtl. am Dateiende eine oder mehrere leere Zeilen enthalten könnte. 
Da passiert also dann nichts, hoff ich.
Die Ausgabe am Bildschirm - nun über eine Messagbox - habe ich inhaltlich mit der Dateiausgabe abgeglichen.
Die Ausgabe auf der Konsole ist auskommentiert.

Das sollte so also als einfache, selbstständige Anwendung brauchbar sein.
Im Zweifel kann das dann auch noch als schlechtes Beispiel dienen 
Ich garantiere also natürlich für nichts. 


```
import java.io.*;
import javax.swing.JOptionPane;

 
/*
 * revised 12/08/05 by pappawinni [url=http://www.java-forum.org]Java programmieren aus Leidenschaft[/url]
 */
public class ZuluftStunden {
  
    public static void main(String[] args) throws FileNotFoundException {
        String strRead, line_separator=System.getProperty("line.separator");
        double d2=0;
        int counter = 1, st = 0, stold = 0;
        BufferedReader namesFile;
        FileWriter writer;
        File file;
        String strOut="", strOutScr="";
        String inFilePath ="", outFilePath="";
               
        inFilePath = fileNameDialog( "Datendatei ?" );
        outFilePath = fileNameDialog( "Ausgabedatei ?" );
                   	
        namesFile = new BufferedReader(new FileReader(inFilePath));
        
        MiniStat myHourStat = new MiniStat();
        MiniStat myDayStat = new MiniStat();
 
        try {
        	
            file = new File(outFilePath);
            writer = new FileWriter(file, true);
            /* move first line from input file to output file */
            strOut = namesFile.readLine();             
            writer.write(strOut+line_separator);
            strOutScr += String.format(strOut + "%n");
            /* put headline for statistics */
            strOut = "|Hour|--------Mean--------|-Standard deviation-|------Variance------|Count-|";
            writer.write(strOut+line_separator);
            strOutScr += String.format(strOut + "%n");

            while ((strRead = namesFile.readLine()) != null) {
            	/* supposed line structure:
            	 * "hh/mm/ss, -#.########## ml/(n)/min, "
            	 */
            	/* extra Lines at End of File ? */
                if (strRead.length() < 20) break;
                
                /* extract hour */
                stold = st; 
                st = Integer.parseInt(strRead.substring(0,2));
                               
                /* extract measured value */
                String splitarray[] = strRead.split(" ");
                if (splitarray.length<2) break;
                d2 = (Double.parseDouble(splitarray[1]) * 60)/1000;
                
                /* hour change, then
                 * output of statistics for last hour */
                if (st != stold && counter >1) {
                	
                    strOut = String.format( "|%4d|%20.15f|%20.15f|%20.15f|%6d|",
                    	 stold,
                 		 myHourStat.mittelwert(), 
           		         myHourStat.standardabweichung(), 
           		         myHourStat.varianz(),
           		         myHourStat.n() 
           		         ).replace(",",".");

                    writer.write(strOut+line_separator);                        
                    strOutScr += String.format(strOut + "%n");

                    myHourStat.reset();

                }
                myHourStat.wertHinzu(d2);
                myDayStat.wertHinzu(d2);
                counter++;                                
            }
            
            /* output statistics for last hour in file */

            strOut = String.format( "|%4d|%20.15f|%20.15f|%20.15f|%6d|",
               	     st,
            		 myHourStat.mittelwert(), 
      		         myHourStat.standardabweichung(), 
      		         myHourStat.varianz(),
      		         myHourStat.n() 
      		         ).replace(",",".");
               		                    
            writer.write(strOut+line_separator);                        
            strOutScr += String.format(strOut + "%n");
            
            writer.flush();
            writer.close();

            /* output over all analysis data */            
            strOut = String.format("|%4s|%20.15f|%20.15f|%20.15f|%6d|",
                 "all",
         		 myDayStat.mittelwert(), 
   		         myDayStat.standardabweichung(), 
   		         myDayStat.varianz(),
   		         myDayStat.n() 
   		         ).replace(",",".");

            strOutScr += String.format(strOut + "%n");
            
/*          terminal output 
            System.out.print(strOutScr);*/
            
            /* Output by messagebox */
            JOptionPane.showMessageDialog(null,strOutScr,"Statstic", JOptionPane.INFORMATION_MESSAGE);

        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (namesFile != null) {
                    namesFile.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
    private static String fileNameDialog(String msg){
    	String fileName;
    	boolean bolRepeat = false;  
    	do {
    		bolRepeat = false;
            fileName = JOptionPane.showInputDialog(msg);
        	try {
        	   new File(fileName).getCanonicalPath();
    		} catch (IOException e) {
    		   bolRepeat = true;
    		}
    	} while (bolRepeat);
        return fileName;
    }
}

/*
/* File Input:
5/8/2012 Number 1
15/25/16, -0.060399998649954795 ml(n)/min,
15/25/17, -0.06559999853372574 ml(n)/min, 
15/25/18, -0.06639999851584434 ml(n)/min, 
15/25/19, -0.08079999819397926 ml(n)/min,
15/25/20, -0.057999998703598975 ml(n)/min,
16/25/21, -0.08079999819397926 ml(n)/min, 
16/25/22, -0.06719999849796295 ml(n)/min, 
16/25/23, -0.06479999855160713 ml(n)/min, 
16/25/24, -0.07999999821186066 ml(n)/min, 
 *
 * Output:
5/8/2012 Number 1
|Hour|--------Mean--------|-Standard deviation-|------Variance------|Count-|
|  15|  -0.003974399911165|   0.000531966904374|   0.000000282988787|     5|
|  16|  -0.004391999901831|   0.000502664887082|   0.000000252671989|     4|
 * 
 */
```

[EDIT]Die JAR- Datei häng ich auch noch an.[/EDIT]


----------



## chrisl77 (6. Aug 2012)

Auf jeden Fall einmal herzlichen Dank für die ausführlichen Antworten. Ich werde sie mir heute im Detail zu Gemüte führen. Wie aus dem code wahrscheinlich ohnehin ersichtlich, bin ich eher den Anfängern zuzurechnen, und lediglich auf der Suche nach der Lösung meines Problems. 

@ pappawinni: SE ist der Standardfehler; der anfängliche counter (>0) soll mir nur die erste Zeile ignorieren, da ich hier eine Art label in meine Messdaten eingefügt habe, was ich unter input-file auch so darstellen wollte; Wie gesagt, vielen herzlichen Dank. Ich habe auch vermutet, dass eine eigene Klasse für die Stabw wahrscheinlich vernünftig gewesen wäre; aber so ganz ist mir java einfach noch nicht klargeworden. Nochmals: Danke.


----------



## chrisl77 (6. Aug 2012)

pappawinni, wie gesagt, vielen herzlichen Dank. 
Auch das mit ein- und Ausgabefile ist äußerst hilfreich. 

Ein Problem ist aufgetaucht, und zwar die line-structure: die stunden-struktur ist natürlich nicht immer zweistellig, wäre ja auch zu einfach gewesen. das habe ich jetzt mit meinem umständlichen code behoben . 

du hast mir extrem weitergeholfen. ich bin dir extrem zu dank verpflichtet, das erleichtert meine arbeit um so vieles. Vielen vielen herzlichen dank. 

lg
chrisl


----------



## pappawinni (6. Aug 2012)

Na toll, 
ich dacht schon das Ganze würde lediglich ne reine Übung für mich als Java-Anfänger.

Vielleicht willst du auch noch:


```
UIManager.put( 
        	    "OptionPane.messageFont", 
        	    new FontUIResource(new Font("Courier New", Font.BOLD, 12)) 
        	);
```

vor der Ausgabe mit der Messagebox rein setzen, dann wird die Ausgabe womöglich auch noch schöner.
Bei der Klasse Ministat hatte ich im Kontruktor ein "void".     (public void MiniStat()..
Gibt zwar "nur" ne Warning, aber besser rausnehmen, falls noch nicht geschehen.


----------

