Neuling sucht Rat

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
bwbg
User
Beiträge: 407
Registriert: Mittwoch 23. Januar 2008, 13:35

Das erste was mir sauer aufstößt; Du greifst aus Deiner Klasse auf Namen zu, welche weiter unten im Quelltext global gebunden werden. Das lässt sich nur sehr schwer nachvollziehen.

Traffic ist kein guter Name. Er beschreibt nicht das, was die Klasse darstellen soll. Traffic hat zu viele Aufgaben: Persistenz und (wirre) GUI-Anbindung.

Grüße ... bwbg
"Du bist der Messias! Und ich muss es wissen, denn ich bin schon einigen gefolgt!"
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Hallo Tengel,
Dein neuer Code wirkt schon viel aufgeräumter, und dazu sind ja Klassen unter anderem auch da.
Trotzdem haben sich noch ein paar Fehler und auch Unschönheiten eingeschlichen.

Schau mal nach, welche Exception von welcher Zeile in »startWert« geworfen werden kann. Du schreibst selbst, dass »startWert« vor jeder anderen Funktion aufgerufen werden muss, und genau das erledigt die »__init__«-Methode. Du überschreibst im übrigen die Methode »startWert« mit der Instanzvariable »startWert«. Das sollte nicht sein. Der Dateiname ist ein guter Kandidat dafür in der __init__-Methode als Argument übergeben zu werden.

Wenn Du das geschafft hast, solltest Du alles, was mit GUI zu tun hat in eine zweite Klasse schreiben, so dass Dein __main__-Teil nur noch aus dem erzeugen dieser Klasse und dem Aufruf von mainloop besteht.
Tengel
User
Beiträge: 210
Registriert: Sonntag 17. März 2013, 12:29

Traffic ist kein guter Name
wäre TrafficVerwaltung besser?

wie kann eine Klasse zu viele Aufgaben haben?

Code: Alles auswählen

Dein neuer Code wirkt schon viel aufgeräumte
Juhu :) endlich mal was positives - nach 100 Jahren ich kanns nicht fassen
Du überschreibst im übrigen die Methode »startWert« mit der Instanzvariable »startWert
?!?!
Der Dateiname ist ein guter Kandidat dafür in der __init__-Methode als Argument übergeben zu werden
mit dem Konstruktor in der Klasse?

Der wurde im Buch nur sehr "oberflächlich" genutzt
z. B.

Code: Alles auswählen

class Fahrzeug:
    def __init__(self,bez,ge):     #Konstruktormethode
        self.bezeichnung = bez
        self.geschwindigkeit = ge
    def beschleunigen(self, wert):
        self.geschwindigkeit += wert
        self.ausgabe()
    def ausgabe(self):
        print(self.bezeichnung,self.geschwindigkeit,"km/h")

BlackJack

@Tengel: Ich würde die `__init__`-Methode nicht Konstruktor nennen. Die konstruiert kein neues Objekt, sondern initialisiert eines, welches es schon gibt und das ihr als erstes Argument übergeben wird. In anderen Sprachen könnte man das als semantische Haarspalterei bezeichnen, in Python gibt es allerdings auch eine `__new__()`-Methode, die *tatsächlich* ein Konstruktor ist.

Die `__init__()`-Methode ist wichtig. In der sollte ein Objekt vollständig initialisiert werden. Nachdem die abgelaufen ist, sollten alle Attribute existieren und sich das Objekt in einem konsistenten, benutzbaren Zustand befinden. Im Grunde der einzige Grund *keine* `__init__()` zu haben wäre eine Basisklasse deren `__init__()`-Methode genau das schon leistet, oder wenn man eine „mix in”-Klasse schreibt, die nicht eigenständig für sich existieren kann, sondern immer als zusätzliche Basisklasse von anderen Klassen verwendet werden muss.

Ad `startWert()`: Du hast auf dem Objekt eine Methode `startWert()` und in dieser Methode bindest Du einen Zahlenwert an das Attribut `startWert`. Damit hast Du die Methode überschrieben. Die kannst Du nur einmal aufrufen, danach hat das Objekt unter diesem Namen nicht mehr die Methode sondern den Zahlenwert gespeichert. Man kann nicht zwei verschiedene Sachen gleichzeitig an den selben Namen beziehungsweise das selbe Attribut binden.
Tengel
User
Beiträge: 210
Registriert: Sonntag 17. März 2013, 12:29

Interessant
__init__ wirds als Konstruktor
__del__ als Desktruktor im Buch beschrieben
naja - das Buch wird wohl einen guten Türstopper/Briefbeschwerer abgeben - heute ist mein neues Buch gekommen - das werde ich nochmal von vorne durch arbeiten - da ich einiges ja schon "kenne" sollte es schneller gehen und evtl. kann ich so einge "Missstände" ausmerzen mal sehen

stimmt - da hab ich wieder nicht aufgepasst :( ich werde die Methode mal umbenennen
BlackJack

@Tengel: Üblicherweise benennt man Funktionen und Methoden nach Tätigkeiten. Wenn man in einer Methode zum Beispiel Daten aus einer Datei lädt, könnte man sie `load()` nennen. Oft wird so eine `load()`-Methode als Klassenmethode implementiert, also eine die nicht auf einem Exemplar aufgerufen wird und die Daten lädt und damit das Objekt verändert oder befüllt, sondern eine die auf der Klasse aufgerufen wird, die Daten lädt und dann ein neues Exemplar mit diesen Daten zurück gibt. Das musst Du jetzt noch nicht so machen, aber vielleicht im Hinterkopf behalten wenn Du zum Thema Klassenmethoden kommst.

`startWert` ist auch kein so passender Name denn erstens ist das nur am Anfang der Startwert, aber nicht mehr wenn man ihn verändert hat, und zweitens ist `Wert` sehr allgemein und beschreibt nicht was die Bedeutung des Wertes ist.
Tengel
User
Beiträge: 210
Registriert: Sonntag 17. März 2013, 12:29

trafficStand
trafficGesamtStand

wobei ich eher zu trafficStand tendiere - oder ist das auch schlecht?
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Ja, du solltest dich fuer eine Sprache entscheiden ;)
Tengel
User
Beiträge: 210
Registriert: Sonntag 17. März 2013, 12:29

Wie für eine Sprache?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Traffic = Englisches Wort, Stand = Deutsches Wort. Zusammen: Denglisch :-(
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Tengel
User
Beiträge: 210
Registriert: Sonntag 17. März 2013, 12:29

achsoooooo ...ich werds versuchen^^
Tengel
User
Beiträge: 210
Registriert: Sonntag 17. März 2013, 12:29

Hm in meinem neuen Buch gibt es eine Fallstudie/Übungen mit TurtleWorld - ist das wirklich so "sinnvoll"?
Mein Problem ist dabei nicht das ich die Funktion nicht schreiben kann... die Funktionen an sich sind ja leicht - nur die Matheformeln ewig zu suchen .... ich weiß nicht wo das im Sinne von programmieren lernen helfen soll?
Tengel
User
Beiträge: 210
Registriert: Sonntag 17. März 2013, 12:29

Code: Alles auswählen


def hat_kein_e():
    Wort_ohne_e = 0
    woerter_gesamt = 0
    d = open("Wortliste.txt")
    for zeile in d:
        woerter_gesamt = woerter_gesamt + 1
        wort = zeile.strip()
        if "e"  not in wort and "E" not in wort:
           print(wort)
           Wort_ohne_e = Wort_ohnet_e + 1
           
        else:
            None

        
            

    prozent = 100/woerter_gesamt*Wort_ohne_e
    print(prozent)
    d.close()


Ich nehme an das so ein else das nichts macht - nicht so gut ist?
webspider
User
Beiträge: 485
Registriert: Sonntag 19. Juni 2011, 13:41

Wohl eher unnötig, genauso wie ein return am Ende jeder Funktion, einfach weil man es weglassen kann ohne die Funktion des Codes zu verändern. Ich würde sogar vermuten der kompilierte Bytecode sieht gleich aus.

Hier einige Denkanstöße:

Code: Alles auswählen

>>> with open('words.txt', 'r') as word_file:
...     words = word_file.read().split()
... 
>>> words
['affe', 'katze', 'hund']
>>> [word for word in words if "e" in word.lower()]
['affe', 'katze']
>>> len(words)
3
Tengel
User
Beiträge: 210
Registriert: Sonntag 17. März 2013, 12:29

Und wenn man das else einfach weg lässt?

Ich hab grad gemerkt man kann aus Dateien auch ohne < import sys lesen...warum wurde das im Buch immer importiert??
webspider
User
Beiträge: 485
Registriert: Sonntag 19. Juni 2011, 13:41

Eben darauf wollte ich hinaus, man kann es problemlos weglassen. Sollte es nicht gehen, dann ist es ein Zeichen, dass der Code umgeschrieben werden sollte.

Was den Import von Modulen angeht: Vielleicht ist es ja ein Warnzeichen das Buch in die Tonne zu kloppen. Ein Import bringt einem nichts wenn keiner der importierten Namen verwendet wird[1], man kann problemlos (außer bei Sternchenimporten) die Datei danach durchsuchen und so feststellen ob er verwendet wird oder nicht[2].

[1]: Ausnahme sind Importe die mit Nebeneffekten behaftet sind, hatte da mal ein interessantes Zusammenspiel von logging und requests, da requests die Präsenz von logging als Grund auffasste bei jedem Request ausführlich zu schwafeln. Das Setzen des Logging-Levels hat den Spuk beendet.

[2]: Dies wird von PyLint und PyFlakes und dergleichen ausgenutzt, Werkzeugen die deinen Code auf übliche Schnitzer überprüfen ehe du ihn ausführst.
Tengel
User
Beiträge: 210
Registriert: Sonntag 17. März 2013, 12:29

Code: Alles auswählen

def rot13(wort, zahl):
    
    neu = []
    x = len(wort)
    i = 0
    for i in range(0,x,1):
        
        rotiert = ord(wort[i]) + zahl
        print(chr(rotiert))
       
        neu.append(rotiert)
        print(rotiert)


    neu2 = []
    x= 0
    for x in range (0,len(neu),1):
        rotiert = chr(neu[x])
        neu2.append(rotiert)
        
        return neu2

    
Wieso wird in der zweiten Schleife nur der erste String in die Liste gespeichert?
anogayales
User
Beiträge: 456
Registriert: Mittwoch 15. April 2009, 14:11

Weil das "return neu2" in der Schleife steht. Außerdem solltest du aussagekräftigere Namen wählen. Und in python kann man direkt über Listen iterieren, dazu brauchst du dann das range und [x] Zeug nicht:

Code: Alles auswählen

for element in neu:
    neu2.append(chr(element))
return neu2
Und wenn du mal range benutzen solltest musst du nicht unbedingt vorher das x definieren. Das macht nur manchmal Sinn, wenn du leere Listen hast und du später was mit dem x außerhalb der Schleife anfangen willst.

Grüße,
anogayales
Tengel
User
Beiträge: 210
Registriert: Sonntag 17. März 2013, 12:29

Das mit dem return hab ich auch gerade gemerkt - das mit der kurzschreibweise war mir nicht klar - thx.
xeike
User
Beiträge: 83
Registriert: Donnerstag 28. Februar 2013, 09:58

Hi Tengel,

kennst du str.translate() schon?

Grüße

Xe
Antworten