Seltsamer Fehler (Pygame)

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.
rady
User
Beiträge: 20
Registriert: Dienstag 3. Mai 2005, 17:08

print schuesse_liste :
(398, 378)

-------------

schuesse_liste[0]=x+42
TypeError: object does not support item assignment


wo is das problem an schuesse_liste[0]=398+42 ?
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Hi!

Naja, anscheinend ist schuesse_liste keine Liste, sondern ein Tupel, und damit immutable ;)

Code: Alles auswählen

>>> l = [1,2,3]
>>> l[0] = 3     # alles ok
>>> t = (1,2,3)
>>> t[0] = 3
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: object does not support item assignment
Gruß, mawe
rady
User
Beiträge: 20
Registriert: Dienstag 3. Mai 2005, 17:08

danke dir !
BlackJack

Ein paar Kritikpunkte vom ewigen Nörgler :-)

Man sollte die `import` Form mit dem ``*`` nicht verwenden, weil man sich damit viele Namen in das Modul holt die man gar nicht benutzt, die aber unter Umständen Probleme machen können. Also zum Beispiel anstatt alles aus dem `random` Modul zu importieren, lieber nur die Namen importieren, die man auch wirklich verwendet, oder sie über das Modul dereferenzieren.

Code: Alles auswählen

from random import randint
dice = randint(1, 6)
# oder
import random
dice = random.randint(1, 6)
Anstelle von `1` und `0` für Wahrheitswerte sind `True` und `False` wesentlich verständlicher.

Die Funktion `menue_optionen` ist, äh, subobtimal. Du willst nacheinander Tasten abfragen und verschachtelst für jede Taste immer tiefere Schleifen. Das sollte in *eine* Schleife gepackt werden, die nacheinander die Tastenbelegung erfragt.

Den Quelltext sollte man sowieso nicht dermassen tief einrücken. Eine Zeile sollte nach 80 Zeichen zuende sein. Und bei Python wird traditionell pro Ebene um vier Leerzeichen eingerückt. Wo wir gerade bei Leerzeichen sind: es sind zu wenig Leerzeichen, z.B. zwischen Operatoren und nach Kommata sollten welche stehen. Wenn man sich Quelltext mal ohne Syntaxhighlighting anschaut, dann wird es schnell sehr unübersichtlich wenn Namen, Gleichheitszeichen und Operatoren alle aneinander kleben.

Einige Abfragen von Wertebereichen kann man kürzer schreiben, weil man in Python auch mehr als einen Vergleich auf einmal machen kann:

Code: Alles auswählen

if x > 0 and x < 100: pass
# ==
if 0 < x < 100: pass
Die beiden Funktionen `vorwaertsrechner()` und `rueckwaertsrechner()` lassen sich zusammenfassen und ohne die vielen ``if``s schreiben:

Code: Alles auswählen

def rechner(ausrichtung, x, y, vorwaerts=True, faktor=1):
    deltas = ((0, 8), (-2, 6), (-4, 4), (-6, 2),
              (-8, 0), (-6, -2), (-4, -4), (-2, -6),
              (0, -8), (2, -6), (4, -4), (6, -2),
              (8, 0), (6, 2), (4, 4), (2, 6))
    
    delta_x, delta_y = deltas[ausrichtung]
    delta_x *= faktor
    delta_y *= faktor
    if vorwaerts:
        return (x + delta_x, y + delta_y)
    else:
        return (x - delta_x, y - delta_y)
Ich habe noch einen `faktor` eingeführt weil Du die Funktion später zweimal aufrufst um doppelte Geschwindigkeit zu erreichen.

In `verschollen()` ist der `verschollen_status` überflüssig.

Die Funktion `collision` ist furchtbar unübersichtlich. Als erstes würde ich da über die Liste `liste` iterieren und nicht den Index `k` benutzen. Und vielleicht den Elementen der Listenelemente Namen geben, damit es nicht so undurchsichtig bleibt:

Code: Alles auswählen

for (dummy, asteroid_x, asteroid_y, speed, zahl) in liste:
    # ...
Dann brauchst Du auch das `level` nicht mehr an die Funktion übergeben. Eine Liste "weiss" ja selbst wie lang sie ist.

Ähnliches gilt für die ``for c in range(level+1)`` Schleife in `level_ablauf()`. In der Funktion ist übrigens eine Rekursion von der ich nicht glaube, dass Du die da wirklich drin haben möchtest.

In `menu_highscore` wird die Datei nicht wieder geschlossen. Und das Anzeigen der Tabelle würde ich in einer Schleife machen.

Insgesamt würde dem ganzen Spiel ein wenig Objektorientierung gut tun.
rady
User
Beiträge: 20
Registriert: Dienstag 3. Mai 2005, 17:08

weil Du die Funktion später zweimal aufrufst um doppelte Geschwindigkeit zu erreichen
hö ? was wo ? weiss ich nichts von :shock:

Objektorientierung ? hatten wir nicht in der schule 8)

aber danke für die tips. ein paar sachen werd ich später sicher noch einbaun.
was mich aber noch interessiert :was genau meinst du mit
das Anzeigen der Tabelle würde ich in einer Schleife machen

thx :)
BlackJack

rady hat geschrieben:
weil Du die Funktion später zweimal aufrufst um doppelte Geschwindigkeit zu erreichen
hö ? was wo ? weiss ich nichts von :shock:
Ups, da habe ich mich geirrt. In `keyboard_action()` rufst Du `vorwaertsrechner()` und `rueckwaertsrechner()` jeweils zweimal auf. Der jeweils erste Aufruf hat keinen Effekt, den kannst Du rausnehmen.
was mich aber noch interessiert :was genau meinst du mit
das Anzeigen der Tabelle würde ich in einer Schleife machen
Ungetestet:

Code: Alles auswählen

    it = iter(scores_content)
    for (i, (name, score)) in enumerate(zip(it, it)):
        y_pos = 210 + 40 * i
        screen.blit(scores_text.render(name, 1, white), [200, y_pos])
        screen.blit(scores_text.render(score, 1, white), [500, y_pos])
`scores_text` sollte besser `scores_font` heissen.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

BlackJack hat geschrieben:Man sollte die `import` Form mit dem ``*`` nicht verwenden, weil ...

Code: Alles auswählen

from random import randint
dice = randint(1, 6)
# oder
import random
dice = random.randint(1, 6)
Ich tendiere immer ehr dazu die zweite Variante zu nehmen... Auch wenn man mehr Tippen muß, man weiß einfach besser woher die Dinge (in dem Beispiel "randint()") kommen ;)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten