%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Tutorial slides on Python. % % Author: Prabhu Ramachandran % Copyright (c) 2005-2009, Prabhu Ramachandran %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \documentclass[compress,14pt]{beamer} % \documentclass[handout]{beamer} % \usepackage{pgfpages} % \pgfpagesuselayout{4 on 1}[a4paper,border, shrink=5mm,landscape] \usepackage{tikz} \newcommand{\hyperlinkmovie}{} %\usepackage{movie15} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Note that in presentation mode % \paperwidth 364.19536pt % \paperheight 273.14662pt % h/w = 0.888 \mode { \usetheme{Warsaw} %\usetheme{Boadilla} %\usetheme{default} \useoutertheme{infolines} \setbeamercovered{transparent} } % To remove navigation symbols \setbeamertemplate{navigation symbols}{} \usepackage{amsmath} \usepackage[english]{babel} \usepackage[latin1]{inputenc} \usepackage{times} \usepackage[T1]{fontenc} % Taken from Fernando's slides. \usepackage{ae,aecompl} \usepackage{mathpazo,courier,euler} \usepackage[scaled=.95]{helvet} \usepackage{pgf} \definecolor{darkgreen}{rgb}{0,0.5,0} \usepackage{listings} \lstset{language=Python, basicstyle=\ttfamily\bfseries, commentstyle=\color{red}\itshape, stringstyle=\color{darkgreen}, showstringspaces=false, keywordstyle=\color{blue}\bfseries} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % My Macros \setbeamercolor{postit}{bg=yellow,fg=black} \setbeamercolor{emphbar}{bg=blue!20, fg=black} \newcommand{\emphbar}[1] {\begin{beamercolorbox}[rounded=true]{emphbar} {#1} \end{beamercolorbox} } %{\centerline{\fcolorbox{gray!50} {blue!10}{ %\begin{minipage}{0.9\linewidth} % {#1} %\end{minipage} % }}} \newcommand{\myemph}[1]{\structure{\emph{#1}}} \newcommand{\PythonCode}[1]{\lstinline{#1}} \newcommand{\tvtk}{\texttt{tvtk}} \newcommand{\mlab}{\texttt{mlab}} \newcommand{\typ}[1]{\lstinline{#1}} \newcounter{time} \setcounter{time}{0} \newcommand{\inctime}[1]{\addtocounter{time}{#1}{\vspace*{0.1in}\tiny \thetime\ m}} \newcommand\BackgroundPicture[1]{% \setbeamertemplate{background}{% \parbox[c][\paperheight]{\paperwidth}{% \vfill \hfill \hfill \vfill }}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Configuring the theme %\setbeamercolor{normal text}{fg=white} %\setbeamercolor{background canvas}{bg=black} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Title page \title[Python Development]{Python Development} \author[FOSSEE] {FOSSEE} \institute[IIT Bombay] {Department of Aerospace Engineering\\IIT Bombay} \date[] {1 May, 2010\\Day 2, Session 4} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %\pgfdeclareimage[height=0.75cm]{iitblogo}{iitblogo} %\logo{\pgfuseimage{iitblogo}} \AtBeginSection[] { \begin{frame} \frametitle{Outline} \Large \tableofcontents[currentsection,currentsubsection] \end{frame} } %% Delete this, if you do not want the table of contents to pop up at %% the beginning of each subsection: \AtBeginSubsection[] { \begin{frame} \frametitle{Outline} \tableofcontents[currentsection,currentsubsection] \end{frame} } \AtBeginSection[] { \begin{frame} \frametitle{Outline} \tableofcontents[currentsection,currentsubsection] \end{frame} } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % DOCUMENT STARTS \begin{document} \begin{frame} \maketitle \end{frame} \section{Tests: Getting started} \begin{frame}[fragile] \frametitle{gcd revisited!} \begin{itemize} \item Open \texttt{gcd.py} \end{itemize} \begin{lstlisting} def gcd(a, b): if a % b == 0: return b return gcd(b, a%b) print gcd(15, 65) print gcd(16, 76) \end{lstlisting} \begin{itemize} \item \texttt{python gcd.py} \end{itemize} \end{frame} \begin{frame}[fragile] \frametitle{Find lcm using our gcd module} \begin{itemize} \item Open \texttt{lcm.py} \item $lcm = \frac{a * b}{gcd(a,b)}$ \end{itemize} \begin{lstlisting} from gcd import gcd def lcm(a, b): return (a * b) / gcd(a, b) print lcm(14, 56) \end{lstlisting} \begin{itemize} \item \texttt{python lcm.py} \end{itemize} \begin{lstlisting} 5 4 56 \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Writing stand-alone module} Edit \texttt{gcd.py} file to: \begin{lstlisting} def gcd(a, b): if a % b == 0: return b return gcd(b, a%b) if __name__ == "__main__": print gcd(15, 65) print gcd(16, 76) \end{lstlisting} \begin{itemize} \item \texttt{python gcd.py} \item \texttt{python lcm.py} \end{itemize} \end{frame} \begin{frame}[fragile] \frametitle{Automating tests} \begin{lstlisting} def gcd(a, b): if a % b == 0: return b return gcd(b, a % b) if __name__ == '__main__': assert gcd(15, 65) == 5 assert gcd(16, 76) == 4 \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Automating tests} \begin{lstlisting} if __name__ == '__main__': for line in open('numbers.txt'): numbers = line.split() x = int(numbers[0]) y = int(numbers[1]) result = int(numbers[2]) if gcd(x, y) != result: print "Failed gcd test for", x, y \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Python Test Packages} \begin{itemize} \item Python's \typ{unittest}:\linebreak \url{http://docs.python.org/library/unittest.html} \linebreak \item \typ{nose}:\linebreak \url{http://code.google.com/p/python-nose/} \end{itemize} \end{frame} \section{Coding Style} \begin{frame}{Readability and Consistency} \begin{itemize} \item Readability Counts!\\Code is read more often than its written. \item Consistency! \item Know when to be inconsistent. \item Play telephone with that line of code. \end{itemize} \end{frame} \begin{frame}[fragile] \frametitle{A question of good style} \begin{lstlisting} amount = 12.68 denom = 0.05 num_coins = round(amount/denom) rounded_amount = num_coins * denom \end{lstlisting} \pause \begin{block}{Style Rule \#1} Naming is 80\% of programming \end{block} \end{frame} \begin{frame}[fragile] \frametitle{Code Layout} \begin{itemize} \item Indentation \item Tabs or Spaces? \item Maximum Line Length \item Blank Lines \item Encodings \item Consider any legible book \end{itemize} \end{frame} \begin{frame}{Whitespaces in Expressions} \begin{itemize} \item When to use extraneous whitespaces? \item When to avoid extra whitespaces? \item Use one statement per line \end{itemize} \end{frame} \begin{frame}[fragile] \frametitle{Whitespace} Whitespace... it's not just for compilers! \begin{lstlisting} def myfanfunc(somevar,another,yetmore): if a%b==0:return b return myfanfunc(b,a%b) \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Whitespace} The compiler doesn't care! Humans do! \begin{lstlisting} def my_fan_func(some_var, another, yet_more): if a % b == 0: return b return my_fan_func(b, a % b) \end{lstlisting} \end{frame} \begin{frame}{Comments} \begin{itemize} \item No comments better than contradicting comments \item Block comments \item Inline comments \end{itemize} \end{frame} \begin{frame}{Docstrings} \begin{itemize} \item When to write docstrings? \item Ending the docstrings \item One liner docstrings \end{itemize} \end{frame} \begin{frame}{The Python Style Guide} \begin{itemize} \item PEP8 \item PEP8 \item PEP8 \item \url{http://www.python.org/dev/peps/pep-0008/} \end{itemize} \end{frame} \section{Debugging} \subsection{Errors and Exceptions} \begin{frame}[fragile] \frametitle{Errors} \begin{lstlisting} In []: while True print 'Hello world' \end{lstlisting} \pause \begin{lstlisting} File "", line 1, in ? while True print 'Hello world' ^ SyntaxError: invalid syntax \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Exceptions} \begin{lstlisting} In []: print spam \end{lstlisting} \pause \begin{lstlisting} Traceback (most recent call last): File "", line 1, in NameError: name 'spam' is not defined \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Exceptions} \begin{lstlisting} In []: 1 / 0 \end{lstlisting} \pause \begin{lstlisting} Traceback (most recent call last): File "", line 1, in ZeroDivisionError: integer division or modulo by zero \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Processing user input} \begin{lstlisting} prompt = 'Enter a number(Q to quit): ' a = raw_input(prompt) num = int(a) if a != 'Q' else 0 \end{lstlisting} \emphbar{What if the user enters some other alphabet?} \end{frame} \begin{frame}[fragile] \frametitle{Handling Exceptions} Python provides \typ{try} and \typ{except} clause. \begin{lstlisting} prompt = 'Enter a number(Q to quit): ' a = raw_input(prompt) try: num = int(a) print num except: if a == 'Q': print "Exiting ..." else: print "Wrong input ..." \end{lstlisting} \end{frame} \subsection{Strategy} \begin{frame}[fragile] \frametitle{Debugging effectively} \begin{itemize} \item \typ{print} based strategy \item Process: \end{itemize} \begin{center} \pgfimage[interpolate=true,width=5cm,height=5cm]{DebugginDiagram.png} \end{center} \end{frame} \begin{frame}[fragile] \frametitle{Debugging effectively} \begin{itemize} \item Using \typ{\%debug} in IPython \end{itemize} \end{frame} \begin{frame}[fragile] \frametitle{Debugging in IPython} \small \begin{lstlisting} In []: import mymodule In []: mymodule.test() --------------------------------------------- NameError Traceback (most recent call last) in () mymodule.py in test() 1 def test(): ----> 2 print spam NameError: global name 'spam' is not defined In []: %debug > mymodule.py(2)test() 0 print spam ipdb> \end{lstlisting} \inctime{15} \end{frame} \begin{frame} \frametitle{The Python Debugger} \url{http://docs.python.org/library/pdb.html} \end{frame} \subsection{Exercise} \begin{frame}[fragile] \frametitle{Debugging: Exercise} \small \begin{lstlisting} science = {} for record in open('sslc1.txt'): fields = record.split(';') region_code = fields[0].strip() score_str = fields[6].strip() score = int(score_str) if score_str != 'AA' else 0 if score > 90: science[region_code] += 1 pie(science.values(), labels=science.keys()) savefig('science.png') \end{lstlisting} \inctime{10} \end{frame} \begin{frame} \frametitle{Documentation} \begin{itemize} \item Python: \linebreak \url{http://docs.python.org/} \item Scipy \& Numpy: \linebreak \url{http://docs.scipy.org/doc/} \item IPython: \linebreak \url{http://ipython.scipy.org/moin/Documentation} \item Matplotlib: \linebreak \url{http://matplotlib.sourceforge.net/} \end{itemize} \end{frame} \begin{frame} \frametitle{Packages} Home for packages \begin{itemize} \item Python Package Index: \linebreak \url{http://pypi.python.org/pypi} \end{itemize} \end{frame} \begin{frame} \frametitle{Mailing lists} \begin{itemize} \item numpy-discussion \& Scipy-User: \linebreak \url{http://scipy.org/Mailing_Lists} \item matplotlib-users: \linebreak \url{http://sourceforge.net/mail/?group_id=80706} \end{itemize} \end{frame} \begin{frame} \frametitle{Summary} We have covered: \begin{itemize} \item Following and Resolving Error Messages. \item Exceptions. \item Handling exceptions \item Approach for Debugging. % \item Writting and running tests. \end{itemize} \end{frame} \end{document} %% \begin{frame}[fragile] %% \frametitle{\incqno} %% Consider a module called \lstinline+gcd.py+ looking like this: %% \begin{lstlisting} %% def gcd(a, b): %% ... %% if __name__ == '__main__': %% print gcd(10, 25) %% \end{lstlisting} %% If this module is imported, will it print the gcd of 10 and 25? %% \end{frame} %% \begin{frame}[fragile] %% \frametitle{\incqno} %% \begin{lstlisting} %% In [1]: print hello %% \end{lstlisting} %% Exactly what exception will you get if you run this on a fresh %% interpreter? %% \end{frame} %% \begin{frame} %% \frametitle{Testing} %% \begin{itemize} %% \item Writing tests is really simple! %% \item Using nose. %% \item Example! %% \end{itemize} %% \end{frame} % \section{Test Driven Approach} % \begin{frame} % \frametitle{Need for Testing!} % % \begin{itemize} % \item Quality % \item Regression % \item Documentation % \end{itemize} % %% \vspace*{0.25in} % %% \emphbar{It is to assure that section of code is working as it is supposed to work} % \end{frame} % % \begin{frame}[fragile] % \frametitle{Example} % \begin{block}{Problem Statement} % Write a function to check whether a given input % string is a palindrome. % \end{block} % \end{frame} % % \begin{frame}[fragile] % \frametitle{Function: palindrome.py} % \begin{lstlisting} % def is_palindrome(input_str): % return input_str == input_str[::-1] % \end{lstlisting} % \end{frame} % % \begin{frame}[fragile] % \frametitle{Test for the palindrome: palindrome.py} % \begin{lstlisting} % def test_function_normal_words(): % input = "noon" % assert is_palindrome(input) == True % % if __name__ == "main'': % test_function_normal_words() % \end{lstlisting} % \end{frame} % % \begin{frame}[fragile] % \frametitle{Running the tests.} % \begin{lstlisting} % $ nosetests palindrome.py % . % ---------------------------------------------- % Ran 1 test in 0.001s % % OK % \end{lstlisting} % \end{frame} % % \begin{frame}[fragile] % \frametitle{Exercise: Including new tests.} % \begin{lstlisting} % def test_function_ignore_cases_words(): % input = "Noon" % assert is_palindrome(input) == True % \end{lstlisting} % \vspace*{0.25in} % Check\\ % \PythonCode{$ nosetests palindrome.py} \\ % \begin{block}{Task} % Tweak the code to pass this test. % \end{block} % \end{frame} % % %\begin{frame}[fragile] % % \frametitle{Lets write some test!} % %\begin{lstlisting} % %#for form of equation y=mx+c % %#given m and c for two equation, % %#finding the intersection point. % %def intersect(m1,c1,m2,c2): % % x = (c2-c1)/(m1-m2) % % y = m1*x+c1 % % return (x,y) % %\end{lstlisting} % % % %Create a simple test for this % % % %function which will make it fail. % % % %\inctime{15} % %\end{frame} % % % % %% \begin{frame}[fragile] % %% \frametitle{Exercise} % %% Based on Euclid's algorithm: % %% \begin{center} % %% $gcd(a,b)=gcd(b,b\%a)$ % %% \end{center} % %% gcd function can be written as: % %% \begin{lstlisting} % %% def gcd(a, b): % %% if a%b == 0: return b % %% return gcd(b, a%b) % %% \end{lstlisting} % %% \vspace*{-0.15in} % %% \begin{block}{Task} % %% \begin{itemize} % %% \item Write at least % %% two tests for above mentioned function. % %% \item Write a non recursive implementation % %% of gcd(), and test it using already % %% written tests. % %% \end{itemize} % %% \end{block} % % %% \inctime{15} % %% \end{frame}