dictionary problem

Fragen zu Tkinter.
Antworten
niko
User
Beiträge: 24
Registriert: Freitag 23. Januar 2004, 20:53

hi leute!
ich hab folgendes vor: ich will ein galtonbrett simulieren. wer es nicht weiß: ein galtonbrett simuliert/veranschaulicht die Binomialverteilung. startet einfach mal das Programm und ihr werdet seht, wie so etwas ungefähr aussieht. das klappt alles schon ziemlich gut.
die theorie: man schmeißt von oben ganz viele Kügelchen hinein. diese fallen nach unten und treffen immer auf den nächsten Kreis. Dann wieder entweder nach links oder nach rechts auf ihrem Weg nach unten.Nimmt man ganz viele Kügelchen, so ergibt sich, wenn diese unten in den Rechtecken(Auffangbehältern) angekommen sind, die Gauß'sche Glockenkurve. Das klappt alles bisher. Der Weg der Kugeln nach unten wird durch die Farbänderung der Kreise gekennzeichnet.
Nun mein Problem: die Auffangbehälter sind im Dictionary "korb" abgelegt. Am Ende eines jeden Durchlaufes wird der Korb, in den ein Kügelchen fällt, einer Liste namens "liste" angehängt. Nun ist das Problem, dass nicht der Schlüssel(Key), sondern der Wert(Value) in der Liste abgelegt wird. Kann ich irgendwie vom Wert auf den jeweiligen Schlüssel schließen?

Naja das war ne schwere Geburt, aber ich hoffe mir kann jemand helfen.
Mfg
Niko

Code: Alles auswählen

from Tkinter import *
from math import *
import random

eo = [0,1]
liste = []

def animation():
    ball = dict[(1,1)]
    cv.itemconfigure(ball,fill="blue")
    n1 = 1
    n2 = 1
    global liste
    for durchlauf in range(1,reihen):
        entscheidung = random.choice(eo)
        n1 += 1
        if durchlauf < reihen-1:
            if entscheidung == 1:
                n2 += 1
                ball = dict[(n1,n2)]
                cv.itemconfigure(ball,fill="blue")
                #print ball,entscheidung
            elif entscheidung == 0:
                try:
                    ball = dict[(n1,n2)]
                    cv.itemconfigure(ball,fill="blue")
                    #print ball,entscheidung
                except:
                    n2 = 1
                    ball = dict[(n1,n2)]
                    cv.itemconfigure(ball,fill="blue")
                    #print ball,entscheidung
        elif durchlauf == reihen-1:
            if entscheidung == 1:
                print korb[(n2,n2+1)],entscheidung
                liste.append(korb[(n2,n2+1)])
            elif entscheidung == 0:
                print korb[(n2-1,n2)],entscheidung
                liste.append(korb[(n2-1,n2)])
        print liste
    
            
def reset():
    global dict
    for each in dict:
        cv.itemconfigure(dict[each],fill="green")



r       = 20     # Durchmesser der Perle 
gap     = 5     # Vertikaler Zwischenraum
gap2    = 8      # Horizontaler Zwischenraum
reihen  = 20     # Anzahl der Reihen 

top     = r     # Oberes Rahmenende 
left    = r     # Linkes Rahmenende 
#right   = left+(numcol+1)*r+8  #Rahmenende rechts 
#bottom  = top+(numrows*r)+(numrows*gap) # Rahmenende unten 
ypos    = 0     # Vertikalposition der Reihenstange
xg      = 0     # Hilfsvariable
yg      = 0     # Hilfsvariable
abs     = 10    # Abstand zum linken Rand
m       = 0     # Verringerungsfaktor
av      = (reihen/2.5)*r # Anzahlverschiebung

dict    = {}
korb    = {}

root = Tk() 
root.title("Quincunx") 
root['bg'] = 'steelblue3'
cv = Canvas(root,height=reihen*(r+gap)+100,width=reihen*(r+gap2)+7*r)
cv.pack()

##for x in range(4):
##    for y in range(x):
##        print x,y

## Zeichne Nägel
for x in range(reihen):
    m += 0.5
    yg += gap
    xg -=(x-0.4)*gap2
    for y in range(1,x+1):
        schieb = reihen/2
        x0 =     y*r + abs + (schieb-m)*r + xg + av
        y0 =     x*r + abs + yg - 20                  
        x1 = (y+1)*r + abs + (schieb-m)*r + xg + av
        y1 = (x+1)*r + abs + yg - 20               
        xg += gap2
        dict[(x,y)]=cv.create_oval(x0,y0,x1,y1,fill='green')
        if x == reihen-1 and y < reihen:
            xap1 = x1 - r/2 - r - gap2 + 3
            xap2 = x1 - r/2
            yap  = y1
            korb[(y-1,y)] = cv.create_rectangle(xap1,yap,xap2,yap+40)
        if korb.has_key((reihen-2,reihen-1)):
            pos = cv.bbox(dict[(reihen-1,reihen-1)])
            xbp1 = pos[2] - r/2 + 2
            xbp2 = pos[2] + r/2 + gap2
            ybp  = pos[3] - 1 ## -1 ist lediglich Korrektur
            korb[(reihen-1,reihen)] = cv.create_rectangle(xbp1,ybp,xbp2,ybp+40)

#for every in korb.keys():
#	print every, korb[every]
        
##for b in range(1,reihen):
##    cv.itemconfigure(dict[(b,1)],fill="blue")
#pos = cv.bbox(dict[(2,1)])
#print pos

##Anzahl der Gesamtdurchläufe
for q in range(10):
    animation()

#print dict
#print korb
print liste
#reset()
quit = Button(root, text="Beenden", width=10, command=root.destroy) 
quit.pack(side="right")
root.mainloop()
Es gibt diejenigen, die angeln, und diejenigen, die nur das Wasser trüben.
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hi niko,

ich würd einfach

Code: Alles auswählen

liste.append(korb[(n2,n2+1)])
in

Code: Alles auswählen

liste.append((n2,n2+1))
ändern, dann wir der Key in der Liste gespeichert. um auf den Eintrag in Korb zu gelangen geht dann

Code: Alles auswählen

entry = korb[liste[x]]
wobei index für den Platz in der Liste steht.


Gruß

Dookie
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

ein

Code: Alles auswählen

    cv.update()
am Ende der animation() Funktion lässt die animation auch animieren.


Gruß

Dookie
niko
User
Beiträge: 24
Registriert: Freitag 23. Januar 2004, 20:53

Hi Dookie!

Wie ist das mit cv.update() ? was soll das ersetzen?
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

das soll gar nichts ersetzen, sondern die Anzeige updaten von einem Animationsschritt zum nächsten.
Jetzt zeigt er ja keine Animation an, sonder durchläuft alle Schritte und zeigt nur am Ende das Ergebnis.
Ich habs am Ende der Funktion eingesetzt.

Code: Alles auswählen

            ...
            elif entscheidung == 0:
                print korb[(n2-1,n2)],entscheidung
                liste.append(korb[(n2-1,n2)])
        print liste
    cv.update()

Gruß

Dookie
niko
User
Beiträge: 24
Registriert: Freitag 23. Januar 2004, 20:53

danke Dookie!
Das sieht interessanter aus.
Kann ich das irgendwie nochmals herunterbremsen? ok, ich könnte es bei jeder Entscheidung einsetzen, aber kann man ihm irgendwie noch sagen, er soll eine 1/2 sekunde warten oder so etwas?

Mfg
Niko
niko
User
Beiträge: 24
Registriert: Freitag 23. Januar 2004, 20:53

Noch ne Frage. Ich hab das jetzt halwegs hinbekommen, dass er eine Liste anlegt mit den Auffangbehältern und für jeden einfach in demjenigen einen kleinen Kreis zeichnet. Jedoch kann er nicht unterscheiden, wie oft eine Kugel in einen Auffangbehölter gefallen ist. D.h. im Klartext: Wenn in der Liste zwei gleiche Auffangbehälter stehen(also sind 2 Kugeln in diesen Behälter gefallen),dann malt er trotzdem einen Kreis und den zweiten einfach darüber. Das jetzt mit irgendwelchen Falluntershceidungen zu machen halte ich für zu umständlich.
Da ich ja meine Liste sortiere brauche ich nur noch zu wissen, ob ein Auffangbehälter öfter als 1 mal vorkommt.Kann man irgendwie Listen durchsuchen? Denn das O'Reilly Einführung in Python sagt nur:"...,es gibt zusätzliche Listen-Methoden und -Operatoren, die wir hier nicht beschreiben wollen(inklusive der Methoden zum Umkehren und SUCHEN)"

Code: Alles auswählen

d1={}
def visualisierung():
    #liste.sort()
    for every in liste:
        position = cv.bbox(korb[every])
        print position
        d1[object] = cv.create_oval(position[0],position[1]+30,position[0]+10,position[1]+40)
Mfg
Niko
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo Niko!

Hier ist eine Animationsbremse.
Ist auf 500 Millisekunden eingestellt.
Neue Funktion:

Code: Alles auswählen

def AnimationTimer():
	global counter

	if counter > numofanimations:
		pass
	else:
		animation()
		counter += 1
		cv.after(500,AnimationTimer)
Ergänzung im Programmstart:

Code: Alles auswählen

#for q in range(10000):
#	animation()
counter = 0
numofanimations  = 10
AnimationTimer()
Gruss wuf :wink:
Take it easy Mates!
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

bei http://python.sandtner.net/viewtopic.php?t=1432 hab ich schonmal ein paar Beispiele für die Behandlung von Mehrfacheinträgen in einer Liste gezeigt.


Gruß

Dookie
Gast

Hi Dookie!
Vielen dank!
Ich führe mir das alles mal zu gemüte und meld mich heut abend wieder mal.
Mfg
Niko
Antworten