updated
authorChristian Urban <urbanc@in.tum.de>
Tue, 07 Nov 2017 13:08:18 +0000
changeset 127 b4def82f3f9f
parent 126 c40f364d87eb
child 128 166bb9b6b20a
updated
cws/cw01.pdf
cws/cw01.tex
progs/alcohol.scala
progs/collatz.scala
progs/collatz_sol.scala
progs/population.cvs
progs/trade_sol.scala
templates/collatz.scala
testing/collatz.scala
testing/collatz_test
testing/collatz_test1.scala
testing/collatz_test2.scala
Binary file cws/cw01.pdf has changed
--- a/cws/cw01.tex	Sun Nov 05 12:56:55 2017 +0000
+++ b/cws/cw01.tex	Tue Nov 07 13:08:18 2017 +0000
@@ -11,24 +11,38 @@
 at 11pm. You are asked to implement three programs about list
 processing and recursion. The third part is more advanced and might
 include material you have not yet seen in the first lecture.
-Make sure the files you submit can be processed by just calling
-\texttt{scala <<filename.scala>>}.\bigskip
+\bigskip
 
 \noindent
-\textbf{Important:} Do not use any mutable data structures in your
+\textbf{Important:}
+
+\begin{itemize}
+\item Make sure the files you submit can be processed by just calling\\
+\mbox{\texttt{scala <<filename.scala>>}} on the commandline.
+
+\item Do not use any mutable data structures in your
 submissions! They are not needed. This means you cannot use 
-\texttt{ListBuffer}s, for example. Do not use \texttt{return} in your
-code! It has a different meaning in Scala, than in Java.
-Do not use \texttt{var}! This declares a mutable variable. ??? Make sure the
-functions you submit are defined on the ``top-level'' of Scala, not
-inside a class or object. Also note that the running time of
-each part will be restricted to a maximum of 360 seconds on my laptop.
+\texttt{ListBuffer}s, for example. 
+
+\item Do not use \texttt{return} in your code! It has a different
+  meaning in Scala, than in Java.
+
+\item Do not use \texttt{var}! This declares a mutable variable. Only
+  use \texttt{val}!
+
+\item Do not use any parallel collections! No \texttt{.par} therefore!
+  Our testing and marking infrastructure is not set up for it.
+\end{itemize}
+
+\noindent
+Also note that the running time of each part will be restricted to a
+maximum of 360 seconds on my laptop.
 
 
 \subsection*{Disclaimer}
 
 It should be understood that the work you submit represents
-your own effort. You have not copied from anyone else. An
+your \textbf{own} effort. You have not copied from anyone else. An
 exception is the Scala code I showed during the lectures or
 uploaded to KEATS, which you can freely use.\bigskip
 
@@ -76,7 +90,6 @@
   (click \href{https://xkcd.com/710/}{here}). If you are able to solve
   this conjecture, you will definitely get famous.}\bigskip
 
-\newpage
 \noindent
 \textbf{Tasks (file collatz.scala):}
 
@@ -88,7 +101,7 @@
   try out this function with large numbers, you should use
   \texttt{Long} as argument type, instead of \texttt{Int}.  You can
   assume this function will be called with numbers between $1$ and
-  $1$ million. \hfill[2 Marks]
+  $1$ Million. \hfill[2 Marks]
 
 \item[(2)] Write a second function that takes an upper bound as
   argument and calculates the steps for all numbers in the range from
@@ -108,91 +121,124 @@
 \item 1 to 1,000 where $871$ takes 179 steps,
 \item 1 to 10,000 where $6,171$ takes 262 steps,
 \item 1 to 100,000 where $77,031$ takes 351 steps, 
-\item 1 to 1 million where $837,799$ takes 525 steps
+\item 1 to 1 Million where $837,799$ takes 525 steps
   %%\item[$\bullet$] $1 - 10$ million where $8,400,511$ takes 686 steps
-\end{itemize}\bigskip
+\end{itemize}
   
+\noindent
+\textbf{Hints:} useful math operators: \texttt{\%} for modulo; useful
+functions: \mbox{\texttt{(1\,to\,10)}} for ranges, \texttt{.toInt},
+\texttt{.toList} for conversions, \texttt{List(...).max} for the
+maximum of a list, \texttt{List(...).indexOf(...)} for the first index of
+a value in a list.
 
 
-\subsection*{Part 2 (4 Marks)}
+
+\subsection*{Part 2 (3 Marks)}
 
-This part is about list processing---it's a variant of
-``buy-low-sell-high'' in Scala. It uses the online financial data
-service from Yahoo.\bigskip 
+This part is about web-scraping and list-processing in Scala. It uses
+online data about the per-capita alcohol consumption for each country
+(per year?), and a file with the data about the population size of
+each country.  From this data you are supposed to estimate how many
+litres of pure alcohol are consumed worldwide.\bigskip
 
 \noindent
-\textbf{Tasks (file trade.scala):}
+\textbf{Tasks (file alcohol.scala):}
 
 \begin{itemize}
-\item[(1)] Given a list of prices for a commodity, for example
-
-\[
-\texttt{List(28.0, 18.0, 20.0, 26.0, 24.0)}
-\]
-
-\noindent
-you need to write a function that returns a pair of indices for when
-to buy and when to sell this commodity. In the example above it should
-return the pair $\texttt{(1, 3)}$ because at index $1$ the price is lowest and
-then at index $3$ the price is highest. Note the prices are given as
-lists of \texttt{Double}s.\newline \mbox{} \hfill[1 Mark]
-
-\item[(2)] Write a function that requests a comma-separated value (CSV) list
-  from the Yahoo websevice that provides historical data for stock
-  indices. For example if you query the URL
+\item[(1)] Write a function that given an URL requests a
+  comma-separated value (CSV) list.  We are interested in the list
+  from the following URL
 
 \begin{center}
-\url{http://ichart.yahoo.com/table.csv?s=GOOG}
+  \url{https://raw.githubusercontent.com/fivethirtyeight/data/master/alcohol-consumption/drinks.csv}
 \end{center}
 
-\noindent where \texttt{GOOG} stands for Google's stock market symbol,
-then you will receive a CSV-list of the daily stock prices since
-Google was listed. You can also try this with other stock market
-symbols, for instance AAPL, MSFT, IBM, FB, YHOO, AMZN, BIDU and so
-on. 
-
-This function should return a List of strings, where each string
-is one line in this CVS-list (representing one day's
-data). Note that Yahoo generates its answer such that the newest data
-is at the front of this list, and the oldest data is at the end.
-\hfill[1 Mark]
-
-\item[(3)] As you can see, the financial data from Yahoo is organised in 7 columns,
-for example
-
-{\small\begin{verbatim}
-Date,Open,High,Low,Close,Volume,Adj Close
-2016-11-04,750.659973,770.359985,750.560974,762.02002,2126900,762.02002
-2016-11-03,767.25,769.950012,759.030029,762.130005,1914000,762.130005
-2016-11-02,778.200012,781.650024,763.450012,768.700012,1872400,768.700012
-2016-11-01,782.890015,789.48999,775.539978,783.609985,2404500,783.609985
-....
-\end{verbatim}}
+\noindent Your function should take a string (the URL) as input, and
+produce a list of strings as output, where each string is one line in
+the corresponding CSV-list.  This list should contain 194 lines.\medskip
 
 \noindent
-Write a function that ignores the first line (the header) and then
-extracts from each line the date (first column) and the Adjusted Close
-price (last column). The Adjusted Close price should be converted into
-a \texttt{Double}. So the result of this function is a list of pairs where the
-first components are strings (the dates) and the second are doubles
-(the adjusted close prices).\newline\mbox{}\hfill\mbox{[1 Mark]}
+Write another function that can read the file \texttt{population.csv}
+from disk (the file is distributed with the coursework). This
+function should take a string as argument, the file name, and again
+return a list of strings corresponding to each entry in the
+CSV-list. For \texttt{population.csv}, this list should contain 216
+lines.\hfill[1 Mark]
+
+
+\item[(2)] Unfortunately, the CSV-lists contain a lot of ``junk'' and we
+  need to extract the data that interests us.  From the header of the
+  alcohol list, you can see there are 5 columns
+  
+  \begin{center}
+    \begin{tabular}{l}
+      \texttt{country (name),}\\
+      \texttt{beer\_servings,}\\
+      \texttt{spirit\_servings,}\\
+      \texttt{wine\_servings,}\\
+      \texttt{total\_litres\_of\_pure\_alcohol}
+    \end{tabular}  
+  \end{center}
+
+  \noindent
+  Write a function that extracts the data from the first column,
+  the country name, and the data from the fifth column (converted into
+  a \texttt{Double}). For this go through each line of the CSV-list
+  (except the first line), use the \texttt{split(",")} function to
+  divide each line into an array of 5 elements. Keep the data from the
+  first and fifth element in these arrays.\medskip
 
-\item[(4)] Write a function that takes a stock market symbol as
-  argument (you can assume it is a valid one, like GOOG or AAPL). The
-  function calculates the \underline{dates} when you should have
-  bought the corresponding shares (lowest price) and when you should
-  have sold them (highest price).\hfill\mbox{[1 Mark]}
+  \noindent
+  Write another function that processes the population size list. This
+  is already of the form country name and population size.\footnote{Your
+    friendly lecturer already did the messy processing for you from the
+  Worldbank database, see \url{https://github.com/datasets/population/tree/master/data}.} Again, split the
+  strings according to the commas. However, this time generate a
+  \texttt{Map} from country names to population sizes.\hfill[1 Mark]
+
+\item[(3)] In (2) you generated the data about the alcohol consumption
+  per capita for each country, and also the population size for each
+  country. From this generate next a sorted(!) list of the overall
+  alcohol consumption for each country. The list should be sorted from
+  highest alcohol consumption to lowest. The difficulty is that the
+  data is scrapped off from ``random'' sources on the Internet and
+  annoyingly the spelling of some country names does not always agree in the
+  lists. For example the alcohol list contains
+  \texttt{Bosnia-Herzegovina}, while the population writes this country as
+  \texttt{Bosnia and Herzegovina}. In your sorted
+  overall list include only countries from the alcohol list, whose
+  exact country name is also in the population size list. This means
+  you can ignore countries like Bosnia-Herzegovina from the overall
+  alcohol consumption. There are 177 countries where the names
+  agree. The UK is ranked 10th on this list with
+  consuming 671,976,864 Litres of pure alcohol each year.\medskip
+  
+  \noindent
+  Finally, write another function that takes an integer, say
+  \texttt{n}, as argument. You can assume this integer is between 0
+  and 177.  The function should use the sorted list from above.  It returns
+  a triple, where the first component is the sum of the alcohol
+  consumption in all countries (on the list); the second component is
+  the sum of the \texttt{n}-highest alcohol consumers on the list; and
+  the third component is the percentage the \texttt{n}-highest alcohol
+  consumers feast on with respect to the the world consumption. You will
+  see that according to our data, 164 countries (out of 177) gobble up 100\%
+  of the world alcohol consumption.\hfill\mbox{[1 Mark]}
 \end{itemize}
 
 \noindent
-\textbf{Test Data:}
-In case of Google, the financial data records 3077 entries starting
-from 2004-08-19 until 2016-11-04 (which is the last entry on the day
-when I prepared the course work...namely on 6 November; remember stock
-markets are typically closed on weekends and no financial data is
-produced then; also I did not count the header line). The lowest
-shareprice for Google was on 2004-09-03 with \$49.95513 per share and the
-highest on 2016-10-24 with \$813.109985 per share.\bigskip
+\textbf{Hints:} useful list functions: \texttt{.drop(n)},
+\texttt{.take(n)} for dropping or taking some elements in a list,
+\texttt{.getLines} for separating lines in a string;
+\texttt{.sortBy(\_.\_2)} sorts a list of pairs according to the second
+elements in the pairs---the sorting is done from smallest to highest;
+useful \texttt{Map} functions: \texttt{.toMap} converts a list of
+pairs into a \texttt{Map}, \texttt{.isDefinedAt(k)} tests whether the
+map is defined at that key, that is would produce a result when
+called with this key.
+
+\newpage
 
 \subsection*{Advanced Part 3 (3 Marks)}
 
@@ -202,10 +248,10 @@
 estimated he is 3 Billion Dollar worth (one is not sure, of course,
 because Mr Drumb refuses to make his tax records public).
 
-Since the question about Mr Drumb's business acumen remains, let's do a
-quick back-of-the-envelope calculation in Scala whether his claim has
-any merit. Let's suppose we are given \$100 in 1978 and we follow a
-really dumb investment strategy, namely:
+Since the question about Mr Drumb's business acumen remains open,
+let's do a quick back-of-the-envelope calculation in Scala whether his
+claim has any merit. Let's suppose we are given \$100 in 1978 and we
+follow a really dumb investment strategy, namely:
 
 \begin{itemize}
 \item We blindly choose a portfolio of stocks, say some Blue-Chip stocks
@@ -220,9 +266,12 @@
   the stocks from our portfolio (there might be more stocks available,
   if companies from our portfolio got listed in that year, or less if
   some companies went bust or de-listed).
-\item We do this for 38 years until January 2016 and check what would
+\item We do this for 38 years until January 2017 and check what would
   have become out of our \$100.
-\end{itemize}\medskip  
+\end{itemize}
+
+
+\medskip  
 
 \noindent
 \textbf{Tasks (file drumb.scala):}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/progs/alcohol.scala	Tue Nov 07 13:08:18 2017 +0000
@@ -0,0 +1,79 @@
+// Part 2 about Alcohol-Consumption Worldwide
+//============================================
+
+
+// (1) Complete the function that is given a list of floats
+// and calculuates the indices for when to buy the commodity 
+// and when to sell
+
+
+// (2) Complete the ``get webpage'' function that takes a
+// a stock symbol as argument and queries the Yahoo server
+// at
+//      http://ichart.yahoo.com/table.csv?s=<<insert stock symbol>>
+// 
+// This servive returns a CSV-list that needs to be separated into
+// a list of strings.
+
+import io.Source
+import scala.util._
+
+def get_csv_page(url: String) : List[String] = 
+  Source.fromURL(url)("ISO-8859-1").getLines.toList
+
+def get_csv_file(file: String) : List[String] = 
+  Source.fromFile(file)("ISO-8859-1").getLines.toList
+
+
+val url_alcohol = 
+  "https://raw.githubusercontent.com/fivethirtyeight/data/master/alcohol-consumption/drinks.csv"
+
+val file_population = 
+  "population.cvs"
+
+get_csv_page(url_alcohol)
+get_csv_file(file_population)
+
+get_csv_page(url_alcohol).size
+get_csv_file(file_population).size
+
+val alcs = get_csv_page(url_alcohol)
+val pops = get_csv_file(file_population)
+
+
+def process_alcs(lines: List[String]) : List[(String, Double)] =
+  for (l <- lines) yield {
+    val entries = l.split(",").toList 
+    (entries(0), entries(4).toDouble) 
+  }
+
+def process_pops(lines: List[String]) : Map[String, Long] =
+  (for (l <- lines) yield {
+    val entries = l.split(",").toList 
+    (entries(0), entries(1).toLong)
+  }).toMap
+
+
+def sorted_country_consumption() : List[(String, Long)] = {
+  val alcs2 = process_alcs(alcs.drop(1))
+  val pops2 = process_pops(pops.drop(1))
+  val cons_list = 
+    for ((cname, cons) <- alcs2; if pops2.isDefinedAt(cname)) yield (cname, (cons * pops2(cname)).toLong)
+  cons_list.sortBy(_._2).reverse
+}
+
+sorted_country_consumption().take(10)
+sorted_country_consumption().size
+
+consumption.foreach { println } 
+
+def percentage(n: Int) : (Long, Long, Double) = {
+  val cons_list = sorted_country_consumption()
+  val sum_n = cons_list.take(n).map(_._2).sum
+  val sum_all = cons_list.map(_._2).sum
+  val perc = (sum_n.toDouble / sum_all.toDouble) * 100.0
+  (sum_all, sum_n, perc)
+}
+
+percentage(164)
+
--- a/progs/collatz.scala	Sun Nov 05 12:56:55 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-// Part 1 about the 3n+1 conceture
-//=================================
-
-
-//(1) Complete the collatz function below. It should
-//    recursively calculate the number of steps needed 
-//    until the collatz series reaches the number 1.
-//    If needed you can use an auxilary function that
-//    performs the recursion. The function should expect
-//    arguments in the range of 1 to 1 Million.
-
-def collatz(n: Long): ... = ...
-
-
-//(2)  Complete the collatz bound function below. It should
-//     calculuate how many steps are needed for each number 
-//     from 1 upto a bound and returns the maximum number of
-//     steps and the corresponding number that needs that many 
-//     steps. You should expect bounds in the range of 1
-//     upto 1 million. The first component of the pair is
-//     the maximum number of steps and the second is the 
-//     corresponding number.
-
-def collatz_max(bnd: Int): (Int, Int) = ...
-
-
--- a/progs/collatz_sol.scala	Sun Nov 05 12:56:55 2017 +0000
+++ b/progs/collatz_sol.scala	Tue Nov 07 13:08:18 2017 +0000
@@ -1,53 +1,31 @@
-// Part 1 about the 3n+1 conceture
-//=================================
+// Part 1 about the 3n+1 conjecture
+//==================================
 
-
+object CW6a {
 
-//(1) Complete the collatz function below. It should
-//    recursively calculate the number of steps needed 
-//    until the collatz series reaches the number 1.
-//    If needed you can use an auxilary function that
-//    performs the recursion. The function should expect
-//    arguments in the range of 1 to 1 Million.
-
-def collatz(n: Long): List[Long] =
-  if (n == 1) List(1) else
-    if (n % 2 == 0) (n::collatz(n / 2)) else 
-      (n::collatz(3 * n + 1))
+def collatz(n: Long): Long =
+  if (n == 1) 1 else
+    if (n % 2 == 0) 1 + collatz(n / 2) else 
+      1 + collatz(3 * n + 1)
 
 
-// an alternative that calculates the steps directly
-def collatz1(n: Long): Int =
-  if (n == 1) 1 else
-    if (n % 2 == 0) (1 + collatz1(n / 2)) else 
-      (1 + collatz1(3 * n + 1))
-
-
-//(2)  Complete the collatz bound function below. It should
-//     calculuate how many steps are needed for each number 
-//     from 1 upto a bound and return the maximum number of
-//     steps and the corresponding number that needs that many 
-//     steps. You should expect bounds in the range of 1
-//     upto 1 million. 
-
-def collatz_max(bnd: Int): (Int, Int) = {
-  val all = for (i <- (1 to bnd).toList) yield collatz(i).length
+def collatz_max(bnd: Long): (Long, Long) = {
+  val all = for (i <- (1 to bnd.toInt).toList) yield collatz(i)
   val max = all.max
-  (all.indexOf(max) + 1, max)
+  (max, all.indexOf(max) + 1)
 }
 
 
-// some testing harness
-val bnds = List(2, 10, 100, 1000, 10000, 100000, 77000, 90000, 1000000, 5000000)
+// some testing harness...5 Mio pushes the envelope
+
+val bnds = List(2, 10, 100, 1000, 10000, 100000, 
+		77000, 90000, 1000000, 5000000)
 
 for (bnd <- bnds) {
-  val (max, steps) = collatz_max(bnd)
+  val (steps, max) = collatz_max(bnd)
   println(s"In the range of 1 - ${bnd} the number ${max} needs the maximum steps of ${steps}")
 }
 
 
-//val all = for (i <- (1 to 100000).toList) yield collatz1(i)
-//println(all.sorted.reverse.take(10))
+}
 
-
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/progs/population.cvs	Tue Nov 07 13:08:18 2017 +0000
@@ -0,0 +1,216 @@
+country,population_size
+Afghanistan,32758020
+Albania,2889104
+Algeria,39113313
+American Samoa,55437
+Andorra,79223
+Angola,26920466
+Antigua and Barbuda,98875
+Argentina,42981515
+Armenia,2906220
+Aruba,103795
+Australia,23460694
+Austria,8541575
+Azerbaijan,9535079
+Bahamas,382169
+Bahrain,1336397
+Bangladesh,159405279
+Barbados,283385
+Belarus,9474511
+Belgium,11209057
+Belize,351694
+Benin,10286712
+Bermuda,65139
+Bhutan,776448
+Bolivia,10562159
+Bosnia and Herzegovina,3566002
+Botswana,2168573
+Brazil,204213133
+British Virgin Islands,29588
+Brunei Darussalam,411704
+Bulgaria,7223938
+Burkina Faso,17585977
+Burundi,9891790
+Cabo Verde,526437
+Cambodia,15270790
+Cameroon,22239904
+Canada,35544564
+Cayman Islands,59172
+Central African Republic,4515392
+Chad,13569438
+Channel Islands,162969
+Chile,17613798
+China,1364270000
+Colombia,47791911
+Comoros,759385
+Congo,73722860
+Costa Rica,4757575
+Cote d'Ivoire,22531350
+Croatia,4238389
+Cuba,11439767
+Curacao,155909
+Cyprus,1152309
+Czech Republic,10525347
+Denmark,5643475
+Djibouti,912164
+Dominica,72778
+Dominican Republic,10405844
+Ecuador,15903112
+Egypt,91812566
+El Salvador,6281189
+Equatorial Guinea,1129424
+Estonia,1314545
+Ethiopia,97366774
+Faroe Islands,48842
+Fiji,885806
+Finland,5461512
+France,66331957
+French Polynesia,275484
+Gabon,1875713
+Gambia,1917852
+Georgia,3727000
+Germany,80982500
+Ghana,26962563
+Gibraltar,34038
+Greece,10892413
+Greenland,56295
+Grenada,106360
+Guam,160967
+Guatemala,15923559
+Guinea,11805509
+Guinea-Bissau,1725744
+Guyana,763393
+Haiti,10572466
+Honduras,8809216
+Hong Kong SAR,7241700
+Hungary,9866468
+Iceland,327386
+India,1293859294
+Indonesia,255131116
+Iran,78411092
+Iraq,35006080
+Ireland,4617225
+Isle of Man,82590
+Israel,8215700
+Italy,60789140
+Jamaica,2862087
+Japan,127276000
+Jordan,8809306
+Kazakhstan,17289224
+Kenya,46024250
+Kiribati,110458
+North Korea,25116363
+South Korea,50746659
+Kosovo,1821800
+Kuwait,3782450
+Kyrgyz Republic,5835500
+Lao PDR,6576397
+Latvia,1993782
+Lebanon,5603279
+Lesotho,2145785
+Liberia,4390737
+Libya,6204108
+Liechtenstein,37127
+Lithuania,2932367
+Luxembourg,556319
+Macao SAR,588781
+Macedonia,2077495
+Madagascar,23589801
+Malawi,17068838
+Malaysia,30228017
+Maldives,401000
+Mali,16962846
+Malta,427364
+Marshall Islands,52898
+Mauritania,4063920
+Mauritius,1260934
+Mexico,124221600
+Micronesia,104015
+Moldova,3556397
+Monaco,38132
+Mongolia,2923896
+Montenegro,621810
+Morocco,34318082
+Mozambique,27212382
+Myanmar,51924182
+Namibia,2370992
+Nauru,11853
+Nepal,28323241
+Netherlands,16865008
+New Caledonia,268000
+New Zealand,4509700
+Nicaragua,6013997
+Niger,19148219
+Nigeria,176460502
+Northern Mariana Islands,54468
+Norway,5137232
+Oman,3960925
+Pakistan,185546257
+Palau,21094
+Panama,3903986
+Papua New Guinea,7755785
+Paraguay,6552584
+Peru,30973354
+Philippines,100102249
+Poland,38011735
+Portugal,10401062
+Puerto Rico,3534874
+Qatar,2374419
+Romania,19908979
+Russian Federation,143819666
+Rwanda,11345357
+Samoa,192290
+San Marino,32657
+Sao Tome and Principe,191266
+Saudi Arabia,30776722
+Senegal,14546111
+Serbia,7130576
+Seychelles,91359
+Sierra Leone,7079162
+Singapore,5469724
+Sint Maarten (Dutch part),37685
+Slovak Republic,5418649
+Slovenia,2061980
+Solomon Islands,575504
+Somalia,13513125
+South Africa,54146734
+South Sudan,11530971
+Spain,46480882
+Sri Lanka,20771000
+St. Kitts and Nevis,53739
+St. Lucia,176421
+St. Martin (French part),31530
+St. Vincent and the Grenadines,109357
+Sudan,37737913
+Suriname,547928
+Swaziland,1295097
+Sweden,9696110
+Switzerland,8188649
+Syrian Arab Republic,19203090
+Tajikistan,8362745
+Tanzania,52234869
+Thailand,68416772
+Timor-Leste,1212814
+Togo,7228915
+Tonga,105782
+Trinidad and Tobago,1354493
+Tunisia,11143908
+Turkey,77030628
+Turkmenistan,5466241
+Turks and Caicos Islands,33739
+Tuvalu,10908
+Uganda,38833338
+Ukraine,45271947
+United Arab Emirates,9070867
+United Kingdom,64613160
+United States,318563456
+Uruguay,3419546
+Uzbekistan,30757700
+Vanuatu,258850
+Venezuela,30738378
+Vietnam,90728900
+Virgin Islands (U.S.),104170
+West Bank and Gaza,4294682
+Yemen,26246327
+Zambia,15620974
+Zimbabwe,15411675
--- a/progs/trade_sol.scala	Sun Nov 05 12:56:55 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-// Part 2 about Buy-Low-Sell-High using Yahoo Financial Data
-//===========================================================
-
-
-// (1) Complete the function that is given a list of floats
-// and calculuates the indices for when to buy the commodity 
-// and when to sell
-
-def trade_times(xs: List[Double]): (Int, Int) = {
-  val low = xs.min
-  val low_index = xs.indexOf(low)
-  val rest = xs.drop(low_index)
-  val high = rest.max
-  val high_index = rest.indexOf(high)
-  (low_index, low_index + high_index)
-}
-
-val prices = List(28.0, 18.0, 20.0, 26.0, 24.0)
-assert(trade_times(prices) == (1, 3), "the trade_times test fails")
-
-
-// (2) Complete the ``get webpage'' function that takes a
-// a stock symbol as argument and queries the Yahoo server
-// at
-//      http://ichart.yahoo.com/table.csv?s=<<insert stock symbol>>
-// 
-// This servive returns a CSV-list that needs to be separated into
-// a list of strings.
-
-import io.Source
-import scala.util._
-
-def get_yahoo_page(symbol: String): List[String] = {
-  val url = """http://ichart.yahoo.com/table.csv?s=""" + symbol
-  Try(Source.fromURL(url)("ISO-8859-1").getLines.toList).
-    getOrElse { println(s"  Problem with: $url"); List() }
-}
-
-// (3) Complete the function that processes the CSV list
-// extracting the dates and anjusted close prices. The
-// prices need to be transformed into Doubles.
-
-def process_page(symbol: String): List[(String, Double)] = {
-  get_yahoo_page(symbol).drop(1).map(_.split(",").toList).map((xs) => (xs(0), xs(6).toDouble))
-}
-
-
-// (4) Complete the query_company function that obtains the
-// processed CSV-list for a stock symbol. It should return
-// the dates for when to buy and sell the stocks of that company.
-
-def query_company(symbol: String): (String, String) = {
-  val list = process_page(symbol).reverse
-  val (tbuy, tsell) = trade_times(list.map(_._2))
-  (list(tbuy)._1, list(tsell)._1)
-}
-
-//query_company("GOOG")
-
-
-val indices = List("GOOG", "AAPL", "MSFT", "IBM", "FB", "YHOO", "AMZN", "BIDU")
-
-for (name <- indices) {
-  val times = query_company(name)
-  println(s"Buy ${name} on ${times._1} and sell on ${times._2}")
-}
-
-
-
-/*
-scala trade.scala 2> /dev/null || echo "command1 borked it"
-
-command1
-if [ $? -ne 0 ]; then
-    echo "command1 borked it"
-fi
-*/
-
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/collatz.scala	Tue Nov 07 13:08:18 2017 +0000
@@ -0,0 +1,28 @@
+// Part 1 about the 3n+1 conjecture
+//=================================
+
+object CW6a {
+
+//(1) Complete the collatz function below. It should
+//    recursively calculate the number of steps needed 
+//    until the collatz series reaches the number 1.
+//    If needed, you can use an auxiliary function that
+//    performs the recursion. The function should expect
+//    arguments in the range of 1 to 1 Million.
+
+//def collatz(n: Long): ... = ...
+
+
+//(2)  Complete the collatz bound function below. It should
+//     calculate how many steps are needed for each number 
+//     from 1 up to a bound and then calculate the maximum number of
+//     steps and the corresponding number that needs that many 
+//     steps. Again, you should expect bounds in the range of 1
+//     up to 1 Million. The first component of the pair is
+//     the maximum number of steps and the second is the 
+//     corresponding number.
+
+//def collatz_max(bnd: Long): (Long, Long) = ...
+
+
+}
--- a/testing/collatz.scala	Sun Nov 05 12:56:55 2017 +0000
+++ b/testing/collatz.scala	Tue Nov 07 13:08:18 2017 +0000
@@ -1,47 +1,20 @@
-// Part 1 about the 3n+1 conceture
-//=================================
+// Part 1 about the 3n+1 conjecture
+//==================================
 
+object CW6a {
 
-//(1) Complete the collatz function below. It should
-//    recursively calculate the number of steps needed 
-//    until the collatz series reaches the number 1.
-//    If needed you can use an auxilary function that
-//    performs the recursion. The function should expect
-//    arguments in the range of 1 to 1 Million.
+def collatz(n: Long): Long =
+  if (n == 1) 1 else
+    if (n % 2 == 0) 1 + collatz(n / 2) else 
+      1 + collatz(3 * n + 1)
 
 
-def collatz(n: Long): Int =
-  if (n == 1) 1 else
-    if (n % 2 == 0) (1 + collatz(n / 2)) else 
-      (1 + collatz(3 * n + 1))
-
-
-//(2)  Complete the collatz bound function below. It should
-//     calculuate how many steps are needed for each number 
-//     from 1 upto a bound and then produce the maximum number of
-//     steps and the corresponding number that needs that many 
-//     steps. You should expect bounds in the range of 1
-//     upto 1 million. 
-
-def collatz_max(bnd: Int): (Int, Int) = {
-  val all = for (i <- (1 to bnd).toList) yield collatz(i)
+def collatz_max(bnd: Long): (Long, Long) = {
+  val all = for (i <- (1 to bnd.toInt).toList) yield collatz(i)
   val max = all.max
-  (all.indexOf(max) + 1, max)
+  (max, all.indexOf(max) + 1)
 }
 
 
-// some testing harness
-/*
-val bnds = List(2, 10, 100, 1000, 10000, 100000, 77000, 90000, 1000000, 5000000)
+}
 
-for (bnd <- bnds) {
-  val (max, steps) = collatz_max(bnd)
-  println(s"In the range of 1 - ${bnd} the number ${max} needs the maximum steps of ${steps}")
-}
-*/
-
-//val all = for (i <- (1 to 100000).toList) yield collatz1(i)
-//println(all.sorted.reverse.take(10))
-
-
-
--- a/testing/collatz_test	Sun Nov 05 12:56:55 2017 +0000
+++ b/testing/collatz_test	Tue Nov 07 13:08:18 2017 +0000
@@ -15,7 +15,7 @@
 # compilation tests
 
 function scala_compile {
-  (ulimit -t 30 -m 1024000 ; scala "$1" 2> $out 1> $out) 
+  (ulimit -t 30 -m 1024000 ; scala "$1" 2>> $out 1>> $out) 
 }
 
 # functional tests
@@ -40,7 +40,7 @@
   echo "  --> fail" >> $out
   tsts0=$(( 1 ))
 else
-  echo "  --> yes" >> $out
+  echo "  --> success" >> $out
   tsts0=$(( 0 )) 
 fi
 
@@ -67,6 +67,7 @@
 
 if [ $tsts -eq 0 ]
 then
+  echo "collatz.scala tests:" >> $out
   echo "  collatz(1) == 0,1 or 4" >> $out
   echo "  collatz(6) == 9" >> $out
   echo "  collatz(9) == 20" >> $out
@@ -83,12 +84,12 @@
 
 if [ $tsts -eq 0 ]
 then
-  echo "  collatz_max(10) == (9, 20)" >> $out
-  echo "  collatz_max(100) == (97, 119)" >> $out
-  echo "  collatz_max(1000) == (871, 179)" >> $out
-  echo "  collatz_max(10000) == (6171, 262)" >> $out
-  echo "  collatz_max(100000) == (77031, 351)" >> $out
-  echo "  collatz_max(1000000) == (837799, 525)" >> $out
+  echo "  collatz_max(10) == (20, 9)" >> $out
+  echo "  collatz_max(100) == (119, 97)" >> $out
+  echo "  collatz_max(1000) == (179, 871)" >> $out
+  echo "  collatz_max(10000) == (262, 6171)" >> $out
+  echo "  collatz_max(100000) == (351, 77031)" >> $out
+  echo "  collatz_max(1000000) == (525, 837799)" >> $out
 
   if (scala_assert "collatz.scala" "collatz_test2.scala") 
   then
--- a/testing/collatz_test1.scala	Sun Nov 05 12:56:55 2017 +0000
+++ b/testing/collatz_test1.scala	Tue Nov 07 13:08:18 2017 +0000
@@ -1,8 +1,8 @@
 
-assert(List(0,1,4).contains(collatz(1)))
+assert(List(0,1,4).contains(CW6a.collatz(1)))
 
-assert(collatz(6) == 9)
+assert(CW6a.collatz(6) == 9)
 
-assert(collatz(9) == 20)
+assert(CW6a.collatz(9) == 20)
 
 
--- a/testing/collatz_test2.scala	Sun Nov 05 12:56:55 2017 +0000
+++ b/testing/collatz_test2.scala	Tue Nov 07 13:08:18 2017 +0000
@@ -1,13 +1,13 @@
 
 
-assert(collatz_max(10) == (9, 20))
+assert(CW6a.collatz_max(10) == (20, 9))
 
-assert(collatz_max(100) == (97, 119))
+assert(CW6a.collatz_max(100) == (119, 97))
 
-assert(collatz_max(1000) == (871, 179))
+assert(CW6a.collatz_max(1000) == (179, 871))
 
-assert(collatz_max(10000) == (6171, 262))
+assert(CW6a.collatz_max(10000) == (262, 6171))
 
-assert(collatz_max(100000) == (77031, 351))
+assert(CW6a.collatz_max(100000) == (351, 77031))
 
-assert(collatz_max(1000000) == (837799, 525))
+assert(CW6a.collatz_max(1000000) == (525, 837799))