\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} In[]: def f(x): ....: return x*x ....: In[]: f(1) In[]: 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} In[]: def greet(): ....: print "Hello World!" ....: In[]: 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} In[]: def avg(a, b): ....: return (a + b)/2 ....: In[]: 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} In[]: def avg(a, b): """ avg takes two numbers as input and returns their average""" ....: return (a + b)/2 ....: In[]: avg? In[]: 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} In[]: 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 ....: In[]: circle(4) In[]: a, p = circle(6) In[]: print a In[]: 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} In[]: 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} In[]: 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} In[]: round(2.484) In[]: round(2.484, 2) In[]: s.split() # split on spaces In[]: s.split(';') # split on ';' In[]: range(10) # returns numbers from 0 to 9 In[]: range(1, 10) # returns numbers from 1 to 9 In[]: range(1, 10, 2) # returns odd numbers from 1 to 9 \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Default arguments \ldots} \begin{lstlisting} In[]: def welcome(greet, name="World"): ....: print greet, name ....: In[]: welcome("Hi", "Guido") In[]: 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} In[]: def welcome(name="World", greet): ....: print greet, name ....: \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Keyword Arguments} \begin{lstlisting} In[]: def welcome(greet, name="World"): ....: print greet, name ....: In[]: welcome("Hello", "James") In[]: welcome("Hi", name="Guido") In[]: welcome(name="Guido", greet="Hey") In[]: 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} In[]: def change(q): ....: q = 10 ....: print q ....: In[]: change(1) In[]: print q \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Variables inside function are local} \begin{lstlisting} In[]: n = 5 In[]: def change(): ....: n = 10 ....: print n ....: In[]: change() In[]: print n \end{lstlisting} \begin{itemize} \item Use the \texttt{global} statement to assign to global variables \end{itemize} \begin{lstlisting} In[]: def change(): ....: global n ....: n = 10 ....: print n ....: In[]: change() In[]: print n \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{global} \begin{itemize} \item Use the \texttt{global} statement to assign to global variables \end{itemize} \begin{lstlisting} In[]: def change(): ....: global n ....: n = 10 ....: print n ....: In[]: change() In[]: 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} In[]: name = ['Mr.', 'Steve', 'Gosling'] In[]: def change_name(): ....: name[0] = 'Dr.' ....: In[]: change_name() In[]: print name \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Passing Arguments \ldots} \begin{lstlisting} In[]: n = 5 In[]: def change(n): ....: n = 10 ....: print "n = %s inside change " %n ....: In[]: change(n) In[]: print n \end{lstlisting} \begin{lstlisting} In[]: name = ['Mr.', 'Steve', 'Gosling'] In[]: def change_name(n): ....: n[0] = 'Dr.' ....: print "n = %s inside change_name" %n ....: In[]: change_name(name) In[]: print name \end{lstlisting} \end{frame}