diff options
Diffstat (limited to 'basic_python/functions.tex')
-rw-r--r-- | basic_python/functions.tex | 435 |
1 files changed, 435 insertions, 0 deletions
diff --git a/basic_python/functions.tex b/basic_python/functions.tex new file mode 100644 index 0000000..7213fea --- /dev/null +++ b/basic_python/functions.tex @@ -0,0 +1,435 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%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} |