As part of Nick Russo’s DevAsc study plan, he recommends doing a few Python challenges to check your existing knowledge of Python. One of these is the Divisors challenge. The goal of of this exercise is to take a number, such as 12, and then find all the divisors, that is the numbers that you can divide 12 with and have no remainder. This would 1, 2, 3, 4, 6, and finally 12 itself.

Now, solving this doesn’t take a lot of code. However, I decided that gold plating is allowed in my studies of code. That is, I would rather practice writing functions from the get go rather than just quickly moving from exercises.

To find divisors, we need a little basic math. We can use the Modulo operation to find the reminder of a division. For example, if you divide 5 by 2, the remainder is 1. We call this 5 modulo 2. Because there is a remainder of 1, this means that 2 is not a divisor for 5. If we however use 9 and 3 instead, with 9 modulo 3, the remainder is 0. This means that 3 is a divisor for 9. We then know that the remainder should be 0 for all divisors and we can easily check this with the modulo operation.

I decided to divide my code into three functions:

  • get_number
  • create_list
  • check_divisor

First, it’s good practice to describe what your program does with a docstring:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
"""Program to check all divisors of a positive integer"""
"""Program to check all divisors of a positive integer"""
"""Program to check all divisors of a positive integer"""

Our program will look for all divisors for positive integers.

The first step to finding a divisor, is to ask the user for what number to check. We can ask the user to input a number using the

input()
input() function in Python.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
number = input("Please enter a positive integer: ")
number = input("Please enter a positive integer: ")
number = input("Please enter a positive integer: ")

It’s important to note that this function returns a string. We need a number, more specifically an integer. Luckily, we can use the

int()
int() function to get an integer from the string specified. We will call this variable
number_int
number_int.

Like I said, I wanted to create a function out of this code:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
def get_number():
"""Get a number from user, convert to integer,
and return the value"""
# Get number, this will be a string
number = input("Please enter a positive integer: ")
# Convert string to an integer
number_int = int(number)
# Return the number
return number_int
def get_number(): """Get a number from user, convert to integer, and return the value""" # Get number, this will be a string number = input("Please enter a positive integer: ") # Convert string to an integer number_int = int(number) # Return the number return number_int
def get_number():
    """Get a number from user, convert to integer,
    and return the value"""
    # Get number, this will be a string
    number = input("Please enter a positive integer: ")
    # Convert string to an integer
    number_int = int(number)
    # Return the number
    return number_int

Notice that the function returns

number_int
number_int and that this function doesn’t require any arguments. When I first tried my complete solution, I had an error saying something about
number_int
number_int not being defined. What I hadn’t realized, was that even though I am returning
number_int
number_int in my function, this variable is only known within the function. It does not have global scope. I wanted to take this value and feed it into the next function. We’ll get back to this later.

Our next goal is to create a list that contains all possible divisors. In Python, there is a function called

range()
range() that we can use to create ranges of values. To find all divisors, we want to create a list where 1 is the first number and where the last number is the number that the user input, namely
number_int
number_int. When using the
range()
range() function, the first argument we give is the starting number. The second argument we give, is the ending number. However, ending number actually means that the range is from starting number to ending number – 1. Meaning that if we use
range(1, 10)
range(1, 10), the range would be from 1 to 9.

One error I did at this point was thinking I could create a list like this:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
>>> mylist = range(1, 10)
>>> print(mylist)
range(1, 10)
>>> mylist = range(1, 10) >>> print(mylist) range(1, 10)
>>> mylist = range(1, 10)
>>> print(mylist)
range(1, 10)

However, as you see, this just created a list containing the range, not the numbers themself. What we need to do is to combine this with the

list()
list() function.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
>>> mylist = list(range(1, 10))
>>> print(mylist)
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> mylist = list(range(1, 10)) >>> print(mylist) [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> mylist = list(range(1, 10))
>>> print(mylist)
[1, 2, 3, 4, 5, 6, 7, 8, 9]

Now we have an actual list.

Great, now let’s turn this into a function. We want to send the argument

number_int
number_int into the function. When creating the list, the range will be from 1 to
number_int
number_int + 1. Why do we need to add 1 to number_int? Because otherwise the list will not be complete because the
range()
range() function creates a range where the range ends one number before the ending number input.

 

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
def create_list(number_int):
"""Create list consisting of all numbers from zero
to user-specified number, to find divisors"""
# Create list using range, user number plus 1 is end number
mylist = list(range(1, (number_int + 1)))
# Return the list
return mylist
def create_list(number_int): """Create list consisting of all numbers from zero to user-specified number, to find divisors""" # Create list using range, user number plus 1 is end number mylist = list(range(1, (number_int + 1))) # Return the list return mylist
def create_list(number_int):
    """Create list consisting of all numbers from zero
    to user-specified number, to find divisors"""
    # Create list using range, user number plus 1 is end number
    mylist = list(range(1, (number_int + 1)))
    # Return the list
    return mylist

We return a list called

mylist
mylist. One mistake I made here was first calling the list I was creating
list
list. Don’t name your variables to something that exists within Python itself, such as function names, you may end up with code not running.

Now for the code that actually looks for divisors. What we are trying to achieve is this:

  • Create an empty list containing divisors
  • Iterate through all numbers in mylist
  • Check if we have a divisor with modulo function
  • If we have a match, add it to the list
  • Print all the divisors

Creating an empty list is as easy as this:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
divisors = []
divisors = []
divisors = []

We then have the code looking for divisors:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
for number in mylist:
# Check if modulo is 0, then divisor is found
if (mylist[-1] % number == 0):
# When divisor found, add to list
divisors.append(number)
for number in mylist: # Check if modulo is 0, then divisor is found if (mylist[-1] % number == 0): # When divisor found, add to list divisors.append(number)
for number in mylist:
        # Check if modulo is 0, then divisor is found
        if (mylist[-1] % number == 0):
            # When divisor found, add to list
            divisors.append(number)

We iterate through all the numbers in mylist using the iterator

number
number. To see if we have a divisor, we have in if statement with
(mylist[-1] % number == 0)
(mylist[-1] % number == 0). What does
mylist[-1]
mylist[-1] mean? It’s the last number in our list, the number that the user originally input. To use the modulo fuction in Python, we use the
%
% operator. If the result is == 0, then we have a divisor.

If a divisor is found, we add it to the list called divisors with the

append()
append() function.

We also want the function to print all the divisors. This is done below:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
for divisor in divisors:
print(divisor)
for divisor in divisors: print(divisor)
for divisor in divisors:
        print(divisor)

All the divisors are in the

divisors
divisors list. We iterate using
divisor
divisor and then simply print them one by one.

We now have three functions, but our code doesn’t really do anything. We need to actually call the functions. This is done below:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
if __name__ == "__main__":
number_int = get_number()
mylist = create_list(number_int)
check_divisor(mylist)
if __name__ == "__main__": number_int = get_number() mylist = create_list(number_int) check_divisor(mylist)
if __name__ == "__main__":
    number_int = get_number()
    mylist = create_list(number_int)
    check_divisor(mylist)

The first if statement just checks that if dunder

name
name is dunder
main
main, the code is run, that is if it’s run standalone and not imported as a module.

Like I mentioned before, variables are local to functions. That’s why I need to use

number_int
number_int globally. I get this value by calling
get_number()
get_number(). Then this number, an integer, is fed into
create_list
create_list, as an argument, to create our list of potential divisors. Finally, we take the result of this function in the form of
mylist
mylist, send it through
check_divisor
check_divisor and get our divisors printed to us. Neat! This is what it looks like:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
daniel@devasc:~/DevAsc$ python3 divisors.py
Please enter a positive integer: 48
1
2
3
4
6
8
12
16
24
48
daniel@devasc:~/DevAsc$
daniel@devasc:~/DevAsc$ python3 divisors.py Please enter a positive integer: 48 1 2 3 4 6 8 12 16 24 48 daniel@devasc:~/DevAsc$
daniel@devasc:~/DevAsc$ python3 divisors.py 
Please enter a positive integer: 48
1
2
3
4
6
8
12
16
24
48
daniel@devasc:~/DevAsc$ 

Finally, here’s the entire code if you want to run it for yourself:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
"""Program to check all divisors of a positive integer"""
def get_number():
"""Get a number from user, convert to integer,
and return the value"""
# Get number, this will be a string
number = input("Please enter a positive integer: ")
# Convert string to an integer
number_int = int(number)
# Return the number
return number_int
def create_list(number_int):
"""Create list consisting of all numbers from zero
to user-specified number, to find divisors"""
# Create list using range, user number plus 1 is end number
mylist = list(range(1, (number_int + 1)))
# Return the list
return mylist
def check_divisor(mylist):
"""Take a list and check for all divisors"""
# Create empty list to store divisors
divisors = []
# Loop through the list
for number in mylist:
# Check if modulo is 0, then divisor is found
if (mylist[-1] % number == 0):
# When divisor found, add to list
divisors.append(number)
# Print all divisors
for divisor in divisors:
print(divisor)
# Run code if not imported as module
if __name__ == "__main__":
number_int = get_number()
mylist = create_list(number_int)
check_divisor(mylist)
"""Program to check all divisors of a positive integer""" def get_number(): """Get a number from user, convert to integer, and return the value""" # Get number, this will be a string number = input("Please enter a positive integer: ") # Convert string to an integer number_int = int(number) # Return the number return number_int def create_list(number_int): """Create list consisting of all numbers from zero to user-specified number, to find divisors""" # Create list using range, user number plus 1 is end number mylist = list(range(1, (number_int + 1))) # Return the list return mylist def check_divisor(mylist): """Take a list and check for all divisors""" # Create empty list to store divisors divisors = [] # Loop through the list for number in mylist: # Check if modulo is 0, then divisor is found if (mylist[-1] % number == 0): # When divisor found, add to list divisors.append(number) # Print all divisors for divisor in divisors: print(divisor) # Run code if not imported as module if __name__ == "__main__": number_int = get_number() mylist = create_list(number_int) check_divisor(mylist)
"""Program to check all divisors of a positive integer"""

def get_number():
    """Get a number from user, convert to integer,
    and return the value"""
    # Get number, this will be a string
    number = input("Please enter a positive integer: ")
    # Convert string to an integer
    number_int = int(number)
    # Return the number
    return number_int

def create_list(number_int):
    """Create list consisting of all numbers from zero
    to user-specified number, to find divisors"""
    # Create list using range, user number plus 1 is end number
    mylist = list(range(1, (number_int + 1)))
    # Return the list
    return mylist

def check_divisor(mylist):
    """Take a list and check for all divisors"""
    # Create empty list to store divisors
    divisors = []
    # Loop through the list
    for number in mylist:
        # Check if modulo is 0, then divisor is found
        if (mylist[-1] % number == 0):
            # When divisor found, add to list
            divisors.append(number)
    # Print all divisors
    for divisor in divisors:
        print(divisor)

# Run code if not imported as module
if __name__ == "__main__":
    number_int = get_number()
    mylist = create_list(number_int)
    check_divisor(mylist)

I have also added the code to Github.

I hope this post was helpful. I certainly learned a lot by writing it.

DevAsc – Python Divisors Challenge
Tagged on:             

4 thoughts on “DevAsc – Python Divisors Challenge

  • Pingback:DevAsc – Python Palindrome Challenge – Daniels Networking Blog

  • November 2, 2020 at 12:21 am
    Permalink

    Hi.
    First of all, this code is very memory hungry. You`re creating the list with every number between 1 and target. Try with a big one, it simply won`t work.
    Please enter a positive integer: 999999999
    Traceback (most recent call last):

    MemoryError

    Second, this code is very slow. Try with a working, but big number.
    My PC needs almost 29 seconds to calculate divisors for 100 000 000 with your program.

    Cheers 🙂

    Reply
  • November 2, 2020 at 12:35 am
    Permalink

    My version of function:

    def check_divisor(targetNumber):
    “””Check for all divisors”””
    # Create empty list to store divisors
    divisors = list()
    for x in range(1, int(math.sqrt(targetNumber))+1): # Should check till sqrt(x)
    if not targetNumber%x:
    divisors.append(x)
    if targetNumber/x != x: # If target is not a square, add second divisor
    divisors.append(int(targetNumber/x))
    divisors.sort() # To get a sorted list
    for x in divisors:
    print(x)

    It stores only divisors it has found and it works quite fast.
    0.23 seconds to find all divisors of 1 000 000 000 000

    Reply
    • November 15, 2020 at 9:31 am
      Permalink

      Cool! Thanks!

      Reply

Leave a Reply to rel1ct0 Cancel reply

Your email address will not be published. Required fields are marked *