CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
Perl to print previous and current value

 



eminempark
Novice

May 21, 2013, 8:11 PM

Post #1 of 10 (625 views)
Perl to print previous and current value Can't Post

How if i want to put formula of (cur_val - 2 * pre_val + pre_pre_val) >= 0.25 into the perl? For example, I have a number.txt consists of

Code
1 0.1 
2 0.4
3 0.9
4 0.6
5 0.5
6 0.6
7 0.9
8 0.4
9 0.1
10 0.0

The expected process is

Code
1 0.1 #by default it will print out the first two value 
2 0.4 #by default it will print out the first two value
3 0.9 # ABS(0.9 - 2 * 0.4 (y of 2)+ 0.1 (y of 1)) = 0.2, 0.2 < 0.25, thus, will not printed out
4 0.6 # ABS(0.6 - 2 * 0.4 (y of 2)+ 0.1 (y of 1)) = 0.1, 0.1 < 0.25, thus, will not printed out
5 0.5 # ABS(0.5 - 2 * 0.4 (y of 2)+ 0.1 (y of 1)) = 0.2, 0.2 < 0.25, thus, will not printed out
6 0.6 # ABS(0.6 - 2 * 0.4 (y of 2)+ 0.1 (y of 1)) = 0.1, 0.1 < 0.25, thus, will not printed out
7 0.9 # ABS(0.9 - 2 * 0.4 (y of 2)+ 0.1 (y of 1)) = 0.2, 0.2 < 0.25, thus, will not printed out But because the x=8 is printed out, x=7 will be printed out as well.
8 0.4 # ABS(0.4 - 2 * 0.4 (y of 2)+ 0.1 (y of 1)) = 0.3, 0.3 >= 0.25, thus, will printed out
9 0.1 # ABS(0.1 - 2 * 0.4 (y of 8)+ 0.9 (y of 7)) = 0.2, 0.2 < 0.25, thus, will not printed out
10 0.0 # ABS(0.0 - 2 * 0.4 (y of 8)+ 0.9 (y of 7)) = 0.1, 0.1 < 0.25, thus, will not printed out

Thus, the output will be

Code
1 0.1 
2 0.4
7 0.9
8 0.4

So far, my perl script is:

Code
#! /usr/bin/perl -w 
#
# compare.pl
#
# Usage: compare.pl number.txt
#
#
use strict;

my $pre_value = 14091989;
my $pre_pre_value = 1;
while(<>){
my( $ID, $cur_value) = split;
if( abs($cur_value-2*$pre_value+$pre_pre_value) >= 0.25 ){
print $_;
$pre_pre_value = $pre_value;
$pre_value = $cur_value;
}
else
{
$pre_value = $pre_value;
$pre_pre_value = $pre_pre_value;
}
}



Laurent_R
Veteran / Moderator

May 22, 2013, 4:48 AM

Post #2 of 10 (616 views)
Re: [eminempark] Perl to print previous and current value [In reply to] Can't Post

Hmm, the code in your else branch isn't very useful, is it?

From your description of the problem, I would think that the assignments:


Code
$pre_pre_value = $pre_value;  
$pre_value = $cur_value;


should be done outside of the if clause, since you presumably want to do that in all cases.

So I would code it this way:


Code
use strict;   
my $pre_value = 14091989;
my $pre_pre_value = 1;
while(<DATA>){
my( $ID, $cur_value) = split;
if( abs($cur_value - 2 *$pre_value + $pre_pre_value) >= 0.25 ){
print $_;
}
$pre_pre_value = $pre_value;
$pre_value = $cur_value;
}
__DATA__
1 0.1
2 0.4
3 0.9
4 0.6
5 0.5
6 0.6
7 0.9
8 0.4
9 0.1
10 0.0


This gives me this result:

Code
$ perl  prevalue.pl 
1 0.1
2 0.4
4 0.6
8 0.4

which seems to be correct to me (it I understood correctly what you are trying to do).


eminempark
Novice

May 23, 2013, 12:22 AM

Post #3 of 10 (597 views)
Re: [Laurent_R] Perl to print previous and current value [In reply to] Can't Post

Hm... Based on your result, sorry to say that it is wrong.
The process is:

Code
1 0.1 #by default it will print out the first two value  
2 0.4 #by default it will print out the first two value
3 0.9 # ABS(0.9 - 2 * 0.4 (y of 2)+ 0.1 (y of 1)) = 0.2, 0.2 < 0.25, thus, will not printed out
4 0.6 # ABS(0.6 - 2 * 0.4 (y of 2)+ 0.1 (y of 1)) = 0.1, 0.1 < 0.25, thus, will not printed out
5 0.5 # ABS(0.5 - 2 * 0.4 (y of 2)+ 0.1 (y of 1)) = 0.2, 0.2 < 0.25, thus, will not printed out
6 0.6 # ABS(0.6 - 2 * 0.4 (y of 2)+ 0.1 (y of 1)) = 0.1, 0.1 < 0.25, thus, will not printed out
7 0.9 # ABS(0.9 - 2 * 0.4 (y of 2)+ 0.1 (y of 1)) = 0.2, 0.2 < 0.25, thus, will not printed out But because the x=8 is printed out, x=7 will be printed out as well.
8 0.4 # ABS(0.4 - 2 * 0.4 (y of 2)+ 0.1 (y of 1)) = 0.3, 0.3 >= 0.25, thus, will printed out
9 0.1 # ABS(0.1 - 2 * 0.4 (y of 8)+ 0.9 (y of 7)) = 0.2, 0.2 < 0.25, thus, will not printed out
10 0.0 # ABS(0.0 - 2 * 0.4 (y of 8)+ 0.9 (y of 7)) = 0.1, 0.1 < 0.25, thus, will not printed out

Thus, the result should be:

Code
1 0.1  
2 0.4
7 0.9
8 0.4



Laurent_R
Veteran / Moderator

May 23, 2013, 4:55 AM

Post #4 of 10 (591 views)
Re: [eminempark] Perl to print previous and current value [In reply to] Can't Post

Let's see. The differences between my results and those that you show are on lines 2 and 7.

Prev value: 14091989
1 0.1
2 0.4

Line 2: 0.4 - 2 * 0.1 + 14091989 = 14091989,2, larger than 2.5, should be printed.

5 0.5
6 0.6
7 0.9

Line 7: 0.9 - 2 * 0.6 + 1 * 05 = 2, smaller than 2.5, should not be printed.

My results are consistent with the rules you have explained, yours are not.

Or you have to explain you rules better.


BillKSmith
Veteran

May 23, 2013, 12:20 PM

Post #5 of 10 (578 views)
Re: [Laurent_R] Perl to print previous and current value [In reply to] Can't Post

Laurent,
I initially got the same result as you. After the OP declared that wrong, I went back to his code. The difference is that he only updates the history if he does the print. I now believe that is intentional. That would be correct, but he now has an additional requirement which looks like a mere comment.


Quote
But because the x=8 is printed out, x=7 will be printed out as well



After line 8 is processed, but before it is printed, he has to print line 7 and revise the history so that line 9 will get its pre from line 8 and its pre_pre from line 7 (not 2).

I assume that this processing is needed every time a line is printed, and its immediate successor was not. It would not make sense to consider this requirement recursive.


This will take some deep thought.
Good Luck,
Bill


Laurent_R
Veteran / Moderator

May 23, 2013, 3:18 PM

Post #6 of 10 (572 views)
Re: [BillKSmith] Perl to print previous and current value [In reply to] Can't Post

Yes, Bill, yes, of course, you are right, I fully understand that what I provided is not what the OP really wanted. But it is my best understanding of the way the OP described the problem. And the code provided does in my opinion what the OP requested.

From the OP's own recognition, his or her code does not do what he or she wants. Therefore, you or I can't rely on the code provided by the OP to guess what he or she wants.

The reason I challenged the OP's opinion that my solution was wrong is certainly not that I wanted absolutely to defend my code (I frankly don't care), the OP hopefully knows better that you or I what he or she wants. The reason I did it is simply to prompt the OP to give better specifications of the requirement.

The table provided by the OP is only confusing to my eyes: for every single line, the second member of the equation if "-0.4 * 2". Even though I have an idea why, the point is that an example is never a substitute for a real explanation of the rule.

I have an idea of what the OP really wants, but I want him or her to state it clearly and to explain precisely the rules of the game.

It is probably not very complicated to obtain the desired result, but I will not commit any more effort on this until the need is clearly specified. Once we know really what the OP wants, I'm willing to take it up again.

To the OP: don't take this as an attack, it is not that, I am just trying to say that you need to make clear what you really want. Quite possibly, if you do the exercise seriously, you will find the solution by yourself. Believe my long experience: dfefining clearly what you need is the key to success. The programming itself is a secondary matter. I have been using probably more than 20 programming languages in my life, of which at least a dozen for real life professional problems, the issue of figuring out exactly what you need is far more important that knowing whether it will be programmed in Fortran, Lisp, C, PHP or Perl (or whatever).


BillKSmith
Veteran

May 23, 2013, 9:39 PM

Post #7 of 10 (566 views)
Re: [Laurent_R] Perl to print previous and current value [In reply to] Can't Post

Laurent,

The table provided by the OP is certainly confusing. But, once I deciphered it, I considered it a reasonably complete description of the problem. My previous post was not based on any guess. It is fully consistent with my understanding of the table. I had hoped that with that much clarification, we could both work on the real problem.

Please reconsider your response. Look at the table once more with the idea that it does contain the spec that you want. The first six lines are consistent with the OP's code. The seventh is different because of an additional requirement explained in the comment.

Note:
Pre and Pre_Pre do not refer the previous physical lines, but to the two previously printed lines.

x and y refer to the integer and real parts of a line respectively

You complained about all the 0.4's in the PRE colulmn. In rows 3 through 8, the 0.4 is the y-value from row 2 (the previously printed row.) The OP documents this with the notation '(y of 2)'
Row 8 is printed. The 0.4 in rows 9 and 10 is the y-value from row 8 which has become the previous printed row. It is an unfortunate coincidence that those y-values are the same.

The PrePre column is more complicated. Rows 2 through 8 contain the y-value from row 1 (the second previously printed row.) Without the new requirement to print row 7, rows 9 and 10 would both use the y-value from row 2. Now that row 7 is printed, they must get the y-value from it.
Good Luck,
Bill


Laurent_R
Veteran / Moderator

May 24, 2013, 1:26 AM

Post #8 of 10 (561 views)
Re: [BillKSmith] Perl to print previous and current value [In reply to] Can't Post

Alright, Bill, you've convinced me. Here we go.

I still think that the OP should learn to express requirements more precisely in plain language, but I can't resist to the pleasure of problem solving.

This is my new version. I am not entirely sure how exactly $pre_value and $pre-pre_value should be modified when one line is printed because the next one matches the condition, I have implemented what looks the most plausible to me.


Code
use strict;   
my $pre_value = 14091989;
my $pre_pre_value = 1;
my $previous_line ="";
while(<DATA>){
my( $ID, $cur_value) = split;
if( abs($cur_value - 2 *$pre_value + $pre_pre_value) >= 0.25 ){
if ($previous_line) {
print $previous_line;
$pre_pre_value = $pre_value; # this line is useless but keeping it conveys the logic better
$pre_value = (split / /, $previous_line)[1];
}
print $_;
$pre_pre_value = $pre_value;
$pre_value = $cur_value;
$previous_line = "";
} else {
$previous_line = $_;
}
}
__DATA__
1 0.1
2 0.4
3 0.9
4 0.6
5 0.5
6 0.6
7 0.9
8 0.4
9 0.1
10 0.0


And the output is:


Code
$ perl prevalue.pl 
1 0.1
2 0.4
7 0.9
8 0.4



BillKSmith
Veteran

May 24, 2013, 6:16 AM

Post #9 of 10 (556 views)
Re: [Laurent_R] Perl to print previous and current value [In reply to] Can't Post

Thanks Laurent, that is exactly what I wanted. I hope the OP can say the same thing.

I found your solution this morning before I had a chance to work on it more myself. Everything I had considered so far was much more complex. I had not thought of extracting the special previous value from the previous line.
Good Luck,
Bill


eminempark
Novice

May 26, 2013, 7:46 PM

Post #10 of 10 (533 views)
Re: [Laurent_R] Perl to print previous and current value [In reply to] Can't Post

Exactly what I need. Thank you Laurent_R and Bill. Wink

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives