#!/tools/bin/perl
#
# Converts an ASCII file of real numbers into the Weka ARFF format
# Optionally takes a file with variable names (if not given, these names
# are created as "N1", "N2", ...
# It accepts missing values, identified as "?" (they are just copied in place)
# The script assumes that the class variable ({0,1}) is in the last column

# Usage:
#   arffer <file> <no. inputs> [<fitxer-noms>]
#
# <file>: the file to be processed
# <no. inputs>: number of columns of <file>
# <file-names>: file with the variable names (optional)

die "\narffer <fitxer> <no. inputs> [<file-names>]\n" 
    if ($#ARGV < 2);

# Configuration

$inputfile = $ARGV[0];
$n_inputs = $ARGV[1];
$namesfile = $ARGV[2];
$separador = ",";       # Weka's default
$missing_symbol = "?";  # Weka's default
$comment_symbol = "%";  # Weka's default

# Try to open the files

open (FILE, $inputfile) || die "Can't open file '$inputfile'\n";
@lines = <FILE>;
close (FILE);

if ($namesfile eq "") { $Names = "False"; }
else { $Names = "True";
       open (FILE, $namesfile) || die "Can't open file '$namesfile'\n";
       @names = <FILE>;
       close (FILE);  
   }

# Check everything is OK

if ($Names eq "True")
{
    @thenames = split (/[, \t\n]+/, $names[0]);
    die "Number of names in '$namesfile' does not match $n_inputs\n" 
	if ($#thenames+1 != $n_inputs);
}

# Write the header

print $comment_symbol,"\n","\n";
print "\@RELATION ",$inputfile,"\n","\n";
print $comment_symbol,"\n","\n";

# Write the variable names

for ($j = 0; $j < $n_inputs - 1; $j++)
{
    if ($Names eq "True") { print "\@ATTRIBUTE ",$thenames[$j]," real","\n"; }
    else { print "\@ATTRIBUTE N", $j+1," real","\n"; }
}

if ($Names eq "True") { print "\@ATTRIBUTE ",$thenames[$j]," {0,1}","\n"; }
else { print "\@ATTRIBUTE N", $j+1," {0,1}","\n"; }

print $comment_symbol,"\n","\n";
 
# Write the data

print "\@DATA ","\n";

for ($i = 0; $i <= $#lines; $i++) 
{

    @F = split (/[ ,\t\n]+/, $lines[$i]);

    # treat the case where there are separators before the first column
    if ($#F>=$n_inputs) { $jj = 1; } else { $jj = 0; } 

    for ($j = $jj; $j <= $n_inputs-(1-$jj); $j++)
    {
	$vv = $F[$j];     
	print $vv;
	if ($j < $n_inputs-(1-$jj)) { print $separador; }
    }
    
    print "\n";
}

