Extract substring from offset to space or full stop

2010-04-18 Thread Mimi Cafe
I used MySQL substr function to extra 100 characters from the result of a
query, but understandably, I don't get what I want.

 

Now I looked at Perl's substr function and it doesn't look like it can help
me achieve what I need to.

 

Let's say I have:

 

$s = "The black cat climbed the green tree";

$substring = substr( $s, 1, 15); # this will return "The black cat c".

 

How can I have this return the whole word climbed rather than the c (i.e. I
need to get "The black cat climbed")? I need to get the remaining characters
from the length till the next white space or end of a phrase.

 

Any other way to overcome this limitation?  How can I use regex here?

 

 

 



Re: Extract substring from offset to space or full stop

2010-04-18 Thread Akhthar Parvez K
Hi Mimi,

> How can I have this return the whole word climbed rather than the c (i.e. I
> need to get "The black cat climbed")? I need to get the remaining characters
> from the length till the next white space or end of a phrase.
> Any other way to overcome this limitation?  How can I use regex here?

This might work for you I guess:


#!/usr/bin/perl
$s = "The black cat climbed the green tree";
$count = 50;
$s =~ /(^[\S\s]{1,$count}\S*)(\s.*|$)/;
print "$1\n";


when $count is 30, it prints:
The black cat climbed the green

when $count is 50, it prints:
The black cat climbed the green tree

My knowledge in Perl is limited, so there may be a more apt solution in your 
case.

Regards,
Akhthar Parvez K
http://Tips.SysAdminGUIDE.COM
UNIX is basically a simple operating system, but you have to be a genius to 
understand the simplicity - Dennie Richie
On Sunday 18 Apr 2010, Mimi Cafe wrote:
> I used MySQL substr function to extra 100 characters from the result of a
> query, but understandably, I don't get what I want.
> 
>  
> 
> Now I looked at Perl's substr function and it doesn't look like it can help
> me achieve what I need to.
> 
>  
> 
> Let's say I have:
> 
>  
> 
> $s = "The black cat climbed the green tree";
> 
> $substring = substr( $s, 1, 15); # this will return "The black cat c".
> 
> 
>  
> 
>  
> 
>  
> 
> 



-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Extract substring from offset to space or full stop

2010-04-18 Thread Shawn H Corey

Mimi Cafe wrote:

$s = "The black cat climbed the green tree";

$substring = substr( $s, 1, 15); # this will return "The black cat c".

 


How can I have this return the whole word climbed rather than the c (i.e. I
need to get "The black cat climbed")? I need to get the remaining characters
from the length till the next white space or end of a phrase.


#!/usr/bin/perl

use strict;
use warnings;

my $str = "The black cat climbed the green tree";
print "string: $str\n";

$str =~ m{ \A ( .{15} .*? ) \s }msx;
my $extracted = $1;
print "extracted: $extracted\n";

__END__



--
Just my 0.0002 million dollars worth,
  Shawn

Programming is as much about organization and communication
as it is about coding.

I like Perl; it's the only language where you can bless your
thingy.

Eliminate software piracy:  use only FLOSS.

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Extract substring from offset to space or full stop

2010-04-18 Thread Akhthar Parvez K
Hi Shawn,

> $str =~ m{ \A ( .{15} .*? ) \s }msx;

I don't think this would work if the value given in the match string (15 as per 
above eg.) is greater than the character count of the particular string. Right?

Regards,
Akhthar Parvez K
http://Tips.SysAdminGUIDE.COM
UNIX is basically a simple operating system, but you have to be a genius to 
understand the simplicity - Dennie Richie

On Sunday 18 Apr 2010, Shawn H Corey wrote:
> #!/usr/bin/perl
> 
> use strict;
> use warnings;
> 
> my $str = "The black cat climbed the green tree";
> print "string: $str\n";
> 
> my $extracted = $1;
> print "extracted: $extracted\n";



-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: How to properly fold a subject header in email

2010-04-18 Thread Harry Putnam
"John W. Krahn"  writes:

[...]

> From:
>
> http://www.rfc-editor.org/rfc/rfc5322.txt
>
> 
> 2.2.  Header Fields

[...]

>   (and even within some of the lexical tokens), folding SHOULD be
>   limited to placing the CRLF at higher-level syntactic breaks.  For

CRLF is mentioned in several places in rfc5322 as being used to fold.

I used a newline and a unix newline isn't the same as CRLF is it?

The wikipedia on CRLF only lead to lots more confusion.  I guess finally
saying many internet protocols such as smtp are tolerant on that
question.

Maybe thats as good an explanation as I'll find.



-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




RE: Extract substring from offset to space or full stop

2010-04-18 Thread Mimi Cafe
Hi,

It works fine and I like it. My regex is not that good, but I can see what
is doing. I modified it a bit (to capture up till a full stop sign).


#!/usr/bin/perl
#
use strict;
use warnings;
#
my $str = "The black cat is trying to climbed the green tree. This time it
failed."; print "string: $str\n";
my $sbstr = substr $str, 0,17;
print "The substr function with length 17 will capture: $sbstr\n";
$str =~ m{ \A ( .{17} .*?\. ) \s }msx;
my $extracted = $1;
print "The pattern with quantifier set 17, extracted: $extracted\n"; 



Outputs:

string: The black cat is trying to climbed the green tree. This time it
failed.
The substr function with length 17 will capture: The black cat is
The pattern with quantifier set 17, extracted: The black cat is trying to
climbed the green tree.


Cool





-Original Message-
From: Akhthar Parvez K [mailto:akht...@sysadminguide.com] 
Sent: 18 April 2010 15:45
To: beginners@perl.org
Subject: Re: Extract substring from offset to space or full stop

Hi Shawn,

> $str =~ m{ \A ( .{15} .*? ) \s }msx;

I don't think this would work if the value given in the match string (15 as
per above eg.) is greater than the character count of the particular string.
Right?

Regards,
Akhthar Parvez K
http://Tips.SysAdminGUIDE.COM
UNIX is basically a simple operating system, but you have to be a genius to
understand the simplicity - Dennie Richie

On Sunday 18 Apr 2010, Shawn H Corey wrote:
> #!/usr/bin/perl
> 
> use strict;
> use warnings;
> 
> my $str = "The black cat climbed the green tree";
> print "string: $str\n";
> 
> my $extracted = $1;
> print "extracted: $extracted\n";



-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Extract substring from offset to space or full stop

2010-04-18 Thread Akhthar Parvez K
Hi,

> It works fine and I like it. My regex is not that good, but I can see what
> is doing. I modified it a bit (to capture up till a full stop sign).

Kewl. Good to hear that!

Regards,
Akhthar Parvez K
http://Tips.SysAdminGUIDE.COM
UNIX is basically a simple operating system, but you have to be a genius to 
understand the simplicity - Dennie Richie

On Sunday 18 Apr 2010, Mimi Cafe wrote:
> Hi,
> 
> 
> 
> #!/usr/bin/perl
> #
> use strict;
> use warnings;
> #
> my $str = "The black cat is trying to climbed the green tree. This time it
> failed."; print "string: $str\n";
> my $sbstr = substr $str, 0,17;
> print "The substr function with length 17 will capture: $sbstr\n";
> $str =~ m{ \A ( .{17} .*?\. ) \s }msx;
> my $extracted = $1;
> print "The pattern with quantifier set 17, extracted: $extracted\n"; 
> 
> 
> 
> Outputs:
> 
> string: The black cat is trying to climbed the green tree. This time it
> failed.
> The substr function with length 17 will capture: The black cat is
> The pattern with quantifier set 17, extracted: The black cat is trying to
> climbed the green tree.
> 
> 
> Cool
> 
> 
> 
> 
> 

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: How to properly fold a subject header in email

2010-04-18 Thread John W. Krahn

Harry Putnam wrote:

"John W. Krahn"  writes:

[...]


From:

http://www.rfc-editor.org/rfc/rfc5322.txt


2.2.  Header Fields


[...]


  (and even within some of the lexical tokens), folding SHOULD be
  limited to placing the CRLF at higher-level syntactic breaks.  For


CRLF is mentioned in several places in rfc5322 as being used to fold.

I used a newline and a unix newline isn't the same as CRLF is it?


No.  But you can use the Socket (or IO::Socket) module to import that 
constant:


perldoc Socket
[ SNIP ]
   Also, some common socket "newline" constants are provided: the
   constants "CR", "LF", and "CRLF", as well as $CR, $LF, and $CRLF,
   which map to "\015", "\012", and "\015\012".  If you do not want
   to use the literal characters in your programs, then use the
   constants provided here.  They are not exported by default, but
   can be imported individually, and with the ":crlf" export tag:



John
--
The programmer is fighting against the two most
destructive forces in the universe: entropy and
human stupidity.   -- Damian Conway

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Extract substring from offset to space or full stop

2010-04-18 Thread Shawn H Corey

Akhthar Parvez K wrote:

Hi Shawn,


$str =~ m{ \A ( .{15} .*? ) \s }msx;


I don't think this would work if the value given in the match string (15 as per 
above eg.) is greater than the character count of the particular string. Right?


No, it will fail if $str is less than 15 characters.  Try:

#!/usr/bin/perl

use strict;
use warnings;

for my $str ( "The black cat climbed the green tree", 'A test' ){
  my $extracted = extract( $str );
  print "string: $str\n";
  print "string: $extracted\n";
}

sub extract {
  my $str = shift @_;

  $str =~ m{ \A ( .{0,15} .*? ) \s }msx;
  my $extracted = $1;

  return $extracted;
}

__END__

--
Just my 0.0002 million dollars worth,
  Shawn

Programming is as much about organization and communication
as it is about coding.

I like Perl; it's the only language where you can bless your
thingy.

Eliminate software piracy:  use only FLOSS.

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Extract substring from offset to space or full stop

2010-04-18 Thread John W. Krahn

Mimi Cafe wrote:

I used MySQL substr function to extra 100 characters from the result of a
query, but understandably, I don't get what I want.

Now I looked at Perl's substr function and it doesn't look like it can help
me achieve what I need to.

Let's say I have:

$s = "The black cat climbed the green tree";

$substring = substr( $s, 1, 15); # this will return "The black cat c".


No it will not.  It will return "he black cat cl" because in perl 
offsets start at 0 and not 1:


$ perl -le'
my $s = "The black cat climbed the green tree";
my $substring = substr( $s, 1, 15 );
print $substring;
'
he black cat cl



How can I have this return the whole word climbed rather than the c (i.e. I
need to get "The black cat climbed")? I need to get the remaining characters
from the length till the next white space or end of a phrase.

Any other way to overcome this limitation?  How can I use regex here?


$ perl -le'
my $s = "The black cat climbed the green tree";
my $length = length $s;
my ( $substring ) = $s =~ / \A ( .{15,$length}? \b ) /x;
print $substring;
'
The black cat climbed




John
--
The programmer is fighting against the two most
destructive forces in the universe: entropy and
human stupidity.   -- Damian Conway

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Regex to validate user input (match any word or phrase)

2010-04-18 Thread Mimi Cafe
I am trying to test user input to ensure it contains special character or
symbols that could cause problems to my program or database.

The user will enter a keyword in the web form to search in my database, and
I want to ensure I don't play around with special character otherwise any
word or phrase is valid.

I have changed my regex several times, but still doesn't work and now I have
something bizarre and it doesn't work either. 


$string !~ /^[A-Za-z0-9]+/ # did not work when 2 words are supplied. 
$string !~ /(^[A-Za-z0-9])+\s*$1/ # did not work.

if ($string =~ /!|\$|%|\?|\^|\+|@|'|\\||/){ # doesn't work.

print qq(Invalid Keyword);
print qq(You have entered an invalid search keyword.
 Please go back and enter a valid word.);
footer();
exit;

}

Any idea how to match this properly?

Mimi






-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Extract substring from offset to space or full stop

2010-04-18 Thread Mimi Cafe

It is a bit tricky. Just tried it and Perl warned:

The string is: The black cat is.
Can't do {n,m} with n > m in regex; marked by <-- HERE in m/ \A ( .{19,18}
<-- HERE ?\s+ \b ) / at substr.pl line 10.


My strings are not fixed length, but I do they are normally longer that the
offset I used, so I should be fine I think.

Mimi



-Original Message-
From: John W. Krahn [mailto:jwkr...@shaw.ca] 
Sent: 18 April 2010 17:03
To: Perl Beginners
Subject: Re: Extract substring from offset to space or full stop

Mimi Cafe wrote:
> I used MySQL substr function to extra 100 characters from the result of a
> query, but understandably, I don't get what I want.
> 
> Now I looked at Perl's substr function and it doesn't look like it can
help
> me achieve what I need to.
> 
> Let's say I have:
> 
> $s = "The black cat climbed the green tree";
> 
> $substring = substr( $s, 1, 15); # this will return "The black cat c".

No it will not.  It will return "he black cat cl" because in perl 
offsets start at 0 and not 1:

$ perl -le'
my $s = "The black cat climbed the green tree";
my $substring = substr( $s, 1, 15 );
print $substring;
'
he black cat cl


> How can I have this return the whole word climbed rather than the c (i.e.
I
> need to get "The black cat climbed")? I need to get the remaining
characters
> from the length till the next white space or end of a phrase.
> 
> Any other way to overcome this limitation?  How can I use regex here?

$ perl -le'
my $s = "The black cat climbed the green tree";
my $length = length $s;
my ( $substring ) = $s =~ / \A ( .{15,$length}? \b ) /x;
print $substring;
'
The black cat climbed




John
-- 
The programmer is fighting against the two most
destructive forces in the universe: entropy and
human stupidity.   -- Damian Conway

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Extract substring from offset to space or full stop

2010-04-18 Thread John W. Krahn

Mimi Cafe wrote:


From: John W. Krahn [mailto:jwkr...@shaw.ca] 


Mimi Cafe wrote:

I used MySQL substr function to extra 100 characters from the result of a
query, but understandably, I don't get what I want.

Now I looked at Perl's substr function and it doesn't look like it can
help me achieve what I need to.

Let's say I have:

$s = "The black cat climbed the green tree";

How can I have this return the whole word climbed rather than the c (i.e.
I need to get "The black cat climbed")? I need to get the remaining
characters from the length till the next white space or end of a phrase.

Any other way to overcome this limitation?  How can I use regex here?


$ perl -le'
my $s = "The black cat climbed the green tree";
my $length = length $s;
my ( $substring ) = $s =~ / \A ( .{15,$length}? \b ) /x;
print $substring;
'
The black cat climbed


It is a bit tricky. Just tried it and Perl warned:

The string is: The black cat is.
Can't do {n,m} with n > m in regex; marked by <-- HERE in m/ \A ( .{19,18}
<-- HERE ?\s+ \b ) / at substr.pl line 10.

My strings are not fixed length, but I do they are normally longer that the
offset I used, so I should be fine I think.


$ perl -le'
my $s = "The black cat climbed the green tree";
my $end = length $s;
my $start = $end < 15 ? $end : 15;
my ( $substring ) = $s =~ / \A ( .{$start,$end}? \b ) /x;
print $substring;
'
The black cat climbed




John
--
The programmer is fighting against the two most
destructive forces in the universe: entropy and
human stupidity.   -- Damian Conway

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Extract substring from offset to space or full stop

2010-04-18 Thread Akhthar Parvez K
>$str =~ m{ \A ( .{0,15} .*? ) \s }msx;

Yeah, this would do. I talked about the scenario where you didn't put "{0,15}", 
but just "{15}".  In that case, it wouldn't work if the value given in the 
match string (15 as per above eg.) is greater than the character count of the 
particular string (36).


my $str = "The black cat climbed the green tree";
print "string: $str\n";

$str =~ m{ \A ( .{50} .*? ) \s }msx;
my $extracted = $1;
print "extracted: $extracted\n";


Result:
string: The black cat climbed the green tree
Use of uninitialized value in concatenation (.) or string at 
scripts/test/test2.pl line 14.
extracted:

But it worked for the OP (the above condition may not have been required for 
him) and that's what is important :-)

Regards,
Akhthar Parvez K
http://Tips.SysAdminGUIDE.COM
UNIX is basically a simple operating system, but you have to be a genius to 
understand the simplicity - Dennie Richie
On Sunday 18 Apr 2010, Shawn H Corey wrote:
> Akhthar Parvez K wrote:
> > Hi Shawn,
> > 
> >> $str =~ m{ \A ( .{15} .*? ) \s }msx;
> > 
> > I don't think this would work if the value given in the match string (15 as 
> > per above eg.) is greater than the character count of the particular 
> > string. Right?
> 
> No, it will fail if $str is less than 15 characters.  Try:
> 
> #!/usr/bin/perl
> 
> use strict;
> use warnings;
> 
> for my $str ( "The black cat climbed the green tree", 'A test' ){
>my $extracted = extract( $str );
>print "string: $str\n";
>print "string: $extracted\n";
> }
> 
> sub extract {
>my $str = shift @_;
> 

>my $extracted = $1;
> 
>return $extracted;
> }
> 
> __END__
> 
> -- 
> Just my 0.0002 million dollars worth,
>Shawn
> 
> Programming is as much about organization and communication
> as it is about coding.
> 
> I like Perl; it's the only language where you can bless your
> thingy.
> 
> Eliminate software piracy:  use only FLOSS.
> 



-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Regex to validate user input (match any word or phrase)

2010-04-18 Thread Owen
On Sun, 18 Apr 2010 17:09:59 +0100
Mimi Cafe  wrote:

> I am trying to test user input to ensure it contains special
> character or symbols that could cause problems to my program or
> database.
> 
> The user will enter a keyword in the web form to search in my
> database, and I want to ensure I don't play around with special
> character otherwise any word or phrase is valid.
> 
> I have changed my regex several times, but still doesn't work and now
> I have something bizarre and it doesn't work either. 
> 
> 
> $string !~ /^[A-Za-z0-9]+/ # did not work when 2 words are supplied. 
> $string !~ /(^[A-Za-z0-9])+\s*$1/ # did not work.
> 
> if ($string =~ /!|\$|%|\?|\^|\+|@|'|\\||/){ # doesn't work.

You might want to simply remove theses characters,

$string =~ s/[`\\"|!$\^&\...@#?><\s]//g  <---an example only

> 
> Any idea how to match this properly?



Try one of the posix character classes.[[:class]] where class would
probably be alnum (See http://perldoc.perl.org/perlre.html )


If the data base contains names like O'Rourke, then you might have to
rethink your database or add the ' to the list of allowed characters




Owen

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Can't locate object method "TIEHASH" via package " Apache::Session::MySQL

2010-04-18 Thread Mimi Cafe
I get following error when trying to open a session using
Apache::Session::MySQL.

 

Here is what I have 

 

  38   tie %session, " Apache::Session::MySQL", undef,{

 39 Handle => $dbh,

 40 LockHandle => $dbh

 41 };

 

 

Could not create new session: Can't locate object method "TIEHASH" via
package " Apache::Session::MySQL" at /var/www/cgi-bin/Lib/Session.pm line
38.

Could not create new session: Can't locate object method "TIEHASH" via
package " Apache::Session::MySQL" at /var/www/cgi-bin/lib/Session.pm line 38

 



Why is the answer right...

2010-04-18 Thread Harry Putnam
I may have turned the question around from the usual approach, but I'm
having trouble seeing why my script gives the right answer.

The script reads data that contains dates in the format YYMMDD N, the
N isn't part of the date but is also a digit.

What the script tries to do is read the dates, run them thru
Time::Local to convert to epochal dates.

Then using the random number... create an offset in epochal time that
represents that many days.

   100418 2

  Would get converted to an offset of 2 * 86400... 2 days worth of
  seconds. 

That answer is then subtracted from the epochal time conversion
And then we print the converted date back in YYMMDD format.

In the above case it should be 100416

All that seems to work ok, whats puzzling me is that the function
`localtime' normally spits out the mnths in 0..11 notation, so in
other scripts I've written where something was converted I've has to
to add a little extra math step to make the mnths come out right.

 $mon  += 1;

But in this script, I was all set to do that but discovered the mnths
come out right only if I DON'T do it.

I'm feeding like localtime($var), a calculated epochal time.  But it
appears to be spitting out the mnth element in (1...12) notation.

I'm sure there is some simple explanation but I'm not seeing it.

incoming data might look like the lines below... and the scripts
output follows at the very end.

----   ---=---   -   

ev   100409 3
  send state tax payment by 15th
ev 100604
  Newsguy account expires 100607
ev 100421 4
  my appt is today

----   ---=---   -   

The real script is quite a lot longer uses getopts and does more
stuff.  Here I've simplified, shortened and just used <> and fed a
file.

 cat myscript: 

#!/usr/local/bin/perl

use strict;
use warnings;
use Time::Local;

my $sec  = 01;
my $min  = 01;
my $hour = 01;

while(<>){
  if( my ($year,$mon,$mday,$predays) = $_ =~ 
m/^ev\s+(\d\d)(\d\d)(\d\d)\s+(\d)\s*$/){
  my ($oyear,$omon,$omday) = ($year,$mon,$mday);
  my $time = timelocal($sec,$min,$hour,$mday,$mon,$year);
## calc based on 86400 second in 24 hr
  my $offset = ($time - ($predays * 86400)); 

 ## We turn the offset time back into YYMMDD for comparison
 ($year,$mon,$mday) = (localtime($offset))[5,4,3];
 $year -= 100;  
# $mon  += 1;
 my $PaddedDateStr = sprintf "%02d%02d%02d", $year,$mon,$mday;
 my $incoming_date = $oyear . $omon . $omday;
 my $str = "\n   Lets see how it works:
  ---=   ---  
 Incoming year mon day  =  $incoming_date
 predays ($predays) * 86400 
 gives us this 
offset $offset 
 Which leaves us with   =  $PaddedDateStr
  ---=   ---
";
print $str;
   ($year,$mon,$mday,$predays,$oyear,$omon,$omday,$offset,$incoming_date,$str) 
= '';
  }
}  
print "\n";

----   ---=---   -   

./myscript file

   Lets see how it works:
  ---=   ---  
 Incoming year mon day  =  100409
 predays (3) * 86400 
 gives us this 
offset 1273125661 
 Which leaves us with   =  100406
  ---=   ---

   Lets see how it works:
  ---=   ---  
 Incoming year mon day  =  100421
 predays (4) * 86400 
 gives us this 
offset 1274076061 
 Which leaves us with   =  100417
  ---=   ---


-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Why is the answer right...

2010-04-18 Thread John W. Krahn

Harry Putnam wrote:

I may have turned the question around from the usual approach, but I'm
having trouble seeing why my script gives the right answer.

The script reads data that contains dates in the format YYMMDD N, the
N isn't part of the date but is also a digit.

What the script tries to do is read the dates, run them thru
Time::Local to convert to epochal dates.

Then using the random number... create an offset in epochal time that
represents that many days.

   100418 2

  Would get converted to an offset of 2 * 86400... 2 days worth of
  seconds. 


That answer is then subtracted from the epochal time conversion
And then we print the converted date back in YYMMDD format.

In the above case it should be 100416

All that seems to work ok, whats puzzling me is that the function
`localtime' normally spits out the mnths in 0..11 notation, so in
other scripts I've written where something was converted I've has to
to add a little extra math step to make the mnths come out right.

 $mon  += 1;

But in this script, I was all set to do that but discovered the mnths
come out right only if I DON'T do it.

I'm feeding like localtime($var), a calculated epochal time.  But it
appears to be spitting out the mnth element in (1...12) notation.

I'm sure there is some simple explanation but I'm not seeing it.


The main problem is that you are not testing edge cases like:

ev   101201 3

Or:

ev   100101 3

If you did you would get an error message like:

Month '12' out of range 0..11 at Why_is_the_answer_right.pl line 74



incoming data might look like the lines below... and the scripts
output follows at the very end.

----   ---=---   -   


ev   100409 3
  send state tax payment by 15th
ev 100604
  Newsguy account expires 100607
ev 100421 4
  my appt is today

----   ---=---   -   


The real script is quite a lot longer uses getopts and does more
stuff.  Here I've simplified, shortened and just used <> and fed a
file.

 cat myscript: 


#!/usr/local/bin/perl

use strict;
use warnings;
use Time::Local;

my $sec  = 01;
my $min  = 01;
my $hour = 01;


Why are you using octal numbers instead of decimal numbers?  Using an 
hour of 1 might conflict with the change of time from/to daylights 
saving time.  Better to use an hour in the middle of the day like 12 for 
example, or use gmtime/timegm instead which doesn't change for daylight 
savings.




while(<>){
  if( my ($year,$mon,$mday,$predays) = $_ =~ 
m/^ev\s+(\d\d)(\d\d)(\d\d)\s+(\d)\s*$/){
  my ($oyear,$omon,$omday) = ($year,$mon,$mday);
  my $time = timelocal($sec,$min,$hour,$mday,$mon,$year);


You need to adjust the month and year correctly:

   my $time = timelocal( $sec, $min, $hour, $mday, $mon - 1, 
"20$year" - 1900 );




## calc based on 86400 second in 24 hr
  my $offset = ($time - ($predays * 86400)); 


 ## We turn the offset time back into YYMMDD for comparison
 ($year,$mon,$mday) = (localtime($offset))[5,4,3];
 $year -= 100;  


That is not the correct way to adjust the year value:

perldoc -f localtime



# $mon  += 1;
 my $PaddedDateStr = sprintf "%02d%02d%02d", $year,$mon,$mday;
 my $incoming_date = $oyear . $omon . $omday;
 my $str = "\n   Lets see how it works:
  ---=   ---  
 Incoming year mon day  =  $incoming_date
 predays ($predays) * 86400 
 gives us this 
offset $offset 
 Which leaves us with   =  $PaddedDateStr

  ---=   ---
";
print $str;
   ($year,$mon,$mday,$predays,$oyear,$omon,$omday,$offset,$incoming_date,$str) 
= '';


The list on the right of the assinment has only one element so only 
$year is assigned a value.  But you are using lexical variables so that 
line is superfluous.




  }
}  
print "\n";


----   ---=---   -   


./myscript file

   Lets see how it works:
  ---=   ---  
 Incoming year mon day  =  100409
 predays (3) * 86400 
 gives us this 
offset 1273125661 
 Which leaves us with   =  100406

  ---=   ---

   Lets see how it works:
  ---=   ---  
 Incoming year mon day  =  100421
 predays (4) * 86400 
 gives us this 
offset 1274076061 
 Which leaves us with   =  100417

  ---=   ---




John
--
The programmer is fighting against the two most
destructive forces in the universe: entropy and
human stupidity.   -- Damian Conway

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/