Array Summe bestimmen?

Diskutiere Array Summe bestimmen? im Java Basics - Anfänger-Themen Bereich.
M

Mico93

Ich bin seit Tagen am Verzweifeln.Es geht darum,dass ich aus einer CSV-Datei Elemente eines Arrays nach bestimmten Kriterien zählen und dann in einer abschließenden Statistik darstellen möchte.

Das Kriterium lautet,dass aus dem Array von Noten,die in Punkten dargestellt sind,ich diese in die Kategorie:

Gesamtzahl aller Teilnehmer,die den Test mit einer 1 bestanden haben,die zwischen 100-88 Punkten bestanden haben

Gesamtzahl aller Teilnehmer,die den Test mit einer 2 bestanden haben,die zwischen 87-73 Punkten bestanden haben

Gesamtzahl aller Teilnehmer,die den Test mit einer 3 bestanden haben,die zwischen 72-58 Punkten bestanden haben

Gesamtzahl aller Teilnehmer,die den Test mit einer 4 bestanden haben,die zwischen 57-50 Punkten bestanden haben

Und eben die Anzahl an Teilnehmern,die den Test nicht bestanden haben.

Jetzt ist es so,dass er mir die CSV-Datei einwandfrei einliest,aber ich bei der Addition aller Teilnehmer Probleme habe,da er mir die einzeln abzählt,sprich mir alle der Reihenfolge gestaffelt auflistet als sie in einer Gesamtzahl eines Arrays ausgibt. Zudem ist noch wichtig zu erwähnen,dass ich bei der Aufgabe maximal nur 3 Methoden werden darf.

Das heißt: CSV-Datei,Die Berechnung und die HTML Statistik.

edit: habe mich vor kurzem angemeldet,daher habe ich meine Grundproblematik leider nicht vollständig formulieren können,daher bitte ich um Nachsicht.





 
M

Mico93

@mihe7 erstmal danke für die freundliche und schnelle Rückmeldung.
Ich habe es mal ausprobiert und musste feststellen,dass er mir als Ausgabe das 4-fache an Antworten ausgibt mit den Fällen,die nicht zutreffen.
Ich habe es auch mit den array-Methoden probiert (array:liste),bin damit leider auch kläglich ums andere mal gescheitert -.-
Ausschnitt Ausgabe.PNG
 
mihe7

mihe7

Ich habe es mal ausprobiert und musste feststellen,dass er mir als Ausgabe das 4-fache an Antworten ausgibt mit den Fällen,die nicht zutreffen.
?!?

Zeig mal Deinen Code (poste aber bitte keinen Screenshot, sondern verwende die drei Punkte neben dem Smiley im Editor, dort auf Code, dann Java auswählen und in das Textfeld einfach den Code inkl. Einrückungen reinkopieren).
 
J

JustNobody

Kann es sein, dass die Ausgabe jetzt immer noch in der Schleife hinter den if Anweisungen sind?

Die Ausgabe soll komplett hinter die Schleife.
 
mihe7

mihe7

Ach, jetzt sehe ich gerade noch etwas: Du machst die Auswertung beim Einlesen nach jeder Zeile, verwendest aber lokale Variablen, das kann so nicht funktionieren.
 
M

Mico93

@mihe7 Alles klar vielen Dank:)
@JustNobody Sollte eigentlich so sein,auch dir danke für die Rückmeldung
Java:
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Abgabe {

    public static void main(String[] args) {
        
        String Speicherort = System.getProperty("user.home");
        Path Datei = Paths.get(Speicherort,"Notenliste.csv");
        
        try(BufferedReader br = Files.newBufferedReader(Datei)){
                String zeile= br.readLine();
                while((zeile = br.readLine())!=null)
                {
                String[]teile = zeile.split(",");
                int werte[]=new int[teile.length];
                for(int i=0;i<teile.length;i++)
                {
                werte[i]=Integer.parseInt(teile[i]);
                }
                
                Auswertung(werte);
                }
        }catch(IOException e) {
            System.out.println("Datei konnte nicht gefunden werden");
        }
    }
    
    public static void Auswertung(int [] werte) {
        
        int laenge=werte.length;
        int sehrgut=0;
        int gut=0;
        int befriedigend=0;
        int ausreichend =0;
        int nichtausreichend=0;
        
        for(int i=0;i<laenge;i++) {
               Integer arrElt =werte[i];
               if(arrElt>=88&&arrElt<=100)
               {
                   sehrgut++;
               }
               if(arrElt>=73&&arrElt<=87)
               {
                   gut++;   
               }
               if(arrElt>=58&&arrElt<=72)
               {
                   befriedigend++;
               }
               if(arrElt>=50&&arrElt<=57)
               {
                   ausreichend++;
                  
               }
               if(arrElt<50)
               {
                   nichtausreichend++;
                  
               }
           }
        System.out.println("Mit abgeschlossen mit sehr gut:"+sehrgut);
        System.out.println("Mit abgeschlossen mit gut:"+gut);
        System.out.println("Mit abgeschlossen befriedigend:"+befriedigend);
        System.out.println("Mit abgeschlossen mit ausreichend:"+ausreichend);
        System.out.println("Mit abgeschlossen mit nicht ausreichend:"+nichtausreichend);
    }
}
 
M

Mico93

Das heißt,ich müsste sie erstmal in einem Array abspeichern bzw die lokalen Variablen durch ein Array ersetzen?
 
mihe7

mihe7

Die Frage wäre für mich, ob Du einfach irgendeine Quick & Dirty Lösung brauchst, oder ob Du lernen willst, wie man so etwas objektorientiert angehen kann. Die Quick & Dirty-Lösung bestünde darin, die Variablen einfach in die Klasse zu ziehen und static zu machen (static ist übrigens der Feind der Objektorientierung). Nachtrag: das ist nur ein Teil der Lösung, da Du die Ausgabe selbst natürlich auch noch separat machen musst.
 
M

Mico93

Ich halte nicht viel von diesen Quick dirty Lösungen,da ich es nachhaltig versuchen möchte zu verinnerlichen und zu optimieren.Daher wäre mir die objektorientierte Variante deutlich lieber.
 
J

JustNobody

Mein Vorschlag wäre dann eine Klasse, in der Du Auswertungen durchführen und speichern kannst.

Also ohne jetzt groß nachzudenken wäre eine Idee: Klasse Auswertung.
Die Klasse bekommt Instanzvariablen countSehrGut, countGut, ....

Dann eine Methode addValues(Final String values), dabei ist values ein String, der einer Zeile entspricht. Das aufteilen der Noten findet da dann statt.

Ausgabe könnte da dann auch eine Methode sein.

Du könntest sogar readNotefromFile oder so haben.

Main würde dann eine Instanz erzeugen, readNotesFromFile mit Datei aufrufen und dann ausgeben oder so aufrufen.

Das kann man aber noch weiter vertiefen. Eine Enum Noten wäre noch interessant. Dann wäre der Counter eine Map von Note auf Integer. Das finden der richtigen Note wäre dann auch ein Code, der da zu finden wäre. Das wäre dann ein weiterer Schritt, es in mehrere Klassen auszuteilen.
 
M

Mico93

@JustNobody Erstmal danke für die schnelle Empfehlung. Ich werde es mal ausprobieren, kann Tage dauern bei mir, aber wenigstens lernt man es richtig :)
Euch beiden Danke für eure Hilfe, Tipps und Ratschläge:)
 
mihe7

mihe7

OK, ich bleibe mal nah an Deinem Code und erkläre das erstmal anhand von zwei Klassen. Da die Aufgabe vorsieht, es mit drei Methoden zu erledigen, gehe ich mal davon aus, dass nur eine Klasse zu erstellen ist, daher werden wir das am Ende in eine Klasse zusammenführen, aber für das Verständnis sind zwei Klassen erstmal besser.

Du willst eine Notenstatistik erstellen, die für jede Notenstufe die Anzahl an Noten ermittelt, wobei es fünf Notenstufen gibt. Wenn Du eine neue Statistik erzeugst, sind alle Werte in der Statistik erst einmal 0 - logisch, sind ja noch keine Noten in die Statistik eingeflossen.

Hier sind zwei Dinge erkennbar: erstens kann man mehrere Objekte einer Klasse erzeugen, d. h. Du kannst auch tausend verschiedene Statistiken verwalten. Zweitens, Du musst die Statistik anhand gegebener Punkte irgendwie aktualisieren können - dafür brauchst Du eine Methode.

Damit könnte ein erster Schritt z. B. so aussehen:
Java:
public class Notenstatistik {
    private int sehrgut;
    private int gut;
    private int befriedigend;
    private int ausreichend;
    private int nichtausreichend;

    public void aktualisieren(int[] allePunkte) {
        for(int punkte : allePunkte) {
            if(punkte >= 88 && punkte <= 100) {
                sehrgut++;
            } else if(punkte >= 73 && punkte <= 87) {
                gut++;  
            } else if(punkte >= 58 && punkte <= 72) {
                befriedigend++;
            } else if(punkte >= 50 && punkte <= 57) {
                ausreichend++;
            } else if(punkte >= 0 && punkte < 50) {
                nichtausreichend++;
            } else {
               System.err.println("Ungültige Punktzahl: " + punkte);
            }
        }
    }
}
Tatsächlich würde man das noch weiter aufteilen, denn die Statistik kümmert sich aktuell um zwei Dinge: einmal um das die Aktualisierung der Statistik und einmal um die Abbildung von Punkte auf Noten. Das kann man wunderbar trennen, aber wir wollen es mal nicht zu kompliziert machen.

Jetzt fehlt noch eine Ausgabe, d. h. eine lesbare Darstellung der Statistik. Für diesen Zweck erbt jede Klasse automatisch die Methode toString() der Klasse Object. Diese Methode lässt sich überschreiben, also fügen wir der Klasse noch hinzu:
Java:
    @Override
    public String toString() {
        return "Abgeschlossen mit sehr gut: " + sehrgut + "\n" +
            "Abgeschlossen mit gut: " + gut + "\n" +
            "Abgeschlossen mit befriedigend: " + befriedigend + "\n" +
            "Abgeschlossen mit ausreichend: " + ausreichend + "\n" +
            "Nicht ausreichende Leistungen: " + nichtausreichend;
    }
Die Klasse kann nun folgendermaßen verwendet werden:
Java:
int[] punkte = {100, 80, 70, 60, 50, 40};
Notenstatistik statistik = new Notenstatistik(); // neue Statistik anlegen
statistik.aktualisieren(punkte); // Statistik aktualisieren
System.out.println(statistik); // Statistik ausgeben
Zum Beispiel kannst Du das in Deine Klasse einbauen:
Java:
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Abgabe {

    public static void main(String[] args) {      
        String speicherort = System.getProperty("user.home");
        Path datei = Paths.get(Speicherort,"Notenliste.csv");

        try(BufferedReader br = Files.newBufferedReader(datei)){
                Notenstatistik statistik = new Notenstatistik();
                String zeile= br.readLine();
                while((zeile = br.readLine())!=null) {
                    String[] teile = zeile.split(",");
                    int punkte[]=new int[teile.length];
                    for(int i=0; i < teile.length; i++) {
                        punkte[i]=Integer.parseInt(teile[i]);
                    }           
                    statistik.aktualisieren(punkte);
                }
                System.out.println(statistik);
        }catch(IOException e) {
            System.out.println("Datei konnte nicht gefunden werden");
        }
    }
}
Zwar ist das etwas, was man normalerweise auch nicht in main erledigt, aber wie oben: wir wollen es nicht zu kompliziert machen. Wenn Du jetzt hergehst und die main-Methode in die Klasse Notenstatistik kopierst (imports nicht vergessen), dann kannst Du die Klasse Abgabe entfernen und hast alles in einer Klasse mit insgesamt drei Methoden :) Vorausgesetzt, ich habe mich nirgends verschrieben :)

Der Punkt ist, dass man in der Objektorientierung mit Abstraktionen arbeitet. Wie oben geschrieben kannst Du nun Tausende solcher Statistiken erzeugen, wenn Du willst. Sie funktionieren alle gleich. In der Regel abstrahiert man noch weiter, damit eine Klasse noch universeller eingesetzt werden kann. Das erreicht man einerseits durch Trennung von Verantwortlichkeiten (die Klasse Notenstatistik erledigt ja mehrere Dinge, wie oben bereits erwähnt), andererseits durch eine andere Modellierung. So könnte man z. B. auf die Idee kommen und sich überlegen: was passiert, wenn ich sechs Notenstufen brauche? Wie lässt sich die Klasse so schreiben, dass sie unabhängig von der Zahl der Notenstufen funktioniert? Was ist, wenn die Bezeichnungen sich ändern sollen? Usw.
 
M

Mico93

Wow.
@mihe7 erstmal möchte ich Ihnen für diese umfangreiche Erklärung in Bezug auf mein Problem danken und für die umfangreiche und informative Aufarbeitung meines Problems.
Selten etwas fachdidaktisch gut aufbereitet gesehen. Für einen Newbie wie mich in der Java-Welt ist das goldwert neben dem Codierung,wohl positiv
Ich stimme Ihren Ausführung zur Aufteilung in mehreren Codes und teile Ihre Ansicht bezüglich der Abstraktion, da unter anderem auch neben der Verantwortungsaufteilung auch eine Form einer sauberen Darstellung einhergeht. Leider hat es-was ich an der Universitäts- und allgemeinen Schulvorgaben älterer Übungsaufgaben zur Erlernung der Sprache leider nicht hergab :/ In der freien Welt der Programmierung bewegt man sich freier und ist im Prinzip in der Kürze liegt die Würze und Achtung eines ressourcensparenden Programmierens.
Was ich auf jeden Fall begrüße ist,dass Sie nahe am Code geblieben sind,da ich nun ganz klar erkennen kann,was genau meine Probleme waren und ich sie nun Stück für Stück abarbeite und im wesentlichen jetzt auch darauf aufbauend mir darüber Gedanken machen kann,was noch stärker geschult werden soll.
Nochmals an Sie beide
@JustNobody
@mihe7
Ich kann mich nur nochmal wiederholen,danke für Ihre Einschätzungen,Tipps und Impressionen!
 
Thema: 

Array Summe bestimmen?

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben