Link to home
Start Free TrialLog in
Avatar of Europa MacDonald
Europa MacDonaldFlag for United Kingdom of Great Britain and Northern Ireland

asked on

how to get perl to write to a VIM file

I have this code from you guys which wrote to a text file fine.

I have installed VIM and I can get the code to read from a .vim file fine, and output to a text file.

When I read from a vim file and write to a vim file, there is nothing in the vim file.

how can I rectify this ?
was I right to add the .vim extension to my vim files ?
Avatar of Adam314
Adam314

When perl reads from or writes to a file, it does not care what the file name or extension is.  Post the code you are using, and we'll take a look.
Avatar of Europa MacDonald

ASKER

use strict;
use warnings;

##### Opens input file to variables and outputs to file

open(IN, "<vimtrial.vim") or die;
open(OUT, ">vimout.vim") or die;

my $s;
 
while($s = <IN>) {
   if($s =~ /(\d+),(\d+),(\d+),(\d+),(\d+),(\d+),(\d+),(\d+)/) {
      my ($n1, $n2, $n3, $n4, $n5, $n6, $n7, $n8) = ($1, $2, $3, $4, $5, $6, $7, $8);





##### calculations

      my $avg = ($n2 + $n3 + $n4 + $n5 + $n6 + $n7 + $n8)/ 7;


##### sort values ascending order

      ($n2,$n3,$n4,$n5,$n6,$n7,$n8)=sort{$a<=>$b}$n2,$n3,$n4,$n5,$n6,$n7,$n8;


##### calculate value difference

      my $vd1 = ($n2 - 0);
      my $vd2 = ($n3 - $n2);
      my $vd3 = ($n4 - $n3);
      my $vd4 = ($n5 - $n4);
      my $vd5 = ($n6 - $n5);
      my $vd6 = ($n7 - $n6);
      my $vd7 = ($n8 - $n7);

      my $avgdif = ($vd1 + $vd2 + $vd3 + $vd4 + $vd5 + $vd6 + $vd7) / 7;

##### sort into groups

      my @groups = (0,0,0,0,0,0,0,0,0,0);
      
      for($n2,$n3,$n4,$n5,$n6,$n7,$n8) {
       
      $groups[floor($_/10)]++;
      
      }      


##### print out to file

use POSIX;

# print out original numbers, value average and number groupings

print OUT "\t$n2\t$n3\t$n4\t$n5\t$n6\t$n7\t$n8 \tavg value \t",(floor $avg),"\t@groups[0..9]\n";
      
# print out value difference and average value difference

print OUT "\t$vd1\t$vd2\t$vd3\t$vd4\t$vd5\t$vd6\t$vd7 \tavg diff \t",(floor $avgdif),"\n\n";





######      

      #print OUT "\t$n2\t$n3\t$n4\t$n5\t$n6\t$n7\t$n8 avg value ",(floor $avg),"\t@groups[0..9]\n"      

######

   }
}




##### this last bit is here to stop the program closing until you hit return



      END {
          print "Press ENTER to close: ";
          ''.<STDIN>
      }


#      print join("\t",$n1,$n2,$n3,$n4,$n5,$n6,$n7,floor $avg),"\n"';
#      print join(",",$n1,$n2,$n3,$n4,$n5,$n6,$n7,floor $avg),"\n"';



SOLUTION
Avatar of Adam314
Adam314

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I was using 6 number combinations instead of seven, to save time while I was testing the code.

How do I adjust this to test only 6 numbers, I tried and the code returned errors


all my numbers are positive, have no white space, and there are no decimal points
I have sets of data to test with 6,7, and 10 data combinations, on a range of values

we are working on protein distribution on developing nerve cells
The easiest way would be to use an array and the split function.  Using an array, you'd replace these lines:
    while($s = <IN>) {
        if($s =~ /(\d+),(\d+),(\d+),(\d+),(\d+),(\d+),(\d+),(\d+)/) {
            my ($n1, $n2, $n3, $n4, $n5, $n6, $n7, $n8) = ($1, $2, $3, $4, $5, $6, $7, $8);
With this:
    while($s = <IN>) {
        my @nums = split(/,/, $s);

Then, you access the individual elements like $num[$index], where $index is the number you want to access, starting at 0.
So, your current $n1 would be $num[0].
Your current $n2 would be $num[1].
Your current $n3 would be $num[2].
And so on...

You can then access the last index with $#num.  So, if you have 5 elements, $#num would be 4 (they would be numbered 0 through 4).  If you have 8 elements, $#num would be 7 (numbered 0 through 7).

You can access a range of elements with @num[$min..$max].  So, for example, this:
    $n2,$n3,$n4
Would become:
    @num[1..3]

To sort, you'd replace this:
    ($n2,$n3,$n4,$n5,$n6,$n7,$n8)=sort{$a<=>$b}$n2,$n3,$n4,$n5,$n6,$n7,$n8;
With this:
    @num[1..$#num] = sort {$a <=> $b} @num[1..$#num]
And this will automatically handle as many numbers as you have - sorting the second (with index 1) to the last (with index $#num), leaving the first (index 0) as the first.


You could replace this:
    my $avg = ($n2 + $n3 + $n4 + $n5 + $n6 + $n7 + $n8)/ 7;
With this:
    use List::Util 'sum';    #Put at the top - this gives you a function to calculate the sum of an array
    my $avg = sum(@num[1..$#num)/$#num;
This will handle any number of elements in @num.

You could replace this:
    my @groups = (0,0,0,0,0,0,0,0,0,0);
    for($n2,$n3,$n4,$n5,$n6,$n7,$n8) {
        $groups[floor($_/10)]++;
    }
With this:
    my @groups = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
    for(@num[1..$#num]) {
        $groups[floor($_/10)]++
    }
And again, this will handle any number of elements.




ASKER CERTIFIED SOLUTION
Avatar of Suhas .
Suhas .
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
few corrections:

@line 2 forgot to add: use POSIX;

@line 3 it should be: open(OUT,">outvim.vim"); instead of open(OUT,"outvim.vim);
suhasbharad&

could you write that code using just scalars please, I like the non-static bit ?
I will repost in a new question
can you share the sample input vim file for better understanding of your requirement.
thankyou