%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Tutorial slides on Python.%% Author: Prabhu Ramachandran <prabhu at aero.iitb.ac.in>% 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<presentation>{ \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}<beamer> \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}<beamer> \frametitle{Outline} \tableofcontents[currentsection,currentsubsection] \end{frame}}\AtBeginSection[]{ \begin{frame}<beamer> \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}5456 \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 "<stdin>", 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 "<stdin>", line 1, in <module>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 "<stdin>", line 1, in <module>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 numexcept: 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 mymoduleIn []: mymodule.test()---------------------------------------------NameError Traceback (most recent call last)<ipython console> in <module>()mymodule.py in test() 1 def test():----> 2 print spamNameError: global name 'spam' is not definedIn []: %debug> mymodule.py(2)test() 0 print spamipdb> \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] += 1pie(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}