• Hallo Gast, du kaufst gerne günstig ein und erfährst oft vor deinen Freunden von interessanten Angeboten? Dann kannst du dein Talent als Schnäppchenjäger jetzt zu Geld machen und anderen PCGH-Lesern beim Sparen helfen! Schau einfach mal rein - beim Test der Community Deals!

[JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

B

boss3D

Guest
[JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

Hi @ all!

Ich habe hier eine Java-Aufgabe, bei der ich nicht ganz verstehe, WAS zu machen ist. Wie das ganze dann code-mäßig aussehen soll, kann ich mir dann schon selbst überlegen (werden wir eh sehen, wie weit ich komme) ...

Capture.JPG

1.) Wie versteht ihr den ersten Punkt? Methoden für Addition, Subtraktion, Multiplikation und Division von römischen Zahlen erstellen? Wo die römischen und dezimalen Zahlen hernehmen? Einlesen per scanner oder gleich ein paar fix definieren?

2.) Ermittlung des numerischen Wertes ist klar. Einfach den dezimalen Wert zu einer beliebigen römischen Zahl ermitteln, nehme ich an?!

3.) Ermittlung der normalisierten Form bezieht sich dann wohl auf die Punkte 4 und 5?! Eine "falsche" römische Zahl gemäß den Regeln in Punkt 4 und 5 korrigieren?! Nur, wie das umsetzen? Das wird ja eine Raterei, welche römische Zahl der User gemeint haben könnte?!

4.) Und was kann ich mir dann unter der Anmerkung nach Punkt 5 vorstellen? Eine römische Zahl wird ja immer als Zeichenkette ein-/angegeben?! Das Gegenteil ist ja dann ein dezimaler int?! Und wieso soll da dann plötzlich eine "falsche" Zeichenkette nicht fehlerbereinigt werden?

^^ Blickt bei der Aufgabe irgendwer durch? :huh:

Vielen Dank für baldige Antworten!
 

DarkMo

Lötkolbengott/-göttin
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

1.) Wie versteht ihr den ersten Punkt? Methoden für Addition, Subtraktion, Multiplikation und Division von römischen Zahlen erstellen? Wo die römischen und dezimalen Zahlen hernehmen? Einlesen per scanner oder gleich ein paar fix definieren?
Na du liest halt meinetwegen ne römische 5 und ne römische 4 ein -> "V" und "IV". da haste schon deine römischen zahlen. die additions methode würde dann szs so aussehen:
string RomanNumber::addition(string a, string b) { ... }
am ende kommt wieder ein string bei raus -> V + IV = IX.

2.) Ermittlung des numerischen Wertes ist klar. Einfach den dezimalen Wert zu einer beliebigen römischen Zahl ermitteln, nehme ich an?!
richtig. das ist ein wichtiger schritt denke ich mal. also aus der "V" machst du ne 5 und aus der "IV" ne 4. eine umkehrfunktion wäre dann noch nicht übel. dann kannst du nämlich aus der additions methode sowas hier machen:
string RomanNumber::addition(string a, string b) { return this.dec2roman( this.roman2dec(a) + this.roman2dec(b) ); }
also, du wandelst die eingegebenen strings in dezimale zahlen um, rechnest mit denen das operations-ergebnis aus, und wandelst dieses wieder in ne römische ziffer (string) um.

3.) Ermittlung der normalisierten Form bezieht sich dann wohl auf die Punkte 4 und 5?! Eine "falsche" römische Zahl gemäß den Regeln in Punkt 4 und 5 korrigieren?! Nur, wie das umsetzen? Das wird ja eine Raterei, welche römische Zahl der User gemeint haben könnte?!
joa, normalisierte form... soll dann aus "ViIi" "VIII" werden? also nen einheitliches format durchgesetzt werden? wobei es da doch sicher string-methoden für gibt. .lower() oder so für alles in kleinbuchstaben. das mit der falschen römischen zahl ergibt sich doch aus der beschreibung, wie sich eine römische zahl zusammensetzt. also wenn einer für ne 4 IIII eingibt, ist das keine römische zahl -> diese soll dann eben in ein IV umgewandelt werden. oder eben das bsp mit der 99. die 99 wird nicht als IC (eins vor 100) dargestellt, sondern als XCIX (10 vor hundert + 1 vor 10 -> 100-10+10-1 quasi ^^). dann soll eben das falsche IC in ein richtiges XCIX umgewandelt werden. vom verständnis her nicht so schwer, das umzusetzen...

4.) Und was kann ich mir dann unter der Anmerkung nach Punkt 5 vorstellen? Eine römische Zahl wird ja immer als Zeichenkette ein-/angegeben?! Das Gegenteil ist ja dann ein dezimaler int?! Und wieso soll da dann plötzlich eine "falsche" Zeichenkette nicht fehlerbereinigt werden?
hmm, hier weis ich grad nich so recht, wass du meinst ^^

aber generell glaube ich, will er hier was ganz anderes, als ich erst gedacht hab (un du vllt auch). wie es scheint, sollst du eine klasse bauen, die EINE zahl repräsentiert. von operationen wie addition seh ich da grad garnix auf anhieb. sprich, du müsstest eine klasse bauen, die einmal einen string und einmal einen int wert enthält sowie 3 konstruktoren -> einmal der default konstruktor (hier müsste dann "n. a." und 0 gespeichert werden, dann einmal ein konstruktor, der aus nem string das objekt erzeugt (also aus der römischen zahl ne dezimale macht - am besten per methode - und nebenbei noch die römische zahl ggf korrigiert) und zu guter letzt noch einen, der das objekt aus ner dezimalen zahl erstellt (also aus der zahl den string für die römische zahl erstellt und die zahl an sich einfach so speichert).

die ermittlung des numerischen wertes is ja dann schon geschehen - einfach den int wert ausgeben. die weitere frage bleibt natürlich, was ne normalisiert römische zahl sein soll ^^


vielleicht kommt ja als nächster schritt dann sowas, wie eigene operatoren entwickeln (hab ich selbst auch noch nie gemacht). wenn mans grundprinzip kennt, dürfte das aber auch wieder simpel sein: man erstellt einfach ein neues objekt der klasse das mit dem ergebnis der numerischen teile gebildet wird. wenn ich jetz konkret wüsste, wie das funzt, würd ich nen bsp liefern ^^
 
TE
B

boss3D

Guest
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

Na du liest halt meinetwegen ne römische 5 und ne römische 4 ein -> "V" und "IV". da haste schon deine römischen zahlen. die additions methode würde dann szs so aussehen:
string RomanNumber::addition(string a, string b) { ... }
am ende kommt wieder ein string bei raus -> V + IV = IX.
Wie Rechenmethoden zu schreiben wären, könnte ich mir schon vorstellen. Meine Frage ist eher, ob man überhaupt welche braucht ... oder ob da ganz was anderes gemeint ist ...

Was ist mit dem Satz gemeint: Erzeugung von römischen Zahlen [...] aus anderen römischen Zahlen. --> ??? Da hätte ich spontan auf Rechenmethoden getippt?!
aber generell glaube ich, will er hier was ganz anderes, als ich erst gedacht hab (un du vllt auch). wie es scheint, sollst du eine klasse bauen, die EINE zahl repräsentiert. von operationen wie addition seh ich da grad garnix auf anhieb. sprich, du müsstest eine klasse bauen, die einmal einen string und einmal einen int wert enthält sowie 3 konstruktoren -> einmal der default konstruktor (hier müsste dann "n. a." und 0 gespeichert werden, dann einmal ein konstruktor, der aus nem string das objekt erzeugt (also aus der römischen zahl ne dezimale macht - am besten per methode - und nebenbei noch die römische zahl ggf korrigiert) und zu guter letzt noch einen, der das objekt aus ner dezimalen zahl erstellt (also aus der zahl den string für die römische zahl erstellt und die zahl an sich einfach so speichert).
Ich schaue mal, wie weit ich das hinkriege. Mit Konstruktoren beschäftige ich mich seit ziemlich genau 2 Wochen ...
 
TE
B

boss3D

Guest
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

So, mit ein Bisschen googeln habe ich jetzt mal folgendes für den Anfang zusammengebastelt:
Code:
public class RomanNumber {
    
    static String romanNum;
    static int decimalNum;
    static char convertToDecimal;
    
    [COLOR=royalblue]/**
     * @return calculated decimal decimalNum of a specific Roman number
     */[/COLOR]
    public int convertToDecimal() {  
        char lastChar=' ';
                
        for (int i=romanNum.length()-1; i>=0; i--) {
            switch (romanNum.charAt(i)) {
                case 'I':
                    if (lastChar=='X' || lastChar=='V') {
                        decimalNum-=1;
                    } else {
                        decimalNum+=1;
                    }
                    break;
                case 'V':
                    decimalNum+=5;
                    break;
                case 'X':
                    if (lastChar=='C' || lastChar=='L') {
                        decimalNum-=10;
                    } else {
                        decimalNum+=10;
                    }
                    break;
                case 'L':
                    decimalNum+=50;
                    break;
                case 'C':
                    if (lastChar=='M' || lastChar=='D') {
                        decimalNum-=100;
                    } else {
                        decimalNum+=100;
                    }
                    break;
                case 'D':
                    decimalNum+=500;
                    break;
                case 'M':
                    decimalNum+=1000;
                    break;
                }
                lastChar=romanNum.charAt(i);
            }

            
        return decimalNum;    
    }

}
Testen kann ich's aber leider nicht, weil's JUnit TestCase nicht so geht, wie ich mir das vorstelle:
Code:
import static org.junit.Assert.assertEquals;

import org.junit.Test;


public class RomanNumberTest {
    
    private final String roman = "IV";
    
    @Test
    public void testConvertToDecimal() {
        assertEquals(roman.convertToDecimal(), 4);
    }
    
}
^^ Da sagt Eclipse: The method convertToDecimal() is undefined for the type String ???
 
Zuletzt bearbeitet:

DarkMo

Lötkolbengott/-göttin
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

ahso, ich glaub ich weis wieso. der erste code ist die roman klasse und die zweite die "main" die diese erste klasse aufruft?

in RomanNumber steht static char convertToDecimal; - und dann die methode public int convertToDecimal(). also das sollte an sich schon probleme geben *denk*, dass ne variable und ne methode gleich benannt sind (wobei ers vllt noch unterscheiden könnt anhand der klammer hinterm namen). jedenfalls rufst du in deiner 2. klasse roman.convertToDecimal() auf - ohne ein roman-objekt überaupt erstelt zu haben. er kann in diesem falle also NUR auf static elemente der klasse zugreifen -> und das ist die char variable, welche du mit nem string penetrierst ^^ also zumindest vom grundkonzept her - was dieses assertEquals sein soll, weis ich grad nich so recht.

ok, JETZT hab ichs grad gesehn ^^ roman ist bei dir ja ein string, und für die klasse string ist keine methode convertToDecimal() festgelegt worden. du hast also tatsächlich ein roman-objekt, allerdings ist das eben vom typ string und nicht vom typ RomanNumber - deine klasse wird also garnich verwendet.

und konstruktoren sind ganz einfach:
die "bauen" - konstruieren eben - das objekt bei der erzeugung -> RomanNumber roman; du erzeugst hier die variable roman vom typ RomanNumber. Jetzt werden speicherbereiche für die ganzen variablen erstellt, die zur klasse gehören - also hier eben romanNum, decimalNum und convertToDecimal (wozu auch immer du die hast ^^) - und das wars im groben mit dem standardkonstruktor (also auch wenn du selber keinen definierst, wird IMMER ein standard konstruktor bemüht - der kann halt nich sehr viel). in java wird alles glaube noch mit "0" initialisiert, das fehlt in c (wenn ichs richtig in erinnerung hab) zum bsp komplett - da steht also im zweifelsfall dann müll in der variablen ^^ der konstruktor hilft hier eben, das alles so zu initialisieren, wie man sich das wünscht. der konstruktor ist dabei eine methode, die einfach dem klassennamen entspricht:
RomanNumber() {}

damit haste schon deinen eigenen konstruktor gebaut - der ganusoviel kann, wie der default konstruktor :P in unserem falle müsste der default konstruktor romanNum mit "n. a." und decimalNum mit 0 initialisieren - und fertig. da wir aber auch noch ein RomanNumber-objekt mit nem string oder nem int direkt erzeugen können wollen, sollten wir den noch überladen (überladen bedeuted, dass man die selbe funktion/methode (vom namen her) mehrfach definiert - sie müsen sich dann in der parameter liste unterscheiden):
RomanNumber(int dNum) {}
RomanNumber(string rNum) {}

bei den beiden wirds dann halt schon schwieriger. der übergebene teil wird einfach weiter gereicht (also this.decimalNum = dNum usw) und den anderen Teil muss man dann aus dem übergebenen generieren. ganz rudimentär kann man die 3 kontruktoren erstmal so definieren *denk* (weis jetz nich, inwiefern das java kompatibel is, geht mir eher ums prinzip ^^):
Code:
RomanNumber() {
    this.romanNum = "n. a.";
    this.decimalNum = 0;
}

RomanNumber(string rNum) {
    this.romanNum = rNum;
    this.convertToDecimal();
}

RomanNumber(int dNum) {
    this.decimalNum = dNum;
    this.convertToRoman();
}

elegant gelöst und das problem auf später verschoben xD natürlich müssten zumindest die funktionsrümpfe der convertfunken existieren, damits wenigstens läuft. jetzt könnte man also schonmal RomanNumber roman = new RomanNumber("IV"); schreiben, und ein roman-objekt mit der entsprechung der römischen 4 erstellen. die convertfunktionen wären dann das nächste problem. ne rückgabe brauchst du eigentlich nicht - aber du kannst ja gern wieder überladen und ne 2. erstellen, die nen wert übernimmt und einen zurückgibt. das als static deklariert, und du kannst diese umwandlung auch extern nutzen, ohne ein RomanNumber-objekt erstellen zu müssen. also als bsp sowas hier:
Code:
private void convertToDecimal() {
    this.decimalNum = this.convertToDecimal(this.romanNum);
}

static int convertToDecimal(string rNum) {
    // umwandlungscode
    // ...
}

hat den vorteil, dass du dann immer nur den code der static funktion ändern musst. würdest du den code in beiden methoden direkt schreiben, müsstest du bei änderungen beide anpassen - das soll ja nich sinn und zweck sein ^^ wie du siehst, wieder elegant gelöst - und dennoch keinen schritt weiter gekommen xD
 
TE
B

boss3D

Guest
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

^^ Ok, danke erstmal!

Die Standarddinge, was Overloading ist und was Konstruktoren überhaupt sind, weiß ich eh. Im Moment sieht der Code so aus:
Code:
public class RomanNumber {
    
    private String romanNum;
    private int decimalNum;
    
    RomanNumber() {
        this.romanNum = "n. a.";
        this.decimalNum = 0;
    }

    RomanNumber(String rNum) {
        this.romanNum = rNum;
        this.convertToDecimal();
    }

    RomanNumber(int dNum) {
        this.decimalNum = dNum;
        this.convertToRoman();
    }
        
    /**
     * @return calculated decimal value of a specific Roman number
     */
    public int convertToDecimal() {  
        char lastChar=' ';
                
        for (int i=romanNum.length()-1; i>=0; i--) {
            switch (romanNum.charAt(i)) {
                case 'I':
                    if (lastChar=='X' || lastChar=='V') {
                        decimalNum-=1;
                    } else {
                        decimalNum+=1;
                    }
                    break;
                case 'V':
                    decimalNum+=5;
                    break;
                case 'X':
                    if (lastChar=='C' || lastChar=='L') {
                        decimalNum-=10;
                    } else {
                        decimalNum+=10;
                    }
                    break;
                case 'L':
                    decimalNum+=50;
                    break;
                case 'C':
                    if (lastChar=='M' || lastChar=='D') {
                        decimalNum-=100;
                    } else {
                        decimalNum+=100;
                    }
                    break;
                case 'D':
                    decimalNum+=500;
                    break;
                case 'M':
                    decimalNum+=1000;
                    break;
                }
                lastChar=romanNum.charAt(i);
            }

            
        return decimalNum;    
    }
    
    public void convertToRoman() {
        
    }

}
^^ Was ich noch gar nicht verstehe, ist, wann ich welches Attribut nehmen kann (final, static, privat, ...). Ich habe jetzt mal die Konstanten ganz oben auf nur private geändert. Das müsste ja erstmal heißen, dass die nur in dieser Klasse sichtbar sind, was eh so passen müsste?! final kann ich ja zumindest bei decimalNum nicht sagen, weil sich dessen Wert verändern können muss. Und wenn ich aber static sage, dann kommt in den Konstruktoren ein Warning: The static field RomanNumber.decimalNum should be accessed in a static way. static mag ich aber eh nicht und will ich möglichst vermeiden. ???

Und dann wäre da noch ein kleines Problemchen: Beim JUnit Test kommt raus, dass der sich "8" erwartet, als Ergebnis! Das verstehe ich überhaupt nicht, wenn ich mir den Code in der RomanNumber Klasse anschaue. Er sieht als erstes (von rechts beginnend) bei "IV" das "V" und rechnet 0+5=5. Dann geht er um eins nach links und sieht das "I". Dabei stellt er im Switch aber auch gleich fest, dass er rechts neben dem "I" ein "V" hat und rechnet daher 5-1=4 ... wieso erwartet sich der Test für "IV" also bitte "8"? :huh:
Code:
import static org.junit.Assert.assertEquals;

import org.junit.Test;


public class RomanNumberTest {
    
    @Test
    public void testConvertToDecimal() {
        RomanNumber roman = new RomanNumber("IV");
        assertEquals(4, roman.convertToDecimal());
    }
    
}
Mit assertEquals kannst du BTW verschiedene Werte des gleichen Datentyps miteinander vergleichen. Z.B. 2 ints, so wie ich das hier vorhabe. Dabei ist der erste/linke Wert der erwartete und der zweite/rechte der eigentliche.

[EDIT]
Gerade gesehen: Bei "V" kommt er auch nicht auf "5", sondern auf "10"! Wieso kommt der immer auf's doppelte?
 

DarkMo

Lötkolbengott/-göttin
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

wegen public und final und was weis ich: beschränk dich (sofern du e nicht unbedingt brauchst) erstmal nur auf public und private. das ist noch recht simpel: public heisst, man kann von aussen direkt auf die variable zugreifen und private bedeuted, dass es nur aus der klasse selbst geändert werden kann. deine klasse hier is dafür sogar nen super bsp:

du hast hier 2 klassen-variablen, die eng miteinander verknüpft sind: roman und decimal teil. beide stellen die selbe zahl dar, nur in unterschiedlichen "systemen". würdest du die public machen, könnte man von aussen (also aus ner aufrufenden funktion/main...) einen der beiden werte ändern und würde den sinn zerstören -> also aus ner 4/IV ne 5/IV machen. aber 5 und IV sind nich mehr das selbe, alles im eimer *ausm fenster hüpf* ^^ mit private verhindert man das geschickt, da ein
Code:
RomanNumber rn = new RomanNumber(4);
rn.decimalNum = 5;
nicht mehr funktioniert. man muss hierfür dann halt "schnittstellen" bereitstellen. damit is ganz simpel ne methode zur manipulation gemeint. gern auch als getter oder setter bezeichnet glaube, weil man eben gern die namenskonvention getDecimalNum() oder eben setRomanNum(newRomanNum) usw nutzt. get returned einfach den wert, set überschreibts mit den übergebenen neuen wert. und bei der set kann man dann eben beide teile hier in einer weise ändern, dass die konsitenz(?) der klasse gewahrt bleibt. also private = zugriff nur mittels this.

static... der meckert warscheinlich, weil du statt this eher den klassen namen nehmen sollst. also statt this.convertToDecimal(this.romanNum); eben RomanNumber.convertToDecimal(this.romanNum);. static sorgt halt dafür, dass man diese methoden nutzen kann, ohne ein klassenobjekt erzeugen zu müssen. wird zum bsp gerade bei so math-klassen gern verwendet. math.sqrt(2); als bsp. hier wärs äusserst ätzend jedesmal erst nen mathe-objekt erschaffen zu müssen.

protected kenn ich noch vom namen her, das wars aber auch schon ^^ war glaube irgendwas wegen vererbung. aber da müsst ich jetz selber nachlesen. und final hab ich jetz auch nur schonmal von gehört. bedeutede das, dass man die bei ner vererbung in der subklasse nich überschreiben musste? abstract musste man ja zwangsläufig überschreiben. ach naja, da hörts bei mir auch auf ^^

ps: falls ich groben unfug schreib, könnt ihr mich gern berichtigen ^^
 

Supeq

Software-Overclocker(in)
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

3.) Ermittlung der normalisierten Form bezieht sich dann wohl auf die Punkte 4 und 5?! Eine "falsche" römische Zahl gemäß den Regeln in Punkt 4 und 5 korrigieren?! Nur, wie das umsetzen? Das wird ja eine Raterei, welche römische Zahl der User gemeint haben könnte?!

4.) Und was kann ich mir dann unter der Anmerkung nach Punkt 5 vorstellen? Eine römische Zahl wird ja immer als Zeichenkette ein-/angegeben?! Das Gegenteil ist ja dann ein dezimaler int?! Und wieso soll da dann plötzlich eine "falsche" Zeichenkette nicht fehlerbereinigt werden?

^^ Blickt bei der Aufgabe irgendwer durch? :huh:

Vielen Dank für baldige Antworten!

ich springe einfach mal rein ;)

3) Ich würde hierfür einfach eine Methode "format_roman(string input_roman)" oder so ähnlich schreiben, die halt eine "römische Zahl" (auch in falscher Formatierung entgegennimmt), sie zunächst mit Hilfe deiner convertToDecimal() umwandelt, um sie dann mit convertToRoman wieder zurückzuwandeln und zurückzugeben.

Beispiel:

Eingabe: CCCCC
convertToDecimal(CCCCC) = 500
convertToRoman(500) = M

Ist eigentlich simpel, tricky wird es dann wenn mit der Subtraktionsregeln interpretiert werden soll. Da kann man dann wie du schon sagtest "raten welche römische Zahl gemeint ist" oder (mein Vorschlag) bei einer ungültigen Zahl (bsp.: IC) einfach eine Fehlermeldung ausgeben.
 
TE
B

boss3D

Guest
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

Als erstes würde ich mal gerne wissen, wieso ich immer genau das doppelte zurückbekomme :huh: Für M 2000, für IV 8, ... ???

Bis mir das wer verraten kann, bastle ich jetzt mal eine convertToRoman Methode ...

[EDIT]
Codemäßig wäre ich wieder weiter, aber irgendwie funktioniert das alles nicht so, wie's soll ... :(
Code:
public class RomanNumber {
    
    private String romanNum;
    private int decimalNum;
    
    [COLOR=royalblue]/**
     * Constructor
     * used if there's no display of a Roman number
     * or it's decimal value is 0
     */[/COLOR]
    RomanNumber() {
        this.romanNum = "n. a.";
        this.decimalNum = 0;
    }
    
    [COLOR=royalblue]/**
     * Constructor
     * used for the decimal representation of a Roman number
     * @param rNum is any Roman number
     */[/COLOR]
    RomanNumber(String rNum) {
        this.romanNum = rNum;
        this.convertToDecimal();
    }
    
 [COLOR=royalblue]   /**
     * Constructor
     * used for the Roman representation of a decimal integer
     * @param dNum is any integer number
     */[/COLOR]
    RomanNumber(int dNum) {
        this.decimalNum = dNum;
        this.convertToRoman();
    }
        
   [COLOR=royalblue] /**
     * @return calculated decimal value of a specific Roman number
     */[/COLOR]
    public int convertToDecimal() {  
        char lastChar=' ';
                
        for (int i=romanNum.length()-1; i>=0; i--) { [COLOR=seagreen]// begin at the right end of the string (= Roman number)[/COLOR]
            switch (romanNum.toUpperCase().charAt(i)) {[COLOR=seagreen] // check the char on each position[/COLOR]
                case 'I':
                    if (lastChar=='X' || lastChar=='V') {
                        decimalNum-=1;
                    } else {
                        decimalNum+=1;
                    }
                    break;
                case 'V':
                    decimalNum+=5;
                    break;
                case 'X':
                    if (lastChar=='C' || lastChar=='L') {
                        decimalNum-=10;
                    } else {
                        decimalNum+=10;
                    }
                    break;
                case 'L':
                    decimalNum+=50;
                    break;
                case 'C':
                    if (lastChar=='M' || lastChar=='D') {
                        decimalNum-=100;
                    } else {
                        decimalNum+=100;
                    }
                    break;
                case 'D':
                    decimalNum+=500;
                    break;
                case 'M':
                    decimalNum+=1000;
                    break;
                }
                lastChar=romanNum.charAt(i); [COLOR=seagreen]// after each round, make current index of the string to position of last char[/COLOR]
            }

            
        return decimalNum;    
    }
    
[COLOR=royalblue]    /**
     * @return calculated Roman number of a decimal integer
     */[/COLOR]
    public String convertToRoman() {        
        String roman="";
        int value=decimalNum;
        
        if (value==0) {
            return romanNum; [COLOR=seagreen]// in this case "n. a."[/COLOR]
        }

        if (value>=0) {
            while (value/1000 >= 1) { [COLOR=seagreen]// while division by 1000 is possible, do so[/COLOR]
                roman+="M";
                value-=1000;
            }
            if (value/900 >= 1) { [COLOR=seagreen]// if division by 1000 is no longer possible, continue with the next smaller integer[/COLOR]
                roman+="CM";
                value-=900;
            }
            if (value/500 >= 1) {
                roman+="D";
                value = value - 500;
            }
            if (value/400 >= 1) {
                roman+="CD";
                value-=400;
            }
            while (value/100 >= 1) { [COLOR=seagreen]// while division by 100 is possible, do so[/COLOR]
                roman+="C";
                value-=100;
            }
            if (value/90 >= 1) { [COLOR=seagreen]// if division by 100 is no longer possible, continue with the next smaller integer[/COLOR]
                roman+="XC";
                value-=90;
            }
            if (value/50 >= 1) {
                roman+="L";
                value-=50;
            }
            if (value/40 >= 1) {
                roman+="XL";
                value-=40;
            }
            while (value/10 >= 1) { [COLOR=seagreen]// while division by 10 is possible, do so[/COLOR]
                roman+="X";
                value-=10;
            }
            if (value/9 >= 1) {[COLOR=seagreen] // if division by 10 is no longer possible, continue with the next smaller integer[/COLOR]
                roman+="IX";
                value-=9;
            }
            if (value/5 >= 1) {
                roman+="V";
                value-=5;
            }
            if (value/4 >= 1) {
                roman+="IV";
                value-=4;
            }
            while (value >= 1) {
                roman+="I";
                value-=1;
            }
        }
        
        return roman;
    }

}
^^ Das Problem mit den doppelten Werten habe ich immer noch und bei folgendem JUnit TestCase ...
Code:
import static org.junit.Assert.assertEquals;

import org.junit.Test;


public class RomanNumberTest {
    
    @Test
    public void testConvertToDecimal() {
        RomanNumber roman = new RomanNumber(0);
        assertEquals("n. a.", roman.convertToRoman());
    }
    
}
... kommt die Meldung: java.lang.AssertionError: expected:<n. a.> but was:<null>

Irgendwas passt da wohl mit dem Konstruktor nicht?!
 
Zuletzt bearbeitet:

Supeq

Software-Overclocker(in)
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

Ich frag mich grad warum du die Methoden nicht Static machst, dann kannst du dir das ganze manuelle Instanzieren sparen und für spätere Anwendungen der Klasse ist es auch einfacher. Hier mal meine Version der convertToDecimal:

Code:
    // *Konstruktoren und Klassen-Variablen rausgeschmissen *


    public static int convertToDecimal(String romanNum) {  
        char lastChar=' ';
        int decimalNum = 0;
                
        for (int i=romanNum.length(); i>=1; i--) { // begin at the right end of the string (= Roman number)
            switch (romanNum.toUpperCase().charAt(i-1)) { // check the char on each position
                case 'I':
                    if (lastChar=='X' || lastChar=='V') {
                        decimalNum-=1;
                    } else {
                        decimalNum+=1;
                    }
                    break;
                case 'V':
                    decimalNum+=5;
                    break;
                case 'X':
                    if (lastChar=='C' || lastChar=='L') {
                        decimalNum-=10;
                    } else {
                        decimalNum+=10;
                    }
                    break;
                case 'L':
                    decimalNum+=50;
                    break;
                case 'C':
                    if (lastChar=='M' || lastChar=='D') {
                        decimalNum-=100;
                    } else {
                        decimalNum+=100;
                    }
                    break;
                case 'D':
                    decimalNum+=500;
                    break;
                case 'M':
                    decimalNum+=1000;
                    break;
                }
                lastChar=romanNum.charAt(i-1); // after each round, make current index of the string to position of last char
            }

            
        return decimalNum;    
    }

Läuft ^^

Deine doppelten Werte kommen übrigens daher, das du die Methode convertToRoman() zweimal aufrufst und zwar im Konstruktor und dann nochmal explizit (wobei die "decimalNum" zwischendurch nicht resetted wird)
 
Zuletzt bearbeitet:
TE
B

boss3D

Guest
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

^^ Moment mal ... habe gerade was rausgefunden: Selbst wenn ich meinen Code lasse (ohne deine Änderungen) kommt schon das richtige raus, wenn ich nur int decimalNum = 0; am Beginn der Methode einfüge!

Scheinbar stimmt meine Logik doch, nur initialisiert Java Variablen wohl nicht standardmäßig mit 0, wie ich ursprünglich dachte?! Wenn decimanlNum bereits irgendeinen Initialwert != 0 hat, ist klar, dass das dann mit den ganzen += und -= nie auf den richtigen Wert rauslaufen kann.

Ich hätte mir allerdings gedacht, dass die decimanlNum-Konstanten verwendet werden würde. Jetzt wird ein gleichnamiger int verwendet. Irgendwie habe ich hier das Gefühl, zu viele Sachen anzulegen?! Jetzt sind ja bald die Konstruktoren/Konstanten umsonst?! :huh:
BTW: Wenn ich die Methoden static mache, dann kommt beim Aufruf in den Konstruktoren: The static method convertToDecimal() from the type RomanNumber should be accessed in a static way
Und bei den Aufrufen der Konstanten kommt: Cannot make a static reference to the non-static field romanNum. Change modifier of 'romanNum' to static.

^^ Drum sag ich ja, ich mag static überhaupt nicht. Da kommen nur immer irgendwelche Probleme. Zumindest, wenn man noch nicht richtig weiß/versteht, wie das in der gesamten Klasse anzuwenden ist ... :huh:
 

Supeq

Software-Overclocker(in)
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

Hab meinen vorigen Beitrag nochmal editiert, da steht warum es zu doppelten Werten kam^^
 
TE
B

boss3D

Guest
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

^^ Ja, aber macht das dann nicht wirklich die Konstruktoren überflüssig? BTW meinst du mit dem zweiten expliziten Aufruf den in der TestKlasse, oder?
 

Supeq

Software-Overclocker(in)
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

Diesen "assertEquals("n. a.", roman.convertToRoman());" Aufruf meinte ich damit.

Wenn du nur statische Mehtoden in deiner Klasse verwendest dann ist ein Konstruktor überflüssig, weil du ja die Methoden aufrufen kannst ohne vorher ein Objekt zu instanzieren. Das ist ja grad das, was statische Mehtoden ausmachen. Schau dir mal die Java-Basicklassen , bspw. Math (Math (Java Platform SE 6)) an, dort sind auch alle Methoden statisch.
 
TE
B

boss3D

Guest
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

Ok ... ich habe aber stark den Verdacht, dass die Aufgabe mit Konstruktoren gelöst werden sollte, wie auch DarkMo das angenommen hat. Insofern spare ich mir lieber das static.

Mir kommt nur immer noch das hier irgendwie "sinnlos" vor: int decimalNum=0; ???
decimalNum gäb's ja schon als Konstante. Das jetzt trotzdem noch mal als int anlegen?! Kann man das nicht "eleganter" lösen, dass es trotzdem mit 0 initialisiert bleibt und ich keine doppelten Werte bekomme?
Und bei der convertToRoman Methode habe ich das Problem, dass die TestKlasse meint:
java.lang.NullPointerException
at RomanNumber.convertToDecimal(RomanNumber.java:48)
at RomanNumberTest.testConvertToRoman(RomanNumberTest.java:17)
 

Supeq

Software-Overclocker(in)
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

Also in deiner Aufgabenstellung steht nix davon, das man Konstruktoren verwenden muss. Aber okay , geht ja auch ohne static^^

Mir fällt jetzt spontan keine elegantere Lösung als Static-Methoden ein um deine Zählvariable (decimalNum) zurückzusetzen.

Unelegant finde ich es aber auch nicht, die Variable "per Hand" wieder auf 0 zu setzen. An irgendeiner Stelle musst du das ja definieren, woher soll dein Programm sonst wissen das die Variable nicht noch weiter verwendet wird.
Du könntest natürlich den Aufruf der Methode im Konstruktor entfernen(da hat die eigtl. sowieso nix zu suchen), aber ich dreh mich hier im Kreis weil static-Methoden die logische und offensichtliche Lösung für derartige Probleme sind.

decimalNum gäb's ja schon als Konstante.

Was meinst du mit Konstante? Das is doch ne Variable :huh:
 
Zuletzt bearbeitet:
TE
B

boss3D

Guest
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

Ich bin gerade stark am Überlegen, ob's nicht am schlauesten/elegantesten wäre, noch wenigstens eine getRoman() Methode zu machen, so wie DarkMo das auch schon vorgeschlagen hat. Vielleicht muss ich mir dann nicht so viele Gedanken um (Doppel)Initialisierungen machen?! Mal schauen, worauf ich da noch komme ...

[EDIT]
Alle Fehler beseitigt! :-)
So funktioniert jetzt erst mal alles (zumindest gültige Umwandlungen):
Code:
public class RomanNumber {
    
    private String romanNum;
    private int decimalNum;
    
    [COLOR=royalblue]/**
     * Constructor
     * used if there's no display of a Roman number
     * or it's decimal value is 0
     */[/COLOR]
    RomanNumber() {
        this.romanNum = "n. a.";
        this.decimalNum = 0;
    }
    
    [COLOR=royalblue]/**
     * Constructor
     * used for the decimal representation of a Roman number
     * @param rNum is any Roman number
     */[/COLOR]
    RomanNumber(String rNum) {
        this.romanNum = rNum;
        this.convertToDecimal();
    }
    
    [COLOR=royalblue]/**
     * Constructor
     * used for the Roman representation of a decimal integer
     * @param dNum is any integer number
     */[/COLOR]
    RomanNumber(int dNum) {
        this.decimalNum = dNum;
        this.convertToRoman();
    }
        
   [COLOR=royalblue] /**
     * @return calculated decimal value of a specific Roman number
     */[/COLOR]
    public int convertToDecimal() {  
        char lastChar=' ';
        int decimalNum=0;
                
        for (int i=romanNum.length()-1; i>=0; i--) { [COLOR=seagreen]// begin at the right end of the string (= Roman number)[/COLOR]
            switch (romanNum.toUpperCase().charAt(i)) { [COLOR=seagreen]// check the char on each position[/COLOR]
                case 'I':
                    if (lastChar=='X' || lastChar=='V') {
                        decimalNum-=1;
                    } else {
                        decimalNum+=1;
                    }
                    break;
                case 'V':
                    decimalNum+=5;
                    break;
                case 'X':
                    if (lastChar=='C' || lastChar=='L') {
                        decimalNum-=10;
                    } else {
                        decimalNum+=10;
                    }
                    break;
                case 'L':
                    decimalNum+=50;
                    break;
                case 'C':
                    if (lastChar=='M' || lastChar=='D') {
                        decimalNum-=100;
                    } else {
                        decimalNum+=100;
                    }
                    break;
                case 'D':
                    decimalNum+=500;
                    break;
                case 'M':
                    decimalNum+=1000;
                    break;
                }
                lastChar=romanNum.charAt(i); [COLOR=seagreen]// after each round, make current index of the string to position of last char[/COLOR]
            }

            
        return decimalNum;    
    }
    
    [COLOR=royalblue]/**
     * @return calculated Roman number of a decimal integer
     */[/COLOR]
    public String convertToRoman() {        
        String roman="";
        int value=decimalNum;
        
        if (value==0) {
            return romanNum; [COLOR=seagreen]// in this case "n. a."[/COLOR]
        }

        if (value>=0) {
            while (value/1000 >= 1) { [COLOR=seagreen]// while division by 1000 is possible, do so[/COLOR]
                roman+="M";
                value-=1000;
            }
            if (value/900 >= 1) { [COLOR=seagreen]// if division by 1000 is no longer possible, continue with the next smaller integer[/COLOR]
                roman+="CM";
                value-=900;
            }
            if (value/500 >= 1) {
                roman+="D";
                value = value - 500;
            } 
            if (value/400 >= 1) {
                roman+="CD";
                value-=400;
            }
            while (value/100 >= 1) { [COLOR=seagreen]// while division by 100 is possible, do so[/COLOR]
                roman+="C";
                value-=100;
            }
            if (value/90 >= 1) { [COLOR=seagreen]// if division by 100 is no longer possible, continue with the next smaller integer[/COLOR]
                roman+="XC";
                value-=90;
            }
            if (value/50 >= 1) {
                roman+="L";
                value-=50;
            }
            if (value/40 >= 1) {
                roman+="XL";
                value-=40;
            }
            while (value/10 >= 1) { [COLOR=seagreen]// while division by 10 is possible, do so[/COLOR]
                roman+="X";
                value-=10;
            }
            if (value/9 >= 1) { [COLOR=seagreen]// if division by 10 is no longer possible, continue with the next smaller integer[/COLOR]
                roman+="IX";
                value-=9;
            }
            if (value/5 >= 1) {
                roman+="V";
                value-=5;
            }
            if (value/4 >= 1) {
                roman+="IV";
                value-=4;
            }
            while (value >= 1) {
                roman+="I";
                value-=1;
            }
        }
        
        return roman;
    }

}
Code:
import static org.junit.Assert.assertEquals;

import org.junit.Test;


public class RomanNumberTest {
    
    @Test
    public void testConvertToDecimal() {
        RomanNumber roman = new RomanNumber("MCDXXVI");
        assertEquals(1426, roman.convertToDecimal());
    }
    
    @Test
    public void testConvertToRoman() {
        RomanNumber roman = new RomanNumber(1426);
        assertEquals("MCDXXVI", roman.convertToRoman());
    }
    
}
Nur sowas hier geht noch nicht. Das muss ich noch ändern:
java.lang.AssertionError: expected:<n. a.> but was:<null>
Code:
    @Test
    public void testConvertToRoman() {
        RomanNumber roman = new RomanNumber(0);
        assertEquals("n. a.", roman.convertToRoman());
    }
^^ Nur wie?

Muss ich da irgendwie der entsprechenden Methode sagen, dass sie in dem Fall auf den ersten Konrtuktor zugreifen soll?! Definiert hätten wir den Fall darin ja schon ...
 
Zuletzt bearbeitet:

Supeq

Software-Overclocker(in)
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

Der erste Konstruktor wird nur aufgerufen wenn du nichts übergibst ;) Das steht in deinem Kommentar auch falsch ^^( "or it's decimal value is 0")

Ich würd den ersten Konstruktor löschen und dafür in der converToRoman folgendes ändern:

Code:
 if (value==0) {
            return romanNum; // in this case "n. a."
        }

zu

Code:
 if (value==0) {
            return "n. a."; // in this case "n. a."
        }

Dann hast du´s^^
 
Zuletzt bearbeitet:
TE
B

boss3D

Guest
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

Ja, das ist schon klar, dass der nur dann aufgerufen wird, aber ich übergebe ja eh nichts, oder? Wo denn?

Wie man's sonst lösen könnte, weiß ich, aber ich hätte es halt gerne über den/die Konstruktor(en) gelöst. Wozu habe ich die denn sonst gemacht? Ich hoffe, DarkMo sagt dazu nochmal was. War ja seine Idee und mich würd's rein vom Verständnis her interessieren. :)

BTW: Ich glaube, so, wie's mein Kommentar sagt, wäre der Konstruktor gedacht?! Nur "verwende" ich den dann nicht/falsch?!
 

Supeq

Software-Overclocker(in)
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

RomanNumber roman = new RomanNumber(0);

Da übergibst du doch die 0^^ Deswegen wird Konstruktor eins nicht aufgerufen.

So wie im Kommentar gedacht kannst du den Konstruktor nicht aufrufen weil du versuchst zwei unterschiedliche Situationen in einen Konstruktor zu packen (kein Parameter / Parameter =0).
 
TE
B

boss3D

Guest
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

^^ Oha! Ich habe gedacht dieses "RomanNumber" wäre die Klasse, die ich aufrufe, aber ist natürlich Blödsinn! Hätte der Hausverstand sagen können, dass es sich dabei um ein neues Objekt der (gleichnamigen) Klasse handelt, das eben vom Konstruktor erzeugt wird. *shame on me* :schief:

Dann stellt sich aber die Frage, wie ich explizit angeben kann, dass sich das "römische" "n. a." auf einen dezimalen 0er bezieht. Bzw. auf irgendeinen anderen ungültigen dezimalen Wert, wie z.B. negative Zahlen. ???

[EDIT]
Ok, so geht's scheinbar:
Code:
@Test
    public void testConvertToRomanInvalid() {
        RomanNumber roman = new RomanNumber();
        roman.decimalNum = 0;
        assertEquals("n. a.", roman.convertToRoman());
    }
Aber dann muss das private in der RomanNumber Klasse vor den Konstanten weg. Ist eh kein Problem, oder?

So ganz langsam blicke ich bei den Konstruktoren durch. Der nächste Schritt ist jetzt, es zu schaffen, dass negative integer genauso zu "n. a." führen ...
Aber ich kann mir ja nicht in den Konstruktor ifs reinbasteln?!
 
Zuletzt bearbeitet:

Supeq

Software-Overclocker(in)
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

Ich will dich nicht verwirren, deswegen bleib ich jetzt mal bei deinem Programmierstil :)

Du musst dir bewusst machen, das es zwei Fälle sind die du versuchst abzudecken. Den ersten Fall würde ich so handeln:

Code:
// Konstruktor "Kein Parameter"   
        RomanNumber() {
        return "n. a.";  // alles andere wäre überflüssig
    }

Und wenn ein Wert kleiner eins eingegeben wird, muss die convertToRoman-Methode sich darum kümmern. Dazu könntest du zu Beginn der Methode ein "if(dNum<1){return "n.a.";}" einfügen.
 
TE
B

boss3D

Guest
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

So geht's auch:
Code:
if (value<=1) {
            decimalNum=0;
            return romanNum; // in this case "n. a."
        }
Code:
@Test
    public void testConvertToRomanInvalid() {
        RomanNumber roman = new RomanNumber();
        roman.decimalNum = -1;
        assertEquals("n. a.", roman.convertToRoman());
        assertEquals(0, roman.decimalNum);
    }
Ich probiere jetzt mal die "normalisierte Form". Ich habe da schon eine Idee und witzigerweise erkennt die convertToDecimal Methode immer den richtigen dezimalen int, selbst wenn ein "römischer Blödsinn" eingegeben wird. Da muss ich gar nicht selbst herumraten. Vielleicht lässt sich das schon irgendwie ausnutzen. :)

[EDIT]
Könnte man "geschummelt" nennen, geht aber so:
Code:
@Test
    public void testNormalizedForm() {
        RomanNumber roman = new RomanNumber("IXX");
        assertEquals(19, roman.convertToDecimal());
        roman.decimalNum = roman.convertToDecimal();
        assertEquals("XIX", roman.convertToRoman());
    }
 
Zuletzt bearbeitet:
TE
B

boss3D

Guest
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

[EDIT]
Jetzt stimmt's auch mit den Sonderzeichen:
Code:
[COLOR=royalblue]/**
     * @return calculated decimal value of a specific Roman number
     */[/COLOR]
    public int convertToDecimal() {  
        char lastChar=' ';
        int decimalNum=0;
        int i=0;
        
        [COLOR=seagreen]// Check for invalid symbols in the Roman number string[/COLOR]
        [B]while (i<romanNum.length()) {
            if (romanNum.toUpperCase().charAt(i)!='I' && 
                romanNum.toUpperCase().charAt(i)!='V' &&
                romanNum.toUpperCase().charAt(i)!='X' && 
                romanNum.toUpperCase().charAt(i)!='L' && 
                romanNum.toUpperCase().charAt(i)!='C' && 
                romanNum.toUpperCase().charAt(i)!='D' && 
                romanNum.toUpperCase().charAt(i)!='M') {
                return decimalNum;
            }
            i++;
        }
        i=0;[/B]
                      
        for (i=romanNum.length()-1; i>=0; i--) { [COLOR=seagreen]// begin at the right end of the string (= Roman number)[/COLOR]
            switch (romanNum.toUpperCase().charAt(i)) {[COLOR=seagreen] // check the char on each position[/COLOR]
                case 'I':
                    if (lastChar=='X' || lastChar=='V') {
                        decimalNum-=1;
                    } else {
                        decimalNum+=1;
                    }
                    break;
                case 'V':
                    decimalNum+=5;
                    break;
                case 'X':
                    if (lastChar=='C' || lastChar=='L') {
                        decimalNum-=10;
                    } else {
                        decimalNum+=10;
                    }
                    break;
                case 'L':
                    decimalNum+=50;
                    break;
                case 'C':
                    if (lastChar=='M' || lastChar=='D') {
                        decimalNum-=100;
                    } else {
                        decimalNum+=100;
                    }
                    break;
                case 'D':
                    decimalNum+=500;
                    break;
                case 'M':
                    decimalNum+=1000;
                    break;
                }
                lastChar=romanNum.charAt(i); [COLOR=seagreen]// after each round, make current index of the string to position of last char[/COLOR]
            }

            
        return decimalNum;    
    }
Damit habe ich eh bald alles abgedeckt, was die Aufgabe haben will, oder liest da noch jemand was raus, das mir fehlt?

[EDIT2]
Ok, das fehlt noch:
Wie mit unsinnigen Kombinationen (z. B. LDDCCMD) umgegangen werden soll, soll von euch festgelegt werden (Dokumentation nicht vergessen!).
 
Zuletzt bearbeitet:

DarkMo

Lötkolbengott/-göttin
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

sry war auf arbeit ^^

also in konstruktoren kannst du natürlich auch if's usw verwenden, kein thema. joa, das mit den konstruktoren hat sich ja soweit geklärt... der default konstruktor wäre dann eben ...new RomanNumber(); aber das haste ja auch schon erkannt ^^ hmm, irgendwie bin ich grad matschig in der birne xD
 
TE
B

boss3D

Guest
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

^^ No Probs ... ;)

Ich muss mir nur noch was sinnvolles überlegen, was mit unsinnigen Kombinatione (siehe oben EDIT2) passieren soll. Wenn da wer Ideen hätte, wäre es gut.
Alles andere aus der Aufgabenstellung müsste durch meinen derzeitigen Code bereits abgedeckt sein?! Was nur sein kann, ist, dass ich doch noch eine main reinbasteln muss, die dann Ausgaben von röm --> int und int --> röm macht. Habe diesbezüglich ein mail an die Lehrerin (soviel zu "was er da will" *lol*) geschrieben.
Code:
public class RomanNumber {
    
    String romanNum;
    int decimalNum;
    
   [COLOR=royalblue] /**
     * Constructor
     * used if there's no (valid) representation of a Roman number
     * or it's decimal value is <=0
     */[/COLOR]
    RomanNumber() {
        this.romanNum = "n. a.";
    }
    
    [COLOR=royalblue]/**
     * Constructor
     * used for the decimal representation of a Roman number
     * @param rNum is any Roman number
     */[/COLOR]
    RomanNumber(String rNum) {
        this.romanNum = rNum;
        this.convertToDecimal();
    }
    
   [COLOR=royalblue] /**
     * Constructor
     * used for the Roman representation of a decimal integer
     * @param dNum is any integer number
     */[/COLOR]
    RomanNumber(int dNum) {
        this.decimalNum = dNum;
        this.convertToRoman();
    }
        
   [COLOR=royalblue] /**
     * @return calculated decimal value of a specific Roman number
     */[/COLOR]
    public int convertToDecimal() {  
        char lastChar=' ';
        int decimal=0;
        int i=0;
        
       [COLOR=seagreen] // Check for invalid symbols in the Roman number string[/COLOR]
        while (i<romanNum.length()) {
            if (romanNum.toUpperCase().charAt(i)!='I' && 
                romanNum.toUpperCase().charAt(i)!='V' && 
                romanNum.toUpperCase().charAt(i)!='X' && 
                romanNum.toUpperCase().charAt(i)!='L' &&
                romanNum.toUpperCase().charAt(i)!='C' && 
                romanNum.toUpperCase().charAt(i)!='D' && 
                romanNum.toUpperCase().charAt(i)!='M') {
                return decimal;
            }
            i++;
        }
                      
        for (i=romanNum.length()-1; i>=0; i--) { [COLOR=seagreen]// begin at the right end of the string (= Roman number)[/COLOR]
            switch (romanNum.toUpperCase().charAt(i)) { [COLOR=seagreen]// check the char on each position[/COLOR]
                case 'I':
                    if (lastChar=='X' || lastChar=='V') {
                        decimal-=1;
                    } else {
                        decimal+=1;
                    }
                    break;
                case 'V':
                    decimal+=5;
                    break;
                case 'X':
                    if (lastChar=='C' || lastChar=='L') {
                        decimal-=10;
                    } else {
                        decimal+=10;
                    }
                    break;
                case 'L':
                    decimal+=50;
                    break;
                case 'C':
                    if (lastChar=='M' || lastChar=='D') {
                        decimal-=100;
                    } else {
                        decimal+=100;
                    }
                    break;
                case 'D':
                    decimal+=500;
                    break;
                case 'M':
                    decimal+=1000;
                    break;
                }
                lastChar=romanNum.charAt(i);[COLOR=seagreen] // after each round, make current index of the string to position of last char[/COLOR]
            }
           
        return decimal;    
    }
    
    [COLOR=royalblue]/**
     * @return calculated Roman number of a decimal integer
     */[/COLOR]
    public String convertToRoman() {        
        String roman="";
        int value=decimalNum;
       
        if (value<=1) {
            decimalNum=0;
            return romanNum; [COLOR=seagreen]// in this case "n. a."[/COLOR]
        }

        if (value>=0) {
            while (value/1000 >= 1) { [COLOR=seagreen]// while division by 1000 is possible, do so[/COLOR]
                roman+="M";
                value-=1000;
            }
            if (value/900 >= 1) { [COLOR=seagreen]// if division by 1000 is no longer possible, continue with the next smaller integer[/COLOR]
                roman+="CM";
                value-=900;
            }
            if (value/500 >= 1) {
                roman+="D";
                value = value - 500;
            } 
            if (value/400 >= 1) {
                roman+="CD";
                value-=400;
            }
            while (value/100 >= 1) { [COLOR=seagreen]// while division by 100 is possible, do so[/COLOR]
                roman+="C";
                value-=100;
            }
            if (value/90 >= 1) { [COLOR=seagreen]// if division by 100 is no longer possible, continue with the next smaller integer[/COLOR]
                roman+="XC";
                value-=90;
            }
            if (value/50 >= 1) {
                roman+="L";
                value-=50;
            }
            if (value/40 >= 1) {
                roman+="XL";
                value-=40;
            }
            while (value/10 >= 1) { [COLOR=seagreen]// while division by 10 is possible, do so[/COLOR]
                roman+="X";
                value-=10;
            }
            if (value/9 >= 1) { [COLOR=seagreen]// if division by 10 is no longer possible, continue with the next smaller integer[/COLOR]
                roman+="IX";
                value-=9;
            }
            if (value/5 >= 1) {
                roman+="V";
                value-=5;
            }
            if (value/4 >= 1) {
                roman+="IV";
                value-=4;
            }
            while (value >= 1) {
                roman+="I";
                value-=1;
            }
        }
        
        return roman;
    }

}
Vorerst mache ich jetzt mal beim zweiten Bsp. (nicht auf der Angabe in Posting #1 zu sehen) weiter. Wenn da fragen kommen, poste ich die ebenfalls ...

Danke schon mal soweit!
------------

[EDIT]
Jetzt zu Bsp 2:

Capture.JPG

^^ Also, es geht darum, dass ich einen fehlerhaften/unvollständigen Code zu einer Wetterstation bekommen habe und den gemäß der Angabe korrigieren/erweitern soll.

Hier der fehlerhafte/unvollständige Code:
Code:
public class weather_station {

    static final int NUMBER_OF_READINGS = 3;
    static final int MAX_NUMBER_OF_STATIONS = 5;

    static weather_station[] stations = new weather_station[MAX_NUMBER_OF_STATIONS];
    static int stationCounter = 0;

    static float overallMinTemperature;
    static String overallMinTemperatureLocation;
    
    static float overallMaxTemperature;
    static String overallMaxTemperatureLocation;
    
    static float maxTotalRainfall;
    static String maxTotalRainfallLocation;

    final String location;

    float minTemperature, maxTemperature;

    float totalRainfall = 0;

    reading[] readings = new reading[NUMBER_OF_READINGS];
    int indexOfNextReading = 0;
    int indexOfLastReading;

    public weather_station(String location) {
        this.location = location;
        while (stationCounter < MAX_NUMBER_OF_STATIONS) {
            stations[stationCounter++] = this;
        }
    }

    void addReading(reading r) {
        readings[indexOfNextReading] = r;
        updateStatistics(r);
        indexOfLastReading = indexOfNextReading;
        indexOfNextReading = ++indexOfNextReading % 3;
    }

    void updateStatistics(reading r) {
        updateMinTemperature(r);
        updateMaxTemparature(r);
        updateRainfall(r);
        UpdateOverallRainfallStatistics(totalRainfall, location);
        UpdateOverallStatistics(r, location);
    }

    void updateRainfall(reading r) {
        totalRainfall += r.rainfall;
    }

    void updateMaxTemparature(reading r) {
        if (r.temperature > maxTemperature) {
            maxTemperature = r.temperature;
        }
    }

    void updateMinTemperature(reading r) {
        if (r.temperature < minTemperature) {
            minTemperature = r.temperature;
        }
    }

    void showMinTemperature() {
        System.out.println("Lowest Temperature: " + minTemperature + " Degree Celsius");
    }

    void showMaxTemperature() {
        System.out.println("Highest Temperature: " + maxTemperature + " Degree Celsius");
    }

    void showLatestReadings() {
        System.out.println("Latest Readings for " + location);
        for (int i = 0; i < readings.length; i++) {
            if (readings[i] != null) {
            System.out.println(readings[i].toString());
            }
        }
    }
    
    void reset() {
        readings = new reading[NUMBER_OF_READINGS];
        minTemperature = 0;
        maxTemperature = 0;
        totalRainfall = 0;
    }

    static void UpdateOverallStatistics(reading r, String location) {
        if (r.temperature < overallMinTemperature) {
            overallMinTemperature = r.temperature;
            overallMinTemperatureLocation = location;
        }
        if (r.temperature > overallMinTemperature) {
            overallMaxTemperature = r.temperature;
            overallMaxTemperatureLocation = location;
        }
    }

    static void UpdateOverallRainfallStatistics(float totalRainfall, String location) {
        if (totalRainfall > maxTotalRainfall) {
            maxTotalRainfall = totalRainfall;
            maxTotalRainfallLocation = location;
        }
    }

    static void showOverallMinTemperature() {
        System.out.println("Lowest Temperature: " + overallMinTemperature + " Degree Celsius in " + overallMinTemperatureLocation);
    }

    static void showOverallMaxTemperature() {
        System.out.println("Highest Temperature: " + overallMaxTemperature + " Degree Celsius in " + overallMaxTemperatureLocation);
    }

    static void showMaxTotalRainfall() {
        System.out.println("Max Amount of Rainfall: " + maxTotalRainfall + " ml in " + maxTotalRainfallLocation);
    }

    static void resetStations() {
        overallMaxTemperature = 0;
        overallMinTemperature = 0;
        maxTotalRainfall = 0;
        for (int i = 0; i < stationCounter; i++) {
            stations[i].reset();
        }
    }

}
Code:
import static org.junit.Assert.assertEquals;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class weather_station_test {

    weather_station linz;
    weather_station wels;
    weather_station hagenberg;
    weather_station steyr;

    @Before
    public void setUp() throws Exception {
        linz = new weather_station("Linz");
        wels = new weather_station("Wels");
        hagenberg = new weather_station("Hagenberg");
        steyr = new weather_station("Steyr");

        linz.addReading(new reading(14, 0));
        linz.addReading(new reading(16, 34));

        wels.addReading(new reading(10, 2));
        wels.addReading(new reading(-8, 3));

        hagenberg.addReading(new reading(-20, 0));
        hagenberg.addReading(new reading(0, 0));

        steyr.addReading(new reading(23, 23));
        steyr.addReading(new reading(21, 3213));
    }

    @After
    public void tearDown() throws Exception {
        weather_station.resetStations();
    }

    @Test
    public void testLinz() {
        assertEquals(14, linz.minTemperature, 0.000001);
        assertEquals(16, linz.maxTemperature, 0.000001);
        assertEquals(34, linz.totalRainfall, 0.000001);
    }

    @Test
    public void testWels() {
        assertEquals(-8, wels.minTemperature, 0.000001);
        assertEquals(10, wels.maxTemperature, 0.000001);
        assertEquals(5, wels.totalRainfall, 0.000001);
    }

    @Test
    public void testHagenberg() {
        assertEquals(-20, hagenberg.minTemperature, 0.000001);
        assertEquals(0, hagenberg.maxTemperature, 0.000001);
        assertEquals(0, hagenberg.totalRainfall, 0.000001);
    }

    @Test
    public void testSteyr() {
        assertEquals(21, steyr.minTemperature, 0.000001);
        assertEquals(23, steyr.maxTemperature, 0.000001);
        assertEquals(3213, steyr.totalRainfall, 0.000001);
    }

    @Test
    public void testStatistics() {
        assertEquals(-20, weather_station.overallMinTemperature, 0.000001);
        assertEquals("Hagenberg", weather_station.overallMinTemperatureLocation);
        assertEquals(23, weather_station.overallMaxTemperature, 0.000001);
        assertEquals("Styer", weather_station.overallMaxTemperatureLocation);
        assertEquals(3213, weather_station.maxTotalRainfall, 0.000001);
        assertEquals("Steyr", weather_station.maxTotalRainfallLocation);
    }
}
Code:
public class reading {
    float temperature;
    float rainfall;

    public reading(float temperature, float rainfall) {
        this.temperature = temperature;
        this.rainfall = rainfall;
    }

    @Override
    public String toString() {
        return temperature + " Degree Celsius, rainfall: " + rainfall + " mm";
    }

}
Und hier die Codes, soweit ich sie schon korrigiert/erweitert habe
Code:
public class weather_station {

    static final int DEFAULT_MAXIMUM_TEMPERATURE = -273;
    static final int DEFAULT_MINIMUM_TEMPERATURE = 100;
    static final int NUMBER_OF_READINGS = 3;
    static final int MAX_NUMBER_OF_STATIONS = 5;

    static weather_station[] stations = new weather_station[MAX_NUMBER_OF_STATIONS];
    static int stationCounter = 0;

    static float overallMinTemperature;
    static String overallMinTemperatureLocation;

    static float overallMaxTemperature;
    static String overallMaxTemperatureLocation;

    static float maxTotalRainfall;
    static String maxTotalRainfallLocation;

    final String location;

    float minTemperature = DEFAULT_MINIMUM_TEMPERATURE;
    float maxTemperature = DEFAULT_MAXIMUM_TEMPERATURE;

    float totalRainfall = 0;

    reading[] readings = new reading[NUMBER_OF_READINGS];
    int indexOfNextReading = 0;
    int indexOfLastReading;

    public weather_station(String location) {
        this.location = location;
        while (stationCounter < MAX_NUMBER_OF_STATIONS) {
            stations[stationCounter++] = this;
        }
    }

    void addReading(reading r) {
        readings[indexOfNextReading] = r;
        updateStatistics(r);
        indexOfLastReading = indexOfNextReading;
        indexOfNextReading = ++indexOfNextReading % 3;
    }

    void updateStatistics(reading r) {
        updateMinTemperature(r);
        updateMaxTemparature(r);
        updateRainfall(r);
        UpdateOverallRainfallStatistics(this.totalRainfall, this.location);
        UpdateOverallStatistics(r, this.location);
    }

    void updateRainfall(reading r) {
        totalRainfall += r.rainfall;
    }

    void updateMaxTemparature(reading r) {
        if (r.temperature > maxTemperature) {
            this.maxTemperature = r.temperature;
        }
    }

    void updateMinTemperature(reading r) {
        if (r.temperature < minTemperature) {
            this.minTemperature = r.temperature;
        }
    }

    void showMinTemperature() {
        System.out.println("Lowest Temperature: " + minTemperature + " Degree Celsius");
    }

    void showMaxTemperature() {
        System.out.println("Highest Temperature: " + maxTemperature + " Degree Celsius");
    }

    void showLatestReadings() {
        System.out.println("Latest Readings for " + this.location);
        for (int i = 0; i < readings.length; i++) {
            if (readings[i] != null) {
                System.out.println(readings[i].toString());
            }
        }
    }

    void reset() {
        readings = new reading[NUMBER_OF_READINGS];
        minTemperature = 100;
        maxTemperature = DEFAULT_MAXIMUM_TEMPERATURE;
        totalRainfall = 0;
    }

    static void UpdateOverallStatistics(reading r, String location) {
        if (r.temperature < overallMinTemperature) {
            overallMinTemperature = r.temperature;
            overallMinTemperatureLocation = location;
        }
        if (r.temperature > overallMaxTemperature) {
            overallMaxTemperature = r.temperature;
            overallMaxTemperatureLocation = location;
        }
    }

    static void UpdateOverallRainfallStatistics(float totalRainfall, String location) {
        if (totalRainfall > maxTotalRainfall) {
            maxTotalRainfall = totalRainfall;
            maxTotalRainfallLocation = location;
        }
    }

    static void showOverallMinTemperature() {
        System.out.println("Lowest Temperature: " + overallMinTemperature + " Degree Celsius in " + overallMinTemperatureLocation);
    }

    static void showOverallMaxTemperature() {
        System.out.println("Highest Temperature: " + overallMaxTemperature + " Degree Celsius in " + overallMaxTemperatureLocation);
    }

    static void showMaxTotalRainfall() {
        System.out.println("Max Amount of Rainfall: " + maxTotalRainfall + " ml in " + maxTotalRainfallLocation);
    }

    static void resetStations() {
        overallMaxTemperature = DEFAULT_MAXIMUM_TEMPERATURE;
        overallMinTemperature = null;
        maxTotalRainfall = DEFAULT_MINIMUM_TEMPERATURE;
        overallMinTemperatureLocation = null;
        maxTotalRainfall = 0;
        maxTotalRainfallLocation = null;
        for (int i = 0; i < stationCounter; i++) {
            stations[i].reset();
        }
    }

}
Code:
import static org.junit.Assert.assertEquals;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class weather_station_test {

    weather_station linz = new weather_station("Linz");
    weather_station wels = new weather_station("Wels");
    weather_station hagenberg = new weather_station("Hagenberg");
    weather_station steyr = new weather_station("Steyr");

    @Before
    public void setUp() throws Exception {
        linz = new weather_station("Linz");
        wels = new weather_station("Wels");
        hagenberg = new weather_station("Hagenberg");
        steyr = new weather_station("Steyr");
    
        linz.addReading(new reading(14, 0));
        linz.addReading(new reading(16, 34));
        
        linz.showLatestReadings();
        linz.showMaxTemperature();
        linz.showMinTemperature();
    
        wels.addReading(new reading(10, 2));
        wels.addReading(new reading(-8, 3));
        
        wels.showLatestReadings();
        wels.showMaxTemperature();
        wels.showMinTemperature();
    
        hagenberg.addReading(new reading(-20, 0));
        hagenberg.addReading(new reading(0, 0));
        
        hagenberg.showLatestReadings();
        hagenberg.showMaxTemperature();
        hagenberg.showMinTemperature();
    
        steyr.addReading(new reading(23, 23));
        steyr.addReading(new reading(21, 3213));
        
        steyr.showLatestReadings();
        steyr.showMaxTemperature();
        steyr.showMinTemperature();
        
        WeatherStation.showOverallMinTemperature();
        WeatherStation.showOverallMaxTemperature();
        WeatherStation.showMaxTotalRainfall();
        
        WeatherStation.resetStations();
        WeatherStation.showOverallMinTemperature();
        WeatherStation.showOverallMaxTemperature();
        WeatherStation.showMaxTotalRainfall();
    }

    @After
    public void tearDown() throws Exception {
        weather_station.resetStations();
    }

    @Test
    public void testLinz() {
        assertEquals(14, linz.minTemperature, 0.000001);
        assertEquals(16, linz.maxTemperature, 0.000001);
        assertEquals(34, linz.totalRainfall, 0.000001);
    }

    @Test
    public void testWels() {
        assertEquals(-8, wels.minTemperature, 0.000001);
        assertEquals(10, wels.maxTemperature, 0.000001);
        assertEquals(5, wels.totalRainfall, 0.000001);
    }

    @Test
    public void testHagenberg() {
        assertEquals(-20, hagenberg.minTemperature, 0.000001);
        assertEquals(0, hagenberg.maxTemperature, 0.000001);
        assertEquals(0, hagenberg.totalRainfall, 0.000001);
    }

    @Test
    public void testSteyr() {
        assertEquals(21, steyr.minTemperature, 0.000001);
        assertEquals(23, steyr.maxTemperature, 0.000001);
        assertEquals(3213, steyr.totalRainfall, 0.000001);
    }

    @Test
    public void testStatistics() {
        assertEquals(-20, weather_station.overallMinTemperature, 0.000001);
        assertEquals("Hagenberg", weather_station.overallMinTemperatureLocation);
        assertEquals(23, weather_station.overallMaxTemperature, 0.000001);
        assertEquals("Styer", weather_station.overallMaxTemperatureLocation);
        assertEquals(3213, weather_station.maxTotalRainfall, 0.000001);
        assertEquals("Steyr", weather_station.maxTotalRainfallLocation);
    }
}
Code:
public class reading {
    float temperature; 
    float rainfall; 
    
    public reading(float temperature, float rainfall) {
        this.temperature = temperature;
        this.rainfall = rainfall;
    }

    @Override
    public String toString() {
        return temperature + " Degree Celsius, rainfall: " + rainfall + " mm";
    }

}
^^ Eigentlich scheitert's eh nur noch an der Korrektur der TestKlasse. Alles andere müsste schon soweit passen?!

Am besten/leichtesten wäre es, wenn sich jemand die Codes ins Eclipse kopieren könnte, damit man auch die Fehlermeldungen angezeigt bekommt. So wird's wahrscheinlich schwierig, diese zu sehen ...
 
Zuletzt bearbeitet:
TE
B

boss3D

Guest
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

So, habe jetzt auch im 2er Bsp nahezu alle Fehler ausbessern können. Die Codes sehen jetzt so aus:
Code:
public class weather_station {

    static final int DEFAULT_MAXIMUM_TEMPERATURE = -273;
    static final int DEFAULT_MINIMUM_TEMPERATURE = 100;
    static final int NUMBER_OF_READINGS = 3;
    static final int MAX_NUMBER_OF_STATIONS = 5;

    static weather_station[] stations = new weather_station[MAX_NUMBER_OF_STATIONS];
    static int stationCounter = 0;

    static float overallMinTemperature;
    static String overallMinTemperatureLocation;
    
    static float overallMaxTemperature;
    static String overallMaxTemperatureLocation;
    
    static float maxTotalRainfall;
    static String maxTotalRainfallLocation;

    final String location;

    float minTemperature = DEFAULT_MINIMUM_TEMPERATURE;
    float maxTemperature = DEFAULT_MAXIMUM_TEMPERATURE;

    float totalRainfall = 0;

    reading[] readings = new reading[NUMBER_OF_READINGS];
    int indexOfNextReading = 0;
    int indexOfLastReading;

    public weather_station(String location) {
        this.location = location;
        while (stationCounter < MAX_NUMBER_OF_STATIONS) {
            stations[stationCounter++] = this;
        }
    }

    void addReading(reading r) {
        readings[indexOfNextReading] = r;
        updateStatistics(r);
        indexOfLastReading = indexOfNextReading;
        indexOfNextReading = ++indexOfNextReading % 3;
    }

    void updateStatistics(reading r) {
        updateMinTemperature(r);
        updateMaxTemparature(r);
        updateRainfall(r);
        UpdateOverallRainfallStatistics(this.totalRainfall, this.location);
        UpdateOverallStatistics(r, this.location);
    }

    void updateRainfall(reading r) {
        totalRainfall += r.rainfall;
    }

    void updateMaxTemparature(reading r) {
        if (r.temperature > maxTemperature) {
            this.maxTemperature = r.temperature;
        }
    }

    void updateMinTemperature(reading r) {
        if (r.temperature < minTemperature) {
            this.minTemperature = r.temperature;
        }
    }

    void showMinTemperature() {
        System.out.println("Lowest Temperature: " + minTemperature + " Degree Celsius");
    }

    void showMaxTemperature() {
        System.out.println("Highest Temperature: " + maxTemperature + " Degree Celsius");
    }
 
    void showLatestReadings() {
        System.out.println("Latest Readings for " + this.location);
        for (int i = 0; i < readings.length; i++) {
            if (readings[i] != null) {
                System.out.println(readings[i].toString());
            }
        }
    }

    void reset() {
        readings = new reading[NUMBER_OF_READINGS];
        minTemperature = DEFAULT_MINIMUM_TEMPERATURE;
        maxTemperature = DEFAULT_MAXIMUM_TEMPERATURE;
        totalRainfall = 0;
    }

    static void UpdateOverallStatistics(reading r, String location) {
        if (r.temperature < overallMinTemperature) {
            overallMinTemperature = r.temperature;
            overallMinTemperatureLocation = location;
        }
        if (r.temperature > overallMaxTemperature) {
            overallMaxTemperature = r.temperature;
            overallMaxTemperatureLocation = location;
        }
    }

    static void UpdateOverallRainfallStatistics(float totalRainfall, String location) {
        if (totalRainfall > maxTotalRainfall) {
            maxTotalRainfall = totalRainfall;
            maxTotalRainfallLocation = location;
        }
    }

    static void showOverallMinTemperature() {
        System.out.println("Lowest Temperature: " + overallMinTemperature + " Degree Celsius in " + overallMinTemperatureLocation);
    }

    static void showOverallMaxTemperature() {
        System.out.println("Highest Temperature: " + overallMaxTemperature + " Degree Celsius in " + overallMaxTemperatureLocation);
    }

    static void showMaxTotalRainfall() {
        System.out.println("Max Amount of Rainfall: " + maxTotalRainfall + " mm in " + maxTotalRainfallLocation);
    }

    static void resetStations() {
        overallMaxTemperature = DEFAULT_MAXIMUM_TEMPERATURE;
        overallMaxTemperatureLocation = null;
        overallMinTemperature = DEFAULT_MINIMUM_TEMPERATURE;
        overallMinTemperatureLocation = null;
        maxTotalRainfall = 0;
        maxTotalRainfallLocation = null;
        for (int i = 0; i < stationCounter; i++) {
            stations[i].reset();
        }
    }

}
Code:
import static org.junit.Assert.assertEquals;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class weather_station_test {

    weather_station linz = new weather_station("Linz");
    weather_station wels = new weather_station("Wels");
    weather_station hagenberg = new weather_station("Hagenberg");
    weather_station steyr = new weather_station("Steyr");

    @Before
    public void setUp() throws Exception {
        linz = new weather_station("Linz");
        wels = new weather_station("Wels");
        hagenberg = new weather_station("Hagenberg");
        steyr = new weather_station("Steyr");
    
        linz.addReading(new reading(14, 0));
        linz.addReading(new reading(16, 34));
        
        linz.showLatestReadings();
        linz.showMaxTemperature();
        linz.showMinTemperature();
    
        wels.addReading(new reading(10, 2));
        wels.addReading(new reading(-8, 3));
        
        wels.showLatestReadings();
        wels.showMaxTemperature();
        wels.showMinTemperature();
    
        hagenberg.addReading(new reading(-20, 0));
        hagenberg.addReading(new reading(0, 0));
        
        hagenberg.showLatestReadings();
        hagenberg.showMaxTemperature();
        hagenberg.showMinTemperature();
    
        steyr.addReading(new reading(23, 23));
        steyr.addReading(new reading(21, 3213));
        
        steyr.showLatestReadings();
        steyr.showMaxTemperature();
        steyr.showMinTemperature();
        
        weather_station.showOverallMinTemperature();
        weather_station.showOverallMaxTemperature();
        weather_station.showMaxTotalRainfall();        
        weather_station.resetStations();
    }

    @After
    public void tearDown() throws Exception {
        weather_station.resetStations();
    }

    @Test
    public void testLinz() {
        assertEquals(14, linz.minTemperature, 0.000001);
        assertEquals(16, linz.maxTemperature, 0.000001);
        assertEquals(34, linz.totalRainfall, 0.000001);
    }

    @Test
    public void testWels() {
        assertEquals(-8, wels.minTemperature, 0.000001);
        assertEquals(10, wels.maxTemperature, 0.000001);
        assertEquals(5, wels.totalRainfall, 0.000001);
    }

    @Test
    public void testHagenberg() {
        assertEquals(-20, hagenberg.minTemperature, 0.000001);
        assertEquals(0, hagenberg.maxTemperature, 0.000001);
        assertEquals(0, hagenberg.totalRainfall, 0.000001);
    }

    @Test
    public void testSteyr() {
        assertEquals(21, steyr.minTemperature, 0.000001);
        assertEquals(23, steyr.maxTemperature, 0.000001);
        [COLOR=red][B]assertEquals(3213, steyr.totalRainfall, 0.000001);[/B][/COLOR]
    }

    @Test
    public void testStatistics() {
       [COLOR=red][B] assertEquals(-20, weather_station.overallMinTemperature, 0.000001);[/B][/COLOR]
        assertEquals("Hagenberg", weather_station.overallMinTemperatureLocation);
        assertEquals(23, weather_station.overallMaxTemperature, 0.000001);
        assertEquals("Styer", weather_station.overallMaxTemperatureLocation);
        assertEquals(3213, weather_station.maxTotalRainfall, 0.000001);
        assertEquals("Steyr", weather_station.maxTotalRainfallLocation);
    }
    
}
Code:
public class reading {
    float temperature; 
    float rainfall; 
    
    public reading(float temperature, float rainfall) {
        this.temperature = temperature;
        this.rainfall = rainfall;
    }

    @Override
    public String toString() {
        return temperature + " Degree Celsius, rainfall: " + rainfall + " mm";
    }

}
^^ Nur die beiden rot markierten Zeilem im zweiten Code-Teil liefern noch Failures im TestCase.
1. rote Zeile: java.lang.AssertionError: expected:<3213.0> but was:<3236.0>
2. rote Zeile: java.lang.AssertionError: expected:<-20.0> but was:<100.0>

Wenn mir jemand helfen könnte, noch die beiden Kleinigkeiten auszubessern, wäre es super! :)
Ist das 3213 auch nur ein Fehler, den ich ausbessern muss? Wo kommt denn das überhaupt her? Ich sehe nicht, wo dieser Wert berechnet wird.

Dann hätte ich nur noch ein paar Verständnisfragen zu den Codes ...
 
Zuletzt bearbeitet:
TE
B

boss3D

Guest
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

So, hier ...
 

DarkMo

Lötkolbengott/-göttin
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

hehe, hatte dir grad eben scho wieder geschrieben, dass ichs mittlerweile hinbekommen hatte.
 
TE
B

boss3D

Guest
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

Hi, DarkMo!

Ich hätte ein neues Beispiel, wenn du Lust hast ... :)

Diesmal geht's um eine ArrayList. Kannst dir gerne mal das Archiv aus dem Anhang runterladen (siehe Link unten). Das Grundgerüst habe ich bereits zusammengebastelt. Jetzt hänge ich bei der Implementierung von ein paar Methoden.
Als erstes müsste ich mal wissen, was genau in Zeile 62 und 63 in der Klasse ArrayList nicht passt: Darf ich da wirklich einfach einen TypCast auf die Klasse selbst machen, wie's die Autokorrektur von Eclipse vorschlägt?

Dann: Was genau soll das Interface Element darstellen? Und was ist der int key, der in manchen Methoden der anderen Interfaces vorkommt? Einen Index gäb's ja auch, also wird key nicht der Index sein.

Und wie kann ich mir die ArrayList überhaupt vorstellenb? Es ist ja nicht ein einzelnes Array. Ist es ein Array mit Arrays als Elementen? Lat google Suche gäb's auch von Java aus schon jede Menge fertige Methoden, aber so wie's aussieht, kann ich die nicht nutzen und muss mir laut Angabe alles selbst implementieren?!

Falls du ein paar Tipps dazu hast, danke im Voraus! ;)

[EDIT]
So, hab's noch ein Bisschen erweitert. Allerdings weiß ich nicht, wie viel Sinn das macht, fertige Java Methoden in (gleichnamige) eigene Methoden (die ich allerdings wegen der Interfaces so verwenden muss) zu packen ... :ugly:

[EDIT2]
Anhang anzeigen DoubleLinkedList.zip
Anhang anzeigen ArrayList.zip

[EDIT3]
Anhang anzeigen Checksum.7z

[EDIT4]
Neues Beispiel ...
Anhang anzeigen Vereinsverwaltung.7z
 
Zuletzt bearbeitet:
TE
B

boss3D

Guest
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

Ich hätte mal wieder eine Aufgabe, bei der ich Hilfe gebrauchen könnte ...

Folgende Angabe:

Capture.JPG

Und folgende Fragen habe ich dazu:

- In Klasse ChairMember: Macht das was, dass fee als nicht initialisiert (von Eclipse) angezeigt wird? Im Konstruktor bekommt's ja dann eh einen Wert zugewiesen.
- In Klasse Section: Selbe Frage, nur hier für overallIncome und overallCosts ... ?
- In Klasse Section: Kann ich eine Variable in einem Konstruktor durch Aufsummieren in einer Schleife initialisieren, oder sollte ich besser eine andere "Hilfsvariable" aufsummieren lassen und dann z.B. sagen: this.overallIncome = hilfsvariable; ?
- In Klasse Section: Wie setze ich das um, dass eine Sektion andere Sektionen beinhalten kann?
- Wieso liefern meine beiden bisher erstellten Testklassen nicht true?

Danke für hilfreiche Antworten! :)
 
Zuletzt bearbeitet:

Anubis12334

Komplett-PC-Aufrüster(in)
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

In der Klasse Member sind die Modifizierer falsch. Schau dir das nochmal an.

In der Klasse Sektion, stimmt die Berechnung der Kosten?

Damit eine Sektion andere Sektions enthälst schreibst du:

private ArrayList<Section> sections;

und dann:
im Konstruktor:
sections = new ArrayList<Section>();

hinzufügen:

public void AddSection(Section section){
sections.Add(section);
}



Die Testklasse sieht so besser aus (imho):

@Test
public void test() {
String testString = "Name: Hans Mueller | Income: 0 | Costs: 0 | Surplus: 0";
assertEquals(true, testString.equals(one.toString()));
}

Vergleich doch mal per Debugger oder Ausgabe die beiden Strings (System.out.println(one.toString()), dann kommst du sicher selber drauf.

---
Ach und rein logisch. Negative Kosten sind doch eigentlich Einnahmen!
 
Zuletzt bearbeitet:
TE
B

boss3D

Guest
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

In der Klasse Member sind die Modifizierer falsch. Schau dir das nochmal an.
In der Angabe heißt's: "Alle Mitglieder (Klasse Member) haben einen Namen und eine eindeutige Mitgliedsnummer, die durch das System beim Anlegen eines Mitglieds automatisch und unveränderbar vergeben wird."
Ich nehme daher an, du meinst, dass ich die Datenfelder von public zu private ändern sollte?! Das final müsste schon stimmen?! Wenn ich die Datenfelder allerdings auf private setze, können sie in den Subklassen nicht mehr verwendet werden. Da will ich aber drauf zugreifen. Bei den Methoden sehe ich jetzt auch keinen Fehler. Ein Konstruktor muss public sein, oder ich kann kein Objekt der Klasse erzeugen ...
In der Klasse Sektion, stimmt die Berechnung der Kosten?
Es geht ja darum, den Gesamtgewinn und Gesamtverlust durch alle Mitglieder der Sektion zu bestimmen. Alle Mitglieder stecken bei mir im Feld Member[] section. Daher habe ich mir gedacht, ich muss das Feld in einer Schleife durchlaufen und für jedes Mitglied, das dabei erwischt wird, den Gewinn und den Verlust in den entsprechenden Variablen dazuaddieren?!

Ich bin mir allerdings nicht sicher, ob ich in mein Feld Mitglieder unterschiedlicher Typen (z.B. TopAthlete, AmateurAthlete, etc.) reinpacken kann, die ja alle unterschiedliche Kosten und Gewinne verursachen. Und ich weiß auch nicht, ob ich in der Schleife direkt in this.overallIncome und this.overallCosts aufsummieren kann, oder ob ich das lieber in einer einfachen double Variable tun und dann nach der Schleife sagen sollte: this.overallIncome = variable1; this.overallCosts = variable2; ... ?
Damit eine Sektion andere Sektions enthälst schreibst du:

private ArrayList<Section> sections;

und dann:
im Konstruktor:
sections = new ArrayList<Section>();

hinzufügen:

public void AddSection(Section section){
sections.Add(section);
}
Ok, danke.
Die Testklasse sieht so besser aus (imho):

@Test
public void test() {
String testString = "Name: Hans Mueller | Income: 0 | Costs: 0 | Surplus: 0";
assertEquals(true, testString.equals(one.toString()));
}

Vergleich doch mal per Debugger oder Ausgabe die beiden Strings (System.out.println(one.toString()), dann kommst du sicher selber drauf.
Aua ... :fresse: Ja, hab's gesehen. Die MemberTest Klasse stimmt jetzt, aber in der SupportMemberTest Klasse will er für surplus 0.0 und ich aber 85.0 (100 € Gewinn - 15 € Kosten).

In meiner Klasse SupportMember habe ich zwar im Konstruktor nur this.income und this.costs angegeben, aber this.surplus müsste ja durch den super() Aufruf aus dem Konstruktor der Member Klasse kommen?! :huh:
Ach und rein logisch. Negative Kosten sind doch eigentlich Einnahmen!
Es gibt keine negativen Kosten, das war ein Fehler von mir. Auch bei der Kostenermittlung muss ich += sagen ... ;)
 
Zuletzt bearbeitet:

Anubis12334

Komplett-PC-Aufrüster(in)
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

ich verstehe den Sinn von private Settern&Gettern und public Attributen nicht.
 
TE
B

boss3D

Guest
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

Die Datenfelder aus der Member Klasse will ich ja auch in den Subklassen wie z. B. SupportMember benutzen können. Insofern müssen die public sein. Die Getter kann ich private machen, weil die anderen Klassen nur auf den Konstruktor von Member zugreifen und dieser bekommt von den privaten Gettern die nötigen Daten. Hätte ich income, costs und surplus nicht im Konstruktor, dann müsste ich die Getter public machen, damit auch die Subklassen darauf zugreifen können ...

^^ Soweit meine Logik. Kann man sicher disktuieren, ob's nicht anders schlauer wäre.

Auf jeden Fall bleiben meine Fragen aus dem vorigen Posting, falls da jemand Antworten hat!
 
TE
B

boss3D

Guest
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

So, hab's jetzt hingekriegt, dass alles läuft. Für surplus musste ich nur den entsprechenden Getter aufrufen anstatt dem Datenfeld selbst. Ich konnte auch noch ein Bisschen sinnlosen Code löschen, sodass das ganze jetzt kompakter aussieht. :)

Das einzige, was mir jetzt noch fehlt, ist die TestKlasse für Section; da hänge ich gerade:
Code:
import static org.junit.Assert.assertEquals;

import org.junit.Test;


public class SectionTest {

    Section sectionOne = new Section();
    
    @Test
    public void test() {
        
    }

}
Die Klasse Section müsste stimmen?! Was mich nur verwirrt, ist, dass ich den super() Aufruf brauche um an den Member Konstruktor zu kommen. Klar, das Member[] section Array, das die Mitglieder enthält, braucht Namen und IDs, aber die Sektion selbst doch nicht?! Wie löse ich das geschickter? :huh:
Code:
import java.util.ArrayList;


public class Section extends Member {

    private final int size; // Größe des Sektions-Arrays
    private int allocation; // aktuelle Belegung mit Mitgliedern
    private Member[] section;
    private double overallIncome;
    private double overallCosts;
    private ArrayList<Section> sections;
    
    public Section(String firstName, String lastName, int ID, int size) {
        super(firstName, lastName, ID);
        this.size = size;
        this.allocation = 0;
        this.section = new Member[this.size];
        for (int i = 0; i < section.length; i++) {
            this.overallIncome += this.section[i].income;
            this.overallCosts += this.section[i].costs;
        }
        this.sections = new ArrayList<Section>();
    }

    public void addMember(Member m) {
        if (this.allocation < this.size) {
            this.section[this.allocation] = m;
            this.allocation++;
        } else {
            System.out.println("Member can't be added! Section already full.");
        }
    }
    
    public void AddSection(Section section) {
        if (this.allocation < this.size) {
            this.sections.add(section);
            this.allocation++;
        } else {
            System.out.println("Sub-Section can't be added! Section already full.");
        }
    }
}
Member:
Code:
public class Member {
    
    public final String firstName;
    public final String lastName;
    public final int ID;
    public double income;
    public double costs;
    public double surplus;
    
    public Member(String firstName, String lastName, int ID) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.ID = ID;
        this.income = this.getIncome();
        this.costs = this.getCosts();
        this.surplus = this.getSurplus();
    }
    
    public double getIncome() {        
        return this.income;        
    }
    
    public double getCosts() {        
        return this.costs;
    }
    
    public double getSurplus() {        
        return this.getIncome()-this.getCosts();
    }
    
    public String toString() {
        String result = new String();
        result = "Name: " + this.firstName + " " + this.lastName + " | Income: " + this.getIncome() + " | Costs: " + this.getCosts() + " | Surplus: " + this.getSurplus();
        return result;        
    }
Die Getter in Klasse Member habe ich jetzt auf public gesetzt, weil man Getter wirklich immer public sieht, aber funktionieren würd's auch mit private. Was also wirklich machen?

Sollte ich z. B. in Klasse SupportMember wieder 2 Datenfelder income und costs anlegen und auf diese über die public Getter der Klasse Member zugreifen? Dafür könnte ich dann die Datenfelder von Member auf private setzen ...
 

DarkMo

Lötkolbengott/-göttin
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

getter und setter sind freilich immer public ^^ sie sollen ja eben überhaupt erstmal den zugriff auf private-variablen geben. wenn die nun selbst private sind... :ugly:

variablen sollten halt möglichst immer private sein, damit man von aussen nicht unkontrolliert drauf zugreifen kann. diesen kontrollierten zugriff ermöglichen dann die setter. puh, als bsp mal *grübel* gute frage auf anhieb. bezieht sich eben meist auf zusammenhänge zwischen den variablen. also wenn man variable A verändert, zieht das änderungen an weiteren variablen nach sich, damit die interne logik stimmt. hmm, vllt als bsp deine array list klasse da. added man ein element ist das ja auch entfernt sone art setter methode. da hatten wir dann die size mit angepasst, ggf das array erweitert usw usf. würde man hier einfach stumpf von aussen auf die daten-variable an sich zugreifen, zerhaut man sich die ganze interne logik. daher is der krams möglichst private und per public zugriffs methoden erreichbar.
 
TE
B

boss3D

Guest
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

^^ Soweit habe ich das schon überprüft, dass mir ein Zugriff auf public Variablen nichts ruiniert. Das doofe ist halt, dass ich dann in mind. 4 Klassen die selben private Variablen anlegen müsste, um mit den public Gettern aus Member Werte zuweisen bzw. abholen zu können. Oder lässt sich das durch die Vererbung, die ja bei mir gegeben ist, geschickter lösen?

Also Member so:
Code:
public class Member {
    
    private final String firstName;
    private final String lastName;
    private final int ID;
    private double income;
    private double costs;
    
    public Member(String firstName, String lastName, int ID) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.ID = ID;
        this.income = this.getIncome();
        this.costs = this.getCosts();
        this.getSurplus();
    }
    
    public double getIncome() {        
        return this.income;        
    }
    
    public double getCosts() {        
        return this.costs;
    }
    
    public double getSurplus() {        
        return this.getIncome()-this.getCosts();
    }
    
    public String toString() {
        String result = new String();
        result = "Name: " + this.firstName + " " + this.lastName + " | Income: " + this.getIncome() + " | Costs: " + this.getCosts() + " | Surplus: " + this.getSurplus();
        return result;        
    }

}
Und SupportMember so:
Code:
public class SupportMember extends Member {

    public SupportMember(String firstName, String lastName, int ID) {
        super(firstName, lastName, ID);
        this.getIncome();
        this.getCosts();
    }

}
^^ Nur wie kriege ich jetzt in income 100 rein und in costs 15?

Und bevor der erste mit Settern in Klasse Member kommt: Geht nicht! Laut Angabe dürfen da nur die 3 Getter und die toString Methode rein.
 
Zuletzt bearbeitet:

Anubis12334

Komplett-PC-Aufrüster(in)
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

setter schreiben und this.setIncome(WERT); schreiben;
 
TE
B

boss3D

Guest
AW: [JAVA] Hilfe beim Programmieren und Verständnis-Fragen zu Code-Beispielen ...

^^ Sieher letzter Satz in meinem vorigen Posting. In Member "darf" ich (laut Angabe) keine Setter machen (nur die Getter und die toString Methode) und in SupportMember bzw. den anderen Klassen bringt's nichts ... oder überseh' ich was in meiner Logik?
 
Oben Unten