Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

We’re showing branches in this repository, but you can also compare across forks.

base fork: mndrix/clk
base: a20ab57c12
...
head fork: mndrix/clk
compare: a7bb398c31
  • 2 commits
  • 2 files changed
  • 0 commit comments
  • 1 contributor
Commits on Feb 21, 2012
Michael Hendricks Build a pie chart summarizing work by category
This graphic should help me control how much time I spend on overhead
and email.  It also helps me restrain my 20% time to only 20% of my
work hours.

classify/3 (11 lines long) is the only part that's really suited to
Mercury.  It probably would have been much more succinct to write this
report in Perl.  String munging, hash table maintenance and IO
dominate.
3a3ad1f
Michael Hendricks Clean up pie report
Using a more functional style makes the code easier to read and also
made determinism easier to deal with.  The trick was slurping all
input lines into memory and then operating over them purely.
Separating IO from computation seems to help a lot.
a7bb398
Showing with 82 additions and 0 deletions.
  1. +3 −0  .gitignore
  2. +79 −0 clk-report-pie.m
3  .gitignore
View
@@ -1,4 +1,7 @@
+Mercury/
*.hi
*.o
*.exe
*.swp
+*.err
+*.mh
79 clk-report-pie.m
View
@@ -0,0 +1,79 @@
+:- module 'clk-report-pie'.
+
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+:- import_module assoc_list.
+:- import_module exception, float, int, list, map, math, parser, string, term.
+
+:- type summary == map(string,float).
+
+main(!IO) :-
+ command_line_arguments(Args,!IO),
+ ( [File]=Args -> see(File,_,!IO) ; true ),
+ slurp(Lines, !IO),
+ filter_map(parse_line, Lines, Entries),
+ foldl( group_by, Entries, init, Summary ),
+ display_graph(Summary, !IO).
+
+:- pred slurp(list(string)::out, io::di, io::uo) is det.
+slurp(Lines, !IO) :-
+ slurp_([],Backwards,!IO),
+ reverse(Backwards,Lines).
+slurp_(Accum,Out,!IO) :-
+ read_line_as_string(Result,!IO),
+ ( eof = Result, Out = Accum
+ ; error(X) = Result, throw(X)
+ ; ok(L) = Result, slurp_([chomp(L)|Accum],Out,!IO)
+ ).
+
+:- pred parse_line(string::in,{string,float}::out) is semidet.
+parse_line(Line,{Group,Duration}) :-
+ [_,_,Seconds,TagsString,Message] = split_at_char('\t', Line),
+ remove_suffix(Seconds,"s",DurationString),
+ to_float(DurationString,Duration),
+ Tags = (TagsString = "" -> [] ; split_at_char(',',TagsString)),
+ Group = (if classify(Tags,Message,G) then G else "other: "++Message),
+ \+ Group = "out".
+
+:- pred display_graph(summary::in,io::di,io::uo) is det.
+display_graph(Summary, !IO) :-
+ foldl_values(max_p, Summary, 0.0, Max),
+ foldl_values(sum_p, Summary, 0.0, Sum),
+ keys_and_values( to_assoc_list(Summary), Ks, Vs),
+ Values = map(float_to_string, Vs),
+ Keys = map_corresponding(
+ (func(K,V)=C:-format("%s (%.0f%%)",[s(K),f(100.0*V/Sum)],C)),
+ Ks, Vs),
+ format(
+ "open 'https://chart.googleapis.com/chart?chds=0,%.0f&cht=p&chs=700x300&chd=t:%s&chl=%s'",
+ [
+ f(Max),
+ s(join_list(",",Values)),
+ s(join_list("|",Keys))
+ ],
+ Cmd
+ ),
+ call_system(Cmd, _, !IO).
+:- pred max_p(float::in,float::in,float::out) is det.
+max_p(X,Y,Z) :- Z = max(X,Y).
+:- pred sum_p(float::in,float::in,float::out) is det.
+sum_p(X,Y,Z) :- Z = X+Y.
+
+:- pred group_by({string,float}::in,summary::in,summary::out) is det.
+group_by({Group,Duration},!Summary) :-
+ OldDuration = (if search(!.Summary,Group,D) then D else 0.0),
+ set(Group,OldDuration+Duration,!Summary).
+
+:- pred classify(list(string)::in,string::in,string::out) is semidet.
+classify([],"out","out").
+classify(["ndrix"],"email","email").
+classify(["ndrix","research"],_,"twenty").
+classify(["ndrix","20"],_,"twenty").
+classify(["ndrix","coincard"],_,"twenty").
+classify(["jjgames"|_],_,"jjgames").
+classify(["scs"|_],_,"scs").
+classify(["vgpc"|_],_,"vgpc").

No commit comments for this range

Something went wrong with that request. Please try again.