Seite 1 von 3

Problem mit update() bei Dict's

Verfasst: Sonntag 2. Dezember 2012, 21:56
von jtschoch
Hallo,
Ich möchte in einen Dictionary zwei Werte updaten.
die normale Ausgabe ist so:

Code: Alles auswählen

0, 0
0, 1
0, 2
0, 3
0, 4
1, 1
.
.
.
Wenn ich es ausprinten lasse ist das so, aber ich habe in meinen Dict sind sie nicht so, die Ausgabe ist so:

Code: Alles auswählen

{'action': None, 'y': 4, 'tile': '/gametiles/baum1.png', 'x': 2}
{'action': None, 'y': 4, 'tile': '/gametiles/grass.png', 'x': 3}
{'action': None, 'y': 4, 'tile': '/gametiles/grass.png', 'x': 3}
{'action': None, 'y': 4, 'tile': '/gametiles/grass.png', 'x': 3}
{'action': None, 'y': 4, 'tile': '/gametiles/grass.png', 'x': 3}
{'action': None, 'y': 4, 'tile': '/gametiles/baum1.png', 'x': 2}
{'action': None, 'y': 4, 'tile': '/gametiles/grass.png', 'x': 3}
{'action': None, 'y': 4, 'tile': '/gametiles/grass.png', 'x': 3}
{'action': None, 'y': 4, 'tile': '/gametiles/grass.png', 'x': 3}
{'action': None, 'y': 4, 'tile': '/gametiles/grass.png', 'x': 3}
{'action': None, 'y': 4, 'tile': '/gametiles/grass.png', 'x': 3}
{'action': None, 'y': 4, 'tile': '/gametiles/grass.png', 'x': 3}
{'action': None, 'y': 4, 'tile': '/gametiles/grass.png', 'x': 3}
{'action': None, 'y': 4, 'tile': '/gametiles/grass.png', 'x': 3}
{'action': None, 'y': 4, 'tile': '/gametiles/grass.png', 'x': 3}
{'action': None, 'y': 4, 'tile': '/gametiles/grass.png', 'x': 3}
{'action': None, 'y': 4, 'tile': '/gametiles/baum2.png', 'x': 4}
{'action': None, 'y': 4, 'tile': '/gametiles/grass.png', 'x': 3}
{'action': None, 'y': 4, 'tile': '/gametiles/grass.png', 'x': 3}
{'action': None, 'y': 4, 'tile': '/gametiles/grass.png', 'x': 3}
{'action': None, 'y': 4, 'tile': '/gametiles/baum3.png', 'x': 0}
{'action': None, 'y': 4, 'tile': '/gametiles/grass.png', 'x': 3}
{'action': None, 'y': 4, 'tile': '/gametiles/baum1.png', 'x': 2}
{'action': None, 'y': 4, 'tile': '/gametiles/grass.png', 'x': 3}
{'action': None, 'y': 4, 'tile': '/gametiles/baum2.png', 'x': 4}
Warum? Ich sehe da keine 1, 1 und so.

Hier ist der Code:

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
Generate the playingfield
"""
#~Imports

import cPickle as pickle
import random

#~Define arena

height_rows=5
width_cols=5

#~Define images

grass = {"tile" : "/gametiles/grass.png", "action" : None, "x" : None, "y": None}
baum1 = {"tile" : "/gametiles/baum1.png", "action" : None, "x" : None, "y": None}
baum2 = {"tile" : "/gametiles/baum2.png", "action" : None, "x" : None, "y": None}
baum3 = {"tile" : "/gametiles/baum3.png", "action" : None, "x" : None, "y": None}

#~Variables

row=[]
for y in range(height_rows):
    col=[]
    for x in range(width_cols):
        number = random.randint(1, 10)
        if number == 5:
            baum1.update({"x" : x, "y" : y})
            col.append(baum1)      
        elif number == 1:
            baum2.update({"x" : x, "y" : y})
            col.append(baum2) 
        elif number == 7:
            baum3.update({"x" : x, "y" : y})
            col.append(baum3)
        else:
            grass.update({"x" : x, "y" : y})
            col.append(grass)
    row.append(col)
for i in row:
    for i in i:
        print i
name = raw_input("mapname: ")
pickle.dump(row, open("../maps/" + name + ".sav", "wb" ) )
print "fertig"

Re: Problem mit update() bei Dict's

Verfasst: Sonntag 2. Dezember 2012, 23:00
von BlackJack
@jtschoch: Du hast da egal wie gross das Spielfeld ist *vier* Wörterbücher und mit den `update()`-Aufrufen veränderst Du immer die selben vier Objekte. Das heisst wenn Du einem `grass.update(…)` zum Beispiel mit den Werten für Feld 1,1 ausführst und später zum Beispiel noch einmal für Feld 2,3 dann ersetzt Du im *selben* Objekt die Werte von vorher.

Du musst vor dem Ändern eine Kopie von dem jeweiligen Wörterbuch erstellen und die dann aktualisieren und dem Spielfeld hinzufügen.

Der Vergleich mit den Zahlen 5, 1, und 7 ist total willkürlich. Da würde ich 1, 2, 3 nehmen, das ist weniger verwirrend und kommt auf das gleiche Ergebnis hinaus.

Re: Problem mit update() bei Dict's

Verfasst: Montag 3. Dezember 2012, 10:41
von jbs
Wenn es etwas meta sein darf, dann kannst du deine if-Abfrage so zusammen fassen:

Code: Alles auswählen

trees = [ {...}, {...}, {...} ]
...
number = random.randint(0, 9)
if number <= 3:
    to_update = trees[number]
else:
    to_update = grass

to_update.update(...)

Re: Problem mit update() bei Dict's

Verfasst: Montag 3. Dezember 2012, 10:48
von BlackJack
Das ``if``/``else`` könnte man sich noch sparen wenn man `max()` verwendet.

Code: Alles auswählen

field = field_prototypes[max(randint(9), 4)].copy().update(...)

Re: Problem mit update() bei Dict's

Verfasst: Montag 3. Dezember 2012, 13:48
von jbs
Meintest du nicht min?

Re: Problem mit update() bei Dict's

Verfasst: Montag 3. Dezember 2012, 13:54
von BlackJack
@jbs: Ja, meinte ich natürlich. :oops:

Re: Problem mit update() bei Dict's

Verfasst: Montag 3. Dezember 2012, 16:39
von jtschoch
Da kommt aber am ende None raus!

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
Generate the playingfield
"""
#~Imports

import cPickle as pickle
import random

#~Define arena
#5*5 = 25

height_rows=5
width_cols=5

#~Define images
objects =  \
[
{"tile" : "/gametiles/grass.png", "action" : None, "x" : None, "y": None},
{"tile" : "/gametiles/baum1.png", "action" : None, "x" : None, "y": None},
{"tile" : "/gametiles/baum2.png", "action" : None, "x" : None, "y": None},
{"tile" : "/gametiles/baum3.png", "action" : None, "x" : None, "y": None}
]
tiles = 3
#~Variables

row=[]
for y in range(height_rows):
    col=[]
    for x in range(width_cols):
        col.append(objects[min(random.randint(1, 9), tiles)].copy().update({"x" : x, "y" : y}))
    row.append(col)
for i in row:
    for i in i:
        print i
name = raw_input("mapname: ")
pickle.dump(row, open("../maps/" + name + ".sav", "wb" ) )
print "fertig"

Re: Problem mit update() bei Dict's

Verfasst: Montag 3. Dezember 2012, 16:41
von BlackJack
@jtschoch: Stimmt. Man muss es geringfügig ändern.

Die Namen sind übrigens teilweise schlecht gewählt. `row` steht nicht für *eine* Zeile sondern viele, und `col` steht nicht für eine Spalte, sondern für eine Zeile. Das ist verwirrend.

Von dem `i` in der zweiten ``for``-Schleife auf Modulebene mal ganz zu schweigen. Das ist ziemlich grausam.

Re: Problem mit update() bei Dict's

Verfasst: Montag 3. Dezember 2012, 16:57
von jtschoch
Oh ja, die schleife soll eigentlich gar nicht ausgeprintet werden hab es nur schnell hingeschrieben,
aber das ändert trotzdem nix!

Achso wie könnte ich es sonnst zum Beispiel nennen?

Re: Problem mit update() bei Dict's

Verfasst: Montag 3. Dezember 2012, 17:04
von EyDu
jtschoch hat geschrieben:Achso wie könnte ich es sonnst zum Beispiel nennen?
"row" als "rows" und "col" als "row".

Re: Problem mit update() bei Dict's

Verfasst: Montag 3. Dezember 2012, 17:08
von jtschoch
Aber das ändert an den None auch nix!

Re: Problem mit update() bei Dict's

Verfasst: Montag 3. Dezember 2012, 17:19
von EyDu
Du packst doch auch jede Menge Nones rein. Schau dir die Stelle an, bei der die Listen befüllt werden und zerlege Ausdrücke in Teilausdrücke.

Re: Problem mit update() bei Dict's

Verfasst: Montag 3. Dezember 2012, 17:23
von jtschoch
hä wie, verstehe gerade Bahnhof sorry!

Re: Problem mit update() bei Dict's

Verfasst: Montag 3. Dezember 2012, 17:35
von EyDu
Du sollst dir einfach anschauen was du in cols packst.

Re: Problem mit update() bei Dict's

Verfasst: Montag 3. Dezember 2012, 17:40
von jtschoch
Hä ich pack das rein,

Code: Alles auswählen

col.append(objects[min(random.randint(1, 9), tiles)].copy().update({"x" : x, "y" : y}))
was ist daran falsch?

Re: Problem mit update() bei Dict's

Verfasst: Montag 3. Dezember 2012, 17:41
von cofi
Der Rueckgabewert von `dict.update`

Re: Problem mit update() bei Dict's

Verfasst: Montag 3. Dezember 2012, 18:07
von jtschoch
Verstehe das trotzdem noch nicht :(

Re: Problem mit update() bei Dict's

Verfasst: Montag 3. Dezember 2012, 18:09
von jbs
Rufe mal im interaktiven Modus ``print({}.update({}))`` auf.

Re: Problem mit update() bei Dict's

Verfasst: Montag 3. Dezember 2012, 18:11
von jtschoch
None, weil der Return None ist, muss ich dann objects adden?
Könnt ihr mir bitte mal eine Lösung oder den richtigen Code schicken habe überhaupt keinen Plan.

Re: Problem mit update() bei Dict's

Verfasst: Montag 3. Dezember 2012, 18:19
von jbs
Ich denke, es ist besser die Schritte einzeln durchzuführen. BlackJacks Beispiel ist eher akademisch interessant und nicht unbedingt im Produktiveinsatz zu empfehlen. Code sollte möglichst klar und verständlich für alle sein, auch wenn jeder etwas anderes darunter versteht.