Binary file handouts/pep-ho.pdf has changed
--- a/handouts/pep-ho.tex Thu Nov 02 14:47:55 2017 +0000
+++ b/handouts/pep-ho.tex Sat Nov 04 16:17:19 2017 +0000
@@ -38,9 +38,10 @@
res0: Int = 5
\end{lstlisting}
-\noindent indicating that the result of the addition is of
-type \code{Int} and the actual result is 5. Another classic
-example you can try out is
+\noindent indicating that the result of the addition is of type
+\code{Int} and the actual result is 5; \code{res0} is a name that
+Scala gives automatically to the result. Yoy can reuse this name later
+on. Another classic example you can try out is
\begin{lstlisting}[numbers=none]
scala> print("hello world")
@@ -49,7 +50,7 @@
\noindent Note that in this case there is no result. The
reason is that \code{print} does not actually produce a result
-(there is no \code{resXX} and no type), rather it is a
+(there is no \code{resX} and no type), rather it is a
function that causes the \emph{side-effect} of printing out a
string. Once you are more familiar with the functional
programming-style, you will know what the difference is
@@ -57,7 +58,7 @@
function that causes a side-effect, like \code{print}. We
shall come back to this point later, but if you are curious
now, the latter kind of functions always has \code{Unit} as
-return type.
+return type. It is just not printed.
You can try more examples with the Scala interpreter, but try
first to guess what the result is (not all answers by Scala are obvious):
@@ -75,7 +76,7 @@
scala> "12345".length
\end{lstlisting}
-\subsection*{Stand-Alone Apps}
+\subsection*{Stand-Alone Scala Apps}
If you want to write a stand-alone app in Scala, you can
implement an object that is an instance of \code{App}, say
@@ -86,7 +87,7 @@
}
\end{lstlisting}
-\noindent save it in a file, say {\tt hello-world.scala}, and
+\noindent save it in a file, for example {\tt hello-world.scala}, and
then run the compiler and runtime environment:
\begin{lstlisting}[language={},numbers=none,basicstyle=\ttfamily\small]
@@ -95,6 +96,7 @@
hello world
\end{lstlisting}
+\noindent
Like Java, Scala targets the JVM and consequently
Scala programs can also be executed by the bog-standard Java
Runtime. This only requires the inclusion of {\tt
@@ -112,10 +114,10 @@
\subsection*{Values}
-In the lectures, I will try as much as possible to avoid the term
-\emph{variables} familiar from other programming languages. Scala
-has \emph{values}, which can be seen as abbreviations of larger
-expressions. For example
+In the lectures I will try to avoid as much as possible the term
+\emph{variables} familiar from other programming languages. The reason
+is that Scala has \emph{values}, which can be seen as abbreviations of
+larger expressions. For example
\begin{lstlisting}[numbers=none]
scala> val x = 42
@@ -130,8 +132,8 @@
\noindent
Why the kerfuffle about values? Well, values are \emph{immutable}. You cannot
-change their value after you defined them. If you try to reassign, say,
-\code{z}, Scala will yell at you:
+change their value after you defined them. If you try to reassign
+\code{z} above, Scala will yell at you:
\begin{lstlisting}[numbers=none]
scala> z = 9
@@ -151,7 +153,7 @@
scala> println(z)
\end{lstlisting}
-\noindent but try to guess what Scala will print out in the code above
+\noindent but try to guess what Scala will print out
for \code{z}? Will it be \code{6} or \code{10}? A final word about
values: Try to stick to the convention that names of values should be
lower case, like \code{x}, \code{y}, \code{foo41} and so on.
@@ -159,7 +161,8 @@
\subsection*{Function Definitions}
-A function \code{f} taking a single argument of type \code{Int} can be defined
+We do functional programming. So defining functions will be our main occupation.
+A function \code{f} taking a single argument of type \code{Int} can be defined in Scala
as follows:
\begin{lstlisting}[numbers=none]
@@ -167,9 +170,10 @@
\end{lstlisting}
\noindent
-It returns the value resulting from evaluating the expression
+This function returns the value resulting from evaluating the expression
\code{EXPR} (whatever is substituted for this). The result will be
-of type \code{String}. Simple examples of Scala functions are:
+of type \code{String}. It is a good habbit to include this information
+about the return type always. Simple examples of Scala functions are:
\begin{lstlisting}[numbers=none]
def incr(x: Int) : Int = x + 1
@@ -188,10 +192,11 @@
\noindent
where each argument requires its type and the result type of the
-function, \code{rty}, shoudl be given. If the body of the function
-is more complex, then it can be enclosed in braces; it it is just a
-simple expression, like \code{x + 1}, you can omit the braces. Very
-often functions are recursive (call themselves) like
+function, \code{rty}, should be given. If the body of the function is
+more complex, then it can be enclosed in braces, like above. If it it
+is just a simple expression, like \code{x + 1}, you can omit the
+braces. Very often functions are recursive (call themselves) like
+the venerable factorial function.
\begin{lstlisting}[numbers=none]
def fact(n: Int): Int =
--- a/progs/lecture1.scala Thu Nov 02 14:47:55 2017 +0000
+++ b/progs/lecture1.scala Sat Nov 04 16:17:19 2017 +0000
@@ -226,7 +226,7 @@
gcd_db(48, 18)
-// Assert/Testing
+// Asserts/Testing
//================
assert(gcd(48, 18) == 6)
@@ -302,7 +302,7 @@
// function for looking up stockmarket data
-def price_lookup(symbol: String): String = {
+def price_lookup(symbol: String) : String = {
val url = "https://download.finance.yahoo.com/d/quotes.csv?s=" + symbol + "&f=snl1"
Source.fromURL(url).mkString.drop(1).dropRight(2)
}
@@ -373,11 +373,12 @@
// run Scala on the commandline. There are also at least
// four IDEs you can use with Scala:
//
-// (0) Some general information for setting up IDEs
+// (0) Some general information about setting up IDEs
// with Scala support can be found at
//
// http://docs.scala-lang.org/getting-started.html
//
+//
// (1) Eclipse for Scala (one big bundle)
//
// http://scala-ide.org/download/sdk.html
@@ -388,7 +389,7 @@
// http://docs.scala-lang.org/getting-started-intellij-track/getting-started-with-scala-in-intellij.html
//
// (3) Sublime (not free, but unlimited trial period;
-// needs SublimeREPL plugin)
+// needs Scala and SublimeREPL plugin)
//
// https://www.sublimetext.com
//
@@ -406,6 +407,13 @@
//
// There is also Scala support in the Atom editor, but my
// experience is mixed. People also use Scala with Vim and Jedit.
+// Finally there is an online editor specifically designed for
+// running Scala applications (but do not blame mne if you lose all
+// what you typed in):
+//
+// https://scalafiddle.io
+//
+//
//
// All of the IDEs above support a REPL for Scala. Some of them have
// the very nifty feature of a Scala Worksheet -- you just save your
@@ -415,6 +423,7 @@
//
//
// Scala Library Docs
+//====================
//
// http://www.scala-lang.org/api/current/
//
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/progs/mandelbrot.scala Sat Nov 04 16:17:19 2017 +0000
@@ -0,0 +1,133 @@
+import java.awt.Color
+import java.awt.Dimension
+import java.awt.Graphics
+import java.awt.Graphics2D
+import java.awt.image.BufferedImage
+import javax.swing.JFrame
+import javax.swing.JPanel
+import javax.swing.WindowConstants
+
+// complex numbers
+case class Complex(val a: Double, val b: Double) {
+ // represents the complex number a + b*i
+ def +(that: Complex) = Complex(this.a + that.a, this.b + that.b)
+ def -(that: Complex) = Complex(this.a - that.a, this.b - that.b)
+ def *(that: Complex) = Complex(this.a * that.a - this.b * that.b,
+ this.a * that.b + that.a * this.b)
+ def *(that: Double) = Complex(this.a * that, this.b * that)
+ def abs() = Math.sqrt(this.a * this.a + this.b * this.b)
+}
+
+// some customn colours
+val colours = List(
+ new Color(66, 30, 15), new Color(25, 7, 26),
+ new Color(9, 1, 47), new Color(4, 4, 73),
+ new Color(0, 7, 100), new Color(12, 44, 138),
+ new Color(24, 82, 177), new Color(57, 125, 209),
+ new Color(134, 181, 229), new Color(211, 236, 248),
+ new Color(241, 233, 191), new Color(248, 201, 95),
+ new Color(255, 170, 0), new Color(204, 128, 0),
+ new Color(153, 87, 0), new Color(106, 52, 3))
+
+// the viewer panel
+class Viewer(width: Int, height: Int) extends JPanel {
+ val canvas = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB)
+ clearCanvas(Color.black)
+
+ override def paintComponent(g: Graphics) =
+ g.asInstanceOf[Graphics2D].drawImage(canvas, null, null)
+
+ override def getPreferredSize() =
+ new Dimension(width, height)
+
+ def clearCanvas(color: Color) = {
+ for(x <- 0 to width - 1;
+ y <- 0 to height - 1) canvas.setRGB(x, y, color.getRGB())
+ repaint()
+ }
+
+}
+
+def openViewer(width: Int, height: Int) = {
+ val frame = new JFrame("XYPlane")
+ val viewer = new Viewer(width, height)
+ frame.add(viewer)
+ frame.pack()
+ frame.setVisible(true)
+ frame.setResizable(false)
+ frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE)
+ viewer
+}
+
+val W = 900
+val H = 800
+val black = Color.black
+val viewer = openViewer(W, H)
+
+
+def pixel(x: Int, y: Int, color: Color) =
+ viewer.canvas.setRGB(x, y, color.getRGB())
+
+
+def mandelbrot(start: Complex, end: Complex, level: Int) : Unit = {
+ viewer.clearCanvas(black)
+
+ val delta_x = (end.a - start.a) / W
+ val delta_y = (end.b - start.b) / H
+
+ for (y0 <- (0 until H).par) {
+ for (x0 <- (0 until W).par) {
+
+ val c = start + Complex(x0 * delta_x, y0 * delta_y)
+
+ def iters(z: Complex, it: Int) : Color = {
+ if (it < level && z.abs < 2) iters(z * z + c, it + 1) else
+ if (it == level) black else colours(it % 16)
+ }
+
+ pixel(x0, y0, iters(Complex(0, 0), 0))
+ }
+ viewer.updateUI()
+ }
+}
+
+// Examples
+//==========
+
+//for measuring time
+def time_needed[T](code: => T) = {
+ val start = System.nanoTime()
+ code
+ val end = System.nanoTime()
+ (end - start) / 1.0e9
+}
+
+
+// example 1
+val exa1 = Complex(-2.0, -1.5)
+val exa2 = Complex( 1.0, 1.5)
+
+time_needed(mandelbrot(exa1, exa2, 1000))
+
+// ehxample 2
+val exb1 = Compylex(-0.37465401, 0.659227668)
+val exb2 = Complex(-0.37332410, 0.66020767)
+
+time_needed(mandelbrot(exb1, exb2, 1000))
+
+// example 3
+val exc1 = Complex(0.435396403, 0.367981352)
+val exc2 = Complex(0.451687191, 0.380210061)
+
+time_needed(mandelbrot(exc1, exc2, 1000))
+
+// some more computations with example 3
+val delta = (exc2 - exc1) * 0.0333
+
+time_needed(
+for (i <- (0 to 12))
+ mandelbrot(exc1 + delta * i,
+ exc2 - delta * i, 1000))
+
+
+