typestar

temp_stats.hs in Haskell

Reports a week of daily highs with the low, high, mean, and a bar chart beside each day.

-- Daily highs in degrees Fahrenheit for one week.
week :: [(String, Int)]
week =
  [ ("Mon", 63), ("Tue", 71), ("Wed", 68), ("Thu", 74)
  , ("Fri", 80), ("Sat", 77), ("Sun", 66)
  ]

highs :: [Int]
highs = map snd week

mean :: [Int] -> Double
mean [] = 0
mean xs = fromIntegral (sum xs) / fromIntegral (length xs)

-- One block per two degrees above the coldest day keeps bars short.
bar :: Int -> Int -> String
bar base t = replicate (1 + (t - base) `div` 2) '#'

-- A day is marked against the weekly mean, not against its neighbors.
mark :: Double -> Int -> Char
mark avg t
  | fromIntegral t > avg = '+'
  | fromIntegral t < avg = '-'
  | otherwise = '='

oneDecimal :: Double -> String
oneDecimal x = show whole ++ "." ++ show frac
  where
    (whole, frac) = round (x * 10) `divMod` (10 :: Int)

pad :: Int -> String -> String
pad n s = s ++ replicate (n - length s) ' '

lpad :: Int -> String -> String
lpad n s = replicate (n - length s) ' ' ++ s

row :: Double -> Int -> (String, Int) -> String
row avg base (day, t) =
  pad 5 day ++ lpad 4 (show t) ++ "  " ++ [mark avg t]
    ++ "  " ++ bar base t

rule :: String
rule = replicate 26 '-'

main :: IO ()
main = do
  let avg = mean highs
      coldest = minimum highs
      warmest = maximum highs
  putStrLn "weekly highs, degrees F"
  putStrLn (pad 5 "day" ++ lpad 4 "high" ++ "  vs  chart")
  putStrLn rule
  mapM_ (putStrLn . row avg coldest) week
  putStrLn rule
  putStrLn (pad 5 "low" ++ lpad 4 (show coldest))
  putStrLn (pad 5 "high" ++ lpad 4 (show warmest))
  putStrLn (pad 5 "mean" ++ lpad 6 (oneDecimal avg))
  putStrLn (pad 5 "range" ++ lpad 4 (show (warmest - coldest)))

How it works

  1. mean highs averages the week, and minimum highs fixes the baseline the bars grow from.
  2. mark avg t yields '+', '-', or '=' according to how that day compares with the mean.
  3. row builds each line from pad 5 day ++ lpad 4 (show t) followed by the mark and the bar.

Keywords and builtins used here

The run, in numbers

Lines
58
Characters to type
1590
Tokens
415
Three-star pace
80 tpm

At the three-star pace of 80 tokens a minute, this run takes about 311 seconds.

Type this snippet

Step 3 of 3 in Encore, step 27 of 27 in Language basics.

← Previous