wsheets/wsh02.tex
changeset 447 f51e593903ac
parent 445 b73e7ce91c10
equal deleted inserted replaced
446:99dcfdf5aed8 447:f51e593903ac
    29 
    29 
    30 
    30 
    31 
    31 
    32 \subsection*{Task 1 (Options)}
    32 \subsection*{Task 1 (Options)}
    33 
    33 
    34 Get familiar with constructing strings and printing strings
    34 Get familiar with the return value of functions that can
    35 (i.e.~\texttt{println}, \texttt{mkString}, \texttt{toString}, \ldots)
    35 ``go wrong'':
    36 
    36 
    37 \begin{lstlisting}[numbers=none]
    37 \begin{lstlisting}[numbers=none]
    38 scala> List(7,2,3,4,5,6).find(_ < 4)
    38 scala> List(7,2,3,4,5,6).find(_ < 4)
    39 scala> List(5,6,7,8,9).find(_ < 4)
    39 scala> List(5,6,7,8,9).find(_ < 4)
    40 scala> 
    40 scala> List(5,6,7,8,9).min
       
    41 scala> List(5,6,7,8,9).minOption
       
    42 scala> List[Int]().minOption
    41 \end{lstlisting}
    43 \end{lstlisting}
    42 
    44 
    43 \subsection*{Task 2 (URLs / Files)}
    45 \noindent
       
    46 Note that there needs to be a type-annotation for \texttt{List()} otherwise
       
    47 Scala will not know which \texttt{min}-version it should use. 
    44 
    48 
    45 ALso Try
    49 \subsection*{Task 2 (Try)}
       
    50 
       
    51 The Scala-Idiom \texttt{Try-getOrElse} allows you to conveniently
       
    52 deal with failure cases.
    46 
    53 
    47 \begin{lstlisting}[numbers=none]
    54 \begin{lstlisting}[numbers=none]
    48 scala> 
    55 scala> Try(Some(List(5,6,7,8,9).min)).getOrElse(None)
    49 scala> 
    56 scala> Try(Some(List[Int]().min)).getOrElse(None)
    50 scala> 
       
    51 \end{lstlisting}
    57 \end{lstlisting}
    52 
    58 
    53 \subsection*{Task 3 (Higher-Order Functions)}
    59 \noindent
       
    60 Note that \texttt{Try} needs the library \texttt{scala.util.\_} to be
       
    61 imported. 
    54 
    62 
    55 Make sure you understand if-conditions in Scala: They are
       
    56 \emph{expressions}, meaning they need to calculate a result. For
       
    57 example an \texttt{if} without an else-branch is nearly always
       
    58 \emph{not} what you intend to write (because you are not meant to
       
    59 change any ``state'' outside the expression). Also, remember the quirks
       
    60 in Scala with if-conditions needing parentheses and there is no
       
    61 \texttt{then}-keyword.
       
    62 
    63 
    63 \begin{lstlisting}[numbers=none]
    64 \begin{lstlisting}[numbers=none]
    64 scala> val s1 = "foo"
    65 def safe_div(x: Int, y: Int) : Option[Int] = 
    65 scala> val s2 = "bar"
    66   Try(Some(x / y)).getOrElse(None)
    66 scala  val s3 = "foobar"
       
    67 scala> if (s1 == s2) print("equal") else print("unequal")
       
    68 scala> if (s1 ++ s2 == s3) print("equal") else print("unequal")
       
    69 \end{lstlisting}
    67 \end{lstlisting}
    70 
    68 
    71 \subsection*{Task 4 (Maps)}
    69 \subsection*{Task 3 (URLs / Files)}
    72 
    70 
    73 Write \texttt{for}-comprehensions that enumerate all triples containing the numbers 1 - 5. That is,
    71 For simple tasks such as reading webpages and files, Scala provides
    74 print the list
    72 convenient functions \texttt{Source.fromURL} and \texttt{Source.fromFile}.
       
    73 To try them out, you need to import \texttt{io.Source}.
    75 
    74 
    76 \[
    75 \begin{lstlisting}[numbers=none]
    77 \texttt{(1,1,1)}, \texttt{(2,1,1)}, \texttt{(3,1,1)} \;\ldots\; \texttt{(5,5,5)}
    76 scala> Source.fromURL(my_url)("ISO-8859-1").mkString
    78 \]
    77 scala> Source.fromFile(my_file)("ISO-8859-1").mkString
       
    78 \end{lstlisting}
    79 
    79 
    80 \noindent
    80 \noindent
    81 Modify the \texttt{for}-comprehensions such that only triples are
    81 These functions return an iterator, which can be transformed into a String
    82 printed where the sum is divisible by 3.  Then sort the list according
    82 using \texttt{mkString}. The second argument fixes the character encoding
    83 to the middle element (for this use \texttt{sortBy}).
    83 and should not be omitted. If you are interested in the individual lines
    84 
    84 in the file, for example, you can use
    85 \subsection*{Task 5 (Pattern-Matching)}
       
    86 
       
    87 \subsection*{Task 6 (Web-Crawler)}
       
    88 
       
    89 Write a pretty print function for lists of integers which
       
    90 ``condenses'' elements in the list, meaning if there is a number
       
    91 several times in a row, then print out \mbox{\texttt{n x e}}, where
       
    92 \texttt{n} is the number of repetitions and \texttt{e} is the
       
    93 number. For example
       
    94 
    85 
    95 \begin{lstlisting}[numbers=none]
    86 \begin{lstlisting}[numbers=none]
    96   List(1,1,1,2,3,3)    =>   List(3 x 1, 2, 2 x 3)
    87 Source.fromFile(my_file)("ISO-8859-1")
    97   List(1,2,3,4,4,4)    =>   List(1, 2, 3, 3 x 4)
    88                             .getLines().toList
    98   List(1,1,1,1,1,1)    =>   List(6 x 1)
       
    99   List(1,1,1,2,1,1)    =>   List(3 x 1, 2, 2 x 1)
       
   100 \end{lstlisting}
    89 \end{lstlisting}
   101 
    90 
   102 You might like to define a separate function that first counts the occurences
    91 \noindent
   103 for each element and returns a list of (Int, Int)-pairs .
    92 If you are after proper error-handling, then you can use Scala's options
       
    93 as follows
       
    94 
       
    95 \begin{lstlisting}[numbers=none]
       
    96 Try(Some(Source.fromFile("test.txt")("ISO-8859-1")
       
    97                           .mkString)).getOrElse(None)
       
    98 \end{lstlisting}  
       
    99 
       
   100 This can also be written slightly shorter as
       
   101 
       
   102 \begin{lstlisting}[numbers=none]
       
   103 Try(Source.fromFile("test.txt")("ISO-8859-1")
       
   104                           .mkString).toOption
       
   105 \end{lstlisting}  
       
   106 
       
   107 \noindent
       
   108 In case of reading files, there can be an issue with closing
       
   109 files properly. For this Scala provides \texttt{Using}
       
   110 
       
   111 \begin{lstlisting}[numbers=none]
       
   112   Using(Source.fromFile("test.txt")("ISO-8859-1"))
       
   113                                  (_.mkString).toOption
       
   114 \end{lstlisting}  
       
   115 
       
   116 \noindent
       
   117 This closes the files automatically after reading, but otherwise
       
   118 behaves as the code shown above: It gives a \texttt{Some} in the
       
   119 success case and \texttt{None} in the failure case. However,
       
   120 \texttt{Using} requires a function as argument for prescribing
       
   121 of what to do with the file content in the success case.
       
   122 
       
   123 \subsection*{Task 4 (Higher-Order Functions)}
       
   124 
       
   125 Higher-Order functions means that Scala allows functions to
       
   126 have functions as arguments and also allows functions to
       
   127 return functions. Get familiar with the short-hand notation
       
   128 for simple functions
       
   129 
       
   130 \begin{lstlisting}[numbers=none]
       
   131 scala> List(7,2,3,4,5,6).find(_ < 4)
       
   132 scala> List(7,2,3,4,5,6).count(_ % 2 == 0)
       
   133 scala> List(7,2,3,4,5,6).sortWith(_ > _)
       
   134 scala> List(7,2,3,4,5,6).filter(_ > 4)
       
   135 \end{lstlisting}
       
   136 
       
   137 \noindent
       
   138 Be aware that this short-hand notation only works for ``smallish'' functions
       
   139 and that sometimes Scala cannot figure out the types involved without
       
   140 explicit type annotations.
       
   141 
       
   142 \subsection*{Task 5 (Maps)}
       
   143 
       
   144 Get familiar with the map-function for lists, sets etc. It is the
       
   145 quintessential higher-order function and frequently used for transforming
       
   146 lists.
       
   147 
       
   148 \begin{lstlisting}[numbers=none]
       
   149 scala> List(7,2,3,4,5,6).map(n => n * n)
       
   150 \end{lstlisting}  
       
   151 
       
   152 \noindent
       
   153 Make also sure you see that Scala's \texttt{for}-comprehensions
       
   154 are just syntactic sugar for \texttt{map}s. What would this
       
   155 expression look like as \texttt{for}-comprehension? What are
       
   156 the advantages of \texttt{for}-comprehensions over \texttt{map}s.
       
   157 
       
   158 
       
   159 \subsection*{Task 6 (Pattern-Matching)}
       
   160 
       
   161 Rewrite the following function using pattern-matching
       
   162 
       
   163 \begin{lstlisting}[numbers=none]
       
   164 def my_map(lst: List[Int], f: Int => Int) : List[Int] = {
       
   165  if (lst == Nil) Nil
       
   166  else f(lst.head) :: my_map(lst.tail, f)
       
   167 }
       
   168 \end{lstlisting}
       
   169 
       
   170 \noindent
       
   171 Observe that the type of the function is from \texttt{Int}s to
       
   172 \texttt{Int}s, which is written in Scala as type \texttt{Int => Int}.
       
   173 
       
   174 
       
   175 \subsection*{Task 7 (Web-Crawler, Hard)}
       
   176 
       
   177 Have a look at the web-crawler at the end of \texttt{lecture2.scala}.
       
   178 Can you modify it such that every page is only visited once? 
   104 
   179 
   105 \end{document}
   180 \end{document}
   106 
   181 
   107 %%% Local Variables: 
   182 %%% Local Variables: 
   108 %%% mode: latex
   183 %%% mode: latex