author | Christian Urban <urbanc@in.tum.de> |
Fri, 10 Nov 2017 09:00:46 +0000 | |
changeset 142 | 6f4d8b5e6d80 |
parent 139 | 3350cc06804b |
child 152 | 114a89518aea |
permissions | -rw-r--r-- |
6 | 1 |
\documentclass{article} |
11
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
2 |
\usepackage{../style} |
6 | 3 |
%%\usepackage{../langs} |
4 |
||
5 |
\begin{document} |
|
6 |
||
9
48a477fdef21
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
6
diff
changeset
|
7 |
\section*{Coursework 6 (Scala)} |
31
d0caa12ab8d8
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
30
diff
changeset
|
8 |
|
11
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
9 |
This coursework is about Scala and is worth 10\%. The first and second |
125 | 10 |
part are due on 16 November at 11pm, and the third part on 21 December |
29
fde9223a5301
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
28
diff
changeset
|
11 |
at 11pm. You are asked to implement three programs about list |
18 | 12 |
processing and recursion. The third part is more advanced and might |
24
66b97f9a40f8
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
20
diff
changeset
|
13 |
include material you have not yet seen in the first lecture. |
127 | 14 |
\bigskip |
79 | 15 |
|
16 |
\noindent |
|
127 | 17 |
\textbf{Important:} |
18 |
||
19 |
\begin{itemize} |
|
20 |
\item Make sure the files you submit can be processed by just calling\\ |
|
21 |
\mbox{\texttt{scala <<filename.scala>>}} on the commandline. |
|
22 |
||
23 |
\item Do not use any mutable data structures in your |
|
110 | 24 |
submissions! They are not needed. This means you cannot use |
127 | 25 |
\texttt{ListBuffer}s, for example. |
26 |
||
27 |
\item Do not use \texttt{return} in your code! It has a different |
|
28 |
meaning in Scala, than in Java. |
|
29 |
||
30 |
\item Do not use \texttt{var}! This declares a mutable variable. Only |
|
31 |
use \texttt{val}! |
|
32 |
||
33 |
\item Do not use any parallel collections! No \texttt{.par} therefore! |
|
34 |
Our testing and marking infrastructure is not set up for it. |
|
35 |
\end{itemize} |
|
36 |
||
37 |
\noindent |
|
38 |
Also note that the running time of each part will be restricted to a |
|
39 |
maximum of 360 seconds on my laptop. |
|
28
f50c6a61a3a2
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
24
diff
changeset
|
40 |
|
6 | 41 |
|
18 | 42 |
\subsection*{Disclaimer} |
6 | 43 |
|
44 |
It should be understood that the work you submit represents |
|
127 | 45 |
your \textbf{own} effort. You have not copied from anyone else. An |
6 | 46 |
exception is the Scala code I showed during the lectures or |
47 |
uploaded to KEATS, which you can freely use.\bigskip |
|
48 |
||
49 |
||
18 | 50 |
\subsection*{Part 1 (3 Marks)} |
6 | 51 |
|
11
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
52 |
This part is about recursion. You are asked to implement a Scala |
18 | 53 |
program that tests examples of the \emph{$3n + 1$-conjecture}, also |
54 |
called \emph{Collatz conjecture}. This conjecture can be described as |
|
55 |
follows: Start with any positive number $n$ greater than $0$: |
|
56 |
||
57 |
\begin{itemize} |
|
58 |
\item If $n$ is even, divide it by $2$ to obtain $n / 2$. |
|
59 |
\item If $n$ is odd, multiply it by $3$ and add $1$ to obtain $3n + |
|
60 |
1$. |
|
61 |
\item Repeat this process and you will always end up with $1$. |
|
62 |
\end{itemize} |
|
63 |
||
64 |
\noindent |
|
65 |
For example if you start with $6$, respectively $9$, you obtain the |
|
66 |
series |
|
11
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
67 |
|
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
68 |
\[ |
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
69 |
\begin{array}{@{}l@{\hspace{5mm}}l@{}} |
18 | 70 |
6, 3, 10, 5, 16, 8, 4, 2, 1 & \text{(= 9 steps)}\\ |
71 |
9, 28, 14, 7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1 & \text{(= 20 steps)}\\ |
|
11
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
72 |
\end{array} |
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
73 |
\] |
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
74 |
|
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
75 |
\noindent |
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
76 |
As you can see, the numbers go up and down like a roller-coaster, but |
18 | 77 |
curiously they seem to always terminate in $1$. The conjecture is that |
78 |
this will \emph{always} happen for every number greater than |
|
79 |
0.\footnote{While it is relatively easy to test this conjecture with |
|
80 |
particular numbers, it is an interesting open problem to |
|
81 |
\emph{prove} that the conjecture is true for \emph{all} numbers ($> |
|
82 |
0$). Paul Erd\"o{}s, a famous mathematician you might have hard |
|
83 |
about, said about this conjecture: ``Mathematics may not be ready |
|
84 |
for such problems.'' and also offered a \$500 cash prize for its |
|
85 |
solution. Jeffrey Lagarias, another mathematician, claimed that |
|
86 |
based only on known information about this problem, ``this is an |
|
87 |
extraordinarily difficult problem, completely out of reach of |
|
88 |
present day mathematics.'' There is also a |
|
89 |
\href{https://xkcd.com/710/}{xkcd} cartoon about this conjecture |
|
90 |
(click \href{https://xkcd.com/710/}{here}). If you are able to solve |
|
91 |
this conjecture, you will definitely get famous.}\bigskip |
|
92 |
||
93 |
\noindent |
|
94 |
\textbf{Tasks (file collatz.scala):} |
|
95 |
||
96 |
\begin{itemize} |
|
97 |
\item[(1)] You are asked to implement a recursive function that |
|
98 |
calculates the number of steps needed until a series ends |
|
99 |
with $1$. In case of starting with $6$, it takes $9$ steps and in |
|
100 |
case of starting with $9$, it takes $20$ (see above). In order to |
|
101 |
try out this function with large numbers, you should use |
|
102 |
\texttt{Long} as argument type, instead of \texttt{Int}. You can |
|
103 |
assume this function will be called with numbers between $1$ and |
|
127 | 104 |
$1$ Million. \hfill[2 Marks] |
18 | 105 |
|
106 |
\item[(2)] Write a second function that takes an upper bound as |
|
107 |
argument and calculates the steps for all numbers in the range from |
|
20
07860dd35c2b
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
18
diff
changeset
|
108 |
1 up to this bound. It returns the maximum number of steps and the |
31
d0caa12ab8d8
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
30
diff
changeset
|
109 |
corresponding number that needs that many steps. More precisely |
24
66b97f9a40f8
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
20
diff
changeset
|
110 |
it returns a pair where the first |
66b97f9a40f8
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
20
diff
changeset
|
111 |
component is the number of steps and the second is the |
66b97f9a40f8
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
20
diff
changeset
|
112 |
corresponding number. \hfill\mbox{[1 Mark]} |
18 | 113 |
\end{itemize} |
11
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
114 |
|
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
115 |
\noindent |
18 | 116 |
\textbf{Test Data:} Some test ranges are: |
11
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
117 |
|
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
118 |
\begin{itemize} |
18 | 119 |
\item 1 to 10 where $9$ takes 20 steps |
120 |
\item 1 to 100 where $97$ takes 119 steps, |
|
121 |
\item 1 to 1,000 where $871$ takes 179 steps, |
|
122 |
\item 1 to 10,000 where $6,171$ takes 262 steps, |
|
123 |
\item 1 to 100,000 where $77,031$ takes 351 steps, |
|
127 | 124 |
\item 1 to 1 Million where $837,799$ takes 525 steps |
18 | 125 |
%%\item[$\bullet$] $1 - 10$ million where $8,400,511$ takes 686 steps |
127 | 126 |
\end{itemize} |
18 | 127 |
|
127 | 128 |
\noindent |
129 |
\textbf{Hints:} useful math operators: \texttt{\%} for modulo; useful |
|
130 |
functions: \mbox{\texttt{(1\,to\,10)}} for ranges, \texttt{.toInt}, |
|
131 |
\texttt{.toList} for conversions, \texttt{List(...).max} for the |
|
132 |
maximum of a list, \texttt{List(...).indexOf(...)} for the first index of |
|
133 |
a value in a list. |
|
11
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
134 |
|
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
135 |
|
127 | 136 |
|
137 |
\subsection*{Part 2 (3 Marks)} |
|
11
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
138 |
|
127 | 139 |
This part is about web-scraping and list-processing in Scala. It uses |
140 |
online data about the per-capita alcohol consumption for each country |
|
129 | 141 |
(per year?), and a file containing the data about the population size of |
127 | 142 |
each country. From this data you are supposed to estimate how many |
143 |
litres of pure alcohol are consumed worldwide.\bigskip |
|
18 | 144 |
|
145 |
\noindent |
|
127 | 146 |
\textbf{Tasks (file alcohol.scala):} |
18 | 147 |
|
148 |
\begin{itemize} |
|
127 | 149 |
\item[(1)] Write a function that given an URL requests a |
150 |
comma-separated value (CSV) list. We are interested in the list |
|
151 |
from the following URL |
|
11
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
152 |
|
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
153 |
\begin{center} |
127 | 154 |
\url{https://raw.githubusercontent.com/fivethirtyeight/data/master/alcohol-consumption/drinks.csv} |
11
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
155 |
\end{center} |
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
156 |
|
127 | 157 |
\noindent Your function should take a string (the URL) as input, and |
158 |
produce a list of strings as output, where each string is one line in |
|
129 | 159 |
the corresponding CSV-list. This list from the URL above should |
160 |
contain 194 lines.\medskip |
|
11
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
161 |
|
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
162 |
\noindent |
127 | 163 |
Write another function that can read the file \texttt{population.csv} |
164 |
from disk (the file is distributed with the coursework). This |
|
165 |
function should take a string as argument, the file name, and again |
|
166 |
return a list of strings corresponding to each entry in the |
|
167 |
CSV-list. For \texttt{population.csv}, this list should contain 216 |
|
168 |
lines.\hfill[1 Mark] |
|
169 |
||
170 |
||
171 |
\item[(2)] Unfortunately, the CSV-lists contain a lot of ``junk'' and we |
|
172 |
need to extract the data that interests us. From the header of the |
|
173 |
alcohol list, you can see there are 5 columns |
|
174 |
||
175 |
\begin{center} |
|
176 |
\begin{tabular}{l} |
|
177 |
\texttt{country (name),}\\ |
|
178 |
\texttt{beer\_servings,}\\ |
|
179 |
\texttt{spirit\_servings,}\\ |
|
180 |
\texttt{wine\_servings,}\\ |
|
181 |
\texttt{total\_litres\_of\_pure\_alcohol} |
|
182 |
\end{tabular} |
|
183 |
\end{center} |
|
184 |
||
185 |
\noindent |
|
186 |
Write a function that extracts the data from the first column, |
|
187 |
the country name, and the data from the fifth column (converted into |
|
188 |
a \texttt{Double}). For this go through each line of the CSV-list |
|
189 |
(except the first line), use the \texttt{split(",")} function to |
|
190 |
divide each line into an array of 5 elements. Keep the data from the |
|
191 |
first and fifth element in these arrays.\medskip |
|
11
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
192 |
|
127 | 193 |
\noindent |
194 |
Write another function that processes the population size list. This |
|
195 |
is already of the form country name and population size.\footnote{Your |
|
196 |
friendly lecturer already did the messy processing for you from the |
|
129 | 197 |
Worldbank database, see \url{https://github.com/datasets/population/tree/master/data} for the original.} Again, split the |
127 | 198 |
strings according to the commas. However, this time generate a |
199 |
\texttt{Map} from country names to population sizes.\hfill[1 Mark] |
|
200 |
||
201 |
\item[(3)] In (2) you generated the data about the alcohol consumption |
|
202 |
per capita for each country, and also the population size for each |
|
203 |
country. From this generate next a sorted(!) list of the overall |
|
204 |
alcohol consumption for each country. The list should be sorted from |
|
205 |
highest alcohol consumption to lowest. The difficulty is that the |
|
129 | 206 |
data is scraped off from ``random'' sources on the Internet and |
207 |
annoyingly the spelling of some country names does not always agree in both |
|
127 | 208 |
lists. For example the alcohol list contains |
209 |
\texttt{Bosnia-Herzegovina}, while the population writes this country as |
|
210 |
\texttt{Bosnia and Herzegovina}. In your sorted |
|
211 |
overall list include only countries from the alcohol list, whose |
|
212 |
exact country name is also in the population size list. This means |
|
213 |
you can ignore countries like Bosnia-Herzegovina from the overall |
|
214 |
alcohol consumption. There are 177 countries where the names |
|
129 | 215 |
agree. The UK is ranked 10th on this list by |
127 | 216 |
consuming 671,976,864 Litres of pure alcohol each year.\medskip |
217 |
||
218 |
\noindent |
|
219 |
Finally, write another function that takes an integer, say |
|
220 |
\texttt{n}, as argument. You can assume this integer is between 0 |
|
129 | 221 |
and 177 (the number of countries in the sorted list above). The |
222 |
function should return a triple, where the first component is the |
|
223 |
sum of the alcohol consumption in all countries (on the list); the |
|
224 |
second component is the sum of the \texttt{n}-highest alcohol |
|
225 |
consumers on the list; and the third component is the percentage the |
|
226 |
\texttt{n}-highest alcohol consumers drink with respect to the |
|
227 |
the world consumption. You will see that according to our data, 164 |
|
228 |
countries (out of 177) gobble up 100\% of the World alcohol |
|
229 |
consumption.\hfill\mbox{[1 Mark]} |
|
18 | 230 |
\end{itemize} |
11
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
231 |
|
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
232 |
\noindent |
127 | 233 |
\textbf{Hints:} useful list functions: \texttt{.drop(n)}, |
234 |
\texttt{.take(n)} for dropping or taking some elements in a list, |
|
235 |
\texttt{.getLines} for separating lines in a string; |
|
236 |
\texttt{.sortBy(\_.\_2)} sorts a list of pairs according to the second |
|
237 |
elements in the pairs---the sorting is done from smallest to highest; |
|
238 |
useful \texttt{Map} functions: \texttt{.toMap} converts a list of |
|
239 |
pairs into a \texttt{Map}, \texttt{.isDefinedAt(k)} tests whether the |
|
240 |
map is defined at that key, that is would produce a result when |
|
135 | 241 |
called with this key; useful data functions: \texttt{Source.fromURL}, |
242 |
\texttt{Source.fromFile} for obtaining a webpage and reading a file. |
|
127 | 243 |
|
244 |
\newpage |
|
18 | 245 |
|
129 | 246 |
\subsection*{Advanced Part 3 (4 Marks)} |
18 | 247 |
|
35
9fea5f751be4
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
31
diff
changeset
|
248 |
A purely fictional character named Mr T.~Drumb inherited in 1978 |
9fea5f751be4
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
31
diff
changeset
|
249 |
approximately 200 Million Dollar from his father. Mr Drumb prides |
20
07860dd35c2b
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
18
diff
changeset
|
250 |
himself to be a brilliant business man because nowadays it is |
07860dd35c2b
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
18
diff
changeset
|
251 |
estimated he is 3 Billion Dollar worth (one is not sure, of course, |
35
9fea5f751be4
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
31
diff
changeset
|
252 |
because Mr Drumb refuses to make his tax records public). |
18 | 253 |
|
127 | 254 |
Since the question about Mr Drumb's business acumen remains open, |
255 |
let's do a quick back-of-the-envelope calculation in Scala whether his |
|
256 |
claim has any merit. Let's suppose we are given \$100 in 1978 and we |
|
257 |
follow a really dumb investment strategy, namely: |
|
18 | 258 |
|
259 |
\begin{itemize} |
|
24
66b97f9a40f8
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
20
diff
changeset
|
260 |
\item We blindly choose a portfolio of stocks, say some Blue-Chip stocks |
18 | 261 |
or some Real Estate stocks. |
262 |
\item If some of the stocks in our portfolio are traded in January of |
|
24
66b97f9a40f8
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
20
diff
changeset
|
263 |
a year, we invest our money in equal amounts in each of these |
18 | 264 |
stocks. For example if we have \$100 and there are four stocks that |
24
66b97f9a40f8
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
20
diff
changeset
|
265 |
are traded in our portfolio, we buy \$25 worth of stocks |
18 | 266 |
from each. |
267 |
\item Next year in January, we look how our stocks did, liquidate |
|
268 |
everything, and re-invest our (hopefully) increased money in again |
|
269 |
the stocks from our portfolio (there might be more stocks available, |
|
270 |
if companies from our portfolio got listed in that year, or less if |
|
129 | 271 |
some companies went bust or were de-listed). |
272 |
\item We do this for 39 years until January 2017 and check what would |
|
18 | 273 |
have become out of our \$100. |
127 | 274 |
\end{itemize} |
275 |
||
129 | 276 |
\noindent |
277 |
Until Yahoo was bought by Altaba this summer, historical stock market |
|
135 | 278 |
data for such back-of-the-envelope calculations was available online |
279 |
for free, but nowadays this kind of data is difficult to obtain, unless |
|
280 |
you are prepared to pay extortionate prices or be severely |
|
281 |
rate-limited. Therefore this coursework comes with a number of files |
|
282 |
containing CSV-lists about historical stock prices for companies of |
|
283 |
our portfolio. Use these files for the following tasks.\bigskip |
|
11
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
284 |
|
18 | 285 |
\noindent |
42
a5106bc13db6
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
35
diff
changeset
|
286 |
\textbf{Tasks (file drumb.scala):} |
18 | 287 |
|
288 |
\begin{itemize} |
|
129 | 289 |
\item[(1.a)] Write a function \texttt{get\_january\_data} that takes a |
135 | 290 |
stock symbol and a year as arguments. The function reads the |
129 | 291 |
corresponding CSV-file and returns the list of strings that start |
292 |
with the given year (each line in the CSV-list is of the form |
|
135 | 293 |
\texttt{year-01-someday,someprice}). |
18 | 294 |
|
129 | 295 |
\item[(1.b)] Write a function \texttt{get\_first\_price} that takes |
135 | 296 |
again a stock symbol and a year as arguments. It should return the |
297 |
first January price for the stock symbol in given the year. For this |
|
298 |
it uses the list of strings generated by |
|
129 | 299 |
\texttt{get\_january\_data}. A problem is that normally a stock |
300 |
exchange is not open on 1st of January, but depending on the day of |
|
301 |
the week on a later day (maybe 3rd or 4th). The easiest way to solve |
|
302 |
this problem is to obtain the whole January data for a stock symbol |
|
135 | 303 |
and then select the earliest, or first, entry in this list. The |
304 |
stock price of this entry should be converted into a double. Such a |
|
305 |
price might not exist, in case the company does not exist in the given |
|
306 |
year. For example, if you query for Google in January of 1980, then |
|
307 |
clearly Google did not exists yet. Therefore you are asked to |
|
308 |
return a trade price as \texttt{Option[Double]}\ldots\texttt{None} |
|
309 |
will be the value for when no price exists. |
|
18 | 310 |
|
129 | 311 |
\item[(1.c)] Write a function \texttt{get\_prices} that takes a |
312 |
portfolio (a list of stock symbols), a years range and gets all the |
|
135 | 313 |
first trading prices for each year in the range. You should organise |
314 |
this as a list of lists of \texttt{Option[Double]}'s. The inner |
|
315 |
lists are for all stock symbols from the portfolio and the outer |
|
316 |
list for the years. For example for Google and Apple in years 2010 |
|
317 |
(first line), 2011 (second line) and 2012 (third line) you obtain: |
|
11
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
318 |
|
18 | 319 |
\begin{verbatim} |
129 | 320 |
List(List(Some(311.349976), Some(27.505054)), |
321 |
List(Some(300.222351), Some(42.357094)), |
|
322 |
List(Some(330.555054), Some(52.852215))) |
|
323 |
\end{verbatim}\hfill[2 Marks] |
|
18 | 324 |
|
325 |
\item[(2.a)] Write a function that calculates the \emph{change factor} (delta) |
|
326 |
for how a stock price has changed from one year to the next. This is |
|
327 |
only well-defined, if the corresponding company has been traded in both |
|
328 |
years. In this case you can calculate |
|
11
417869f65585
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
9
diff
changeset
|
329 |
|
18 | 330 |
\[ |
331 |
\frac{price_{new} - price_{old}}{price_{old}} |
|
332 |
\] |
|
333 |
||
334 |
||
335 |
\item[(2.b)] Write a function that calculates all change factors |
|
336 |
(deltas) for the prices we obtained under Task 1. For the running |
|
24
66b97f9a40f8
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
20
diff
changeset
|
337 |
example of Google and Apple for the years 2010 to 2012 you should |
66b97f9a40f8
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
20
diff
changeset
|
338 |
obtain 4 change factors: |
18 | 339 |
|
340 |
\begin{verbatim} |
|
129 | 341 |
List(List(Some(-0.03573992567129673), Some(0.5399749442411563)) |
342 |
List(Some(0.10103412653643493), Some(0.2477771728154912))) |
|
18 | 343 |
\end{verbatim} |
344 |
||
24
66b97f9a40f8
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
20
diff
changeset
|
345 |
That means Google did a bit badly in 2010, while Apple did very well. |
135 | 346 |
Both did OK in 2011.\\ |
347 |
\mbox{}\hfill\mbox{[1 Mark]} |
|
18 | 348 |
|
349 |
\item[(3.a)] Write a function that calculates the ``yield'', or |
|
350 |
balance, for one year for our portfolio. This function takes the |
|
351 |
change factors, the starting balance and the year as arguments. If |
|
352 |
no company from our portfolio existed in that year, the balance is |
|
353 |
unchanged. Otherwise we invest in each existing company an equal |
|
354 |
amount of our balance. Using the change factors computed under Task |
|
355 |
2, calculate the new balance. Say we had \$100 in 2010, we would have |
|
135 | 356 |
received in our running example involving Google and Apple: |
6 | 357 |
|
18 | 358 |
\begin{verbatim} |
129 | 359 |
$50 * -0.03573992567129673 + $50 * 0.5399749442411563 |
360 |
= $25.21175092849298 |
|
18 | 361 |
\end{verbatim} |
362 |
||
363 |
as profit for that year, and our new balance for 2011 is \$125 when |
|
364 |
converted to a \texttt{Long}. |
|
365 |
||
366 |
\item[(3.b)] Write a function that calculates the overall balance |
|
367 |
for a range of years where each year the yearly profit is compounded to |
|
135 | 368 |
the new balances and then re-invested into our portfolio.\\ |
369 |
\mbox{}\hfill\mbox{[1 Mark]} |
|
18 | 370 |
\end{itemize}\medskip |
371 |
||
372 |
\noindent |
|
373 |
\textbf{Test Data:} File \texttt{drumb.scala} contains two portfolios |
|
374 |
collected from the S\&P 500, one for blue-chip companies, including |
|
129 | 375 |
Facebook, Amazon and Baidu; and another for listed real-estate |
376 |
companies, whose names I have never heard of. Following the dumb |
|
377 |
investment strategy from 1978 until 2017 would have turned a starting |
|
139 | 378 |
balance of \$100 into roughly \$30,895 for real estate and a whopping |
135 | 379 |
\$349,597 for blue chips. Note when comparing these results with your |
380 |
own calculations: there might be some small rounding errors, which |
|
381 |
when compounded, lead to moderately different values.\bigskip |
|
382 |
||
383 |
\noindent |
|
142 | 384 |
\textbf{Hints:} useful string functions: \texttt{.startsWith(...)} for |
385 |
checking whether a string has a given prefix, \texttt{\_ + \_} for |
|
386 |
concatenating two strings; useful option functions: \texttt{.flatten} |
|
135 | 387 |
flattens a list of options such that it filters way all |
388 |
\texttt{None}'s, \texttt{Try(...) getOrElse ...} runs some code that |
|
389 |
might raise an exception, if yes, then a default value can be given; |
|
390 |
useful list functions: \texttt{.head} for obtaining the first element |
|
391 |
in a non-empty list, \texttt{.length} for the length of a |
|
392 |
list.\bigskip |
|
393 |
||
18 | 394 |
|
395 |
\noindent |
|
24
66b97f9a40f8
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
20
diff
changeset
|
396 |
\textbf{Moral:} Reflecting on our assumptions, we are over-estimating |
18 | 397 |
our yield in many ways: first, who can know in 1978 about what will |
398 |
turn out to be a blue chip company. Also, since the portfolios are |
|
399 |
chosen from the current S\&P 500, they do not include the myriad |
|
400 |
of companies that went bust or were de-listed over the years. |
|
35
9fea5f751be4
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
31
diff
changeset
|
401 |
So where does this leave our fictional character Mr T.~Drumb? Well, given |
18 | 402 |
his inheritance, a really dumb investment strategy would have done |
129 | 403 |
equally well, if not much better.\medskip |
404 |
||
135 | 405 |
|
6 | 406 |
\end{document} |
407 |
||
408 |
%%% Local Variables: |
|
409 |
%%% mode: latex |
|
410 |
%%% TeX-master: t |
|
411 |
%%% End: |