The problem statement: Program 2 showed us how to iterate over a list of numbers and print them to the screen. For our next program we will also need to iterate over a list of number but this time we need to count the two different types of numbers in the list as we iterate over them.
The task is to write a Python program that displays the counts of odd and even numbers in a list of positive integers (i.e. whole numbers). In order for us to begin to think about a solution we first need to know the exact definition of odd and even numbers.
Definitions:
- An odd number when divided by two will always have a remainder in addition to a quotient. Some examples of odd numbers in decimal form follow. 1/2 = 0.5, 3/2 = 1.5, 5/2 = 2.5, etc. (Note that 5/2 = 2.5, is read as five divided by 2 is equal to 2.5).
- An even number is the opposite of an odd number. That is, an even number divided by 2 has a quotient but no remainder, does not leave a remainder. Some examples of an even number follow. 0/2 = 0, 2/2 = 1, 4/2 = 2, 6/2 = 3, etc. Note how no decimal is needed since the result of the division does not have a remainder.
The following is the expected approximate output of program 3. Given the list, [0, 4, 9, 5, 11, 15, 7]:
- Even count = 2
- Odd count = 5
The Solution:
def count_odd_and_even_numbers_first_attempt():
even_count = 0
odd_count = 0
for number in [0, 4, 9, 5, 11, 15, 7]:
result = number / 2
if int(result) == result:
'''Even'''
even_count = even_count + 1
else:
'''Odd'''
odd_count = odd_count + 1
print("Even count =", even_count)
print("Odd count =", odd_count)
def count_odd_and_even_numbers_second_attempt():
even_count = 0
odd_count = 0
for number in [0, 4, 9, 5, 11, 15, 7]:
result = number % 2
if result == 0:
'''Even'''
even_count += 1
else:
'''Odd'''
odd_count += 1
print("Even count =", even_count)
print("Odd count =", odd_count)
def count_odd_and_even_numbers_third_attempt():
even_count, odd_count = 0, 0
for number in [0, 4, 9, 5, 11, 15, 7]:
if number % 2 == 0:
'''Even'''
even_count += 1
else:
'''Odd'''
odd_count += 1
print("Even count =", even_count)
print("Odd count =", odd_count)
def program_3():
count_odd_and_even_numbers_first_attempt()
print("--END--")
count_odd_and_even_numbers_second_attempt()
print("--END--")
count_odd_and_even_numbers_third_attempt()
print("--END--")
if __name__ == '__main__':
program_3()
In previous problems our solutions required the use of a for loop, the mathematical operator of multiplication, and the use of the print function. This time the calculations are a little more complex. The additional complexity comes from the fact that we need to consider two possible conditions when looking at a number when determining if a number falls into the odd or even category of numbers. Once we know what category the number is in then we increment one of two variable that holds the running count of the category we detected.
We present three solutions. Each solution is intended to showcase different approaches and programing techniques. Let's start with the function
count_odd_and_even_numbers_second_attempt().
The Counting Variables: The first thing that we do is define two variables, even_count and odd_count. They are initialized to zero, indicating we have yet to see an odd or even number since we have not iterated over the list of numbers. As we iterate over the numbers using a for loop, these two variables will hold a current count of odd and even numbers.
Is it Odd or Even?
By the definition of an odd or even number given above we know that an odd number divided by 2 results in a value that has a remainder, otherwise it is an even number. So the first order of business is to divided the number provided by the for loop by 2 and capture the result as follow. result = number / 2. This expression is our first logic inside the for loop. Suppose the number given inside the for loop is 3. We know that 3 divided by 2 is 1.5. From this result we can see with our eyes and determine with our brain that 3 is an odd number because when we examine the value of 1.5 we observe that there is a value other than zero past the decimal point. But how do we program our thought process into a machine? The short answer is that we use built-in operations or functions that come shipped with the Python programming language. One such built-in function that we can use is the int(...) function. This function will convert inputs to the function into integers only if the input is convertible. If your input is a name like Steve then the int(...) will not be able to do the conversion. In fact, in this particular instance the entire program will crash. But it will work if our input is a number with a decimal value. For example, if our input is 1.0 then it will convert it to the whole value of 1. In a similar fashion, if our input is 2.7 then this function will convert it to the whole value of 2; dropping or truncating the decimal point and any value past the decimal point. Given the int(...) function we can compare its conversion output to its input. For example, suppose we need to determine if the number 3 is even or odd. We first perform the following computation. result = 3 / 2. The result variable will be assigned the value of 1.5 in this expression. We then give the init function the result variable which holds a value of 1.5 as follow. conversion = int(result). If we inspect the conversion variable with the print function we will see that it has a value of 1. Lastly, we compare the conversion value (1) to the result value (1.5). From the comparison we determine that the value three is odd because the conversion value of 1 does not equal the result value of 1.5.
How do we Compare Numbers?
We use the built-in equal operator to compare two values. The symbols or characters used to represent the equal operator is ==. The equal operator works by first comparing two values and then replaces the entire expression with a boolean value. A boolean value has one of two possible states: True or False. Here are two examples of an equal operator (==) that is evaluated (or converted) to the boolean value of True and False.
- 2.0 == 2.0 is evaluated to True
- 3.6 == 3.2 is evaluated to False
How do we Make Decisions using Booleans?
Inside the for loop we need to decide if the current number delivered by the loop is an odd or even number. Our program will need to branch or split into two separate logic flows such that if a given number is even we only increment the even_count variable by a value of 1. If, however, the given number is odd then we only increment the odd_count variable by a value of 1.
This branching (or splitting) of our program into two separate logic flows that depends on the given number being even or odd condition can be accomplished with the use of the concept of an if: ... else: ... block of code. This block of code works as follow. If the if statement of this block of code is followed by a boolean value of True then only the code indented immediately under the if statement is executed; the code indented under the else statement is not executed (or ignored). But if the if statement of this block of code is followed by a boolean value of False then only the code indented immediately under the else statement is executed; the code indented under the if statement is not executed (or ignored). Recall that an equal operator converts an expression like 2.0 == 2.0 to a boolean value of True or False. This equal operator together with the branching feature of the if: ... else: ... block of code can be used to solve the problem statement as shown by the code above. All that needs to be done to complete the solution is to increment the appropriate count variable.
How does the Incrementing of a Variable Work?
The expression even_count = even_count + 1, for example, works as follow. Suppose event_count is initially assigned a value of 5. The assignment operator (=) first evaluates the expression on its right side; event_count + 1 is replaced with the value of 6 because 5 + 1 is equal to this value. Then the assignment operator assigns this new value to the variable, thus overwriting or replacing the old value of 5 with the new value of 6 as follow. event_count = 6
The Modulo Operator:
The modulo operator, represented by the % symbol, is used just like the division operator but instead of getting the result in decimal form, 5 / 3 = 1.66 for example, the [modulo] operator gives us only the remainder of a division operation, 5 % 3 = 2 for example.
Revisiting the definition of an odd and even number we see that an odd number will always have a remainder whereas an even number will not have a remainder. We can combine this definition with the modulo (%) operator to check if a number is odd or even in a more concise way. Before we can use the modulo operator we make the observation that any even number modulo 2 will always compute a remainder of zero whereas an odd number modulo 2 gives us 1. Examples of even numbers follow. 0 % 2 = 0, 2 % 2 = 0, 4 % 2 = 0, 6 % 2 = 0, etc. Examples of odd numbers follow. 1 % 2 = 1, 3 % 2 = 1, 5 % 2 = 1, 7 % 2 = 1, 9 % 2 = 1, etc.
To use the % operator we can either assign the result (or evaluation) of the operator to a variable as shown in the count_odd_and_even_numbers_second_attempt() function like so, result = number % 2, and then check the value in an if statement or allow for the evaluation of the % operator to occur directly in the if statement without the need to use an additional variable as shown in the count_odd_and_even_numbers_third_attempt() function, like so if number % 2 == 0:.
The Increment Operator:
Another useful operator that allows us to increment a variable is +=. As we saw in our first attempt function we incremented a variable with the following code. some_variable = some_variable + 1. We can write the equivalent of this expression instead as some_variable += 1. An actual use of this operator can be seen in the second attempt function.
Multiple Assignments:
Note that in our third attempt function we declared and assigned initialization values of zero to both count variables but we did so on a single line. This is equivalent to declaring and assigning the count variables on separate lines. Both approaches are valid and you should pick the option that makes the most sense and is most visually pleasing to you.
Note that the third attempt function is less verbose than our first attempt and arguably more readable. It's also possible to make further refinements but we will explore other options in future tutorials.
Page with links to the entire series can be found here
Are you having any issues running or understanding the program? Please, add a comment explaining where you are stuck or where the tutorial is not clear so we can improve it.