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:
Code wont work for names other than last two in the list!!

 



iThunder
Novice

Oct 18, 2013, 1:15 AM

Post #1 of 20 (375 views)
Code wont work for names other than last two in the list!! Can't Post

#!C:\Perl64\bin
init_words();
print "What is your name Mr. \n";
$name = <STDIN>;
chomp ($name);
if ($name =~ /^randal\b/i){
print "Hello, Randal, How are you doing \n";
}
else{
print "Hello, $name!\n";
print "Tell the secret word\n";
$guess = <STDIN>;
chomp ($guess);
while (!good_word ($name,$guess)){
print "Wrong, please try again\n";
$guess = <STDIN>;
chomp ($guess);
}
}


sub init_words {
open (WORDSLIST, "wordslist.txt") || die "can't open wordslist: $!";
$k = 1;
$a = 0;
$b = 0;
while (defined ($name = <WORDSLIST>)) {


if ($k % 2 == 0){

chomp ($name);

@words1[$a] = $name;
++$k;
++$a; }

else{
chomp ($name);
@words2[$b] = $name;
++$k;
++$b;

}

}

close (WORDSLIST) || die "couldn't close wordlist: $!";
}

sub good_word {
my ($somename, $someguess) = @_;
$somename =~ s/\W.*//;
$somename =~ tr/A-Z/a-z/;
if ($somename eq "randal"){
return 1;}
else {
#$n = 0;
$t = scalar @words1;
$u = scalar @words2;
print "the words2 array is @words2";
for ($d = 0; $d < $u; $d++)
{
print "currently name in array is @words2[$d]\n";
print "The value of somename is $somename \n";
if ("@words2[$d]" eq "$somename"){
print "test";
return 1;}
}
#print "The final value of d is $d";
#print " The final value of array is @words1[$d]";
#if ("groucho" eq $someguess){
#return 1;}
#else{
#while ($n < $t){
#if (@words1[$n] eq $someguess) {
#return 1;}
#else { ++$n};
}

}
# }
#}


the main purpose of the program is that if i input a name along with a guess, perl program should look for all names stored in @words2 and if it find a match, 1 should be returned.
I have wordlist of 12 words where every odd number of list items will be put into wordslist2. For some reason, this code is only working if last words of the wordslist are input.
Any suggestions??
Crazy


Zhris
User

Oct 18, 2013, 6:11 AM

Post #2 of 20 (369 views)
Re: [iThunder] Code wont work for names other than last two in the list!! [In reply to] Can't Post

Hi,

You could try wrapping the printed variables in square brackets to visually guarantee that they really are equal, then monitor.


Code
print "currently name in array is [@words2[$d]]\n";  
print "The value of somename is [$somename] \n";


If there appears to be a newline after @words[$d], then its possible that your input data contains carriage returns, therefore locally adjust the input record separator.


Code
sub init_words {  
local $/ = "\r\n";


Chris


BillKSmith
Veteran

Oct 18, 2013, 6:19 AM

Post #3 of 20 (367 views)
Re: [iThunder] Code wont work for names other than last two in the list!! [In reply to] Can't Post

You must access elements of an array with $word1[$d] not with @word1[$d]. This error occurs in several places.
Always use strict and warnings. Fix all errors they report.(They would have found this problem.)
Good Luck,
Bill


iThunder
Novice

Oct 18, 2013, 11:28 AM

Post #4 of 20 (354 views)
Re: [Zhris] Code wont work for names other than last two in the list!! [In reply to] Can't Post

Hi,

Thanks for quick reply. The frustating part is that if i replace@words2 with @words1 and $name with $someguess in my "if statement", it start working absolutely fine i.e. it will check all the elements in @words1 and if finds that guess value is same as one of the elements, the program will end with "test" being printed.
I do not know what i am doing wrong when putting @words2.

In Reply To


iThunder
Novice

Oct 18, 2013, 11:34 AM

Post #5 of 20 (353 views)
Re: [BillKSmith] Code wont work for names other than last two in the list!! [In reply to] Can't Post

Hi,

Thanks for your reply. For a test, i ran the following code and it is executing as expected i.e. no need to use $word1[$d]

$n = 2;
@tw = qw (nasir bashir salman);
$u = scalar @tw;
for ($k = 0; $k <= $u; $k++){

if (@tw[$k] eq "bashir"){
print "this is the test $k \n";
}
}


Zhris
User

Oct 18, 2013, 11:50 AM

Post #6 of 20 (350 views)
Re: [iThunder] Code wont work for names other than last two in the list!! [In reply to] Can't Post

Hi,

You should always use strict and warnings. Run the snippet below and you'll see numerous errors:


Code
use strict; 
use warnings;

$n = 2;
@tw = qw (nasir bashir salman);
$u = scalar @tw;
for ($k = 0; $k <= $u; $k++){

if (@tw[$k] eq "bashir"){
print "this is the test $k \n";
}
}


Could you please attach wordslist.txt so I can test with the same data as you. Unless i'm misunderstanding the issue, I do not experience any problems running a slightly modified version of your code.

Chris


FishMonger
Veteran / Moderator

Oct 18, 2013, 11:55 AM

Post #7 of 20 (347 views)
Re: [iThunder] Code wont work for names other than last two in the list!! [In reply to] Can't Post


Quote

Code
for ($k = 0; $k <= $u; $k++){


C style for loops are ugly. It's cleaner AND more efficient to use the perl style for loop.


Code
for my $k (0..$u) { # single letter var names are generally not desirable.



Zhris
User

Oct 18, 2013, 12:03 PM

Post #8 of 20 (345 views)
Re: [iThunder] Code wont work for names other than last two in the list!! [In reply to] Can't Post

Also,

If you replace @words2 with @words1, you'll probably want to adjust the for loop to use $t instead of $u.

A better way would be:

Code
foreach my $word2 (@words2) { ... }


Chris


iThunder
Novice

Oct 18, 2013, 12:08 PM

Post #9 of 20 (340 views)
Re: [Zhris] Code wont work for names other than last two in the list!! [In reply to] Can't Post

yup thats correct. i did it and its working fine...
but wont work with @words2.


FishMonger
Veteran / Moderator

Oct 18, 2013, 12:10 PM

Post #10 of 20 (340 views)
Re: [iThunder] Code wont work for names other than last two in the list!! [In reply to] Can't Post

Another suggestion would be to store the word list in a hash instead of an array. Doing a hash lookup is much more efficient that looping over array elements.

However, I'm assuming that using the arrays were your design and not a requirement made by your instructor.


iThunder
Novice

Oct 18, 2013, 12:19 PM

Post #11 of 20 (338 views)
Re: [FishMonger] Code wont work for names other than last two in the list!! [In reply to] Can't Post

You are right FishMonger..but my question is what is different between @words1 and @words2. I am going over program again and again but not able to understand that why is it working for @words1 and not @words2.


Zhris
User

Oct 18, 2013, 12:31 PM

Post #12 of 20 (333 views)
Re: [iThunder] Code wont work for names other than last two in the list!! [In reply to] Can't Post

Can you attach wordslist.txt please.

Chris


iThunder
Novice

Oct 18, 2013, 12:37 PM

Post #13 of 20 (330 views)
Re: [Zhris] Code wont work for names other than last two in the list!! [In reply to] Can't Post

john
bubble
catherine
pencil


above is my wordlist...only four words...stored in wordslist.txt file in same directory as where my perl program is stored....The main goal is to split the above list into two sublists i.e. words1 = [bubble pencil] and words2 = [john catherine]. User is asked for input i.e. name and a secret word. If name matches any of names in words2, the program should print test and exit.


Zhris
User

Oct 18, 2013, 1:07 PM

Post #14 of 20 (321 views)
Re: [iThunder] Code wont work for names other than last two in the list!! [In reply to] Can't Post

Hi,

Its always best to attach the actual input file because I can't guarantee that my input file will be identical to yours after copying and pasting. For example, there is an extra whitespace on the end of each word which I have removed.


Quote
The main goal is to split the above list into two sublists i.e. words1 = [bubble pencil] and words2 = [john catherine]. User is asked for input i.e. name and a secret word. If name matches any of names in words2, the program should print test and exit.


Based on your description above, for now you do not make use of the secret word. Here is my substantially modified version I am testing against your data using http://www.compileonline.com/execute_perl_online.php. NOTE that its been modified to work with compileonline only and will not work in your environment. I have switched the arrays and do not experience any issues either way (using @words1 or @words2), so long as I choose an appropriate name...


Code
init_words();  
print "What is your name Mr. \n";
$name = <STDIN>;
chomp ($name);
if ($name =~ /^randal\b/i){
print "Hello, Randal, How are you doing \n";
}
else{
print "Hello, $name!\n";
print "Tell the secret word\n";
$guess = <STDIN>;
chomp ($guess);
print good_word($name,$guess);
}


sub init_words {
local $/ = "\r\n";
open (WORDSLIST, "input.txt") || die "can't open wordslist: $!";
$k = 1;
$a = 0;
$b = 0;
while (defined ($name = <WORDSLIST>)) {


if ($k % 2 == 0){

chomp ($name);

@words1[$a] = $name;
++$k;
++$a; }

else{
chomp ($name);
@words2[$b] = $name;
++$k;
++$b;

}

}

close (WORDSLIST) || die "couldn't close wordlist: $!";
}

sub good_word {
my ($somename, $someguess) = @_;
$somename =~ s/\W.*//;
$somename =~ tr/A-Z/a-z/;
if ($somename eq "randal"){
return 1;}
else {
#$n = 0;
$t = scalar @words1;
$u = scalar @words2;
print "the words2 array is @words1\n\n";
for ($d = 0; $d < $t; $d++)
{
print "currently name in array is [@words1[$d]]\n";
print "The value of somename is [$somename] \n\n";
if ("@words1[$d]" eq "$somename"){
print "test";
return 1;}
}
#print "The final value of d is $d";
#print " The final value of array is @words1[$d]";
#if ("groucho" eq $someguess){
#return 1;}
#else{
#while ($n < $t){
#if (@words1[$n] eq $someguess) {
#return 1;}
#else { ++$n};
}

}
# }
#}


Since I don't understand the problem, I can't be of much more help.

Here is my rework of your script. You can switch whether you use odd or even words by negating the (++$i % 2) i.e. !(++$i % 2)...


Code
#!/usr/bin/perl 
use strict;
use warnings;

chomp(my $name = <STDIN>);

my $words = init_words('wordslist.txt');
my $response = good_word($words, $name);

print $response;

sub init_words
{
my $filename = shift;

open my $fh, '<', $filename or die "cannot open $filename: $!";
my @words = <$fh>;
close $fh;

chomp @words;

return \@words;
}

sub good_word
{
my ($words, $name) = @_;

#$name =~ s/\W.*//;
$name = lc $name;

my $i = 0;
return 1 if (($name eq 'randal') || (grep { (++$i % 2) && ($_ eq $name) } @$words));

return 0;
}


or...


Code
#!/usr/bin/perl 
use strict;
use warnings;

chomp(my $name = <STDIN>);

my ($odd_words, $even_words) = init_words('wordslist.txt');
my $response = good_word($even_words, $name);

print $response;

sub init_words
{
my $filename = shift;

open my $fh, '<', $filename or die "cannot open $filename: $!";
my @words = <$fh>;
close $fh;

chomp @words;

my ($i, @odd_words, @even_words);
push @{++$i % 2 ? \@odd_words : \@even_words}, $_ for (@words);

return (\@odd_words, \@even_words);
}

sub good_word
{
my ($words, $name) = @_;

#$name =~ s/\W.*//;
$name = lc $name;

return 1 if (($name eq 'randal') || (grep { $_ eq $name } @$words));

return 0;
}


Chris


(This post was edited by Zhris on Oct 18, 2013, 2:24 PM)


FishMonger
Veteran / Moderator

Oct 18, 2013, 1:49 PM

Post #15 of 20 (308 views)
Re: [iThunder] Code wont work for names other than last two in the list!! [In reply to] Can't Post

As I understand it, @words2 should hold names and @words1 should hold "secret" words i.e., passwords.

I'm going to assume that your description of what needs to be done is incomplete and that you need to match a name with a password.

If john was the name entered, should a successful match for the "secret" word be bubble, or is it ok for it to match any of the secret words?


iThunder
Novice

Oct 18, 2013, 5:51 PM

Post #16 of 20 (297 views)
Re: [FishMonger] Code wont work for names other than last two in the list!! [In reply to] Can't Post

That is correct FishMonger... this is my ultimate goal but before gettting to it , i need my list names to be matched with input. For easiness, i have tested another script and seeing the same issue.

$somename = <STDIN>;
chomp ($somename);
@words2 = qw (john catherine alex);
$u = @words2;
for ($d = 0; $d < $u; $d++)
{
#print "currently name in array is @words2[$d]\n";
#print "The value of somename is $somename \n";

$delta = $words2[$d];
print "The value of delta is $delta \n";
#use strict; use warnings;
if ($delta eq $somename){
print "test";
#return 1;
}
}

Now in this script, if i input any of the words i.e. john, catherine or alex, "test" wont be printed. Looks like if statement is not matching...


FishMonger
Veteran / Moderator

Oct 18, 2013, 6:21 PM

Post #17 of 20 (292 views)
Re: [iThunder] Code wont work for names other than last two in the list!! [In reply to] Can't Post

I see a couple issues with that code, but won't be able to post a proper response until tomorrow.


iThunder
Novice

Oct 18, 2013, 6:59 PM

Post #18 of 20 (285 views)
Re: [FishMonger] Code wont work for names other than last two in the list!! [In reply to] Can't Post

ok no problem....thanks


BillKSmith
Veteran

Oct 18, 2013, 7:40 PM

Post #19 of 20 (280 views)
Re: [iThunder] Code wont work for names other than last two in the list!! [In reply to] Can't Post

I cannot duplicate your problem with the new code. The word 'test' is hidden in a sea of messages.
Sample Output:

Code
The value of delta is john  
The value of delta is catherine
testThe value of delta is alex


I also find that your original code 'works' if I use all lower case in the data file and in the user input. The code to convert everything to lower case is in the wrong place.
Good Luck,
Bill


iThunder
Novice

Oct 18, 2013, 9:31 PM

Post #20 of 20 (274 views)
Re: [BillKSmith] Code wont work for names other than last two in the list!! [In reply to] Can't Post

yup you are right...its working on new code.

 
 


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

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