%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %Tutorial slides on Python. % % Author: FOSSEE % Copyright (c) 2017, FOSSEE, IIT Bombay %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \documentclass[14pt,compress]{beamer} \input{macros.tex} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Title page \title[Functions]{Python language: Functions} \author[FOSSEE Team] {The FOSSEE Group} \institute[IIT Bombay] {Department of Aerospace Engineering\\IIT Bombay} \date[] {Mumbai, India} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % DOCUMENT STARTS \begin{document} \begin{frame} \titlepage \end{frame} \section{Functions} \begin{frame}[fragile] \frametitle{Functions for abstraction} \begin{itemize} \item Reduce duplication of code \item Fewer lines of code: lesser scope for bugs \item Re-usability of code \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 In Python: \end{itemize} \begin{lstlisting} In []: def f(x): .....: return x*x .....: In []: f(1) In []: f(1+2j) \end{lstlisting} \begin{itemize} \item \typ{def} is a keyword \item \typ{f} is the name of the function \item \typ{x} the parameter of the function \item \typ{return} is a keyword \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 It returns nothing explicitly \item Implicitly, Python returns \typ{None} \item \typ{None} is also a built-in, immutable data type \end{itemize} \end{frame} \begin{frame}[fragile] \frametitle{Defining functions \ldots} \begin{lstlisting} In []: def avg(a, b): .....: return (a + b)/2 .....: In []: avg(12, 10) \end{lstlisting} \begin{itemize} \item \typ{avg} takes two arguments \item Returns one value \end{itemize} \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): """Returns the average of two given numbers.""" 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} def circle(r): """Returns area and perimeter of circle given radius r""" pi = 3.14 area = pi * r * r perimeter = 2 * pi * r return area, perimeter In []: circle(4) In []: a, p = circle(6) \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) In []: range(1, 10) In []: range(1, 10, 2) \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} \end{frame} \begin{frame}[fragile] \frametitle{Default arguments \ldots} \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,plain] \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} Cannot have non-keyword args after kwargs \end{frame} \begin{frame}[fragile] \frametitle{Built-in functions} \begin{itemize} \item Variety of built-in functions are available \item \typ{abs, any, all, len, max, min} \item \typ{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} \end{frame} \begin{frame}[fragile] \frametitle{If not defined, look in parent scope} \begin{lstlisting} In []: n = 5 In []: def scope(): .....: print(n) .....: In []: scope() \end{lstlisting} \begin{itemize} \item Note that \typ{n} was not defined in \typ{scope} \item It looked for the variable in previous scope \item See: \url{pythontutor.com} \end{itemize} \end{frame} \begin{frame}[fragile] \frametitle{\texttt{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, "inside change") .....: In []: change(n) In []: print(n) \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Passing Arguments \ldots} \begin{lstlisting} In []: name = ['Mr.', 'Steve','Gosling'] In []: def change_name(x): .....: x[0] = 'Dr.' .....: print(x, 'in change') .....: In []: change_name(name) In []: print(name) \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Passing Arguments \ldots} \begin{lstlisting} In []: name = ['Mr.', 'Steve','Gosling'] In []: def change_name(x): .....: x = [1,2,3] .....: print(x, 'in change') .....: In []: change_name(name) In []: print(name) \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Passing Arguments \ldots} \begin{lstlisting} In []: name = ['Mr.', 'Steve','Gosling'] In []: def change_name(x): .....: x[:] = [1,2,3] .....: print(x, 'in change') .....: In []: change_name(name) In []: print(name) \end{lstlisting} \end{frame} \subsection{Examples} \begin{frame}[fragile] \frametitle{Functions: example} \begin{lstlisting} def signum( r ): """returns 0 if r is zero -1 if r is negative +1 if r is positive""" if r < 0: return -1 elif r > 0: return 1 else: return 0 \end{lstlisting} \emphbar{Note docstrings} \end{frame} \begin{frame}[fragile] \frametitle {What does this function do?} \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 does this function do?} \begin{lstlisting} def what(n): i = 1 while i * i < n: i += 1 return i * i == n, i \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle {What does this function do?} \begin{lstlisting} def what(x, n): if n < 0: n = -n x = 1.0 / x z = 1.0 while n > 0: if n % 2 == 1: z *= x x *= x n //= 2 return z \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Nested functions} \begin{lstlisting} def f(x): def g(x): return x+1 return g(x)**2 \end{lstlisting} \end{frame} \begin{frame}[fragile] \frametitle{Nested functions: returning functions} \begin{lstlisting} def f(): def g(x): return x+1 return g In []: func = f() In []: func(1) In []: f()(1) # Also valid! \end{lstlisting} \end{frame} \begin{frame} \frametitle{Summary} \begin{itemize} \item Defining functions \item Taking either 0, or more arguments \item Returning \typ{None} implicitly or any number of values \item Default and keyword arguments \item Variable scope, \typ{global} \item Mutable and immutable arguments \item Nested functions \end{itemize} \end{frame} \end{document}