Statistics
| Branch: | Tag: | Revision:

root / Ganeti / HTools / Utils.hs @ 7bc82927

History | View | Annotate | Download (2.7 kB)

1 e4f08c46 Iustin Pop
{-| Utility functions -}
2 e4f08c46 Iustin Pop
3 209b3711 Iustin Pop
module Ganeti.HTools.Utils
4 209b3711 Iustin Pop
    (
5 209b3711 Iustin Pop
      debug
6 209b3711 Iustin Pop
    , sepSplit
7 209b3711 Iustin Pop
    , varianceCoeff
8 209b3711 Iustin Pop
    , readData
9 3d7cd10b Iustin Pop
    , commaJoin
10 9ba5c28f Iustin Pop
    , readEitherString
11 9ba5c28f Iustin Pop
    , loadJSArray
12 9ba5c28f Iustin Pop
    , fromObj
13 3f6af65c Iustin Pop
    , asJSObject
14 3f6af65c Iustin Pop
    , asObjectList
15 942403e6 Iustin Pop
    , fromJResult
16 209b3711 Iustin Pop
    ) where
17 e4f08c46 Iustin Pop
18 29ac5975 Iustin Pop
import Data.List
19 942403e6 Iustin Pop
import Control.Monad
20 dd4c56ed Iustin Pop
import System
21 dd4c56ed Iustin Pop
import System.IO
22 942403e6 Iustin Pop
import qualified Text.JSON as J
23 9ba5c28f Iustin Pop
import Text.Printf (printf)
24 e4f08c46 Iustin Pop
25 e4c5beaf Iustin Pop
import Ganeti.HTools.Types
26 e4c5beaf Iustin Pop
27 e4f08c46 Iustin Pop
import Debug.Trace
28 e4f08c46 Iustin Pop
29 e4f08c46 Iustin Pop
-- | To be used only for debugging, breaks referential integrity.
30 e4f08c46 Iustin Pop
debug :: Show a => a -> a
31 e4f08c46 Iustin Pop
debug x = trace (show x) x
32 e4f08c46 Iustin Pop
33 1b7cf8ca Iustin Pop
34 5aa48dbe Iustin Pop
fromJResult :: Monad m => J.Result a -> m a
35 5aa48dbe Iustin Pop
fromJResult (J.Error x) = fail x
36 5aa48dbe Iustin Pop
fromJResult (J.Ok x) = return x
37 1b7cf8ca Iustin Pop
38 e4f08c46 Iustin Pop
-- | Comma-join a string list.
39 e4f08c46 Iustin Pop
commaJoin :: [String] -> String
40 e4f08c46 Iustin Pop
commaJoin = intercalate ","
41 e4f08c46 Iustin Pop
42 e4f08c46 Iustin Pop
-- | Split a string on a separator and return an array.
43 e4f08c46 Iustin Pop
sepSplit :: Char -> String -> [String]
44 e4f08c46 Iustin Pop
sepSplit sep s
45 e4f08c46 Iustin Pop
    | x == "" && xs == [] = []
46 e4f08c46 Iustin Pop
    | xs == []            = [x]
47 e4f08c46 Iustin Pop
    | ys == []            = x:"":[]
48 e4f08c46 Iustin Pop
    | otherwise           = x:(sepSplit sep ys)
49 e4f08c46 Iustin Pop
    where (x, xs) = break (== sep) s
50 e4f08c46 Iustin Pop
          ys = drop 1 xs
51 e4f08c46 Iustin Pop
52 e4f08c46 Iustin Pop
-- | Partial application of sepSplit to @'.'@
53 e4f08c46 Iustin Pop
commaSplit :: String -> [String]
54 e4f08c46 Iustin Pop
commaSplit = sepSplit ','
55 e4f08c46 Iustin Pop
56 e4f08c46 Iustin Pop
-- Simple and slow statistical functions, please replace with better versions
57 e4f08c46 Iustin Pop
58 e4f08c46 Iustin Pop
-- | Mean value of a list.
59 e4f08c46 Iustin Pop
meanValue :: Floating a => [a] -> a
60 e4f08c46 Iustin Pop
meanValue lst = (sum lst) / (fromIntegral $ length lst)
61 e4f08c46 Iustin Pop
62 e4f08c46 Iustin Pop
-- | Standard deviation.
63 e4f08c46 Iustin Pop
stdDev :: Floating a => [a] -> a
64 e4f08c46 Iustin Pop
stdDev lst =
65 e4f08c46 Iustin Pop
    let mv = meanValue lst
66 e4f08c46 Iustin Pop
        square = (^ (2::Int)) -- silences "defaulting the constraint..."
67 e4f08c46 Iustin Pop
        av = sum $ map square $ map (\e -> e - mv) lst
68 e4f08c46 Iustin Pop
        bv = sqrt (av / (fromIntegral $ length lst))
69 e4f08c46 Iustin Pop
    in bv
70 e4f08c46 Iustin Pop
71 e4f08c46 Iustin Pop
-- | Coefficient of variation.
72 e4f08c46 Iustin Pop
varianceCoeff :: Floating a => [a] -> a
73 e4f08c46 Iustin Pop
varianceCoeff lst = (stdDev lst) / (fromIntegral $ length lst)
74 dd4c56ed Iustin Pop
75 942403e6 Iustin Pop
-- | Get an Ok result or print the error and exit
76 942403e6 Iustin Pop
readData :: Result a -> IO a
77 942403e6 Iustin Pop
readData nd =
78 942403e6 Iustin Pop
    (case nd of
79 942403e6 Iustin Pop
       Bad x -> do
80 942403e6 Iustin Pop
         putStrLn x
81 dd4c56ed Iustin Pop
         exitWith $ ExitFailure 1
82 942403e6 Iustin Pop
       Ok x -> return x)
83 9ba5c28f Iustin Pop
84 5aa48dbe Iustin Pop
readEitherString :: (Monad m) => J.JSValue -> m String
85 9ba5c28f Iustin Pop
readEitherString v =
86 9ba5c28f Iustin Pop
    case v of
87 5aa48dbe Iustin Pop
      J.JSString s -> return $ J.fromJSString s
88 5aa48dbe Iustin Pop
      _ -> fail "Wrong JSON type"
89 9ba5c28f Iustin Pop
90 5aa48dbe Iustin Pop
loadJSArray :: (Monad m) => String -> m [J.JSObject J.JSValue]
91 942403e6 Iustin Pop
loadJSArray s = fromJResult $ J.decodeStrict s
92 9ba5c28f Iustin Pop
93 5aa48dbe Iustin Pop
fromObj :: (J.JSON a, Monad m) => String -> J.JSObject J.JSValue -> m a
94 9ba5c28f Iustin Pop
fromObj k o =
95 942403e6 Iustin Pop
    case lookup k (J.fromJSObject o) of
96 585d4420 Iustin Pop
      Nothing -> fail $ printf "key '%s' not found in %s" k (show o)
97 942403e6 Iustin Pop
      Just val -> fromJResult $ J.readJSON val
98 9ba5c28f Iustin Pop
99 5aa48dbe Iustin Pop
asJSObject :: (Monad m) => J.JSValue -> m (J.JSObject J.JSValue)
100 5aa48dbe Iustin Pop
asJSObject (J.JSObject a) = return a
101 5aa48dbe Iustin Pop
asJSObject _ = fail "not an object"
102 942403e6 Iustin Pop
103 5aa48dbe Iustin Pop
asObjectList :: (Monad m) => [J.JSValue] -> m [J.JSObject J.JSValue]
104 942403e6 Iustin Pop
asObjectList = sequence . map asJSObject