Kirby Urner schrieb:
> At 12:23 PM 7/7/2003 -0700, you wrote:
>
>> routines running! Sure, there are some kids that can abstract things
>> and get
>> all excited about rearranging letters and numbers, etc. But a lot of
>> people
>> in general like the visual pleasure of seeing things work. *sigh*
>
>
> Some kids even like both! (and some neither :-( -- sigh again).
> ...
>
> So whereas I'm all for flashy visuals, a well-rounded diet should
> include some regular expressions and such, IMO (but not exclusively
> -- turtle graphics with Tkinter, yes! (including the demo). And
> Kevin implemented some turtle stuff in PythonCard that's pretty
> nifty as well).
Could this be part of your well-roundet diet? (Aims at visualizing
some fundamental concepts of computer-science)
################################
# Mini Lindenmayer tool
###############################
from __future__ import generators
from turtle import Pen
def ersetze( folge, ersetzungsregeln, n ):
for i in range(n):
neuefolge = ""
for element in folge:
neuefolge = neuefolge + ersetzungsregeln.get(element,element)
folge = neuefolge
return folge
def lindenmayer(turtle,
axiom = "",
ersetzungsregeln = {},
tiefe = 1,
schritt = 5,
winkel = 90,
startpos = (0,-120),
startdir = 90,
updating = 20):
turtle.step, turtle.angle = schritt, winkel
zeichnung = ersetze(axiom, ersetzungsregeln, tiefe)
turtle.start(startpos, startdir)
return turtle.zeichne(zeichnung, turtle.standardregeln(), updating)
class LPen(Pen):
def __init__(self):
Pen.__init__(self)
self.tstack = []
def start(self, startpos, startdir):
self.up()
self.goto(startpos)
self.left(startdir)
self.down()
self.tracer(1)
self.tracer(0)
def zeichne( self, befehle, regeln, updating ):
i = 0
for b in befehle:
try:
regeln[b]()
except:
pass
i += 1
if i % updating == 0:
self.tracer(1)
self.tracer(0)
# Wir machen draus einen Generator!
yield 1
################################
# Standardregeln
################################
def r(self):
self.right(self.angle)
def l(self):
self.left(self.angle)
def f(self):
self.up()
self.forward(self.step)
def F(self):
self.down()
self.forward(self.step)
def turn(self):
self.left(180)
def save(self):
self.tstack.append( (self.pos(), self.heading()) )
def load(self):
position, richtung = self.tstack.pop()
self.up()
self.goto(position)
self.setheading(richtung)
def standardregeln(self):
return {"-":self.l, "+":self.r, "F": self.F, "f":self.f,
"|": self.turn, "[":self.save, "]":self.load}
# 2 examples for Lindenmayer plants:
kraut = {
"axiom" : "G",
"ersetzungsregeln" : { "G" : "GFX[+G][-G]",
"X" : "X[-FFF][+FFF]FX" },
"tiefe" : 5,
"schritt" : 4.5,
"winkel" : 180.0/7,
"startpos" : (-90, -128),
"startdir" : 90
}
busch = {
"axiom" : "F",
"ersetzungsregeln" : { "F" : "FF+[+F-F-F]-[-F+F+F]" },
"tiefe" : 3,
"schritt" : 9,
"winkel" : 180.0/8,
"startpos" : (60, -128),
"startdir" : 90,
"updating" : 20
}
l1, l2 = lindenmayer(LPen(), **kraut), lindenmayer(LPen(), **busch)
done = 0
while done < 2:
done = 0
for l in l1, l2:
try:
l.next()
except:
done += 1
raw_input()
>
> And lets not forget the cellular automata (perhaps a bridge between
> text and graphics, as simple CA may be displayed using a kind of
> 'ascii art' -- see below).
Or this:
from Tkinter import Tk, Canvas, mainloop
from Canvas import Rectangle
class ZACanvas(Canvas):
def __init__(self, root, NX=59, NY=40, feldbreite=4):
self.NX, self.NY = NX, NY
w,h = NX*feldbreite, NY*feldbreite
Canvas.__init__(self, root, width = w+1, height = h+1,
bg = "yellow")
self.pack()
self.farbe = ["white", "red", "green", "blue", "yellow"]
self.gitter = {}
for spalte in range(NX):
for zeile in range(NY):
x0 = 2 + spalte * feldbreite
y0 = 2 + zeile * feldbreite
x1 = x0 + feldbreite
y1 = y0 + feldbreite
r = Rectangle(self, x0, y0, x1, y1,
fill="black", outline="black")
self.gitter[(spalte,zeile)] = r
def set(self,feld,farbe):
self.gitter[feld]['fill'] = farbe
self.gitter[feld]['outline'] = farbe
def draw(self,welt):
for y in range(self.NY):
for x in range(self.NX):
self.set((x,y), self.farbe[welt[y][x]])
self.update()
def ZA(code, spalten = 59, zeilen = 40):
code = code[:13]
code = code + "0"*(13-len(code))
welt = []
altezeile = [0]*spalten
altezeile[spalten//2] = 1
for z in range(0,zeilen):
welt.append(altezeile)
neuezeile = [0]*spalten
for s in range(1,spalten-1):
summe = altezeile[s-1]+altezeile[s]+altezeile[s+1]
neuezeile[s] = int(code[summe])
altezeile = neuezeile
return welt
ZACanvas(Tk()).draw(ZA("0211021"))
mainloop()
If necessary, ZACanvas-class could be supplied by the teacher.
Remark: (Easy) implementation in wxPython, will result in
faster graphics.
(Code for both examples attached, for your convenience)
Gregor
################################
# Mini Lindenmayer tool
###############################
from __future__ import generators
from turtle import Pen
def ersetze( folge, ersetzungsregeln, n ):
for i in range(n):
neuefolge = ""
for element in folge:
neuefolge = neuefolge + ersetzungsregeln.get(element,element)
folge = neuefolge
return folge
def lindenmayer(turtle,
axiom = "",
ersetzungsregeln = {},
tiefe = 1,
schritt = 5,
winkel = 90,
startpos = (0,-120),
startdir = 90,
updating = 20):
turtle.step, turtle.angle = schritt, winkel
zeichnung = ersetze(axiom, ersetzungsregeln, tiefe)
turtle.start(startpos, startdir)
return turtle.zeichne(zeichnung, turtle.standardregeln(), updating)
class LPen(Pen):
def __init__(self):
Pen.__init__(self)
self.tstack = []
def start(self, startpos, startdir):
self.up()
self.goto(startpos)
self.left(startdir)
self.down()
self.tracer(1)
self.tracer(0)
def zeichne( self, befehle, regeln, updating ):
i = 0
for b in befehle:
try:
regeln[b]()
except:
pass
i += 1
if i % updating == 0:
self.tracer(1)
self.tracer(0)
# Wir machen draus einen Generator!
yield 1
################################
# Standardregeln
################################
def r(self):
self.right(self.angle)
def l(self):
self.left(self.angle)
def f(self):
self.up()
self.forward(self.step)
def F(self):
self.down()
self.forward(self.step)
def turn(self):
self.left(180)
def save(self):
self.tstack.append( (self.pos(), self.heading()) )
def load(self):
position, richtung = self.tstack.pop()
self.up()
self.goto(position)
self.setheading(richtung)
def standardregeln(self):
return {"-":self.l, "+":self.r, "F": self.F, "f":self.f,
"|": self.turn, "[":self.save, "]":self.load}
# 2 examples for Lindenmayer plants:
kraut = {
"axiom" : "G",
"ersetzungsregeln" : { "G" : "GFX[+G][-G]",
"X" : "X[-FFF][+FFF]FX" },
"tiefe" : 5,
"schritt" : 4.5,
"winkel" : 180.0/7,
"startpos" : (-90, -128),
"startdir" : 90
}
busch = {
"axiom" : "F",
"ersetzungsregeln" : { "F" : "FF+[+F-F-F]-[-F+F+F]" },
"tiefe" : 3,
"schritt" : 9,
"winkel" : 180.0/8,
"startpos" : (60, -128),
"startdir" : 90,
"updating" : 20
}
l1, l2 = lindenmayer(LPen(), **kraut), lindenmayer(LPen(), **busch)
done = 0
while done < 2:
done = 0
for l in l1, l2:
try:
l.next()
except:
done += 1
raw_input()
from Tkinter import Tk, Canvas, mainloop
from Canvas import Rectangle
class ZACanvas(Canvas):
def __init__(self, root, NX=59, NY=40, feldbreite=4):
self.NX, self.NY = NX, NY
w,h = NX*feldbreite, NY*feldbreite
Canvas.__init__(self, root, width = w+1, height = h+1,
bg = "yellow")
self.pack()
self.farbe = ["white", "red", "green", "blue", "yellow"]
self.gitter = {}
for spalte in range(NX):
for zeile in range(NY):
x0 = 2 + spalte * feldbreite
y0 = 2 + zeile * feldbreite
x1 = x0 + feldbreite
y1 = y0 + feldbreite
r = Rectangle(self, x0, y0, x1, y1,
fill="black", outline="black")
self.gitter[(spalte,zeile)] = r
def set(self,feld,farbe):
self.gitter[feld]['fill'] = farbe
self.gitter[feld]['outline'] = farbe
def draw(self,welt):
for y in range(self.NY):
for x in range(self.NX):
self.set((x,y), self.farbe[welt[y][x]])
self.update()
def ZA(code, spalten = 59, zeilen = 40):
code = code[:13]
code = code + "0"*(13-len(code))
welt = []
altezeile = [0]*spalten
altezeile[spalten//2] = 1
for z in range(0,zeilen):
welt.append(altezeile)
neuezeile = [0]*spalten
for s in range(1,spalten-1):
summe = altezeile[s-1]+altezeile[s]+altezeile[s+1]
neuezeile[s] = int(code[summe])
altezeile = neuezeile
return welt
ZACanvas(Tk()).draw(ZA("0211021"))
mainloop()