Skip to content

Ch 7 unit tests pass #146

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions exercises/chapter3/test/Main.purs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Prelude
import Data.AddressBook (emptyBook, findEntry, insertEntry)
import Data.Maybe (Maybe(..))
import Effect (Effect)
import Test.Solutions (findEntryByStreet)
import Test.Solutions (findEntryByStreet, isInBook, removeDuplicates)
import Test.Unit (suite, test)
import Test.Unit.Assert as Assert
import Test.Unit.Main (runTest)
Expand Down Expand Up @@ -54,7 +54,6 @@ main =
test "Lookup existing"
$ Assert.equal (Just john)
$ findEntryByStreet john.address.street book
{- Move this block comment starting point to enable more tests
test "Lookup missing"
$ Assert.equal Nothing
$ findEntryByStreet "456 Nothing St." book
Expand All @@ -68,4 +67,3 @@ main =
test "Exercise 4 - Remove duplicates" do
Assert.equal book
$ removeDuplicates john.firstName john.lastName bookWithDuplicate
-}
22 changes: 19 additions & 3 deletions exercises/chapter3/test/Solutions.purs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,24 @@ module Test.Solutions where

import Prelude
import Data.AddressBook (AddressBook, Entry)
import Data.Maybe (Maybe(..))
import Data.List (filter, head, nubBy, null)
import Data.Maybe (Maybe)

-- Todo, fix this function
findEntryByStreet :: String -> AddressBook -> Maybe Entry
findEntryByStreet streetName book = Nothing
-- Equivalent: findEntryByStreet streetName book = head $ filter filterEntry book
findEntryByStreet streetName = filter filterEntry >>> head
where
filterEntry :: Entry -> Boolean
filterEntry e = e.address.street == streetName

isInBook :: String -> String -> AddressBook -> Boolean
isInBook firstName lastName book = not null $ filter filterEntry book
where
filterEntry :: Entry -> Boolean
filterEntry entry = entry.firstName == firstName && entry.lastName == lastName

removeDuplicates :: String -> String -> AddressBook -> AddressBook
removeDuplicates firstName lastName book = nubBy filterEntry book
where
filterEntry :: Entry -> Entry -> Boolean
filterEntry e1 e2 = e1.firstName == e2.firstName && e1.lastName == e2.lastName
22 changes: 19 additions & 3 deletions exercises/chapter4/test/Main.purs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,25 @@ import Data.Maybe (Maybe(..))
import Data.Path (filename, root)
import Data.Tuple (fst)
import Effect (Effect)
import Test.Solutions
( allTrue
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't seem like this is rebased correctly on the latest solutions (or master) branch, since there shouldn't be any changes here outside of ch7

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I've noticed (and wondered about) that as well. It's become tricky.

, cartesianProduct
, evenCount
, exclusiveOrThenTrue
, factorizations
, fib
, isEven
, isPrime
, keepNonNegative
, keepNonNegativeRewrite
, largestSmallest
, onlyFiles
, reverse
, squared
, triples
, whereIs
, (<$?>)
)
import Test.Unit (suite, test)
import Test.Unit.Assert as Assert
import Test.Unit.Main (runTest)
Expand All @@ -15,8 +34,6 @@ main =
runTest do
test "Initial passing test"
$ Assert.equal true true

{- Move this block comment starting point to enable more tests
suite "Exercise Group 1" do
suite "Exercise 1 - Test if integer is even" do
test "0 is even"
Expand Down Expand Up @@ -184,4 +201,3 @@ main =
test "doesn't locate a file"
$ Assert.equal (Nothing)
$ whereIs "lss"
-}
157 changes: 156 additions & 1 deletion exercises/chapter4/test/Solutions.purs
Original file line number Diff line number Diff line change
@@ -1,4 +1,159 @@
module Test.Solutions where

import Prelude
import Test.Starter
import Data.String.Pattern (Pattern(..))
import Data.Foldable (foldl)
import Data.Int (rem, quot)
import Data.Path (Path(), filename, isDirectory, ls, root, size)
import Data.Array (cons, filter, head, last, length, tail, (:), (..))
import Data.Maybe (Maybe(..), fromMaybe, maybe)
import Data.String.Common (split)
import Data.Tuple (Tuple(..), snd)
import Control.MonadZero (guard)
import Data.Array (cons, filter, head, last, length, tail, (..))
import Data.Foldable (foldl)
import Data.Int (rem, quot)
import Data.Maybe (Maybe(..), fromMaybe, maybe)
import Data.Path (Path(), filename, isDirectory, ls, root, size)
import Data.String.Common (split)
import Data.String.Pattern (Pattern(..))
import Data.Tuple (Tuple(..), snd)

isEven :: Int -> Boolean
isEven n = case n of
0 -> true
1 -> false
_ -> isEven $ n - 2

oneIfEven :: Int -> Int
oneIfEven n = if isEven n then 1 else 0

evenCount :: Array Int -> Int
evenCount ints = evenCount' ints 0
where
evenCount' :: Array Int -> Int -> Int
evenCount' [] count = count

evenCount' ints' count = evenCount' (fromMaybe [] (tail ints')) $ add count $ maybe 0 oneIfEven $ head ints'

squared :: Array Number -> Array Number
squared arr = map (\n -> n * n) arr

keepNonNegative :: Array Number -> Array Number
keepNonNegative arr = filter (\n -> n >= 0.0) arr

infix 4 filter as <$?>

keepNonNegativeRewrite :: Array Number -> Array Number
keepNonNegativeRewrite arr = (\n -> n >= 0.0) <$?> arr

factors :: Int -> Array (Array Int)
factors n = do
i <- 1 .. n
j <- i .. n
guard $ i * j == n
pure [ i, j ]

isPrime :: Int -> Boolean
isPrime n = eq 1 $ length $ factors n

cartesianProduct :: ∀ a. Array a -> Array a -> Array (Array a)
cartesianProduct left right = do
a_ <- left
b_ <- right
[ [ a_, b_ ] ]

triples :: Int -> Array (Array Int)
triples n = do
i <- 1 .. n
j <- i .. n
k <- j .. n
guard $ i * i + j * j == k * k
pure [ i, j, k ]

-- | Provide the prime numbers that, multiplied together, make the argument.
factorizations :: Int -> Array Int
factorizations n = factorizations' 2 n []
where
factorizations' :: Int -> Int -> Array Int -> Array Int
factorizations' _ 1 result = result

factorizations' divisor dividend result =
let
remainder = rem dividend divisor
in
if remainder == 0 then
factorizations' (divisor) (quot dividend divisor) (cons divisor result)
else
factorizations' (divisor + 1) dividend result

allTrue :: Array Boolean -> Boolean
allTrue bools = foldl (\acc bool -> acc && bool) true bools

exclusiveOrThenTrue :: Array Boolean -> Boolean
exclusiveOrThenTrue bools = foldl (==) false bools

-- | The fib routine in tail recursive form
fib :: Int -> Int
fib n = fib' n 0 0 1
where
fib' :: Int -> Int -> Int -> Int -> Int
fib' limit count n1 n2 =
if limit == count then
n1 + n2
else
fib' limit (count + 1) (n1 + n2) n1

reverse :: ∀ a. Array a -> Array a
reverse = foldl (\xs x -> [ x ] <> xs) []

-- Section for : A Virtual Filesystem exercise
allFiles :: Path -> Array Path
allFiles file =
file
: do
child <- ls file
allFiles child

onlyFiles :: Path -> Array Path
onlyFiles p = filter (\p' -> not $ isDirectory p') $ allFiles p

maxSigned32BitInt :: Int
maxSigned32BitInt = 2147483647

largestSmallest :: Path -> Array (Tuple String Int)
largestSmallest path = largestSmallestPaths (allFiles path)
where
largestSmallestPaths :: Array Path -> Array (Tuple String Int)
largestSmallestPaths paths = [ outlier (\i j -> i > j) 0 paths, outlier (\i j -> i < j) maxSigned32BitInt paths ]
where
outlier :: (Int -> Int -> Boolean) -> Int -> Array Path -> Tuple String Int
outlier criteria startValue paths' =
foldl
( \acc p' ->
( case size p' of
Just n -> if criteria n $ snd acc then Tuple (filename p') n else acc
Nothing -> acc
)
)
(Tuple "" startValue)
paths'

allSizes :: Array Path -> Array (Tuple String Int)
allSizes paths =
map
( \p -> case size p of
Just n -> Tuple (filename p) n
Nothing -> Tuple (filename p) 0
)
paths

whereIs :: String -> Maybe String
whereIs fileName = head $ whereIs' $ allFiles root
where
whereIs' :: Array Path -> Array String
whereIs' paths = do
path <- paths
child <- ls path
guard $ eq fileName $ fromMaybe "" $ last $ split (Pattern "/") $ filename child
pure $ filename path
5 changes: 1 addition & 4 deletions exercises/chapter6/test/Main.purs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Data.Hashable (hash)
import Data.List (List(..), (:))
import Effect (Effect)
import Partial.Unsafe (unsafePartial)
import Test.Solutions (Complex(..), Extended(..), Hour(..), Multiply(..), NonEmpty(..), OneMore(..), Self(..), act)
import Test.Solutions (Complex(..), Extended(..), Hour(..), Multiply(..), NonEmpty(..), OneMore(..), Self(..), act, arrayHasDuplicates, unsafeMaximum)
import Test.Unit (suite, test)
import Test.Unit.Assert as Assert
import Test.Unit.Main (runTest)
Expand All @@ -16,8 +16,6 @@ main =
runTest do
test "Initial passing test"
$ Assert.equal true true

{- Move this block comment starting point to enable more tests
-- Tests for the first exercise in this chapter (Show Shape)
-- can be found at the end of the previous chapter (chapter 5).
suite "Exercise Group 1" do
Expand Down Expand Up @@ -186,4 +184,3 @@ main =
$ Assert.equal (hash $ Hour 1)
$ hash
$ Hour 14
-}
Loading