Hi,<br><br>I&#39;ve added a few new examples to Pippy. They&#39;re available in my repository (<a href="http://git.sugarlabs.org/projects/pippy/repos/dgaletic-gsoc2010">http://git.sugarlabs.org/projects/pippy/repos/dgaletic-gsoc2010</a>); I haven&#39;t made an .xo since I&#39;m having some problems with my Sugar installation.<br>

<br>Since this is about learning Python, in each of them I&#39;ve tried to have several places where the learner is invited to modify come code.<br><br>This one draws the Koch snowflake using pygame. The user can decrease/increase the number of triangles with left and right arrows.<br>

<br>diff --git a/data/GSOC examples/Koch snowflake b/data/GSOC examples/Koch snowfla<br>new file mode 100644<br>index 0000000..2fb218e<br>--- /dev/null<br>+++ b/data/GSOC examples/Koch snowflake <br>@@ -0,0 +1,208 @@<br>
+# This example draws a shape called the Koch snowflake. <br>
+<br>+import pippy, pygame, sys<br>+from pygame.locals import *<br>+from random import *<br>+import math<br>+<br>+# always need to init first thing<br>+pygame.init()<br>+<br>+# XO screen is 1200x900<br>+size = width, height = 1200, 900<br>

+<br>+# create the window and keep track of the surface<br>+# for drawing into<br>+screen = pygame.display.set_mode(size)<br>+<br>+# turn off the cursor<br>+pygame.mouse.set_visible(False)<br>+<br>+<br>+# Set some variables.<br>

+# Snowflakes are white!<br>+color = (255,255,255)<br>+<br>+# the center point of the screen<br>+# We need it because we&#39;ll place out triangle around it.<br>+center = width / 2, height / 2<br>+<br>+# Side of an equilateral triangle (the one we start with).<br>

+# Here it is defined relative to the resolution of the screen.<br>+# Practice: We could play with other values, absolute (like a = 100) or <br>+# relative (a = height / 2, a = width / 3, etc). What looks best for you?<br>

+a = height/1.4  <br>+<br>+# Height of that triangle.<br>+# Just a simple geometry formula, nothing Python-special about it.<br>+h = int(a * math.sqrt(3) / 2) <br>+<br>+# These will be the vertices for the starting triangle.<br>

+# The triangle vertices are named like this:<br>+#<br>+#    C<br>+#   / \<br>+#  A _ B<br>+#<br>+A = center[0]- a/2, center[1] + h/3<br>+B = A[0] + a, A[1]<br>+# To find the third point, we need slightly more advanced math.<br>

+# If you with to understand it, you could try finding some material about trigo<br>+# We use the coordinates of vertice A to calculate where point C will be.<br>+C = A[0] + math.cos(math.pi/3) * a, A[1] - math.sin(math.pi/3) * a<br>

+<br>+# This class will allow us to store data about a line.<br>+class Line(object):<br>+    def __init__(self, a = A, b = B):<br>+        # This is how a line object will remember its points and length.<br>+        self.A = a<br>

+        self.B = b<br>+        self.points = [self.A, self.B]<br>+<br>+        # We use the Pythagorean theorem to calculate the length of a line<br>+        # from the coordinates of its points.<br>+        self.length = math.sqrt( (a[0]-b[0])**2 + (a[1]-b[1])**2 ) <br>

+        <br>+        # Projection of the line on the x axis.<br>+        # We use it to figure out the angle which the line closes with the x ax<br>+        projection_length = b[0] - a[0]<br>+<br>+        # If the line is descending, the angle is negative. Trigonometry, again<br>

+        if b[1] &gt; a[1]:<br>+            self.angle = -math.acos(projection_length / self.length)<br>+        else:<br>+            self.angle = math.acos(projection_length / self.length)<br>+<br>+    # To draw new shapes, an old line must be split into its thirds.<br>

+    def split(self):<br>+        third = self.length / 3.0<br>+        self.D = self.A[0] + math.cos(self.angle) * third, \<br>+                 self.A[1] - math.sin(self.angle) * third<br>+        self.E = self.A[0] + math.cos(self.angle) * 2*third, \<br>

+                 self.A[1] - math.sin(self.angle) * 2*third<br>+        self.points.append(self.D)<br>+        self.points.append(self.E)<br>+<br>+# Give a line (from which we&#39;ll need the coordinates of its starting point) and<br>

+# an angle, calculate the position of a new point - the vertex of out snowflake<br>+# The length of its sides should be 1/3 of the length of the line from which<br>+# it is made. <br>+def calculate_new_point(line, angle):<br>

+    p = line.D[0] + math.cos(angle + line.angle) * line.length / 3, \<br>+        line.D[1] - math.sin(angle + line.angle) * line.length / 3<br>+    return p<br>+<br>+<br>+# The following function from a single line, like this: <br>

+# <br>+# A___B<br>+# <br>+# creates four lines, like this:<br>+#<br>+#     F<br>+# A_D/ \E_B<br>+#<br>+def transform_line(line):<br>+    line.split()<br>+    C = calculate_new_point(line, math.pi/3)<br>+    line1 = Line(line.A, line.D)<br>

+    line2 = Line(line.D, C)<br>+    line3 = Line(C, line.E)<br>+    line4 = Line(line.E, line. B)<br>+    lines = [line1, line2, line3, line4]<br>+    return lines<br>+<br>+# For each line in starting_lines, call transform_line().<br>

+# Repeat &quot;depth&quot; times for each line created this way.<br>+def produce_lines(starting_lines, depth):<br>+    all_lines = starting_lines<br>+    for i in range(depth):<br>+        new_lines = []<br>+        for line in all_lines:    <br>

+           new_lines += transform_line(line)<br>+        # clearn the old lines first<br>+        all_lines = [] <br>+        all_lines = new_lines<br>+    return all_lines<br>+<br>+# Write the lines on screen.<br>+def draw_lines(lines):<br>

+    for line in lines:<br>+        pygame.draw.line(screen, color, line.A, line.B)<br>+<br>+<br>+# The color we&#39;ll use for the screen background (black).<br>+bgcolor = (0,0,0)<br>+<br>+<br>+# Lines for the initial triangle.<br>

+# Remember, the vertices are named like this:<br>+#<br>+#    C<br>+#   / \<br>+#  A _ B<br>+#<br>+# , could be changed to:<br>+#<br>+#    B<br>+#   / \<br>+#  A _ C<br>+#<br>+# if that felt more natural.<br>+AC = Line(A, C)<br>

+CB = Line(C, B)<br>+BA = Line(B, A) <br>+starting_lines = []<br>+starting_lines.append(AC)<br>+starting_lines.append(CB)<br>+starting_lines.append(BA)<br>+<br>+# The starting depth is 0; we just need the triangle.<br>+depth = 0<br>

+<br>+# For displaying the instructions.<br>+use = &quot;Use left and right arrows&quot;<br>+font_size = 36<br>+# Remember, colors are in RGB (Red, Green, Blue) system. <br>+font_colour = (10, 250, 20)<br>+font = pygame.font.Font(None, font_size)<br>

+text = font.render(use, True, font_colour)<br>+text_box = text.get_rect()<br>+# Where the box will be placed.<br>+text_box.top = 100<br>+text_box.left = 50<br>+<br>+lines = starting_lines<br>+<br>+while pippy.pygame.next_frame():<br>

+    for event in pygame.event.get():<br>+        if event.type == QUIT:<br>+            sys.exit()<br>+        # When R arrow is pressed, go one step further.<br>+        # This means creating new lines on each existing line.<br>

+        elif event.type == KEYDOWN and event.key == K_RIGHT and depth &lt; 6:<br>+            lines = produce_lines(lines, 1)<br>+            depth = depth +1<br>+        # When L arrow is pressed, go one step back, reducing the complexity of<br>

+        # the snowflake.<br>+        # Basically, goes depth-1 steps forward from the starting lines.<br>+        elif event.type == KEYDOWN and event.key == K_LEFT and depth &gt; 0:<br>+            depth = depth-1<br>+            lines = produce_lines(starting_lines, depth)<br>

+        elif event.type == KEYDOWN:<br>+            sys.exit()    <br>+    screen.fill(bgcolor)<br>+    # Display the current step.<br>+    msg = &quot;Step: &quot; + str(depth) + &quot;/6&quot;<br>+    text2 = font.render(msg , True, font_colour)<br>

+    text_box2 = text2.get_rect()<br>+    text_box2.top = 130<br>+    text_box2.left = 50<br>+    # Write the instructions and the current step on the screen.<br>+    screen.blit(text, text_box)<br>+    screen.blit(text2, text_box2)<br>

+    # Draw the lines on the screen.<br>+    draw_lines(lines)<br>+    # Refresh the screen.<br>+    pygame.display.flip()<br>+<br><br>