Objektorientiertes Programmieren

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

ja, die kannst du weglassen. die bewirken nur, dass die funktion verlassen wird. aber da die immer am ende der funktionen stehen haben sie keinerlei wirkung. return brauchst du wenn die funktion was zurückgeben soll.

Code: Alles auswählen

def addiere(a, b):
   return a + b
und deinen testcode am ende solltest du ergänzen mit:

Code: Alles auswählen

if __name__ == "__main__":
    square = Quadrat(50,(0,0)) 
    square.anzeigen() 
    (...)
dann kannst du dein quadrat.py oder wie du die datei nennst in einem anderen script benutzen mit:

Code: Alles auswählen

import quadrat
ohne dass der testcode aufgerufen wird.
kannst das ja mal probieren und evtl noch ein "print __name__" in den testcode einfügen und schauen was passiert wenn du das script direkt startest und wenn du es importierst.
Zuletzt geändert von Dill am Mittwoch 10. Juni 2009, 17:23, insgesamt 1-mal geändert.
http://www.kinderpornos.info
Sconine
User
Beiträge: 49
Registriert: Montag 1. Juni 2009, 11:00

VIELEN DANK.

So kann ich es beruhigt abgeben. :D
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

EyDu hat geschrieben: - riskiere mal einen Blick in PEP8 bzgl. der Klassen- und Variablennamen und Leerzeichen zwischen den Parametern einer Funktion.
wenn dus wirklich schön machen willst, könntest du dir das noch zu herzen nehmen.
http://www.kinderpornos.info
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Besser als "leere returns" wegzulassen ist es, die print-Anweisung aus den Methoden zu verbannen und stattdessen "volle returns" zu verwenden.

Was umfang() und inhalt() angeht, so wäre es passender, keine Seitenlänge zu übergeben, weil es ja Methoden eines Quadrat-Objekts sind, was zu jedem Zeitpunkt schon eine bestimmte Seitenlänge hat.

Ich würde sogar noch weitergehen und dafür gar keine Methode verwenden, sondern es in Datenattributen ablegen, die jeweils beim Skalieren neu berechnet werden.

Nimmt man statt turtle das frog-Modul, dann könnte das ganze so aussehen:

Code: Alles auswählen

from frog import Pool, Frog

class Quadrat(Frog):

    def __init__(self,tafel,seite=50):
        Frog.__init__(self, tafel)
        self.seite = seite
        self.skaliere(1)

    def verschiebe(self, *zentrum):
        self.pos = zentrum

    def loesche(self):
        self.exit()

    def skaliere(self, faktor):
        self.seite *= faktor
        self.umfang = 4*self.seite
        self.flaeche = self.seite ** 2
        self.shape = (0,0), (self.seite,0), (self.seite,self.seite), (0,self.seite), (0,0)

tafel = Pool()
quad1 = Quadrat(tafel)
quad1.verschiebe(40,50)
quad2 = Quadrat(tafel, seite=40)
quad2.color = "red"
quad2.verschiebe(-50,-30)
quad2.skaliere(2)
print quad2.flaeche
print quad1.umfang
quad1.loesche()
tafel.ready()

Hast du Python >= 2.6, dann sollte das mit dem turtle-Modul ähnlich gehen. Hast du noch Python <= 2.5, dann hast du noch die alte, magere turtle-Fassung. Mit der kommt nicht so viel Freude auf. Dann entweder Python auf eine aktuellere Version bringen oder xturtle einsetzen. (Oder den Frosch)
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

numerix hat geschrieben:Besser als "leere returns" wegzulassen ist es, die print-Anweisung aus den Methoden zu verbannen und stattdessen "volle returns" zu verwenden.
die hab ich garnicht gesehen, ja das solltest du ändern, also:

Code: Alles auswählen

(...)
def berechne_umfang(self):
   return 4 * self.seitenlaenge

print mein_quadrat.berechne_umfang()
also da stecken doch noch ein paar probleme in dem code:
- bei einigen methoden übergibst du nutzlose variablen. (ist dir klar warum die nicht notwendig ist bei umfang?)
- die methodennamen sollten verben sein
- nicht englisch und deutsch mischen (daher habe ich jetzt mal das quadrat statt square "mein_quadrat" genannt.

und vergleich mal den code von numerix mit deinem, das könnte lehrreich sein. (obwohl der sich auch nicht wirklich an pep8 hält :cry: )
verstehst du was bei ihm mit den ganzen methoden wie umfang() passiert ist?
http://www.kinderpornos.info
Sconine
User
Beiträge: 49
Registriert: Montag 1. Juni 2009, 11:00

Ok, dann werde ich mir die Probleme gleich nochmal genau anschauen.

Ich habe Python 2.5. :(
Sconine
User
Beiträge: 49
Registriert: Montag 1. Juni 2009, 11:00

Jetzt bin ich verwirrt.

Code: Alles auswählen

import turtle

import Quadrat

class Quadrat:
    def __init__(self,seitenlaenge,zentrum):
        self.seitenlaenge = seitenlaenge
        self.zentrum = zentrum
        #return
    
    def anzeigen(self):
        angle = 90
        turtle.color("white")
        turtle.setx(self.zentrum[0]-0.5*self.seitenlaenge)
        turtle.sety(self.zentrum[1]-0.5*self.seitenlaenge)
        turtle.color("black")
        for i in range(4):
            turtle.forward(self.seitenlaenge)
            turtle.left(angle)
        #return
    
    def loeschen(self):
        turtle.color("white")
        angle = 90
        for i in range(4):
            turtle.forward(self.seitenlaenge)
            turtle.left(angle)
        #return
    
    def verschieben(self,neues_zentrum):
        self.loeschen()
        turtle.color("white")
        self.zentrum = neues_zentrum
        self.anzeigen()
        #return
    
    def skalieren(self,faktor):
        self.loeschen()
        self.seitenlaenge *= faktor
        self.anzeigen()
        #return

    def berechne_umfang(self,seitenlaenge):
        #U = 4*self.seitenlaenge
        #print U
        return 4 * self.seitenlänge

        print mein_Quadrat.berechne_umfang()

    def berechne_inhalt(self,seitenlaenge):
        #A = self.seitenlaenge**2
        #print A
        #return
        return self.seitenlänge**2

        print mein_Quadrat_.berechne_inhalt()
    
if __name__=="__main__":
    square = Quadrat(50,(0,0))
    square.anzeigen()
    Umfang = square.umfang(50)
    Inhalt = square.inhalt(50)
    square.verschieben((100,100))
    square.skalieren(4)

Code: Alles auswählen

Traceback (most recent call last):
  File "C:/Python25/Eigene/Quadrat.py", line 3, in <module>
    import Quadrat
  File "C:/Python25/Eigene\Quadrat.py", line 46
SyntaxError: Non-ASCII character '\xe4' in file C:/Python25/Eigene\Quadrat.py on line 46, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details (Quadrat.py, line 46)
Jetzt komme ich mit der Groß- und Kleinschreibung durcheinander.
In der Klasse wird der Name groß geschrieben.
class Quadrat:

In der Methode klein
def anzeigen()
skalieren()
usw


Beim Umfang verstehe ich es mit dem return, aber woher kommt das mein_quadrat? Muss es jetzt auch groß geschrieben werden?

Mit den Testläufen verstehe ich es nicht so ganz? Was bedeutet denn __main__? Ich weiss schonmal, dass es keine Funktion ist. :)

import Quadrat verstehe ich auch nicht. Wieso sollten da die testläufe nicht durchgehen??? Ich habe das Programm unter Quadrat.py abgespeichert.

Ich sag ja, ich tue mich wirklich schwer mit Python. Wundert mich, dass überhaupt was läuft.

Das mit dem frog kann ich etwas nachvollziehen, aber unser Dozent ist immer sehr skeptisch, wenn er etwas sieht, was er uns noch nicht vorgetragen hat. Deshalb bleibe ich lieber bei turtle.
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

Sconine hat geschrieben:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:/Python25/Eigene/Quadrat.py", line 3, in <module>
    import Quadrat
  File "C:/Python25/Eigene\Quadrat.py", line 46
SyntaxError: Non-ASCII character '\xe4' in file C:/Python25/Eigene\Quadrat.py on line 46, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details (Quadrat.py, line 46)
du hast einen umlaut in "seitenlänge". im code solltest du nur ascii-zeichen verwenden, ändere das also in seitenlaenge. in kommentaren sind umlaute natürlich in ordnung, werden aber auch angemeckert. daher musst du an den anfang des codes folgendes schreiben:

Code: Alles auswählen

#-*- coding: iso-8859-1 -*-
Jetzt komme ich mit der Groß- und Kleinschreibung durcheinander.
In der Klasse wird der Name groß geschrieben.
class Quadrat:

In der Methode klein
def anzeigen()
skalieren()
usw
Klassennamen schreibst du groß (In CamelCase), den rest klein (mit underscores). also auch eine instanz.

Code: Alles auswählen

class MeineKlasse:
   pass

eine_klasse = MeineKlasse()
Beim Umfang verstehe ich es mit dem return, aber woher kommt das mein_quadrat? Muss es jetzt auch groß geschrieben werden?
das mein_quadrat soll eine instanz von Quadrat sein. hab ich doch geschrieben. du hattest es square genannt, ws nicht schön ist, da du sonst alles in deutsch hast.

habe oben einfach folgendes ausgelassen:

Code: Alles auswählen

mein_quadrat = Quadrat()
Mit den Testläufen verstehe ich es nicht so ganz? Was bedeutet denn __main__? Ich weiss schonmal, dass es keine Funktion ist. :)
probier es doch einfach. schreib mal ein print __name__ an den anfang des skripts. und schau was passiert wenn du das skript direkt startest und was wenn du es importierst.
import Quadrat verstehe ich auch nicht. Wieso sollten da die testläufe nicht durchgehen??? Ich habe das Programm unter Quadrat.py abgespeichert.
das verstehst du dann wenn du obiges getestet hast.


du hast zwar noch einiges an arbeit vor dir mit dem code, aber das wird schon. ist noch kein kleister vom himmel gefallen.
http://www.kinderpornos.info
Sconine
User
Beiträge: 49
Registriert: Montag 1. Juni 2009, 11:00

Es tut mir echt leid, aber ich bin jetzt total durcheinander.

square habe ich jetzt mein_quadrat genannt, da ich englisch und deutsch nicht mixen soll.

Code: Alles auswählen

import turtle

import Quadrat

class Quadrat:
    def __init__(self,seitenlaenge,zentrum):
        self.seitenlaenge = seitenlaenge
        self.zentrum = zentrum
       
    
    def anzeigen(self):
        angle = 90
        turtle.color("white")
        turtle.setx(self.zentrum[0]-0.5*self.seitenlaenge)
        turtle.sety(self.zentrum[1]-0.5*self.seitenlaenge)
        turtle.color("black")
        for i in range(4):
            turtle.forward(self.seitenlaenge)
            turtle.left(angle)
       
    
    def loeschen(self):
        turtle.color("white")
        angle = 90
        for i in range(4):
            turtle.forward(self.seitenlaenge)
            turtle.left(angle)
       
    
    def verschieben(self,neues_zentrum):
        self.loeschen()
        turtle.color("white")
        self.zentrum = neues_zentrum
        self.anzeigen()
        
    
    def skalieren(self,faktor):
        self.loeschen()
        self.seitenlaenge *= faktor
        self.anzeigen()
        

    def berechne_umfang(self,seitenlaenge):
        return 4 * self.seitenlänge
        print mein_Quadrat.berechne_umfang()

    def berechne_inhalt(self,seitenlaenge):
        return self.seitenlänge**2
        print mein_Quadrat_.berechne_inhalt()
    
if __name__=="__main__":
    mein_quadrat = Quadrat(50,(0,0))
    mein_quadrat.anzeigen()
    umfang = mein_quadrat.umfang(50)
    inhalt = mein_quadrat.inhalt(50)
    mein_quadrat.verschieben((100,100))
    mein_quadrat.skalieren(4)
Da mein Kopf schon völlig raucht, habe ich das mit dem print__name__ noch nicht ausprobiert.

Das erste Quadrat wird gezeichnet, aber dann kommt:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:\Python25\Eigene\Quadrat.py", line 54, in <module>
    umfang = mein_quadrat.umfang(50)
AttributeError: Quadrat instance has no attribute 'umfang'
Habe gedacht, dass ich unten anstatt umfang, berechne_umfang schreiben muss, aber ich habe dann dieselbe Fehrlermeldung bekommen.

Ich bin echt nicht für das Programmieren geschaffen. :cry:[
Deshalb VIELEN DANK für eure "Geduld".
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

:o also seit weit sind wir nun wirklich noch nicht, dass programmiersprachen natürliche sprache verstehen.
du unterstellst ja, dass python das wort "berechne" versteht und daher aus der existenz der methode "berechne_umfang" folgert, dass es dir per mein_quadrat.umfang() diesen zurückgeben kann. ich hoffe du siehst ein, dass das unfug ist! :?

python ist das komplett egal wie du die methoden und klassen benennst (solage die namen gültig sind). Du könntest die klasse Quadrat _sogar_ "Kreis" nennen. python wäre das vollkommen egal. nur eben nicht den lesern des codes. beim vergeben von namen geht es allein darum den code lesbar zu machen.

also zu deinem problem:

Code: Alles auswählen

mein_quadrat.berechne_umfang()
wird sicher nicht den gleichen fehler produzieren, sondern einen anderen, nämlich: "self.seitenlänge gibt es nicht"

lösch doch endlich mal die überflüssigen parameter, in berechne_umfang "seitenlaenge". ist dir klar warum der überflüssig ist? (was ist self?)
und die prints hinter den return werden nie ereicht, da ist die funktion ja schon verlassen worden.

ich glaube, du solltest nochmal eine einführung zu python durcharbeiten.

http://docs.python.org/tutorial/
http://abop-german.berlios.de/

lass dich nicht entmutigen, aller anfang ist schwer.
vor allem bei der programmierung, das ist einfach ne andere welt :)
http://www.kinderpornos.info
Sconine
User
Beiträge: 49
Registriert: Montag 1. Juni 2009, 11:00

Jetzt zeichnet er wieder alles, aber berechnet den Umfang und Inhalt nicht.

Code: Alles auswählen

import turtle

import Quadrat

class Quadrat:
    def __init__(self,seitenlaenge,zentrum):
        self.seitenlaenge = seitenlaenge
        self.zentrum = zentrum
       
    
    def anzeigen(self):
        angle = 90
        turtle.color("white")
        turtle.setx(self.zentrum[0]-0.5*self.seitenlaenge)
        turtle.sety(self.zentrum[1]-0.5*self.seitenlaenge)
        turtle.color("black")
        for i in range(4):
            turtle.forward(self.seitenlaenge)
            turtle.left(angle)
       
    
    def loeschen(self):
        turtle.color("white")
        angle = 90
        for i in range(4):
            turtle.forward(self.seitenlaenge)
            turtle.left(angle)
       
    
    def verschieben(self,neues_zentrum):
        self.loeschen()
        turtle.color("white")
        self.zentrum = neues_zentrum
        self.anzeigen()
        
    
    def skalieren(self,faktor):
        self.loeschen()
        self.seitenlaenge *= faktor
        self.anzeigen()
        

    def berechne_umfang(self,seitenlaenge):
        return 4 * self.seitenlaenge
        print mein_quadrat.berechne_umfang()

    def berechne_inhalt(self,seitenlaenge):
        return self.seitenlaenge**2
        print mein_quadrat_.berechne_inhalt()
    
if __name__=="__main__":
    mein_quadrat = Quadrat(50,(0,0))
    mein_quadrat.anzeigen()
    berechne_umfang = mein_quadrat.berechne_umfang(50)
    berechne_inhalt = mein_quadrat.berechne_inhalt(50)
    mein_quadrat.verschieben((100,100))
    mein_quadrat.skalieren(4)
Der Umfang und Inhalt sind doch definiert, wieso rechnet er jetzt nicht?
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

was bezweckst du mit dem

Code: Alles auswählen

import Quadrat
das brauchst du nur wenn du deine Quadrat klasse in einem _anderen_skript benutzen willst. hier kannst du das weglassen.

die werden schon berechnet, du gibst sie nur nicht aus.
wie gesagt, die prints in den methoden werden nicht erreicht.
bitte nimm dir die zeit die antworten in ruhe und gründlich zu lesen, das schont meine geduld. :)

noch ein paar anmerkungen:

Code: Alles auswählen

mein_quadrat = Quadrat(50,(0,0)) 
mein_quadrat.anzeigen() 
#das ist kein schöner name für eine variabel, nenne sie "umfang" oder 
#"berechneter_umfang" wegen mir 
berechne_umfang = mein_quadrat.berechne_umfang(50) 
#und hier ein print hin: 
print umfang #dazu musst du erst die variable umbennen!! dann gehts! 

#siehe oben
berechne_inhalt = mein_quadrat.berechne_inhalt(50) 
mein_quadrat.verschieben((100,100)) 
mein_quadrat.skalieren(4) 
http://www.kinderpornos.info
Sconine
User
Beiträge: 49
Registriert: Montag 1. Juni 2009, 11:00

Ich weiß, ich weiß... Ich will alles immer schnell schnell machen und dann lese ich nicht richtig.

Jetzt läuft zum Glück alles.

Nochmal vielen, vielen, Dank für deine Geduld.

Code: Alles auswählen

import turtle

class Quadrat:
    def __init__(self,seitenlaenge,zentrum):
        self.seitenlaenge = seitenlaenge
        self.zentrum = zentrum
       
    
    def anzeigen(self):
        angle = 90
        turtle.color("white")
        turtle.setx(self.zentrum[0]-0.5*self.seitenlaenge)
        turtle.sety(self.zentrum[1]-0.5*self.seitenlaenge)
        turtle.color("black")
        for i in range(4):
            turtle.forward(self.seitenlaenge)
            turtle.left(angle)
       
    
    def loeschen(self):
        turtle.color("white")
        angle = 90
        for i in range(4):
            turtle.forward(self.seitenlaenge)
            turtle.left(angle)
       
    
    def verschieben(self,neues_zentrum):
        self.loeschen()
        turtle.color("white")
        self.zentrum = neues_zentrum
        self.anzeigen()
        
    
    def skalieren(self,faktor):
        self.loeschen()
        self.seitenlaenge *= faktor
        self.anzeigen()
        

    def umfang(self,seitenlaenge):
        return 4 * self.seitenlaenge
        print mein_quadrat.umfang()

    def inhalt(self,seitenlaenge):
        return self.seitenlaenge**2
        print mein_quadrat.inhalt()
    
if __name__=="__main__":    
    mein_quadrat = Quadrat(60,(0,0))
    mein_quadrat.anzeigen()
    umfang = mein_quadrat.umfang(60)
    print umfang
    inhalt = mein_quadrat.inhalt(60)
    print inhalt
    mein_quadrat.verschieben((100,100))
    mein_quadrat.skalieren(4)
Auch wenn es noch paar Schöheitsfehler gibt, kann ich die Lösung so abgeben. Das Programm läuft ja.

Und nochmal DANKE.
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

wenn du das so abgibst, wird sicher die frage kommen, was die paramter "seitenlaenge" bei umfang() und inhalt() sollen. entferne die noch, dann ist der code in ordnung.

schau dir mal __init__ an. da hast du seitenlaenge (sinnvollerweise) an die instanz gebunden. ab dann ist es ein attribut der instanz und kann von überall in der klasse erreicht werden über "self". das musst du dir glaub ich nochmal ansehen, was es mit diesem self auf sich hat.
http://www.kinderpornos.info
Sconine
User
Beiträge: 49
Registriert: Montag 1. Juni 2009, 11:00

Wenn ich seitenlaenge wegnehme bei Umfang und Inhalt, bekomme ich schon wieder eine Fehlermeldung:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:\Python25\Eigene\Quadrat.py", line 52, in <module>
    umfang = mein_quadrat.umfang(60)
TypeError: umfang() takes exactly 1 argument (2 given)
Warum ändert sich denn bei umfang etwas? Unten steht doch nichts mit seitenlängen, die ich hätte wegnehmen können.

Und schon wieder wird deine Geduld strapaziert. :(

Ich verstehe so langsam gar nix mehr.
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Lass die 60 beim Aufruf weg. Die solltest du schon beim Aufruf von __init__ übergeben haben.
Sconine
User
Beiträge: 49
Registriert: Montag 1. Juni 2009, 11:00

Wow, es geht.

Ich glaube ich muss nochmal erklärt bekommen, was genau __init__ bedeutet, da ich nicht weiss, warum da schon die 60 drin steht.


Es wurde schon öfer probiert, aber irgendwie bleibt es nicht in mein Gehirn haften. :(
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

das sind ganz elementare dinge. wenn dir diese grundlagen nicht klar sind, machst du dir nur das leben schwer. arbeite lieber _in_ _ruhe_ nochmal ein tutorial durch. dann ordnet sich das alles etwas in deinem kopf.
http://www.kinderpornos.info
Antworten