Dr Manhattan has asked for the wisdom of the Perl Monks concerning the following question:
How come when I run this script
#!/usr/bin/perl -w
use strict;
my $dir = 'C:\Users\ZB\Desktop\Text Files';
opendir (DIR, $dir) or die "cannot opendir $dir";
foreach my $file (readdir(DIR))
{
next if $file eq '.';
next if $file eq '..';
process_file ($file);
}
sub process_file
{
my $fname=join("/",@_);
open FIN,"< $fname" or die "$fname:$!";
my @lines=<FIN>;
chomp @lines;
close FIN;
my $count=0;
foreach my $line(@lines)
{
map { $count++ } split (/[\s\t\n]+/,$line);
}
printf "There are %d words in %s\n",$count,$fname;
}
closedir (DIR);
it works just fine, but when I try using it in a bigger program it gives me the ":No such file or directory found at lingo4.pl line 508" error?
#!/usr/bin/perl -w
use strict;
open (INPUT2, "<korpusENG.txt") or die "can't open";
open (INPUT3, "<korpusAFR.txt") or die "can't open";
open (INPUT4, "<korpusNDB.txt") or die "can't open";
open (INPUT5, "<korpusSEP.txt") or die "can't open";
open (INPUT6, "<korpusSIS.txt") or die "can't open";
open (INPUT7, "<korpusSOT.txt") or die "can't open";
open (INPUT8, "<korpusTSO.txt") or die "can't open";
open (INPUT9, "<korpusTSW.txt") or die "can't open";
open (INPUT10, "<korpusVEN.txt") or die "can't open";
open (INPUT11, "<korpusXHO.txt") or die "can't open";
open (INPUT12, "<korpusZUL.txt") or die "can't open";
################################################################
my %EN;
my %AFR;
my %NDB;
my %SEP;
my %SIS;
my %SOT;
my %TSO;
my %TSW;
my %VEN;
my %XHO;
my %ZUL;
my $dir = 'C:\Users\ZB\Desktop\Text Files';
opendir (DIR, $dir) or die "cannot opendir $dir";
while (<INPUT2>) #sit Eng korpus in hash
{
my $word = $_;
chomp $word;
$EN{$word}++;
}
while (<INPUT3>) #sit Afr korpus in hash
{
my $word = $_;
chomp $word;
$AFR{$word}++;
}
while (<INPUT4>) #sit ndbele korpus in hash
{
my $word = $_;
chomp $word;
$NDB{$word}++;
}
while (<INPUT5>) #sit sepedi korpus in hash
{
my $word = $_;
chomp $word;
$SEP{$word}++;
}
while (<INPUT6>) #sit siswati korpus in hash
{
my $word = $_;
chomp $word;
$SIS{$word}++;
}
while (<INPUT7>) #sit sotho korpus in hash
{
my $word = $_;
chomp $word;
$SOT{$word}++;
}
while (<INPUT8>) #sit tsonga korpus in hash
{
my $word = $_;
chomp $word;
$TSO{$word}++;
}
while (<INPUT9>) #sit tswana korpus in hash
{
my $word = $_;
chomp $word;
$TSW{$word}++;
}
while (<INPUT10>) #sit venda korpus in hash
{
my $word = $_;
chomp $word;
$VEN{$word}++;
}
while (<INPUT11>) #sit xhosa korpus in hash
{
my $word = $_;
chomp $word;
$XHO{$word}++;
}
while (<INPUT12>) #sit zulu korpus in hash
{
my $word = $_;
chomp $word;
$ZUL{$word}++;
}
#############################################################
print "To classify a single file, press 1\nTo work within a directory,
+ press 2\n";
my $input = <STDIN>;
chomp($input);
while(&validate($input)==0)
{
print "Incorrect, please try again\n";
$input = <STDIN>;
chomp($input);
}
if ($input == 1)
{
&doc();
}
else
{
print "To classify each document within the directory, press 1\nTo
+ search for all the files of a specific language wihtin the directory
+, press 2\n";
my $input2 = <STDIN>;
chomp($input2);
while(&validate($input2)==0)
{
print "Incorrect, please try again\n";
$input2 = <STDIN>;
chomp($input2);
}
if ($input2 == 1)
{
foreach my $file (readdir(DIR))
{
next if $file eq '.';
next if $file eq '..';
&folder($file);
while(&folder()== 1)
{
print "The $file is ENGLISH";
}
while(folder()== 2)
{
print "The $file is AFRIKAANS";
}
while(folder()== 3)
{
print "The $file is NDEBELE";
}
while(folder()== 4)
{
print "The $file is SEPEDI";
}
while(folder()== 5)
{
print "The $file is SISWATI";
}
while(folder()== 6)
{
print "The $file is SOTHO";
}
while(folder()== 7)
{
print "The $file is TSONGA";
}
while(folder()== 8)
{
print "The $file is TSWANA";
}
while(folder()== 9)
{
print "The $file is VENDA";
}
while(folder()== 10)
{
print "The $file is XHOSA";
}
while(folder()== 11)
{
print "The $file is ZULU";
}
}
}
else
{
print "Search for\n\n1)English\n2)Afrikaans\n3)Ndebele\n4)Sepe
+di\n5)Siswati\n6)Sotho\n7)Tsonga\n8)Tswana\n9)Venda\n10)Xhosa\n11)Zul
+u\n\nPress the number\n";
my $input3 = <STDIN>;
chomp($input3);
while(&validate2($input3)==0)
{
print "Incorrect, please try again\n";
$input3 = <STDIN>;
chomp($input3);
}
}
}
############################################################# sub1
sub doc
{
print "Please type the name of the file you wish to classify\n";
my $filename = <STDIN>;
chomp ($filename);
open (INPUT, "<$filename") or die "can't open";
my @words; #array met input in
my @words2; #array met korrekte input in
my %hash;
while (<INPUT>)
{
my $word = $_;
chomp $word;
push @words, split(/ /, $word);
}
foreach my $correct (@words) #sit net woorde in @words2, niks ander
+ funny goed nie
{
if ($correct =~ /^\w+$/)
{
push (@words2, lc $correct);
}
}
foreach my $val (@words2) #sit input vanaf 2 array in hash in (fre
+kwensie lys)
{
$hash{$val}++;
}
#################################################### #aantal wo
+orde in hash
my $total = 0;
foreach my $keys (keys %hash)
{
$total = $total + $hash{$keys};
}
###################################################################
+ENGELS
my $varEN = 0;
foreach my $keys (keys %hash)
{
foreach my $key (keys %EN)
{
if ($keys eq $key)
{
$varEN = $varEN + $hash{$keys};
}
}
}
my $percentileEN = ($varEN/$total)*100;
###################################################################
+AFRIKAANS
my $varAFR = 0;
foreach my $keys (keys %hash)
{
foreach my $afr (keys %AFR)
{
if ($keys eq $afr)
{
$varAFR = $varAFR + $hash{$keys};
}
}
}
my $percentileAFR = ($varAFR/$total)*100;
####################################################################
+ NDEBELE
my $varNDB = 0;
foreach my $keys (keys %hash)
{
foreach my $ndb (keys %NDB)
{
if ($keys eq $ndb)
{
$varNDB = $varNDB + $hash{$keys};
}
}
}
my $percentileNDB = ($varNDB/$total)*100;
####################################################################
+SEPEDI
my $varSEP = 0;
foreach my $keys (keys %hash)
{
foreach my $sep (keys %SEP)
{
if ($keys eq $sep)
{
$varSEP = $varSEP + $hash{$keys};
}
}
}
my $percentileSEP = ($varSEP/$total)*100;
####################################################################
+SISWATI
my $varSIS = 0;
foreach my $keys (keys %hash)
{
foreach my $sis (keys %SIS)
{
if ($keys eq $sis)
{
$varSIS = $varSIS + $hash{$keys};
}
}
}
my $percentileSIS = ($varSIS/$total)*100;
####################################################################
+SOTHO
my $varSOT = 0;
foreach my $keys (keys %hash)
{
foreach my $sot (keys %SOT)
{
if ($keys eq $sot)
{
$varSOT = $varSOT + $hash{$keys};
}
}
}
my $percentileSOT = ($varSOT/$total)*100;
##################################################################
+TSONGA
my $varTSO = 0;
foreach my $keys (keys %hash)
{
foreach my $tso (keys %TSO)
{
if ($keys eq $tso)
{
$varTSO = $varTSO + $hash{$keys};
}
}
}
my $percentileTSO = ($varTSO/$total)*100;
##################################################################
+TSWANA
my $varTSW = 0;
foreach my $keys (keys %hash)
{
foreach my $tsw (keys %TSW)
{
if ($keys eq $tsw)
{
$varTSW = $varTSW + $hash{$keys};
}
}
}
my $percentileTSW = ($varTSW/$total)*100;
##################################################################
+VENDA
my $varVEN = 0;
foreach my $keys (keys %hash)
{
foreach my $ven (keys %VEN)
{
if ($keys eq $ven)
{
$varVEN = $varVEN + $hash{$keys};
}
}
}
my $percentileVEN = ($varVEN/$total)*100;
##################################################################
+XHOSA
my $varXHO = 0;
foreach my $keys (keys %hash)
{
foreach my $xho (keys %XHO)
{
if ($keys eq $xho)
{
$varXHO = $varXHO + $hash{$keys};
}
}
}
my $percentileXHO = ($varXHO/$total)*100;
###################################################################
+ZULU
my $varZUL = 0;
foreach my $keys (keys %hash)
{
foreach my $zul (keys %ZUL)
{
if ($keys eq $zul)
{
$varZUL = $varZUL + $hash{$keys};
}
}
}
my $percentileZUL = ($varZUL/$total)*100;
########################################################## Deter
+mine lingo through percentiles
my $highest = $percentileEN;
if ($percentileAFR > $highest)
{
$highest = $percentileAFR;
}
if ($percentileNDB > $highest)
{
$highest = $percentileNDB;
}
if ($percentileSEP > $highest)
{
$highest = $percentileSEP;
}
if ($percentileSIS > $highest)
{
$highest = $percentileSIS;
}
if ($percentileSOT > $highest)
{
$highest = $percentileSOT;
}
if ($percentileTSO > $highest)
{
$highest = $percentileTSO;
}
if ($percentileTSW > $highest)
{
$highest = $percentileTSW;
}
if ($percentileVEN > $highest)
{
$highest = $percentileVEN;
}
if ($percentileXHO > $highest)
{
$highest = $percentileXHO;
}
if ($percentileZUL > $highest)
{
$highest = $percentileZUL;
}
#############################################
if ($highest == $percentileEN)
{
print "This document is ENGLISH\n";
}
elsif ($highest == $percentileAFR)
{
print "This document is AFRIKAANS\n";
}
elsif ($highest == $percentileNDB)
{
print "This document is NDEBELE\n";
}
elsif ($highest == $percentileSEP)
{
print "This document is SEPEDI\n";
}
elsif ($highest == $percentileSIS)
{
print "This document is SISWATI\n";
}
elsif ($highest == $percentileSOT)
{
print "This document is SOTHO\n";
}
elsif ($highest == $percentileTSO)
{
print "This document is TSONGA\n";
}
elsif ($highest == $percentileTSW)
{
print "This document is TSWANA\n";
}
elsif ($highest == $percentileVEN)
{
print "This document is VENDA\n";
}
elsif ($highest == $percentileXHO)
{
print "This document is XHOSA\n";
}
elsif ($highest == $percentileZUL)
{
print "This document is ZULU\n";
}
}
######################################################################
+############################
sub folder
{
my $fname = join("/",@_);
open FIN,"< $fname" or die "$fname:$!";
my @words =<FIN>;
chomp @words;
close FIN;
my @words2;
my @words3;
my %hash;
foreach my $line(@words)
{
@words2 = split(/[\s\t\n]+/,$line);
}
foreach my $correct(@words2)
{
if ($correct =~ /^\w+$/)
{
push (@words3, lc $correct);
}
}
foreach my $val (@words3) #sit input vanaf 2 array in hash in (fre
+kwensie lys)
{
$hash{$val}++;
}
######################################################
my $total = 0;
foreach my $keys (keys %hash)
{
$total = $total + $hash{$keys};
}
###################################################################
+ENGELS
my $varEN = 0;
foreach my $keys (keys %hash)
{
foreach my $key (keys %EN)
{
if ($keys eq $key)
{
$varEN = $varEN + $hash{$keys};
}
}
}
my $percentileEN = ($varEN/$total)*100;
###################################################################
+AFRIKAANS
my $varAFR = 0;
foreach my $keys (keys %hash)
{
foreach my $afr (keys %AFR)
{
if ($keys eq $afr)
{
$varAFR = $varAFR + $hash{$keys};
}
}
}
my $percentileAFR = ($varAFR/$total)*100;
####################################################################
+ NDEBELE
my $varNDB = 0;
foreach my $keys (keys %hash)
{
foreach my $ndb (keys %NDB)
{
if ($keys eq $ndb)
{
$varNDB = $varNDB + $hash{$keys};
}
}
}
my $percentileNDB = ($varNDB/$total)*100;
####################################################################
+SEPEDI
my $varSEP = 0;
foreach my $keys (keys %hash)
{
foreach my $sep (keys %SEP)
{
if ($keys eq $sep)
{
$varSEP = $varSEP + $hash{$keys};
}
}
}
my $percentileSEP = ($varSEP/$total)*100;
####################################################################
+SISWATI
my $varSIS = 0;
foreach my $keys (keys %hash)
{
foreach my $sis (keys %SIS)
{
if ($keys eq $sis)
{
$varSIS = $varSIS + $hash{$keys};
}
}
}
my $percentileSIS = ($varSIS/$total)*100;
####################################################################
+SOTHO
my $varSOT = 0;
foreach my $keys (keys %hash)
{
foreach my $sot (keys %SOT)
{
if ($keys eq $sot)
{
$varSOT = $varSOT + $hash{$keys};
}
}
}
my $percentileSOT = ($varSOT/$total)*100;
##################################################################
+TSONGA
my $varTSO = 0;
foreach my $keys (keys %hash)
{
foreach my $tso (keys %TSO)
{
if ($keys eq $tso)
{
$varTSO = $varTSO + $hash{$keys};
}
}
}
my $percentileTSO = ($varTSO/$total)*100;
##################################################################
+TSWANA
my $varTSW = 0;
foreach my $keys (keys %hash)
{
foreach my $tsw (keys %TSW)
{
if ($keys eq $tsw)
{
$varTSW = $varTSW + $hash{$keys};
}
}
}
my $percentileTSW = ($varTSW/$total)*100;
##################################################################
+VENDA
my $varVEN = 0;
foreach my $keys (keys %hash)
{
foreach my $ven (keys %VEN)
{
if ($keys eq $ven)
{
$varVEN = $varVEN + $hash{$keys};
}
}
}
my $percentileVEN = ($varVEN/$total)*100;
##################################################################
+XHOSA
my $varXHO = 0;
foreach my $keys (keys %hash)
{
foreach my $xho (keys %XHO)
{
if ($keys eq $xho)
{
$varXHO = $varXHO + $hash{$keys};
}
}
}
my $percentileXHO = ($varXHO/$total)*100;
###################################################################
+ZULU
my $varZUL = 0;
foreach my $keys (keys %hash)
{
foreach my $zul (keys %ZUL)
{
if ($keys eq $zul)
{
$varZUL = $varZUL + $hash{$keys};
}
}
}
my $percentileZUL = ($varZUL/$total)*100;
########################################################## Deter
+mine lingo through percentiles
my $highest = $percentileEN;
if ($percentileAFR > $highest)
{
$highest = $percentileAFR;
}
if ($percentileNDB > $highest)
{
$highest = $percentileNDB;
}
if ($percentileSEP > $highest)
{
$highest = $percentileSEP;
}
if ($percentileSIS > $highest)
{
$highest = $percentileSIS;
}
if ($percentileSOT > $highest)
{
$highest = $percentileSOT;
}
if ($percentileTSO > $highest)
{
$highest = $percentileTSO;
}
if ($percentileTSW > $highest)
{
$highest = $percentileTSW;
}
if ($percentileVEN > $highest)
{
$highest = $percentileVEN;
}
if ($percentileXHO > $highest)
{
$highest = $percentileXHO;
}
if ($percentileZUL > $highest)
{
$highest = $percentileZUL;
}
if ($highest == $percentileEN)
{
return 1;
}
elsif ($highest == $percentileAFR)
{
return 2;
}
elsif ($highest == $percentileNDB)
{
return 3;
}
elsif ($highest == $percentileSEP)
{
return 4;
}
elsif ($highest == $percentileSIS)
{
return 5;
}
elsif ($highest == $percentileSOT)
{
return 6;
}
elsif ($highest == $percentileTSO)
{
return 7;
}
elsif ($highest == $percentileTSW)
{
return 8;
}
elsif ($highest == $percentileVEN)
{
return 9;
}
elsif ($highest == $percentileXHO)
{
return 10;
}
elsif ($highest == $percentileZUL)
{
return 11;
}
}
######################################################################
+########################################
sub validate
{
my $num = $_[0];
{
if ($num == 1 || $num == 2)
{
return 1;
}
return 0;
}
}
sub validate2
{
my $num = $_[0];
{
if ($num =~ /1-9/)
{
return 1;
}
return 0;
}
}
close (DIR);
Line 508 is
open FIN,"< $fname" or die "$fname:$!";
Why would the same code work in 1 script, but crash in the other?
Re: No such file or directory error
by eyepopslikeamosquito (Archbishop) on Jan 10, 2013 at 09:52 UTC
|
I can see you are either new to programming or being paid per line of code.
To improve, you need to master the art of abstraction.
When you find yourself repeating the same code over and over again,
stop and think about how you might avoid that nasty duplication.
Based on your sample program, you don't need to get that fancy,
just need to master the basics: functions, loops, arrays and hashes. See also:
As for learning Perl, take a look at learn.perl.org and Perl Tutorial Hub.
Also, be sure to refer to the
Perl online documentation.
Good luck!
| [reply] |
Re: No such file or directory error
by davido (Cardinal) on Jan 10, 2013 at 08:48 UTC
|
I wish I could say that it fails because Perl doesn't let you write 293-line subroutines, but that would be a lie. Perl will let you do that, copy/paste of nearly duplicated code, abstain from reasonable code formatting, and many other practices that make it extremely difficult to spot bugs -- difficult enough that I almost wish the lie were true. Instead, I just move on to questions that don't make my eyes burn.
| [reply] |
|
| [reply] |
Re: No such file or directory error
by jwkrahn (Abbot) on Jan 10, 2013 at 12:50 UTC
|
You have a lot of duplication in your code so I cleaned it up a bit and removed some redundant code.
#!/usr/bin/perl
use warnings;
use strict;
use List::Util qw/ max sum /;
my %file_types = (
ENG => 'ENGLISH',
AFR => 'AFRIKAANS',
NDB => 'NDEBELE',
SEP => 'SEPEDI',
SIS => 'SISWATI',
SOT => 'SOTHO',
TSO => 'TSONGA',
TSW => 'TSWANA',
VEN => 'VENDA',
XHO => 'XHOSA',
ZUL => 'ZULU',
);
my %words;
for my $file ( <korpus*.txt> ) {
$file =~ /\Akorpus([A-Z]{3})\.txt\z/ or next;
my $type = $1;
exists $file_types{ $type } or next;
local $/;
open my $FH, '<', $file or die "Cannot open '$file' because: $!";
@{ $words{ $type } }{ grep length, split /\n/, <$FH> } = ();
}
#############################################################
my $input;
do {
print "To classify a single file, press 1\nTo work within a direct
+ory, press 2\n";
chomp( $input = <STDIN> );
} until $input =~ /\A[12]\z/;
if ( $input == 1 ) {
print "Please type the name of the file you wish to classify\n";
chomp( my $filename = <STDIN> );
folder( $filename );
}
else {
my $dir = 'C:\Users\ZB\Desktop\Text Files';
opendir my $DIR, $dir or die "cannot opendir $dir";
for my $file ( map "$dir/$_", readdir $DIR ) {
next unless -f $file;
folder( $file );
}
}
######################################################################
+############################
sub folder {
my ( $fname ) = @_;
open my $FIN, '<', $fname or die "Cannot open '$fname' because: $!
+";
my %hash;
while ( <$FIN> ) {
while ( /(\w+)/g ) {
$hash{ lc $1 }++;
}
}
######################################################
my $total = sum values %hash;
my @highest = ( '', 0 );
for my $type ( keys %file_types ) {
my $percentile = sum( @hash{ keys %{ $words{ $type } } } ) / $
+total;
@highest = ( $type, $percentile ) if $highest[ 1 ] < $percenti
+le;
}
########################################################## D
+etermine lingo through percentiles
print "The file '$fname' is $file_types{ $highest[ 0 ] }\n";
}
| [reply] [d/l] |
Re: No such file or directory
by CountZero (Bishop) on Jan 10, 2013 at 07:35 UTC
|
Not an answer to your question, but this looks rather "strange": if ($num =~ /1-9/)
Unless you want to check whether $num contains the string '1-9', it will do not what you want, which is probably to check whether $num only contains the figures 1 to 9: if ($num =~ /^[1-9]+$/)
But watch out! The figure 10 will not be accepted by this. Why don't you just do: if ($num >= $minimum and $num <= $maximum and int($num) == $num) { ...
+ }
for whatever the acceptable minimum and maximum values are.
CountZero A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James My blog: Imperial Deltronics
| [reply] [d/l] [select] |
Re: No such file or directory error
by Anonymous Monk on Jan 10, 2013 at 08:59 UTC
|
How come when I run this script ... it works just fine, but when I try using it in a bigger program it gives me the ":No such file or directory found at lingo4.pl line 508" error?
Because cwd is cwd and and readdir doesn't return absolute paths
If you opendir /a/s/d/f and readdir returns . .. foo.txt, then if you try to open foo.txt, you're trying to open cwd()/foo.txt not /a/s/d/f/foo.txt, so open will fail
you should have used File::Find::Rule
Because your bigger program is unwieldy
subroutine declarations are mixed with the main code -- write a single subroutine called Main, and confine the main logic of your program there -- see template at (tye)Re: Stupid question (and see one discussion of that template at Re^2: RFC: Creating unicursal stars
your code is 11 times as long as it should be -- you know how to make subroutines, so write subroutines, don't copy/paste the same code (same loops) 11 times
You're using short and/or meaningless variable names and putting the meaning in comments -- just use meaningful variable names :)
(sub folder) you already know how to use hashes, so don't code long if/else structures to return an integer, use a hash
(calling folder) dozens of while loops are not a substitute for a giant if/else structure -- which you wouldn't need if sub folder teturned a string instead of an integer
or just have sub folder take care of the printing
and while you're at it "folder" is a terrible name for a "sub" -- call it sub processFolder
If you have 14 minutes, watch String Calculator TDD Kata done in Perl , then rewrite your code in a similar fashion
my %korpusEng;
sitKorpusInHash( \%korpusEng , 'korpusENG.txt' )l
...
Another example Out of memory and While replacements with excel XLSX application / Re^2: Out of memory and While replacements with excel XLSX application
good luck | [reply] [d/l] |
|
| [reply] |
|
| [reply] |
|
|