diff options
| author | Simon Proctor <simon.proctor@zpg.co.uk> | 2019-10-28 14:08:38 +0000 |
|---|---|---|
| committer | Simon Proctor <simon.proctor@zpg.co.uk> | 2019-10-28 14:08:38 +0000 |
| commit | 703cfbab1a0be3847f83ab7e1b9b07c64aca3f01 (patch) | |
| tree | 49921ac6912c1c7061e42c055c1559895b7f8aa0 | |
| parent | b1e98f68aa91f041d7e83034bd9b98a08e6b9ca0 (diff) | |
| download | perlweeklychallenge-club-703cfbab1a0be3847f83ab7e1b9b07c64aca3f01.tar.gz perlweeklychallenge-club-703cfbab1a0be3847f83ab7e1b9b07c64aca3f01.tar.bz2 perlweeklychallenge-club-703cfbab1a0be3847f83ab7e1b9b07c64aca3f01.zip | |
Graph all the things
| -rw-r--r-- | challenge-032/simon-proctor/all.csv | 7 | ||||
| -rw-r--r-- | challenge-032/simon-proctor/all.txt | 7 | ||||
| -rw-r--r-- | challenge-032/simon-proctor/perl6/ch-2.p6 | 84 |
3 files changed, 98 insertions, 0 deletions
diff --git a/challenge-032/simon-proctor/all.csv b/challenge-032/simon-proctor/all.csv new file mode 100644 index 0000000000..a9dc63c1c6 --- /dev/null +++ b/challenge-032/simon-proctor/all.csv @@ -0,0 +1,7 @@ +"apple",29 +"cherry",29 +"strawberry",28 +"lime",24 +"pear",23 +"lemon",22 +"banana",1 diff --git a/challenge-032/simon-proctor/all.txt b/challenge-032/simon-proctor/all.txt new file mode 100644 index 0000000000..1c38af6052 --- /dev/null +++ b/challenge-032/simon-proctor/all.txt @@ -0,0 +1,7 @@ +cherry 29 +apple 29 +strawberry 28 +lime 24 +pear 23 +lemon 22 +banana 1 diff --git a/challenge-032/simon-proctor/perl6/ch-2.p6 b/challenge-032/simon-proctor/perl6/ch-2.p6 new file mode 100644 index 0000000000..6e497adf27 --- /dev/null +++ b/challenge-032/simon-proctor/perl6/ch-2.p6 @@ -0,0 +1,84 @@ +#!/usr/bin/env perl6 + +use v6; + +enum SortType <value key>; +enum SortDir <asc desc>; +subset ValidFile of Str where *.IO.f; +my %*SUB-MAIN-OPTS = :named-anywhere; + +#| Print help text +multi sub MAIN( Bool :h($help) where so * ) { + say $*USAGE; +} + +sub read-data( IO::CatHandle $files, Bool $csv ) { + my &line-reader = $csv ?? &parse-csv !! &parse-space-sep; + my %results := BagHash.new(); + $files.lines.map( &line-reader ).map( -> ( $k, $v ) { %results{$k} = $v } ); + return %results; +} + +#| Read data from standard out. +#| Prints a bar chart of the data +multi sub MAIN( + Bool :$csv = False, #= Input in CSV + SortType :$sort-type=value, #= Sort Type + SortDir :$sort-dir=desc, #= Sort Direction +) { + draw-graph( read-data( IO::CatHandle.new( $*IN ), $csv ), $sort-type, $sort-dir ); +} + +#| Given a list of filenames reads each in turn +multi sub MAIN( + *@files where all(@files) ~~ ValidFile, #= Files to read + Bool :$csv = False, #= Output in CSV + SortType :$sort-type=value, #= Sort Type + SortDir :$sort-dir=desc, #= Sort Direction +) { + draw-graph( read-data( IO::CatHandle.new( @files ), $csv ), $sort-type, $sort-dir ); +} + +sub draw-graph( %data, SortType $sort-type, SortDir $sort-dir ) { + my $k-width = %data.keys.map(*.codes).max; + my $max-val = %data.values.max; + my $screen-width = get-screen-width(); + + my &sorter = make-sorter( $sort-type, $sort-dir ); + + my $available = $screen-width - $k-width - 5; + .say for %data.sort( &sorter ).map( { sprintf( "% -{$k-width}s | %s", $_.key, get-bar( $available, $max-val, $_.value ) ) } ); +} + +sub make-sorter( SortType $sort-type, SortDir $sort-dir ) { + given $sort-dir { + when asc { + -> $a, $b { $a.^lookup($sort-type)($a) cmp $b.^lookup($sort-type)($b) } + } + when desc { + -> $a, $b { $b.^lookup($sort-type)($b) cmp $a.^lookup($sort-type)($a) } + } + } +} + +sub get-bar( Int $available, $max, $value ) { + '#' x ceiling( $available * ( $value / $max ) ); +} + +sub get-screen-width() { + run("tput","cols",:out).out.slurp.chomp; +} + +sub parse-space-sep( Str $line ) { + if ( my $match = $line ~~ m!^ (\S+) \s+ (\S+) $! ) { + return $match[0], $match[1]; + } + die "Line parser didn't work on $line"; +} + +sub parse-csv( Str $line ) { + if ( my $match = $line ~~ m!^ (\"?) (.+) $0 "," (.+) $! ) { #" Editor bug + return $match[1], $match[2]; + } + die "Lazy CSV parser didn't work on $line"; +} |
