0

I was writing a simple perl script which calculates payment based on the hours given by the user and the program mustn't allow payments above 500 hrs but has to allow upto 600 for females, and I was using the unless function but it is not working it allows more than 600 hrs for females.

here is the code I used

print("Enter your working hours");
    $hours=<stdin>;
    print("Enter your gender");
    $gender=<stdin>;
    chomp($gender);
    unless($gender ne "f" && $hours>=600){
        print("Your have earned ",$hours*10," Birr \n");
    }
    else{
         unless($hours>=500){
            print("Your have earned ",$hours*10," Birr \n");
        }
        else{
            print("You have worked beyond the payable hrs!");
        }
    }
akram seid
  • 91
  • 5
  • Perl has come far since my time. Should it not be `print "bah\n" unless $tasty";`? – Joop Eggen Feb 06 '22 at 18:13
  • yeah it works opposite to if. – akram seid Feb 06 '22 at 18:17
  • 1
    @JoopEggen — `unless` works just like `if`, you **can** use it postfix , but don't have to. – Quentin Feb 06 '22 at 18:18
  • 6
    `unless`...`else` is a huge red flag. `unless` is for short Boolean expressions that need to be negated anyway and can make code cleaner in some limited situations. If you use it with `else`, you're already dealing with both cases, so the negation at the beginning just adds complexity. – Silvio Mayolo Feb 06 '22 at 18:19
  • I tried the code with if reversing the operators and it worked fine but I ran the same code before when we were learning and it just worked fine to. – akram seid Feb 06 '22 at 18:27

2 Answers2

8

Break it down.

it allows more than 600 hrs for females.

Let's try some test data.

$gender = "f";
$hours = 750;

Feed that into your test:

unless($gender ne "f" && $hours>=600){

Replace the variables with the values

unless("f" ne "f" && 750>=600){

Convert the tests to booleans

unless(false && true){

Resolve the logical operator

unless(false);

Which means it runs the expression.


You're confusing yourself with a double negative.

Try to simplify the logic by splitting it apart and avoiding negatives.

my $allowedHours = 500;
if ($gender eq "f") {
    $allowedHours = 600;
}
if ($hours <= $allowedHours) {
    # report
} else {
    # error
}
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
0

I always like to state my assumptions up front in a data structure.

my %allowable_hours = (
  m => 500, # I'm assuming that's your other gender :-)
  f => 600,
);

unless (exists $allowable_hours{$gender}) {
  die "$gender is an unknown gender\n";
}

if ($hours <= $allowable_hours{$gender}) {
  # report
} else {
  # error
}

Makes it easier to edit the allowable hours and add new genders (if that ever becomes necessary).

Dave Cross
  • 68,119
  • 3
  • 51
  • 97