Don Roberto
Don Roberto

Reputation: 11

Is there something wrong with my if-else statements?

Given an integer, , perform the following conditional actions:

If is odd, print Weird If is even and in the inclusive range of 2 to 5, print Not Weird If is even and in the inclusive range of 6 to 20, print Weird If is even and greater than 20, print Not Weird

Every time I run the code, it only executes the else statement else: print("lol") , whether I type any value from 1 to 25. What's wrong?

n = input("Enter a number here: ")
num = int(n)
if (num % 2) == 0 >= 2 and (num % 2) == 0 <= 5:
  print("Not Weird")
elif num % 2 == 0 >= 6 and num % 2 == 0 <= 20:
  print("Weird")
elif num % 2 == 0 > 20:
  print("Not Weird")
else:
  print("lol")

Upvotes: 0

Views: 645

Answers (4)

kd4ttc
kd4ttc

Reputation: 1185

There are a couple of problems with your solution. There is nothing wrong with your if-else statements. They are valid, but are not doing what you want. Looking at the first if:

if (num % 2) == 0 >= 2 and (num % 2) == 0 <= 5:
    print("Not Weird")

You first use modulo and test for equality with 0, which is a reasonable test for even vs odd. However, you then compare the boolean result of the even-add test with the number 2. You want to test num with 2, not the boolean of evenness with 2. Testing a boolean result for >= 2 always comes out false. That is True >= 2 is False; and False >=2 is False. Python is smart enough to know that False and (anything else) will be false, so Python won't even evaluate the rest of the statement.

So to test if a number is even and in the range of 2 to 5 inclusive you should want to do:

if num % 2 == 0 and 2 <= num <= 5 :
    print("Not Weird")

A few words about Python: Python differs from other languages in that the form "2 <= num <= 5" is a legal construct. It is darn convenient, but atypical among languages. In other languages the initial 2<=num results in a boolean and then then you would get an error comparing a boolean to 5. It is interesting that Python does not throw an error but results in a boolean. Though Python is atypical it is useful. Other languages would require something like

if (2 <= num) and (num <= 5) then       # Not a Python statement!

Another oddity is that the and operator is lower precedence than the other comparison operators. In other languages and is higher or equal. The Python rules of precedence let you use "num % 2 == 0 and 2 <= num <= 5", so the evenness test and the double inequality run before the "and", so you get a natureal human result. BUT IT IS DIFFERENT FROM OTHER LANGUAGES. You will probably learn a lot of languages over the years. Appreciate how they work.

I'll let you figure out the rest of the statements in your original solution. However, there is another problem: You don't handle odd numbers in your solution correctly, since you are printing out lol. For debugging you are doing the correct thing, since the printing of "Weird" for odd numbers is an ambiguous result. If you did that on purpose for debugging, CONGRATULATIONS!, you are thinking like a programmer digging through your program.

I submit that your approach is a bit of a brute force approach. The directions do say:

If is odd, print Weird 
If is even and in the inclusive range of 2 to 5, print Not Weird 
If is even and in the inclusive range of 6 to 20, print Weird 
If is even and greater than 20, print Not Weird

As a programmer, you do not have to follow the given directions. You need to formulate a solution that results in an algorithm that meets the specifications. Part of the art of programming is to recognize whether the specs are subject to change, anticipate needs for updates, and even correct some assumptions that the specs make that might be in error. So while this is a simple task, it is rich in teaching. (Kudo's to your instructor).

One way to look at the specs is that it implies non-negative inputs. What is one to do with -4 or 0? Not in the specs. It is fair to look at proposed input and see what it is so you can handle that case. Sometimes other logic is added to reject illegal entries. It isn't specified here, so I would handle it with a comment in the code that input is expected to be a positive non-zero integer.

In addition, there is a certain approach that is a bit more wholistic: If odd print Weird and quit, otherwise you know num is even, so further checking is not needed for evenness. So then you print Weird for num in the range [6..20], otherwise print Not Weird. The big picture is odds print Weird, any number [6..20] prints Weird, everything else prints Not Weird.

if num % 2 == 1 :   # Handle odd num
    print("Weird")  # Any odd prints Weird
else:               # Handle even num
    if 6 <= num <= 20: 
        print("Weird") 
    else:
        print("Not Weird")

The point is once you do a test you know womething that can be carried forward in your code. Once you test that something is odd, handle it, and after that the code knows the number if not odd is even, and you don't have to keep testing it. Logically, if odd print and be done. Otherwise (num is even) print "Weird" for num in [6..20], print "Not Weird" otherwise. Rather than 3 tests when a number is even now there is just the one test for num being in the range [6..20].

A few comments are sprinkled in. No testing for input less than 1.

The whole thing could be simplified further

if num % 2 == 1 or 6 <= num <= 20: print("Weird")
else:print("Not Weird")

That does simplify the whole thing.

It is interesting that in programming the simple question of "what is wrong with my statement" can sometimes be addressed with "should I be using this approach?" I've gone far afield with this answer. Originally, what's with my if statement was the issue, but this little gem of a problem is really teaching a lot. (Again, Kudo's to the teacher!)

So, do you transform thw whole question and use an or, or does the first approach work better. In the real world you might have a sense of how the specification may be changed and your solution will be best when it is correct, uses reasonable resources, and is maintainable.

Upvotes: 0

Michael Welch
Michael Welch

Reputation: 1784

As others have pointed out your conditions are not written correctly. Here's the first part to get you started (if the number is odd, and if the number is even and between 2 and 5):

n = input("Enter a number here: ")
num = int(n)
isEven = (num % 2) == 0
if not isEven:
  print("Weird")
elif 2 <= num <= 5:
  print("Not Weird")

Upvotes: 1

Ali Asgar Padaria
Ali Asgar Padaria

Reputation: 25

Just as Random Davis said , the problem is in precedence(or whatever it is called sorry XD) so what it does is : when you check for [(num % 2) == 0 >= 2] : what it does is first checks if num is even[(num % 2)] and then it checks the relation between 0 and 2[0 >= 2] and then equates [ [(num % 2){maybe true or false} == (0 >= 2){always false}]] which results in a LOGICAL ERROR

Rather what you should do is this (((num % 2) == 0) and (1 < num <= 5)) {just as Random Davis said.} what it does is checks whether number is even or not[(num % 2) == 0)] and then if number is between 1 and 5[(1 < num <= 5)] and then cheks if both are true or not.

Hope you understand what I am trying to say.

Upvotes: 0

Random Davis
Random Davis

Reputation: 6857

(num % 2) == 0 >= 2 is not the correct way to check if a number is even and in the range you want. If you want to check if num is even and in that range, you'd do something like:

(((num % 2) == 0) and (1 < num <= 5))

Upvotes: 3

Related Questions