<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">\section{Functional programming}

\begin{frame}[fragile]
  \frametitle{List Comprehensions}
  \begin{itemize}
  \item A different style of Programming
  \item Functions `emulate' mathematical functions
  \item Output depends only on input arguments
  \item There is no `state' associated with the program
  \end{itemize}
\end{frame}

\begin{frame}[fragile]
  \frametitle{List Comprehensions}
  \begin{block}{}
    Given a list of weights of people, and we need to
    calculate the corresponding weights on the moon. Return a new
    list, with each of the values divided by 6.0. 
  \end{block}

  \begin{itemize}
  \item Solution using \texttt{for} loop is shown
  \end{itemize}
  \begin{lstlisting}
    weights = [30, 45.5, 78, 81, 55.5, 62.5]
    weights_moon = []
    for w in weights:
        weights_moon.append(w/6.0)
    print weights_moon
  \end{lstlisting}
\end{frame}

\begin{frame}[fragile]
  \frametitle{List Comprehensions \ldots}
  \begin{itemize}
  \item List comprehensions are compact and readable
  \end{itemize}
  \begin{lstlisting}
    [ w/6.0 for w in weights ]
  \end{lstlisting}
\end{frame}

\begin{frame}[fragile]
  \frametitle{List Comprehensions \ldots}
  \begin{itemize}
  \item Return the weight on moon, only if weight on earth &gt; 50
  \end{itemize}
  \begin{lstlisting}
    weights = [30, 45.5, 78, 81, 55.5, 62.5]
    weights_moon = []
    for w in weights:
        if w &gt; 50:
            weights_moon.append(w/6.0)

    print weights_moon
  \end{lstlisting}
  \begin{itemize}
  \item List comprehension that checks for a condition
  \end{itemize}
  \begin{lstlisting}
    [ w/6.0 for w in weights if w&gt;50 ]
  \end{lstlisting}
\end{frame}

\begin{frame}[fragile]
  \frametitle{List Comprehensions \ldots}
  \begin{itemize}
  \item if weight &gt; 50, return weight/6.0
  \item else, return weight*3.0
  \end{itemize}
  \begin{lstlisting}
    weights = [30, 45.5, 78, 81, 55.5, 62.5]
    weights_migrate = []
    for w in weights:
        if w &gt; 50:
            weights_migrate.append(w/6.0)
        else:
            weights_migrate.append(w * 3.0)

    print weights_migrate
  \end{lstlisting}
  \begin{itemize}
  \item This problem \alert{CANNOT} be solved using list
    comprehensions
  \item Try \texttt{map}
  \end{itemize}
\end{frame}

\begin{frame}[fragile]
  \frametitle{\texttt{map}}
  \begin{itemize}
  \item Takes a function and a sequence as arguments
  \item Calls function with each element of sequence as argument
  \item Returns a sequence with all the results as elements
  \item We solve the easier problem first, using \texttt{map}
  \end{itemize}

  \begin{lstlisting}
    def moonize(weight):
        return weight/6.0

    map(moonize, weights)
  \end{lstlisting}
\end{frame}

\begin{frame}[fragile]
  \frametitle{\texttt{map} \ldots}
  \begin{lstlisting}
    def migrate(weight):
        if weight &lt; 50:
            return weight*3.0
        else:
            return weight/6.0
  \end{lstlisting}

  \begin{itemize}
  \item \texttt{migrate} compares weight with 50 and returns the
    required value.
  \item We can now use \texttt{map}
  \end{itemize}
  \begin{lstlisting}
    map(migrate, weights)
  \end{lstlisting}
  \begin{itemize}
  \item Now, we wish to get away with the function definition
  \end{itemize}
\end{frame}

\begin{frame}[fragile]
  \frametitle{\texttt{lambda}}
  \begin{itemize}
  \item Allows function definition, anonymously
  \end{itemize}
  \begin{lstlisting}
    map(lambda x: x/6.0, weights)
  \end{lstlisting}
  \begin{itemize}
  \item \texttt{lambda} actually returns a function which we could in
    fact assign to a name and use later.
  \end{itemize}
  \begin{lstlisting}
    l_moonize = lambda x: x/6.0
    map(l_moonize, weights)
  \end{lstlisting}
  \begin{lstlisting}
    l_migrate = lambda x: x*3.0 if x &lt; 50 else x/6.0
  \end{lstlisting}
\end{frame}

\begin{frame}[fragile]
  \frametitle{\texttt{filter}}

  \begin{itemize}
  \item We avoided discussion of problem of returning new weights only
    when actual weight is more than 50. 
  \item \texttt{filter} can be used to filter out ``bad'' weights
  \item Later, we could use \texttt{map}
  \end{itemize}
  \begin{lstlisting}
    filter(lambda x: x &gt; 50, weights)
  \end{lstlisting}
  \begin{itemize}
  \item Takes a function and a sequence
  \item Returns a sequence, containing only those elements of the
    original sequence, for which the function returned \texttt{True}
  \end{itemize}
  \begin{lstlisting}
    map(lambda x: x/6.0, filter(lambda x: x &gt; 50, weights))
  \end{lstlisting}
\end{frame}

\begin{frame}[fragile]
  \frametitle{\texttt{reduce}}
  \begin{itemize}
  \item ``reduces'' a sequence
  \end{itemize}
  \begin{lstlisting}
    reduce(lambda x,y: x*y, [1, 2, 3, 4])
  \end{lstlisting}
  \begin{itemize}
  \item Takes function and sequence as arguments; the function should
    take two arguments
  \item Passes first two elements of sequence, and continues to move
    over the sequence, passing the output in the previous step and the
    current element as the arguments
  \item The function above essentially calculates $((1*2)*3)*4$ 
  \end{itemize}
\end{frame}

</pre></body></html>