Brüche programmieren im Informatik-Unterricht?

EragonSaphira17  26.05.2021, 22:58

Welche Programmiersprache?

exxad 
Beitragsersteller
 26.05.2021, 23:02

Java denke ich, kam zumindest raus als ich nach BlueJ gegooglet habe.

3 Antworten

Fang erstmal an mit einer Klasse, die Bruchzahlen darstellen kann.

public class Bruchzahl {
	private int zaehler;
	private int nenner;
	
	public Bruchzahl(int zaehler, int nenner) {
		this.zaehler = zaehler;
		this.nenner = nenner;
	}
	
	public Bruchzahl(int ganze, int zaehler, int nenner) {
		this((ganze*nenner)+zaehler, nenner);
	}
}

Dann kannst du dir überlegen, welche Methoden die Klasse braucht. Du brauchst z.B. für jede Grundrechenart eine Methode. Addieren, Subtrahieren, Multiplizieren und Dividieren. Außerdem ist es vermutlich praktisch, wenn du Methoden zum kürzen und erweitern von Brüchen hast. Zusätzlich ist es bei jeder Klasse, die die Möglichkeit bietet, best practice, die Methoden toString und equals zu überschreiben und in diesem Fall auch das Interface Comparable<Bruchzahl> zu implementieren.

Überlege dir für jede Grundrechenart, wie du sie schriftlich lösen würdest, damit du einen Ansatz hast, wie du sie in Java umsetzt. Z.B. beim multiplizieren musst du die Zähler und die Nenner von beiden Zahlen multiplizieren. Beim dividieren machst du das gleiche, nur dass du Zähler und Nenner vom Divisor (also von der zweiten Zahl) vertauschst.


phillip1872r  27.05.2021, 22:28

Kritik: Man Stellt Brüche keine Bruchzahlen da

Erweiterung: Bruchrechner als klasse und dann noch nen gemischter/un... Bruch als klasse welcher bruch extendet

0
daCypher  28.05.2021, 09:03
@phillip1872r

Ja, den Namen der Klasse kann man ja noch so anpassen, wie man es für richtig hält. Für mich hat sich die Klasse "Bruch" bloß irgendwie komisch angehört. Am besten wäre es, wenn man konsequent bei englischen Bezeichnungen bleibt, also "Fraction".

Jeweils eine Klasse für echte und gemischte Brüche finde ich nicht notwendig. Der Zahlenwert ist ja gleich, egal ob man jetzt 3 2/3 oder 11/3 schreibt. Ich würde einfach die toString-Methode so überschreiben, dass standardmäßig ein echter Bruch ausgegeben wird und zusätzlich eine toMixedString-Methode schreiben, die den Bruch als gemischten Bruch ausgibt.

0
exxad 
Beitragsersteller
 28.05.2021, 15:42

public class Bruch
{
  //Attribute 
  private int zaehler;
  private int nenner;
  private int faktor;
   
  //Konstruktor
  public Bruch(int pZaehler, int pNenner)

  {

    zaehler = pZaehler;

    nenner = pNenner;
     
  }
  //Methoden für Bruchrechnung
  public int ggt(int a, int b) {
 
   if (a == 0)
   return b;
   while (b != 0) {
   if (a > b)
   a = a - b;
   else
   b = b - a;
   }
   return a;
   }
   
   
 
  private void kuerze()
  {  
     
    zaehler = zaehler / ggt(zaehler, nenner);
    nenner = nenner / ggt(zaehler, nenner);
    if (nenner < 0)
    zaehler = -zaehler;
    nenner = -nenner;
   
   
  }
     
   
  private int erweitern(int faktor)
  {  
    zaehler = zaehler * faktor;
    nenner = nenner * faktor;
   
   
  }
   
   
}

Das habe ich bis jetzt zum Bruch, aber bei (ich glaube das ist die Methode) private int erweitern fehlt noch der "return", da komme ich nicht weiter.

public class GemischterBruch extends Bruch
{
    private int GanzeZahl;
    // Konstruktor
    public GemischterBruch(int ganzeZahl, int pNenner, int pZaehler,)
    {
        super(int pZaehler; int pNenner;)
        GanzeZahl = GanzeZahl;


    }

}

Das ist meine Klasse zum Gemischten Bruch, da sind aber auch Fehler drin enthalten die mit der Klasse Bruch zusammenhängen, jedoch komme ich da auch komplett durcheinander, eventuell versteht jemand so den Fehler.

0
daCypher  28.05.2021, 16:26
@exxad

Das sieht doch so weit schon sehr gut aus. Bei erweitern musst du halt statt "public int" ein "public void" draus machen. Oder als Überlegung: Die ganzen Standard-Wrapper Klassen in Java sind alle immutable, also unveränderlich. Das heißt, dass z.B. ein Objekt vom Typ Integer nicht mehr verändert werden kann, sobald es einmal erstellt wurde. Wenn du Berechnungen damit machst, wird immer ein neues Objekt vom Typ Integer zurückgegeben. Ob du die Strategie für deine Klasse auch übernehmen willst, kannst du dir selbst überlegen.

Diese zusätzliche Klasse "GemischterBruch" würde ich gar nicht machen. Das hab ich oben in einem anderen Kommentar ja schon geschrieben, sondern ich würde einfach einen zusätzlichen Konstruktor in Bruch erstellen, der einen gemischten Bruch automatisch in einen echten Bruch umwandelt. Also so:

public Bruch (int ganzeZahl, int zaehler, int nenner) {
    this((ganzeZahl*nenner)+zaehler, nenner);
}

Ich würde dir auch empfehlen, die Parameter in den Konstruktoren genauso zu benennen, wie die Attribute und dann mit dem this Keyword zwischen Attribut und Parameter zu unterscheiden. In dem Konstruktor für den GemischtenBruch hast du nämlich schon den kleinen, aber feinen Fehler eingebaut, dass du GanzeZahl = GanzeZahl zuweist, was beides groß geschrieben ist und daher beides das Attribut anspricht (laut den Konventionen sollte man übrigens ausschließlich Klassennamen groß schreiben, bzw. alles, was wie eine Klasse ist, also z.B. auch Enums und Interfaces).

Schreib also lieber:

public Bruch(int zaehler, int nenner)
{
    this.zaehler = zaehler;
    this.nenner = nenner; 
}

Das Attribut "faktor" brauchst du übrigens nicht, bzw. ich wüsste nicht wozu.

Aber bis dahin ist das schon gute Arbeit 👍

0
exxad 
Beitragsersteller
 28.05.2021, 19:46
@daCypher

Ja, das funktioniert, ich danke dir vielmals! Ich werde im nächsten Unterricht nochmal nachfragen, ob das so in Ordnung ist oder ich das wieder umschreiben soll. Ich melde mich wieder, wenn ich eine Frage habe. Danke nochmal. :)

0
exxad 
Beitragsersteller
 31.05.2021, 21:59
@daCypher

Das hat alles ganz gut geklappt, jedoch bin ich jetzt überfordert mit dem Bruch-Rechner. Er sollte addieren, subtrahieren, dividieren und multiplizieren, aber ich kriege nichts davon hin.

public class Rechner


{   private int Bruch1;
    private int Bruch2;
    private int ErgebnisBruch;
    
    public Rechner(int pBruch1, int pBruch2, int pErgebnisBruch)
    {
        
        this.Bruch1 = pBruch1;
        this.Bruch2 = pBruch2;
        this.ErgebnisBruch= pErgebnisBruch;
        
    }
    public Bruch addiere() {
        

}

Weiter komme ich nicht, habe auch schon versucht was reinzuschreiben und "addiere" zu beschreiben, aber das bekomme ich nicht hin. Vielleicht könnte mir man da nochmal helfen.

0
daCypher  01.06.2021, 11:51
@exxad

Ich glaub, mit der Rechner-Klasse verläufst du dich ein bisschen. Die Funktionen für Berechnungen (also addiere(), subtrahiere() ...) sollten alle in der Klasse Bruch sein. Die Klasse Rechner kannst du dann für Ein-/Ausgabe benutzen, aber nicht um die Rechenfunktionen zu definieren.

Ich hab mal die Bruch Klasse so gebaut, wie ich sie mir vorstelle. Sie ist zu lang, um sie hier als Kommentar zu posten, aber du kannst sie dir auf PasteBin anschauen: https://pastebin.com/N4ij3uPE

Hier sind noch ein paar Tests, wo du auch sehen kannst, wie die Bruch Klasse funktioniert:

	public static void main(String[] args) {
		Bruch z1 = new Bruch(1, 2);
		Bruch z2 = new Bruch(2, 3);
		System.out.println(z1 + " + " + z2 + " = " + z1.addiere(z2)); // 1/2 + 2/3 = 7/6
		System.out.println(z1 + " + " + z2 + " = " + z1.addiere(z2).toMixedString()); // 1/2 + 2/3 = 1 1/6
		System.out.println(z1 + " - " + z2 + " = " + z1.subtrahiere(z2)); // 1/2 - 2/3 = -1/6
		System.out.println(z1 + " * " + z2 + " = " + z1.multipliziere(z2)); // 1/2 * 2/3 = 1/3
		System.out.println(z1 + " / " + z2 + " = " + z1.dividiere(z2)); // 1/2 / 2/3 = 3/4

		System.out.println(new Bruch(1,2).equals(new Bruch(2,4))); // true
		System.out.println(new Bruch(1,2).equals(new Bruch(1,4))); // false
		System.out.println(new Bruch(1,2).equals(1)); // false
		System.out.println(new Bruch(1).equals(1)); // true
		System.out.println(new Bruch(1,2).equals(0.5)); // true
		System.out.println(new Bruch(1,2).equals(0.6)); // false
	}
1
exxad 
Beitragsersteller
 01.06.2021, 21:31
@daCypher

Es klappt soweit, danke dir vielmals für die Mühe! Bei der stelle

return this.equals(new Bruch(((int) obj).intValue()));

wird mir jedoch bei "int Value" der Fehler "int cannot be dereferenced" angezeigt, im Internet hab ich nichts dazu gefunden, weißt du wie man dieses Problem noch löst?

0
daCypher  02.06.2021, 10:10
@exxad

Bitteschön, gerne.

An der Stelle musst du bedenken, dass "int" ein primitiver Datentyp ist. Ein Objekt kann nicht zu einem int konvertiert werden. Die Klasse "Integer" ist allerdings ein Objekttyp und kann daher an der Stelle benutzt werden. Wenn du einen Bruch mit einem int vergleichst, wird der automatisch zu einem Integer-Objekt umgerechnet (autoboxing), wenn es erforderlich ist.

Also kurz gesagt: Du musst das "int" austauschen durch "Integer". Steht in meinem Beispielcode aber auch so drin.

0
daCypher  02.06.2021, 11:38
@exxad

Ich hab an meinem Beispielcode nochmal ein bisschen rumgebastelt und hier und da was verbessert. Die Klasse Bruch ist jetzt eine Subklasse von Number und implementiert das Interface Comparable<Number>, wodurch sie mit allen anderen Zahlentypen verglichen werden kann. Subtraktion und Division wurden etwas vereinfacht, Nenner dürfen nicht mehr 0 sein, negative Nenner werden beim kürzen automatisch korrigiert.

https://pastebin.com/QBNLVNG8

0
exxad 
Beitragsersteller
 03.06.2021, 15:52
@daCypher

Hab jetzt beide Projekte gespeichert, funktionieren auch beide. Ich danke dir vielmals du hast mich echt gerettet! :)

0

mit python geht das sehr leicht (du hast ja keine sprache angegeben)

while True:
  try:
    x = int(input('Zahl 1: '))
    y = int(input('Zahl 2: '))

    out = round((x / y), 2)
    print(f'Das Ergebnis lautet {out}\n')
  except:
    print('Nur Zahlen erlaubt!\n')
    

-> dividiert und rundet auf zwei nachkommastellen. wenn du ein bisschen flexen willst kannst du mit pyinstaller --one-file ... (.py Dateiname ergänzen) eine .exe erstellen die man auch ohne python verwenden kann

while True wiederholt den Code darunter so lange, bis unterbrochen wird. in diesem fall wird nicht unterbrochen, also läuft er unendlich lang bis jemand das programm schließt.

int(...) konvertiert den input vom nutzer in einen Integer, also eine zahl.

falls das nicht funktioniert, also falls der nutzer eine buchstaben eingibt, wird 'except' ausgelöst. except fängt fehler auf, die beim 'try' code auftreten

\n steht einfach für eine neue zeile. es wird also eine leerzeile hinzugefügt damit der output besser lesbar ist

round rundet auf '2' nachkommastellen

/ ist das Divisionszeichen

print "druckt" den text in anführungszeichen im terminal

Bild zum Beitrag

 - (Schule, programmieren, Informatik)

exxad 
Beitragsersteller
 26.05.2021, 23:09

Danke schonmal! Wir benutzen BlueJ, eventuell weißt du auch wie man es in dem Programm schreiben kann.

0
daCypher  27.05.2021, 08:05

So, wie ich die Frage verstehe, ist nicht gemeint, dass man einfach einen Bruch in eine Dezimalzahl umrechnen soll, sondern dass man verschiedene Funktionen baut, mit denen Bruchzahlen addiert, subtrahiert, gekürzt etc. werden können. Also sowas, wie 1/2 + 2/3 = 7/6

0

ich würde eine klasse machen die einen bruch darstellt und eben einen integer für den zähler und einen für den nenner enthält und dann eben methoden hat wie addieren, multiplizieren und so weiter


DinoMath  26.05.2021, 23:42

und kürzen, würde ich.

0