import Data.List -- Exercise 7.1, Part 1 webData :: [String] webData = ["Youtube", "Google", "Facebook", "Youtube", "Facebook", "Youtube", "Facebook", "Google", "Youtube"] {- 7.1.1 Write a function that returns a list with unique websites occuring in a dataset like webData -} -- uniqueWebsites :: uniqueWebsites = undefined {- 7.1.2 Write a higher-order function that counts the number of times a website occurs in a dataset like webData -} -- count :: count website = undefined {- 7.1.3 Write a function that returns the ranking of website visits using the count and uniqueWebsites functions -} -- result :: result = undefined -- Exercise 7.1, Part 2 webDataDuration :: [(String, Double)] webDataDuration = [("Youtube", 2.5), ("Google", 23.2), ("Facebook", 23.2), ("Youtube", 3.4), ("Facebook", 4.5), ("Youtube", 34.5), ("Facebook", 33.2),("Google", 34.3), ("Youtube", 12.4)] {- 7.1.4 Write a new function to retrieve a list with unique websites occuring in a dataset like webDataDuration -} -- uniqueWebsites2 :: uniqueWebsites2 = undefined {- 7.1.5 Write a new function that returns the total time website has been visited based on a dataset like webDataDuration -} -- count2 :: count2 = undefined {- 7.1.6 Write a higher-order function, similar to result, such that it can be used for the webData and webDataDuration dataset by turning it into a higher-order function -} -- result2 :: result2 = undefined {- 7.2.1 define datatypes for our points in the coordinate systems -} data Polar data Cart -- createPolar :: createPolar r phi = undefined {- 7.2.2 Write a function which converts Cart into a Tuple -} -- cart2Tuple :: cart2Tuple = undefined -- polar2Cart :: polar2Tuple = undefined {- 7.2.3 define conversion functions between the coordinate systems -} polar2Cart :: Polar -> Cart polar2Cart p = undefined cart2Polar :: Cart -> Polar cart2Polar c = undefined {- TESTS -} {- Test Webdata Exercise -} testFunEq :: (Show a,Show b,Eq c) => (b -> c) -> (a -> b) -> [(a,b)] -> Bool testFunEq eq f = all (\p -> eq (f (fst p)) == eq (snd p) || error ("on input "++(show (fst p))++" output is "++(show (f (fst p)))++" but should be "++(show (snd p)))) testFun :: (Show a,Show b,Eq b) => (a -> b) -> [(a,b)] -> Bool testFun = testFunEq id testFunFract f = all (\p -> abs ((f (fst p)) - snd p) < 1e-6 || error ("on input "++(show (fst p))++" output is "++(show (f (fst p)))++" but should be "++(show (snd p)))) testFun2 testFun f l = testFun (\p -> f (fst p) (snd p)) (map (\(x,y,z) -> ((x,y),z)) l) splitter [] = [] splitter xs = case span (\ (a,_) -> a == fst (head xs)) xs of (as, rest) -> (fst $ head xs, sort (map snd as)) : splitter rest ioTestWebData = ["Facebook", "Google", "Google", "Facebook", "Youtube", "Twitter", "Twitter", "Facebook", "Google", "Google", "Facebook", "Twitter"] testUniqueWebsites = testFunEq sort uniqueWebsites [(webData, ["Google","Facebook","Youtube"]), (ioTestWebData, ["Facebook", "Google", "Youtube", "Twitter"])] testCount = testFun2 testFun count [("Google", webData, 2), ("Youtube", webData, 4), ("Facebook", webData, 3), ("Fake", webData, 0), ("Facebook", ioTestWebData, 4), ("Google", ioTestWebData, 4), ("Youtube", ioTestWebData, 1), ("Twitter", ioTestWebData, 3)] testResult = testFunEq splitter result [(webData, [(4,"Youtube"),(3,"Facebook"),(2,"Google")]), (ioTestWebData, [(4,"Google"),(4,"Facebook"),(3,"Twitter"),(1,"Youtube")])] ioTestWebDataDuration :: [(String, Float)] ioTestWebDataDuration = [("Facebook", 24.3), ("Facebook", 22.2), ("Twitter", 32.2), ("Youtube", 12.3), ("Youtube", 53.3), ("Twitter", 22.3)] testUniqueWebsites2_Double = testFunEq sort uniqueWebsites2 [(webDataDuration, ["Google", "Facebook", "Youtube"])] testUniqueWebsites2_Float = testFunEq sort uniqueWebsites2 [(ioTestWebDataDuration, ["Facebook", "Twitter", "Youtube"])] testCount2_Double = testFun2 testFunFract count2 [("Google", webDataDuration, 57.5), ("Facebook", webDataDuration, 60.9), ("Youtube", webDataDuration, 52.8), ("Fake", webDataDuration, 0.0)] testCount2_Float = testFun2 testFunFract count2 [("Youtube", ioTestWebDataDuration, 65.6), ("Twitter", ioTestWebDataDuration, 54.5), ("Facebook", ioTestWebDataDuration, 46.5)] testResult2_WebData = testFunEq splitter (result2 count uniqueWebsites) [(webData, [(4,"Youtube"),(3,"Facebook"),(2,"Google")]), (ioTestWebData, [(4,"Google"),(4,"Facebook"),(3,"Twitter"),(1,"Youtube")])] testFunResult2 f = all (\(dataset, idx, count, website) -> ((abs (fst (f dataset !! idx)) - count) < 1e-6 && (snd (f dataset !! idx)) == website) || error ("on input "++(show dataset)++".\n The result ranked on position "++(show idx)++ " is "++(show (f dataset !! idx))++" but should be "++(show (count, website)))) testResult2_Double = testFunResult2 (result2 count2 uniqueWebsites2) [(webDataDuration, 0, 60.9, "Facebook"), (webDataDuration, 1, 57.5, "Google"), (webDataDuration, 2, 52.8, "Youtube")] testResult2_Float = testFunResult2 (result2 count2 uniqueWebsites2) [(ioTestWebDataDuration, 0, (65.6 :: Float), "Youtube"), (ioTestWebDataDuration, 1, (54.5 :: Float), "Twitter"), (ioTestWebDataDuration, 2, (46.5 :: Float), "Facebook")] testAllWeb = testUniqueWebsites && testCount && testResult && testUniqueWebsites2_Double && testUniqueWebsites2_Float && testCount2_Double && testCount2_Float && testResult2_WebData && testResult2_Double && testResult2_Float {- Test Polar coordinates -} epsilon, radius, angle :: Double epsilon = 0.001 radius = sqrt 2 angle = 45 polar :: Polar polar = createPolar radius angle cart :: Cart cart = polar2Cart $ polar testCP = (\(r,a) -> r == radius && a == (angle / (180 / pi))) . polar2Tuple $ polar diff (r, p) (r', p') = (abs $ r - r') < epsilon && (abs $ p - p') < epsilon testConversionP = diff p mP where mP = polar2Tuple . cart2Polar . polar2Cart $ polar p = polar2Tuple $ polar testConversionC = diff c mC where mC = cart2Tuple . polar2Cart . cart2Polar $ cart c = cart2Tuple $ cart testConversionPT = diff (radius, angle / (180 / pi)) (polar2Tuple $ polar) testConversionCT = diff (1.0, 1.0) (cart2Tuple $ cart) testPolar = testCP && testConversionP && testConversionC && testConversionPT && testConversionCT testAll = testAllWeb && testPolar