Just a collection of things I encounter and my initial, though sometimes considered, thoughts on them.
Friday, December 12, 2008
Quotations for Software Developpers
-- Capers Jones
"I love deadlines! I like the 'whooshing' sound they make as the fly by."
-- Douglas Adams
Software gets late one day at a time - Freb Brooks.
Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.
-- Antoine de Saint-Exupery (1900 - 1944)
"A truly great computer programmer is lazy, impatient and full of hubris"
-- Larry Wall
"No Silver Bullets - Essence and Accident in Software Engineering" - Fred Brooks
- essential attributes (high level - design)
- accidental attributes (code - implementation)
"The esscence of system design is interface design" - Stroustrup
"... as a rule of thumb, I can suggest that more resources, time, effort and talent should be spent testing a system than on constructing the initial implementation"
-- Stroustrup B.; The C++ Programming Language
~The fundamental motivation in defining a new type is to separate the incidental from the essential
-- Stroustrup
Programming is understanding - Kristen Nygaard
"Making the simple complex is easy. Making the complex simple, awesomely simple, now THAT is genius."
--Charles Mingus
"There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult."
-- C.A.R. Hoare
Key concept of MMM(Brooks) :
Essential problem with large systems is to maintain their conceptual integrity
"Plan to throw one away, you will anyway" - 1975 Brooks (MMM)
"If you plan to throw one away, you'll throw two!" - Zerounti
"Software is not written, or grown, or farmed. The best analogy is constructed or built" - McConnell (91)
"Don't comment tricky code - rewrite it" - McConnell (91)
"90% of code deals with exceptional or error cases, 10% with nominal cases"
-- Shaw in Bentley(82)
"When in doubt, use brute force" - Lampson
"Informal review procedures were passed from person to person in the general culture of computing for many years before they were acknoledged in print. The need for reviews was
so obvious to the best programmers that they rarely mentioned it in print, while the worst programmers thought that their work was so good that _their_ work didn't need reviewing.
-- Freedman/Weinberg
"Debugging is anticipated with distaste, performed with reluctance, and bragged about
forever."
-- Anon.
"Never debug standing up" - Weinberg(Psycology of a CP)
"More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity."
-- W.A.Wulf.
Rules of Optimization: -- M.A. Jackson
Rule 1: Don't do it.
Rule 2 (for experts only): Don't do it yet.
"We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil." -- Donald Knuth
Program-testing can be used very effectively to show the presence of bugs; but never to show their absence. (Dijkstra)
"Programming can be fun, so can cryptography, however they shouldn't be mixed"
- Kreitzberg & Schneiderman
Computer Science is no more about computers than astronomy is about telescopes.
E. W. Dijkstra
The question of whether a computer can think is no more interesting than the question of whether a submarine can swim.
Edsger W. Dijkstra
Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.
Rick Cook, The Wizardry Compiled
If debugging is the art of removing bugs, then programming must be the art of inserting them.
- unknown
“…documentation is a love letter that you write to your future self.” – Damian Conway
Computers make it easier to do a lot of things, but most of the things they make it easier to do don't need to be done.
Andy Rooney (1919 - )
Project Management Cookies
"If it is developed thoughtlessly and applied mindlessly, process can become the death of common sense" - Philip K. Howard
A leader knows where to go, and goes - J Erskine
"Do, or do not, there is no try." - Yoda
"Failure to prepare is preparing to fail" - Ben Franklin
Management Myopia : The subconscious tells you that anything you don't understand must be easy.
"Risk management is project management for adults" - Tim Lister
So much of what we call management consists in making it difficult for people to work.
Peter Drucker (1909 - 2005)
Management is doing things right; leadership is doing the right things.
Peter Drucker (1909 - 2005)
Not everything that can be counted counts, and not everything that counts can be counted"
- Einstein
"Not every group is a team and not every team is effective."
At Group L, Stoffel oversees six first-rate programmers, a managerial challenge roughly
comparable to herding cats. -- The Washington Post Magazine, 1985
"It must be remembered that there is nothing more difficult to plan,
more doubtful of success, more dangerous to manage, than the creation of a new system.
For the initiator has the enmity of all who would profit by the preservation of the old
institutions and merely lukewarm defenders in those who would gain by the new ones."
-- Machiavelli
"Any fool can defend his/her mistakes, most fools do!" - Dale Carnegie
"The moral virtues, then, are engendered in us neither by nor contrary to nature ... their full development is in us due to habit ... Anything that we have to learn to do we learn by the actual doing of it. Men will become good builders as a result of building well and bad ones as a results of building badly ... so it is a matter of no little importance what sort of habits we form from the earliest age - it makes a vast difference, or rather, all the difference in the world."
-- Aristotle
Why waste time learning, when ignorance is instantaneous
- (Bill Waterson) - Calvin / Hobbes.
Experience is largely non-transferrable.
"The best is the enemy of the good." Voltaire
Confidence is contagious. So is lack of confidence. Michael O'Brien
Judge a leader by his followers.
"If you can't explain something to a six year old, you don't really understand it" - Einstein
Albert Einstein, three rules of work
1. Out of clutter, find simplicity.
2. From discord, find harmony.
3. In the middle of difficulty lies opportunity.
"When I am working on a problem I never think about beauty. I only think about how to
solve the problem. But when I have finished, if the solution is not beautiful, I know
it is wrong." -- Buckminster Fuller
"You cannot apply a technological solution to a sociological problem."
- Edwards' Law
Language shapes the way we think and determines what we can think about
-- Benjamin Lee Whorf (engineer and linguist).
"All buildings are predictions. All predictions are wrong."
-- Stewart Brand, How Buildings Learn, p. 178.
A leader is best when people barely know he exists. Not so good when people acclaim him.
Worse when they despise him. But of a good leader who talks little when his work is done,
his aim fullfilled, they will say, "we did it ourselves."
-- Lao-Tzu, c. 550 BC
Big jobs usually go to those who prove their ability to outgrow small ones.
--Ralph Waldo Emerson
"The best executive is the one who has sense enough to pick good men to do what he wants, and the self-restraint to keep from meddling with them while their doing it."
--Theodore Roosevelt.
There is no necessary connection between the desire to lead and the ability to lead, and even less the ability to lead somewhere that will be to the advantage of the led...
--Bergen Evans.
OFFICE ARITHMETIC
Smart boss + smart employee = profit
Smart boss + dumb employee = production
Dumb boss + smart employee = promotion
Dumb boss + dumb employee = overtime
By working faithfully 8 hours a day, you may get eventually get to be a boss and work 12
hours a day.
-Robert Frost
Tuesday, December 2, 2008
Doxygen
This seems really quite nice. I've used Javadoc before, and found Doxygen really easy to set up on a large code base ...and the results (html option) look real nice. Javadoc was nice too.
However, it just doesn't add up. The compiler knowns the linkages of everything. A good IDE will jump around the code from reference to definition, and literate coding permits easy reading.
Why mess with these commenting props? Are they not defunct? My number one rule for comments is: "Is this needed?" This is not an aloof minimalism, but a pragmatism born of being a slow but careful reader. If a name can adaqutely describe thedefinition, consider a redesign with smaller responsibility!
As an note - when attempting to read-into code for the first overview, there is an old tool that answers all the questions : cscope. This was added (still available) to the programmers tool-chest way back and it beats these shiny new toys hands down.
Learning how to comment may be helped by reading the tagging methods of Doxygen and other "automatic documentation tools", but it's a deeper and more valuable lesson when gleaned from reading good code. As more and more code is made available online, the only issue is telling the wheat from the chaff.
Asimov - for the Big Screen
Airports
Why are airports so slow?
I recently travelled from Dublin to Newcastle-Upon-Tyne. The time in the air for the aircraft is 50 minutes. Door-to-Door, the trip took over 5 hours. If everyone was payed for their time queuing in this system, how much would it cost ?
That is 300 minutes or 500% overhead on the the required flying time.
Who will look at these overheads and attempt to start shaving some of the fat off? How much would it be worth to do so? There were over 10 million outward journeys in 2006, if the overage time wasted is 4 hours, at a low wage of 15 euros per hour, that 600 million euros in wasted opportunity per year (2006 numbers) !
The only meaningful answer, of course, is I'll look at these overheads and decide that drivingto Belfast instead is better. For an "Island Nation" however, shouldn't some body with power in the area, the IAA perhaps, look at these problems and propose some improvements ?
If not the IAA, could Ryanair perhaps see some profits to shaving the overheads ? Probably they'd follow their tradition and blame the Dublin Aiport Authority. Perhaps they'd be right !
How to tackle the problem, in my humble opinion:
- All airports should be size limited, perhaps no airport greater than 3 million passengers per year in either direction
- An airport on the south side of the city, perhaps on the Tallaght light rail line
- Reliable frequent rail links to the airports,
- Consider zero car parking spaces for travellers
- Aircraft HAVE to get more accurate timetables. I find it very hard to swallow that weather is so bad that it effects a modern aircraft every day!
- Security permits the services to run, OK. Now what can be done there ? Couldn't the gates have the required equipment to scan people at the gates, and the crew could be trained to use the equipment? This delegates the security of the aircraft to those who own and operate the aircraft. The captain is responsible again for the security of his/her passengers.
Ok - so I'm griping... and beggars can't be choosers. How much would a train tunnel between Ireland and England cost ? Well - as the chanel tunnel will probably never return it's cost, I can write that idea off !
Wednesday, November 26, 2008
The Process of Making a Decision
- break problem into manageable pieces
- propose solutions to the sub-problems
- evaluate solutions by theory, experiments and prototypes
- select from the set of solutions based on feasibility, cost and other stakeholder interests
- implement the solution, testing for adherence to the design, and the ultimate goal. As tests fail, cycle through the design - implement - test "cycle" until results are acceptible
- as you implement and learn, feed back the knowledge into the original plans, to get improvements into the overall design as soon as possible.
This, or a similar formula, is widely accepted. There is a less widely accepted formula for making decisions. Perhaps decisions are less weighty? Less important ? Less consistent in their nature?
Well, the design process is controlled by decision making ... so decision making must be more fundamental. Design does attempt to pull a solution from an infinity of options, and good design has hallmarks of simplicity, durability, longevity or something more asthetic. But decisions have inifinities all their own, as they too are based in predictions of the future, but often in a domain that is less clear that that of a potential design.
A good desision is not generally known to be a good decision until some time passes, or events unfold that indicate that there is a benefit, or a loss. Often the world changes and events overtake the framework in which a decision is made, and even though the decision might have been correct given the available information, it may passively cease to be correct.
The share markets provide enough examples of this.
So, a good decision must be managed within the framework in which it is made, and it should include ways of checking the validity of the framework. Even better, it should provide a way of telling the duration for which the framework will stay valid.
Unfortunately, this type of decision seems to only exist in the imagination of authors with an eye to intrigue, suspense and climax.
In the real world, people do not have the patience to formulate their decisions correctly ?
I say patience, some might say that people naturally manage their time, providing sufficient time only, as the decisions need to be made. I accept this economisation as true, but I question the accounting. Some decisions are many orders of magniture more important than others, but there is not an appropriately scalled investment in time, advise or research. People will spend as much time researching their next car as researching their next house? Sometimes it's even more apparent.
In business, there would seem to be a pro-rata increase in research before an expenditure. Before embarking on a million euro development over a year, a portion of that money and time would be invested in planning or selecting the best way to achieve the goals. I would guess that the research portion of the funds would indeed be spent, but I wonder what the ratio is comparing the the daily value returned during that "investigative" phase, to the value being generated when the project is under way.
Here are a list of decision support tools that are well known:
- Brainstorming (rarely used, poorly understood! perceived as simply getting heads into a room = discussion / arguement. Brainstorming is about geting as many ideas out in a fixed amount of time without evaluation or criticism )
- Pareto's Law (widely and well used, intuitive and fast)
- Priority (widely used, bur the quantification suffers from opinions which are not qualified)
- Paired Choice Analysis (takes patience to go through the pairs in any meaningful set of options, I've not seen it used widely)
- Decision Trees (rarely used, complex to handle all the possibilities and their probabilies)
- Sensitivity Analysis (never seen this used, people at middle management have little energy for the maths needed to build the models)
- Weighted attribute comparisons (rarely seen used, the result can used, but also less than confidence inspiring)
- Various perspectives / stakeholder review (delegate the decision upwards, widely and smartly used. However, dodges the real issue)
- Forcefield analysis - how strong are the set of forces that act on the decision (never seen used, but seems highly valuable)
- Balanced score card ... perspective grouped goals and measures (used for decision makeing - or status monitoring?)
- Cost / Benefit ( widely considered, but very difficult as both costs and benefits are often estimated with prejudice)
- Risk Analysis (not widely used formally, but intuitively integrated to general decision making
...
Sunday, November 23, 2008
http://www.youtube.com/watch?v=9PWXrnsSrf0
Ray Kurzweil : The Singularity Summit at Stanford
Extrapolating the explonential growth seen in many (all?) areas of human endeavour indicates that, even as the world in changing at rates faster than ever seen, the rate if change is not slowing, it is increasing. Many people feel a sense of inability to cope with the changes, but the percentage is likely to increase perhaps to include most people. Ray Kurzweil indicates that we may have truely intelligent, learning systems, "strong artificial intelligence", before 2020. He cites the recent breakthroughs in voice recognition, reading machines and translating machines to drive home the point that growth here is exponential.
If this is the case, machines will be surpassing the abilities of humans not only in chess, but also in many, if not all, areas of human enterprise. Are we already investing too much control of the worlds economies in machines ? In themoney and futures markets, is there a trade-off being made between control and human understanding and the potential to make money ?
"Singularity" is a math term for a point on a surface where the value is infinite. In astronomical terms, a black-hole: a body whose mass is so great that at a certain boundary, there is no escape for any matter, or any radiation.
Is there an implication that there will be an intelligence that will win all arguments ?
So, what will decide when the rate of change is "fast enough" ?
Will it be the population of democracies ? Or, business ? Government ? .... or will people take the outputs of probabilistic models generated by semi- or super- intelligent machines that are far too detailed and intertwined for human checks ? Man will get other machines to test the models, and again these will be checked and verified by machines.
So... okay machines shouldn't become autonomous or dangerous on their own. The problem is that there will always be men that will fly too close to the sun, and build machines that would not be built, and those who would fight for stability need machines to counter such threats.
Update 26.11.08 from /.
DARPA's IBM-Led Neural Network Project Seeks To Imitate Brain
posted by timothy on Friday November 21, @16:49 (supercomputing)
According to an article in the BBC, IBM will lead an [0]ambitious DARPA-funded project in 'cognitive computing.' According to Dharmendra Modha, the lead scientist on the project, '[t]he
key idea of cognitive computing is to engineer mind-like intelligent machines by reverse engineering the structure, dynamics, function and behaviour of the brain.' The article continues, 'IBM will join five US universities in an ambitious effort to integrate what is known from real biological systems with the results of supercomputer simulations of neurons. The team will then aim to produce for the first time an electronic system that behaves as the simulations do. The longer-term goal is to create a system with the level of complexity of a cat's brain. ' "
Wednesday, November 19, 2008
What we are
The human genome is a digital code that somehow contains all the information needed to build a human body, including that most remarkable of organs, the human brain. The data is stored in 3 billion bases of DNA, A,C,G,T. Therefore, there are 750 megabytes of information in the genome.
... only 10% is actually needed ...
-- Jim Kent, from Beautiful Code
This is staggering. I can't get it out of my head. 75 MBytes of data could create a human. With the immune system, eyes, sense of touch, the ability to recognise new ideas, and evaluate them with respect to themselves. Also, these 75MBs probably hold the human ability of compassion, empathy and hope. A CD could hold the definition of 10 humans. I don't say people, that would probably take many times that memory to store their retained experiences which influences who the human has "grown into".
In no common, trite way, this is still awesome.
Tuesday, November 18, 2008
Perl Timers v1
A simple perl script that permits 3 timers to be controlled from a Tk GUI:
The script keeps a log of it's uses, and there is a simple help pop-up.
## ------------------------------------------------#!/usr/bin/perl
use English;
require Tk;
require Tk::Balloon;
use Tk;
my $main = MainWindow->new();
my $timeStamp;
open( LOG, ">>.timers.log" ) or die "can't open .timers.log logfile.";
print LOG "==== Program Start ====\n";
##$main->minsize( qw(440 140));
$main->configure( - background => 'grey' );
my $introFrm = $main->Frame( -background=>'cyan' )->
pack( -side => 'top'); #, pady => 9, -padx => 7
my $imgPause = $main->Photo(-file => 'pause.gif');
my $imgStart = $main->Photo(-file => 'play.gif');
my $imgStop = $main->Photo(-file => 'stop.gif');
my $intro = $introFrm->Label(
-text=>'Countdown to alarm, or time a duration', # Enter a time (minutes) and start countdown.
-background=>'lightgrey',
)->pack(-side=>'top'
);
$ticker = $intro->repeat(1000, \&tick );
$balloon = $main->Balloon();
$balloon->attach($intro,
-balloonmsg =>
"Down count from set number of minutes,\n".
"or up count by setting minutes value to zero.\n".
"2h34 can be used for 2 hrs 34 minutes."
);
#############################################
my $timer1Running = 0;
my $timer1Paused = 0;
my $secs1;
#my $new = $introFrm->Button(
# -background=>'lightblue',
# -text=>'+',
# -padx=>'3',
# -command => sub { print "Add another timer ...\n"; },
# )->pack(-side=>'left');
my $alarmFrame1 = $main->Frame( -background=>'grey' )->
pack( -side => 'top', -fill => 'x' );
my $name1 = $alarmFrame1->Entry(
-background=>'white',
-width=>24 ) -> pack(-side=>'left', -padx=>4);
$name1->insert("end", "Citrix");
my $minute1 = $alarmFrame1->Entry(
-background=>'white',
-width=>3 ) ->pack(-side=>'left');
$minute1->insert("end", "35");
my $ctrl1 = $alarmFrame1->Button(
-background=>'lightgreen',
-image => $imgStart,
-command => [ \&HandleCtrl1 ]
)->pack(-side=>'left', -padx=>1);
my $pause1 = $alarmFrame1->Button(
-background=>'lightgrey',
-image => $imgPause,
-state=>'disabled',
-command => [ \&HandlePause1 ]
)->pack(-side=>'left');
my $remain1 = $alarmFrame1->Label(
-background=>'lightgreen',
-text=>'0',
-width=>7,
-padx=>3,
-relief=>'sunken' ) ->pack(-side=>'left' );
sub HandleCtrl1 ()
{
my $title = $name1->get();
chomp $title;
if ($timer1Running) {
$ctrl1->configure (
-image => $imgStart,
-background=>'lightgreen') ;
$pause1->configure (
-state=>'disable',
-text => 'Pause' );
$timer1Running = 0;
consoleLog("Stop ".$name1->get(), 1, $secs1);
} else {
my $mins = $minute1->get();
chomp $mins;
$ctrl1->configure (
-image => $imgStop,
-background=>'pink'
) ;
$secs1 = getSecsFromMins($mins); ## 60 * $mins;
consoleLog("Start ".$name1->get(), 1, $secs1);
$timer1Running = 1;
$timer1Paused = 0;
$pause1->configure (
-state=>'normal',
-text => 'Pause',
-background=>'lightgrey');
$remain1->configure(
-text => timeStr($secs3),
-background=>'lightgreen'
);
}
}
sub HandlePause1 ()
{
my $title = $name1->get();
chomp $title;
if (!$timer1Paused) {
$pause1->configure (
-text => 'Resume',
-background=>'lightgreen') ;
consoleLog("Pause ".$name1->get(), 1, $secs1);
$timer1Paused = 1;
} else {
$pause1->configure(
-text => 'Pause ',
-background=>'lightgrey' );
consoleLog("Resume ".$name1->get(), 1, $secs1);
$timer1Paused = 0;
}
}
#############################################
my $timer2Running = 0;
my $timer2Paused = 0;
my $secs2;
my $alarmFrame2 = $main->Frame( -background=>'grey' )->
pack( -side => 'top', -fill => 'x' );
my $name2 = $alarmFrame2->Entry(
-background=>'white',
-width=>24 ) -> pack(-side=>'left', -padx=>4);
$name2->insert("end", "Timer2");
my $minute2 = $alarmFrame2->Entry(
-background=>'white',
-width=>3 ) ->pack(-side=>'left');
$minute2->insert("end", "10");
my $ctrl2 = $alarmFrame2->Button(
-background=>'lightgreen',
-image => $imgStart,
-command => [ \&HandleCtrl2 ]
)->pack(-side=>'left', -padx=>1);
my $pause2 = $alarmFrame2->Button(
-background=>'lightgrey',
-image => $imgPause,
-state=>'disabled',
-command => [ \&HandlePause2 ]
)->pack(-side=>'left');
my $remain2 = $alarmFrame2->Label(
-background=>'lightgreen',
-text=>'0',
-width=>7,
-padx=>3,
-relief=>'sunken' ) ->pack(-side=>'left' );
sub HandleCtrl2 ()
{
my $title = $name2->get();
chomp $title;
if ($timer2Running) {
consoleLog("Stop ".$name2->get(), 2, $secs2);
$timer2Running = 0;
$ctrl2->configure (
-image => $imgStart,
-background=>'lightgreen') ;
$remain2->configure ( -background=>'lightgreen') ;
$pause2->configure (
-state=>'disable',
-text => 'Pause' );
} else {
my $mins = $minute2->get();
chomp $title; chomp $mins;
$ctrl2->configure (
-image => $imgStop,
-background=>'pink'
) ;
$secs2 = getSecsFromMins($mins); ## 60 * $mins;
consoleLog("Start ".$name2->get(), 2, $secs2);
$timer2Running = 1;
$timer2Paused = 0;
$pause2->configure (
-state=>'normal',
-text => 'Pause',
-background=>'lightgrey');
$remain2->configure(
-text => timeStr($secs3),
-background=>'lightgreen'
);
}
}
sub HandlePause2 ()
{
my $title = $name2->get();
chomp $title;
if (!$timer2paused) {
$pause2->configure (-text => 'Resume', -background=>'lightgreen') ;
consoleLog("Pause ".$name2->get(), 2, $secs2);
$timer2Paused = 1;
} else {
$pause2->configure (-text => 'Pause ', -background=>'lightgrey') ;
consoleLog("Resume ".$name2->get(), 2, $secs2);
$timer2Paused = 0;
}
}
#############################################
my $timer3Running = 0;
my $timer3Paused = 0;
my $secs3;
my $alarmFrame3 = $main->Frame( -background=>'grey' )->
pack( -side => 'top', -fill => 'x' );
my $name3 = $alarmFrame3->Entry(
-background=>'white',
-width=>24 ) -> pack(-side=>'left', -padx=>4);
$name3->insert("end", "Timer3");
my $minute3 = $alarmFrame3->Entry(
-background=>'white',
-width=>3 ) ->pack(-side=>'left');
$minute3->insert("end", "0");
my $ctrl3 = $alarmFrame3->Button(
-background=>'lightgreen',
-image => $imgStart,
-command => [ \&HandleCtrl3 ]
)->pack(-side=>'left', -padx=>1);
my $pause3 = $alarmFrame3->Button(
-background=>'lightgrey',
-image => $imgPause,
-state=>'disabled',
-command => [ \&HandlePause3 ]
)->pack(-side=>'left');
my $remain3 = $alarmFrame3->Label(
-background=>'lightgreen',
-text=>'0',
-width=>7,
-padx=>3,
-relief=>'sunken' ) ->pack(-side=>'left' );
sub HandleCtrl3 ()
{
my $title = $name3->get();
chomp $title;
if ($timer3Running) {
consoleLog("Stop ".$name3->get(), 3, $secs3);
$timer3Running = 0;
$ctrl3->configure (
-image => $imgStart,
-background=>'lightgreen'
) ;
$pause3->configure (
-state=>'disable',
-text => 'Pause'
);
} else {
my $mins = $minute3->get();
chomp $mins;
$ctrl3->configure (
-image => $imgStop,
-background=>'pink'
) ;
$secs3 = getSecsFromMins($mins); ## 60 * $mins;
# print "Running \"$title\" (3) from $mins\n";
consoleLog("Start ".$name3->get(), 3, $secs3);
$timer3Running = 1;
$timer3Paused = 0;
$pause3->configure (
-state=>'normal',
-text => 'Pause',
-background=>'lightgrey'
);
$remain3->configure(
-text => timeStr($secs3),
-background=>'lightgreen'
);
}
}
sub HandlePause3 ()
{
my $title = $name3->get();
chomp $title;
if (!$timer3Paused) {
$pause3->configure (-text => 'Resume', -background=>'lightgreen') ;
consoleLog("Pause ".$name3->get(), 3, $secs3);
$timer3Paused = 1;
} else {
$pause3->configure (-text => 'pause ', -background=>'lightgrey') ;
consoleLog("Resume ".$name3->get(), 3, $secs3);
$timer3Paused = 0;
}
}
#################################
sub getSecsFromMins($)
{
my ($hm, $hrs, $mins, @vals);
if ( $_[0]=~ /[hH]/ ) ## if there's a 'h'
{
# print "Hours detected\n";
$hm = "0".$_[0]; ## cater for 'h32' => 32 mins
@vals = split ( /[hH]/, $hm );
# print "#".@vals."\n";
# print "".$vals[0]."-=-".$vals[1]."-=-".$vals[2]."\n";
$mins = $vals[0] * 60 + $vals[1];
# print "mins $mins\n";
return 60 * $mins;
}
else
{
return 60 * $_[0];
}
}
sub timeStr($)
{
my ($times, $s);
$s = abs( $_[0] );
$times = sprintf("%02d:%02s", $s/60, $s%60 );
return $times;
}
sub consoleLog ($$$)
{
($title, $inst, $secs) = @_;
print "$timeStamp ($inst) \"$title\" @ ".timeStr($secs)."\n";
print LOG "$timeStamp ($inst) \"$title\" @ ".timeStr($secs)."\n";
if ($title =~ "EXPIRE")
{
printf "%c%c%c\n",7,7,7;
}
}
sub getDaySuffix($)
{
my $DoM = $_[0];
if ($DoM == 1 || $DoM == 21 || $DoM == 31 ) { return "st"; }
if ($DoM == 2 || $DoM == 22 ) { return "nd"; }
return "th";
}
sub setTime() {
# print "t";
my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday );
( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday ) = localtime(time);
my $winTitle = "".sprintf
"%02d%s %02d:%02d",
$mday, getDaySuffix($mday), $hour, $min;
$timeStamp = sprintf(
"%02d-%02d-%04d %02d:%02d:%02d",
$mday, $mon + 1, $year + 1900, $hour, $min, $sec
);
$main->title($winTitle);
}
sub tick() {
setTime();
if ($timer1Running && !$timer1Paused)
{
$secs1 --;
if ($secs1 == 0)
{
my $title = $name1->get();
chomp $title;
consoleLog("".$name1->get()." EXPIRED", 1, $secs1);
$remain1->configure(-text => "0", -background=>'pink' );
} else {
$remain1->configure( -text => timeStr($secs1) );
}
}
if ($timer2Running && !$timer2Paused)
{
$secs2 --;
if ($secs2 == 0)
{
my $title = $name2->get();
chomp $title;
consoleLog("".$name2->get()." EXPIRED", 2, $secs2);
$remain2->configure(-text => "0", -background=>'pink');
} else {
$remain2->configure(-text => timeStr($secs2) );
}
}
if ($timer3Running && !$timer3Paused)
{
$secs3 --;
if ($secs3 == 0)
{
my $title = $name3->get();
chomp $title;
consoleLog("".$name3->get()." EXPIRED", 3, $secs3);
$remain3->configure(-text => "0", -background=>'pink');
} else {
$remain3->configure(-text => timeStr($secs3) );
}
}
}
##########
setTime();
# start first timer ...
HandleCtrl1 ();
MainLoop();
print LOG "==== Program Exit ====\n";
close LOG;
## -------------------------- End ---
It's a kind of opiate ... TV
Right - now we know what is driving the popularity of Eastenders !
10,000 hours
/. "The Guardian has an interesting article based on a new book (Outliers: The Story Of Success, by Malcolm Gladwell) which examines some persons of interest to computer technology (Bill Joy, Bill Gates and Steve Jobs, amongst others). It examines reasons for their successes and strongly suggests a link between practice (10,000 hours by age 20 being the magic milestone) and luck. This maybe an obvious truism, but the article does give interesting anecdotes on how their personal circumstances led to today's technological landscape. It points out that many of the luminaries of the current tech industry were born around 1955, and thus able to [0]take advantage of the emerging technologies."
Hmmmm, 4 hours a day on a computer for 7 years before I was 20 ??? I'd be close - why is it that I'm no billionaire ? Darn luck - I suppose :-J