aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad S Anwar <Mohammad.Anwar@yahoo.com>2019-10-07 00:58:21 +0100
committerGitHub <noreply@github.com>2019-10-07 00:58:21 +0100
commitfc740086b17d06acda0ac7dce959409ae529d82d (patch)
tree78207d49773b52f8f855b999f9289e2bbc2c1c23
parent102d2510fcc43bb6722801e4504a76ec2c22f07f (diff)
parentc4f59e7b721a8e4ffc2db93db7dc6292d7a6336d (diff)
downloadperlweeklychallenge-club-fc740086b17d06acda0ac7dce959409ae529d82d.tar.gz
perlweeklychallenge-club-fc740086b17d06acda0ac7dce959409ae529d82d.tar.bz2
perlweeklychallenge-club-fc740086b17d06acda0ac7dce959409ae529d82d.zip
Merge pull request #725 from dcw803/master
incorporated my solutions.. ch-1.pl is ridiculous, but
-rw-r--r--challenge-028/duncan-c-white/README47
-rwxr-xr-xchallenge-028/duncan-c-white/perl5/ch-1.pl48
-rwxr-xr-xchallenge-028/duncan-c-white/perl5/ch-2.pl228
3 files changed, 291 insertions, 32 deletions
diff --git a/challenge-028/duncan-c-white/README b/challenge-028/duncan-c-white/README
index 69197e921e..75c9f80743 100644
--- a/challenge-028/duncan-c-white/README
+++ b/challenge-028/duncan-c-white/README
@@ -1,36 +1,19 @@
-Challenge 1: "Write a script to find the intersection of two straight
-lines. The co-ordinates of the two lines should be provided as command
-line parameter. For example:
+Challenge 1: "Write a script to check the file content without explicitly
+reading the content. It should accept file name with path as command
+line argument and print 'The file content is binary.' or else 'The file
+content is ascii.' accordingly."
-The two ends of Line 1 are represented as co-ordinates (a,b) and (c,d).
+My notes: That's bafflingly unclear! Without "explicitly" reading
+the content, does that imply "implicitly" reading it is ok, or that
+we're really not supposed to read the content at all. In the former
+case, I guess we can run "file" and parse the outout. In the latter
+case, unless there's some magic metadata somewhere else, that only
+leaves file extensions. In that case, we just need a hash of file
+extension -> binary/ascii choices. Dull.
-The two ends of Line 2 are represented as co-ordinates (p,q) and (r,s).
-The script should print the co-ordinates of point of intersection of
-the above two lines."
+Challenge 2: "Write a script to display Digital Clock. Feel free to be
+as creative as you can when displaying digits. We expect bare minimum
+something like '14:10:11'"
-My notes: Clearly defined, very easy if I can remember the formulae - let's
-have a go.. after doing it, I decided to run Gnuplot to display the results
-as it's an intensely graphical concept..
-
-
-Challenge 2: "Write a script that allows you to capture/display historical
-data. It could be an object or a scalar. For example
-
- my $x = 10; $x = 20; $x -= 5;
-
-After the above operations, it should list $x historical value in order."
-
-My notes: The idea is easy, but we're not told the API to implement. I'm
-certainly not going to introspect into Perl to find out whenever a scalar
-variable is assigned to! I have chosen to implement this for numeric
-variables, using an input sequence of VARNAME OP VALUE triples (where OP='=',
-'+=', '-=', '*=', '/=' or '%='), where each input triple N occurs at time N,
-and we track the historic value of each variable over time.
-
-I did that, using __DATA__ (at the end of this file) for the default sequence,
-or the contents of a named input file if given.
-
-I also graphed the time-series results via Gnuplot as I seem to be having
-a Gnuplot kick this week:-) It's not really the ideal output format, but
-it's relatively cute.
+My notes: Sounds like a job for Tk:-)
diff --git a/challenge-028/duncan-c-white/perl5/ch-1.pl b/challenge-028/duncan-c-white/perl5/ch-1.pl
new file mode 100755
index 0000000000..cb4f7444b2
--- /dev/null
+++ b/challenge-028/duncan-c-white/perl5/ch-1.pl
@@ -0,0 +1,48 @@
+#!/usr/bin/perl
+#
+# Challenge 1: "Write a script to check the file content without explicitly
+# reading the content. It should accept file name with path as command
+# line argument and print 'The file content is binary.' or else 'The file
+# content is ascii.' accordingly."
+#
+# My notes: That's bafflingly unclear! Without "explicitly" reading
+# the content, does that imply "implicitly" reading it is ok, or that
+# we're really not supposed to read the content at all. In the former
+# case, I guess we can run "file" and parse the outout. In the latter
+# case, unless there's some magic metadata somewhere else, that only
+# leaves file extensions. In that case, we just need a hash of file
+# extension -> binary/ascii choices. Dull both ways. I'll do the latter."
+#
+#
+
+use v5.10; # to get "say"
+use strict;
+use warnings;
+use Function::Parameters;
+
+die "Usage: ch-1.pl FILENAME+\n" if @ARGV == 0;
+
+foreach my $filename (@ARGV)
+{
+ my $binary = ClassifyBinaryOrText( $filename );
+ say "file $filename is ", $binary?"binary":"text";
+}
+
+my %knownbinary = map { $_ => 1 }
+qw(tar gz bz2 tbz tbz2 tgz tar.gz tar.bz2 tar.bz Z tar.Z
+ zip jpg gif png cpio out a o);
+
+
+#
+# my $binary = ClassifyBinaryOrText( $filename );
+# Classify filename into binary or text without reading
+# the content =s (why???). So based on the extension then.
+# Returns 1 for binary, 0 for text.
+#
+fun ClassifyBinaryOrText( $filename )
+{
+ my $ext = $filename;
+ $ext =~ s|^[^.]+/\.|| or return 0;
+ return 1 if $knownbinary{$ext};
+ return 0;
+}
diff --git a/challenge-028/duncan-c-white/perl5/ch-2.pl b/challenge-028/duncan-c-white/perl5/ch-2.pl
new file mode 100755
index 0000000000..04fd92f06a
--- /dev/null
+++ b/challenge-028/duncan-c-white/perl5/ch-2.pl
@@ -0,0 +1,228 @@
+#!/usr/bin/perl
+#
+# Challenge 2: "Write a script to display Digital Clock. Feel free to be
+# as creative as you can when displaying digits. We expect bare minimum
+# something like '14:10:11'"
+#
+# My notes: Sounds like a job for Tk:-) in this version, after earlier
+# building a simple coloured-label clock, I now build a 7-segment LED based
+# clock, which handles window resizing properly. There's something slightly
+# strange about the "font" of the LED segments, with the verticals being
+# surprisingly thin, actually that's a bug I've run out of time to track
+# down, but it's quite appealing somehow:-)
+#
+
+use v5.10; # for "say"
+use strict;
+use warnings;
+use Tk;
+use Function::Parameters;
+use Data::Dumper;
+
+my $width = 1000;
+my $height = 400;
+my $mw;
+my $eg = 50; # edge gap (above, below, to left, and right)
+my $g = 30; # internal gap (between things)
+my $dotw = 20; # dot width
+my $linew = 12; # width of segment lines
+my $digitw; # 7-segment led digit width, recalculated when we resize
+my $hiy; # high coord of led digits, recalculated when we resize
+my $midy; # middle coord of led digits, recalculated when we resize
+my $loy; # low coord of led digits, recalculated when we resize
+
+die "Usage: ch-2.pl\n" if @ARGV>0;
+$mw = MainWindow->new();
+$mw->minsize( 200, 50 );
+my $canvas = $mw->Canvas(
+ -width => $width, -height => $height,
+ -background => 'black',
+ )->pack(-expand => 1, -fill => 'both');
+layout( $width, $height );
+$mw->after( 1000, \&setupbindings );
+
+#
+# setupbindings();
+# Set up the bindings, not sure why but unless I
+# delay this, the configure event triggers itself
+# with gradually smaller WxH and the clock shrinks
+# to it's minimum size... gross hack time:-)
+#
+sub setupbindings
+{
+ $mw->bind('<q>' => \&exit);
+ $mw->bind( "<Configure>" => \&handleresize );
+}
+
+
+#
+# handleresize( $widget );
+# Handle a configure (resize or something else) event on $widget.
+# Figure out the new width and height, update globals width and height
+# and change the font size for the label to fit.
+#
+fun handleresize( $widget )
+{
+ my $e = $widget->XEvent;
+ if( $width != $e->w || $height != $e->h )
+ {
+ $width = $e->w;
+ $height = $e->h;
+ #say "w=$width, h=$height";
+
+ # change layout using $width
+ layout( $width, $height );
+ }
+}
+
+
+#
+# layout( $width, $height );
+# Ok, the dimensions of the mainwindow (and canvas) have changed,
+# now work out how the layout of the LEDs changes in response.
+#
+fun layout( $width, $height )
+{
+ $digitw = ( $width - 2 * $eg - 7 * $g - 2 * $dotw ) / 6;
+ $hiy = $eg;
+ $midy = $height/2;
+ $loy = $height - $eg;
+
+ # blank canvas
+ $canvas->delete('all');
+
+ # now draw everything grey
+ drawdigit( 0, 0 );
+ drawdigit( 1, 0 );
+ drawcolon( 0 );
+ drawdigit( 2, 0 );
+ drawdigit( 3, 0 );
+ drawdigit( 4, 0);
+ drawdigit( 5, 0 );
+ drawcolon( 1 );
+}
+
+
+#
+# drawdigit( $digitno, $bitset );
+# Draw a 7-led LED, all grey except those elements in the $bitset which
+# are on (which are shown in red), digitno is 0 for leftmost (h1).. 5 for
+# rightmost (s2)
+#
+fun drawdigit( $digitno, $bitset )
+{
+ my $lx = $eg + ($digitno*($digitw+$g));
+ $lx += $g + $dotw if $digitno>1;
+ $lx += $g + $dotw if $digitno>3;
+
+ my $rx = $lx+$digitw-1;
+
+ my $oncol = 'red';
+ my $offcol = 'black';
+
+ # line 0: across the top
+ my $col = ($bitset&1) ? $oncol : $offcol;
+ $canvas->createRectangle( $lx+$linew, $hiy, $rx-$linew, $hiy+$linew,
+ -fill=>$col, -outline=>$col );
+
+ # line 1: left hand side, upper
+ $col = ($bitset&2) ? $oncol : $offcol;
+ $canvas->createRectangle( $lx+$linew, $hiy, $lx+$linew, $midy+$linew,
+ -fill=>$col, -outline=>$col );
+
+ # line 2: right hand side, upper
+ $col = ($bitset&4) ? $oncol : $offcol;
+ $canvas->createRectangle( $rx-$linew, $hiy, $rx-$linew, $midy+$linew,
+ -fill=>$col, -outline=>$col );
+
+ # line 3: across the middle
+ $col = ($bitset&8) ? $oncol : $offcol;
+ $canvas->createRectangle( $lx+$linew, $midy, $rx-$linew, $midy+$linew,
+ -fill=>$col, -outline=>$col );
+
+ # line 4: left hand side, lower
+ $col = ($bitset&16) ? $oncol : $offcol;
+ $canvas->createRectangle( $lx+$linew, $midy, $lx+$linew, $loy+$linew,
+ -fill=>$col, -outline=>$col );
+
+ # line 5: right hand side, lower
+ $col = ($bitset&32) ? $oncol : $offcol;
+ $canvas->createRectangle( $rx-$linew, $midy, $rx-$linew, $loy+$linew,
+ -fill=>$col, -outline=>$col );
+
+ # line 6: across the bottom
+ $col = ($bitset&64) ? $oncol : $offcol;
+ $canvas->createRectangle( $lx+$linew, $loy, $rx-$linew, $loy+$linew,
+ -fill=>$col, -outline=>$col );
+}
+
+
+#
+# drawcolon( $lr );
+# Draw one colon (either the one between hours/mins if lr==0,
+# or the one between mins/seconds if lr==1
+#
+fun drawcolon( $lr )
+{
+ my $lx = $eg + 2 * $digitw + 2 * $g + $dotw/2;
+ $lx += 2 * $digitw + 3 * $g + $dotw if $lr==1;
+
+ $canvas->createOval( $lx-$dotw/2, $midy-3*$dotw,
+ $lx+$dotw/2, $midy-2*$dotw,
+ -fill=>'red', -outline=>'red' );
+ $canvas->createOval( $lx-$dotw/2, $midy+2*$dotw,
+ $lx+$dotw/2, $midy+3*$dotw,
+ -fill=>'red', -outline=>'red' );
+}
+
+
+# the 7-led sets representing each digit
+my @set =
+(
+ 0b1110111,
+ 0b0100100,
+ 0b1011101,
+ 0b1101101,
+ 0b0101110,
+ 0b1101011,
+ 0b1111011,
+ 0b0100101,
+ 0b1111111,
+ 0b0101111,
+);
+
+
+#
+# showleds( $h1, $h2, $m1, $m2, $s1, $s2 );
+# Show the LEDs for each digit
+#
+fun showleds( $h1, $h2, $m1, $m2, $s1, $s2 )
+{
+ drawdigit( 0, $set[$h1] );
+ drawdigit( 1, $set[$h2] );
+ drawdigit( 2, $set[$m1] );
+ drawdigit( 3, $set[$m2] );
+ drawdigit( 4, $set[$s1] );
+ drawdigit( 5, $set[$s2] );
+}
+
+
+#
+# tick();
+# Update the counter every 1000 milliseconds (second)
+sub tick
+{
+ my( $sec, $min, $hour ) = localtime(time());
+ my $h1 = int( $hour / 10 );
+ my $h2 = $hour % 10;
+ my $m1 = int( $min / 10 );
+ my $m2 = $min % 10;
+ my $s1 = int( $sec / 10 );
+ my $s2 = $sec % 10;
+ showleds( $h1, $h2, $m1, $m2, $s1, $s2 );
+ $mw->after(1000, \&tick);
+}
+
+tick();
+
+MainLoop;