MP: The Frequency Count Program 2.0
Consider a similar program to the Frequency Count Program 1.0.
# print the results with the dictionary sorted.
number_list = []
count_dict = {}
input_string = input("Please enter a whole number: ")
while input_string != "q":
number_list.append(int(input_string))
if int(input_string) in count_dict.keys():
count_dict[int(input_string)] += 1
else:
count_dict[int(input_string)] = 1
input_string = input("Please enter a whole number: ")
# print out the count of the numbers
print(f"The numbers seen were {number_list}")
for key, value in sorted(count_dict.items()):
print(f"The count for {key} is: {value}")
For example, the program will work as follows:
Please enter a whole number: 3
Please enter a whole number: 5
Please enter a whole number: 2
Please enter a whole number: 6
Please enter a whole number: 7
Please enter a whole number: 1
Please enter a whole number: 10
Please enter a whole number: 63
Please enter a whole number: q
The numbers seen were [3, 5, 2, 6, 7, 1, 10, 63]
The count for 1 is: 1
The count for 2 is: 1
The count for 3 is: 1
The count for 5 is: 1
The count for 6 is: 1
The count for 7 is: 1
The count for 10 is: 1
The count for 63 is: 1
Decomposition
We can reorder this program to do the three tasks separately.
- Collect the numbers
- Do the counting
- Print out to the count of the numbers to the user
# print the results with the dictionary sorted.
# collect the numbers
number_list = []
input_string = input("Please enter a whole number: ")
while input_string != "q":
number_list.append(int(input_string))
input_string = input("Please enter a whole number: ")
# do the counting
count_dict = {}
for num in number_list:
if num in count_dict.keys():
count_dict[num] += 1
else:
count_dict[num] = 1
# print out the count of the numbers
print(f"The numbers seen were {number_list}")
for key, value in sorted(count_dict.items()):
print(f"The count for {key} is: {value}")
This program now has three distinct parts. That is, it has been decomposed into three separate parts.
We can now go further and wrap each of these parts in a function.
Decompostion with Functions
def get_numbers():
""" Get a sequence of numbers from the user """
number_list = []
input_string = input("Please enter a whole number: ")
while input_string != "q":
number_list.append(int(input_string))
input_string = input("Please enter a whole number: ")
return number_list
def frequency_count(num_list):
""" Count the frequency of the numbers """
count_dict = {}
for num in num_list:
if num in count_dict.keys():
count_dict[num] += 1
else:
count_dict[num] = 1
return count_dict
def print_frequency_count(count_dict):
"""Print out the count of the numbers"""
for key, value in sorted(count_dict.items()):
print(f"The count for {key} is: {value}")
def main():
number_list = get_numbers() # get numbers from user
freq_count_dict = frequency_count(number_list) # get freq count
print(f"The numbers seen were {number_list}")
print_frequency_count(freq_count_dict) # print feedback
if __name__ == '__main__':
main()
You can see here that we now have three functions that have the responsibility for single parts of our program. These are then called in sequence by the main()
function.
get_numbers()
returns the numbers entered by the userfrequency_count()
takes in a list of numbers and counts the frequency. Returns a dictionary.print_frequency_count()
takes in a dictionary containing the frequency count. Prints out the frequency count to the terminal.
Abstraction
This is now much more manageable and I don't care how these functions work, just that they do! You could replace any of these functions with something that has the same inputs and outputs and the main()
program would still work.
Here is an example.
def get_numbers():
return [1,1,1,2,2,4,5,7,35]
The whole program will still work even though we changed get_numbers()
. This is because it still just returns a list of numbers. This is the essence of abstraction. Functions can be treated as black-boxes.
We can even replace frequency_count()
with dictionary comprehension using a list method and some set magic.
def frequency_count(num_list):
return {item:num_list.count(item) for item in set(num_list)}
I'll leave you to try and work this out, but the point again is that we don't care how it works, we just care it does! Black-box!