Trotz (vermeintlich) erfüllter Bedingung geschieht nichts

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.
Antworten
Krabman318
User
Beiträge: 21
Registriert: Sonntag 14. August 2011, 14:36

Mein Problem ist folgendes:
Ich möchte eine Methode so definieren, dass eine Variable verändert wird, und wenn diese größer als 2 und größer als 5 andere Variablen ist, "mehrheit" ausgegeben wird.
Nach dreimaligem Aufrufen der Methode mit immer gleichem Parameter geschieht jedoch nichts, obwohl die Bedingung scheinbar erfüllt ist.
Was ist jetzt der Fehler? :?:

Code: Alles auswählen

global votes1,votes2,votes3,votes4,votes5,votes6
votes1 = 0
votes2 = 0
votes3 = 0
votes4 = 0
votes5 = 0
votes6 = 0

def define_names(player1, player2, player3, player4, player5, player6):
    global playerlist
    playerlist = [player1, player2, player3, player4, player5, player6]
    global playertupel
    playertupel = (playerlist)

define_names("Mauritz","Luigi","Giuseppe","Giacomo","Moritz","Paolo")

vote_dictionary = {playertupel[0] : votes1, playertupel[1] : votes2,
                   playertupel[2] : votes3, playertupel[3] : votes4,
                   playertupel[4] : votes5, playertupel[5] : votes6}

class Villager:
    def __init__(self, werewolf = False, alive = True, awake = True, name = "Default"):
        self.werewolf = werewolf
        self.alive = alive
        self.awake = awake
        self.name = name
        #diese Methode:
        def voting(self, vote):
            if vote in playertupel:
                print "Eine Stimme mehr für " + vote
                vote_dictionary[vote] += 1
                print (vote_dictionary[vote])
                if (vote_dictionary[vote] == max(vote_dictionary)
                and vote_dictionary[vote] > 2):
                    print "mehrheit"
            elif vote not in playertupel:
                print "Gib einen existierenden Spieler an!"
Mauritz = Villager()
deets

Whao. Spannend. Statt "define_names" wuerde ein einfaches

Code: Alles auswählen

playerlist = ["Mauritz", ...]
voellig reichen. Dann kommst du auch ohne globals aus, und kannst die Anzahl deiner Mitspieler variieren.


Das vote-dictionary solltest du so machen:

Code: Alles auswählen

from collections import defaultdict

vote_dictionary = defaultdict(lambda: 0)
Und was dein Villager so genau sein soll ist mir nicht klar, aber fehlt da nicht mindestens ein *name*? Und wann das das wichtigste Argument ist, sollte das auch das erste sein... und keinen default haben.
BlackJack

@Krabman318: Die Verwendung von ``global`` ist schon mal falsch. Davon abgesehen, dass es auf Modulebene gar keinen Effekt hat, sollte man da sowieso die Finger von lassen.

Dann ist der Name `playertupel` falsch. Daran bindest Du das selbe Objekt wie an den Namen `playerslist`. Klammern erzeugen kein Tupel (mit Ausnahme beim leeren Tupel) sondern sind einfach nur Klammern und haben hier keinen weiteren Effekt. Den Namen der Datenstruktur sollte man aber sowieso aus dem Namen heraus halten. Und die Funktion `define_names` ist irgendwie sinnfrei.

Namen sollte man nicht durchnummerieren. Wenn man das tut, will man in der Regel eigentlich eine Liste verwenden und der *einen* Namen geben.

Bei `vote_dictionary` steckt wieder der Name der Datenstruktur drin. Namen sollten eher die Bedeutung im Programm, denn die Typen angeben. Also zum Beispiel `name2votes` für ein Wörterbuch das Namen auf Stimmen abbildet.

Dieses ganze furchtbare durchnummerierte Zeugs vor der Klasse könnte man in folgenden zwei Zeilen ausdrücken:

Code: Alles auswählen

names = ['Mauritz', 'Luigi', 'Giuseppe', 'Giacomo', 'Moritz', 'Paolo']
name2votes = dict.fromkeys(names, 0)
Bei `Villager.__init__()` würde ich die Argumente so anordnen, dass die die sich auf jeden Fall, oder zumindest sehr wahrscheinlich von Default unterscheiden, weiter vorne stehen. Der Name zum Beispiel erscheint mir am wichtigsten und da würde ich auch gar keinen Default für angeben. Denn wie oft braucht man schon wirklich eine Person mit dem Default-Namen "Default".

`Villager.voting()` ist falsch eingerückt.

In der Methode werden globale Datenstrukturen verwendet. Das ist keine gute Idee, weil es das Programm unübersichtlich macht und alles fest miteinander verbindet. Werte die in Methoden verwendet werden und keine Konstanten sind, sollten entweder Attribute des Objekts sein, oder als Argumente übergeben werden.

Ein Fehler liegt im inneren ``if`` in dieser Methode. Der erste Teil der Bedingung kann nie wahr werden. Lass Dir einfach mal die Ergebnisse der Teilausdrücke des Vergleichs ausgeben, dann wird schnell klar warum das nicht das ist was Du denkst was es bedeutet.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Deets, es scheint sich dabei um http://de.wikipedia.org/wiki/Die_Werw%C ... BCsterwald zu handeln. Das wichtigste an den Dorfbewohnern ist schon, ob sie ein Werwolf sind oder nicht. Namen sind Schall und Rauch.

Krabman318, deine "Methode" voting() ist falsch eingerückt und daher gar keine Methode sondern eine lokale Funktion von __init__. Dass das Programm deutlich kürzer sein konnte, hatte Deets ja schon erwähnt. Versuche mal, auf alle "global"-Deklarationen zu verzichten und möglichst auf auf globale Variablen. Definiere vielleicht noch ein Dorf-Objekt, das alle Dorfbewohner kennt oder eine Abstimmung, die weiß, wie die Dörfler gewählt haben.

Stefan
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Was soll das Attribut `werewolf` überhaupt repräsentieren?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@Hyperion: Ob der Dörfler der Werwolf ist oder nicht. Ist also ein Flag. sma hat das Spiel ja bereits verlinkt. Ist ganz witzig.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

BlackJack hat geschrieben:@Hyperion: Ob der Dörfler der Werwolf ist oder nicht. Ist also ein Flag. sma hat das Spiel ja bereits verlinkt. Ist ganz witzig.
Ich würde das Attribut dann aber is_werewolf nennen. Das Spiel an sich ist aber in der Tat recht nett, vor allem mit > 10 Mitspielern.
Antworten