View Full Version : help with counting/matching array items.
After much head-scratching I have reached this point.
@vacantRooms = 010 010 010 010 010 011 011 011 011 011
$numberOfNightsBeingChecked = 5;
Ths array (having been popped in a loop), shows that on all of the $numberOfNightsBeingChecked, rooms 010 and 011 are available for booking.
I need the script to conclude that the number of 010's == $numberOfNightsBeingChecked, to then perfrom a function.
If a hash would be better ( ;) ) I need help wth building it plz.
How can I read the array to know that 010 occurs the same number of times as $numberOfNightsBeingChecked?
bazz
FishMonger
03-04-2006, 07:22 PM
See if this helps.
#!/usr/bin/perl
use Data::Dumper;
$numberOfNightsBeingChecked = 5;
@vacantRooms = qw(010 010 010 010 010 011 011 011 011 011);
for (@vacantRooms) { $booked{$_}++; }
print Dumper %booked;
for $room (keys %booked) {
print "Room $room booked for $booked{$room} nights\n";
if ($numberOfNightsBeingChecked == $booked{$room}) {
print "\tnumber Of Nights Being Checked == nights booked\n";
}
}
Outputs:
$VAR1 = '011';
$VAR2 = 5;
$VAR3 = '010';
$VAR4 = 5;
Room 011 booked for 5 nights
number Of Nights Being Checked == nights booked
Room 010 booked for 5 nights
number Of Nights Being Checked == nights booked
FishMonger,without that I'd have been sitting here next month . Thanks, though I get a different output and it shows that rooms 010 is booked for ten nights, when only 5 should be checked. I think this is because its in a loop If I take it outside of the loop, it returns a result for all the files, not just those which I have already read in.
numberOfNightsRequested = 5 at = 010 010 010 010 010
$VAR1 = '010'; $VAR2 = '5'; Room 010 vacant for 5 nights number Of Nights Being Checked == nights booked numberOfNightsRequested = 5 at = 010 010 010 010 010 011 011 011 011 011
$VAR1 = '010'; $VAR2 = '10'; $VAR3 = '011'; $VAR4 = '5'; Room 010 vacant for 10 nights Room 011 vacant for 5 nights number Of Nights Being Checked == nights booked
I've tried it outside the loop and inside. This output is closest as it prefroms the function only for the files that are relevant.
In case you need the full script here it is. I hope it's within the limit.
As ever, any assistance really appreciated
sub processBooking {
my $dateRequested = $query->param('dateRequested');
my $monthRequested = $query->param('monthRequested');
my $yearRequested = $query->param('yearRequested');
my $numberOfNightsRequested = $query->param('numberOfNightsRequested');
my $booked = 0;
my $roomTypeRequested = $query->param('roomTypeRequested');
my $numericalMonthOfYear;
my $numericalMonthRequested;
my $actualNumericalMonthRequested;
my $countVacancies = 0;
my $additionalNight;
my $actualNightOfStay;
my $date = $dateRequested;
my $last = substr($date, -1, length($date)); #Get the last digit
my $first = substr($date, 0, 1); #for dates that are like: 01,02,03 etc.
if($first == 0){$date = $last;} #change them to: 1,2,3 etc.
unless(($first == 1)&&(length($date) == 2)){ #take care of the "teens"
if($last == 0){$date = $date."th";}
if($last == 1){$date = $date."st";}
if($last == 2){$date = $date."nd";}
if($last == 3){$date = $date."rd";}
if($last == 4){$date = $date."th";}
if($last == 5){$date = $date."th";}
if($last == 6){$date = $date."th";}
if($last == 7){$date = $date."th";}
if($last == 8){$date = $date."th";}
if($last == 9){$date = $date."th";}
}
else
{
$date = $date."th";
}
if ($monthRequested eq "January") {
$numericalMonthRequested = "01";}
if ($monthRequested eq "February") {
$numericalMonthRequested = "02";}
if ($monthRequested eq "March") {
$numericalMonthRequested = "03";}
if ($monthRequested eq "April") {
$numericalMonthRequested = "04";}
if ($monthRequested eq "May") {
$numericalMonthRequested = "05";}
if ($monthRequested eq "June") {
$numericalMonthRequested = "06";}
if ($monthRequested eq "July") {
$numericalMonthRequested = "07";}
if ($monthRequested eq "August") {
$numericalMonthRequested = "08";}
if ($monthRequested eq "September") {
$numericalMonthRequested = "09";}
if ($monthRequested eq "October") {
$numericalMonthRequested = "10";}
if ($monthRequested eq "November") {
$numericalMonthRequested = "11";}
if ($monthRequested eq "December") {
$numericalMonthRequested = "12";}
my $dateBeingChecked = join "-", ($yearRequested, $numericalMonthRequested, $dateRequested);
my $titleDate = join " ", $dateRequested, $monthRequested, $yearRequested;
my $Filepath = "/domains/574/2317/html/cgi-bin/$clientsReservationsDir/Rooms_Booked/$yearRequested/"; # to read in files for all dates.
opendir(my $dir,$Filepath);
while(my $roomsBooked=readdir($dir)){
next unless -f $Filepath.$roomsBooked && $roomsBooked!~/^\.+$/;
push(@rooms,$roomsBooked);
}
closedir($dir); # All booked dates are now read in.
foreach my $filename (sort @rooms ) { # sort thru the booked rooms files
chomp;
my ($roomType, $roomNumber, $date) = split /_/, $filename, 4;
#$rooms{$roomNumber}{$roomDate}{$roomType}= $_;
my $fullDateRequested = join "-", $yearRequested, $numericalMonthRequested, $dateRequested;
my $specificRoomRequested = join "_", $roomTypeRequested, $roomNumber, $fullDateRequested;
#my $specificRoom = join "_", ($roomTypeRequested, $roomNumber, $fullDateRequested);
#my $dat_file = "$Filepath$specificRoomRequested";
my ($checkOutYear, $checkOutMonth, $checkOutDay) = split /\-/, $checkOutDate, 3;
my($roomYear,$roomMonth, $roomDay) = split /\-/, $dateBeingChecked, 3;
my ($checkInYear, $checkInMonth, $checkInDay ) = split /\-/, $checkInDate, 3;
if ($specificRoomRequested eq $filename) {
my $zero = 0;
my $nightOfStay = ($dateRequested - 1);
while ($nightOfStay < ($dateRequested + ($numberOfNightsRequested - 1))) {
$nightOfStay++;
if ($numericalMonthRequested == '09' || $numericalMonthRequested == '04' || $numericalMonthRequested == '06' || $numericalMonthRequested == '11' ){
$actualNightOfStay = $nightOfStay;
$actualNumericalMonthRequested = $numericalMonthRequested;
if ( $actualNightOfStay > 30 ){
$actualNightOfStay = ($actualNightOfStay - 30);
$actualNightOfStay = join "", "$zero", "$actualNightOfStay";
$actualNumericalMonthRequested = ($actualNumericalMonthRequested + 1);
$actualNumericalMonthRequested = join "", "$zero", "$actualNumericalMonthRequested";
}
}
if ($Month == 02 && $Date > '29' ) {
next;
} elsif ($Month == 02 && $yearDivided =~ m/\./ && $Date > '28' ) {
next;
}
my $allDatesRequested = join "-", $yearRequested, $actualNumericalMonthRequested, $actualNightOfStay;
my $roomFileHandle = join "_", $roomType, $roomNumber, $allDatesRequested;
$datFile="$Filepath$roomFileHandle";
#open DAT, "< $datFile" || die "couldnt open file\n";
while ( my $Line = <DAT> ) {
last if ( index($Line, ':') == -1 );
chomp $Line;
my ( $Keyword, $Value ) = split /:/, $Line, 2; #splits the line at the first : ignoring any others
if ($Keyword eq "BookingReference") {
$bookingReference = $Value;
chop $bookingReference;
} # end of if
} # end of while
if (!$bookingReference) {
$countVacancies++;
} # end of if
push(@vacantRooms, $roomNumber);
} # end while loop
print "numberOfNightsRequested = $numberOfNightsRequested\n";
print "at = @vacantRooms<br />\n";
for (@vacantRooms) { $vacant{$_}++; }
print Dumper %vacant;
for $room (keys %vacant) {
print "Room $room vacant for $vacant{$room} nights\n";
if ($numberOfNightsRequested == $vacant{$room}) {
print "\tnumber Of Nights Being Checked == nights booked\n";
}
}
} # end if $specificRoomRequested = $filename
} # end foreach @rooms
FishMonger
03-04-2006, 11:08 PM
I haven't had a chance to troubleshoot it, but it would make it a lot easier if you used proper indentation.
sub processBooking {
my $dateRequested = $query->param('dateRequested');
my $monthRequested = $query->param('monthRequested');
my $yearRequested = $query->param('yearRequested');
my $numberOfNightsRequested = $query->param('numberOfNightsRequested');
my $booked = 0;
my $roomTypeRequested = $query->param('roomTypeRequested');
my $numericalMonthOfYear;
my $numericalMonthRequested;
my $actualNumericalMonthRequested;
my $countVacancies = 0;
my $additionalNight;
my $actualNightOfStay;
my $date = $dateRequested;
my $last = substr($date, -1, length($date)); #Get the last digit
my $first = substr($date, 0, 1); #for dates that are like: 01,02,03 etc.
if($first == 0){$date = $last;} #change them to: 1,2,3 etc.
unless(($first == 1)&&(length($date) == 2)){ #take care of the "teens"
if($last == 0){$date = $date."th";}
if($last == 1){$date = $date."st";}
if($last == 2){$date = $date."nd";}
if($last == 3){$date = $date."rd";}
if($last == 4){$date = $date."th";}
if($last == 5){$date = $date."th";}
if($last == 6){$date = $date."th";}
if($last == 7){$date = $date."th";}
if($last == 8){$date = $date."th";}
if($last == 9){$date = $date."th";}
}
else
{
$date = $date."th";
}
if ($monthRequested eq "January") {$numericalMonthRequested = "01";}
if ($monthRequested eq "February") {$numericalMonthRequested = "02";}
if ($monthRequested eq "March") {$numericalMonthRequested = "03";}
if ($monthRequested eq "April") {$numericalMonthRequested = "04";}
if ($monthRequested eq "May") {$numericalMonthRequested = "05";}
if ($monthRequested eq "June") {$numericalMonthRequested = "06";}
if ($monthRequested eq "July") {$numericalMonthRequested = "07";}
if ($monthRequested eq "August") {$numericalMonthRequested = "08";}
if ($monthRequested eq "September") {$numericalMonthRequested = "09";}
if ($monthRequested eq "October") {$numericalMonthRequested = "10";}
if ($monthRequested eq "November") {$numericalMonthRequested = "11";}
if ($monthRequested eq "December") {$numericalMonthRequested = "12";}
my $dateBeingChecked = join "-", ($yearRequested, $numericalMonthRequested, $dateRequested);
my $titleDate = join " ", $dateRequested, $monthRequested, $yearRequested;
my $Filepath = "/domains/574/2317/html/cgi-bin/$clientsReservationsDir/Rooms_Booked/$yearRequested/"; # to read in files for all dates.
opendir(my $dir,$Filepath);
while(my $roomsBooked=readdir($dir)){
next unless -f $Filepath.$roomsBooked && $roomsBooked!~/^\.+$/;
push(@rooms,$roomsBooked);
}
closedir($dir); # All booked dates are now read in.
foreach my $filename (sort @rooms ) { # sort thru the booked rooms files
chomp;
my ($roomType, $roomNumber, $date) = split /_/, $filename, 4;
#$rooms{$roomNumber}{$roomDate}{$roomType}= $_;
my $fullDateRequested = join "-", $yearRequested, $numericalMonthRequested, $dateRequested;
my $specificRoomRequested = join "_", $roomTypeRequested, $roomNumber, $fullDateRequested;
#my $specificRoom = join "_", ($roomTypeRequested, $roomNumber, $fullDateRequested);
#my $dat_file = "$Filepath$specificRoomRequested";
my ($checkOutYear, $checkOutMonth, $checkOutDay) = split /\-/, $checkOutDate, 3;
my($roomYear,$roomMonth, $roomDay) = split /\-/, $dateBeingChecked, 3;
my ($checkInYear, $checkInMonth, $checkInDay ) = split /\-/, $checkInDate, 3;
if ($specificRoomRequested eq $filename) {
my $zero = 0;
my $nightOfStay = ($dateRequested - 1);
while ($nightOfStay < ($dateRequested + ($numberOfNightsRequested - 1))) {
$nightOfStay++;
if ($numericalMonthRequested == '09' || $numericalMonthRequested == '04' || $numericalMonthRequested == '06' || $numericalMonthRequested == '11' ){
$actualNightOfStay = $nightOfStay;
$actualNumericalMonthRequested = $numericalMonthRequested;
if ( $actualNightOfStay > 30 ){
$actualNightOfStay = ($actualNightOfStay - 30);
$actualNightOfStay = join "", "$zero", "$actualNightOfStay";
$actualNumericalMonthRequested = ($actualNumericalMonthRequested + 1);
$actualNumericalMonthRequested = join "", "$zero", "$actualNumericalMonthRequested";
}
}
if ($Month == 02 && $Date > '29' ) {
next;
} elsif ($Month == 02 && $yearDivided =~ m/\./ && $Date > '28' ) {
next;
}
my $allDatesRequested = join "-", $yearRequested, $actualNumericalMonthRequested, $actualNightOfStay;
my $roomFileHandle = join "_", $roomType, $roomNumber, $allDatesRequested;
$datFile="$Filepath$roomFileHandle";
#open DAT, "< $datFile" || die "couldnt open file\n";
while ( my $Line = <DAT> ) {
last if ( index($Line, ':') == -1 );
chomp $Line;
my ( $Keyword, $Value ) = split /:/, $Line, 2; #splits the line at the first : ignoring any others
if ($Keyword eq "BookingReference") {
$bookingReference = $Value;
chop $bookingReference;
} # end of if
} # end of while
if (!$bookingReference) {
$countVacancies++;
} # end of if
push(@vacantRooms, $roomNumber);
} # end while loop
print "numberOfNightsRequested = $numberOfNightsRequested\n";
print "at = @vacantRooms<br />\n";
for (@vacantRooms) { $vacant{$_}++; }
print Dumper %vacant;
for $room (keys %vacant) {
print "Room $room vacant for $vacant{$room} nights\n";
if ($numberOfNightsRequested == $vacant{$room}) {
print "\tnumber Of Nights Being Checked == nights booked\n";
}
}
} # end if $specificRoomRequested = $filename
} # end foreach @rooms
I agree FishMonger and Thank you.
My eyes find it much easier now whereas, before, I had trouble working out a consistent method of indentation. :(
Using that code, above, with this, possibly, different dataDumper part,
for (@vacantRooms) { $vacant{$_}++; }
# print Dumper %vacant;
for $room (keys %vacant) {
print "Room $room vacant for $vacant{$room} nights<br />\n";
#print "cv =$countLoops<br />\n";
if ($numberOfNightsRequested == $vacant{$room}) {
print "\tnumber Of Nights Being Checked == nights booked<br />\n";
} # end if
} # end for $room(keys %vacant)
I find a potential bug. Not with your code - I hasten to add.
On the basis that I want to stay from 29th April 2007, for two nights, in a twin room, and that room 010 is not available for the second of those nights , I get this output.
Room 010 vacant for 1 nights
Room 010 vacant for 2 nights
number Of Nights Being Checked == nights booked
Room 011 vacant for 2 nights
number Of Nights Being Checked == nights booked
so even though it knows on first read that room 010 is unavailable for the $numberOfNightsRequested, it shows that it is available because of the looping. I am trying to think how to make it loop without re-reading the rooms of the previous loop. possibly using 'count' or the $VAR2 from the %vacant hash?
And I notice that the array has, at the end of looping, reads like this:
@vacantRrooms = 010 011 012 012 013 013
The frequency of each room number equates to frequency of times the room is available.
bazz
Maybe this is better.
output
at vacant rooms = 010 011 012 012 013 013
$VAR1 = '012'; $VAR2 = '2'; $VAR3 = '013'; $VAR4 = '2'; $VAR5 = '010'; $VAR6 = '1'; $VAR7 = '011'; $VAR8 = '1'; Room 012 vacant for 2 nights
number Of Nights Being Checked == nights booked
Room 013 vacant for 2 nights
number Of Nights Being Checked == nights booked
Room 010 vacant for 1 nights
Room 011 vacant for 1 nights
so Rooms 12 and 13 are available for a booking for two nights. Can you tell me: -
1. will $VAR1 always hold the lower room number which shows availability?
2. Bearing in mind that there could be a lot of rooms in the above list, is there a way to jump out of the loop as soon as the @vacancies holds the correct data?
bazz
ps here's the full sub in its present form.
sub processBooking {
my $dateRequested = $query->param('dateRequested');
my $monthRequested = $query->param('monthRequested');
my $yearRequested = $query->param('yearRequested');
my $numberOfNightsRequested = $query->param('numberOfNightsRequested');
my $booked = 0;
my $roomTypeRequested = $query->param('roomTypeRequested');
my $numericalMonthOfYear;
my $numericalMonthRequested;
my $actualNumericalMonthRequested;
my $countVacancies = 0;
my $countLoops = 0;
my $additionalNight;
my $actualNightOfStay;
my $date = $dateRequested;
my $last = substr($date, -1, length($date)); #Get the last digit
my $first = substr($date, 0, 1); #for dates that are like: 01,02,03 etc.
if($first == 0){$date = $last;} #change them to: 1,2,3 etc.
unless(($first == 1)&&(length($date) == 2)){ #take care of the "teens"
if($last == 0){$date = $date."th";}
if($last == 1){$date = $date."st";}
if($last == 2){$date = $date."nd";}
if($last == 3){$date = $date."rd";}
if($last == 4){$date = $date."th";}
if($last == 5){$date = $date."th";}
if($last == 6){$date = $date."th";}
if($last == 7){$date = $date."th";}
if($last == 8){$date = $date."th";}
if($last == 9){$date = $date."th";}
}
else
{
$date = $date."th";
}
if ($monthRequested eq "January") {$numericalMonthRequested = "01";}
if ($monthRequested eq "February") {$numericalMonthRequested = "02";}
if ($monthRequested eq "March") {$numericalMonthRequested = "03";}
if ($monthRequested eq "April") {$numericalMonthRequested = "04";}
if ($monthRequested eq "May") {$numericalMonthRequested = "05";}
if ($monthRequested eq "June") {$numericalMonthRequested = "06";}
if ($monthRequested eq "July") {$numericalMonthRequested = "07";}
if ($monthRequested eq "August") {$numericalMonthRequested = "08";}
if ($monthRequested eq "September") {$numericalMonthRequested = "09";}
if ($monthRequested eq "October") {$numericalMonthRequested = "10";}
if ($monthRequested eq "November") {$numericalMonthRequested = "11";}
if ($monthRequested eq "December") {$numericalMonthRequested = "12";}
my $dateBeingChecked = join "-", ($yearRequested, $numericalMonthRequested, $dateRequested);
my $titleDate = join " ", $dateRequested, $monthRequested, $yearRequested;
my $Filepath = "/domains/574/2317/html/cgi-bin/$clientsReservationsDir/Rooms_Booked/$yearRequested/"; # to read in files for all dates.
opendir(my $dir,$Filepath);
while(my $roomsBooked=readdir($dir)){
next unless -f $Filepath.$roomsBooked && $roomsBooked!~/^\.+$/;
push(@rooms,$roomsBooked);
}
closedir($dir); # All booked dates are now read in.
foreach my $filename (sort @rooms ) { # sort thru the booked rooms files
chomp;
my ($roomType, $roomNumber, $date) = split /_/, $filename, 4;
#$rooms{$roomNumber}{$roomDate}{$roomType}= $_;
my $fullDateRequested = join "-", $yearRequested, $numericalMonthRequested, $dateRequested;
my $specificRoomRequested = join "_", $roomTypeRequested, $roomNumber, $fullDateRequested;
#my $specificRoom = join "_", ($roomTypeRequested, $roomNumber, $fullDateRequested);
#my $dat_file = "$Filepath$specificRoomRequested";
my ($checkOutYear, $checkOutMonth, $checkOutDay) = split /\-/, $checkOutDate, 3;
my($roomYear,$roomMonth, $roomDay) = split /\-/, $dateBeingChecked, 3;
my ($checkInYear, $checkInMonth, $checkInDay ) = split /\-/, $checkInDate, 3;
if ($specificRoomRequested eq $filename) {
my $zero = 0;
my $nightOfStay = ($dateRequested - 1);
while ($nightOfStay < ($dateRequested + ($numberOfNightsRequested - 1))) {
$nightOfStay++;
if ($numericalMonthRequested == '09' || $numericalMonthRequested == '04' || $numericalMonthRequested == '06' || $numericalMonthRequested == '11' ){
$actualNightOfStay = $nightOfStay;
$actualNumericalMonthRequested = $numericalMonthRequested;
if ( $actualNightOfStay > 30 ){
$actualNightOfStay = ($actualNightOfStay - 30);
$actualNightOfStay = join "", "$zero", "$actualNightOfStay";
$actualNumericalMonthRequested = ($actualNumericalMonthRequested + 1);
$actualNumericalMonthRequested = join "", "$zero", "$actualNumericalMonthRequested";
}
}
if ($Month == 02 && $Date > '29' ) {
next;
} elsif ($Month == 02 && $yearDivided =~ m/\./ && $Date > '28' ) {
next;
}
my $allDatesRequested = join "-", $yearRequested, $actualNumericalMonthRequested, $actualNightOfStay;
my $roomFileHandle = join "_", $roomType, $roomNumber, $allDatesRequested;
$datFile="$Filepath$roomFileHandle";
#print "dat_file =$datFile<br />\n"; # successful
open DAT, "< $datFile" || die "couldnt open file\n";
while ( my $Line = <DAT> ) {
last if ( index($Line, ':') == -1 );
chomp $Line;
my ( $Keyword, $Value ) = split /:/, $Line, 2; #splits the line at the first : ignoring any others
if ($Keyword eq "BookingReference") {
$bookingReference = $Value;
chop $bookingReference;
} # end of if
} # end of while
if (!$bookingReference) {
$countVacancies++;
push(@vacantRooms, $roomNumber);
} # end of if
} # end while loop
} # end if $specificRoomRequested = $filename
} # end foreach @rooms
print "at vacant rooms = @vacantRooms<br />\n";
for (@vacantRooms) { $vacant{$_}++; }
print Dumper %vacant;
for $room (keys %vacant) {
print "Room $room vacant for $vacant{$room} nights<br />\n";
if ($numberOfNightsRequested == $vacant{$room}) {
print "\tnumber Of Nights Being Checked == nights booked<br />\n";
#&enterDetails;
#exit;
} # end if
} # end for $room(keys %vacant)
## make sure this file outputs the number of rooms available ###
} # end sub
vBulletin® v3.8.2, Copyright ©2000-2012, Jelsoft Enterprises Ltd.