<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Blog 4 &#187; Python</title>
	<atom:link href="http://nickzarr.com/blog4/category/programming-2/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://nickzarr.com/blog4</link>
	<description>Chosen by fair dice roll. Guaranteed random.</description>
	<lastBuildDate>Sun, 22 Apr 2012 18:29:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Scheme in Python &#8211; lambda</title>
		<link>http://nickzarr.com/blog4/2011/10/scheme-in-python-lambda/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=scheme-in-python-lambda</link>
		<comments>http://nickzarr.com/blog4/2011/10/scheme-in-python-lambda/#comments</comments>
		<pubDate>Sat, 29 Oct 2011 08:55:03 +0000</pubDate>
		<dc:creator>Nick Zarczynski</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Scheme]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[interpreter]]></category>
		<category><![CDATA[Language Design]]></category>

		<guid isPermaLink="false">http://nickzarr.com/blog4/?p=1690</guid>
		<description><![CDATA[GOTO Part 9 &#124; Environments We are finally going to implement lambda and procedures. To begin implementing procedures we have to define a procedure type, just like we did with primitives. A procedure has 3 basic parts. A list of parameters, a body and an environment. So we&#8217;ll set up a new procedure type with [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://nickzarr.com/blog4/2011/10/scheme-in-python-environments/" title="Scheme in Python – Environments">GOTO Part 9 | Environments</a></p>
<p>We are finally going to implement lambda and procedures.</p>
<p>To begin implementing procedures we have to define a <strong>procedure</strong> type, just like we did with primitives.  A procedure has 3 basic parts.  A list of <strong>parameters</strong>, a <strong>body</strong> and an <strong>environment</strong>.  So we&#8217;ll set up a new procedure type with these fields and call it <strong>Procedure</strong>.</p>
<p><strong>scheme_types.py</strong></p>
<pre class="brush: python; highlight: [29,30,31,32,33]; title: ; wrap-lines: false; notranslate">
class Symbol(str):
  &quot;&quot;&quot;A symbol is an immutable string, but must be its own type.&quot;&quot;&quot;
  pass

class The_Empty_List():
  &quot;&quot;&quot;The empty list is used as a list terminator and should be a singleton&quot;&quot;&quot;
  def __repr__(self):
    return &quot;()&quot;

the_empty_list = The_Empty_List()

class Pair(object):
  &quot;&quot;&quot;A pair is a classic Lisp cons cell used to implement lists&quot;&quot;&quot;
  def __init__(self, car, cdr):
    self.car = car
    self.cdr = cdr
  def __iter__(self):
    x = self
    while not isinstance(x, The_Empty_List):
      yield x.car
      x = x.cdr
  def __repr__(self):
    return &quot;(&quot; + ' '.join([str(i) for i in list(self)]) + &quot;)&quot;

class Primitive(object):
  def __init__(self, fn):
    self.fn = fn

class Procedure(object):
  def __init__(self, parameters, body, environment):
    self.parameters = parameters
    self.body = body
    self.environment = environment
</pre>
<p>Like primitives, procedures are handled by the <strong>scheme_apply</strong> procedure.  We&#8217;ll temporarily add a placeholder in scheme_apply for procedures.  In addition we need new syntax to create a procedure.  The syntax for procedures in Scheme is (lambda (parameters) body).  Most Schemes allow the syntax (define (name params &#8230;) body &#8230;) but this is really just shorthand for (define name (lambda (params &#8230;) body &#8230;)).  For now we won&#8217;t overload the define keyword, choosing instead to define functions the more verbose way.</p>
<p>It is important to take note of this before moving on.  In many programming languages defining a function is a single step.  However logically, there are 2 different operations that take place.  First a function object is created, then that function object is bound to a symbol.  By requiring the (define name (lambda &#8230;)) syntax we are making these two steps explicit.</p>
<p><strong>scheme_eval.py</strong></p>
<pre class="brush: python; highlight: [1,62,63]; title: ; wrap-lines: false; notranslate">
from scheme_types import Symbol, Pair, Primitive, the_empty_list, Procedure
from buffered_input import Buff
from scheme_read import scheme_read

##############################################################################
## Environments
##############################################################################

def current_environment(env):
  &quot;&quot;&quot;Return the frame of the current environment&quot;&quot;&quot;
  return env.car

def enclosing_environment(env):
  &quot;&quot;&quot;Return the environment stack with the first frame removed&quot;&quot;&quot;
  return env.cdr

def extend_environment(bindings, base_environment):
  &quot;&quot;&quot;Push a new frame onto the given base_environment&quot;&quot;&quot;
  return Pair(bindings, base_environment)

global_environment = extend_environment({}, the_empty_list)
special_forms = {}

def set_symbol(symbol, val, env):
  &quot;&quot;&quot;Set the binding (symbol, val) in the current frame of env&quot;&quot;&quot;
  current_environment(env)[symbol] = val

def lookup_symbol_value(symbol, environment):
  &quot;&quot;&quot;Return the value of symbol or Unbound Symbol error&quot;&quot;&quot;
  env = environment
  while env != the_empty_list:
    if symbol in current_environment(env):
      return current_environment(env)[symbol]
    else:
      env = enclosing_environment(env)
  return &quot;Error: Unbound symbol: &quot; + symbol

##############################################################################
## Eval and Apply
##############################################################################

def self_evaluating(expr):
  t = type(expr)
  return t is int or t is float or t is str or t is bool

def scheme_eval(expr, env):
  if self_evaluating(expr):
    return expr
  elif type(expr) is Symbol:
    return lookup_symbol_value(expr, env)
  elif type(expr) is Pair:
    if expr.car in special_forms:
      return special_forms[expr.car](expr.cdr, env)
    else:
      return scheme_apply(scheme_eval(expr.car, env), [scheme_eval(a, env) for a in expr.cdr])
  else:
    return &quot;scheme_eval: not implemented&quot;

def scheme_apply(proc, args):
  if type(proc) is Primitive:
    return apply(proc.fn, args)
  elif type(proc) is Procedure:
    return &quot;Attempted to apply a procedure&quot;
  else:
    return &quot;Error: Undefined procedure&quot;

##############################################################################
## Builtin Syntax
##############################################################################

def special_form_handler(expr, env):
  &quot;&quot;&quot;Register a symbol with a Python function named &quot;f&quot; that implements a special form&quot;&quot;&quot;
  exec(expr.cdr.car)
  special_forms[expr.car] = f

def load(expr):
  &quot;&quot;&quot;Given a filename, open it and eval each expression in the global_environment&quot;&quot;&quot;
  f = open(expr.car, 'r')
  b = Buff(f)
  while b.peek():
    scheme_eval(scheme_read(b), global_environment)
    b.remove_whitespace()
  f.close()

special_forms['scheme-syntax'] = special_form_handler
special_forms['load'] = load
</pre>
<p><strong>syntax.scm</strong></p>
<pre class="brush: plain; highlight: [19,20,21,22]; title: ; notranslate">
(scheme-syntax define-primitive &quot;
def f(expr, env):
  set_symbol(expr.car, Primitive(eval(expr.cdr.car)), env)
&quot;)

(scheme-syntax define &quot;
def f(expr, env):
  set_symbol(expr.car, scheme_eval(expr.cdr.car, env), env)
&quot;)

(scheme-syntax if &quot;
def f(expr, env):
  if scheme_eval(expr.car, env):
    return scheme_eval(expr.cdr.car, env)
  else:
    return scheme_eval(expr.cdr.cdr.car, env)
&quot;)

(scheme-syntax lambda &quot;
def f(expr, env):
  return Procedure(expr.car, expr.cdr.car, env)
&quot;)
</pre>
<pre class="brush: plain; gutter: false; title: ; notranslate">
(define a (lambda (x) x))
a
;===&gt; &lt;scheme_types.Procedure object at 0xb733b10c&gt;
(a 42)
;===&gt; Attempted to apply a procedure
</pre>
<p>Now that we have a basic outline for what our procedures will look like, we can focus on making them work!</p>
<p>To apply a procedure we have to evaluate the <strong>body</strong>.  In the example above the body of the procedure is just <strong>x</strong>.  However we can&#8217;t just evaluate <strong>x</strong> because <strong>x</strong> is not bound to anything yet.  </p>
<p>First we need to create a new environment and bind the parameters to the arguments supplied in the procedure call.  In this case we have to bind <strong>x</strong> to the value <strong>42</strong>.  Then we just evaluate each expression in the body within the new environment and return the result of evaluating the last expression.</p>
<pre class="brush: python; highlight: [63,64]; title: ; wrap-lines: false; notranslate">
from scheme_types import Symbol, Pair, Primitive, the_empty_list, Procedure
from buffered_input import Buff
from scheme_read import scheme_read

##############################################################################
## Environments
##############################################################################

def current_environment(env):
  &quot;&quot;&quot;Return the frame of the current environment&quot;&quot;&quot;
  return env.car

def enclosing_environment(env):
  &quot;&quot;&quot;Return the environment stack with the first frame removed&quot;&quot;&quot;
  return env.cdr

def extend_environment(bindings, base_environment):
  &quot;&quot;&quot;Push a new frame onto the given base_environment&quot;&quot;&quot;
  return Pair(bindings, base_environment)

global_environment = extend_environment({}, the_empty_list)
special_forms = {}

def set_symbol(symbol, val, env):
  &quot;&quot;&quot;Set the binding (symbol, val) in the current frame of env&quot;&quot;&quot;
  current_environment(env)[symbol] = val

def lookup_symbol_value(symbol, environment):
  &quot;&quot;&quot;Return the value of symbol or Unbound Symbol error&quot;&quot;&quot;
  env = environment
  while env != the_empty_list:
    if symbol in current_environment(env):
      return current_environment(env)[symbol]
    else:
      env = enclosing_environment(env)
  return &quot;Error: Unbound symbol: &quot; + symbol

##############################################################################
## Eval and Apply
##############################################################################

def self_evaluating(expr):
  t = type(expr)
  return t is int or t is float or t is str or t is bool

def scheme_eval(expr, env):
  if self_evaluating(expr):
    return expr
  elif type(expr) is Symbol:
    return lookup_symbol_value(expr, env)
  elif type(expr) is Pair:
    if expr.car in special_forms:
      return special_forms[expr.car](expr.cdr, env)
    else:
      return scheme_apply(scheme_eval(expr.car, env), [scheme_eval(a, env) for a in expr.cdr])
  else:
    return &quot;scheme_eval: not implemented&quot;

def scheme_apply(proc, args):
  if type(proc) is Primitive:
    return apply(proc.fn, args)
  elif type(proc) is Procedure:
    new_env = extend_environment(dict(zip(proc.parameters, args)), proc.environment)
    return [scheme_eval(e,new_env) for e in proc.body][-1]
  else:
    return &quot;Error: Undefined procedure&quot;

##############################################################################
## Builtin Syntax
##############################################################################

def special_form_handler(expr, env):
  &quot;&quot;&quot;Register a symbol with a Python function named &quot;f&quot; that implements a special form&quot;&quot;&quot;
  exec(expr.cdr.car)
  special_forms[expr.car] = f

def load(expr):
  &quot;&quot;&quot;Given a filename, open it and eval each expression in the global_environment&quot;&quot;&quot;
  f = open(expr.car, 'r')
  b = Buff(f)
  while b.peek():
    scheme_eval(scheme_read(b), global_environment)
    b.remove_whitespace()
  f.close()

special_forms['scheme-syntax'] = special_form_handler
special_forms['load'] = load
</pre>
<pre class="brush: plain; gutter: false; title: ; notranslate">
(define test (pred conseq alt)
  (if pred conseq alt))
(test 1 2 3)
;===&gt; 2
(define-primitive + &quot;lambda x,y: x+y&quot;)
(define-primitive &lt; &quot;lambda x,y: x&lt;y&quot;)
(define a (lambda (x y) (if (&lt; x y) (a (+ x 1) y) x)))
(a 1 3)
;===&gt; 3
</pre>
<p>With that, we have implemented lambda in Scheme!  However there are some glaring omissions from our implementation.  For example ((lambda () 42)) will result in an iteration over non-sequence error from trying to iterate over the_empty_list.  Also, tail-call elimination is not implemented as required by the Scheme standard.  </p>
<p>Also note that there is very little error-checking going on here.  For instance calling a procedure with the wrong number of arguments results in the whole interpreter crashing.  This would not be good in a production language.  However including error checking in this code would probably triple its size at least.  The point of this exercise is to learn the concepts, not write a bullet-proof language.</p>
<p>I will likely come back to this at some point in the future and address some of these concerns.  The rest is left for you to experiment with.  You can get more information on how and what to implement from <a href="http://www.schemers.org/Documents/Standards/R5RS/">R5RS</a>.</p>
<p>I will be <a href="http://nickzarr.com/blog4/tag/jumping-into-javascript/">Jumping back into Javascript</a> for the next few posts at least, so this series will not be updated for a while (with the exception of bug fixes).  When I do get back to language design and implementation, I will probably pick back up with the Scheme version of this interpreter, or possibly with a new project on compiling.</p>
<p>If you have any questions about how to proceed from here, or just want to show off your own version, please leave a comment.</p>
<p><a href="https://github.com/jacktrades/Scheme-in-Python/tree/v0.10">Checkout this version on GitHub (v0.10)</a></p>
<p><a href="http://nickzarr.com/blog4/series/scheme-in-python/" title="Scheme in Python">GOTO | Table of Contents</a></p>
]]></content:encoded>
			<wfw:commentRss>http://nickzarr.com/blog4/2011/10/scheme-in-python-lambda/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scheme in Python &#8211; Environments</title>
		<link>http://nickzarr.com/blog4/2011/10/scheme-in-python-environments/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=scheme-in-python-environments</link>
		<comments>http://nickzarr.com/blog4/2011/10/scheme-in-python-environments/#comments</comments>
		<pubDate>Sun, 23 Oct 2011 23:54:46 +0000</pubDate>
		<dc:creator>Nick Zarczynski</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Scheme]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[interpreter]]></category>
		<category><![CDATA[Language Design]]></category>

		<guid isPermaLink="false">http://nickzarr.com/blog4/?p=1669</guid>
		<description><![CDATA[GOTO Part 8 &#124; Primitive procedures and apply We&#8217;ve been dealing with an environment ever since part 5 in this series when we implemented define, except we&#8217;ve been calling it a frame. Until now our frame has served us well, it has provided a simple environment where we could set and retrieve the value of [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://nickzarr.com/blog4/2011/10/scheme-in-python-primitive-procedures-and-apply/" title="Scheme in Python – Primitive procedures and apply">GOTO Part 8 | Primitive procedures and apply</a></p>
<p>We&#8217;ve been dealing with an <strong>environment</strong> ever since <a href="http://nickzarr.com/blog4/2011/10/scheme-in-python-assignment-and-define/" title="Scheme in Python – Assignment and define">part 5</a> in this series when we implemented define, except we&#8217;ve been calling it a <strong>frame</strong>.  Until now our frame has served us well, it has provided a simple environment where we could set and retrieve the value of symbols.  However implementing procedures requires us to add a few features to our frame.  Consider the code below.</p>
<pre class="brush: plain; title: ; notranslate">
(define x 5)
(define (func x)
  x)
(func 100)
;===&gt; 100
</pre>
<p>With our frame this wouldn&#8217;t work as expected.  Because we have already defined x in the global environment, there will be one of two problems with the x in <strong>func</strong>.  Our function could use the global value of x (5) instead of the supplied value (100) or when the supplied value (100) is mapped onto the function body it will overwrite the value of the global value of x (5) with the supplied value (100).</p>
<p>Currently we do not make any distinction between variables in a function body and in the global environment.  To properly implement procedures we will have to figure out a way to do that.  Consider the next bit of code.</p>
<pre class="brush: plain; title: ; notranslate">
(define x 5)
(define (func y)
  (+ x y))
(func 10)
;===&gt; 15
</pre>
<p>Even though we need to make a distinction between environments they also need to be connected.  In the example above we use the global variable x in func without ever declaring it.  This is accomplished by a method called chaining environments.  </p>
<pre class="brush: plain; title: ; notranslate">
(define x 1)
(define (outer-func y)
  (define (inner-func z)
    (+ x y z)
  (inner-func 3))
(outer-func 2)
;===&gt; 6
</pre>
<p>The environments produced by the above code are best described by the diagram below.</p>
<p><img src="https://docs.google.com/drawings/pub?id=1ODj7-OmaC-KHAITY2fvGrQIFqCn9sxMbit2iNjWrj2E&amp;w=580&amp;h=568"></p>
<p>So when x appears in inner-func we have to check inner-func&#8217;s environment for x, then outer-func&#8217;s environment for x and finally the global environment for x before we raise an undefined symbol error.</p>
<p>You may have noticed that the diagram above looks a lot like a <a href="http://nickzarr.com/blog4/2011/02/20/what-in-the-hell-are-linked-lists/">linked list</a>.  We can take our frame and combine it with linked lists to form an environment.  It is more informative (and closer to the actual design) to view environments from the point of view of eval.  This diagram is a view of the environment structure when the code (+ x y z) is evaluated.</p>
<p><img src="https://docs.google.com/drawings/pub?id=1RkD5O0pGCY08TLdkPzRIIp0fsxkPrB7z2vXqY37ZyZs&amp;w=580&amp;h=568"></p>
<p>I used the names <strong>current-environment</strong> to refer to the inner-func environment and <strong>enclosing-environment</strong> to refer to the outer-func environment.  We will use these same names in our source code.  Note that the <strong>global-environment</strong> is just the <strong>enclosing-environment</strong> of outer-func, the only thing special about it is that its <strong>enclosing-environment</strong> is the empty list.</p>
<p>In addition we need to replace our global frame with <strong>global_environment</strong>, which we&#8217;ll do by providing a procedure <strong>extend_environment</strong>, and change <strong>lookup_symbol_value</strong> to check enclosing-environments if the symbol is not found.</p>
<p><strong>scheme_eval.py</strong></p>
<pre class="brush: python; highlight: [1,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,42]; title: ; wrap-lines: false; notranslate">
from scheme_types import Symbol, Pair, Primitive, the_empty_list
from buffered_input import Buff
from scheme_read import scheme_read

def current_environment(env):
  &quot;&quot;&quot;Return the frame of the current environment&quot;&quot;&quot;
  return env.car

def enclosing_environment(env):
  &quot;&quot;&quot;Return the environment stack with the first frame removed&quot;&quot;&quot;
  return env.cdr

def extend_environment(bindings, base_environment):
  &quot;&quot;&quot;Push a new frame onto the given base_environment&quot;&quot;&quot;
  return Pair(bindings, base_environment)

global_environment = extend_environment({}, the_empty_list)
special_forms = {}

def set_symbol(symbol, val, env):
  &quot;&quot;&quot;Set the binding (symbol, val) in the current frame of env&quot;&quot;&quot;
  current_environment(env)[symbol] = val

def lookup_symbol_value(symbol, environment):
  &quot;&quot;&quot;Return the value of symbol or Unbound Symbol error&quot;&quot;&quot;
  env = environment
  while env != the_empty_list:
    if symbol in current_environment(env):
      return current_environment(env)[symbol]
    else:
      env = enclosing_environment(env)
  return &quot;Error: Unbound symbol: &quot; + symbol

def self_evaluating(expr):
  t = type(expr)
  return t is int or t is float or t is str or t is bool

def scheme_eval(expr):
  if self_evaluating(expr):
    return expr
  elif type(expr) is Symbol:
    return lookup_symbol_value(expr, global_environment)
  elif type(expr) is Pair:
    if expr.car in special_forms:
      return special_forms[expr.car](expr.cdr)
    else:
      return scheme_apply(scheme_eval(expr.car), [scheme_eval(a) for a in expr.cdr])
  else:
    return &quot;scheme_eval: not implemented&quot;

def scheme_apply(proc, args):
  if type(proc) is Primitive:
    return apply(proc.fn, args)
  else:
    return &quot;Error: Undefined procedure&quot;

def special_form_handler(expr):
  &quot;&quot;&quot;Register a symbol with a Python function named &quot;f&quot; that implements a special form&quot;&quot;&quot;
  exec(expr.cdr.car)
  special_forms[expr.car] = f

def load(expr):
  &quot;&quot;&quot;Given a filename, open it and eval each expression in the global_environment&quot;&quot;&quot;
  f = open(expr.car, 'r')
  b = Buff(f)
  while b.peek():
    scheme_eval(scheme_read(b))
    b.remove_whitespace()
  f.close()

special_forms['scheme-syntax'] = special_form_handler
special_forms['load'] = load
</pre>
<p>We also need to make some changes to syntax.scm to use the new set_symbol function.</p>
<p><strong>syntax.scm</strong></p>
<pre class="brush: plain; highlight: [3,8]; title: ; notranslate">
(scheme-syntax define-primitive &quot;
def f(expr):
  set_symbol(expr.car, Primitive(eval(expr.cdr.car)), global_environment)
&quot;)

(scheme-syntax define &quot;
def f(expr):
  set_symbol(expr.car, scheme_eval(expr.cdr.car), global_environment)
&quot;)

(scheme-syntax if &quot;
def f(expr):
  if scheme_eval(expr.car):
    return scheme_eval(expr.cdr.car)
  else:
    return scheme_eval(expr.cdr.cdr.car)
&quot;)
</pre>
<pre class="brush: plain; gutter: false; title: ; notranslate">
(define a 5)
;===&gt; #&lt;unspecified&gt;
a
;===&gt; 5
</pre>
<p>Before we go any further I&#8217;m going to add in some comments to the scheme_eval.py file, mainly to group code into logical sections.  I won&#8217;t provide a highlighted diff here, but you will notice the sections in the next bit of code.</p>
<p>To use the full potential of our new environments we are going to have to rewrite our program a little bit to pass them around correctly.  Since eval is the main method of dispatch for our interpreter we&#8217;ll supply the environment as an argument to eval, which means finding every use of scheme_eval and adding the env argument.  We&#8217;ll also have to pass an environment variable to procedures like set_symbol and lookup_symbol_value.  One final place we&#8217;ll need environments is in scheme-syntax, we&#8217;ll have to change the stored procedures there to use &#8220;def f(expr, env):&#8221; instead of just &#8220;def f(expr):&#8221;.</p>
<pre class="brush: python; highlight: [46,50,53,55,69,79]; title: ; wrap-lines: false; notranslate">
from scheme_types import Symbol, Pair, Primitive, the_empty_list
from buffered_input import Buff
from scheme_read import scheme_read

##############################################################################
## Environments
##############################################################################

def current_environment(env):
  &quot;&quot;&quot;Return the frame of the current environment&quot;&quot;&quot;
  return env.car

def enclosing_environment(env):
  &quot;&quot;&quot;Return the environment stack with the first frame removed&quot;&quot;&quot;
  return env.cdr

def extend_environment(bindings, base_environment):
  &quot;&quot;&quot;Push a new frame onto the given base_environment&quot;&quot;&quot;
  return Pair(bindings, base_environment)

global_environment = extend_environment({}, the_empty_list)
special_forms = {}

def set_symbol(symbol, val, env):
  &quot;&quot;&quot;Set the binding (symbol, val) in the current frame of env&quot;&quot;&quot;
  current_environment(env)[symbol] = val

def lookup_symbol_value(symbol, environment):
  &quot;&quot;&quot;Return the value of symbol or Unbound Symbol error&quot;&quot;&quot;
  env = environment
  while env != the_empty_list:
    if symbol in current_environment(env):
      return current_environment(env)[symbol]
    else:
      env = enclosing_environment(env)
  return &quot;Error: Unbound symbol: &quot; + symbol

##############################################################################
## Eval and Apply
##############################################################################

def self_evaluating(expr):
  t = type(expr)
  return t is int or t is float or t is str or t is bool

def scheme_eval(expr, env):
  if self_evaluating(expr):
    return expr
  elif type(expr) is Symbol:
    return lookup_symbol_value(expr, env)
  elif type(expr) is Pair:
    if expr.car in special_forms:
      return special_forms[expr.car](expr.cdr, env)
    else:
      return scheme_apply(scheme_eval(expr.car, env), [scheme_eval(a, env) for a in expr.cdr])
  else:
    return &quot;scheme_eval: not implemented&quot;

def scheme_apply(proc, args):
  if type(proc) is Primitive:
    return apply(proc.fn, args)
  else:
    return &quot;Error: Undefined procedure&quot;

##############################################################################
## Builtin Syntax
##############################################################################

def special_form_handler(expr, env):
  &quot;&quot;&quot;Register a symbol with a Python function named &quot;f&quot; that implements a special form&quot;&quot;&quot;
  exec(expr.cdr.car)
  special_forms[expr.car] = f

def load(expr):
  &quot;&quot;&quot;Given a filename, open it and eval each expression in the global_environment&quot;&quot;&quot;
  f = open(expr.car, 'r')
  b = Buff(f)
  while b.peek():
    scheme_eval(scheme_read(b), global_environment)
    b.remove_whitespace()
  f.close()

special_forms['scheme-syntax'] = special_form_handler
special_forms['load'] = load
</pre>
<p><strong>repl.py</strong></p>
<pre class="brush: python; highlight: [3,10]; title: ; notranslate">
import sys
from scheme_read import scheme_read
from scheme_eval import scheme_eval, special_forms, global_environment
from scheme_types import Pair
from buffered_input import Buff

special_forms['load'](Pair(&quot;syntax.scm&quot;, None))

while True:
  inp = scheme_eval(scheme_read(Buff(sys.stdin)), global_environment)
  if inp != None:
    print ';===&gt;', inp
</pre>
<p><strong>syntax.chicken</strong></p>
<pre class="brush: plain; highlight: [2,3,7,8,12,13,14,16]; title: ; notranslate">
(scheme-syntax define-primitive &quot;
def f(expr, env):
  set_symbol(expr.car, Primitive(eval(expr.cdr.car)), env)
&quot;)

(scheme-syntax define &quot;
def f(expr, env):
  set_symbol(expr.car, scheme_eval(expr.cdr.car, env), env)
&quot;)

(scheme-syntax if &quot;
def f(expr, env):
  if scheme_eval(expr.car, env):
    return scheme_eval(expr.cdr.car, env)
  else:
    return scheme_eval(expr.cdr.cdr.car, env)
&quot;)
</pre>
<pre class="brush: plain; gutter: false; title: ; notranslate">
(define a 5)
a
;===&gt; 5
(if 1 2 3)
;===&gt; 2
(if #f 1 2)
;===&gt; 2
(define-primitive + &quot;lambda x,y: x+y&quot;)
(+ 3 5)
;===&gt; 8
</pre>
<p>If you still don&#8217;t fully understand environments, that&#8217;s OK.  You&#8217;ll get a chance to play around with them in the next part where we&#8217;ll finally cover implementing procedures in Lispy!</p>
<p><a href="https://github.com/jacktrades/Scheme-in-Python/tree/v0.09">Checkout this version on GitHub (v0.09)</a></p>
<p><a href="http://nickzarr.com/blog4/2011/10/scheme-in-python-lambda/" title="Scheme in Python – lambda">GOTO Part 10 | lambda</a></p>
<p><a href="http://nickzarr.com/blog4/series/scheme-in-python/" title="Scheme in Python">GOTO | Table of Contents</a></p>
]]></content:encoded>
			<wfw:commentRss>http://nickzarr.com/blog4/2011/10/scheme-in-python-environments/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scheme in Python &#8211; Primitive procedures and apply</title>
		<link>http://nickzarr.com/blog4/2011/10/scheme-in-python-primitive-procedures-and-apply/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=scheme-in-python-primitive-procedures-and-apply</link>
		<comments>http://nickzarr.com/blog4/2011/10/scheme-in-python-primitive-procedures-and-apply/#comments</comments>
		<pubDate>Sun, 23 Oct 2011 20:16:32 +0000</pubDate>
		<dc:creator>Nick Zarczynski</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Scheme]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[interpreter]]></category>
		<category><![CDATA[Language Design]]></category>

		<guid isPermaLink="false">http://nickzarr.com/blog4/?p=1652</guid>
		<description><![CDATA[GOTO Part 7 &#124; Refactor and load The goal for this part is to implement primitive procedures, apply and a method of setting new primitives. The first thing we need to do is figure out a way to represent our primitive procedures. SICP uses tagged lists, which are just regular lists with the first element [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://nickzarr.com/blog4/2011/10/scheme-in-python-refactor-and-load/" title="Scheme in Python – Refactor and load">GOTO Part 7 | Refactor and load</a></p>
<p>The goal for this part is to implement primitive procedures, apply and a method of setting new primitives.</p>
<p>The first thing we need to do is figure out a way to represent our primitive procedures. <a href="http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-26.html#%_sec_4.1.3"> SICP</a> uses tagged lists, which are just regular lists with the first element designated as a tag.  Python uses objects to define new types and since we&#8217;ve already been doing that, we&#8217;ll continue here.  </p>
<pre class="brush: python; highlight: [25,26,27]; title: ; notranslate">
class Symbol(str):
  &quot;&quot;&quot;A symbol is an immutable string, but must be its own type.&quot;&quot;&quot;
  pass

class The_Empty_List():
  &quot;&quot;&quot;The empty list is used as a list terminator and should be a singleton&quot;&quot;&quot;
  def __repr__(self):
    return &quot;()&quot;

the_empty_list = The_Empty_List()

class Pair(object):
  &quot;&quot;&quot;A pair is a classic Lisp cons cell used to implement lists&quot;&quot;&quot;
  def __init__(self, car, cdr):
    self.car = car
    self.cdr = cdr
  def __iter__(self):
    x = self
    while not isinstance(x, The_Empty_List):
      yield x.car
      x = x.cdr
  def __repr__(self):
    return &quot;(&quot; + ' '.join([str(i) for i in list(self)]) + &quot;)&quot;

class Primitive(object):
  def __init__(self, fn):
    self.fn = fn
</pre>
<p>If the symbol of an expression of the form (symbol args &#8230;) is not found in special_forms it must be a procedure application (or not exist).  To apply a primitive procedure first we have to evaluate all the arguments using scheme_eval.  Then we use that list as the args value to apply(primitive, args).  The primitive returns a Scheme value and we continue on.</p>
<p>For now we&#8217;re going to hardcode one primitive + into our interpreter.  We&#8217;ll come up with something a little more elegant next.</p>
<pre class="brush: python; highlight: [1,5,27,31,32,33,34,35]; title: ; wrap-lines: false; notranslate">
from scheme_types import Symbol, Pair, Primitive
from buffered_input import Buff
from scheme_read import scheme_read

frame = {'+':Primitive(lambda x,y: x+y)}
special_forms = {}

def lookup_symbol_value(symbol):
  try:
    return frame[symbol]
  except KeyError:
    return &quot;Error: Unbound variable&quot;

def self_evaluating(expr):
  t = type(expr)
  return t is int or t is float or t is str or t is bool

def scheme_eval(expr):
  if self_evaluating(expr):
    return expr
  elif type(expr) is Symbol:
    return lookup_symbol_value(expr)
  elif type(expr) is Pair:
    if expr.car in special_forms:
      return special_forms[expr.car](expr.cdr)
    else:
      return scheme_apply(scheme_eval(expr.car), [scheme_eval(a) for a in expr.cdr])
  else:
    return &quot;scheme_eval: not implemented&quot;

def scheme_apply(proc, args):
  if type(proc) is Primitive:
    return apply(proc.fn, args)
  else:
    return &quot;Error: Undefined procedure&quot;

def special_form_handler(expr):
  &quot;&quot;&quot;Register a symbol with a Python function named &quot;f&quot; that implements a special form&quot;&quot;&quot;
  exec(expr.cdr.car)
  special_forms[expr.car] = f

def load(expr):
  &quot;&quot;&quot;Given a filename, open it and eval each expression in the global_environment&quot;&quot;&quot;
  f = open(expr.car, 'r')
  b = Buff(f)
  while b.peek():
    scheme_eval(scheme_read(b))
    b.remove_whitespace()
  f.close()

special_forms['scheme-syntax'] = special_form_handler
special_forms['load'] = load
</pre>
<pre class="brush: plain; title: ; notranslate">
(+ 3 4)
;===&gt; 7
(- 3 4)
;===&gt; Error: Undefined procedure
</pre>
<p>The next step is to allow defining primitive procedures from within Scheme, as we did with special forms.  We&#8217;ll implement define-primitive as a scheme-syntax macro.  First remove the line that sets the + symbol.  We&#8217;re only going to be modifying the syntax.scm file for now so that&#8217;s all I&#8217;ll show you.</p>
<p>We need to create a scheme-syntax macro that makes a Primitive object and sets it as the value of a symbol.  This macro is a lot like the define macro that we wrote earlier.  The only difference is instead of calling scheme_eval on the cadr we call eval and pass that result to make-primitive.</p>
<p><strong>syntax.scm</strong></p>
<pre class="brush: plain; highlight: [1,2,3,4]; title: ; notranslate">
(scheme-syntax define-primitive &quot;
def f(expr):
  frame[expr.car] = Primitive(eval(expr.cdr.car))
&quot;)

(scheme-syntax define &quot;
def f(expr):
  frame[expr.car] = scheme_eval(expr.cdr.car)
&quot;)

(scheme-syntax if &quot;
def f(expr):
  if scheme_eval(expr.car):
    return scheme_eval(expr.cdr.car)
  else:
    return scheme_eval(expr.cdr.cdr.car)
&quot;)
</pre>
<p>With that we can define all sorts of primitives for our language&#8230;</p>
<pre class="brush: plain; title: ; notranslate">
(define-primitive + &quot;lambda x,y: x+y&quot;)
(+ 3 4)
;===&gt; 7
(- 3 4)
;===&gt; Error: Undefined procedure

(define-primitive - &quot;lambda x,y: x-y&quot;)
(- 3 4)
;===&gt; -1

(define-primitive square &quot;lambda x: x*x&quot;)
(square 4)
;===&gt; 16

(define-primitive len &quot;len&quot;)
(len &quot;hello&quot;)
;===&gt; 5
</pre>
<p>You can start a new file and define a bunch of primitives, load it the same way you load syntax.scm.  I&#8217;m not going to define any primitives just yet but you are more than welcome to.  Instead in the next post we&#8217;ll implement environments and then it&#8217;s on to implementing lambda!</p>
<p><a href="https://github.com/jacktrades/Scheme-in-Python/tree/v0.08">Checkout this version on GitHub (v0.08)</a></p>
<p><a href="http://nickzarr.com/blog4/2011/10/scheme-in-python-environments/" title="Scheme in Python – Environments">GOTO Part 9 | Environments</a></p>
<p><a href="http://nickzarr.com/blog4/series/scheme-in-python/" title="Scheme in Python">GOTO | Table of Contents</a></p>
]]></content:encoded>
			<wfw:commentRss>http://nickzarr.com/blog4/2011/10/scheme-in-python-primitive-procedures-and-apply/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scheme in Python &#8211; Refactor and load</title>
		<link>http://nickzarr.com/blog4/2011/10/scheme-in-python-refactor-and-load/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=scheme-in-python-refactor-and-load</link>
		<comments>http://nickzarr.com/blog4/2011/10/scheme-in-python-refactor-and-load/#comments</comments>
		<pubDate>Wed, 19 Oct 2011 04:05:44 +0000</pubDate>
		<dc:creator>Nick Zarczynski</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Scheme]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[interpreter]]></category>
		<category><![CDATA[Language Design]]></category>

		<guid isPermaLink="false">http://nickzarr.com/blog4/?p=1603</guid>
		<description><![CDATA[GOTO Part 6 &#124; scheme-syntax macro In this part we&#8217;re going to be doing a bit of refactoring, so let&#8217;s start with that and a recap. The first thing that we&#8217;re going to do is remove define and if from our language. We&#8217;ll put them back in later, but first let&#8217;s look at what our [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://nickzarr.com/blog4/2011/10/scheme-in-python-scheme-syntax-macro-2/" title="Scheme in Python – scheme-syntax macro">GOTO Part 6 | scheme-syntax macro</a></p>
<p>In this part we&#8217;re going to be doing a bit of refactoring, so let&#8217;s start with that and a recap.  The first thing that we&#8217;re going to do is remove define and if from our language.  We&#8217;ll put them back in later, but first let&#8217;s look at what our language looks like with only scheme-syntax defined.</p>
<pre class="brush: python; title: ; wrap-lines: false; notranslate">
from scheme_types import Symbol, Pair

frame = {}
special_forms = {}

def lookup_symbol_value(symbol):
  try:
    return frame[symbol]
  except KeyError:
    return &quot;Error: Unbound variable&quot;

def self_evaluating(expr):
  t = type(expr)
  return t is int or t is float or t is str or t is bool

def scheme_eval(expr):
  if self_evaluating(expr):
    return expr
  elif type(expr) is Symbol:
    return lookup_symbol_value(expr)
  elif type(expr) is Pair:
    if expr.car in special_forms:
      return special_forms[expr.car](expr.cdr)
    else:
      return &quot;Error: unbound special form&quot;
  else:
    return &quot;scheme_eval: not implemented&quot;

def special_form_handler(expr):
  &quot;&quot;&quot;Register a symbol with a Python function named &quot;f&quot; that implements a special form&quot;&quot;&quot;
  exec(expr.cdr.car)
  special_forms[expr.car] = f

special_forms['scheme-syntax'] = special_form_handler
</pre>
<p>Let&#8217;s take a moment to consider what we can do so far.  We now have a language that can understand self-evaluating Scheme values and lookup symbol values.  In addition to that it has exactly one primitive, a macro that defines other primitives by giving us access to Python.</p>
<p>You may consider this language lacking, and I admit it does not have many features.  However it is now possible to define any language construct (including procedures, eval and apply) from within Scheme with the help of scheme-syntax and Python underneath.  After writing this code we could define the rest of the language 100% from within Scheme (though it may not be easy).</p>
<p>However there are a few more things that conceptually belong in the core language.  One of those things is the ability to load a Scheme file.  This will let us break out our syntax definitions into another file and load it automatically before we start the repl.</p>
<pre class="brush: python; highlight: [2,3,36,37,38,39,40,41,42,43,46]; title: ; wrap-lines: false; notranslate">
from scheme_types import Symbol, Pair
from buffered_input import Buff
from scheme_read import scheme_read

frame = {}
special_forms = {}

def lookup_symbol_value(symbol):
  try:
    return frame[symbol]
  except KeyError:
    return &quot;Error: Unbound variable&quot;

def self_evaluating(expr):
  t = type(expr)
  return t is int or t is float or t is str or t is bool

def scheme_eval(expr):
  if self_evaluating(expr):
    return expr
  elif type(expr) is Symbol:
    return lookup_symbol_value(expr)
  elif type(expr) is Pair:
    if expr.car in special_forms:
      return special_forms[expr.car](expr.cdr)
    else:
      return &quot;Error: unbound special form&quot;
  else:
    return &quot;scheme_eval: not implemented&quot;

def special_form_handler(expr):
  &quot;&quot;&quot;Register a symbol with a Python function named &quot;f&quot; that implements a special form&quot;&quot;&quot;
  exec(expr.cdr.car)
  special_forms[expr.car] = f

def load(expr):
  &quot;&quot;&quot;Given a filename, open it and eval each expression in the global_environment&quot;&quot;&quot;
  f = open(expr.car, 'r')
  b = Buff(f)
  while b.peek():
    scheme_eval(scheme_read(b))
    b.remove_whitespace()
  f.close()

special_forms['scheme-syntax'] = special_form_handler
special_forms['load'] = load
</pre>
<p>Now that we have load, we need something to load.  Create a new file called syntax.scm, or whatever you prefer.  This is where we will define our primitive syntax forms like define, if and lambda.  For this moment we&#8217;re going to leave it blank, and make the repl load it by default so we don&#8217;t have to do it manually each time.  </p>
<p>Also I&#8217;m going to make some changes to the repl to make our sessions look more like the examples I&#8217;ve been giving (so ;===> will come before the output and there will be no prompt for input).  Later I may go back to the beginning of this series and change this, as this is how it should have been from the start.  I&#8217;ll also take this opportunity to skip printing any None value which will make using expressions that don&#8217;t return values more aesthetically pleasing.</p>
<p><strong>repl.py</strong></p>
<pre class="brush: python; highlight: [3,4,7,10,11,12]; title: ; wrap-lines: false; notranslate">
import sys
from scheme_read import scheme_read
from scheme_eval import scheme_eval, special_forms
from scheme_types import Pair
from buffered_input import Buff

special_forms['load'](Pair(&quot;syntax.scm&quot;, None))

while True:
  inp = scheme_read(Buff(sys.stdin))
  if inp != None:
    print ';===&gt;', scheme_eval(inp)
</pre>
<p>Now we can define some special forms in syntax.scm to load by default.  For now we&#8217;ll just reimplement define and if.</p>
<p><strong>syntax.scm</strong></p>
<pre class="brush: plain; title: ; notranslate">
(scheme-syntax define &quot;
def f(expr):
  special_forms[expr.car] = scheme_eval(expr.cdr.car)
&quot;)

(scheme-syntax if &quot;
def f(expr):
  if scheme_eval(expr.car):
    return scheme_eval(expr.cdr.car)
  else:
    return scheme_eval(expr.cdr.cdr.car)
&quot;)
</pre>
<pre class="brush: plain; title: ; notranslate">
(define a 5)
a
;===&gt; 5
(if 1 2 3)
;===&gt; 2
</pre>
<p>Now that we have implemented load we are one step closer to having a platform that we can build almost any language we want with.  To change languages all we would have to do is load a different syntax file.</p>
<p>I encourage you to play around with that concept for a little while.  Write two different syntax.scm files and implement a couple of basic forms like define, or and if.  Try to make your two implementations as different as possible even if making it different doesn&#8217;t make sense.  For instance in one implementation if could take a mandatory keyword before the alternate branch (if pred consequent else alt) or it could act like and, taking two predicates and only evaluating the consequent branch if both predicates evaluate to true.</p>
<p>This article is a little short on code because we made some larger conceptual changes that I did not want to breeze past.  In the next article we&#8217;ll implement primitive procedures and apply.  The ability to define procedures from within Scheme is just around the corner.</p>
<p><a href="https://github.com/jacktrades/Scheme-in-Python/tree/v0.07">Checkout this version on GitHub (v0.07)</a></p>
<p><a href="http://nickzarr.com/blog4/2011/10/scheme-in-python-primitive-procedures-and-apply/" title="Scheme in Python – Primitive procedures and apply">GOTO Part 8 | Primitive procedures and apply</a></p>
<p><a href="http://nickzarr.com/blog4/series/scheme-in-python/" title="Scheme in Python">GOTO | Table of Contents</a></p>
]]></content:encoded>
			<wfw:commentRss>http://nickzarr.com/blog4/2011/10/scheme-in-python-refactor-and-load/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scheme in Python &#8211; scheme-syntax macro</title>
		<link>http://nickzarr.com/blog4/2011/10/scheme-in-python-scheme-syntax-macro-2/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=scheme-in-python-scheme-syntax-macro-2</link>
		<comments>http://nickzarr.com/blog4/2011/10/scheme-in-python-scheme-syntax-macro-2/#comments</comments>
		<pubDate>Tue, 18 Oct 2011 22:18:35 +0000</pubDate>
		<dc:creator>Nick Zarczynski</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Scheme]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[interpreter]]></category>
		<category><![CDATA[Language Design]]></category>

		<guid isPermaLink="false">http://nickzarr.com/blog4/?p=1587</guid>
		<description><![CDATA[GOTO Part 5 &#124; Assignment and define In the last part we implemented our first special form and the first expression that was not self-evaluating, define. The goal for this part is to implement (if predicate consequent alternate). We&#8217;re going to start by implementing if the same way we implemented define. The first thing to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://nickzarr.com/blog4/2011/10/scheme-in-python-assignment-and-define/" title="Scheme in Python – Assignment and define">GOTO Part 5 | Assignment and define</a></p>
<p>In the last part we implemented our first special form and the first expression that was not self-evaluating, define.  The goal for this part is to implement (if predicate consequent alternate).</p>
<p>We&#8217;re going to start by implementing if the same way we implemented define.  The first thing to do is test if the car of the pair equals if, then call a helper procedure we&#8217;ll name apply_if.</p>
<p>We know that if will have to evaluate the predicate argument to determine whether to evaluate the consequent or alternate arguments.  If the predicate is true we will evaluate the consequent expression and not the alternate.  If the predicate is false we will evaluate the alternate expression and not the consequent.</p>
<pre class="brush: python; highlight: [24,25,31,32,33,34,35]; title: ; wrap-lines: false; notranslate">
from scheme_types import Symbol, Pair

frame = {}

def lookup_symbol_value(symbol):
  try:
    return frame[symbol]
  except KeyError:
    return &quot;Error: Unbound variable&quot;

def self_evaluating(expr):
  t = type(expr)
  return t is int or t is float or t is str or t is bool

def scheme_eval(expr):
  if self_evaluating(expr):
    return expr
  elif type(expr) is Symbol:
    return lookup_symbol_value(expr)
  elif type(expr) is Pair:
    if expr.car == &quot;define&quot;:
      frame[expr.cdr.car] = scheme_eval(expr.cdr.cdr.car)
      return &quot;set symbol -&gt; value&quot;
    elif expr.car == &quot;if&quot;:
      return apply_if(expr.cdr.car, expr.cdr.cdr.car, expr.cdr.cdr.cdr.car)
    else:
      return &quot;scheme_eval: not implemented&quot;
  else:
    return &quot;scheme_eval: not implemented&quot;

def apply_if(predicate, consequent, alternate):
  if scheme_eval(predicate):
    return scheme_eval(consequent)
  else:
    return scheme_eval(alternate)
</pre>
<pre class="brush: plain; title: ; notranslate">
(if 1 2 3)
;===&gt; 2
(if #f 2 3)
;===&gt; 3
</pre>
<p>Dispatching special forms using if is fine while you have a small number of primitive syntax forms.  However once you implement a large number of primitive syntax forms this method of dispatch becomes cumbersome.  Also note that it is not possible to extend the primitive syntax forms except by modifying the original source by hand.</p>
<p>&nbsp;</p>
<h3>Reusing the Frame</h3>
<p>On top of that we have already implemented a mechanism of associating and storing symbol and value pairs.  Let&#8217;s try something like that first, we&#8217;ll start by making another global dictionary called special_forms.  Then we&#8217;ll modify eval to check this dictionary instead of using if/elif.</p>
<pre class="brush: python; highlight: [4,22,23,24,25,29,30,31,32,33,34,35,36,37,38,39,40]; title: ; wrap-lines: false; notranslate">
from scheme_types import Symbol, Pair

frame = {}
special_forms = {}

def lookup_symbol_value(symbol):
  try:
    return frame[symbol]
  except KeyError:
    return &quot;Error: Unbound variable&quot;

def self_evaluating(expr):
  t = type(expr)
  return t is int or t is float or t is str or t is bool

def scheme_eval(expr):
  if self_evaluating(expr):
    return expr
  elif type(expr) is Symbol:
    return lookup_symbol_value(expr)
  elif type(expr) is Pair:
    if expr.car in special_forms:
      return special_forms[expr.car](expr.cdr)
    else:
      return &quot;Error: unbound special form&quot;
  else:
    return &quot;scheme_eval: not implemented&quot;

def define(expr):
  frame[expr.car] = scheme_eval(expr.cdr.car)
  return &quot;set symbol -&gt; value&quot;

def apply_if(expr):
  if scheme_eval(expr.car):
    return scheme_eval(expr.cdr.car)
  else:
    return scheme_eval(expr.cdr.cdr.car)

special_forms['define'] = define
special_forms['if'] = apply_if
</pre>
<pre class="brush: plain; title: ; notranslate">
(repl)
(define a 5)
;===&gt; #&lt;unspecified&gt;
a
;===&gt; 5
(if 1 2 3)
;===&gt; 2
(hello)
;===&gt; Not implemented
</pre>
<p>With that addition we are finished with the first level of the eval function.  An expression can only be one of three things: self-evaluating, a symbol or an application (either syntax or procedure which we&#8217;ll cover later).</p>
<p>How does it work?  special_forms stores (symbol, procedure) pairs where the symbol is a keyword (like define or if) and the procedure is the Python code that implements that special form.  Every procedure in special_forms takes a single argument, an unevaluated pair representing the rest of the expression passed to scheme_eval.  Because special forms have their own evaluation rules, it is the responsibility of this procedure to evaluate the expression and return a result.</p>
<p>In other words, when lispy-eval comes across a special form it transfers control to a Python procedure located in the special_forms dict.  That Python procedure is responsible for evaluating the arguments and returning a Scheme value.</p>
<p>Now that we have a data structure to hold our special_forms it would be a good idea to supply an easy mechanism to set a new special form.  For this purpose we&#8217;ll design a special form in Scheme that will set new special forms called scheme-syntax.</p>
<pre class="brush: python; highlight: [29,30,31,32,33,34]; title: ; wrap-lines: false; notranslate">
from scheme_types import Symbol, Pair

frame = {}
special_forms = {}

def lookup_symbol_value(symbol):
  try:
    return frame[symbol]
  except KeyError:
    return &quot;Error: Unbound variable&quot;

def self_evaluating(expr):
  t = type(expr)
  return t is int or t is float or t is str or t is bool

def scheme_eval(expr):
  if self_evaluating(expr):
    return expr
  elif type(expr) is Symbol:
    return lookup_symbol_value(expr)
  elif type(expr) is Pair:
    if expr.car in special_forms:
      return special_forms[expr.car](expr.cdr)
    else:
      return &quot;Error: unbound special form&quot;
  else:
    return &quot;scheme_eval: not implemented&quot;

def special_form_handler(expr):
  &quot;&quot;&quot;Register a symbol with a Python function named &quot;f&quot; that implements a special form&quot;&quot;&quot;
  exec(expr.cdr.car)
  special_forms[expr.car] = f

special_forms['scheme-syntax'] = special_form_handler

def define(expr):
  frame[expr.car] = scheme_eval(expr.cdr.car)
  return &quot;set symbol -&gt; value&quot;

def apply_if(expr):
  if scheme_eval(expr.car):
    return scheme_eval(expr.cdr.car)
  else:
    return scheme_eval(expr.cdr.cdr.car)

special_forms['define'] = define
special_forms['if'] = apply_if
</pre>
<pre class="brush: plain; title: ; notranslate">
(scheme-syntax quote &quot;def f(expr): return expr.car&quot;)
;===&gt; None
(1 2 3)
;===&gt; Error: unbound special form
(quote (1 2 3))
;===&gt; (1 2 3)
</pre>
<p>With the addition of scheme-syntax it is now possible to write Python directly in our interpreter.  Because of this we can now implement all of the primitive syntax forms in Scheme.  Some might consider this cheating, but eventually we&#8217;re going to want a way to interface with Python.  Why not implement it right away, use it, test it and make it solid by implementing everything else in it?  We&#8217;ll still have to make some modifications to the core interpreter to implement procedures and a load form later.</p>
<p>Because of Python&#8217;s restrictions on lambda expressions, this solution is not as elegant as the <a href="http://nickzarr.com/blog4/2011/02/scheme-syntax/" title="Lispy in Scheme | scheme-syntax macro">scheme-syntax form in Scheme in Scheme</a>.  For this version you must define a named function, and it must be named &#8220;f&#8221; to make this implementation work.  If you know of a more elegant way to approach this please let me know in the comments.  </p>
<p>We haven&#8217;t even gotten to the mutually recursive yin-yang that is the eval/apply cycle yet.  However, thanks to piggy-backing on Python, we already have a somewhat useful language.  A language without procedures is a pretty bad one, so we&#8217;ll keep pressing on, but check out some of the things that are possible already&#8230;</p>
<pre class="brush: plain; title: ; notranslate">
(scheme-syntax print &quot;
def f(expr):
  print scheme_eval(expr.car)
  return None
&quot;)
;===&gt; None
(scheme-syntax loop &quot;
def f(expr):
  for n in range(scheme_eval(expr.car)):
    scheme_eval(expr.cdr.car)
&quot;)
;===&gt; None
(loop 3 (print &quot;Hi&quot;))
;===&gt; Hi
;===&gt; Hi
;===&gt; Hi
;===&gt; None
</pre>
<p>In the next article we&#8217;ll do  a little refactoring, remove define and if from the core of the interpreter and implement a load function so we can remove our syntax definitions out of the main interpreter file.</p>
<p><a href="https://github.com/jacktrades/Scheme-in-Python/tree/v0.06">Checkout this version on GitHub (v0.06)</a></p>
<p><a href="http://nickzarr.com/blog4/2011/10/scheme-in-python-refactor-and-load/" title="Scheme in Python – Refactor and load">GOTO Part 7 | Refactor and load</a></p>
<p><a href="http://nickzarr.com/blog4/series/scheme-in-python/" title="Scheme in Python">GOTO | Table of Contents</a></p>
]]></content:encoded>
			<wfw:commentRss>http://nickzarr.com/blog4/2011/10/scheme-in-python-scheme-syntax-macro-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scheme in Python &#8211; Assignment and define</title>
		<link>http://nickzarr.com/blog4/2011/10/scheme-in-python-assignment-and-define/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=scheme-in-python-assignment-and-define</link>
		<comments>http://nickzarr.com/blog4/2011/10/scheme-in-python-assignment-and-define/#comments</comments>
		<pubDate>Thu, 13 Oct 2011 04:14:03 +0000</pubDate>
		<dc:creator>Nick Zarczynski</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Scheme]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[interpreter]]></category>
		<category><![CDATA[Language Design]]></category>

		<guid isPermaLink="false">http://nickzarr.com/blog4/?p=1574</guid>
		<description><![CDATA[GOTO Part 4 &#124; Self-evaluating values Our goal in this part is to implement assignment via the form (define symbol value). There are three challenges to this goal. First we need to come up with a system to store symbol names and their values. Then we need to display those values when the symbol is [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://nickzarr.com/blog4/2011/10/scheme-in-python-self-evaluating-values/" title="Scheme in Python – Self-evaluating values">GOTO Part 4 | Self-evaluating values</a></p>
<p>Our goal in this part is to implement assignment via the form (define symbol value).  There are three challenges to this goal.  First we need to come up with a system to store symbol names and their values.  Then we need to display those values when the symbol is eval&#8217;d.  Finally we need to recognize the define form and set the value of its symbol.</p>
<p>&nbsp;</p>
<h3>Starting with a Stub</h3>
<p>To start with we need to modify our eval procedure to recognize symbols.  We&#8217;ll call a procedure lookup_symbol_value that will eventually give the value of the symbol.  Right now we&#8217;ll just have it return a string stating our intentions.</p>
<pre class="brush: python; highlight: [1,3,4,13,14]; title: ; notranslate">
from scheme_types import Symbol

def lookup_symbol_value(symbol):
  return &quot;Here's where we lookup the value of the symbol.&quot;

def self_evaluating(expr):
  t = type(expr)
  return t is int or t is float or t is str or t is bool

def scheme_eval(expr):
  if self_evaluating(expr):
    return expr
  elif type(expr) is Symbol:
    return lookup_symbol_value(expr)
  else:
    return &quot;scheme_eval: not implemented&quot;
</pre>
<p>&nbsp;</p>
<h3>The Global Frame</h3>
<p>To set the value of a symbol we need to have somewhere to set it.  That somewhere is going to be a <a href="http://nickzarr.com/blog4/2011/02/20/what-in-the-hell-are-hash-tables/">dictionary</a>.  The dictionary that stores a set of names and their associated values is referred to as a frame.</p>
<p>For now we&#8217;ll define our frame as a global variable named frame.  Since we don&#8217;t have any method of assigning values to symbols yet, we define a symbol &#8220;test&#8221; when we make the frame so we can see if it works.</p>
<pre class="brush: python; highlight: [3,6,7,8,9]; title: ; notranslate">
from scheme_types import Symbol

frame = {'test':&quot;Value retrieved successfully&quot;}

def lookup_symbol_value(symbol):
  try:
    return frame[symbol]
  except KeyError:
    return &quot;Error: Unbound variable&quot;

def self_evaluating(expr):
  t = type(expr)
  return t is int or t is float or t is str or t is bool

def scheme_eval(expr):
  if self_evaluating(expr):
    return expr
  elif type(expr) is Symbol:
    return lookup_symbol_value(expr)
  else:
    return &quot;scheme_eval: not implemented&quot;
</pre>
<p><br/></p>
<pre class="brush: plain; title: ; notranslate">
test
;===&gt; Value retrieved successfully
hello
;===&gt; Error: Unbound variable
</pre>
<p><br/></p>
<h3>(define symbol value)</h3>
<p>Now that we can store and retrieve the value of a symbol, we need a way to do it from within Scheme.  Scheme uses the form (define symbol value) to define a new symbol or set the value of an existing symbol.</p>
<p>The form (define symbol value) is a pair (also a list, but all lists are also pairs) so the first step to detecting its usage is to look for pairs.  The next step is to check the symbol in the car of that pair (or the first item of the list), if that symbol is &#8220;define&#8221; we run the code to define a symbol.  For now we&#8217;ll just return a string stating our intentions.</p>
<pre class="brush: python; highlight: [1,20,21,22,23,24]; title: ; notranslate">
from scheme_types import Symbol, Pair

frame = {'test':&quot;Value retrieved successfully&quot;}

def lookup_symbol_value(symbol):
  try:
    return frame[symbol]
  except KeyError:
    return &quot;Error: Unbound variable&quot;

def self_evaluating(expr):
  t = type(expr)
  return t is int or t is float or t is str or t is bool

def scheme_eval(expr):
  if self_evaluating(expr):
    return expr
  elif type(expr) is Symbol:
    return lookup_symbol_value(expr)
  elif type(expr) is Pair:
    if expr.car == &quot;define&quot;:
      return &quot;set the value of the symbol&quot;
    else:
      return &quot;scheme_eval: not implemented&quot;
  else:
    return &quot;scheme_eval: not implemented&quot;
</pre>
<p><br/></p>
<pre class="brush: plain; title: ; notranslate">
test
;===&gt; Value retrieved successfully
(define a 1)
;===&gt; Set the value of the symbol.
(set a 1)
;===&gt; scheme_eval: not implemented
</pre>
<p><br/></p>
<h3>Setting the Value of Symbols</h3>
<p>To actually set the value of the symbol we need to get the arguments to define.  Getting the symbol argument is straightforward, however we need to eval the value argument as it might not be self-evaluating.</p>
<p>Usually (define symbol value) will return void, or nothing.  I have chosen to return a string here to give some visual feedback that setting the symbol happened as well as avoid having to modify the repl to handle None.  You can choose to take the more standard approach and return None here, then modify the repl to skip printing None values.</p>
<pre class="brush: python; highlight: [22,23]; title: ; notranslate">
from scheme_types import Symbol, Pair

frame = {}

def lookup_symbol_value(symbol):
  try:
    return frame[symbol]
  except KeyError:
    return &quot;Error: Unbound variable&quot;

def self_evaluating(expr):
  t = type(expr)
  return t is int or t is float or t is str or t is bool

def scheme_eval(expr):
  if self_evaluating(expr):
    return expr
  elif type(expr) is Symbol:
    return lookup_symbol_value(expr)
  elif type(expr) is Pair:
    if expr.car == &quot;define&quot;:
      frame[expr.cdr.car] = scheme_eval(expr.cdr.cdr.car)
      return &quot;set symbol -&gt; value&quot;
    else:
      return &quot;scheme_eval: not implemented&quot;
  else:
    return &quot;scheme_eval: not implemented&quot;
</pre>
<p><br/></p>
<pre class="brush: plain; title: ; notranslate">
a
;===&gt; Error: Unbound variable
(define a 5)
;===&gt; set symbol -&gt; value
a
;===&gt; 5
</pre>
<p><br/></p>
<p>In addition to being able to set symbols, we now have a glimpse into how basic forms (like define) are handled.  It really is no more complicated than checking the procedure name, evaluating the arguments that need to be, then passing the arguments to a Python procedure that implements the desired functionality.</p>
<p>* To any Schemers that may be reading this:  I avoided implementing environments here for two reasons.  I wanted to show the simplest implementation possible and in an upcoming post we will transform our global frame into a lookup table for primitive syntax.</p>
<p><a href="https://github.com/jacktrades/Scheme-in-Python/tree/v0.05">Checkout this version on GitHub (v0.05)</a></p>
<p><a href="http://nickzarr.com/blog4/2011/10/scheme-in-python-scheme-syntax-macro-2/" title="Scheme in Python – scheme-syntax macro">GOTO Part 6 | scheme-syntax macro</a></p>
<p><a href="http://nickzarr.com/blog4/series/scheme-in-python/" title="Scheme in Python">GOTO | Table of Contents</a></p>
]]></content:encoded>
			<wfw:commentRss>http://nickzarr.com/blog4/2011/10/scheme-in-python-assignment-and-define/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scheme in Python &#8211; Self-evaluating values</title>
		<link>http://nickzarr.com/blog4/2011/10/scheme-in-python-self-evaluating-values/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=scheme-in-python-self-evaluating-values</link>
		<comments>http://nickzarr.com/blog4/2011/10/scheme-in-python-self-evaluating-values/#comments</comments>
		<pubDate>Wed, 12 Oct 2011 04:24:37 +0000</pubDate>
		<dc:creator>Nick Zarczynski</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Scheme]]></category>
		<category><![CDATA[interpreter]]></category>
		<category><![CDATA[Language Design]]></category>

		<guid isPermaLink="false">http://nickzarr.com/blog4/?p=1558</guid>
		<description><![CDATA[GOTO Part 3 &#124; Pairs and linked lists In the last post we finished implementing the read layer. There is a lot of room for improvement, however it will serve our purposes for the moment. With the read layer complete we can move on to the eval layer. The eval layer is where the Scheme [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://nickzarr.com/blog4/2011/10/scheme-in-python-pairs-and-linked-lists/" title="Scheme in Python – Pairs and linked lists">GOTO Part 3 | Pairs and linked lists</a></p>
<p>In the last post we finished implementing the read layer.  There is a lot of room for improvement, however it will serve our purposes for the moment.  With the read layer complete we can move on to the eval layer.</p>
<p>The eval layer is where the <a href="http://nickzarr.com/blog4/series/lispy-in-scheme/" title="Lispy in Scheme">Scheme in Scheme</a> series starts and from here on there will be many similarities between these two series.  In fact a sizable portion of this post was simply copy/pasted from the <a href="http://nickzarr.com/blog4/series/lispy-in-scheme/" title="Lispy in Scheme">Scheme in Scheme</a> series.  With the exception of the code and language specific explanation of it, the rest of the series will also be a close replica.</p>
<p>Create a new file called scheme_eval.py, the rest of this series will focus mainly on this file.  In it we will define a function scheme_eval.  For now we&#8217;re simply going to echo the input back without processing it at all.</p>
<p><strong>scheme_eval.py</strong></p>
<pre class="brush: python; highlight: [1,2]; title: ; notranslate">
def scheme_eval(expr):
  return expr
</pre>
<p><strong>repl.py</strong></p>
<pre class="brush: python; highlight: [3,8]; title: ; notranslate">
import sys
from scheme_read import scheme_read
from scheme_eval import scheme_eval
from buffered_input import Buff

while True:
  print &quot;&gt; &quot;,
  print scheme_eval(scheme_read(Buff(sys.stdin)))
</pre>
<p>With that we have the basic layout of the interpreter.  If you read the last line backward you will see the layers of the interpreter print(eval(read(stdin))) all wrapped up in an infinite loop.  From this point we can concentrate on evaluating the expressions that scheme_read returns.</p>
<p><br/></p>
<h3>A Language of Numbers</h3>
<p>The simplest language is a language of numbers. Numbers are self-evaluating, so if the expression is a number we’ll just return it for now.  If the expression is anything else, we&#8217;ll return an error string, just as we did in the read layer.  If you are following along, you will probably want to add proper errors/error handling to your version.</p>
<pre class="brush: python; highlight: [2,3,4,5]; title: ; notranslate">
def scheme_eval(expr):
  if type(expr) is int:
    return expr
  else:
    return &quot;scheme_eval: not implemented&quot;
</pre>
<p><br/></p>
<h3>A Language of Self-Evaluating Values</h3>
<p>Continuing with our language of self-evaluating values is just as simple. Booleans, strings and characters are also self-evaluating so we’ll add them now. More complex data structures like hash tables are also self evaluating, however we’ll leave them for later.</p>
<pre class="brush: python; highlight: [1,2,3,6]; title: ; notranslate">
def self_evaluating(expr):
  t = type(expr)
  return t is int or t is float or t is str or t is bool

def scheme_eval(expr):
  if self_evaluating(expr):
    return expr
  else:
    return &quot;scheme_eval: not implemented&quot;
</pre>
<p>The first stage of the eval layer is complete. We now have a functional language of self-evaluating values. Though one could argue exactly how functional it really is. The next step along our path will be to introduce symbols and implement assignment.</p>
<p><a href="https://github.com/jacktrades/Scheme-in-Python/tree/v0.04">Checkout this version on GitHub (v0.04)</a></p>
<p><a href="http://nickzarr.com/blog4/2011/10/scheme-in-python-assignment-and-define/" title="Scheme in Python – Assignment and define">GOTO Part 5 | Assignment and define</a></p>
<p><a href="http://nickzarr.com/blog4/series/scheme-in-python/" title="Scheme in Python">GOTO | Table of Contents</a></p>
]]></content:encoded>
			<wfw:commentRss>http://nickzarr.com/blog4/2011/10/scheme-in-python-self-evaluating-values/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scheme in Python &#8211; Pairs and linked lists</title>
		<link>http://nickzarr.com/blog4/2011/10/scheme-in-python-pairs-and-linked-lists/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=scheme-in-python-pairs-and-linked-lists</link>
		<comments>http://nickzarr.com/blog4/2011/10/scheme-in-python-pairs-and-linked-lists/#comments</comments>
		<pubDate>Sat, 08 Oct 2011 22:53:19 +0000</pubDate>
		<dc:creator>Nick Zarczynski</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Scheme]]></category>
		<category><![CDATA[interpreter]]></category>
		<category><![CDATA[Language Design]]></category>

		<guid isPermaLink="false">http://nickzarr.com/blog4/?p=1514</guid>
		<description><![CDATA[GOTO Part 2 &#124; Extending the read layer In the last post we added support for booleans, characters, symbols and strings. There is only one major data type left to add in the read layer, the pair/linked list. A pair is a structure which contains 2 elements normally referred to as the car and cdr [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://nickzarr.com/blog4/2011/10/scheme-in-python-extending-the-read-layer/" title="Scheme in Python – Extending the read layer">GOTO Part 2 | Extending the read layer</a></p>
<p>In the last post we added support for booleans, characters, symbols and strings.  There is only one major data type left to add in the read layer, the pair/linked list.</p>
<p>A pair is a structure which contains 2 elements normally referred to as the <strong>car</strong> and <strong>cdr</strong> in Scheme.  Lists are built on top of pairs where the car is some value and the cdr is another pair or the empty list.  In a <em>proper list</em> the cdr of the last pair must be the empty list.</p>
<p>To illustrate this concept a bit more clearly here is a diagram of the list &#8216;(1 2 3) in Scheme:</p>
<p><img src="http://docs.google.com/drawings/pub?id=1D5UHl9anYnTkiFgjCKYt14-MTUnCa4oXYiqGQkL6NpM&amp;w=354&amp;h=55"></p>
<p>This list is constructed out of 3 pairs.  The car of the first pair is the value 1 and the cdr is the second pair.  The car of the second pair has the value 2 and the cdr is the third pair.  The car of the third pair has the value 3 and the cdr contains the empty list (Nil in the diagram).</p>
<pre class="brush: python; title: ; notranslate">
class Pair:
  def __init__(self, car, cdr):
    self.car = car
    self.cdr = cdr
</pre>
<p>Above is the class definition for a very simple Pair object in Python.  We can construct the above list using the Pair class as follows:</p>
<pre class="brush: python; title: ; notranslate">
lst = Pair(1, Pair(2, Pair(3, None)))
</pre>
<p>This implementation of a list is called a linked list and you can find a more detailed description in my article <a href="http://nickzarr.com/blog4/2011/02/what-in-the-hell-are-linked-lists/" title="What In The Hell Are Linked Lists">WITH Linked Lists</a>.  Python does not have an implementation of a list in the core language, the list data type in Python is called an array in most other languages.</p>
<p>Scheme sourcecode is written using the linked list data type.  This is one of the most powerful features of the language as the sourcecode is just a regular Scheme data type.  This allows some really interesting features such as macros, but we won&#8217;t get into that just yet.</p>
<p>To start with we&#8217;ll implement the empty list.  Since this is a distinct object in Scheme we&#8217;ll make a new type called The_Empty_List and since we only need one empty list we&#8217;ll also make a global variable to refer to it called the_empty_list.  We&#8217;ll do this in the scheme_types.py file.</p>
<pre class="brush: python; highlight: [5,6,7,8,9,10]; title: ; notranslate">
class Symbol(str):
  &quot;&quot;&quot;A symbol is an immutable string, but must be its own type.&quot;&quot;&quot;
  pass

class The_Empty_List():
  &quot;&quot;&quot;The empty list is used as a list terminator and should be a singleton&quot;&quot;&quot;
  def __repr__(self):
    return &quot;()&quot;

the_empty_list = The_Empty_List()
</pre>
<p>Now that we have an empty list type we need to modify our reader to recognize it.  When the &#8220;(&#8221; character is encountered, scheme_read will call read_pair.  Since the only pair we&#8217;re going to allow for the moment is the empty list, we just need to check that the next character is &#8220;)&#8221; and return the_empty_list.</p>
<pre class="brush: python; highlight: [1,65,66,67,68,69,93,94]; title: ; notranslate">
from scheme_types import Symbol, the_empty_list

def is_delimiter(c):
  &quot;&quot;&quot;Is c a valid expression delimiter?&quot;&quot;&quot;
  return c in (' ', '(', ')', '\&quot;', ';', '\n') or not c

def is_initial(c):
  &quot;&quot;&quot;Is c a valid initial character for an identifier?&quot;&quot;&quot;
  return c.isalpha() or c in '-+*/&gt;&lt;=?!&amp;'

def read_number(f):
  buf = []
  c = f.getc()
  while not is_delimiter(c):
    buf.append(c)
    c = f.getc()
  f.ungetc(c)
  buf = &quot;&quot;.join(buf)
  if '.' in buf:
    return float(buf)
  elif '/' in buf:
    return &quot;rationals not implemented&quot;
  else:
    return int(buf)

def read_expected_string(f, s):
  &quot;&quot;&quot;Consume expected characters from the input buffer.&quot;&quot;&quot;
  expected_chars = list(s)
  c = f.getc()
  while expected_chars:
    if c == expected_chars[0]:
      expected_chars.pop(0)
      c = f.getc()
    else:
      return &quot;unexpected character&quot;

def read_character(f):
  c = f.getc()
  if c == 's' and f.peek() == 'p':
    read_expected_string(f, &quot;pace&quot;)
    return ' '
  elif c == 'n' and f.peek() == 'e':
    read_expected_string(f, &quot;ewline&quot;)
    return '\n'
  else:
    return c

def read_symbol(f):
  buf = []
  c = f.getc()
  while not is_delimiter(c):
    buf.append(c)
    c = f.getc()
  f.ungetc(c)
  return ''.join(buf)

def read_string(f):
  buf = []
  c = f.getc()
  while c != '\&quot;':
    buf.append(c)
    c = f.getc()
  return ''.join(buf)

def read_pair(f):
  f.remove_whitespace()
  c = f.getc()
  if c == ')':
    return the_empty_list

def scheme_read(f):
  f.remove_whitespace()
  c = f.getc()
  if (c.isdigit() or (c == '-' and f.peek().isdigit() or f.peek() == '.')
      or (c == '.' and f.peek().isdigit())):
    f.ungetc(c)
    return read_number(f)
  elif c == '#':
    c = f.getc()
    if c == 't':
      return True
    elif c == 'f':
      return False
    elif c == '\\':
      return read_character(f)
    else:
      return &quot;Error boolean value must be #t or #f not #&quot; + c
  elif is_initial(c):
    f.ungetc(c)
    return Symbol(read_symbol(f))
  elif c == '\&quot;':
    return read_string(f)
  elif c == '(':
    return read_pair(f)
  else:
    return &quot;scheme_read: not implemented&quot;
</pre>
<p>With that done, we&#8217;re only two steps away from being able to read linked lists.  First we have to create a Pair type that will represent a Scheme pair.  To do this, we&#8217;ll add the following to the scheme_types.py file.</p>
<pre class="brush: python; highlight: [12,13,14,15,16,17,18,19,20,21,22]; title: ; notranslate">
class Symbol(str):
  &quot;&quot;&quot;A symbol is an immutable string, but must be its own type.&quot;&quot;&quot;
  pass

class The_Empty_List():
  &quot;&quot;&quot;The empty list is used as a list terminator and should be a singleton&quot;&quot;&quot;
  def __repr__(self):
    return &quot;()&quot;

the_empty_list = The_Empty_List()

class Pair(object):
  &quot;&quot;&quot;A pair is a classic Lisp cons cell used to implement lists&quot;&quot;&quot;
  def __init__(self, car, cdr):
    self.car = car
    self.cdr = cdr
  def __iter__(self):
    x = self
    while not isinstance(x, The_Empty_List):
      yield x.car
      x = x.cdr
  def __repr__(self):
    return &quot;(&quot; + ' '.join([str(i) for i in list(self)]) + &quot;)&quot;
</pre>
<p>In addition to a car and cdr field I have also implemented the __iter__ and __repr__ special methods.  __iter__ will help us later on when we work with these pairs by allowing easy conversion to a Python list data type or allowing the use of for/in or map.  For more information on __iter__ see the <a href="http://docs.python.org/library/stdtypes.html#typeiter">Python docs on iterators</a>.</p>
<p>The only thing left to do is modify read_pair.  The procedure to read a pair is as follows:</p>
<ol>
<li>Get a value for the car slot by calling scheme_read on the input file</li>
<li>Remove any whitespace</li>
<li>Get a value for the cdr by calling read_pair on the input file
<ul>
<li>If the next character is &#8220;)&#8221; set the cdr to the_empty_list</li>
<li>If the next character is anything else set the cdr to a new pair by calling read_pair</li>
</ul>
</li>
</ol>
<pre class="brush: python; highlight: [1,70,71,72,73,74]; title: ; notranslate">
from scheme_types import Symbol, the_empty_list, Pair

def is_delimiter(c):
  &quot;&quot;&quot;Is c a valid expression delimiter?&quot;&quot;&quot;
  return c in (' ', '(', ')', '\&quot;', ';', '\n') or not c

def is_initial(c):
  &quot;&quot;&quot;Is c a valid initial character for an identifier?&quot;&quot;&quot;
  return c.isalpha() or c in '-+*/&gt;&lt;=?!&amp;'

def read_number(f):
  buf = []
  c = f.getc()
  while not is_delimiter(c):
    buf.append(c)
    c = f.getc()
  f.ungetc(c)
  buf = &quot;&quot;.join(buf)
  if '.' in buf:
    return float(buf)
  elif '/' in buf:
    return &quot;rationals not implemented&quot;
  else:
    return int(buf)

def read_expected_string(f, s):
  &quot;&quot;&quot;Consume expected characters from the input buffer.&quot;&quot;&quot;
  expected_chars = list(s)
  c = f.getc()
  while expected_chars:
    if c == expected_chars[0]:
      expected_chars.pop(0)
      c = f.getc()
    else:
      return &quot;unexpected character&quot;

def read_character(f):
  c = f.getc()
  if c == 's' and f.peek() == 'p':
    read_expected_string(f, &quot;pace&quot;)
    return ' '
  elif c == 'n' and f.peek() == 'e':
    read_expected_string(f, &quot;ewline&quot;)
    return '\n'
  else:
    return c

def read_symbol(f):
  buf = []
  c = f.getc()
  while not is_delimiter(c):
    buf.append(c)
    c = f.getc()
  f.ungetc(c)
  return ''.join(buf)

def read_string(f):
  buf = []
  c = f.getc()
  while c != '\&quot;':
    buf.append(c)
    c = f.getc()
  return ''.join(buf)

def read_pair(f):
  f.remove_whitespace()
  c = f.getc()
  if c == ')':
    return the_empty_list
  f.ungetc(c)
  car = scheme_read(f)
  f.remove_whitespace()
  cdr = read_pair(f)
  return Pair(car, cdr)

def scheme_read(f):
  f.remove_whitespace()
  c = f.getc()
  if (c.isdigit() or (c == '-' and f.peek().isdigit() or f.peek() == '.')
      or (c == '.' and f.peek().isdigit())):
    f.ungetc(c)
    return read_number(f)
  elif c == '#':
    c = f.getc()
    if c == 't':
      return True
    elif c == 'f':
      return False
    elif c == '\\':
      return read_character(f)
    else:
      return &quot;Error boolean value must be #t or #f not #&quot; + c
  elif is_initial(c):
    f.ungetc(c)
    return Symbol(read_symbol(f))
  elif c == '\&quot;':
    return read_string(f)
  elif c == '(':
    return read_pair(f)
  else:
    return &quot;scheme_read: not implemented&quot;
</pre>
<p>There are two things to note about this implementation.  First, () is matched as the_empty_list when it really shouldn&#8217;t be, the correct syntax is &#8216;().  Second, any literal list over 1,000 elements will hit Python&#8217;s recursion limit.  This shouldn&#8217;t be a problem in the vast majority of cases, however it is something to be aware of.</p>
<p>With that, the read layer of our interpreter is complete (for the purposes of this series, there is a lot more that <em>could</em> be done).  From this point on we will be concentrating on the eval layer of the interpreter.</p>
<p><a href="https://github.com/jacktrades/Scheme-in-Python/tree/v0.03">Checkout this version on GitHub (v0.03)</a></p>
<p><a href="http://nickzarr.com/blog4/2011/10/scheme-in-python-self-evaluating-values/" title="Scheme in Python – Self-evaluating values">GOTO Part 4 | Self-evaluating values</a></p>
<p><a href="http://nickzarr.com/blog4/series/scheme-in-python/" title="Scheme in Python">GOTO | Table of Contents</a></p>
]]></content:encoded>
			<wfw:commentRss>http://nickzarr.com/blog4/2011/10/scheme-in-python-pairs-and-linked-lists/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scheme in Python &#8211; Extending the read layer</title>
		<link>http://nickzarr.com/blog4/2011/10/scheme-in-python-extending-the-read-layer/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=scheme-in-python-extending-the-read-layer</link>
		<comments>http://nickzarr.com/blog4/2011/10/scheme-in-python-extending-the-read-layer/#comments</comments>
		<pubDate>Sat, 08 Oct 2011 15:09:38 +0000</pubDate>
		<dc:creator>Nick Zarczynski</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Scheme]]></category>
		<category><![CDATA[interpreter]]></category>
		<category><![CDATA[Language Design]]></category>

		<guid isPermaLink="false">http://nickzarr.com/blog4/?p=1501</guid>
		<description><![CDATA[GOTO Part 1 &#124; Numbers In the last post we created a read function that worked with integers and floating point numbers. We also covered the basic layout of the read function. In this post we will extend the read function to handle booleans, characters, strings and symbols. We&#8217;ll start with booleans as they are [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://nickzarr.com/blog4/2011/09/scheme-in-python-numbers/" title="Scheme in Python – Numbers">GOTO Part 1 | Numbers</a></p>
<p>In the last post we created a read function that worked with integers and floating point numbers.  We also covered the basic layout of the read function.  In this post we will extend the read function to handle booleans, characters, strings and symbols.</p>
<p>We&#8217;ll start with booleans as they are the smallest set.  There are 2 boolean values in Scheme #t and #f, which represent true and false respectively.  You probably noticed that both start with a # character and that is how we will recognize them in the reader.</p>
<p>We will represent #t and #f by the Python values True and False.  Since the code for this is so simple, we will handle this within the scheme_read function.</p>
<pre class="brush: python; highlight: [27,28,29,30,31,32,33,34]; title: ; notranslate">
def is_delimiter(c):
  &quot;&quot;&quot;Is c a valid expression delimiter?&quot;&quot;&quot;
  return c in (' ', '(', ')', '\&quot;', ';', '\n') or not c

def read_number(f):
  buf = []
  c = f.getc()
  while not is_delimiter(c):
    buf.append(c)
    c = f.getc()
  f.ungetc(c)
  buf = &quot;&quot;.join(buf)
  if '.' in buf:
    return float(buf)
  elif '/' in buf:
    return &quot;rationals not implemented&quot;
  else:
    return int(buf)

def scheme_read(f):
  f.remove_whitespace()
  c = f.getc()
  if (c.isdigit() or (c == '-' and f.peek().isdigit() or f.peek() == '.')
      or (c == '.' and f.peek().isdigit())):
    f.ungetc(c)
    return read_number(f)
  elif c == '#':
    c = f.getc()
    if c == 't':
      return True
    elif c == 'f':
      return False
    else:
      return &quot;Error boolean value must be #t or #f not #&quot; + c
  else:
    return &quot;scheme_read: not implemented&quot;
</pre>
<p>The code to handle booleans is pretty straightforward.  If the first character is #, then we get the next character.  If the next character is t or f, we return the appropriate boolean.  Otherwise, we return an error string.</p>
<p>The next thing we&#8217;ll handle is characters.  Characters in Scheme also start with the # symbol followed by a \, which gives us #\c where c is any character.  </p>
<p>There are some special characters, but we&#8217;ll start by implementing the basics.  We&#8217;ll check if an expression is a character in the same place as we check for booleans since they&#8217;re so similar.</p>
<pre class="brush: python; highlight: [20,21,22,37,38]; title: ; notranslate">
def is_delimiter(c):
  &quot;&quot;&quot;Is c a valid expression delimiter?&quot;&quot;&quot;
  return c in (' ', '(', ')', '\&quot;', ';', '\n') or not c

def read_number(f):
  buf = []
  c = f.getc()
  while not is_delimiter(c):
    buf.append(c)
    c = f.getc()
  f.ungetc(c)
  buf = &quot;&quot;.join(buf)
  if '.' in buf:
    return float(buf)
  elif '/' in buf:
    return &quot;rationals not implemented&quot;
  else:
    return int(buf)

def read_character(f):
  c = f.getc()
  return c

def scheme_read(f):
  f.remove_whitespace()
  c = f.getc()
  if (c.isdigit() or (c == '-' and f.peek().isdigit() or f.peek() == '.')
      or (c == '.' and f.peek().isdigit())):
    f.ungetc(c)
    return read_number(f)
  elif c == '#':
    c = f.getc()
    if c == 't':
      return True
    elif c == 'f':
      return False
    elif c == '\\':
      return read_character(f)
    else:
      return &quot;Error boolean value must be #t or #f not #&quot; + c
  else:
    return &quot;scheme_read: not implemented&quot;
</pre>
<p>Scheme has a few special characters that we must deal with, namely #\space and #\newline.  These will require a bit more work to process.  To help, we&#8217;ll define a function read_expected_string which will consume characters from the input buffer, provided they match what&#8217;s expected (and return an error if they don&#8217;t).</p>
<p>I won&#8217;t go over the workings of read_expected_string any further than to say it compares characters from the expected string and the input buffer one-by-one until it reaches the end.  We also need to add a check in read_character if the input buffer contains #\s or #\n.  Both of these could be either the characters s or n or the special characters #\space or #\newline.  To tell the difference we need to check the next character.</p>
<p>There are a few problems with this implementation, namely if you enter an invalid special character such as #\spxce it will leave unconsumed characters on the input buffer and will not return the error string.  Handling these error conditions would add a lot of bloat to the code, though you would definitely want to do this in your own implementation.</p>
<pre class="brush: python; highlight: [20,21,22,23,24,25,26,27,28,29,33,34,35,36,37,38,39,40]; title: ; notranslate">
def is_delimiter(c):
  &quot;&quot;&quot;Is c a valid expression delimiter?&quot;&quot;&quot;
  return c in (' ', '(', ')', '\&quot;', ';', '\n') or not c

def read_number(f):
  buf = []
  c = f.getc()
  while not is_delimiter(c):
    buf.append(c)
    c = f.getc()
  f.ungetc(c)
  buf = &quot;&quot;.join(buf)
  if '.' in buf:
    return float(buf)
  elif '/' in buf:
    return &quot;rationals not implemented&quot;
  else:
    return int(buf)

def read_expected_string(f, s):
  &quot;&quot;&quot;Consume expected characters from the input buffer.&quot;&quot;&quot;
  expected_chars = list(s)
  c = f.getc()
  while expected_chars:
    if c == expected_chars[0]:
      expected_chars.pop(0)
      c = f.getc()
    else:
      return &quot;unexpected character&quot;

def read_character(f):
  c = f.getc()
  if c == 's' and f.peek() == 'p':
    read_expected_string(f, &quot;pace&quot;)
    return ' '
  elif c == 'n' and f.peek() == 'e':
    read_expected_string(f, &quot;ewline&quot;)
    return '\n'
  else:
    return c

def scheme_read(f):
  f.remove_whitespace()
  c = f.getc()
  if (c.isdigit() or (c == '-' and f.peek().isdigit() or f.peek() == '.')
      or (c == '.' and f.peek().isdigit())):
    f.ungetc(c)
    return read_number(f)
  elif c == '#':
    c = f.getc()
    if c == 't':
      return True
    elif c == 'f':
      return False
    elif c == '\\':
      return read_character(f)
    else:
      return &quot;Error boolean value must be #t or #f not #&quot; + c
  else:
    return &quot;scheme_read: not implemented&quot;
</pre>
<p>Next up are symbols, which are the names of variables/constants.  In most other languages symbols are not given their own type and you, as a user, are not allowed to manipulate them as first-class values.  However this is not the case in Scheme.</p>
<p>We will represent symbols in our implementation as strings.  However since we also need to implement strings, it is necessary to make symbols a distinct type.  Since we will need to make other types as well as have access to them outside the read layer, make a new file called scheme_types.py and enter the following definition.</p>
<pre class="brush: python; title: ; notranslate">
class Symbol(str):
  &quot;&quot;&quot;A symbol is an immutable string, but must be its own type.&quot;&quot;&quot;
  pass
</pre>
<p>How do we know if an expression is a symbol?  There is a limited set of values that a symbol may start with.  To test if a character is part of this set, we&#8217;ll provide a function is_initial.</p>
<p>Once we&#8217;ve identified that the expression is a symbol, the next step is to read each character into a buffer until we&#8217;ve hit a delimiter (just like reading a number).  Then we turn the buffer into a string and pass it to Symbol to create a new symbol.</p>
<pre class="brush: python; highlight: [1,7,8,9,48,49,50,51,52,53,54,55,74,75,76]; title: ; notranslate">
from scheme_types import Symbol

def is_delimiter(c):
  &quot;&quot;&quot;Is c a valid expression delimiter?&quot;&quot;&quot;
  return c in (' ', '(', ')', '\&quot;', ';', '\n') or not c

def is_initial(c):
  &quot;&quot;&quot;Is c a valid initial character for an identifier?&quot;&quot;&quot;
  return c.isalpha() or c in '-+*/&gt;&lt;=?!&amp;'

def read_number(f):
  buf = []
  c = f.getc()
  while not is_delimiter(c):
    buf.append(c)
    c = f.getc()
  f.ungetc(c)
  buf = &quot;&quot;.join(buf)
  if '.' in buf:
    return float(buf)
  elif '/' in buf:
    return &quot;rationals not implemented&quot;
  else:
    return int(buf)

def read_expected_string(f, s):
  &quot;&quot;&quot;Consume expected characters from the input buffer.&quot;&quot;&quot;
  expected_chars = list(s)
  c = f.getc()
  while expected_chars:
    if c == expected_chars[0]:
      expected_chars.pop(0)
      c = f.getc()
    else:
      return &quot;unexpected character&quot;

def read_character(f):
  c = f.getc()
  if c == 's' and f.peek() == 'p':
    read_expected_string(f, &quot;pace&quot;)
    return ' '
  elif c == 'n' and f.peek() == 'e':
    read_expected_string(f, &quot;ewline&quot;)
    return '\n'
  else:
    return c

def read_symbol(f):
  buf = []
  c = f.getc()
  while not is_delimiter(c):
    buf.append(c)
    c = f.getc()
  f.ungetc(c)
  return ''.join(buf)

def scheme_read(f):
  f.remove_whitespace()
  c = f.getc()
  if (c.isdigit() or (c == '-' and f.peek().isdigit() or f.peek() == '.')
      or (c == '.' and f.peek().isdigit())):
    f.ungetc(c)
    return read_number(f)
  elif c == '#':
    c = f.getc()
    if c == 't':
      return True
    elif c == 'f':
      return False
    elif c == '\\':
      return read_character(f)
    else:
      return &quot;Error boolean value must be #t or #f not #&quot; + c
  elif is_initial(c):
    f.ungetc(c)
    return Symbol(read_symbol(f))
  else:
    return &quot;scheme_read: not implemented&quot;
</pre>
<p>The reader does not lookup the value of symbols, that&#8217;s the job of the eval layer, so we&#8217;re all done for handling symbols.  </p>
<p>With symbols done we only have strings left to implement for this part in the series.  Luckily the implementation for strings is almost exactly the same as the one for symbols.  Strings in Scheme start and end with &#8220;, so an expression is a string if the first character is a &#8220;.</p>
<p>The read_string function we&#8217;ll provide is a copy/paste of the read_symbol function with only one change.  Instead of <em>while not is_delimiter(c)</em> we will use <em>while c != &#8216;\&#8221;&#8216;</em> since delimiter characters are allowed to appear in strings.  Since the functionality is identical, you could abstract this into one function by adding a parameter that passes the stopping condition.  However I feel that it&#8217;s more clear, for this series, as two.</p>
<pre class="brush: python; highlight: [57,58,59,60,61,62,63,85,86]; title: ; notranslate">
from scheme_types import Symbol

def is_delimiter(c):
  &quot;&quot;&quot;Is c a valid expression delimiter?&quot;&quot;&quot;
  return c in (' ', '(', ')', '\&quot;', ';', '\n') or not c

def is_initial(c):
  &quot;&quot;&quot;Is c a valid initial character for an identifier?&quot;&quot;&quot;
  return c.isalpha() or c in '-+*/&gt;&lt;=?!&amp;'

def read_number(f):
  buf = []
  c = f.getc()
  while not is_delimiter(c):
    buf.append(c)
    c = f.getc()
  f.ungetc(c)
  buf = &quot;&quot;.join(buf)
  if '.' in buf:
    return float(buf)
  elif '/' in buf:
    return &quot;rationals not implemented&quot;
  else:
    return int(buf)

def read_expected_string(f, s):
  &quot;&quot;&quot;Consume expected characters from the input buffer.&quot;&quot;&quot;
  expected_chars = list(s)
  c = f.getc()
  while expected_chars:
    if c == expected_chars[0]:
      expected_chars.pop(0)
      c = f.getc()
    else:
      return &quot;unexpected character&quot;

def read_character(f):
  c = f.getc()
  if c == 's' and f.peek() == 'p':
    read_expected_string(f, &quot;pace&quot;)
    return ' '
  elif c == 'n' and f.peek() == 'e':
    read_expected_string(f, &quot;ewline&quot;)
    return '\n'
  else:
    return c

def read_symbol(f):
  buf = []
  c = f.getc()
  while not is_delimiter(c):
    buf.append(c)
    c = f.getc()
  f.ungetc(c)
  return ''.join(buf)

def read_string(f):
  buf = []
  c = f.getc()
  while c != '\&quot;':
    buf.append(c)
    c = f.getc()
  return ''.join(buf)

def scheme_read(f):
  f.remove_whitespace()
  c = f.getc()
  if (c.isdigit() or (c == '-' and f.peek().isdigit() or f.peek() == '.')
      or (c == '.' and f.peek().isdigit())):
    f.ungetc(c)
    return read_number(f)
  elif c == '#':
    c = f.getc()
    if c == 't':
      return True
    elif c == 'f':
      return False
    elif c == '\\':
      return read_character(f)
    else:
      return &quot;Error boolean value must be #t or #f not #&quot; + c
  elif is_initial(c):
    f.ungetc(c)
    return Symbol(read_symbol(f))
  elif c == '\&quot;':
    return read_string(f)
  else:
    return &quot;scheme_read: not implemented&quot;
</pre>
<p>With string handling completed there is only one major feature left for scheme_read, pairs.  Pairs are used to implement linked lists in Scheme.  The linked list is a very important data structure as all Scheme code is written and parsed into linked list format.  This code/data duality is one of the things that gives Scheme (and other Lisps) its great power.  The next post will be about the implementation of linked lists and how to parse them.</p>
<p><a href="https://github.com/jacktrades/Scheme-in-Python/tree/v0.02">Checkout this version on GitHub (v0.02)</a></p>
<p><a href="http://nickzarr.com/blog4/2011/10/scheme-in-python-pairs-and-linked-lists/" title="Scheme in Python – Pairs and linked lists">GOTO Part 3 | Pairs and linked lists</a></p>
<p><a href="http://nickzarr.com/blog4/series/scheme-in-python/" title="Scheme in Python">GOTO | Table of Contents</a></p>
]]></content:encoded>
			<wfw:commentRss>http://nickzarr.com/blog4/2011/10/scheme-in-python-extending-the-read-layer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scheme in Python &#8211; Numbers</title>
		<link>http://nickzarr.com/blog4/2011/09/scheme-in-python-numbers/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=scheme-in-python-numbers</link>
		<comments>http://nickzarr.com/blog4/2011/09/scheme-in-python-numbers/#comments</comments>
		<pubDate>Sat, 17 Sep 2011 04:08:19 +0000</pubDate>
		<dc:creator>Nick Zarczynski</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Scheme]]></category>
		<category><![CDATA[Language Design]]></category>

		<guid isPermaLink="false">http://nickzarr.com/blog4/?p=1476</guid>
		<description><![CDATA[GOTO Part 0 &#124; Reading from stdin Stage 1 of implementing Scheme in Python is to write the reader. The entire read layer is self-contained so we don&#8217;t need to worry about evaluating and printing values just yet. To start with let&#8217;s take a look at the basic shape of the read function. We&#8217;re going [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://nickzarr.com/blog4/2011/09/scheme-in-python-reading-from-stdin/" title="Scheme in Python – Reading from stdin">GOTO Part 0 | Reading from stdin</a></p>
<p>Stage 1 of implementing Scheme in Python is to write the reader.  The entire read layer is self-contained so we don&#8217;t need to worry about evaluating and printing values just yet.</p>
<p>To start with let&#8217;s take a look at the basic shape of the read function.  We&#8217;re going to call it scheme_read to avoid any name clashes that might arise, but other than that it should be more-or-less equivalent to any other Scheme read function.</p>
<pre class="brush: python; title: ; notranslate">
def scheme_read(f):
  f.remove_whitespace()
  c = f.getc()
  if c:
    return &quot;Representation of a Scheme type.&quot;
</pre>
<p>scheme_read(f) is called with a buffered file-like object <strong>f</strong> that must support getc, ungetc, peek and remove_whitespace methods.  First we remove any leading whitespace as whitespace in Scheme is only significant as a delimiter.</p>
<p>Before we get started let&#8217;s implement a simple repl so that we can play with our new features as we add them.  Create a new file named repl.py and insert the following code.</p>
<pre class="brush: python; title: ; notranslate">
#!/usr/bin/env python
import sys
from scheme_read import scheme_read
from buffered_input import Buff

while True:
  print &quot;&gt; &quot;,
  print scheme_read(Buff(sys.stdin))
</pre>
<p>The next step is to get the first non-whitespace character, which we store in the variable <strong>c</strong>.  We will use this character (and possibly the next) to determine the type of the expression.  For instance if <strong>c</strong> is a digit then the remaining characters (until the next delimiter) must form a number, since digits are not allowed as the first character of an identifier.  We&#8217;ll do this check in the <strong>if c:</strong> portion of our code.  Let&#8217;s look at that code.</p>
<pre class="brush: python; highlight: [4,5]; title: ; notranslate">
def scheme_read(f):
  f.remove_whitespace()
  c = f.getc()
  if c.isdigit():
    return &quot;Representation of a Scheme number.&quot;
</pre>
<p>What if c is not a digit?  In that case, our read function does not recognize the input and we should return something that states this fact.  For now let&#8217;s just return a string that says &#8220;scheme_read: not implemented&#8221;.  Later on you may wish to make this a proper error, but returning a string here keeps things simple.</p>
<pre class="brush: python; highlight: [6,7]; title: ; notranslate">
def scheme_read(f):
  f.remove_whitespace()
  c = f.getc()
  if c.isdigit():
    return &quot;Representation of a Scheme number.&quot;
  else:
    return &quot;scheme_read: not implemented&quot;
</pre>
<p>Now obviously, &#8220;Representation of a Scheme number.&#8221; is not actually a representation of a Scheme number.  To get that we have to read the number from <strong>f</strong>.  Instead of putting all the logic of reading a number into the if block, we should use a helper function here called read_number.</p>
<pre class="brush: python; highlight: [1,2,8]; title: ; notranslate">
def read_number(f):
  return &quot;Representation of a Scheme number.&quot;

def scheme_read(f):
  f.remove_whitespace()
  c = f.getc()
  if c.isdigit():
    return read_number(f)
  else:
    return &quot;scheme_read: not implemented&quot;
</pre>
<p>We pass the file object <strong>f</strong> to <strong>read_number</strong> so that it can read and return the rest of the number.  But wait, we already read the first digit!  Before we pass the work off to <strong>read_number</strong>, we have to put the first digit back onto <strong>f</strong>.  We do this using the ungetc method.</p>
<pre class="brush: python; highlight: [8]; title: ; notranslate">
def read_number(f):
  return &quot;Representation of a Scheme number.&quot;

def scheme_read(f):
  f.remove_whitespace()
  c = f.getc()
  if c.isdigit():
    f.ungetc(c)
    return read_number(f)
  else:
    return &quot;scheme_read: not implemented&quot;
</pre>
<p>Now to read a number we simply read a character at a time, placing each into a buffer, until we hit a delimiter.  To make that job easier we&#8217;ll provide a function <strong>is_delimiter</strong> that takes a character and returns <strong>True</strong> if that character is a delimiter and <strong>False</strong> if not.  Then we&#8217;ll use that to build a buffer and return an integer.</p>
<pre class="brush: python; highlight: [1,2,3,4,7,8,9,10,11,12,13]; title: ; notranslate">
def is_delimiter(c):
  &quot;&quot;&quot;Is c a valid expression delimiter?&quot;&quot;&quot;
  return c in (' ', '(', ')', '\&quot;', ';', '\n') or not c

def read_number(f):
  buf = []
  c = f.getc()
  while not is_delimiter(c):
    buf.append(c)
    c = f.getc()
  f.ungetc(c)
  buf = &quot;&quot;.join(buf)
  return int(buf)

def scheme_read(f):
  f.remove_whitespace()
  c = f.getc()
  if c.isdigit():
    f.ungetc(c)
    return read_number(f)
  else:
    return &quot;scheme_read: not implemented&quot;
</pre>
<p>That takes care of positive integers, however the positive integers are a very small subset of numbers.  We are going to want to handle negative integers as well as positive and negative floating point numbers at least.  Luckily, this is very simple to do in Python.</p>
<pre class="brush: python; highlight: [13,14,15,16]; title: ; notranslate">
def is_delimiter(c):
  &quot;&quot;&quot;Is c a valid expression delimiter?&quot;&quot;&quot;
  return c in (' ', '(', ')', '\&quot;', ';', '\n') or not c

def read_number(f):
  buf = []
  c = f.getc()
  while not is_delimiter(c):
    buf.append(c)
    c = f.getc()
  f.ungetc(c)
  buf = &quot;&quot;.join(buf)
  if '.' in buf:
    return float(buf)
  elif '/' in buf:
    return &quot;rationals not implemented&quot;
  else:
    return int(buf)

def scheme_read(f):
  f.remove_whitespace()
  c = f.getc()
  if c.isdigit():
    f.ungetc(c)
    return read_number(f)
  else:
    return &quot;scheme_read: not implemented&quot;
</pre>
<p>However, we&#8217;re not quite done yet.  Our implementation won&#8217;t handle negative numbers.  To do that we&#8217;re going to have to go back to the reader because &#8220;-&#8221; is not a digit and our current implementation will skip right over it.</p>
<pre class="brush: python; highlight: [23]; title: ; notranslate">
def is_delimiter(c):
  &quot;&quot;&quot;Is c a valid expression delimiter?&quot;&quot;&quot;
  return c in (' ', '(', ')', '\&quot;', ';', '\n') or not c

def read_number(f):
  buf = []
  c = f.getc()
  while not is_delimiter(c):
    buf.append(c)
    c = f.getc()
  f.ungetc(c)
  buf = &quot;&quot;.join(buf)
  if '.' in buf:
    return float(buf)
  elif '/' in buf:
    return &quot;rationals not implemented&quot;
  else:
    return int(buf)

def scheme_read(f):
  f.remove_whitespace()
  c = f.getc()
  if c.isdigit() or (c == '-' and f.peek().isdigit()):
    f.ungetc(c)
    return read_number(f)
  else:
    return &quot;scheme_read: not implemented&quot;
</pre>
<p>We&#8217;re still not quite done though.  What about floating point values where 0 < n < 1 that start with a decimal point?</p>
<pre class="brush: python; highlight: [24]; title: ; notranslate">
def is_delimiter(c):
  &quot;&quot;&quot;Is c a valid expression delimiter?&quot;&quot;&quot;
  return c in (&#8216; &#8216;, &#8216;(&#8216;, &#8216;)&#8217;, &#8216;\&quot;&#8217;, &#8216;;&#8217;, &#8216;\n&#8217;) or not c

def read_number(f):
  buf = []
  c = f.getc()
  while not is_delimiter(c):
    buf.append(c)
    c = f.getc()
  f.ungetc(c)
  buf = &quot;&quot;.join(buf)
  if &#8216;.&#8217; in buf:
    return float(buf)
  elif &#8216;/&#8217; in buf:
    return &quot;rationals not implemented&quot;
  else:
    return int(buf)

def scheme_read(f):
  f.remove_whitespace()
  c = f.getc()
  if (c.isdigit() or (c == &#8216;-&#8217; and f.peek().isdigit())
      or (c == &#8216;.&#8217; and f.peek().isdigit())):
    f.ungetc(c)
    return read_number(f)
  else:
    return &quot;scheme_read: not implemented&quot;
</pre>
<p>But wait, there's more!  What about negative floating point numbers where -1 < n < 0 which start with a "-."?</p>
<pre class="brush: python; highlight: [23]; title: ; notranslate">
def is_delimiter(c):
  &quot;&quot;&quot;Is c a valid expression delimiter?&quot;&quot;&quot;
  return c in (' ', '(', ')', '\&quot;', ';', '\n') or not c

def read_number(f):
  buf = []
  c = f.getc()
  while not is_delimiter(c):
    buf.append(c)
    c = f.getc()
  f.ungetc(c)
  buf = &quot;&quot;.join(buf)
  if '.' in buf:
    return float(buf)
  elif '/' in buf:
    return &quot;rationals not implemented&quot;
  else:
    return int(buf)

def scheme_read(f):
  f.remove_whitespace()
  c = f.getc()
  if (c.isdigit() or (c == '-' and f.peek().isdigit() or f.peek() == '.')
      or (c == '.' and f.peek().isdigit())):
    f.ungetc(c)
    return read_number(f)
  else:
    return &quot;scheme_read: not implemented&quot;
</pre>
<p>As you can see, a lot of the work of implementing a programming language goes into dealing with corner cases.  In the next post we'll extend our reader to handle booleans, characters, strings and symbols.</p>
<p><a href="https://github.com/jacktrades/Scheme-in-Python/tree/v0.01">Checkout this version on GitHub (v0.01)</a></p>
<p><a href="http://nickzarr.com/blog4/2011/10/scheme-in-python-extending-the-read-layer/" title="Scheme in Python – Extending the read layer">GOTO Part 2 | Extending the read layer</a></p>
<p><a href="http://nickzarr.com/blog4/series/scheme-in-python/" title="Scheme in Python">GOTO | Table of Contents</a></p>
]]></content:encoded>
			<wfw:commentRss>http://nickzarr.com/blog4/2011/09/scheme-in-python-numbers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scheme in Python &#8211; Reading from stdin</title>
		<link>http://nickzarr.com/blog4/2011/09/scheme-in-python-reading-from-stdin/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=scheme-in-python-reading-from-stdin</link>
		<comments>http://nickzarr.com/blog4/2011/09/scheme-in-python-reading-from-stdin/#comments</comments>
		<pubDate>Sat, 17 Sep 2011 02:43:03 +0000</pubDate>
		<dc:creator>Nick Zarczynski</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Scheme]]></category>
		<category><![CDATA[Language Design]]></category>

		<guid isPermaLink="false">http://nickzarr.com/blog4/?p=1466</guid>
		<description><![CDATA[This implementation of Scheme in Python will be done in three phases: 1) Read Layer 2) Eval Layer 3) Language Layer The read layer The read layer is responsible for consuming source code and transforming it into a data structure so that it can be passed to the eval layer. The eval layer After the [...]]]></description>
			<content:encoded><![CDATA[<p>This implementation of Scheme in Python will be done in three phases:</p>
<p>1) Read Layer<br />
2) Eval Layer<br />
3) Language Layer</p>
<h3>The read layer</h3>
<p>The read layer is responsible for consuming source code and transforming it into a data structure so that it can be passed to the eval layer.</p>
<h3>The eval layer</h3>
<p>After the reader returns a data structure representing the source code, the eval layer evaluates it according to a set of rules and returns a value.</p>
<p>After an expression has been evaluated it&#8217;s value is often printed to the screen.  Immediately after that the program usually loops back to reading the next expression, hence the term REPL (Read, Eval, Print, Loop).</p>
<h3>The language layer</h3>
<p>This interpreter is designed using the &#8220;languages as libraries&#8221; concept.  This approach is currently being used by the Racket and PyPy projects (though in a much more advanced form).</p>
<p>A language is usually defined as the core components, or primitives, plus additional libraries written using those primitives.  In most languages it is an error to attempt to redefine a primitive procedure and even in languages where this is permissible, there is usually no way to swap all of the primitives.</p>
<p>Using the languages as libraries approach, we implement as little as possible in the source code of the interpreter and allow a file to be loaded with definitions of the primitives in the language itself.  This implementation only requires one primitive to be defined at the interpreter level<sup><a href="#1">1</a></sup>, define-syntax, which allows the user to define new primitive syntax.</p>
<h3>Before we begin</h3>
<p>The read function presented here is a port of the read function in <a href="http://michaux.ca/articles/scheme-from-scratch-bootstrap-v0_1-integers">Bootstrap Scheme by Peter Michaux</a>.  His implementation relies on the C functions getc and ungetc.  Unfortunately input in Python is line-buffered and not character-buffered and Python does not provide ungetc.</p>
<p>To accommodate for this I have created a class (Buff) which wraps stdin (or any other file-like object) and provides the functions getc, ungetc and peek.  Reading from input in this manner is not in the least bit Pythonic, however this method of reading is very simple and clearly shows the steps involved in lexing and parsing input strings.</p>
<p>The operation of Buff is simple.  getc reads a single character from the given file if there are no characters waiting in the buffer, otherwise it pops off the last character added to the buffer.  ungetc simply adds a character to the buffer, and peek uses getc to read a character and store it in a variable, then ungetc to put the character back in the buffer.</p>
<pre class="brush: python; title: ; notranslate">
class Buff:
  def __init__(self, f):
    self.f = f
    self.last = []

  def getc(self):
    if self.last:
      return self.last.pop(0)
    else:
      return self.f.read(1)

  def ungetc(self, c):
    self.last.insert(0, c)

  def peek(self):
    if self.last:
      return self.last[0]
    else:
      c = self.f.read(1)
      self.last.append(c)
      return c

  def remove_whitespace(self):
    c = self.getc()
    while c:
      if c == ' ':
        c = self.getc()
      elif c == '\n':
        c = self.getc()
      elif c == ';':
        c = self.getc()
        while c and c != '\n':
          c = self.getc()
        self.ungetc(c)
      else:
        self.ungetc(c)
        break
</pre>
<p>You may notice that there is also a function: remove_whitespace.  This simply reads and discards any characters which are whitespace (space and newline) and discards comments ;starting at the semicolon and continuing until a newline is reached.</p>
<p>With that we have the tools we need to get started building the read level.</p>
<p><a name="1">[1]</a> In theory, in practice we also define &#8220;load&#8221; to avoid the necessity of redefining it every time we restart the interpreter.</p>
<p><a href="https://github.com/jacktrades/Scheme-in-Python">Checkout this project on GitHub</a></p>
<p><a href="http://nickzarr.com/blog4/2011/09/scheme-in-python-numbers/" title="Scheme in Python – Numbers">GOTO Part 1 | Numbers</a></p>
<p><a href="http://nickzarr.com/blog4/series/scheme-in-python/" title="Scheme in Python">GOTO | Table of Contents</a></p>
]]></content:encoded>
			<wfw:commentRss>http://nickzarr.com/blog4/2011/09/scheme-in-python-reading-from-stdin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pipes in Python &#8211; Infix Syntax for Function Calls</title>
		<link>http://nickzarr.com/blog4/2011/03/pipes-in-python-infix-syntax-for-function-calls/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=pipes-in-python-infix-syntax-for-function-calls</link>
		<comments>http://nickzarr.com/blog4/2011/03/pipes-in-python-infix-syntax-for-function-calls/#comments</comments>
		<pubDate>Tue, 29 Mar 2011 02:47:27 +0000</pubDate>
		<dc:creator>Nick Zarczynski</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://nickzarr.com/blog4/?p=980</guid>
		<description><![CDATA[Usually posting nothing more than a simple link is not my style, but this is just really cool. Pipe: Infix syntax for Python Here&#8217;s some more links&#8230; Python Package Index Page Github Page For now this is simply a reminder to myself to play around with this code a bit. At some point in the [...]]]></description>
			<content:encoded><![CDATA[<p>Usually posting nothing more than a simple link is not my style, but this is just really cool.</p>
<p><a href="http://dev-tricks.net/pipe-infix-syntax-for-python">Pipe: Infix syntax for Python</a></p>
<p>Here&#8217;s some more links&#8230;</p>
<p><a href="http://pypi.python.org/pypi/pipe/1.3">Python Package Index Page</a><br />
<a href="https://github.com/JulienPalard/Pipe">Github Page</a></p>
<p>For now this is simply a reminder to myself to play around with this code a bit.  At some point in the future I may write up a short post on this.</p>
<p>Here&#8217;s a short excerpt from Julien Palard&#8217;s post:</p>
<blockquote><p>Compare the readability of the classical prefix syntax :</p>
<pre class="brush: python; gutter: false; title: ; wrap-lines: false; notranslate">
sum(select(where(take_while(fib(), lambda x: x &lt; 1000000) lambda x: x % 2), lambda x: x * x))
</pre>
<p>And the infix syntax :</p>
<pre class="brush: python; gutter: false; title: ; wrap-lines: false; notranslate">
fib() | take_while(lambda x: x &lt; 1000000)
      | where(lambda x: x % 2)
      | select(lambda x: x * x)
      | sum()</pre>
<p>Isn’t the infix syntax more readable?</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://nickzarr.com/blog4/2011/03/pipes-in-python-infix-syntax-for-function-calls/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Television Episode Tracker &#8211; A strange question with a fun answer</title>
		<link>http://nickzarr.com/blog4/2011/03/television-episode-tracker-a-strange-question-with-a-fun-answer/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=television-episode-tracker-a-strange-question-with-a-fun-answer</link>
		<comments>http://nickzarr.com/blog4/2011/03/television-episode-tracker-a-strange-question-with-a-fun-answer/#comments</comments>
		<pubDate>Fri, 25 Mar 2011 03:58:07 +0000</pubDate>
		<dc:creator>Nick Zarczynski</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[beginner]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[television tracker]]></category>
		<category><![CDATA[tv]]></category>

		<guid isPermaLink="false">http://nickzarr.com/blog4/?p=867</guid>
		<description><![CDATA[Yesterday I was browsing Yahoo Answers1 and came across an interesting question&#8230; I want to create a program that can keep track of what episode of different shows im on. I&#8217;m watching several and have trouble remembering which in&#8217;s im on. I know i could just make a word doc but this seems cooler. Id [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday I was browsing Yahoo Answers<sup>1</sup> and came across an interesting question&#8230;</p>
<blockquote><p>I want to create a program that can keep track of what episode of different shows im on.<br />
I&#8217;m watching several and have trouble remembering which in&#8217;s im on. I know i could just make a word doc but this seems cooler. Id like each show to have a button that says what episode and when i click it, the number goes up. Also, it has to save that information. Thanks anybody for helping.</p></blockquote>
<p>The first response was priceless.  I&#8217;m only going to quote part of it, you can find the rest <a href="http://answers.yahoo.com/question/index;_ylt=At3wsA6XbYPDOaCZThyuAlLsy6IX;_ylv=3?qid=20110323170158AAOXyRl">here</a>.</p>
<blockquote><p>geez dude, what you&#8217;re asking for isnt exactly a DOS kind output&#8230;(sic)</p></blockquote>
<p>I had the same reaction to the question at first.  After a minute or so I realized that I could probably use a program like this.  I too watch a number of television shows, almost exclusively downloaded from the internet, and I find myself looking through my file system to figure out which episode I need to download next.  Surely this is wasteful, and a quick program could save me precious seconds each day (which I would undoubtedly use to browse <a href="http://www.reddit.com/r/programming">reddit</a> or <a href="http://lambda-the-ultimate.org/">LtU</a>).</p>
<p>About 20 minutes later I hacked together some of the ugliest code I&#8217;ve seen in a while and posted an answer to the question.  Then I made some nachos.  About an hour later I decided to spend another 10 minutes and fix a few bugs in my first version.  After about 30 minutes of hacking I came up with this code, which is probably the most functionality I&#8217;ve ever created from scratch in 30 minutes of coding (though the code itself is crap).</p>
<p>You can also find a more current version of this as a <a href="https://gist.github.com/884629/352df52244b550355df0022453bfee1a17604062">gist at my github account</a>.</p>
<pre class="brush: python; title: ; notranslate">
#!/usr/bin/env python
##############################################################################
## If you would like to contribute, contact jacktradespublic@gmail.com
##
## tvtracker is free software: you can redistribute it and/or
## modify it under the terms of the GNU Affero General Public
## License version 3 as published by the Free Software Foundation.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU Affero General Public License version 3 for more details.
##
## You should have received a copy of the GNU Affero General Public
## License version 3 along with this program. If not, see
## &lt;http://www.gnu.org/licenses/&gt;.
##############################################################################
## Known Bugs:
## - This needs some serious refactoring, even for this simple script
## - The current episode number just keeps growing and doesn't wrap
##   around seasons.
## - There is no way to undo an increment.
##
## Improvements
## - Next episode available: Input the day of the week that the
##   show is usually aired and the program will notify you when the
##   next episode is available. You should also be able to enter a
##   delay (for things like hulu or torrents).
##############################################################################

from Tkinter import *
import pickle

def loadShows():
  global shows
  f = open(filename, 'r')
  shows = pickle.load(f)
  f.close()

def saveShows():
  f = open(filename, 'wb')
  pickle.dump(shows, f)
  f.close()

class Add_Episode:
  def __init__(self, parent):
    self.add_frame = Frame(parent)

    self.name_label = Label(self.add_frame, text=&quot;Name: &quot;)
    self.name_entry = Entry(self.add_frame)
    self.episode_label = Label(self.add_frame, text=&quot;Current Episode: &quot;)
    self.episode_entry = Entry(self.add_frame)
    self.add_show_button = Button(self.add_frame, text=&quot;Add Show&quot;, command=self.add_show)

    self.name_label.pack(side=LEFT)
    self.name_entry.pack(side=LEFT)
    self.episode_label.pack(side=LEFT)
    self.episode_entry.pack(side=LEFT)
    self.add_show_button.pack(side=LEFT)
    self.add_frame.pack(side=TOP)

  def add_show(self):
    name = self.name_entry.get()
    episode = int(self.episode_entry.get())
    shows[name] = episode
    Show(root, name, episode)
    saveShows()

class Show:
  def __init__(self, parent, name, episode):
    self.name = name
    self.episode = episode

    f = Frame(parent)
    f.pack(side=LEFT)
    self.label = Label(f, text=name)
    self.entry = Label(f, text=episode)
    self.button = Button(f, text=&quot;Increment&quot;, command=self.increment)

    self.label.pack()
    self.entry.pack()
    self.button.pack()

  def increment(self):
    self.episode += 1
    self.entry.config(text = self.episode)
    shows[self.name] += 1
    saveShows()

if __name__ == &quot;__main__&quot;:

  filename = &quot;tvshows.pk&quot;

  try:
    loadShows()
  except IOError:
    shows = {}

  root = Tk()
  root.title('Tv Shows')

  Add_Episode(root)

  for n, e in shows.items():
    Show(root, n, e)

  root.mainloop()
</pre>
<p>The reason I&#8217;m posting this here is not because the code is elegant (it definately isn&#8217;t) or because the app is great (again, not so much).  I&#8217;m posting this because I think this is a good project for a beginner to bite into.  This is a very simple application and adding features, fixing bugs and refactoring my poorly thought out code is a great exercise.</p>
<p>If anyone is interested in helping with this project I would be more than willing to give you help, hints, code reviews, ideas or whatever other assistance you want.  You can also take this code and work on it yourself if you want, it&#8217;s really up to you.  Though I haven&#8217;t started using it yet, it is quickly approaching &#8220;good enough for my use case&#8221; and I probably won&#8217;t be doing much more to it.</p>
<p><sup>1</sup> Yahoo Answers is just about the worst service I&#8217;ve ever used.  The interface is horrible and if you copy/paste the question into a search engine, the vast majority of the time the answer will be the #1 result.  However, unlike stackoverflow or the mailing lists, I don&#8217;t feel like I have to spend all day watching for a new question, just to have a chance at answering it before someone else.</p>
]]></content:encoded>
			<wfw:commentRss>http://nickzarr.com/blog4/2011/03/television-episode-tracker-a-strange-question-with-a-fun-answer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Learn to Program with Python</title>
		<link>http://nickzarr.com/blog4/2011/03/learn-to-program-with-python-2/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=learn-to-program-with-python-2</link>
		<comments>http://nickzarr.com/blog4/2011/03/learn-to-program-with-python-2/#comments</comments>
		<pubDate>Wed, 09 Mar 2011 15:56:13 +0000</pubDate>
		<dc:creator>Nick Zarczynski</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[beginner]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://nickzarr.com/blog4/?p=683</guid>
		<description><![CDATA[Learn the basics of programming with Python. This tutorial will eventually become part of the What In The Hell series. There are two schools of thought when it comes to writing code. The first is to sit down and throughly plan out your code and what it should do. The second is to sit down [...]]]></description>
			<content:encoded><![CDATA[<p>Learn the basics of programming with Python.  This tutorial will eventually become part of the <a href="http://nickzarr.com/blog4/what-in-the-hell-series/">What In The Hell series</a>.</p>
<p>There are two schools of thought when it comes to writing code. The first is to sit down and throughly plan out your code and what it should do. The second is to sit down and start writing code, no matter how ugly and bug prone it may be, then hammer at the bugs until you have a beautifully exquisite piece of software. It is the latter approach that I recommend that you use, because it not only teaches you what works, but more importantly what doesn&#8217;t so that you can avoid that in the future.</p>
<p>This is a relatively short intro to the programming language Python. Python is a great beginner language as it hides many of the more advanced aspects of programming from the programmer. This doesn&#8217;t mean though, that Python is not a &#8216;real&#8217; programming language, rather it takes care of things like memory management and object typing behind the scenes, making your code less buggy and error prone.</p>
<p>There are some terms you should know before setting out to learn any programming language. To those power-users some of these terms might be redundant.</p>
<p><strong>Code:</strong> Code is a command, or commands, that are executed by the interpreter.  Code can be saved in a file and run or typed into the interpreter.</p>
<p><strong>Script:</strong> A script is simply a text file that contains code to be executed by an interpreter.  You create a python script by putting <strong>.py</strong> at the end of the filename.</p>
<p><strong>Program:</strong> A program can be a script or a collection of scripts that interact with each other.</p>
<p><strong>Interpreter:</strong> An interpreter is a program that reads code and produces the output specified by the code. The Python interpreter will accept single lines of code, scripts or programs.</p>
<p>&nbsp;</p>
<h2>0) Using Python</h2>
<p>Why does this tutorial start at zero? Computers usually start counting from zero.  The simplest way to look at this is that zero is the first number in our number system, though there are some other reasons that may become clear to you later.</p>
<p>There are a number of ways to use Python, we will concentrate on the easiest method first (later on we will discuss some of the more advanced methods). First you must download the python executable from the Python website (www.python.org at the time of this writing). Once you have the program downloaded go ahead and set it up by double clicking on the icon and following along with the prompts (you will notice that it is no different than any windows program installation). Click &#8216;finished&#8217; when you are done and you are now ready to start using Python. The program that we will be doing all our work in is called &#8216;Idle&#8217; and it is Python&#8217;s default interactive interpreter (there are others, which we will get to toward the end of this tutorial). To start idle go to the Start menu, then All Programs, then Python. Click on Idle and the the Idle interpreter will pop up.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
Python 2.4.3 (#1, Jun 13 2006, 14:23:21)
[GCC 4.1.1 20060612 (Red Hat 4.1.1-2)] on linux2
Type &quot;copyright&quot;, &quot;credits&quot; or &quot;license()&quot; for more information.

 ****************************************************************
 Personal firewall software may warn about the connection IDLE
 makes to its subprocess using this computer's internal loopback
 interface. This connection is not visible on any external
 interface and no data is sent to or received from the Internet.
 ****************************************************************

IDLE 1.1.3
&gt;&gt;&gt;
</pre>
<p>You should see something like the above when you open Idle. For now the only significant thing here is the >>>. This is the command prompt where you will enter all your commands. Just to make sure it works type 2+2 and then hit return. Did it print 4 on the line below 2+2? As you can see Python can do math too, but we&#8217;ll save that for a little bit later. Now you can move on to writing your first program.</p>
<p>&nbsp;</p>
<h2>1) Hello World</h2>
<p>It is customary to start each introductory text with a hello world program. This is typically the simplest program you can write in any programming language. It is a very simple program which only does one thing, it prints &#8220;hello world&#8221; to the screen on the interpreter.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; print 'Hello World!'
'Hello World!'
</pre>
<p>Great, you have just created your very first program. Don&#8217;t feel special yet? Don&#8217;t worry there&#8217;s much more to come. Let&#8217;s break this simple program down to see what Python does with it.</p>
<p><strong>print</strong> &#8211; print is the command used to display results on the screen. It doesn&#8217;t print anything to your printer so don&#8217;t go putting paper in.</p>
<p><strong>&#8216;Hello World!&#8217;</strong> &#8211; This is a string. A string is any combination of letters, numbers and special symbols encased in either single quotes &#8216; &#8216;, double quotes &#8221; &#8220;, or triple quotes &#8220;&#8221;" &#8220;&#8221;" or &#8221;&#8217; &#8221;&#8217;.</p>
<p>Let&#8217;s try something else:</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; print &quot;hello&quot;, 'world'
'hello world'
</pre>
<p>The comma separates objects to be printed and automatically inserts a space between them. You can separate letters, numbers and symbols with a comma. Note also that we can use different types of quoting in the same sentence and Python doesn&#8217;t care.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; print &quot;I can't&quot;, 'run today'
I can't run today
</pre>
<p>This illustrates why we would want to use different quotes around different strings. If we used single quotes around &#8216;I can&#8217;t&#8217; you see that the computer could get confused as to where to end the string (after n or t?).</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; print 'Go see &quot;The Rock&quot;'
Go see &quot;The Rock&quot;
</pre>
<p>One of the best reasons to use single quotes is to preserve quotation within a string.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; print 'hello'+'world'
helloworld
</pre>
<p>Using the + sign between words performs an operation called <strong>concatenation</strong>, which is basically a big word for joining together strings without a space. Below you can see how to use concatenation and enter spaces between the words.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; print 'hello '+'world'
hello world
</pre>
<p>This prints a space between the words because there is a space after hello and before the ending quotation.</p>
<p>Print also can print numbers and the results of mathematical operators.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; print 5
5

&gt;&gt;&gt; print 2435656
2435656

&gt;&gt;&gt; print 5+5
10
</pre>
<p>Numbers with quotes around them are strings so the &#8216;+&#8217; operator will concatenate instead of adding the two numbers.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; print '5'+'5'
'55'
</pre>
<p>&nbsp;</p>
<h2>2) Basic Math</h2>
<p>Python as well as every other programming language is simply an overpowered calculator. Math in Python is very simple and the rules that you learned in math class will apply directly here. Here are a few math problems and their results.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; 5+5
10
&gt;&gt;&gt; 5-4
1
&gt;&gt;&gt; 5*5
25
&gt;&gt;&gt; 5.0/2.0
2.5
&gt;&gt;&gt; 5/2
2
</pre>
<p>The last problem is the only one here that seems strange. All whole numbers are automatically considered to be <strong>integers</strong>. A decimal is a special type of number called a <strong>floating point number</strong>, or <strong>float</strong> for short. You can declare a float by putting a .0 on the end of a whole number, so that 5 becomes 5.0.</p>
<p>To get the remainder of an expression you simply use the &#8216;%&#8217; operator.  The remainder of 5/2 is 1.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; 5 % 2
1
</pre>
<p>Python can also return a float.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; 5/2.0
2.5
&gt;&gt;&gt; 5.0/2
2.5
</pre>
<p>Python will convert the number to float if one number in the expression is a float.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; 2**3
8
&gt;&gt;&gt; 3**3
27
</pre>
<p>The &#8216;**&#8217; operator represents raising the number to the x power, so that 2**x raises 2 to the x power.</p>
<p><strong>Introducing Parenthesis</strong></p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; (5*5)+3
28
</pre>
<p>The parenthesis in Python are equivalent to the parenthesis in math. Anything inside a parenthesis gets done before the things outside the parenthesis. So the expression above reads (25)+3.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; ((2*5)*5)+10
510
</pre>
<p>Parenthesis can be nested also. In this case the innermost parenthesis get evaluated first. So ((2*5)*5)+10 == (10*5)+10 == 500+10 == 510.</p>
<p>You might wonder why I used two equals signs (==). Python uses one equal sign to assign a variable. If you want to describe an <strong>equal to</strong> relationship you must use two equal signs ==.</p>
<p>Python has other comparison operators that you probably remember from grade school math class.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
== equal to
!= not equal to
&gt;= greater than or equal to
&lt;= less than or equal to
&gt; greater than
&lt; less than
</pre>
<p>There are a few common ways to write Python code but I suggest that you stick with the method described in this tutorial. Other ways are as follows:</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; 5+5
10
&gt;&gt;&gt; 5 + 5
10
&gt;&gt;&gt; ( 5+5 ) + 3
13
&gt;&gt;&gt; (5 + 5) + 3
13
&gt;&gt;&gt; (5+5)+ 3
13
</pre>
<p>Whitespace in Python is very important, however whitespace within expressions can be used however you want. It is best though, to pick a style and stick with it so that other developers don&#8217;t get confused when they read your code.</p>
<p>&nbsp;</p>
<h2>3) Variables</h2>
<p>Variables come in very handy when programming. A variable is an identifier that holds a value. The best way to explain this is to show you.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; a = 10
&gt;&gt;&gt; print a
10
</pre>
<p>The above example demonstrates how to create a variable (a = 10) and how to access that variable (print a). From now on when we enter the letter &#8216;a&#8217; the interpreter will substitute the letter for the number 10. Let&#8217;s try some more.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; b = 5
&gt;&gt;&gt; print b
5
&gt;&gt;&gt; print a+b
15
</pre>
<p>As you can see we can perform mathematical operations on the variables.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; c = 5+15
&gt;&gt;&gt; print c
20
&gt;&gt;&gt; d = a+b
&gt;&gt;&gt; print d
15
</pre>
<p>We can also assign the value of a mathematical expression to a variable.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; print d
15
&gt;&gt;&gt; d = d+1
&gt;&gt;&gt; print d
16
</pre>
<p>We can also change the variable by referring to itself.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; print d
16
&gt;&gt;&gt; d = d/2
&gt;&gt;&gt; print d
8
</pre>
<p>We can also assign multiple variables at once by using tuples (tuples are a type of list that we will discuss a little later)</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; (i, j, k) = (1, 2, 3)
&gt;&gt;&gt; print i
1
&gt;&gt;&gt; print j
2
&gt;&gt;&gt; print k
3
</pre>
<p>Tuples are always enclosed in parenthesis and each value is separated by a comma. The first variable (i) is assigned to the first value (1), the second variable (j) is assigned to the second value (2) and so on. You can have as many variables/values as you like, just make sure that you have equal numbers of each. Below you can see what happens if you don&#8217;t.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; (i, j, k) = (1, 2)
Traceback (most recent call last):
 File &quot;&lt;stdin&gt;&quot;, line 1, in &lt;module&gt;
ValueError: need more than 2 values to unpack

&gt;&gt;&gt; (i, j, k) = (1, 2, 3, 4)
Traceback (most recent call last):
 File &quot;&lt;stdin&gt;&quot;, line 1, in &lt;module&gt;
ValueError: too many values to unpack
</pre>
<p>In both instances above the Python interpreter spits out a nasty error message. We&#8217;ll take this opportunity to talk a little about error messages. Let&#8217;s break down the error message into its three lines.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
Traceback (most recent call last):
</pre>
<p>Line 1 of the error message simply tells you that the last instruction that the interpreter tried to do failed, and that the following messages are a result of this instruction failing.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
File &quot;&lt;stdin&gt;&quot;, line 1, in &lt;module&gt;
</pre>
<p>This line tells us exactly what instruction failed.</p>
<p>First it tells us what file the error was in. Since we aren&#8217;t using a file (we are typing directly into the interpreter) it tells us that the error was in &#8220;&lt;stdin&gt;&#8221; which is a cryptic way of saying standard input, or input from the keyboard.</p>
<p>Then it tells us what line the program failed on. Here we only have one line so it tells us the error occurred on line 1.</p>
<p>The final hint, <strong>in &lt;module&gt;</strong>, tells us what function or class the instruction was in. Since we haven&#8217;t covered functions or classes yet, just ignore this part.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
ValueError: too many values to unpack
</pre>
<p>Finally this line tells us what type of error occurred. This time it tells us that we gave it too many values (before it told us that we gave it too few values). This line will give you a good hint as to what you need to change to make the instruction work, here we need to take away one value.</p>
<p>For more information on errors, check out <a href="http://nickzarr.com/blog4/2011/02/24/what-in-the-hell-are-errors/">What In The Hell Are Errors</a>.</p>
<p>You can also store your values in a variable like the example below.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; w = (4, 5, 6)
&gt;&gt;&gt; (x, y, z) = w
&gt;&gt;&gt; print x
4
&gt;&gt;&gt; print y
5
&gt;&gt;&gt; print z
6
</pre>
<p>Remember here that a variable is simply a placeholder, so when the Python interpreter sees the command <strong>(x, y, z) = w</strong> it changes it to <strong>(x, y, z) = (4, 5, 6)</strong>.</p>
<p>Variables aren&#8217;t just for numbers, you can store any data type in a variable. You can even store a variable in a variable.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; m = 'Hello'
&gt;&gt;&gt; o = 'World'
&gt;&gt;&gt; print m, o
Hello World

&gt;&gt;&gt; p = m
&gt;&gt;&gt; q = o
&gt;&gt;&gt; print p, q
Hello World
</pre>
<p>One of the main reasons to store a variable in a variable is if you want to change the initial variable.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; s = 50
&gt;&gt;&gt; t = s
&gt;&gt;&gt; s = s/2
&gt;&gt;&gt; print s
25
&gt;&gt;&gt; print t
50
</pre>
<p>Notice that <strong>t</strong> keeps the initial value of <strong>s</strong> even after we change <strong>s</strong> by dividing it. This feature will come in very handy when you begin to learn about loops.</p>
<p>&nbsp;</p>
<h2>4) Functions</h2>
<p>A function is a set of instructions.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
def HelloWorld():
 print 'Hello World!'
</pre>
<p>Above is probably the simplest function that you can create. Let&#8217;s break it down.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
def HelloWorld():
</pre>
<p>This is where we <strong>define the function</strong>. We do this by giving the <strong>def</strong> command followed by a name (like a variable name). We follow the name with a set of parenthesis and after the parenthesis we put a colon. The colon tells the interpreter that we are done defining the function.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
 print 'Hello World'
</pre>
<p>You should remember this from chapter 1. Under the definition you can list any number of commands. These commands should be indented one level from the definition and there should only be one command per line.</p>
<p>When you want to use a function you simply type the name followed by parenthesis.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; HelloWorld()
Hello World!
</pre>
<p>Here&#8217;s some more functions and their output when you use them.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; def add():
 print 2 + 2

&gt;&gt;&gt; add()
4

&gt;&gt;&gt; def multiply():
 print 2 * 3

&gt;&gt;&gt; multiply()
6

&gt;&gt;&gt; def mu():
 print 2 * 3

&gt;&gt;&gt; mu()
6
</pre>
<p>You can think of a function as a variable that stores multiple commands. Below we&#8217;ll see some more advanced functions that use some of the things we learned in previous chapters.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; def commands():
 print 'Hello. I will show you the multiples of 2'
 print 2**0
 print 2**1
 print 2**2
 print 2**3
 print 'There are ' , (2**4)*2 , 'possible combinations in a binary byte'

&gt;&gt;&gt; commands()
Hello. I will show you the multiples of 2
0
2
4
8
There are 16 possible combinations in a binary byte
</pre>
<p>As you can see above each line in the function <strong>commands()</strong> is executed one by one until it reaches the end. So far we have only used the print statement in our functions. Let&#8217;s see what happens when we use a variable to store data.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; def twoPlusTwo():
 add2 = 2+2

&gt;&gt;&gt; twoPlusTwo()
</pre>
<p>Notice that the function <strong>twoPlusTwo()</strong> did not print anything when we called it? You might have noticed that <strong>add2 = 2+2</strong> will not print anything either when we type it on the command line. Let&#8217;s try to use the variable add2 by printing it.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; print add2
Traceback (most recent call last):
 File &quot;&quot;, line 1, in ?
NameError: name 'add2' is not defined
</pre>
<p>The interpreter spits out a error message telling us that <strong>add2</strong> has not been defined. How can that be? Any variable that you define in a function stays in that function, and is not accessible from outside of the function. The technical term for this is a <strong>local variable</strong>. Why does Python do this? There are many reasons which you will come to find are very useful, but the main reason is so you don&#8217;t have to keep track of all the variables that you used in your program, because redefining a global variable (or a variable accessible from anywhere, more on this below) will erase it&#8217;s current value and replace it with the new one. Yikes, that means that if we forget that we used a variable name we could crash the program, or make it spit out completely wrong data!</p>
<p>Functions do not <strong>return</strong> values by default, instead we must specify a return value if we want the function to produce something. In the above example of twoPlusTwo() when we called it it just gave us a new command line. The function is not broken (Python really did calculate 2+2 and assign it to add2) it merely has no <strong>return value</strong>. Let&#8217;s redefine twoPlusTwo() and give it a return value.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; def twoPlusTwo():
 add2 = 2+2
 return add2

&gt;&gt;&gt; twoPlusTwo()
4
</pre>
<p>Notice that we added one more line, <strong>return add2</strong>. This line tells the interpreter to <strong>return (or give back when called) a value</strong>. Note that return and print are two completely different commands (even though they produce the same output here) print simply prints a message to the screen, while return gives us back a value that we can use. Let&#8217;s look at an example of this.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; def r():
 add2 = 2+2
 return add2

&gt;&gt;&gt; r() + 2
6
</pre>
<p>Here we can see that we can use the function just like a variable. In this example <strong>r() + 2</strong> the interpreter executes the function <strong>r()</strong> and get a return value of 4. Then it takes that value and adds 2 to it and returns the value of 6. Let&#8217;s see what happens if we try this using print.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; def p():
 add2 = 2+2
 print add2

&gt;&gt;&gt; p() + 2
Traceback (most recent call last):
 File &quot;&quot;, line 1, in ?
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
</pre>
<p>Python spits out another error message that tells us that we cannot add <strong>NoneType</strong> and <strong>int</strong>. This tells us that the function p() returned NoneType, which is a way of saying that p() returned nothing, and that we cannot add 2 to nothing (note here that NoneType is not equivalent to 0, we could add 0+2)</p>
<p>Earlier we talked about local variables. Let&#8217;s try a little experiment with the return statement.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
&gt;&gt;&gt; def ret():
 sub2 = 4 - 2
 return sub2

&gt;&gt;&gt; ret()
2
&gt;&gt;&gt; print sub2
Traceback (most recent call last):
 File &quot;&quot;, line 1, in ?
NameError: name 'sub2' is not defined
</pre>
<p>Note here that the return statement did not give us a global variable of sub2. Instead it just returned the value of sub2.</p>
<p>&nbsp;</p>
<h2>4.1) Global and Local Variables</h2>
<p>Close your Python interpreter and reopen it (this will get rid of all the variables and commands we entered already, and give us a clean slate to work with). Below is a session that shows us the difference between local and global variables.</p>
<pre class="brush: plain; gutter: false; title: ; wrap-lines: false; notranslate">
&gt;&gt;&gt; a = 10 ## a is a global variable because it is not inside a function
&gt;&gt;&gt; b = 15 ## b is a global variable because it is not inside a function
&gt;&gt;&gt; def add():
 c = 20 ## c is a local variable
 return a+b+c
</pre>
<p><strong>Global variables</strong> are variables defined outside of any function (or class, but we haven&#8217;t learned about classes yet). Another way to think about it is that any variable that is declared and is not indented is a global variable (this will be a little more clear below)</p>
<p>We can use global variables anywhere, but we can only use local variables inside the function that declared them.  When we are using more than a few lines to tell the interpreter what to do it is often easier to create a <strong>script</strong>, or a file containing commands for the interpreter. Every Python script must end in the &#8216;.py&#8217; extension, you can do this simply by typing &#8216;.py&#8217; at the end of the filename when you save it. Let&#8217;s rewrite the above code in a script.</p>
<p>First go to <strong>File</strong> then click <strong>New Window</strong> in the Python interpreter. This will give you a blank window. The first thing we&#8217;ll do is save the file (even thought it&#8217;s blank). Go to <strong>File &#8211;&gt; Save</strong>. A window will pop up asking you where you would like to save the file and what you would like to name it. For now we&#8217;ll choose the default location and we&#8217;ll name the file &#8216;test.py&#8217;. Saving the file right away does a few things for us that make writing a script easier. First, and most important, it lets us save the document anytime we want by simply using the keyboard shortcut <strong>Ctrl &#8211; s</strong>. Second saving the file as a Python script enables a feature of the text editor called <strong>syntax highlighting</strong> that changes certain keywords to a different color, while this might seem frivolous or even confusing at first, when you get used to the colors it will help you identify your code.</p>
<p>OK now that we&#8217;ve got that out of the way let&#8217;s get down to writing our script.</p>
<pre class="brush: python; title: ; wrap-lines: false; notranslate">
#############
## test.py ##
#############

# This is a comment. Anything after the '#' until the next line will be ignored by the interpreter
# Use comments to explain your code so that it is easier for you to remember what does what

a = 10
b = 15

def add():
 c = 20
 return a+b+c
</pre>
<p>The code above is a script. Strictly speaking any comments are not necessary, but to help us remember or to help someone else understand the code they are useful. I use a comment box, which is simply text surrounded by comment symbols, to identify things like filename, date created, date revised, changes to the script, TODOs and special sections of code. You do not have to use the comment box, instead you can use just a single comment (#) to denote the same thing. I also often use two comments to signify a comment (##) instead of just one. Again this is just personal preference and you can choose to comment however you like.</p>
<p>Like I stated earlier, one of the easiest ways to identify a global variable is to look at the level of indentation. Global variables will have no spaces before their declaration. This means that <strong>a</strong> and <strong>b</strong> are both global variables, while <strong>c</strong> is not (because it has spaces before it).</p>
<p>This script right now will run, but it won&#8217;t output anything. This is because we haven&#8217;t yet used any of the variables/functions that we defined. Let&#8217;s add a little bit to the script so that it does something.</p>
<pre class="brush: python; title: ; wrap-lines: false; notranslate">
#############
## test.py ##
#############

a = 10
b = 15

def add():
 c = 20
 return a+b+c

add() ## This line uses the function add() just like we've done on the command line
</pre>
<p>One of the nice features of the IDLE text editor is the F5 key. To run your script you simply press the F5 key and a window will pop up that tells you that you must save the script before you can run it (if you haven&#8217;t saved it already). Hit OK and IDLE will save the script for you and then run it on the command line.  You will see the interpreter pop up and then you will see it spit out the number 45 (10 + 15 + 20).  Congratulations, you have written your first script.</p>
<p>Python executes a script one line at a time (like we did manually at the command line). The script above is executed as follows.</p>
<p>1) set a = 10<br />
2) set b = 15<br />
3) define the function add()<br />
4) execute add() and return the value</p>
<p>If we were to change the script and put the definition and the command add() before we declared <strong>a</strong> and <strong>b</strong> we would get an error telling us that <strong>a</strong> and <strong>b</strong> haven&#8217;t been defined yet. The code below is an example of trying to define and use a function before declaring the variables that are used in the function.</p>
<pre class="brush: python; title: ; notranslate">
#############
## test.py ##
#############

def add():
 c = 20
 return a+b+c

add()

a = 10
b = 15
</pre>
<p>One of the properties of functions is that they are not executed in order. Instead a function is only executed when it is called. The script above breaks when we try to run it. But is that because we defined the function before we defined the variables? Or because we tried to use the function before we defined the variables. Look at the code below for the answer.</p>
<pre class="brush: python; title: ; notranslate">
#############
## test.py ##
#############

def add():
 c = 20
 return a+b+c

a = 10
b = 15

add()
</pre>
<p>This works! The only thing we&#8217;ve changed here is where we execute the function (after we declare the variables). This shows us that a function is not evaluated until it is used. So even though we used variables in the function that don&#8217;t yet exist (from a line-by-line execution viewpoint) we define the variables before we use the function, making the script work.</p>
<p>To learn more about functions check out <a href="http://nickzarr.com/blog4/2011/02/20/what-in-the-hell-are-functions/">What In The Hell Are Functions</a>.</p>
<p>&nbsp;</p>
<h2>5) Conditionals</h2>
<p>A <strong>conditional</strong> is an if/then statement. We use these all the time in everyday life. For instance we might say; if the temperature is over 80 degrees, then turn on the air conditioning. The code for this statement would look something like this:</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
if temperature over 80:
 turn on air conditioning
</pre>
<p>The above code is what we programmers call psudocode. Psudocode won&#8217;t actually run, its purpose is instead to give us an idea of how the code should look. It is also very easy to turn psudocode into real code.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
if temp &gt; 80:
 runAC()
</pre>
<p>This is the real code for the psudocode above. Notice the similarities? One of the new features here is the &gt; sign. &gt; is called an operator and is part of a group of operators.</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
== equal to
!= not equal to
&gt;= greater than or equal to
&lt;= less than or equal to
&gt; greater than
&lt; less than
</pre>
<p>Each of these operators returns a <strong>boolean</strong> value. A <strong>boolean</strong> value is either <strong>True</strong> or <strong>False</strong> so if we say <strong>a &gt; b</strong> the boolean response would be True if a is greater than b, or False if a was less than or equal to b.</p>
<p>Operators are used extensively in conditional statements so it is best to fully understand them and their use. Operators return only a boolean value, you cannot for instance, get an integer or string from an operator. </p>
<p>You can execute as many commands as you would like in an if statement. The following code demonstrates this:</p>
<pre class="brush: plain; gutter: false; title: ; notranslate">
if number &gt; 60:
 hours = number/60
 minutes = number % 60
 string = hours + ':' + minutes
 print string
</pre>
<p>This code takes a number of minutes and transforms it into hours:minutes, then prints the output.</p>
<p>To learn more about conditionals check out <a href="http://nickzarr.com/blog4/2011/02/20/what-in-the-hell-are-conditionals/">What In The Hell Are Conditionals</a>.</p>
<p>&nbsp;</p>
<h2>Links</h2>
<p><a href="http://nickzarr.com/blog4/what-in-the-hell-series/">Pointless Programming &#8211; What In The Hell Series</a></p>
<p><a href="http://docs.python.org/release/2.5.2/tut/tut.html">Official Python Tutorial</a></p>
<p><a href="http://openbookproject.net/thinkcs/python/english2e/">How to Think Like a Computer Scientist</a></p>
<p><a href="http://www.swaroopch.com/notes/Python">A Byte of Python</a></p>
<p><a href="http://wiki.python.org/moin/BeginnersGuide/NonProgrammers">More books and tutorials for beginner programmers.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://nickzarr.com/blog4/2011/03/learn-to-program-with-python-2/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Python Surprises</title>
		<link>http://nickzarr.com/blog4/2011/03/python-surprises/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=python-surprises</link>
		<comments>http://nickzarr.com/blog4/2011/03/python-surprises/#comments</comments>
		<pubDate>Tue, 08 Mar 2011 13:43:46 +0000</pubDate>
		<dc:creator>Nick Zarczynski</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://nickzarr.com/blog4/?p=643</guid>
		<description><![CDATA[Python is a very intuitive language to code in, however there are some surprises that might catch you off guard. This article lists a few of the ones I find interesting. Many such articles have been published and there are links to some of them at the bottom of this page. &#160; In Python for [...]]]></description>
			<content:encoded><![CDATA[<p>Python is a very intuitive language to code in, however there are some surprises that might catch you off guard.  This article lists a few of the ones I find interesting.  Many such articles have been published and there are links to some of them at the bottom of this page.</p>
<p>&nbsp;</p>
<p>In Python for and while loops are not blocks.  This means that variables defined within a loop still exist after that loop ends.</p>
<pre class="brush: python; title: ; notranslate">
for i in range(3):
  pass
i
#===&gt; 2

while True:
  a = 42
  break
a
#===&gt; 42
</pre>
<p>&nbsp;</p>
<p>Python&#8217;s for loop also accepts an else statement that only executes if the loop runs to completion.</p>
<pre class="brush: python; title: ; notranslate">
for i in range(3):
  if i == 1:
    break
else:
  print &quot;Else not executed here because the for loop ended with a break.&quot;

for i in range(3):
  pass
else:
  print &quot;This will print because the loop completed successfully.&quot;
</pre>
<p>&nbsp;</p>
<p>Booleans can act like integers, but only sometimes.</p>
<pre class="brush: python; title: ; notranslate">
isinstance(False, bool)
#===&gt; True
isinstance(False, int)
#===&gt; True

a = True
b = True
a + b
#===&gt; 2
a == 1
#===&gt; True
a is 1
#===&gt; False
</pre>
<p>&nbsp;</p>
<p>Tuples always need commas.</p>
<pre class="brush: python; title: ; notranslate">
a = (1)
type(a)
#===&gt; integer

b = (1,)
type(b)
#===&gt; tuple
</pre>
<p>&nbsp;</p>
<p>+= vs + with mutable objects</p>
<pre class="brush: python; title: ; notranslate">
a = [1, 2, 3]
id(a)
#===&gt; 140415741190800
a += [4]
id(a)
#===&gt; 140415741190800
a = a + [5]
id(a)
#===&gt; 140415741191304
</pre>
<p>&nbsp;</p>
<p>Default arguments are assigned when a function is defined, not when it is evaluated.</p>
<pre class="brush: python; title: ; notranslate">
from time import time, sleep

def test(a=time()):
  print a

test()
#===&gt; 1299590594.48
sleep(3)
test()
#===&gt; 1299590594.48
# a is bound to time() at def, so will always return the same value
</pre>
<p>&nbsp;</p>
<p>Tuple object does not support item assignment&#8230; or does it?</p>
<pre class="brush: python; title: ; notranslate">
a = ([42],)
a[0] += [43, 44]
#===&gt; TypeError: 'tuple' object does not support item assignment
a
#===&gt; ([42, 43, 44],)
</pre>
<p>&nbsp;</p>
<h4>Links</h4>
<p>Here are links to similar articles, in no particular order.</p>
<p><a href="http://zephyrfalcon.org/labs/python_pitfalls.html">Python Pitfalls</a><br />
<a href="http://stackoverflow.com/questions/530530/python-2-x-gotchas-and-landmines">Stack Overflow &#8211; Python Gotchas and Landmines</a><br />
<a href="http://wiki.python.org/moin/PythonWarts">Python Warts</a><br />
Charming Python: Python Elegance and Warts <a href="http://www.ibm.com/developerworks/linux/library/l-python-elegance-1.html">Part 1</a> and <a href="http://www.ibm.com/developerworks/linux/library/l-python-elegance-2.html">Part 2</a><br />
<a href="http://stackoverflow.com/questions/101268/hidden-features-of-python">Stack Overflow &#8211; Hidden Features of Python</a><br />
<a href="http://onlamp.com/pub/a/python/2004/02/05/learn_python.html">When Pythons Attack</a><br />
<a href="http://www.ferg.org/projects/python_gotchas.html">Python Gotchas</a><br />
<a href="http://blog.brush.co.nz/2008/01/ten-python-quirkies/">10 Python Quirks</a><br />
<a href="http://bayes.colorado.edu/PythonIdioms.html">Python Idioms and Efficiency</a><br />
<a href="http://www.peterbe.com/plog/bool-is-int">bool is int</a></p>
<p>* Most of these will only be &#8220;surprises&#8221; to newer Python programmers.<br />
** These are not necessarily problems/warts/bugs in Python.</p>
]]></content:encoded>
			<wfw:commentRss>http://nickzarr.com/blog4/2011/03/python-surprises/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Reversing a String in Python</title>
		<link>http://nickzarr.com/blog4/2011/02/reversing-a-string-in-python/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=reversing-a-string-in-python</link>
		<comments>http://nickzarr.com/blog4/2011/02/reversing-a-string-in-python/#comments</comments>
		<pubDate>Thu, 24 Feb 2011 23:19:53 +0000</pubDate>
		<dc:creator>Nick Zarczynski</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[extended slice syntax]]></category>
		<category><![CDATA[reverse a string]]></category>
		<category><![CDATA[reverse a string in python]]></category>
		<category><![CDATA[reverse string]]></category>
		<category><![CDATA[reverse string in python]]></category>
		<category><![CDATA[reversed]]></category>
		<category><![CDATA[string]]></category>

		<guid isPermaLink="false">http://nickzarr.com/blog4/?p=276</guid>
		<description><![CDATA[I came across a post about reversing strings in Python and it led me to write this post. Python strings do not come with a built-in .reverse() method as do lists. This leads many people to come up with their own versions of a string reverse. Two of the most common solutions that I have [...]]]></description>
			<content:encoded><![CDATA[<p>I came across a <a href="http://onelinercode.wordpress.com/2011/02/23/reversing-a-string-in-python-version-the-first/">post</a> about reversing strings in Python and it led me to write this post.  Python strings do not come with a built-in .reverse() method as do lists.  This leads many people to come up with their own versions of a string reverse.  Two of the most common solutions that I have seen are below.</p>
<pre class="brush: python; title: ; notranslate">
def reverse(s):
  r = &quot;&quot;
  for c in s:
    r = c + r
  return r
s = &quot;String to reverse.&quot;
print reverse(s)
</pre>
<p>and&#8230;</p>
<pre class="brush: python; title: ; notranslate">
s = &quot;String to reverse.&quot;
print &quot;&quot;.join(s1 for c in xrange(len(s) - 1, -1, -1))
</pre>
<p>Probably the easiest and close to the fastest way to reverse a string is to use Python&#8217;s <a href="http://docs.python.org/release/2.3.5/whatsnew/section-slices.html">extended slice syntax</a>.  This allows you to specify a start, stop and step value to use when creating a slice.  The syntax is: [start:stop:step].</p>
<pre class="brush: python; title: ; notranslate">
s = &quot;String to reverse.&quot;
print s[::-1]
</pre>
<p>If start is omitted it defaults to 0 and if stop is omitted it defaults to the length of the string.  A step of -1 tells Python to start counting by 1 from the stop until it reaches the start.</p>
<p>When working with large strings, or when you just don&#8217;t want to reverse the whole string at once, you can use the <a href="http://docs.python.org/release/2.4.4/whatsnew/node7.html">reversed()</a> built-in.  reversed() returns an iterator and is arguably the most Pythonic way to reverse a string.</p>
<pre class="brush: python; title: ; notranslate">
s = &quot;String to reverse.&quot;
print &quot;&quot;.join(reversed(s))
</pre>
]]></content:encoded>
			<wfw:commentRss>http://nickzarr.com/blog4/2011/02/reversing-a-string-in-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Get total word count from WordPress blog with Python</title>
		<link>http://nickzarr.com/blog4/2011/02/get-word-count-of-blog/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=get-word-count-of-blog</link>
		<comments>http://nickzarr.com/blog4/2011/02/get-word-count-of-blog/#comments</comments>
		<pubDate>Thu, 24 Feb 2011 09:26:45 +0000</pubDate>
		<dc:creator>Nick Zarczynski</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[word count]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[wordpress api]]></category>
		<category><![CDATA[wordpress word count]]></category>
		<category><![CDATA[xmlrpclib]]></category>

		<guid isPermaLink="false">http://nickzarr.com/blog4/?p=232</guid>
		<description><![CDATA[I just came across this script by Jabba Laci to download your posts from WordPress. It reminded me that I wanted to see how many words I have written to my blog so far. Maybe it&#8217;s just because I&#8217;m still new to WordPress, but I haven&#8217;t seen a total word count anywhere. Here&#8217;s the modified [...]]]></description>
			<content:encoded><![CDATA[<p>I just came across <a href="http://ubuntuincident.wordpress.com/2011/02/22/wordpress-python-metaweblog/trackback/">this script by Jabba Laci</a> to download your posts from WordPress.  It reminded me that I wanted to see how many words I have written to my blog so far.  Maybe it&#8217;s just because I&#8217;m still new to WordPress, but I haven&#8217;t seen a total word count anywhere.  Here&#8217;s the modified script:</p>
<pre class="brush: python; title: ; notranslate">
#!/usr/bin/env python
from __future__ import division
import xmlrpclib

MAX_POSTS = 100

server = xmlrpclib.ServerProxy('https://YOUR_BLOG_ADDRESS.wordpress.com/xmlrpc.php')
result = server.metaWeblog.getRecentPosts('YOUR_BLOG_ADDRESS', 'YOUR_USERNAME', 'YOUR_PASSWORD', MAX_POSTS)

numPosts = len(result)
numWords = 0
for post in result:
  numWords += len(post['description'].split())
avgWords = numWords/numPosts

print &quot;&quot;&quot;Total Posts: %d
Total Words: %d
Avg Words: %d&quot;&quot;&quot; % (numPosts, numWords, avgWords)
</pre>
<p>And the output I get is:</p>
<pre class="brush: plain; title: ; notranslate">
Total Posts: 21
Total Words: 9731
Avg Words: 463
</pre>
<p>Which is slightly wrong because this simple script does not differentiate between drafts and posts (and my word counting routine is probably too naive among other things).  A more correct and robust version of this is left as an exercise to the reader.  I&#8217;m more than satisfied with this simple, rough estimate.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://nickzarr.com/blog4/2011/02/get-word-count-of-blog/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Simple Python CGI Server Tutorial -CGI Input/Output</title>
		<link>http://nickzarr.com/blog4/2011/02/python-cgi-tutorial-2/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=python-cgi-tutorial-2</link>
		<comments>http://nickzarr.com/blog4/2011/02/python-cgi-tutorial-2/#comments</comments>
		<pubDate>Sun, 13 Feb 2011 03:18:57 +0000</pubDate>
		<dc:creator>Nick Zarczynski</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://nickzarr.com/blog4/?p=23</guid>
		<description><![CDATA[GOTO Part 1 This article will deal with retrieving and using input to your CGI programs.  There are two ways to get input from your CGI programs, encoded within the URL and submitted through forms.  This tutorial will go over both methods. We&#8217;ll need to do a little setup to begin, if you&#8217;ve already read [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://nickzarr.com/blog4/2011/02/python-cgi-tutorial-1/" title="A Simple Python CGI Server Tutorial">GOTO Part 1</a></p>
<p>This  article will deal with retrieving and using input to your CGI  programs.  There are two ways to get input from your CGI programs,  encoded within the URL and submitted through forms.  This tutorial will  go over both methods.</p>
<p>We&#8217;ll need to do a little setup to begin,  if you&#8217;ve already read through the <a title="A Simple Python CGI Server Tutorial" href="http://nickzarr.com/blog4/2011/02/13/python-cgi-tutorial-1/">first tutorial</a> you should be very  familiar with this process.</p>
<p>First we need to create a directory  to house our CGI server and scripts, for this tutorial we&#8217;ll name it  &#8216;server&#8217;.  Create a new file, with the following program, in the  &#8216;server&#8217; directory and name it &#8216;server.py&#8217;.</p>
<pre class="brush: python; title: ; notranslate">
#!/usr/bin/env python

import BaseHTTPServer
import CGIHTTPServer

server = BaseHTTPServer.HTTPServer
handler = CGIHTTPServer.CGIHTTPRequestHandler
server_address = (&quot;&quot;, 8000)
handler.cgi_directories = [&quot;&quot;]

httpd = server(server_address, handler)
httpd.serve_forever()
</pre>
<p>Give  &#8216;server.py&#8217; executable permissions ($ chmod +x server.py).  The next  step is to create a page that will give us a link with an encoded URL.   To do this we&#8217;ll create a simple HTML page with nothing but the encoded  link in it.  Create a new file named &#8216;link.py&#8217; in the &#8216;server&#8217;  directory, with the following code and give it executable permissions ($  chmod +x link.py).</p>
<pre class="brush: python; title: ; notranslate">
#!/usr/bin/env python

print &quot;&quot;&quot;Content-type: text/html

&lt;html&gt;&lt;head&gt;&lt;title&gt;Test URL Encoding&lt;/title&gt;&lt;/head&gt;&lt;body&gt;
&lt;a href=&quot;http://localhost:8000/test_urlencode.py?first=Jack&amp;last=Trades&quot;&gt;Link&lt;/a&gt;
&lt;/body&gt;&lt;/html&gt;'
</pre>
<p>Now  we need to create the CGI script that will receive this data and output  it into a new page.  Create a new file named &#8216;test_urlencode.py&#8217; in the  &#8216;server&#8217; directory and input the following code.</p>
<pre class="brush: python; title: ; notranslate">
#!/usr/bin/env python

import cgi

form = cgi.FieldStorage()

val1 = form.getvalue('first')
val2 = form.getvalue('last')

print &quot;&quot;&quot;Content-type: text/html

&lt;html&gt;&lt;head&gt;&lt;title&gt;Test URL Encoding&lt;/title&gt;&lt;/head&gt;&lt;body&gt;
Hello my name is %s %s
&lt;/body&gt;&lt;/html&gt;&quot;&quot;&quot; % (val1, val2)
</pre>
<p>Remember  to give executable permissions to all your CGI scripts ($ chmod +x  test_urlencode.py).  That&#8217;s it!  We now have a working CGI script.  To  test it type the following into the location bar of your browser.</p>
<p><strong>http://localhost:8000/link.py</strong></p>
<p>Click  on the link and the &#8216;test_urlencode.py&#8217; script will output a page that  says &#8220;Hello my name is Jack Trades&#8221;.  You can play around with the  output by changing the URL of the link to whatever you want.  Below is a  sample of URLs and their output, you can type/paste these directly into  the location bar (no need to modify the &#8216;link.py&#8217; script).</p>
<p><strong>http://localhost:8000/test_urlencode.py?first=Jack&amp;last=Trades<br />
</strong>Hello my name is Jack Trades</p>
<p><strong>http://localhost:8000/test_urlencode.py?first=Adam&amp;last=Baum</strong><br />
Hello my name is Adam Baum</p>
<p><strong>http://localhost:8000/test_urlencode.py?first=Anna&amp;last=Grahm</strong><br />
Hello my name is Anna Grahm</p>
<p>Courtesy of Bart Simpson&#8230;<br />
<strong>http://localhost:8000/test_urlencode.py?last=Tinkle&amp;first=Ivana</strong><br />
Hello my name is Ivana Tinkle</p>
<p>OK,  that&#8217;s enough fun for now.  Let&#8217;s move on to retrieving input from form  data.  The first thing we must do is create a form to enter some data  into.  We&#8217;ll do this by writing another CGI script to output the HTML  form.  Create another file in the &#8216;server&#8217; directory named &#8216;form.py&#8217;  with the code below.</p>
<pre class="brush: python; title: ; notranslate">
#!/usr/bin/env python

print &quot;&quot;&quot;Content-type: text/html

&lt;form method=&quot;post&quot; action=&quot;test_form.py&quot;&gt;
&lt;textarea name=&quot;comments&quot; cols=&quot;40&quot; rows=&quot;5&quot;&gt;
Enter comments here...
&lt;/textarea&gt;
&lt;br/&gt;
&lt;input type=&quot;submit&quot; value=&quot;Submit&quot;&gt;
&lt;/form&gt;&quot;&quot;&quot;
</pre>
<p>This  is the form that will be presented to the user to allow them to enter  their &#8216;comments&#8217;.  Remember to give this script executable permissions  ($ chmod +x form.py).  Next create another file in the &#8216;server&#8217;  directory named &#8216;test_form.py&#8217;, this is the CGI script that will accept  the form data and create a new page that includes the data.</p>
<pre class="brush: python; title: ; notranslate">
#!/usr/bin/env python

import cgi

form = cgi.FieldStorage()

val1 = form.getvalue('comments')

print &quot;&quot;&quot;Content-type: text/html

The form input is below...&lt;br/&gt;&quot;&quot;&quot;
print val1
</pre>
<p>Give  this file executable permissions as well ($ chmod +x test_form.py) and  then go back to your browser and enter the following line in the  location bar.</p>
<p><strong>http://localhost:8000/form.py</strong></p>
<p>You  should see a form with a single text area and a submit button.  Type  whatever you want to in the text area, I chose &#8220;la de da de, we like to  party&#8221;, and hit the submit button.  You should be presented by a page  that says&#8230;</p>
<p>The form input is below&#8230;<br />
la de da de, we like to party</p>
<p>Congratulations  you have successfully handled form data with a CGI script.  You&#8217;ll  notice that Python&#8217;s cgi module uses cgi.FieldStorage() to access both  URL encoded input as well as form based input.  I neglected to go over  the scripts line-by-line because there are very few concepts introduced  in each of them.  If you have any questions, or would like me to clarify  something, please leave a comment below.</p>
]]></content:encoded>
			<wfw:commentRss>http://nickzarr.com/blog4/2011/02/python-cgi-tutorial-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>A Simple Python CGI Server Tutorial</title>
		<link>http://nickzarr.com/blog4/2011/02/python-cgi-tutorial-1/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=python-cgi-tutorial-1</link>
		<comments>http://nickzarr.com/blog4/2011/02/python-cgi-tutorial-1/#comments</comments>
		<pubDate>Sun, 13 Feb 2011 03:14:12 +0000</pubDate>
		<dc:creator>Nick Zarczynski</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://nickzarr.com/blog4/?p=18</guid>
		<description><![CDATA[In this post I&#8217;m going to explain how to create a simple Python CGI Server. To illustrate the concepts involved more clearly I will not attempt to make this server extensible, rather I will try to keep the code as simple and clear as possible. To start with we need to create a directory for [...]]]></description>
			<content:encoded><![CDATA[<p>In this post I&#8217;m going to explain how to create a simple Python CGI  Server.  To illustrate the concepts involved more clearly I will not  attempt to make this server extensible, rather I will try to keep the  code as simple and clear as possible.</p>
<p>To start with we need to  create a directory for our server and CGI scripts to reside in.  I  simply created a directory named &#8216;server&#8217; in my home directory, but you  may name it anything you wish and place it anywhere in your filesystem.</p>
<p>The  next step is to create a simple CGI server.  To do this open up your  favorite text editor and write the program below.  (I&#8217;ll go through it  line-by-line at the end of this tutorial.)</p>
<pre class="brush: python; title: ; notranslate">
#!/usr/bin/env python

import BaseHTTPServer
import CGIHTTPServer
import cgitb; cgitb.enable()  ## This line enables CGI error reporting

server = BaseHTTPServer.HTTPServer
handler = CGIHTTPServer.CGIHTTPRequestHandler
server_address = (&quot;&quot;, 8000)
handler.cgi_directories = [&quot;&quot;]

httpd = server(server_address, handler)
httpd.serve_forever()
</pre>
<p>Save  this file in the &#8216;server&#8217; directory as &#8216;server.py&#8217;, or whatever name  tickles your fancy, and give it executable permissions.  On Linux  systems this is achieved with the command below&#8230;</p>
<pre class="brush: plain; title: ; notranslate">
$ chmod +x server.py
</pre>
<p>That&#8217;s  it for the server!  Simple wasn&#8217;t that?  Now that we have a server  ready to go we need something for it to serve.  For that we will create a  simple &#8220;Hello World!&#8221; CGI script.  Open up your text editor again and  type in the following program.</p>
<pre class="brush: python; title: ; notranslate">
#!/usr/bin/env python

print &quot;Content-type: text/html&quot;
print
print &quot;&amp;lt;title&amp;gt;Test CGI&amp;lt;/title&amp;gt;&quot;
print &quot;&amp;lt;p&amp;gt;Hello World!&amp;lt;/p&amp;gt;&quot;
</pre>
<p>Save this file in the &#8216;server&#8217; directory as &#8216;test_cgi.py&#8217; and give it executable permissions, just like the server.py file.</p>
<pre class="brush: plain; title: ; notranslate">
$ chmod +x test_cgi.py
</pre>
<p>Now  we have all the components in place.  To start your Python CGI server  simply open up a terminal and cd into your &#8216;server&#8217; directory.  When you  are there simply type the following command.</p>
<pre class="brush: plain; title: ; notranslate">
$ ./server.py
</pre>
<p>Your server is now fully operational!  To see your first page fire up a browser and type the following into the location bar.</p>
<p>http://localhost:8000/test_cgi.py</p>
<p>You  should be greeted by a webpage that proudly proclaims &#8220;Hello World!&#8221;.   If you are not, make sure to check your file permissions (both the  server and CGI script should be given executable permissions) and make  sure you copied the programs above verbatim.  To kill your server simply  go back to the terminal and hit &#8216;ctrl-c&#8217;.</p>
<p>&nbsp;</p>
<h2>Server Code Line-By-Line</h2>
<p>For those of you who want a more in-depth analysis of what this code is doing, here is a line-by-line explanation.</p>
<p>The  first thing we need to do is make this script executable on the command  line.  The following &#8216;she-bang&#8217; line simplifies this process so that we  can type: ./server.py instead of the more verbose: python server.py</p>
<pre class="brush: python; title: ; notranslate">
#!/usr/bin/env python
</pre>
<p>The  next two lines import the necessary libraries.  The first,  BaseHTTPServer, provides us with a simple web server and CGIHTTPServer  provides us with a request handler.</p>
<pre class="brush: python; title: ; notranslate">
import BaseHTTPServer
import CGIHTTPServer
</pre>
<p>The  following line enables in-browser CGI error reporting.  This can be  very handy as you develop CGI scripts, however if you don&#8217;t want to  expose the internals of your program to users you may wish to log the  output of this to a file instead.</p>
<pre class="brush: python; title: ; notranslate">
import cgitb; cgitb.enable()  ## This line enables CGI error reporting
</pre>
<p>The next two lines create a server and a request handler.</p>
<pre class="brush: python; title: ; notranslate">
server = BaseHTTPServer.HTTPServer
handler = CGIHTTPServer.CGIHTTPRequestHandler
</pre>
<p>The  next line specifies an address for the server, in this case we want to  use &#8216;localhost&#8217; so simply specifing &#8220;&#8221; will give us this.  This line  also specifies a port number to associate with our server.  You can  choose whatever port number you wish.</p>
<pre class="brush: python; title: ; notranslate">
server_address = (&quot;&quot;, 8000)
</pre>
<p>The  next line specifies where the CGI scripts will reside in relation to  the &#8216;server&#8217; directory.  In this example we put our CGI script in the  base directory by using &#8220;&#8221;, however you may perfer to place your scripts  in a special &#8216;cgi&#8217; or &#8216;cgi-bin&#8217; directory.</p>
<pre class="brush: python; title: ; notranslate">
handler.cgi_directories = [&quot;&quot;]
</pre>
<p>The  next line actually &#8216;creates&#8217; our server, passing it the server address  and port number, as well as the CGI handler.  If you&#8217;re wondering why we name it httpd it stands for HTTP Daemon.</p>
<pre class="brush: python; title: ; notranslate">
httpd = server(server_address, handler)
</pre>
<p>The  final line puts our program into an infinite loop so that the server  can &#8216;serve_forever&#8217;.  Until you kill the server with &#8216;ctrl-c&#8217; from the  terminal, it will continue to listen for requests and serve the  appropriate web pages.</p>
<pre class="brush: python; title: ; notranslate">
httpd.serve_forever()
</pre>
<p><a title="A Simple Python CGI Server Tutorial -CGI Input/Output" href="2011/02/13/python-cgi-tutorial-2/"> GOTO Part 2 | A Simple Python CGI Tutorial &#8211; CGI Input and Output</a></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://nickzarr.com/blog4/2011/02/python-cgi-tutorial-1/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

