CSV-Daten auswählen, Graph anzeigen

Eine Frage noch: Kommen die Zeitpunkt- und Temperaturwerte aus einer MongoDB?

Nein, die stammen von einem Temperatursensor. Ich habe auch wie oben bereits erwähnt mir ein paar Zeilen zum „splitten“ der Daten geschrieben :wink: Sodass ich auch wirklich nur das habe, was ich wirklich brauche

ein kleines bisschen hat mich dein erstellen wollen einer KI schon ein bisschen abgeschreckt :wink: aber ja, ich fühle mich keinesfalls „genötigt“. Ich freue mich dass ihr mir helfen wollt, alles ein kleines bisschen klarer zu sehen & zu einem Ergebnis zu kommen, mit dem ich Leben kann weil ich es verstehe :slight_smile:

Ich weiß nicht ob ich grad auf dem Schlauch steh oder mir die Sonne zu stark auf den Kopf geschienen hat, aber ich weiß nicht genau was du meinst…

ich hätte das sortieren jetzt wieder so angegangen:

             boolean fileNameOkForNrString (String textausgabe){  
           if(textausgabe.equals(nrString) &&  textausgabe.contains("praktikum"+ nrString) && f.lastModified() >mod))
       {
    	   mod =f.lastModified();
    	   found = f;
       else if (textausgabe.equals(nrString +1) && textausgabe.contains("praktikum" + nrString) && f.lastModified() > mod)
     {
    	   mod = f.lastModified(); 
    	   found = f; 
       }

}

Ich denke aber nicht dass das das ist was du ursprünglich gemeint hast…

Ich hab hier mal den Export der Daten hochgeladen. Das sind die csv-Dateien, die im Verzeichnis aufgerufen werden.
Export.zip (3,8 KB)

Ich denke, @SlaterB wird sich später melden.

geht wieder zurück auf die Grundfrage, was möchtest du eigentlich erreichen?

ich habe es so verstanden, dass du EINE CSV-Datei aus einer Liste auswählen willst:

diesen ersten Schritt leistet die Methode mit der Schleife,
Variable ‚found‘ ist ja auch von dir

so rum geht es doch in die falsche Richtung :wink:

bedeutend ist doch nur was du brauchst, was genau soll passieren?,
soll ein CSV bestimmt werden (und danach als nächster ferner Schritt etwas mit dessen Inhalt passieren),
willst du mehrere CSV irgendwie sortieren, aus allen Werte auslesen,
oder was auch immer genau?

Okay, ich bin eindeutig verwirrt…also die Schleife
if (fileNameOkForNrString && f.lastModified() > mod) { mod = f.lastModified(); found = f; }
gibt mir den Wert aus der Textdatei zurück, dessen Export ich grafisch darstellen lassen möchte. (hier also die 1)

wieso bewege ich mich damit in die falsche Richtung? Ich überprüfe doch, ob mein String gleich der Zahl in der Textdatei ist & dass die richtige Datei mit entsprechender Endung ausgewählt wird mit dem aktuellsten Datum. Oder etwa nicht?
Tut mir leid, wenn sich das jetzt blöd anhört oder so von mir rüberkommt, aber ich brauche da echt nen großen stupser um das Fragezeichen auf meinem Kopf zu lösen :frowning:

genau so würde ich es gerne machen. Ein csv aus der Liste der Csv bestimmt & dann desen Inhalt grafisch darstellen.

alles verstehst du falsch…, ich meinte, dass wenn du danach fragst was ich mit dem Code vorhabe, dass das die falsche Richtung in diesem Thread ist…

sondern es geht doch allein darum was du als Problem hast, das muss geklärt werden und das dann als Programm verfolgt,
doch nicht was ich mir vorstelle, ich habe hier gar kein Beitrag, es geht nur um dein Problem…


jetzt schreibst du wieder

aber vorher

ist da so ein großer Unterschied zwischen den Sichten?
wenn man eine Sache x von vielen Sachen y auswählen will, durchläuft man y mit einer Schleife, so dass am Ende ein x ausgewählt herauskommt,

‚found‘ ist das gesuchte einzelne CSV aus einer Liste der vielen CSV, wie kann das schwer zu verstehen sein?

In der Tat…

Auch auf die Gefahr hin, noch mehr zu verwirren oder nichts sinnvolles beizutragen, ein paar Codeschnipsel, die bestimmte Aufgaben erledigen:

  • Aus einer Datei, die das besagte Format hat, also einen Verzeichnisnammen und eine Nummer enthält, kann mit readInputInfo ein InputInfo-Objekt gelesen werden, wo diese Infos drinstecken
  • Mit ein paar utility-Funktionen kann man aus den Namen von Dateien (die das angedeutete Format haben) diese Informationen extrahieren:
    • Diese Nummer (1 oder 2)
    • Das erste Datum
    • Das zweite Datum
  • Mit der fetchRelevantFiles-Methode kann man sich die Dateien auflisten lassen, die relevant sind

Alleine schon den Task in solche Building-Blocks aufzuteilen kann helfen. Mit JFreeChart hat das jetzt freilich nichts zu tun, aber … das könnte der nächste Schritt sein.

So weit erstmal. Muss da jetzt noch irgendwas nach Datum sortiert werden oder so? :confused:

package bytewelt;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

public class DateianzeigeUnklareFrage
{
    public static void main(String[] args) throws IOException
    {
        File inputFile = new File("./FileList.txt");
        InputInfo inputInfo = readInputInfo(inputFile);
        
        List<File> relevantFiles = 
            fetchRelevantFiles(inputInfo.directoryName, inputInfo.number, 
                LocalDate.of(2017, 6, 23));
        
        for (File file : relevantFiles)
        {
            System.out.println(file);
        }
    }

    private static class InputInfo
    {
        String directoryName;
        int number;
    }

    private static InputInfo readInputInfo(File file) throws IOException
    {
        try (BufferedReader br = new BufferedReader(new FileReader(file)))
        {
            String directoryName = br.readLine();
            String numberString = br.readLine();
            InputInfo inputInfo = new InputInfo();
            inputInfo.directoryName = directoryName;
            inputInfo.number = tryParseInt(numberString);
            return inputInfo;
        }
    }

    static List<File> fetchRelevantFiles(String directoryName, int number,
        LocalDate date)
    {
        List<File> relevantFiles = new ArrayList<File>();
        List<File> files = listFiles(directoryName);
        for (File file : files)
        {
            String fileName = file.getName();
            int fileNumber = extractNumberFromFileName(fileName);
            LocalDate startDate = extractStartDateFromFileName(fileName);
            LocalDate endDate = extractEndDateFromFileName(fileName);

            if (fileNumber == number 
                && !startDate.isAfter(date)
                && !endDate.isBefore(date))
            {
                relevantFiles.add(file);
            }
        }
        return relevantFiles;
    }

    private static LocalDate extractStartDateFromFileName(String name)
    {
        int lastUnderscoreIndex = name.lastIndexOf('_');
        if (lastUnderscoreIndex == -1)
        {
            System.out.println("Invalid file name: " + name);
            return null;
        }
        int prevUnderscoreIndex =
            name.lastIndexOf('_', lastUnderscoreIndex - 1);
        if (prevUnderscoreIndex == -1)
        {
            System.out.println("Invalid file name: " + name);
            return null;
        }
        String startDateString =
            name.substring(prevUnderscoreIndex + 1, lastUnderscoreIndex);
        return LocalDate.parse(startDateString);
    }

    private static LocalDate extractEndDateFromFileName(String name)
    {
        int lastDotIndex = name.lastIndexOf('.');
        if (lastDotIndex == -1)
        {
            System.out.println("Invalid file name: " + name);
            return null;
        }
        int lastUnderscoreIndex = name.lastIndexOf('_');
        if (lastUnderscoreIndex == -1)
        {
            System.out.println("Invalid file name: " + name);
            return null;
        }
        String endDateString =
            name.substring(lastUnderscoreIndex + 1, lastDotIndex);
        return LocalDate.parse(endDateString);
    }

    private static int extractNumberFromFileName(String name)
    {
        int dashIndex = name.indexOf('-');
        if (dashIndex == -1)
        {
            System.out.println("Invalid file name: " + name);
            return -1;
        }
        int numberEndIndex = name.indexOf('_', dashIndex + 1);
        if (numberEndIndex < 0)
        {
            System.out.println("Invalid file name: " + name);
            return -1;
        }
        String numberString = name.substring(dashIndex + 1, numberEndIndex);
        return tryParseInt(numberString);
    }

    private static int tryParseInt(String string)
    {
        try
        {
            return Integer.parseInt(string.trim());
        }
        catch (NumberFormatException e)
        {
            System.out.println("Invalid number: " + string);
            return -1;
        }
    }

    private static List<File> listFiles(String directoryName)
    {
        File directory = new File(directoryName);
        File[] filesArray = directory.listFiles();
        List<File> files = new ArrayList<File>();
        for (File file : filesArray)
        {
            if (!file.isDirectory())
            {
                files.add(file);
            }
        }
        return files;
    }

    private static void someBasicTests()
    {
        String fileName = "export_test_practise-1_2017-06-23_2017-06-23.csv";
        System.out.println(extractNumberFromFileName(fileName));
        System.out.println(extractStartDateFromFileName(fileName));
        System.out.println(extractEndDateFromFileName(fileName));
        System.out.println(listFiles("C:/Develop"));
    }

}

Es tut mir echt leid, wenn das von mir so rüberkommt. Ich wollte eigentlich nur sagen, dass ich versucht habe deinen Code zu verstehen (& jetzt verstehe) :slight_smile: Ich sehe ja selber, dass mein anfänglicher Code ziemlich durcheinander geschrieben war, ohne jede wirkliche Ordnung…& freue mich dass du mir das leichter gemacht hast es zu verstehen.
Du schlägst ja anschließend vor fileNameOkFoNrString zu befüllen um bestimmte Dateinamen mit nrString = 1 oder 2 auszuwählen.
Ich habe versucht, deinen Vorschlag umzusetzen, komme aber noch nicht wirklich auf einen grünen Zweig. Habe ich schonwieder etwas falsch verstanden?
Hier wäre mein Versuch:

      boolean fileNameOkForNrString(String textausgabe){
       if(textausgabe.equals(nrString) && textausgabe.contains("praktikum"+ nrString) && f.lastModified() >mod)
       {
    	   mod =f.lastModified();
    	   found = f; 
       }
       else if (textausgabe.equals(nrString +1) &&textausgabe.contains("praktikum" + nrString) && f.lastModified() > mod)
       {
    	   mod = f.lastModified(); 
    	   found = f; 
       }
      }

Ich glaube, du solltest nur mit allen Einzelheiten beschrieben, was du machen möchtest… Ganz unabhängig vom Code jetzt. :wink:

Ich blicke da nicht durch so richtig…

Meinst du jetzt allgemein, was ich machen möchte oder nur jetzt auf mein Codefragment bezogen?

allgemein :wink: unabhängig vom Code… vielleicht in Stichpunkten, aber vollständig. :slight_smile:

nun ja, Programmierung ist kein Unkraut jäten, nur Fleiß alleine macht es doch nicht ganz, etwas Talent gehört schon dazu :wink:
oder vielleicht kommt es ja noch mit weiterer Übung,

wenn du die Bestimmung von fileNameOkForNrString ja oder nein in eine Methode auslagerst,
dann hast du dort sicherlich keinen Zugriff auf mod, found + f, es sei denn die sind zu Instanzattributen der Klasse geworden,

aber du brauchst die alle auch nicht, es geht nur darum, eben fileNameOkForNrString ja oder nein auszusagen,
ein boolean zurückzugeben,
dabei muss nicht noch lastModified geprüft werden oder found gesetzt werden, das sind Aufgaben für andere Stellen des Codes,

auf sowas zu achten ist wichtig, jede Methode hat ihre Aufgabe,

Parameter ‚textausgabe‘ für diese Methode ist auch reichlich fraglich, was sollte das sein, der Name der Datei?
warum dann den Parameter nicht passender benannt?
wie würde diese Methode aufgerufen werden?
solche Dinge sind alle zu beachten


was du mit deinen zwei ifs vorhast, verstehe ich nicht,
es hilft dann nicht zu schreiben ‚ich verstehe nicht was du meinst‘ oder ‚habe ich was falsch gemacht‘,
sondern du musst erklären, welche Ziele du exakt verfolgst, wie du das umzusetzen planst?
im Moment von dir nicht viel zu hören und Code anscheinend nur irgendwelche planlosen Versuche, das hilft nicht viel…

wie ich mir die Situation weiterhin vorstelle (wenn falsch, genauer beschreiben), ist:
es gibt in der Liste verschiedene Dateien mit Namen wie practise-1/ practise-2,
neuerdings vielleicht stattdessen praktikum1/ praktikum2?

wenn man die Liste durchgehst und jeden Namen prüft, außerdem einen Suchstring 1/ 2 hat,
dann kann man keine zwei ifs bauen, stell dir vor der Suchstring wäre zwischen 1 und 1000, sollen es dann 1000 ifs sein?

aber zum Glück gibt es ja die mächtige Programmierung, man kann einfach name.contains(nrString) ausführen,
oder name.contains(„praktikum“+nrString), was auch immer passt,

und dann wird für nrString 567 genau dann ein Dateiname akzeptiert, wenn dieser ‚praktikum567‘ enthält,

so, und das gibt auch nur einen boolean, in der Schleife berechnet weil nur eine Zeile, oder auch in einer Untermethode,
der weitere Code zu found usw. bleibt dann unberührt:

    for (File f : fileList)
    {
        System.out.println(f.getName());

        boolean fileNameOkForNrString = ... // irgendwie bestimmen
        if (fileNameOkForNrString && f.lastModified() > mod)
        {
            mod = f.lastModified();
            found = f;
        }
    }

okay^^ dann versuche ich das nochmal:

  • Ich habe einen Temperatursensor, der mir jeden Tag die gemessenen Werte als csv-Export wiedergibt

  • Ich habe nun ein Programm geschrieben um mich ein bisschen in Java Programmierung zu üben. Dieses Programm liest mir Direkt (mit File/BufferedReadeR) die gewünschte csv datei ein & gibt mir mithilfe von JFreeChart einen XYGraphen der Temperatur wieder

  • Nun möchte ich aber, dass mein Programm „unabhängig“ ist & auch von nicht Progammierern verwendet werden kann. Dazu wollte ich nun, mithilfe einer Textdatei (in der sich das Verzeichnis in der die csv Exporte drinnenstehen) von außen auf mein Programm zugreifen. Innerhalb dieser Textdatei soll dann in der zweiten Zeile mit Hilfe der Nummernangabe ausgesucht werden, welchen Temperaturverlauf ich mir anschauen möchte. → so können auch meine Eltern sich die Temperatur im Laufe des Tages anschauen (beispielsweise)

  • Mein Problem ist nun, wie oben schon erwähnt: das selektieren bzw das direkte Aufrufen der richtigen CSV-Datei. Es soll immer die aktuellste der jeweiligen Nummer angezeigt werden

Ich hoffe das war jetzt verstänlich erklärt & du siehst woran ich hänge :wink:

Also ich hoffe es auch…ich denke das Problem besteht darin, dass wir uns in der VL mit sowas nie beschäftigt haben…das war alles immer recht theoretisch & das bringt mir leider (wie man sieht) fürs verständnis gar nichts…

ich hab versucht, alles ein bisschen verständlicher zu gestalten (also zu „verdeutschten“), ebenso textdatei…[quote=„SlaterB, post:35, topic:19403“]
es hilft dann nicht zu schreiben ‚ich verstehe nicht was du meinst‘ oder ‚habe ich was falsch gemacht‘,
sondern du musst erklären, welche Ziele du exakt verfolgst, wie du das umzusetzen planst?
im Moment von dir nicht viel zu hören und Code anscheinend nur irgendwelche planlosen Versuche, das hilft nicht viel…
[/quote]
Ich dachte eigentlich, dass mein Fragment da sehr deutlich ist…ich wollte mit meinen beiden if-Abfragen den String textausgabe (wäre hier als 1 definiert gewesen) mit der zweiten Zeile in der Textdatei vergleichen, ebenso mit dem Namen der Datei & dem aktuellsten Datum…Aber ja, wenn du es so schreibst, ist es völliger mist, was ich da fabriziert habe…

So, um das ganze nocheinmal richtig zu verstehen
Hier ist mein Codefragment dazu:

        for (File f : fileList)
    {
       System.out.println(f.getName()); 
      
     boolean fileNameOkForNrString = path.contains("praktikum-" + nrString); 
     System.out.println("Methode gibt zurück: " + fileNameOkForNrString);
    
        if (fileNameOkForNrString && f.lastModified() > mod)
        {
            mod = f.lastModified();
            found = f;
        }
       
    }

Kurze Erklärung, was ich mir dabei gedacht hab. Ich habe mein Verzeichnis der Dateien, das die CSV-Dateien enthält (path), dieses vergleiche ich nun mit meinen String nrString (befindet sich in Textdatei & ist momentan 2). Anschließend lasse ich mir das ganze ausgeben in der Konsole (zur Überprüfung). Nur leider bekomme ich kein true zurück, wie zu erwarten wäre…

Code und Erklärung dazu sind erfreulich, aber inhaltlich:

tja, Programmierung erfordert wie gesagt etwas mehr Pepp als Wände weiß zu streichen :wink:

was ist path, auf welches du da contains() aufrufst? der Pfad zum Verzeichnis für die CSV-Dateien wenn ich mich recht erinnere/ oben nachschaue,
es liegt hier eine Schleife vor, in jedem Schleifendurchlauf gibt es ein f, f.getName() wird auch mit System.out.println() ausgegeben,
→ auf f.getName() musst du prüfen?!

solche Entscheidungen sind beim Programmieren tausendfach täglich zu machen, in jeder einzelnen Zeile, das kann dir nicht immer jemand anders lösen, so kommst du ja auch nicht voran,
irgendwie braucht es mehr Grundfähigkeiten, es richtig zu machen, ein Gefühl für den Code,

oder alternativ etwas mehr Skepsis, jeden Schritt selber hinterfragen, insbesondere im Fehlerfall ganz genau nachschauen,
System.out.println() hatte ich schon genannt, hier ja auch da,
hilft aber auch nur, wenn man es halbwegs richtig einsetzt, nicht A ausgeben und dann mit B etwas machen und sich wundern, wo doch die Ausgabe A so gut erscheint,

ein Debugger-Tool mag dann noch mehr helfen, würde dir den Inhalt der path-Variable anzeigen,
aber Nutzung für sich auch wieder nicht leicht zu erlernen


edit:

hmm, du hast sogar selber schon erkannt, dass path genutzt wird?,
aber wie soll dir eine Prüfung auf path helfen, eine Datei aus der Liste auszuwählen?
du musst die Namen der Dateien in der Liste prüfen?!

also ich habe schon viel an begrenzten Verständnis gesehen, aber du versuchst dich ja wirklich weit vorne zu platzieren :wink:

Langsam nicht mehr scrollbar das Thema…

Jetzt ist es verständlich…

  1. Dateien auflisten (.csv s)
  2. Liste zuerst nach Datum sortieren
  3. Liste dann nach Nummer/Index sortieren
  4. Das Elem., welches man gerne habn möchte, aus der anderen Datei lesen
  5. Chart erstellen

2 und 3 „müsstest“ du noch umsetzen.


Sorry, ich hab mich gerade vertan… also es gibt zu einem Datum mehrere Indices… dann erst nach Index sortieren und dann nach Datum, denn bei gleichem Datum bleibt die vorherige Reihenfolge der Indices erhalten. :sweat:

Das ist die Stabilität des Sortieralgos.