Bruchrechner

Code-Stücke können hier veröffentlicht werden.
Antworten
yearx
User
Beiträge: 3
Registriert: Donnerstag 21. Dezember 2006, 00:16

Donnerstag 21. Dezember 2006, 00:32

So mhm ich weiß gar nicht wo das hier jetzt hingehört falls es falsch sein sollte bitte ich um Entschuldigung und bitte das es dann verschoben wird.

Also ich habe ein Problem und zwar habe versuche ich gerade ein Bruchrechner mi einer Grafikoberfläche zu erstellen. Die Grafik sache ist ja eher kein Problem. Das Problem ist ich kann zwar werte eingeben diese aber nicht multiplizieren. Ich schaffe es nur einen Wert vom Zähler und einen vom Nenner einzugeben. Nun meine Frage könnt ihr mir helfen?

Hier ist ein mal der Code für die Rechnung und Ersellung des Bruches:

Code: Alles auswählen

class Bruch:                                ## Bruch Erstellung
    def __init__(self):
        self.zaehler = 1                    ## Variable für Zähler
        self.nenner = 1                     ##     "    für Nenner
        self.dezimal = 1                    ##     "    für Dezimal
        
    def setze_zaehler(self,z):              ## setzt den Wert Zähler 
        self.zaehler=z

    def gib_zaehler(self):          
        return self.zaehler

    def setze_nenner(self,n):               ## setzt den Wert Nenner
        self.nenner=n

    def gib_nenner(self):
        return self.nenner


    def gib_dezimal(self):                  ## Umrechnung des Bruches in ein Dezimalzahl
        self.dezimal =float (self.zaehler)/float (self.nenner)
        return self.dezimal

    def bigteiler(self, z1,n1):                            ##größter gemeinsamer teiler
        while n1>0:
            rest=z1%n1
            z1=n1
            n1=rest
        return z1

    def smalteiler(self, z1, n1):
        teiler = (z1 * n1) / self.bigteiler(z1, n1)
        return teiler


class MonaBruch(Bruch):
    def __init__(self):    
        Bruch.__init__(self)
        self.kurz=1

    def bilde_kehrwert(self):                       ##kehrwertfunktion
        lager=self.zaehler
        self.zaehler=self.nenner
        self.nenner=lager

    def setze_erweiterung(self):                  ##erweiterungs faktor
        teiler1=self.samlteiler(self.zaehler,self.nenner)
        self.zaehler=self.zaehler*teiler
        self.nenner=self.nenner*teiler
        
    def kuerzen(self):                              ##kürzfunktion
        kurz=self.bigteiler(self.zaehler,self.nenner)
        self.zaehler=self.zaehler/kurz
        self.nenner=self.nenner/kurz

   

class DiaBruch(MonaBruch):
    def __init__(self):
        MonaBruch.__init__(self)
        self.bruch2=Bruch()

    def multi(self):
        ##br2 = bruch2
        self.zaehler=self.zaehler*self.bruch2.gib_zaehler()
        self.nenner*=self.bruch2.gib_nenner()

    def divi(self, br2):
        bruch2 = br2
        bruch2.bilde_kehrwert()
        bruch2.multi(bruch2)

    def addition(self, br2):
        bruch2 = br2
        bruch2.setze_erweiterung()
        self.zaehler+=bruch2.gib_zaehler()
        self.nenner+=bruch2.gib_nenner()
        
    def subtrahieren(self, br2):
        bruch2 = br2
        bruch2.setze_erweiterung()
        self.zaehler-=bruch2.gib_zaehler()
        self.nenner-=bruch2.gib_nenner()
        
so nun der gui teil:

Code: Alles auswählen

import Tkinter
from tkmodule import *
from model import*

class GUI_Bruchrechner:

    def __init__(self,ref_bruch):
        self.bruch=ref_bruch
        self.bruch2=ref_bruch

        rootwin=Tkinter.Tk()
        rootwin.title ("Bruchrechner by ")
        bruchwin=XThemenRahmen(rootwin,"Bruchrechner",Seite=TOP)
        ergebninswin=XThemenRahmen(rootwin,"Ergebnis",Seite=BOTTOM)
        rechenartwin=XThemenRahmen(rootwin,"Rechenart",Seite=BOTTOM)
        
        RahmenEingabe=XThemenRahmen(bruchwin,"Bruch",Seite=LEFT)
        RahmenEingabe2=XThemenRahmen(bruchwin,"Bruch2",Seite=RIGHT)
        RahmenDezimal=XThemenRahmen(ergebninswin,"Dezimal",Seite=LEFT)
        RahmenAusgabe=XThemenRahmen(ergebninswin,"Ausgabe",Seite=LEFT)
        RahmenRechenArt=XHilfsRahmen(rechenartwin,Seite=LEFT)
        RahmenRechenArt2=XHilfsRahmen(rechenartwin,Seite=LEFT)
        
        self.ZaehlerEingabe=XEingabe(RahmenEingabe,'Zähler')
        self.NennerEingabe=XEingabe(RahmenEingabe,'Nenner')
        self.ZaehlerEingabe2=XEingabe(RahmenEingabe2,"Zähler")
        self.NennerEingabe2=XEingabe(RahmenEingabe2,'Nenner')
        
        self.DezimalAusgabe=XEingabe(RahmenDezimal,'Dezimal')
        self.ZaehlerAusgabe=XEingabe(RahmenAusgabe,"Zähler")
        self.NennerAusgabe=XEingabe(RahmenAusgabe,"Nenner")

        self.UmwandelnTaste=XTaste(rootwin,'Umwandeln in Dezimal',self.aktion,Seite=LEFT)
        self.UmwandelnTaste=XTaste(rootwin,'Umwandeln in Dezimal',self.aktion,Seite=LEFT)
        self.RechenartTaste=XTaste(RahmenRechenArt,"+",self.addition,Seite=TOP)
        self.RechenartTaste1=XTaste(RahmenRechenArt,"*",self.multi,Seite=BOTTOM)
        self.RechenartTaste2=XTaste(RahmenRechenArt2,"/",self.divi,Seite=TOP)
        self.RechenartTaste3=XTaste(RahmenRechenArt2,"-",self.sub,Seite=BOTTOM)
    
                         
    def aktion(self):
        zaehler = self.ZaehlerEingabe.get_xEingabe()
        zaehler = float(zaehler)
        nenner  = self.NennerEingabe.get_xEingabe()
        nenner = float(nenner)
        self.bruch.setze_zaehler(zaehler)
        self.bruch.setze_nenner(nenner)
        dezimal = self.bruch.gib_dezimal()
        self.DezimalAusgabe.set_xEingabe(dezimal)
        

    def addition(self):
        zaehler = self.ZaehlerEingabe.get_xEingabe()
        zaehler = float(zaehler)
        nenner  = self.NennerEingabe.get_xEingabe()
        nenner = float(nenner)
        self.bruch.setze_zaehler(zaehler)
        self.bruch.setze_nenner(nenner)

        zaehler2 = self.ZaehlerEingabe2.get_xEingabe()
        zaehler2 = float(zaehler2)
        nenner2  = self.NennerEingabe2.get_xEingabe()
        nenner2 = float(nenner2)
        self.bruch2.gib_zaehler(zaehler2)
        self.bruch2.gib_nenner(nenner2)

        zaehleraddition = self.bruch.addition(zaehler)
        nenneraddition  = self.bruch.addition(nenner)
        
        self.ZaehlerAusgabe.set_xEingabe(zaehleraddition)
        self.NennerAusgabe.set_xEingabe(nenneraddition)
         

    def multi(self):
        zaehler = self.ZaehlerEingabe.get_xEingabe()
        zaehler = float(zaehler)
        nenner  = self.NennerEingabe.get_xEingabe()
        nenner = float(nenner)
        self.bruch.setze_zaehler(zaehler)
        self.bruch.setze_nenner(nenner)

        
        zaehler2 = self.ZaehlerEingabe2.get_xEingabe()
        zaehler2 = float(zaehler2)
        nenner2  = self.NennerEingabe2.get_xEingabe()
        nenner2 = float(nenner2)
        test=self.bruch2.setze_zaehler(zaehler2),self.bruch2.setze_nenner(nenner2)
        ##self.bruch2.setze_nenner(nenner2)
        
        

        self.bruch.multi()
        zaehlermulti = self.bruch2.gib_zaehler()
        nennermulti  = self.bruch2.gib_nenner()
        
        self.ZaehlerAusgabe.set_xEingabe(zaehlermulti)
        self.NennerAusgabe.set_xEingabe(nennermulti)

    def divi(self):
        pass

    def sub(self):
        pass
        



br=DiaBruch()
gui=GUI_Bruchrechner(br)
Tkinter.mainloop()

ich weiß nich aber vielleicht brauch jemand ja das tkmodule

Code: Alles auswählen

import  Tkinter
from    Tkconstants     import  *


class XHilfsRahmen(Tkinter.Frame):
   """
   /* GUI-Darstellung eines Hilfsrahmens fuer grobe Einteilung
   """
   def __init__(self, Win, Seite=TOP):
      """
      /* Effekt: Ein Hilfsrahmen wird angelegt,
      /* Win kennzeichnet das Parent-Objekt, in dem er sitzen soll.
      /* Seite: optionaler Parameter,
      /*        um Rahmen auch nebeneinander anordnen zu können.
      """
      Ausbreitung = BOTH
      Tkinter.Frame.__init__(self, Win)
      self.pack(side=Seite, fill=Ausbreitung, expand=1)

class XThemenRahmen(Tkinter.Frame):
   """
   /* GUI-Darstellung eines beschrifteten Rahmens
   """
   def __init__(self, Win, derText, Seite=TOP):
      """
      /* Effekt: Ein beschrifteter Rahmen wird angelegt,
      /* Win kennzeichnet das Parent-Objekt, in dem er sitzen soll,
      /* derText kennzeichnet die Beschriftung (oberhalb).
      /* Seite: optionaler Parameter,
      /*        um Rahmen auch nebeneinander anordnen zu können.
      """
#      if Seite == TOP:
#        Ausbreitung = X
#      else:
#        Ausbreitung = Y
      Ausbreitung = BOTH
      HilfRahmen   = Tkinter.Frame(Win, relief=SUNKEN, bd=2)
      HilfRahmen.pack(side=Seite, padx=4, pady=4, fill=Ausbreitung, expand=1)
      LabelThRahmen = Tkinter.Label(HilfRahmen, text=derText)
      LabelThRahmen.pack()
      Tkinter.Frame.__init__(self, HilfRahmen, relief=RIDGE, bd=2)
      self.pack(padx=2, pady=2, fill=Ausbreitung, expand=1)

class XEingabe:
   """
   /* GUI-Darstellung einer Dateneingabe
   """
   def __init__(self, Win, derText, Bef="pass", Seite=TOP):
      """
      /* Effekt: Ein (Text-) Eingabefeld wird angelegt,
      /* Win kennzeichnet das Parent-Objekt, in dem es sitzen soll.
      /* derText kennzeichnet die Beschriftung (links).
      /* Bef: option. Parameter, noch nicht implementiert ...
      /* Seite: option. Parameter, zum Rahmen nebeneinander Anordnen
      """
      tWert=Tkinter.StringVar()
      HilfRahmen   = Tkinter.Frame(Win)
      LblEingabe = Tkinter.Label(HilfRahmen, text=derText)
      self.Eingabe=Tkinter.Entry(HilfRahmen,textvariable=tWert, width=15)
      HilfRahmen.pack(side=Seite, fill=X, expand=1)
      self.Eingabe.pack(side=RIGHT, padx=2, pady=2)
      LblEingabe.pack(side=RIGHT)

   def get_xEingabe(self):
      """
      /* liefert den eingegebenen Wert aus dem Text-Eingabefeld,
      /* bei fehlender Eingabe: ein Leerzeichen!
      """
      Eing = self.Eingabe.get()
      if Eing == "" :
           Eing = " "
      return Eing

   def set_xEingabe(self,wert):
      """
      /* Belegung des Text-Eingabefeldes mit einem Wert
      """
      self.Eingabe.delete(0,END)
      self.Eingabe.insert(0,wert)

class XTaste:
   """
   /* GUI-Darstellung einer Taste
   """
   def __init__(self, Win, derText, Bef, Seite=LEFT):
      """
      /* Effekt: Eine beschriftete Taste wird angelegt,
      /* Win kennzeichnet das Parent-Objekt, in das sie gesetzt wird.
      /* derText : string : Beschriftung der Taste
      /* Bef  : Methodenreferenz : Methode, die beim Drücken der Taste
      /*                           ausgeführt werden soll.
      /* Seite: optionaler Parameter,
      /*        um Tasten auch übereinander anordnen zu können
      """
      Knopf=Tkinter.Button(Win, text=derText, command=Bef,fg="red")
      Knopf.pack(side=Seite, fill=X, expand=1)

class XDialog:
    """
    /* GUI-Darstellung einer Dialogbox
    """
    def __init__(self,derText):
      """
      /* Effekt  : Eine beschriftete Dialogbox ("Weiter") wird angelegt,
      /*      aber nicht gezeigt!
      /* derText : string : Beschriftung der Box
      """
      self.extraRahmen   = Tkinter.Toplevel()
      self.extraRahmen.withdraw()
      self.extraRahmen.geometry ("+50+120")
      extraLabel  = Tkinter.Label(self.extraRahmen,text=derText,bg="red")
      extraKnopf  = Tkinter.Button(self.extraRahmen,text="Weiter",command=self.extraRahmen.destroy)
      extraLabel.pack()
      extraKnopf.pack()
    def zeige(self):
      """
      /* Effekt  : Die zuvor angelegte Dialogbox ("Weiter") wird anzeigt!
      /*           Bei Betätigen der "Weiter"-Taste verschwindet die Box.
      """
      self.extraRahmen.deiconify()

class XWahl:
    """
    /* GUI-Darstellung einer Radio-Button-Leiste
    """
    def __init__(self,Win,derText,liste,Seite=TOP):
        """
        /* Erzeugt Knopfleiste entsprechend der übergebenen Werte-"liste"
        /* Win kennzeichnet das Parent-Objekt, in das sie gesetzt wird.
        """
        dieSeite      = Seite
        derRahmen     = XThemenRahmen(Win,derText,dieSeite)
	self.gewaehlt = Tkinter.StringVar()
	self.alleWerte = liste
	for dieserWert in liste:
		dieWahl = Tkinter.Radiobutton(derRahmen,
			text     = dieserWert,
			variable = self.gewaehlt,
			value    = dieserWert)
		dieWahl.pack(side = Seite,ipadx=4,ipady=4)

    def get_xEingabe(self):
      """
      /* liefert den Wert der gedrückten Taste,
      /* bei fehlender Eingabe: ein Leerzeichen!
      """
      Eing = self.gewaehlt.get()
      if Eing == "" :
           Eing = " "
      return Eing

    def set_xEingabe(self,wert):
      """
      /* Knopf markieren, entsprechend übergebenem "wert"
      """
      if wert == " ":
        self.gewaehlt.set(NONE)
      else:
        self.gewaehlt.set(wert)

class XListe :
    """
    /* GUI-Darstellung einer scrollbaren Mehrfach-Auswahl-Liste
    """
    def __init__ (self, derText, liste=[], Bef="None"):
        """
        /* Erzeugt Listbox entsprechend der übergebenen Werte-"liste",
#        /* ... muss mit "zeige" sichtbar gemacht werden!
        /* derText : string : Beschriftung der Box
        """
        self.Inhalt = liste
        self.extraRahmen   = Tkinter.Toplevel()
        self.extraRahmen.title(" List-Box ")
        self.extraRahmen.transient()
        self.extraRahmen.withdraw()
        if Bef == "None":
          Befehl = self.extraRahmen.iconify
        else :
          Befehl = Bef
        listRahmen  = XThemenRahmen(self.extraRahmen,derText)
        listRahmen.pack()
        rollBalken = Tkinter.Scrollbar(listRahmen, orient=VERTICAL)
        self.listBox = Tkinter.Listbox(listRahmen,yscrollcommand=rollBalken.set,selectmode=EXTENDED)
        rollBalken.config(command=self.listBox.yview)
        rollBalken.pack(side=RIGHT, fill=Y)
        self.listBox.pack(side=LEFT, fill=BOTH, expand=1)
        listOkKnopf  = Tkinter.Button(self.extraRahmen,text="OK",command=Befehl)
        listOkKnopf.pack(side=LEFT)
        listEndeKnopf  = Tkinter.Button(self.extraRahmen,text="Schließen",command=self.extraRahmen.iconify)
        listEndeKnopf.pack(side=RIGHT)

        for element in self.Inhalt:
          self.listBox.insert(END, element)

    def get_xAuswahl(self):
      """
      /* liefert eine Liste der gewaehlten Elemente,
      /* bei leerer Box oder fehlender Wahl: eine leere Liste
      """
      Auswahl = []
      welche  = self.listBox.curselection()
      for index in welche:
        Auswahl.append(self.listBox.get(int(index)))
      return Auswahl

    def zeige(self):
      """
      /* Effekt  : Die zuvor angelegte Listenbox wird angezeigt!
      /* Bei Betätigen der "Beende"-Taste verschwindet die Box.
      """
      self.extraRahmen.deiconify()
      self.listBox.see(0)

    def fuelle(self,liste):
      """
      /* Effekt  : In der Listenbox wird die "liste" angezeigt!
      """
      self.listBox.delete(0, END)
      self.Inhalt = liste
      for element in self.Inhalt:
            self.listBox.insert(END, element)
#      self.listBox.see(0)


so ich hoffe mir kann jemand helfen.
Achso das subtraktion und Division nicht Funktionieren, also noch nicht weiter geschrieben wurden in der gui lag daran das ich noch zu gefrustet bin wegen dem nicht Funktionieren der multiplikation.

P.S.: Wenn jemand weitere fehler findet bitte bescheidsagen
Zuletzt geändert von yearx am Sonntag 18. Mai 2008, 15:04, insgesamt 1-mal geändert.
BlackJack

Donnerstag 21. Dezember 2006, 09:36

Nimm erst einmal den ganzen GUI-Teil weg und teste Deine Brüche ohne GUI.

Du bist mit Deinen Leerzeichen ein bisschen inkonsequent. Üblicherweise setzt man welche vor und nach Operatoren. Manchmal machst Du es und manchmal nicht.

In `MonaBruch.setze_erweiterung()` ist `teiler` nicht definiert. Denke mal das ist ein Tippfehler, weil in der Methode `teiler1` definiert wird. In der selben Methode: `samlteiler` ist wohl auch ein Vertipper.

Mit den Namen `MonaBruch` und `DiaBruch` kann ich übrigens nichts anfangen. Falls das Abkürzungen sind, dann könnte man sie ausschreiben. Oder zumindest dokumentieren. Braucht man die überhaupt? Mir scheint die implementieren Funktionalität, die man von einem ganz normalen Bruch erwarten würde.

Die Kommentare bei einigen Methoden würden sich prima als Docstrings machen.

Die `setze_*()`- und `gib_*()`-Methoden für einfache Attribute sind überflüssig, die kann man weglassen. `dezimal` würde ich auch nicht als Attribut setzen, da der Wert immer ungültig wird, wenn man etwas an Zähler oder Nenner ändert.

Die Anfangswerte für Zähler und Nenner sollte man als Argumente der `__init__()` mitgeben können, so dass man ``Bruch(1, 2)`` für 0.5 schreiben kann.

Methoden die keinen Gebrauch von `self` machen, sind eigentlich Funktionen. Gerade so etwas wie der grösste gemeinsame Teiler macht auch ausserhalb von einer Bruch-Klasse Sinn. Python ist nicht Java, also bitte keine Angst davor haben Klassen *und* Funktionen zu benutzen. :-)

Zum eigentlichen Problem: Mal davon abgesehen das `multi()` immer mit `self.bruch2` multipliziert, der ja auf 1/1 gesetzt wird, sehe ich kein Problem. Auch wenn man die Werte ändert, kommen korrekte Ergebnisse heraus.

Gerade bei Brüchen, die ja "mathematische" Objekte sind, würde es sich übrigens anbieten die Operatoren zu überladen. Damit lässt sich dann viel "natürlicher" aussehender Quelltext schreiben.
yearx
User
Beiträge: 3
Registriert: Donnerstag 21. Dezember 2006, 00:16

Donnerstag 21. Dezember 2006, 23:14

Erst einmal danke für deine Antwort, denn noch habe ich das Problem das die
Rechnung nicht ausgeführt wird oder das Ergebnis angezeigt wird.
Antworten