day2/session4.tex
changeset 263 8a4a1e5aec85
parent 256 a06196a05043
child 288 c4e25269a86c
equal deleted inserted replaced
262:9664eddee075 263:8a4a1e5aec85
    93 
    93 
    94 
    94 
    95 
    95 
    96 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    96 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    97 % Title page
    97 % Title page
    98 \title[]{Debugging and \\Test Driven Approach}
    98 \title[Python Development]{Python Development}
    99 
    99 
   100 \author[FOSSEE] {FOSSEE}
   100 \author[FOSSEE] {FOSSEE}
   101 
   101 
   102 \institute[IIT Bombay] {Department of Aerospace Engineering\\IIT Bombay}
   102 \institute[IIT Bombay] {Department of Aerospace Engineering\\IIT Bombay}
   103 \date[] {11, October 2009}
   103 \date[] {1 November, 2009\\Day 2, Session 3}
   104 \date[] % (optional)
       
   105 
       
   106 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   104 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   107 
   105 
   108 %\pgfdeclareimage[height=0.75cm]{iitblogo}{iitblogo}
   106 %\pgfdeclareimage[height=0.75cm]{iitblogo}{iitblogo}
   109 %\logo{\pgfuseimage{iitblogo}}
   107 %\logo{\pgfuseimage{iitblogo}}
   110 
   108 
   140 
   138 
   141 \begin{frame}
   139 \begin{frame}
   142   \maketitle
   140   \maketitle
   143 \end{frame}
   141 \end{frame}
   144 
   142 
       
   143 \section{Tests: Getting started}
       
   144 \begin{frame}[fragile] 
       
   145   \frametitle{gcd revisited!}
       
   146   \begin{itemize}
       
   147   \item Open gcd.py
       
   148   \end{itemize}  
       
   149 \begin{lstlisting}
       
   150     def gcd(a, b):
       
   151         if a % b == 0: 
       
   152             return b
       
   153         return gcd(b, a%b)
       
   154 
       
   155     print gcd(15, 65)
       
   156     print gcd(16, 76)
       
   157 \end{lstlisting}
       
   158   \begin{itemize}
       
   159   \item python gcd.py
       
   160   \end{itemize}
       
   161 \end{frame}
       
   162 
       
   163 \begin{frame}[fragile] 
       
   164   \frametitle{Find lcm using our gcd module}
       
   165   \begin{itemize}
       
   166   \item Open lcm.py  
       
   167   \item $lcm = \frac{a*b}{gcd(a,b)}$
       
   168   \end{itemize}  
       
   169 \begin{lstlisting}
       
   170     from gcd import gcd    
       
   171     def lcm(a, b):
       
   172         return (a * b) / gcd(a, b)
       
   173     
       
   174     print lcm(14, 56)
       
   175 \end{lstlisting}
       
   176   \begin{itemize}
       
   177   \item python lcm.py
       
   178   \end{itemize}
       
   179   \begin{lstlisting}
       
   180 5
       
   181 4
       
   182 56
       
   183   \end{lstlisting}    
       
   184 \end{frame}
       
   185 
       
   186 \begin{frame}[fragile] 
       
   187   \frametitle{Writing stand-alone module}  
       
   188 Edit gcd.py file to:
       
   189 \begin{lstlisting}
       
   190     def gcd(a, b):
       
   191         if a % b == 0: 
       
   192             return b
       
   193         return gcd(b, a%b)
       
   194 
       
   195     if __name__ == "__main__":        
       
   196         print gcd(15, 65)
       
   197         print gcd(16, 76)
       
   198 \end{lstlisting}
       
   199   \begin{itemize}
       
   200   \item python gcd.py
       
   201   \item python lcm.py
       
   202   \end{itemize}
       
   203 \end{frame}
       
   204 
       
   205 \begin{frame}[fragile]
       
   206   \frametitle{More use of main}
       
   207   For automating tests.
       
   208   \begin{lstlisting}
       
   209 if __name__ == '__main__':
       
   210     for line in open('numbers.txt'):
       
   211         numbers = line.split()
       
   212         x = int(numbers[0])
       
   213         y = int(numbers[1])
       
   214         result = (int(numbers[2]))
       
   215         assert gcd(x, y) == result
       
   216   \end{lstlisting}  
       
   217 \end{frame}
       
   218 
       
   219 \section{Coding Style}
       
   220 \begin{frame}{Readability and Consistency}
       
   221     \begin{itemize}
       
   222         \item Readability Counts!\\Code is read more often than its written.
       
   223         \item Consistency!
       
   224         \item Know when to be inconsistent.
       
   225       \end{itemize}
       
   226 \end{frame}
       
   227 
       
   228 \begin{frame}[fragile] \frametitle{A question of good style}
       
   229   \begin{lstlisting}
       
   230     amount = 12.68
       
   231     denom = 0.05
       
   232     nCoins = round(amount/denom)
       
   233     rAmount = nCoins * denom
       
   234   \end{lstlisting}
       
   235   \pause
       
   236   \begin{block}{Style Rule \#1}
       
   237     Naming is 80\% of programming
       
   238   \end{block}
       
   239 \end{frame}
       
   240 
       
   241 \begin{frame}[fragile]
       
   242   \frametitle{Code Layout}
       
   243   \begin{itemize}
       
   244         \item Indentation
       
   245         \item Tabs or Spaces??
       
   246         \item Maximum Line Length
       
   247         \item Blank Lines
       
   248         \item Encodings
       
   249    \end{itemize}
       
   250 \end{frame}
       
   251 
       
   252 \begin{frame}{Whitespaces in Expressions}
       
   253   \begin{itemize}
       
   254         \item When to use extraneous whitespaces??
       
   255         \item When to avoid extra whitespaces??
       
   256         \item Use one statement per line
       
   257    \end{itemize}
       
   258 \end{frame}
       
   259 
       
   260 \begin{frame}{Comments}
       
   261   \begin{itemize}
       
   262         \item No comments better than contradicting comments
       
   263         \item Block comments
       
   264         \item Inline comments
       
   265    \end{itemize}
       
   266 \end{frame}
       
   267 
       
   268 \begin{frame}{Docstrings}
       
   269   \begin{itemize}
       
   270         \item When to write docstrings?
       
   271         \item Ending the docstrings
       
   272         \item One liner docstrings
       
   273    \end{itemize}
       
   274 More information at PEP8: http://www.python.org/dev/peps/pep-0008/
       
   275 \inctime{5}
       
   276 \end{frame}
   145 
   277 
   146 \section{Debugging}
   278 \section{Debugging}
   147 \subsection{Errors and Exceptions}
   279 \subsection{Errors and Exceptions}
   148 \begin{frame}[fragile]
   280 \begin{frame}[fragile]
   149  \frametitle{Errors}
   281  \frametitle{Errors}
   150  \begin{lstlisting}
   282  \begin{lstlisting}
   151 >>> while True print 'Hello world'
   283 In []: while True print 'Hello world'
   152  \end{lstlisting}
   284  \end{lstlisting}
   153 \pause
   285 \pause
   154   \begin{lstlisting}
   286   \begin{lstlisting}
   155   File "<stdin>", line 1, in ?
   287   File "<stdin>", line 1, in ?
   156     while True print 'Hello world'
   288     while True print 'Hello world'
   160 \end{frame}
   292 \end{frame}
   161 
   293 
   162 \begin{frame}[fragile]
   294 \begin{frame}[fragile]
   163  \frametitle{Exceptions}
   295  \frametitle{Exceptions}
   164  \begin{lstlisting}
   296  \begin{lstlisting}
   165 >>> print spam
   297 In []: print spam
   166 \end{lstlisting}
   298 \end{lstlisting}
   167 \pause
   299 \pause
   168 \begin{lstlisting}
   300 \begin{lstlisting}
   169 Traceback (most recent call last):
   301 Traceback (most recent call last):
   170   File "<stdin>", line 1, in <module>
   302   File "<stdin>", line 1, in <module>
   173 \end{frame}
   305 \end{frame}
   174 
   306 
   175 \begin{frame}[fragile]
   307 \begin{frame}[fragile]
   176  \frametitle{Exceptions}
   308  \frametitle{Exceptions}
   177  \begin{lstlisting}
   309  \begin{lstlisting}
   178 >>> 1 / 0
   310 In []: 1 / 0
   179 \end{lstlisting}
   311 \end{lstlisting}
   180 \pause
   312 \pause
   181 \begin{lstlisting}
   313 \begin{lstlisting}
   182 Traceback (most recent call last):
   314 Traceback (most recent call last):
   183   File "<stdin>", line 1, in <module>
   315   File "<stdin>", line 1, in <module>
   184 ZeroDivisionError: integer division 
   316 ZeroDivisionError: integer division 
   185 or modulo by zero
   317 or modulo by zero
   186 \end{lstlisting}
   318 \end{lstlisting}
   187 \end{frame}
   319 \end{frame}
   188 
   320 
       
   321 \begin{frame}[fragile]
       
   322   \frametitle{Handling Exceptions}
       
   323   Python uses \typ{try} and \typ{except} clause.
       
   324   %%Revisiting the raw\_input
       
   325   \begin{lstlisting}
       
   326 a = raw_input('Enter number(Q to quit):')
       
   327 try:
       
   328     num = int(a)
       
   329     print num
       
   330 except:
       
   331     if a == 'Q':
       
   332         print 'Exiting...'
       
   333     else:
       
   334         print 'Wrong input!'      
       
   335   \end{lstlisting}
       
   336   
       
   337   
       
   338 \end{frame}
       
   339 
       
   340 %% \begin{frame}[fragile]
       
   341 %%   \frametitle{Solving it with \typ{try} and \typ{except}}
       
   342 %% \vspace{-0.2in}
       
   343 %%   \begin{lstlisting}
       
   344 %% highest = 0
       
   345 %% for record in open('sslc1.txt'):
       
   346 %%     fields = record.split(';')
       
   347 %%     try:
       
   348 %%         total = 0
       
   349 %%         for score_str in fields[3:8]:
       
   350 %%             score = int(score_str)
       
   351 %%             total += score
       
   352 %%         if total > highest:
       
   353 %%             highest = total
       
   354 %%     except:        
       
   355 %%         pass
       
   356 %% print highest
       
   357 %%   \end{lstlisting}
       
   358 %% \end{frame}
   189 \subsection{Strategy}
   359 \subsection{Strategy}
   190 \begin{frame}[fragile]
   360 \begin{frame}[fragile]
   191     \frametitle{Debugging effectively}
   361     \frametitle{Debugging effectively}
   192     \begin{itemize}
   362     \begin{itemize}
   193         \item \typ{print} based strategy
   363         \item \typ{print} based strategy
   207 
   377 
   208 \begin{frame}[fragile]
   378 \begin{frame}[fragile]
   209 \frametitle{Debugging in IPython}
   379 \frametitle{Debugging in IPython}
   210 \small
   380 \small
   211 \begin{lstlisting}
   381 \begin{lstlisting}
   212 In [1]: import mymodule
   382 In []: import mymodule
   213 In [2]: mymodule.test()
   383 In []: mymodule.test()
   214 ---------------------------------------------
   384 ---------------------------------------------
   215 NameError   Traceback (most recent call last)
   385 NameError   Traceback (most recent call last)
   216 <ipython console> in <module>()
   386 <ipython console> in <module>()
   217 mymodule.py in test()
   387 mymodule.py in test()
   218       1 def test():
   388       1 def test():
   219 ----> 2     print spam
   389 ----> 2     print spam
   220 NameError: global name 'spam' is not defined
   390 NameError: global name 'spam' is not defined
   221 
   391 
   222 In [3]: %debug
   392 In []: %debug
   223 > mymodule.py(2)test()
   393 > mymodule.py(2)test()
   224       0     print spam
   394       0     print spam
   225 ipdb> 
   395 ipdb> 
   226 \end{lstlisting}
   396 \end{lstlisting}
   227 \inctime{15} 
   397 \inctime{15} 
   230 \subsection{Exercise}
   400 \subsection{Exercise}
   231 \begin{frame}[fragile]
   401 \begin{frame}[fragile]
   232 \frametitle{Debugging: Exercise}
   402 \frametitle{Debugging: Exercise}
   233 \small
   403 \small
   234 \begin{lstlisting}
   404 \begin{lstlisting}
   235 import keyword
   405 science = {}
   236 f = open('/path/to/file')
   406 
   237 
   407 for record in open('sslc1.txt'):
   238 freq = {}
   408     fields = record.split(';')
   239 for line in f:
   409     region_code = fields[0].strip()
   240     words = line.split()
   410 
   241     for word in words:
   411     score_str = fields[6].strip()
   242         key = word.strip(',.!;?()[]: ')
   412     score = int(score_str) if score_str != 'AA' 
   243         if keyword.iskeyword(key):
   413                            else 0
   244             value = freq[key]
   414 
   245             freq[key] = value + 1
   415     if score > 90:
   246 
   416         science[region_code] += 1
   247 print freq
   417 
       
   418 pie(science.values(), labels=science.keys())
       
   419 savefig('science.png')
   248 \end{lstlisting}
   420 \end{lstlisting}
   249 \inctime{10}
   421 \inctime{10}
   250 \end{frame}
   422 \end{frame}
   251 
   423 
   252 %% \begin{frame}
   424 %% \begin{frame}
   261 %%     \end{itemize}
   433 %%     \end{itemize}
   262 %% \end{frame}
   434 %% \end{frame}
   263 
   435 
   264 \section{Test Driven Approach}
   436 \section{Test Driven Approach}
   265 \begin{frame}
   437 \begin{frame}
   266     \frametitle{Need of Testing!}
   438     \frametitle{Need for Testing!}
   267    
   439    
   268     \begin{itemize}
   440     \begin{itemize}
   269         \item Quality
   441         \item Quality
   270         \item Regression
   442         \item Regression
   271         \item Documentation
   443         \item Documentation
   291 \end{frame}
   463 \end{frame}
   292 
   464 
   293 \begin{frame}[fragile]
   465 \begin{frame}[fragile]
   294     \frametitle{Test for the palindrome: palindrome.py}
   466     \frametitle{Test for the palindrome: palindrome.py}
   295 \begin{lstlisting}    
   467 \begin{lstlisting}    
   296 from plaindrome import is_palindrome
       
   297 def test_function_normal_words():
   468 def test_function_normal_words():
   298   input = "noon"
   469   input = "noon"
   299   assert is_palindrome(input) == True
   470   assert is_palindrome(input) == True
       
   471 
       
   472 if __name__ == "main'':
       
   473   test_function_normal_words()
   300 \end{lstlisting}    
   474 \end{lstlisting}    
   301 \end{frame}
   475 \end{frame}
   302 
   476 
   303 \begin{frame}[fragile]
   477 \begin{frame}[fragile]
   304     \frametitle{Running the tests.}
   478     \frametitle{Running the tests.}
   305 \begin{lstlisting}    
   479 \begin{lstlisting}    
   306 $ nosetests test.py 
   480 $ nosetests palindrome.py 
   307 .
   481 .
   308 ----------------------------------------------
   482 ----------------------------------------------
   309 Ran 1 test in 0.001s
   483 Ran 1 test in 0.001s
   310 
   484 
   311 OK
   485 OK
   319   input = "Noon"
   493   input = "Noon"
   320   assert is_palindrome(input) == True
   494   assert is_palindrome(input) == True
   321 \end{lstlisting}
   495 \end{lstlisting}
   322      \vspace*{0.25in}
   496      \vspace*{0.25in}
   323      Check\\
   497      Check\\
   324      \PythonCode{$ nosetests test.py} \\
   498      \PythonCode{$ nosetests palindrome.py} \\
   325      \begin{block}{Task}
   499      \begin{block}{Task}
   326      Tweak the code to pass this test.
   500      Tweak the code to pass this test.
   327      \end{block}
   501      \end{block}
   328 \end{frame}
   502 \end{frame}
   329 
   503 
   345 %
   519 %
   346 %\inctime{15} 
   520 %\inctime{15} 
   347 %\end{frame}
   521 %\end{frame}
   348 %
   522 %
   349 
   523 
   350 \begin{frame}[fragile]
   524 %% \begin{frame}[fragile]
   351     \frametitle{Exercise}
   525 %%     \frametitle{Exercise}
   352     Based on Euclid's algorithm:
   526 %%     Based on Euclid's algorithm:
   353     \begin{center}
   527 %%     \begin{center}
   354     $gcd(a,b)=gcd(b,b\%a)$
   528 %%     $gcd(a,b)=gcd(b,b\%a)$
   355     \end{center}
   529 %%     \end{center}
   356     gcd function can be written as:
   530 %%     gcd function can be written as:
   357     \begin{lstlisting}
   531 %%     \begin{lstlisting}
   358     def gcd(a, b):
   532 %%     def gcd(a, b):
   359       if a%b == 0: return b
   533 %%       if a%b == 0: return b
   360       return gcd(b, a%b)
   534 %%       return gcd(b, a%b)
   361     \end{lstlisting}
   535 %%     \end{lstlisting}
   362     \vspace*{-0.15in}
   536 %%     \vspace*{-0.15in}
   363     \begin{block}{Task}
   537 %%     \begin{block}{Task}
   364       \begin{itemize}
   538 %%       \begin{itemize}
   365       \item Write at least 
   539 %%       \item Write at least 
   366         two tests for above mentioned function.
   540 %%         two tests for above mentioned function.
   367       \item Write a non recursive implementation
   541 %%       \item Write a non recursive implementation
   368       of gcd(), and test it using already 
   542 %%       of gcd(), and test it using already 
   369       written tests.
   543 %%       written tests.
   370       \end{itemize}
   544 %%       \end{itemize}
   371     \end{block}
   545 %%     \end{block}
   372     
   546     
   373 \inctime{15} 
   547 %% \inctime{15} 
   374 \end{frame}
   548 %% \end{frame}
   375 
   549 
   376 \begin{frame}
   550 \begin{frame}
   377   \frametitle{We have learned}
   551   \frametitle{Summary}
       
   552 We have coverd:
   378   \begin{itemize}
   553   \begin{itemize}
   379   \item Following and Resolving Error Messages.
   554   \item Following and Resolving Error Messages.
   380   \item Exceptions.
   555   \item Exceptions.
       
   556   \item Handling exceptions
   381   \item Approach for Debugging.
   557   \item Approach for Debugging.
   382   \item Writting and running tests.
   558   \item Writting and running tests.
   383   \end{itemize}
   559   \end{itemize}
   384 \end{frame}
   560 \end{frame}
   385 
   561