\section{Functions} \begin{frame}[fragile] \frametitle{Abstracting} \begin{itemize} \item Reduce duplication of code \item Fewer lines of code and hence lesser scope for bugs \item Re-usability of code, that's already been written \item Use functions written by others, without exactly knowing how they do, what they are doing \item \alert{Enter Functions!} \end{itemize} \end{frame} \begin{frame}[fragile] \frametitle{Defining functions} \begin{itemize} \item Consider the function \texttt{f(x) = x\textasciicircum{}2} \item Let's write a Python function, equivalent to this \end{itemize} \begin{lstlisting} def f(x): return x*x f(1) f(2) \end{lstlisting} \begin{itemize} \item \texttt{def} is a keyword \item \texttt{f} is the name of the function \item \texttt{x} the parameter of the function \item \texttt{return} is a keyword; specifies what should be returned \end{itemize} \end{frame} \begin{frame}[fragile] \frametitle{Defining functions \ldots} \begin{lstlisting} def greet(): print "Hello World!" greet() \end{lstlisting} \begin{itemize} \item \texttt{greet} is a function that takes no arguments \item Also, it is not returning anything explicitly \item But implicitly, Python returns \texttt{None} \end{itemize} \begin{lstlisting} def avg(a, b): return (a + b)/2 avg(12, 10) \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Doc-strings} \begin{itemize} \item It's highly recommended that all functions have documentation \item We write a doc-string along with the function definition \end{itemize} \begin{lstlisting} def avg(a, b): """ avg takes two numbers as input and returns their average""" return (a + b)/2 avg? greet? \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Returning multiple values} \begin{itemize} \item Return area and perimeter of circle, given radius \item Function needs to return two values \end{itemize} \begin{lstlisting} def circle(r): """returns area and perimeter of a circle given, the radius r""" pi = 3.14 area = pi * r * r perimeter = 2 * pi * r return area, perimeter circle(4) a, p = circle(6) print a print p \end{lstlisting} \begin{itemize} \item Any number of values can be returned \end{itemize} \end{frame} \begin{frame}[fragile] \frametitle{What? -- 1} \begin{lstlisting} def what( n ): if n < 0: n = -n while n > 0: if n % 2 == 1: return False n /= 10 return True \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{What? -- 2} \begin{lstlisting} def what( n ): i = 1 while i * i < n: i += 1 return i * i == n, i \end{lstlisting} \end{frame} \subsection*{Default \& Keyword Arguments} \begin{frame}[fragile] \frametitle{Default arguments} \begin{lstlisting} round(2.484) round(2.484, 2) s.split() # split on spaces s.split(';') # split on ';' range(10) # returns numbers from 0 to 9 range(1, 10) # returns numbers from 1 to 9 range(1, 10, 2) # returns odd numbers from 1 to 9 \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Default arguments \ldots} \begin{lstlisting} def welcome(greet, name="World"): print greet, name welcome("Hi", "Guido") welcome("Hello") \end{lstlisting} \begin{itemize} \item Arguments with default values, should be placed at the end \item The following definition is \alert{WRONG} \end{itemize} \begin{lstlisting} def welcome(name="World", greet): print greet, name \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Keyword Arguments} \begin{lstlisting} def welcome(greet, name="World"): print greet, name welcome("Hello", "James") welcome("Hi", name="Guido") welcome(name="Guido", greet="Hey") welcome(name="Guido", "Hey") \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Built-in functions} \begin{itemize} \item Variety of built-in functions are available \item \texttt{abs, any, all, len, max, min} \item \texttt{pow, range, sum, type} \item Refer here: \url{http://docs.python.org/library/functions.html} \end{itemize} \end{frame} \subsection*{Variable Scope} \begin{frame}[fragile] \frametitle{Arguments are local} \begin{lstlisting} def change(q): q = 10 print q change(1) print q \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Variables inside function are local} \begin{lstlisting} n = 5 def change(): n = 10 print n change() print n \end{lstlisting} \begin{itemize} \item Use the \texttt{global} statement to assign to global variables \end{itemize} \begin{lstlisting} def change(): global n n = 10 print n change() print n \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Mutable variables} \begin{itemize} \item Behavior is different when assigning to a list element/slice \item Python looks up for the name, from innermost scope outwards, until the name is found \end{itemize} \begin{lstlisting} name = ['Mr.', 'Steve', 'Gosling'] def change_name(): name[0] = 'Dr.' change_name() print name \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Passing Arguments \ldots} \begin{lstlisting} n = 5 def change(n): n = 10 print "n = %s inside change " %n change(n) print n \end{lstlisting} \begin{lstlisting} name = ['Mr.', 'Steve', 'Gosling'] def change_name(n): n[0] = 'Dr.' print "n = %s inside change_name" %n change_name(n) print name \end{lstlisting} \end{frame}