Seite 6 von 14

Re: Neuling sucht Rat

Verfasst: Mittwoch 27. März 2013, 17:31
von BlackJack
@Tengel: In `ergebnisBerechnung()` wird `arbeitsTage` verwendet ohne dass es als Argument übergeben wurde. Das geht nur weil es zufällig auf Modulebene existiert. Wenn Du es dort umbenennst oder den Quelltext vom Hauptprogramm in eine Funktion verschiebst, dann gibt es einen `NameError` in der Funktion an der Stelle.

Re: Neuling sucht Rat

Verfasst: Mittwoch 27. März 2013, 17:46
von Tengel
Das exisitiert doch nicht zufällig?^^

Also sollte ich das als Parameter übergeben?

Re: Neuling sucht Rat

Verfasst: Samstag 30. März 2013, 00:35
von Tengel

Code: Alles auswählen



# Definition der klasse Fahrzeug
class Fahrzeug:
    def __init__(self,bez,ge):
        self.bezeichnung = bez
        self.geschwindigkeit = ge
    def beschleunigen(self,wert):
        self.geschwindigkeit =+ wert
    def __str__(self):
        return self.bezeichnung + " "\
               + str(self.geschwindigkeit) +" km/h"

import copy
#objekt der Klasse Fahrzeug erzeugen
opel = Fahrzeug("Opel Admiral",40)

#kopie eines Objektes erzeugen
zweit_opel = Fahrzeug(opel.bezeichnung,opel.geschwindigkeit)
zweit_opel.beschleunigen(30)

# Tiefe Kopie eines Objekts erzeugen
dritt_opel = copy.deepcopy(opel)
dritt_opel.beschleunigen(35)

# Zweite Referenz auf Objekt erzeugen
viert_opel = opel
viert_opel.beschleunigen(20)

#Kontrollausgaben
print("Original:",opel)
print("Kopie:",zweit_opel)
print("Kopie:",dritt_opel)
print("zweite Referenz auf Original:",viert_opel)

#identisch
print("2:",opel is zweit_opel)
print("3:",opel is dritt_opel)
print("4:",opel is viert_opel)



man übergibt für das Objekt opel, eine Geschwindigkeit von 40 - warum gibt er aber 20 aus?
Laut Buch müsste die Ausgabe
60
70
75
60
sein.
Bei mir ist es aber
20
30
35
20

Re: Neuling sucht Rat

Verfasst: Samstag 30. März 2013, 00:38
von Tengel
okay - hab den Fehler gefunden.

Hab =+ statt +=
Wahnsinn was so kleine dreher anrichten.

Re: Neuling sucht Rat

Verfasst: Samstag 30. März 2013, 06:28
von Tengel

Code: Alles auswählen

class Spiel:
    def __init__(self):
        #Start des Spiels
        random.seed()
        self.richtig = 0

        #Anzahl bestimmen
        self.anzahl = -1
        while self.anzahl<0 or self.anzahl>10:
            try:
                print("Wie viele Aufgaben(1 bis 10)")
                self.anzahl = int(input())
            except:
                continue

    def spielen(self):
        #Spielablauf
        for i in range(1,self.anzahl+1):
            a = Aufgabe(i,self.anzahl)
            print(a)
            self.richtig += a.beantworten()

    def __str__(self):
        #Ergebnis
        return "Richtig: " + str(self.richtig) + " von " + str(self.anzahl)




class Aufgabe:
    def __init__(self,i,anzahl):
        self.nr = i
        self.gesamt = anzahl

    #Aufgabe stellen
    def __str__(self):
        a=random.randint(10,30)
        b=random.randint(10,30)
        self.ergebnis=a+b
        return "Aufgabe "+str(self.nr) + " von "+str(self.gesamt) +" : " + str(a) + " + " + str(b)

    #Aufgabe beantworten
    def beantworten(self):
        try:
            if self.ergebnis == int(input()):
                print(self.nr,":***Richtig***")
                return 1
            else:
                raise
        except:
            print(self.nr,":***Falsch***")
            return 0






import random

#Hauptprogramm
s = Spiel()
s.spielen()
print(s)



So - bin mit dem OOP Kapitel durch - und dachte ich hätte es einigermaßen verstanden - und dann kam dieser Abschluß :(

Ich versteh nicht so wirklich wie das ineinander übergreift? Da wird ja nichts vererbt oder so.
Alles im "Hauptprogramm hat ja mit der Klasse Spiel zu tun - woher kommen dann die Informationen aus der Klasse Aufgabe?

Re: Neuling sucht Rat

Verfasst: Samstag 30. März 2013, 07:37
von kbr
Tengel hat geschrieben:Alles im "Hauptprogramm hat ja mit der Klasse Spiel zu tun - woher kommen dann die Informationen aus der Klasse Aufgabe?
Na, schau Dir mal die Methode 'Spiel.spielen()' an. Dort wird die Klasse 'Aufgabe' verwendet.

Re: Neuling sucht Rat

Verfasst: Samstag 30. März 2013, 07:38
von Sirius3
Hallo Tengel,
aus welchem Buch war das Beispiel gleich nochmal?

Klassen verwende ich nur ganz selten um etwas zu vererben.
Wenn Du Daten hast und Funktionen, die mit diesen Daten arbeiten, dann ist es einfach praktisch, diese in eine Klasse zu packen. Von der gleiche Struktur an Daten kann man dann viele Exemplare erzeugen, was ja bei globalen Variablen nicht möglich ist.

Re: Neuling sucht Rat

Verfasst: Samstag 30. März 2013, 08:02
von Sirius3
und hier noch die schlimmsten Fehler der Klasse Aufgabe:
1. ändere niemals den Zustand der Klasse in der Method __str__!!!
2. benutze niemals ein nacktes except, dadurch werden auch Schreibfehler (AttributeError) abgefangen und Du wirst nur sehr schwer den Grund für Programmierfehler finden. Hier wäre ein »except ValueError« das Mittel der Wahl.
3. benutze keine try-raise-except Konstrukte als goto-Ersatz.
4. vermische Eingabelogik nicht mit Berechnungen
5. Klassen sollten nur die Informationen enthalten, die sie auch brauchen. nr und gesamt beschreiben einen Zustand des Spiels und nicht der Aufgabe, haben also dort nichts zu suchen.

Re: Neuling sucht Rat

Verfasst: Samstag 30. März 2013, 08:28
von Sirius3
Das hier ist zum Lernen besser geeignet:

Code: Alles auswählen

import random

def input_int():
    """ Liest eine ganze Zahl von der Konsole.
    Wird keine Zahl eingegeben wird None zurueckgegeben."""
    try:
        return int(input())
    except ValueError:
        return None

class Spiel:
    def __init__(self):
        self.aufgaben = []
        
    def erzeuge_aufgaben(self):
        while True:
            print("Wie viele Aufgaben(1 bis 10)")
            anzahl = input_int()
            if anzahl and 1<=anzahl<=10:
                break
        self.aufgaben = [Aufgabe() for _ in range(anzahl)]

    def beantworte_aufgaben(self):
        for nr, aufgabe in enumerate(self.aufgaben,1):
            print("Aufgabe {nr} von {gesamt}: {aufgabe}".format(
                nr=nr, gesamt=len(self.aufgaben), aufgabe=aufgabe))
            antwort = input_int()
            aufgabe.setze_antwort(antwort)
            if aufgabe.ist_richtig():
                print('***Richtig***')
            else:
                print('***Falsch***')
        print("Alle Aufgaben beantwortet")
        
    def zeige_ergebnis(self):
        print(str(self))

    def __str__(self):
        #Ergebnis
        return "Richtig: {richtig} von {anzahl}".format(
            richtig=sum(1 if aufgabe.ist_richtig() else 0 for aufgabe in self.aufgaben),
            anzahl=len(self.aufgaben))

class Aufgabe:
    def __init__(self):
        self.a = random.randint(10,30)
        self.b = random.randint(10,30)
        self.ergebnis = self.a + self.b
        self.antwort = None

    def __str__(self):
        return "{a} + {b}".format(a=self.a, b=self.b)

    def setze_antwort(self, antwort):
        self.antwort = antwort
        
    def ist_richtig(self):
        return self.ergebnis == self.antwort

if __name__=='__main__':
    spiel = Spiel()
    spiel.erzeuge_aufgaben()
    spiel.beantworte_aufgaben()
    spiel.zeige_ergebnis()
Die Klasse »Aufgabe« erzeugt nur Aufgaben und prüft das Ergebnis, hat also keine UI.
Von »Aufgabe« gibt es mehrere Exemplare, man könnte sie zu einer Basisklasse machen und davon Klassen zum Addieren/Multiplizieren usw. ableiten.

Die Klasse »Spiel« ist dagegen eine reine UI-Klasse, nimmt also Eingaben vom Nutzer entgegen und gibt Text dazu aus. Außer für Statusmeldungen wird hier aber nichts gerechnet.
Mehrere Exemplare machen nicht wirklich Sinn. Hier soll nur Funktionen und Variablen an einem Ort gebündelt werden.

Re: Neuling sucht Rat

Verfasst: Samstag 30. März 2013, 19:34
von Tengel
Ich hab das halt 1:1 ausm Buch übernommen - Einstieg in Python von Thomas Theis und wie gesagt einfach nur oO?!?!?!?

Es wurde meiner Meinung nach nicht annähernd so erklärt das Gebilde da zu begreifen.

Ich dachte außerdem man nutzt Klassen für Objekte die man mehrmals benötigt - denn Einsatz bei so einem Spiel versteh ich nicht so ganz.

Re: Neuling sucht Rat

Verfasst: Samstag 30. März 2013, 20:50
von Hyperion
Tengel hat geschrieben: Ich dachte außerdem man nutzt Klassen für Objekte die man mehrmals benötigt.
Nö. Es gibt durchaus Klassen, von denen man im Programmverlauf nur ein einziges Exemplar erstellt - es gibt sogar einen Design-Pattern, der dieses explizit verfolgt: Den Singleton-Pattern.

Klassen sind ja mehr als nur "Schablonen" für zig Objekte. Sie dienen der Strukturierung und Kapselung von Daten und Funktionalität. Wenn man dann nur ein Exemplar während des Programms benötigt, wieso sollte man dann auf eine Klasse verzichten? Wenn diese sich als gute Möglichkeit darstellt, einen Sachverhalt zu modellieren, dann sollte man das auch nutzen - ungeachtet dessen, wie "oft" man diese im Programmablauf "verwendet".

Re: Neuling sucht Rat

Verfasst: Samstag 30. März 2013, 22:32
von Tengel

Code: Alles auswählen


import time
import _thread

#Thread Funktion
def show():
    print("Start Thread")
    for i in range(5):
        print(i,time.time())
        time.sleep(1.5)
    print("Ende Thread")
    return

#Hauptprogramm
print("Start Hauptprogramm:",time.time())
_thread.start_new_thread(show,())
time.sleep(10)
print("Ende des Hauptprogramms",time.time())



Dieses Beispiel soll Multithreading verdeutlichen - ich sehe da aber nix multi ...sondern nur einen Thread?

_thread.start_new_thread(show,()) und was genau hat das , da zu suchen - das hab ich an so einer Stelle noch nie gesehen.

Re: Neuling sucht Rat

Verfasst: Samstag 30. März 2013, 23:15
von BlackJack
@Tengel: Du solltest zwei ”sehen”. Einen der nichts tut (`sleep()`) und einen der `print()`-Ausgaben macht.

Das Beispiel verwendet das `_thread`-Modul — welches man nicht verwenden sollte, wie der führende Unterstrich eigentlich nahelegt. Threads erstellt man mit dem `threading`-Modul.

Re: Neuling sucht Rat

Verfasst: Samstag 30. März 2013, 23:26
von Tengel
Und was genau hat es mit dem , auf sich?

Irgendwie kommt es mir so vor als würde in dem Buch viel verwendet was man eigentlich anders machen sollte^^

Re: Neuling sucht Rat

Verfasst: Samstag 30. März 2013, 23:29
von Tengel

Code: Alles auswählen

import time
import _thread

def show():
    global counter
    id = _thread.get_ident()
    for i in range(5):
        counter+=1
        print(i,id,counter)
        time.sleep(1.5)
    return

#Hauptprogramm
id = _thread.get_ident()

counter = 0
print(id,counter)

_thread.start_new_thread(show,())
time.sleep(0.5)
_thread.start_new_thread(show,())
time.sleep(10)
counter += 1
print(id,counter)




also

Code: Alles auswählen

def show():
    global counter
    id = _thread.get_ident()
bedeutet das beim Funktionsaufruf für jeden aufrufenden Thread eine ID erstellt wird

und

Code: Alles auswählen

#Hauptprogramm
id = _thread.get_ident()
bedeutet das dem "Haupthread" auch eine ID zugewiesen wird.
Was bedeutet das 3 Threads laufen?

Re: Neuling sucht Rat

Verfasst: Samstag 30. März 2013, 23:53
von BlackJack
@Tengel: Das Komma hast Du ganz sicher an so einer Stelle schon gesehen, das trennt einfach die *zwei* Argumente die an `_thread.start_new_thread()` übergeben werden: Die `show`-Funktion und ein leeres Tupel.

Es wird nicht beim Funktionsaufruf eine ID für den jeweiligen Thread erstellt sondern wenn er gestartet wird. Die IDs gibt es unabhängig davon ob man sie abfragt oder nicht. Die werden vom System beziehungsweise der Threading-Bibliothek verwendet um die Threads identifizieren zu können.

Das 3 Threads laufen bedeutet, dass innerhalb des Prozesses der Code an drei Stellen (potentiell) *gleichzeitig* ausgeführt wird. Wenn `_thread.start_new_thread()` aufgerufen wird, dann wird danach der Code in der übergebenen Funktion *und* der Code nach dem Funktionsaufruf gleichzeitig, man sagt auch nebenläufig, ausgeführt.

Re: Neuling sucht Rat

Verfasst: Sonntag 31. März 2013, 02:20
von Tengel
Dateien- Dateitypen- Öffnen und Schließen einer Datei - nur gut das ich gar nicht verwirrt bin oO

Re: Neuling sucht Rat

Verfasst: Sonntag 31. März 2013, 20:46
von Tengel
Hm Kapitel bald durch dann kommt
-> Internet
-> Datenbanken
-> GUI

kann man das Internet Kapitel erstmal weglassen?^^

Re: Neuling sucht Rat

Verfasst: Montag 1. April 2013, 11:47
von Hyperion
Tengel hat geschrieben: kann man das Internet Kapitel erstmal weglassen?^^
Wieso nicht? Thematisch scheinen das ja weiterführende Kapitel zu sein... sofern das keine Aufhänger Themen sind, an denen Sprachgrundlagen erklärt werden, kannst Du Dir doch die Themen raussuchen, die Dich interessieren. In einem guten Buch sollte das - möglichst zu Beginn - auch explizit erwähnt werden.

Re: Neuling sucht Rat

Verfasst: Montag 1. April 2013, 21:27
von Tengel
Nachdem mein letztes Kapitel Dateien lesen und schreiben war und ich damit irgend etwas "anfangen" wollte hab ich nun versucht ein kleines Programm zu schreiben das eine Eingabe speichert - in diesem Fall, denn Trafficverbrauch meines Surfsticks da dieser leider nur denn Verbrauch je Sitzung speichert.

Code: Alles auswählen

import glob
import pickle


def traffic_lesen():
    global traffic

    if not glob.glob("traffic.bin"):
        traffic = []
        return

    d = open("traffic.bin","r")
    traffic = pickle.load(d)
    d.close()
    traffic = traffic+neuer_verbrauch


def traffic_anzeigen():
    if not traffic:
        print("Kein Traffic verbrauch bisher")
        return
    print(traffic)

def traffic_schreiben():
    d = open("traffic.bin","w")
    pickle.dump(traffic,d)
    d.close()


def eingabe():
    try:
        neuer_verbrauch = int(input("Bitte den verbrauchten Traffic eingeben: "))
    except:
        print("Falsche Eingabe")





# Hauptprogramm



traffic_lesen()


while True:
    auswahl = int(input("Bitte wählen\n0: Beenden\n1: momentanen Verbrauch anzeigen:\n2: Verbrauch aktualisieren:\nIhre Eingabe: "))
    if auswahl == 0:
        break

    if auswahl == 1:
        print("Der momentane verbrauch liegt bei: ")
        traffic_anzeigen()
        print()

    if auswahl == 2:
        eingabe()

traffic_schreiben()

    

    


Da ich gerade auf Arbeit bin hab ich leider mein Buch nicht da und musste mich am Beispiel Spiel orientieren und mir das gewünschte ableiten - leider klappt das nicht so wie ich mir das vorgestellt habe.

Das "w" - also das "gnadenlose Überschreiben" nutze ich - da ich nicht weiß wie genau ich nur denn letzen Wert abfrage.
Ich möchte hier natürlich kein laufendes Programm - sondern nur einen Denkanstoß was falsch ist.