# HG changeset patch # User Christian Urban # Date 1574440905 0 # Node ID 1f8005b4cdf666676e0137df1e13e4c1bf986c72 # Parent 755d165633ec8e11402b0b447fbfd7dd87674764 updated diff -r 755d165633ec -r 1f8005b4cdf6 marking2/docdiff_test.sh --- a/marking2/docdiff_test.sh Tue Nov 19 06:38:20 2019 +0000 +++ b/marking2/docdiff_test.sh Fri Nov 22 16:41:45 2019 +0000 @@ -98,6 +98,10 @@ echo -e " " | tee -a $out echo -e " occurrences(List(\"d\", \"b\", \"d\", \"b\", \"d\")) == " | tee -a $out echo -e " Map(\"d\" -> 3, \"b\" -> 2)" | tee -a $out + echo -e " " | tee -a $out + echo -e " occurrences(Nil) == Map() " | tee -a $out + echo -e " " | tee -a $out + echo -e " occurrences(List(\"b\", \"b\", \"b\", \"b\", \"b\")) == Map(\"b\" -> 5)" | tee -a $out if (scala_assert "docdiff.scala" "docdiff_test2.scala") then @@ -118,6 +122,9 @@ echo -e " prod(l1, l2) == 7 " | tee -a $out echo -e " prod(l1, l1) == 7 " | tee -a $out echo -e " prod(l2, l2) == 13 " | tee -a $out + echo -e " " | tee -a $out + echo -e " val l3 = List(\"1\", \"2\", \"3\", \"4\", \"5\")" | tee -a $out + echo -e " prod(l1, l3) == 0 " | tee -a $out if (scala_assert "docdiff.scala" "docdiff_test3.scala") then diff -r 755d165633ec -r 1f8005b4cdf6 marking2/docdiff_test2.scala --- a/marking2/docdiff_test2.scala Tue Nov 19 06:38:20 2019 +0000 +++ b/marking2/docdiff_test2.scala Fri Nov 22 16:41:45 2019 +0000 @@ -4,3 +4,7 @@ assert(occurrences(List("a", "b", "b", "c", "d")) == Map("a" -> 1, "b" -> 2, "c" -> 1, "d" -> 1)) assert(occurrences(List("d", "b", "d", "b", "d")) == Map("d" -> 3, "b" -> 2)) + +assert(occurrences(List("b", "b", "b", "b", "b")) == Map("b" -> 5)) + +assert(occurrences(Nil) == Map()) diff -r 755d165633ec -r 1f8005b4cdf6 marking2/docdiff_test3.scala --- a/marking2/docdiff_test3.scala Tue Nov 19 06:38:20 2019 +0000 +++ b/marking2/docdiff_test3.scala Fri Nov 22 16:41:45 2019 +0000 @@ -7,3 +7,9 @@ assert(prod(urban_list1, urban_list2) == 7) assert(prod(urban_list1, urban_list1) == 7) assert(prod(urban_list2, urban_list2) == 13) + + +val urban_listA = List("a", "b", "b", "c", "d") +val urban_listB = List("1", "2", "3", "4", "5") + +assert(prod(urban_listA, urban_listB) == 0) diff -r 755d165633ec -r 1f8005b4cdf6 misc/decompile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/misc/decompile Fri Nov 22 16:41:45 2019 +0000 @@ -0,0 +1,28 @@ +#!/bin/bash +set -euo pipefail + +trap "exit" INT + +files=${1:-assignment2019scala-*/Part7} + +function scala_compile { + (ulimit -t 30; JAVA_OPTS="-Xmx1g" scala "$1" 2>> /dev/null 1>> /dev/null) +} + +for sd in $files; do + cd $sd + echo $sd + if (scala_compile docdiff.scala) + then + scalac -g:notailcalls -d docdiff-decompiled.jar docdiff.scala + java -jar ~/pep-material/procyon-decompiler-0.5.36.jar -ln -jar docdiff-decompiled.jar -o . + rm CW7a.java + mv CW7a$.java CW7a.java + else + echo -e " --> SCALA DID NOT RUN docdiff.scala" + fi + cd .. + cd .. +done + + diff -r 755d165633ec -r 1f8005b4cdf6 progs/lecture2.scala --- a/progs/lecture2.scala Tue Nov 19 06:38:20 2019 +0000 +++ b/progs/lecture2.scala Fri Nov 22 16:41:45 2019 +0000 @@ -159,6 +159,12 @@ Some(x / y) }).getOrElse(None) + +// minOption +// maxOption +// minByOption +// maxByOption + // Higher-Order Functions //======================== diff -r 755d165633ec -r 1f8005b4cdf6 progs/lecture3.scala --- a/progs/lecture3.scala Tue Nov 19 06:38:20 2019 +0000 +++ b/progs/lecture3.scala Fri Nov 22 16:41:45 2019 +0000 @@ -7,6 +7,32 @@ // higher-order function +def add(x: Int, y: Int) : Int = x + y + +def plus5(x: Int) : Int = add(5, x) + +plus5(6) + +def add2(x: Int)(y: Int) : Int = x + y + +def plus3(y: Int) : Int => Int = add2(3)(y) + +plus3(9) + +List(1,2,3,4,5).map(add2(3)) +List(1,2,3,4,5).map(add(3, _)) + +type Pos = (Int, Int) + +def test(p: Pos) = { + if (p._1 < 5 && p._2 < 5) { + Some(p) + } +} + +val l = List((1,2), (5,3), (2,5), (1,3)) + +l.map(test).flatten // Recursion Again ;o) //==================== @@ -57,7 +83,7 @@ crawl(startURL, 2) - +for (x <- List(1,2,3,4,5,6)) println(x) // a primitive email harvester def emails(url: String, n: Int) : Set[String] = { @@ -66,11 +92,11 @@ println(s" Visiting: $n $url") val page = get_page(url) val new_emails = email_pattern.findAllIn(page).toSet - new_emails ++ (for (u <- get_all_URLs(page)) yield emails(u, n - 1)).flatten + new_emails ++ (for (u <- get_all_URLs(page).par) yield emails(u, n - 1)).flatten } } -emails(startURL, 2) +emails(startURL, 3) // if we want to explore the internet "deeper", then we @@ -109,8 +135,8 @@ def moves(xs: List[Int], n: Int) : List[List[Int]] = (xs, n) match { case (Nil, _) => Nil - case (xs, 0) => Nil - case (x::xs, n) => (x::xs) :: moves(xs, n - 1) + case (_, 0) => Nil + case (y::ys, n) => xs :: moves(ys, n - 1) } @@ -181,17 +207,22 @@ // User-defined Datatypes //======================== +abstract class Tree +case class Leaf(x: Int) extends Tree +case class Node(s: String, left: Tree, right: Tree) extends Tree + +List(Leaf(20), Node("foo", Leaf(1), Leaf(2))) sealed abstract class Colour case object Red extends Colour case object Green extends Colour case object Blue extends Colour +case object Yellow extends Colour def fav_colour(c: Colour) : Boolean = c match { - case Red => false case Green => true - case Blue => false + case _ => false } fav_colour(Green) @@ -209,7 +240,7 @@ type RomanNumeral = List[RomanDigit] -List(X,I) +List(X,I,M,D) /* I -> 1 @@ -271,6 +302,10 @@ // trees + + +// expressions + sealed abstract class Exp case class N(n: Int) extends Exp // for numbers case class Plus(e1: Exp, e2: Exp) extends Exp diff -r 755d165633ec -r 1f8005b4cdf6 slides/slides03.pdf Binary file slides/slides03.pdf has changed diff -r 755d165633ec -r 1f8005b4cdf6 slides/slides03.tex --- a/slides/slides03.tex Tue Nov 19 06:38:20 2019 +0000 +++ b/slides/slides03.tex Fri Nov 22 16:41:45 2019 +0000 @@ -301,6 +301,21 @@ {\Large$\Rightarrow$}\bigskip {\;\;\Large\bl{$3\;\;1\;+\;2\;\;9\;+\;*$}} + +\begin{textblock}{3}(11,4) +\begin{onlyenv}<2> +\begin{lstlisting}[language=JVMIS] +ldc 3 +ldc 1 +iadd +ldc 2 +ldc 9 +iadd +imul +\end{lstlisting} +\end{onlyenv} +\end{textblock} + \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -321,6 +336,19 @@ \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{frame}[t] + + \begin{center} + \includegraphics[scale=0.3]{../pics/blow.png} + \end{center} + + \begin{textblock}{14}(2,11.4) + \large\bf{}Mind-Blowing Programming Languages:\\ + \centering JavaScript + \end{textblock} +\end{frame} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \end{document} diff -r 755d165633ec -r 1f8005b4cdf6 testing1/collatz.scala --- a/testing1/collatz.scala Tue Nov 19 06:38:20 2019 +0000 +++ b/testing1/collatz.scala Fri Nov 22 16:41:45 2019 +0000 @@ -6,48 +6,18 @@ // 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 stepsCounter(n: Long, s: Long) : Long = n match{ + case 1 => s + case n if(n%2==0) => stepsCounter(n/2,s+1) + case _ => stepsCounter(3*n+1, s+1) +} + +def collatz(n: Long) : Long = n match { + case n if(n>0) => stepsCounter(n,0) + case n if(n<=0) => stepsCounter(1,0) +} -// def collatz(n: Long) : Long = { -// if (n == 1) 1 //else -// // if (n % 2 == 0) { -// // collatz(n/2) -// // steps + 1 -// // } //else -// // if (n % 2 != 0) { -// // collatz((3 * n) + 1) -// // steps + 1 -// // } -// } - -// val steps: Long = 1 -// val lst = List() -// def collatz(n: Long) : Long = { -// if (n == 1) { steps + 1 } -// else if (n % 2 == 0) { -// collatz(n/2); -// } -// else { -// collatz((3 * n) + 1); -// } -// steps + 1 -// } -// collatz(6) - -def collatz(n: Long, list: List[Long] = List()): Long = { - if (n == 1) { - n :: list - list.size.toLong - } - else if (n % 2 == 0) { - collatz(n / 2, n :: list) - } - else { - collatz((3 * n) + 1, n :: list) - } -} - -val test = collatz(6) //(2) Complete the collatz_max function below. It should // calculate how many steps are needed for each number @@ -58,13 +28,10 @@ // the maximum number of steps and the second is the // corresponding number. -//def collatz_max(bnd: Long) : (Long, Long) = ... -def collatz_max(bnd: Long) : (Long, Long) = { - val stepsTable = for (n <- (1 to bnd.toInt).toList) yield (collatz(n), n.toLong) - //println(stepsTable) - stepsTable.max +def collatz_max(bnd: Long) : (Long, Long) = { + val allCollatz = for(i<-1L until bnd) yield collatz(i) + val pair = (allCollatz.max, (allCollatz.indexOf(allCollatz.max) +1).toLong) + pair } - } - diff -r 755d165633ec -r 1f8005b4cdf6 testing2/docdiff.scala --- a/testing2/docdiff.scala Tue Nov 19 06:38:20 2019 +0000 +++ b/testing2/docdiff.scala Fri Nov 22 16:41:45 2019 +0000 @@ -1,122 +1,81 @@ // Preliminary Part about Code Similarity //======================================== - -object CW7a { +object CW7a { //(1) Complete the clean function below. It should find // all words in a string using the regular expression -// \w+ and the library function +// \w+ and the library function // // some_regex.findAllIn(some_string) // // The words should be Returned as a list of strings. -def clean(s: String) : List[String] = { - val regex = """\w+""".r; - val list_of_words = s.split(" ").toList - for(word <- list_of_words; - actual_word <- divide_string_where_different(word, regex.findAllIn(word).mkString, 0)) yield actual_word -} +//def clean(s: String) : List[String] = ... +def clean(s: String) : List[String] = + "\\w+".r.findAllIn(s).toList -/* - A secondary function that takes as parameters @param original which is the original word, @param returned which is thea word after the process of removing - some characters not allowed by a regular expression, and @param i which is the index where to start compare the characters of the two words. - It @return a List of strings which represents all the substrings of returned which were previously divided by characters not allowed by the regular expression applied on it. -*/ -def divide_string_where_different(original: String, returned: String, i : Int): List[String] ={ - val max_i = original.length -1 - if(original(i) != returned(i)) returned.substring(0, i)::divide_string_where_different(original.substring(i+1), returned.substring(i), 0).filter(_.nonEmpty) - else if (i == max_i) List(returned) - else divide_string_where_different(original,returned, i +1) - -} - -//(2) The function occurrences calculates the number of times -// strings occur in a list of strings. These occurrences should +//(2) The function occurrences calculates the number of times +// strings occur in a list of strings. These occurrences should // be calculated as a Map from strings to integers. -def occurrences(xs: List[String]): Map[String, Int] = { - val lst = xs.distinct - val word_pairs = (for (word <- lst) yield (word, xs.count(_==word))).toList - word_pairs.toMap -} - - +//def occurrences(xs: List[String]): Map[String, Int] = .. +def occurrences(xs: List[String]) : Map[String, Int] = + xs.groupBy(identity).view.mapValues(_.size).toMap //(3) This functions calculates the dot-product of two documents // (list of strings). For this it calculates the occurrence -// maps from (2) and then multiplies the corresponding occurrences. +// maps from (2) and then multiplies the corresponding occurrences. // If a string does not occur in a document, the product is zero. -// The function finally sums up all products. +// The function finally sums up all products. -def prod(lst1: List[String], lst2: List[String]) : Int = { - val map1 = occurrences(lst1) - val map2 = occurrences(lst2) - print(s"map1 is $map1 \n and map2 is $map2") - val pairs = (for(pair1 <- map1 if(map2.get(pair1._1) != None)) yield (pair1._2, map2.get(pair1._1).get)).toList - print(s"\n pairs are $pairs") - val products = (for(pair <- pairs) yield pair._1 * pair._2).toList - products.sum - -} - +//def prod(lst1: List[String], lst2: List[String]) : Int = .. +def prod(lst1: List[String], lst2: List[String]) : Int = + occurrences(lst1).map(x => occurrences(lst2).getOrElse(x._1, 0) * x._2).reduce(_ + _) //(4) Complete the functions overlap and similarity. The overlap of // two documents is calculated by the formula given in the assignment // description. The similarity of two strings is given by the overlap -// of the cleaned strings (see (1)). +// of the cleaned strings (see (1)). //def overlap(lst1: List[String], lst2: List[String]) : Double = ... - +def overlap(lst1: List[String], lst2: List[String]) : Double = + prod(lst1, lst2).toDouble/Math.max(prod(lst1, lst1).toDouble, prod(lst2, lst2).toDouble) //def similarity(s1: String, s2: String) : Double = ... - - +def similarity(s1: String, s2: String) : Double = + overlap(clean(s1), clean(s2)) /* Test cases - - -val list1 = List("a", "b", "b", "c", "d") +import CW7a._ +val list1 = List("a", "b", "b", "c", "d") val list2 = List("d", "b", "d", "b", "d") - -occurrences(List("a", "b", "b", "c", "d")) // Map(a -> 1, b -> 2, c -> 1, d -> 1) -occurrences(List("d", "b", "d", "b", "d")) // Map(d -> 3, b -> 2) - -prod(list1,list2) // 7 -prod(list1,list1) -prod(list2,list2) - +occurrences(List("a", "b", "b", "c", "d")) +occurrences(List("d", "b", "d", "b", "d")) +prod(list1,list2) // 7 overlap(list1, list2) // 0.5384615384615384 overlap(list2, list1) // 0.5384615384615384 overlap(list1, list1) // 1.0 overlap(list2, list2) // 1.0 - -// Plagiarism examples from +// Plagiarism examples from // https://desales.libguides.com/avoidingplagiarism/examples - val orig1 = """There is a strong market demand for eco-tourism in Australia. Its rich and diverse natural heritage ensures Australia's capacity to attract international ecotourists and gives Australia a comparative advantage in the highly competitive tourism industry.""" - val plag1 = """There is a high market demand for eco-tourism in Australia. Australia has a comparative advantage in the highly competitive tourism industry due to its rich and varied natural heritage which ensures Australia's capacity to attract international ecotourists.""" - similarity(orig1, plag1) // 0.8679245283018868 - - -// Plagiarism examples from +// Plagiarism examples from // https://www.utc.edu/library/help/tutorials/plagiarism/examples-of-plagiarism.php - val orig2 = """No oil spill is entirely benign. Depending on timing and location, even a relatively minor spill can cause significant harm to individual organisms and entire populations. Oil spills can cause @@ -125,7 +84,6 @@ (short-term) and chronic (long-term) effects. Both types are part of a complicated and often controversial equation that is addressed after an oil spill: ecosystem recovery.""" - val plag2 = """There is no such thing as a "good" oil spill. If the time and place are just right, even a small oil spill can cause damage to sensitive ecosystems. Further, spills can cause harm days, months, @@ -134,16 +92,10 @@ effects. Both of these types of harm must be addressed in ecosystem recovery: a controversial tactic that is often implemented immediately following an oil spill.""" - overlap(clean(orig2), clean(plag2)) // 0.728 similarity(orig2, plag2) // 0.728 - - - -// The punchline: everything above 0.6 looks suspicious and +// The punchline: everything above 0.6 looks suspicious and // should be investigated by staff. - */ } -