verdammt, ich kapier es einfach nicht

Fragen zu Tkinter.
Benutzeravatar
wuf
User
Beiträge: 1419
Registriert: Sonntag 8. Juni 2003, 09:50

Freitag 11. Juli 2008, 18:11

Hallo

@numerix & @EyDu -> Danke noch für eure Vorschläge

Hier ist noch die dritte Variante. Habe die for...Schleifen noch in einer neuen Funktion 'create_poly_array' untergebracht. Das Code-Snippet enthält noch keine Klasse.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

# Skriptname derkai_05_02_03 (11.07.2008)

import Tkinter as tk
from math import sqrt,sin,cos,pi
from random import choice

def create_xyoffset(length):
    """Berechnet die XY-Versatzabstände"""

    poly_data = [(cos(pi/3*x)*length,sin(pi/3*x)*length) for x in range(6)]

    xa,ya = poly_data[0]
    xb,yb = poly_data[1]
    xc,yc = poly_data[5]

    return (length+(xa-xb),yb-yc)

def create_hex_polygon(spiel_feld,length,xpos,ypos,farbe):
    """Erzeugt das grafische Sechseck-Objekt"""

    poly_data = [(cos(pi/3*x)*length+xpos,
        sin(pi/3*x)*length+ypos) for x in range(6)]

    poly_obj = spiel_feld.create_polygon(
        poly_data,outline="black",fill=choice(farbe))

    return poly_obj

def create_poly_array(spiel_feld,xorg,yorg,spalten,zeilen,hex_laenge,farbe):
    """Platziere ein zweidimensionalen Sechseck-Array"""

    xpos = xorg
    ypos = yorg
    toggle = 0
    poly_id_list = []

    #~~ Berechnung der XY-Versatzabstände für die Platzierung der Sechsecke
    xoffset,yoffset = create_xyoffset(hex_laenge)

    #~~ Poly Objekte platzieren
    for x in xrange(spalten):
        for y in xrange(zeilen):
            poly_id = create_hex_polygon(spiel_feld,hex_laenge,xpos,ypos,farbe)
            ypos += yoffset
            poly_id_list.append(poly_id)

        xpos += xoffset

        if not toggle:
            toggle = 1
            ypos = yorg + yoffset/2.0
        else:
            toggle = 0
            ypos = yorg

    return poly_id_list

def main():
    #~~ Erzeugt das Hauptfenster
    master = tk.Tk()
    spiel_feld = tk.Canvas(master, width=1024, height=768)
    spiel_feld.pack()

    HEX_LAENGE = 20.0 # Seitenlänge
    XORG = 30         # X Start-Koordinate
    YORG = 30         # Y Start-Koordinate
    SPALTEN = 10      # Anzahl Spalten
    ZEILEN = 10       # Anzahl Zeilen
    HEX_FARBE = ("yellow","green","blue","red") # Zufalls-Farben

    poly_id_list = create_poly_array(
        spiel_feld,XORG,YORG,SPALTEN,ZEILEN,HEX_LAENGE,HEX_FARBE)

    print poly_id_list

    master.mainloop()

main()
Wie steht es mit der PEP8-Konformität bitte kontrollieren. Verbesserungsvorschläge.

Gruss wuf :wink:
Zuletzt geändert von wuf am Freitag 11. Juli 2008, 19:37, insgesamt 1-mal geändert.
Take it easy Mates!
derkai
User
Beiträge: 169
Registriert: Montag 12. Mai 2008, 11:43

Freitag 11. Juli 2008, 18:23

ja und nein, ich habe es leider noch nicht vollständig verstanden, beschränke mich aber für den Moment auf den URsprungscode.
Eh ich den nicht vollständig begriffen habe, möchte ich mich noch
nicht an Verändeurngen ran machen.

Leider hatte ich bisher kaum Zeit mich "wieder ein zu denken". Das mach
ich aber heute abend und morgen vormittag.

Ich würde dann bestimmt wieder ne Frage fragen.

Trotzdem muss ich auch den Original Code nochmals ändern, da
ich es mir in den Kopf gesetzt hatte, dass der Aufbau und speziell die Reihenfolge der Hexfelder anders von statten gehen soll.
(bin halt ´n kleiner Sturkopf, sagt meine Frau)

Die Felder sollen sich zeilenweise von links nach rechts aufbauen. Betrachtet man das Spielfeld, so würde das 1. Hesagon natürlich "links oben" erzeugt werden. Weiter ging es dann x + 2 x laenge, y ist gleiche Höhe. Und das so lange, bis 15 .. 16 Felder nebeneinander horizontal aufgebaut sind. Danach erfolgt die nächste Zeile. x = x + laenge

Deswegen und weil ich es mir anders ausgemalt hatte, habe ich im Moment auch noch Schwierigkeiten mit dem Code.

Ich werde aber jetzt mal weiter drüber brüten ...

Die Geschwindigkeit ist genial !!!!

besten Dank

Kai
imac
20 Zoll
2,4 ghz
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Freitag 11. Juli 2008, 18:27

wuf hat geschrieben:Verbesserungsvorschläge.
Die Sache mit dem toggle in Zeile 52-59 kann man sich sparen.
Stattdessen einfach

Code: Alles auswählen

ypos = yorg + (x+1)%2*0.5*yoffset
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Freitag 11. Juli 2008, 18:32

derkai hat geschrieben:Trotzdem muss ich auch den Original Code nochmals ändern, da ich es mir in den Kopf gesetzt hatte, dass der Aufbau und speziell die Reihenfolge der Hexfelder anders von statten gehen soll.

Die Felder sollen sich zeilenweise von links nach rechts aufbauen.
Warum willst du das so haben? Wichtig ist doch für das Spielfeld nur das Ergebnis und das ist doch - jedenfalls auf meinem 7 Jahre alten Rechner - sofort nach dem Start komplett da. Wenn du beim Aufbau zugucken willst, dann nimm halt wieder das frog-Modul ... :wink:
derkai
User
Beiträge: 169
Registriert: Montag 12. Mai 2008, 11:43

Freitag 11. Juli 2008, 18:49

weil wenn ICH das hinbekomme, dann hab ich es KAPIERT.
Ausserdem dachte ich halt, dass ich bei jedem Schleifendurchlauf
direkt die Koordinaten + n speichern könnte. z.b. in einem Dictionary.
Dann hätte ich später eine Lister aller Koordinaten.
Ich weiss, dass geht soo auch.

Aber wenn ich später noch Entfernung und Bewegung einfügen muss,
dann wäre es doch bestimmt einfacher, oder ? (auch für den Kopf)

Denkst Du denn, es wäre anders programmiert langsamen ?
Es geht nicht ums zugucken, sondern um die Reihenfolge
:D

Kai
imac
20 Zoll
2,4 ghz
derkai
User
Beiträge: 169
Registriert: Montag 12. Mai 2008, 11:43

Freitag 11. Juli 2008, 18:57

mit diesen "booleschen" Ausdrücken habe ich
auch noch so mein Problem.

toggle = 0

Code: Alles auswählen

if not toggle:
            toggle = 1
            ypos = yorg + yoffset/2.0
        else:
            toggle = 0
            ypos = yorg
Was passiert hier genau ?
Ich weiss, dass hier entchieden wird, ob die Spalte Versatz haben soll, oder nicht. Aber wie könnte man das "umgangssprachlich" beschreiben.

Gruß
kai
imac
20 Zoll
2,4 ghz
derkai
User
Beiträge: 169
Registriert: Montag 12. Mai 2008, 11:43

Freitag 11. Juli 2008, 19:02

und dann noch eine kleine andere Frage :

Code: Alles auswählen

def create_hex_polygon(spiel,xpos,ypos,points,farbe):
    """Erzeugt das grafische Sechseck-Objekt"""

    x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,x6,y6 = points

    x1 += xpos
    y1 += ypos
    x2 += xpos
    y2 += ypos
    x3 += xpos
    y3 += ypos
    x4 += xpos
    y4 += ypos
    x5 += xpos
    y5 += ypos
    x6 += xpos
    y6 += ypos

    return spiel.create_polygon(x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,x6,y6,
                outline="black",fill=choice(farbe))
in die Funktion wird das Argument "points" übergeben. Dieses erhält dann die Werte aus hex_point_list.

Frage ?
was macht diese Zeile : x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,x6,y6 = points
wenn doch die weitere Verarbeitung weiter unten statt findet ?
imac
20 Zoll
2,4 ghz
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Freitag 11. Juli 2008, 19:07

derkai hat geschrieben:Ich weiss, dass hier entchieden wird, ob die Spalte Versatz haben soll, oder nicht. Aber wie könnte man das "umgangssprachlich" beschreiben.
Umgangssprachlich: Es wird immer abwechselnd die Hälfte von yoffset dazu addiert oder eben nicht. Das toggle sorgt dafür, dass es immer abwechselnd (alternierend) passiert. Wie man das kürzer machen kann, habe ich ja schon gepostet.

derkai hat geschrieben:was macht diese Zeile : x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,x6,y6 = points
Das nennt man "Entpacken einer Sequenz": Die einzelnen Koordinaten der Sequenz points werden den Variablen x1 ... y6 zugewiesen. Auch das ist hier ja nicht erforderlich, wie schon gezeigt wurde.
Benutzeravatar
wuf
User
Beiträge: 1419
Registriert: Sonntag 8. Juni 2003, 09:50

Freitag 11. Juli 2008, 20:36

Hallo derkai

Das ist klar wir machen hier erst weiter, wenn du verstanden hast wie dein Spiel-Code abläuft und was er macht, und natürlich, dass er so abläuft wie du dir es vorgestellt hast. Es kamen in kurzer Zeit sehr viele interessante Vorschläge für die Code-Optimierung und Minimierung zusammen. Aber es ist schon so, dass bei den ersten Programmier-Gehversuchen einem viel neues über den Weg läuft. Sicher ist es besser den Code so zu schrieben, dass man in ohne grosse Decodierarbeit beim durchlesen versteht. Das optimieren kann später erfolgen

Das mit der Platzierung der Poly-Objekte von link nach rechts machen wir sollte kein Problem sein. Wegen den Positions-Koordinaten jedes platzierten Objekt es mache dir auch keine Sorgen. Du kannst die Eigenschaften jedes platzierten Poly-Objektes über dessen ID-Nummer abfragen. Bei der Erstellung des Poly-Objektes gibt die 'create_poly'-Methode eine ID-Nummer (Ganzzahl) des erstellten Objektes zurück. Wie du richtig vermutet hast müssen diese Nummern gespeichert werden. Ich habe bei der letzten dritten Variante eine Sammel-Liste 'poly_id_list' hierfür verwendet.

So wie ich dich verstanden habe möchstes du nicht mehr zu deinem Projekt mit dem frog-Modul zurück sondern zum ersten Code-Snippet unter dem Post vom Do Jul 10, 2008 18:04. Ist das richtig?

Die 5. Zeile dieses Code-Snippets sieht wie folgt aus:

Code: Alles auswählen

# Skriptname derkai_05_02 (10.07.2008)
Dort hast du noch dein eigenes Code-Fragment für die Berechnung der Sechseck Eckdaten drin. Wenn du möchtest fahren wir dort weiter. Überlege dirs. Wir machen das nach deiner Tempovorgabe. Step by Step bis du jede Code-Zeile verstehst. Wir haben hier keine Zeittreibende Bestie hinter uns stehen. :lol:

OK. derkai Gruss wuf :wink:
Take it easy Mates!
derkai
User
Beiträge: 169
Registriert: Montag 12. Mai 2008, 11:43

Freitag 11. Juli 2008, 20:46

ihr seit wirklich klasse, aber wie viel Zeit habt Ihr ?
Ich plane mein Projekt so ungefähr bis zu meiner Rente.
Wenn ich viel Glück habe, dann bietet man mir irgendwann einmal
den Vorrihestand an.

Da ich aber erst 34 Lenze zähle muss ich da wohl viel viel Glück haben.

Neee, Spass bei Seite.

Ja, ich würde gerne mit dem Code vom 10. Juli fortfahren, nicht mit dem Frog. Das da vielleicht etwas zu viel Code "drin" ist, stört mich nicht. Im Gegenteil. Ich brauch das um es zu verstehen. Ich möchte das halt als Hobby betreiben und habe halt neben meiner normalen Arbeit halt auch nicht so viel Zeit dafür.

Wie gesagt, ich werde Morgen vormittag versuchen den Code so umzustricken, dass er so abläuft wie ich es mit wünschen würde.

Danke für die vielen Erklärungen.
Das mit dem Entpacken ist nun klar.
Über Toggle mache ich mir gleich noch mal Gedanken.

Kai
imac
20 Zoll
2,4 ghz
Benutzeravatar
wuf
User
Beiträge: 1419
Registriert: Sonntag 8. Juni 2003, 09:50

Samstag 12. Juli 2008, 06:39

Hallo derkai

Alles klar. Betreffs dem 'toggle'. Hier nochmals der Code-Abschnitt:

Code: Alles auswählen

if not toggle:
            toggle = 1
            ypos = yorg + yoffset/2.0
        else:
            toggle = 0
            ypos = yorg
Die Variable 'toggle' ist nicht ein spezieller Datentyp 'BOOL'. Gib es übrigens in Python nicht. Eine Variable wir in Python auch als Objekt bezeichnet. Da für Python der Name 'toggle' nicht der zugewiesene Wert darstellt sondern eine Adressnummer (auch als Referenz oder Zeiger benannt), welche sich auf die Position des zugewiesenen Wertes im Speicher bezieht. Ich hoffe ich habe mich hier richtig ausgedrückt, sonst wird das sicher durch anderen Forummitglieder umgehend korrigiert.

Wichtig ist einfach das die Variable 'toggle' in deinem Code schon existiert bevor dein Programm das obige Code-Stück durchläuft. Sonst wird Python eine Fehlermeldung (Exception) erzeugen. Wenn du das bestehende Code-Snippet 'derkai_05_02.py' vom 10. Juni durchliest siehst du, dass dieser Variable 'toggle' schon vor derer Benützung den wert 0 zugewiesen bekommt. Hier der entsprechende Code-Abschnitt:

Code: Alles auswählen

toggle = 0

#~~ Platziere den zweidimensionalen Sechseck-Array
for x in xrange(columns): 
Zurück zu deiner Frage:
Die Variable 'toggle' wird in diesem Programm nur mit der Zahl 0 oder 1 belegt. Bei jedem Durchlauf der Schleife wird der Wert von 'toggle' von 0 auf 1 oder von 1 auf 0 gewechselt.

Code: Alles auswählen

if not toggle:
Heisst einfach, wenn 'toggle' den Wert 0 hat für den folgenden Code aus:

Code: Alles auswählen

toggle = 1
ypos = yorg + yoffset/2.0
Der Wert 0 entspricht 'falsch' bzw. 'FALSE'
und der Wert 1 entspicht 'wahr' bzw. 'TRUE'

OK. Ich hoffe deine Frage beantwortet zu haben.

Gruss wuf :wink:
Take it easy Mates!
BlackJack

Samstag 12. Juli 2008, 07:19

Und die Korrektur kommt auch umgehend: Python kennt einen Typ für Wahrheitswerte und der heisst `bool`:

Code: Alles auswählen

In [248]: map(type, (True, False))
Out[248]: [<type 'bool'>, <type 'bool'>]
Und den sollte man auch verwenden und nicht Zahlen als Wahrheitswerte missbrauchen. Umgekehrt ändert es nichts daran, dass man mit `True` und `False` "rechnen" kann, weil `bool` eine Unterklasse von `int` ist, und sich `True` und `False` bei Rechenoperationen wie 1 und 0 verhalten.

Der Name `toggle` ist vielleicht auch etwas zu nichtssagend. `is_even_row`, `is_odd_column` oder irgend etwas in der Richtung, was verdeutlicht was der Schalter *bedeutet* statt es einfach "Schalter" zu nennen.
Benutzeravatar
wuf
User
Beiträge: 1419
Registriert: Sonntag 8. Juni 2003, 09:50

Samstag 12. Juli 2008, 08:35

Hallo BlackJack

Danke für deine lehrreiche und erleuchtende Korrektur. Ein Chemiker, Physiker oder Biologe hätte für 'toggle' sicher noch eine andere in sein Umfeld passende Bezeichnung gefunden. Aber du hast recht deine Bezeichnungen sind für die Allgemeinheit besser verständlich.

@derkai Du siehst in diesem Forum kannst du nicht auf einen falschen Pfad geraten. Sorry für meine Fehlorientierung :lol:

Habe es mir durch 'Idle' bestätigen lassen:
>>> is_even_row = True
>>> print type(is_even_row)
<type 'bool'>
>>>
Gruss wuf :wink:
Take it easy Mates!
Benutzeravatar
wuf
User
Beiträge: 1419
Registriert: Sonntag 8. Juni 2003, 09:50

Samstag 12. Juli 2008, 09:38

Hallo derkai

Nach der erleuchtenden Korrektur von BlackJack habe ich den Code-Abschnitt des Code-Snippet 'derkai_05_02.py' für bessere Lesbarkeit und Verständlichkeit wie folgt abgeändert:

Code: Alles auswählen

    GERADE = True
    UNGERADE = False

    xpos = xorg = 10           # X Start-Koordinate
    ypos = yorg = 10           # Y Start-Koordinate
    spalten = 30               # Anzahl vertikale Reihen
    zeilen = 10                # Anzahl horizontale Reihen
    farbe = ("yellow","green") # Zufalls-Farben

    #~~ Erste Spalte hat die Nummer 0
    #   0 = gerade
    #   1 = ungerade
    #   2 = gerade
    #   usw.
    spalten_nummer = GERADE

    #~~ Platziere den zweidimensionalen Sechseck-Array
    for spalte in xrange(spalten):
        for zeile in xrange(zeilen):
            create_hex_polygon(spiel,xpos,ypos,hex_point_list,farbe)
            ypos += yoffset

        xpos += xoffset

        if spalten_nummer == GERADE:
            spalten_nummer = UNGERADE
            ypos = yorg + yoffset/2.0
        else:
            spalten_nummer = GERADE
            ypos = yorg 
@derkai Somit wird die Verwirrung mit dem magischen Wort 'toggle' etwas transparenter. Hi.

Gruss wuf :wink:
Take it easy Mates!
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Samstag 12. Juli 2008, 09:48

Ich verstehe nicht, warum ihr so an dem "toggle" hängt.
In einem vorangegangenen Post hatte ich ja schon darauf hingewiesen, dass man das ganze in einer Zeile erledigen kann.

Für den letzten Codeschnipsel von wuf würde es dann so aussehen (und exakt das gleiche leisten):

Code: Alles auswählen

    xpos = xorg = 10           # X Start-Koordinate
    ypos = yorg = 10           # Y Start-Koordinate
    spalten = 30               # Anzahl vertikale Reihen
    zeilen = 10                # Anzahl horizontale Reihen
    farbe = ("yellow","green") # Zufalls-Farben

    #~~ Platziere den zweidimensionalen Sechseck-Array
    for spalte in xrange(spalten):
        for zeile in xrange(zeilen):
            create_hex_polygon(spiel,xpos,ypos,hex_point_list,farbe)
            ypos += yoffset
        xpos += xoffset
        ypos = yorg + (spalte+1)%2*0.5*yoffset
Antworten