Skip to content

Instantly share code, notes, and snippets.

@dgulino
Last active December 12, 2015 09:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dgulino/4750139 to your computer and use it in GitHub Desktop.
Save dgulino/4750139 to your computer and use it in GitHub Desktop.
Output chunked average of numeric stream The main use case is when I'm looking into a problem, and tailing a log. Too much data. Awk/perl/pyline the interesting numbers and tail that. Numbers running too fast or changing too often to see a pattern. So I then pipe the number stream through a block average and then to tgraph. tail -f some.log | aw…
#!/usr/bin/env escript
%% -*- erlang -*-
%%! -smp disable
%% Author: Drew Gulino
-module(runavg).
-export([main/1]).
main(CmdLine) ->
OptSpecList = option_spec_list(),
case getopt:parse(OptSpecList, CmdLine) of
{ok, {Options, NonOptArgs}} ->
true;
{error, {Reason, Data}} ->
Options = [],
NonOptArgs = [],
io:format("Error: ~s ~p~n~n", [Reason, Data]),
version(),
getopt:usage(OptSpecList, "runavg")
end,
SampleSize = get_opt_value(size,Options),
OutputInterval = get_opt_value(interval,Options),
case NonOptArgs of
[] ->
F = standard_io;
_ ->
{ok, F} = file:open(NonOptArgs, read)
end,
%io:format("~p,~p,~p~n",[F, SampleSize, OutputInterval]),
proc_file(F, SampleSize, OutputInterval ).
proc_file(F, SampleSize, OutputInterval) ->
%io:format("1"),
proc_file(F, SampleSize, OutputInterval, [], 0, 0).
proc_file(F, SampleSize, OutputInterval, SampleAcc, SampleCount, IntervalCount) when IntervalCount >= OutputInterval ->
io:format("~.2f~n",[lists:sum(SampleAcc)/erlang:length(SampleAcc)]),
proc_file(F, SampleSize, OutputInterval, SampleAcc, SampleCount, 0);
proc_file(F, SampleSize, OutputInterval, [_|T] , SampleCount, IntervalCount) when SampleCount >= SampleSize ->
%io:format("T: ~p~n",[T]),
proc_file(F, SampleSize, OutputInterval, T, SampleCount - 1, IntervalCount);
proc_file(F, SampleSize, OutputInterval, SampleAcc, SampleCount, IntervalCount) ->
%io:format("SampleAcc: ~p~n", [SampleAcc]),
L = io:get_line(F, ''),
case L of
eof ->
ok;
"\n" ->
false;
Line ->
Stripped = strip_newlines(Line),
Num = cast_to_integer(Stripped),
proc_file(F, SampleSize, OutputInterval, [Num] ++ SampleAcc, SampleCount + 1, IntervalCount + 1)
end.
version() ->
io:format("Version: 1.0\n").
get_opt_value(Key, Options) ->
case lists:keyfind(Key,1,Options) of
{Key, Value} ->
Value
end,
Value.
option_spec_list() ->
[
%% {Name, ShortOpt, LongOpt, ArgSpec, HelpMsg}
{help, $h, "help", undefined, "Show the program options"},
{version, $v, "version", undefined, "Version"},
{size, $s, "size", {integer, 5}, "Size of average sample, Default=5"},
{interval, $i, "interval", {integer, 5}, "How many input entries before average is displayed, Default=5"}
].
strip_newlines(String) ->
string:strip(re:replace(String,"(.*)[\n\r]","\\1", [global,{return,list}])).
cast_to_integer([]) ->
[];
cast_to_integer(Input) when is_integer(Input) ->
Input;
cast_to_integer(Input) when is_float(Input) ->
erlang:round(Input);
cast_to_integer(Input) when is_list(Input)->
case lists:member($., Input) of
true ->
erlang:round(erlang:list_to_float(Input));
false ->
erlang:list_to_integer(Input)
end.
#!/usr/bin/env escript
%% -*- erlang -*-
%%! -smp disable
%% Author: Drew Gulino
-module(test_rand_stream).
-export([main/1]).
main(_) ->
{A1,A2,A3} = now(),
random:seed(A1, A2, A3),
rand().
rand() ->
Num = random:uniform(100),
io:format("~B~n",[Num]),
rand().
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment