Sparkline in unicode: Difference between revisions

→‎{{header|Python}}: Redraft of second Python version.
(→‎{{header|Python}}: Redraft of second Python version.)
Line 1,629:
 
 
Or, by functional composition: of pure functions,
 
with type comments for the reader, rather than the compiler:
<lang python>import re
 
 
# sparkLine :: [NumFloat] -> [String]
def sparkLine(xs):
(rng, lo) =def rangeFromgo(xs):
unit = rng / 7ys = sorted(xs)
mn, mx = ys[0], ys[-1]
return ''.join(map(
lambda n: chr(9601= + intlen((n - lo) / unit)xs),
xsmid = n // 2
w = (mx - mn) / 8
))
lbounds = list(map(lambda i: mn + (w * i), range(1, 8)))
return [
''.join(map(
lambda x: maybe('█')(
lambda i: '▁▂▃▄▅▆▇'[i]
)(findIndex(lambda b: b > x)(lbounds)),
xs
)),
' '.join(map(str, xs)),
'\t'.join([
'Min ' + str(mn),
'Mean ' + str(round(mean(xs), 2)),
'Median ' + str(
(ys[mid - 1] + ys[mid]) / 2 if even(n) else (
ys[mid]
)
),
'Max ' + str(mx)
]),
''
]
return go(xs) if xs else []
 
 
# main :: IO ()
# TEST ----------------------------------------------------
def main():
for x in map(
lambda s: sparkLine(readFloats(s)),
[
"0, 1, 19, 20",
"0, 999, 4000, 4999, 7000, 7999",
"1 2 3 4 5 6 7 8 7 6 5 4 3 2 1",
"1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5"
]
):
print ('\n'.join(x))
 
# sparkAndStats :: String -> String
def sparkAndStats(s):
xs = readFloats(s)
(rng, lo) = rangeFrom(xs)
return sparkLine(xs).ljust(16) + '\n' + \
str(len(xs)).rjust(3) + \
' data points in range' + \
str(lo).rjust(8) + ' to ' + str(lo + rng).rjust(6)
 
# GENERIC -------------------------------------------------
 
# main :: IO ()
def main():
print (
unlines(
map(
sparkAndStats,
[
'1 2 3 4 5 6 7 8 7 6 5 4 3 2 1',
'1.5, 0.5 3.5, 2.5 5.5, 4.5 7.5, 6.5',
'3 2 1 0 -1 -2 -3 -4 -3 -2 -1 0 1 2 3',
'-1000 100 1000 500 200 -400 -700 621 -189 3'
]
)
)
)
 
# Just :: a -> Maybe a
def Just(x):
return {'type': 'Maybe', 'Nothing': False, 'Just': x}
 
# GENERIC FUNCTIONS ---------------------------------------
 
# Nothing :: Maybe a
def Nothing():
return {'type': 'Maybe', 'Nothing': True}
 
 
# rangeFrom :: [Float] -> Float
# even :: Int -> Bool
def rangeFrom(xs):
def even(x):
lo = min(xs)
return (max(xs)0 -== lo,x lo)% 2
 
 
# findIndex :: (a -> Bool) -> [a] -> Maybe Int
def findIndex(p):
def go(xs):
try:
return Just(next(
i for i, v in enumerate(xs) if p(v)
))
except StopIteration:
return Nothing()
return lambda xs: go(xs)
 
 
# maybe :: b -> (a -> b) -> Maybe a -> b
def maybe(v):
return lambda f: lambda m: v if m.get('Nothing') else (
f(m.get('Just'))
)
 
 
# mean :: [Num] -> Float
def mean(xs):
return sum(xs) / float(len(xs))
 
 
Line 1,689 ⟶ 1,731:
 
 
# TEST -------------------------------------------------
# unlines :: [String] -> String
def unlines(xs):
return '\n'.join(xs)
 
 
# MAIN -------------------
if __name__ == '__main__':
main()</lang>
{{Out}}
<pre>▁▁██
<pre>▁▂▃▄▅▆▇█▇▆▅▄▃▂▁
0.0 1.0 19.0 20.0
15 data points in range 1.0 to 8.0
Min 0.0 Mean 10.0 Median 10.0 Max 20.0
▂▁▄▃▆▅█▇
 
8 data points in range 0.5 to 7.5
▁▁▅▅██
█▇▆▅▄▃▂▁▂▃▄▅▆▇█
0.0 999.0 4000.0 4999.0 7000.0 7999.0
15 data points in range -4.0 to 3.0
Min 0.0 Mean 4166.17 Median 4499.5 Max 7999.0
▁▄█▆▅▃▂▆▃▄
 
10 data points in range -1000.0 to 1000.0</pre>
▁▂▃▄▅▆▇█▇▆▅▄▃▂▁
1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 7.0 6.0 5.0 4.0 3.0 2.0 1.0
Min 1.0 Mean 4.27 Median 4.0 Max 8.0
 
▂▁▄▃▆▅█▇
1.5 0.5 3.5 2.5 5.5 4.5 7.5 6.5
Min 0.5 Mean 4.0 Median 4.0 Max 7.5</pre>
 
=={{header|REXX}}==
9,655

edits