Pippy: Difference between revisions

From OLPC
Jump to navigation Jump to search
m (Reverted edits by 201.221.44.62 (Talk) to last revision by Patrol)
 
(7 intermediate revisions by 7 users not shown)
Line 333: Line 333:
* Author: Tyler Conlee
* Author: Tyler Conlee
* About: Calculates the windchill given a temperature and a wind speed. For my high school senior project I learned about Linux and the OLPC Foundation. With the help of my mentor, Bill C. Smith, I learned simple Python programming. This program is one the items I turned in for the project. By placing in the /usr/share/activities/Pippy.activity/data/math directory it can appear under math examples in Pippy.
* About: Calculates the windchill given a temperature and a wind speed. For my high school senior project I learned about Linux and the OLPC Foundation. With the help of my mentor, Bill C. Smith, I learned simple Python programming. This program is one the items I turned in for the project. By placing in the /usr/share/activities/Pippy.activity/data/math directory it can appear under math examples in Pippy.
* Shows: The sys.exit function to stop a program, the round funcion, and Celsius to Fahrenheit conversion in a pratical math example.
* Shows: The sys.exit function to stop a program, the round function, and Celsius to Fahrenheit conversion in a pratical math example.


<pre>
<pre>
Line 369: Line 369:


</pre>
</pre>

=== Compute pi! ===
=== Compute pi! ===
Author: [[User:Odel|Travis Hall]]
Author: [[User:Odel|Travis Hall]]
Line 561: Line 562:
# now using python's r" strings which were meant for regex's
# now using python's r" strings which were meant for regex's
# i didn't have to do that in C64 BASIC
# i didn't have to do that in C64 BASIC
for i in xrange(0,50):
for i in xrange(50):
clear_scr()
clear_scr()
print r"\o/"
print r"\o/"
Line 686: Line 687:
# move crashed robots to scrap list
# move crashed robots to scrap list
scrap += [r for r in robots if robots.count(r) >= 2]
scrap += [r for r in robots if robots.count(r) >= 2]
robots = [r for r in robots if scrap.count(r) == 0]
robots = [r for r in robots if r not in scrap]


# draw the screen
# draw the screen
Line 725: Line 726:
if abs(robot[0] - hero[0]) <= 1
if abs(robot[0] - hero[0]) <= 1
and abs(robot[1] - hero[1]) <= 1]
and abs(robot[1] - hero[1]) <= 1]
robots = [r for r in robots if scrap.count(r) == 0]
robots = [r for r in robots if r not in scrap]


# update hero and robot positions
# update hero and robot positions
hero = (hero[0] + commands[key][0],
hero = (hero[0] + commands[key][0],
hero[1] + commands[key][1])
hero[1] + commands[key][1])
def sign(x): return (x / abs(x)) if x else 0
def sign(x): return cmp(x, 0)
def follow(fr, to): return (fr[0] + sign(to[0]-fr[0]),
def follow(fr, to): return (fr[0] + sign(to[0]-fr[0]),
fr[1] + sign(to[1]-fr[1]))
fr[1] + sign(to[1]-fr[1]))

Latest revision as of 03:23, 30 June 2012

Pippy-icon.png This activity was bundled
TST Pippy
Trac print.png Tickets all - active - new
OlpcProject.png Chris Ball

see more templates or propose new

The Pippy interface

Description & Goals

Summary

Teaches Python programming by providing access to Python code samples and a fully interactive Python interpreter.

The user can type and execute simple Python expressions. For example, it would be possible for a user to write Python statements to calculate expressions, play sounds, or make simple text animation.

The initial build ships with about twenty short Python examples covering various aspects of the language.

Goals

  • To introduce children to computer programming
  • Give the possibility to the children to collaborate and share while doing computer programming.

Collaboration

Wiki to contribute

Collaboration on this Wiki can help the keeper of Pippy by letting the community offer code snips and code lessons to draw from.

In a normal Python program one would not have comments about the language. That rule would be relaxed here to help the student or make a point.

Pippy

Pippy adventures can be shared with others in the neighborhood via the Sugar user interface. One way to share is to use the "Journal" after quitting a Pippy activity. Resume that activity with "Write" instead of Pippy. Then use the share Activity of Write to share the Plain text with others.

There may be other ways too.

Examples

Please add examples here, or modify the existing ones!

Math

Apples

  • Author: Madeleine Ball
  • About: Adding and dividing
  • Shows: Print Statements and Basic Math
  • XOversion: Bundled in 656
print "Let's do math!"

print "On Monday I picked 22 apples. On Tuesday I picked 12."

print "Now I have: ", 22 + 12

print "My brother says he picked twice as many apples last week."

print "This means he picked: ", (22 + 12) * 2

print "I have 3 friends to whom I would like to give apples."

print "One third of my apples is about: ", (22 + 12) // 3

print "Or, more exactly: ", (22.0 + 12.0) / 3.0

Pascal's triangle

  • Author: Madeleine Ball
  • About: Character graphic of Pascal's triangle
  • Shows: loops, vectors
  • XOversion: Bundled in 656
# Pascal's triangle
lines = 8

vector = [1]

for i in range(0,lines):
  vector.insert(0,0)
  vector.append(0)

for i in range(0,lines):
  newvector = vector[:]
  for j in range(0,len(vector)-1):
    if newvector[j] == 0:
      print "  ",
    else:
      print "%2d" % newvector[j],
    newvector[j] = vector[j-1] + vector[j+1]
  print
  vector = newvector[:]

Sierpinski triangle

  • Author: Madeleine Ball
  • About: Character graphics of a Sierpinski triangle
  • Shows: Modifying Pascal's triangle program, loops, vectors
  • XOversion: Bundled in 656
size = 5
modulus = 2

lines = modulus**size

vector = [1]
for i in range(0,lines):
  vector.insert(0,0)
  vector.append(0)

for i in range(0,lines):
  newvector = vector[:]
  for j in range(0,len(vector)-1):
    if newvector[j] == 0:
      print " ",
    else:
      remainder = newvector[j] % modulus
      if remainder == 0:
        print "O",
      else:
        print ".",
    newvector[j] = vector[j-1] + vector[j+1]
  print
  vector = newvector[:]

Times1

  • Author: Chris Ball
  • About: The 4 times table
  • Shows: Loops, the range statement
  • XOversion: Bundled in 656
for i in range(1,13):
    print i, "x 4 =", (i*4)

Times2

  • Author: Chris Ball
  • About: Print any times table
  • Shows: Loops, range, and input
  • XOversion: Bundled in 656
number = input("Which times table? ")
for i in range(1,13):
    print i, "x", number, "=", i*number

Fibonacci Series

a, b = 0, 1
while b < 1001:
     print b,
     a, b = b, a+b

Stern-Brocot Tree

# The Stern-Brocot tree contains every non-negative rational number
# expressed in its lowest terms
# Reference: Brian Hayes, Computing Science On the Teeth of Wheels,
#            American Scientist, July-August, Volume 88, No. 4, 

# define a class for rational numbers: 
# numerator / denominator
class Rational:
    def __init__(self, num, den): self.num, self.den = num, den
    def __repr__(self): return str(self.num) + '/' + str(self.den)

# define the mediant function
# mediant (a/b, c/d) = (a+c)/(b+d)
def mediant(a, b): return Rational(a.num + b.num, a.den + b.den)

# expand a row by calculating mediants between each pair of elements
# e.g., [0/1, 1/0] -> [0/1, 1/1, 1/0]
def expand(row):
    x = [row[0]]
    for i in range(1, len(row)): x += [mediant(row[i-1], row[i])] + [row[i]]
    return x

# initialize the first row with 0/1, 1/0
# each pass will yield an expanded row
def rationals():
    row = [Rational(0, 1), Rational(1, 0)]
    while True:
        yield row
        row = expand(row)

# iterate through successive rows
r = rationals()
i = 1
while i<5:
    print r.next()
    i+=1

Pythagoras

import math
from math import sqrt

print "This is the Pythagoras Theorem"
a=float(raw_input("Type a ="))
b=float(raw_input("Type b ="))

c=sqrt((a*a)+(b*b))

print "c =",c

Factorize

  • Author: Reinier Heeres
  • About: Factoring Numbers with trial divisions
  • Shows: Appending to arrays, import, sys.stdout
import math
import sys

orignum = input("Enter a number to factorize ")

factors = []
num = orignum
i = 2
while i <= math.sqrt(num):
    if num % i == 0:
        factors.append(i)
        num /= i
        i = 2
    elif i == 2:
        i += 1
    else:
        i += 2

factors.append(num)

if len(factors) == 1:
    print "%d is prime" % orignum
else:
    sys.stdout.write("%d is %d" % (orignum, factors[0]))
    for fac in factors[1:]:
        sys.stdout.write(" * %d" % fac)
    print

Zeros of a second degree polynomial

  • Author: Pilar Saenz
  • About: Zeros of a second grade polynomial, e.g., 3x^2+6x+3.
  • Shows: Converting strings to float, import, sqrt (square root)
import math
from math import sqrt

print "These are the zeros of a second grade polynomial"
a=float(raw_input("Type a ="))
b=float(raw_input("Type b ="))
c=float(raw_input("Type c ="))
aux=b*b-4*a*c;
if aux>0:
    x1=(-b+sqrt(aux))/(2*a)
    x2=(-b-sqrt(aux))/(2*a)
    print "x1= " , x1 ,", x2=" ,x2 
elif aux==0:
    print "x= " , -b/(2*a)
else:
    x1=(-b+sqrt(-aux)*1j)/(2*a)
    x2=(-b+sqrt(-aux)*1j)/(2*a)
    print "x1= " , x1 , ", x2" , x2 

Factorial of a number

  • Author: Pilar Saenz
  • About: Prints a factorial
  • Shows: Defining and calling a function. Casting to int.
def factorial(a):
  fac=a
  for i in range(1,a):
    fac=fac*i
  print  a,"!=",fac

a=int(raw_input("Type a="))
factorial(a)

Greatest common divisor

n= input("Enter a number ")
m= input("Enter another number ")
r=n%m
if r!=0:
    while (r!=0):
        n=m
        m=r 
        r=n%m  
print "The greatest common divisor is ", m

Windchill Calculator

  • Author: Tyler Conlee
  • About: Calculates the windchill given a temperature and a wind speed. For my high school senior project I learned about Linux and the OLPC Foundation. With the help of my mentor, Bill C. Smith, I learned simple Python programming. This program is one the items I turned in for the project. By placing in the /usr/share/activities/Pippy.activity/data/math directory it can appear under math examples in Pippy.
  • Shows: The sys.exit function to stop a program, the round function, and Celsius to Fahrenheit conversion in a pratical math example.
###Windchill calculator for XO
import sys
Tscale = raw_input ("Enter F for Fahrenheit, or C for Celsius: ")

if Tscale == 'F' or Tscale == 'f': 
    print "Temperature is in Fahrenheit"
elif Tscale == 'C' or Tscale == 'c':
    print "Temperature is in Celsius"
else:
    print "Invalid temperature scale"
    ## sys.exit is used to stop the program.
    sys.exit(1)

T = input("Enter a temperature: ")
if Tscale == 'C' or Tscale == 'c':
    T = (9.0/5.0) * T + 32.0

if T > 50.0:
    print "Temperature must be <= 50F/10C"
    sys.exit(1)
WSPD = input ("Enter the wind speed (mph):")
if WSPD < 3.0:
    print "Wind speed must be >= 3 mph"
    sys.exit(1)

WCL = 35.74 + 0.6215 * T - 35.75 * (WSPD**0.16) + 0.4275 * T * (WSPD**0.16)
WCLC = (WCL - 32.0) * (5.0/9.0)

# Round is used to round the answers. In this case to two decimal places.
print "Windchill =", round (WCL, 2), "Fahrenheit"
print "Windchill =", round (WCLC, 2),"Celsius"

Compute pi!

Author: Travis Hall

Extended By: Tom Mitchell

Simple pi computation demo, does 1000 loops... to do more loops change the breakpoint varible to a higher number.Travis Hall

I have added a couple lines to explore various ways that floating point numbers might be printed. Tom Mitchell

a,b = 1.0,3.0
breakpoint = 1000
pi = 0.0
for loop in range(1, breakpoint):
      pi += (4.0/a) - (4.0/b)
      a += 4
      b += 4
      print pi
# Now that the result has been computed we can explore printing the result.
print "There are multiple ways to print numbers here is a quick sample."
print "Just print it    :", pi
print "Using repr()     :", repr(pi)
print "Our approximation: %3.20f" % pi
print "\nPi is a very famous number...."
# Use python's math module it is faster and close enough for most computations.
import math
print "Python's Math library computes"
print "a better value pi: %3.39f" % math.pi; # it uses...(math.atan(1.0) * 4.0)
# when running computations based on "pi" it is good to begin with the best value you can get.
# from the gnu 'C' comiler /usr/include/math.h"
print "For reference a more exact 32 bit floating point value for pi is."
print "Known value of pi: 3.14159265358979323846"

Python

Function

  • Author: Chris Ball
  • XOversion: Bundled in 656
def square(x): 
    print x * x

square(3)
square(4)

If

  • Author: Chris Ball
  • XOversion: Bundled in 656
number = input("Enter a number: ")

if number > 5:
    print "Greater than 5"
elif number < 5:
    print "Less than 5"
else:
    print "Number is 5!"

Count backwards with Recursion

  • Author: Mel Chua with comments by Tom Mitchell
  • XOversion: Bundled in 656

In a UCSD Pascal manual the classic glossary description for "recursion" was "see recursion". This is sort of inside joke is an example of recursion not an informative description.

An external link to Wikipedia is more informative.

Note how "countbackwards" is defined to use itself. Recursion can be a very clear and precise way to express some things in a program. It does have some disadvantages. Each time a recursive function calls itself the computer must push a return call onto the stack. If the recursion is very deep, stack exhaustion is possible.

# Note this assumes you understand functions and if-else.
def countbackwards(number):
    print "I have the number", number
    if number > 0:
        print "Calling countbackwards again!"
        countbackwards(number-1)
    else:
        print "I am done counting"

number = input("Enter a number: ")
countbackwards(number):

While

Author Pilar Saenz

n=input("enter a number")
while n>0:
  print  n, " ",
  n-=1
print "Surprise!\n"

Title Case Capitalisation

Author: Alan Davies

# This is an example of a list comprehension
oldtitle = "this TITLE iS NOW coRRecTly CAPItalised"
oldwords = oldtitle.split()
newwords = [word.capitalize() for word in oldwords]
newtitle = " ".join(newwords)
print "Before:", oldtitle
print "After:", newtitle

Names Drawn From a Hat

Author: Alan Davies

# Simple and possibly useful program for
# drawing names in a random order from a hat
import random
names = []
name = raw_input("Enter the first name to go in the hat:")
while name != "":
    names.append(name)
    name = raw_input("Enter another name, leave blank if you have finished:")
random.shuffle(names)
print "The random order from the hat is:"
for x,name in enumerate(names):
    print x+1, name

String

Hello1

Author: Chris Ball

print "Hello everyone!"

Hello2

  • Author: Chris Ball
  • XOversion: Bundled in 656
name = raw_input("Type your name here: ")
print "Hello " + name + "!"

Thanks

Author: Walter Bender

Comment: Please add names as appropriate

import random
from random import choice

table = {
          'Hardware & Mechanicals': 'John Watlington, Mark Foster, Mary Lou Jepsen, Yves Behar, Bret Recor, Mitch Pergola, Martin Schnitzer, Kenneth Jewell, Kevin Young, Jacques Gagne, Nicholas Negroponte, Frank Lee, Victor Chau, Albert Hsu, HT Chen, Vance Ke, Ben Chuang, Johnson Huang, Sam Chang, Alex Chu, Roger Huang, and the rest of the Quanta team, the Marvell team, the AMD team, the ChiMei team..',
          'Firmware':               'Ron Minnich, Richard Smith, Mitch Bradley, Tom Sylla, Lilian Walter, Bruce Wang..',
          'Kernel & Drivers':       'Jaya Kumar, Jon Corbet, Reynaldo Verdejo, Pierre Ossman, Dave Woodhouse, Matthew Garrett, Chris Ball, Andy Tanenbaum, Linus Torvalds, Dave Jones, Andres Salomon, Marcelo Tosatti..',
          'Graphics systems':       'Jordan Crouse, Daniel Stone, Zephaniah Hull, Bernardo Innocenti, Behdad Esfahbod, Jim Gettys, Adam Jackson, Behdad Esfahbod..',
          'Programming':            'Guido Van Rossum, Johan Dahlin, Brian Silverman, Alan Kay, Kim Rose, Bert Freudenberg, Yoshiki Ohshima, Takashi Yamamiya, Scott Wallace, Ted Kaehler, Stephane Ducasse, Hilaire Fernandes..',
          'Sugar':                  'Marco Pesenti Gritti, Dan Williams, Chris Blizzard, John Palmieri, Lisa Strausfeld, Christian Marc Schmidt, Takaaki Okada, Eben Eliason, Walter Bender, Tomeu Vizoso, Simon Schampijer, Reinier Heeres, Ben Saller, Miguel Alvarez..',
          'Activities':             'Erik Blankinship, Bakhtiar Mikhak, Manusheel Gupta, J.M. Maurer (uwog) and the Abiword team, the Mozilla team, Jean Piche, Barry Vercoe, Richard Boulanger, Greg Thompson, Arjun Sarwal, Cody Lodrige, Shannon Sullivan, Idit Harel, and the MaMaMedia team, John Huang, Bruno Coudoin, Eduardo Silva, H&?kon Wium Lie, Don Hopkins, Muriel de Souza Godoi, Benjamin M. Schwartz..',
          'Network':                'Michael Bletsas, James Cameron, Javier Cardona, Ronak Chokshi, Polychronis Ypodimatopoulos, Simon McVittie, Dafydd Harries, Sjoerd Simons, Morgan Collett, Guillaume Desmottes, Robert McQueen..',
          'Security':               'Ivan Krstic, Michael Stone, C. Scott Ananian, Noah Kantrowitz, Herbert Poetzl, Marcus Leech..',
          'Content':                'SJ Klein, Mako Hill, Xavier Alvarez, Alfonso de la Guarda, Sayamindu Dasgupta, Mallory Chua, Lauren Klein, Zdenek Broz, Felicity Tepper, Andy Sisson, Christine Madsen, Matthew Steven Carlos, Justin Thorp, Ian Bicking, Christopher Fabian, Wayne Mackintosh, the OurStories team, Will Wright, Chuck Normann..',
          'Testing':                'Kim Quirk, Alex Latham, Giannis Galanis, Ricardo Carrano, Zach Cerza, John Fuhrer..',
          'Country Support':        'Carla Gomez Monroy, David Cavallo, Matt Keller, Khaled Hassounah, Antonio Battro, Audrey Choi, Habib Kahn, Arnan (Roger) Sipitakiat',
          'Administrative Support': 'Nia Lewis, Felice Gardner, Lindsay Petrillose, Jill Clarke, Julia Reynolds, Tracy Price, David Robertson, Danny Clark',
          'Finance & Legal':        'Eben Moglen, Bruce Parker, William Kolb, John Sare, Sandra Lee, Richard Bernstein, Jaclyn Tsai, Jaime Cheng, Robert Fadel, Charles Kane (Grasshopper), Kathy Paur, Andriani Ferti',
          'PR and Media':           'Larry Weber, Jackie Lustig, Jodi Petrie, George Snell, Kyle Austin, Hilary Meserole, Erick A. Betancourt, Michael Borosky, Sylvain Lefebvre, Martin Le Sauteur',
          'Directors & Advisors':   'Howard Anderson, Rebecca Allen, Ayo Kusamotu, Jose Maria Aznar, V. Michael Bove, Jr., Rodrigo Mesquita, Seymour Papert, Ted Selker, Ethan Beard (Google); John Roese (Nortel); Dandy Hsu (Quanta); Marcelo Claure (Brightstar); Gary Dillabough (eBay); Gustavo Arenas (AMD); Mike Evans (Red Hat); Ed Horowitz (SES Astra); Jeremy Philips (NewsCorp); Scott Soong (Chi Lin); Sehat Sutardja (Marvell); Joe Jacobson (MIT Media Lab); Steve Kaufman (Riverside); and Tom Meredith (MFI)',
          'Pippy':                  'Chris Ball'
       }
 
print "OLPC would like to take this opportunity to acknowledge the community of people and projects that have made the XO laptop possible."

subsystem = random.choice(table.keys());
print subsystem, '\t',table[subsystem]

Graphics

Jump

  • Author: C. Scott Ananian
  • XOversion: Bundled in 656
# both of these functions should be in the 'basic' package or some such
def clear_scr():
    print '\x1B[H\x1B[J' # clear screen, the hard way.
def wait():
    import time
    time.sleep(0.1)

# jumping man!
# was having to escape the backslash which was rather unfortunate, 
# now using python's r" strings which were meant for regex's
# i didn't have to do that in C64 BASIC
for i in xrange(50):
    clear_scr()
    print r"\o/"
    print r"_|_"
    print r"   "
    wait()
    
    clear_scr()
    print r"_o_"
    print r" | "
    print r"/ \ "
    wait()
    
    clear_scr()
    print r" o "
    print r"/|\ "
    print r"| |"
    wait()
    
    clear_scr()
    print r"_o_"
    print r" | "
    print r"/ \ "
    wait()

Mandelbrot Set

Author: Alan Davies

# Text-based Mandelbrot set generator
# Play with the values of 'centre' and 'realsize'
# to explore the set.
centre, realsize, maxiter = -.7+0j, 2.8, 50
width, height, aspect = 60, 30, 1.9
charmap = "abcdefghijklmnopqrstuvwxyz"
for y in range(height):
    output = ""
    for x in range(width):
        real = (float(x)/width-.5)*realsize
        imag = (float(y)/height-.5)*aspect*realsize*height/width
        z = c = complex(real, imag) + centre
        iterations = 0
        while abs(z) < 2 and iterations < maxiter:
            z = z**2 + c
            iterations += 1
        if iterations == maxiter:
            output += " " 
        else:
            output += charmap[iterations%len(charmap)]
    print output

Games

Guess a number

import random
from random import randrange
R = randrange(1,100)


print "Guess a number between 1 and 100!!!"
N = int(raw_input("Enter a number: "))
i=1
while N!=R:
  if N>R :
    print "Too big... try again"
  else :
    print "Too small.. try again"
  N = input("Enter a number: ")
  i+=1
print "You got it in ", i, "tries"

Robots

Author: Alan Davies

This is a playable implementation of Robots (also known as Daleks). I tried to keep the code clear and well commented, even at the expense of space. I also made sure that the lines don't wrap in Pippy, as that looks quite ugly.

I'm not sure if this is considered too large for the samples to be included with Pippy- a simpler implementation could be trimmed down considerably. I figured it might be nice to have at least one complete implementation for kids and adults to play with.

from random import randint
import curses
stdscr = curses.initscr()
curses.noecho()

xmax, ymax, alive = 60, 10, True
commands = {"q":(-1,-1), "w":(0,-1), "e":(1,-1),
            "a":(-1,0),  "s":(0,0),  "d":(1,0),
            "z":(-1,1),  "x":(0,1),  "c":(1,1),
            " ":(0,0),   "t":(0,0)}

def message(text, yoffset=0, wait=True):
    stdscr.addstr(ymax/2+yoffset, xmax/2-len(text)/2, text)
    stdscr.refresh()
    if wait:
        stdscr.getch()

message("Welcome to Robots!", -3, False)
message("          QWE    Screwdriver: S       ", -1, False)
message("Movement: A D    Teleport:    T       ", 0, False)
message("          ZXC    Do nothing:  Spacebar", 1, False)
message("Press any key...", 3)

while True:
  level = 1
  alive = True

  while alive:       
    # Initialise powers, hero position, and enemy lists
    teleport = screwdriver = True
    hero = (xmax/2, ymax/2)
    scrap = [(randint(0, xmax), randint(0, ymax))
             for dummy in range(level/3+3)]
    robots = [(randint(0, xmax), randint(0, ymax))
              for dummy in range(level*4-3)]
    scrap = [s for s in scrap if s != hero] 
    robots = [r for r in robots if r != hero]

    while True:         
      # move crashed robots to scrap list
      scrap += [r for r in robots if robots.count(r) >= 2]
      robots = [r for r in robots if r not in scrap]

      # draw the screen
      stdscr.clear()
      stdscr.addstr(hero[1], hero[0], "@")
      for robot in robots:
        stdscr.addstr(robot[1], robot[0], "$")
      for scr in scrap:
        stdscr.addstr(scr[1], scr[0], "#")
      if screwdriver:
        stdscr.addstr(ymax-1, xmax+1, "S")
      stdscr.addstr(ymax, xmax+1,"T" if teleport else "")
      stdscr.refresh()

      # test for win or loss
      if len(robots) == 0:
        break
      elif hero in robots or hero in scrap:
        stdscr.addstr(hero[1], hero[0], "X")
        message("You lost! Press any key...")
        alive = False
        break

      # get a valid keypress	    
      key = ""
      while key not in commands:
        key = chr(stdscr.getch()).lower()

      # teleport - move to a random location
      if teleport and key == "t":
        teleport = False
        hero = (randint(0, xmax), randint(0, ymax ))

      # sonic screwdriver - scraps nearby robots
      if screwdriver and key == "s":
        screwdriver = False
        scrap += [robot for robot in robots
                  if abs(robot[0] - hero[0]) <= 1
                  and abs(robot[1] - hero[1]) <= 1]
        robots = [r for r in robots if r not in scrap]

      # update hero and robot positions
      hero = (hero[0] + commands[key][0],
              hero[1] + commands[key][1])
      def sign(x): return cmp(x, 0)
      def follow(fr, to): return (fr[0] + sign(to[0]-fr[0]),
                                  fr[1] + sign(to[1]-fr[1]))
      robots = [follow(robot, hero) for robot in robots]

    # move to next level
    if alive:
      level += 1
      message(" Level %d! Press any key... " % level)


Beginning Programming

Operations on Numbers

  • Author: Tom Mitchell
  • About: addition, subtraction, multiply, divide. power(exponents) and modulo arithmetic
  • Shows: basic arithmetic with integer and floating point numbers.
# Understanding how a computer works with numbers is interesting.
# Python (Pippy) supports the basic set of operators on integers, floating point, decimal numbers and more.
# This exercise will look at integers and floating point numbers.
# Look at these samples and when you think you have the answer click run.  
# Change the numbers and experiment...

# Add
print 6 + 1

# Subtract
print 6 - 1

# Multiply
print 6 * 2

# Division - hint, dividing integers by integers result in integers.
print 3/6
print 3.0/6.0
print 1/3      # integer
print 1.0/3.0  # floating  point

# Modulo (remainder)..
print 1%3
print 3%6
print 1.1234%3.0
print 3%2
print 3.0%2

# Power or exponents
print 2**2
print 3**6
print 3.3**22

Parentheses and Operators

  • Author: Tom Mitchell
  • About: Parentheses with addition, subtraction, multiply, divide, power(exponents) and modulo arithmetic
  • Shows: basic arithmetic precidence rules and the use of parentheses.
# Understanding the order with which a computer works with numbers is interesting.
# Python (Pippy) supports the basic set of operators on integers, floating point, decimal numbers and more.
# This exercise will look at Pythons rules for basic integers and floating point operations and the use of parentheses.
# Note the assignment to a variable and then the use of print to display a result. 

# Look at these samples and when you think you have the answer click run.  
# Change the numbers and experiment.   
# Regroup numbers and operators with parentheses to clarify what you want Python to do.

# Add and Multiply some numbers but what is done first: 
#     is is multiply or add; 
#     is the order left to right or is it right to left.
answer = 6 + 2 * 3
print answer
answer = (6 + 2) * 3
print answer
answer = 6 + (2 * 3)
print answer
# now exponents..
answer = 3.3**(20+2)+10
print answer
answer = 3.3**(20)+ -(2+10)
print answer

# To convert from degrees Fahrenheit to Centigrade we can use an equation.
F = 212
# but which equation is correct: C1, C2, C3 or C4?
C1 = (F - 32.0)/ 9.0 * 5
C2 = F - 32.0/ 9.0 *5 
C3 = F - (32.0/ 9.0) *5
C4 = F - 32.0/ (9.0 *5)
print C1
print C2
print C3  # Why are C2 and C3 the same.
print C4

# hint Water boils at 212 F and 100 C;  Water freezes at 0 C and 32 F.
F = 32.0
C = (F - 32.0)/ 9.0 * 5
print C
print "%f F degrees converts to %3.10f C" %( F ,C)

# Question what is interesting about -40 degrees?

"""
In Algebra one might write:

         3 + 3 + 5 + 55
  x = ----------------------
              22
"""
        # The next line is incorrect  because the division only involves 55
x = 3.0 + 3 + 5 + 55 / 22

        # This line is correct
xx = (3.0 + 3 + 5 + 55) / 22

print "This is incorrect %i"  % x
print "This is   correct %i"  % xx



# Question what is interesting about -40 degrees?


# Hint -- use parentheses to clarify what you want Python to do.
#         Doing so you can make it clear to others what you intend.

Take Pippy for a Loop

  • Author: Tom Mitchell
  • About: Looping
  • Shows: While and for loops introduces a generator.
 
#!  /usr/bin/python  
""" The Gauss Schoolroom Anecdote:
A teacher once was inclined to assign long tedious 
problems to students.   One problem was to add all
the numbers from 1 to 100 or more.

A student "Gauss" turned over his slate moments
after starting the problem  to signal
that he was finished.   His slate had a single 
number on the  back ...  5050.

How did he solve this so quickly?  Who is "Gauss"?
"""
# lets explore loops to check the answer.

# first a "while loop".
i = 1
a = 0
while i <= 100:
  a += i
  i += 1
print a 

# now a "for loop" using the generator range()
a = 0
for i in range(100+1):  # the +1 is because range() returns a list N long 
  a += i             # that begins with 0.  More on generators like range(N) later.
print a

# Will this get the correct answer?  If so why?
last  = 100.0
print  last * (1 + last ) / 2


"""
Additional reading
  http://www.math.uwaterloo.ca/navigation/ideas/grains/gauss.shtml
"""

Loops do not need to be restricted to numbers. Try this little loop.

for tree in "oak", "maple", "plum":
  print tree

Printing various Number Types in Pippy

  • Author: Tom Mitchell
  • About: Formatting when printing numbers
  • Shows: type(), if, elif, else and the use of % in formatting of numbers.

#! /usr/bin/python
import decimal
a = 1.5
b = 55
c = -55.12345
d = True
e = 5555555555555555555555555555L
f = 4444444444444444444444444444.12345678
g = 55.77e22
h = 'string'
i = decimal.Decimal("3333333333333333333333333333.12345678")
j = decimal.Decimal("2222222222222222222222222222.12345678")
k = i * j
k = k * k * k  # should now be very big
l = 0567   # hint this is octal i.e. base 8
m = 0x456ABCD # base 16 i.e  hex

for thing in [ a, b, c, d, e, f, g, h, i, j, k, l, m ]: 
  print "========================"
  print "printing it  ",thing
#  print type(thing)
  if type(thing) is float:
        print "found a float",  thing
        print "float can be formatted: %f " % thing
        print "float can be formatted: %4.9f " % thing
        print "float can be formatted: %1.5f " % thing
        print "float can be formatted: %1.3e " % thing
        print "float can be formatted: %1.1E " % thing
  elif type(thing) is int:
        print "found a int  ",  thing
        print "int can be formatted: %i # right justified" % thing
        print "int can be formatted: %+25i # right justified with sign" % thing 
        print "int can be formatted: %-25i # left justified" % thing
        print "int can be formatted: %+25i # right justified with sign" % thing
        print "int can be formatted as hex: %-+20x # Hex left justified with sign" % thing
        print "int can be formatted as hex: 0x%-20x # Hex left justified make it look like Hex " % thing 
        print "int can be formatted as hex: 0x%+20X # Hex signed right justified bad try at looking like Hex" % thing
        print "int can be formatted as hex: %#-20X # Hex left justified make it look like Hex best way" % thing 
        print "int can be formatted as hex: %#20X # Hex right justified make it look like Hex best way" % thing 
        print "int can be formatted as hex: %#+20X # Hex signed right justified  make it look like Hex best way" % thing 
        print "int can be formatted as octal: %o # Octal" % thing
        print "int can be formatted as octal: 0%o # Octal make it look octal " % thing
        print "int can be formatted as octal: 0%-15o # Octal left justified, make it look octal incorrectly " % thing
        print "int can be formatted as octal: 0%15o # Octal make it look octal incorrectly and why" % thing
        print "int can be formatted as octal: %#o # Octal make it look octal correctly" % thing
        print "int can be formatted as octal: %#15o # Octal make it look octal correctly" % thing
        print "int can be formatted as octal: %#-15o # Octal left justified  correctly" % thing
  elif type(thing) is long:
        print "found a long ",  thing
        print "long can be formatted: %i " % thing     # right justified is the default
        print "long can be formatted: %+i signed " % thing    # right justified with sign
        print "long can be formatted as hex: %x " % thing   # Hex 
        print "long can be formatted as hex: 0x%x " % thing   # Hex lower case
        print "long can be formatted as octal: %o " % thing   # Octal 
        print "long can be formatted as octal: %#o " % thing   # Octal make look like octal
  elif type(thing) is str:
        print "found a str  ",  thing
  elif type(thing) is decimal.Decimal:
        print "found a decimal.Decimal ",  thing
        print "decimal.Decimal can be formatted: %1.5f " % thing
        print "decimal.Decimal can be formatted: %1.3e " % thing
        print "decimal.Decimal can be formatted: %1.3E " % thing
        print "decimal.Decimal can be formatted: %55.55e " % thing
  else:
        print "this type is not in my list"  # this will trip on the boolian "True" for d.


"""
Make changes to the above and see what changes.
Shorten the list to focus on one type or another.

Formating of numbers builds on the C library so the % formats are 
best described by looking at the printf man page. Use the
web and search for:

PRINTF(3)                  Linux Programmer's Manual                 PRINTF(3)

 ....

    Format of the format string
       The format string is a character string, beginning and  ending  in  its
       initial  shift state, if any.  The format string is composed of zero or
       more  directives:  ordinary  characters  (not %),  which  are   copied
       unchanged  to the output stream; and conversion specifications, each of
       which results in fetching zero or more subsequent arguments.  Each con-
       version specification is introduced by the character '%', and ends with a
       conversion specifier.  In between there may be (in this order) zero  or
       more  flags, an optional minimum field width, an optional precision and
       an optional length modifier.

 .... and lots more ...
"""

Comparing objects in Pippy

  • Author: Tom Mitchell
  • About: Comparisons and tests >, <, <=, >=, ==, not
  • Shows: Shows some very introductory ways to build truth tables.

This is a bit long but the goal here is to show how to build some skills with tests and truth tables.

#!  /usr/bin/python
#  Comparison tests are the key to program flow and decisions.
#  All objects can be compared....

"""
 from the Python Library Reference.

        <       strictly less than  
        <=      less than or equal 
        >       strictly greater than 
        >=      greater than or equal 
        ==      equal 
        !=      not equal (prefered over <> )
        <>      not equal (not prefered)
        is      object identity 
        is not  negated object identity 

   Boolean Operations
        x or y          if x is false, then y, else x   (1)
        x and y         if x is false, then x, else y   (1)
        not x   if x is false, then True, else False    (2)

                1) These only evaluate their second argument if needed
                for their outcome.
                (2) "not" has a lower priority than non-Boolean operators,
                so not a == b is interpreted as not (a == b), and a ==
                not b is a syntax error.

"""

a = 1
b = 2   # could also do "a, b = 1, 2"

# - - - - - - - - - - - - - - - - - - - -
print "\n==============================="
print "Control program flow with an if"

if a < b :
  print "Less Than"

# - - - - - - - - - - - - - - - - - - - -
print "\n==============================="
print "Looping while a test stays true"

a, b = 1, 4
while a < b:
  print "a is still less than b"
  b -= 1   # same as "b = b -1"

# - - - - - - - - - - - - - - - - - - - -
print "\nBreak out of a loop when a test becomes true"
a, b = 1, 4
while a < b:
  print "a is still less than b"
  b += 1
  c = b
#  One common error in JavaScript and C is confusing 
#  assignment '=' and  a test for equality '=='.
#   Uncoment this block and see what happens.
#   if c = 10:
#        print "Exit on assignment not equality"
#        break
  if b == 10:
    print "Exit the loop \'b\' is now ten."
    break

# - - - - - - - - - - - - - - - - - - - -
print "\nBreak out of a loop when a test becomes true"
a, b = 1, 4.0000000001
while a < b:
  print "a is still less than b"
  b += 1
  c = b
  # testing floating point numbers for exact equality is problematic.
  if b == 10:
    print "Exit the loop \'b\' is now ten."
    break
  if b >= 10: 
    print "Exit the loop \'b\' is now ten or more."
    break


# - - - - - - - - - - - - - - - - - - - -
T, F = True, False
# what is the truth table for 'or', 'and', 'not' ?
print "\n==============================="
print "Exploring Boolean\'s  \'or\'."

if  F or F:
  print "F or F tests true"
if  T or F:
  print "T or F tests true"
if  F or T:
  print "F or T tests true"
if  T or T:
  print "T or T tests true"

# - - - - - - - - - - - - - - - - - - - -
print "\n==============================="
print "Exploring Boolean\'s  \'and\'."
if  F and F:
  print "F and F tests true"
if  T and T:
  print "T and T tests true"
if  T and F:
  print "T and F tests true"
if  F and T:
  print "F and T tests true"


# - - - - - - - - - - - - - - - - - - - -
print "\n==============================="
print "Exploring Boolean\'s  \'not\'."
if  not(F or F):
  print "not(F or F) tests true"
if  not(T or T):
  print "not(T or T) tests true"
if  not(T or F):
  print "not(T or F) tests true"
if  not(F or T):
  print "not(F or T) tests true"
if  not(F and F):
  print "not(F and F) tests true"
if  not(T and T):
  print "not(T and T) tests true"
if  not(T and F):
  print "not(T and F) tests true"
if  not(F and T):
  print "not(F and T) tests true"
if  not F or F:
  print "not F or F tests true"
if  not T or T:
  print "not T or T tests true"
if  not T or F:
  print "T or F tests true"
if  not F or T:
  print "not F or T tests true"
if  not F and F:
  print "not F and F tests true"
if  not T and T:
  print "not T and T tests true"
if  not T and F:
  print "not T and F tests true"
if  not F and T:
  print "not F and T tests true"

# - - - - - - - - - - - - - - - - - - - -
print "\n==============================="
print "Exploring comparisons of strings'."
lc="lower case string"
UC="Upper Case string"
if lc == UC:
  print "String test:\n \"%s\" is the same as \"%s\" ." % (lc, UC)
else:
  print "String test:\n \"%s\" is NOT the same as \"%s\" " % (lc, UC)


Lists, Tuples, Sets and more

  • Author: Tom Mitchell
  • About: Lists, tuples, sets and some string tinkering
  • Shows: Introduction to ways to define and convert from one to the other.

#! /usr/bin/python
""" Lists, Tuples, Sets and Dictionaries:
Data structures are fundamental to programing.  In python most data
structures are built with tuples, sets, lists and dictionaries.  
Data structures are how data is organized and passed to and from
functions.  """

# lists are bounded by "[]" a sequence of objects that can be modified.
print "\nExploring Lists:"
Bob, Carol, Ted = "Bob Johnson", "Carol Johnson", "Ted Turner"
somenames = [ Bob, Carol, Ted ]
sometrees = ["teak", "oak", "pine"]
sometrees = sometrees + ["maple", "apple"]
print sometrees
sometrees[2] = "willow"  # legal for lists 
print sometrees

# tuples are bounded by "()" , cannot modify a tuple's contents.
print "\nExploring tuples:"
nums = (1, 2, 3, 5.01)
trees = ("teak", "oak", "pine")
bushes = "blueberry", "Sage"  # when expected a tuple is assumed.
tuptup = (nums, trees, bushes)
# This is illegal for a tuple.  Uncomment it and try.
#nums[2] = 55

print nums, trees, bushes     # print EXPECTS a tuple
print (nums, trees, bushes, "Tuple")     # print EXPECTS a tuple
print tuptup


# sets are introduced by the key word "set", and no duplicates no special order
print "\nExploring sets:"
aa = set("Happy is Pippy")
print aa  #  how many p's and y's will be printed?

# dictionaries are bounded with {} and use : with ,  to associate pairs.
print "\nExploring dictionaries:"
telescope = {
        'mirror' : 'reflection',   # three ways to indicate strings '
        "lens"   : "refraction",   #  "
        """Hubble""" : """reflector""",  # and the triple """
        "Cassegrain" : "reflector",
        "Great Lick" : "refractor"
        }
print telescope["Hubble"]

# strings are  are bounded with ' or " or """.  It makes some sense
# to include them here.
print "\nExploring strings:"

# The following string is interesting in English, but why?
s1 = "The quick brown FOX jumped over the lazy dogs"
print s1            # some things are easy to do with strings.
print s1[4:9]
print s1.upper()
print s1.swapcase()
print s1.title()

# sorting and moving the characters about is not one of them.
# sorting is easy to do in a list.

sL = s1.lower()
l1= list(sL)
l1.sort()
print l1
print ""

s2= "".join(l1)  # "" is the (empty) string seperating the objects providing the method
sX= "X".join(l1)  # "X" is the string seperating the objects providing the method
print s2
print sX

# sets can only have one of each.
t1=set(l1)
print t1
L2= list(t1)
L2.sort()
S1="".join(L2)
print "It might be clear what is fun about the phrase now.\n" + S1

Functions lots of functions

  • Author: Tom Mitchell
  • About: functions
  • Shows: Shows lots function permutations
#!  /usr/bin/python
"""  
#  Functions are a critical part of programming.
#  This File explores some of the ways to pass 
#  information into a function and back out.
#
#  The design of a program and function often centers on how data
#  is passed into and out of the function.  This is commonly refered to
#  as the "interface".  Clearly documenting the interface is important 
#  and can be as simple as well chosen function and variable names, or coments.
#  An interface has three key parts: input, output and error.
#

# A function is introduced by the opertor "def"
# 
#       def FunctionName(tupple of inpupt ):
#         indented code
#         more indented code
#         Watch out for tabs, 
#         a tab is one character but may look like up to 8 spaces.
#           more indented code.... Smart editors may confuse the handling of tabs.
#           Python does expand tabs and assumes up to 8 char.  Good style is to
#           use one or the other.  i.e. Try to not mix spaces and tabs in python source.
#           See: http://docs.python.org/ref/indentation.html
# 
# A function can take advantage of other functions.

# An ideal function returns a result and does not modify data
# outside of it's own scope.

"""

# - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#   The cannocal Hello World can be writen in Python thusly
print "\n================\nExample function: \"Hello\""
def  Hello(): 
  print "Hello World\n"

# now call it
Hello()

# - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#   Simple data can be passed to a function.
print "\n================\nExample function: \"Twice\""
def Twice(x):
        """Twice uses + to operate on a single input object.

        This is a good place to introduce documentation...
        The first line should be short and precise.  
        The second doc line should be blank.  In this style of
        documentation the information stays with the object even if
        it is complied to byte code.
        """
        print x + x

Twice(5)
Twice("Cat")
print (Twice.__doc__)  # 


# - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#   Multiple data objects can be passed to a function by position.
print "\n================\nExample function: \"Volume\""
def Volume(L, W, H):
        """Length times Width times Height is Volume of a rectangular box"""
        V = L * W * H
        return(V)

L1, W1, H1 = 5, 6, 2
V1= Volume(L1, W1, H1)

print("The volume of a box  %i x  %i x %i is %i" % (L1, W1, H1, V1))


# - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#   Multiple data objects can be passed to a function by name.
print "\n================\nExample function: \"PetFood\""
def PetFood(cat=0, dog=0, bird=0):
        # a house cat eats 25 gr of cat food per day.
        catfood = 25 * cat
        # a dog eats 100 gr of dog food per day. 
        dogfood = 100 * dog
        # a bird eats 15 gr of bird food per day. 
        birdfood = 15 * bird
        print "\n\tHow much Cat, Dog and Bird food?"
        print "\tWith %i cats we need %i gr of catfood." % (cat, catfood)
        print "\tWith %i dogs we need %i gr of dogfood." % (dog, dogfood)
        print "\tWith %i birds we need %i gr of birdfood." % (bird, birdfood)
        print "\tAll together the full bag should weigh about %i gr." % (catfood+dogfood+birdfood)
        return (cat, catfood, dog, dogfood, bird, birdfood)


PetFood(cat=5, bird=10)      # note that 'dog' has a default value of 0.

print PetFood(dog=12, cat=5, bird=10)

execv() of another python file in Pippy

  • Author: Tom Mitchell
  • About: execv()
  • Shows: Shows how to run a file that might be edited in a terminal Activity"

This is a bit advanced but someone asked in the discussions. One value is that is much the way Python programmers work.

First in a terminal Activity use vim to generate a short python program like this:

#!/usr/bin/python
print "this file is /tmp/t1.py"
print "Fun with Python and Pippy"

Now make it executable:

chmod +x /tmp/t1.py

Next start Pippy and enter this code:

import os
f2="/tmp/t1.py"

print "================\nGetting ready to leave "
os.execv(f2, ("/tmp/t1.py", "Additional args here"))

print "N.B. This line is never reached"

Slice notation

  • Author: Stuart Morrow
  • Shows: The using the slice notation on subscriptable data in Python

Some of the more advanced examples on this page just dive in to list/string slicing without explaining.

print "A list is an order collection of things"
things = ['bike', 'tree', 'the Sun']
print things
print

print """You can access individual thing using the slice and a number
The first thing is numbered 0, not 1"""
thing = things[0]
print "The third thing is numbered 2"
thirdThing = things[2]
print thing; print thirdThing
print

print """You can access more than one thing at a time if you use two
numbers and a colon (:)
things[start : howMany] finds things[start], then shows howMany things"""
twoThings = things[0:2]
threeThings = things[0:3]
print "twothings =", twoThings, "and threeThings =", threeThings
print

print """If you specify a third number called the step or increment,
you can take howMany things at regular intervals, instead of
strictly one next to the other"""
things = things * 3
print "things[0:7:1] is:"
print things[0:7:1]
print "things[0:7:2] is:"
print things[0:7:2]
print

print """A list of numbers will be clearer now that we are learning
increments"""
numbers = range(5) # This is the same as numbers=[0,1,2,3,4]
print numbers[1]   # 'range' is English for ...
print numbers [1:5:1]
print numbers [1:5:2]
print numbers [5:1:-1]
print

print """Words and sentences are subscriptable according to the same rules
as lists and tuples"""
print "'I am a sentence'[0] is", "I am a sentence"[0]
print "'I am a sentence'[7:15] is", 'I am a sentence'[7:15]
print """Note that the spaces between words are significant.
"We are some words" is the same as ['W','e',' ','a','r','e',' ',...]
                                              ^               ^"""
print list('We are some words')[0:10]
print

print """Conveniently, -1 is the last element of a subscriptable
and -2 is the second-last, and so on"""
print 'I am a sentence'[-1]
print 'I am a sentence'[-8:-1]
print

print """The final section of this list-slicing is about omitting the numbers
If you use [:x] it is the same as [0:x]"""
print things[:3]; print things[0:3]
print """If you do not specify the second index it is the same as saying
"until the end of the list" """
print numbers[3:]; print numbers[3: len(numbers) ]
print """Therefore, numbers[::] == numbers[:] == numbers"""
print numbers; print numbers[:]
print "And,"
string = things[0]
print string, string[::-1]; print
print "Finally,"
print "See that string[:n] + string[n:] == string"
print string; print string[:1] + string[1:]

print """Further
Note that things[::-1] is not the same as things.reverse()"""
print things.reverse() # Nothing!
print things # ah, There it is
print """You might liken this to the difference between list.sort() and sorted(list)
Slices can be used anywhere a list can, so you can use them in tuple assignment
for example"""
(a, b) = "abcdefghijklmnop"[:2]
print (a, b)


More Examples

C. Scott Ananian created a small library of programming examples, based on the BASIC examples in the Commodore 64 manual. It can be found at http://dev.laptop.org/git?p=users/cscott/pippy-examples;a=tree

See also

  • Canvas tutorial is a similar environment to learn JavaScript and <canvas> programming, it runs in Browse.

Activity Summary

Icon: Sugar icon::Image:Pippy-icon.png
Genre: Activity genre::Programming
Activity group: ,|x|Activity group::x}}
Short description: [[Short description::Activity for learning Python programming:Pippy provides access to Python code samples and a fully interactive Python interpreter.

The user can type and execute simple Python expressions. For example, it would be possible for a user to write Python statements to calculate expressions, play sounds, or make simple text animation.

The initial build ships with about twenty short Python examples covering various aspects of the language.]]

Description:
Maintainers: ,|x|Contact person::x}}
Repository URL: Source code::http://dev.laptop.org/git?p=projects/pippy-activity
Available languages: ,|x|Available languages::x}}
Available languages (codes): ,|x|Language code::x}}
Pootle URL:
Related projects: Related projects,|x|Related projects::x}}
Contributors: ,|x|Team member::x}}
URL from which to download the latest .xo bundle Activity bundle::http://dev.laptop.org/~cscott/bundles/Pippy-30.xo
Last tested version number: Activity version::30
The releases with which this version of the activity has been tested. ,|x|Software release::x}}
Development status:
Ready for testing (development has progressed to the point where testers should try it out): ,|x|Ready for testing::x}}
smoke tested :
test plan available :
test plan executed :
developer response to testing :


URL from which to download the last .xo bundle that works with old releases Activity bundle::http://dev.laptop.org/~erikos/bundles/0.82/Pippy-25.xo
Activity version number: Activity version::
The releases with which this version of the activity has been tested. ,|x|Software release::x}}
Development status: