Skip to content

Commit

Permalink
Implement 2nd assignment
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-myltsev committed Dec 12, 2013
1 parent 6658d47 commit d177286
Show file tree
Hide file tree
Showing 6 changed files with 253 additions and 58 deletions.
22 changes: 11 additions & 11 deletions a2-funsets/src/main/scala/funsets/FunSets.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,30 @@ object FunSets {
/**
* Returns the set of the one given element.
*/
def singletonSet(elem: Int): Set = ???
def singletonSet(elem: Int): Set = x => x == elem

/**
* Returns the union of the two given sets,
* the sets of all elements that are in either `s` or `t`.
*/
def union(s: Set, t: Set): Set = ???
def union(s: Set, t: Set): Set = x => s(x) || t(x)

/**
* Returns the intersection of the two given sets,
* the set of all elements that are both in `s` and `t`.
*/
def intersect(s: Set, t: Set): Set = ???
def intersect(s: Set, t: Set): Set = x => s(x) && t(x)

/**
* Returns the difference of the two given sets,
* the set of all elements of `s` that are not in `t`.
*/
def diff(s: Set, t: Set): Set = ???
def diff(s: Set, t: Set): Set = x => s(x) && !t(x)

/**
* Returns the subset of `s` for which `p` holds.
*/
def filter(s: Set, p: Int => Boolean): Set = ???
def filter(s: Set, p: Int => Boolean): Set = x => s(x) && p(x)

/**
* The bounds for `forall` and `exists` are +/- 1000.
Expand All @@ -55,23 +55,23 @@ object FunSets {
*/
def forall(s: Set, p: Int => Boolean): Boolean = {
def iter(a: Int): Boolean = {
if (???) ???
else if (???) ???
else iter(???)
if (a > bound) true
else if (contains(s, a)) p(a) && iter(a + 1)
else iter(a + 1)
}
iter(???)
iter(-bound)
}

/**
* Returns whether there exists a bounded integer within `s`
* that satisfies `p`.
*/
def exists(s: Set, p: Int => Boolean): Boolean = ???
def exists(s: Set, p: Int => Boolean): Boolean = !forall(s, x => !p(x))

/**
* Returns a set transformed by applying `f` to each element of `s`.
*/
def map(s: Set, f: Int => Int): Set = ???
def map(s: Set, f: Int => Int): Set = { case x => exists(s, (si => f(si) == x)) }

/**
* Displays the contents of a set
Expand Down
56 changes: 56 additions & 0 deletions a2-funsets/src/test/scala/funsets/FractionSpec.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package funsets

/*
import org.scalatest.PropSpec
import org.scalatest.prop.PropertyChecks
import org.scalatest.matchers.ShouldMatchers
class Fraction(n: Int, d: Int) {
require(d != 0)
require(d != Integer.MIN_VALUE)
require(n != Integer.MIN_VALUE)
val numer = if (d < 0) -1 * n else n
val denom = d.abs
override def toString = numer + " / " + denom
}
class FractionSpec extends PropSpec with PropertyChecks with ShouldMatchers {
property("Fraction constructor normalizes numerator and denominator") {
forAll { (n: Int, d: Int) =>
whenever(d != 0 && d != Integer.MIN_VALUE && n != Integer.MIN_VALUE) {
val f = new Fraction(n, d)
if (n < 0 && d < 0 || n > 0 && d > 0)
f.numer should be > 0
else if (n != 0)
f.numer should be < 0
else
f.numer should be === 0
f.denom should be > 0
}
}
}
property("Fraction constructor throws IAE on bad data.") {
val invalidCombos =
Table(
("n", "d"),
(Integer.MIN_VALUE, Integer.MIN_VALUE),
(1, Integer.MIN_VALUE),
(Integer.MIN_VALUE, 1),
(Integer.MIN_VALUE, 0),
(1, 0))
forAll(invalidCombos) { (n: Int, d: Int) =>
evaluating {
new Fraction(n, d)
} should produce[IllegalArgumentException]
}
}
}
*/
99 changes: 52 additions & 47 deletions a2-funsets/src/test/scala/funsets/FunSetSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,64 +13,30 @@ import org.scalatest.junit.JUnitRunner
*/
@RunWith(classOf[JUnitRunner])
class FunSetSuite extends FunSuite {


/**
* Link to the scaladoc - very clear and detailed tutorial of FunSuite
*
* http://doc.scalatest.org/1.9.1/index.html#org.scalatest.FunSuite
*
* Operators
* - test
* - ignore
* - pending
*/

/**
* Tests are written using the "test" operator and the "assert" method.
*/
test("string take") {
val message = "hello, world"
assert(message.take(5) == "hello")
}

/**
* For ScalaTest tests, there exists a special equality operator "===" that
* can be used inside "assert". If the assertion fails, the two values will
* be printed in the error message. Otherwise, when using "==", the test
* error message will only say "assertion failed", without showing the values.
*
* Try it out! Change the values so that the assertion fails, and look at the
* error message.
*/
test("adding ints") {
assert(1 + 2 === 3)
}


import FunSets._
import SetExtension._

test("contains is implemented") {
assert(contains(x => true, 100))
}

/**
* When writing tests, one would often like to re-use certain values for multiple
* tests. For instance, we would like to create an Int-set and have multiple test
* about it.
*
*
* Instead of copy-pasting the code for creating the set into every test, we can
* store it in the test class using a val:
*
*
* val s1 = singletonSet(1)
*
*
* However, what happens if the method "singletonSet" has a bug and crashes? Then
* the test methods are not even executed, because creating an instance of the
* test class fails!
*
*
* Therefore, we put the shared values into a separate trait (traits are like
* abstract classes), and create an instance inside each test method.
*
*
*/

trait TestSets {
Expand All @@ -82,15 +48,15 @@ class FunSetSuite extends FunSuite {
/**
* This test is currently disabled (by using "ignore") because the method
* "singletonSet" is not yet implemented and the test would fail.
*
*
* Once you finish your implementation of "singletonSet", exchange the
* function "ignore" by "test".
*/
ignore("singletonSet(1) contains 1") {
test("singletonSet(1) contains 1") {

/**
* We create a new instance of the "TestSets" trait, this gives us access
* to the values "s1" to "s3".
* to the values "s1" to "s3".
*/
new TestSets {
/**
Expand All @@ -101,12 +67,51 @@ class FunSetSuite extends FunSuite {
}
}

ignore("union contains all elements") {
test("singletonSet(1) does not contain 1") {
new TestSets {
assert(!contains(s1, 2), "Singleton not")
}
}

test("union contains all elements") {
new TestSets {
val s = union(s1, s2)
assert(contains(s, 1), "Union 1")
assert(contains(s, 2), "Union 2")
assert(!contains(s, 3), "Union 3")
}
}
}

test("forall: {1,2,3,4}") {
assert(forall(toFunSet(Set(1, 2, 3, 4)), x => x < 5), "All elements in the set are strictly less than 5")
}

test("forall: {-1000,0}") {
assert(forall(toFunSet(Set(-1000)), x => x < 1000), "All elements in the set are strictly less than 1000")
}

test("forall & filter: even") {
val s: Set = toFunSet((-500 to 500).toSet)
def even(x: Int) = x % 2 == 0
assert(forall(FunSets.filter(s, even), even), "The set of all even numbers should contain only even numbers")
}

test("forall & map: doubling numbers") {
val s: Set = toFunSet((-500 to 500).toSet)
def even(x: Int) = x % 2 == 0
def double(x: Int) = x * 2
assert(forall(FunSets.map(s, double), even), "The set obtained by doubling all numbers should contain only even numbers")
}

test("exists: given {1,3,4,5,7,1000}") {
val s: Set = toFunSet(Set(1, 3, 4, 5, 7, 1000))
assert(!FunSets.exists(s, x => x == 2), "2 shouldn't exist in the given set")
}

test("exists & filter: even") {
val s: Set = toFunSet((-300 to 300).toSet)
def even(x: Int) = x % 2 == 0
def odd(x: Int) = !even(x)
assert(!FunSets.exists(FunSets.filter(s, even), odd), "The set of all even numbers should not contain odd element.")
}
}
9 changes: 9 additions & 0 deletions a2-funsets/src/test/scala/funsets/SetExtension.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package funsets

import FunSets._
import scala.language.implicitConversions
import scala.collection.immutable

object SetExtension {
def toFunSet(l: immutable.Set[Int]): Set = (x => l.contains(x))
}
102 changes: 102 additions & 0 deletions a2-funsets/src/test/scala/funsets/SetSpecs.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package funsets

import org.scalatest.FunSuite

import org.scalatest.PropSpec
import org.scalatest.prop.PropertyChecks
import org.scalatest.matchers.ShouldMatchers

class SetsSpec extends PropSpec with PropertyChecks with ShouldMatchers {
import FunSets._
import SetExtension._
import scala.collection.immutable

val emptySet: Set = (x => false)
val universalSet: Set = (x => true)

property("union -- from definition") {
forAll { (l1: immutable.Set[Int], l2: immutable.Set[Int]) =>
val unionSet: Set = FunSets.union(toFunSet(l1), toFunSet(l2))
(l1 forall (contains(unionSet, _))) should be(true)
(l2 forall (contains(unionSet, _))) should be(true)
((l1 ++ l2) forall (contains(unionSet, _))) should be(true)
}
}

property("union -- no additional elements") {
forAll { (n: Int, l: immutable.Set[Int]) =>
whenever(!(l contains n)) {
val unionSet: Set = FunSets.union(toFunSet(l), toFunSet(l))
(!contains(unionSet, n)) should be(true)
}
}
}

property("union -- with empty set") {
forAll { (l: immutable.Set[Int]) =>
{
val unionSet: Set = FunSets.union(emptySet, toFunSet(l))
(l forall (contains(unionSet, _))) should be(true)
}
}
}

property("intersect -- from definition") {
forAll { (l1: immutable.Set[Int], l2: immutable.Set[Int]) =>
val intersectSet: Set = FunSets.intersect(toFunSet(l1), toFunSet(l2))
((l1 intersect l2) forall (contains(intersectSet, _))) should be(true)
((l1 diff l2) forall (!contains(intersectSet, _))) should be(true)
((l2 diff l1) forall (!contains(intersectSet, _))) should be(true)
}
}

property("intersect -- no additional elements") {
forAll { (n: Int, l: immutable.Set[Int]) =>
whenever(!(l contains n)) {
val unionSet: Set = FunSets.union(toFunSet(l), toFunSet(l))
(contains(unionSet, n)) should be(false)
}
}
}

property("intersect -- with universal set") {
forAll { (l: immutable.Set[Int]) =>
{
val intersectSet: Set = FunSets.intersect(universalSet, toFunSet(l))
(l forall (contains(intersectSet, _))) should be(true)
}
}
}

property("diff") {
forAll { (s1: immutable.Set[Int], s2: immutable.Set[Int]) =>
{
val diffSet: Set = FunSets.diff(toFunSet(s1), toFunSet(s2))
((s1 diff s2) forall (contains(diffSet, _))) should be(true)
((s2 diff s1) forall (!contains(diffSet, _))) should be(true)
}
}
}

property("filter") {
forAll { (s: immutable.Set[Int]) =>
{
def even(x: Int) = x % 2 == 0
val filterSet: Set = FunSets.filter(toFunSet(s), even)
((s filter even) forall (contains(filterSet, _))) should be(true)
((s filter (x => !even(x))) forall (!contains(filterSet, _))) should be(true)
}
}
}

property("map") {
forAll { (s1: immutable.Set[Int]) =>
{
val s = s1.map(x => x % 300)
def double(x: Int) = 2 * x
val mappedSet: Set = FunSets.map(toFunSet(s), double)
((s map double) forall (contains(mappedSet, _))) should be(true)
}
}
}
}
Loading

0 comments on commit d177286

Please sign in to comment.