\documentclass[english,serif,mathserif,xcolor=pdftex,dvipsnames,table]{beamer}
\usepackage{lsci}
\usepackage{epigraph}

\title[Python II]{%
  Introduction to Python programming, II
}
\author[R. Murri]{%
  \textbf{Riccardo Murri} \\
  Grid Computing Competence Center, \\
  Organisch-Chemisches Institut, \\
  University of Zurich
}
\date{Nov.~16,~2011}


\begin{document}
% title frame
\maketitle

\section{Introduction}

\begin{frame}
  \frametitle{Today's class}
  
  More Python: objects and classes, list comprehensions, iteration and
  objects (again), exceptions, decorators, callable objects, etc.

  \+
  {\small These slides are available for download from: 
    \url{http://www.gc3.uzh.ch/teaching/lsci2011/lecture08.pdf}}
\end{frame}


\section{Objects}

\begin{frame}[fragile]
  \frametitle{User-defined objects}
  \begin{columns}[t]
    \begin{column}{0.5\textwidth}
\begin{lstlisting}
import unittest as ut

class SpTest(ut.TestCase):

  def test_sp_1(self):
    (x, y) = sp(100, [5, 75, 25])
    self.assertTrue((x,y) in 
                    [(75, 25), (25,75)])

  def test_sp_2(self):
    (x,y) = sp(8, [2,1,9,4,4,56,90,3])
    self.assertEqual((x,y), (4,4))
\end{lstlisting}
    \end{column}
    \begin{column}{0.5\textwidth}
      \raggedleft 
      This was your first encounter with Python object, during the
      last Lab session.  Today we are going to examine Python objects
      and classes in more detail.
    \end{column}
  \end{columns}
\end{frame}


\begin{frame}[fragile]
  \begin{columns}[t]
    \begin{column}{0.5\textwidth}
\begin{lstlisting}
import unittest as ut

!\HL{\textbf{class} SpTest(ut.TestCase):}!

  def test_sp_1(self):
    (x, y) = sp(100, [5, 75, 25])
    self.assertTrue((x,y) in
                    [(75,25), (25,75)])

  def test_sp_2(self):
    (x,y) = sp(8, [2,1,9,4,4,56,90,3])
    self.assertEqual((x,y), (4,4))
\end{lstlisting}
    \end{column}
    \begin{column}{0.5\textwidth}
      \raggedleft
      Declare a new class, ihneriting from \texttt{ut.TestCase}.
      The body of the declaration is indented relative to the
      \textbf{class} statement.
    \end{column}
  \end{columns}
\end{frame}


\begin{frame}[fragile]
  \begin{columns}[t]
    \begin{column}{0.5\textwidth}
\begin{lstlisting}
import unittest as ut

class SpTest(ut.TestCase):

  def test_sp_1(!\HL{\textbf{self}}!):
    (x, y) = sp(100, [5, 75, 25])
    self.assertTrue((x,y) in
                    [(75,25), (25,75)])

  def test_sp_2(self):
    (x,y) = sp(8, [2,1,9,4,4,56,90,3])
    self.assertEqual((x,y), (4,4))
\end{lstlisting}
    \end{column}
    \begin{column}{0.5\textwidth}
      \raggedleft
      A method declaration looks exactly like a function
      definition. Every method \emph{must} have at least one argument,
      named \textbf{self}.
    \end{column}
  \end{columns}
\end{frame}


\begin{frame}[fragile]
  \begin{columns}[t]
    \begin{column}{0.45\textwidth}
\begin{lstlisting}
import unittest as ut

class SpTest(ut.TestCase):

  def test_sp_1(self):
    (x, y) = sp(100, [5, 75, 25])
    !\HL{\textbf{self}}!.assertTrue((x,y) in
                     [(75, 25), (25,75)])

  def test_sp_2(self):
    (x,y) = sp(8, [2,1,9,4,4,56,90,3])
    self.assertEqual((x,y), (4,4))
\end{lstlisting}
    \end{column}
    \begin{column}{0.5\textwidth}
      \raggedleft
      {\tt\bf self} is a reference to the object instance (like, e.g.,
      \texttt{this} in Java).  It is used to access attributes and
      invoke methods of the instance itself.
    \end{column}
  \end{columns}
\end{frame}


\begin{frame}[fragile]
  \frametitle{The \texttt{self} argument}

  \textbf{Every method of a Python object always has \texttt{self}
    as first argument.}

  \+
  However, you do not specify it when calling a method: it's
  automatically inserted by Python:
\begin{lstlisting}
>>> class ShowSelf(object):
...   def show(self):
...     print(self)
... 
>>> x = ShowSelf() # construct instance
>>> x.show() # `self' automatically inserted!
<__main__.ShowSelf object at 0x299e150>
\end{lstlisting}

  \+ 
  The \texttt{self} variable is a reference to the object instance
  itself.  You \emph{need to} use \texttt{self} when accessing methods
  or attributes of this instance.
\end{frame}


\begin{frame}[fragile]
  \begin{columns}[t]
    \begin{column}{0.5\textwidth}
\begin{lstlisting}
import unittest as ut

class SpTest(ut.TestCase):

  def test_sp_1(self):
    (x, y) = sp(100, [5, 75, 25])
    !\HL{\textbf{self}.assertTrue}!((x,y) in
                     [(75, 25), (25,75)])

  def test_sp_2(self):
    (x,y) = sp(8, [2,1,9,4,4,56,90,3])
    !\HL{\textbf{self}.assertEqual}!((x,y), (4,4))
\end{lstlisting}
    \end{column}
    \begin{column}{0.5\textwidth}
      \raggedleft
      These call methods defined on the current
      instance.
      \\
      \begin{question}
        Where are they defined, exactly?
      \end{question}
    \end{column}
  \end{columns}
\end{frame}


\begin{frame}[fragile]
  \frametitle{Name resolution rules}
  \small

  Within a function body, names are resolved according to \href{http://stackoverflow.com/questions/291978/short-description-of-python-scoping-rules/292502#292502}{the LEGB rule}:
  \begin{description}
  \item[L] Local scope: any names defined in the current function;
  \item[E] Enclosing function scope: names defined in enclosing
    functions (outermost last);
  \item[G] global scope: names defined in the toplevel of the current module;
  \item[B] Built-in names (i.e., Python's \texttt{\_\_builtins\_\_} module).
  \end{description}

  \+
  \textbf{Any name that is not in one of the above scopes \emph{must}
    be qualified.}

  \+
  So you have to write \texttt{self.assertEqual} to call a method on
  this instance, \texttt{ut.TestCase} to mean a class defined in module
  \texttt{ut}, etc.

  % \begin{references}
  %   \url{http://stackoverflow.com/questions/291978/short-description-of-python-scoping-rules/292502#292502}}
  % \end{references}
\end{frame}

% \begin{frame}[fragile]
%   \begin{columns}[t]
%     \begin{column}{0.5\textwidth}
% \begin{lstlisting}
% import unittest as ut

% class SpTest(ut.TestCase):

%   def test_sp_1(self):
%     (x, y) = sp(100, [5, 75, 25])
%     self.assertTrue((x,y) in [(75,25), (25,75)])

%   def test_sp_2(self):
%     (x,y) = sp(8, [2,1,9,4,4,56,90,3])
%     self.assertEqual((x,y), (4,4))
% \end{lstlisting}
%     \end{column}
%     \begin{column}{0.5\textwidth}
%       This declares a new class, ihneriting from \texttt{ut.TestCase}
%     \end{column}
%   \end{columns}
% \end{frame}


\section{Generalized iteration}

\begin{frame}
  \frametitle{An easy exercise}
  A \emph{dotfile} is a file whose name starts with a dot character
  ``\texttt{.}''.

  \+
  How can you list all dotfiles in a given directory?

  \+
  (Recall that the Python library call for listing the entries in a
  directory is \texttt{os.listdir()})
\end{frame}

\begin{frame}[fragile]
  \frametitle{A very basic solution}
  Use a \lstinline|for| loop to accumulate the results into a list:
  \begin{python}
dotfiles = [ ]
for entry in os.listdir(path):
  if entry.startswith('.'):
    dotfiles.append(entry)
  \end{python}
\end{frame}


\begin{frame}[fragile]
  \frametitle{List comprehensions, I}
  Python has a better and more compact syntax for \emph{filtering} elements
  of a list and/or \emph{applying} a function to them:
  \begin{python}
dotfiles = [ entry for entry in dotfiles 
             if entry.startswith('.') ]
  \end{python}
  
  \+ 
  This is called a \emph{list comprehension}.
\end{frame}


\begin{frame}[fragile]
  \frametitle{List comprehensions, II}
  \def\e{\ttfamily\itshape}
  
  The general syntax of a list comprehension is:
  \begin{python}
    !\bf[! !\e expr! for !\e var! in !\e iterable! if !\e condition! !\bf]!
  \end{python}
  where:
  \begin{description}
  \item[\e expr] is any Python expression;
  \item[\e iterable] is a (generalized) sequence;
  \item[\e condition] is a boolean expression, depending on
    {\e var};
  \item[\e var] is a variable that will be bound in turn to each item
    in {\e iterable} which satisfies {\e condition}.
  \end{description}

  \+
  The `{\lstinline|if| \e condition}' part is optional.
\end{frame}


\begin{frame}[fragile]
  \frametitle{Generator expressions}
  \def\e{\ttfamily\itshape}

  List comprehensions are a special case of \emph{generator expressions}:
  \begin{python}
    ( !\e expr! for !\e var! in !\e iterable! if !\e condition! )
  \end{python}

  \+
  A generator expression is a valid iterable and can be used to
  initialize tuples, sets, dicts, etc.:
  \begin{python}
    # the set of square numbers < 100
    squares = set(n*n for n in range(10))
  \end{python}

  \+
  Generator expressions are valid \emph{expression}, so they can be nested:
  \begin{python}
    # cartesian product of sets A and B
    C = set( (a,b) for a in A for b in B )
  \end{python}
\end{frame}


\begin{frame}[fragile]
  \frametitle{Generators}
  Generator expressions are a special case of \emph{generators}.

  \+ A generator is like a function, except it uses \lstinline|yield|
  instead of \lstinline|return|:
  \begin{python}
    def squares():
      n = 0
      while True:
        yield n*n
        n += 1
  \end{python}

  \+
  At each iteration, execution resumes with the statement logically
  following \lstinline|yield| in the generator's execution flow.

  \+
  There can be multiple \lstinline|yield| statements in a generator.

  \begin{references}
    \url{http://wiki.python.org/moin/Generators}
  \end{references}
\end{frame}


\begin{frame}[fragile]
  \frametitle{The Iterator Protocol}

  An object can function as an iterator iff it implements a
  \texttt{next()} method, that:
  \begin{description}
  \item[\emph{either}] returns the next value in the iteration,
  \item[\emph{or}] raises \texttt{StopIteration} to signal the end of the
    iteration.
  \end{description}

  \+
  An object can be iterated over with \lstinline|for| if it implements a
  \lstinline|__iter__()| method.

  \begin{references}
    \url{http://www.python.org/dev/peps/pep-0234/}
  \end{references}
\end{frame}


\begin{frame}[fragile]
  \begin{columns}[t]
    \begin{column}{0.5\textwidth}
\begin{lstlisting}
class WordIterator(object):

  def __init__(self, text):
    self._words = text.split()

  def next(self):
      if len(self._words) > 0:
          return self._words.pop(0)
      else:
          raise StopIteration

  def __iter__(self):
      return self
\end{lstlisting}
    \end{column}
    \begin{column}{0.5\textwidth}
      \raggedleft
      Iterate over the words in the given text: split the text at
      white spaces, and return the parts one~by~one.
    \end{column}
  \end{columns}

  \+
  {\scriptsize Source code available at:
    \url{http://www.gc3.uzh.ch/teaching/lsci2011/lecture08/worditerator.py}}
\end{frame}


\begin{frame}[fragile]
  \begin{columns}[t]
    \begin{column}{0.5\textwidth}
\begin{lstlisting}
class WordIterator(!\HL{object}!):

  def __init__(self, text):
    self._words = text.split()

  def next(self):
      if len(self._words) > 0:
          return self._words.pop(0)
      else:
          raise StopIteration

  def __iter__(self):
      return self
\end{lstlisting}
    \end{column}
    \begin{column}{0.5\textwidth}
      \raggedleft
      Every class must inherit from a parent class.
      \\
      If there's no other class, inherit from the \texttt{object}
      class. (Root of the class hierarchy.)
      
    \end{column}
  \end{columns}
\end{frame}


\begin{frame}[fragile]
  \begin{columns}[t]
    \begin{column}{0.5\textwidth}
\begin{lstlisting}
class WordIterator(object):

  !\HL{\textbf{def} \_\_init\_\_(\textbf{self}, text):}!
    self._words = text.split()

  def next(self):
      if len(self._words) > 0:
          return self._words.pop(0)
      else:
          raise StopIteration

  def __iter__(self):
      return self
\end{lstlisting}
    \end{column}
    \begin{column}{0.5\textwidth}
      \raggedleft
      The constructor.
    \end{column}
  \end{columns}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Constructors}

  The \lstinline|__init__| method is the object constructor.
  It should \emph{never} return any value (other than \texttt{None}).

  \+
  However, you call a constructor by class name:
\begin{lstlisting}
# make `w' an instance of `WordIterator'
w = WordIterator("some text")
\end{lstlisting}

  \+
  (Again, note that the \texttt{self} part is automatically inserted
  by Python.)
\end{frame}


\begin{frame}
  \frametitle{No overloading}

  \textbf{Python does not allow overloading of functions.}

  \+
  Any function.

  \+
  Hence, no overloading of constructors.

  \+
  So: \textbf{a class can have one and only one constructor.}
\end{frame}


\begin{frame}[fragile]
  \frametitle{Constructor chaining}
  % \begin{flushright}
  %   \footnotesize%
  %   {\em ``Explicit is better than implicit''}
  %   --- T.~Peters, \href{http://www.python.org/dev/peps/pep-0020/}{The
  %     Zen of Python}
  % \end{flushright}

    When a class is instanciated, Python only calls the first
    constructor it can find in the
    \href{http://www.python.org/download/releases/2.3/mro/}{class inheritance call-chain}.

    \+ \textbf{If you need to call a superclass' constructor, you need
      to do it \emph{explicitly}:}
    \begin{python}
class Application(Task):
  def __init__(self, ...):
    # do Application-specific stuff here
    Task.__init__(self, ...)
    # some more Application-specific stuff
    \end{python}

    \+
    Calling a superclass constructor is optional, and
    it can happen anywhere in the \lstinline|__init__| method body.
\end{frame}


\begin{frame}[fragile]
  \frametitle{Multiple-inheritance}
  Python allows multiple inheritance.

  \+
  Just list all the parent classes:
  \begin{python}
class C(A,B):
  # class definition
  \end{python}
  
  \+
  With multiple inheritance, it is your responsibility to call all the
  needed superclass constructors.

  \+ 
  Python uses the
  \href{http://www.python.org/download/releases/2.3/mro/}{C3
    algorithm} to determine the call precedence in an inheritance
  chain.

  \+
  You can always query a class for its ``method resolution order'',
  via the \lstinline|__mro__| attribute:
  \begin{lstlisting}[basicstyle=\scriptsize\ttfamily]
>>> C.__mro__
(<class 'ex.C'>, <class 'ex.A'>, <class 'ex.B'>, <type 'object'>)
  \end{lstlisting}
\end{frame}


\begin{frame}[fragile]
  \begin{columns}[t]
    \begin{column}{0.5\textwidth}
\begin{lstlisting}
class WordIterator(object):

  def __init__(self, text):
    !\HL{\textbf{self}.\_words}! = text.split()

  def next(self):
      if len(self._words) > 0:
          return self._words.pop(0)
      else:
          raise StopIteration

  def __iter__(self):
      return self
\end{lstlisting}
    \end{column}
    \begin{column}{0.5\textwidth}
      \raggedleft
      This creates an \emph{attribute} of the current object.
    \end{column}
  \end{columns}
\end{frame}


\begin{frame}[fragile]
  \frametitle{Object attributes}

  A Python object is (in particular) a key-value mapping: attributes
  (keys) are valid identifiers, values can be any Python object.

  \+
  Any object has attributes, which you can access (create, read,
  overwrite) using the dot notation:
\begin{lstlisting}
# create or overwrite the `name' attribute of `w'
w.name = "Joe"

# get the value of `w.name' and print it
print (w.name)
\end{lstlisting}

  \+ 
  So, in the constructor you create the required \emph{instance}
  attributes using \lstinline|self.var = ...|

  \+
  \emph{Note:} also methods are attributes!
\end{frame}


\begin{frame}
  \frametitle{No access control}
  There are no ``public''/``private''/etc. qualifiers for object
  attributes.

  \+
  \textbf{\emph{Any} code can create/read/overwrite/delete \emph{any} attribute on
    \emph{any} object.}

  \+
  There are \emph{conventions}, though:
  \begin{itemize}
  \item ``protected'' attributes: \texttt{\_name}
  \item ``private'' attributes: \texttt{\_\_name}
  \end{itemize}
  (But again, note that this is not \emph{enforced} by the system in
  any way.)

\end{frame}


\begin{frame}[fragile]
  \begin{columns}[t]
    \begin{column}{0.5\textwidth}
\begin{lstlisting}
class WordIterator(object):

  def __init__(self, text):
    self._words = text.split()

  def next(self):
      if len(self._words) > 0:
          return self._words.pop(0)
      else:
          !\HL{\textbf{raise} StopIteration}!

  def __iter__(self):
      return self
\end{lstlisting}
    \end{column}
    \begin{column}{0.5\textwidth}
      \raggedleft
      Raise the \texttt{StopIteration} exception if there are no more
      words to return.
      \\
      (More on exceptions in a~moment.)
    \end{column}
  \end{columns}
\end{frame}


\begin{frame}[fragile]
  \begin{columns}[t]
    \begin{column}{0.5\textwidth}
\begin{lstlisting}
class WordIterator(object):

  def __init__(self, text):
    self._words = text.split()

  def next(self):
      if len(self._words) > 0:
          return self._words.pop(0)
      else:
          raise StopIteration

  def __iter__(self):
      !\HL{\bfseries return self}!
\end{lstlisting}
    \end{column}
    \begin{column}{0.5\textwidth}
      \raggedleft
      The \lstinline|__iter__| method should return a valid iterator.
      Since this object \emph{is} an iterator, just
      return~{\ttfamily\bfseries self}.
    \end{column}
  \end{columns}
\end{frame}


\begin{frame}[fragile]
  \frametitle{Using iterators}
  
  Iterators can be used in a \lstinline|for| loop:
\begin{lstlisting}
>>> for word in WordIterator("a nice sunny day"):
...     print '*'+word+'*',
... 
*a* *nice* *sunny* *day*
\end{lstlisting}

  \+ 
  They can be composed with other iterators for effect:
\begin{lstlisting}
>>> for n, word in enumerate(WordIterator("a ...")):
...     print str(n)+':'+word,
... 
0:a 1:nice 2:sunny 3:day
\end{lstlisting}

  \begin{seealso}
    \url{http://docs.python.org/library/itertools.html}
  \end{seealso}
\end{frame}


\section{Exceptions}

\begin{frame}[fragile]
  \frametitle{Exceptions}

  Exceptions are objects that inherit from the built-in
  \lstinline|Exception| class.

  \+
  To create a new exception just make a new class:
\begin{lstlisting}
class NewKindOfError(Exception):
  """
  Do use the docstring to document 
  what this error is about.
  """
  pass
\end{lstlisting}

  \+
  Exceptions are handled by class name, so they usually do not need
  any new methods (although you are free to define some if needed).

  \begin{seealso}
    \url{http://docs.python.org/library/exceptions.html}
  \end{seealso}
\end{frame}


\begin{frame}[fragile]
\begin{lstlisting}
try:
  # code that might raise an exception
except SomeException:
  # handle some exception
except AnotherException, ex:
  # the actual Exception instance
  # is available as variable `ex'
else:
  # performed on normal exit from `try'
finally:
  # performed on exit in any case
\end{lstlisting}

  \+
  The optional \lstinline|else| clause is executed if and when control flows off the
  \emph{end} of the \lstinline|try| clause.

  \+
  The optional \lstinline|finally| clause is executed on exit from the
  \lstinline|try| or \lstinline|except| block in \emph{any} case.

  \begin{references}
    \scriptsize
    \url{http://docs.python.org/reference/compound_stmts.html#try}
\end{references}
\end{frame}


\begin{frame}[fragile]
  \frametitle{Raising exceptions}
  
  Use the \lstinline|raise| statement with an \texttt{Exception}
  instance:
\begin{lstlisting}
if an_error_occurred:
  raise AnError("Spider sense is tingling.")
\end{lstlisting}

  \+
  Within an \lstinline|except| clause, you can use \lstinline|raise|
  with no arguments to re-raise the current exception:
\begin{lstlisting}
try:
  something()
except ItDidntWork:
  do_cleanup()
  # re-raise exception to caller
  raise
\end{lstlisting}
\end{frame}


\begin{frame}[fragile]
  \frametitle{Exception handling example}

Read lines from a CSV file, ignoring those that do not have the
required number of fields.  If other errors occur, abort. 
Close the file when done.
\begin{lstlisting}
job_state = { } # empty dict
try:
  csv_file = open('jobs.csv', 'r')
  for line in csv_file:
    line = line.strip() # remove trailing newline
    try:
      name, jobid, state = line.split(",")
    except ValueError:
      continue # ignore line
    job_state[jobid] = state
except IOError:
  raise # up to caller
finally:
  csv_file.close()
\end{lstlisting}
\end{frame}


\begin{frame}[fragile]
  \frametitle{A common case}
  The ``cleanup'' pattern is so common that Python has a special
  statement to deal with it:
\begin{lstlisting}
with open('jobs.csv', 'r') as csv_file:
  for line in csv_file:
    line = line.strip() # remove trailing newline
    try:
      name, jobid, state = line.split(",")
    except ValueError:
      continue # ignore line
    job_state[jobid] = state
\end{lstlisting}

  \+
  The \lstinline|with| statement ensures that the file is closed upon
  exit from the \lstinline|with| block (for whatever reason).

  \begin{references}
    \scriptsize \url{http://docs.python.org/reference/compound_stmts.html#with}
  \end{references}
\end{frame}


\begin{frame}
  \frametitle{The ``context manager'' protocol}

  Any object can be used in a \lstinline|with|
  statement, provided it defines the following two methods:

  \begin{describe}{\lstinline|__enter__()|}
    Called upon entrance of the \lstinline|with| block; it return
    value is assigned to the variable following \lstinline|as| (if
    any).
  \end{describe}

  \begin{describe}{\lstinline|__exit__(exc_cls, exc_val, exc_tb)|}
    Called with three arguments upon exit from the block.  If an
    exception occurred, the three arguments are the exception type,
    value and traceback; otherwise, the three argument are all set to
    \texttt{None}
  \end{describe}
  
  \begin{question}
    {Can you think of other examples where this could be useful?}
  \end{question}

  \begin{seealso}
    \url{http://www.python.org/dev/peps/pep-0343/}
  \end{seealso}
\end{frame}

\section{Decorators}

% decorators
% - 'debug' decorator example
% - *args and *kwargs

\begin{frame}[fragile]
  Functions are first-class in Python: so you can pass them as
  arguments to other functions, return them from a function, and hence
  \emph{modify} them.

  \+
  The \emph{decorator} syntax:
  \begin{python}
    @decorator
    def func(...):
      # function body
  \end{python}
  is an alternate and more readable form for:
  \begin{python}
    def func(...):
      # function body
    func = decorator(func)
  \end{python}

  \+
  Here, \lstinline|decorator| is a function that takes a function as
  argument and returns (another) function.
\end{frame}

\begin{frame}
  \frametitle{Decorators}
  Decorators are expressions that take a function and evaluate to a
  function. 

  \+
  They are made possible (and interesting) because of two Python
  features:
  \begin{itemize}
  \item Functions are first-class.
  \item Functions can be defined \emph{inside} other functions.
  \end{itemize}
\end{frame}


\begin{frame}[fragile]
  \frametitle{A debug decorator, I}
  This is a real decorator, that modifies a function to print a log
  line with its calling parameters.

  \+
  \begin{python}
def trace(func):
  name = func.func_name
  def substitute(*posargs, **kwargs):
    print ("Calling %s with args=%r, kwargs=%r"
           % (name, posargs, kwargs))
    return func(*posargs, **kwargs)
  return substitute
  \end{python}

  \+
  {\footnotesize Source code available at: 
    \url{http://www.gc3.uzh.ch/teaching/lsci2011/lecture08/debug.py}}
\end{frame}

\begin{frame}[fragile]
  \frametitle{A debug decorator, II}
  So, for example this code:
  \begin{python}
@trace
def factorial(n):
  return 1 if n==0 else n*factorial(n-1)
  \end{python}

  \+
  Produces the following output:
  \begin{python}
>>> factorial(3)
Calling factorial with args=(2,), kwargs={}
Calling factorial with args=(1,), kwargs={}
Calling factorial with args=(0,), kwargs={}
6
  \end{python}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Interlude: the ternary operator}
  \begin{python}
@trace
def factorial(n):
  return !\HL{1 \textbf{if} n==0 \textbf{else} n*factorial(n-1)}!
  \end{python}
  
  \+
  Incidentally, this is the
  \href{http://en.wikipedia.org/wiki/Ternary_operator}{ternary
    operator}, which in C and Java reads {\ttfamily \emph{condition} ?
  \emph{if\_true} : \emph{if\_false}}
\end{frame}

\begin{frame}[fragile]
  \frametitle{The debug decorator explained}
  \begin{python}
!\HL{\textbf{def} trace(func):}!
  name = func.func_name
  def substitute(*posargs, **kwargs):
    print ("Calling %s with args=%r, kwargs=%r"
           % (name, posargs, kwargs))
    return func(*posargs, **kwargs)
  return substitute
  \end{python}

  \+
  A decorator is just an ordinary function\ldots
\end{frame}

\begin{frame}[fragile]
  \frametitle{The debug decorator explained}
  \begin{python}
def trace(func):
  name = func.func_name
  !\HL{\textbf{def} substitute(*posargs, **kwargs):}!
    print ("Calling %s with args=%r, kwargs=%r"
           % (name, posargs, kwargs))
    return func(*posargs, **kwargs)
  return substitute
  \end{python}

  \+
  \ldots that creates an inner function \ldots
\end{frame}

\begin{frame}[fragile]
  \frametitle{The debug decorator explained}
  \begin{python}
def trace(func):
  name = func.func_name
  def substitute(*posargs, **kwargs):
    print ("Calling %s with args=%r, kwargs=%r"
           % (name, posargs, kwargs))
    return func(*posargs, **kwargs)
  !\HL{\textbf{return} substitute}!
  \end{python}

  \+
  \ldots which is then returned as result of the outer function.
\end{frame}

\begin{frame}[fragile]
  \frametitle{The debug decorator explained}
  \begin{python}
def trace(!\HL{func}!):
  !\HL{name = func.func\_name}!
  def substitute(*posargs, **kwargs):
    print ("Calling %s with args=%r, kwargs=%r"
           % (!\HL{name}!, posargs, kwargs))
    return !\HL{func}!(*posargs, **kwargs)
  return substitute
  \end{python}

  \+
  Any names that are bound in the outer function are available in the
  inner function.

  \+
  Each invocation of the outer function creates a new set of bindings
  (i.e., two inner functions created by different invocations will not
  see each other's bindings).
\end{frame}

\begin{frame}[fragile]
  \frametitle{star-arguments, I}
  \begin{python}
def trace(func):
  name = func.func_name
  def substitute(!\HL{*posargs}!, **kwargs):
    print ("Calling %s with args=%r, kwargs=%r"
           % (name, posargs, kwargs))
    return func(*posargs, **kwargs)
  return substitute
  \end{python}

  \+
  In a function \emph{definition}, \lstinline|*args| indicates that the
  variable \lstinline|args| is bound to the tuple of actual parameters
  that were passed to the function.
\end{frame}

\begin{frame}[fragile]
  \frametitle{star-arguments, II}
  \begin{python}
def trace(func):
  name = func.func_name
  def substitute(*posargs, **kwargs):
    print ("Calling %s with args=%r, kwargs=%r"
           % (name, posargs, kwargs))
    return func(!\HL{*posargs}!, **kwargs)
  return substitute
  \end{python}

  \+ In a function \emph{call}, \lstinline|*args| indicates that the
  remaining positional arguments are taken from the \emph{sequence}
  \lstinline|args|.
\end{frame}

\begin{frame}[fragile]
  \frametitle{star-star-arguments}
  \begin{python}
def trace(func):
  name = func.func_name
  def substitute(*posargs, !\HL{**kwargs}!):
    print ("Calling %s with args=%r, kwargs=%r"
           % (name, posargs, kwargs))
    return func(*posargs, !\HL{**kwargs}!)
  return substitute
  \end{python}

  \+
  Similarly, \lstinline|**kwargs| in a definition binds variable
  \lstinline|kwargs| to a dictionary containing the passed keyword
  arguments.

  \+
  In a function call, \lstinline|**kwargs| takes additional keyword
  arguments from \emph{dictionary} \lstinline|kwargs|.
\end{frame}


\section{Special methods}

\begin{frame}[fragile]
  \frametitle{What's a decorator, again?}
  Decorators are \sout{functions} callable objects that take a
  function and return a function.

  \+
  An object is \emph{callable} iff it defines a \lstinline|__call__()|
  method.  Functions are callable objects.

  \+
  \begin{python}
class CallMe(object):
  def __call__(self, name="baby"):
    return ("Call me, %s" % name)
  \end{python}

  \begin{columns}
    \begin{column}{0.5\textwidth}
      \begin{python}
>>> c = CallMe() 
>>> c() 
'Call me, baby' 
>>> c("Mister")
'Call me, Mister'
      \end{python}
    \end{column}
    \begin{column}{0.5\textwidth}
      A callable object may be called as if it were a function.  The
      signature of the \lstinline|__call__()| method determines the
      arguments used in the call.
    \end{column}
  \end{columns}
\end{frame}


\begin{frame}[fragile]
  \frametitle{Example: The \texttt{memoize} decorator}
  The \lstinline|memoize| decorator caches function results and
  re-uses them instead of running the computation again.

  \+
  \begin{python}
class memoize(object):

  def __init__(self, func):
    self._func = func
    self._cache = dict()

  def __call__(self, *args):
    if args not in self._cache:
      self._cache[args] = self._func(*args)
    return self._cache[args]
  \end{python}

  \+
  {\scriptsize Source code available at:
    \url{http://www.gc3.uzh.ch/teaching/lsci2011/lecture08/memoize.py}}
\end{frame}


\begin{frame}[fragile]
  \frametitle{Class attributes}
  Classes are Python objects too, hence they can have attributes.

  \+
  Class attributes can be created with the variable assignment syntax
  in a class definition block:
\begin{lstlisting}
class A(object):
  class_attr = value
  def __init__(self):
    # ...
\end{lstlisting}

  \+
  \textbf{Class attributes are shared among all instances of the same
    class!}
\end{frame}


\begin{frame}[fragile]
  \frametitle{Class attributes example}
\begin{lstlisting}
class AutoInc(object):
  _cnt = 0
  def __init__(self):
    AutoInc._cnt += 1
    self._value = AutoInc._cnt
  def value(self):
    return self._value
\end{lstlisting}

  \+
  \begin{question}
    Create three instances of the class: \texttt{u1}, \texttt{u2},
    \texttt{u3}.  What would the \lstinline|value()| method return for
    each of them?
  \end{question}
\end{frame}


\section{The End}

\begin{frame}
  \frametitle{Further reading}
  \href{http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html}
  {Idiomatic Python}:  
  A presentation of Python programming idioms for writing better
  (simpler, cleaner and often faster) code, by
  \href{http://python.net/~goodger/}{David Goodger}.

  \+
  \href{http://pixelmonkey.org/pub/python-training/}
  {The Zen of Python in 3 days}:
  Great set of slides from a 3-day course, covering topics from the
  very basics of Python programming to advanced real-world topics like
  SQL ORM usage and web programming.

  \+
  {\small A commented list of online resources on the course Wiki:
    \url{http://www.gc3.uzh.ch/teaching/lsci2011/python.html}}
\end{frame}

\begin{frame}
  \begin{center}
    \lstinline[basicstyle=\Large\ttfamily]|import antigravity|
  \end{center}

  \+
  (You need at least Python 2.7 for this to work, though.)
\end{frame}
\end{document}

%%% Local Variables: 
%%% mode: latex
%%% TeX-master: t
%%% End: 

