import sys
sys.dont_write_bytecode=True 
import math
from go import *

def say(x):
  sys.stdout.write("["+x+"]")

class yourFirstClass:
  def __init__(self,x) :
    self.mine = x
  def x(self):
    return self.mine
  def setX(self,new):
    self.mine=new

def _class1():
  "example of set, get, init of a class"
  y = yourFirstClass("morgantown")
  y.setX("fairmont")
  y.mine="clarksburg"
  print y.x()

def f1(n) :
   if n < 2 : 
     return 1
   else:
     return  f1(n-2) + f1(n-1)

def _f1() : print 32, f1(32)

def f(n):
    a, b = 0, 1
    for i in range(0, n):
        a, b = b, a + b
        #print a,b
    return a



def _i2():
  "iterating"
  for x in ["m","f","c"]:
    print x


def bigguns(lst,n):
  for x in lst:
    if x > n:
      yield x

def biggunsd():
   lst = [8347, 6230, 923834, 1, 404, 993]
   for x in [1,3]:
     print x

y ={"a":10,"b":20,"c":30}

def _dict1():
  "accessing a dictionary"
  print y["c"]

def _sorteddic():
  "example of walking a dictinary in key sort order"
  for key in sorted(y.keys()):
    print ":key",key,":val:",y[key]

def _dict2():
  "accessing keys and values"
  for k,v in y.items():
    print ":key new",k,":val:",v


def odd(x) : return x % 2 == 1

def _odd(): print odd(2), odd(21)

def largeOdd(x) : return odd(x) and x > 10

def _largeOdd(): return largeOdd(11)

def lcomp():
  "example of list comprehension"
  print [x/3.0 for x in 
           xrange(60,110,3) if largeOdd(x)]

def myOdds() :
  for x in xrange(60,110,3):
    if odd(x):
      yield(x)

def _iterate():
  "example of defining your own iterator"
  for y in myOdds():
    if y> 90:
      break
    print y

    
root = math.sqrt

x=2


def _x():
  "example of global"
  print x

def fred(y,x=100,
         z=2,pretty = lambda x: int(x)):
  "e.g.1) var scope; 2) code as data"
  print y+z
  print "x",x
  print "pretty",pretty(y+z)
  print root(100)

def _fred(): fred(20)

def _fred1():
  "example of passing code as data"
  fred(22.99,pretty = lambda x: x)

    
def _string1(fruit="banana"):
  index = 0 
  while index < len(fruit): 
    letter = fruit[index] 
    say(letter) 
    index = index + 1 


import string
def _string2():
  "finds 'na' at '2' (i.e. third arg)"
  print string.find("banana", "na")


def _string3():
  "as above, but starts at 3"
  print string.find("banana", "na", 3)


def _string4():
  "fails: specificed range has no 'na'"
  print string.find("banana", "na", 2,3)


def _whites():
  print "[" + string.whitespace+"]"
  for ch in string.whitespace:
    print ord(ch),"["+ch+"]"


def _lowers():
  print string.lowercase


def isLower1(ch="a"):
  print string.find(string.lowercase, ch) != -1


def isLower2(ch="b"):
  print ch in string.lowercase


def isLower3(ch="c",banner="hekko there"):
  print banner,'a' <= ch <= 'z'


def _test1():
  isLower3(banner="work more on python",ch="D")


def _slice():
  a=[1,2,3,4]
  print 0,a[0]
  print 1,a[1:]
  print 2,a[:2]
  print 1,3,a[1:3]
  print -1,a[-1]
    

def _alias():
  a = [1, 2, 3]
  b = a
  a[0]=100
  print a,b
  

def _clones():
  a = [1, 2, 3]
  b = a[:]
  a[0]=100
  print a,b
    
def _dict():
  inventory = {'apples': 430,
               'bananas': 312, 'oranges': 525,
               'pears': 217}
  print "\n:all",inventory
  del inventory['pears']
  print "\n:less",inventory
  print "\n:keys",inventory.keys()
  print "\n:values",inventory.values()
  print "\n:parts",inventory.items()
  print "\n:iterate"
  for key,value in inventory.items():
    print ":key",key,":value",value
    

def _counts():
  seen = {}
  for letter in "Mississippi":
    seen[letter] = seen.get(letter, 0) + 1
    print seen

import copy

class Holds(dict):
  """Dictionary with a default value for unknown keys."""
  def __init__(self, default):
    self.default = default
        
  def __getitem__(self, key):
    if key in self: return self.get(key)
    return self.setdefault(key, copy.deepcopy(self.default))    

def args(*args):
   print args

#@go
def _args() : print args(1,2,3,4,5)

def memo(f):
  memo = {}
  def wrapper(*args):
    if args in memo:
      return memo[args]
    else:
      tmp = f(*args)
      memo[args] = tmp
    return tmp
  return wrapper

@memo
def f2(n) :
    return n if n < 2 else f2(n-2) + f2(n-1)
  

def _f2() : print 320,f2(320)

def _f2slow(): print 320,f1(320)


def _holds1():
  d = Holds(0)
  d['hello'] += 1
  print d

def _holds2():
  d2 = Holds([])
  d2[1].append('hello')
  d2[2].append('world')
  d2[1].append('there')
  print d2


if len(sys.argv)> 1:
  f = sys.argv[1]
  print f
  eval(f + '()')
