Schaltjahr

thor_norsk

Bekanntes Mitglied
Guten Tag,

Schreiben Sie ein Programm, das eine Jahreszahl über einen grafischen Eingabedialog abfragt und dann ausgibt, ob das Jahr ein Schaltjahr ist.
Die Überprüfung können Sie mit folgenden Regeln durchführen:
Ein Jahr ist kein Schaltjahr, wenn die Jahreszahl nicht durch 4 teilbar ist.
Ein Jahr ist ein Schaltjahr, wenn die Jahreszahl durch 4, aber nicht durch 100 teilbar ist.
Es ist ebenfalls ein Schaltjahr, wenn die Jahreszahl gleichzeitig durch 4, durch 100 und durch 400 teilbar ist.
Ein Beispiel:
Das Jahr 1964 war ein Schaltjahr. Die Jahreszahl lässt sich durch 4, aber nicht durch 100 teilen.
Das Jahr 1900 war kein Schaltjahr. Die Jahreszahl lässt sich zwar durch 4 und auch durch 100 teilen, aber nicht durch 400.
Sie können für die Überprüfung der Teilbarkeit den Modulo-Operator % und if … else-Verzweigungen benutzen. Zur Erinnerung: Wenn eine Zahl x nicht glatt durch y teilbar ist, dann liefert der Ausdruck (x % y) einen Wert größer als 0.
Setzen Sie bei der Überprüfung der Teilbarkeit eine weitere Variable ein, die markiert, ob das Jahr ein Schaltjahr ist oder nicht. Werten Sie diese Variable am Ende des Programms aus und lassen Sie dann auf dem Bildschirm ausgeben, ob es sich um ein Schaltjahr handelt oder nicht.

Meine Lösung:

import javax.swing.*;

public class Schaltjahr {

public static void main(String[] args) {

int eingabe;
int zahl1 = 4;
int zahl2 = 100;
int zahl3 = 400;

eingabe = Integer.parseInt(JOptionPane.showInputDialog("Bitte geben Sie ein Jahr ein:"));

if( (eingabe % zahl1 ==0) && (eingabe % zahl2 !=0) || (eingabe % zahl1 == 0) && (eingabe % zahl2 == 0) && (eingabe % zahl3 == 0 ) ) {
System.out.println("Es ist ein Schaltjahr");
}
else {
System.out.println("Ihre Eingabe ist kein Schaltjahr!");
}
}
}

Es funktioniert, aber ich habe mir andere Bespiele angeschaut, die haben if - Verzweigung verschachtelt und eine boolesche Variable ins Spiel gebracht.

Danke!
 

mihe7

Top Contributor
Es sollte korrekt funktionieren.

Wenn Du meinst, Variablen (hier wären Konstanten angebracht) für fixe Zahlen einführen zu müssen, dann sollten die auch passende Namen und nicht zahl1, zahl2, zahl3 haben.

Und dann wäre die Frage, welche Zahl sich durch 400 aber nicht durch 4 oder 100 teilen lässt...
 

Blender3D

Top Contributor
[CODE lang="java" highlight="5-7"]import javax.swing.JOptionPane;

public class TestLeapYear {
public static void main(String[] args) {
int year = inputYear("Geben Sie eine Jahreszahl ein: ", 1900, 2999);
String message = year + " ist " + (isLeapYear(year) ? "" : "k") + "ein Schaltjahr!";
JOptionPane.showMessageDialog(null, message);
}

public static int inputYear(String text, int min, int max) {
int jahr = min;
boolean ok = false;
do {
String eingabe = JOptionPane.showInputDialog(text, min + "");
try {
jahr = Integer.parseInt(eingabe);
if (jahr < min || jahr > max)
JOptionPane.showMessageDialog(null, "Der Bereich für gültige Jahre ist [" + min + "-" + max + "]");
else
ok = true;
} catch (NumberFormatException e) {
JOptionPane.showMessageDialog(null, "Bitte nur Zahlen eingeben!");
}
} while (!ok);
return jahr;
}

public static boolean isLeapYear(int year) {
return (year % 4 == 0 && year % 100 != 0 || year % 400 == 0);
}
}[/CODE]
 

thor_norsk

Bekanntes Mitglied
Guten Abend,
ich habe über meine Fallunterscheidungen nachgedacht und andere Variante programmiert! Hätte gerne gewusst, ob ich richtig programmiert habe?


package schaltjahr;
import javax.swing.*;

public class Schaltjahr {

public static boolean Schaltjahr(int jahr) {
if (jahr % 400 == 0) {
return true;
}
else if (jahr % 100 == 0) {
return false;
}
else if (jahr % 4 == 0) {
return true;
}
else {
return false;
}
}

public static void main(String[] args) {

int eingabe;
eingabe = Integer.parseInt(JOptionPane.showInputDialog("Bitte geben Sie ein Jahr ein:"));

if (Schaltjahr(eingabe)) {
System.out.println("Schaltjahr!");
}
else {
System.out.println("Kein Schaltjahr!");
}
}
}
 

Blender3D

Top Contributor
Hätte gerne gewusst, ob ich richtig programmiert habe?
Ist richtig.
[CODE lang="java" title="Deine Variante"]public static boolean Schaltjahr(int jahr) {
if (jahr % 400 == 0) {
return true;
}else if (jahr % 100 == 0) {
return false;
}else if (jahr % 4 == 0) {
return true;
}else {
return false;
}
}[/CODE]
Mach aber das selbe wie das
Java:
 public static boolean isLeapYear(int year) {
        return (year % 4 == 0 && year % 100 != 0 || year % 400 == 0);
    }

Vergleiche den Code und überlege welcher von beiden übersichtlicher ist.
 

LimDul

Top Contributor
Ist richtig.
[CODE lang="java" title="Deine Variante"]public static boolean Schaltjahr(int jahr) {
if (jahr % 400 == 0) {
return true;
}else if (jahr % 100 == 0) {
return false;
}else if (jahr % 4 == 0) {
return true;
}else {
return false;
}
}[/CODE]
Mach aber das selbe wie das
Java:
 public static boolean isLeapYear(int year) {
        return (year % 4 == 0 && year % 100 != 0 || year % 400 == 0);
    }

Vergleiche den Code und überlege welcher von beiden übersichtlicher ist.
Die erste Variante find ich besser als die zweite. Ich bin überhaupt kein Freund davon && und || zu mischen ohne Klammern zu setzen. Das heißt, wenn die zweite Variante, dann so:

Java:
        return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);

Sie sind aber alle signifikant besser als das aus dem ersten Beitrag aus folgenden Gründen:

Eigene Methode
Eine eigene Methode erlaubt es mit Unit-Tests diese Funktionalität einfach zu testen. Das heißt insbesondere, dass im restlichen Code man nicht mehr die Logik verstehen muss, was der Block macht, sondern man am Methodenaufruf das bereits sieht.

Verzicht auf unötige, schlecht benannte Variablen
Durch den Verzicht auf die Hilfsvariablen zahl1, zahl2 und zahl3 ist der Code lesbar ohne das man dauernd zwischen verschiedenen Zeilen springen muss um ihn zu verstehen.


Was noch zu korrigieren wäre:
* Methoden fangen immer mit einem Kleinbuchstaben an
* Methoden mit einem boolean Rückgabewert sollte man - sofern sinnvoll - mit dem Präfix is benennen (und dann Camel-Case).

Sprich der richtige Name wäre "isSchaltjahr".
 

Blender3D

Top Contributor
Die erste Variante find ich besser als die zweite. Ich bin überhaupt kein Freund davon && und || zu mischen ohne Klammern zu setzen. Das heißt, wenn die zweite Variante, dann so:
Das ist in Java in durch die Priorität geregelt. && (Priorität 10) || (Priorität 11) % (Priorität 2)
Insofern sind hier Klammern nicht nötig.
Eine solche Funktion wird normalerweise nicht mehr verändert sondern nur mehr benutzt. Daher ist kein eigener Test dafür notwendig.
 

LimDul

Top Contributor
Das ist in Java in durch die Priorität geregelt. && (Priorität 10) || (Priorität 11) % (Priorität 2)
Insofern sind hier Klammern nicht nötig.
Technisch nicht - zum Verständnis schon. Ja, es keine Änderung der Funktionlität. Aber es macht den Code um längen lesbarer. Auch wenn man es Wissen sollte, das && vor || gilt - Code sollte so einfach lesbar wie möglich sein und da gehören Klammern meines Erachtens dazu

Eine solche Funktion wird normalerweise nicht mehr verändert sondern nur mehr benutzt. Daher ist kein eigener Test dafür notwendig.
Was ist den das für ein Unfug? Was ich nicht ändere muss ich nicht testen?

Das ist doch genau der Sinn von Unit-Tests - Sicherstellen, dass es sich nicht ändert!

Ich würde so einen Code ohne Unit-Test auch immer im Code Review zurückweisen. Das ist Funktionalität die über ein get hinaus geht- damit müssen dafür Unit-Tests geschrieben werden, wenn möglich. Und die kosten hier keine 5 Minuten.
 

Michelangelo

Mitglied
Guten Tag,

Schreiben Sie ein Programm, das eine Jahreszahl über einen grafischen Eingabedialog abfragt und dann ausgibt, ob das Jahr ein Schaltjahr ist.
Die Überprüfung können Sie mit folgenden Regeln durchführen:
Ein Jahr ist kein Schaltjahr, wenn die Jahreszahl nicht durch 4 teilbar ist.
Ein Jahr ist ein Schaltjahr, wenn die Jahreszahl durch 4, aber nicht durch 100 teilbar ist.
Es ist ebenfalls ein Schaltjahr, wenn die Jahreszahl gleichzeitig durch 4, durch 100 und durch 400 teilbar ist.
Ein Beispiel:
Das Jahr 1964 war ein Schaltjahr. Die Jahreszahl lässt sich durch 4, aber nicht durch 100 teilen.
Das Jahr 1900 war kein Schaltjahr. Die Jahreszahl lässt sich zwar durch 4 und auch durch 100 teilen, aber nicht durch 400.
Sie können für die Überprüfung der Teilbarkeit den Modulo-Operator % und if … else-Verzweigungen benutzen. Zur Erinnerung: Wenn eine Zahl x nicht glatt durch y teilbar ist, dann liefert der Ausdruck (x % y) einen Wert größer als 0.
Setzen Sie bei der Überprüfung der Teilbarkeit eine weitere Variable ein, die markiert, ob das Jahr ein Schaltjahr ist oder nicht. Werten Sie diese Variable am Ende des Programms aus und lassen Sie dann auf dem Bildschirm ausgeben, ob es sich um ein Schaltjahr handelt oder nicht.

Meine Lösung:

import javax.swing.*;

public class Schaltjahr {

public static void main(String[] args) {

int eingabe;
int zahl1 = 4;
int zahl2 = 100;
int zahl3 = 400;

eingabe = Integer.parseInt(JOptionPane.showInputDialog("Bitte geben Sie ein Jahr ein:"));

if( (eingabe % zahl1 ==0) && (eingabe % zahl2 !=0) || (eingabe % zahl1 == 0) && (eingabe % zahl2 == 0) && (eingabe % zahl3 == 0 ) ) {
System.out.println("Es ist ein Schaltjahr");
}
else {
System.out.println("Ihre Eingabe ist kein Schaltjahr!");
}
}
}

Es funktioniert, aber ich habe mir andere Bespiele angeschaut, die haben if - Verzweigung verschachtelt und eine boolesche Variable ins Spiel gebracht.

Danke!
Hallo, habe da mal eine Frage.... wie hast den Teil von:"" Setzen Sie bei der Überprüfung der Teilbarkeit eine weitere Variable ein, die markiert, ob das Schaltjahr...................- ganz zu Schluss der Aufgabenstellung?! Hast du es hinbekommen? MFG
 

thor_norsk

Bekanntes Mitglied
Guten Abend,
Bedingung für Schaltjahr ist vorgegeben. Die boolesche Methode überprüft Alle Fälle und liefert das Ergebnis zurück .
Oder habe ich dich falsch verstanden?
 

Michelangelo

Mitglied
Guten Abend,
Bedingung für Schaltjahr ist vorgegeben. Die boolesche Methode überprüft Alle Fälle und liefert das Ergebnis zurück .
Oder habe ich dich falsch verstanden?
Guten Morgen,
Aus der Aufgabenstellung geht hervor daß man eine weitere variable zur Überprüfung und Markierung des Schaltjahres verwenden soll welche zum Schluss mit ausgegeben werden soll. Letzter Absatz in der Aufgabenstellung.
Hattest du für die Aufgabe volle Punktzahl bekommen?
Liebe Grüße
 
M

Mart

Gast
Java:
boolean sinnLoseZwischenVariable  = isLeapYear(1942);
System.out.println(sinnLoseZwischenVariable);
das?
 

Michelangelo

Mitglied
Guten Abend,
Bedingung für Schaltjahr ist vorgegeben. Die boolesche Methode überprüft Alle Fälle und liefert das Ergebnis zurück .
Oder habe ich dich falsch verstanden?
Guten morgen, aus der Aufgabenstellung geht hervor,daß man eine weitere variable einsetzen soll zur Überprüfung und Markierung. Diese soll zum Schluss auch ausgegeben werden( letzter Absatz in der Aufgabenstellung). Wie viele Punkte hast du für diese Aufgabe bekommen? Ich mache den selben Lehrgang🤓.
Liebe Grüße
 

mihe7

Top Contributor
Ich vermute mal, es ist sowas in der Richung gemeint:
Java:
boolean schaltjahr = (jahr % 4 == 0);
schaltjahr = schaltjahr && (jahr % 100 != 0);
schaltjahr = schaltjahr || (jahr % 400 = 0);

if (schaltjahr) {
     System.out.println("%d ist ein Schaltjahr%n", jahr);
} else {
     System.out.println("%d ist kein Schaltjahr%n", jahr);
}
 

Neue Themen


Oben