Katie Hough
Katie Hough

Reputation: 41

Using multiple Ifs in python that are not mutually exclusive

a=0
while a<30:
    a+=1
    print(a)
    if a%3==0:
        print("This is a multiple of 3.")
    if a%5==0:
        print("This is a multiple of 5.")
    else:
        print("This is not a multiple of 3 or 5.")

I'd like for this else statement to only print if NEITHER of the previous if statements are true. I don't want to use if, elif, else because the variable could be both a multiple of 3 and 5.

Upvotes: 4

Views: 1548

Answers (5)

Eric Duminil
Eric Duminil

Reputation: 54313

You could use a list comprehension with an integrated if to get a list of the divisors. If it's empty, you can print "This is not a multiple of ..."

This way, it's easier to add possible divisors and to write a sentence describing the result:

N = 30
primes = [3, 5]
primes_str = ' or '.join(str(p) for p in primes)

for n in range(1, N + 1):
    divisors = [str(p) for p in primes if n % p == 0]
    if divisors:
        print("%d is a multiple of %s." % (n, ' and '.join(divisors)))
    else:
        print("%d is not a multiple of %s." % (n, primes_str))

It outputs:

1 is not a multiple of 3 or 5.
2 is not a multiple of 3 or 5.
3 is a multiple of 3.
4 is not a multiple of 3 or 5.
5 is a multiple of 5.
6 is a multiple of 3.
7 is not a multiple of 3 or 5.
8 is not a multiple of 3 or 5.
9 is a multiple of 3.
10 is a multiple of 5.
11 is not a multiple of 3 or 5.
12 is a multiple of 3.
13 is not a multiple of 3 or 5.
14 is not a multiple of 3 or 5.
15 is a multiple of 3 and 5.
16 is not a multiple of 3 or 5.
17 is not a multiple of 3 or 5.
18 is a multiple of 3.
19 is not a multiple of 3 or 5.
20 is a multiple of 5.
21 is a multiple of 3.
22 is not a multiple of 3 or 5.
23 is not a multiple of 3 or 5.
24 is a multiple of 3.
25 is a multiple of 5.
26 is not a multiple of 3 or 5.
27 is a multiple of 3.
28 is not a multiple of 3 or 5.
29 is not a multiple of 3 or 5.
30 is a multiple of 3 and 5.

If you only want to test if the number isn't a multiple, you can use any or all:

for n in range(1, N + 1):
    if all(n % p for p in primes):
        print("%d is not a multiple of %s." % (n, primes_str))

for n in range(1, N + 1):
    if not any(n % p == 0 for p in primes):
        print("%d is not a multiple of %s." % (n, primes_str))

If you want to consider 7 and 11, just define primes = [3, 5, 7, 11].

Upvotes: 2

Chris
Chris

Reputation: 23003

Another option is to test if both the modulo for 3 and 5 are "truthy". If they are, then you know that a is not a multiple of 3 or 5. You can also avoid recalculating the modulo for each number by doing at once at the beginning of the loop, and using the results throughout the rest of the body:

a = 0
while a < 30:
    a += 1
    mod3, mod5 = a % 3, a % 5
    if not mod3:
        print("This is a multiple of 3.")
    if not mod5:
        print("This is a multiple of 5.")
    if mod3 and mod5:
        print("This is not a multiple of 3 or 5.") 

Upvotes: 2

cs95
cs95

Reputation: 403278

Expanding upon my comment:

if not a % 3:
    print("This is a multiple of 3.")

if not a % 5:
    print("This is a multiple of 5.")

if a % 3 and a % 5:
    print("Not a multiple of 3 or 5.")

If a number is divisible, a % x is 0, which is False. We use the truthiness of 0 and 1 to determine the outcome of the conditional.


Slight optimisation:

if not a % 3:
   ...

if not a % 5:
   ...

elif a % 3:
   ...

Condenses the last 3 tests slightly to prevent a redundant test.


In the end, I believe a flag is nicer, because you perform your arithmetic operations one time less.

Upvotes: 2

cdlane
cdlane

Reputation: 41925

Retaining the flavor of the original (except for the while/for swap):

for a in range(1, 31):
    print(a)

    if a % 3 == 0:
        print("This is a multiple of 3.")

        if a % 15 != 0:
            continue
    if a % 5 == 0:
        print("This is a multiple of 5.")
    else:
        print("This is not a multiple of 3 or 5."

Upvotes: 1

Jean-Fran&#231;ois Fabre
Jean-Fran&#231;ois Fabre

Reputation: 140316

you could set a flag if one of both conditions is matched. If the flag is still False after both tests, print the fallback message:

a=0
while a<30:
    a+=1
    print(a)
    match = False
    if a%3==0:
        print("This is a multiple of 3.")
        match = True
    if a%5==0:
        print("This is a multiple of 5.")
        match = True
    if not match:
        print("This is not a multiple of 3 or 5.") 

this technique also avoids computing modulo of 3 and 5 more than once.

If you want to add more divisors, avoid copy/paste, and consider testing in a loop (BTW why using a while loop when you have for and range ?):

for a in range(1,31):
    print(a)
    match = False
    for i in [3,5]:
        if a%i==0:
            print("This is a multiple of {}.".format(i))
            match = True
    if not match:
        print("This is not a multiple of 3 or 5.")

Upvotes: 6

Related Questions