Python Forum
Functions with conditionals and comparison operators
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Functions with conditionals and comparison operators
#1
Here is an exercise provided by an instructor of a Udemy course I am taking:

Quote:LESSER OF TWO EVENS: Write a function that returns the lesser of two given numbers if both numbers are even, but returns the greater if one or both numbers are odd
lesser_of_two_evens(2,4) --> 2
lesser_of_two_evens(2,5) --> 5

Here is my feeble attempt:

def lesser_of_two_evens(a,b):
    if (a % 2 and b % 2) != 0:
        if b > a:
            print(b)
        if a > b:
            print(a)    
    elif (a % 2 and b % 2) == 0:
        if a < b:
            print(a)
        else:
            print(b)    
    pass
To check my work:

lesser_of_two_evens(2,4)
...this correctly prints 2 as output. So this is a partial success. However:

lesser_of_two_evens(2,5)
...invoking this functional call incorrectly prints 2. I was expecting it to print 5 because b is an odd number not divisible by two, so my second conditional if (a % 2 and b % 2) != 0: should have been triggered but it isn’t.

Can anyone provide some insight into why my script is behaving incorrectly?

For my future reference, the course material can be found here: Pierian-Data/Complete-Python-3-Bootcamp. The specific sub- module I am working on is: 03-Methods and Functions/03-Function Practice Exercises.ipynb
Reply
#2
You are detecting two evens correctly. Note that the other case is one or both are odd. Well, if it is not the case that both are even, then one or both are odd. There's no third possibility. So change the elif blah blah blah: to just a plain else.

The pass is not needed. If the code had gotten to that point, it would have done nothing anyway, which is what pass does.

Note that the assignment says to return a number. You are printing a number. That's not the same thing. I would replace print(a) with return a.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#3
Just to add that you don't need to compare boolean variables with 0 (or False/True)
Instead of
if (a % 2 and b % 2) != 0:
just do
if a % 2 and b % 2:
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#4
Based on @Ichabod’s and @buranfor’s feedback, here are the changes I have made since my last forum post:
  • I replaced the line which previously read elif (a % 2 and b % 2) != 0: to just else
  • I removed the explicit pass operation
  • I replaced the print statements with return
  • I removed the explicit boolean references. Instead of if (a % 2 and b % 2) != 0: I now just use: if a % 2 and b % 2:

With these changes, here is what my script looks like now:

def lesser_of_two_evens(a,b):
    if a % 2 and b % 2:
        if b < a:
            return a
        if a > b:
            return b
    else:
        if a < b:
            return b
        else:
            return a
As outlined initially, I’m expecting the following output:

Quote:lesser_of_two_evens(2,4) --> 2
lesser_of_two_evens(2,5) --> 5
lesser_of_two_evens(245,13) --> 245
lesser_of_two_evens(52,10) --> 10

But I am actually getting:

Quote:lesser_of_two_evens(2,4) --> 4
lesser_of_two_evens(2,5) --> 5
lesser_of_two_evens(245,13) --> 245
lesser_of_two_evens(52,10) --> 52

It partially worked. I’ve tried many combinations at lines 4, 6, 9, and 11 (swapping a and b) and then running the script and testing the output. The output is correct for two lines, but then the other two test output lines are incorrect.

What would I need to change in my script to produce the expected output?

The answer key from the instructor is much simpler and less complicated. It reads:

def lesser_of_two_evens(a,b):
    if a%2 == 0 and b%2 == 0:
        return min(a,b)
    else:
        return max(a,b)
Even with this as the most elegant solution, how would you folks modify my script to return the correct output?
Reply
#5
The first problem is on line 2. If the numbers are even, the modulus will be 0. In Python, 0 means false. The direct result is that the code is always going to execute the else statement unless both numbers are odd.

The next problem is on lines 3 and 5. These lines are the same logical statement, just reversed. If b is less than a, then a is greater than b; these are what those two lines say.

The last problem is on line 4. You want to return the lower even and test if b is less than a. If b is less than a, your code returns a, which is the greater value.

Here's a corrected version:

def lesser_of_two_evens(a,b):
    if a % 2 == 0 and b % 2 == 0:
        if b < a: 
            return b
        else:
            return a
    else:
        if a < b:
            return b
        else:
            return a
Reply
#6
What about
def lesser_of_two_evens(a, b):
    return sorted((a, b))[(a | b) & 1]
Reply
#7
First of all, let me say that
if (a % 2 and b % 2) != 0:
and
if a % 2 and b % 2:
have same outcome, as you can see
for a, b in ((3, 5), (2, 5), (5, 2), (4, 2)):
    print((a%2 and b%2) != 0)
    print(a%2 and b%2)
Output:
True 1 False 0 False 0 False 0
I didn't claim it will do what is required in the exercise, just it will do the same as the original code.

def min_max(a, b):
    if a%2 or b%2: # at least one is odd
        return max(a,b)
    else:
        return min(a, b)
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#8
(Dec-26-2018, 05:02 PM)Gribouillis Wrote: What about
def lesser_of_two_evens(a, b):
    return sorted((a, b))[(a | b) & 1]

Would someone care to explain in english sentences this function? I see are two variables (a and b). I see that the built-in sorted function is invoked. I see a tuple and a pipe, in addition to a conjunction and the integer 1. That's about as much as I can understand. Would someone care to translate this python syntax into plain english?

What is really throwing me off is the pipe. This SO question (and ensuing answers from the community) on Python and the pipe operator I find only a little helpful.
Reply
#9
This is about as plain English as I can manage it and it took me a few minutes to figure out because I almost never use bitwise.

First, sorted((a,b)) will return a list of a and b that as been sorted lowest to highest. We can immediately slice it with a value in square brackets. To determine the slice value, it's using bitwise comparisons to determine the index.

Quote:| = bitwise or
& = bitwise and
^ - bitwise xor (exclusive or)

Bitwise comparisons evaluate the values of the underlying bits that comprise the value. Suppose we're performing the code in question with 5 and 6. According to the problem, we should return the higher value because one of the values is odd. So, here it goes:

Quote:The bits of 5 are 0000 0101.
The bits of 6 are 0000 0110.
When compared with or (pipe, |) we get 0000 0111. It compares the corresponding bits at each index; if either is a 1 (true) then it evaluates to true and enters a 1 at that index in the result.

Then, it compares the result to the number 1:

The bits of 1 are 0000 00001.
The bits of our result are 0000 0111.
When compared with and (ampersand, &) we get 0000 0001.

In the function, that would return 1 as the slicing index and return the higher value since one of the numbers is odd. We know it is odd because any byte with a 1 for bit 8 is odd. If both numbers were positive...

Quote:The bits of 6 are 0000 0110.
The bits of 8 are 0000 1000.
Using or 0000 1110.
Using & 1 0000 0000.
0 is returned and index 0 is sliced.
Reply
#10
This Bitwise operation really is next level. Thank you @stullis for this clarification. Wink
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Meltdown Mitigation (operators + conditionals) beware: Exercism potential spoiler Drone4four 5 2,622 Feb-21-2022, 08:49 AM
Last Post: Gribouillis
  Need help with a homework problem on logical operators voodoo 3 4,577 Jun-28-2019, 03:45 PM
Last Post: jefsummers
  Guessing game with comparison operators Drone4four 9 13,730 Dec-02-2018, 06:12 PM
Last Post: ichabod801
  Nested Conditionals Elero 3 7,914 Apr-16-2018, 07:58 PM
Last Post: Elero
  Error with conditionals RiceGum 17 7,168 Oct-18-2017, 01:45 AM
Last Post: ichabod801

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020